diff --git a/AUTHORS b/AUTHORS
index 6c9f5e7..58c300d7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -89,6 +89,7 @@
 anatoly techtonik <techtonik@gmail.com>
 Ancil George <ancilgeorge@samsung.com>
 Andra Paraschiv <andra.paraschiv@intel.com>
+Andras Tokodi <a.tokodi@eyeo.com>
 Andreas Papacharalampous <andreas@apap04.com>
 Andrei Borza <andrei.borza@gmail.com>
 Andrei Parvu <andrei.prv@gmail.com>
@@ -191,7 +192,6 @@
 Carlos Santa <carlos.santa@intel.com>
 Catalin Badea <badea@adobe.com>
 Cathie Chen <cathiechen@tencent.com>
-Cedric Tio <cedric.tio@xperi.com>
 Cem Kocagil <cem.kocagil@gmail.com>
 Cezary Kułakowski <cezary.kulakowski@gmail.com>
 Chakshu Ahuja <chakshu.a@samsung.com>
@@ -309,7 +309,6 @@
 Dongyu Lin <l2d4y3@gmail.com>
 Donna Wu <donna.wu@intel.com>
 Douglas F. Turner <doug.turner@gmail.com>
-Douglas Wong <Douglas.wong@xperi.com>
 Dustin Doloff <doloffd@amazon.com>
 Ebrahim Byagowi <ebrahim@gnu.org>
 Ebrahim Byagowi <ebraminio@gmail.com>
@@ -967,7 +966,6 @@
 Rosen Dash <rosen.dash@gmail.com>
 Ross Kirsling <rkirsling@gmail.com>
 Ross Wollman <ross.wollman@gmail.com>
-Roy Funderburk <roy.funderburk@xperi.com>
 Roy Le <royle0502@gmail.com>
 Ruan Beihong <ruanbeihong@gmail.com>
 ruben <chromium@hybridsource.org>
diff --git a/BUILD.gn b/BUILD.gn
index dc8b05b..5ef5628 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -12,6 +12,7 @@
 import("//build/config/compiler/compiler.gni")
 import("//build/config/dcheck_always_on.gni")
 import("//build/config/features.gni")
+import("//build/config/rust.gni")
 import("//build/config/sanitizers/sanitizers.gni")
 import("//build/config/ui.gni")
 import("//build/gn_logs.gni")
@@ -669,7 +670,6 @@
       "//sandbox/win:sbox_unittests",
       "//sandbox/win:sbox_validation_tests",
       "//testing/gtest:gtest_main",
-      "//third_party/tcmalloc:addr2line-pdb",
 
       # The following two are accessibility API debugging tools.
       "//tools/accessibility/inspect:ax_dump_events",
@@ -854,6 +854,14 @@
 
   # Minimal binaries to exercise Rust toolchain.
   deps += [ ":rust_build_tests" ]
+
+  # More Rust targets.
+  if (toolchain_has_rust) {
+    deps += [
+      "//mojo/public/rust",
+      "//mojo/public/rust:tests",
+    ]
+  }
 }
 
 group("rust_build_tests") {
@@ -1604,7 +1612,6 @@
     if (is_chromeos_ash) {
       data_deps += [
         "ash/webui:closure_compile",
-        "chromeos/components:closure_compile",
         "ui/file_manager:closure_compile",
       ]
     }
diff --git a/DEPS b/DEPS
index 53c1ce9..9db82fb 100644
--- a/DEPS
+++ b/DEPS
@@ -213,7 +213,7 @@
   # luci-go CIPD package version.
   # Make sure the revision is uploaded by infra-packagers builder.
   # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console
-  'luci_go': 'git_revision:09f8b3edbbf18dc63d0d5aa7722ae7acc20b11b4',
+  'luci_go': 'git_revision:7528d700b89db0b6feb32be098d40597f738d3c7',
 
   # This can be overridden, e.g. with custom_vars, to build clang from HEAD
   # instead of downloading the prebuilt pinned revision.
@@ -245,23 +245,23 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '2b80cb6636efda8e6635809f937ca50f259f792a',
+  'skia_revision': '0cfc76a0dd82d43b4ba0241d76250187ee75118c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'b0a622059936a78d0c9f079e08797ed7200a9099',
+  'v8_revision': 'e44c84d7815a1124e3a0e4f82172b9acb2bef738',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '1316d15349dbbef7c48b44b48bcbc321215a3605',
+  'angle_revision': '2ad5f350c55575d73585e47ee2f50e90035cc4ec',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '7119686677488e18ff635d39f4a41fab0d8ed940',
+  'swiftshader_revision': 'bca23447ad4667a7b79973569ab5d8d905d211ac',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'e8369ac66e9954ba8039baf4d51db21bb2312d2e',
+  'pdfium_revision': '2155ad65d144466a6789e5dae9f03e4e3c35649d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -292,7 +292,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '267c6918d1575c83fc4412e3ffff91ae0b07b823',
+  'freetype_revision': '837f0345a9a6f3f64c94a41d944b097ffa359e5a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -320,7 +320,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '547e711f3aea29c343bd256bec73be1aa4908c4f',
+  'devtools_frontend_revision': 'd8e38badf3d8c1edf91a8a2f606e7816f7d06d0f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -360,7 +360,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '3d3e1757c42b1e494817bf7b6d4f5bc9c503af11',
+  'dawn_revision': '153d1cfecee566aa2e2729a1bcbf14c3db369aff',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -564,6 +564,27 @@
       ],
   },
 
+  'src/third_party/updater/chromium_win_x86': {
+      'dep_type': 'cipd',
+      'condition': 'checkout_win',
+      'packages': [
+        {
+          'package': 'chromium/third_party/updater/chromium_win_x86',
+          'version': 'zdcQMuiuIXnQQ4eBsYyk0uNTr4N0LaphcQYs0RUByZQC',
+        },
+      ],
+  },
+
+  'src/third_party/updater/chromium_win_x86_64': {
+      'dep_type': 'cipd',
+      'condition': 'checkout_win',
+      'packages': [
+        {
+          'package': 'chromium/third_party/updater/chromium_win_x86_64',
+          'version': 'tpakNFR82tZRgkWuRbgyNlc-O93aCKAm5S2zV26snOkC',
+        },
+      ],
+  },
 
   'src/tools/clang/dsymutil': {
     'packages': [
@@ -642,7 +663,7 @@
     Var('chromium_git') + '/external/github.com/toji/webvr.info.git' + '@' + 'c58ae99b9ff9e2aa4c524633519570bf33536248',
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + '198b96feac9e0ea762b8c568ac823078adf13c33',
+    'url': Var('chromium_git') + '/website.git' + '@' + '6d85be91ee86cf0727cacc8a772f4089d15bb9f9',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -1069,7 +1090,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'd05a2e03953bf7e58696a0401ba41360b627401c',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'd5862557d6a2ceef3f85092aa76682a4cdf2fc4e',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1209,7 +1230,7 @@
     Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '18e09b9197a3b1d771c077c530d1a4ebad04c167',
 
   'src/third_party/icu':
-    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'b9f6d0a5c5375dc4643f35360d257dba37c1d3e1',
+    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '609143a639dcc0884a87c899614895ce129afdb8',
 
   'src/third_party/icu4j': {
       'packages': [
@@ -1435,7 +1456,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b52786888ddce9d6bc06b7825ba9bffc65924e0c',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + '18b812750535e0433718472f5aa35b6a18f3f310',
+    Var('chromium_git') + '/openscreen' + '@' + 'fd78efa171d154ac801cf615b95dbe8798d1501d',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245',
@@ -1452,7 +1473,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '90067240375687eadb2465ea6d4c940ebf6772eb',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'a0de991bf39c5744ab4eef00eae823c378eb99a9',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1634,7 +1655,7 @@
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '62d7d0c928c9a040dce96aa2f16c00e7e67d59cb',
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@3dcebfc43aa488de8020ab980adbcaf6b498e944',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@0ce8f86158f9b2bbcb96b66c324e26c5e7110af1',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907',
@@ -1670,10 +1691,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'b1f3776e4913637221733a4da09f3339e783b771',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '195cc926f756bb060aac1e7597f87bf4db479fcf',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '89f20c5e69574ffbede2d89e18b4dba71bf9c1f2',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '38c762c0abca22eb2c23f38dfd20a5ecf9163ef2',
+    Var('webrtc_git') + '/src.git' + '@' + 'c9105da7a0ee4527ee02613f366542b06edc196d',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1743,7 +1764,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@17f9945a4db5c6ba7498c9766322a3b20c3705e3',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@03056849eb5d6a1ced7b6f1f42e93cb70da6ced6',
     'condition': 'checkout_src_internal',
   },
 
@@ -4744,6 +4765,17 @@
     ],
   },
   {
+    'name': 'Fetch PGO profiles for mac arm',
+    'pattern': '.',
+    'condition': 'checkout_pgo_profiles and checkout_mac',
+    'action': [ 'python3',
+                'src/tools/update_pgo_profiles.py',
+                '--target=mac-arm',
+                'update',
+                '--gs-url-base=chromium-optimization-profiles/pgo_profiles',
+    ],
+  },
+  {
     'name': 'Fetch PGO profiles for linux',
     'pattern': '.',
     'condition': 'checkout_pgo_profiles and checkout_linux',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 48bcc58..dca0909 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1735,6 +1735,8 @@
     "wm/desks/templates/desks_templates_presenter.h",
     "wm/desks/templates/desks_templates_util.cc",
     "wm/desks/templates/desks_templates_util.h",
+    "wm/desks/templates/save_desk_template_button.cc",
+    "wm/desks/templates/save_desk_template_button.h",
     "wm/desks/zero_state_button.cc",
     "wm/desks/zero_state_button.h",
     "wm/drag_details.cc",
@@ -2594,6 +2596,7 @@
     "system/power/power_prefs_unittest.cc",
     "system/power/power_status_unittest.cc",
     "system/power/video_activity_notifier_unittest.cc",
+    "system/progress_indicator/progress_indicator_animation_registry_unittest.cc",
     "system/rotation/rotation_lock_feature_pod_controller_unittest.cc",
     "system/scheduled_feature/scheduled_feature_unittest.cc",
     "system/screen_layout_observer_unittest.cc",
diff --git a/ash/ambient/model/ambient_animation_photo_provider.cc b/ash/ambient/model/ambient_animation_photo_provider.cc
index de114f3..a8c1c3f3 100644
--- a/ash/ambient/model/ambient_animation_photo_provider.cc
+++ b/ash/ambient/model/ambient_animation_photo_provider.cc
@@ -49,26 +49,21 @@
 class StaticImageAssetImpl : public cc::SkottieFrameDataProvider::ImageAsset {
  public:
   StaticImageAssetImpl(base::StringPiece asset_id,
-                       const AmbientAnimationStaticResources* static_resources)
-      : asset_id_(asset_id), static_resources_(static_resources) {
-    DCHECK(!ambient::util::IsDynamicLottieAsset(asset_id_));
-    DCHECK(static_resources_);
+                       const AmbientAnimationStaticResources& static_resources)
+      : image_(static_resources.GetStaticImageAsset(asset_id)) {
+    DCHECK(!ambient::util::IsDynamicLottieAsset(asset_id));
+    DCHECK(!image_.isNull())
+        << "Static image asset " << asset_id << " is unknown.";
+    DVLOG(1) << "Loaded static asset " << asset_id;
   }
 
-  absl::optional<cc::SkottieFrameData> GetFrameData(float t, float scale_factor)
-      override {
-    // The static image only needs to be provided one time in the animation's
-    // lifetime. Afterwards, return nullopt to indicate no change to the asset's
-    // contents.
-    if (has_provided_first_frame_)
-      return absl::nullopt;
-
-    has_provided_first_frame_ = true;
-    gfx::ImageSkia image = static_resources_->GetStaticImageAsset(asset_id_);
-    DCHECK(!image.isNull())
-        << "Static image asset " << asset_id_ << " is unknown.";
-    DVLOG(1) << "Returning static asset " << asset_id_;
-    return BuildSkottieFrameData(image, scale_factor);
+  cc::SkottieFrameData GetFrameData(float t, float scale_factor) override {
+    if (!current_frame_data_.image ||
+        current_frame_data_scale_factor_ != scale_factor) {
+      current_frame_data_ = BuildSkottieFrameData(image_, scale_factor);
+      current_frame_data_scale_factor_ = scale_factor;
+    }
+    return current_frame_data_;
   }
 
  private:
@@ -76,9 +71,9 @@
   // ref-counted API.
   ~StaticImageAssetImpl() override = default;
 
-  const std::string asset_id_;
-  const AmbientAnimationStaticResources* const static_resources_;
-  bool has_provided_first_frame_ = false;
+  const gfx::ImageSkia image_;
+  cc::SkottieFrameData current_frame_data_;
+  float current_frame_data_scale_factor_ = 0;
 };
 
 }  // namespace
@@ -105,8 +100,7 @@
     new_image_ = std::move(image);
   }
 
-  absl::optional<cc::SkottieFrameData> GetFrameData(float t, float scale_factor)
-      override {
+  cc::SkottieFrameData GetFrameData(float t, float scale_factor) override {
     DVLOG(4) << "GetFrameData for asset " << asset_id_ << " time " << t;
     bool is_first_rendered_frame =
         last_observed_animation_timestamp_ == kAnimationTimestampInvalid;
@@ -118,18 +112,18 @@
     last_observed_animation_timestamp_ = t;
     if (!is_first_rendered_frame && !is_starting_new_cycle) {
       DVLOG(4) << "No update required to dynamic asset at this time";
-      return absl::nullopt;
+      return GetCurrentFrameData(scale_factor);
     }
 
     if (new_image_.isNull())
       refresh_image_cb_.Run();
 
     DCHECK(!new_image_.isNull());
-    cc::SkottieFrameData frame_data =
-        BuildSkottieFrameData(new_image_, scale_factor);
+    current_frame_data_ = BuildSkottieFrameData(new_image_, scale_factor);
+    current_frame_data_scale_factor_ = scale_factor;
     new_image_ = gfx::ImageSkia();
     DVLOG(4) << "Returning new image for dynamic asset " << asset_id_;
-    return frame_data;
+    return current_frame_data_;
   }
 
  private:
@@ -139,11 +133,22 @@
   // ref-counted API.
   ~DynamicImageAssetImpl() override = default;
 
+  const cc::SkottieFrameData& GetCurrentFrameData(float scale_factor) {
+    DCHECK(current_frame_data_.image);
+    if (current_frame_data_scale_factor_ != scale_factor) {
+      current_frame_data_ = BuildSkottieFrameData(new_image_, scale_factor);
+      current_frame_data_scale_factor_ = scale_factor;
+    }
+    return current_frame_data_;
+  }
+
   const std::string asset_id_;
   const base::RepeatingClosure refresh_image_cb_;
   // Last animation frame timestamp that was observed.
   float last_observed_animation_timestamp_ = kAnimationTimestampInvalid;
   gfx::ImageSkia new_image_;
+  cc::SkottieFrameData current_frame_data_;
+  float current_frame_data_scale_factor_ = 0;
 };
 
 AmbientAnimationPhotoProvider::AmbientAnimationPhotoProvider(
@@ -182,7 +187,7 @@
     return dynamic_assets_.back();
   } else {
     return base::MakeRefCounted<StaticImageAssetImpl>(asset_id,
-                                                      static_resources_);
+                                                      *static_resources_);
   }
 }
 
diff --git a/ash/ambient/model/ambient_animation_photo_provider_unittest.cc b/ash/ambient/model/ambient_animation_photo_provider_unittest.cc
index 78e0315b..d248195a 100644
--- a/ash/ambient/model/ambient_animation_photo_provider_unittest.cc
+++ b/ash/ambient/model/ambient_animation_photo_provider_unittest.cc
@@ -26,8 +26,6 @@
 
 using ::testing::Each;
 using ::testing::ElementsAre;
-using ::testing::IsFalse;
-using ::testing::IsTrue;
 using ::testing::NotNull;
 using ::testing::SizeIs;
 using ::testing::UnorderedElementsAre;
@@ -37,13 +35,10 @@
 
 constexpr float kTestScaleFactor = 1;
 
-// Test argument is absl::optional<cc::SkottieFrameData>.
+// Test argument is cc::SkottieFrameData.
 MATCHER_P2(HasImageDimensions, width, height, "") {
-  if (!arg.has_value())
-    return false;
-
-  return arg->image.GetSkImageInfo().width() == width &&
-         arg->image.GetSkImageInfo().height() == height;
+  return arg.image.GetSkImageInfo().width() == width &&
+         arg.image.GetSkImageInfo().height() == height;
 }
 
 }  // namespace
@@ -90,7 +85,7 @@
     return all_assets;
   }
 
-  std::vector<absl::optional<cc::SkottieFrameData>> GetFrameDataForAssets(
+  std::vector<cc::SkottieFrameData> GetFrameDataForAssets(
       const std::vector<scoped_refptr<ImageAsset>>& assets,
       float timestamp) {
     // The timestamp for a given frame is not guaranteed to be the same for each
@@ -98,7 +93,7 @@
     // correctly.
     static constexpr float kTimestampJitter = 0.01f;
     bool add_jitter = false;
-    std::vector<absl::optional<cc::SkottieFrameData>> all_frame_data;
+    std::vector<cc::SkottieFrameData> all_frame_data;
     for (const scoped_refptr<ImageAsset>& asset : assets) {
       float jitter = add_jitter ? kTimestampJitter : 0.f;
       all_frame_data.push_back(
@@ -123,9 +118,8 @@
   std::vector<scoped_refptr<ImageAsset>> all_assets = LoadAllDynamicAssets();
 
   // Cycle 0 Frame 0
-  std::vector<absl::optional<cc::SkottieFrameData>> frame_data =
+  std::vector<cc::SkottieFrameData> frame_data =
       GetFrameDataForAssets(all_assets, /*timestamp=*/0);
-  ASSERT_THAT(frame_data, Each(IsTrue()));
   EXPECT_THAT(frame_data, UnorderedElementsAre(HasImageDimensions(10, 10),
                                                HasImageDimensions(11, 11),
                                                HasImageDimensions(12, 12),
@@ -133,7 +127,10 @@
 
   // Cycle 0 Frame 1
   frame_data = GetFrameDataForAssets(all_assets, /*timestamp=*/1);
-  EXPECT_THAT(frame_data, Each(IsFalse()));
+  EXPECT_THAT(frame_data, UnorderedElementsAre(HasImageDimensions(10, 10),
+                                               HasImageDimensions(11, 11),
+                                               HasImageDimensions(12, 12),
+                                               HasImageDimensions(13, 13)));
 
   AddImageToModel(gfx::test::CreateImageSkia(/*width=*/20, /*height=*/20));
   AddImageToModel(gfx::test::CreateImageSkia(/*width=*/21, /*height=*/21));
@@ -142,7 +139,6 @@
 
   // Cycle 1 Frame 0
   frame_data = GetFrameDataForAssets(all_assets, /*timestamp=*/0);
-  ASSERT_THAT(frame_data, Each(IsTrue()));
   EXPECT_THAT(frame_data, UnorderedElementsAre(HasImageDimensions(20, 20),
                                                HasImageDimensions(21, 21),
                                                HasImageDimensions(22, 22),
@@ -150,7 +146,10 @@
 
   // Cycle 1 Frame 1
   frame_data = GetFrameDataForAssets(all_assets, /*timestamp=*/1);
-  EXPECT_THAT(frame_data, Each(IsFalse()));
+  EXPECT_THAT(frame_data, UnorderedElementsAre(HasImageDimensions(20, 20),
+                                               HasImageDimensions(21, 21),
+                                               HasImageDimensions(22, 22),
+                                               HasImageDimensions(23, 23)));
 }
 
 TEST_F(AmbientAnimationPhotoProviderTest,
@@ -175,9 +174,8 @@
   AddImageToModel(gfx::test::CreateImageSkia(/*width=*/21, /*height=*/21));
 
   // Cycle 1 Frame 0
-  std::vector<absl::optional<cc::SkottieFrameData>> frame_data =
+  std::vector<cc::SkottieFrameData> frame_data =
       GetFrameDataForAssets(all_assets, /*timestamp=*/0);
-  ASSERT_THAT(frame_data, Each(IsTrue()));
   EXPECT_THAT(frame_data, UnorderedElementsAre(HasImageDimensions(12, 12),
                                                HasImageDimensions(13, 13),
                                                HasImageDimensions(20, 20),
@@ -193,9 +191,8 @@
   std::vector<scoped_refptr<ImageAsset>> all_assets = LoadAllDynamicAssets();
 
   // Cycle 0 Frame 0
-  std::vector<absl::optional<cc::SkottieFrameData>> frame_data =
+  std::vector<cc::SkottieFrameData> frame_data =
       GetFrameDataForAssets(all_assets, /*timestamp=*/0);
-  ASSERT_THAT(frame_data, Each(IsTrue()));
   EXPECT_THAT(frame_data, UnorderedElementsAre(HasImageDimensions(10, 10),
                                                HasImageDimensions(10, 10),
                                                HasImageDimensions(11, 11),
@@ -210,9 +207,8 @@
   std::vector<scoped_refptr<ImageAsset>> all_assets = LoadAllDynamicAssets();
 
   // Cycle 0 Frame 0
-  std::vector<absl::optional<cc::SkottieFrameData>> frame_data =
+  std::vector<cc::SkottieFrameData> frame_data =
       GetFrameDataForAssets(all_assets, /*timestamp=*/0);
-  ASSERT_THAT(frame_data, Each(IsTrue()));
   ASSERT_THAT(frame_data, SizeIs(kNumDynamicAssets));
   EXPECT_THAT(frame_data, Each(HasImageDimensions(10, 10)));
 }
@@ -228,19 +224,20 @@
   std::vector<scoped_refptr<ImageAsset>> all_assets = {
       LoadAsset("static-asset-0"), LoadAsset("static-asset-1")};
 
-  std::vector<absl::optional<cc::SkottieFrameData>> frame_data =
+  std::vector<cc::SkottieFrameData> frame_data =
       GetFrameDataForAssets(all_assets, /*timestamp=*/0);
-  ASSERT_THAT(frame_data, Each(IsTrue()));
   EXPECT_THAT(frame_data, ElementsAre(HasImageDimensions(10, 10),
                                       HasImageDimensions(11, 11)));
 
   frame_data = GetFrameDataForAssets(all_assets, /*timestamp=*/1);
-  EXPECT_THAT(frame_data, Each(IsFalse()));
+  EXPECT_THAT(frame_data, ElementsAre(HasImageDimensions(10, 10),
+                                      HasImageDimensions(11, 11)));
 
   // Unlike dynamic assets, static assets only get loaded one time in the
   // animation's lifetime.
   frame_data = GetFrameDataForAssets(all_assets, /*timestamp=*/0);
-  EXPECT_THAT(frame_data, Each(IsFalse()));
+  EXPECT_THAT(frame_data, ElementsAre(HasImageDimensions(10, 10),
+                                      HasImageDimensions(11, 11)));
 }
 
 }  // namespace ash
diff --git a/ash/components/arc/session/BUILD.gn b/ash/components/arc/session/BUILD.gn
index 10aa251..14adae93 100644
--- a/ash/components/arc/session/BUILD.gn
+++ b/ash/components/arc/session/BUILD.gn
@@ -109,6 +109,8 @@
     "arc_session_runner_unittest.cc",
     "arc_stop_reason_unittest.cc",
     "arc_vm_client_adapter_unittest.cc",
+    "connection_holder_unittest.cc",
+    "connection_notifier_unittest.cc",
     "file_system_status_unittest.cc",
   ]
 
diff --git a/ash/components/arc/session/arc_vm_client_adapter.cc b/ash/components/arc/session/arc_vm_client_adapter.cc
index e1027be2..751310d 100644
--- a/ash/components/arc/session/arc_vm_client_adapter.cc
+++ b/ash/components/arc/session/arc_vm_client_adapter.cc
@@ -105,8 +105,6 @@
 constexpr base::TimeDelta kConnectSleepDurationInitial =
     base::Milliseconds(100);
 
-constexpr const char kEmptyDiskPath[] = "/dev/null";
-
 absl::optional<base::TimeDelta> g_connect_timeout_limit_for_testing;
 absl::optional<base::TimeDelta> g_connect_sleep_duration_initial_for_testing;
 absl::optional<int> g_boot_notification_server_fd;
@@ -403,36 +401,15 @@
     disk_image->set_block_size(kBlockSize);
 
   // Add /run/imageloader/.../android_demo_apps.squash as /dev/block/vdc if
-  // needed. If it's not needed we pass /dev/null so that /dev/block/vdc
-  // always corresponds to the demo image.
-  disk_image = request.add_disks();
-  disk_image->set_image_type(vm_tools::concierge::DISK_IMAGE_AUTO);
-  disk_image->set_writable(false);
-  disk_image->set_do_mount(true);
+  // needed.
   if (!demo_session_apps_path.empty()) {
+    disk_image = request.add_disks();
     disk_image->set_path(demo_session_apps_path.value());
+    disk_image->set_image_type(vm_tools::concierge::DISK_IMAGE_AUTO);
+    disk_image->set_writable(false);
+    disk_image->set_do_mount(true);
     if (should_set_blocksize)
       disk_image->set_block_size(kBlockSize);
-  } else {
-    // This should never be mounted as it's only mounted if
-    // ro.boot.arc_demo_mode is set.
-    disk_image->set_path(kEmptyDiskPath);
-  }
-
-  // Add /opt/google/vms/android/apex/payload.img as /dev/block/vdd if
-  // needed. If it's not needed we pass /dev/null so that /dev/block/vdd
-  // always corresponds to the block apex composite disk.
-  disk_image = request.add_disks();
-  disk_image->set_image_type(vm_tools::concierge::DISK_IMAGE_AUTO);
-  disk_image->set_writable(false);
-  disk_image->set_do_mount(true);
-  if (!file_system_status.block_apex_path().empty()) {
-    disk_image->set_path(file_system_status.block_apex_path().value());
-  } else {
-    // Android will not mount this is the system property
-    // apexd.payload_metadata.path is not set, and it should
-    // always be set if the block apex payload exists.
-    disk_image->set_path(kEmptyDiskPath);
   }
 
   // Add Android fstab.
diff --git a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
index d2e3f4f..5917e5d5 100644
--- a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
+++ b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
@@ -614,10 +614,6 @@
     return boot_server_.get();
   }
 
-  void set_block_apex_path(base::FilePath block_apex_path) {
-    block_apex_path_ = block_apex_path;
-  }
-
   void set_host_rootfs_writable(bool host_rootfs_writable) {
     host_rootfs_writable_ = host_rootfs_writable;
   }
@@ -633,7 +629,6 @@
 
  private:
   void RewriteStatus(FileSystemStatus* status) {
-    status->set_block_apex_path_for_testing(block_apex_path_);
     status->set_host_rootfs_writable_for_testing(host_rootfs_writable_);
     status->set_system_image_ext_format_for_testing(system_image_ext_format_);
   }
@@ -647,7 +642,6 @@
   ArcServiceManager arc_service_manager_;
 
   // Variables to override the value in FileSystemStatus.
-  base::FilePath block_apex_path_;
   bool host_rootfs_writable_;
   bool system_image_ext_format_;
 
@@ -2135,38 +2129,6 @@
   EXPECT_FALSE(request.has_balloon_policy());
 }
 
-// Test that the request passes an empty disk for the demo image
-// or the block apex composite disk when they are not present.
-// There should be two empty disks (/dev/block/vdc and /dev/block/vdd)
-// and they should have path /dev/null.
-TEST_F(ArcVmClientAdapterTest, ArcVmEmptyVirtualDisksExist) {
-  StartMiniArc();
-
-  auto request = GetTestConciergeClient()->start_arc_vm_request();
-  EXPECT_EQ(request.disks(1).path(), "/dev/null");
-  EXPECT_EQ(request.disks(2).path(), "/dev/null");
-}
-
-// Test that block apex disk path exists when the composite disk payload
-// exists.
-TEST_F(ArcVmClientAdapterTest, ArcVmBlockApexDiskExists) {
-  constexpr const char path[] = "/opt/google/vms/android/apex/payload.img";
-  set_block_apex_path(base::FilePath(path));
-  StartMiniArc();
-  auto request = GetTestConciergeClient()->start_arc_vm_request();
-  EXPECT_TRUE(base::Contains(request.disks(), path,
-                             [](const auto& p) { return p.path(); }));
-}
-
-// Test that the block apex disk path isn't included when it doesn't exist.
-TEST_F(ArcVmClientAdapterTest, ArcVmNoBlockApexDisk) {
-  constexpr const char path[] = "/opt/google/vms/android/apex/payload.img";
-  StartMiniArc();
-  auto request = GetTestConciergeClient()->start_arc_vm_request();
-  EXPECT_FALSE(base::Contains(request.disks(), path,
-                              [](const auto& p) { return p.path(); }));
-}
-
 // Tests that OnConnectionReady() calls the MakeRtVcpu call D-Bus method.
 TEST_F(ArcVmClientAdapterTest, OnConnectionReady) {
   StartParams start_params(GetPopulatedStartParams());
diff --git a/ash/components/arc/session/connection_holder_unittest.cc b/ash/components/arc/session/connection_holder_unittest.cc
new file mode 100644
index 0000000..9e4b6a6
--- /dev/null
+++ b/ash/components/arc/session/connection_holder_unittest.cc
@@ -0,0 +1,87 @@
+// Copyright 2022 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 "ash/components/arc/session/connection_holder.h"
+
+#include "ash/components/arc/session/connection_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+namespace {
+
+struct FakeInstance {
+  static constexpr uint32_t Version_ = 1;
+  static constexpr char Name_[] = "FakeInstance";
+};
+
+struct Observer : public ConnectionObserver<FakeInstance> {
+  void OnConnectionReady() override { ++connection_ready_count_; }
+  void OnConnectionClosed() override { ++connection_closed_count_; }
+
+  size_t connection_ready_count_ = 0;
+  size_t connection_closed_count_ = 0;
+};
+
+// Tests that ConnectionHolder<>::AddObserver() works as intended.
+TEST(ConnectionHolder, AddObserver) {
+  Observer observer_1;
+  Observer observer_2;
+
+  ConnectionHolder<FakeInstance> holder;
+  holder.AddObserver(&observer_1);
+
+  // Since the holder doesn't have the instance yet, OnConnectionReady()
+  // shouldn't be called back.
+  EXPECT_EQ(0u, observer_1.connection_ready_count_);
+
+  FakeInstance instance;
+  holder.SetInstance(&instance);
+  EXPECT_TRUE(holder.IsConnected());
+
+  // Since the holder got the instance, OnConnectionReady() should have been
+  // called.
+  EXPECT_EQ(1u, observer_1.connection_ready_count_);
+
+  // Add the second observer for the same holder. OnConnectionReady() should be
+  // called back immediately for that observer.
+  holder.AddObserver(&observer_2);
+  EXPECT_EQ(1u, observer_2.connection_ready_count_);
+
+  // But the AddObserver call shouldn't affect other observer(s).
+  EXPECT_EQ(1u, observer_1.connection_ready_count_);
+
+  // Both observers should be notified when the instance is closed.
+  holder.CloseInstance(&instance);
+  EXPECT_EQ(1u, observer_1.connection_closed_count_);
+  EXPECT_EQ(1u, observer_2.connection_closed_count_);
+
+  holder.RemoveObserver(&observer_1);
+  holder.RemoveObserver(&observer_2);
+}
+
+// Tests that the holder recognizes the instance's version.
+TEST(ConnectionHolder, Version) {
+  ConnectionHolder<FakeInstance> holder;
+  FakeInstance instance;
+  holder.SetInstance(&instance);
+  EXPECT_EQ(FakeInstance::Version_, holder.instance_version());
+}
+
+// Tests that the GetInstance method works as intended.
+TEST(ConnectionHolder, GetInstance) {
+  ConnectionHolder<FakeInstance> holder;
+  FakeInstance instance;
+  holder.SetInstance(&instance);
+  // Version 1 of the instance exists.
+  EXPECT_EQ(&instance, holder.GetInstanceForVersionDoNotCallDirectly(
+                           FakeInstance::Version_, "MethodName"));
+  // Version 2 of the instance doesn't.
+  EXPECT_EQ(nullptr, holder.GetInstanceForVersionDoNotCallDirectly(
+                         FakeInstance::Version_ + 1, "MethodName"));
+}
+
+// TODO(yusukes|team): Test SetHost() method too.
+
+}  // namespace
+}  // namespace arc
diff --git a/ash/components/arc/session/connection_notifier_unittest.cc b/ash/components/arc/session/connection_notifier_unittest.cc
new file mode 100644
index 0000000..6a4bd634
--- /dev/null
+++ b/ash/components/arc/session/connection_notifier_unittest.cc
@@ -0,0 +1,86 @@
+// Copyright 2022 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 "ash/components/arc/session/connection_notifier.h"
+
+#include "ash/components/arc/session/connection_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+namespace {
+
+struct FakeInstance {};
+
+struct Observer : public ConnectionObserver<FakeInstance> {
+  void OnConnectionReady() override { ++connection_ready_count_; }
+  void OnConnectionClosed() override { ++connection_closed_count_; }
+
+  size_t connection_ready_count_ = 0;
+  size_t connection_closed_count_ = 0;
+};
+
+// Tests that NotifyConnectionReady works as intended.
+TEST(ConnectionNotifier, NotifyConnectionReady) {
+  Observer observer_1;
+  Observer observer_2;
+  internal::ConnectionNotifier notifier;
+
+  notifier.AddObserver(&observer_1);
+  // Notify the observer and check the results.
+  notifier.NotifyConnectionReady();
+  EXPECT_EQ(1u, observer_1.connection_ready_count_);
+  EXPECT_EQ(0u, observer_2.connection_ready_count_);
+
+  notifier.AddObserver(&observer_2);
+  // Notify the observers and check the results.
+  notifier.NotifyConnectionReady();
+  EXPECT_EQ(2u, observer_1.connection_ready_count_);
+  EXPECT_EQ(1u, observer_2.connection_ready_count_);
+
+  notifier.RemoveObserver(&observer_1);
+  // Notify the observer and check the results.
+  notifier.NotifyConnectionReady();
+  EXPECT_EQ(2u, observer_1.connection_ready_count_);
+  EXPECT_EQ(2u, observer_2.connection_ready_count_);
+
+  notifier.RemoveObserver(&observer_2);
+  // Notify and check that this is no-op.
+  notifier.NotifyConnectionReady();
+  EXPECT_EQ(2u, observer_1.connection_ready_count_);
+  EXPECT_EQ(2u, observer_2.connection_ready_count_);
+}
+
+// Tests NotifyConnectionClosed in the same way.
+TEST(ConnectionNotifier, NotifyConnectionClosed) {
+  Observer observer_1;
+  Observer observer_2;
+  internal::ConnectionNotifier notifier;
+
+  notifier.AddObserver(&observer_1);
+  // Notify the observer and check the results.
+  notifier.NotifyConnectionClosed();
+  EXPECT_EQ(1u, observer_1.connection_closed_count_);
+  EXPECT_EQ(0u, observer_2.connection_closed_count_);
+
+  notifier.AddObserver(&observer_2);
+  // Notify the observers and check the results.
+  notifier.NotifyConnectionClosed();
+  EXPECT_EQ(2u, observer_1.connection_closed_count_);
+  EXPECT_EQ(1u, observer_2.connection_closed_count_);
+
+  notifier.RemoveObserver(&observer_1);
+  // Notify the observer and check the results.
+  notifier.NotifyConnectionClosed();
+  EXPECT_EQ(2u, observer_1.connection_closed_count_);
+  EXPECT_EQ(2u, observer_2.connection_closed_count_);
+
+  notifier.RemoveObserver(&observer_2);
+  // Notify and check that this is no-op.
+  notifier.NotifyConnectionClosed();
+  EXPECT_EQ(2u, observer_1.connection_closed_count_);
+  EXPECT_EQ(2u, observer_2.connection_closed_count_);
+}
+
+}  // namespace
+}  // namespace arc
diff --git a/ash/components/arc/session/file_system_status.cc b/ash/components/arc/session/file_system_status.cc
index 607bd98..411c5e0 100644
--- a/ash/components/arc/session/file_system_status.cc
+++ b/ash/components/arc/session/file_system_status.cc
@@ -24,10 +24,6 @@
 constexpr const char kKernel[] = "vmlinux";
 constexpr const char kRootFs[] = "system.raw.img";
 constexpr const char kVendorImage[] = "vendor.raw.img";
-// Path to block apex payload. This is a composite disk containing
-// Android apexes which will be mounted as block devices.
-// This is a relative path starting from kBuiltinPath.
-constexpr const char kBlockApexPath[] = "apex/payload.img";
 
 }  // namespace
 
@@ -43,11 +39,7 @@
       guest_kernel_path_(base::FilePath(kBuiltinPath).Append(kKernel)),
       fstab_path_(kFstabPath),
       is_system_image_ext_format_(IsSystemImageExtFormat(system_image_path_)),
-      has_adbd_json_(base::PathExists(base::FilePath(kAdbdJson))) {
-  auto apex_path = base::FilePath(kBuiltinPath).Append(kBlockApexPath);
-  block_apex_path_ =
-      base::PathExists(apex_path) ? apex_path : base::FilePath("");
-}
+      has_adbd_json_(base::PathExists(base::FilePath(kAdbdJson))) {}
 
 // static
 bool FileSystemStatus::IsHostRootfsWritable() {
diff --git a/ash/components/arc/session/file_system_status.h b/ash/components/arc/session/file_system_status.h
index f313bb8..d2901c3a 100644
--- a/ash/components/arc/session/file_system_status.h
+++ b/ash/components/arc/session/file_system_status.h
@@ -34,7 +34,6 @@
   const base::FilePath& vendor_image_path() const { return vendor_image_path_; }
   const base::FilePath& guest_kernel_path() const { return guest_kernel_path_; }
   const base::FilePath& fstab_path() const { return fstab_path_; }
-  const base::FilePath& block_apex_path() const { return block_apex_path_; }
 
   // Setters for testing.
   void set_host_rootfs_writable_for_testing(bool is_host_rootfs_writable) {
@@ -59,9 +58,6 @@
   void set_fstab_path_for_testing(const base::FilePath& fstab_path) {
     fstab_path_ = fstab_path;
   }
-  void set_block_apex_path_for_testing(const base::FilePath& block_apex_path) {
-    block_apex_path_ = block_apex_path;
-  }
 
   static bool IsSystemImageExtFormatForTesting(const base::FilePath& path) {
     return IsSystemImageExtFormat(path);
@@ -82,7 +78,6 @@
   base::FilePath vendor_image_path_;
   base::FilePath guest_kernel_path_;
   base::FilePath fstab_path_;
-  base::FilePath block_apex_path_;
   bool is_system_image_ext_format_;
   bool has_adbd_json_;
 };
diff --git a/ash/components/fwupd/firmware_update_manager.cc b/ash/components/fwupd/firmware_update_manager.cc
index 9d18a01..3eb60e3 100644
--- a/ash/components/fwupd/firmware_update_manager.cc
+++ b/ash/components/fwupd/firmware_update_manager.cc
@@ -244,6 +244,7 @@
   for (auto& observer : update_list_observers_) {
     observer->OnUpdateListChanged(mojo::Clone(updates_));
   }
+  is_fetching_updates_ = false;
 }
 
 bool FirmwareUpdateManager::HasPendingUpdates() {
@@ -284,7 +285,10 @@
 
 // Query all updates for all devices.
 void FirmwareUpdateManager::RequestAllUpdates() {
-  DCHECK(!HasPendingUpdates());
+  if (is_fetching_updates_) {
+    return;
+  }
+  is_fetching_updates_ = true;
   RequestDevices();
 }
 
diff --git a/ash/components/fwupd/firmware_update_manager.h b/ash/components/fwupd/firmware_update_manager.h
index ef59de1a..5d40d41 100644
--- a/ash/components/fwupd/firmware_update_manager.h
+++ b/ash/components/fwupd/firmware_update_manager.h
@@ -190,6 +190,9 @@
   // We only want to show the notification once, at startup.
   bool should_show_notification_ = true;
 
+  // Whether or not fetching updates in inflight.
+  bool is_fetching_updates_ = false;
+
   // Remotes for tracking observers that will be notified of changes to the
   // list of firmware updates.
   mojo::RemoteSet<firmware_update::mojom::UpdateObserver>
diff --git a/ash/components/fwupd/firmware_update_manager_unittest.cc b/ash/components/fwupd/firmware_update_manager_unittest.cc
index 1841355..e4a6d483 100644
--- a/ash/components/fwupd/firmware_update_manager_unittest.cc
+++ b/ash/components/fwupd/firmware_update_manager_unittest.cc
@@ -75,6 +75,7 @@
       std::vector<ash::firmware_update::mojom::FirmwareUpdatePtr>
           firmware_updates) override {
     updates_ = std::move(firmware_updates);
+    ++num_times_notified_;
   }
 
   mojo::PendingRemote<ash::firmware_update::mojom::UpdateObserver>
@@ -87,9 +88,12 @@
     return updates_;
   }
 
+  int num_times_notified() { return num_times_notified_; }
+
  private:
   std::vector<ash::firmware_update::mojom::FirmwareUpdatePtr> updates_;
   mojo::Receiver<ash::firmware_update::mojom::UpdateObserver> receiver_{this};
+  int num_times_notified_ = 0;
 };
 
 class FakeUpdateProgressObserver
@@ -447,6 +451,8 @@
     firmware_update_manager_->BeginUpdate(device_id, filepath);
   }
 
+  void RequestAllUpdates() { firmware_update_manager_->RequestAllUpdates(); }
+
   // `FwupdClient` must be be before `FirmwareUpdateManager`.
   std::unique_ptr<FwupdClient> dbus_client_;
   std::unique_ptr<FakeFwupdDownloadClient> fake_fwupd_download_client_;
@@ -588,6 +594,46 @@
             updates[0]->priority);
 }
 
+TEST_F(FirmwareUpdateManagerTest, RequestUpdatesMutipleTimes) {
+  EXPECT_CALL(*proxy_, DoCallMethodWithErrorResponse(_, _, _))
+      .WillRepeatedly(Invoke(this, &FirmwareUpdateManagerTest::OnMethodCalled));
+
+  dbus_responses_.push_back(CreateTwoDeviceResponse());
+  dbus_responses_.push_back(CreateNoUpdateResponse());
+  dbus_responses_.push_back(CreateOneUpdateResponse());
+  FakeUpdateObserver update_observer;
+  SetupObserver(&update_observer);
+  base::RunLoop().RunUntilIdle();
+
+  const std::vector<firmware_update::mojom::FirmwareUpdatePtr>& updates =
+      update_observer.updates();
+
+  base::RunLoop().RunUntilIdle();
+  ASSERT_EQ(1, update_observer.num_times_notified());
+  ASSERT_EQ(1U, updates.size());
+
+  // Request all updates multiple times, this time while a request is already
+  // being made.
+  dbus_responses_.push_back(CreateOneDeviceResponse());
+  dbus_responses_.push_back(CreateOneUpdateResponse());
+  RequestAllUpdates();
+  RequestAllUpdates();
+  base::RunLoop().RunUntilIdle();
+  // Expect only one additional RequestAllUpdates() to go through.
+  ASSERT_EQ(1U, updates.size());
+  ASSERT_EQ(2, update_observer.num_times_notified());
+
+  // Now request all updates again, this time after the previous request has
+  // been completed.
+  dbus_responses_.push_back(CreateOneDeviceResponse());
+  dbus_responses_.push_back(CreateOneUpdateResponse());
+  RequestAllUpdates();
+  base::RunLoop().RunUntilIdle();
+  // Expect another additional RequestAllUpdates() to go through.
+  ASSERT_EQ(1U, updates.size());
+  ASSERT_EQ(3, update_observer.num_times_notified());
+}
+
 TEST_F(FirmwareUpdateManagerTest, RequestInstall) {
   EXPECT_CALL(*proxy_, DoCallMethodWithErrorResponse(_, _, _))
       .WillRepeatedly(Invoke(this, &FirmwareUpdateManagerTest::OnMethodCalled));
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 6e113664..419bb6f 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -285,7 +285,7 @@
 // If enabled, the clipboard history shortcut will appear in screenshot
 // notifications.
 const base::Feature kClipboardHistoryScreenshotNudge{
-    "ClipboardHistoryScreenshotNudge", base::FEATURE_DISABLED_BY_DEFAULT};
+    "ClipboardHistoryScreenshotNudge", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables compositing-based throttling to throttle appropriate frame sinks that
 // do not need to be refreshed at high fps.
@@ -302,7 +302,7 @@
 
 // Enables upgrading the crostini container to debian bullseye.
 const base::Feature kCrostiniBullseyeUpgrade{"CrostiniBullseyeUpgrade",
-                                             base::FEATURE_DISABLED_BY_DEFAULT};
+                                             base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables or disables Crostini Disk Resizing.
 const base::Feature kCrostiniDiskResizing{"CrostiniDiskResizing",
@@ -568,8 +568,7 @@
 
 // Enables or disables enterprise policy control for eSIM cellular networks.
 // See https://crbug.com/1231305.
-const base::Feature kESimPolicy{"ESimPolicy",
-                                base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kESimPolicy{"ESimPolicy", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enable or disable bubble showing when an application gains any UI lock.
 const base::Feature kExoLockNotification{"ExoLockNotification",
@@ -1226,6 +1225,10 @@
 const base::Feature kTerminalTmuxIntegration{"TerminalTmuxIntegration",
                                              base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enables the TrafficCountersHandler class to handle traffic counter resets.
+const base::Feature kTrafficCountersHandlerEnabled{
+    "TrafficCountersHandlerEnabled", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables the Settings UI to show data usage for cellular networks.
 const base::Feature kTrafficCountersSettingsUi{
     "TrafficCountersSettingsUi", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -1878,6 +1881,10 @@
   return base::FeatureList::IsEnabled(kTabClusterUI);
 }
 
+bool IsTrafficCountersHandlerEnabled() {
+  return base::FeatureList::IsEnabled(kTrafficCountersHandlerEnabled);
+}
+
 bool IsTrilinearFilteringEnabled() {
   static bool use_trilinear_filtering =
       base::FeatureList::IsEnabled(kTrilinearFiltering);
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 63e1c6f..d79c798 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -467,6 +467,8 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kTerminalTmuxIntegration;
 COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const base::Feature kTrafficCountersHandlerEnabled;
+COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kTrafficCountersSettingsUi;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kTrilinearFiltering;
 COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -652,6 +654,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSystemJapanesePhysicalTypingEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSystemKoreanPhysicalTypingEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTabClusterUIEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTrafficCountersHandlerEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTrilinearFilteringEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsUseStorkSmdsServerAddressEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWallpaperWebUIEnabled();
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc
index 027549f..bdc6321 100644
--- a/ash/display/window_tree_host_manager.cc
+++ b/ash/display/window_tree_host_manager.cc
@@ -27,6 +27,7 @@
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/wm/window_util.h"
 #include "base/bind.h"
+#include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_functions.h"
@@ -67,8 +68,13 @@
 // This is initialized in the constructor, and then in CreatePrimaryHost().
 int64_t primary_display_id = -1;
 
-// The default memory limit: 512mb.
-const char kUICompositorDefaultMemoryLimitMB[] = "512";
+// The default compositor memory limit.
+constexpr char kUICompositorDefaultMemoryLimitMB[] = "512";
+// The compositor memory limit when display size is larger than a threshold.
+constexpr char kUICompositorLargeMemoryLimitMB[] = "1024";
+// The display size threshold, above which the larger memory limit is used.
+// Pixel size was chosen to trigger for 4K+ displays. See: crbug.com/1261776
+constexpr int kUICompositorMemoryLimitDisplaySizeThreshold = 3500;
 
 // An UMA signal for the current effective resolution is sent at this rate. This
 // keeps track of the effective resolution most used on internal display by the
@@ -298,14 +304,6 @@
 
 void WindowTreeHostManager::CreatePrimaryHost(
     const AshWindowTreeHostInitParams& init_params) {
-  auto* command_line = base::CommandLine::ForCurrentProcess();
-  if (!command_line->HasSwitch(
-          switches::kUiCompositorMemoryLimitWhenVisibleMB)) {
-    command_line->AppendSwitchASCII(
-        switches::kUiCompositorMemoryLimitWhenVisibleMB,
-        kUICompositorDefaultMemoryLimitMB);
-  }
-
   const display::Display& primary_candidate =
       GetDisplayManager()->GetPrimaryDisplayCandidate();
   primary_display_id = primary_candidate.id();
@@ -865,6 +863,29 @@
   }
   params_with_bounds.display_id = display.id();
   params_with_bounds.device_scale_factor = display.device_scale_factor();
+
+  auto* command_line = base::CommandLine::ForCurrentProcess();
+  base::ScopedClosureRunner switch_remover;
+  if (!command_line->HasSwitch(
+          switches::kUiCompositorMemoryLimitWhenVisibleMB)) {
+    // TODO(crbug/1261776): Temporarily increase compositor memory limit for
+    // 4K+ displays to avoid rendering corruption.
+    // Check both width and height in case of rotated display.
+    const char* memory_limit =
+        std::max(display.GetSizeInPixel().width(),
+                 display.GetSizeInPixel().height()) >
+                kUICompositorMemoryLimitDisplaySizeThreshold
+            ? kUICompositorLargeMemoryLimitMB
+            : kUICompositorDefaultMemoryLimitMB;
+    command_line->AppendSwitchASCII(
+        switches::kUiCompositorMemoryLimitWhenVisibleMB, memory_limit);
+    switch_remover.ReplaceClosure(base::BindOnce(
+        [](base::CommandLine* cmd) {
+          cmd->RemoveSwitch(switches::kUiCompositorMemoryLimitWhenVisibleMB);
+        },
+        command_line));
+  }
+
   // The AshWindowTreeHost ends up owned by the RootWindowControllers created
   // by this class.
   AshWindowTreeHost* ash_host =
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index cfa4605..615d213 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -96,17 +96,6 @@
   }
 }
 
-aura::Window* GetTarget(const ui::LocatedEvent& event) {
-  gfx::Point location_in_screen = event.location();
-  ::wm::ConvertPointToScreen(static_cast<aura::Window*>(event.target()),
-                             &location_in_screen);
-  aura::Window* root_window_at_point =
-      window_util::GetRootWindowAt(location_in_screen);
-  gfx::Point location_in_root = location_in_screen;
-  ::wm::ConvertPointFromScreen(root_window_at_point, &location_in_root);
-  return root_window_at_point->GetEventHandlerForPoint(location_in_root);
-}
-
 std::unique_ptr<ui::LocatedEvent> ConvertEvent(aura::Window* target,
                                                const ui::LocatedEvent& event) {
   gfx::Point target_location = event.location();
@@ -347,7 +336,8 @@
     event->StopPropagation();
     return;
   }
-  aura::Window* translated_target = GetTarget(*event);
+  aura::Window* translated_target =
+      window_util::GetEventHandlerForEvent(*event);
   if (!translated_target) {
     // ET_MOUSE_CAPTURE_CHANGED event does not have a location that can
     // be used to locate a translated target.
@@ -429,7 +419,8 @@
     translated_target = capture_delegate_->GetTarget(touch_offset_event);
   } else {
     ui::Event::DispatcherApi(&touch_offset_event).set_target(event->target());
-    translated_target = GetTarget(touch_offset_event);
+    translated_target =
+        window_util::GetEventHandlerForEvent(touch_offset_event);
   }
 
   if (!translated_target) {
diff --git a/ash/login/ui/auth_factor_model.h b/ash/login/ui/auth_factor_model.h
index 463e212..65f62d8 100644
--- a/ash/login/ui/auth_factor_model.h
+++ b/ash/login/ui/auth_factor_model.h
@@ -40,24 +40,38 @@
     // hardware that isn’t present.
     kUnavailable,
     // The auth factor cannot be used because of an unrecoverable
-    // error, e.g. Fingerprint’s “Too many attempts”. GetLabel()
-    // and UpdateIcon() show the relevant messages.
+    // error, for example:
+    //   - Fingerprint’s “Too many attempts”,
+    //   - Smart Lock's "Failed to sign-in",
+    //   - etc.
+    // GetLabel() and UpdateIcon() show the relevant messages.
     kErrorPermanent,
     // The auth factor can be used but requires additional steps
-    // before use, e.g. turn on Bluetooth.
+    // before use. For example, Smart Lock will be in this state if Bluetooth
+    // needs to be enabled.
     kAvailable,
     // The auth factor is ready to authenticate. This state should
     // only be returned if authentication can be completed in one
-    // step (two if a click is required).
+    // step (two if a click is required). For each auth factor, this looks like:
+    //   - Fingerprint: the sensor is ready to read the user's finger(s).
+    //   - Smart Lock: the phone has been found/connected, but its screen is
+    //     locked and/or it's too far away.
     kReady,
-    // The auth factor has a non-blocking error to show the
-    // user, e.g. Fingerprint’s “Not recognized”, which clears
-    // after a few seconds. GetLabel() and UpdateIcon() show the
-    // relevant messages.
+    // The auth factor has a non-blocking error to show the user, e.g.,
+    // Fingerprint’s “Not recognized”, which clears after a few seconds.
+    // GetLabel() and UpdateIcon() show the relevant messages.
     kErrorTemporary,
-    // The auth factor requires the user to tap/click to enter.
+    // The auth factor requires the user to tap/click to enter. At the moment,
+    // only Smart Lock enters this state, and it occurs when the phone is
+    // unlocked and nearby.
     kClickRequired,
-    // Authentication is complete.
+    // Authentication is complete. Notes for each auth factor:
+    //   - Fingerprint: this is the last state; Fingerprint will not transition
+    //     to any other state after this.
+    //   - Smart Lock: in the lock screen, this is also Smart Lock's last state.
+    //     However, at the login screen, there is a chance that Cryptohome can
+    //     fail to decrypt the user directory via the phone-provided decryption
+    //     key -- in which case Smart Lock can transition to kErrorPermanent.
     kAuthenticated,
   };
 
diff --git a/ash/login/ui/login_auth_factors_view.cc b/ash/login/ui/login_auth_factors_view.cc
index a7306e99..71ea148 100644
--- a/ash/login/ui/login_auth_factors_view.cc
+++ b/ash/login/ui/login_auth_factors_view.cc
@@ -166,11 +166,9 @@
 }
 
 LoginAuthFactorsView::LoginAuthFactorsView(
-    base::RepeatingClosure on_click_to_enter,
-    base::RepeatingCallback<void(bool)> on_click_required_changed)
-    : on_click_to_enter_callback_(on_click_to_enter),
-      on_click_required_changed_callback_(on_click_required_changed) {
-  DCHECK(on_click_required_changed);
+    base::RepeatingClosure on_click_to_enter_callback)
+    : on_click_to_enter_callback_(on_click_to_enter_callback) {
+  DCHECK(on_click_to_enter_callback);
 
   SetPaintToLayer();
   layer()->SetFillsBoundsOpaquely(false);
@@ -258,6 +256,10 @@
   UpdateState();
 }
 
+bool LoginAuthFactorsView::ShouldHidePasswordField() {
+  return should_hide_password_field_;
+}
+
 void LoginAuthFactorsView::UpdateState() {
   AuthFactorModel* active_auth_factor =
       GetHighestPriorityAuthFactor(auth_factors_);
@@ -278,17 +280,16 @@
     error_timer_.Stop();
   }
 
-  // Fire a callback whenever entering/leaving the kClickRequired state. Avoid
-  // firing the callback for the kAuthenticated state since we do not want to
-  // change the visibility of the password/PIN fields when transitioning from
-  // kClickRequired to kAuthenticated.
-  bool should_show_arrow_button =
-      state == PrioritizedAuthFactorViewState::kClickRequired;
-  if (on_click_required_changed_callback_ &&
-      should_show_arrow_button != arrow_button_->GetVisible() &&
-      state != PrioritizedAuthFactorViewState::kAuthenticated) {
-    on_click_required_changed_callback_.Run(should_show_arrow_button);
-  }
+  // Update |should_hide_password_field_| when entering/leaving a state that
+  // requires hiding/showing the password/PIN fields.
+  //
+  // At the moment, Smart Lock is the only auth factor which needs to hide
+  // the password field, and it does so only during states kClickRequired and
+  // kAuthenticated.
+  should_hide_password_field_ =
+      active_auth_factor->GetType() == AuthFactorType::kSmartLock &&
+      (state == PrioritizedAuthFactorViewState::kClickRequired ||
+       state == PrioritizedAuthFactorViewState::kAuthenticated);
 
   int ready_label_id;
   size_t num_factors_in_error_background_state;
diff --git a/ash/login/ui/login_auth_factors_view.h b/ash/login/ui/login_auth_factors_view.h
index b6feafb0..acb8f44 100644
--- a/ash/login/ui/login_auth_factors_view.h
+++ b/ash/login/ui/login_auth_factors_view.h
@@ -51,9 +51,7 @@
     LoginAuthFactorsView* const view_;
   };
 
-  LoginAuthFactorsView(
-      base::RepeatingClosure on_click_to_enter,
-      base::RepeatingCallback<void(bool)> on_click_required_changed);
+  LoginAuthFactorsView(base::RepeatingClosure on_click_to_enter_callback);
   LoginAuthFactorsView(LoginAuthFactorsView&) = delete;
   LoginAuthFactorsView& operator=(LoginAuthFactorsView&) = delete;
   ~LoginAuthFactorsView() override;
@@ -71,6 +69,10 @@
   // authentication mechanism.
   void SetCanUsePin(bool can_use_pin);
 
+  // Returns true if the active auth factor is requesting to take visual
+  // precedence, by hiding the password field.
+  bool ShouldHidePasswordField();
+
  private:
   // Recomputes the state and updates the label and icons. Should be called
   // whenever any auth factor's state changes so that those changes can be
@@ -145,8 +147,11 @@
   // multiple are visible.
   std::vector<std::unique_ptr<AuthFactorModel>> auth_factors_;
 
+  // True if an active auth factor is requesting to hide the password field.
+  // Changes value based on the current state of the active auth factor.
+  bool should_hide_password_field_ = false;
+
   base::RepeatingClosure on_click_to_enter_callback_;
-  base::RepeatingCallback<void(bool)> on_click_required_changed_callback_;
   base::OneShotTimer error_timer_;
 };
 
diff --git a/ash/login/ui/login_auth_factors_view_unittest.cc b/ash/login/ui/login_auth_factors_view_unittest.cc
index 1fd88e39..9250bd3 100644
--- a/ash/login/ui/login_auth_factors_view_unittest.cc
+++ b/ash/login/ui/login_auth_factors_view_unittest.cc
@@ -136,12 +136,10 @@
     container_->SetLayoutManager(std::make_unique<views::BoxLayout>(
         views::BoxLayout::Orientation::kVertical));
 
-    view_ = container_->AddChildView(std::make_unique<LoginAuthFactorsView>(
-        base::BindRepeating(
+    view_ = container_->AddChildView(
+        std::make_unique<LoginAuthFactorsView>(base::BindRepeating(
             &LoginAuthFactorsViewUnittest::set_click_to_enter_called,
-            base::Unretained(this), true),
-        base::BindRepeating(&LoginAuthFactorsViewUnittest::set_click_required,
-                            base::Unretained(this))));
+            base::Unretained(this), true)));
   }
 
   void TearDown() override {
@@ -169,12 +167,26 @@
     return count;
   }
 
+  bool ShouldHidePasswordField() { return view_->ShouldHidePasswordField(); }
+
   void set_click_to_enter_called(bool called) {
     click_to_enter_called_ = called;
   }
 
-  void set_click_required(bool click_required) {
-    click_required_ = click_required;
+  void VerifyAuthenticatedUiState(
+      bool is_lock_screen,
+      LoginAuthFactorsView::TestApi& test_api,
+      bool should_hide_password_field_when_authenticated) {
+    EXPECT_TRUE(test_api.checkmark_icon()->GetVisible());
+    EXPECT_FALSE(test_api.arrow_button()->GetVisible());
+    EXPECT_FALSE(test_api.arrow_nudge_animation()->GetVisible());
+    EXPECT_FALSE(test_api.auth_factor_icon_row()->GetVisible());
+    EXPECT_EQ(l10n_util::GetStringUTF16(is_lock_screen
+                                            ? IDS_AUTH_FACTOR_LABEL_UNLOCKED
+                                            : IDS_AUTH_FACTOR_LABEL_SIGNED_IN),
+              test_api.label()->GetText());
+    EXPECT_EQ(should_hide_password_field_when_authenticated,
+              ShouldHidePasswordField());
   }
 
   base::test::ScopedFeatureList feature_list_;
@@ -182,7 +194,6 @@
   LoginAuthFactorsView* view_ = nullptr;  // Owned by container.
   std::vector<FakeAuthFactorModel*> auth_factors_;
   bool click_to_enter_called_ = false;
-  bool click_required_ = false;
 };
 
 TEST_F(LoginAuthFactorsViewUnittest, NotVisibleIfNoAuthFactors) {
@@ -299,12 +310,14 @@
       test_api.label()->GetText());
 }
 
-TEST_F(LoginAuthFactorsViewUnittest, ClickRequired) {
+// Note: At the moment, Smart Lock is the only auth factor that uses state
+// kClickRequired (hence no similar test for Fingerprint).
+TEST_F(LoginAuthFactorsViewUnittest, ClickRequired_SmartLock) {
   ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
       ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
 
   AddAuthFactors({AuthFactorType::kFingerprint, AuthFactorType::kSmartLock});
-  ASSERT_FALSE(click_required_);
+  ASSERT_FALSE(ShouldHidePasswordField());
 
   LoginAuthFactorsView::TestApi test_api(view_);
   auth_factors_[0]->state_ = AuthFactorState::kReady;
@@ -319,12 +332,12 @@
   EXPECT_FALSE(test_api.auth_factor_icon_row()->GetVisible());
   EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTH_FACTOR_LABEL_CLICK_TO_ENTER),
             test_api.label()->GetText());
-  EXPECT_TRUE(click_required_);
+  EXPECT_TRUE(ShouldHidePasswordField());
 
   auth_factors_[1]->state_ = AuthFactorState::kReady;
   test_api.UpdateState();
 
-  EXPECT_FALSE(click_required_);
+  EXPECT_FALSE(ShouldHidePasswordField());
 }
 
 TEST_F(LoginAuthFactorsViewUnittest, ClickingArrowButton) {
@@ -353,44 +366,100 @@
   EXPECT_FALSE(test_api.arrow_nudge_animation()->GetVisible());
 }
 
-TEST_F(LoginAuthFactorsViewUnittest, Authenticated_LockScreen) {
+// Present all possible auth factors on the lock screen, and verify behavior
+// when only Fingerprint is in state kAuthenticated. When Fingerprint is in
+// kAuthenticated state, it should not request to hide the password field, and
+// that is its final state as the screen becomes unlocked (it doesn't
+// transition to any further states).
+TEST_F(LoginAuthFactorsViewUnittest, Authenticated_LockScreen_Fingerprint) {
   GetSessionControllerClient()->SetSessionState(
       session_manager::SessionState::LOCKED);
   Shell::Get()->login_screen_controller()->ShowLockScreen();
-  AddAuthFactors({AuthFactorType::kFingerprint, AuthFactorType::kSmartLock});
+
+  AddAuthFactors({AuthFactorType::kSmartLock, AuthFactorType::kFingerprint});
+  ASSERT_FALSE(ShouldHidePasswordField());
+
   LoginAuthFactorsView::TestApi test_api(view_);
-  auth_factors_[0]->state_ = AuthFactorState::kAuthenticated;
-  auth_factors_[1]->state_ = AuthFactorState::kClickRequired;
+  auth_factors_[0]->state_ = AuthFactorState::kReady;
+  auth_factors_[1]->state_ = AuthFactorState::kAuthenticated;
   test_api.UpdateState();
 
-  // Check that only the arrow button is shown and that the label has been
-  // updated.
-  EXPECT_TRUE(test_api.checkmark_icon()->GetVisible());
-  EXPECT_FALSE(test_api.arrow_button()->GetVisible());
-  EXPECT_FALSE(test_api.arrow_nudge_animation()->GetVisible());
-  EXPECT_FALSE(test_api.auth_factor_icon_row()->GetVisible());
-  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTH_FACTOR_LABEL_UNLOCKED),
-            test_api.label()->GetText());
+  // Fingerprint should not request to hide the password field when
+  // authenticated.
+  VerifyAuthenticatedUiState(
+      /*is_lock_screen=*/true, test_api,
+      /*should_hide_password_field_when_authenticated=*/false);
+
+  // Fingerprint does not leave the kAuthenticated state once entering it.
 }
 
-TEST_F(LoginAuthFactorsViewUnittest, Authenticated_LoginScreen) {
+// Present all possible auth factors on the lock screen, and verify behavior
+// when only Smart Lock is in state kAuthenticated.
+//
+// When Smart Lock is in kAuthenticated state, it should request to hide the
+// password field.
+//
+// On the lock screen, kAuthenticated is its final state as the screen becomes
+// unlocked (it doesn't transition to any further states).
+TEST_F(LoginAuthFactorsViewUnittest, Authenticated_LockScreen_SmartLock) {
+  GetSessionControllerClient()->SetSessionState(
+      session_manager::SessionState::LOCKED);
+  Shell::Get()->login_screen_controller()->ShowLockScreen();
+
+  AddAuthFactors({AuthFactorType::kFingerprint, AuthFactorType::kSmartLock});
+  ASSERT_FALSE(ShouldHidePasswordField());
+
+  LoginAuthFactorsView::TestApi test_api(view_);
+  auth_factors_[0]->state_ = AuthFactorState::kReady;
+  auth_factors_[1]->state_ = AuthFactorState::kAuthenticated;
+  test_api.UpdateState();
+
+  // Smart Lock is authenticated -- it should request to hide the password
+  // field.
+  VerifyAuthenticatedUiState(
+      /*is_lock_screen=*/true, test_api,
+      /*should_hide_password_field_when_authenticated=*/true);
+
+  // On the lock screen, Smart Lock does not leave the kAuthenticated state
+  // once entering it.
+}
+
+// Present all possible auth factors on the login screen, and verify behavior
+// when Smart Lock is in state kAuthenticated.
+//
+// At the moment, Smart Lock is the only auth factor which can be present on the
+// login screen.
+//
+// When Smart Lock is in kAuthenticated state, it should request to hide the
+// password field.
+//
+// On the login screen, Smart Lock may transition the kErrorPermanent
+// state (if Cryptohome fails to decrypt the user directory with the
+// phone-provided decryption key). When Smart Lock transitions out of
+// kAuthenticated, it should no longer request to hide the password field.
+TEST_F(LoginAuthFactorsViewUnittest, Authenticated_LoginScreen_SmartLock) {
   GetSessionControllerClient()->SetSessionState(
       session_manager::SessionState::LOGIN_PRIMARY);
   Shell::Get()->login_screen_controller()->ShowLoginScreen();
-  AddAuthFactors({AuthFactorType::kFingerprint, AuthFactorType::kSmartLock});
+
+  AddAuthFactors({AuthFactorType::kSmartLock});
+  ASSERT_FALSE(ShouldHidePasswordField());
+
   LoginAuthFactorsView::TestApi test_api(view_);
   auth_factors_[0]->state_ = AuthFactorState::kAuthenticated;
-  auth_factors_[1]->state_ = AuthFactorState::kClickRequired;
   test_api.UpdateState();
 
-  // Check that only the arrow button is shown and that the label has been
-  // updated.
-  EXPECT_TRUE(test_api.checkmark_icon()->GetVisible());
-  EXPECT_FALSE(test_api.arrow_button()->GetVisible());
-  EXPECT_FALSE(test_api.arrow_nudge_animation()->GetVisible());
-  EXPECT_FALSE(test_api.auth_factor_icon_row()->GetVisible());
-  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTH_FACTOR_LABEL_SIGNED_IN),
-            test_api.label()->GetText());
+  // Smart Lock is authenticated -- it should request to hide the password
+  // field.
+  VerifyAuthenticatedUiState(
+      /*is_lock_screen=*/false, test_api,
+      /*should_hide_password_field_when_authenticated=*/true);
+
+  // Simulate Cryptohome failure. Smart Lock should no longer request to hide
+  // the password field.
+  auth_factors_[0]->state_ = AuthFactorState::kErrorPermanent;
+  test_api.UpdateState();
+  EXPECT_FALSE(ShouldHidePasswordField());
 }
 
 TEST_F(LoginAuthFactorsViewUnittest, ErrorTemporary) {
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc
index 668e3ba1..0edc25b3 100644
--- a/ash/login/ui/login_auth_user_view.cc
+++ b/ash/login/ui/login_auth_user_view.cc
@@ -140,8 +140,8 @@
 constexpr int kLockedTpmMessageDeltaDp = 0;
 constexpr int kLockedTpmMessageRoundedCornerRadiusDp = 8;
 
-constexpr int kAuthFactorClickRequiredSlideUpDistanceDp = 42;
-constexpr base::TimeDelta kAuthFactorClickRequiredSlideUpDuration =
+constexpr int kAuthFactorHidingPasswordFieldSlideUpDistanceDp = 42;
+constexpr base::TimeDelta kAuthFactorHidingPasswordFieldSlideUpDuration =
     base::Milliseconds(600);
 
 constexpr int kNonEmptyWidthDp = 1;
@@ -1139,13 +1139,10 @@
         std::make_unique<SmartLockAuthFactorModel>(base::BindRepeating(
             &LoginAuthUserView::OnUserViewTap, base::Unretained(this)));
     smart_lock_auth_factor_model_ = smart_lock_auth_factor_model.get();
-    auth_factors_view = std::make_unique<LoginAuthFactorsView>(
-        base::BindRepeating(
+    auth_factors_view =
+        std::make_unique<LoginAuthFactorsView>(base::BindRepeating(
             &SmartLockAuthFactorModel::OnArrowButtonTapOrClickEvent,
-            base::Unretained(smart_lock_auth_factor_model_)),
-        base::BindRepeating(
-            &LoginAuthUserView::OnAuthFactorClickRequiredChanged,
-            base::Unretained(this)));
+            base::Unretained(smart_lock_auth_factor_model_)));
     auth_factors_view_ = auth_factors_view.get();
     auth_factors_view_->AddAuthFactor(std::move(fingerprint_auth_factor_model));
     auth_factors_view_->AddAuthFactor(std::move(smart_lock_auth_factor_model));
@@ -1569,28 +1566,32 @@
   }
 
   ////////
-  // Slide the auth factors view up/down when entering/leaving the click
-  // required state.
+  // Slide the auth factors view up/down when entering/leaving a state of
+  // |auth_factors_view_| that requests the password field to be hidden.
   if (smart_lock_ui_revamp_enabled_) {
+    bool should_hide_password_field =
+        auth_factors_view_->ShouldHidePasswordField();
+
     {
       CHECK(auth_factors_view_);
       ui::ScopedLayerAnimationSettings settings(
           auth_factors_view_->layer()->GetAnimator());
-      settings.SetTransitionDuration(kAuthFactorClickRequiredSlideUpDuration);
+      settings.SetTransitionDuration(
+          kAuthFactorHidingPasswordFieldSlideUpDuration);
       settings.SetTweenType(gfx::Tween::Type::ACCEL_20_DECEL_100);
 
       gfx::Transform transform;
       transform.Translate(/*x=*/0,
-                          /*y=*/auth_factor_has_click_required_
-                              ? -kAuthFactorClickRequiredSlideUpDistanceDp
+                          /*y=*/should_hide_password_field
+                              ? -kAuthFactorHidingPasswordFieldSlideUpDistanceDp
                               : 0);
       auth_factors_view_->layer()->GetAnimator()->SetTransform(transform);
     }
 
-    // Translate the user view to its previous position when in the click
-    // required state. This prevents the user view from moving when the password
-    // view collapses.
-    if (auth_factor_has_click_required_) {
+    // Translate the user view to its previous position when in the auth factor
+    // view requests to hide the password field. This prevents the user view
+    // from moving when the password view collapses.
+    if (should_hide_password_field) {
       layer()->GetAnimator()->StopAnimating();
       int non_pin_y_end_in_screen = GetBoundsInScreen().y();
       gfx::Transform transform;
@@ -1823,13 +1824,6 @@
     pin_view_->OnPasswordTextChanged(is_empty);
 }
 
-void LoginAuthUserView::OnAuthFactorClickRequiredChanged(bool click_required) {
-  if (click_required == auth_factor_has_click_required_) {
-    return;
-  }
-  auth_factor_has_click_required_ = click_required;
-}
-
 bool LoginAuthUserView::HasAuthMethod(AuthMethods auth_method) const {
   return (auth_methods_ & auth_method) != 0;
 }
@@ -1906,16 +1900,18 @@
   ApplyAnimationPostLayout(/*animate*/ true);
 }
 
+// TODO(b/213926876): Write a unit test for ShouldHidePasswordField() usage.
 void LoginAuthUserView::UpdateInputFieldMode() {
   // There isn't an input field when any of the following is true:
   // - Challenge response is active (Smart Card)
   // - Online sign in message shown
   // - Disabled message shown
   // - No password auth available
-  // - Auth factors view is showing "click to enter"
+  // - Auth factors view is requesting to hide the password/PIN field
   if (HasAuthMethod(AUTH_CHALLENGE_RESPONSE) ||
       HasAuthMethod(AUTH_ONLINE_SIGN_IN) || HasAuthMethod(AUTH_DISABLED) ||
-      !HasAuthMethod(AUTH_PASSWORD) || auth_factor_has_click_required_) {
+      !HasAuthMethod(AUTH_PASSWORD) ||
+      (auth_factors_view_ && auth_factors_view_->ShouldHidePasswordField())) {
     input_field_mode_ = InputFieldMode::NONE;
     return;
   }
diff --git a/ash/login/ui/login_auth_user_view.h b/ash/login/ui/login_auth_user_view.h
index 2e491247..52e428e 100644
--- a/ash/login/ui/login_auth_user_view.h
+++ b/ash/login/ui/login_auth_user_view.h
@@ -231,11 +231,6 @@
   void OnPasswordTextChanged(bool is_empty);
   void OnPinTextChanged(bool is_empty);
 
-  // Called when the |auth_factors_view_| enters or leaves the "click to enter"
-  // state, which indicates that the user has authenticated with an auth factor
-  // but is required to click a button to complete login/unlock.
-  void OnAuthFactorClickRequiredChanged(bool click_required);
-
   // Helper method to check if an auth method is enable. Use it like this:
   // bool has_tap = HasAuthMethod(AUTH_TAP).
   bool HasAuthMethod(AuthMethods auth_method) const;
@@ -322,8 +317,6 @@
   // `ApplyAnimationPostLayout`.
   std::unique_ptr<UiState> previous_state_;
 
-  bool auth_factor_has_click_required_ = false;
-
   base::WeakPtrFactory<LoginAuthUserView> weak_factory_{this};
 };
 
diff --git a/ash/quick_pair/common/BUILD.gn b/ash/quick_pair/common/BUILD.gn
index 4fcf37b..e8833f1e 100644
--- a/ash/quick_pair/common/BUILD.gn
+++ b/ash/quick_pair/common/BUILD.gn
@@ -69,6 +69,7 @@
   deps = [
     "//ash/services/quick_pair/public/mojom",
     "//base/test:test_support",
+    "//components/image_fetcher/core",
     "//services/network/public/cpp",
     "//testing/gtest",
   ]
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc
index 7e3b799..955960e 100644
--- a/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc
+++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc
@@ -185,6 +185,8 @@
     "Bluetooth.ChromeOS.FastPair.RequestPasskey.Latency";
 const char kConfirmPasskeyConfirmTime[] =
     "Bluetooth.ChromeOS.FastPair.ConfirmPasskey.Latency";
+const char kFastPairRetryCount[] =
+    "Bluetooth.ChromeOS.FastPair.PairRetry.Count";
 
 }  // namespace
 
@@ -532,5 +534,10 @@
   base::UmaHistogramTimes(kConfirmPasskeyAskTime, total_ask_time);
 }
 
+void RecordPairFailureRetry(int num_retries) {
+  base::UmaHistogramExactLinear(kFastPairRetryCount, num_retries,
+                                /*exclusive_max=*/10);
+}
+
 }  // namespace quick_pair
 }  // namespace ash
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.h b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h
index 7fdb04a..1cb037f9 100644
--- a/ash/quick_pair/common/fast_pair/fast_pair_metrics.h
+++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h
@@ -257,6 +257,9 @@
 COMPONENT_EXPORT(QUICK_PAIR_COMMON)
 void RecordConfirmPasskeyAskTime(base::TimeDelta total_ask_time);
 
+COMPONENT_EXPORT(QUICK_PAIR_COMMON)
+void RecordPairFailureRetry(int num_retries);
+
 }  // namespace quick_pair
 }  // namespace ash
 
diff --git a/ash/quick_pair/common/mock_quick_pair_browser_delegate.h b/ash/quick_pair/common/mock_quick_pair_browser_delegate.h
index 90c01dc..745329f2 100644
--- a/ash/quick_pair/common/mock_quick_pair_browser_delegate.h
+++ b/ash/quick_pair/common/mock_quick_pair_browser_delegate.h
@@ -8,6 +8,7 @@
 #include "ash/quick_pair/common/quick_pair_browser_delegate.h"
 #include "base/component_export.h"
 #include "base/memory/scoped_refptr.h"
+#include "components/image_fetcher/core/image_fetcher.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -16,7 +17,7 @@
 
 namespace signin {
 class IdentityManager;
-}
+}  // namespace signin
 
 namespace ash {
 namespace quick_pair {
@@ -34,6 +35,10 @@
               (),
               (override));
   MOCK_METHOD(signin::IdentityManager*, GetIdentityManager, (), (override));
+  MOCK_METHOD(std::unique_ptr<image_fetcher::ImageFetcher>,
+              GetImageFetcher,
+              (),
+              (override));
   MOCK_METHOD(PrefService*, GetActivePrefService, (), (override));
   MOCK_METHOD(void,
               RequestService,
diff --git a/ash/quick_pair/common/quick_pair_browser_delegate.h b/ash/quick_pair/common/quick_pair_browser_delegate.h
index f3791f1..cc23e02 100644
--- a/ash/quick_pair/common/quick_pair_browser_delegate.h
+++ b/ash/quick_pair/common/quick_pair_browser_delegate.h
@@ -12,6 +12,10 @@
 
 class PrefService;
 
+namespace image_fetcher {
+class ImageFetcher;
+}  // namespace image_fetcher
+
 namespace network {
 class SharedURLLoaderFactory;
 }  // namespace network
@@ -42,6 +46,8 @@
   // Returns a pointer to the IdentityManager for the active user.
   virtual signin::IdentityManager* GetIdentityManager() = 0;
 
+  virtual std::unique_ptr<image_fetcher::ImageFetcher> GetImageFetcher() = 0;
+
   // For accessing prefs of the active user.
   virtual PrefService* GetActivePrefService() = 0;
 
diff --git a/ash/quick_pair/pairing/pairer_broker_impl.cc b/ash/quick_pair/pairing/pairer_broker_impl.cc
index 17e347a..b69cdc58 100644
--- a/ash/quick_pair/pairing/pairer_broker_impl.cc
+++ b/ash/quick_pair/pairing/pairer_broker_impl.cc
@@ -7,6 +7,7 @@
 
 #include "ash/quick_pair/common/account_key_failure.h"
 #include "ash/quick_pair/common/device.h"
+#include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h"
 #include "ash/quick_pair/common/logging.h"
 #include "ash/quick_pair/common/pair_failure.h"
 #include "ash/quick_pair/common/protocol.h"
@@ -20,6 +21,12 @@
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 
+namespace {
+
+constexpr int kMaxFailureRetryCount = 3;
+
+}  // namespace
+
 namespace ash {
 namespace quick_pair {
 
@@ -60,6 +67,9 @@
     return;
   }
 
+  if (!base::Contains(pair_failure_counts_, device->ble_address))
+    pair_failure_counts_[device->ble_address] = 0;
+
   QP_LOG(INFO) << __func__ << ": " << device;
 
   DCHECK(adapter_);
@@ -81,17 +91,34 @@
   for (auto& observer : observers_) {
     observer.OnDevicePaired(device);
   }
+
+  RecordPairFailureRetry(
+      /*num_retries=*/pair_failure_counts_[device->ble_address]);
+  pair_failure_counts_.erase(device->ble_address);
 }
 
 void PairerBrokerImpl::OnFastPairPairingFailure(scoped_refptr<Device> device,
                                                 PairFailure failure) {
-  QP_LOG(INFO) << __func__ << ": Device=" << device << ", Failure=" << failure;
+  ++pair_failure_counts_[device->ble_address];
+  QP_LOG(INFO) << __func__ << ": Device=" << device << ", Failure=" << failure
+               << ", Failure Count = "
+               << pair_failure_counts_[device->ble_address];
 
-  for (auto& observer : observers_) {
-    observer.OnPairFailure(device, failure);
+  if (pair_failure_counts_[device->ble_address] == kMaxFailureRetryCount) {
+    QP_LOG(INFO) << __func__
+                 << ": Reached max failure count. Notifying observers.";
+    for (auto& observer : observers_) {
+      observer.OnPairFailure(device, failure);
+    }
+
+    FastPairHandshakeLookup::GetInstance()->Erase(device);
+    pair_failure_counts_.erase(device->ble_address);
+    fast_pair_pairers_.erase(device->ble_address);
+    return;
   }
 
-  FastPairHandshakeLookup::GetInstance()->Erase(device);
+  fast_pair_pairers_.erase(device->ble_address);
+  PairFastPairDevice(device);
 }
 
 void PairerBrokerImpl::OnAccountKeyFailure(scoped_refptr<Device> device,
diff --git a/ash/quick_pair/pairing/pairer_broker_impl.h b/ash/quick_pair/pairing/pairer_broker_impl.h
index 5cc3ab6..4455113e 100644
--- a/ash/quick_pair/pairing/pairer_broker_impl.h
+++ b/ash/quick_pair/pairing/pairer_broker_impl.h
@@ -59,6 +59,7 @@
 
   base::flat_map<std::string, std::unique_ptr<FastPairPairer>>
       fast_pair_pairers_;
+  base::flat_map<std::string, int> pair_failure_counts_;
   scoped_refptr<device::BluetoothAdapter> adapter_;
   std::unique_ptr<FastPairUnpairHandler> fast_pair_unpair_handler_;
   base::ObserverList<Observer> observers_;
diff --git a/ash/quick_pair/repository/BUILD.gn b/ash/quick_pair/repository/BUILD.gn
index 3f3de4c..cecb5d82 100644
--- a/ash/quick_pair/repository/BUILD.gn
+++ b/ash/quick_pair/repository/BUILD.gn
@@ -19,6 +19,8 @@
     "fast_pair/device_metadata_fetcher.h",
     "fast_pair/fast_pair_image_decoder.cc",
     "fast_pair/fast_pair_image_decoder.h",
+    "fast_pair/fast_pair_image_decoder_impl.cc",
+    "fast_pair/fast_pair_image_decoder_impl.h",
     "fast_pair/footprints_fetcher.cc",
     "fast_pair/footprints_fetcher.h",
     "fast_pair/pairing_metadata.cc",
@@ -67,6 +69,8 @@
   sources = [
     "fake_fast_pair_repository.cc",
     "fake_fast_pair_repository.h",
+    "fast_pair/mock_fast_pair_image_decoder.cc",
+    "fast_pair/mock_fast_pair_image_decoder.h",
     "mock_fast_pair_repository.cc",
     "mock_fast_pair_repository.h",
     "mock_http_fetcher.cc",
diff --git a/ash/quick_pair/repository/fast_pair/device_image_store.cc b/ash/quick_pair/repository/fast_pair/device_image_store.cc
index e0ffe1ab..9475b47 100644
--- a/ash/quick_pair/repository/fast_pair/device_image_store.cc
+++ b/ash/quick_pair/repository/fast_pair/device_image_store.cc
@@ -5,12 +5,16 @@
 #include "ash/quick_pair/repository/fast_pair/device_image_store.h"
 
 #include "ash/quick_pair/common/logging.h"
+#include "ash/quick_pair/proto/fastpair.pb.h"
+#include "ash/quick_pair/proto/fastpair_data.pb.h"
+#include "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h"
 #include "ash/shell.h"
 #include "chromeos/services/bluetooth_config/public/cpp/device_image_info.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "ui/base/webui/web_ui_util.h"
+#include "url/gurl.h"
 
 namespace ash {
 namespace quick_pair {
@@ -26,30 +30,58 @@
   registry->RegisterDictionaryPref(kDeviceImageStorePref);
 }
 
-DeviceImageStore::DeviceImageStore() = default;
+DeviceImageStore::DeviceImageStore(FastPairImageDecoder* image_decoder)
+    : image_decoder_(image_decoder) {}
 
 DeviceImageStore::~DeviceImageStore() = default;
 
-void DeviceImageStore::SaveDeviceImages(
+void DeviceImageStore::FetchDeviceImages(
     const std::string& model_id,
     DeviceMetadata* device_metadata,
-    SaveDeviceImagesCallback on_images_saved_callback) {
+    FetchDeviceImagesCallback on_images_saved_callback) {
   DCHECK(device_metadata);
   DeviceImageInfo& images = model_id_to_images_[model_id];
 
   if (images.default_image().empty() && !device_metadata->image().IsEmpty()) {
     SaveImageAsBase64(model_id, DeviceImageType::kDefault,
-                      std::move(on_images_saved_callback),
-                      device_metadata->image());
+                      on_images_saved_callback, device_metadata->image());
   } else {
-    QP_LOG(WARNING) << __func__ << ": No default device image to save.";
-    std::move(on_images_saved_callback).Run(SaveDeviceImagesResult::kFailure);
+    on_images_saved_callback.Run(std::make_pair(
+        DeviceImageType::kDefault, FetchDeviceImagesResult::kSkipped));
+  }
+
+  nearby::fastpair::TrueWirelessHeadsetImages true_wireless_images =
+      device_metadata->GetDetails().true_wireless_images();
+
+  if (images.left_bud_image().empty() &&
+      true_wireless_images.has_left_bud_url()) {
+    DecodeImage(model_id, DeviceImageType::kLeftBud,
+                true_wireless_images.left_bud_url(), on_images_saved_callback);
+  } else {
+    on_images_saved_callback.Run(std::make_pair(
+        DeviceImageType::kLeftBud, FetchDeviceImagesResult::kSkipped));
+  }
+
+  if (images.right_bud_image().empty() &&
+      true_wireless_images.has_right_bud_url()) {
+    DecodeImage(model_id, DeviceImageType::kRightBud,
+                true_wireless_images.right_bud_url(), on_images_saved_callback);
+  } else {
+    on_images_saved_callback.Run(std::make_pair(
+        DeviceImageType::kRightBud, FetchDeviceImagesResult::kSkipped));
+  }
+
+  if (images.case_image().empty() && true_wireless_images.has_case_url()) {
+    DecodeImage(model_id, DeviceImageType::kCase,
+                true_wireless_images.case_url(), on_images_saved_callback);
+  } else {
+    on_images_saved_callback.Run(std::make_pair(
+        DeviceImageType::kCase, FetchDeviceImagesResult::kSkipped));
   }
 }
 
 bool DeviceImageStore::PersistDeviceImages(const std::string& model_id) {
-  chromeos::bluetooth_config::DeviceImageInfo& images =
-      model_id_to_images_[model_id];
+  DeviceImageInfo& images = model_id_to_images_[model_id];
 
   if (!DeviceImageInfoHasImages(images)) {
     QP_LOG(WARNING)
@@ -99,8 +131,7 @@
     LoadPersistedImagesFromPrefs();
   }
 
-  chromeos::bluetooth_config::DeviceImageInfo& images =
-      model_id_to_images_[model_id];
+  DeviceImageInfo& images = model_id_to_images_[model_id];
 
   if (!DeviceImageInfoHasImages(images)) {
     return absl::nullopt;
@@ -118,9 +149,8 @@
       local_state->GetDictionary(kDeviceImageStorePref);
   for (std::pair<const std::string&, const base::Value&> record :
        device_image_store->DictItems()) {
-    absl::optional<chromeos::bluetooth_config::DeviceImageInfo> images =
-        chromeos::bluetooth_config::DeviceImageInfo::FromDictionaryValue(
-            record.second);
+    absl::optional<DeviceImageInfo> images =
+        DeviceImageInfo::FromDictionaryValue(record.second);
     if (!images) {
       QP_LOG(WARNING) << __func__
                       << ": Failed to load persisted images from prefs.";
@@ -136,26 +166,55 @@
          !images.right_bud_image_.empty() || !images.case_image_.empty();
 }
 
+void DeviceImageStore::DecodeImage(
+    const std::string& model_id,
+    DeviceImageType image_type,
+    const std::string& image_url,
+    FetchDeviceImagesCallback on_images_saved_callback) {
+  DCHECK(image_decoder_);
+  image_decoder_->DecodeImageFromUrl(
+      GURL(image_url), /*resize_to_notification_size=*/true,
+      base::BindOnce(&DeviceImageStore::SaveImageAsBase64,
+                     weak_ptr_factory_.GetWeakPtr(), model_id, image_type,
+                     std::move(on_images_saved_callback)));
+}
+
 void DeviceImageStore::SaveImageAsBase64(
     const std::string& model_id,
     DeviceImageType image_type,
-    SaveDeviceImagesCallback on_images_saved_callback,
+    FetchDeviceImagesCallback on_images_saved_callback,
     gfx::Image image) {
+  if (image.IsEmpty()) {
+    QP_LOG(WARNING) << __func__ << ": Failed to fetch device image.";
+    std::move(on_images_saved_callback)
+        .Run(std::make_pair(image_type, FetchDeviceImagesResult::kFailure));
+    return;
+  }
+
   // Encode the image as a base64 data URL.
   std::string encoded_image = webui::GetBitmapDataUrl(image.AsBitmap());
 
   // Save the image in the correct path.
   if (image_type == DeviceImageType::kDefault) {
     model_id_to_images_[model_id].default_image_ = encoded_image;
+  } else if (image_type == DeviceImageType::kLeftBud) {
+    model_id_to_images_[model_id].left_bud_image_ = encoded_image;
+  } else if (image_type == DeviceImageType::kRightBud) {
+    model_id_to_images_[model_id].right_bud_image_ = encoded_image;
+  } else if (image_type == DeviceImageType::kCase) {
+    model_id_to_images_[model_id].case_image_ = encoded_image;
   } else {
     QP_LOG(WARNING) << __func__
                     << ": Can't save device image to invalid image field.";
-    std::move(on_images_saved_callback).Run(SaveDeviceImagesResult::kFailure);
+    std::move(on_images_saved_callback)
+        .Run(std::make_pair(DeviceImageType::kNotSupportedType,
+                            FetchDeviceImagesResult::kFailure));
     return;
   }
 
   // Once successfully saved, return success.
-  std::move(on_images_saved_callback).Run(SaveDeviceImagesResult::kSuccess);
+  std::move(on_images_saved_callback)
+      .Run(std::make_pair(image_type, FetchDeviceImagesResult::kSuccess));
 }
 
 }  // namespace quick_pair
diff --git a/ash/quick_pair/repository/fast_pair/device_image_store.h b/ash/quick_pair/repository/fast_pair/device_image_store.h
index 55ce6d6..3afdd7fb 100644
--- a/ash/quick_pair/repository/fast_pair/device_image_store.h
+++ b/ash/quick_pair/repository/fast_pair/device_image_store.h
@@ -20,6 +20,8 @@
 namespace ash {
 namespace quick_pair {
 
+class FastPairImageDecoder;
+
 // Saves any discovered device images in a flat_map model_id_to_images_.
 // Images are saved in DeviceImageInfo objects and are loaded from prefs on
 // creation. Images can be persisted to prefs (i.e. on device pair) or
@@ -34,30 +36,42 @@
   // to keep track of pending downloads.
   // kNotSupportedType is an error state that signifies that the image is not a
   // supported type.
-  enum class DeviceImageType { kNotSupportedType = 0, kDefault = 1 };
+  enum class DeviceImageType {
+    kNotSupportedType = 0,
+    kDefault = 1,
+    kLeftBud = 2,
+    kRightBud = 3,
+    kCase = 4
+  };
 
-  // Corresponds to the status of a SaveDeviceImages call.
-  enum class SaveDeviceImagesResult { kSuccess = 0, kFailure = 1 };
+  // Corresponds to the status of a FetchDeviceImages call.
+  enum class FetchDeviceImagesResult {
+    kSuccess = 0,
+    kFailure = 1,
+    // Skipped refers to when an image was already saved or there is no matching
+    // URL to attempt a download.
+    kSkipped = 2
+  };
 
-  // Returns the type of image that was was saved, i.e.
-  // DeviceImageInfo::DeviceImageType::kDefault for default image, on success.
-  // If images already exist or there are any errors, return empty kNone.
-  using SaveDeviceImagesCallback =
-      base::OnceCallback<void(SaveDeviceImagesResult)>;
+  // Returns the type of image that was was fetched and the result, i.e.
+  // DeviceImageType::kDefault and FetchDeviceImagesResult::kSuccess after
+  // successfully saving a default image.
+  using FetchDeviceImagesCallback = base::RepeatingCallback<void(
+      std::pair<DeviceImageType, FetchDeviceImagesResult>)>;
 
   // Registers preferences used by this class in the provided |registry|.
   static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
 
-  DeviceImageStore();
+  explicit DeviceImageStore(FastPairImageDecoder* image_decoder);
   DeviceImageStore(const DeviceImageStore&) = delete;
   DeviceImageStore& operator=(const DeviceImageStore&) = delete;
   ~DeviceImageStore();
 
   // Saves the device images stored in |device_metadata| to model_id_to_images_,
   // mapped to by |model_id|, if there are images.
-  void SaveDeviceImages(const std::string& model_id,
-                        DeviceMetadata* device_metadata,
-                        SaveDeviceImagesCallback on_images_saved_callback);
+  void FetchDeviceImages(const std::string& model_id,
+                         DeviceMetadata* device_metadata,
+                         FetchDeviceImagesCallback on_images_saved_callback);
 
   // Persists the DeviceImageInfo for |model_id| in model_id_to_images_
   // to local state prefs. Returns true if images were persisted, false
@@ -82,6 +96,14 @@
   bool DeviceImageInfoHasImages(
       const chromeos::bluetooth_config::DeviceImageInfo& images) const;
 
+  // Wrapper around a call to FastPairImageDecoder's DecodeImage. Downloads
+  // and decodes the image at |image_url|, then passes the |model_id|,
+  // |image_type|, and decoded image to SaveImageAsBase64.
+  void DecodeImage(const std::string& model_id,
+                   DeviceImageType image_type,
+                   const std::string& image_url,
+                   FetchDeviceImagesCallback on_images_saved_callback);
+
   // Callee ensures |image| is not empty. Encodes |image| as a base64 data URL
   // and saves it to the DeviceImageInfo belonging to |model_id| in field
   // |image_type|. Invokes |on_images_saved_callback| with the
@@ -89,7 +111,7 @@
   // otherwise.
   void SaveImageAsBase64(const std::string& model_id,
                          DeviceImageType image_type,
-                         SaveDeviceImagesCallback on_images_saved_callback,
+                         FetchDeviceImagesCallback on_images_saved_callback,
                          gfx::Image image);
 
   // Maps from model IDs to images stored in DeviceImageInfo.
@@ -97,6 +119,8 @@
       model_id_to_images_;
   // Used to lazily load images from prefs.
   bool loaded_images_from_prefs_ = false;
+  FastPairImageDecoder* image_decoder_;
+  base::WeakPtrFactory<DeviceImageStore> weak_ptr_factory_{this};
 };
 
 }  // namespace quick_pair
diff --git a/ash/quick_pair/repository/fast_pair/device_image_store_unittest.cc b/ash/quick_pair/repository/fast_pair/device_image_store_unittest.cc
index 43a132f..b464899 100644
--- a/ash/quick_pair/repository/fast_pair/device_image_store_unittest.cc
+++ b/ash/quick_pair/repository/fast_pair/device_image_store_unittest.cc
@@ -5,10 +5,13 @@
 #include "ash/quick_pair/repository/fast_pair/device_image_store.h"
 
 #include "ash/quick_pair/proto/fastpair.pb.h"
+#include "ash/quick_pair/proto/fastpair_data.pb.h"
 #include "ash/quick_pair/repository/fast_pair/device_metadata.h"
+#include "ash/quick_pair/repository/fast_pair/mock_fast_pair_image_decoder.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "base/callback_helpers.h"
+#include "base/test/gmock_callback_support.h"
 #include "base/test/mock_callback.h"
 #include "chromeos/services/bluetooth_config/public/cpp/device_image_info.h"
 #include "components/prefs/pref_service.h"
@@ -20,64 +23,178 @@
 namespace {
 
 constexpr char kTestModelId[] = "ABC123";
+constexpr char kTestLeftBudUrl[] = "left_bud";
+constexpr char kTestRightBudUrl[] = "right_bud";
+constexpr char kTestCaseUrl[] = "case";
 
 }  // namespace
 
 namespace ash {
 namespace quick_pair {
 
-// Alias DeviceImageInfo for convenience.
+using ::base::test::RunOnceCallback;
 using chromeos::bluetooth_config::DeviceImageInfo;
+using ::testing::_;
+using ::testing::Return;
 
 class DeviceImageStoreTest : public AshTestBase {
  public:
   void SetUp() override {
     AshTestBase::SetUp();
 
-    nearby::fastpair::GetObservedDeviceResponse response;
-    test_image_ = gfx::test::CreateImage(100, 100);
-    device_metadata_ =
-        std::make_unique<DeviceMetadata>(std::move(response), test_image_);
+    nearby::fastpair::TrueWirelessHeadsetImages true_wireless_images;
+    true_wireless_images.set_left_bud_url(kTestLeftBudUrl);
+    true_wireless_images.set_right_bud_url(kTestRightBudUrl);
+    true_wireless_images.set_case_url(kTestCaseUrl);
 
-    device_image_store_ = std::make_unique<DeviceImageStore>();
+    nearby::fastpair::Device device;
+    *device.mutable_true_wireless_images() = true_wireless_images;
+
+    nearby::fastpair::GetObservedDeviceResponse response;
+    *response.mutable_device() = device;
+
+    test_image_ = gfx::test::CreateImage(100, 100);
+    device_metadata_ = std::make_unique<DeviceMetadata>(response, test_image_);
+
+    mock_decoder_ = std::make_unique<MockFastPairImageDecoder>();
+    // On call to DecodeImage, run the third argument callback with test_image_.
+    ON_CALL(*mock_decoder_, DecodeImageFromUrl(_, _, _))
+        .WillByDefault(RunOnceCallback<2>(test_image_));
+
+    device_image_store_ =
+        std::make_unique<DeviceImageStore>(mock_decoder_.get());
   }
 
  protected:
   std::unique_ptr<DeviceMetadata> device_metadata_;
   gfx::Image test_image_;
+  std::unique_ptr<MockFastPairImageDecoder> mock_decoder_;
   std::unique_ptr<DeviceImageStore> device_image_store_;
 };
 
-TEST_F(DeviceImageStoreTest, SaveDeviceImagesValid) {
-  base::MockCallback<
-      base::OnceCallback<void(DeviceImageStore::SaveDeviceImagesResult)>>
-      callback;
-  EXPECT_CALL(callback,
-              Run(DeviceImageStore::SaveDeviceImagesResult::kSuccess));
+TEST_F(DeviceImageStoreTest, FetchDeviceImagesValidDefaultOnly) {
+  base::MockCallback<DeviceImageStore::FetchDeviceImagesCallback> callback;
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kDefault,
+                         DeviceImageStore::FetchDeviceImagesResult::kSuccess)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kLeftBud,
+                         DeviceImageStore::FetchDeviceImagesResult::kSkipped)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kRightBud,
+                         DeviceImageStore::FetchDeviceImagesResult::kSkipped)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kCase,
+                         DeviceImageStore::FetchDeviceImagesResult::kSkipped)))
+      .Times(1);
 
-  device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(),
-                                        callback.Get());
+  // Only include the default image in the metadata.
+  nearby::fastpair::GetObservedDeviceResponse response;
+  DeviceMetadata default_only_metadata =
+      DeviceMetadata(std::move(response), test_image_);
+  device_image_store_->FetchDeviceImages(kTestModelId, &default_only_metadata,
+                                         callback.Get());
 }
 
-TEST_F(DeviceImageStoreTest, SaveDeviceImagesInvalidDeviceImage) {
-  base::MockCallback<
-      base::OnceCallback<void(DeviceImageStore::SaveDeviceImagesResult)>>
-      callback;
-  EXPECT_CALL(callback,
-              Run(DeviceImageStore::SaveDeviceImagesResult::kFailure));
+TEST_F(DeviceImageStoreTest, FetchDeviceImagesInvalidDefaultOnly) {
+  base::MockCallback<DeviceImageStore::FetchDeviceImagesCallback> callback;
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kDefault,
+                         DeviceImageStore::FetchDeviceImagesResult::kSkipped)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kLeftBud,
+                         DeviceImageStore::FetchDeviceImagesResult::kSkipped)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kRightBud,
+                         DeviceImageStore::FetchDeviceImagesResult::kSkipped)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kCase,
+                         DeviceImageStore::FetchDeviceImagesResult::kSkipped)))
+      .Times(1);
 
+  // Include only an empty default image in the metadata.
   nearby::fastpair::GetObservedDeviceResponse response;
   DeviceMetadata empty_image_metadata =
       DeviceMetadata(std::move(response), gfx::Image());
+  device_image_store_->FetchDeviceImages(kTestModelId, &empty_image_metadata,
+                                         callback.Get());
+}
 
-  device_image_store_->SaveDeviceImages(kTestModelId, &empty_image_metadata,
-                                        callback.Get());
+TEST_F(DeviceImageStoreTest, FetchDeviceImagesValidTrueWireless) {
+  base::MockCallback<DeviceImageStore::FetchDeviceImagesCallback> callback;
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kDefault,
+                         DeviceImageStore::FetchDeviceImagesResult::kSuccess)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kLeftBud,
+                         DeviceImageStore::FetchDeviceImagesResult::kSuccess)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kRightBud,
+                         DeviceImageStore::FetchDeviceImagesResult::kSuccess)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kCase,
+                         DeviceImageStore::FetchDeviceImagesResult::kSuccess)))
+      .Times(1);
+
+  device_image_store_->FetchDeviceImages(kTestModelId, device_metadata_.get(),
+                                         callback.Get());
+}
+
+TEST_F(DeviceImageStoreTest, FetchDeviceImagesInvalidTrueWireless) {
+  base::MockCallback<DeviceImageStore::FetchDeviceImagesCallback> callback;
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kDefault,
+                         DeviceImageStore::FetchDeviceImagesResult::kSuccess)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kLeftBud,
+                         DeviceImageStore::FetchDeviceImagesResult::kFailure)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kRightBud,
+                         DeviceImageStore::FetchDeviceImagesResult::kFailure)))
+      .Times(1);
+  EXPECT_CALL(
+      callback,
+      Run(std::make_pair(DeviceImageStore::DeviceImageType::kCase,
+                         DeviceImageStore::FetchDeviceImagesResult::kFailure)))
+      .Times(1);
+
+  // Simulate an error during download/decode by returning an empty image.
+  ON_CALL(*mock_decoder_, DecodeImageFromUrl(_, _, _))
+      .WillByDefault(RunOnceCallback<2>(gfx::Image()));
+  device_image_store_->FetchDeviceImages(kTestModelId, device_metadata_.get(),
+                                         callback.Get());
 }
 
 TEST_F(DeviceImageStoreTest, PersistDeviceImagesValid) {
   // First, save the device images to memory.
-  device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(),
-                                        base::DoNothing());
+  device_image_store_->FetchDeviceImages(kTestModelId, device_metadata_.get(),
+                                         base::DoNothing());
   EXPECT_TRUE(device_image_store_->PersistDeviceImages(kTestModelId));
 
   // Validate that the images are persisted to prefs.
@@ -101,8 +218,8 @@
 
 TEST_F(DeviceImageStoreTest, EvictDeviceImagesValid) {
   // First, persist the device images to disk.
-  device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(),
-                                        base::DoNothing());
+  device_image_store_->FetchDeviceImages(kTestModelId, device_metadata_.get(),
+                                         base::DoNothing());
   EXPECT_TRUE(device_image_store_->PersistDeviceImages(kTestModelId));
   EXPECT_TRUE(device_image_store_->EvictDeviceImages(kTestModelId));
 
@@ -123,8 +240,8 @@
 
 TEST_F(DeviceImageStoreTest, EvictDeviceImagesInvalidDoubleFree) {
   // First, persist the device images to disk.
-  device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(),
-                                        base::DoNothing());
+  device_image_store_->FetchDeviceImages(kTestModelId, device_metadata_.get(),
+                                         base::DoNothing());
   EXPECT_TRUE(device_image_store_->PersistDeviceImages(kTestModelId));
   EXPECT_TRUE(device_image_store_->EvictDeviceImages(kTestModelId));
 
@@ -133,8 +250,8 @@
 }
 
 TEST_F(DeviceImageStoreTest, GetImagesForDeviceModelValid) {
-  device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(),
-                                        base::DoNothing());
+  device_image_store_->FetchDeviceImages(kTestModelId, device_metadata_.get(),
+                                         base::DoNothing());
 
   absl::optional<DeviceImageInfo> images =
       device_image_store_->GetImagesForDeviceModel(kTestModelId);
@@ -142,10 +259,19 @@
 
   const std::string default_image = images->default_image();
   EXPECT_FALSE(default_image.empty());
+  EXPECT_EQ(default_image, webui::GetBitmapDataUrl(test_image_.AsBitmap()));
 
-  std::string expected_encoded_image =
-      webui::GetBitmapDataUrl(test_image_.AsBitmap());
-  EXPECT_EQ(default_image, expected_encoded_image);
+  const std::string left_bud_image = images->left_bud_image();
+  EXPECT_FALSE(left_bud_image.empty());
+  EXPECT_EQ(left_bud_image, webui::GetBitmapDataUrl(test_image_.AsBitmap()));
+
+  const std::string right_bud_image = images->right_bud_image();
+  EXPECT_FALSE(right_bud_image.empty());
+  EXPECT_EQ(right_bud_image, webui::GetBitmapDataUrl(test_image_.AsBitmap()));
+
+  const std::string case_image = images->case_image();
+  EXPECT_FALSE(case_image.empty());
+  EXPECT_EQ(case_image, webui::GetBitmapDataUrl(test_image_.AsBitmap()));
 }
 
 TEST_F(DeviceImageStoreTest, GetImagesForDeviceModelInvalidUninitialized) {
@@ -156,8 +282,8 @@
 }
 
 TEST_F(DeviceImageStoreTest, GetImagesForDeviceModelInvalidNotAdded) {
-  device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(),
-                                        base::DoNothing());
+  device_image_store_->FetchDeviceImages(kTestModelId, device_metadata_.get(),
+                                         base::DoNothing());
   // Look for a model ID that wasn't added.
   absl::optional<DeviceImageInfo> images =
       device_image_store_->GetImagesForDeviceModel("DEF456");
@@ -166,14 +292,32 @@
 
 TEST_F(DeviceImageStoreTest, LoadPersistedImagesFromPrefs) {
   // First, persist the device images to disk.
-  device_image_store_->SaveDeviceImages(kTestModelId, device_metadata_.get(),
-                                        base::DoNothing());
+  device_image_store_->FetchDeviceImages(kTestModelId, device_metadata_.get(),
+                                         base::DoNothing());
   device_image_store_->PersistDeviceImages(kTestModelId);
 
   // A new/restarted DeviceImageStore instance should load persisted images
   // from prefs.
-  DeviceImageStore new_device_image_store;
-  EXPECT_TRUE(new_device_image_store.GetImagesForDeviceModel(kTestModelId));
+  DeviceImageStore new_device_image_store(mock_decoder_.get());
+  absl::optional<DeviceImageInfo> images =
+      new_device_image_store.GetImagesForDeviceModel(kTestModelId);
+  EXPECT_TRUE(images);
+
+  const std::string default_image = images->default_image();
+  EXPECT_FALSE(default_image.empty());
+  EXPECT_EQ(default_image, webui::GetBitmapDataUrl(test_image_.AsBitmap()));
+
+  const std::string left_bud_image = images->left_bud_image();
+  EXPECT_FALSE(left_bud_image.empty());
+  EXPECT_EQ(left_bud_image, webui::GetBitmapDataUrl(test_image_.AsBitmap()));
+
+  const std::string right_bud_image = images->right_bud_image();
+  EXPECT_FALSE(right_bud_image.empty());
+  EXPECT_EQ(right_bud_image, webui::GetBitmapDataUrl(test_image_.AsBitmap()));
+
+  const std::string case_image = images->case_image();
+  EXPECT_FALSE(case_image.empty());
+  EXPECT_EQ(case_image, webui::GetBitmapDataUrl(test_image_.AsBitmap()));
 }
 
 }  // namespace quick_pair
diff --git a/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc b/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc
index 1e2ef14..c42bc44 100644
--- a/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc
+++ b/ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc
@@ -4,6 +4,7 @@
 
 #include "ash/quick_pair/repository/fast_pair/device_metadata_fetcher.h"
 
+#include "ash/quick_pair/common/fast_pair/fast_pair_http_result.h"
 #include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h"
 #include "ash/quick_pair/common/logging.h"
 #include "ash/quick_pair/proto/fastpair.pb.h"
@@ -20,9 +21,8 @@
     "https://nearbydevices-pa.googleapis.com/v1/device/"
     "%d?key=%s&mode=MODE_RELEASE&alt=proto";
 
-// TODO(crbug/1226117): Update annotation with policy details when available.
 const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
-    net::DefineNetworkTrafficAnnotation("fast_pair", R"(
+    net::DefineNetworkTrafficAnnotation("fast_pair_device_metadata_fetcher", R"(
         semantics {
           sender: "Fast Pair repository access"
           description:
@@ -35,9 +35,15 @@
         }
         policy {
           cookies_allowed: NO
-          setting: "There is a toggle in OS Settings under Bluetooth."
-          policy_exception_justification:
-            "Not yet created, feature disabled by flag"
+          setting:
+            "You can enable or disable this feature by toggling on/off the "
+            "Fast Pair toggle in chrome://os-settings under 'Bluetooth'. The "
+            "feature is enabled by default. "
+          chrome_policy {
+            FastPairEnabled {
+                FastPairEnabled: true
+            }
+          }
         })");
 
 }  // namespace
diff --git a/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.cc b/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.cc
index 7631a30..c75454c 100644
--- a/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.cc
+++ b/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.cc
@@ -1,118 +1,15 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2022 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 "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h"
 
-#include "ash/quick_pair/common/logging.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "components/image_fetcher/core/image_fetcher.h"
-#include "components/image_fetcher/core/request_metadata.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/data_decoder/public/cpp/decode_image.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/image/image_skia_operations.h"
-
-namespace {
-
-constexpr char kImageFetcherUmaClientName[] = "FastPair";
-
-// Needs to stay in sync with |kLargeImageMaxHeight| declared in
-// ui/message_center/views/notification_view_md.cc.
-const int kMaxNotificationHeight = 218;
-
-// TODO(crbug.com/1226117) Update policy from Nearby to Fast Pair.
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
-    net::DefineNetworkTrafficAnnotation("fast_pair", R"(
-        semantics {
-          sender: "Get Fast Pair Device Image Data from Google"
-          description:
-            "Fast Pair can provide device images to be used in notifications "
-            "for corresponding Fast Pair devices. For a given image url, "
-            "Google's servers will return the image data in bytes to be "
-            "futher decoded here."
-          trigger: "A notification is being triggered for a Fast Pair device."
-          data: "Image pixels and URLs. No user identifier is sent along with "
-                "the data."
-          destination: GOOGLE_OWNED_SERVICE
-        }
-        policy {
-          cookies_allowed: NO
-          setting:
-            "This feature is only enabled for signed-in users who enable "
-            "Nearby Share"
-          chrome_policy {
-            BrowserSignin {
-              policy_options {mode: MANDATORY}
-              BrowserSignin: 0
-            }
-          }
-        })");
-
-int CalculateScaledWidth(int width, int height) {
-  return (kMaxNotificationHeight * width) / height;
-}
-
-void ToImage(DecodeImageCallback on_image_decoded_callback,
-             const SkBitmap& bitmap) {
-  if (bitmap.empty()) {
-    QP_LOG(WARNING) << "Failed to decode image";
-    std::move(on_image_decoded_callback).Run(gfx::Image());
-    return;
-  }
-  gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
-
-  if (image.height() > kMaxNotificationHeight) {
-    image = gfx::ImageSkiaOperations::CreateResizedImage(
-        image, skia::ImageOperations::RESIZE_BEST,
-        gfx::Size(CalculateScaledWidth(image.width(), image.height()),
-                  kMaxNotificationHeight));
-  }
-
-  std::move(on_image_decoded_callback).Run(gfx::Image(image));
-}
-
-}  // namespace
-
 namespace ash {
 namespace quick_pair {
 
-FastPairImageDecoder::FastPairImageDecoder(
-    std::unique_ptr<image_fetcher::ImageFetcher> fetcher)
-    : fetcher_(std::move(fetcher)) {}
+FastPairImageDecoder::FastPairImageDecoder() = default;
 
 FastPairImageDecoder::~FastPairImageDecoder() = default;
 
-void FastPairImageDecoder::DecodeImage(
-    const GURL& image_url,
-    DecodeImageCallback on_image_decoded_callback) {
-  fetcher_->FetchImageData(
-      image_url,
-      base::BindOnce(&FastPairImageDecoder::OnImageDataFetched,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     std::move(on_image_decoded_callback)),
-      image_fetcher::ImageFetcherParams(kTrafficAnnotation,
-                                        kImageFetcherUmaClientName));
-}
-
-void FastPairImageDecoder::DecodeImage(
-    const std::vector<uint8_t>& encoded_image_bytes,
-    DecodeImageCallback on_image_decoded_callback) {
-  data_decoder::DecodeImageIsolated(
-      encoded_image_bytes, data_decoder::mojom::ImageCodec::kDefault,
-      /*shrink_to_fit=*/false, data_decoder::kDefaultMaxSizeInBytes,
-      /*desired_image_frame_size=*/gfx::Size(),
-      base::BindOnce(&ToImage, std::move(on_image_decoded_callback)));
-}
-
-void FastPairImageDecoder::OnImageDataFetched(
-    DecodeImageCallback on_image_decoded_callback,
-    const std::string& image_data,
-    const image_fetcher::RequestMetadata& request_metadata) {
-  DecodeImage(std::vector<uint8_t>(image_data.begin(), image_data.end()),
-              std::move(on_image_decoded_callback));
-}
-
 }  // namespace quick_pair
 }  // namespace ash
diff --git a/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h b/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h
index f8f1af9..766e311b 100644
--- a/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h
+++ b/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h
@@ -12,13 +12,6 @@
 #include "ui/gfx/image/image.h"
 #include "url/gurl.h"
 
-using DecodeImageCallback = base::OnceCallback<void(gfx::Image)>;
-
-namespace image_fetcher {
-class ImageFetcher;
-struct RequestMetadata;
-}  // namespace image_fetcher
-
 namespace ash {
 namespace quick_pair {
 
@@ -27,27 +20,19 @@
 // given url or from given bytes of image data.
 class FastPairImageDecoder {
  public:
-  explicit FastPairImageDecoder(
-      std::unique_ptr<image_fetcher::ImageFetcher> fetcher);
-  FastPairImageDecoder(const FastPairImageDecoder&) = delete;
-  FastPairImageDecoder& operator=(const FastPairImageDecoder&) = delete;
-  ~FastPairImageDecoder();
+  using DecodeImageCallback = base::OnceCallback<void(gfx::Image)>;
 
-  void DecodeImage(const GURL& image_url,
-                   DecodeImageCallback on_image_decoded_callback);
+  FastPairImageDecoder();
+  virtual ~FastPairImageDecoder();
 
-  void DecodeImage(const std::vector<uint8_t>& encoded_image_bytes,
-                   DecodeImageCallback on_image_decoded_callback);
+  virtual void DecodeImageFromUrl(
+      const GURL& image_url,
+      bool resize_to_notification_size,
+      DecodeImageCallback on_image_decoded_callback) = 0;
 
- private:
-  // ImageDataFetcher callback
-  void OnImageDataFetched(
-      DecodeImageCallback on_image_decoded_callback,
-      const std::string& image_data,
-      const image_fetcher::RequestMetadata& request_metadata);
-
-  std::unique_ptr<image_fetcher::ImageFetcher> fetcher_;
-  base::WeakPtrFactory<FastPairImageDecoder> weak_ptr_factory_{this};
+  virtual void DecodeImage(const std::vector<uint8_t>& encoded_image_bytes,
+                           bool resize_to_notification_size,
+                           DecodeImageCallback on_image_decoded_callback) = 0;
 };
 
 }  // namespace quick_pair
diff --git a/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.cc b/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.cc
new file mode 100644
index 0000000..87dd27d
--- /dev/null
+++ b/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.cc
@@ -0,0 +1,134 @@
+// Copyright 2021 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 "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.h"
+
+#include "ash/quick_pair/common/logging.h"
+#include "ash/quick_pair/common/quick_pair_browser_delegate.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "components/image_fetcher/core/image_fetcher.h"
+#include "components/image_fetcher/core/image_fetcher_impl.h"
+#include "components/image_fetcher/core/request_metadata.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/data_decoder/public/cpp/decode_image.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/image/image_skia_operations.h"
+
+namespace {
+
+constexpr char kImageFetcherUmaClientName[] = "FastPair";
+
+// Needs to stay in sync with |kLargeImageMaxHeight| declared in
+// ui/message_center/views/notification_view_md.cc.
+const int kMaxNotificationHeight = 218;
+
+constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+    net::DefineNetworkTrafficAnnotation("fast_pair_image_decoder", R"(
+        semantics {
+          sender: "Get Fast Pair Device Image Data from Google"
+          description:
+            "Fast Pair can provide device images to be used in notifications "
+            "for corresponding Fast Pair devices. For a given image url, "
+            "Google's servers will return the image data in bytes to be "
+            "futher decoded here."
+          trigger: "A notification is being triggered for a Fast Pair device."
+          data: "Image pixels and URLs. No user identifier is sent along with "
+                "the data."
+          destination: GOOGLE_OWNED_SERVICE
+        }
+        policy {
+          cookies_allowed: NO
+          setting:
+            "You can enable or disable this feature by toggling on/off the "
+            "Fast Pair toggle in chrome://os-settings under 'Bluetooth'. The "
+            "feature is enabled by default. "
+          chrome_policy {
+            FastPairEnabled {
+                FastPairEnabled: true
+            }
+          }
+        })");
+
+int CalculateScaledWidth(int width, int height) {
+  return (kMaxNotificationHeight * width) / height;
+}
+
+void ToImage(DecodeImageCallback on_image_decoded_callback,
+             bool resize_to_notification_size,
+             const SkBitmap& bitmap) {
+  if (bitmap.empty()) {
+    QP_LOG(WARNING) << "Call to DecodeImageIsolated returned null.";
+    std::move(on_image_decoded_callback).Run(gfx::Image());
+    return;
+  }
+  gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
+
+  if (resize_to_notification_size && image.height() > kMaxNotificationHeight) {
+    image = gfx::ImageSkiaOperations::CreateResizedImage(
+        image, skia::ImageOperations::RESIZE_BEST,
+        gfx::Size(CalculateScaledWidth(image.width(), image.height()),
+                  kMaxNotificationHeight));
+  }
+
+  std::move(on_image_decoded_callback).Run(gfx::Image(image));
+}
+
+}  // namespace
+
+namespace ash {
+namespace quick_pair {
+
+FastPairImageDecoderImpl::FastPairImageDecoderImpl() = default;
+
+FastPairImageDecoderImpl::~FastPairImageDecoderImpl() = default;
+
+void FastPairImageDecoderImpl::DecodeImageFromUrl(
+    const GURL& image_url,
+    bool resize_to_notification_size,
+    DecodeImageCallback on_image_decoded_callback) {
+  if (!fetcher_ && !LoadImageFetcher()) {
+    QP_LOG(INFO) << __func__ << " Could not load image fetcher. ";
+    return;
+  }
+
+  fetcher_->FetchImageData(
+      image_url,
+      base::BindOnce(&FastPairImageDecoderImpl::OnImageDataFetched,
+                     weak_ptr_factory_.GetWeakPtr(),
+                     std::move(on_image_decoded_callback),
+                     resize_to_notification_size),
+      image_fetcher::ImageFetcherParams(kTrafficAnnotation,
+                                        kImageFetcherUmaClientName));
+}
+
+void FastPairImageDecoderImpl::DecodeImage(
+    const std::vector<uint8_t>& encoded_image_bytes,
+    bool resize_to_notification_size,
+    DecodeImageCallback on_image_decoded_callback) {
+  data_decoder::DecodeImageIsolated(
+      encoded_image_bytes, data_decoder::mojom::ImageCodec::kDefault,
+      /*shrink_to_fit=*/false, data_decoder::kDefaultMaxSizeInBytes,
+      /*desired_image_frame_size=*/gfx::Size(),
+      base::BindOnce(&ToImage, std::move(on_image_decoded_callback),
+                     resize_to_notification_size));
+}
+
+void FastPairImageDecoderImpl::OnImageDataFetched(
+    DecodeImageCallback on_image_decoded_callback,
+    bool resize_to_notification_size,
+    const std::string& image_data,
+    const image_fetcher::RequestMetadata& request_metadata) {
+  DecodeImage(std::vector<uint8_t>(image_data.begin(), image_data.end()),
+              resize_to_notification_size,
+              std::move(on_image_decoded_callback));
+}
+
+bool FastPairImageDecoderImpl::LoadImageFetcher() {
+  fetcher_ = QuickPairBrowserDelegate::Get()->GetImageFetcher();
+  return !!fetcher_;
+}
+
+}  // namespace quick_pair
+}  // namespace ash
diff --git a/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.h b/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.h
new file mode 100644
index 0000000..005fe653
--- /dev/null
+++ b/ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.h
@@ -0,0 +1,62 @@
+// Copyright 2021 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 ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_FAST_PAIR_IMAGE_DECODER_IMPL_H_
+#define ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_FAST_PAIR_IMAGE_DECODER_IMPL_H_
+
+#include <memory>
+
+#include "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h"
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/gfx/image/image.h"
+#include "url/gurl.h"
+
+using DecodeImageCallback = base::OnceCallback<void(gfx::Image)>;
+
+namespace image_fetcher {
+class ImageFetcher;
+struct RequestMetadata;
+}  // namespace image_fetcher
+
+namespace ash {
+namespace quick_pair {
+
+// The FastPairImageDecoderImpl decodes and returns images for the device used
+// in the notifications. FastPairImageDecoderImpl can decode images from either
+// a given url or from given bytes of image data.
+class FastPairImageDecoderImpl : public FastPairImageDecoder {
+ public:
+  FastPairImageDecoderImpl();
+  FastPairImageDecoderImpl(const FastPairImageDecoderImpl&) = delete;
+  FastPairImageDecoderImpl& operator=(const FastPairImageDecoderImpl&) = delete;
+  ~FastPairImageDecoderImpl() override;
+
+  void DecodeImageFromUrl(
+      const GURL& image_url,
+      bool resize_to_notification_size,
+      DecodeImageCallback on_image_decoded_callback) override;
+
+  void DecodeImage(const std::vector<uint8_t>& encoded_image_bytes,
+                   bool resize_to_notification_size,
+                   DecodeImageCallback on_image_decoded_callback) override;
+
+ private:
+  // ImageDataFetcher callback
+  void OnImageDataFetched(
+      DecodeImageCallback on_image_decoded_callback,
+      bool resize_to_notification_size,
+      const std::string& image_data,
+      const image_fetcher::RequestMetadata& request_metadata);
+
+  bool LoadImageFetcher();
+
+  std::unique_ptr<image_fetcher::ImageFetcher> fetcher_;
+  base::WeakPtrFactory<FastPairImageDecoderImpl> weak_ptr_factory_{this};
+};
+
+}  // namespace quick_pair
+}  // namespace ash
+
+#endif  // ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_FAST_PAIR_IMAGE_DECODER_IMPL_H_
diff --git a/ash/quick_pair/repository/fast_pair/footprints_fetcher.cc b/ash/quick_pair/repository/fast_pair/footprints_fetcher.cc
index 9465e98..273d4f1 100644
--- a/ash/quick_pair/repository/fast_pair/footprints_fetcher.cc
+++ b/ash/quick_pair/repository/fast_pair/footprints_fetcher.cc
@@ -31,7 +31,6 @@
     "https://nearbydevices-pa.googleapis.com/v1/user/devices/%s"
     "?key=%s&alt=proto";
 
-// TODO(crbug/1226117): Update annotation with policy details when available.
 const net::PartialNetworkTrafficAnnotationTag kTrafficAnnotation =
     net::DefinePartialNetworkTrafficAnnotation("fast_pair_footprints_request",
                                                "oauth2_api_call_flow",
@@ -48,10 +47,17 @@
       }
       policy {
           cookies_allowed: NO
-          setting: "There is a toggle in OS Settings under Bluetooth."
-          policy_exception_justification:
-            "Not yet created, feature disabled by flag"
-      })");
+          setting:
+            "You can enable or disable this feature by toggling on/off the "
+            "Fast Pair toggle in chrome://os-settings under 'Bluetooth'. The "
+            "feature is enabled by default. Fast Pair does not fetch data from "
+            "the repository if the user is not signed in."
+          chrome_policy {
+            FastPairEnabled {
+                FastPairEnabled: true
+            }
+          }
+        })");
 
 std::unique_ptr<HttpFetcher> CreateHttpFetcher() {
   return std::make_unique<OAuthHttpFetcher>(
diff --git a/ash/quick_pair/repository/fast_pair/mock_fast_pair_image_decoder.cc b/ash/quick_pair/repository/fast_pair/mock_fast_pair_image_decoder.cc
new file mode 100644
index 0000000..e20c533a
--- /dev/null
+++ b/ash/quick_pair/repository/fast_pair/mock_fast_pair_image_decoder.cc
@@ -0,0 +1,15 @@
+// Copyright 2022 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 "ash/quick_pair/repository/fast_pair/mock_fast_pair_image_decoder.h"
+
+namespace ash {
+namespace quick_pair {
+
+MockFastPairImageDecoder::MockFastPairImageDecoder() = default;
+
+MockFastPairImageDecoder::~MockFastPairImageDecoder() = default;
+
+}  // namespace quick_pair
+}  // namespace ash
diff --git a/ash/quick_pair/repository/fast_pair/mock_fast_pair_image_decoder.h b/ash/quick_pair/repository/fast_pair/mock_fast_pair_image_decoder.h
new file mode 100644
index 0000000..7b39c191
--- /dev/null
+++ b/ash/quick_pair/repository/fast_pair/mock_fast_pair_image_decoder.h
@@ -0,0 +1,39 @@
+// Copyright 2021 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 ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_MOCK_FAST_PAIR_IMAGE_DECODER_H_
+#define ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_MOCK_FAST_PAIR_IMAGE_DECODER_H_
+
+#include "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace ash {
+namespace quick_pair {
+
+class MockFastPairImageDecoder : public FastPairImageDecoder {
+ public:
+  MockFastPairImageDecoder();
+  MockFastPairImageDecoder(const MockFastPairImageDecoder&) = delete;
+  MockFastPairImageDecoder& operator=(const MockFastPairImageDecoder&) = delete;
+  ~MockFastPairImageDecoder() override;
+
+  MOCK_METHOD(void,
+              DecodeImageFromUrl,
+              (const GURL& image_url,
+               bool resize_to_notification_size,
+               DecodeImageCallback on_image_decoded_callback),
+              (override));
+
+  MOCK_METHOD(void,
+              DecodeImage,
+              (const std::vector<uint8_t>& encoded_image_bytes,
+               bool resize_to_notification_size,
+               DecodeImageCallback on_image_decoded_callback),
+              (override));
+};
+
+}  // namespace quick_pair
+}  // namespace ash
+
+#endif  // ASH_QUICK_PAIR_REPOSITORY_FAST_PAIR_MOCK_FAST_PAIR_IMAGE_DECODER_H_
diff --git a/ash/quick_pair/repository/fast_pair_repository_impl.cc b/ash/quick_pair/repository/fast_pair_repository_impl.cc
index 7e6da0f..972b1ce 100644
--- a/ash/quick_pair/repository/fast_pair_repository_impl.cc
+++ b/ash/quick_pair/repository/fast_pair_repository_impl.cc
@@ -11,7 +11,7 @@
 #include "ash/quick_pair/repository/fast_pair/device_id_map.h"
 #include "ash/quick_pair/repository/fast_pair/device_image_store.h"
 #include "ash/quick_pair/repository/fast_pair/device_metadata_fetcher.h"
-#include "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h"
+#include "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.h"
 #include "ash/quick_pair/repository/fast_pair/footprints_fetcher.h"
 #include "ash/quick_pair/repository/fast_pair/proto_conversions.h"
 #include "ash/quick_pair/repository/fast_pair/saved_device_registry.h"
@@ -21,7 +21,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "chromeos/services/bluetooth_config/public/cpp/device_image_info.h"
-#include "components/image_fetcher/core/image_fetcher.h"
 #include "device/bluetooth/bluetooth_device.h"
 
 namespace ash {
@@ -31,10 +30,10 @@
     : FastPairRepository(),
       device_metadata_fetcher_(std::make_unique<DeviceMetadataFetcher>()),
       footprints_fetcher_(std::make_unique<FootprintsFetcher>()),
-      image_decoder_(std::make_unique<FastPairImageDecoder>(
-          std::unique_ptr<image_fetcher::ImageFetcher>())),
+      image_decoder_(std::make_unique<FastPairImageDecoderImpl>()),
       device_id_map_(std::make_unique<DeviceIdMap>()),
-      device_image_store_(std::make_unique<DeviceImageStore>()),
+      device_image_store_(
+          std::make_unique<DeviceImageStore>(image_decoder_.get())),
       saved_device_registry_(std::make_unique<SavedDeviceRegistry>()),
       footprints_last_updated_(base::Time::UnixEpoch()) {}
 
@@ -78,6 +77,7 @@
 
   image_decoder_->DecodeImage(
       binary_data,
+      /*resize_to_notification_size=*/true,
       base::BindOnce(&FastPairRepositoryImpl::OnImageDecoded,
                      weak_ptr_factory_.GetWeakPtr(), normalized_model_id,
                      std::move(callback), *response));
@@ -260,8 +260,8 @@
   QP_LOG(INFO) << __func__
                << ": Completing fetching device images for model ID "
                << hex_model_id;
-  device_image_store_->SaveDeviceImages(hex_model_id, device_metadata,
-                                        base::DoNothing());
+  device_image_store_->FetchDeviceImages(hex_model_id, device_metadata,
+                                         base::DoNothing());
 }
 
 bool FastPairRepositoryImpl::PersistDeviceImages(scoped_refptr<Device> device) {
diff --git a/ash/system/holding_space/holding_space_animation_registry.cc b/ash/system/holding_space/holding_space_animation_registry.cc
index 6b6888f4..f2aa63cad 100644
--- a/ash/system/holding_space/holding_space_animation_registry.cc
+++ b/ash/system/holding_space/holding_space_animation_registry.cc
@@ -57,78 +57,6 @@
       const ProgressIndicatorAnimationDelegate&) = delete;
   ~ProgressIndicatorAnimationDelegate() override = default;
 
-  // Adds the specified `callback` to be notified of changes to the icon
-  // animation associated with the specified `key`. The `callback` will continue
-  // to receive events so long as both `this` and the returned subscription
-  // exist.
-  base::CallbackListSubscription AddIconAnimationChangedCallbackForKey(
-      const void* key,
-      ProgressIconAnimationChangedCallbackList::CallbackType callback) {
-    auto it =
-        registry_->icon_animation_changed_callback_lists_by_key().find(key);
-
-    // If this is the first time that an icon animation changed callback is
-    // being registered for the specified `key`, set a callback to destroy the
-    // created callback list when it becomes empty.
-    if (it == registry_->icon_animation_changed_callback_lists_by_key().end()) {
-      it = registry_->icon_animation_changed_callback_lists_by_key()
-               .emplace(std::piecewise_construct, std::forward_as_tuple(key),
-                        std::forward_as_tuple())
-               .first;
-      it->second.set_removal_callback(base::BindRepeating(
-          &ProgressIndicatorAnimationDelegate::
-              EraseIconAnimationChangedCallbackListForKeyIfEmpty,
-          base::Unretained(this), base::Unretained(key)));
-    }
-
-    return it->second.Add(std::move(callback));
-  }
-
-  // Adds the specified `callback` to be notified of changes to the ring
-  // animation associated with the specified `key`. The `callback` will continue
-  // to receive events so long as both `this` and the returned subscription
-  // exist.
-  base::CallbackListSubscription AddRingAnimationChangedCallbackForKey(
-      const void* key,
-      ProgressRingAnimationChangedCallbackList::CallbackType callback) {
-    auto it =
-        registry_->ring_animation_changed_callback_lists_by_key().find(key);
-
-    // If this is the first time that a ring animation changed callback is being
-    // registered for the specified `key`, set a callback to destroy the
-    // created callback list when it becomes empty.
-    if (it == registry_->ring_animation_changed_callback_lists_by_key().end()) {
-      it = registry_->ring_animation_changed_callback_lists_by_key()
-               .emplace(std::piecewise_construct, std::forward_as_tuple(key),
-                        std::forward_as_tuple())
-               .first;
-      it->second.set_removal_callback(base::BindRepeating(
-          &ProgressIndicatorAnimationDelegate::
-              EraseRingAnimationChangedCallbackListForKeyIfEmpty,
-          base::Unretained(this), base::Unretained(key)));
-    }
-
-    return it->second.Add(std::move(callback));
-  }
-
-  // Returns the registered icon animation for the specified `key`.
-  // NOTE: This may return `nullptr` if no such animation is registered.
-  HoldingSpaceProgressIconAnimation* GetIconAnimationForKey(const void* key) {
-    auto it = registry_->icon_animations_by_key().find(key);
-    return it != registry_->icon_animations_by_key().end()
-               ? it->second.animation.get()
-               : nullptr;
-  }
-
-  // Returns the registered ring animation for the specified `key`.
-  // NOTE: This may return `nullptr` if no such animation is registered.
-  HoldingSpaceProgressRingAnimation* GetRingAnimationForKey(const void* key) {
-    auto it = registry_->ring_animations_by_key().find(key);
-    return it != registry_->ring_animations_by_key().end()
-               ? it->second.animation.get()
-               : nullptr;
-  }
-
  private:
   // HoldingSpaceControllerObserver:
   void OnHoldingSpaceModelAttached(HoldingSpaceModel* model) override {
@@ -180,40 +108,6 @@
     UpdateAnimations(/*for_removal=*/false);
   }
 
-  // Erases all animations, notifying any animation changed callbacks.
-  void EraseAllAnimations() {
-    EraseAllAnimationsForKeyIf(
-        base::BindRepeating([](const void* key) { return true; }));
-  }
-
-  // Erases all animations for the specified `key`, notifying any animation
-  // changed callbacks.
-  void EraseAllAnimationsForKey(const void* key) {
-    EraseIconAnimationForKey(key);
-    EraseRingAnimationForKey(key);
-  }
-
-  // Erases all animations for keys for which `predicate` returns `true`,
-  // notifying any animation changed callbacks.
-  void EraseAllAnimationsForKeyIf(
-      base::RepeatingCallback<bool(const void* key)> predicate) {
-    std::set<const void*> keys_to_erase;
-    for (const auto& icon_animation_by_key :
-         registry_->icon_animations_by_key()) {
-      const void* key = icon_animation_by_key.first;
-      if (predicate.Run(key))
-        keys_to_erase.insert(key);
-    }
-    for (const auto& ring_animation_by_key :
-         registry_->ring_animations_by_key()) {
-      const void* key = ring_animation_by_key.first;
-      if (predicate.Run(key))
-        keys_to_erase.insert(key);
-    }
-    for (const void* key : keys_to_erase)
-      EraseAllAnimationsForKey(key);
-  }
-
   // Erases the icon animation callback list for the specified `key` if empty.
   void EraseIconAnimationChangedCallbackListForKeyIfEmpty(const void* key) {
     auto it =
@@ -224,26 +118,6 @@
       registry_->icon_animation_changed_callback_lists_by_key().erase(it);
   }
 
-  // Erases the icon animation for the specified `key`, notifying any animation
-  // changed callbacks.
-  void EraseIconAnimationForKey(const void* key) {
-    auto it = registry_->icon_animations_by_key().find(key);
-    if (it == registry_->icon_animations_by_key().end())
-      return;
-    registry_->icon_animations_by_key().erase(it);
-    NotifyIconAnimationChangedForKey(key);
-  }
-
-  // Erases the ring animation for the specified `key`, notifying any animation
-  // changed callbacks.
-  void EraseRingAnimationForKey(const void* key) {
-    auto it = registry_->ring_animations_by_key().find(key);
-    if (it == registry_->ring_animations_by_key().end())
-      return;
-    registry_->ring_animations_by_key().erase(it);
-    NotifyRingAnimationChangedForKey(key);
-  }
-
   // Erases the ring animation for the specified `key` if it is not of the
   // desired `type`, notifying any animation changed callbacks.
   void EraseRingAnimationIfNotOfTypeForKey(
@@ -252,7 +126,7 @@
     auto it = registry_->ring_animations_by_key().find(key);
     if (it != registry_->ring_animations_by_key().end() &&
         it->second.animation->type() != type) {
-      EraseRingAnimationForKey(key);
+      registry_->SetProgressRingAnimationForKey(key, nullptr);
     }
   }
 
@@ -358,13 +232,13 @@
     // Animations will be updated if and when a `model_` is attached.
     if (model_ == nullptr) {
       cumulative_progress_ = HoldingSpaceProgress();
-      EraseAllAnimations();
+      registry_->EraseAllAnimations();
       return;
     }
 
     // Clean up all animations associated with holding space items that are no
     // longer present in the attached `model_`.
-    EraseAllAnimationsForKeyIf(base::BindRepeating(
+    registry_->EraseAllAnimationsForKeyIf(base::BindRepeating(
         [](const std::vector<std::unique_ptr<HoldingSpaceItem>>& items,
            const void* controller, const void* key) {
           return key != controller &&
@@ -381,7 +255,7 @@
       // If an `item` is not initialized or is not visibly in-progress, it
       // shouldn't contribute to `cumulative_progress_` nor have an animation.
       if (!item->IsInitialized() || item->progress().IsHidden()) {
-        EraseAllAnimationsForKey(item.get());
+        registry_->EraseAllAnimationsForKey(item.get());
         continue;
       }
 
@@ -392,7 +266,7 @@
       // animated. Any other type of animation should be cleared. Note that a
       // completed `item` does not contribute to `cumulative_progress_`.
       if (item->progress().IsComplete()) {
-        EraseIconAnimationForKey(item.get());
+        registry_->SetProgressIconAnimationForKey(item.get(), nullptr);
         EraseRingAnimationIfNotOfTypeForKey(
             item.get(), HoldingSpaceProgressRingAnimation::Type::kPulse);
         continue;
@@ -415,20 +289,20 @@
 
       // If `item` is not in an indeterminate state, it should not have an
       // associated ring animation.
-      EraseRingAnimationForKey(item.get());
+      registry_->SetProgressRingAnimationForKey(item.get(), nullptr);
     }
 
     if (cumulative_progress_.IsComplete()) {
       // Because `cumulative_progress_` is complete, the `controller_` should
       // not have an associated icon animation.
-      EraseIconAnimationForKey(controller_);
+      registry_->SetProgressIconAnimationForKey(controller_, nullptr);
 
       if (!last_cumulative_progress.IsComplete()) {
         if (for_removal) {
           // If `cumulative_progress_` has just become complete as a result of
           // one or more holding space items being removed, the `controller_`
           // should not have an associated ring animation.
-          EraseRingAnimationForKey(controller_);
+          registry_->SetProgressRingAnimationForKey(controller_, nullptr);
         } else {
           // If `cumulative_progress_` has just become complete and is *not* due
           // to the removal of one or more holding space items, ensure that a
@@ -461,7 +335,7 @@
 
     // If `cumulative_progress_` is not in an indeterminate state, the
     // `controller_` should not have an associated ring animation.
-    EraseRingAnimationForKey(controller_);
+    registry_->SetProgressRingAnimationForKey(controller_, nullptr);
   }
 
   // Invoked when the specified ring `animation` for the specified `key` has
@@ -480,10 +354,11 @@
             [](const base::WeakPtr<ProgressIndicatorAnimationDelegate>&
                    delegate,
                const void* key, HoldingSpaceProgressRingAnimation* animation) {
-              if (delegate &&
-                  delegate->GetRingAnimationForKey(key) == animation) {
-                delegate->EraseRingAnimationForKey(key);
-              }
+              if (!delegate)
+                return;
+              auto* registry = delegate->registry_;
+              if (registry->GetProgressRingAnimationForKey(key) == animation)
+                registry->SetProgressRingAnimationForKey(key, nullptr);
             },
             weak_factory_.GetWeakPtr(), key, animation));
   }
@@ -528,32 +403,6 @@
   return instance_owner.get();
 }
 
-base::CallbackListSubscription
-HoldingSpaceAnimationRegistry::AddProgressIconAnimationChangedCallbackForKey(
-    const void* key,
-    ProgressIconAnimationChangedCallbackList::CallbackType callback) {
-  return progress_indicator_animation_delegate_
-      ->AddIconAnimationChangedCallbackForKey(key, std::move(callback));
-}
-
-base::CallbackListSubscription
-HoldingSpaceAnimationRegistry::AddProgressRingAnimationChangedCallbackForKey(
-    const void* key,
-    ProgressRingAnimationChangedCallbackList::CallbackType callback) {
-  return progress_indicator_animation_delegate_
-      ->AddRingAnimationChangedCallbackForKey(key, std::move(callback));
-}
-
-HoldingSpaceProgressIconAnimation*
-HoldingSpaceAnimationRegistry::GetProgressIconAnimationForKey(const void* key) {
-  return progress_indicator_animation_delegate_->GetIconAnimationForKey(key);
-}
-
-HoldingSpaceProgressRingAnimation*
-HoldingSpaceAnimationRegistry::GetProgressRingAnimationForKey(const void* key) {
-  return progress_indicator_animation_delegate_->GetRingAnimationForKey(key);
-}
-
 void HoldingSpaceAnimationRegistry::OnShellDestroying() {
   auto& instance_owner = GetInstanceOwner();
   DCHECK_EQ(instance_owner.get(), this);
diff --git a/ash/system/holding_space/holding_space_animation_registry.h b/ash/system/holding_space/holding_space_animation_registry.h
index 8e12c554..9e0d12431 100644
--- a/ash/system/holding_space/holding_space_animation_registry.h
+++ b/ash/system/holding_space/holding_space_animation_registry.h
@@ -15,9 +15,6 @@
 
 namespace ash {
 
-class HoldingSpaceProgressIconAnimation;
-class HoldingSpaceProgressRingAnimation;
-
 // A lazily initialized singleton registry for holding space animations.
 //
 // Since registered animations are owned by the singleton, they can be shared
@@ -43,18 +40,6 @@
   // when `Shell` is being destroyed.
   static HoldingSpaceAnimationRegistry* GetInstance();
 
-  // ProgressIndicatorAnimationRegistry:
-  base::CallbackListSubscription AddProgressIconAnimationChangedCallbackForKey(
-      const void* key,
-      ProgressIconAnimationChangedCallbackList::CallbackType callback) override;
-  base::CallbackListSubscription AddProgressRingAnimationChangedCallbackForKey(
-      const void* key,
-      ProgressRingAnimationChangedCallbackList::CallbackType callback) override;
-  HoldingSpaceProgressIconAnimation* GetProgressIconAnimationForKey(
-      const void* key) override;
-  HoldingSpaceProgressRingAnimation* GetProgressRingAnimationForKey(
-      const void* key) override;
-
  private:
   HoldingSpaceAnimationRegistry();
 
diff --git a/ash/system/holding_space/holding_space_progress_icon_animation.h b/ash/system/holding_space/holding_space_progress_icon_animation.h
index 689cb67..20dd4a9 100644
--- a/ash/system/holding_space/holding_space_progress_icon_animation.h
+++ b/ash/system/holding_space/holding_space_progress_icon_animation.h
@@ -5,12 +5,13 @@
 #ifndef ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_PROGRESS_ICON_ANIMATION_H_
 #define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_PROGRESS_ICON_ANIMATION_H_
 
+#include "ash/ash_export.h"
 #include "ash/system/holding_space/holding_space_progress_indicator_animation.h"
 
 namespace ash {
 
 // An animation for a `HoldingSpaceProgressIndicator`'s icon.
-class HoldingSpaceProgressIconAnimation
+class ASH_EXPORT HoldingSpaceProgressIconAnimation
     : public HoldingSpaceProgressIndicatorAnimation {
  public:
   HoldingSpaceProgressIconAnimation();
diff --git a/ash/system/holding_space/holding_space_progress_indicator_animation.h b/ash/system/holding_space/holding_space_progress_indicator_animation.h
index 143f1a3..0551465 100644
--- a/ash/system/holding_space/holding_space_progress_indicator_animation.h
+++ b/ash/system/holding_space/holding_space_progress_indicator_animation.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "ash/ash_export.h"
 #include "base/callback_list.h"
 #include "base/time/time.h"
 #include "ui/gfx/animation/animation_delegate.h"
@@ -18,7 +19,8 @@
 namespace ash {
 
 // An animation for a `HoldingSpaceProgressIndicator`.
-class HoldingSpaceProgressIndicatorAnimation : public gfx::AnimationDelegate {
+class ASH_EXPORT HoldingSpaceProgressIndicatorAnimation
+    : public gfx::AnimationDelegate {
  public:
   HoldingSpaceProgressIndicatorAnimation(
       const HoldingSpaceProgressIndicatorAnimation&) = delete;
diff --git a/ash/system/holding_space/holding_space_progress_ring_animation.h b/ash/system/holding_space/holding_space_progress_ring_animation.h
index 5a331bb..3e38e90 100644
--- a/ash/system/holding_space/holding_space_progress_ring_animation.h
+++ b/ash/system/holding_space/holding_space_progress_ring_animation.h
@@ -7,13 +7,14 @@
 
 #include <memory>
 
+#include "ash/ash_export.h"
 #include "ash/system/holding_space/holding_space_progress_indicator_animation.h"
 
 namespace ash {
 
 // An animation for a `HoldingSpaceProgressIndicator` to be painted in lieu of
 // the determinate progress ring that would otherwise be painted.
-class HoldingSpaceProgressRingAnimation
+class ASH_EXPORT HoldingSpaceProgressRingAnimation
     : public HoldingSpaceProgressIndicatorAnimation {
  public:
   enum class Type {
diff --git a/ash/system/message_center/ash_notification_view.cc b/ash/system/message_center/ash_notification_view.cc
index d30a0e42..60069c71 100644
--- a/ash/system/message_center/ash_notification_view.cc
+++ b/ash/system/message_center/ash_notification_view.cc
@@ -131,7 +131,7 @@
 }
 
 // Create a view that will contain the `content_row`,
-// `message_view_in_expanded_state_`, inline settings and the large image.
+// `message_label_in_expanded_state_`, inline settings and the large image.
 views::Builder<views::View> CreateMainRightViewBuilder() {
   auto layout_manager = std::make_unique<views::FlexLayout>();
   layout_manager
@@ -362,10 +362,10 @@
           .AddChild(content_row_builder)
           .AddChild(
               views::Builder<views::Label>()
-                  .CopyAddressTo(&message_view_in_expanded_state_)
+                  .CopyAddressTo(&message_label_in_expanded_state_)
                   .SetHorizontalAlignment(gfx::ALIGN_TO_HEAD)
                   .SetMultiLine(true)
-                  .SetMaxLines(message_center::kMaxLinesForExpandedMessageView)
+                  .SetMaxLines(message_center::kMaxLinesForExpandedMessageLabel)
                   .SetAllowCharacterBreak(true)
                   .SetBorder(
                       views::CreateEmptyBorder(kMainRightViewChildPadding))
@@ -374,12 +374,12 @@
                   // original bug, but it seems there's no obvious solution for
                   // the bug according to https://crbug.com/678337#c7. We will
                   // consider making changes to this code when the bug is fixed.
-                  .SetMaximumWidth(GetExpandedMessageViewWidth()))
+                  .SetMaximumWidth(GetExpandedMessageLabelWidth()))
           .AddChild(CreateInlineSettingsBuilder())
           .AddChild(CreateImageContainerBuilder().SetBorder(
               views::CreateEmptyBorder(kImageContainerPadding)));
 
-  ConfigureLabelStyle(message_view_in_expanded_state_, kMessageLabelSize,
+  ConfigureLabelStyle(message_label_in_expanded_state_, kMessageLabelSize,
                       false);
 
   AddChildView(
@@ -474,7 +474,8 @@
 
   // Create layer in some views for animations.
   message_center_utils::InitLayerForAnimations(header_row());
-  message_center_utils::InitLayerForAnimations(message_view_in_expanded_state_);
+  message_center_utils::InitLayerForAnimations(
+      message_label_in_expanded_state_);
   message_center_utils::InitLayerForAnimations(actions_row());
 
   UpdateWithNotification(notification);
@@ -664,15 +665,15 @@
                                  (IsExpandable() && !expanded));
   }
 
-  if (message_view()) {
-    // `message_view()` is shown only in collapsed mode.
+  if (message_label()) {
+    // `message_label()` is shown only in collapsed mode.
     if (!expanded) {
-      ConfigureLabelStyle(message_view(), kMessageLabelSize, false);
-      message_center_utils::InitLayerForAnimations(message_view());
+      ConfigureLabelStyle(message_label(), kMessageLabelSize, false);
+      message_center_utils::InitLayerForAnimations(message_label());
     }
-    message_view()->SetVisible(!expanded);
-    message_view_in_expanded_state_->SetVisible(expanded &&
-                                                !is_grouped_parent_view_);
+    message_label()->SetVisible(!expanded);
+    message_label_in_expanded_state_->SetVisible(expanded &&
+                                                 !is_grouped_parent_view_);
   }
 
   // Custom padding for app icon and expand button. These 2 views should always
@@ -722,7 +723,7 @@
     grouped_notifications_scroll_view_->SetVisible(is_grouped_parent_view_);
 
   header_row()->SetVisible(!is_grouped_child_view_);
-  UpdateMessageViewInExpandedState(notification);
+  UpdateMessageLabelInExpandedState(notification);
 
   NotificationViewBase::UpdateWithNotification(notification);
 
@@ -1013,18 +1014,18 @@
   snooze_button_ = action_buttons_row()->AddChildView(std::move(snooze_button));
 }
 
-void AshNotificationView::UpdateMessageViewInExpandedState(
+void AshNotificationView::UpdateMessageLabelInExpandedState(
     const message_center::Notification& notification) {
   if (notification.type() == message_center::NOTIFICATION_TYPE_PROGRESS ||
       notification.message().empty()) {
-    message_view_in_expanded_state_->SetVisible(false);
+    message_label_in_expanded_state_->SetVisible(false);
     return;
   }
-  message_view_in_expanded_state_->SetText(gfx::TruncateString(
+  message_label_in_expanded_state_->SetText(gfx::TruncateString(
       notification.message(), message_center::kMessageCharacterLimit,
       gfx::WORD_BREAK));
 
-  message_view_in_expanded_state_->SetVisible(true);
+  message_label_in_expanded_state_->SetVisible(true);
 }
 
 void AshNotificationView::UpdateBackground(int top_radius, int bottom_radius) {
@@ -1052,7 +1053,7 @@
           top_radius_, bottom_radius_, background_color_)));
 }
 
-int AshNotificationView::GetExpandedMessageViewWidth() {
+int AshNotificationView::GetExpandedMessageLabelWidth() {
   int notification_width = shown_in_popup_ ? message_center::kNotificationWidth
                                            : kNotificationInMessageCenterWidth;
 
@@ -1144,24 +1145,24 @@
                                      kHeaderRowFadeInAnimationDurationMs);
   }
 
-  // Fade in `message_view()`. We only do fade in for both message view in
+  // Fade in `message_label()`. We only do fade in for both message view in
   // expanded and collapsed mode if there's a difference between them (a.k.a
-  // when `message_view()` is truncated).
-  if (message_view() && message_view()->GetVisible() &&
-      message_view()->IsDisplayTextTruncated()) {
-    message_center_utils::FadeInView(message_view(),
-                                     kMessageViewFadeInAnimationDelayMs,
-                                     kMessageViewFadeInAnimationDurationMs);
+  // when `message_label()` is truncated).
+  if (message_label() && message_label()->GetVisible() &&
+      message_label()->IsDisplayTextTruncated()) {
+    message_center_utils::FadeInView(message_label(),
+                                     kMessageLabelFadeInAnimationDelayMs,
+                                     kMessageLabelFadeInAnimationDurationMs);
   }
 
-  // Fade in `message_view_in_expanded_state_`.
-  if (message_view_in_expanded_state_ &&
-      message_view_in_expanded_state_->GetVisible() && message_view() &&
-      message_view()->IsDisplayTextTruncated()) {
+  // Fade in `message_label_in_expanded_state_`.
+  if (message_label_in_expanded_state_ &&
+      message_label_in_expanded_state_->GetVisible() && message_label() &&
+      message_label()->IsDisplayTextTruncated()) {
     message_center_utils::FadeInView(
-        message_view_in_expanded_state_,
-        kMessageViewInExpandedStateFadeInAnimationDelayMs,
-        kMessageViewInExpandedStateFadeInAnimationDurationMs);
+        message_label_in_expanded_state_,
+        kMessageLabelInExpandedStateFadeInAnimationDelayMs,
+        kMessageLabelInExpandedStateFadeInAnimationDurationMs);
   }
 
   if (!image_container_view()->children().empty()) {
diff --git a/ash/system/message_center/ash_notification_view.h b/ash/system/message_center/ash_notification_view.h
index 7607deb..fbf0b6b 100644
--- a/ash/system/message_center/ash_notification_view.h
+++ b/ash/system/message_center/ash_notification_view.h
@@ -173,14 +173,14 @@
       const message_center::Notification& notification);
 
   // Update `message_in_expanded_view_` according to the given notification.
-  void UpdateMessageViewInExpandedState(
+  void UpdateMessageLabelInExpandedState(
       const message_center::Notification& notification);
 
   // Update the background color with rounded corner.
   void UpdateBackground(int top_radius, int bottom_radius);
 
-  // Get the available space for `message_view_in_expanded_state_` width.
-  int GetExpandedMessageViewWidth();
+  // Get the available space for `message_label_in_expanded_state_` width.
+  int GetExpandedMessageLabelWidth();
 
   // Disable the notification of this view. Called after the turn of
   // notifications button is clicked.
@@ -217,7 +217,7 @@
   views::FlexLayoutView* expand_button_container_ = nullptr;
   views::View* control_buttons_container_ = nullptr;
   views::View* left_content_ = nullptr;
-  views::Label* message_view_in_expanded_state_ = nullptr;
+  views::Label* message_label_in_expanded_state_ = nullptr;
   views::ScrollView* grouped_notifications_scroll_view_ = nullptr;
   views::View* grouped_notifications_container_ = nullptr;
   views::View* collapsed_summary_view_ = nullptr;
diff --git a/ash/system/message_center/ash_notification_view_unittest.cc b/ash/system/message_center/ash_notification_view_unittest.cc
index d692e370a..ab0d79a 100644
--- a/ash/system/message_center/ash_notification_view_unittest.cc
+++ b/ash/system/message_center/ash_notification_view_unittest.cc
@@ -171,9 +171,9 @@
   views::Label* timestamp_in_collapsed_view() {
     return notification_view_->title_row_->timestamp_in_collapsed_view_;
   }
-  views::Label* message_view() { return notification_view_->message_view(); }
-  views::Label* message_view_in_expanded_state() {
-    return notification_view_->message_view_in_expanded_state_;
+  views::Label* message_label() { return notification_view_->message_label(); }
+  views::Label* message_label_in_expanded_state() {
+    return notification_view_->message_label_in_expanded_state_;
   }
   AshNotificationExpandButton* expand_button() {
     return notification_view_->expand_button_;
@@ -201,9 +201,9 @@
 
 TEST_F(AshNotificationViewTest, UpdateViewsOrderingTest) {
   EXPECT_NE(nullptr, title_row());
-  EXPECT_NE(nullptr, message_view());
+  EXPECT_NE(nullptr, message_label());
   EXPECT_EQ(0, left_content()->GetIndexOf(title_row()));
-  EXPECT_EQ(1, left_content()->GetIndexOf(message_view()));
+  EXPECT_EQ(1, left_content()->GetIndexOf(message_label()));
 
   std::unique_ptr<Notification> notification = CreateTestNotification();
   notification->set_title(std::u16string());
@@ -211,17 +211,17 @@
   notification_view()->UpdateWithNotification(*notification);
 
   EXPECT_EQ(nullptr, title_row());
-  EXPECT_NE(nullptr, message_view());
-  EXPECT_EQ(0, left_content()->GetIndexOf(message_view()));
+  EXPECT_NE(nullptr, message_label());
+  EXPECT_EQ(0, left_content()->GetIndexOf(message_label()));
 
   notification->set_title(u"title");
 
   notification_view()->UpdateWithNotification(*notification);
 
   EXPECT_NE(nullptr, title_row());
-  EXPECT_NE(nullptr, message_view());
+  EXPECT_NE(nullptr, message_label());
   EXPECT_EQ(0, left_content()->GetIndexOf(title_row()));
-  EXPECT_EQ(1, left_content()->GetIndexOf(message_view()));
+  EXPECT_EQ(1, left_content()->GetIndexOf(message_label()));
 }
 
 TEST_F(AshNotificationViewTest, CreateOrUpdateTitle) {
@@ -287,16 +287,16 @@
   EXPECT_FALSE(header_row()->GetVisible());
   EXPECT_TRUE(timestamp_in_collapsed_view()->GetVisible());
   EXPECT_TRUE(title_row_divider()->GetVisible());
-  EXPECT_TRUE(message_view()->GetVisible());
-  EXPECT_FALSE(message_view_in_expanded_state()->GetVisible());
+  EXPECT_TRUE(message_label()->GetVisible());
+  EXPECT_FALSE(message_label_in_expanded_state()->GetVisible());
 
   // Expected behavior in expanded mode.
   notification_view()->SetExpanded(true);
   EXPECT_TRUE(header_row()->GetVisible());
   EXPECT_FALSE(timestamp_in_collapsed_view()->GetVisible());
   EXPECT_FALSE(title_row_divider()->GetVisible());
-  EXPECT_FALSE(message_view()->GetVisible());
-  EXPECT_TRUE(message_view_in_expanded_state()->GetVisible());
+  EXPECT_FALSE(message_label()->GetVisible());
+  EXPECT_TRUE(message_label_in_expanded_state()->GetVisible());
 }
 
 TEST_F(AshNotificationViewTest, GroupedNotificationStartsCollapsed) {
diff --git a/ash/system/message_center/message_center_constants.h b/ash/system/message_center/message_center_constants.h
index fa0dda34..c6c9dd67 100644
--- a/ash/system/message_center/message_center_constants.h
+++ b/ash/system/message_center/message_center_constants.h
@@ -61,10 +61,10 @@
 constexpr int kTitleRowTimestampFadeInAnimationDurationMs = 100;
 constexpr int kHeaderRowFadeInAnimationDelayMs = 50;
 constexpr int kHeaderRowFadeInAnimationDurationMs = 150;
-constexpr int kMessageViewFadeInAnimationDelayMs = 100;
-constexpr int kMessageViewFadeInAnimationDurationMs = 100;
-constexpr int kMessageViewInExpandedStateFadeInAnimationDelayMs = 100;
-constexpr int kMessageViewInExpandedStateFadeInAnimationDurationMs = 183;
+constexpr int kMessageLabelFadeInAnimationDelayMs = 100;
+constexpr int kMessageLabelFadeInAnimationDurationMs = 100;
+constexpr int kMessageLabelInExpandedStateFadeInAnimationDelayMs = 100;
+constexpr int kMessageLabelInExpandedStateFadeInAnimationDurationMs = 183;
 constexpr int kActionsRowFadeInAnimationDelayMs = 50;
 constexpr int kActionsRowFadeInAnimationDurationMs = 100;
 constexpr int kActionButtonsFadeOutAnimationDurationMs = 100;
diff --git a/ash/system/progress_indicator/progress_indicator_animation_registry.cc b/ash/system/progress_indicator/progress_indicator_animation_registry.cc
index 28fcddc..87abd684 100644
--- a/ash/system/progress_indicator/progress_indicator_animation_registry.cc
+++ b/ash/system/progress_indicator/progress_indicator_animation_registry.cc
@@ -4,7 +4,121 @@
 
 #include "ash/system/progress_indicator/progress_indicator_animation_registry.h"
 
+#include <set>
+
 namespace ash {
+namespace {
+
+// Type aliases ----------------------------------------------------------------
+
+template <typename AnimationType>
+using KeyedAnimationWithSubscriptionMap =
+    std::map<const void*,
+             ProgressIndicatorAnimationRegistry::AnimationWithSubscription<
+                 AnimationType>>;
+
+template <typename CallbackListType>
+using KeyedAnimationChangedCallbackListMap =
+    std::map<const void*, CallbackListType>;
+
+// Helpers ---------------------------------------------------------------------
+
+// Notifies any animation changed callbacks registered for the specified `key`
+// that the associated animation has changed.
+template <typename AnimationType, typename CallbackListType>
+void NotifyAnimationChangedForKey(
+    KeyedAnimationWithSubscriptionMap<AnimationType>* animations_by_key,
+    KeyedAnimationChangedCallbackListMap<CallbackListType>*
+        animation_changed_callback_lists_by_key,
+    const void* key) {
+  auto callback_lists_it = animation_changed_callback_lists_by_key->find(key);
+  if (callback_lists_it == animation_changed_callback_lists_by_key->end())
+    return;
+  auto animations_it = animations_by_key->find(key);
+  callback_lists_it->second.Notify(animations_it != animations_by_key->end()
+                                       ? animations_it->second.animation.get()
+                                       : nullptr);
+}
+
+// Implements:
+// * `AddProgressIconAnimationChangedCallbackForKey()`
+// * `AddProgressRingAnimationChangedCallbackForKey()`
+template <typename CallbackListType>
+base::CallbackListSubscription AddAnimationChangedCallbackForKey(
+    KeyedAnimationChangedCallbackListMap<CallbackListType>*
+        animation_changed_callback_lists_by_key,
+    const void* key,
+    typename CallbackListType::CallbackType callback) {
+  auto it = animation_changed_callback_lists_by_key->find(key);
+
+  // If this is the first time that an animation changed callback is being
+  // registered for the specified `key`, set a callback to destroy the created
+  // callback list when it becomes empty.
+  if (it == animation_changed_callback_lists_by_key->end()) {
+    it = animation_changed_callback_lists_by_key
+             ->emplace(std::piecewise_construct, std::forward_as_tuple(key),
+                       std::forward_as_tuple())
+             .first;
+    it->second.set_removal_callback(base::BindRepeating(
+        [](KeyedAnimationChangedCallbackListMap<CallbackListType>*
+               animation_changed_callback_lists_by_key,
+           const void* key) {
+          auto it = animation_changed_callback_lists_by_key->find(key);
+          if (it != animation_changed_callback_lists_by_key->end() &&
+              it->second.empty()) {
+            animation_changed_callback_lists_by_key->erase(it);
+          }
+        },
+        base::Unretained(animation_changed_callback_lists_by_key),
+        base::Unretained(key)));
+  }
+
+  return it->second.Add(std::move(callback));
+}
+
+// Implements:
+// * `GetProgressIconAnimationForKey()`
+// * `GetProgressRingAnimationForKey()`
+template <typename AnimationType>
+AnimationType* GetAnimationForKey(
+    KeyedAnimationWithSubscriptionMap<AnimationType>* animations_by_key,
+    const void* key) {
+  auto it = animations_by_key->find(key);
+  return it != animations_by_key->end() ? it->second.animation.get() : nullptr;
+}
+
+// Implements:
+// * `SetProgressIconAnimationForKey()`
+// * `SetProgressRingAnimationForKey()`
+template <typename AnimationType, typename CallbackListType>
+AnimationType* SetAnimationForKey(
+    KeyedAnimationWithSubscriptionMap<AnimationType>* animations_by_key,
+    KeyedAnimationChangedCallbackListMap<CallbackListType>*
+        animation_changed_callback_lists_by_key,
+    const void* key,
+    std::unique_ptr<AnimationType> animation) {
+  AnimationType* animation_ptr = animation.get();
+  if (animation) {
+    (*animations_by_key)[key] =
+        ProgressIndicatorAnimationRegistry::AnimationWithSubscription<
+            AnimationType>{.animation = std::move(animation),
+                           .subscription = base::CallbackListSubscription()};
+    NotifyAnimationChangedForKey(animations_by_key,
+                                 animation_changed_callback_lists_by_key, key);
+  } else {
+    auto it = animations_by_key->find(key);
+    if (it != animations_by_key->end()) {
+      animations_by_key->erase(it);
+      NotifyAnimationChangedForKey(
+          animations_by_key, animation_changed_callback_lists_by_key, key);
+    }
+  }
+  return animation_ptr;
+}
+
+}  // namespace
+
+// ProgressIndicatorAnimationRegistry ------------------------------------------
 
 ProgressIndicatorAnimationRegistry::ProgressIndicatorAnimationRegistry() =
     default;
@@ -12,4 +126,78 @@
 ProgressIndicatorAnimationRegistry::~ProgressIndicatorAnimationRegistry() =
     default;
 
+base::CallbackListSubscription ProgressIndicatorAnimationRegistry::
+    AddProgressIconAnimationChangedCallbackForKey(
+        const void* key,
+        ProgressIconAnimationChangedCallbackList::CallbackType callback) {
+  return AddAnimationChangedCallbackForKey(
+      &icon_animation_changed_callback_lists_by_key_, key, std::move(callback));
+}
+
+base::CallbackListSubscription ProgressIndicatorAnimationRegistry::
+    AddProgressRingAnimationChangedCallbackForKey(
+        const void* key,
+        ProgressRingAnimationChangedCallbackList::CallbackType callback) {
+  return AddAnimationChangedCallbackForKey(
+      &ring_animation_changed_callback_lists_by_key_, key, std::move(callback));
+}
+
+HoldingSpaceProgressIconAnimation*
+ProgressIndicatorAnimationRegistry::GetProgressIconAnimationForKey(
+    const void* key) {
+  return GetAnimationForKey(&icon_animations_by_key_, key);
+}
+
+HoldingSpaceProgressRingAnimation*
+ProgressIndicatorAnimationRegistry::GetProgressRingAnimationForKey(
+    const void* key) {
+  return GetAnimationForKey(&ring_animations_by_key_, key);
+}
+
+HoldingSpaceProgressIconAnimation*
+ProgressIndicatorAnimationRegistry::SetProgressIconAnimationForKey(
+    const void* key,
+    std::unique_ptr<HoldingSpaceProgressIconAnimation> animation) {
+  return SetAnimationForKey(&icon_animations_by_key_,
+                            &icon_animation_changed_callback_lists_by_key_, key,
+                            std::move(animation));
+}
+
+HoldingSpaceProgressRingAnimation*
+ProgressIndicatorAnimationRegistry::SetProgressRingAnimationForKey(
+    const void* key,
+    std::unique_ptr<HoldingSpaceProgressRingAnimation> animation) {
+  return SetAnimationForKey(&ring_animations_by_key_,
+                            &ring_animation_changed_callback_lists_by_key_, key,
+                            std::move(animation));
+}
+
+void ProgressIndicatorAnimationRegistry::EraseAllAnimations() {
+  EraseAllAnimationsForKeyIf(
+      base::BindRepeating([](const void* key) { return true; }));
+}
+
+void ProgressIndicatorAnimationRegistry::EraseAllAnimationsForKey(
+    const void* key) {
+  SetProgressIconAnimationForKey(key, nullptr);
+  SetProgressRingAnimationForKey(key, nullptr);
+}
+
+void ProgressIndicatorAnimationRegistry::EraseAllAnimationsForKeyIf(
+    base::RepeatingCallback<bool(const void* key)> predicate) {
+  std::set<const void*> keys_to_erase;
+  for (const auto& icon_animation_by_key : icon_animations_by_key_) {
+    const void* key = icon_animation_by_key.first;
+    if (predicate.Run(key))
+      keys_to_erase.insert(key);
+  }
+  for (const auto& ring_animation_by_key : ring_animations_by_key_) {
+    const void* key = ring_animation_by_key.first;
+    if (predicate.Run(key))
+      keys_to_erase.insert(key);
+  }
+  for (const void* key : keys_to_erase)
+    EraseAllAnimationsForKey(key);
+}
+
 }  // namespace ash
diff --git a/ash/system/progress_indicator/progress_indicator_animation_registry.h b/ash/system/progress_indicator/progress_indicator_animation_registry.h
index 4302502e..138935ca 100644
--- a/ash/system/progress_indicator/progress_indicator_animation_registry.h
+++ b/ash/system/progress_indicator/progress_indicator_animation_registry.h
@@ -8,6 +8,7 @@
 #include <map>
 #include <memory>
 
+#include "ash/ash_export.h"
 #include "ash/system/holding_space/holding_space_progress_icon_animation.h"
 #include "ash/system/holding_space/holding_space_progress_ring_animation.h"
 #include "base/callback_forward.h"
@@ -30,7 +31,7 @@
 //     for a progress indicator's outer ring, as opposed to progress icon
 //     animations which independently drive the animation of properties for a
 //     progress indicator's inner icon.
-class ProgressIndicatorAnimationRegistry {
+class ASH_EXPORT ProgressIndicatorAnimationRegistry {
  public:
   ProgressIndicatorAnimationRegistry();
   ProgressIndicatorAnimationRegistry(
@@ -46,10 +47,9 @@
   // icon animation associated with the specified `key`. The `callback` will
   // continue to receive events so long as both `this` and the returned
   // subscription exist.
-  virtual base::CallbackListSubscription
-  AddProgressIconAnimationChangedCallbackForKey(
+  base::CallbackListSubscription AddProgressIconAnimationChangedCallbackForKey(
       const void* key,
-      ProgressIconAnimationChangedCallbackList::CallbackType callback) = 0;
+      ProgressIconAnimationChangedCallbackList::CallbackType callback);
 
   using ProgressRingAnimationChangedCallbackList =
       base::RepeatingCallbackList<void(HoldingSpaceProgressRingAnimation*)>;
@@ -58,20 +58,42 @@
   // ring animation associated with the specified `key`. The `callback` will
   // continue to receive events so long as both `this` and the returned
   // subscription exist.
-  virtual base::CallbackListSubscription
-  AddProgressRingAnimationChangedCallbackForKey(
+  base::CallbackListSubscription AddProgressRingAnimationChangedCallbackForKey(
       const void* key,
-      ProgressRingAnimationChangedCallbackList::CallbackType callback) = 0;
+      ProgressRingAnimationChangedCallbackList::CallbackType callback);
 
   // Returns the progress icon animation registered for the specified `key`.
   // NOTE: This may return `nullptr` if no such animation is registered.
-  virtual HoldingSpaceProgressIconAnimation* GetProgressIconAnimationForKey(
-      const void* key) = 0;
+  HoldingSpaceProgressIconAnimation* GetProgressIconAnimationForKey(
+      const void* key);
 
   // Returns the progress ring animation registered for the specified `key`.
   // NOTE: This may return `nullptr` if no such animation is registered.
-  virtual HoldingSpaceProgressRingAnimation* GetProgressRingAnimationForKey(
-      const void* key) = 0;
+  HoldingSpaceProgressRingAnimation* GetProgressRingAnimationForKey(
+      const void* key);
+
+  // Sets and returns the progress icon animation registered for the specified
+  // `key`. NOTE: `animation` may be `nullptr` to unregister `key`.
+  HoldingSpaceProgressIconAnimation* SetProgressIconAnimationForKey(
+      const void* key,
+      std::unique_ptr<HoldingSpaceProgressIconAnimation> animation);
+
+  // Sets and returns the progress ring animation registered for the specified
+  // `key`. NOTE: `animation` may be `nullptr` to unregister `key`.
+  HoldingSpaceProgressRingAnimation* SetProgressRingAnimationForKey(
+      const void* key,
+      std::unique_ptr<HoldingSpaceProgressRingAnimation> animation);
+
+  // Erases all animations for all keys.
+  void EraseAllAnimations();
+
+  // Erases all animations for the specified `key`.
+  void EraseAllAnimationsForKey(const void* key);
+
+  // Erases all animations for all keys for which the specified `predicate`
+  // returns `true`.
+  void EraseAllAnimationsForKeyIf(
+      base::RepeatingCallback<bool(const void* key)> predicate);
 
   // TODO(dmblack): Move to private after completing refactor of
   // `ProgressIndicatorAnimationRegistry` and `HoldingSpaceAnimationRegistry`.
diff --git a/ash/system/progress_indicator/progress_indicator_animation_registry_unittest.cc b/ash/system/progress_indicator/progress_indicator_animation_registry_unittest.cc
new file mode 100644
index 0000000..2c3c0239
--- /dev/null
+++ b/ash/system/progress_indicator/progress_indicator_animation_registry_unittest.cc
@@ -0,0 +1,243 @@
+// Copyright 2022 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 "ash/system/progress_indicator/progress_indicator_animation_registry.h"
+
+#include <vector>
+
+#include "ash/constants/ash_features.h"
+#include "ash/system/holding_space/holding_space_progress_icon_animation.h"
+#include "ash/system/holding_space/holding_space_progress_indicator_animation.h"
+#include "ash/system/holding_space/holding_space_progress_ring_animation.h"
+#include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ash {
+namespace {
+
+// ProgressIndicatorAnimationRegistryTest --------------------------------------
+
+// Base class for tests of the `ProgressIndicatorAnimationRegistry`
+// parameterized by whether animation v2 is enabled.
+class ProgressIndicatorAnimationRegistryTest
+    : public testing::Test,
+      public testing::WithParamInterface<
+          /*animation_v2_enabled=*/bool> {
+ public:
+  ProgressIndicatorAnimationRegistryTest() {
+    scoped_feature_list_.InitWithFeatureState(
+        features::kHoldingSpaceInProgressAnimationV2, IsAnimationV2Enabled());
+  }
+
+  // Returns whether animation v2 is enabled given test parameterization.
+  bool IsAnimationV2Enabled() const { return GetParam(); }
+
+  // Returns the `registry_` under test.
+  ProgressIndicatorAnimationRegistry* registry() { return &registry_; }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  ProgressIndicatorAnimationRegistry registry_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         ProgressIndicatorAnimationRegistryTest,
+                         /*in_progress_animation_v2_enabled=*/testing::Bool());
+
+}  // namespace
+
+// Tests -----------------------------------------------------------------------
+
+TEST_P(ProgressIndicatorAnimationRegistryTest, EraseAllAnimations) {
+  // Create `master_keys` for progress animations which may be referenced from
+  // each test case.
+  std::vector<size_t> master_keys = {1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u};
+
+  // A test case is defined by:
+  // * keys for which to add progress animations,
+  // * a callback to invoke to erase progress animations,
+  // * keys for which to expect progress animations after erase invocation.
+  struct TestCase {
+    std::vector<size_t*> keys;
+    base::OnceClosure erase_callback;
+    std::vector<size_t*> keys_with_animations_after_erase_callback;
+  };
+
+  std::vector<TestCase> test_cases;
+
+  // Test case: Invoke `EraseAllAnimations()`.
+  test_cases.push_back(
+      TestCase{.keys = {&master_keys[0], &master_keys[1], &master_keys[2]},
+               .erase_callback = base::BindOnce(
+                   &ProgressIndicatorAnimationRegistry::EraseAllAnimations,
+                   base::Unretained(registry())),
+               .keys_with_animations_after_erase_callback = {}});
+
+  // Test case: Invoke `EraseAllAnimationsForKey()`.
+  test_cases.push_back(TestCase{
+      .keys = {&master_keys[3], &master_keys[4], &master_keys[5]},
+      .erase_callback = base::BindOnce(
+          &ProgressIndicatorAnimationRegistry::EraseAllAnimationsForKey,
+          base::Unretained(registry()), base::Unretained(&master_keys[4])),
+      .keys_with_animations_after_erase_callback = {&master_keys[3],
+                                                    &master_keys[5]}});
+
+  // Test case: Invoke `EraseAllAnimationsForKeyIf()`.
+  test_cases.push_back(TestCase{
+      .keys = {&master_keys[6], &master_keys[7], &master_keys[8]},
+      .erase_callback = base::BindOnce(
+          &ProgressIndicatorAnimationRegistry::EraseAllAnimationsForKeyIf,
+          base::Unretained(registry()),
+          base::BindRepeating(
+              [](const void* key, const void* candidate_key) {
+                return candidate_key != key;
+              },
+              base::Unretained(&master_keys[7]))),
+      .keys_with_animations_after_erase_callback = {&master_keys[7]}});
+
+  // Iterate over `test_cases`.
+  for (auto& test_case : test_cases) {
+    const auto& keys = test_case.keys;
+
+    // Track number of animation changed events.
+    std::vector<base::CallbackListSubscription> subscriptions;
+    size_t icon_callback_call_count = 0u;
+    size_t ring_callback_call_count = 0u;
+
+    // Iterate over `keys`.
+    for (auto it = keys.begin(); it != keys.end(); ++it) {
+      const auto* key = *it;
+      const size_t index = std::distance(keys.begin(), it);
+
+      // Verify no progress animations are set for `key`.
+      EXPECT_FALSE(registry()->GetProgressIconAnimationForKey(key));
+      EXPECT_FALSE(registry()->GetProgressRingAnimationForKey(key));
+
+      // Count progress icon animation changed events for `key`.
+      subscriptions.push_back(
+          registry()->AddProgressIconAnimationChangedCallbackForKey(
+              key, base::BindLambdaForTesting(
+                       [&](HoldingSpaceProgressIconAnimation*) {
+                         ++icon_callback_call_count;
+                       })));
+
+      // Count progress ring animation changed events for `key`.
+      subscriptions.push_back(
+          registry()->AddProgressRingAnimationChangedCallbackForKey(
+              key, base::BindLambdaForTesting(
+                       [&](HoldingSpaceProgressRingAnimation*) {
+                         ++ring_callback_call_count;
+                       })));
+
+      // Create a progress icon animation for `key`.
+      registry()->SetProgressIconAnimationForKey(
+          key, std::make_unique<HoldingSpaceProgressIconAnimation>());
+      EXPECT_TRUE(registry()->GetProgressIconAnimationForKey(key));
+      EXPECT_EQ(icon_callback_call_count, index + 1u);
+
+      // Create a progress ring animation for `key`.
+      registry()->SetProgressRingAnimationForKey(
+          key, HoldingSpaceProgressRingAnimation::CreateOfType(
+                   HoldingSpaceProgressRingAnimation::Type::kPulse));
+      EXPECT_TRUE(registry()->GetProgressRingAnimationForKey(key));
+      EXPECT_EQ(ring_callback_call_count, index + 1u);
+    }
+
+    // Reset animation changed event counts.
+    icon_callback_call_count = 0u;
+    ring_callback_call_count = 0u;
+
+    // Erase animations.
+    std::move(test_case.erase_callback).Run();
+    EXPECT_EQ(icon_callback_call_count,
+              keys.size() -
+                  test_case.keys_with_animations_after_erase_callback.size());
+    EXPECT_EQ(ring_callback_call_count,
+              keys.size() -
+                  test_case.keys_with_animations_after_erase_callback.size());
+
+    // Iterate over `keys`.
+    for (const auto* key : keys) {
+      const bool expected = base::Contains(
+          test_case.keys_with_animations_after_erase_callback, key);
+
+      // Verify progress animations are set for `key` only if `expected`.
+      EXPECT_EQ(!!registry()->GetProgressIconAnimationForKey(key), expected);
+      EXPECT_EQ(!!registry()->GetProgressRingAnimationForKey(key), expected);
+    }
+  }
+}
+
+TEST_P(ProgressIndicatorAnimationRegistryTest, SetProgressIconAnimationForKey) {
+  // Create `key` and verify no progress icon animation is set.
+  size_t key = 0u;
+  EXPECT_FALSE(registry()->GetProgressIconAnimationForKey(&key));
+
+  // Count progress icon animation changed events.
+  size_t callback_call_count = 0u;
+  auto subscription = registry()->AddProgressIconAnimationChangedCallbackForKey(
+      &key, base::BindLambdaForTesting([&](HoldingSpaceProgressIconAnimation*) {
+        ++callback_call_count;
+      }));
+
+  // Unset progress icon animation for `key`.
+  EXPECT_FALSE(registry()->SetProgressIconAnimationForKey(&key, nullptr));
+  EXPECT_FALSE(registry()->GetProgressIconAnimationForKey(&key));
+  EXPECT_EQ(callback_call_count, 0u);
+
+  // Create a progress icon `animation`.
+  auto animation = std::make_unique<HoldingSpaceProgressIconAnimation>();
+  auto* animation_ptr = animation.get();
+
+  // Set progress icon `animation` for `key`.
+  EXPECT_EQ(
+      registry()->SetProgressIconAnimationForKey(&key, std::move(animation)),
+      animation_ptr);
+  EXPECT_EQ(registry()->GetProgressIconAnimationForKey(&key), animation_ptr);
+  EXPECT_EQ(callback_call_count, 1u);
+
+  // Unset progress icon animation for `key`.
+  EXPECT_FALSE(registry()->SetProgressIconAnimationForKey(&key, nullptr));
+  EXPECT_FALSE(registry()->GetProgressIconAnimationForKey(&key));
+  EXPECT_EQ(callback_call_count, 2u);
+}
+
+TEST_P(ProgressIndicatorAnimationRegistryTest, SetProgressRingAnimationForKey) {
+  // Create `key` and verify no progress ring animation is set.
+  size_t key = 0u;
+  EXPECT_FALSE(registry()->GetProgressRingAnimationForKey(&key));
+
+  // Count progress ring animation changed events.
+  size_t callback_call_count = 0u;
+  auto subscription = registry()->AddProgressRingAnimationChangedCallbackForKey(
+      &key, base::BindLambdaForTesting([&](HoldingSpaceProgressRingAnimation*) {
+        ++callback_call_count;
+      }));
+
+  // Unset progress ring animation for `key`.
+  EXPECT_FALSE(registry()->SetProgressRingAnimationForKey(&key, nullptr));
+  EXPECT_FALSE(registry()->GetProgressRingAnimationForKey(&key));
+  EXPECT_EQ(callback_call_count, 0u);
+
+  // Create a progress ring `animation`.
+  auto animation = HoldingSpaceProgressRingAnimation::CreateOfType(
+      HoldingSpaceProgressRingAnimation::Type::kPulse);
+  auto* animation_ptr = animation.get();
+
+  // Set progress ring `animation` for `key`.
+  EXPECT_EQ(
+      registry()->SetProgressRingAnimationForKey(&key, std::move(animation)),
+      animation_ptr);
+  EXPECT_EQ(registry()->GetProgressRingAnimationForKey(&key), animation_ptr);
+  EXPECT_EQ(callback_call_count, 1u);
+
+  // Unset progress ring animation for `key`.
+  EXPECT_FALSE(registry()->SetProgressRingAnimationForKey(&key, nullptr));
+  EXPECT_FALSE(registry()->GetProgressRingAnimationForKey(&key));
+  EXPECT_EQ(callback_call_count, 2u);
+}
+
+}  // namespace ash
diff --git a/ash/system/time/calendar_month_view.cc b/ash/system/time/calendar_month_view.cc
index 87049d9..b4ff8450f 100644
--- a/ash/system/time/calendar_month_view.cc
+++ b/ash/system/time/calendar_month_view.cc
@@ -40,6 +40,9 @@
 // present for that day.
 constexpr float kEventsPresentRoundedRadius = 2.f;
 
+// The gap padding between the date and the indicator.
+constexpr int kGapBetweenDateAndIndicator = 1;
+
 // The padding of the focus circle.
 constexpr int kFocusCirclePadding = 4;
 
@@ -229,8 +232,8 @@
   const gfx::Rect content = GetContentsBounds();
   return gfx::Point(
       (content.width() + calendar_utils::kDateHorizontalPadding * 2) / 2,
-      (content.height() + calendar_utils::kDateVerticalPadding * 2) / 2 +
-          calendar_utils::kDateVerticalPadding);
+      content.height() + calendar_utils::kDateVerticalPadding +
+          kGapBetweenDateAndIndicator);
 }
 
 void CalendarDateCellView::MaybeDrawEventsIndicator(gfx::Canvas* canvas) {
diff --git a/ash/system/time/calendar_view.cc b/ash/system/time/calendar_view.cc
index 90daf62..388d1f7 100644
--- a/ash/system/time/calendar_view.cc
+++ b/ash/system/time/calendar_view.cc
@@ -61,6 +61,10 @@
 constexpr base::TimeDelta kDelayVisibilityAnimationDuration =
     base::Milliseconds(200);
 
+// Duration of events moving animation.
+constexpr base::TimeDelta kAnimationDurationForEventsMoving =
+    base::Milliseconds(400);
+
 // The cool-down time for enabling animation.
 constexpr base::TimeDelta kAnimationDisablingTimeout = base::Milliseconds(500);
 
@@ -686,17 +690,6 @@
   scroll_view_->SetVerticalScrollBarMode(
       views::ScrollView::ScrollBarMode::kHiddenButEnabled);
 
-  if (!calendar_view_controller_->IsSelectedDateInCurrentMonth())
-    ScrollDownOneMonth();
-  base::AutoReset<bool> is_resetting_scrolling(&is_resetting_scroll_, true);
-  scroll_view_->ScrollToPosition(scroll_view_->vertical_scroll_bar(),
-                                 PositionOfSelectedDate());
-
-  scroll_view_->ClipHeightTo(0, kExpandedCalendarViewHeightScale *
-                                    calendar_view_controller_->row_height());
-  scroll_view_->SetVerticalScrollBarMode(
-      views::ScrollView::ScrollBarMode::kDisabled);
-
   // The event list is in a container, which will be used for escaping the
   // focusing from the date cells.
   event_list_container_ = AddChildView(std::make_unique<views::View>());
@@ -711,7 +704,75 @@
   event_list_->GetViewAccessibility().OverrideName(GetClassName());
   event_list_->GetViewAccessibility().OverrideRole(ax::mojom::Role::kGroup);
   event_list_->SetFocusBehavior(FocusBehavior::ALWAYS);
-  calendar_view_controller_->OnEventListOpened();
+
+  event_list_->SetBounds(
+      scroll_view_->GetVisibleRect().x(),
+      scroll_view_->GetVisibleRect().bottom(),
+      scroll_view_->GetVisibleRect().width(),
+      calendar_view_controller_->expanded_area_available_height());
+
+  if (!should_months_animate_) {
+    OnOpenEventListAnimationComplete();
+    return;
+  }
+
+  set_should_months_animate(false);
+  gfx::Vector2dF moving_up_location = gfx::Vector2dF(
+      0, -PositionOfSelectedDate() + scroll_view_->GetVisibleRect().y());
+
+  gfx::Transform current_month_moving = gfx::TransformAboutPivot(
+      current_month_->GetLocalBounds().CenterPoint(), gfx::Transform());
+  current_month_moving.Translate(moving_up_location);
+
+  gfx::Transform current_label_moving = gfx::TransformAboutPivot(
+      current_label_->GetLocalBounds().CenterPoint(), gfx::Transform());
+  current_label_moving.Translate(moving_up_location);
+
+  gfx::Transform next_label_moving = gfx::TransformAboutPivot(
+      next_label_->GetLocalBounds().CenterPoint(), gfx::Transform());
+  next_label_moving.Translate(moving_up_location);
+
+  gfx::Transform next_month_moving = gfx::TransformAboutPivot(
+      next_month_->GetLocalBounds().CenterPoint(), gfx::Transform());
+  next_month_moving.Translate(moving_up_location);
+
+  gfx::Transform list_view_moving = gfx::TransformAboutPivot(
+      event_list_->GetBoundsInScreen().CenterPoint(), gfx::Transform());
+  list_view_moving.Translate(gfx::Vector2dF(
+      0, -event_list_->GetBoundsInScreen().y() +
+             scroll_view_->GetBoundsInScreen().bottom() -
+             calendar_view_controller_->expanded_area_available_height()));
+
+  views::AnimationBuilder()
+      .SetPreemptionStrategy(
+          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET)
+      .OnEnded(base::BindOnce(
+          [](base::WeakPtr<CalendarView> calendar_view) {
+            if (!calendar_view)
+              return;
+            calendar_view->OnOpenEventListAnimationComplete();
+          },
+          weak_factory_.GetWeakPtr()))
+      .OnAborted(base::BindOnce(
+          [](base::WeakPtr<CalendarView> calendar_view) {
+            if (!calendar_view)
+              return;
+            calendar_view->OnOpenEventListAnimationComplete();
+          },
+          weak_factory_.GetWeakPtr()))
+      .Once()
+      .SetTransform(current_month_, std::move(current_month_moving),
+                    gfx::Tween::EASE_OUT_2)
+      .SetTransform(current_label_, std::move(current_label_moving),
+                    gfx::Tween::EASE_OUT_2)
+      .SetTransform(next_label_, std::move(next_label_moving),
+                    gfx::Tween::EASE_OUT_2)
+      .SetTransform(next_month_, std::move(next_month_moving),
+                    gfx::Tween::EASE_OUT_2)
+      .At(base::Milliseconds(0))
+      .SetDuration(kAnimationDurationForEventsMoving)
+      .SetTransform(event_list_, std::move(list_view_moving),
+                    gfx::Tween::EASE_OUT_2);
 }
 
 void CalendarView::CloseEventList() {
@@ -1154,6 +1215,25 @@
                  bounds.width(), bounds.height()));
 }
 
+void CalendarView::OnOpenEventListAnimationComplete() {
+  // Scrolls to the next month if the selected date is in the `next_month_`, so
+  // that the `current_month_`is updated to the next month.
+  if (!calendar_view_controller_->IsSelectedDateInCurrentMonth())
+    ScrollDownOneMonth();
+  base::AutoReset<bool> is_resetting_scrolling(&is_resetting_scroll_, true);
+  RestoreMonthStatus();
+  scroll_view_->ScrollToPosition(scroll_view_->vertical_scroll_bar(),
+                                 PositionOfSelectedDate());
+  scroll_view_->ClipHeightTo(0, kExpandedCalendarViewHeightScale *
+                                    calendar_view_controller_->row_height());
+  event_list_->SetTransform(gfx::Transform());
+  if (!should_months_animate_)
+    months_animation_restart_timer_.Reset();
+  scroll_view_->SetVerticalScrollBarMode(
+      views::ScrollView::ScrollBarMode::kDisabled);
+  calendar_view_controller_->OnEventListOpened();
+}
+
 BEGIN_METADATA(CalendarView, views::View)
 END_METADATA
 
diff --git a/ash/system/time/calendar_view.h b/ash/system/time/calendar_view.h
index 1e22aced..a8fb7d7 100644
--- a/ash/system/time/calendar_view.h
+++ b/ash/system/time/calendar_view.h
@@ -180,6 +180,11 @@
   // Adjusts the Chrome Vox box position for date cells in the scroll view.
   void AdjustDateCellVoxBounds();
 
+  // Handles the position and status of `event_list_` and other views after the
+  // opening event list animation. Such as restoring the position of them,
+  // re-enabling animation and etc.
+  void OnOpenEventListAnimationComplete();
+
   // Unowned.
   UnifiedSystemTrayController* controller_;
 
diff --git a/ash/webui/BUILD.gn b/ash/webui/BUILD.gn
index 70f331d3..fb5aade0 100644
--- a/ash/webui/BUILD.gn
+++ b/ash/webui/BUILD.gn
@@ -65,6 +65,7 @@
     "//ash/webui/firmware_update_ui:closure_compile",
     "//ash/webui/help_app_ui:closure_compile",
     "//ash/webui/media_app_ui:closure_compile",
+    "//ash/webui/multidevice_debug/resources:closure_compile",
     "//ash/webui/os_feedback_ui:closure_compile",
     "//ash/webui/print_management:closure_compile",
     "//ash/webui/projector_app/resources:closure_compile",
diff --git a/ash/webui/camera_app_ui/resources/js/device/mode/square.ts b/ash/webui/camera_app_ui/resources/js/device/mode/square.ts
index 821f413..d935aa3 100644
--- a/ash/webui/camera_app_ui/resources/js/device/mode/square.ts
+++ b/ash/webui/camera_app_ui/resources/js/device/mode/square.ts
@@ -29,11 +29,9 @@
     ctx.drawImage(
         img, Math.floor((img.width - side) / 2),
         Math.floor((img.height - side) / 2), side, side, 0, 0, side, side);
-    const croppedBlob = await new Promise<Blob>((resolve) => {
-      // TODO(b/174190121): Patch important exif entries from input blob to
-      // result blob.
-      canvas.toBlob(resolve, 'image/jpeg');
-    });
+    // TODO(b/174190121): Patch important exif entries from input blob to
+    // result blob.
+    const croppedBlob = await util.canvasToJpegBlob(canvas);
     return croppedBlob;
   } finally {
     URL.revokeObjectURL(img.src);
diff --git a/ash/webui/camera_app_ui/resources/js/device/preview.ts b/ash/webui/camera_app_ui/resources/js/device/preview.ts
index e61b1eb..9e39ad0 100644
--- a/ash/webui/camera_app_ui/resources/js/device/preview.ts
+++ b/ash/webui/camera_app_ui/resources/js/device/preview.ts
@@ -394,15 +394,7 @@
     const {canvas, ctx} = util.newDrawingCanvas(
         {width: this.video.videoWidth, height: this.video.videoHeight});
     ctx.drawImage(this.video, 0, 0);
-    return new Promise((resolve, reject) => {
-      canvas.toBlob((blob) => {
-        if (blob) {
-          resolve(blob);
-        } else {
-          reject(new Error('Photo blob error.'));
-        }
-      }, 'image/jpeg');
-    });
+    return util.canvasToJpegBlob(canvas);
   }
 
   /**
diff --git a/ash/webui/camera_app_ui/resources/js/thumbnailer.ts b/ash/webui/camera_app_ui/resources/js/thumbnailer.ts
index a69f3d99..f673b09 100644
--- a/ash/webui/camera_app_ui/resources/js/thumbnailer.ts
+++ b/ash/webui/camera_app_ui/resources/js/thumbnailer.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {assert, assertInstanceof} from './assert.js';
+import {assertInstanceof} from './assert.js';
 import {
   EmptyThumbnailError,
   LoadError,
@@ -10,7 +10,7 @@
   PlayError,
   PlayMalformedError,
 } from './type.js';
-import {newDrawingCanvas} from './util.js';
+import {canvasToJpegBlob, newDrawingCanvas} from './util.js';
 import {WaitableEvent} from './waitable_event.js';
 
 /**
@@ -33,12 +33,7 @@
     throw new EmptyThumbnailError();
   }
 
-  return new Promise((resolve) => {
-    canvas.toBlob((blob) => {
-      assert(blob !== null);
-      resolve(blob);
-    }, 'image/jpeg');
-  });
+  return canvasToJpegBlob(canvas);
 }
 
 /**
diff --git a/ash/webui/camera_app_ui/resources/js/util.ts b/ash/webui/camera_app_ui/resources/js/util.ts
index 06ff1b1..d50996c 100644
--- a/ash/webui/camera_app_ui/resources/js/util.ts
+++ b/ash/webui/camera_app_ui/resources/js/util.ts
@@ -29,19 +29,23 @@
   return {canvas, ctx};
 }
 
+export function canvasToJpegBlob(canvas: HTMLCanvasElement): Promise<Blob> {
+  return new Promise((resolve, reject) => {
+    canvas.toBlob((blob) => {
+      if (blob !== null) {
+        resolve(blob);
+      } else {
+        reject(new Error('Failed to convert canvas to jpeg blob.'));
+      }
+    }, 'image/jpeg');
+  });
+}
+
 export function bitmapToJpegBlob(bitmap: ImageBitmap): Promise<Blob> {
   const {canvas, ctx} =
       newDrawingCanvas({width: bitmap.width, height: bitmap.height});
   ctx.drawImage(bitmap, 0, 0);
-  return new Promise((resolve, reject) => {
-    canvas.toBlob((blob) => {
-      if (blob) {
-        resolve(blob);
-      } else {
-        reject(new Error('Photo blob error.'));
-      }
-    }, 'image/jpeg');
-  });
+  return canvasToJpegBlob(canvas);
 }
 
 /**
diff --git a/ash/webui/diagnostics_ui/backend/BUILD.gn b/ash/webui/diagnostics_ui/backend/BUILD.gn
index 99abf73..6527b935 100644
--- a/ash/webui/diagnostics_ui/backend/BUILD.gn
+++ b/ash/webui/diagnostics_ui/backend/BUILD.gn
@@ -73,6 +73,7 @@
     "//ui/events/ozone/layout",
     "//ui/gfx",
     "//ui/shell_dialogs",
+    "//ui/web_dialogs",
     "//ui/webui",
   ]
 }
@@ -130,6 +131,7 @@
     "//ui/events/ozone/evdev:event_device_info_test_utils",
     "//ui/gfx",
     "//ui/shell_dialogs",
+    "//ui/views:test_support",
     "//ui/webui",
   ]
 }
diff --git a/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc b/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc
index 35a4bec7..69d986f 100644
--- a/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc
+++ b/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc
@@ -4,6 +4,7 @@
 
 #include "ash/webui/diagnostics_ui/backend/diagnostics_manager.h"
 
+#include <ui/aura/window.h>
 #include "ash/constants/ash_features.h"
 #include "ash/webui/diagnostics_ui/backend/input_data_provider.h"
 #include "ash/webui/diagnostics_ui/backend/network_health_provider.h"
@@ -14,19 +15,17 @@
 namespace ash {
 namespace diagnostics {
 
-DiagnosticsManager::DiagnosticsManager(SessionLogHandler* session_log_handler)
+DiagnosticsManager::DiagnosticsManager(SessionLogHandler* session_log_handler,
+                                       content::WebUI* webui)
     : system_data_provider_(std::make_unique<SystemDataProvider>(
           session_log_handler->GetTelemetryLog())),
       system_routine_controller_(std::make_unique<SystemRoutineController>(
-          session_log_handler->GetRoutineLog())) {
+          session_log_handler->GetRoutineLog())),
+      webui_(webui) {
   if (features::IsNetworkingInDiagnosticsAppEnabled()) {
     network_health_provider_ = std::make_unique<NetworkHealthProvider>(
         session_log_handler->GetNetworkingLog());
   }
-
-  if (features::IsInputInDiagnosticsAppEnabled()) {
-    input_data_provider_ = std::make_unique<InputDataProvider>();
-  }
 }
 
 DiagnosticsManager::~DiagnosticsManager() = default;
@@ -45,7 +44,14 @@
   return system_routine_controller_.get();
 }
 
-InputDataProvider* DiagnosticsManager::GetInputDataProvider() const {
+InputDataProvider* DiagnosticsManager::GetInputDataProvider() {
+  // Do not construct the InputDataProvider until it is requested;
+  // performing this in the constructor is too early, and the native
+  // window will not be available.
+  if (features::IsInputInDiagnosticsAppEnabled() && !input_data_provider_) {
+    input_data_provider_ = std::make_unique<InputDataProvider>(
+        webui_->GetWebContents()->GetTopLevelNativeWindow());
+  }
   return input_data_provider_.get();
 }
 
diff --git a/ash/webui/diagnostics_ui/backend/diagnostics_manager.h b/ash/webui/diagnostics_ui/backend/diagnostics_manager.h
index ca7805e..fe39d57 100644
--- a/ash/webui/diagnostics_ui/backend/diagnostics_manager.h
+++ b/ash/webui/diagnostics_ui/backend/diagnostics_manager.h
@@ -7,6 +7,8 @@
 
 #include <memory>
 
+#include "ui/web_dialogs/web_dialog_ui.h"
+
 namespace ash {
 namespace diagnostics {
 
@@ -20,7 +22,8 @@
 // used by the Diagnostics SWA.
 class DiagnosticsManager {
  public:
-  explicit DiagnosticsManager(SessionLogHandler* session_log_handler);
+  DiagnosticsManager(SessionLogHandler* session_log_handler,
+                     content::WebUI* webui);
   ~DiagnosticsManager();
 
   DiagnosticsManager(const DiagnosticsManager&) = delete;
@@ -29,13 +32,14 @@
   NetworkHealthProvider* GetNetworkHealthProvider() const;
   SystemDataProvider* GetSystemDataProvider() const;
   SystemRoutineController* GetSystemRoutineController() const;
-  InputDataProvider* GetInputDataProvider() const;
+  InputDataProvider* GetInputDataProvider();
 
  private:
   std::unique_ptr<NetworkHealthProvider> network_health_provider_;
   std::unique_ptr<SystemDataProvider> system_data_provider_;
   std::unique_ptr<SystemRoutineController> system_routine_controller_;
   std::unique_ptr<InputDataProvider> input_data_provider_;
+  content::WebUI* webui_;
 };
 
 }  // namespace diagnostics
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider.cc b/ash/webui/diagnostics_ui/backend/input_data_provider.cc
index 7dfe99c1..f425a30 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider.cc
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider.cc
@@ -8,23 +8,16 @@
 #include <linux/input.h>
 #include <vector>
 
-#include "ash/constants/ash_switches.h"
-#include "base/command_line.h"
-#include "base/files/scoped_file.h"
 #include "base/logging.h"
+#include "base/message_loop/message_pump_for_ui.h"
 #include "base/ranges/algorithm.h"
 #include "base/run_loop.h"
-#include "base/strings/strcat.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "chromeos/system/statistics_provider.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/current_thread.h"
 #include "ui/base/ime/ash/input_method_manager.h"
 #include "ui/events/devices/device_util_linux.h"
 #include "ui/events/devices/input_device.h"
-#include "ui/events/event_constants.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
-#include "ui/events/ozone/evdev/event_device_info.h"
 
 namespace ash {
 namespace diagnostics {
@@ -49,8 +42,166 @@
            !device_info->event_device_info.HasStylus()));
 }
 
+const int kKeyReleaseValue = 0;
+
 }  // namespace
 
+// Class for dispatching relevant events from evdev to the input_data_provider.
+// While it would be nice to re-use EventConverterEvdevImpl for this purpose,
+// it has a lot of connections (ui::Cursor, full ui::DeviceEventDispatcherEvdev
+// interface) that take more room to stub out rather than just implementing
+// another evdev FdWatcher from scratch.
+class InputDataEventWatcherImpl : public InputDataEventWatcher,
+                                  base::MessagePumpForUI::FdWatcher {
+ public:
+  InputDataEventWatcherImpl(
+      uint32_t id,
+      base::WeakPtr<InputDataEventWatcher::Dispatcher> dispatcher);
+  ~InputDataEventWatcherImpl() override;
+  void ConvertKeyEvent(uint32_t key_code,
+                       uint32_t key_state,
+                       uint32_t scan_code);
+  void ProcessEvent(const input_event& input);
+  void Start();
+  void Stop();
+
+ protected:
+  // base::MessagePumpForUI::FdWatcher:
+  void OnFileCanReadWithoutBlocking(int fd) override;
+  void OnFileCanWriteWithoutBlocking(int fd) override;
+
+  // Device id
+  const uint32_t id_;
+
+  // Path to input device.
+  const base::FilePath path_;
+
+  // File descriptor to read.
+  const int fd_;
+
+  // Scoped auto-closer for FD.
+  const base::ScopedFD input_device_fd_;
+
+  // Whether we're polling for input on the device.
+  bool watching_ = false;
+
+  // EV_ information pending for SYN_REPORT to dispatch.
+  uint32_t pending_scan_code_;
+  uint32_t pending_key_code_;
+  uint32_t pending_key_state_;
+
+  base::WeakPtr<InputDataEventWatcher::Dispatcher> dispatcher_;
+
+  // Controller for watching the input fd.
+  base::MessagePumpForUI::FdWatchController controller_;
+};
+
+class InputDataEventWatcherFactoryImpl : public InputDataEventWatcher::Factory {
+ public:
+  InputDataEventWatcherFactoryImpl() = default;
+  InputDataEventWatcherFactoryImpl(const InputDataEventWatcherFactoryImpl&) =
+      delete;
+  InputDataEventWatcherFactoryImpl& operator=(
+      const InputDataEventWatcherFactoryImpl&) = delete;
+  ~InputDataEventWatcherFactoryImpl() override = default;
+
+  std::unique_ptr<InputDataEventWatcher> MakeWatcher(
+      uint32_t id,
+      base::WeakPtr<InputDataEventWatcher::Dispatcher> dispatcher) override {
+    return std::make_unique<InputDataEventWatcherImpl>(id,
+                                                       std::move(dispatcher));
+  }
+};
+
+InputDataEventWatcher::~InputDataEventWatcher() = default;
+InputDataEventWatcher::Factory::~Factory() = default;
+
+InputDataEventWatcherImpl::InputDataEventWatcherImpl(
+    uint32_t id,
+    base::WeakPtr<InputDataEventWatcher::Dispatcher> dispatcher)
+    : id_(id),
+      path_(base::FilePath(base::StringPrintf("/dev/input/event%d", id_))),
+      fd_(open(path_.value().c_str(), O_RDWR | O_NONBLOCK)),
+      input_device_fd_(fd_),
+      dispatcher_(dispatcher),
+      controller_(FROM_HERE) {
+  if (fd_ == -1) {
+    PLOG(ERROR) << "Unable to open event device " << id_
+                << ", not forwarding events for input diagnostics.";
+    // Leave un-Started(), so we never enable the fd watcher.
+    return;
+  }
+
+  Start();
+}
+
+InputDataEventWatcherImpl::~InputDataEventWatcherImpl() = default;
+
+void InputDataEventWatcherImpl::Start() {
+  base::CurrentUIThread::Get()->WatchFileDescriptor(
+      fd_, true, base::MessagePumpForUI::WATCH_READ, &controller_, this);
+  watching_ = true;
+}
+
+void InputDataEventWatcherImpl::Stop() {
+  controller_.StopWatchingFileDescriptor();
+  watching_ = false;
+}
+
+void InputDataEventWatcherImpl::OnFileCanReadWithoutBlocking(int fd) {
+  while (true) {
+    input_event input;
+    ssize_t read_size = read(fd, &input, sizeof(input));
+    if (read_size != sizeof(input)) {
+      if (errno == EINTR || errno == EAGAIN)
+        return;
+      if (errno != ENODEV)
+        PLOG(ERROR) << "error reading device " << path_.value();
+      Stop();
+      return;
+    }
+
+    ProcessEvent(input);
+  }
+}
+
+void InputDataEventWatcherImpl::OnFileCanWriteWithoutBlocking(int fd) {}
+
+// Once we have an entire keypress/release, dispatch it.
+void InputDataEventWatcherImpl::ConvertKeyEvent(uint32_t key_code,
+                                                uint32_t key_state,
+                                                uint32_t scan_code) {
+  bool down = key_state != kKeyReleaseValue;
+  if (dispatcher_)
+    dispatcher_->SendInputKeyEvent(id_, key_code, scan_code, down);
+}
+
+// Process evdev event structures directly from the kernel.
+void InputDataEventWatcherImpl::ProcessEvent(const input_event& input) {
+  // Accumulate relevant data about an event until a SYN_REPORT event releases
+  // the full report. For more information, see kernel documentation for
+  // input/event-codes.rst.
+  switch (input.type) {
+    case EV_MSC:
+      if (input.code == MSC_SCAN)
+        pending_scan_code_ = input.value;
+      break;
+    case EV_KEY:
+      pending_key_code_ = input.code;
+      pending_key_state_ = input.value;
+      break;
+    case EV_SYN:
+      if (input.code == SYN_REPORT)
+        ConvertKeyEvent(pending_key_code_, pending_key_state_,
+                        pending_scan_code_);
+
+      pending_key_code_ = 0;
+      pending_key_state_ = 0;
+      pending_scan_code_ = 0;
+      break;
+  }
+}
+
 // All blockings calls for identifying hardware need to go here: both
 // EventDeviceInfo::Initialize and ui::GetInputPathInSys can block in
 // base::MakeAbsoluteFilePath.
@@ -59,14 +210,14 @@
     base::FilePath path) {
   base::ScopedFD fd(open(path.value().c_str(), O_RDWR | O_NONBLOCK));
   if (fd.get() < 0) {
-    LOG(ERROR) << "Couldn't open device path " << path;
+    PLOG(ERROR) << "Couldn't open device path " << path << ".";
     return nullptr;
   }
 
   auto info = std::make_unique<InputDeviceInformation>();
 
   if (!info->event_device_info.Initialize(fd.get(), path)) {
-    LOG(ERROR) << "Failed to get device info for " << path;
+    LOG(ERROR) << "Failed to get device info for " << path << ".";
     return nullptr;
   }
 
@@ -91,19 +242,24 @@
   return info;
 }
 
-InputDataProvider::InputDataProvider()
-    : device_manager_(ui::CreateDeviceManager()) {
-  Initialize();
+InputDataProvider::InputDataProvider(aura::Window* window)
+    : device_manager_(ui::CreateDeviceManager()),
+      watcher_factory_(std::make_unique<InputDataEventWatcherFactoryImpl>()) {
+  Initialize(window);
 }
 
 InputDataProvider::InputDataProvider(
-    std::unique_ptr<ui::DeviceManager> device_manager_for_test)
-    : device_manager_(std::move(device_manager_for_test)) {
-  Initialize();
+    aura::Window* window,
+    std::unique_ptr<ui::DeviceManager> device_manager_for_test,
+    std::unique_ptr<InputDataEventWatcher::Factory> watcher_factory)
+    : device_manager_(std::move(device_manager_for_test)),
+      watcher_factory_(std::move(watcher_factory)) {
+  Initialize(window);
 }
 
 InputDataProvider::~InputDataProvider() {
   device_manager_->RemoveObserver(this);
+  widget_->RemoveObserver(this);
 }
 
 // static
@@ -121,9 +277,15 @@
   }
 }
 
-void InputDataProvider::Initialize() {
+void InputDataProvider::Initialize(aura::Window* window) {
+  // Window and widget are needed for security enforcement.
+  CHECK(window);
+  widget_ = views::Widget::GetWidgetForNativeWindow(window);
+  CHECK(widget_);
   device_manager_->AddObserver(this);
   device_manager_->ScanDevices(this);
+  widget_->AddObserver(this);
+  UpdateMaySendEvents();
 }
 
 void InputDataProvider::BindInterface(
@@ -174,12 +336,135 @@
     GetKeyboardVisualLayoutCallback callback) {
   if (!keyboards_.contains(id)) {
     LOG(ERROR) << "Couldn't find keyboard with ID " << id
-               << "when retrieving visual layout.";
+               << " when retrieving visual layout.";
     return;
   }
 
-  keyboard_helper_.GetKeyboardVisualLayout(keyboards_[id]->Clone(),
-                                           std::move(callback));
+  keyboard_helper_.GetKeyboardVisualLayout(keyboards_[id], std::move(callback));
+}
+
+void InputDataProvider::OnWidgetVisibilityChanged(views::Widget* widget,
+                                                  bool visible) {
+  UpdateEventObservers();
+}
+
+void InputDataProvider::OnWidgetActivationChanged(views::Widget* widget,
+                                                  bool active) {
+  UpdateEventObservers();
+}
+
+void InputDataProvider::UpdateMaySendEvents() {
+  const bool widget_open = !widget_->IsClosed();
+  const bool widget_active = widget_->IsActive();
+  const bool widget_visible = widget_->IsVisible();
+
+  may_send_events_ = widget_open && widget_visible && widget_active;
+}
+
+void InputDataProvider::UpdateEventObservers() {
+  const bool previous = may_send_events_;
+  UpdateMaySendEvents();
+
+  if (previous != may_send_events_) {
+    if (!may_send_events_)
+      SendPauseEvents();
+    else
+      SendResumeEvents();
+  }
+}
+
+void InputDataProvider::ForwardKeyboardInput(uint32_t id) {
+  if (!keyboards_.contains(id)) {
+    LOG(ERROR) << "Couldn't find keyboard with ID " << id
+               << " when trying to forward input.";
+    return;
+  }
+
+  keyboard_watchers_[id] =
+      watcher_factory_->MakeWatcher(id, weak_factory_.GetWeakPtr());
+}
+
+void InputDataProvider::UnforwardKeyboardInput(uint32_t id) {
+  if (!keyboards_.contains(id)) {
+    LOG(ERROR) << "Couldn't find keyboard with ID " << id
+               << " when trying to unforward input.";
+  }
+  if (!keyboard_watchers_.erase(id)) {
+    LOG(ERROR) << "Couldn't find keyboard watcher with ID " << id
+               << " when trying to unforward input.";
+  }
+}
+
+void InputDataProvider::OnObservedKeyboardInputDisconnect(
+    uint32_t id,
+    mojo::RemoteSetElementId) {
+  if (!keyboard_observers_.contains(id)) {
+    LOG(ERROR) << "received keyboard observer disconnect for ID " << id
+               << " without observer.";
+    return;
+  }
+
+  // When the last observer has been disconnected, stop forwarding events.
+  if (keyboard_observers_[id]->empty()) {
+    UnforwardKeyboardInput(id);
+
+    // The observer RemoteSet remains empty at this point; if a new
+    // observer comes in, we will Forward it again.
+  }
+}
+
+void InputDataProvider::ObserveKeyEvents(
+    uint32_t id,
+    mojo::PendingRemote<mojom::KeyboardObserver> observer) {
+  CHECK(widget_) << "Observing Key Events for input diagnostics not allowed "
+                    "without widget to track focus.";
+
+  if (!keyboards_.contains(id)) {
+    LOG(ERROR) << "Couldn't find keyboard with ID " << id
+               << " when trying to receive input.";
+    return;
+  }
+
+  // When keyboard observer remote set is constructed, establish the disconnect
+  // handler.
+  if (!keyboard_observers_.contains(id)) {
+    keyboard_observers_[id] =
+        std::make_unique<mojo::RemoteSet<mojom::KeyboardObserver>>();
+    keyboard_observers_[id]->set_disconnect_handler(base::BindRepeating(
+        &InputDataProvider::OnObservedKeyboardInputDisconnect,
+        base::Unretained(this), id));
+  }
+
+  auto& observers = *keyboard_observers_[id];
+
+  const auto observer_id = observers.Add(std::move(observer));
+
+  // Ensure first callback is 'Paused' if we do not currently have focus
+  if (!may_send_events_)
+    observers.Get(observer_id)->OnKeyEventsPaused();
+
+  // When we are adding the first observer, start forwarding events.
+  if (observers.size() == 1)
+    ForwardKeyboardInput(id);
+}
+
+void InputDataProvider::SendPauseEvents() {
+  for (const auto& keyboard : keyboard_observers_) {
+    for (const auto& observer : *keyboard.second) {
+      observer->OnKeyEventsPaused();
+    }
+  }
+
+  // Re-arm our log message for future events.
+  logged_not_dispatching_key_events_ = false;
+}
+
+void InputDataProvider::SendResumeEvents() {
+  for (const auto& keyboard : keyboard_observers_) {
+    for (const auto& observer : *keyboard.second) {
+      observer->OnKeyEventsResumed();
+    }
+  }
 }
 
 void InputDataProvider::OnDeviceEvent(const ui::DeviceEvent& event) {
@@ -203,13 +488,21 @@
   } else {
     DCHECK(event.action_type() == ui::DeviceEvent::ActionType::REMOVE);
     if (keyboards_.contains(id)) {
+      if (keyboard_observers_.erase(id)) {
+        // Unref'ing the observers does not trigger their
+        // OnObservedKeyboardInputDisconnect handlers (which would normally
+        // clean up any watchers), so we must explicitly release the watchers
+        // here.
+        keyboard_watchers_.erase(id);
+      }
       keyboards_.erase(id);
-      for (auto& observer : connected_devices_observers_) {
+      keyboard_aux_data_.erase(id);
+      for (const auto& observer : connected_devices_observers_) {
         observer->OnKeyboardDisconnected(id);
       }
     } else if (touch_devices_.contains(id)) {
       touch_devices_.erase(id);
-      for (auto& observer : connected_devices_observers_) {
+      for (const auto& observer : connected_devices_observers_) {
         observer->OnTouchDeviceDisconnected(id);
       }
     }
@@ -237,20 +530,56 @@
   touch_devices_[device_info->evdev_id] =
       touch_helper_.ConstructTouchDevice(device_info);
 
-  for (auto& observer : connected_devices_observers_) {
+  for (const auto& observer : connected_devices_observers_) {
     observer->OnTouchDeviceConnected(
         touch_devices_[device_info->evdev_id]->Clone());
   }
 }
 
 void InputDataProvider::AddKeyboard(const InputDeviceInformation* device_info) {
-  keyboards_[device_info->evdev_id] =
-      keyboard_helper_.ConstructKeyboard(device_info);
+  auto aux_data = std::make_unique<InputDataProviderKeyboard::AuxData>();
 
-  for (auto& observer : connected_devices_observers_) {
+  keyboards_[device_info->evdev_id] =
+      keyboard_helper_.ConstructKeyboard(device_info, aux_data.get());
+  keyboard_aux_data_[device_info->evdev_id] = std::move(aux_data);
+
+  for (const auto& observer : connected_devices_observers_) {
     observer->OnKeyboardConnected(keyboards_[device_info->evdev_id]->Clone());
   }
 }
 
+void InputDataProvider::SendInputKeyEvent(uint32_t id,
+                                          uint32_t key_code,
+                                          uint32_t scan_code,
+                                          bool down) {
+  CHECK(widget_) << "Sending Key Events for input diagnostics not allowed "
+                    "without widget to track focus.";
+
+  if (!keyboard_observers_.contains(id)) {
+    LOG(ERROR) << "Couldn't find keyboard observer with ID " << id
+               << " when trying to dispatch key.";
+    return;
+  }
+
+  if (!may_send_events_) {
+    if (!logged_not_dispatching_key_events_) {
+      // Note: this will be common if the input diagnostics window is opened,
+      // but not focused, so just log once.
+      LOG(ERROR) << "Will not dispatch keys when diagnostics window does not "
+                    "have focus.";
+      logged_not_dispatching_key_events_ = true;
+    }
+    return;
+  }
+
+  mojom::KeyEventPtr event = keyboard_helper_.ConstructInputKeyEvent(
+      keyboards_[id], keyboard_aux_data_[id].get(), key_code, scan_code, down);
+
+  const auto& observers = *keyboard_observers_[id];
+  for (const auto& observer : observers) {
+    observer->OnKeyEvent(event->Clone());
+  }
+}
+
 }  // namespace diagnostics
 }  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider.h b/ash/webui/diagnostics_ui/backend/input_data_provider.h
index 3c57eeb..4d43827 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider.h
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider.h
@@ -18,15 +18,41 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote_set.h"
-#include "ui/chromeos/events/event_rewriter_chromeos.h"
+#include "ui/aura/window.h"
 #include "ui/events/ozone/device/device_event.h"
 #include "ui/events/ozone/device/device_event_observer.h"
 #include "ui/events/ozone/device/device_manager.h"
 #include "ui/events/ozone/evdev/event_device_info.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_observer.h"
 
 namespace ash {
 namespace diagnostics {
 
+// Interfaces for watching and dispatching relevant events from evdev to the
+// input_data_provider.
+class InputDataEventWatcher {
+ public:
+  class Dispatcher {
+   public:
+    virtual void SendInputKeyEvent(uint32_t id,
+                                   uint32_t key_code,
+                                   uint32_t scan_code,
+                                   bool down) = 0;
+  };
+
+  class Factory {
+   public:
+    virtual ~Factory() = 0;
+
+    virtual std::unique_ptr<InputDataEventWatcher> MakeWatcher(
+        uint32_t evdev_id,
+        base::WeakPtr<Dispatcher> dispatcher) = 0;
+  };
+
+  virtual ~InputDataEventWatcher() = 0;
+};
+
 // Wrapper for tracking several pieces of information about an evdev-backed
 // device.
 class InputDeviceInformation {
@@ -50,7 +76,7 @@
       keyboard_scan_code_map;
 };
 
-// Class for running GetDeviceInfo in its own sequence that can block.
+// Class for running GetDeviceInfo in its own sequence, to allow it to block.
 class InputDeviceInfoHelper {
  public:
   InputDeviceInfoHelper() {}
@@ -62,13 +88,18 @@
 };
 
 // Provides information about input devices connected to the system. Implemented
-// in the browser process and called by the Diagnostics SWA (a renderer
-// process).
+// in the browser process, constructed within the Diagnostics_UI in the browser
+// process, and eventually called by the Diagnostics SWA (a renderer process).
 class InputDataProvider : public mojom::InputDataProvider,
-                          public ui::DeviceEventObserver {
+                          public ui::DeviceEventObserver,
+                          public InputDataEventWatcher::Dispatcher,
+                          public views::WidgetObserver {
  public:
-  InputDataProvider();
-  explicit InputDataProvider(std::unique_ptr<ui::DeviceManager> device_manager);
+  explicit InputDataProvider(aura::Window* window);
+  explicit InputDataProvider(
+      aura::Window* window,
+      std::unique_ptr<ui::DeviceManager> device_manager,
+      std::unique_ptr<InputDataEventWatcher::Factory> watcher_factory);
   InputDataProvider(const InputDataProvider&) = delete;
   InputDataProvider& operator=(const InputDataProvider&) = delete;
   ~InputDataProvider() override;
@@ -78,9 +109,16 @@
   // Handler for when remote attached to |receiver_| disconnects.
   void OnBoundInterfaceDisconnect();
   bool ReceiverIsBound();
+
   static mojom::ConnectionType ConnectionTypeFromInputDeviceType(
       ui::InputDeviceType type);
 
+  // InputDataEventWatcher::Dispatcher:
+  void SendInputKeyEvent(uint32_t id,
+                         uint32_t key_code,
+                         uint32_t scan_code,
+                         bool down) override;
+
   // mojom::InputDataProvider:
   void GetConnectedDevices(GetConnectedDevicesCallback callback) override;
 
@@ -91,34 +129,72 @@
       uint32_t id,
       GetKeyboardVisualLayoutCallback callback) override;
 
+  void ObserveKeyEvents(
+      uint32_t id,
+      mojo::PendingRemote<mojom::KeyboardObserver> observer) override;
+
   // ui::DeviceEventObserver:
   void OnDeviceEvent(const ui::DeviceEvent& event) override;
 
+  // views::WidgetObserver:
+  void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override;
+  void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
+
  protected:
   base::SequenceBound<InputDeviceInfoHelper> info_helper_{
       base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()})};
 
  private:
-  void Initialize();
+  void Initialize(aura::Window* window);
 
   void ProcessDeviceInfo(std::unique_ptr<InputDeviceInformation> device_info);
 
   void AddTouchDevice(const InputDeviceInformation* device_info);
   void AddKeyboard(const InputDeviceInformation* device_info);
 
+  bool may_send_events_ = false;
+
+  // Review widget state to determine whether it is safe to send events.
+  void UpdateMaySendEvents();
+  // Pass on pause or resume events to observers if that state has changed.
+  void UpdateEventObservers();
+
+  void SendPauseEvents();
+  void SendResumeEvents();
+
   InputDataProviderKeyboard keyboard_helper_;
   InputDataProviderTouch touch_helper_;
 
-  // Map by evdev ids to information blocks
+  // Handle destroyed KeyboardObservers.
+  void OnObservedKeyboardInputDisconnect(uint32_t evdev_id,
+                                         mojo::RemoteSetElementId observer_id);
+  // Manage watchers that read an evdev and process events for observers.
+  void ForwardKeyboardInput(uint32_t id);
+  void UnforwardKeyboardInput(uint32_t id);
+
+  // Map by evdev ids to information blocks.
   base::flat_map<int, mojom::KeyboardInfoPtr> keyboards_;
+  base::flat_map<int, std::unique_ptr<InputDataProviderKeyboard::AuxData>>
+      keyboard_aux_data_;
   base::flat_map<int, mojom::TouchDeviceInfoPtr> touch_devices_;
 
+  // Map by evdev ids to remote observers and event watchers.
+  base::flat_map<int, std::unique_ptr<mojo::RemoteSet<mojom::KeyboardObserver>>>
+      keyboard_observers_;
+  base::flat_map<int, std::unique_ptr<InputDataEventWatcher>>
+      keyboard_watchers_;
+
+  bool logged_not_dispatching_key_events_ = false;
+  views::Widget* widget_ = nullptr;
+
   mojo::RemoteSet<mojom::ConnectedDevicesObserver> connected_devices_observers_;
 
   mojo::Receiver<mojom::InputDataProvider> receiver_{this};
 
   std::unique_ptr<ui::DeviceManager> device_manager_;
 
+  std::unique_ptr<InputDataEventWatcher::Factory> watcher_factory_;
+
   base::WeakPtrFactory<InputDataProvider> weak_factory_{this};
 };
 
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider_keyboard.cc b/ash/webui/diagnostics_ui/backend/input_data_provider_keyboard.cc
index 3ff6e11..d4ed5498 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider_keyboard.cc
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider_keyboard.cc
@@ -23,7 +23,6 @@
 #include "base/strings/string_util.h"
 #include "chromeos/system/statistics_provider.h"
 #include "ui/base/ime/ash/input_method_manager.h"
-#include "ui/chromeos/events/event_rewriter_chromeos.h"
 #include "ui/events/devices/device_util_linux.h"
 #include "ui/events/devices/input_device.h"
 #include "ui/events/event_constants.h"
@@ -53,16 +52,35 @@
   kFKey15
 };
 
+// Numeric values of evdev KEY_F# are non-contiguous, making this mapping
+// non-trivial.
+constexpr auto kFKeyOrder =
+    base::MakeFixedFlatMap<uint32_t, unsigned int>({{KEY_F1, kFKey1},
+                                                    {KEY_F2, kFKey2},
+                                                    {KEY_F3, kFKey3},
+                                                    {KEY_F4, kFKey4},
+                                                    {KEY_F5, kFKey5},
+                                                    {KEY_F6, kFKey6},
+                                                    {KEY_F7, kFKey7},
+                                                    {KEY_F8, kFKey8},
+                                                    {KEY_F9, kFKey9},
+                                                    {KEY_F10, kFKey10},
+                                                    {KEY_F11, kFKey11},
+                                                    {KEY_F12, kFKey12},
+                                                    {KEY_F13, kFKey13},
+                                                    {KEY_F14, kFKey14},
+                                                    {KEY_F15, kFKey15}});
+
 // Mapping from keyboard scancodes to TopRowKeys (must be in scancode-sorted
-// order). This replicates and should be identical to the mapping behaviour
-// of ChromeOS: changes will be needed if new AT scancodes or HID mappings
-// are used in a top-row key, likely added in
-// ui/events/keycodes/dom/dom_code_data.inc
+// order) for keyboards with custom top row layouts (vivaldi). This replicates
+// and should be identical to the mapping behaviour of ChromeOS: changes will
+// be needed if new AT scancodes or HID mappings are used in a top-row key,
+// likely added in ui/events/keycodes/dom/dom_code_data.inc.
 //
-// Note that there are no dedicated scancodes for kScreenMirror.
-constexpr auto kScancodeMapping =
+// Note that there are currently no dedicated scancodes for kScreenMirror.
+constexpr auto kCustomScancodeMapping =
     base::MakeFixedFlatMap<uint32_t, mojom::TopRowKey>({
-        // Vivaldi extended Set-1 AT-style scancodes
+        // Vivaldi-specific extended Set-1 AT-style scancodes.
         {0x90, mojom::TopRowKey::kPreviousTrack},
         {0x91, mojom::TopRowKey::kFullscreen},
         {0x92, mojom::TopRowKey::kOverview},
@@ -77,7 +95,6 @@
         {0xA0, mojom::TopRowKey::kVolumeMute},
         {0xAE, mojom::TopRowKey::kVolumeDown},
         {0xB0, mojom::TopRowKey::kVolumeUp},
-        {0xD3, mojom::TopRowKey::kDelete},  // Only relevant for Drallion.
         {0xE9, mojom::TopRowKey::kForward},
         {0xEA, mojom::TopRowKey::kBack},
         {0xE7, mojom::TopRowKey::kRefresh},
@@ -164,6 +181,19 @@
     mojom::TopRowKey::kDelete  // Just a normal Delete key, but in the top row.
 };
 
+// Wilco and Drallion have unique 'action' scancodes for their top rows,
+// that are different from the vivaldi mappings. These scancodes are generated
+// when a top-tow key is pressed without the /Fn/ modifier.
+constexpr uint32_t kScancodesWilco[] = {
+    0xEA, 0xE7, 0xD5, 0xD6, 0x95, 0x91, 0xA0,
+    0xAE, 0xB0, 0x44, 0x57, 0x8B, 0xD3,
+};
+
+constexpr uint32_t kScancodesDrallion[] = {
+    0xEA, 0xE7, 0xD5, 0xD6, 0x95, 0x91, 0xA0,
+    0xAE, 0xB0, 0x44, 0x57, 0xd7, 0x8B, 0xD3,
+};
+
 mojom::MechanicalLayout GetSystemMechanicalLayout() {
   chromeos::system::StatisticsProvider* stats_provider =
       chromeos::system::StatisticsProvider::GetInstance();
@@ -203,10 +233,14 @@
     : xkb_layout_engine_(xkb_evdev_codes_) {}
 InputDataProviderKeyboard::~InputDataProviderKeyboard() {}
 
+InputDataProviderKeyboard::AuxData::AuxData() = default;
+InputDataProviderKeyboard::AuxData::~AuxData() = default;
+
 void InputDataProviderKeyboard::GetKeyboardVisualLayout(
-    mojom::KeyboardInfoPtr keyboard,
+    const mojom::KeyboardInfoPtr& keyboard,
     mojom::InputDataProvider::GetKeyboardVisualLayoutCallback callback) {
   std::string layout_name;
+
   if (keyboard->connection_type == mojom::ConnectionType::kInternal) {
     chromeos::system::StatisticsProvider* stats_provider =
         chromeos::system::StatisticsProvider::GetInstance();
@@ -295,24 +329,38 @@
     ui::EventRewriterChromeOS::KeyboardTopRowLayout top_row_layout,
     const base::flat_map<uint32_t, ui::EventRewriterChromeOS::MutableKeyState>&
         scan_code_map,
-    std::vector<mojom::TopRowKey>* out_top_row_keys) {
+    std::vector<mojom::TopRowKey>* out_top_row_keys,
+    AuxData* out_aux_data) {
   ui::InputDevice input_device = device_info->input_device;
 
   // Simple array in physical order from left to right
   std::vector<mojom::TopRowKey> top_row_keys = {};
 
+  // Map of scan-code -> index within tow_row_keys: 0 is first key to the
+  // right of Escape, 1 is next key to the right of it, etc.
+  base::flat_map<uint32_t, uint32_t> top_row_key_scancode_indexes;
+
   switch (top_row_layout) {
     case ui::EventRewriterChromeOS::kKbdTopRowLayoutWilco:
       top_row_keys.assign(std::begin(kSystemKeysWilco),
                           std::end(kSystemKeysWilco));
+
+      for (size_t i = 0; i < top_row_keys.size(); i++)
+        top_row_key_scancode_indexes[kScancodesWilco[i]] = i;
       break;
 
     case ui::EventRewriterChromeOS::kKbdTopRowLayoutDrallion:
       top_row_keys.assign(std::begin(kSystemKeysDrallion),
                           std::end(kSystemKeysDrallion));
 
+      for (size_t i = 0; i < top_row_keys.size(); i++)
+        top_row_key_scancode_indexes[kScancodesDrallion[i]] = i;
+
       // On some Drallion devices, the F12 key is used for the Privacy Screen.
 
+      // The scancode for F12 does not need to be modified, it is the same on
+      // all Drallion devices, only the interpretation of the key is different.
+
       // This should be the same logic as in
       // EventRewriterControllerImpl::Initialize. This is a historic device, and
       // this logic should not need to be updated, as newer devices will use
@@ -328,7 +376,7 @@
 
       // Process scan-code map generated from custom top-row key layout: it maps
       // from physical scan codes to several things, including VKEY key-codes,
-      // which we will use to produce indexes.
+      // which we will use to derive a linear index.
 
       for (auto iter = scan_code_map.begin(); iter != scan_code_map.end();
            iter++) {
@@ -338,27 +386,43 @@
         if (top_row_keys.size() < fn_key_number + 1)
           top_row_keys.resize(fn_key_number + 1, mojom::TopRowKey::kNone);
 
-        if (kScancodeMapping.contains(scancode))
-          top_row_keys[fn_key_number] = kScancodeMapping.at(scancode);
+        if (kCustomScancodeMapping.contains(scancode))
+          top_row_keys[fn_key_number] = kCustomScancodeMapping.at(scancode);
         else
           top_row_keys[fn_key_number] = mojom::TopRowKey::kUnknown;
+
+        top_row_key_scancode_indexes[scancode] = fn_key_number;
       }
       break;
 
     case ui::EventRewriterChromeOS::kKbdTopRowLayout2:
       top_row_keys.assign(std::begin(kSystemKeys2), std::end(kSystemKeys2));
+      // No specific top_row_key_scancode_indexes are needed
+      // for classic ChromeOS keyboards, as they do not have an /Fn/ key and
+      // only emit /F[0-9]+/ keys.
       break;
 
     case ui::EventRewriterChromeOS::kKbdTopRowLayout1:
     default:
       top_row_keys.assign(std::begin(kSystemKeys1), std::end(kSystemKeys1));
+      // No specific top_row_key_scancode_indexes are needed for classic
+      // ChromeOS keyboards, as they do not have an /Fn/ key and only emit
+      // /F[0-9]+/ keys.
+      //
+      // If this is an unknown keyboard and we are just using Layout1 as
+      // the default, we also do not want to assign any scancode or keycode
+      // indexes, as we do not know whether the keyboard can generate special
+      // keys, or their location relative to the top row.
   }
 
   *out_top_row_keys = std::move(top_row_keys);
+  out_aux_data->top_row_key_scancode_indexes =
+      std::move(top_row_key_scancode_indexes);
 }
 
 mojom::KeyboardInfoPtr InputDataProviderKeyboard::ConstructKeyboard(
-    const InputDeviceInformation* device_info) {
+    const InputDeviceInformation* device_info,
+    AuxData* out_aux_data) {
   mojom::KeyboardInfoPtr result = mojom::KeyboardInfo::New();
 
   result->id = device_info->evdev_id;
@@ -370,7 +434,7 @@
 
   ProcessKeyboardTopRowLayout(device_info, device_info->keyboard_top_row_layout,
                               device_info->keyboard_scan_code_map,
-                              &result->top_row_keys);
+                              &result->top_row_keys, out_aux_data);
 
   // Work out the physical layout.
   if (device_info->keyboard_type ==
@@ -439,5 +503,35 @@
   return result;
 }
 
+mojom::KeyEventPtr InputDataProviderKeyboard::ConstructInputKeyEvent(
+    const mojom::KeyboardInfoPtr& keyboard,
+    const AuxData* aux_data,
+    uint32_t key_code,
+    uint32_t scan_code,
+    bool down) {
+  mojom::KeyEventPtr event = mojom::KeyEvent::New();
+  event->id = keyboard->id;
+  event->type =
+      down ? mojom::KeyEventType::kPress : mojom::KeyEventType::kRelease;
+  event->key_code = key_code;    // evdev code
+  event->scan_code = scan_code;  // scan code
+  event->top_row_position = -1;
+
+  // If a top row action key was pressed, note its physical index in the row.
+  const auto iter =
+      aux_data->top_row_key_scancode_indexes.find(event->scan_code);
+  if (iter != aux_data->top_row_key_scancode_indexes.end()) {
+    event->top_row_position = iter->second;
+  }
+
+  // Do the same if F1-F15 was pressed.
+  const auto* jter = kFKeyOrder.find(event->key_code);
+  if (event->top_row_position == -1 && jter != kFKeyOrder.end()) {
+    event->top_row_position = jter->second;
+  }
+
+  return event;
+}
+
 }  // namespace diagnostics
 }  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider_keyboard.h b/ash/webui/diagnostics_ui/backend/input_data_provider_keyboard.h
index cda2dc58..d5437f13 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider_keyboard.h
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider_keyboard.h
@@ -5,10 +5,11 @@
 #ifndef ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_INPUT_DATA_PROVIDER_KEYBOARD_H_
 #define ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_INPUT_DATA_PROVIDER_KEYBOARD_H_
 
+#include <vector>
+
 #include "ash/webui/diagnostics_ui/mojom/input_data_provider.mojom.h"
 #include "base/memory/weak_ptr.h"
 #include "ui/chromeos/events/event_rewriter_chromeos.h"
-#include "ui/events/ozone/evdev/event_device_info.h"
 #include "ui/events/ozone/layout/xkb/xkb_evdev_codes.h"
 #include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
 
@@ -21,6 +22,20 @@
 // keyboard-specific logic.
 class InputDataProviderKeyboard {
  public:
+  // Holder for any data that needs to be persisted per keyboard, that
+  // does not need to be exposed in the mojo::KeyboardInfo.
+  class AuxData {
+   public:
+    AuxData();
+    AuxData(const AuxData&) = delete;
+    AuxData& operator=(const AuxData&) = delete;
+    ~AuxData();
+
+    // Map of scancodes that map to particular indexes within the top_row_keys
+    // for that evdev. May contain AT and HID-style scancodes.
+    base::flat_map<uint32_t, uint32_t> top_row_key_scancode_indexes;
+  };
+
   InputDataProviderKeyboard();
   InputDataProviderKeyboard(const InputDataProviderKeyboard&) = delete;
   InputDataProviderKeyboard& operator=(const InputDataProviderKeyboard&) =
@@ -28,11 +43,19 @@
   ~InputDataProviderKeyboard();
 
   void GetKeyboardVisualLayout(
-      mojom::KeyboardInfoPtr keyboard,
+      const mojom::KeyboardInfoPtr& keyboard,
       mojom::InputDataProvider::GetKeyboardVisualLayoutCallback callback);
 
   mojom::KeyboardInfoPtr ConstructKeyboard(
-      const InputDeviceInformation* device_info);
+      const InputDeviceInformation* device_info,
+      AuxData* out_aux_data);
+
+  mojom::KeyEventPtr ConstructInputKeyEvent(
+      const mojom::KeyboardInfoPtr& keyboard,
+      const AuxData* aux_data,
+      uint32_t key_code,
+      uint32_t scan_code,
+      bool down);
 
  private:
   void ProcessXkbLayout(
@@ -45,7 +68,8 @@
       const base::flat_map<uint32_t,
                            ui::EventRewriterChromeOS::MutableKeyState>&
           scan_code_map,
-      std::vector<mojom::TopRowKey>* out_top_row_keys);
+      std::vector<mojom::TopRowKey>* out_top_row_keys,
+      AuxData* out_aux_data);
 
   ui::XkbEvdevCodes xkb_evdev_codes_;
   ui::XkbKeyboardLayoutEngine xkb_layout_engine_;
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider_touch.cc b/ash/webui/diagnostics_ui/backend/input_data_provider_touch.cc
index 48b05e87..854b6f2 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider_touch.cc
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider_touch.cc
@@ -4,7 +4,6 @@
 
 #include "ash/webui/diagnostics_ui/backend/input_data_provider_touch.h"
 #include "ash/webui/diagnostics_ui/backend/input_data_provider.h"
-#include "base/logging.h"
 #include "ui/events/ozone/evdev/event_device_info.h"
 
 namespace ash {
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider_touch.h b/ash/webui/diagnostics_ui/backend/input_data_provider_touch.h
index 5fe7db2..7cf17e4 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider_touch.h
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider_touch.h
@@ -6,7 +6,6 @@
 #define ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_INPUT_DATA_PROVIDER_TOUCH_H_
 
 #include "ash/webui/diagnostics_ui/mojom/input_data_provider.mojom.h"
-#include "ui/events/ozone/evdev/event_device_info.h"
 
 namespace ash {
 namespace diagnostics {
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc b/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc
index c4eab92..37b3c66 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc
@@ -4,18 +4,24 @@
 
 #include "ash/webui/diagnostics_ui/backend/input_data_provider.h"
 
+#include <iostream>
+#include <map>
 #include <vector>
 
+#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/containers/flat_map.h"
+#include "base/message_loop/message_pump_for_ui.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/bind.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "chromeos/system/fake_statistics_provider.h"
 #include "chromeos/system/statistics_provider.h"
+#include "content/public/test/browser_task_environment.h"
 #include "device/udev_linux/fake_udev_loader.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/chromeos/events/event_rewriter_chromeos.h"
 #include "ui/events/keycodes/dom/dom_code.h"
@@ -23,6 +29,16 @@
 #include "ui/events/ozone/device/device_event_observer.h"
 #include "ui/events/ozone/device/device_manager.h"
 #include "ui/events/ozone/evdev/event_device_test_util.h"
+#include "ui/views/test/views_test_base.h"
+#include "ui/views/widget/widget.h"
+
+// Note: this is not a recommended pattern, but works and allows cleanly
+// formatted invocations for this test set.
+#define EXPECT_KEY_EVENTS(observerptr, id, ...)    \
+  do {                                             \
+    SCOPED_TRACE("EXPECT_KEY_EVENTS invocation");  \
+    ExpectKeyEvents(observerptr, id, __VA_ARGS__); \
+  } while (0);
 
 namespace ash {
 namespace diagnostics {
@@ -96,6 +112,61 @@
 
 constexpr char kInvalidMechnicalLayout[] = "Not ANSI, JIS, or ISO";
 
+// Privacy Screen replaced with unknown 0xC4 scancode.
+constexpr char kModifiedJinlonDescriptor[] =
+    "EA E7 91 92 93 94 95 C4 97 98 A0 AE B0";
+constexpr uint32_t kUnknownScancode = 0xC4;
+constexpr int kUnknownScancodeIndex = 7;
+
+struct KeyDefinition {
+  uint32_t key_code;
+  uint32_t at_scan_code;
+  uint32_t usb_scan_code;
+};
+
+// TODO(b/211780758): we should acquire these tuples from dom_code_data.inc,
+// where feasible.
+constexpr KeyDefinition kKeyA = {KEY_A, 0x1E, 0x70004};
+constexpr KeyDefinition kKeyB = {KEY_B, 0x30, 0x70005};
+constexpr KeyDefinition kKeyEsc = {KEY_ESC, 0x30, 0x70005};
+constexpr KeyDefinition kKeyF1 = {KEY_F1, 0x3B, 0x7003A};
+constexpr KeyDefinition kKeyF8 = {KEY_F8, 0x42, 0x70041};
+constexpr KeyDefinition kKeyF10 = {KEY_F10, 0x44, 0x70043};
+// Drallion AT codes for F11-F12; not standardized
+constexpr KeyDefinition kKeyF11 = {KEY_F11, 0x57, 0x700044};
+constexpr KeyDefinition kKeyF12 = {KEY_F12, 0xD7, 0x700045};
+constexpr KeyDefinition kKeyDelete = {KEY_DELETE, 0xD3, 0x7004C};
+// Eve AT code; unknown if this is standard
+constexpr KeyDefinition kKeyMenu = {KEY_CONTROLPANEL, 0x5D, 0};
+// Jinlon AT code; unknown if this is standard
+constexpr KeyDefinition kKeySleep = {KEY_SLEEP, 0x5D, 0};
+constexpr KeyDefinition kKeyActionBack = {KEY_BACK, 0xEA, 0x0C0224};
+constexpr KeyDefinition kKeyActionRefresh = {KEY_REFRESH, 0xE7, 0x0C0227};
+constexpr KeyDefinition kKeyActionFullscreen = {KEY_ZOOM, 0x91, 0x0C0232};
+constexpr KeyDefinition kKeyActionOverview = {KEY_SCALE, 0x92, 0x0C029F};
+constexpr KeyDefinition kKeyActionScreenshot = {KEY_SYSRQ, 0x93, 0x070046};
+constexpr KeyDefinition kKeyActionScreenBrightnessDown = {KEY_BRIGHTNESSDOWN,
+                                                          0x94, 0x0C0070};
+constexpr KeyDefinition kKeyActionScreenBrightnessUp = {KEY_BRIGHTNESSUP, 0x95,
+                                                        0x0C006F};
+constexpr KeyDefinition kKeyActionKeyboardBrightnessDown = {KEY_KBDILLUMDOWN,
+                                                            0x97, 0x0C007A};
+constexpr KeyDefinition kKeyActionKeyboardBrightnessUp = {KEY_KBDILLUMUP, 0x98,
+                                                          0x0C0079};
+constexpr KeyDefinition kKeyActionKeyboardVolumeMute = {KEY_MUTE, 0xA0,
+                                                        0x0C00E2};
+constexpr KeyDefinition kKeyActionKeyboardVolumeDown = {KEY_VOLUMEDOWN, 0xAE,
+                                                        0x0C00EA};
+constexpr KeyDefinition kKeyActionKeyboardVolumeUp = {KEY_VOLUMEUP, 0xB0,
+                                                      0x0C00E9};
+#if 0
+// TODO(b/208729519): Not useful until we can test Drallion keyboards.
+// Drallion, no HID equivalent
+constexpr KeyDefinition kKeySwitchVideoMode = {KEY_SWITCHVIDEOMODE, 0x8B, 0};
+constexpr KeyDefinition kKeyActionPrivacyScreenToggle =
+   {KEY_PRIVACY_SCREEN_TOGGLE, 0x96, 0x0C02D0};
+#endif
+
 // NOTE: This is only creates a simple ui::InputDevice based on a device
 // capabilities report; it is not suitable for subclasses of ui::InputDevice.
 ui::InputDevice InputDeviceFromCapabilities(
@@ -115,6 +186,22 @@
 
 }  // namespace
 
+namespace mojom {
+
+std::ostream& operator<<(std::ostream& os, const KeyEvent& event) {
+  os << "KeyEvent{ id=" << event.id << ", ";
+  os << "type=" << event.type << ", ";
+  os << "key_code=" << event.key_code << ", ";
+  os << "scan_code=" << event.scan_code << ", ";
+  os << "top_row_position=" << event.top_row_position;
+  os << "}";
+  return os;
+}
+
+}  // namespace mojom
+
+// Fake device manager that lets us control the input devices that
+// an InputDataProvider can see.
 class FakeDeviceManager : public ui::DeviceManager {
  public:
   FakeDeviceManager() {}
@@ -128,6 +215,62 @@
   void RemoveObserver(ui::DeviceEventObserver* observer) override {}
 };
 
+class FakeInputDataEventWatcher;
+typedef std::map<uint32_t, FakeInputDataEventWatcher*> watchers_t;
+
+// Fake evdev watcher class that lets us manually post input
+// events into an InputDataProvider; this keeps an external
+// map of watchers updated so that instances can easily be found.
+class FakeInputDataEventWatcher : public InputDataEventWatcher {
+ public:
+  FakeInputDataEventWatcher(
+      uint32_t id,
+      base::WeakPtr<InputDataEventWatcher::Dispatcher> dispatcher,
+      watchers_t& watchers)
+      : id_(id), dispatcher_(dispatcher), watchers_(watchers) {
+    EXPECT_EQ(0u, watchers_.count(id_));
+    watchers_[id_] = this;
+  }
+  ~FakeInputDataEventWatcher() override {
+    EXPECT_EQ(watchers_[id_], this);
+    watchers_.erase(id_);
+  }
+
+  void PostKeyEvent(bool down, uint32_t evdev_code, uint32_t scan_code) {
+    if (dispatcher_)
+      dispatcher_->SendInputKeyEvent(id_, evdev_code, scan_code, down);
+  }
+
+ private:
+  uint32_t id_;
+  base::WeakPtr<InputDataEventWatcher::Dispatcher> dispatcher_;
+  watchers_t& watchers_;
+};
+
+// Utility to construct FakeInputDataEventWatcher for InputDataProvider.
+class FakeInputDataEventWatcherFactory : public InputDataEventWatcher::Factory {
+ public:
+  FakeInputDataEventWatcherFactory(watchers_t& watchers)
+      : watchers_(watchers) {}
+  FakeInputDataEventWatcherFactory(const FakeInputDataEventWatcherFactory&) =
+      delete;
+  FakeInputDataEventWatcherFactory& operator=(
+      const FakeInputDataEventWatcherFactory&) = delete;
+  ~FakeInputDataEventWatcherFactory() override = default;
+
+  std::unique_ptr<InputDataEventWatcher> MakeWatcher(
+      uint32_t id,
+      base::WeakPtr<InputDataEventWatcher::Dispatcher> dispatcher) override {
+    return std::make_unique<FakeInputDataEventWatcher>(
+        id, std::move(dispatcher), watchers_);
+  }
+
+ private:
+  watchers_t& watchers_;
+};
+
+// A mock observer that records device change events emitted from an
+// InputDataProvider.
 class FakeConnectedDevicesObserver : public mojom::ConnectedDevicesObserver {
  public:
   // mojom::ConnectedDevicesObserver:
@@ -153,6 +296,29 @@
   mojo::Receiver<mojom::ConnectedDevicesObserver> receiver{this};
 };
 
+// A mock observer that records key event events emitted from an
+// InputDataProvider.
+class FakeKeyboardObserver : public mojom::KeyboardObserver {
+ public:
+  enum EventType {
+    kEvent = 1,
+    kPause = 2,
+    kResume = 3,
+  };
+
+  // mojom::KeyboardObserver:
+  void OnKeyEvent(mojom::KeyEventPtr key_event) override {
+    events_.push_back({kEvent, std::move(key_event)});
+  }
+  void OnKeyEventsPaused() override { events_.push_back({kPause, nullptr}); }
+  void OnKeyEventsResumed() override { events_.push_back({kResume, nullptr}); }
+
+  std::vector<std::pair<EventType, mojom::KeyEventPtr>> events_;
+
+  mojo::Receiver<mojom::KeyboardObserver> receiver{this};
+};
+
+// A utility class that fakes obtaining information about an evdev.
 class FakeInputDeviceInfoHelper : public InputDeviceInfoHelper {
  public:
   FakeInputDeviceInfoHelper() {}
@@ -225,6 +391,22 @@
       info->keyboard_top_row_layout = ui::EventRewriterChromeOS::
           KeyboardTopRowLayout::kKbdTopRowLayoutDefault;
       EXPECT_EQ(9, id);
+    } else if (base_name == "event10") {
+      device_caps = ui::kDrallionKeyboard;
+      EXPECT_EQ(10, id);
+    } else if (base_name == "event11") {
+      // Used for customized top row layout.
+      device_caps = ui::kJinlonKeyboard;
+      device_caps.kbd_function_row_physmap = kModifiedJinlonDescriptor;
+      info->keyboard_type =
+          ui::EventRewriterChromeOS::DeviceType::kDeviceInternalKeyboard;
+      info->keyboard_top_row_layout = ui::EventRewriterChromeOS::
+          KeyboardTopRowLayout::kKbdTopRowLayoutCustom;
+      info->keyboard_scan_code_map = kInternalJinlonScanCodeMap;
+      info->keyboard_scan_code_map.erase(0x96);
+      info->keyboard_scan_code_map[0xC4] = {ui::EF_NONE, ui::DomCode::F8,
+                                            ui::DomKey::F8, ui::VKEY_F8};
+      EXPECT_EQ(11, id);
     } else if (base_name == kSillyDeviceName) {
       // Simulate a device that is properly described, but has a malformed
       // device name.
@@ -251,31 +433,62 @@
   }
 };
 
+// Our modifications to InputDataProvider that carries around its own
+// widget (representing the window that needs to be visible for key events
+// to be observed), the needed factories for our fake utilities, and a
+// reference to the current event watchers.
 class TestInputDataProvider : public InputDataProvider {
  public:
-  TestInputDataProvider(std::unique_ptr<ui::DeviceManager> device_manager)
-      : InputDataProvider(std::move(device_manager)) {
+  TestInputDataProvider(std::unique_ptr<views::Widget> widget,
+                        watchers_t& watchers)
+      : InputDataProvider(
+            widget->GetNativeWindow(),
+            std::make_unique<FakeDeviceManager>(),
+            std::make_unique<FakeInputDataEventWatcherFactory>(watchers)),
+        attached_widget_(std::move(widget)),
+        watchers_(watchers) {
     info_helper_ = base::SequenceBound<FakeInputDeviceInfoHelper>(
         base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}));
   }
   explicit TestInputDataProvider(const TestInputDataProvider&) = delete;
   TestInputDataProvider& operator=(const TestInputDataProvider&) = delete;
+
+  // The widget represents the tab that input diagnostics would normally be
+  // shown in.
+  std::unique_ptr<views::Widget> attached_widget_;
+  // Keep a list of watchers for each evdev in the provider. This is a
+  // reference to an instance outside of this class, as the lifetime of the list
+  // needs to exceed the destruction of this test class, and can only be cleaned
+  // up once all watchers have been destroyed by the base InputDataProvider,
+  // which occurs after our destruction.
+  watchers_t& watchers_;
 };
 
-class InputDataProviderTest : public testing::Test {
+class InputDataProviderTest : public views::ViewsTestBase {
  public:
-  InputDataProviderTest() {
+  InputDataProviderTest()
+      : views::ViewsTestBase(std::unique_ptr<base::test::TaskEnvironment>(
+            std::make_unique<content::BrowserTaskEnvironment>(
+                content::BrowserTaskEnvironment::MainThreadType::UI,
+                content::BrowserTaskEnvironment::TimeSource::MOCK_TIME))) {}
+
+  void SetUp() override {
+    views::ViewsTestBase::SetUp();
+
+    // Note: some init for creating widgets is performed in base SetUp
+    // instead of the constructor, so our init must also be delayed until SetUp,
+    // so we can safely invoke CreateTestWidget().
+
     statistics_provider_.SetMachineStatistic(
         chromeos::system::kKeyboardMechanicalLayoutKey, "ANSI");
     chromeos::system::StatisticsProvider::SetTestProvider(
         &statistics_provider_);
 
-    auto manager = std::make_unique<FakeDeviceManager>();
-    manager_ = manager.get();
     fake_udev_ = std::make_unique<testing::FakeUdevLoader>();
-    provider_ = std::make_unique<TestInputDataProvider>(std::move(manager));
+    provider_ =
+        std::make_unique<TestInputDataProvider>(CreateTestWidget(), watchers_);
 
-    // Apply these early; delaying until
+    // Apply these early, in SetUp; delaying until
     // FakeInputDeviceInfoHelper::GetDeviceInfo() is not appropriate, as
     // fake_udev is not thread safe. (If multiple devices are constructed in a
     // row, then GetDeviceInfo() invocation can overlap with
@@ -283,15 +496,64 @@
     UdevAddFakeDeviceCapabilities("/dev/input/event5", ui::kSarienKeyboard);
     UdevAddFakeDeviceCapabilities("/dev/input/event6", ui::kEveKeyboard);
     UdevAddFakeDeviceCapabilities("/dev/input/event7", ui::kJinlonKeyboard);
+    UdevAddFakeDeviceCapabilities("/dev/input/event10", ui::kDrallionKeyboard);
+    // Tweak top row keys for event11.
+    auto device_caps = ui::kJinlonKeyboard;
+    device_caps.kbd_function_row_physmap = kModifiedJinlonDescriptor;
+    UdevAddFakeDeviceCapabilities("/dev/input/event11", device_caps);
+  }
+
+  InputDataProviderTest(const InputDataProviderTest&) = delete;
+  InputDataProviderTest& operator=(const InputDataProviderTest&) = delete;
+  ~InputDataProviderTest() override {
+    provider_.reset();
+    base::RunLoop().RunUntilIdle();
+  }
+
+ protected:
+  struct ExpectedKeyEvent {
+    KeyDefinition key;
+    int position;
+    bool down = true;
+  };
+
+  void ExpectKeyEvents(FakeKeyboardObserver* fake_observer,
+                       uint32_t id,
+                       std::initializer_list<ExpectedKeyEvent> list) {
+    // Make sure the test does something...
+    EXPECT_TRUE(std::size(list) > 0);
+
+    size_t i;
+
+    i = 0;
+    for (auto* iter = list.begin(); iter != list.end(); iter++, i++) {
+      provider_->watchers_[id]->PostKeyEvent(iter->down, iter->key.key_code,
+                                             iter->key.at_scan_code);
+    }
+    base::RunLoop().RunUntilIdle();
+
+    ASSERT_EQ(std::size(list), fake_observer->events_.size());
+
+    i = 0;
+    for (auto* iter = list.begin(); iter != list.end(); iter++, i++) {
+      EXPECT_EQ(*fake_observer->events_[i].second,
+                mojom::KeyEvent(/*id=*/id, /*type=*/iter->down
+                                               ? mojom::KeyEventType::kPress
+                                               : mojom::KeyEventType::kRelease,
+                                /*key_code=*/iter->key.key_code,
+                                /*scan_code=*/iter->key.at_scan_code,
+                                /*top_row_position=*/iter->position))
+          << " which is EXPECT_KEY_EVENTS item #" << i;
+    }
   }
 
   void UdevAddFakeDeviceCapabilities(
       const std::string& device_name,
       const ui::DeviceCapabilities& device_caps) {
     std::map<std::string, std::string>
-        sysfs_properties;  // Old style numeric tags
+        sysfs_properties;  // Old style numeric tags.
     std::map<std::string, std::string>
-        sysfs_attributes;  // New style vivaldi scancode layouts
+        sysfs_attributes;  // New style vivaldi scancode layouts.
 
     if (device_caps.kbd_function_row_physmap &&
         strlen(device_caps.kbd_function_row_physmap) > 0) {
@@ -304,7 +566,10 @@
       sysfs_properties[kKbdTopRowPropertyName] = device_caps.kbd_top_row_layout;
     }
 
-    // Each device needs a unique sys path
+    // Each device needs a unique sys path; many of the ones embedded in
+    // capabilities are the same, so uniquify them with the event device name.
+    // These aren't actual valid paths, but nothing in the testing logic needs
+    // them to be real.
     const std::string sys_path = device_name + "-" + device_caps.path;
 
     fake_udev_->AddFakeDevice(device_caps.name, sys_path.c_str(),
@@ -314,17 +579,11 @@
                               std::move(sysfs_properties));
   }
 
-  ~InputDataProviderTest() override {
-    provider_.reset();
-    base::RunLoop().RunUntilIdle();
-  }
-
- protected:
-  base::test::TaskEnvironment task_environment_;
-  FakeDeviceManager* manager_;
   std::unique_ptr<testing::FakeUdevLoader> fake_udev_;
   chromeos::system::FakeStatisticsProvider statistics_provider_;
-  std::unique_ptr<InputDataProvider> provider_;
+  // All evdev watchers in use by provider_.
+  watchers_t watchers_;
+  std::unique_ptr<TestInputDataProvider> provider_;
 };
 
 TEST_F(InputDataProviderTest, GetConnectedDevices_DeviceInfoMapping) {
@@ -344,7 +603,7 @@
   provider_->OnDeviceEvent(event1);
   provider_->OnDeviceEvent(event2);
   provider_->OnDeviceEvent(event3);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
                          std::vector<mojom::TouchDeviceInfoPtr>>
@@ -393,7 +652,7 @@
                         ui::DeviceEvent::ActionType::ADD,
                         base::FilePath("/dev/input/event4"));
   provider_->OnDeviceEvent(event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   {
     base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
@@ -415,6 +674,8 @@
 }
 
 TEST_F(InputDataProviderTest, GetConnectedDevices_AddUnusualDevices) {
+  // Add two devices with unusual bus types, and verify connection types.
+
   ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
                          ui::DeviceEvent::ActionType::ADD,
                          base::FilePath("/dev/input/event8"));
@@ -423,7 +684,7 @@
                          base::FilePath("/dev/input/event9"));
   provider_->OnDeviceEvent(event0);
   provider_->OnDeviceEvent(event1);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
                          std::vector<mojom::TouchDeviceInfoPtr>>
@@ -434,7 +695,6 @@
   const auto& touch_devices = future.Get<1>();
 
   ASSERT_EQ(2ul, keyboards.size());
-  // The stylus device should be filtered out, hence only 2 touch devices.
   ASSERT_EQ(0ul, touch_devices.size());
 
   const mojom::KeyboardInfoPtr& keyboard1 = keyboards[0];
@@ -457,7 +717,7 @@
                                 ui::DeviceEvent::ActionType::ADD,
                                 base::FilePath("/dev/input/event4"));
   provider_->OnDeviceEvent(add_kbd_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   {
     base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
@@ -483,7 +743,7 @@
                                    ui::DeviceEvent::ActionType::REMOVE,
                                    base::FilePath("/dev/input/event4"));
   provider_->OnDeviceEvent(remove_kbd_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   {
     base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
@@ -519,7 +779,7 @@
   provider_->OnDeviceEvent(event1);
   provider_->OnDeviceEvent(event2);
   provider_->OnDeviceEvent(event3);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
                          std::vector<mojom::TouchDeviceInfoPtr>>
@@ -591,7 +851,7 @@
                             base::FilePath("/dev/input/event6"));
   provider_->OnDeviceEvent(link_event);
   provider_->OnDeviceEvent(eve_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
                          std::vector<mojom::TouchDeviceInfoPtr>>
@@ -619,7 +879,7 @@
                              ui::DeviceEvent::ActionType::ADD,
                              base::FilePath("/dev/input/event0"));
   provider_->OnDeviceEvent(link_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
                          std::vector<mojom::TouchDeviceInfoPtr>>
@@ -644,7 +904,7 @@
                                      ui::DeviceEvent::ActionType::ADD,
                                      base::FilePath("/dev/input/event4"));
   provider_->OnDeviceEvent(add_keyboard_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   ASSERT_EQ(1ul, fake_observer.keyboards_connected.size());
   EXPECT_EQ(4u, fake_observer.keyboards_connected[0]->id);
 
@@ -652,7 +912,7 @@
                                         ui::DeviceEvent::ActionType::REMOVE,
                                         base::FilePath("/dev/input/event4"));
   provider_->OnDeviceEvent(remove_keyboard_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   ASSERT_EQ(1ul, fake_observer.keyboards_disconnected.size());
   EXPECT_EQ(4u, fake_observer.keyboards_disconnected[0]);
 }
@@ -666,7 +926,7 @@
                                   ui::DeviceEvent::ActionType::ADD,
                                   base::FilePath("/dev/input/event1"));
   provider_->OnDeviceEvent(add_touch_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   ASSERT_EQ(1ul, fake_observer.touch_devices_connected.size());
   EXPECT_EQ(1u, fake_observer.touch_devices_connected[0]->id);
 
@@ -674,7 +934,7 @@
                                      ui::DeviceEvent::ActionType::REMOVE,
                                      base::FilePath("/dev/input/event1"));
   provider_->OnDeviceEvent(remove_touch_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   ASSERT_EQ(1ul, fake_observer.touch_devices_disconnected.size());
   EXPECT_EQ(1u, fake_observer.touch_devices_disconnected[0]);
 }
@@ -687,18 +947,18 @@
                                       ui::DeviceEvent::ActionType::CHANGE,
                                       base::FilePath("/dev/input/event1"));
   provider_->OnDeviceEvent(add_device_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   provider_->OnDeviceEvent(change_device_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(InputDataProviderTest, BadDeviceDoesNotCrash) {
-  // Try a device that specifically fails to be processed
+  // Try a device that specifically fails to be processed.
   ui::DeviceEvent add_bad_device_event(ui::DeviceEvent::DeviceType::INPUT,
                                        ui::DeviceEvent::ActionType::ADD,
                                        base::FilePath("/dev/input/event99"));
   provider_->OnDeviceEvent(add_bad_device_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(InputDataProviderTest, SillyDeviceDoesNotCrash) {
@@ -707,7 +967,7 @@
                                          ui::DeviceEvent::ActionType::ADD,
                                          base::FilePath(kSillyDeviceName));
   provider_->OnDeviceEvent(add_silly_device_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(InputDataProviderTest, GetKeyboardVisualLayout_AmericanEnglish) {
@@ -718,7 +978,7 @@
                                      ui::DeviceEvent::ActionType::ADD,
                                      base::FilePath("/dev/input/event6"));
   provider_->OnDeviceEvent(add_keyboard_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   base::test::TestFuture<base::flat_map<uint32_t, mojom::KeyGlyphSetPtr>>
       future;
@@ -749,7 +1009,7 @@
                                      ui::DeviceEvent::ActionType::ADD,
                                      base::FilePath("/dev/input/event6"));
   provider_->OnDeviceEvent(add_keyboard_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   base::test::TestFuture<base::flat_map<uint32_t, mojom::KeyGlyphSetPtr>>
       future;
@@ -779,7 +1039,7 @@
                                      ui::DeviceEvent::ActionType::ADD,
                                      base::FilePath("/dev/input/event6"));
   provider_->OnDeviceEvent(add_keyboard_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   {
     base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
@@ -809,7 +1069,7 @@
                                      ui::DeviceEvent::ActionType::ADD,
                                      base::FilePath("/dev/input/event6"));
   provider_->OnDeviceEvent(add_keyboard_event);
-  task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   {
     base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
@@ -850,5 +1110,671 @@
   ASSERT_TRUE(provider_->ReceiverIsBound());
 }
 
+TEST_F(InputDataProviderTest, KeyObservationBasic) {
+  std::unique_ptr<FakeKeyboardObserver> fake_observer =
+      std::make_unique<FakeKeyboardObserver>();
+
+  // Widget must be active and visible.
+  provider_->attached_widget_->Show();
+  provider_->attached_widget_->Activate();
+
+  // Construct a keyboard.
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event6"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, fake_observer->events_.size());
+  EXPECT_EQ(0u, provider_->watchers_.size());
+
+  // Attach a key observer.
+  provider_->ObserveKeyEvents(
+      6u, fake_observer->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  // Ensure an event watcher was constructed for the observer,
+  // but has not posted any events.
+  EXPECT_EQ(0u, fake_observer->events_.size());
+  EXPECT_EQ(1u, provider_->watchers_.size());
+  ASSERT_TRUE(provider_->watchers_[6]);
+
+  // Post a key event through the watcher that
+  // was created for the observer.
+  provider_->watchers_[6]->PostKeyEvent(true, kKeyA.key_code,
+                                        kKeyA.at_scan_code);
+  base::RunLoop().RunUntilIdle();
+
+  // Ensure the event came through.
+  EXPECT_EQ(1u, fake_observer->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kEvent, fake_observer->events_[0].first);
+  ASSERT_TRUE(fake_observer->events_[0].second);
+
+  EXPECT_EQ(*fake_observer->events_[0].second,
+            mojom::KeyEvent(/*id=*/6u, /*type=*/mojom::KeyEventType::kPress,
+                            /*key_code=*/kKeyA.key_code,
+                            /*scan_code=*/kKeyA.at_scan_code,
+                            /*top_row_position=*/-1));
+}
+
+TEST_F(InputDataProviderTest, KeyObservationRemoval) {
+  std::unique_ptr<FakeKeyboardObserver> fake_observer =
+      std::make_unique<FakeKeyboardObserver>();
+
+  // Widget must be active and visible.
+  provider_->attached_widget_->Show();
+  provider_->attached_widget_->Activate();
+
+  // Construct a keyboard.
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event6"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, fake_observer->events_.size());
+  EXPECT_EQ(0u, provider_->watchers_.size());
+
+  bool disconnected = false;
+
+  // Attach a key observer.
+  provider_->ObserveKeyEvents(
+      6u, fake_observer->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  fake_observer->receiver.set_disconnect_handler(
+      base::BindOnce([](bool* disconnected) { *disconnected = true; },
+                     base::Unretained(&disconnected)));
+
+  base::RunLoop().RunUntilIdle();
+
+  // Ensure an event watcher was constructed for the observer,
+  // but has not posted any events.
+  EXPECT_EQ(0u, fake_observer->events_.size());
+  EXPECT_EQ(1u, provider_->watchers_.size());
+  EXPECT_FALSE(disconnected);
+  ASSERT_TRUE(provider_->watchers_[6]);
+
+  // Test a key event.
+  EXPECT_KEY_EVENTS(fake_observer.get(), 6u, {{kKeyA, -1}});
+
+  // Disconnect keyboard while it is being observed.
+  ui::DeviceEvent remove_kbd_event(ui::DeviceEvent::DeviceType::INPUT,
+                                   ui::DeviceEvent::ActionType::REMOVE,
+                                   base::FilePath("/dev/input/event6"));
+  provider_->OnDeviceEvent(remove_kbd_event);
+  base::RunLoop().RunUntilIdle();
+
+  // Watcher should have been shut down, and receiver disconnected.
+  EXPECT_FALSE(provider_->watchers_[6]);
+  EXPECT_TRUE(disconnected);
+}
+
+TEST_F(InputDataProviderTest, KeyObservationMultiple) {
+  std::unique_ptr<FakeKeyboardObserver> fake_observer =
+      std::make_unique<FakeKeyboardObserver>();
+
+  // Widget must be active and visible.
+  provider_->attached_widget_->Show();
+  provider_->attached_widget_->Activate();
+
+  // Construct a keyboard.
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event6"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  // Attach a key observer.
+  provider_->ObserveKeyEvents(
+      6u, fake_observer->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  ASSERT_TRUE(provider_->watchers_[6]);
+
+  EXPECT_KEY_EVENTS(fake_observer.get(), 6u,
+                    {{kKeyA, -1, true},
+                     {kKeyB, -1, true},
+                     {kKeyA, -1, false},
+                     {kKeyB, -1, false}});
+}
+
+TEST_F(InputDataProviderTest, KeyObservationObeysFocus) {
+  std::unique_ptr<FakeKeyboardObserver> fake_observer =
+      std::make_unique<FakeKeyboardObserver>();
+
+  provider_->attached_widget_->Deactivate();
+  provider_->attached_widget_->Hide();
+
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event6"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  provider_->ObserveKeyEvents(
+      6u, fake_observer->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  // Verify we got the pause event from hiding the window.
+  ASSERT_EQ(1u, fake_observer->events_.size());
+  ASSERT_TRUE(provider_->watchers_[6]);
+
+  EXPECT_EQ(FakeKeyboardObserver::kPause, fake_observer->events_[0].first);
+
+  // Post a key event through the watcher that
+  // was created for the observer.
+  provider_->watchers_[6]->PostKeyEvent(true, kKeyA.key_code,
+                                        kKeyA.at_scan_code);
+  base::RunLoop().RunUntilIdle();
+
+  // Ensure the event did not come through, as the widget was not visible and
+  // focused.
+  ASSERT_EQ(1u, fake_observer->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kPause, fake_observer->events_[0].first);
+}
+
+TEST_F(InputDataProviderTest, KeyObservationDisconnect) {
+  std::unique_ptr<FakeKeyboardObserver> fake_observer =
+      std::make_unique<FakeKeyboardObserver>();
+
+  // Widget must be active and visible.
+  provider_->attached_widget_->Show();
+  provider_->attached_widget_->Activate();
+
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event6"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  provider_->ObserveKeyEvents(
+      6u, fake_observer->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, fake_observer->events_.size());
+  ASSERT_TRUE(provider_->watchers_[6]);
+
+  fake_observer->receiver.reset();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, fake_observer->events_.size());
+  ASSERT_FALSE(provider_->watchers_[6]);
+}
+
+TEST_F(InputDataProviderTest, KeyObservationObeysFocusSwitching) {
+  std::unique_ptr<FakeKeyboardObserver> fake_observer =
+      std::make_unique<FakeKeyboardObserver>();
+  std::unique_ptr<views::Widget> other_widget = CreateTestWidget();
+
+  // Provider's widget must be active and visible.
+  provider_->attached_widget_->Show();
+
+  // Construct a keyboard.
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event6"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, fake_observer->events_.size());
+  EXPECT_EQ(0u, provider_->watchers_.size());
+
+  // Attach a key observer.
+  provider_->ObserveKeyEvents(
+      6u, fake_observer->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  // Ensure an event watcher was constructed for the observer,
+  // but has not posted any events.
+  EXPECT_EQ(0u, fake_observer->events_.size());
+  EXPECT_EQ(1u, provider_->watchers_.size());
+  ASSERT_TRUE(provider_->watchers_[6]);
+
+  // Focus on the other window.
+  other_widget->Show();
+  other_widget->Activate();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(provider_->attached_widget_->IsActive());
+  EXPECT_TRUE(other_widget->IsVisible());
+  EXPECT_TRUE(other_widget->IsActive());
+
+  EXPECT_EQ(1u, fake_observer->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kPause, fake_observer->events_[0].first);
+  ASSERT_FALSE(fake_observer->events_[0].second);
+
+  // Post a key event through the watcher that
+  // was created for the observer.
+  provider_->watchers_[6]->PostKeyEvent(true, kKeyA.key_code,
+                                        kKeyA.at_scan_code);
+  base::RunLoop().RunUntilIdle();
+
+  // Ensure the event did not come through.
+  EXPECT_EQ(1u, fake_observer->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kPause, fake_observer->events_[0].first);
+
+  // Clear events for next round.
+  fake_observer->events_.clear();
+
+  // Switch windows back.
+  provider_->attached_widget_->Show();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_TRUE(provider_->attached_widget_->IsActive());
+  EXPECT_FALSE(other_widget->IsActive());
+
+  // Post another key event.
+  provider_->watchers_[6]->PostKeyEvent(true, kKeyB.key_code,
+                                        kKeyB.at_scan_code);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(2u, fake_observer->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kResume, fake_observer->events_[0].first);
+  EXPECT_EQ(FakeKeyboardObserver::kEvent, fake_observer->events_[1].first);
+  ASSERT_TRUE(fake_observer->events_[1].second);
+
+  EXPECT_EQ(*fake_observer->events_[1].second,
+            mojom::KeyEvent(/*id=*/6u, /*type=*/mojom::KeyEventType::kPress,
+                            /*key_code=*/kKeyB.key_code,
+                            /*scan_code=*/kKeyB.at_scan_code,
+                            /*top_row_position=*/-1));
+}
+
+// Test overlapping lifetimes of separate observers of one device.
+TEST_F(InputDataProviderTest, KeyObservationOverlappingeObserversOfDevice) {
+  std::unique_ptr<FakeKeyboardObserver> fake_observer1 =
+      std::make_unique<FakeKeyboardObserver>();
+
+  provider_->attached_widget_->Show();
+
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event6"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  provider_->ObserveKeyEvents(
+      6u, fake_observer1->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, fake_observer1->events_.size());
+  EXPECT_EQ(1u, provider_->watchers_.size());
+  EXPECT_TRUE(provider_->watchers_[6]);
+
+  std::unique_ptr<FakeKeyboardObserver> fake_observer2 =
+      std::make_unique<FakeKeyboardObserver>();
+
+  provider_->ObserveKeyEvents(
+      6u, fake_observer2->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, fake_observer1->events_.size());
+  EXPECT_EQ(0u, fake_observer2->events_.size());
+  EXPECT_TRUE(provider_->watchers_[6]);
+
+  fake_observer1.reset();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, fake_observer2->events_.size());
+  ASSERT_TRUE(provider_->watchers_[6]);
+
+  // And send an event through to check functionality.
+  provider_->watchers_[6]->PostKeyEvent(true, kKeyA.key_code,
+                                        kKeyA.at_scan_code);
+  base::RunLoop().RunUntilIdle();
+
+  // Ensure an event comes through properly after all that.
+  EXPECT_EQ(1u, fake_observer2->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kEvent, fake_observer2->events_[0].first);
+  ASSERT_TRUE(fake_observer2->events_[0].second);
+  EXPECT_EQ(*fake_observer2->events_[0].second,
+            mojom::KeyEvent(/*id=*/6u, /*type=*/mojom::KeyEventType::kPress,
+                            /*key_code=*/kKeyA.key_code,
+                            /*scan_code=*/kKeyA.at_scan_code,
+                            /*top_row_position=*/-1));
+
+  fake_observer2.reset();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, provider_->watchers_.count(6));
+}
+
+// Double-check security model and ensure that multiple instances
+// do not interfere with each other, and that key observations obey
+// individual window focus combined with multiple instances.
+TEST_F(InputDataProviderTest, KeyObservationMultipleProviders) {
+  // Create a second InputDataProvider, with a separate window/widget,
+  // as would happen if multiple instances of the SWA were created.
+  watchers_t provider2_watchers;
+  std::unique_ptr<TestInputDataProvider> provider2_ =
+      std::make_unique<TestInputDataProvider>(CreateTestWidget(),
+                                              provider2_watchers);
+  auto& provider1_ = provider_;
+
+  std::unique_ptr<FakeKeyboardObserver> fake_observer1 =
+      std::make_unique<FakeKeyboardObserver>();
+  std::unique_ptr<FakeKeyboardObserver> fake_observer2 =
+      std::make_unique<FakeKeyboardObserver>();
+
+  // Show and activate first window.
+  provider1_->attached_widget_->Show();
+  // Show and activate second window; this will deactivate the first window.
+  provider2_->attached_widget_->Show();
+
+  EXPECT_FALSE(provider1_->attached_widget_->IsActive());
+  EXPECT_TRUE(provider2_->attached_widget_->IsActive());
+
+  // Construct a keyboard.
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event6"));
+  provider1_->OnDeviceEvent(event0);
+  provider2_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_TRUE(provider1_->watchers_.empty());
+  EXPECT_TRUE(provider2_->watchers_.empty());
+
+  // Connected observer 1 to provider 1.
+  provider1_->ObserveKeyEvents(
+      6u, fake_observer1->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(provider1_->watchers_.empty());
+  EXPECT_TRUE(provider2_->watchers_.empty());
+  EXPECT_EQ(1u, fake_observer1->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kPause, fake_observer1->events_[0].first);
+  EXPECT_EQ(1u, provider1_->watchers_.count(6));
+
+  EXPECT_EQ(0u, fake_observer2->events_.size());
+  EXPECT_EQ(0u, provider2_->watchers_.count(6));
+
+  // Connected observer 2 to provider 2.
+
+  provider2_->ObserveKeyEvents(
+      6u, fake_observer2->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(provider1_->watchers_.empty());
+  EXPECT_FALSE(provider2_->watchers_.empty());
+  EXPECT_EQ(1u, fake_observer1->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kPause, fake_observer1->events_[0].first);
+  EXPECT_EQ(1u, provider1_->watchers_.size());
+  EXPECT_EQ(1u, provider1_->watchers_.size());
+  ASSERT_TRUE(provider1_->watchers_[6]);
+  ASSERT_TRUE(provider2_->watchers_[6]);
+
+  EXPECT_EQ(0u, fake_observer2->events_.size());
+  EXPECT_EQ(1u, provider2_->watchers_.size());
+  EXPECT_TRUE(provider2_->watchers_[6]);
+  // Providers should have distinct Watcher instances.
+  EXPECT_NE(provider1_->watchers_[6], provider2_->watchers_[6]);
+
+  // Reset event logs for next round.
+  fake_observer1->events_.clear();
+  fake_observer2->events_.clear();
+
+  // Post two separate key events.
+  provider1_->watchers_[6]->PostKeyEvent(true, kKeyA.key_code,
+                                         kKeyA.at_scan_code);
+  provider2_->watchers_[6]->PostKeyEvent(true, kKeyB.key_code,
+                                         kKeyB.at_scan_code);
+  base::RunLoop().RunUntilIdle();
+
+  // Ensure the events came through to expected targets.
+  EXPECT_EQ(0u, fake_observer1->events_.size());
+
+  EXPECT_EQ(1u, fake_observer2->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kEvent, fake_observer2->events_[0].first);
+  ASSERT_TRUE(fake_observer2->events_[0].second);
+  EXPECT_EQ(*fake_observer2->events_[0].second,
+            mojom::KeyEvent(/*id=*/6u, /*type=*/mojom::KeyEventType::kPress,
+                            /*key_code=*/kKeyB.key_code,
+                            /*scan_code=*/kKeyB.at_scan_code,
+                            /*top_row_position=*/-1));
+
+  // Reset event logs for next round.
+  fake_observer1->events_.clear();
+  fake_observer2->events_.clear();
+
+  // Switch active window.
+  provider1_->attached_widget_->Activate();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_TRUE(provider1_->attached_widget_->IsActive());
+  EXPECT_TRUE(provider1_->attached_widget_->IsVisible());
+  EXPECT_FALSE(provider2_->attached_widget_->IsActive());
+
+  provider1_->watchers_[6]->PostKeyEvent(true, kKeyA.key_code,
+                                         kKeyA.at_scan_code);
+  provider2_->watchers_[6]->PostKeyEvent(true, kKeyB.key_code,
+                                         kKeyB.at_scan_code);
+  base::RunLoop().RunUntilIdle();
+
+  // Ensure the events came through to expected targets.
+
+  EXPECT_EQ(2u, fake_observer1->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kResume, fake_observer1->events_[0].first);
+  EXPECT_FALSE(fake_observer1->events_[0].second);
+  EXPECT_EQ(FakeKeyboardObserver::kEvent, fake_observer1->events_[1].first);
+  ASSERT_TRUE(fake_observer1->events_[1].second);
+  EXPECT_EQ(*fake_observer1->events_[1].second,
+            mojom::KeyEvent(/*id=*/6u, /*type=*/mojom::KeyEventType::kPress,
+                            /*key_code=*/kKeyA.key_code,
+                            /*scan_code=*/kKeyA.at_scan_code,
+                            /*top_row_position=*/-1));
+
+  EXPECT_EQ(1u, fake_observer2->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kPause, fake_observer2->events_[0].first);
+  EXPECT_FALSE(fake_observer2->events_[0].second);
+
+  // Reset event logs for next round.
+  fake_observer1->events_.clear();
+  fake_observer2->events_.clear();
+
+  // Activate a new widget, ensuring neither previous window is active.
+  auto widget3 = CreateTestWidget();
+  widget3->Activate();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(provider1_->attached_widget_->IsActive());
+  EXPECT_FALSE(provider2_->attached_widget_->IsActive());
+
+  // Event should show key paused from previously active window.
+  EXPECT_EQ(1u, fake_observer1->events_.size());
+  EXPECT_EQ(FakeKeyboardObserver::kPause, fake_observer1->events_[0].first);
+  EXPECT_FALSE(fake_observer1->events_[0].second);
+
+  // Reset event logs for next round.
+  fake_observer1->events_.clear();
+  fake_observer2->events_.clear();
+
+  // Deliver keys to both.
+  provider1_->watchers_[6]->PostKeyEvent(true, kKeyA.key_code,
+                                         kKeyA.at_scan_code);
+  provider2_->watchers_[6]->PostKeyEvent(true, kKeyB.key_code,
+                                         kKeyB.at_scan_code);
+  base::RunLoop().RunUntilIdle();
+
+  // Neither window is visible and active, no events should be received.
+  EXPECT_FALSE(provider1_->attached_widget_->IsVisible() &&
+               provider1_->attached_widget_->IsActive());
+  EXPECT_FALSE(provider2_->attached_widget_->IsVisible() &&
+               provider2_->attached_widget_->IsActive());
+  EXPECT_EQ(0u, fake_observer1->events_.size());
+  EXPECT_EQ(0u, fake_observer2->events_.size());
+}
+
+TEST_F(InputDataProviderTest, KeyObservationTopRowBasic) {
+  // Test with Eve keyboard: [Escape, Back, ..., Louder, Menu]
+  std::unique_ptr<FakeKeyboardObserver> fake_observer =
+      std::make_unique<FakeKeyboardObserver>();
+
+  // Widget must be active and visible.
+  provider_->attached_widget_->Show();
+  provider_->attached_widget_->Activate();
+
+  // Construct a keyboard.
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event6"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  // Attach a key observer.
+  provider_->ObserveKeyEvents(
+      6u, fake_observer->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  ASSERT_TRUE(provider_->watchers_[6]);
+
+  EXPECT_KEY_EVENTS(fake_observer.get(), 6u,
+                    {{kKeyEsc, -1},
+                     {kKeyF1, 0},
+                     {kKeyF10, 9},
+                     {kKeyMenu, -1},
+                     {kKeyDelete, -1}});
+}
+
+TEST_F(InputDataProviderTest, KeyObservationTopRowUnknownAction) {
+  // Test for Vivaldi descriptor having an unrecognized scan-code;
+  // most likely due to external keyboard being newer than OS image.
+
+  std::unique_ptr<FakeKeyboardObserver> fake_observer =
+      std::make_unique<FakeKeyboardObserver>();
+
+  // Widget must be active and visible.
+  provider_->attached_widget_->Show();
+  provider_->attached_widget_->Activate();
+
+  std::vector<mojom::TopRowKey> modified_top_row_keys =
+      std::vector(std::begin(kInternalJinlonTopRowKeys),
+                  std::end(kInternalJinlonTopRowKeys));
+  modified_top_row_keys[kUnknownScancodeIndex] = mojom::TopRowKey::kUnknown;
+
+  // Construct a keyboard.
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event11"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  base::test::TestFuture<std::vector<mojom::KeyboardInfoPtr>,
+                         std::vector<mojom::TouchDeviceInfoPtr>>
+      future;
+  provider_->GetConnectedDevices(future.GetCallback());
+
+  const auto& keyboards = future.Get<0>();
+
+  ASSERT_EQ(1ul, keyboards.size());
+  const mojom::KeyboardInfoPtr& keyboard = keyboards[0];
+  EXPECT_EQ(11u, keyboard->id);
+  EXPECT_EQ(modified_top_row_keys, keyboard->top_row_keys);
+
+  // Attach a key observer.
+  provider_->ObserveKeyEvents(
+      11u, fake_observer->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  ASSERT_TRUE(provider_->watchers_[11]);
+
+  EXPECT_KEY_EVENTS(fake_observer.get(), 11u,
+                    {{kKeyEsc, -1},
+                     {kKeyActionBack, 0},
+                     {kKeyF1, 0},
+                     {kKeyActionRefresh, 1},
+                     {kKeyActionFullscreen, 2},
+                     {kKeyActionOverview, 3},
+                     {kKeyActionScreenshot, 4},
+                     {kKeyActionScreenBrightnessDown, 5},
+                     {kKeyActionScreenBrightnessUp, 6},
+                     {{0, kUnknownScancode, 0}, kUnknownScancodeIndex},
+                     {kKeyF8, 7},
+                     {kKeyActionKeyboardBrightnessDown, 8},
+                     {kKeyActionKeyboardBrightnessUp, 9},
+                     {kKeyActionKeyboardVolumeMute, 10},
+                     {kKeyF10, 9},
+                     {kKeyActionKeyboardVolumeDown, 11},
+                     {kKeyActionKeyboardVolumeUp, 12},
+                     {kKeySleep, -1}});
+}
+
+// TODO(b/208729519): Not available until we can test Drallion keyboards.
+#if 0
+TEST_F(InputDataProviderTest, KeyObservationTopRowDrallion) {
+  // Test with Drallion keyboard:
+  //  [Escape, Back, ..., Louder, F10, F11, F12, Mirror, Delete]
+  // ...
+
+  // Construct a keyboard
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event10"));
+  // ...
+  struct {
+    KeyDefinition key;
+    int position;
+  } keys[] = {
+      {kKeyA, -1},
+      {kKeyB, -1},
+      {kKeyEsc, -1},
+      {kKeyF1, 0},
+      {kKeyF10, 9},
+      {kKeyF11, 10},
+      {kKeyF12, 11},
+      {kKeySwitchVideoMode, 12},
+      {kKeyDelete, 13},
+  };
+
+  for (size_t i = 0; i < std::size(keys); i++) {
+    auto item = keys[i];
+    provider_->watchers_[10]->PostKeyEvent(true, item.key.key_code,
+         item.key.at_scan_code);
+  }
+  base::RunLoop().RunUntilIdle();
+
+  // ...
+}
+#endif  // 0
+
+TEST_F(InputDataProviderTest, KeyObservationTopRowExternalUSB) {
+  std::unique_ptr<FakeKeyboardObserver> fake_observer =
+      std::make_unique<FakeKeyboardObserver>();
+
+  // Widget must be active and visible.
+  provider_->attached_widget_->Show();
+  provider_->attached_widget_->Activate();
+
+  // Construct a keyboard.
+  const ui::DeviceEvent event0(ui::DeviceEvent::DeviceType::INPUT,
+                               ui::DeviceEvent::ActionType::ADD,
+                               base::FilePath("/dev/input/event9"));
+  provider_->OnDeviceEvent(event0);
+  base::RunLoop().RunUntilIdle();
+
+  // Attach a key observer.
+  provider_->ObserveKeyEvents(
+      9u, fake_observer->receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  ASSERT_TRUE(provider_->watchers_[9]);
+
+  // Test with generic external keyboard.
+  EXPECT_KEY_EVENTS(fake_observer.get(), 9u,
+                    {{kKeyA, -1},
+                     {kKeyB, -1},
+                     {kKeyMenu, -1},
+                     {kKeyDelete, -1},
+                     {kKeyEsc, -1},
+                     {kKeyF1, 0},
+                     {kKeyF10, 9},
+                     {kKeyF11, 10},
+                     {kKeyF12, 11}});
+}
+
+// TODO(b/211780758): Test all Fx scancodes using
+// ui/events/keycodes/dom/dom_code_data.inc as source of truth.
+
 }  // namespace diagnostics
 }  // namespace ash
diff --git a/ash/webui/diagnostics_ui/diagnostics_ui.cc b/ash/webui/diagnostics_ui/diagnostics_ui.cc
index e85cc908..b65b6362 100644
--- a/ash/webui/diagnostics_ui/diagnostics_ui.cc
+++ b/ash/webui/diagnostics_ui/diagnostics_ui.cc
@@ -391,7 +391,7 @@
   auto session_log_handler = std::make_unique<diagnostics::SessionLogHandler>(
       select_file_policy_creator, holding_space_client, log_directory_path);
   diagnostics_manager_ = std::make_unique<diagnostics::DiagnosticsManager>(
-      session_log_handler.get());
+      session_log_handler.get(), web_ui);
   web_ui->AddMessageHandler(std::move(session_log_handler));
 
   AddDiagnosticsStrings(html_source.get());
diff --git a/ash/webui/diagnostics_ui/diagnostics_ui.h b/ash/webui/diagnostics_ui/diagnostics_ui.h
index b04038da..4808a756 100644
--- a/ash/webui/diagnostics_ui/diagnostics_ui.h
+++ b/ash/webui/diagnostics_ui/diagnostics_ui.h
@@ -27,6 +27,7 @@
 
 namespace diagnostics {
 class DiagnosticsManager;
+class InputDataProvider;
 }  // namespace diagnostics
 
 // The WebDialogUI for chrome://diagnostics.
@@ -67,6 +68,7 @@
   std::unique_ptr<diagnostics::DiagnosticsManager> diagnostics_manager_;
   std::unique_ptr<diagnostics::metrics::DiagnosticsMetrics>
       diagnostics_metrics_;
+  std::unique_ptr<diagnostics::InputDataProvider> input_data_provider_;
 };
 
 }  // namespace ash
diff --git a/ash/webui/diagnostics_ui/mojom/input_data_provider.mojom b/ash/webui/diagnostics_ui/mojom/input_data_provider.mojom
index cb76da5..74c4c80 100644
--- a/ash/webui/diagnostics_ui/mojom/input_data_provider.mojom
+++ b/ash/webui/diagnostics_ui/mojom/input_data_provider.mojom
@@ -82,12 +82,53 @@
   PhysicalLayout physical_layout;
   MechanicalLayout mechanical_layout;
   NumberPadPresence number_pad_present;
-  // Excludes left-most Escape key, and right-most key (usually Power/Lock).
+  // List of ChromeOS specific action keys in the top row. This list excludes
+  // the left-most Escape key, and right-most key (usually Power/Lock).
+  // If a keyboard has F11-F15 keys beyond the rightmost action key, they may
+  // not be included in this list (even as kNone).
   array<TopRowKey> top_row_keys;
   // Only applicable to CrOS keyboards.
   bool has_assistant_key;
 };
 
+enum KeyEventType {
+  kPress,
+  kRelease,
+};
+
+// Describes an event on a connected keyboard.
+struct KeyEvent {
+  // The number of the keyboard's /dev/input/event* node.
+  uint32 id;
+  KeyEventType type;
+  // The evdev key code
+  uint32 key_code;
+  // The kernel-reported 'physical' scancode; this may be a 32-bit Usage for
+  // USB and Bluetooth HID devices, or an AT-style scancode for some internal
+  // keyboards.
+  uint32 scan_code;
+  // Position of the key on the top row after escape (0 is leftmost, 1 is next
+  // to the right, etc.), or -1 for keys not on the top row. Generally, 0 is F1,
+  // in some fashion.
+  // NOTE: This position may exceed the length of top_row_keys, for external
+  // keyboards with keys in the F11-F15 range.
+  int32 top_row_position;
+};
+
+// Implemented by clients that wish to be updated when input devices have keys
+// pressed or released, while the client has focus and is visible; pause and
+// resume events will be generated if focus/visibility changes.
+interface KeyboardObserver {
+  // Called when a key is pressed or released on the observed device, and
+  // events to this observer have not been paused.
+  OnKeyEvent(KeyEvent event);
+  // Called when delivery of events to the app are paused temporarily for
+  // security reasons. While paused, events will be discarded.
+  OnKeyEventsPaused();
+  // Called when delivery of events resumes.
+  OnKeyEventsResumed();
+};
+
 // Describes the glyphs that appear on a single key.
 struct KeyGlyphSet {
   // Glyph if pressed without modifiers. Displayed in the centre or on the lower
@@ -136,9 +177,18 @@
   GetConnectedDevices() =>
     (array<KeyboardInfo> keyboards,
      array<TouchDeviceInfo> touch_devices);
-  // Registers an observer of connected input devices.
+
+  // Registers an observer for changes to the connected input devices.
   ObserveConnectedDevices(pending_remote<ConnectedDevicesObserver> observer);
 
+  // id is the number of the keyboard device's /dev/input/event* node.
+  // Observation is cancelled when KeyboardObserver (or InputDataProvider)
+  // is destroyed.
+  // The native implementation of InputDataProvider has a reference to the
+  // target SWA window, and enforces the security policy of only forwarding
+  // key events to the observer when that window is visible and has focus.
+  ObserveKeyEvents(uint32 id, pending_remote<KeyboardObserver> observer);
+
   // Returns the visual layout for the keyboard with the given ID. For external
   // keyboards where we can't be sure of their layout, this will default to the
   // system layout.
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_types.js b/ash/webui/diagnostics_ui/resources/diagnostics_types.js
index 4b0e379..3f291f3 100644
--- a/ash/webui/diagnostics_ui/resources/diagnostics_types.js
+++ b/ash/webui/diagnostics_ui/resources/diagnostics_types.js
@@ -521,6 +521,33 @@
 export const ConnectedDevicesObserverReceiver =
     ash.diagnostics.mojom.ConnectedDevicesObserverReceiver;
 
+/**
+ * Type alias for KeyboardObserver.
+ * @typedef {ash.diagnostics.mojom.KeyboardObserver}
+ */
+export const KeyboardObserver = ash.diagnostics.mojom.CpuUsageObserver;
+
+/**
+ * Type alias for KeyboardObserverRemote.
+ * @typedef {ash.diagnostics.mojom.KeyboardObserverRemote}
+ */
+export const KeyboardObserverRemote =
+    ash.diagnostics.mojom.KeyboardObserverRemote;
+
+/**
+ * Type alias for KeyboardObserverInterface.
+ * @typedef {ash.diagnostics.mojom.KeyboardObserverInterface}
+ */
+export const KeyboardObserverInterface =
+    ash.diagnostics.mojom.KeyboardObserverInterface;
+
+/**
+ * Type alias for KeyboardObserverReceiver.
+ * @typedef {ash.diagnostics.mojom.KeyboardObserverReceiver}
+ */
+export const KeyboardObserverReceiver =
+    ash.diagnostics.mojom.KeyboardObserverReceiver;
+
 
 /**
  * Type alias for the the response from InputDataProvider.GetConnectedDevices.
diff --git a/ash/webui/diagnostics_ui/resources/fake_input_data_provider.js b/ash/webui/diagnostics_ui/resources/fake_input_data_provider.js
index 7db7417e..1936e77d 100644
--- a/ash/webui/diagnostics_ui/resources/fake_input_data_provider.js
+++ b/ash/webui/diagnostics_ui/resources/fake_input_data_provider.js
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {ConnectedDevicesObserverRemote, ConnectionType, GetConnectedDevicesResponse, GetKeyboardVisualLayoutResponse, InputDataProviderInterface, KeyboardInfo, TouchDeviceInfo, TouchDeviceType} from './diagnostics_types.js';
 import {FakeMethodResolver} from 'chrome://resources/ash/common/fake_method_resolver.js';
 
+import {ConnectedDevicesObserverRemote, ConnectionType, GetConnectedDevicesResponse, GetKeyboardVisualLayoutResponse, InputDataProviderInterface, KeyboardInfo, KeyboardObserverRemote, TouchDeviceInfo, TouchDeviceType} from './diagnostics_types.js';
+
 /**
  * @fileoverview
  * Implements a fake version of the InputDataProvider Mojo interface.
@@ -18,6 +19,8 @@
     this.observers_ = [];
     /** @private {!Array<!KeyboardInfo>} */
     this.keyboards_ = [];
+    /** @private {!Array<!Array<!KeyboardObserverRemote>>} */
+    this.keyboard_observers_ = [];
     /** @private {!Array<!TouchDeviceInfo>} */
     this.touchDevices_ = [];
 
@@ -40,6 +43,7 @@
   registerMethods() {
     this.methods_.register('getConnectedDevices');
     this.methods_.register('getKeyboardVisualLayout');
+    this.methods_.register('observeKeyEvents');
   }
 
   /**
@@ -50,6 +54,18 @@
   }
 
   /**
+   * Registers an observer for key events on the specific device.
+   * @param {number} id The ID of the keyboard to observe
+   * @param {!KeyboardObserverRemote} remote
+   */
+  observeKeyEvents(id, remote) {
+    if (!this.keyboard_observers_[id]) {
+      return;
+    }
+    this.keyboard_observers_[id].push(remote);
+  }
+
+  /**
    * Sets the values that will be returned when calling getConnectedDevices(),
    * but does not notify connected device observers of the changes.
    * @param {!Array<!KeyboardInfo>} keyboards
@@ -78,6 +94,7 @@
    */
   addFakeConnectedKeyboard(keyboard) {
     this.keyboards_.push(keyboard);
+    this.keyboard_observers_[keyboard.id] = [];
     this.methods_.setResult('getConnectedDevices',
                             {keyboards: [...this.keyboards_],
                              touchDevices: [...this.touchDevices_]});
@@ -94,6 +111,7 @@
    */
   removeFakeConnectedKeyboardById(id) {
     this.keyboards_ = this.keyboards_.filter((device) => device.id !== id);
+    delete this.keyboard_observers_[id];
 
     for (const observer of this.observers_) {
       observer.onKeyboardDisconnected(id);
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html
index b88771f..9517cd5 100644
--- a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html
+++ b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html
@@ -44,10 +44,18 @@
       <label id="progress" class="firmware-dialog-installing-font">
         [[dialogContent.footer]]
       </label>
-      <paper-progress id="updateProgressBar"
-          value="[[computePercentageValue_(installationProgress.percentage)]]"
-          max="100">
-      </paper-progress>
+      <template is="dom-if"
+          if="[[!isInIndeterminateState_(installationProgress.*)]]" restamp>
+        <paper-progress id="updateProgressBar"
+            value="[[computePercentageValue_(installationProgress.percentage)]]"
+            max="100">
+        </paper-progress>
+      </template>
+      <template is="dom-if"
+          if="[[isInIndeterminateState_(installationProgress.*)]]" restamp>
+        <paper-progress id="indeterminateProgressBar" indeterminate>
+        </paper-progress>
+      </template>
     </div>
     <div slot="button-container"
         hidden$="[[!isUpdateDone_(installationProgress.state)]]">
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js
index 163e402..23c4e30c 100644
--- a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js
+++ b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js
@@ -298,6 +298,19 @@
     }
     return initialDialogContent;
   }
+
+  /**
+   * @protected
+   * @return {boolean}
+   */
+  isInIndeterminateState_() {
+    if (this.installationProgress) {
+      return inactiveDialogStates.includes(this.installationProgress.state) ||
+          this.isDeviceRestarting_();
+    }
+
+    return false;
+  }
 }
 
 customElements.define(
diff --git a/ash/webui/multidevice_debug/BUILD.gn b/ash/webui/multidevice_debug/BUILD.gn
new file mode 100644
index 0000000..51a374f
--- /dev/null
+++ b/ash/webui/multidevice_debug/BUILD.gn
@@ -0,0 +1,40 @@
+# 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.
+
+import("//build/config/chromeos/ui_mode.gni")
+
+assert(is_chromeos_ash, "Proximity Auth is ash-chrome only")
+
+static_library("multidevice_debug") {
+  sources = [
+    "proximity_auth_ui.cc",
+    "proximity_auth_ui.h",
+    "proximity_auth_webui_handler.cc",
+    "proximity_auth_webui_handler.h",
+    "url_constants.cc",
+    "url_constants.h",
+  ]
+
+  deps = [
+    "//ash/constants",
+    "//ash/webui/resources:multidevice_debug_resources",
+    "//base",
+    "//base:i18n",
+    "//chromeos/components/multidevice/logging",
+    "//chromeos/services/device_sync/proto",
+    "//chromeos/services/device_sync/proto:util",
+    "//chromeos/services/device_sync/public/cpp",
+    "//chromeos/services/multidevice_setup/public/mojom",
+    "//chromeos/services/secure_channel/public/cpp/client",
+    "//chromeos/services/secure_channel/public/mojom",
+    "//components/prefs",
+    "//components/resources",
+    "//content/public/browser",
+    "//device/bluetooth",
+    "//device/bluetooth/public/cpp",
+    "//ui/resources",
+    "//ui/webui",
+  ]
+  public_deps = [ "//chromeos/services/device_sync/public/mojom" ]
+}
diff --git a/ash/webui/multidevice_debug/DEPS b/ash/webui/multidevice_debug/DEPS
new file mode 100644
index 0000000..d1986f4
--- /dev/null
+++ b/ash/webui/multidevice_debug/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+  "+chromeos/services/device_sync/proto",
+  "+chromeos/services/device_sync/public/cpp",
+  "+chromeos/services/multidevice_setup/public/mojom",
+  "+device/bluetooth",
+]
diff --git a/ash/webui/multidevice_debug/OWNERS b/ash/webui/multidevice_debug/OWNERS
new file mode 100644
index 0000000..7027ab73
--- /dev/null
+++ b/ash/webui/multidevice_debug/OWNERS
@@ -0,0 +1 @@
+file://chromeos/components/multidevice/OWNERS
diff --git a/ash/webui/multidevice_debug/proximity_auth_ui.cc b/ash/webui/multidevice_debug/proximity_auth_ui.cc
new file mode 100644
index 0000000..d761916
--- /dev/null
+++ b/ash/webui/multidevice_debug/proximity_auth_ui.cc
@@ -0,0 +1,61 @@
+// 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 "ash/webui/multidevice_debug/proximity_auth_ui.h"
+
+#include <memory>
+
+#include "ash/grit/ash_multidevice_debug_resources.h"
+#include "ash/webui/multidevice_debug/proximity_auth_webui_handler.h"
+#include "ash/webui/multidevice_debug/url_constants.h"
+#include "base/bind.h"
+#include "chromeos/services/device_sync/public/cpp/device_sync_client.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+namespace ash {
+
+namespace multidevice {
+
+ProximityAuthUI::ProximityAuthUI(
+    content::WebUI* web_ui,
+    device_sync::DeviceSyncClient* device_sync_client,
+    MultiDeviceSetupBinder multidevice_setup_binder)
+    : ui::MojoWebUIController(web_ui, true /* enable_chrome_send */),
+      multidevice_setup_binder_(std::move(multidevice_setup_binder)) {
+  content::WebUIDataSource* source =
+      content::WebUIDataSource::Create(kChromeUIProximityAuthHost);
+  source->SetDefaultResource(IDR_MULTIDEVICE_DEBUG_INDEX_HTML);
+  source->AddResourcePath("common.css", IDR_MULTIDEVICE_DEBUG_COMMON_CSS);
+  source->AddResourcePath("webui.js", IDR_MULTIDEVICE_DEBUG_WEBUI_JS);
+  source->AddResourcePath("logs.js", IDR_MULTIDEVICE_DEBUG_LOGS_JS);
+  source->AddResourcePath("proximity_auth.html",
+                          IDR_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_HTML);
+  source->AddResourcePath("proximity_auth.css",
+                          IDR_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_CSS);
+  source->AddResourcePath("proximity_auth.js",
+                          IDR_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_JS);
+
+  content::BrowserContext* browser_context =
+      web_ui->GetWebContents()->GetBrowserContext();
+  content::WebUIDataSource::Add(browser_context, source);
+  web_ui->AddMessageHandler(
+      std::make_unique<ProximityAuthWebUIHandler>(device_sync_client));
+}
+
+ProximityAuthUI::~ProximityAuthUI() = default;
+
+void ProximityAuthUI::BindInterface(
+    mojo::PendingReceiver<chromeos::multidevice_setup::mojom::MultiDeviceSetup>
+        receiver) {
+  multidevice_setup_binder_.Run(std::move(receiver));
+}
+
+WEB_UI_CONTROLLER_TYPE_IMPL(ProximityAuthUI)
+
+}  // namespace multidevice
+
+}  // namespace ash
diff --git a/ash/webui/multidevice_debug/proximity_auth_ui.h b/ash/webui/multidevice_debug/proximity_auth_ui.h
new file mode 100644
index 0000000..87ca22b
--- /dev/null
+++ b/ash/webui/multidevice_debug/proximity_auth_ui.h
@@ -0,0 +1,53 @@
+// 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 ASH_WEBUI_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_UI_H_
+#define ASH_WEBUI_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_UI_H_
+
+// TODO(https://crbug.com/1164001): move to forward declaration
+#include "chromeos/services/device_sync/public/cpp/device_sync_client.h"
+#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
+#include "content/public/browser/web_ui_controller.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "ui/webui/mojo_web_ui_controller.h"
+
+namespace ash {
+
+namespace multidevice {
+
+// The WebUI controller for chrome://proximity-auth.
+class ProximityAuthUI : public ui::MojoWebUIController {
+ public:
+  using MultiDeviceSetupBinder = base::RepeatingCallback<void(
+      mojo::PendingReceiver<
+          chromeos::multidevice_setup::mojom::MultiDeviceSetup>)>;
+
+  // Note: |web_ui| is not owned by this instance and must outlive this
+  // instance.
+  ProximityAuthUI(content::WebUI* web_ui,
+                  device_sync::DeviceSyncClient* device_sync_client,
+                  MultiDeviceSetupBinder multidevice_setup_binder);
+
+  ProximityAuthUI(const ProximityAuthUI&) = delete;
+  ProximityAuthUI& operator=(const ProximityAuthUI&) = delete;
+
+  ~ProximityAuthUI() override;
+
+  // Instantiates implementor of the mojom::MultiDeviceSetup mojo interface
+  // passing the pending receiver that will be internally bound.
+  void BindInterface(
+      mojo::PendingReceiver<
+          chromeos::multidevice_setup::mojom::MultiDeviceSetup> receiver);
+
+ private:
+  const MultiDeviceSetupBinder multidevice_setup_binder_;
+
+  WEB_UI_CONTROLLER_TYPE_DECL();
+};
+
+}  // namespace multidevice
+
+}  // namespace ash
+
+#endif  // ASH_WEBUI_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_UI_H_
diff --git a/ash/webui/multidevice_debug/proximity_auth_webui_handler.cc b/ash/webui/multidevice_debug/proximity_auth_webui_handler.cc
new file mode 100644
index 0000000..1732673
--- /dev/null
+++ b/ash/webui/multidevice_debug/proximity_auth_webui_handler.cc
@@ -0,0 +1,439 @@
+// 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 "ash/webui/multidevice_debug/proximity_auth_webui_handler.h"
+
+#include <algorithm>
+#include <memory>
+#include <sstream>
+#include <utility>
+
+#include "base/base64url.h"
+#include "base/bind.h"
+#include "base/i18n/time_formatting.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/default_clock.h"
+#include "base/time/default_tick_clock.h"
+#include "base/values.h"
+#include "chromeos/components/multidevice/logging/logging.h"
+#include "chromeos/components/multidevice/software_feature_state.h"
+#include "chromeos/services/device_sync/proto/enum_util.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_ui.h"
+#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
+
+namespace ash {
+
+namespace multidevice {
+
+namespace {
+
+// TODO(https://crbug.com/1164001): remove when device_sync moved to ash
+namespace device_sync = ::chromeos::device_sync;
+
+constexpr const multidevice::SoftwareFeature kAllSoftareFeatures[] = {
+    multidevice::SoftwareFeature::kBetterTogetherHost,
+    multidevice::SoftwareFeature::kBetterTogetherClient,
+    multidevice::SoftwareFeature::kSmartLockHost,
+    multidevice::SoftwareFeature::kSmartLockClient,
+    multidevice::SoftwareFeature::kInstantTetheringHost,
+    multidevice::SoftwareFeature::kInstantTetheringClient,
+    multidevice::SoftwareFeature::kMessagesForWebHost,
+    multidevice::SoftwareFeature::kMessagesForWebClient,
+    multidevice::SoftwareFeature::kPhoneHubHost,
+    multidevice::SoftwareFeature::kPhoneHubClient,
+    multidevice::SoftwareFeature::kWifiSyncHost,
+    multidevice::SoftwareFeature::kWifiSyncClient,
+    multidevice::SoftwareFeature::kEcheHost,
+    multidevice::SoftwareFeature::kEcheClient,
+    multidevice::SoftwareFeature::kPhoneHubCameraRollHost,
+    multidevice::SoftwareFeature::kPhoneHubCameraRollClient};
+
+// Keys in the JSON representation of a log message.
+const char kLogMessageTextKey[] = "text";
+const char kLogMessageTimeKey[] = "time";
+const char kLogMessageFileKey[] = "file";
+const char kLogMessageLineKey[] = "line";
+const char kLogMessageSeverityKey[] = "severity";
+
+// Keys in the JSON representation of a SyncState object for enrollment or
+// device sync.
+const char kSyncStateLastSuccessTime[] = "lastSuccessTime";
+const char kSyncStateNextRefreshTime[] = "nextRefreshTime";
+const char kSyncStateRecoveringFromFailure[] = "recoveringFromFailure";
+const char kSyncStateOperationInProgress[] = "operationInProgress";
+
+// 9999 days in milliseconds.
+const double kFakeInfinityMillis = 863913600000;
+
+double ConvertNextAttemptTimeToDouble(base::TimeDelta delta) {
+  // If no future attempt is scheduled, the next-attempt time is
+  // base::TimeDelta::Max(), which corresponds to an infinite double value. In
+  // order to store the next-attempt time as a double base::Value,
+  // std::isfinite() must be true. So, here we use 9999 days to represent the
+  // max next-attempt time to allow use with base::Value.
+  if (delta.is_max())
+    return kFakeInfinityMillis;
+
+  return delta.InMillisecondsF();
+}
+
+// Converts |log_message| to a raw dictionary value used as a JSON argument to
+// JavaScript functions.
+std::unique_ptr<base::DictionaryValue> LogMessageToDictionary(
+    const multidevice::LogBuffer::LogMessage& log_message) {
+  std::unique_ptr<base::DictionaryValue> dictionary(
+      new base::DictionaryValue());
+  dictionary->SetString(kLogMessageTextKey, log_message.text);
+  dictionary->SetString(
+      kLogMessageTimeKey,
+      base::TimeFormatTimeOfDayWithMilliseconds(log_message.time));
+  dictionary->SetString(kLogMessageFileKey, log_message.file);
+  dictionary->SetInteger(kLogMessageLineKey, log_message.line);
+  dictionary->SetInteger(kLogMessageSeverityKey,
+                         static_cast<int>(log_message.severity));
+  return dictionary;
+}
+
+// Keys in the JSON representation of an ExternalDeviceInfo proto.
+const char kExternalDevicePublicKey[] = "publicKey";
+const char kExternalDevicePublicKeyTruncated[] = "publicKeyTruncated";
+const char kExternalDeviceFriendlyName[] = "friendlyDeviceName";
+const char kExternalDeviceNoPiiName[] = "noPiiName";
+const char kExternalDeviceUnlockKey[] = "unlockKey";
+const char kExternalDeviceMobileHotspot[] = "hasMobileHotspot";
+const char kExternalDeviceFeatureStates[] = "featureStates";
+
+// Creates a SyncState JSON object that can be passed to the WebUI.
+std::unique_ptr<base::DictionaryValue> CreateSyncStateDictionary(
+    double last_success_time,
+    double next_refresh_time,
+    bool is_recovering_from_failure,
+    bool is_enrollment_in_progress) {
+  std::unique_ptr<base::DictionaryValue> sync_state(
+      new base::DictionaryValue());
+  sync_state->SetDoubleKey(kSyncStateLastSuccessTime, last_success_time);
+  sync_state->SetDoubleKey(kSyncStateNextRefreshTime, next_refresh_time);
+  sync_state->SetBoolean(kSyncStateRecoveringFromFailure,
+                         is_recovering_from_failure);
+  sync_state->SetBoolean(kSyncStateOperationInProgress,
+                         is_enrollment_in_progress);
+  return sync_state;
+}
+
+std::string GenerateFeaturesString(const multidevice::RemoteDeviceRef& device) {
+  std::stringstream ss;
+  ss << "{";
+
+  bool logged_feature = false;
+  for (const auto& software_feature : kAllSoftareFeatures) {
+    multidevice::SoftwareFeatureState state =
+        device.GetSoftwareFeatureState(software_feature);
+
+    // Only log features with values.
+    if (state == multidevice::SoftwareFeatureState::kNotSupported)
+      continue;
+
+    logged_feature = true;
+    ss << software_feature << ": " << state << ", ";
+  }
+
+  if (logged_feature)
+    ss.seekp(-2, ss.cur);  // Remove last ", " from the stream.
+
+  ss << "}";
+  return ss.str();
+}
+
+}  // namespace
+
+ProximityAuthWebUIHandler::ProximityAuthWebUIHandler(
+    device_sync::DeviceSyncClient* device_sync_client)
+    : device_sync_client_(device_sync_client),
+      web_contents_initialized_(false) {}
+
+ProximityAuthWebUIHandler::~ProximityAuthWebUIHandler() {
+  multidevice::LogBuffer::GetInstance()->RemoveObserver(this);
+
+  device_sync_client_->RemoveObserver(this);
+}
+
+void ProximityAuthWebUIHandler::RegisterMessages() {
+  web_ui()->RegisterDeprecatedMessageCallback(
+      "onWebContentsInitialized",
+      base::BindRepeating(&ProximityAuthWebUIHandler::OnWebContentsInitialized,
+                          base::Unretained(this)));
+
+  web_ui()->RegisterDeprecatedMessageCallback(
+      "clearLogBuffer",
+      base::BindRepeating(&ProximityAuthWebUIHandler::ClearLogBuffer,
+                          base::Unretained(this)));
+
+  web_ui()->RegisterDeprecatedMessageCallback(
+      "getLogMessages",
+      base::BindRepeating(&ProximityAuthWebUIHandler::GetLogMessages,
+                          base::Unretained(this)));
+
+  web_ui()->RegisterDeprecatedMessageCallback(
+      "getLocalState",
+      base::BindRepeating(&ProximityAuthWebUIHandler::GetLocalState,
+                          base::Unretained(this)));
+
+  web_ui()->RegisterDeprecatedMessageCallback(
+      "forceEnrollment",
+      base::BindRepeating(&ProximityAuthWebUIHandler::ForceEnrollment,
+                          base::Unretained(this)));
+
+  web_ui()->RegisterDeprecatedMessageCallback(
+      "forceDeviceSync",
+      base::BindRepeating(&ProximityAuthWebUIHandler::ForceDeviceSync,
+                          base::Unretained(this)));
+}
+
+void ProximityAuthWebUIHandler::OnLogMessageAdded(
+    const multidevice::LogBuffer::LogMessage& log_message) {
+  std::unique_ptr<base::DictionaryValue> dictionary =
+      LogMessageToDictionary(log_message);
+  web_ui()->CallJavascriptFunctionUnsafe("LogBufferInterface.onLogMessageAdded",
+                                         *dictionary);
+}
+
+void ProximityAuthWebUIHandler::OnLogBufferCleared() {
+  web_ui()->CallJavascriptFunctionUnsafe(
+      "LogBufferInterface.onLogBufferCleared");
+}
+
+void ProximityAuthWebUIHandler::OnEnrollmentFinished() {
+  // OnGetDebugInfo() will call NotifyOnEnrollmentFinished() with the enrollment
+  // state info.
+  enrollment_update_waiting_for_debug_info_ = true;
+  device_sync_client_->GetDebugInfo(
+      base::BindOnce(&ProximityAuthWebUIHandler::OnGetDebugInfo,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ProximityAuthWebUIHandler::OnNewDevicesSynced() {
+  // OnGetDebugInfo() will call NotifyOnSyncFinished() with the device sync
+  // state info.
+  sync_update_waiting_for_debug_info_ = true;
+  device_sync_client_->GetDebugInfo(
+      base::BindOnce(&ProximityAuthWebUIHandler::OnGetDebugInfo,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ProximityAuthWebUIHandler::OnWebContentsInitialized(
+    const base::ListValue* args) {
+  if (!web_contents_initialized_) {
+    device_sync_client_->AddObserver(this);
+    multidevice::LogBuffer::GetInstance()->AddObserver(this);
+    web_contents_initialized_ = true;
+  }
+}
+
+void ProximityAuthWebUIHandler::GetLogMessages(const base::ListValue* args) {
+  base::ListValue json_logs;
+  for (const auto& log : *multidevice::LogBuffer::GetInstance()->logs()) {
+    json_logs.Append(LogMessageToDictionary(log));
+  }
+  web_ui()->CallJavascriptFunctionUnsafe("LogBufferInterface.onGotLogMessages",
+                                         json_logs);
+}
+
+void ProximityAuthWebUIHandler::ClearLogBuffer(const base::ListValue* args) {
+  // The OnLogBufferCleared() observer function will be called after the buffer
+  // is cleared.
+  multidevice::LogBuffer::GetInstance()->Clear();
+}
+
+void ProximityAuthWebUIHandler::ForceEnrollment(const base::ListValue* args) {
+  device_sync_client_->ForceEnrollmentNow(
+      base::BindOnce(&ProximityAuthWebUIHandler::OnForceEnrollmentNow,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ProximityAuthWebUIHandler::ForceDeviceSync(const base::ListValue* args) {
+  device_sync_client_->ForceSyncNow(
+      base::BindOnce(&ProximityAuthWebUIHandler::OnForceSyncNow,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ProximityAuthWebUIHandler::GetLocalState(const base::ListValue* args) {
+  // OnGetDebugInfo() will call NotifyGotLocalState() with the enrollment and
+  // device sync state info.
+  get_local_state_update_waiting_for_debug_info_ = true;
+  device_sync_client_->GetDebugInfo(
+      base::BindOnce(&ProximityAuthWebUIHandler::OnGetDebugInfo,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+std::unique_ptr<base::Value>
+ProximityAuthWebUIHandler::GetTruncatedLocalDeviceId() {
+  absl::optional<multidevice::RemoteDeviceRef> local_device_metadata =
+      device_sync_client_->GetLocalDeviceMetadata();
+
+  std::string device_id =
+      local_device_metadata
+          ? local_device_metadata->GetTruncatedDeviceIdForLogs()
+          : "Missing Device ID";
+
+  return std::make_unique<base::Value>(device_id);
+}
+
+std::unique_ptr<base::ListValue>
+ProximityAuthWebUIHandler::GetRemoteDevicesList() {
+  std::unique_ptr<base::ListValue> devices_list_value(new base::ListValue());
+
+  for (const auto& remote_device : device_sync_client_->GetSyncedDevices())
+    devices_list_value->Append(RemoteDeviceToDictionary(remote_device));
+
+  return devices_list_value;
+}
+
+std::unique_ptr<base::DictionaryValue>
+ProximityAuthWebUIHandler::RemoteDeviceToDictionary(
+    const multidevice::RemoteDeviceRef& remote_device) {
+  // Set the fields in the ExternalDeviceInfo proto.
+  std::unique_ptr<base::DictionaryValue> dictionary(
+      new base::DictionaryValue());
+  dictionary->SetString(kExternalDevicePublicKey, remote_device.GetDeviceId());
+  dictionary->SetString(kExternalDevicePublicKeyTruncated,
+                        remote_device.GetTruncatedDeviceIdForLogs());
+  dictionary->SetString(kExternalDeviceFriendlyName, remote_device.name());
+  dictionary->SetString(kExternalDeviceNoPiiName,
+                        remote_device.pii_free_name());
+  dictionary->SetBoolean(kExternalDeviceUnlockKey,
+                         remote_device.GetSoftwareFeatureState(
+                             multidevice::SoftwareFeature::kSmartLockHost) ==
+                             multidevice::SoftwareFeatureState::kEnabled);
+  dictionary->SetBoolean(
+      kExternalDeviceMobileHotspot,
+      remote_device.GetSoftwareFeatureState(
+          multidevice::SoftwareFeature::kInstantTetheringHost) ==
+          multidevice::SoftwareFeatureState::kSupported);
+  dictionary->SetString(kExternalDeviceFeatureStates,
+                        GenerateFeaturesString(remote_device));
+
+  return dictionary;
+}
+
+void ProximityAuthWebUIHandler::OnForceEnrollmentNow(bool success) {
+  PA_LOG(VERBOSE) << "Force enrollment result: " << success;
+}
+
+void ProximityAuthWebUIHandler::OnForceSyncNow(bool success) {
+  PA_LOG(VERBOSE) << "Force sync result: " << success;
+}
+
+void ProximityAuthWebUIHandler::OnSetSoftwareFeatureState(
+    const std::string public_key,
+    device_sync::mojom::NetworkRequestResult result_code) {
+  std::string device_id = RemoteDevice::GenerateDeviceId(public_key);
+
+  if (result_code == device_sync::mojom::NetworkRequestResult::kSuccess) {
+    PA_LOG(VERBOSE) << "Successfully set SoftwareFeature state for device: "
+                    << device_id;
+  } else {
+    PA_LOG(ERROR) << "Failed to set SoftwareFeature state for device: "
+                  << device_id << ", error code: " << result_code;
+  }
+}
+
+void ProximityAuthWebUIHandler::OnGetDebugInfo(
+    device_sync::mojom::DebugInfoPtr debug_info_ptr) {
+  // If enrollment is not yet complete, no debug information is available.
+  if (!debug_info_ptr)
+    return;
+
+  if (enrollment_update_waiting_for_debug_info_) {
+    enrollment_update_waiting_for_debug_info_ = false;
+    NotifyOnEnrollmentFinished(
+        true /* success */,
+        CreateSyncStateDictionary(
+            debug_info_ptr->last_enrollment_time.ToJsTime(),
+            ConvertNextAttemptTimeToDouble(
+                debug_info_ptr->time_to_next_enrollment_attempt),
+            debug_info_ptr->is_recovering_from_enrollment_failure,
+            debug_info_ptr->is_enrollment_in_progress));
+  }
+
+  if (sync_update_waiting_for_debug_info_) {
+    sync_update_waiting_for_debug_info_ = false;
+    NotifyOnSyncFinished(true /* was_sync_successful */, true /* changed */,
+                         CreateSyncStateDictionary(
+                             debug_info_ptr->last_sync_time.ToJsTime(),
+                             ConvertNextAttemptTimeToDouble(
+                                 debug_info_ptr->time_to_next_sync_attempt),
+                             debug_info_ptr->is_recovering_from_sync_failure,
+                             debug_info_ptr->is_sync_in_progress));
+  }
+
+  if (get_local_state_update_waiting_for_debug_info_) {
+    get_local_state_update_waiting_for_debug_info_ = false;
+    NotifyGotLocalState(
+        GetTruncatedLocalDeviceId(),
+        CreateSyncStateDictionary(
+            debug_info_ptr->last_enrollment_time.ToJsTime(),
+            ConvertNextAttemptTimeToDouble(
+                debug_info_ptr->time_to_next_enrollment_attempt),
+            debug_info_ptr->is_recovering_from_enrollment_failure,
+            debug_info_ptr->is_enrollment_in_progress),
+        CreateSyncStateDictionary(
+            debug_info_ptr->last_sync_time.ToJsTime(),
+            ConvertNextAttemptTimeToDouble(
+                debug_info_ptr->time_to_next_sync_attempt),
+            debug_info_ptr->is_recovering_from_sync_failure,
+            debug_info_ptr->is_sync_in_progress),
+        GetRemoteDevicesList());
+  }
+}
+
+void ProximityAuthWebUIHandler::NotifyOnEnrollmentFinished(
+    bool success,
+    std::unique_ptr<base::DictionaryValue> enrollment_state) {
+  PA_LOG(VERBOSE) << "Enrollment attempt completed with success=" << success
+                  << ":\n"
+                  << *enrollment_state;
+  web_ui()->CallJavascriptFunctionUnsafe(
+      "LocalStateInterface.onEnrollmentStateChanged", *enrollment_state);
+}
+
+void ProximityAuthWebUIHandler::NotifyOnSyncFinished(
+    bool was_sync_successful,
+    bool changed,
+    std::unique_ptr<base::DictionaryValue> device_sync_state) {
+  PA_LOG(VERBOSE) << "Device sync completed with result=" << was_sync_successful
+                  << ":\n"
+                  << *device_sync_state;
+  web_ui()->CallJavascriptFunctionUnsafe(
+      "LocalStateInterface.onDeviceSyncStateChanged", *device_sync_state);
+
+  if (changed) {
+    std::unique_ptr<base::ListValue> synced_devices = GetRemoteDevicesList();
+    PA_LOG(VERBOSE) << "New unlock keys obtained after device sync:\n"
+                    << *synced_devices;
+    web_ui()->CallJavascriptFunctionUnsafe(
+        "LocalStateInterface.onRemoteDevicesChanged", *synced_devices);
+  }
+}
+
+void ProximityAuthWebUIHandler::NotifyGotLocalState(
+    std::unique_ptr<base::Value> truncated_local_device_id,
+    std::unique_ptr<base::DictionaryValue> enrollment_state,
+    std::unique_ptr<base::DictionaryValue> device_sync_state,
+    std::unique_ptr<base::ListValue> synced_devices) {
+  PA_LOG(VERBOSE) << "==== Got Local State ====\n"
+                  << "Device ID (truncated): " << *truncated_local_device_id
+                  << "\nEnrollment State: \n"
+                  << *enrollment_state << "Device Sync State: \n"
+                  << *device_sync_state << "Synced devices: \n"
+                  << *synced_devices;
+  web_ui()->CallJavascriptFunctionUnsafe(
+      "LocalStateInterface.onGotLocalState", *truncated_local_device_id,
+      *enrollment_state, *device_sync_state, *synced_devices);
+}
+
+}  // namespace multidevice
+
+}  // namespace ash
diff --git a/ash/webui/multidevice_debug/proximity_auth_webui_handler.h b/ash/webui/multidevice_debug/proximity_auth_webui_handler.h
new file mode 100644
index 0000000..c84bde2
--- /dev/null
+++ b/ash/webui/multidevice_debug/proximity_auth_webui_handler.h
@@ -0,0 +1,105 @@
+// 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 ASH_WEBUI_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_WEBUI_HANDLER_H_
+#define ASH_WEBUI_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_WEBUI_HANDLER_H_
+
+#include "base/memory/weak_ptr.h"
+#include "base/values.h"
+#include "chromeos/components/multidevice/logging/log_buffer.h"
+#include "chromeos/components/multidevice/remote_device_ref.h"
+#include "chromeos/services/device_sync/public/cpp/device_sync_client.h"
+#include "content/public/browser/web_ui_message_handler.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace base {
+class ListValue;
+}
+
+namespace ash {
+
+namespace multidevice {
+
+// Handles messages from the chrome://proximity-auth page.
+class ProximityAuthWebUIHandler
+    : public content::WebUIMessageHandler,
+      public multidevice::LogBuffer::Observer,
+      public device_sync::DeviceSyncClient::Observer {
+ public:
+  explicit ProximityAuthWebUIHandler(
+      device_sync::DeviceSyncClient* device_sync_client);
+
+  ProximityAuthWebUIHandler(const ProximityAuthWebUIHandler&) = delete;
+  ProximityAuthWebUIHandler& operator=(const ProximityAuthWebUIHandler&) =
+      delete;
+
+  ~ProximityAuthWebUIHandler() override;
+
+  // content::WebUIMessageHandler:
+  void RegisterMessages() override;
+
+ private:
+  // multidevice::LogBuffer::Observer:
+  void OnLogMessageAdded(
+      const multidevice::LogBuffer::LogMessage& log_message) override;
+  void OnLogBufferCleared() override;
+
+  // device_sync::DeviceSyncClient::Observer:
+  void OnEnrollmentFinished() override;
+  void OnNewDevicesSynced() override;
+
+  // Message handler callbacks.
+  void OnWebContentsInitialized(const base::ListValue* args);
+  void GetLogMessages(const base::ListValue* args);
+  void ClearLogBuffer(const base::ListValue* args);
+  void GetLocalState(const base::ListValue* args);
+  void ForceEnrollment(const base::ListValue* args);
+  void ForceDeviceSync(const base::ListValue* args);
+
+  std::unique_ptr<base::DictionaryValue> RemoteDeviceToDictionary(
+      const multidevice::RemoteDeviceRef& remote_device);
+
+  void OnForceEnrollmentNow(bool success);
+  void OnForceSyncNow(bool success);
+  void OnSetSoftwareFeatureState(
+      const std::string public_key,
+      chromeos::device_sync::mojom::NetworkRequestResult result_code);
+  void OnGetDebugInfo(
+      chromeos::device_sync::mojom::DebugInfoPtr debug_info_ptr);
+
+  void NotifyOnEnrollmentFinished(
+      bool success,
+      std::unique_ptr<base::DictionaryValue> enrollment_state);
+  void NotifyOnSyncFinished(
+      bool was_sync_successful,
+      bool changed,
+      std::unique_ptr<base::DictionaryValue> device_sync_state);
+  void NotifyGotLocalState(
+      std::unique_ptr<base::Value> truncated_local_device_id,
+      std::unique_ptr<base::DictionaryValue> enrollment_state,
+      std::unique_ptr<base::DictionaryValue> device_sync_state,
+      std::unique_ptr<base::ListValue> synced_devices);
+
+  std::unique_ptr<base::Value> GetTruncatedLocalDeviceId();
+  std::unique_ptr<base::ListValue> GetRemoteDevicesList();
+
+  // The delegate used to fetch dependencies. Must outlive this instance.
+  device_sync::DeviceSyncClient* device_sync_client_;
+
+  // True if we get a message from the loaded WebContents to know that it is
+  // initialized, and we can inject JavaScript.
+  bool web_contents_initialized_;
+
+  bool enrollment_update_waiting_for_debug_info_ = false;
+  bool sync_update_waiting_for_debug_info_ = false;
+  bool get_local_state_update_waiting_for_debug_info_ = false;
+
+  base::WeakPtrFactory<ProximityAuthWebUIHandler> weak_ptr_factory_{this};
+};
+
+}  // namespace multidevice
+
+}  // namespace ash
+
+#endif  // ASH_WEBUI_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_WEBUI_HANDLER_H_
diff --git a/ash/webui/multidevice_debug/resources/BUILD.gn b/ash/webui/multidevice_debug/resources/BUILD.gn
new file mode 100644
index 0000000..733be79
--- /dev/null
+++ b/ash/webui/multidevice_debug/resources/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2019 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.
+
+import("//build/config/chromeos/ui_mode.gni")
+import("//third_party/closure_compiler/compile_js.gni")
+
+assert(is_chromeos_ash, "Proximity Auth is ash-chrome only")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":logs",
+    ":proximity_auth",
+    ":webui",
+  ]
+}
+
+js_library("webui") {
+  externs_list = [ "$externs_path/chrome_send.js" ]
+}
+
+js_library("logs") {
+  deps = [ ":webui" ]
+}
+
+js_library("proximity_auth") {
+  deps = [
+    ":logs",
+    ":webui",
+    "//chromeos/services/multidevice_setup/public/mojom:mojom_js_library_for_compile",
+  ]
+}
diff --git a/chromeos/components/multidevice/debug_webui/resources/common.css b/ash/webui/multidevice_debug/resources/common.css
similarity index 100%
rename from chromeos/components/multidevice/debug_webui/resources/common.css
rename to ash/webui/multidevice_debug/resources/common.css
diff --git a/chromeos/components/multidevice/debug_webui/resources/index.html b/ash/webui/multidevice_debug/resources/index.html
similarity index 100%
rename from chromeos/components/multidevice/debug_webui/resources/index.html
rename to ash/webui/multidevice_debug/resources/index.html
diff --git a/ash/webui/multidevice_debug/resources/logs.js b/ash/webui/multidevice_debug/resources/logs.js
new file mode 100644
index 0000000..d7d927c
--- /dev/null
+++ b/ash/webui/multidevice_debug/resources/logs.js
@@ -0,0 +1,160 @@
+/* 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.
+ */
+
+/**
+ * @typedef {{
+ *   text: string,
+ *   time: string,
+ *   file: string,
+ *   line: number,
+ *   severity: number,
+ *}}
+ */
+let Log;
+
+const Logs = {
+  controller_: null,
+
+  /**
+   * Initializes the logs UI.
+   */
+  init: function() {
+    Logs.controller_ = new LogsListController();
+
+    const clearLogsButton = document.querySelector('#clear-logs-button');
+    clearLogsButton.onclick = function() {
+      WebUI.clearLogs();
+    };
+
+    const saveLogsButton = document.querySelector('#save-logs-button');
+    saveLogsButton.onclick = () => {
+      Logs.saveLogs();
+    };
+
+    WebUI.getLogMessages();
+  },
+
+  saveLogs: function() {
+    const blob = new Blob(
+        [document.querySelector('#logs-list').innerText],
+        {type: 'text/plain;charset=utf-8'});
+    const url = URL.createObjectURL(blob);
+
+    const anchorEl = document.createElement('a');
+    anchorEl.href = url;
+    anchorEl.download = 'proximity_auth_logs_' + new Date().toJSON() + '.txt';
+    document.body.appendChild(anchorEl);
+    anchorEl.click();
+
+    window.setTimeout(function() {
+      document.body.removeChild(anchorEl);
+      window.URL.revokeObjectURL(url);
+    }, 0);
+  },
+};
+
+/**
+ * Interface with the native WebUI component for LogBuffer events. The functions
+ * contained in this object will be invoked by the browser for each operation
+ * performed on the native LogBuffer.
+ */
+const LogBufferInterface = {
+  /**
+   * Called when a new log message is added.
+   * @param {!Log} log
+   */
+  onLogMessageAdded: function(log) {
+    if (Logs.controller_) {
+      Logs.controller_.add(log);
+    }
+  },
+
+  /**
+   * Called when the log buffer is cleared.
+   */
+  onLogBufferCleared: function() {
+    if (Logs.controller_) {
+      Logs.controller_.clear();
+    }
+  },
+
+  /**
+   * Called in response to chrome.send('getLogMessages') with the log messages
+   * currently in the buffer.
+   * @param {!Array<Log>} messages
+   */
+  onGotLogMessages: function(messages) {
+    if (Logs.controller_) {
+      Logs.controller_.set(messages);
+    }
+  },
+};
+
+/**
+ * Controller for the logs list element, updating it based on user input and
+ * logs received from native code.
+ */
+class LogsListController {
+  constructor() {
+    this.logsList_ = document.querySelector('#logs-list');
+    this.itemTemplate_ = document.querySelector('#item-template');
+    this.shouldSnapToBottom_ = true;
+
+    this.logsList_.onscroll = this.onScroll_.bind(this);
+  }
+
+  /**
+   * Listener for scroll event of the logs list element, used for snap to bottom
+   * logic.
+   */
+  onScroll_() {
+    const list = this.logsList_;
+    this.shouldSnapToBottom_ =
+        list.scrollTop + list.offsetHeight == list.scrollHeight;
+  }
+
+  /**
+   * Clears all log items from the logs list.
+   */
+  clear() {
+    const items = this.logsList_.querySelectorAll('.log-item');
+    for (let i = 0; i < items.length; ++i) {
+      items[i].remove();
+    }
+    this.shouldSnapToBottom_ = true;
+  }
+
+  /**
+   * Adds a log to the logs list.
+   * @param {!Log} log
+   */
+  add(log) {
+    const directories = log.file.split('/');
+    const source = directories[directories.length - 1] + ':' + log.line;
+
+    const t = this.itemTemplate_.content;
+    t.querySelector('.log-item').attributes.severity.value = log.severity;
+    t.querySelector('.item-time').textContent = log.time;
+    t.querySelector('.item-source').textContent = source;
+    t.querySelector('.item-text').textContent = log.text;
+
+    const newLogItem = document.importNode(this.itemTemplate_.content, true);
+    this.logsList_.appendChild(newLogItem);
+    if (this.shouldSnapToBottom_) {
+      this.logsList_.scrollTop = this.logsList_.scrollHeight;
+    }
+  }
+
+  /**
+   * Initializes the log list from an array of logs.
+   * @param {!Array<!Log>} logs
+   */
+  set(logs) {
+    this.clear();
+    for (let i = 0; i < logs.length; ++i) {
+      this.add(logs[i]);
+    }
+  }
+}
diff --git a/ash/webui/multidevice_debug/resources/multidevice_debug_resources.grd b/ash/webui/multidevice_debug/resources/multidevice_debug_resources.grd
new file mode 100644
index 0000000..18ece03
--- /dev/null
+++ b/ash/webui/multidevice_debug/resources/multidevice_debug_resources.grd
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
+  <outputs>
+    <output filename="grit/ash_multidevice_debug_resources.h" type="rc_header">
+      <emit emit_type='prepend'></emit>
+    </output>
+    <output filename="grit/ash_multidevice_debug_resources_map.cc"
+      type="resource_file_map_source" />
+    <output filename="grit/ash_multidevice_debug_resources_map.h"
+      type="resource_map_header" />
+    <output filename="ash_multidevice_debug_resources.pak" type="data_package" />
+  </outputs>
+  <release seq="1">
+    <includes>
+      <!-- Resources for ProximityAuth debug page. -->
+      <include name="IDR_MULTIDEVICE_DEBUG_INDEX_HTML" file="index.html" type="BINDATA" />
+      <include name="IDR_MULTIDEVICE_DEBUG_COMMON_CSS" file="common.css" type="BINDATA" />
+      <include name="IDR_MULTIDEVICE_DEBUG_LOGS_JS" file="logs.js" type="BINDATA" />
+      <include name="IDR_MULTIDEVICE_DEBUG_WEBUI_JS" file="webui.js" type="BINDATA" />
+      <include name="IDR_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_HTML" file="proximity_auth.html" type="BINDATA" />
+      <include name="IDR_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_CSS" file="proximity_auth.css" type="BINDATA" />
+      <include name="IDR_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_JS" file="proximity_auth.js" type="BINDATA" />
+    </includes>
+  </release>
+</grit>
diff --git a/chromeos/components/multidevice/debug_webui/resources/proximity_auth.css b/ash/webui/multidevice_debug/resources/proximity_auth.css
similarity index 100%
rename from chromeos/components/multidevice/debug_webui/resources/proximity_auth.css
rename to ash/webui/multidevice_debug/resources/proximity_auth.css
diff --git a/chromeos/components/multidevice/debug_webui/resources/proximity_auth.html b/ash/webui/multidevice_debug/resources/proximity_auth.html
similarity index 100%
rename from chromeos/components/multidevice/debug_webui/resources/proximity_auth.html
rename to ash/webui/multidevice_debug/resources/proximity_auth.html
diff --git a/ash/webui/multidevice_debug/resources/proximity_auth.js b/ash/webui/multidevice_debug/resources/proximity_auth.js
new file mode 100644
index 0000000..c7a6354c
--- /dev/null
+++ b/ash/webui/multidevice_debug/resources/proximity_auth.js
@@ -0,0 +1,361 @@
+/* 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.
+ */
+
+/**
+ * An object containing information about the Chromebook's latest Enrollment or
+ * DeviceSync call to the CryptAuth server.
+ * @typedef {{
+ *   lastSuccessTime: number,
+ *   nextRefreshTime: number,
+ *   recoveringFromFailure: boolean,
+ *   operationInProgress: boolean,
+ * }}
+ */
+let SyncState;
+
+/**
+ * @typedef {{
+ *   userPresent: number,
+ *   secureScreenLock: number,
+ *   trustAgent: number,
+ *}}
+ */
+let RemoteState;
+
+/**
+ * An object containing data for devices returned by CryptAuth DeviceSync.
+ * @typedef {{
+ *   publicKey: string,
+ *   publicKeyTruncated: string,
+ *   friendlyDeviceName: string,
+ *   noPiiName: string,
+ *   unlockKey: boolean,
+ *   hasMobileHotspot: boolean,
+ *   connectionStatus: string,
+ *   featureStates: string,
+ *   remoteState: (!RemoteState|undefined),
+ *   isArcPlusPlusEnrollment: (boolean|undefined),
+ *   isPixelPhone: (boolean|undefined),
+ *   bluetoothAddress: (string|undefined),
+ * }}
+ */
+let RemoteDevice;
+
+const ProximityAuth = {
+  cryptauthController_: null,
+  remoteDevicesController_: null,
+
+  /**
+   * Initializes all UI elements of the ProximityAuth debug page.
+   */
+  init: function() {
+    ProximityAuth.cryptauthController_ = new CryptAuthController();
+    ProximityAuth.remoteDevicesController_ = new DeviceListController(
+        document.querySelector('#remote-devices-control'));
+    WebUI.getLocalState();
+  }
+};
+
+/**
+ * Controller for the CryptAuth controls section.
+ */
+class CryptAuthController {
+  constructor() {
+    this.elements_ = {
+      localDeviceId: document.querySelector('#local-device-id'),
+      gcmRegistration: document.querySelector('#gcm-registration'),
+      currentEid: document.querySelector('#current-eid'),
+      enrollmentTitle: document.querySelector('#enrollment-title'),
+      lastEnrollment: document.querySelector('#last-enrollment'),
+      nextEnrollment: document.querySelector('#next-enrollment'),
+      enrollmentButton: document.querySelector('#force-enrollment'),
+      deviceSyncTitle: document.querySelector('#device-sync-title'),
+      lastDeviceSync: document.querySelector('#last-device-sync'),
+      nextDeviceSync: document.querySelector('#next-device-sync'),
+      deviceSyncButton: document.querySelector('#force-device-sync'),
+      newUserNotifButton: document.querySelector('#show-new-user-notif'),
+      existingUserNewHostNotifButton:
+          document.querySelector('#show-existing-user-new-host-notif'),
+      existingUserNewChromebookNotifButton:
+          document.querySelector('#show-existing-user-new-chromebook-notif'),
+    };
+
+    this.elements_.enrollmentButton.onclick = this.forceEnrollment_.bind(this);
+    this.elements_.deviceSyncButton.onclick = this.forceDeviceSync_.bind(this);
+    this.elements_.newUserNotifButton.onclick =
+        this.showNewUserNotification_.bind(this);
+    this.elements_.existingUserNewHostNotifButton.onclick =
+        this.showExistingUserNewHostNotification_.bind(this);
+    this.elements_.existingUserNewChromebookNotifButton.onclick =
+        this.showExistingUserNewChromebookNotification_.bind(this);
+
+    this.multiDeviceSetup =
+        chromeos.multideviceSetup.mojom.MultiDeviceSetup.getRemote();
+  }
+
+  /**
+   * Sets the local device's ID. Note that this value is truncated since the
+   * full value is very long and does not cleanly fit on the screen.
+   * @param {string} deviceIdTruncated
+   */
+  setLocalDeviceId(deviceIdTruncated) {
+    this.elements_.localDeviceId.textContent = deviceIdTruncated;
+  }
+
+  /**
+   * Update the enrollment state in the UI.
+   * @param {!SyncState} state
+   */
+  updateEnrollmentState(state) {
+    this.elements_.lastEnrollment.textContent =
+        this.getLastSyncTimeString_(state, 'Never enrolled');
+    this.elements_.nextEnrollment.textContent =
+        this.getNextRefreshString_(state);
+
+    if (state.recoveringFromFailure) {
+      this.elements_.enrollmentTitle.setAttribute('state', 'failure');
+    } else if (state.operationInProgress) {
+      this.elements_.enrollmentTitle.setAttribute('state', 'in-progress');
+    } else {
+      this.elements_.enrollmentTitle.setAttribute('state', 'synced');
+    }
+  }
+
+  /**
+   * Updates the device sync state in the UI.
+   * @param {!SyncState} state
+   */
+  updateDeviceSyncState(state) {
+    this.elements_.lastDeviceSync.textContent =
+        this.getLastSyncTimeString_(state, 'Never synced');
+    this.elements_.nextDeviceSync.textContent =
+        this.getNextRefreshString_(state);
+
+    if (state.recoveringFromFailure) {
+      this.elements_.deviceSyncTitle.setAttribute('state', 'failure');
+    } else if (state.operationInProgress) {
+      this.elements_.deviceSyncTitle.setAttribute('state', 'in-progress');
+    } else {
+      this.elements_.deviceSyncTitle.setAttribute('state', 'synced');
+    }
+  }
+
+  /**
+   * Returns the formatted string of the time of the last sync to be displayed.
+   * @param {!SyncState} syncState
+   * @return {string}
+   */
+  getLastSyncTimeString_(syncState, neverSyncedString) {
+    if (syncState.lastSuccessTime == 0) {
+      return neverSyncedString;
+    }
+    const date = new Date(syncState.lastSuccessTime);
+    return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
+  }
+
+  /**
+   * Returns the formatted string of the next time to refresh to be displayed.
+   * @param {!SyncState} syncState
+   * @return {string}
+   */
+  getNextRefreshString_(syncState) {
+    const deltaMillis = syncState.nextRefreshTime;
+    if (deltaMillis == null) {
+      return 'unknown';
+    }
+    if (deltaMillis == 0) {
+      return 'sync in progress...';
+    }
+
+    const seconds = deltaMillis / 1000;
+    if (seconds < 60) {
+      return Math.round(seconds) + ' seconds to refresh';
+    }
+
+    const minutes = seconds / 60;
+    if (minutes < 60) {
+      return Math.round(minutes) + ' minutes to refresh';
+    }
+
+    const hours = minutes / 60;
+    if (hours < 24) {
+      return Math.round(hours) + ' hours to refresh';
+    }
+
+    const days = hours / 24;
+    return Math.round(days) + ' days to refresh';
+  }
+
+  /**
+   * Forces a CryptAuth enrollment on button click.
+   */
+  forceEnrollment_() {
+    WebUI.forceEnrollment();
+  }
+
+  /**
+   * Forces a device sync on button click.
+   */
+  forceDeviceSync_() {
+    WebUI.forceDeviceSync();
+  }
+
+  /**
+   * Shows the "new user, potential host exists" notification.
+   */
+  showNewUserNotification_() {
+    this.showMultiDeviceSetupPromoNotification_(
+        chromeos.multideviceSetup.mojom.EventTypeForDebugging
+            .kNewUserPotentialHostExists);
+  }
+
+  /**
+   * Shows the "existing user, new host" notification.
+   */
+  showExistingUserNewHostNotification_() {
+    this.showMultiDeviceSetupPromoNotification_(
+        chromeos.multideviceSetup.mojom.EventTypeForDebugging
+            .kExistingUserConnectedHostSwitched);
+  }
+
+  /**
+   * Shows the "existing user, new Chromebook" notification.
+   */
+  showExistingUserNewChromebookNotification_() {
+    this.showMultiDeviceSetupPromoNotification_(
+        chromeos.multideviceSetup.mojom.EventTypeForDebugging
+            .kExistingUserNewChromebookAdded);
+  }
+
+  /**
+   * Shows a "MultiDevice Setup" notification of the given type.
+   * @param {!chromeos.multideviceSetup.mojom.EventTypeForDebugging} type
+   */
+  showMultiDeviceSetupPromoNotification_(type) {
+    this.multiDeviceSetup.triggerEventForDebugging(type)
+        .then(function(responseParams) {
+          if (responseParams.success) {
+            console.log(
+                'Successfully triggered notification for type ' + type + '.');
+          } else {
+            console.error(
+                'Failed to trigger notification for type ' + type +
+                '; no NotificationPresenter has been registered.');
+          }
+        })
+        .catch(function(error) {
+          console.error('Failed to trigger notification type. ' + error);
+        });
+  }
+}
+
+/**
+ * Controller for a list of remote devices. These lists are displayed in a
+ * number of locations on the debug page.
+ */
+class DeviceListController {
+  constructor(rootElement) {
+    this.rootElement_ = rootElement;
+    this.remoteDeviceTemplate_ =
+        document.querySelector('#remote-device-template');
+  }
+
+  /**
+   * Updates the UI with the given remote devices.
+   * @param {!Array<!RemoteDevice>} remoteDevices
+   */
+  updateRemoteDevices(remoteDevices) {
+    const existingItems = this.rootElement_.querySelectorAll('.remote-device');
+    for (let i = 0; i < existingItems.length; ++i) {
+      existingItems[i].remove();
+    }
+
+    for (let i = 0; i < remoteDevices.length; ++i) {
+      this.rootElement_.appendChild(
+          this.createRemoteDeviceItem_(remoteDevices[i]));
+    }
+
+    this.rootElement_.setAttribute('device-count', remoteDevices.length);
+  }
+
+  /**
+   * Creates a DOM element for a given remote device.
+   * @param {!RemoteDevice} remoteDevice
+   * @return {!Node}
+   */
+  createRemoteDeviceItem_(remoteDevice) {
+    const isUnlockKey = !!remoteDevice.unlockKey;
+    const hasMobileHotspot = !!remoteDevice.hasMobileHotspot;
+    const isArcPlusPlusEnrollment = !!remoteDevice.isArcPlusPlusEnrollment;
+    const isPixelPhone = !!remoteDevice.isPixelPhone;
+
+    const t = this.remoteDeviceTemplate_.content;
+    t.querySelector('.device-connection-status')
+        .setAttribute('state', remoteDevice.connectionStatus);
+    t.querySelector('.device-name').textContent =
+        remoteDevice.friendlyDeviceName;
+    t.querySelector('.no-pii-name').textContent = remoteDevice.noPiiName;
+    t.querySelector('.device-id').textContent = remoteDevice.publicKeyTruncated;
+    t.querySelector('.software-features').textContent =
+        remoteDevice.featureStates;
+    t.querySelector('.is-unlock-key').textContent = isUnlockKey;
+    t.querySelector('.supports-mobile-hotspot').textContent = hasMobileHotspot;
+    t.querySelector('.is-arc-plus-plus-enrollment').textContent =
+        isArcPlusPlusEnrollment;
+    t.querySelector('.is-pixel-phone').textContent = isPixelPhone;
+    if (remoteDevice.bluetoothAddress) {
+      t.querySelector('.bluetooth-address-row').classList.remove('hidden');
+      t.querySelector('.bluetooth-address').textContent =
+          remoteDevice.bluetoothAddress;
+    }
+
+    return document.importNode(this.remoteDeviceTemplate_.content, true);
+  }
+}
+
+/**
+ * Interface for the native WebUI to call into our JS.
+ */
+const LocalStateInterface = {
+  /**
+   * @param {string} localDeviceId
+   * @param {!SyncState} enrollmentState
+   * @param {!SyncState} deviceSyncState
+   * @param {!Array<!RemoteDevice>} remoteDevices
+   */
+  onGotLocalState: function(
+      localDeviceId, enrollmentState, deviceSyncState, remoteDevices) {
+    LocalStateInterface.setLocalDeviceId(localDeviceId);
+    LocalStateInterface.onEnrollmentStateChanged(enrollmentState);
+    LocalStateInterface.onDeviceSyncStateChanged(deviceSyncState);
+    LocalStateInterface.onRemoteDevicesChanged(remoteDevices);
+  },
+
+  /** @param {string} localDeviceId */
+  setLocalDeviceId: function(localDeviceId) {
+    ProximityAuth.cryptauthController_.setLocalDeviceId(localDeviceId);
+  },
+
+  /** @param {!SyncState} enrollmentState */
+  onEnrollmentStateChanged: function(enrollmentState) {
+    ProximityAuth.cryptauthController_.updateEnrollmentState(enrollmentState);
+  },
+
+  /** @param {!SyncState} deviceSyncState */
+  onDeviceSyncStateChanged: function(deviceSyncState) {
+    ProximityAuth.cryptauthController_.updateDeviceSyncState(deviceSyncState);
+  },
+
+  /** @param {!Array<!RemoteDevice>} remoteDevices */
+  onRemoteDevicesChanged: function(remoteDevices) {
+    ProximityAuth.remoteDevicesController_.updateRemoteDevices(remoteDevices);
+  }
+};
+
+document.addEventListener('DOMContentLoaded', function() {
+  WebUI.onWebContentsInitialized();
+  Logs.init();
+  ProximityAuth.init();
+});
diff --git a/chromeos/components/multidevice/debug_webui/resources/webui.js b/ash/webui/multidevice_debug/resources/webui.js
similarity index 100%
rename from chromeos/components/multidevice/debug_webui/resources/webui.js
rename to ash/webui/multidevice_debug/resources/webui.js
diff --git a/ash/webui/multidevice_debug/url_constants.cc b/ash/webui/multidevice_debug/url_constants.cc
new file mode 100644
index 0000000..168ef0714
--- /dev/null
+++ b/ash/webui/multidevice_debug/url_constants.cc
@@ -0,0 +1,16 @@
+// 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 "ash/webui/multidevice_debug/url_constants.h"
+
+namespace ash {
+
+namespace multidevice {
+
+const char kChromeUIProximityAuthHost[] = "proximity-auth";
+const char kChromeUIProximityAuthURL[] = "chrome://proximity-auth/";
+
+}  // namespace multidevice
+
+}  // namespace ash
diff --git a/ash/webui/multidevice_debug/url_constants.h b/ash/webui/multidevice_debug/url_constants.h
new file mode 100644
index 0000000..ccf60aa
--- /dev/null
+++ b/ash/webui/multidevice_debug/url_constants.h
@@ -0,0 +1,19 @@
+// 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 ASH_WEBUI_MULTIDEVICE_DEBUG_URL_CONSTANTS_H_
+#define ASH_WEBUI_MULTIDEVICE_DEBUG_URL_CONSTANTS_H_
+
+namespace ash {
+
+namespace multidevice {
+
+extern const char kChromeUIProximityAuthHost[];
+extern const char kChromeUIProximityAuthURL[];
+
+}  // namespace multidevice
+
+}  // namespace ash
+
+#endif  // ASH_WEBUI_MULTIDEVICE_DEBUG_URL_CONSTANTS_H_
diff --git a/ash/webui/personalization_app/mojom/personalization_app.mojom b/ash/webui/personalization_app/mojom/personalization_app.mojom
index 35cd50c..2b34b5c3 100644
--- a/ash/webui/personalization_app/mojom/personalization_app.mojom
+++ b/ash/webui/personalization_app/mojom/personalization_app.mojom
@@ -276,4 +276,7 @@
 
   // Select one of the default images from the provided default user images.
   SelectDefaultImage(int32 index);
+
+  // Select the downloaded profile image as the user image.
+  SelectProfileImage();
 };
diff --git a/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.html b/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.html
index 9d94be2e..14c04f1 100644
--- a/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.html
+++ b/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.html
@@ -2,7 +2,9 @@
 <div id="container">
   <p>Avatar list</p>
   <template is="dom-if" if="[[profileImage_]]">
-    <img src="[[profileImage_.url]]">
+    <img id="profileImage" src="[[profileImage_.url]]"
+        on-click="onSelectProfileImage_"
+        on-keypress="onSelectProfileImage_">
   </template>
   <template is="dom-repeat" items="[[defaultUserImages_]]">
     <img src="[[item.url.url]]" data-id$="[[item.index]]"
diff --git a/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.ts b/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.ts
index 909e774..7d19bf2 100644
--- a/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.ts
+++ b/ash/webui/personalization_app/resources/trusted/user/avatar_list_element.ts
@@ -60,6 +60,14 @@
     const index = parseInt(id, 10);
     getUserProvider().selectDefaultImage(index);
   }
+
+  private onSelectProfileImage_(event: Event) {
+    if (!isSelectionEvent(event)) {
+      return;
+    }
+
+    getUserProvider().selectProfileImage();
+  }
 }
 
 customElements.define(AvatarList.is, AvatarList);
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_user_provider.cc b/ash/webui/personalization_app/test/fake_personalization_app_user_provider.cc
index efe1254..361f4f1f 100644
--- a/ash/webui/personalization_app/test/fake_personalization_app_user_provider.cc
+++ b/ash/webui/personalization_app/test/fake_personalization_app_user_provider.cc
@@ -42,4 +42,6 @@
 
 void FakePersonalizationAppUserProvider::SelectDefaultImage(int index) {}
 
+void FakePersonalizationAppUserProvider::SelectProfileImage() {}
+
 }  // namespace ash
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_user_provider.h b/ash/webui/personalization_app/test/fake_personalization_app_user_provider.h
index dac6665..bc13d04 100644
--- a/ash/webui/personalization_app/test/fake_personalization_app_user_provider.h
+++ b/ash/webui/personalization_app/test/fake_personalization_app_user_provider.h
@@ -45,6 +45,7 @@
   void GetUserInfo(GetUserInfoCallback callback) override;
   void GetDefaultUserImages(GetDefaultUserImagesCallback callback) override;
   void SelectDefaultImage(int index) override;
+  void SelectProfileImage() override;
 
  private:
   mojo::Receiver<ash::personalization_app::mojom::UserProvider> user_receiver_{
diff --git a/ash/webui/resources/BUILD.gn b/ash/webui/resources/BUILD.gn
index 8987a7e..5cdda140 100644
--- a/ash/webui/resources/BUILD.gn
+++ b/ash/webui/resources/BUILD.gn
@@ -350,3 +350,17 @@
 
   output_dir = "$root_gen_dir/ash"
 }
+
+grit("multidevice_debug_resources") {
+  source =
+      "//ash/webui/multidevice_debug/resources/multidevice_debug_resources.grd"
+
+  outputs = [
+    "grit/ash_multidevice_debug_resources.h",
+    "grit/ash_multidevice_debug_resources_map.cc",
+    "grit/ash_multidevice_debug_resources_map.h",
+    "ash_multidevice_debug_resources.pak",
+  ]
+
+  output_dir = "$root_gen_dir/ash"
+}
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.cc b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
index 0dc4203..73b55ed 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
@@ -437,6 +437,7 @@
         state_proto_.mutable_components_repair()->add_components();
     proto_component->set_component(component.component());
     proto_component->set_repair_status(component.repair_status());
+    proto_component->set_identifier(component.identifier());
   }
   TransitionNextStateGeneric(std::move(callback));
 }
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
index 5858981..997073e5 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
@@ -1073,6 +1073,7 @@
   component->set_repair_status(
       rmad::ComponentsRepairState::ComponentRepairStatus::
           RMAD_REPAIR_STATUS_ORIGINAL);
+  component->set_identifier("Keyboard_1");
   // second component
   component = components_repair_state.mutable_state()
                   ->mutable_components_repair()
@@ -1081,6 +1082,7 @@
   component->set_repair_status(
       rmad::ComponentsRepairState::ComponentRepairStatus::
           RMAD_REPAIR_STATUS_REPLACED);
+  component->set_identifier("Touchpad_1");
   const std::vector<rmad::GetStateReply> fake_states = {
       components_repair_state,
       CreateStateReply(rmad::RmadState::kDeviceDestination,
@@ -1104,11 +1106,13 @@
         EXPECT_EQ(components[0].repair_status(),
                   rmad::ComponentsRepairState::ComponentRepairStatus::
                       RMAD_REPAIR_STATUS_ORIGINAL);
+        EXPECT_EQ(components[0].identifier(), "Keyboard_1");
         EXPECT_EQ(components[1].component(),
                   rmad::RmadComponent::RMAD_COMPONENT_TOUCHPAD);
         EXPECT_EQ(components[1].repair_status(),
                   rmad::ComponentsRepairState::ComponentRepairStatus::
                       RMAD_REPAIR_STATUS_REPLACED);
+        EXPECT_EQ(components[1].identifier(), "Touchpad_1");
         run_loop.Quit();
       }));
   run_loop.Run();
@@ -1175,11 +1179,15 @@
         EXPECT_EQ(state.components_repair().components(0).repair_status(),
                   rmad::ComponentsRepairState::ComponentRepairStatus::
                       RMAD_REPAIR_STATUS_REPLACED);
+        EXPECT_EQ(state.components_repair().components(0).identifier(),
+                  "Keyboard_1");
         EXPECT_EQ(state.components_repair().components(1).component(),
                   rmad::RmadComponent::RMAD_COMPONENT_TOUCHPAD);
         EXPECT_EQ(state.components_repair().components(1).repair_status(),
                   rmad::ComponentsRepairState::ComponentRepairStatus::
                       RMAD_REPAIR_STATUS_ORIGINAL);
+        EXPECT_EQ(state.components_repair().components(1).identifier(),
+                  "Touchpad_1");
         EXPECT_EQ(state.components_repair().mainboard_rework(), false);
       });
   base::RunLoop run_loop;
@@ -1196,10 +1204,12 @@
   components[0].set_repair_status(
       rmad::ComponentsRepairState::ComponentRepairStatus::
           RMAD_REPAIR_STATUS_REPLACED);
+  components[0].set_identifier("Keyboard_1");
   components[1].set_component(rmad::RmadComponent::RMAD_COMPONENT_TOUCHPAD);
   components[1].set_repair_status(
       rmad::ComponentsRepairState::ComponentRepairStatus::
           RMAD_REPAIR_STATUS_ORIGINAL);
+  components[1].set_identifier("Touchpad_1");
 
   shimless_rma_provider_->SetComponentList(
       std::move(components),
diff --git a/ash/webui/shimless_rma/mojom/shimless_rma.mojom b/ash/webui/shimless_rma/mojom/shimless_rma.mojom
index 7939b8e9..c7c2cb9 100644
--- a/ash/webui/shimless_rma/mojom/shimless_rma.mojom
+++ b/ash/webui/shimless_rma/mojom/shimless_rma.mojom
@@ -264,6 +264,7 @@
 struct Component {
   ComponentType component;
   ComponentRepairStatus state;
+  string identifier;
 };
 
 // Enumeration of all instructions for next steps after manually disabling write
diff --git a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.cc b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.cc
index 440cf096..5e061a9 100644
--- a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.cc
+++ b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.cc
@@ -618,6 +618,15 @@
 }
 
 // static
+const std::string&
+StructTraits<ash::shimless_rma::mojom::ComponentDataView,
+             rmad::ComponentsRepairState_ComponentRepairStatus>::
+    identifier(
+        const rmad::ComponentsRepairState_ComponentRepairStatus& component) {
+  return component.identifier();
+}
+
+// static
 MojomWpDisableAction
 EnumTraits<MojomWpDisableAction, ProtoWpDisableAction>::ToMojom(
     ProtoWpDisableAction action) {
diff --git a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h
index cc6b717..5cfcde7 100644
--- a/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h
+++ b/ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h
@@ -96,6 +96,9 @@
     return component.repair_status();
   }
 
+  static const std::string& identifier(
+      const rmad::ComponentsRepairState_ComponentRepairStatus& component);
+
   static bool Read(ash::shimless_rma::mojom::ComponentDataView data,
                    rmad::ComponentsRepairState_ComponentRepairStatus* out);
 };
diff --git a/ash/webui/shimless_rma/resources/fake_data.js b/ash/webui/shimless_rma/resources/fake_data.js
index 470edc0f..8d426b32 100644
--- a/ash/webui/shimless_rma/resources/fake_data.js
+++ b/ash/webui/shimless_rma/resources/fake_data.js
@@ -149,18 +149,42 @@
 
 /** @type {!Array<!Component>} */
 export const fakeComponents = [
-  {component: ComponentType.kCamera, state: ComponentRepairStatus.kOriginal},
-  {component: ComponentType.kBattery, state: ComponentRepairStatus.kMissing},
-  {component: ComponentType.kTouchpad, state: ComponentRepairStatus.kOriginal},
+  {
+    component: ComponentType.kCamera,
+    state: ComponentRepairStatus.kOriginal,
+    identifier: 'Camera_XYZ_1'
+  },
+  {
+    component: ComponentType.kBattery,
+    state: ComponentRepairStatus.kMissing,
+    identifier: 'Battery_XYZ_Lithium'
+  },
+  {
+    component: ComponentType.kTouchpad,
+    state: ComponentRepairStatus.kOriginal,
+    identifier: 'Touchpad_XYZ_2'
+  },
 ];
 
 // onboarding_select_components_page_test needs a components list covering all
 // possible repair states.
 /** @type {!Array<!Component>} */
 export const fakeComponentsForRepairStateTest = [
-  {component: ComponentType.kCamera, state: ComponentRepairStatus.kOriginal},
-  {component: ComponentType.kBattery, state: ComponentRepairStatus.kMissing},
-  {component: ComponentType.kTouchpad, state: ComponentRepairStatus.kReplaced},
+  {
+    component: ComponentType.kCamera,
+    state: ComponentRepairStatus.kOriginal,
+    identifier: 'Camera_XYZ_1'
+  },
+  {
+    component: ComponentType.kBattery,
+    state: ComponentRepairStatus.kMissing,
+    identifier: 'Battery_XYZ_Lithium'
+  },
+  {
+    component: ComponentType.kTouchpad,
+    state: ComponentRepairStatus.kReplaced,
+    identifier: 'Touchpad_XYZ_2'
+  },
 ];
 
 /** @type {!Array<!CalibrationComponentStatus>} */
diff --git a/ash/webui/shimless_rma/resources/onboarding_select_components_page.html b/ash/webui/shimless_rma/resources/onboarding_select_components_page.html
index d4e2c75..193dfe1a 100644
--- a/ash/webui/shimless_rma/resources/onboarding_select_components_page.html
+++ b/ash/webui/shimless_rma/resources/onboarding_select_components_page.html
@@ -16,7 +16,7 @@
           disabled$="[[isComponentDisabled_(component.disabled,
               allButtonsDisabled)]]"
           component-name="[[component.name]]"
-          component-id="[[component.uniqueId]]">
+          component-identifier="[[component.identifier]]">
         </repair-component-chip>
       </template>
     </div>
diff --git a/ash/webui/shimless_rma/resources/onboarding_select_components_page.js b/ash/webui/shimless_rma/resources/onboarding_select_components_page.js
index b31a92fb..d79a448c 100644
--- a/ash/webui/shimless_rma/resources/onboarding_select_components_page.js
+++ b/ash/webui/shimless_rma/resources/onboarding_select_components_page.js
@@ -18,7 +18,7 @@
  * @typedef {{
  *   component: !ComponentType,
  *   id: string,
- *   uniqueId: string,
+ *   identifier: string,
  *   name: string,
  *   checked: boolean,
  *   disabled: boolean
@@ -97,12 +97,11 @@
       }
 
       this.componentCheckboxes_ = result.components.map(item => {
-        const component = assert(item.component);
+        assert(item.component);
         return {
           component: item.component,
           id: ComponentTypeToId[item.component],
-          // TODO(gavinwill): Source |uniqueId| from proto.
-          uniqueId: '',
+          identifier: item.identifier,
           name: this.i18n(ComponentTypeToId[item.component]),
           checked: item.state === ComponentRepairStatus.kReplaced,
           disabled: item.state === ComponentRepairStatus.kMissing
@@ -124,7 +123,11 @@
       } else if (item.checked) {
         state = ComponentRepairStatus.kReplaced;
       }
-      return {component: item.component, state: state};
+      return {
+        component: item.component,
+        state: state,
+        identifier: item.identifier,
+      };
     });
   }
 
diff --git a/ash/webui/shimless_rma/resources/repair_component_chip.html b/ash/webui/shimless_rma/resources/repair_component_chip.html
index 4e7f04c..463d60e 100644
--- a/ash/webui/shimless_rma/resources/repair_component_chip.html
+++ b/ash/webui/shimless_rma/resources/repair_component_chip.html
@@ -39,7 +39,7 @@
     on-click="onComponentButtonClicked_">
   <div id="labelDiv">
     <span id="componentName">[[componentName]]</span>
-    <div>[[componentId]]</div>
+    <div id="componentIdentifier">[[componentIdentifier]]</div>
   </div>
   <iron-icon id="checkIcon" icon="shimless-icon24:check-circle"
       hidden="[[!checked]]">
diff --git a/ash/webui/shimless_rma/resources/repair_component_chip.js b/ash/webui/shimless_rma/resources/repair_component_chip.js
index 3d4665a6..858527e 100644
--- a/ash/webui/shimless_rma/resources/repair_component_chip.js
+++ b/ash/webui/shimless_rma/resources/repair_component_chip.js
@@ -47,7 +47,7 @@
       componentName: {type: String, value: ''},
 
       /** @type {string} */
-      componentId: {type: String, value: ''},
+      componentIdentifier: {type: String, value: ''},
     };
   }
 
diff --git a/ash/wm/desks/templates/desks_templates_dialog_controller.cc b/ash/wm/desks/templates/desks_templates_dialog_controller.cc
index 08d4e2d..0b8904e 100644
--- a/ash/wm/desks/templates/desks_templates_dialog_controller.cc
+++ b/ash/wm/desks/templates/desks_templates_dialog_controller.cc
@@ -149,7 +149,6 @@
   unsupported_apps_callback_ = std::move(callback);
   unsupported_apps_template_ = std::move(desk_template);
 
-  DesksTemplatesIconContainer* icon_container = nullptr;
   auto dialog =
       views::Builder<DesksTemplatesDialog>()
           .SetTitleText(IDS_ASH_DESKS_TEMPLATES_UNSUPPORTED_APPS_DIALOG_TITLE)
@@ -180,10 +179,9 @@
                               kTextColorPrimary))
                   .SetText(l10n_util::GetStringUTF16(
                       IDS_ASH_DESKS_TEMPLATES_UNSUPPORTED_APPS_DIALOG_HEADER)),
-              views::Builder<DesksTemplatesIconContainer>().CopyAddressTo(
-                  &icon_container))
+              views::Builder<DesksTemplatesIconContainer>()
+                  .PopulateIconContainerFromWindows(unsupported_apps))
           .Build();
-  icon_container->PopulateIconContainerFromWindows(unsupported_apps);
   CreateDialogWidget(std::move(dialog), root_window);
   RecordUnsupportedAppDialogShowHistogram();
 }
diff --git a/ash/wm/desks/templates/desks_templates_icon_container.h b/ash/wm/desks/templates/desks_templates_icon_container.h
index f8831641..ff3a440a 100644
--- a/ash/wm/desks/templates/desks_templates_icon_container.h
+++ b/ash/wm/desks/templates/desks_templates_icon_container.h
@@ -81,6 +81,9 @@
 BEGIN_VIEW_BUILDER(/* no export */,
                    DesksTemplatesIconContainer,
                    views::BoxLayoutView)
+VIEW_BUILDER_METHOD(PopulateIconContainerFromTemplate, DeskTemplate*)
+VIEW_BUILDER_METHOD(PopulateIconContainerFromWindows,
+                    const std::vector<aura::Window*>&)
 END_VIEW_BUILDER
 
 }  // namespace ash
diff --git a/ash/wm/desks/templates/desks_templates_item_view.cc b/ash/wm/desks/templates/desks_templates_item_view.cc
index 15877d02..f9a99233 100644
--- a/ash/wm/desks/templates/desks_templates_item_view.cc
+++ b/ash/wm/desks/templates/desks_templates_item_view.cc
@@ -93,8 +93,9 @@
 
 DesksTemplatesItemView::DesksTemplatesItemView(DeskTemplate* desk_template)
     : desk_template_(desk_template->Clone()) {
-  auto launch_template_callback = base::BindRepeating(
-      &DesksTemplatesItemView::OnGridItemPressed, base::Unretained(this));
+  auto launch_template_callback =
+      base::BindRepeating(&DesksTemplatesItemView::OnGridItemPressed,
+                          weak_ptr_factory_.GetWeakPtr());
 
   const std::u16string template_name = desk_template_->template_name();
   auto* color_provider = AshColorProvider::Get();
@@ -159,30 +160,30 @@
                       .SetPreferredSize(gfx::Size(
                           kTemplateNameAndTimePreferredWidth, kTimeViewHeight)),
                   views::Builder<views::View>().CopyAddressTo(&spacer),
-                  views::Builder<DesksTemplatesIconContainer>().CopyAddressTo(
-                      &icon_container_view_)),
-          views::Builder<views::View>().CopyAddressTo(&hover_container_))
+                  views::Builder<DesksTemplatesIconContainer>()
+                      .CopyAddressTo(&icon_container_view_)
+                      .PopulateIconContainerFromTemplate(desk_template_.get())
+                      .SetVisible(true)),
+          views::Builder<views::View>()
+              .CopyAddressTo(&hover_container_)
+              .SetUseDefaultFillLayout(true)
+              .SetVisible(false))
       .BuildChildren();
 
   launch_button_ = hover_container_->AddChildView(std::make_unique<PillButton>(
       base::BindRepeating(&DesksTemplatesItemView::OnGridItemPressed,
-                          base::Unretained(this)),
+                          weak_ptr_factory_.GetWeakPtr()),
       l10n_util::GetStringUTF16(IDS_ASH_DESKS_TEMPLATES_USE_TEMPLATE_BUTTON),
       PillButton::Type::kIconless, /*icon=*/nullptr));
 
   delete_button_ = hover_container_->AddChildView(std::make_unique<CloseButton>(
       base::BindRepeating(&DesksTemplatesItemView::OnDeleteButtonPressed,
-                          base::Unretained(this)),
+                          weak_ptr_factory_.GetWeakPtr()),
       CloseButton::Type::kMedium));
 
   name_view_->set_controller(this);
   name_view_observation_.Observe(name_view_);
 
-  hover_container_->SetUseDefaultFillLayout(true);
-  hover_container_->SetVisible(false);
-
-  icon_container_view_->PopulateIconContainerFromTemplate(desk_template_.get());
-  icon_container_view_->SetVisible(true);
   card_container->SetFlexForView(spacer, 1);
 
   StyleUtil::SetUpInkDropForButton(this, gfx::Insets(),
@@ -378,11 +379,12 @@
       DesksTemplatesDialogController::Get()->ShowReplaceDialog(
           root_window, new_name,
           base::BindOnce(
-              &DesksTemplatesItemView::ReplaceTemplate, base::Unretained(this),
+              &DesksTemplatesItemView::ReplaceTemplate,
+              weak_ptr_factory_.GetWeakPtr(),
               template_item->desk_template_->uuid().AsLowercaseString(),
               new_name),
           base::BindOnce(&DesksTemplatesItemView::RevertTemplateName,
-                         base::Unretained(this)));
+                         weak_ptr_factory_.GetWeakPtr()));
       return;
     }
   }
@@ -541,7 +543,7 @@
   dialog_controller->ShowDeleteDialog(
       Shell::GetPrimaryRootWindow(), name_view_->GetAccessibleName(),
       base::BindOnce(&DesksTemplatesItemView::OnDeleteTemplate,
-                     base::Unretained(this)));
+                     weak_ptr_factory_.GetWeakPtr()));
 }
 
 void DesksTemplatesItemView::OnGridItemPressed(const ui::Event& event) {
diff --git a/ash/wm/desks/templates/desks_templates_item_view.h b/ash/wm/desks/templates/desks_templates_item_view.h
index acb36fbf..1980d13 100644
--- a/ash/wm/desks/templates/desks_templates_item_view.h
+++ b/ash/wm/desks/templates/desks_templates_item_view.h
@@ -7,6 +7,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/wm/overview/overview_highlightable_view.h"
+#include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/controls/button/button.h"
@@ -167,6 +168,8 @@
 
   base::ScopedObservation<views::View, views::ViewObserver>
       name_view_observation_{this};
+
+  base::WeakPtrFactory<DesksTemplatesItemView> weak_ptr_factory_{this};
 };
 
 BEGIN_VIEW_BUILDER(/* no export */, DesksTemplatesItemView, views::Button)
diff --git a/ash/wm/desks/templates/desks_templates_unittest.cc b/ash/wm/desks/templates/desks_templates_unittest.cc
index c5bad1e..17d0497 100644
--- a/ash/wm/desks/templates/desks_templates_unittest.cc
+++ b/ash/wm/desks/templates/desks_templates_unittest.cc
@@ -32,6 +32,7 @@
 #include "ash/wm/desks/templates/desks_templates_test_util.h"
 #include "ash/wm/desks/zero_state_button.h"
 #include "ash/wm/mru_window_tracker.h"
+#include "ash/wm/overview/overview_constants.h"
 #include "ash/wm/overview/overview_grid.h"
 #include "ash/wm/overview/overview_highlight_controller.h"
 #include "ash/wm/overview/overview_item.h"
@@ -693,6 +694,23 @@
                                     expected_deletes);
 }
 
+// Tests that the save desk as template button is aligned with the first
+// overview item. Regression test for https://crbug.com/1285491.
+TEST_F(DesksTemplatesTest, SaveDeskAsTemplateButtonAligned) {
+  // Create a test window in the current desk.
+  auto test_window = CreateAppWindow();
+  ToggleOverview();
+  aura::Window* root_window = Shell::GetPrimaryRootWindow();
+  auto* overview_grid =
+      GetOverviewSession()->GetGridWithRootWindow(root_window);
+  views::Widget* save_desk_as_template_widget =
+      GetSaveDeskAsTemplateButtonForRoot(root_window);
+  auto& window_list = overview_grid->window_list();
+  ASSERT_FALSE(window_list.empty());
+  EXPECT_EQ(window_list.front()->target_bounds().x() + kWindowMargin,
+            save_desk_as_template_widget->GetWindowBoundsInScreen().x());
+}
+
 // Tests that the save desk as template button is disabled when the maximum
 // number of templates has been reached.
 TEST_F(DesksTemplatesTest, SaveDeskAsTemplateButtonDisabled) {
diff --git a/ash/wm/desks/templates/save_desk_template_button.cc b/ash/wm/desks/templates/save_desk_template_button.cc
new file mode 100644
index 0000000..eb3db8b
--- /dev/null
+++ b/ash/wm/desks/templates/save_desk_template_button.cc
@@ -0,0 +1,58 @@
+// Copyright 2022 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 "ash/wm/desks/templates/save_desk_template_button.h"
+
+#include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/strings/grit/ash_strings.h"
+#include "ash/wm/wm_highlight_item_border.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
+
+namespace ash {
+
+constexpr int kCornerRadius = 16;
+
+SaveDeskTemplateButton::SaveDeskTemplateButton(base::RepeatingClosure callback)
+    : PillButton(callback,
+                 l10n_util::GetStringUTF16(
+                     IDS_ASH_DESKS_TEMPLATES_SAVE_DESK_AS_TEMPLATE_BUTTON),
+                 PillButton::Type::kIcon,
+                 &kSaveDeskAsTemplateIcon),
+      callback_(callback) {
+  SetBorder(std::make_unique<WmHighlightItemBorder>(kCornerRadius));
+}
+
+SaveDeskTemplateButton::~SaveDeskTemplateButton() = default;
+
+views::View* SaveDeskTemplateButton::GetView() {
+  return this;
+}
+
+void SaveDeskTemplateButton::MaybeActivateHighlightedView() {
+  callback_.Run();
+}
+
+void SaveDeskTemplateButton::MaybeCloseHighlightedView() {}
+
+void SaveDeskTemplateButton::MaybeSwapHighlightedView(bool right) {}
+
+void SaveDeskTemplateButton::OnViewHighlighted() {
+  UpdateBorderState();
+}
+
+void SaveDeskTemplateButton::OnViewUnhighlighted() {
+  UpdateBorderState();
+}
+
+void SaveDeskTemplateButton::UpdateBorderState() {
+  auto* border = static_cast<WmHighlightItemBorder*>(GetBorder());
+  border->SetFocused(IsViewHighlighted());
+  SchedulePaint();
+}
+
+BEGIN_METADATA(SaveDeskTemplateButton, PillButton)
+END_METADATA
+
+}  // namespace ash
diff --git a/ash/wm/desks/templates/save_desk_template_button.h b/ash/wm/desks/templates/save_desk_template_button.h
new file mode 100644
index 0000000..8b3db81
--- /dev/null
+++ b/ash/wm/desks/templates/save_desk_template_button.h
@@ -0,0 +1,42 @@
+// Copyright 2022 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 ASH_WM_DESKS_TEMPLATES_SAVE_DESK_TEMPLATE_BUTTON_H_
+#define ASH_WM_DESKS_TEMPLATES_SAVE_DESK_TEMPLATE_BUTTON_H_
+
+#include "ash/ash_export.h"
+#include "ash/style/pill_button.h"
+#include "ash/wm/overview/overview_highlightable_view.h"
+#include "base/callback.h"
+#include "ui/base/metadata/metadata_header_macros.h"
+
+namespace ash {
+
+class ASH_EXPORT SaveDeskTemplateButton : public PillButton,
+                                          public OverviewHighlightableView {
+ public:
+  METADATA_HEADER(SaveDeskTemplateButton);
+
+  explicit SaveDeskTemplateButton(base::RepeatingClosure callback);
+  SaveDeskTemplateButton(const SaveDeskTemplateButton&) = delete;
+  SaveDeskTemplateButton& operator=(const SaveDeskTemplateButton&) = delete;
+  ~SaveDeskTemplateButton() override;
+
+ private:
+  // OverviewHighlightableView:
+  views::View* GetView() override;
+  void MaybeActivateHighlightedView() override;
+  void MaybeCloseHighlightedView() override;
+  void MaybeSwapHighlightedView(bool right) override;
+  void OnViewHighlighted() override;
+  void OnViewUnhighlighted() override;
+
+  void UpdateBorderState();
+
+  base::RepeatingClosure callback_;
+};
+
+}  // namespace ash
+
+#endif  // ASH_WM_DESKS_TEMPLATES_SAVE_DESK_TEMPLATE_BUTTON_H_
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc
index 0b103d0..471927d 100644
--- a/ash/wm/overview/overview_grid.cc
+++ b/ash/wm/overview/overview_grid.cc
@@ -19,14 +19,12 @@
 #include "ash/public/cpp/shelf_types.h"
 #include "ash/public/cpp/system/toast_catalog.h"
 #include "ash/public/cpp/window_properties.h"
-#include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/root_window_controller.h"
 #include "ash/root_window_settings.h"
 #include "ash/rotator/screen_rotation_animator.h"
 #include "ash/screen_util.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
-#include "ash/style/pill_button.h"
 #include "ash/system/toast/toast_manager_impl.h"
 #include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/desks/desk_mini_view.h"
@@ -41,6 +39,7 @@
 #include "ash/wm/desks/templates/desks_templates_name_view.h"
 #include "ash/wm/desks/templates/desks_templates_presenter.h"
 #include "ash/wm/desks/templates/desks_templates_util.h"
+#include "ash/wm/desks/templates/save_desk_template_button.h"
 #include "ash/wm/desks/zero_state_button.h"
 #include "ash/wm/mru_window_tracker.h"
 #include "ash/wm/overview/cleanup_animation_observer.h"
@@ -1850,12 +1849,10 @@
 
   if (!save_desk_as_template_widget_) {
     save_desk_as_template_widget_ = SaveDeskAsTemplateWidget(root_window_);
-    save_desk_as_template_widget_->SetContentsView(std::make_unique<PillButton>(
-        base::BindRepeating(&OverviewGrid::OnSaveDeskAsTemplateButtonPressed,
-                            weak_ptr_factory_.GetWeakPtr()),
-        l10n_util::GetStringUTF16(
-            IDS_ASH_DESKS_TEMPLATES_SAVE_DESK_AS_TEMPLATE_BUTTON),
-        PillButton::Type::kIcon, &kSaveDeskAsTemplateIcon));
+    save_desk_as_template_widget_->SetContentsView(
+        std::make_unique<SaveDeskTemplateButton>(base::BindRepeating(
+            &OverviewGrid::OnSaveDeskAsTemplateButtonPressed,
+            weak_ptr_factory_.GetWeakPtr())));
   }
   save_desk_as_template_widget_->Show();
   PerformFadeInLayer(save_desk_as_template_widget_->GetLayer());
@@ -1866,8 +1863,8 @@
   auto* desk = DesksController::Get()->active_desk();
   if (presenter->GetEntryCount() >= presenter->GetMaxEntryCount() ||
       desk->num_supported_windows() == 0) {
-    auto* button = static_cast<PillButton*>(
-        save_desk_as_template_widget_->GetContentsView());
+    auto* button = GetSaveDeskAsTemplateButton();
+    DCHECK(button);
     button->SetState(views::Button::STATE_DISABLED);
   }
 
@@ -1878,7 +1875,9 @@
   const gfx::Size preferred_size =
       save_desk_as_template_widget_->GetContentsView()->GetPreferredSize();
   save_desk_as_template_widget_->SetBounds(gfx::Rect(
-      overview_item_bounds.x(),
+      // Align the widget so it is visually aligned with the first overview
+      // item, which has a invisible border of `kWindowMargin` thickness.
+      overview_item_bounds.x() + kWindowMargin,
       overview_item_bounds.y() - kSaveDeskAsTemplateOverviewItemSpacingDp,
       preferred_size.width(), preferred_size.height()));
 
@@ -1893,6 +1892,13 @@
          save_desk_as_template_widget_->GetLayer()->GetTargetOpacity() == 1.f;
 }
 
+SaveDeskTemplateButton* OverviewGrid::GetSaveDeskAsTemplateButton() const {
+  return save_desk_as_template_widget_
+             ? static_cast<SaveDeskTemplateButton*>(
+                   save_desk_as_template_widget_->GetContentsView())
+             : nullptr;
+}
+
 void OverviewGrid::OnSplitViewStateChanged(
     SplitViewController::State previous_state,
     SplitViewController::State state) {
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h
index 1baba27..33fa6c5b4 100644
--- a/ash/wm/overview/overview_grid.h
+++ b/ash/wm/overview/overview_grid.h
@@ -34,6 +34,7 @@
 class OverviewGridEventHandler;
 class OverviewItem;
 class PresentationTimeRecorder;
+class SaveDeskTemplateButton;
 
 // Represents a grid of windows in the Overview Mode in a particular root
 // window, and manages a selection widget that can be moved with the arrow keys.
@@ -363,6 +364,9 @@
 
   bool IsSaveDeskAsTemplateButtonVisible() const;
 
+  // Returns the button if available, otherwise null.
+  SaveDeskTemplateButton* GetSaveDeskAsTemplateButton() const;
+
   // SplitViewObserver:
   void OnSplitViewStateChanged(SplitViewController::State previous_state,
                                SplitViewController::State state) override;
diff --git a/ash/wm/overview/overview_highlight_controller.cc b/ash/wm/overview/overview_highlight_controller.cc
index c2d3ad1..c731fe82 100644
--- a/ash/wm/overview/overview_highlight_controller.cc
+++ b/ash/wm/overview/overview_highlight_controller.cc
@@ -17,6 +17,7 @@
 #include "ash/wm/desks/templates/desks_templates_grid_view.h"
 #include "ash/wm/desks/templates/desks_templates_item_view.h"
 #include "ash/wm/desks/templates/desks_templates_name_view.h"
+#include "ash/wm/desks/templates/save_desk_template_button.h"
 #include "ash/wm/desks/zero_state_button.h"
 #include "ash/wm/overview/overview_grid.h"
 #include "ash/wm/overview/overview_highlightable_view.h"
@@ -252,6 +253,9 @@
         }
       }
     }
+
+    if (grid->IsSaveDeskAsTemplateButtonVisible())
+      traversable_views.push_back(grid->GetSaveDeskAsTemplateButton());
   }
   return traversable_views;
 }
diff --git a/ash/wm/overview/overview_highlight_controller_unittest.cc b/ash/wm/overview/overview_highlight_controller_unittest.cc
index 3f4fc3f..816c68c 100644
--- a/ash/wm/overview/overview_highlight_controller_unittest.cc
+++ b/ash/wm/overview/overview_highlight_controller_unittest.cc
@@ -15,6 +15,7 @@
 #include "ash/wm/desks/desks_test_util.h"
 #include "ash/wm/desks/expanded_desks_bar_button.h"
 #include "ash/wm/desks/templates/desks_templates_util.h"
+#include "ash/wm/desks/templates/save_desk_template_button.h"
 #include "ash/wm/desks/zero_state_button.h"
 #include "ash/wm/overview/overview_constants.h"
 #include "ash/wm/overview/overview_controller.h"
@@ -437,13 +438,17 @@
   CheckDeskBarViewSize(desk_bar_view, "new desk button");
 
   // Tests that tabbing past the new desk button, we highlight the desks
-  // templates button.
+  // templates button and the button to save to a new desk template.
   if (IsDesksTemplatesEnabled()) {
     SendKey(ui::VKEY_TAB);
     EXPECT_EQ(
         desk_bar_view->expanded_state_desks_templates_button()->inner_button(),
         GetHighlightedView());
     CheckDeskBarViewSize(desk_bar_view, "desks templates button");
+
+    SendKey(ui::VKEY_TAB);
+    EXPECT_EQ(desk_bar_view->overview_grid()->GetSaveDeskAsTemplateButton(),
+              GetHighlightedView());
   }
 
   // Tests that after tabbing through the overview items, we go back to the
@@ -464,10 +469,14 @@
       GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
   EXPECT_EQ(2u, desk_bar_view->mini_views().size());
 
-  // Tests that the first highlight item when reversing is the desks templates
-  // button if the feature is enabled.
+  // Tests that the first highlighted item when reversing is the save desk as
+  // template button, if the feature is enabled.
   if (IsDesksTemplatesEnabled()) {
     SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
+    EXPECT_EQ(desk_bar_view->overview_grid()->GetSaveDeskAsTemplateButton(),
+              GetHighlightedView());
+
+    SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
     EXPECT_EQ(
         desk_bar_view->expanded_state_desks_templates_button()->inner_button(),
         GetHighlightedView());
@@ -498,11 +507,15 @@
   auto* item1 = GetOverviewItemForWindow(window1.get());
   EXPECT_EQ(item1->overview_item_view(), GetHighlightedView());
 
-  // Tests that we return to the desks templates button after reverse tabbing
-  // through the overview items if the feature was enabled.
+  // Tests that we return to the save desk as template button after reverse
+  // tabbing through the overview items if the feature was enabled.
   if (IsDesksTemplatesEnabled()) {
     SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
     SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
+    EXPECT_EQ(desk_bar_view->overview_grid()->GetSaveDeskAsTemplateButton(),
+              GetHighlightedView());
+
+    SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
     EXPECT_EQ(
         desk_bar_view->expanded_state_desks_templates_button()->inner_button(),
         GetHighlightedView());
@@ -562,6 +575,10 @@
     EXPECT_EQ(
         desk_bar_view1->expanded_state_desks_templates_button()->inner_button(),
         GetHighlightedView());
+
+    SendKey(ui::VKEY_TAB);
+    EXPECT_EQ(desk_bar_view1->overview_grid()->GetSaveDeskAsTemplateButton(),
+              GetHighlightedView());
   }
 
   // Tests that the next tab will bring us to the first overview item on the
@@ -586,6 +603,10 @@
     EXPECT_EQ(
         desk_bar_view2->expanded_state_desks_templates_button()->inner_button(),
         GetHighlightedView());
+
+    SendKey(ui::VKEY_TAB);
+    EXPECT_EQ(desk_bar_view2->overview_grid()->GetSaveDeskAsTemplateButton(),
+              GetHighlightedView());
   }
 
   // Tests that after tabbing through the items on the second display, the
@@ -610,6 +631,10 @@
     EXPECT_EQ(
         desk_bar_view3->expanded_state_desks_templates_button()->inner_button(),
         GetHighlightedView());
+
+    SendKey(ui::VKEY_TAB);
+    EXPECT_EQ(desk_bar_view3->overview_grid()->GetSaveDeskAsTemplateButton(),
+              GetHighlightedView());
   }
 
   // Tests that after tabbing through the items on the third display, the next
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc
index 6fd5191..a4fe73c 100644
--- a/ash/wm/window_util.cc
+++ b/ash/wm/window_util.cc
@@ -45,6 +45,7 @@
 #include "ui/compositor/layer_tree_owner.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
+#include "ui/events/event.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/transform_util.h"
@@ -445,5 +446,15 @@
   return account_id == multi_user_window_manager->CurrentAccountId();
 }
 
+aura::Window* GetEventHandlerForEvent(const ui::LocatedEvent& event) {
+  gfx::Point location_in_screen = event.location();
+  ::wm::ConvertPointToScreen(static_cast<aura::Window*>(event.target()),
+                             &location_in_screen);
+  aura::Window* root_window_at_point = GetRootWindowAt(location_in_screen);
+  gfx::Point location_in_root = location_in_screen;
+  ::wm::ConvertPointFromScreen(root_window_at_point, &location_in_root);
+  return root_window_at_point->GetEventHandlerForPoint(location_in_root);
+}
+
 }  // namespace window_util
 }  // namespace ash
diff --git a/ash/wm/window_util.h b/ash/wm/window_util.h
index 2d473b7..43f6fe2d 100644
--- a/ash/wm/window_util.h
+++ b/ash/wm/window_util.h
@@ -23,6 +23,10 @@
 class RectF;
 }  // namespace gfx
 
+namespace ui {
+class LocatedEvent;
+}  // namespace ui
+
 namespace ash {
 
 namespace window_util {
@@ -144,6 +148,8 @@
 // user.
 bool ShouldShowForCurrentUser(aura::Window* window);
 
+ASH_EXPORT aura::Window* GetEventHandlerForEvent(const ui::LocatedEvent& event);
+
 }  // namespace window_util
 }  // namespace ash
 
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 29d888d..247befa 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1280,8 +1280,8 @@
       "ios/ns_range.h",
       "ios/scoped_critical_action.h",
       "ios/scoped_critical_action.mm",
-      "message_loop/message_pump_kqueue.cc",
-      "message_loop/message_pump_kqueue.h",
+      "message_loop/message_pump_io_ios.cc",
+      "message_loop/message_pump_io_ios.h",
       "native_library_ios.mm",
       "process/launch_ios.cc",
       "process/process_metrics_ios.cc",
@@ -3611,7 +3611,7 @@
     sources += [
       "ios/device_util_unittest.mm",
       "ios/weak_nsobject_unittest.mm",
-      "message_loop/message_pump_kqueue_unittest.cc",
+      "message_loop/message_pump_io_ios_unittest.cc",
     ]
 
     # ios does not use test_launcher to run gtests.
diff --git a/base/allocator/partition_allocator/hardening_unittest.cc b/base/allocator/partition_allocator/hardening_unittest.cc
index 602166f..3b600a2 100644
--- a/base/allocator/partition_allocator/hardening_unittest.cc
+++ b/base/allocator/partition_allocator/hardening_unittest.cc
@@ -21,7 +21,7 @@
 
 // Death tests misbehave on Android, crbug.com/1240184
 #if !BUILDFLAG(IS_ANDROID) && defined(GTEST_HAS_DEATH_TEST) && \
-    defined(PA_HAS_FREELIST_HARDENING)
+    defined(PA_HAS_FREELIST_SHADOW_ENTRY)
 
 TEST(HardeningTest, PartialCorruption) {
   std::string important_data("very important");
@@ -107,7 +107,7 @@
   EXPECT_DEATH(root.Alloc(kAllocSize, ""), "");
 }
 #endif  // !BUILDFLAG(IS_ANDROID) && defined(GTEST_HAS_DEATH_TEST) &&
-        // defined(PA_HAS_FREELIST_HARDENING)
+        // defined(PA_HAS_FREELIST_SHADOW_ENTRY)
 
 TEST(HardeningTest, SuccessfulCorruption) {
   PartitionRoot<ThreadSafe> root({
diff --git a/base/allocator/partition_allocator/partition_alloc_config.h b/base/allocator/partition_allocator/partition_alloc_config.h
index f0b9ed047..390cca7 100644
--- a/base/allocator/partition_allocator/partition_alloc_config.h
+++ b/base/allocator/partition_allocator/partition_alloc_config.h
@@ -106,18 +106,19 @@
 // hence enabled by default.
 #define PA_THREAD_CACHE_ENABLE_STATISTICS
 
-// Enable free list hardening as much as possible.
+// Enable free list shadow entry to strengthen hardening as much as possible.
+// The shadow entry is an inversion (bitwise-NOT) of the encoded `next` pointer.
 //
-// Disabled when putting refcount in the previous slot, which is what
-// PUT_REF_COUNT_IN_PREVIOUS_SLOT does. In this case the refcount overlaps with
-// the next pointer shadow for the smallest bucket.
+// Disabled when ref-count is placed in the previous slot, as it will overlap
+// with the shadow for the smallest slots.
 //
-// Only for Little endian CPUs, as the freelist encoding used on big endian
-// platforms complicates things. Note that Chromium is not officially supported
-// on any big endian architecture as well.
+// Disabled on Big Endian CPUs, because encoding is also a bitwise-NOT there,
+// making the shadow entry equal to the original, valid pointer to the next
+// slot. In case Use-after-Free happens, we'd rather not hand out a valid,
+// ready-to-use pointer.
 #if !BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) && \
     defined(ARCH_CPU_LITTLE_ENDIAN)
-#define PA_HAS_FREELIST_HARDENING
+#define PA_HAS_FREELIST_SHADOW_ENTRY
 #endif
 
 // Specifies whether allocation extras need to be added.
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc
index a6fd7cd..10eee42 100644
--- a/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -2061,7 +2061,7 @@
 #endif
 
 // These tests rely on precise layout. They handle cookie, not ref-count.
-#if !BUILDFLAG(USE_BACKUP_REF_PTR) && defined(PA_HAS_FREELIST_HARDENING)
+#if !BUILDFLAG(USE_BACKUP_REF_PTR) && defined(PA_HAS_FREELIST_SHADOW_ENTRY)
 
 TEST_F(PartitionAllocDeathTest, UseAfterFreeDetection) {
   CPU cpu;
@@ -2141,7 +2141,8 @@
 }
 #endif  // !DCHECK_IS_ON()
 
-#endif  // !BUILDFLAG(USE_BACKUP_REF_PTR) && defined(PA_HAS_FREELIST_HARDENING)
+#endif  // !BUILDFLAG(USE_BACKUP_REF_PTR) &&
+        // defined(PA_HAS_FREELIST_SHADOW_ENTRY)
 
 #endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
 
diff --git a/base/allocator/partition_allocator/partition_freelist_entry.h b/base/allocator/partition_allocator/partition_freelist_entry.h
index 09b48f7a..cb20598 100644
--- a/base/allocator/partition_allocator/partition_freelist_entry.h
+++ b/base/allocator/partition_allocator/partition_freelist_entry.h
@@ -14,6 +14,7 @@
 #include "base/allocator/partition_allocator/partition_alloc_config.h"
 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
 #include "base/allocator/partition_allocator/partition_ref_count.h"
+#include "base/bits.h"
 #include "base/compiler_specific.h"
 #include "base/dcheck_is_on.h"
 #include "base/immediate_crash.h"
@@ -25,39 +26,16 @@
 
 namespace {
 
-#if defined(PA_HAS_FREELIST_HARDENING) || DCHECK_IS_ON()
 [[noreturn]] NOINLINE void FreelistCorruptionDetected(size_t extra) {
   // Make it visible in minidumps.
   PA_DEBUG_DATA_ON_STACK("extra", extra);
   IMMEDIATE_CRASH();
 }
-#endif  // defined(PA_HAS_FREELIST_HARDENING) || DCHECK_IS_ON()
 
 }  // namespace
 
 class PartitionFreelistEntry;
 
-#if defined(PA_HAS_FREELIST_HARDENING)
-static_assert(kSmallestBucket >= 2 * sizeof(void*),
-              "Need enough space for two pointers in freelist entries");
-#endif
-
-#if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)
-constexpr size_t kMinimalBucketSizeWithRefCount =
-    (1 + sizeof(PartitionRefCount) + kSmallestBucket - 1) &
-    ~(kSmallestBucket - 1);
-#if defined(PA_HAS_FREELIST_HARDENING)
-static_assert(
-    kMinimalBucketSizeWithRefCount >=
-        sizeof(PartitionRefCount) + 2 * sizeof(void*),
-    "Need enough space for two pointer and one refcount in freelist entries");
-#else
-static_assert(
-    kMinimalBucketSizeWithRefCount >= sizeof(PartitionRefCount) + sizeof(void*),
-    "Need enough space for one pointer and one refcount in freelist entries");
-#endif
-#endif
-
 class EncodedPartitionFreelistEntryPtr {
  private:
   explicit ALWAYS_INLINE constexpr EncodedPartitionFreelistEntryPtr(
@@ -110,7 +88,7 @@
  private:
   explicit constexpr PartitionFreelistEntry(nullptr_t)
       : encoded_next_(EncodedPartitionFreelistEntryPtr(nullptr))
-#if defined(PA_HAS_FREELIST_HARDENING)
+#if defined(PA_HAS_FREELIST_SHADOW_ENTRY)
         ,
         shadow_(encoded_next_.Inverted())
 #endif
@@ -118,7 +96,7 @@
   }
   explicit PartitionFreelistEntry(PartitionFreelistEntry* next)
       : encoded_next_(EncodedPartitionFreelistEntryPtr(next))
-#if defined(PA_HAS_FREELIST_HARDENING)
+#if defined(PA_HAS_FREELIST_SHADOW_ENTRY)
         ,
         shadow_(encoded_next_.Inverted())
 #endif
@@ -127,7 +105,7 @@
   // For testing only.
   PartitionFreelistEntry(void* next, bool make_shadow_match)
       : encoded_next_(EncodedPartitionFreelistEntryPtr(next))
-#if defined(PA_HAS_FREELIST_HARDENING)
+#if defined(PA_HAS_FREELIST_SHADOW_ENTRY)
         ,
         shadow_(make_shadow_match ? encoded_next_.Inverted() : 12345)
 #endif
@@ -179,20 +157,16 @@
   ALWAYS_INLINE PartitionFreelistEntry* GetNext(size_t extra) const;
 
   NOINLINE void CheckFreeList(size_t extra) const {
-#if defined(PA_HAS_FREELIST_HARDENING)
     for (auto* entry = this; entry; entry = entry->GetNext(extra)) {
       // |GetNext()| checks freelist integrity.
     }
-#endif
   }
 
   NOINLINE void CheckFreeListForThreadCache(size_t extra) const {
-#if defined(PA_HAS_FREELIST_HARDENING)
     for (auto* entry = this; entry;
          entry = entry->GetNextForThreadCache(extra)) {
       // |GetNextForThreadCache()| checks freelist integrity.
     }
-#endif
   }
 
   ALWAYS_INLINE void SetNext(PartitionFreelistEntry* ptr) {
@@ -211,7 +185,7 @@
 #endif  // DCHECK_IS_ON()
 
     encoded_next_ = EncodedPartitionFreelistEntryPtr(ptr);
-#if defined(PA_HAS_FREELIST_HARDENING)
+#if defined(PA_HAS_FREELIST_SHADOW_ENTRY)
     shadow_ = encoded_next_.Inverted();
 #endif
   }
@@ -221,7 +195,7 @@
   // data.
   ALWAYS_INLINE uintptr_t ClearForAllocation() {
     encoded_next_.Override(0);
-#if defined(PA_HAS_FREELIST_HARDENING)
+#if defined(PA_HAS_FREELIST_SHADOW_ENTRY)
     shadow_ = 0;
 #endif
     uintptr_t slot_start = reinterpret_cast<uintptr_t>(this);
@@ -236,7 +210,7 @@
   ALWAYS_INLINE PartitionFreelistEntry* GetNextInternal(
       size_t extra,
       bool for_thread_cache) const;
-#if defined(PA_HAS_FREELIST_HARDENING)
+
   static ALWAYS_INLINE bool IsSane(const PartitionFreelistEntry* here,
                                    const PartitionFreelistEntry* next,
                                    bool for_thread_cache) {
@@ -251,7 +225,11 @@
     uintptr_t here_address = reinterpret_cast<uintptr_t>(here);
     uintptr_t next_address = reinterpret_cast<uintptr_t>(next);
 
+#if defined(PA_HAS_FREELIST_SHADOW_ENTRY)
     bool shadow_ptr_ok = here->encoded_next_.Inverted() == here->shadow_;
+#else
+    bool shadow_ptr_ok = true;
+#endif
 
     bool same_superpage = (here_address & kSuperPageBaseMask) ==
                           (next_address & kSuperPageBaseMask);
@@ -266,17 +244,31 @@
     else
       return shadow_ptr_ok & same_superpage & not_in_metadata;
   }
-#endif  // defined(PA_HAS_FREELIST_HARDENING)
 
   EncodedPartitionFreelistEntryPtr encoded_next_;
   // This is intended to detect unintentional corruptions of the freelist.
   // These can happen due to a Use-after-Free, or overflow of the previous
   // allocation in the slot span.
-#if defined(PA_HAS_FREELIST_HARDENING)
+#if defined(PA_HAS_FREELIST_SHADOW_ENTRY)
   uintptr_t shadow_;
 #endif
 };
 
+static_assert(kSmallestBucket >= sizeof(PartitionFreelistEntry),
+              "Need enough space for freelist entries in the smallest slot");
+#if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)
+// The smallest bucket actually used. Note that the smallest request is 1 (if
+// it's 0, it gets patched to 1), and ref-count gets added to it.
+namespace {
+constexpr size_t kSmallestUsedBucket =
+    bits::AlignUp(1 + sizeof(PartitionRefCount), kSmallestBucket);
+}
+static_assert(kSmallestUsedBucket >=
+                  sizeof(PartitionFreelistEntry) + sizeof(PartitionRefCount),
+              "Need enough space for freelist entries and the ref-count in the "
+              "smallest *used* slot");
+#endif  // BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)
+
 ALWAYS_INLINE PartitionFreelistEntry* PartitionFreelistEntry::GetNextInternal(
     size_t extra,
     bool for_thread_cache) const {
@@ -286,12 +278,10 @@
     return nullptr;
 
   auto* ret = encoded_next_.Decode();
-#if defined(PA_HAS_FREELIST_HARDENING)
   // We rely on constant propagation to remove the branches coming from
   // |for_thread_cache|, since the argument is always a compile-time constant.
   if (UNLIKELY(!IsSane(this, ret, for_thread_cache)))
     FreelistCorruptionDetected(extra);
-#endif
 
   // In real-world profiles, the load of |encoded_next_| above is responsible
   // for a large fraction of the allocation cost. However, we cannot anticipate
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h
index 465ac1e..2bc95e39 100644
--- a/base/allocator/partition_allocator/partition_root.h
+++ b/base/allocator/partition_allocator/partition_root.h
@@ -417,8 +417,9 @@
   NOINLINE static void Free(void* ptr);
   // Same as |Free()|, bypasses the allocator hooks.
   ALWAYS_INLINE static void FreeNoHooks(void* ptr);
-  // Immediately frees the pointer bypassing the quarantine.
-  ALWAYS_INLINE void FreeNoHooksImmediate(uintptr_t address,
+  // Immediately frees the pointer bypassing the quarantine. |slot_start| is the
+  // beginning of the slot that contains |object|.
+  ALWAYS_INLINE void FreeNoHooksImmediate(uintptr_t object,
                                           SlotSpan* slot_span,
                                           uintptr_t slot_start);
 
@@ -1077,7 +1078,7 @@
 
 template <bool thread_safe>
 ALWAYS_INLINE void PartitionRoot<thread_safe>::FreeNoHooksImmediate(
-    uintptr_t address,
+    uintptr_t object,
     SlotSpan* slot_span,
     uintptr_t slot_start) {
   // The thread cache is added "in the middle" of the main allocator, that is:
@@ -1089,31 +1090,37 @@
   // 2. Deallocation
   //   a. Return to the thread cache if possible. If it succeeds, return.
   //   b. Otherwise, call the "raw" allocator <-- Locking
-  PA_DCHECK(address);
+  PA_DCHECK(object);
   PA_DCHECK(slot_span);
   PA_DCHECK(IsValidSlotSpan(slot_span));
   PA_DCHECK(slot_start);
 
-  // |address| points after the ref-count.
-  //
   // Layout inside the slot:
-  //  <-extras->                  <-extras->
-  //  <-------GetUtilizedSlotSize()-------->
-  //           <-GetUsableSize()-->
-  //  |[refcnt]|...data...|[empty]|[cookie]|[unused]|
-  //           ^
-  //        address
+  //   |[refcnt]|...object...|[empty]|[cookie]|[unused]|
+  //            <--------(a)--------->
+  //   <--(b)--->         +          <--(b)--->
+  //   <-----------------(c)------------------>
+  //     (a) usable_size
+  //     (b) extras
+  //     (c) utilized_slot_size
+  //
+  // If PUT_REF_COUNT_IN_PREVIOUS_SLOT is set, the layout is:
+  //   |...object...|[empty]|[cookie]|[unused]|[refcnt]|
+  //   <--------(a)--------->
+  //                        <--(b)--->   +    <--(b)--->
+  //   <-------------(c)------------->   +    <--(c)--->
   //
   // Note: ref-count and cookie can be 0-sized.
   //
-  // For more context, see the other "Layout inside the slot" comment below.
+  // For more context, see the other "Layout inside the slot" comment inside
+  // AllocFlagsNoHooks().
 
 #if DCHECK_IS_ON()
   if (allow_cookie) {
     // Verify the cookie after the allocated region.
     // If this assert fires, you probably corrupted memory.
     internal::PartitionCookieCheckValue(
-        reinterpret_cast<unsigned char*>(address) +
+        reinterpret_cast<unsigned char*>(object) +
         slot_span->GetUsableSize(this));
   }
 #endif
@@ -1121,7 +1128,7 @@
   // TODO(bikineev): Change the condition to LIKELY once PCScan is enabled by
   // default.
   if (UNLIKELY(IsQuarantineEnabled())) {
-    if (LIKELY(internal::IsManagedByNormalBuckets(address))) {
+    if (LIKELY(internal::IsManagedByNormalBuckets(object))) {
       uintptr_t unmasked_slot_start = memory::UnmaskPtr(slot_start);
       // Mark the state in the state bitmap as freed.
       internal::StateBitmapFromAddr(unmasked_slot_start)
@@ -1138,7 +1145,7 @@
     // immediately. Otherwise, defer the operation and zap the memory to turn
     // potential use-after-free issues into unexploitable crashes.
     if (UNLIKELY(!ref_count->IsAliveWithNoKnownRefs()))
-      internal::SecureMemset(reinterpret_cast<void*>(address), kQuarantinedByte,
+      internal::SecureMemset(reinterpret_cast<void*>(object), kQuarantinedByte,
                              slot_span->GetUsableSize(this));
 
     if (UNLIKELY(!(ref_count->ReleaseFromAllocator()))) {
@@ -1575,23 +1582,22 @@
     return nullptr;
 
   // Layout inside the slot:
-  //  |[refcnt]|...data...|[empty]|[cookie]|[unused]|
-  //           <---(a)---->
-  //           <-------(b)-------->
-  //  <--(c)--->                  <--(c)--->
-  //  <--------(d)-------->   +   <--(d)--->
-  //  <----------------(e)----------------->
-  //  <---------------------(f)--------------------->
-  //   (a) requested_size
-  //   (b) usable_size
-  //   (c) extras
-  //   (d) raw_size
-  //   (e) utilized_slot_size
-  //   (f) slot_size
-  //
-  // - Ref-count may or may not exist in the slot, depending on raw_ptr<T>
-  //   implementation.
-  // - Cookie exists only when DCHECK is on.
+  //   |[refcnt]|...object...|[empty]|[cookie]|[unused]|
+  //            <----(a)----->
+  //            <--------(b)--------->
+  //   <--(c)--->         +          <--(c)--->
+  //   <---------(d)--------->   +   <--(d)--->
+  //   <-----------------(e)------------------>
+  //   <----------------------(f)---------------------->
+  //     (a) requested_size
+  //     (b) usable_size
+  //     (c) extras
+  //     (d) raw_size
+  //     (e) utilized_slot_size
+  //     (f) slot_size
+  // Notes:
+  // - Ref-count may or may not exist in the slot, depending on brp_enabled().
+  // - Cookie exists only in the DCHECK_IS_ON() case.
   // - Think of raw_size as the minimum size required internally to satisfy
   //   the allocation request (i.e. requested_size + extras)
   // - Note, at most one "empty" or "unused" space can occur at a time. It
@@ -1605,37 +1611,28 @@
   //   we have no other choice than putting the cookie at the very end of the
   //   slot, thus creating the "empty" space.
   //
-  // If BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) is true, Layout inside the
-  // slot of small buckets:
-  //  |...data...|[empty]|[cookie]|[refcnt]|
-  //  <---(a)---->
-  //  <-------(b)-------->
-  //                     <-------(c)------->
-  //  <---(d)---->   +   <-------(d)------->
-  //  <----------------(e)----------------->
-  //  <----------------(f)----------------->
-  //
-  // If the slot start address is not SystemPageSize() aligned (this also means,
-  // the slot size is small), [refcnt] of this slot is stored at the end of
-  // the previous slot. So this makes us to obtain refcount address with slot
-  // start address minus sizeof(refcount).
-  // If the slot start address is SystemPageSize() aligned (regarding single
-  // slot span, the slot start address is always SystemPage size-aligned),
-  // [refcnt] is stored in refcount bitmap placed after SuperPage metadata.
-  // However, the space for refcnt is still reserved at the end of slot, even
-  // though redundant. Because, regarding not single slot span, it is a little
-  // difficult to change usable_size if refcnt serves the slot in the next
-  // system page.
-  // TODO(tasak): we don't need to add/subtract sizeof(refcnt) to requested size
-  // in single slot span case.
+  // If PUT_REF_COUNT_IN_PREVIOUS_SLOT is set, the layout is:
+  //   |...object...|[empty]|[cookie]|[unused]|[refcnt]|
+  //   <----(a)----->
+  //   <--------(b)--------->
+  //                        <--(c)--->   +    <--(c)--->
+  //   <----(d)----->   +   <--(d)--->   +    <--(d)--->
+  //   <-------------(e)------------->   +    <--(e)--->
+  //   <----------------------(f)---------------------->
+  // Notes:
+  // If |slot_start| is not SystemPageSize()-aligned (possible only for small
+  // allocations), ref-count of this slot is stored at the end of the previous
+  // slot. Otherwise it is stored in ref-count table placed after the super page
+  // metadata. For simplicity, the space for ref-count is still reserved at the
+  // end of previous slot, even though redundant.
 
   // The value given to the application is just after the ref-count.
-  void* ret = AdjustPointerForExtrasAdd(slot_start);
+  void* object = AdjustPointerForExtrasAdd(slot_start);
 
 #if DCHECK_IS_ON()
   // Add the cookie after the allocation.
   if (allow_cookie) {
-    internal::PartitionCookieWriteValue(static_cast<unsigned char*>(ret) +
+    internal::PartitionCookieWriteValue(static_cast<unsigned char*>(object) +
                                         usable_size);
   }
 #endif
@@ -1647,10 +1644,10 @@
   if (LIKELY(!zero_fill)) {
     // memset() can be really expensive.
 #if EXPENSIVE_DCHECKS_ARE_ON()
-    memset(ret, kUninitializedByte, usable_size);
+    memset(object, kUninitializedByte, usable_size);
 #endif
   } else if (!is_already_zeroed) {
-    memset(ret, 0, usable_size);
+    memset(object, 0, usable_size);
   }
 
 #if BUILDFLAG(USE_BACKUP_REF_PTR)
@@ -1666,7 +1663,7 @@
   // default.
   if (UNLIKELY(is_quarantine_enabled)) {
     if (LIKELY(internal::IsManagedByNormalBuckets(
-            reinterpret_cast<uintptr_t>(ret)))) {
+            reinterpret_cast<uintptr_t>(object)))) {
       uintptr_t unmasked_slot_start =
           memory::UnmaskPtr(reinterpret_cast<uintptr_t>(slot_start));
       // Mark the corresponding bits in the state bitmap as allocated.
@@ -1675,7 +1672,7 @@
     }
   }
 
-  return ret;
+  return object;
 }
 
 template <bool thread_safe>
diff --git a/base/allocator/partition_allocator/thread_cache.h b/base/allocator/partition_allocator/thread_cache.h
index 99caef1..1dbb0ea 100644
--- a/base/allocator/partition_allocator/thread_cache.h
+++ b/base/allocator/partition_allocator/thread_cache.h
@@ -504,7 +504,7 @@
 
 ALWAYS_INLINE void ThreadCache::PutInBucket(Bucket& bucket,
                                             uintptr_t slot_start) {
-#if defined(PA_HAS_FREELIST_HARDENING) && defined(ARCH_CPU_X86_64) && \
+#if defined(PA_HAS_FREELIST_SHADOW_ENTRY) && defined(ARCH_CPU_X86_64) && \
     defined(PA_HAS_64_BITS_POINTERS)
   // We see freelist corruption crashes happening in the wild.  These are likely
   // due to out-of-bounds accesses in the previous slot, or to a Use-After-Free
@@ -536,7 +536,17 @@
       "The computation below assumes that cache lines are 64 bytes long.");
   int distance_to_next_cacheline_in_16_bytes = 4 - ((address >> 4) & 3);
   int slot_size_remaining_in_16_bytes =
-      std::min(bucket.slot_size / 16, distance_to_next_cacheline_in_16_bytes);
+#if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)
+      // When BRP is on in the "previous slot" mode, this slot may have a BRP
+      // ref-count of the next, potentially allocated slot. Make sure we don't
+      // overwrite it.
+      (bucket.slot_size - sizeof(PartitionRefCount)) / 16;
+#else
+      bucket.slot_size / 16;
+#endif  // BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)
+
+  slot_size_remaining_in_16_bytes = std::min(
+      slot_size_remaining_in_16_bytes, distance_to_next_cacheline_in_16_bytes);
 
   static const uint32_t poison_16_bytes[4] = {0xdeadbeef, 0xdeadbeef,
                                               0xdeadbeef, 0xdeadbeef};
@@ -547,7 +557,7 @@
     memcpy(address_aligned, poison_16_bytes, sizeof(poison_16_bytes));
     address_aligned += 4;
   }
-#endif  // defined(PA_HAS_FREELIST_HARDENING) && defined(ARCH_CPU_X86_64) &&
+#endif  // defined(PA_HAS_FREELIST_SHADOW_ENTRY) && defined(ARCH_CPU_X86_64) &&
         // defined(PA_HAS_64_BITS_POINTERS)
 
   auto* entry = PartitionFreelistEntry::EmplaceAndInitForThreadCache(
diff --git a/base/message_loop/message_pump_for_io.h b/base/message_loop/message_pump_for_io.h
index 7de5cdd47..9a9b9df 100644
--- a/base/message_loop/message_pump_for_io.h
+++ b/base/message_loop/message_pump_for_io.h
@@ -12,7 +12,9 @@
 
 #if BUILDFLAG(IS_WIN)
 #include "base/message_loop/message_pump_win.h"
-#elif BUILDFLAG(IS_APPLE)
+#elif BUILDFLAG(IS_IOS)
+#include "base/message_loop/message_pump_io_ios.h"
+#elif BUILDFLAG(IS_MAC)
 #include "base/message_loop/message_pump_kqueue.h"
 #elif BUILDFLAG(IS_NACL)
 #include "base/message_loop/message_pump_default.h"
@@ -27,7 +29,9 @@
 #if BUILDFLAG(IS_WIN)
 // Windows defines it as-is.
 using MessagePumpForIO = MessagePumpForIO;
-#elif BUILDFLAG(IS_APPLE)
+#elif BUILDFLAG(IS_IOS)
+using MessagePumpForIO = MessagePumpIOSForIO;
+#elif BUILDFLAG(IS_MAC)
 using MessagePumpForIO = MessagePumpKqueue;
 #elif BUILDFLAG(IS_NACL)
 using MessagePumpForIO = MessagePumpDefault;
diff --git a/base/message_loop/message_pump_io_ios.cc b/base/message_loop/message_pump_io_ios.cc
new file mode 100644
index 0000000..6dcc0d7
--- /dev/null
+++ b/base/message_loop/message_pump_io_ios.cc
@@ -0,0 +1,184 @@
+// Copyright 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/message_loop/message_pump_io_ios.h"
+
+#include "base/notreached.h"
+
+namespace base {
+
+MessagePumpIOSForIO::FdWatchController::FdWatchController(
+    const Location& from_here)
+    : FdWatchControllerInterface(from_here) {}
+
+MessagePumpIOSForIO::FdWatchController::~FdWatchController() {
+  StopWatchingFileDescriptor();
+}
+
+bool MessagePumpIOSForIO::FdWatchController::StopWatchingFileDescriptor() {
+  if (fdref_ == NULL)
+    return true;
+
+  CFFileDescriptorDisableCallBacks(fdref_.get(), callback_types_);
+  if (pump_)
+    pump_->RemoveRunLoopSource(fd_source_);
+  fd_source_.reset();
+  fdref_.reset();
+  callback_types_ = 0;
+  pump_.reset();
+  watcher_ = NULL;
+  return true;
+}
+
+void MessagePumpIOSForIO::FdWatchController::Init(CFFileDescriptorRef fdref,
+                                                  CFOptionFlags callback_types,
+                                                  CFRunLoopSourceRef fd_source,
+                                                  bool is_persistent) {
+  DCHECK(fdref);
+  DCHECK(!fdref_.is_valid());
+
+  is_persistent_ = is_persistent;
+  fdref_.reset(fdref);
+  callback_types_ = callback_types;
+  fd_source_.reset(fd_source);
+}
+
+void MessagePumpIOSForIO::FdWatchController::OnFileCanReadWithoutBlocking(
+    int fd,
+    MessagePumpIOSForIO* pump) {
+  DCHECK(callback_types_ & kCFFileDescriptorReadCallBack);
+  watcher_->OnFileCanReadWithoutBlocking(fd);
+}
+
+void MessagePumpIOSForIO::FdWatchController::OnFileCanWriteWithoutBlocking(
+    int fd,
+    MessagePumpIOSForIO* pump) {
+  DCHECK(callback_types_ & kCFFileDescriptorWriteCallBack);
+  watcher_->OnFileCanWriteWithoutBlocking(fd);
+}
+
+MessagePumpIOSForIO::MessagePumpIOSForIO() : weak_factory_(this) {
+}
+
+MessagePumpIOSForIO::~MessagePumpIOSForIO() {
+}
+
+bool MessagePumpIOSForIO::WatchFileDescriptor(int fd,
+                                              bool persistent,
+                                              int mode,
+                                              FdWatchController* controller,
+                                              FdWatcher* delegate) {
+  DCHECK_GE(fd, 0);
+  DCHECK(controller);
+  DCHECK(delegate);
+  DCHECK(mode == WATCH_READ || mode == WATCH_WRITE || mode == WATCH_READ_WRITE);
+
+  // WatchFileDescriptor should be called on the pump thread. It is not
+  // threadsafe, and your watcher may never be registered.
+  DCHECK(watch_file_descriptor_caller_checker_.CalledOnValidThread());
+
+  CFFileDescriptorContext source_context = {0};
+  source_context.info = controller;
+
+  CFOptionFlags callback_types = 0;
+  if (mode & WATCH_READ) {
+    callback_types |= kCFFileDescriptorReadCallBack;
+  }
+  if (mode & WATCH_WRITE) {
+    callback_types |= kCFFileDescriptorWriteCallBack;
+  }
+
+  CFFileDescriptorRef fdref = controller->fdref_.get();
+  if (fdref == NULL) {
+    base::ScopedCFTypeRef<CFFileDescriptorRef> scoped_fdref(
+        CFFileDescriptorCreate(
+            kCFAllocatorDefault, fd, false, HandleFdIOEvent, &source_context));
+    if (scoped_fdref == NULL) {
+      NOTREACHED() << "CFFileDescriptorCreate failed";
+      return false;
+    }
+
+    CFFileDescriptorEnableCallBacks(scoped_fdref, callback_types);
+
+    // TODO(wtc): what should the 'order' argument be?
+    base::ScopedCFTypeRef<CFRunLoopSourceRef> scoped_fd_source(
+        CFFileDescriptorCreateRunLoopSource(
+            kCFAllocatorDefault, scoped_fdref, 0));
+    if (scoped_fd_source == NULL) {
+      NOTREACHED() << "CFFileDescriptorCreateRunLoopSource failed";
+      return false;
+    }
+    CFRunLoopAddSource(run_loop(), scoped_fd_source, kCFRunLoopCommonModes);
+
+    // Transfer ownership of scoped_fdref and fd_source to controller.
+    controller->Init(scoped_fdref.release(), callback_types,
+                     scoped_fd_source.release(), persistent);
+  } else {
+    // It's illegal to use this function to listen on 2 separate fds with the
+    // same |controller|.
+    if (CFFileDescriptorGetNativeDescriptor(fdref) != fd) {
+      NOTREACHED() << "FDs don't match: "
+                   << CFFileDescriptorGetNativeDescriptor(fdref)
+                   << " != " << fd;
+      return false;
+    }
+    if (persistent != controller->is_persistent_) {
+      NOTREACHED() << "persistent doesn't match";
+      return false;
+    }
+
+    // Combine old/new event masks.
+    CFFileDescriptorDisableCallBacks(fdref, controller->callback_types_);
+    controller->callback_types_ |= callback_types;
+    CFFileDescriptorEnableCallBacks(fdref, controller->callback_types_);
+  }
+
+  controller->set_watcher(delegate);
+  controller->set_pump(weak_factory_.GetWeakPtr());
+
+  return true;
+}
+
+void MessagePumpIOSForIO::RemoveRunLoopSource(CFRunLoopSourceRef source) {
+  CFRunLoopRemoveSource(run_loop(), source, kCFRunLoopCommonModes);
+}
+
+// static
+void MessagePumpIOSForIO::HandleFdIOEvent(CFFileDescriptorRef fdref,
+                                          CFOptionFlags callback_types,
+                                          void* context) {
+  FdWatchController* controller = static_cast<FdWatchController*>(context);
+  DCHECK_EQ(fdref, controller->fdref_.get());
+
+  // Ensure that |fdref| will remain live for the duration of this function
+  // call even if |controller| is deleted or |StopWatchingFileDescriptor()| is
+  // called, either of which will cause |fdref| to be released.
+  ScopedCFTypeRef<CFFileDescriptorRef> scoped_fdref(
+      fdref, base::scoped_policy::RETAIN);
+
+  int fd = CFFileDescriptorGetNativeDescriptor(fdref);
+  MessagePumpIOSForIO* pump = controller->pump().get();
+  DCHECK(pump);
+  if (callback_types & kCFFileDescriptorWriteCallBack)
+    controller->OnFileCanWriteWithoutBlocking(fd, pump);
+
+  // Perform the read callback only if the file descriptor has not been
+  // invalidated in the write callback. As |FdWatchController| invalidates
+  // its file descriptor on destruction, the file descriptor being valid also
+  // guarantees that |controller| has not been deleted.
+  if (callback_types & kCFFileDescriptorReadCallBack &&
+      CFFileDescriptorIsValid(fdref)) {
+    DCHECK_EQ(fdref, controller->fdref_.get());
+    controller->OnFileCanReadWithoutBlocking(fd, pump);
+  }
+
+  // Re-enable callbacks after the read/write if the file descriptor is still
+  // valid and the controller is persistent.
+  if (CFFileDescriptorIsValid(fdref) && controller->is_persistent_) {
+    DCHECK_EQ(fdref, controller->fdref_.get());
+    CFFileDescriptorEnableCallBacks(fdref, callback_types);
+  }
+}
+
+}  // namespace base
diff --git a/base/message_loop/message_pump_io_ios.h b/base/message_loop/message_pump_io_ios.h
new file mode 100644
index 0000000..ad3c33e
--- /dev/null
+++ b/base/message_loop/message_pump_io_ios.h
@@ -0,0 +1,93 @@
+// Copyright 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_MESSAGE_LOOP_MESSAGE_PUMP_IO_IOS_H_
+#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_IO_IOS_H_
+
+#include "base/base_export.h"
+#include "base/mac/scoped_cffiledescriptorref.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_pump_mac.h"
+#include "base/message_loop/watchable_io_message_pump_posix.h"
+#include "base/threading/thread_checker.h"
+
+namespace base {
+
+// This file introduces a class to monitor sockets and issue callbacks when
+// sockets are ready for I/O on iOS.
+class BASE_EXPORT MessagePumpIOSForIO : public MessagePumpNSRunLoop,
+                                        public WatchableIOMessagePumpPosix {
+ public:
+  class FdWatchController : public FdWatchControllerInterface {
+   public:
+    explicit FdWatchController(const Location& from_here);
+
+    FdWatchController(const FdWatchController&) = delete;
+    FdWatchController& operator=(const FdWatchController&) = delete;
+
+    // Implicitly calls StopWatchingFileDescriptor.
+    ~FdWatchController() override;
+
+    // FdWatchControllerInterface:
+    bool StopWatchingFileDescriptor() override;
+
+   private:
+    friend class MessagePumpIOSForIO;
+    friend class MessagePumpIOSForIOTest;
+
+    // Called by MessagePumpIOSForIO, ownership of |fdref| and |fd_source|
+    // is transferred to this object.
+    void Init(CFFileDescriptorRef fdref,
+              CFOptionFlags callback_types,
+              CFRunLoopSourceRef fd_source,
+              bool is_persistent);
+
+    void set_pump(base::WeakPtr<MessagePumpIOSForIO> pump) { pump_ = pump; }
+    const base::WeakPtr<MessagePumpIOSForIO>& pump() const { return pump_; }
+
+    void set_watcher(FdWatcher* watcher) { watcher_ = watcher; }
+
+    void OnFileCanReadWithoutBlocking(int fd, MessagePumpIOSForIO* pump);
+    void OnFileCanWriteWithoutBlocking(int fd, MessagePumpIOSForIO* pump);
+
+    bool is_persistent_ = false;  // false if this event is one-shot.
+    base::mac::ScopedCFFileDescriptorRef fdref_;
+    CFOptionFlags callback_types_ = 0;
+    base::ScopedCFTypeRef<CFRunLoopSourceRef> fd_source_;
+    base::WeakPtr<MessagePumpIOSForIO> pump_;
+    FdWatcher* watcher_ = nullptr;
+  };
+
+  MessagePumpIOSForIO();
+
+  MessagePumpIOSForIO(const MessagePumpIOSForIO&) = delete;
+  MessagePumpIOSForIO& operator=(const MessagePumpIOSForIO&) = delete;
+
+  ~MessagePumpIOSForIO() override;
+
+  bool WatchFileDescriptor(int fd,
+                           bool persistent,
+                           int mode,
+                           FdWatchController* controller,
+                           FdWatcher* delegate);
+
+  void RemoveRunLoopSource(CFRunLoopSourceRef source);
+
+ private:
+  friend class MessagePumpIOSForIOTest;
+
+  static void HandleFdIOEvent(CFFileDescriptorRef fdref,
+                              CFOptionFlags callback_types,
+                              void* context);
+
+  ThreadChecker watch_file_descriptor_caller_checker_;
+
+  base::WeakPtrFactory<MessagePumpIOSForIO> weak_factory_;
+};
+
+}  // namespace base
+
+#endif  // BASE_MESSAGE_LOOP_MESSAGE_PUMP_IO_IOS_H_
diff --git a/base/message_loop/message_pump_io_ios_unittest.cc b/base/message_loop/message_pump_io_ios_unittest.cc
new file mode 100644
index 0000000..b61aedd
--- /dev/null
+++ b/base/message_loop/message_pump_io_ios_unittest.cc
@@ -0,0 +1,155 @@
+// Copyright 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/message_loop/message_pump_io_ios.h"
+
+#include <unistd.h>
+
+#include "base/logging.h"
+#include "base/message_loop/message_pump_for_io.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/test/gtest_util.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+class MessagePumpIOSForIOTest : public testing::Test {
+ public:
+  MessagePumpIOSForIOTest(const MessagePumpIOSForIOTest&) = delete;
+  MessagePumpIOSForIOTest& operator=(const MessagePumpIOSForIOTest&) = delete;
+
+ protected:
+  MessagePumpIOSForIOTest() = default;
+  ~MessagePumpIOSForIOTest() override = default;
+
+  void SetUp() override {
+    int ret = pipe(pipefds_);
+    ASSERT_EQ(0, ret);
+    ret = pipe(alternate_pipefds_);
+    ASSERT_EQ(0, ret);
+  }
+
+  void TearDown() override {
+    if (IGNORE_EINTR(close(pipefds_[0])) < 0)
+      PLOG(ERROR) << "close";
+    if (IGNORE_EINTR(close(pipefds_[1])) < 0)
+      PLOG(ERROR) << "close";
+  }
+
+  void HandleFdIOEvent(MessagePumpForIO::FdWatchController* watcher) {
+    MessagePumpIOSForIO::HandleFdIOEvent(watcher->fdref_.get(),
+        kCFFileDescriptorReadCallBack | kCFFileDescriptorWriteCallBack,
+        watcher);
+  }
+
+  int pipefds_[2];
+  int alternate_pipefds_[2];
+};
+
+namespace {
+
+// Concrete implementation of MessagePumpIOSForIO::FdWatcher that does
+// nothing useful.
+class StupidWatcher : public MessagePumpIOSForIO::FdWatcher {
+ public:
+  ~StupidWatcher() override {}
+
+  // base:MessagePumpIOSForIO::FdWatcher interface
+  void OnFileCanReadWithoutBlocking(int fd) override {}
+  void OnFileCanWriteWithoutBlocking(int fd) override {}
+};
+
+class BaseWatcher : public MessagePumpIOSForIO::FdWatcher {
+ public:
+  BaseWatcher(MessagePumpIOSForIO::FdWatchController* controller)
+      : controller_(controller) {
+    DCHECK(controller_);
+  }
+  ~BaseWatcher() override {}
+
+  // MessagePumpIOSForIO::FdWatcher interface
+  void OnFileCanReadWithoutBlocking(int /* fd */) override { NOTREACHED(); }
+
+  void OnFileCanWriteWithoutBlocking(int /* fd */) override { NOTREACHED(); }
+
+ protected:
+  MessagePumpIOSForIO::FdWatchController* controller_;
+};
+
+class DeleteWatcher : public BaseWatcher {
+ public:
+  explicit DeleteWatcher(MessagePumpIOSForIO::FdWatchController* controller)
+      : BaseWatcher(controller) {}
+
+  ~DeleteWatcher() override { DCHECK(!controller_); }
+
+  void OnFileCanWriteWithoutBlocking(int /* fd */) override {
+    DCHECK(controller_);
+    delete controller_;
+    controller_ = NULL;
+  }
+};
+
+TEST_F(MessagePumpIOSForIOTest, DeleteWatcher) {
+  std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
+  MessagePumpIOSForIO::FdWatchController* watcher =
+      new MessagePumpIOSForIO::FdWatchController(FROM_HERE);
+  DeleteWatcher delegate(watcher);
+  pump->WatchFileDescriptor(pipefds_[1],
+      false, MessagePumpIOSForIO::WATCH_READ_WRITE, watcher, &delegate);
+
+  // Spoof a callback.
+  HandleFdIOEvent(watcher);
+}
+
+class StopWatcher : public BaseWatcher {
+ public:
+  StopWatcher(MessagePumpIOSForIO::FdWatchController* controller,
+              MessagePumpIOSForIO* pump,
+              int fd_to_start_watching = -1)
+      : BaseWatcher(controller),
+        pump_(pump),
+        fd_to_start_watching_(fd_to_start_watching) {}
+
+  ~StopWatcher() override {}
+
+  void OnFileCanWriteWithoutBlocking(int /* fd */) override {
+    controller_->StopWatchingFileDescriptor();
+    if (fd_to_start_watching_ >= 0) {
+      pump_->WatchFileDescriptor(fd_to_start_watching_,
+          false, MessagePumpIOSForIO::WATCH_READ_WRITE, controller_, this);
+    }
+  }
+
+ private:
+  MessagePumpIOSForIO* pump_;
+  int fd_to_start_watching_;
+};
+
+TEST_F(MessagePumpIOSForIOTest, StopWatcher) {
+  std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
+  MessagePumpIOSForIO::FdWatchController watcher(FROM_HERE);
+  StopWatcher delegate(&watcher, pump.get());
+  pump->WatchFileDescriptor(pipefds_[1],
+      false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
+
+  // Spoof a callback.
+  HandleFdIOEvent(&watcher);
+}
+
+TEST_F(MessagePumpIOSForIOTest, StopWatcherAndWatchSomethingElse) {
+  std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
+  MessagePumpIOSForIO::FdWatchController watcher(FROM_HERE);
+  StopWatcher delegate(&watcher, pump.get(), alternate_pipefds_[1]);
+  pump->WatchFileDescriptor(pipefds_[1],
+      false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
+
+  // Spoof a callback.
+  HandleFdIOEvent(&watcher);
+}
+
+}  // namespace
+
+}  // namespace base
diff --git a/base/message_loop/message_pump_kqueue.cc b/base/message_loop/message_pump_kqueue.cc
index ab437895..21d0580 100644
--- a/base/message_loop/message_pump_kqueue.cc
+++ b/base/message_loop/message_pump_kqueue.cc
@@ -23,12 +23,8 @@
 // port sets. MessagePumpKqueue will directly use Mach ports in the kqueue if
 // it is possible.
 bool KqueueNeedsPortSet() {
-#if BUILDFLAG(IS_MAC)
   static const bool kqueue_needs_port_set = mac::IsAtMostOS10_11();
   return kqueue_needs_port_set;
-#else
-  return false;
-#endif
 }
 
 #if DCHECK_IS_ON()
@@ -38,13 +34,8 @@
 // Note that updating a kqueue timer from one thread while another thread is
 // waiting in a kevent64 invocation is still (inherently) racy.
 bool KqueueTimersSpuriouslyWakeUp() {
-#if BUILDFLAG(IS_MAC)
   static const bool kqueue_timers_spuriously_wakeup = mac::IsAtMostOS10_13();
   return kqueue_timers_spuriously_wakeup;
-#else
-  // This still happens on iOS15.
-  return true;
-#endif
 }
 #endif
 
diff --git a/base/task/task_features.cc b/base/task/task_features.cc
index eff2d24c..057b44ef 100644
--- a/base/task/task_features.cc
+++ b/base/task/task_features.cc
@@ -47,6 +47,6 @@
     "UseFiveMinutesThreadReclaimTime", base::FEATURE_DISABLED_BY_DEFAULT};
 
 const BASE_EXPORT Feature kRemoveCanceledTasksInTaskQueue = {
-    "RemoveCanceledTasksInTaskQueue", base::FEATURE_DISABLED_BY_DEFAULT};
+    "RemoveCanceledTasksInTaskQueue2", base::FEATURE_DISABLED_BY_DEFAULT};
 
 }  // namespace base
diff --git a/base/test/task_environment.cc b/base/test/task_environment.cc
index 9f7befb..f3a2f89 100644
--- a/base/test/task_environment.cc
+++ b/base/test/task_environment.cc
@@ -784,8 +784,13 @@
                    << debug::StackTrace();
     }
   } else if (ThreadPoolInstance::Get()) {
-    LOG(WARNING) << "ParallelExecutionFence is ineffective when "
-                    "ThreadPoolInstance is not managed by a TaskEnvironment.";
+    LOG(WARNING)
+        << "ParallelExecutionFence is ineffective when ThreadPoolInstance is "
+           "not managed by a TaskEnvironment.\n"
+           "Test fixtures should use a TaskEnvironment member or statically "
+           "invoke TaskEnvironment::CreateThreadPool() + "
+           "ThreadPoolInstance::Get()->StartWithDefaultParams() when the "
+           "former is not possible.";
   }
 }
 
diff --git a/base/win/shortcut_unittest.cc b/base/win/shortcut_unittest.cc
index 4f5d7b24..12d5f98 100644
--- a/base/win/shortcut_unittest.cc
+++ b/base/win/shortcut_unittest.cc
@@ -184,6 +184,10 @@
 }
 
 TEST_F(ShortcutTest, CreateShortcutWithOnlySomeProperties) {
+  // This test is extremely flaky on Win7, so disable.
+  // TODO(crbug.com/1291225): Investigate why it's so flaky on Win7 bots.
+  if (base::win::OSInfo::GetInstance()->version() <= base::win::Version::WIN7)
+    GTEST_SKIP() << "Skipping test for win7";
   ShortcutProperties target_and_args_properties;
   target_and_args_properties.set_target(link_properties_.target);
   target_and_args_properties.set_arguments(link_properties_.arguments);
diff --git a/build/config/compiler/pgo/BUILD.gn b/build/config/compiler/pgo/BUILD.gn
index 637436b..2a3bf98 100644
--- a/build/config/compiler/pgo/BUILD.gn
+++ b/build/config/compiler/pgo/BUILD.gn
@@ -48,8 +48,13 @@
         inputs = [ "//chrome/build/win32.pgo.txt" ]
       }
     } else if (is_mac) {
-      _pgo_target = "mac"
-      inputs = [ "//chrome/build/mac.pgo.txt" ]
+      if (target_cpu == "arm64") {
+        _pgo_target = "mac-arm"
+        inputs = [ "//chrome/build/mac-arm.pgo.txt" ]
+      } else {
+        _pgo_target = "mac"
+        inputs = [ "//chrome/build/mac.pgo.txt" ]
+      }
     } else if (is_linux || is_chromeos_lacros) {
       _pgo_target = "linux"
       inputs = [ "//chrome/build/linux.pgo.txt" ]
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index ae77469..1c3897b 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-7.20220126.1.1
+7.20220126.2.3
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index ae77469..1c3897b 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-7.20220126.1.1
+7.20220126.2.3
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index ae77469..1c3897b 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-7.20220126.1.1
+7.20220126.2.3
diff --git a/cc/paint/skottie_frame_data_provider.h b/cc/paint/skottie_frame_data_provider.h
index 01c1552..3e0fcfa5 100644
--- a/cc/paint/skottie_frame_data_provider.h
+++ b/cc/paint/skottie_frame_data_provider.h
@@ -11,7 +11,6 @@
 #include "base/strings/string_piece.h"
 #include "cc/paint/paint_export.h"
 #include "cc/paint/skottie_frame_data.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace cc {
 
@@ -31,19 +30,12 @@
   class CC_PAINT_EXPORT ImageAsset : public base::RefCounted<ImageAsset> {
    public:
     // Returns the image to use for an asset in a frame of a skottie animation.
-    // If absl::nullopt is returned, the most recently provided image for this
-    // asset is reused when the frame is rendered. Thus, the ImageAsset may
-    // return "null" if: a) The most recent image intentionally should be
-    // reused or b) The provider knows that this particular asset does not
-    // appear at the specified timestamp of the animation.
     //
     // |t|: See skresources::ImageAsset::getFrame(). Same semantics. Specifies
     //      the frame of interest in the animation that's about to be rendered.
     // |scale_factor|: See |image_scale| in gfx::Canvas. Can be used to generate
     //                 a PaintImage from a gfx::ImageSkia instance.
-    virtual absl::optional<SkottieFrameData> GetFrameData(
-        float t,
-        float scale_factor) = 0;
+    virtual SkottieFrameData GetFrameData(float t, float scale_factor) = 0;
 
    protected:
     virtual ~ImageAsset() = default;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 139e028..81400cbf 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -449,9 +449,12 @@
 
 void LayerTreeHost::UpdateDeferMainFrameUpdateInternal() {
   DCHECK(IsMainThread());
-  proxy_->SetDeferMainFrameUpdate(
-      defer_main_frame_update_count_ > 0 ||
-      !pending_commit_state()->local_surface_id_from_parent.is_valid());
+  proxy_->SetDeferMainFrameUpdate(MainFrameUpdatesAreDeferred());
+}
+
+bool LayerTreeHost::MainFrameUpdatesAreDeferred() const {
+  return defer_main_frame_update_count_ > 0 ||
+         !pending_commit_state()->local_surface_id_from_parent.is_valid();
 }
 
 bool LayerTreeHost::IsUsingLayerLists() const {
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index dc3903a..4db1f86 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -295,6 +295,9 @@
   // StopDeferringCommits is called.
   std::unique_ptr<ScopedDeferMainFrameUpdate> DeferMainFrameUpdate();
 
+  // Returns whether main frame updates are deferred. See conditions above.
+  bool MainFrameUpdatesAreDeferred() const;
+
   // Notification that the proxy started or stopped deferring main frame updates
   void OnDeferMainFrameUpdatesChanged(bool);
 
diff --git a/chrome/VERSION b/chrome/VERSION
index 075075a..29e909f 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=100
 MINOR=0
-BUILD=4855
+BUILD=4856
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 1ab2225..67841ccf 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -373,7 +373,6 @@
     "//chrome/browser/metrics_settings/android:java",
     "//chrome/browser/notifications/chime/android:java",
     "//chrome/browser/offline_pages/android:java",
-    "//chrome/browser/offline_pages/measurements/proto:offline_measurements_proto_java",
     "//chrome/browser/omaha/android:java",
     "//chrome/browser/optimization_guide/android:java",
     "//chrome/browser/page_annotations/android:java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni
index c789bc2e..1f3e8ed3 100644
--- a/chrome/android/chrome_junit_test_java_sources.gni
+++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -161,6 +161,7 @@
   "junit/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineDetectorUnitTest.java",
   "junit/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerV2UnitTest.java",
   "junit/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorMetricsDelegateUnitTest.java",
+  "junit/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTaskUnitTest.java",
   "junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java",
   "junit/src/org/chromium/chrome/browser/omaha/ResponseParserTest.java",
   "junit/src/org/chromium/chrome/browser/omaha/VersionNumberTest.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index a9c3232..b4fd306 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -315,7 +315,6 @@
   "javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java",
   "javatests/src/org/chromium/chrome/browser/offlinepages/RequestCoordinatorBridgeTest.java",
   "javatests/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerTest.java",
-  "javatests/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTaskTest.java",
   "javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskTest.java",
   "javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchConfigurationTest.java",
   "javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/TestOfflinePageService.java",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/ButtonView.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/ButtonView.java
index 93b7b49..ae0eefe 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/ButtonView.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/ButtonView.java
@@ -81,8 +81,7 @@
         int borderWidth =
                 a.getResourceId(R.styleable.ButtonView_chipBorderWidth, R.dimen.chip_border_width);
         int verticalInset = a.getDimensionPixelSize(R.styleable.ButtonView_verticalInset,
-                getResources().getDimensionPixelSize(
-                        org.chromium.ui.R.dimen.chip_bg_vertical_inset));
+                getResources().getDimensionPixelSize(R.dimen.chip_bg_vertical_inset));
         a.recycle();
 
         mIcon = new ChromeImageView(getContext());
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_address_info.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_address_info.xml
index b491a19..c6d400dc 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_address_info.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_address_info.xml
@@ -15,28 +15,28 @@
     android:layout_marginBottom="@dimen/keyboard_accessory_sheet_bottom_margin"
     android:orientation="vertical">
 
-    <org.chromium.ui.widget.ChipView
+    <org.chromium.components.browser_ui.widget.chips.ChipView
         android:id="@+id/name_full"
         android:gravity="center_vertical|start"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         style="@style/InputChip" />
 
-    <org.chromium.ui.widget.ChipView
+    <org.chromium.components.browser_ui.widget.chips.ChipView
         android:id="@+id/company_name"
         android:gravity="center_vertical|start"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         style="@style/InputChip" />
 
-    <org.chromium.ui.widget.ChipView
+    <org.chromium.components.browser_ui.widget.chips.ChipView
         android:id="@+id/address_home_line_1"
         android:gravity="center_vertical|start"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         style="@style/InputChip" />
 
-    <org.chromium.ui.widget.ChipView
+    <org.chromium.components.browser_ui.widget.chips.ChipView
         android:id="@+id/address_home_line_2"
         android:gravity="center_vertical|start"
         android:layout_width="wrap_content"
@@ -50,7 +50,7 @@
         android:layout_width="match_parent"
         android:orientation="horizontal">
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/address_home_state"
             android:gravity="center_vertical|start"
             android:layout_marginEnd="@dimen/keyboard_accessory_sheet_padding"
@@ -58,7 +58,7 @@
             android:layout_height="wrap_content"
             style="@style/InputChip" />
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/address_home_city"
             android:gravity="center_vertical|start"
             android:layout_marginEnd="@dimen/keyboard_accessory_sheet_padding"
@@ -66,7 +66,7 @@
             android:layout_height="wrap_content"
             style="@style/InputChip" />
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/address_home_zip"
             android:gravity="center_vertical|start"
             android:layout_width="wrap_content"
@@ -75,21 +75,21 @@
 
     </LinearLayout>
 
-    <org.chromium.ui.widget.ChipView
+    <org.chromium.components.browser_ui.widget.chips.ChipView
         android:id="@+id/address_home_country"
         android:gravity="center_vertical|start"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         style="@style/InputChip" />
 
-    <org.chromium.ui.widget.ChipView
+    <org.chromium.components.browser_ui.widget.chips.ChipView
         android:id="@+id/phone_home_whole_number"
         android:gravity="center_vertical|start"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         style="@style/InputChip" />
 
-    <org.chromium.ui.widget.ChipView
+    <org.chromium.components.browser_ui.widget.chips.ChipView
         android:id="@+id/email_address"
         android:gravity="center_vertical|start"
         android:layout_width="wrap_content"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_credit_card_info.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_credit_card_info.xml
index ee86ce4..c31c74bb 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_credit_card_info.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_credit_card_info.xml
@@ -31,7 +31,7 @@
             android:layout_weight="1"
             android:orientation="vertical">
 
-            <org.chromium.ui.widget.ChipView
+            <org.chromium.components.browser_ui.widget.chips.ChipView
                 android:id="@+id/cc_number"
                 android:gravity="center_vertical|start"
                 android:layout_width="wrap_content"
@@ -46,7 +46,7 @@
                 android:layout_width="match_parent"
                 android:orientation="horizontal">
 
-                <org.chromium.ui.widget.ChipView
+                <org.chromium.components.browser_ui.widget.chips.ChipView
                     android:id="@+id/exp_month"
                     android:gravity="center_vertical|start"
                     android:layout_width="wrap_content"
@@ -62,7 +62,7 @@
                     android:layout_marginEnd="@dimen/keyboard_accessory_sheet_padding"
                     android:textAppearance="@style/TextAppearance.DividerText"/>
 
-                <org.chromium.ui.widget.ChipView
+                <org.chromium.components.browser_ui.widget.chips.ChipView
                     android:id="@+id/exp_year"
                     android:gravity="center_vertical|start"
                     android:layout_width="wrap_content"
@@ -72,14 +72,14 @@
             </LinearLayout>
 
 
-            <org.chromium.ui.widget.ChipView
+            <org.chromium.components.browser_ui.widget.chips.ChipView
                 android:id="@+id/cardholder"
                 android:gravity="center_vertical|start"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 style="@style/InputChip" />
 
-            <org.chromium.ui.widget.ChipView
+            <org.chromium.components.browser_ui.widget.chips.ChipView
                 android:id="@+id/cvc"
                 android:gravity="center_vertical|start"
                 android:layout_width="wrap_content"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_password_info.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_password_info.xml
index f78d43a..1e893cb2 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_password_info.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_password_info.xml
@@ -32,7 +32,7 @@
         android:layout_width="match_parent"
         android:orientation="horizontal">
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/suggestion_text"
             android:gravity="center_vertical|start"
             android:layout_width="wrap_content"
@@ -53,7 +53,7 @@
 
     </LinearLayout>
 
-    <org.chromium.ui.widget.ChipView
+    <org.chromium.components.browser_ui.widget.chips.ChipView
         android:id="@+id/password_text"
         android:gravity="center_vertical|start"
         android:layout_width="wrap_content"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_promo_code_info.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_promo_code_info.xml
index dcc638c..ab72e16 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_promo_code_info.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_promo_code_info.xml
@@ -31,7 +31,7 @@
             android:layout_weight="1"
             android:orientation="vertical">
 
-            <org.chromium.ui.widget.ChipView
+            <org.chromium.components.browser_ui.widget.chips.ChipView
                 android:id="@+id/promo_code"
                 android:gravity="center_vertical|start"
                 android:layout_width="wrap_content"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_suggestion.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_suggestion.xml
index 0012c95..1b2391d 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_suggestion.xml
+++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_suggestion.xml
@@ -3,7 +3,7 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<org.chromium.ui.widget.ChipView
+<org.chromium.components.browser_ui.widget.chips.ChipView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:gravity="center"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewBinder.java
index 702bab7..157420b2 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewBinder.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewBinder.java
@@ -29,6 +29,7 @@
 import org.chromium.chrome.browser.keyboard_accessory.R;
 import org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.ItemType;
 import org.chromium.chrome.browser.keyboard_accessory.helper.FaviconHelper;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.url_formatter.SchemeDisplay;
 import org.chromium.components.url_formatter.UrlFormatter;
 import org.chromium.ui.modelutil.MVCListAdapter;
@@ -36,7 +37,6 @@
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.RecyclerViewAdapter;
 import org.chromium.ui.modelutil.SimpleRecyclerViewMcp;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.url.GURL;
 
 /**
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java
index e983ad4..f04cbbe 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java
@@ -26,10 +26,10 @@
 import org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.TabLayoutBarItem;
 import org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryViewBinder.BarItemViewHolder;
 import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.feature_engagement.FeatureConstants;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.ui.widget.RectProvider;
 
 /**
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryInfoView.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryInfoView.java
index a65f96c..72cab575 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryInfoView.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryInfoView.java
@@ -9,7 +9,7 @@
 import android.widget.LinearLayout;
 
 import org.chromium.chrome.browser.keyboard_accessory.R;
-import org.chromium.ui.widget.ChipView;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 
 /**
  * This view represents a section of user data in the address tab of the keyboard accessory.
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetViewBinder.java
index 5b45744..badc443c 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetViewBinder.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetViewBinder.java
@@ -14,8 +14,8 @@
 import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField;
 import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece;
 import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabViewBinder.ElementViewHolder;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.ui.modelutil.ListModel;
-import org.chromium.ui.widget.ChipView;
 
 /**
  * This stateless class provides methods to bind a {@link ListModel<AccessorySheetDataPiece>}
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessoryInfoView.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessoryInfoView.java
index e40bf6e7c..e0e92274 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessoryInfoView.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessoryInfoView.java
@@ -14,7 +14,7 @@
 import androidx.annotation.Nullable;
 
 import org.chromium.chrome.browser.keyboard_accessory.R;
-import org.chromium.ui.widget.ChipView;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 
 /**
  * This view represents a section of user credit card details in the payment method tab of the
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetViewBinder.java
index ca227654..0881b520 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetViewBinder.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetViewBinder.java
@@ -18,9 +18,9 @@
 import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField;
 import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece;
 import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabViewBinder.ElementViewHolder;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.ui.modelutil.RecyclerViewAdapter;
 import org.chromium.ui.modelutil.SimpleRecyclerViewMcp;
-import org.chromium.ui.widget.ChipView;
 
 class CreditCardAccessorySheetViewBinder {
     static ElementViewHolder create(ViewGroup parent, @AccessorySheetDataPiece.Type int viewType) {
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryInfoView.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryInfoView.java
index 40f1343..8a9f026 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryInfoView.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryInfoView.java
@@ -14,7 +14,7 @@
 import androidx.annotation.Nullable;
 
 import org.chromium.chrome.browser.keyboard_accessory.R;
-import org.chromium.ui.widget.ChipView;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 
 /**
  * This view represents a section of user credentials in the password tab of the keyboard accessory.
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java
index f2ffeee..a97dbd0 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java
@@ -19,8 +19,8 @@
 import org.chromium.chrome.browser.keyboard_accessory.helper.FaviconHelper;
 import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece;
 import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabViewBinder.ElementViewHolder;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.ui.modelutil.ListModel;
-import org.chromium.ui.widget.ChipView;
 
 /**
  * This stateless class provides methods to bind a {@link ListModel<AccessorySheetDataPiece>}
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PromoCodeAccessoryInfoView.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PromoCodeAccessoryInfoView.java
index b02cd87..465c9f6 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PromoCodeAccessoryInfoView.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PromoCodeAccessoryInfoView.java
@@ -15,7 +15,7 @@
 import androidx.annotation.Nullable;
 
 import org.chromium.chrome.browser.keyboard_accessory.R;
-import org.chromium.ui.widget.ChipView;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 
 /**
  * This view represents a section of promo code offer details in the payment methods tab of the
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetIntegrationTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetIntegrationTest.java
index 4bfdfea..d64ad998 100644
--- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetIntegrationTest.java
+++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetIntegrationTest.java
@@ -28,8 +28,8 @@
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.content_public.browser.test.util.TouchCommon;
-import org.chromium.ui.widget.ChipView;
 
 /**
  * Integration tests for the AllPasswordsBottomSheet check that the calls to the
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewTest.java
index 10b69b6..85bdeaa 100644
--- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewTest.java
+++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewTest.java
@@ -40,10 +40,10 @@
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
 import org.chromium.ui.modelutil.PropertyModel;
-import org.chromium.ui.widget.ChipView;
 
 /**
  * View tests for the AllPasswordsBottomSheet ensure that model changes are reflected in the sheet.
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java
index d1508eec..9ba6b9fe 100644
--- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java
+++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java
@@ -80,6 +80,7 @@
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.components.autofill.AutofillSuggestion;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.feature_engagement.EventConstants;
 import org.chromium.components.feature_engagement.FeatureConstants;
 import org.chromium.components.feature_engagement.Tracker;
@@ -92,7 +93,6 @@
 import org.chromium.ui.ViewProvider;
 import org.chromium.ui.modelutil.LazyConstructionPropertyMcp;
 import org.chromium.ui.modelutil.PropertyModel;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.ui.widget.ChromeImageView;
 import org.chromium.url.GURL;
 
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetViewTest.java
index 7f24d951..cb4a1023 100644
--- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetViewTest.java
+++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetViewTest.java
@@ -40,8 +40,8 @@
 import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.ui.widget.ChipView;
 
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicBoolean;
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetViewTest.java
index 802faf2..a6e25ee 100644
--- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetViewTest.java
+++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetViewTest.java
@@ -52,8 +52,8 @@
 import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.url.GURL;
 
 import java.util.concurrent.ExecutionException;
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java
index 698b57ec..e4736b5 100644
--- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java
+++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java
@@ -46,8 +46,8 @@
 import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.ui.widget.ChipView;
 
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicReference;
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
index b9c85fa..c7a447a 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -133,6 +133,7 @@
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.embedder_support.util.UrlUtilities;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
@@ -142,7 +143,6 @@
 import org.chromium.ui.test.util.DisableAnimationsTestRule;
 import org.chromium.ui.test.util.UiRestriction;
 import org.chromium.ui.util.ColorUtils;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.ui.widget.ChromeImageView;
 import org.chromium.ui.widget.ViewLookupCachingFrameLayout;
 
diff --git a/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml b/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml
index c9527de..6dfd866 100644
--- a/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml
+++ b/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml
@@ -84,7 +84,7 @@
                 android:text="@string/tabswitcher_create_group"
                 android:visibility="gone"
                 style="@style/FilledButton"/>
-            <org.chromium.ui.widget.ChipView
+            <org.chromium.components.browser_ui.widget.chips.ChipView
                 android:id="@+id/page_info_button"
                 android:gravity="center"
                 android:layout_height="wrap_content"
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
index e85e109c..9bf3db65 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -27,10 +27,10 @@
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.Callback;
 import org.chromium.chrome.tab_ui.R;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.widget.ButtonCompat;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.ui.widget.ChromeImageView;
 import org.chromium.ui.widget.ViewLookupCachingFrameLayout;
 
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
index 494d9f41..14b47da 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
@@ -63,6 +63,7 @@
 import org.chromium.chrome.browser.tab.state.ShoppingPersistedTabData;
 import org.chromium.chrome.tab_ui.R;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.browser_ui.widget.selectable_list.SelectionDelegate;
 import org.chromium.components.commerce.PriceTracking.BuyableProduct;
 import org.chromium.components.commerce.PriceTracking.PriceTrackingData;
@@ -80,7 +81,6 @@
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
 import org.chromium.ui.widget.ButtonCompat;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.ui.widget.ChromeImageView;
 import org.chromium.url.GURL;
 
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java
index 828f78ac..2ea7162 100644
--- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java
+++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java
@@ -882,7 +882,6 @@
                                    .with(TabProperties.TAB_ID, id)
                                    .with(CARD_TYPE, TAB)
                                    .build();
-        doReturn(position).when(viewHolder).getAdapterPosition();
         return viewHolder;
     }
 
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
index 0be4ea6..01f7330 100644
--- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
+++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -70,6 +70,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
@@ -564,6 +565,9 @@
         verify(mTabModel).closeTab(eq(mTab2), eq(null), eq(false), eq(false), eq(true));
     }
 
+    // TODO(crbug.com/1288629): Ignore until we have a way to test onMove without mocking final
+    // methods.
+    @Ignore
     @Test
     public void sendsMoveTabSignalCorrectlyWithoutGroup() {
         initAndAssertAllProperties();
@@ -575,6 +579,7 @@
         verify(mTabModel).moveTab(eq(TAB1_ID), eq(2));
     }
 
+    @Ignore
     @Test
     public void sendsMoveTabSignalCorrectlyWithGroup() {
         setUpForTabGroupOperation(TabListMediatorType.TAB_SWITCHER, TabListMode.GRID);
@@ -589,6 +594,7 @@
         verify(mTabGroupModelFilter).moveRelatedTabs(eq(TAB1_ID), eq(2));
     }
 
+    @Ignore
     @Test
     public void sendsMoveTabSignalCorrectlyWithinGroup() {
         setUpForTabGroupOperation(TabListMediatorType.TAB_GRID_DIALOG, TabListMode.GRID);
@@ -3116,7 +3122,6 @@
                                    .with(TabProperties.TAB_ID, id)
                                    .with(CARD_TYPE, TAB)
                                    .build();
-        doReturn(position).when(viewHolder).getAdapterPosition();
         return viewHolder;
     }
 
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
index db9c073..97320d7 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -39,6 +39,7 @@
 import org.chromium.chrome.browser.feed.sections.SectionHeaderView;
 import org.chromium.chrome.browser.feed.sections.SectionHeaderViewBinder;
 import org.chromium.chrome.browser.feed.settings.FeedAutoplaySettingsFragment;
+import org.chromium.chrome.browser.feed.sort_ui.FeedOptionsCoordinator;
 import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncher;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.ntp.NewTabPageLaunchOrigin;
@@ -284,12 +285,14 @@
 
         // Pull-to-refresh set up.
         if (mSwipeRefreshLayout != null && mSwipeRefreshLayout.getParent() == null) {
-            mSwipeRefreshLayout.addOnRefreshListener(this);
             mSwipeRefreshLayout.addView(mRecyclerView);
             mRootView.addView(mSwipeRefreshLayout);
         } else {
             mRootView.addView(mRecyclerView);
         }
+        if (mSwipeRefreshLayout != null) {
+            mSwipeRefreshLayout.addOnRefreshListener(this);
+        }
 
         mHandler = new Handler(Looper.getMainLooper());
 
@@ -312,9 +315,13 @@
         mSectionHeaderModel.get(SectionHeaderListProperties.SECTION_HEADERS_KEY)
                 .addObserver(mSectionHeaderListModelChangeProcessor);
 
+        FeedOptionsCoordinator optionsCoordinator = new FeedOptionsCoordinator(mActivity);
+        mSectionHeaderModel.set(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY,
+                optionsCoordinator.getView());
+
         // Mediator should be created before any Stream changes.
         mMediator = new FeedSurfaceMediator(this, mActivity, snapScrollHelper, mSectionHeaderModel,
-                getTabIdFromLaunchOrigin(launchOrigin), actionDelegate);
+                getTabIdFromLaunchOrigin(launchOrigin), actionDelegate, optionsCoordinator);
 
         FeedSurfaceTracker.getInstance().trackSurface(this);
 
@@ -636,7 +643,7 @@
             // Feed header view in multi does not need padding added.
             int lateralPaddingsPx = getLateralPaddingsPx();
             if (ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_FEED)
-                    && header == mSectionHeaderView) {
+                    && (header == mSectionHeaderView)) {
                 lateralPaddingsPx = 0;
             }
 
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
index 4c809f5bb..5e91b7a 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -30,6 +30,7 @@
 import org.chromium.chrome.browser.feed.sections.SectionHeaderProperties;
 import org.chromium.chrome.browser.feed.sections.SectionType;
 import org.chromium.chrome.browser.feed.sections.ViewVisibility;
+import org.chromium.chrome.browser.feed.sort_ui.FeedOptionsCoordinator;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.ntp.NewTabPageLaunchOrigin;
 import org.chromium.chrome.browser.ntp.cards.SignInPromo;
@@ -91,7 +92,7 @@
             FeedFeatures.setLastSeenFeedTabId(index);
 
             Stream newStream = mTabToStreamMap.get(index);
-            if (newStream.getOptionsView() != null) {
+            if (newStream.supportsOptions()) {
                 headerList.get(index).set(SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY,
                         ViewVisibility.VISIBLE);
             }
@@ -106,22 +107,19 @@
             PropertyListModel<PropertyModel, PropertyKey> headerList =
                     mSectionHeaderModel.get(SectionHeaderListProperties.SECTION_HEADERS_KEY);
             PropertyModel headerModel = headerList.get(index);
-            if (mTabToStreamMap.get(index).getOptionsView() != null) {
+            if (mTabToStreamMap.get(index).supportsOptions()) {
                 headerModel.set(SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY,
                         ViewVisibility.INVISIBLE);
             }
-            mSectionHeaderModel.set(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY, null);
+            mOptionsCoordinator.ensureGone();
         }
 
         @Override
         public void onSectionHeaderReselected(int index) {
             Stream stream = mTabToStreamMap.get(index);
-            if (stream.getOptionsView() == null) return;
+            if (!stream.supportsOptions()) return;
             // Reselected toggles the visibility of the options view.
-            View currentView =
-                    mSectionHeaderModel.get(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY);
-            mSectionHeaderModel.set(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY,
-                    currentView == null ? stream.getOptionsView() : null);
+            mOptionsCoordinator.toggleVisibility();
         }
     }
 
@@ -185,6 +183,7 @@
     private final SigninManager mSigninManager;
     private final PropertyModel mSectionHeaderModel;
     private final FeedActionDelegate mActionDelegate;
+    private final FeedOptionsCoordinator mOptionsCoordinator;
 
     private @Nullable RecyclerView.OnScrollListener mStreamScrollListener;
     private final ObserverList<ScrollListener> mScrollListeners = new ObserverList<>();
@@ -222,17 +221,19 @@
      * @param snapScrollHelper The {@link SnapScrollHelper} that handles snap scrolling.
      * @param headerModel The {@link PropertyModel} that contains this mediator should work with.
      * @param openingTabId The {@link FeedSurfaceCoordinator.StreamTabId} the feed should open to.
+     * @param optionsCoordinator The {@link FeedOptionsCoordinator} for the feed.
      */
     FeedSurfaceMediator(FeedSurfaceCoordinator coordinator, Context context,
             @Nullable SnapScrollHelper snapScrollHelper, PropertyModel headerModel,
-            @FeedSurfaceCoordinator.StreamTabId int openingTabId,
-            FeedActionDelegate actionDelegate) {
+            @FeedSurfaceCoordinator.StreamTabId int openingTabId, FeedActionDelegate actionDelegate,
+            FeedOptionsCoordinator optionsCoordinator) {
         mCoordinator = coordinator;
         mContext = context;
         mSnapScrollHelper = snapScrollHelper;
         mSigninManager = IdentityServicesProvider.get().getSigninManager(
                 Profile.getLastUsedRegularProfile());
         mActionDelegate = actionDelegate;
+        mOptionsCoordinator = optionsCoordinator;
 
         if (sTestPrefChangeRegistar != null) {
             mPrefChangeRegistrar = sTestPrefChangeRegistar;
@@ -447,10 +448,10 @@
 
         PropertyModel headerModel = SectionHeaderProperties.createSectionHeader(headerText);
         ViewVisibility indicatorVisibility;
-        if (stream.getOptionsView() == null) {
-            indicatorVisibility = ViewVisibility.GONE;
-        } else {
+        if (stream.supportsOptions()) {
             indicatorVisibility = ViewVisibility.INVISIBLE;
+        } else {
+            indicatorVisibility = ViewVisibility.GONE;
         }
         headerModel.set(
                 SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY, indicatorVisibility);
@@ -701,7 +702,7 @@
 
         // Make sure to collapse option panel if not shown.
         if (!suggestionsVisible) {
-            mSectionHeaderModel.set(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY, null);
+            mOptionsCoordinator.ensureGone();
         }
 
         // Set enabled last because it makes the animation smoother.
@@ -741,14 +742,14 @@
 
         // If feed turned on, we bind the last stream that was visible. Else unbind it.
         if (suggestionsVisible) {
-            if (currentStream.getOptionsView() != null) {
+            if (currentStream.supportsOptions()) {
                 currentStreamHeaderModel.set(
                         SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY,
                         ViewVisibility.VISIBLE);
             }
             rebindStream();
         } else {
-            if (currentStream.getOptionsView() != null) {
+            if (currentStream.supportsOptions()) {
                 currentStreamHeaderModel.set(
                         SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY,
                         ViewVisibility.INVISIBLE);
@@ -869,7 +870,7 @@
     }
 
     /**
-     * @return Whether the touch events are enabled on the {@link FeedNewTabPage}.
+     * @return Whether the touch events are enabled.
      * TODO(huayinz): Move this method to a Model once a Model is introduced.
      */
     boolean getTouchEnabled() {
diff --git a/chrome/android/java/res/layout/context_menu_chip.xml b/chrome/android/java/res/layout/context_menu_chip.xml
index abcbb30e..f7364c2 100644
--- a/chrome/android/java/res/layout/context_menu_chip.xml
+++ b/chrome/android/java/res/layout/context_menu_chip.xml
@@ -2,7 +2,7 @@
 <!-- Copyright 2020 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. -->
-<org.chromium.ui.widget.ChipView
+<org.chromium.components.browser_ui.widget.chips.ChipView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/context_menu_chip"
     android:layout_width="wrap_content"
diff --git a/chrome/android/java/res/layout/settings_activity.xml b/chrome/android/java/res/layout/settings_activity.xml
index 62848855..35548db 100644
--- a/chrome/android/java/res/layout/settings_activity.xml
+++ b/chrome/android/java/res/layout/settings_activity.xml
@@ -15,6 +15,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:fitsSystemWindows="true"
+        android:theme="@style/ThemeOverlay.Settings.DisableElevationOverlay"
         app:liftOnScroll="true">
 
         <com.google.android.material.appbar.MaterialToolbar
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index 29573c8..744df5e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -9,6 +9,7 @@
 import org.chromium.build.BuildConfig;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
+import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
 import org.chromium.chrome.browser.feed.FeedPlaceholderLayout;
 import org.chromium.chrome.browser.firstrun.FirstRunUtils;
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
@@ -97,7 +98,6 @@
                 add(ChromeFeatureList.INSTANCE_SWITCHER);
                 add(ChromeFeatureList.INTEREST_FEED_V2);
                 add(ChromeFeatureList.NEW_WINDOW_APP_MENU);
-                add(ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK);
                 add(ChromeFeatureList.OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS);
                 add(ChromeFeatureList.PAINT_PREVIEW_DEMO);
                 add(ChromeFeatureList.PAINT_PREVIEW_SHOW_ON_STARTUP);
@@ -131,6 +131,9 @@
                         add(OptimizationGuidePushNotificationManager.MAX_CACHE_SIZE);
                         add(PageAnnotationsServiceConfig.PAGE_ANNOTATIONS_BASE_URL);
                         add(ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS);
+                        add(CustomTabIntentDataProvider.THIRD_PARTIES_DEFAULT_POLICY);
+                        add(CustomTabIntentDataProvider.DENYLIST_ENTRIES);
+                        add(CustomTabIntentDataProvider.ALLOWLIST_ENTRIES);
                         add(StartSurfaceConfiguration.CHECK_SYNC_BEFORE_SHOW_START_AT_STARTUP);
                         add(StartSurfaceConfiguration.FINALE_ANIMATION_ENABLED);
                         add(StartSurfaceConfiguration.HOME_BUTTON_ON_GRID_TAB_SWITCHER);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java
index 49fb678..345ffb27 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java
@@ -14,7 +14,6 @@
 import org.chromium.chrome.browser.notifications.NotificationTriggerBackgroundTask;
 import org.chromium.chrome.browser.notifications.scheduler.NotificationSchedulerTask;
 import org.chromium.chrome.browser.offlinepages.OfflineBackgroundTask;
-import org.chromium.chrome.browser.offlinepages.measurements.OfflineMeasurementsBackgroundTask;
 import org.chromium.chrome.browser.offlinepages.prefetch.PrefetchBackgroundTask;
 import org.chromium.chrome.browser.omaha.OmahaService;
 import org.chromium.chrome.browser.services.gcm.GCMBackgroundTask;
@@ -84,8 +83,6 @@
                 return new NotificationTriggerBackgroundTask();
             case TaskIds.PERIODIC_BACKGROUND_SYNC_CHROME_WAKEUP_TASK_JOB_ID:
                 return new PeriodicBackgroundSyncChromeWakeUpTask();
-            case TaskIds.OFFLINE_MEASUREMENT_JOB_ID:
-                return new OfflineMeasurementsBackgroundTask();
             case TaskIds.ATTRIBUTION_PROVIDER_FLUSH_JOB_ID:
                 return AttributionReportingJobFactory.getAttributionReportingProviderFlushTask();
             // End of Java tasks. All native tasks should be listed here.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java
index 7b798862..641a3df 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java
@@ -26,9 +26,9 @@
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.components.bookmarks.BookmarkId;
 import org.chromium.components.browser_ui.widget.RoundedCornerOutlineProvider;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.image_fetcher.ImageFetcher;
 import org.chromium.components.payments.CurrencyFormatter;
-import org.chromium.ui.widget.ChipView;
 
 import java.util.Arrays;
 import java.util.Locale;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java
index f15a8ce3..4240a8c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java
@@ -16,10 +16,10 @@
 
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.ui.text.SpanApplier;
 import org.chromium.ui.text.SpanApplier.SpanInfo;
 import org.chromium.ui.widget.AnchoredPopupWindow;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.ui.widget.ViewRectProvider;
 
 import java.lang.annotation.Retention;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInternalStateController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInternalStateController.java
index c7b544c..a54bc4bb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInternalStateController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInternalStateController.java
@@ -431,9 +431,7 @@
                 transitionTo(InternalState.START_SHOWING_TAP_UI);
                 break;
             case InternalState.START_SHOWING_TAP_UI:
-                transitionTo(mPolicy.isLiteralSearchTapEnabled()
-                                ? InternalState.SHOWING_LITERAL_SEARCH
-                                : InternalState.SHOW_RESOLVING_UI);
+                transitionTo(InternalState.SHOW_RESOLVING_UI);
                 break;
             case InternalState.SHOW_RESOLVING_UI:
                 transitionTo(mPolicy.shouldPreviousGestureResolve()
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
index a55942b3..4542872 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -1824,8 +1824,7 @@
                     // Also clear any tap-based selection unless the Tap IPH is showing. In the
                     // latter case we preserve the selection so the help bubble has something to
                     // point to.
-                    if (!mPolicy.isLiteralSearchTapEnabled()
-                            && mSelectionController.getSelectionType() == SelectionType.TAP
+                    if (mSelectionController.getSelectionType() == SelectionType.TAP
                             && !mInProductHelp.isShowingForTappedButShouldLongpress()) {
                         mSelectionController.clearSelection();
                     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
index 0d8283f6..5641466 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
@@ -152,8 +152,7 @@
      * This only checks the gesture, not privacy status -- {@see #shouldPreviousGestureResolve}.
      */
     boolean isResolvingGesture() {
-        return (mSelectionController.getSelectionType() == SelectionType.TAP
-                       && !isLiteralSearchTapEnabled())
+        return mSelectionController.getSelectionType() == SelectionType.TAP
                 || mSelectionController.getSelectionType() == SelectionType.RESOLVING_LONG_PRESS;
     }
 
@@ -309,14 +308,6 @@
     }
 
     /**
-     * @return whether the experiment that causes a tap gesture to trigger a literal search for the
-     *         selection (rather than sending context to resolve a search term) is enabled.
-     */
-    boolean isLiteralSearchTapEnabled() {
-        return ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP);
-    }
-
-    /**
      * Determines whether an error from a search term resolution request should
      * be shown to the user, or not.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
index 998c698..cdc16ea 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -44,6 +44,7 @@
 import org.chromium.chrome.browser.flags.ActivityType;
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.flags.StringCachedFieldTrialParameter;
 import org.chromium.components.browser_ui.widget.TintedDrawable;
 import org.chromium.components.embedder_support.util.UrlConstants;
 import org.chromium.components.version_info.VersionInfo;
@@ -168,6 +169,22 @@
     public static final String EXTRA_INITIAL_ACTIVITY_HEIGHT_IN_PIXEL =
             "androidx.browser.customtabs.extra.INITIAL_ACTIVITY_HEIGHT_IN_PIXEL";
 
+    private static final String DEFAULT_POLICY_PARAM_NAME = "default_policy";
+    private static final String DEFAULT_POLICY_USE_DENYLIST = "use-denylist";
+    private static final String DEFAULT_POLICY_USE_ALLOWLIST = "use-allowlist";
+    private static final String ALLOWLIST_ENTRIES_PARAM_NAME = "allowlist_entries";
+    private static final String DENYLIST_ENTRIES_PARAM_NAME = "denylist_entries";
+
+    public static final StringCachedFieldTrialParameter THIRD_PARTIES_DEFAULT_POLICY =
+            new StringCachedFieldTrialParameter(ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES,
+                    DEFAULT_POLICY_PARAM_NAME, DEFAULT_POLICY_USE_DENYLIST);
+    public static final StringCachedFieldTrialParameter DENYLIST_ENTRIES =
+            new StringCachedFieldTrialParameter(ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES,
+                    DENYLIST_ENTRIES_PARAM_NAME, "");
+    public static final StringCachedFieldTrialParameter ALLOWLIST_ENTRIES =
+            new StringCachedFieldTrialParameter(ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES,
+                    ALLOWLIST_ENTRIES_PARAM_NAME, "");
+
     private final Intent mIntent;
     private final CustomTabsSessionToken mSession;
     private final boolean mIsTrustedIntent;
@@ -801,15 +818,36 @@
 
     @Override
     public @Px int getInitialActivityHeight() {
-        boolean enabledForAll =
-                CachedFeatureFlags.isEnabled(ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES);
         boolean enabledDueToFirstParty = mIsTrustedIntent
                 && CachedFeatureFlags.isEnabled(ChromeFeatureList.CCT_RESIZABLE_FOR_FIRST_PARTIES);
-
-        if (enabledForAll || enabledDueToFirstParty) {
+        boolean enabledDueToThirdParty =
+                CachedFeatureFlags.isEnabled(ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES)
+                && isAllowedThirdParty(getClientPackageName());
+        if (enabledDueToThirdParty || enabledDueToFirstParty) {
             return mInitialActivityHeight;
-        } else {
-            return 0;
         }
+        return 0;
+    }
+
+    boolean isAllowedThirdParty(String packageName) {
+        if (packageName == null) return false;
+        String defaultPolicy = THIRD_PARTIES_DEFAULT_POLICY.getValue();
+        if (defaultPolicy.equals(DEFAULT_POLICY_USE_ALLOWLIST)) {
+            String allowList = ALLOWLIST_ENTRIES.getValue();
+            if (TextUtils.isEmpty(allowList)) return false;
+            for (String p : allowList.split("\\|")) {
+                if (packageName.equals(p)) return true;
+            }
+            return false;
+        } else if (defaultPolicy.equals(DEFAULT_POLICY_USE_DENYLIST)) {
+            String denyList = DENYLIST_ENTRIES.getValue();
+            if (TextUtils.isEmpty(denyList)) return true;
+            for (String p : denyList.split("\\|")) {
+                if (packageName.equals(p)) return false;
+            }
+            return true;
+        }
+        assert false : "We can't get here since the default policy is use denylist.";
+        return false;
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
index ffb14d3..5f75116 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
@@ -7,12 +7,13 @@
 import android.app.Activity;
 import android.os.Bundle;
 
+import com.google.android.material.color.DynamicColors;
+
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.TraceEvent;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.LaunchIntentDispatcher;
 import org.chromium.chrome.browser.theme.ThemeUtils;
-import org.chromium.chrome.browser.ui.theme.ColorDelegateImpl;
 import org.chromium.chrome.browser.vr.VrModuleProvider;
 
 /**
@@ -60,7 +61,7 @@
         // The effect of this activity's theme is currently limited to CCTs, so we should only apply
         // dynamic colors when we enable them everywhere.
         if (ThemeUtils.ENABLE_FULL_DYNAMIC_COLORS.getValue()) {
-            new ColorDelegateImpl().applyDynamicColorsIfAvailable(this);
+            DynamicColors.applyIfAvailable(this);
         }
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
index f047233..804debbd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
@@ -423,7 +423,7 @@
         deferredStartupHandler.addDeferredTask(
                 () -> TosDialogBehaviorSharedPrefInvalidator.refreshSharedPreferenceIfTosSkipped());
         deferredStartupHandler.addDeferredTask(
-                () -> OfflineMeasurementsBackgroundTask.maybeScheduleTask());
+                () -> OfflineMeasurementsBackgroundTask.clearPersistedDataFromPrefs());
         deferredStartupHandler.addDeferredTask(() -> QueryTileUtils.isQueryTilesEnabledOnNTP());
         deferredStartupHandler.addDeferredTask(
                 ()
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
index 146fb03..ef80623 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -16,7 +16,6 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.browser.offlinepages.measurements.OfflineMeasurementsBackgroundTask;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileKey;
 import org.chromium.chrome.browser.tab.Tab;
@@ -660,16 +659,6 @@
         return loadUrlParams;
     }
 
-    @CalledByNative
-    private static byte[] getSystemStateListFromOfflineMeasurementsAsBytes() {
-        return OfflineMeasurementsBackgroundTask.getPersistedSystemStateListAsBytes();
-    }
-
-    @CalledByNative
-    private static void reportOfflineMeasurementMetricsToUmaAndClear() {
-        OfflineMeasurementsBackgroundTask.reportMetricsToUmaAndClear();
-    }
-
     @NativeMethods
     interface Natives {
         boolean canSavePage(GURL url);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTask.java
index bec07ff4..8b268271 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTask.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTask.java
@@ -4,333 +4,22 @@
 
 package org.chromium.chrome.browser.offlinepages.measurements;
 
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Base64;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.ApplicationState;
-import org.chromium.base.ApplicationStatus;
-import org.chromium.base.Callback;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.task.AsyncTask;
-import org.chromium.chrome.browser.content.ContentUtils;
-import org.chromium.chrome.browser.flags.CachedFeatureFlags;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.offline_pages.measurements.proto.OfflineMeasurementsProto.SystemState;
-import org.chromium.chrome.browser.offline_pages.measurements.proto.OfflineMeasurementsProto.SystemStateList;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.components.background_task_scheduler.BackgroundTask;
-import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
-import org.chromium.components.background_task_scheduler.TaskIds;
-import org.chromium.components.background_task_scheduler.TaskInfo;
-import org.chromium.components.background_task_scheduler.TaskParameters;
-import org.chromium.net.ChromiumNetworkAdapter;
-import org.chromium.net.NetworkTrafficAnnotationTag;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Calendar;
-import java.util.concurrent.TimeUnit;
 
 /**
- * Collects data about how often the user is offline, and what they do while offline.
+ * This class clears the persisted data in prefs from OfflineMeasurementsBackgroundTask.
  */
-public class OfflineMeasurementsBackgroundTask implements BackgroundTask {
-    // Finch parameters and default values.
-    public static final String MEASUREMENT_INTERVAL_IN_MINUTES = "measurement_interval_in_minutes";
-    public static final int DEFAULT_MEASUREMENT_INTERVAL_IN_MINUTES = 60;
-
-    private static final String HTTP_PROBE_URL = "http_probe_url";
-    private static final String DEFAULT_HTTP_PROBE_URL = "https://www.google.com/generate_204";
-
-    private static final String HTTP_PROBE_TIMEOUT_MS = "http_probe_timeout_ms";
-    private static final int DEFAULT_HTTP_PROBE_TIMEOUT_MS = 5000;
-
-    private static final String HTTP_PROBE_METHOD = "http_probe_method";
-    private static final String DEFAULT_HTTP_PROBE_METHOD = "GET";
-
-    // HTTP probe constant.
-    private static final String USER_AGENT_HEADER_NAME = "User-Agent";
-
-    // Testing overrides
-    private static int sNewMeasurementIntervalInMinutesTestingOverride;
-    private static Boolean sIsAirplaneModeEnabledTestingOverride;
-    private static Boolean sIsRoamingTestingOverride;
-    private static Boolean sIsInteractiveTestingOverride;
-    private static Boolean sIsApplicationForegroundTestingOverride;
-
-    // UMA histograms.
-    public static final String OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL =
-            "Offline.Measurements.MeasurementInterval";
-    public static final String OFFLINE_MEASUREMENTS_TIME_BETWEEN_CHECKS =
-            "Offline.Measurements.TimeBetweenChecks";
-    public static final String OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT =
-            "Offline.Measurements.HttpProbeResult";
-    public static final String OFFLINE_MEASUREMENTS_IS_AIRPLANE_MODE_ENABLED =
-            "Offline.Measurements.IsAirplaneModeEnabled";
-    public static final String OFFLINE_MEASUREMENTS_IS_ROAMING = "Offline.Measurements.IsRoaming";
-    public static final String OFFLINE_MEASUREMENTS_USER_STATE = "Offline.Measurements.UserState";
-
-    // The result of the HTTP probing. Defined in tools/metrics/histograms/enums.xml.
-    // These values are persisted to logs. Entries should not be renumbered and
-    // numeric values should never be reused. These values are also defined in
-    // chrome/browser/offline_pages/measurements/proto/system_state.proto.
-    @IntDef({ProbeResult.INVALID, ProbeResult.NO_INTERNET, ProbeResult.SERVER_ERROR,
-            ProbeResult.UNEXPECTED_RESPONSE, ProbeResult.VALIDATED, ProbeResult.CANCELLED,
-            ProbeResult.MULTIPLE_URL_CONNECTIONS_OPEN})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ProbeResult {
-        // Value could not be parsed from Prefs.
-        int INVALID = 0;
-        // The HTTP probe could not connect to the Internet.
-        int NO_INTERNET = 1;
-        // Server returns response code >= 400.
-        int SERVER_ERROR = 2;
-        // Received an unepxected response from the server. This is most likely from either a
-        // captive protal or a broken transparent proxy.
-        int UNEXPECTED_RESPONSE = 3;
-        // Validated when the expected result is received from server.
-        int VALIDATED = 4;
-        // The HTTP probe was cancelled before it could finish, because the background task was
-        // stopped.
-        int CANCELLED = 5;
-        // Multiple HttpURLConnections were running at the same time causing the HTTP probe to fail.
-        int MULTIPLE_URL_CONNECTIONS_OPEN = 6;
-        // Count.
-        int RESULT_COUNT = 7;
-    }
-
-    // The state of the phone and how / if the user is interacting with it. Defined in
-    // tools/metrics/histograms/enums.xml. These values are persisted to logs. Entries should not be
-    // renumbered and numeric values should never be reused. These values are also defined in
-    // chrome/browser/offline_pages/measurements/proto/system_state.proto.
-    @IntDef({UserState.INVALID, UserState.PHONE_OFF, UserState.NOT_USING_PHONE,
-            UserState.USING_CHROME})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface UserState {
-        // Value could not be parsed from Prefs.
-        int INVALID = 0;
-        // The user's phone was off..
-        int PHONE_OFF = 1;
-        // The user's phone screen is not interactive.
-        int NOT_USING_PHONE = 2;
-        // The user's phone screen is interactive and Chrome is not in the foreground.
-        int USING_PHONE_NOT_CHROME = 3;
-        // The user's phone screen is interactive and Chrome is in the foreground.
-        int USING_CHROME = 4;
-        // Count.
-        int RESULT_COUNT = 5;
-    }
-
-    /**
-     * Clock to use so we can mock the time in tests.
-     */
-    public static class Clock {
-        long currentTimeMillis() {
-            return System.currentTimeMillis();
-        }
-
-        long elapsedRealtime() {
-            return SystemClock.elapsedRealtime();
-        }
-
-        int getLocalHourOfDay() {
-            return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
-        }
-    }
-    private static Clock sClock = new Clock();
-
-    @VisibleForTesting
-    static void setClockForTesting(Clock clock) {
-        sClock = clock;
-    }
-
-    // Runs the HTTP probe.
-    private AsyncTask<Integer> mHttpProbeAsyncTask;
-
-    public OfflineMeasurementsBackgroundTask() {}
-
-    public static void maybeScheduleTask() {
-        if (ChromeFeatureList.isEnabled(ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK)) {
-            scheduleTask();
-        } else {
-            cancelTaskAndClearPersistedMetrics();
-        }
-    }
-
-    public static byte[] getPersistedSystemStateListAsBytes() {
-        return getSystemStateListFromPrefs().toByteArray();
-    }
-
-    public static void reportMetricsToUmaAndClear() {
-        SystemStateList systemStateList = getSystemStateListFromPrefs();
-
-        // Record the data in the system state list to UMA.
-        // TODO(1131600): Move the logging of UMA metrics to Native alongside the logging of metrics
-        // to UKM.
-        for (SystemState systemState : systemStateList.getSystemStatesList()) {
-            if (systemState.hasTimeSinceLastCheckMillis()) {
-                RecordHistogram.recordCustomTimesHistogram(OFFLINE_MEASUREMENTS_TIME_BETWEEN_CHECKS,
-                        systemState.getTimeSinceLastCheckMillis(), TimeUnit.MINUTES.toMillis(1),
-                        TimeUnit.DAYS.toMillis(1), 50);
-            }
-
-            if (systemState.hasUserState()) {
-                RecordHistogram.recordEnumeratedHistogram(OFFLINE_MEASUREMENTS_USER_STATE,
-                        systemState.getUserState().getNumber(), UserState.RESULT_COUNT);
-            }
-
-            if (systemState.hasProbeResult()) {
-                RecordHistogram.recordEnumeratedHistogram(OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT,
-                        systemState.getProbeResult().getNumber(), ProbeResult.RESULT_COUNT);
-            }
-
-            if (systemState.hasIsRoaming()) {
-                RecordHistogram.recordBooleanHistogram(
-                        OFFLINE_MEASUREMENTS_IS_ROAMING, systemState.getIsRoaming());
-            }
-
-            if (systemState.hasIsAirplaneModeEnabled()) {
-                RecordHistogram.recordBooleanHistogram(
-                        OFFLINE_MEASUREMENTS_IS_AIRPLANE_MODE_ENABLED,
-                        systemState.getIsAirplaneModeEnabled());
-            }
-        }
-
-        // Clear the data from prefs so it isn't logged again.
-        clearSystemStateListFromPrefs();
-    }
-
-    private static void scheduleTask() {
-        updateHttpProbeParameters();
-
-        int newMeasurementIntervalInMinutes = getNewMeasurementIntervalInMinutes();
-        int currentTaskMeasurementIntervalInMinutes = getCurrentTaskMeasurementIntervalInMinutes();
-
-        // If the current task has the same parameters as the parameter from Finch, then we don't
-        // have to do anything.
-        if (currentTaskMeasurementIntervalInMinutes == newMeasurementIntervalInMinutes) {
-            return;
-        }
-
-        // If the parameter stored in Prefs is non-zero, then the task is already running. In that
-        // case we need to cancel it first so we can schedule it with the new parameter.
-        if (currentTaskMeasurementIntervalInMinutes != 0) {
-            cancelTaskAndClearPersistedMetrics();
-        }
-
-        // Schedule the task with the new interval.
-        TaskInfo.TimingInfo timingInfo =
-                TaskInfo.PeriodicInfo.create()
-                        .setIntervalMs(TimeUnit.MINUTES.toMillis(newMeasurementIntervalInMinutes))
-                        .build();
-
-        TaskInfo taskInfo = TaskInfo.createTask(TaskIds.OFFLINE_MEASUREMENT_JOB_ID, timingInfo)
-                                    .setIsPersisted(true)
-                                    .build();
-
-        BackgroundTaskSchedulerFactory.getScheduler().schedule(
-                ContextUtils.getApplicationContext(), taskInfo);
-
-        RecordHistogram.recordCustomTimesHistogram(OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL,
-                TimeUnit.MINUTES.toMillis(newMeasurementIntervalInMinutes),
-                TimeUnit.MINUTES.toMillis(1), TimeUnit.DAYS.toMillis(1), 50);
-
-        setCurrentTaskMeasurementIntervalInMinutes(newMeasurementIntervalInMinutes);
-        setLastCheckMillis(-1);
-    }
-
-    private static void cancelTaskAndClearPersistedMetrics() {
-        // Cancels the task if is currently running.
-        long currentTaskMeasurementIntervalInMinutes = getCurrentTaskMeasurementIntervalInMinutes();
-        if (currentTaskMeasurementIntervalInMinutes != 0) {
-            BackgroundTaskSchedulerFactory.getScheduler().cancel(
-                    ContextUtils.getApplicationContext(), TaskIds.OFFLINE_MEASUREMENT_JOB_ID);
-        }
-
-        // Clears the state stored in Prefs.
+public class OfflineMeasurementsBackgroundTask {
+    public static void clearPersistedDataFromPrefs() {
+        // Clear any data persisted in prefs.
         SharedPreferencesManager sharedPreferencesManager = SharedPreferencesManager.getInstance();
+
         sharedPreferencesManager.removeKey(
                 ChromePreferenceKeys.OFFLINE_MEASUREMENTS_LAST_CHECK_MILLIS);
         sharedPreferencesManager.removeKey(
                 ChromePreferenceKeys
                         .OFFLINE_MEASUREMENTS_CURRENT_TASK_MEASUREMENT_INTERVAL_IN_MINUTES);
-        clearHttpProbeParametersFromPrefs();
-    }
-
-    private static int getNewMeasurementIntervalInMinutes() {
-        if (sNewMeasurementIntervalInMinutesTestingOverride > 0) {
-            return sNewMeasurementIntervalInMinutesTestingOverride;
-        }
-
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK,
-                MEASUREMENT_INTERVAL_IN_MINUTES, DEFAULT_MEASUREMENT_INTERVAL_IN_MINUTES);
-    }
-
-    @VisibleForTesting
-    static void setNewMeasurementIntervalInMinutesForTesting(int measurementIntervalInMinutes) {
-        sNewMeasurementIntervalInMinutesTestingOverride = measurementIntervalInMinutes;
-    }
-
-    /**
-     * Gets the latest Finch parameters for the HTTP probe, then writes them to prefs if using a
-     * non-default value.
-     */
-    private static void updateHttpProbeParameters() {
-        // Clears any params currently stored in Prefs.
-        clearHttpProbeParametersFromPrefs();
-
-        SharedPreferencesManager sharedPreferencesManager = SharedPreferencesManager.getInstance();
-
-        // Gets the User Agent from ContentUtils.
-        String userAgentString = ContentUtils.getBrowserUserAgent();
-        sharedPreferencesManager.writeString(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_USER_AGENT_STRING, userAgentString);
-
-        // Gets the parameters from Finch. If there is a value for a given parameter and it doesn't
-        // match the default value, then it is written to Prefs.
-        String httpProbeUrl = ChromeFeatureList.getFieldTrialParamByFeature(
-                ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK, HTTP_PROBE_URL);
-        if (!httpProbeUrl.isEmpty() && !httpProbeUrl.equals(DEFAULT_HTTP_PROBE_URL)) {
-            sharedPreferencesManager.writeString(
-                    ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_URL, httpProbeUrl);
-        }
-
-        int httpProbeTimeoutMs = ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK, HTTP_PROBE_TIMEOUT_MS,
-                DEFAULT_HTTP_PROBE_TIMEOUT_MS);
-        if (httpProbeTimeoutMs != DEFAULT_HTTP_PROBE_TIMEOUT_MS) {
-            sharedPreferencesManager.writeInt(
-                    ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_TIMEOUT_MS,
-                    httpProbeTimeoutMs);
-        }
-
-        String httpProbeMethod = ChromeFeatureList.getFieldTrialParamByFeature(
-                ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK, HTTP_PROBE_METHOD);
-        if (!httpProbeMethod.isEmpty() && !httpProbeMethod.equals(DEFAULT_HTTP_PROBE_METHOD)) {
-            sharedPreferencesManager.writeString(
-                    ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_METHOD, httpProbeMethod);
-        }
-    }
-
-    /** Clears the HTTP probe parameters from Prefs. */
-    private static void clearHttpProbeParametersFromPrefs() {
-        // Clears the state stored in Prefs.
-        SharedPreferencesManager sharedPreferencesManager = SharedPreferencesManager.getInstance();
         sharedPreferencesManager.removeKey(
                 ChromePreferenceKeys.OFFLINE_MEASUREMENTS_USER_AGENT_STRING);
         sharedPreferencesManager.removeKey(
@@ -339,353 +28,7 @@
                 ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_TIMEOUT_MS);
         sharedPreferencesManager.removeKey(
                 ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_METHOD);
-    }
-
-    @VisibleForTesting
-    static void setHttpProbeUrlForTesting(String httpProbeUrl) {
-        SharedPreferencesManager.getInstance().writeString(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_URL, httpProbeUrl);
-    }
-
-    @VisibleForTesting
-    static void setHttpProbeMethodForTesting(String httpProbeMethod) {
-        SharedPreferencesManager.getInstance().writeString(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_METHOD, httpProbeMethod);
-    }
-
-    /** Writes the interval used to schedule the current task to Prefs. */
-    private static void setCurrentTaskMeasurementIntervalInMinutes(
-            int currentTaskMeasurementIntervalInMinutes) {
-        SharedPreferencesManager.getInstance().writeInt(
-                ChromePreferenceKeys
-                        .OFFLINE_MEASUREMENTS_CURRENT_TASK_MEASUREMENT_INTERVAL_IN_MINUTES,
-                currentTaskMeasurementIntervalInMinutes);
-    }
-
-    /**
-     * Gets the value of the current measurement interval stored in Prefs. If the task is not
-     * running, this will be zero. If the task is running already, it will be the Finch parameter
-     * used to start it.
-     */
-    private static int getCurrentTaskMeasurementIntervalInMinutes() {
-        return SharedPreferencesManager.getInstance().readInt(
-                ChromePreferenceKeys
-                        .OFFLINE_MEASUREMENTS_CURRENT_TASK_MEASUREMENT_INTERVAL_IN_MINUTES);
-    }
-
-    /** Writes the time (in milliseconds) of the last background check to Prefs. */
-    private static void setLastCheckMillis(long lastCheckMillis) {
-        SharedPreferencesManager.getInstance().writeLong(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_LAST_CHECK_MILLIS, lastCheckMillis);
-    }
-
-    /** Gets the time (in milliseconds) of the last background check to Prefs. */
-    private static long getLastCheckMillis() {
-        return SharedPreferencesManager.getInstance().readLong(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_LAST_CHECK_MILLIS);
-    }
-
-    @Override
-    public void reschedule(Context context) {
-        scheduleTask();
-    }
-
-    @Override
-    public boolean onStartTask(
-            Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
-        // If feature is no longer enabled, cancels the periodic task so it doesn't run again.
-        if (!CachedFeatureFlags.isEnabled(ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK)) {
-            cancelTaskAndClearPersistedMetrics();
-            return false;
-        }
-
-        // Calculates the time since the last time this task was run and record it to UMA.
-        long lastCheckMillis = getLastCheckMillis();
-        long currentCheckMillis = sClock.currentTimeMillis();
-        setLastCheckMillis(currentCheckMillis);
-
-        boolean didSystemBootSinceLastCheck = false;
-        SystemState.Builder partialSystemState = SystemState.newBuilder();
-        if (lastCheckMillis > 0) {
-            long timeSinceLastChecksMillis = currentCheckMillis - lastCheckMillis;
-
-            long timeSinceBootMillis = sClock.elapsedRealtime();
-            didSystemBootSinceLastCheck = timeSinceBootMillis < timeSinceLastChecksMillis;
-
-            partialSystemState.setTimeSinceLastCheckMillis(timeSinceLastChecksMillis);
-        }
-
-        int localHourOfDay = sClock.getLocalHourOfDay();
-
-        // Gets whether airplane mode is enabled or disabled.
-        boolean isAirplaneModeEnabled = isAirplaneModeEnabled(context);
-        boolean isInteractive = isInteractive(context);
-        boolean isApplicationForeground = isApplicationForeground();
-
-        int userState = convertToUserState(
-                didSystemBootSinceLastCheck, isInteractive, isApplicationForeground);
-
-        partialSystemState.setUserState(SystemState.UserState.forNumber(userState))
-                .setIsAirplaneModeEnabled(isAirplaneModeEnabled)
-                .setLocalHourOfDayStart(localHourOfDay);
-
-        try {
-            boolean isRoaming = isRoaming(context);
-            partialSystemState.setIsRoaming(isRoaming);
-        } catch (SecurityException e) {
-            // When getting the capabilities of a network, we can encounter a SecurityException in
-            // some cases. When this happens we cannot determine if the network is marked as roaming
-            // or not roaming, so we do not record a value for IsRoaming. See crbug/1246848.
-        }
-
-        // Starts the HTTP probe.
-        sendHttpProbe((Integer probeResult) -> {
-            processResult(partialSystemState, probeResult, callback);
-        });
-
-        return true;
-    }
-
-    /**
-     * Saves the result of the HTTP probe to Prefs, and informs the task scheduler that the task is
-     * finished.
-     * @param partialSystemState The portion of the system state that has already been determined.
-     * @param probeResult The result of the HTTP probe as a |ProbeResult|.
-     * @param callback The callback used to inform the background task scheduler that the task has
-     * finished.
-     */
-    private void processResult(SystemState.Builder partialSystemState, Integer probeResult,
-            TaskFinishedCallback callback) {
-        // Adds the result of the HTTP probe to the system state proto, then write the full proto to
-        // Prefs.
-        addSystemStateToListInPrefs(
-                partialSystemState.setProbeResult(SystemState.ProbeResult.forNumber(probeResult))
-                        .build());
-
-        // Informs scheduler that the background task has finished.
-        callback.taskFinished(false);
-    }
-
-    @Override
-    public boolean onStopTask(Context context, TaskParameters taskParameters) {
-        // Cancels the HTTP probe if it is still running.
-        if (mHttpProbeAsyncTask != null) {
-            mHttpProbeAsyncTask.cancel(true);
-            addSystemStateToListInPrefs(SystemState.newBuilder()
-                                                .setProbeResult(SystemState.ProbeResult.CANCELLED)
-                                                .build());
-        }
-
-        // Informs the scheduler that the task does not need to be rescheduled.
-        return false;
-    }
-
-    /**
-     * Starts an HTTP probe in an async task which calls the given callback once with the results of
-     * the probe as input.
-     * @param callback The callback called once the HTTP probe has finished. The input to the
-     * callback is the result of the probe as a |ProbeResult|.
-     */
-    private void sendHttpProbe(final Callback<Integer> callback) {
-        // Gets the HTTP parameters from Prefs. Uses the default value if no value in prefs.
-        SharedPreferencesManager sharedPreferencesManager = SharedPreferencesManager.getInstance();
-        String userAgentString = sharedPreferencesManager.readString(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_USER_AGENT_STRING, "");
-        String httpProbeUrl = sharedPreferencesManager.readString(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_URL, DEFAULT_HTTP_PROBE_URL);
-        int httpProbeTimeoutMs = sharedPreferencesManager.readInt(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_TIMEOUT_MS,
-                DEFAULT_HTTP_PROBE_TIMEOUT_MS);
-        String httpProbeMethod = sharedPreferencesManager.readString(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_METHOD,
-                DEFAULT_HTTP_PROBE_METHOD);
-
-        mHttpProbeAsyncTask = new AsyncTask<Integer>() {
-            @Override
-            protected Integer doInBackground() {
-                HttpURLConnection urlConnection = null;
-                try {
-                    URL url = new URL(httpProbeUrl);
-                    urlConnection = (HttpURLConnection) ChromiumNetworkAdapter.openConnection(
-                            url, NetworkTrafficAnnotationTag.MISSING_TRAFFIC_ANNOTATION);
-                    urlConnection.setInstanceFollowRedirects(false);
-                    urlConnection.setRequestMethod(httpProbeMethod);
-                    urlConnection.setConnectTimeout(httpProbeTimeoutMs);
-                    urlConnection.setReadTimeout(httpProbeTimeoutMs);
-                    urlConnection.setUseCaches(false);
-                    urlConnection.setRequestProperty(USER_AGENT_HEADER_NAME, userAgentString);
-
-                    urlConnection.connect();
-                    int responseCode = urlConnection.getResponseCode();
-
-                    if (responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
-                        // Validated the connection with no content.
-                        return ProbeResult.VALIDATED;
-                    }
-
-                    if (responseCode >= 400) {
-                        // There is still needs to be a connection in order to receive a server
-                        // error response.
-                        return ProbeResult.SERVER_ERROR;
-                    }
-                } catch (IOException e) {
-                    // Most likely the exception is thrown due to host name not resolved or socket
-                    // timeout.
-                    return ProbeResult.NO_INTERNET;
-                } catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
-                    // Most likely these exceptions were thrown due to two HttpURLConnections
-                    // running at the same time.
-                    return ProbeResult.MULTIPLE_URL_CONNECTIONS_OPEN;
-                } finally {
-                    if (urlConnection != null) {
-                        urlConnection.disconnect();
-                    }
-                }
-                // The result doesn't match the expected result. This is likely caused by a captive
-                // portal or a broken transparent proxy.
-                return ProbeResult.UNEXPECTED_RESPONSE;
-            }
-
-            @Override
-            protected void onPostExecute(Integer result) {
-                callback.onResult(result);
-            }
-        };
-        mHttpProbeAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-    }
-
-    /**
-     * Determines if airplane mode is enabled or disabled currently.
-     * @param context The current application context.
-     * @return Whether or not airplane mode is currently enabled. If context is null, then false is
-     *         returned.
-     */
-    private static boolean isAirplaneModeEnabled(Context context) {
-        if (sIsAirplaneModeEnabledTestingOverride != null) {
-            return sIsAirplaneModeEnabledTestingOverride;
-        }
-
-        return Settings.Global.getInt(
-                       context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0)
-                != 0;
-    }
-
-    /**
-     * Whether or not the system is currently roaming.
-     * @param context the current application context.
-     * @return Whether or not all current networks are roaming or not. If at least one network is
-     *         not roaming, then false is returned. If context is null, then false is also returned.
-     */
-    private static boolean isRoaming(Context context) {
-        if (sIsRoamingTestingOverride != null) {
-            return sIsRoamingTestingOverride;
-        }
-
-        ConnectivityManager connectivityManager =
-                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        Network[] allNetworks = connectivityManager.getAllNetworks();
-
-        // If there are no networks, then the system is completely offline. We consider this as not
-        // roaming.
-        if (allNetworks.length == 0) {
-            return false;
-        }
-
-        // If and only if all networks are roaming, then the system is roaming.
-        for (Network network : allNetworks) {
-            NetworkCapabilities networkCapabilities =
-                    connectivityManager.getNetworkCapabilities(network);
-            if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private static boolean isInteractive(Context context) {
-        if (sIsInteractiveTestingOverride != null) {
-            return sIsInteractiveTestingOverride;
-        }
-
-        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        return powerManager.isInteractive();
-    }
-
-    private static boolean isApplicationForeground() {
-        if (sIsApplicationForegroundTestingOverride != null) {
-            return sIsApplicationForegroundTestingOverride;
-        }
-
-        return ApplicationStatus.getStateForApplication()
-                == ApplicationState.HAS_RUNNING_ACTIVITIES;
-    }
-
-    @VisibleForTesting
-    static void setIsAirplaneModeEnabledForTesting(boolean isAirplaneModeEnabled) {
-        sIsAirplaneModeEnabledTestingOverride = isAirplaneModeEnabled;
-    }
-
-    @VisibleForTesting
-    static void setIsRoamingForTesting(boolean isRoaming) {
-        sIsRoamingTestingOverride = isRoaming;
-    }
-
-    @VisibleForTesting
-    static void setIsInteractiveForTesting(boolean isInteractive) {
-        sIsInteractiveTestingOverride = isInteractive;
-    }
-
-    @VisibleForTesting
-    static void setIsApplicationForegroundForTesting(boolean isApplicationForeground) {
-        sIsApplicationForegroundTestingOverride = isApplicationForeground;
-    }
-
-    private static int convertToUserState(boolean didSystemBootSinceLastCheck,
-            boolean isInteractive, boolean isApplicationForeground) {
-        if (didSystemBootSinceLastCheck) {
-            return UserState.PHONE_OFF;
-        }
-        if (!isInteractive) {
-            return UserState.NOT_USING_PHONE;
-        }
-        if (isApplicationForeground) {
-            return UserState.USING_CHROME;
-        }
-        return UserState.USING_PHONE_NOT_CHROME;
-    }
-
-    private static String getSystemStateListFromPrefsAsString() {
-        return SharedPreferencesManager.getInstance().readString(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_SYSTEM_STATE_LIST, "");
-    }
-
-    private static void addSystemStateToListInPrefs(SystemState systemState) {
-        SystemStateList systemStateList = getSystemStateListFromPrefs();
-        systemStateList =
-                SystemStateList.newBuilder(systemStateList).addSystemStates(systemState).build();
-        SharedPreferencesManager.getInstance().writeString(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_SYSTEM_STATE_LIST,
-                Base64.encodeToString(systemStateList.toByteArray(), Base64.DEFAULT));
-    }
-
-    private static SystemStateList getSystemStateListFromPrefs() {
-        String rawList = getSystemStateListFromPrefsAsString();
-        try {
-            return SystemStateList.parseFrom(Base64.decode(rawList, Base64.DEFAULT));
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            // If we can't parse the system state list from prefs, return a list with one invalid
-            // entry.
-            SystemState invalidSystemState =
-                    SystemState.newBuilder()
-                            .setUserState(SystemState.UserState.INVALID_USER_STATE)
-                            .setProbeResult(SystemState.ProbeResult.INVALID_PROBE_RESULT)
-                            .build();
-            return SystemStateList.newBuilder().addSystemStates(invalidSystemState).build();
-        }
-    }
-
-    private static void clearSystemStateListFromPrefs() {
-        SharedPreferencesManager.getInstance().removeKey(
+        sharedPreferencesManager.removeKey(
                 ChromePreferenceKeys.OFFLINE_MEASUREMENTS_SYSTEM_STATE_LIST);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
index 6e217a0e..9b2a9ac 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
@@ -443,13 +443,6 @@
         }
     }
 
-    @Override
-    protected void applyThemeOverlays() {
-        super.applyThemeOverlays();
-
-        setTheme(R.style.ThemeRefactorOverlay_Disabled_Settings);
-    }
-
     /**
      * Set device status bar to match the activity background color, if supported.
      */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
index 7ccbde21..8c09843 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
@@ -118,21 +118,18 @@
      */
     private static final ImmutableMap<String, Boolean> ENABLE_NONE =
             ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, false,
                     ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, false);
     /**
-     * This represents the Longpress with LiteralTap configurations, a good launch candidate.
+     * This represents the Longpress configuration, currently launching.
      */
     private static final ImmutableMap<String, Boolean> ENABLE_LONGPRESS =
             ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, true,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, true,
                     ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, false);
     /**
-     * This represents the Translations addition to the Longpress with LiteralTap configuration.
+     * This represents the Translations addition to the Longpress configuration.
      */
     private static final ImmutableMap<String, Boolean> ENABLE_TRANSLATIONS =
             ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, true,
                     ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, true);
 
     /**
@@ -301,13 +298,10 @@
     private class ContextualSearchInstrumentationTestHost implements ContextualSearchTestHost {
         @Override
         public void triggerNonResolve(String nodeId) throws TimeoutException {
-            if (mPolicy.isLiteralSearchTapEnabled()) {
-                clickWordNode(nodeId);
-            } else if (!mPolicy.canResolveLongpress()) {
+            if (!mPolicy.canResolveLongpress() || mPolicy.isUserUndecided()) {
                 longPressNode(nodeId);
             } else {
-                Assert.fail(
-                        "Cannot trigger a non-resolving gesture with literal tap or non-resolve!");
+                Assert.fail("Cannot trigger a non-resolving gesture!");
             }
         }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
index 8e1ab91..fa585291 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -208,15 +208,13 @@
     /** This represents the current fully-launched configuration. */
     private static final ImmutableMap<String, Boolean> ENABLE_NONE =
             ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, false,
                     ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, false);
     /**
-     * This represents the Translations addition to the Longpress with LiteralTap configuration.
+     * This represents the Translations addition to the Longpress configuration.
      * This is likely the best launch candidate.
      */
     private static final ImmutableMap<String, Boolean> ENABLE_TRANSLATIONS =
             ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, true,
                     ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, true);
 
     /** Feature maps that we use for individual tests. */
@@ -348,14 +346,10 @@
     private class ContextualSearchManagerTestHost implements ContextualSearchTestHost {
         @Override
         public void triggerNonResolve(String nodeId) throws TimeoutException {
-            // TODO(donnd): remove support for the LiteralSearchTap Feature.
-            if (mPolicy.isLiteralSearchTapEnabled()) {
-                clickWordNode(nodeId);
-            } else if (!mPolicy.canResolveLongpress()) {
+            if (!mPolicy.canResolveLongpress() || mPolicy.isUserUndecided()) {
                 longPressNode(nodeId);
             } else {
-                Assert.fail(
-                        "Cannot trigger a non-resolving gesture with literal tap or non-resolve!");
+                Assert.fail("Cannot trigger a non-resolving gesture!");
             }
         }
 
@@ -1545,7 +1539,8 @@
     @Feature({"ContextualSearch"})
     @ParameterAnnotations.UseMethodParameter(FeatureParamProvider.class)
     public void testNonResolveTrigger(@EnabledFeature int enabledFeature) throws Exception {
-        if (isConfigurationForResolvingGesturesOnly()) return;
+        // Mark the user undecided so we won't resolve the search.
+        mPolicy.overrideDecidedStateForTesting(false);
         triggerNonResolve("states");
 
         Assert.assertNull(mFakeServer.getSearchTermRequested());
@@ -1596,6 +1591,8 @@
     @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
     @ParameterAnnotations.UseMethodParameter(FeatureParamProvider.class)
     public void testNonResolveSwipeExpand(@EnabledFeature int enabledFeature) throws Exception {
+        // Mark the user undecided so we won't resolve the search.
+        mPolicy.overrideDecidedStateForTesting(false);
         simulateNonResolveSearch("search");
         assertNoWebContents();
         assertLoadedNoUrl();
@@ -2744,6 +2741,8 @@
     @ParameterAnnotations.UseMethodParameter(FeatureParamProvider.class)
     public void testNonResolveContentVisibility(@EnabledFeature int enabledFeature)
             throws Exception {
+        // Mark the user undecided so we won't resolve the search.
+        mPolicy.overrideDecidedStateForTesting(false);
         // Simulate a non-resolve search and make sure no Content is created.
         simulateNonResolveSearch("search");
         assertNoWebContents();
@@ -2809,6 +2808,8 @@
     @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.P, message = "crbug.com/1032760")
     public void testNonResolveMultipleSwipeOnlyLoadsContentOnce(@EnabledFeature int enabledFeature)
             throws Exception {
+        // Mark the user undecided so we won't resolve the search.
+        mPolicy.overrideDecidedStateForTesting(false);
         // Simulate a non-resolve search and make sure no Content is created.
         simulateNonResolveSearch("search");
         assertNoWebContents();
@@ -3083,6 +3084,8 @@
     @Feature({"ContextualSearch"})
     @ParameterAnnotations.UseMethodParameter(FeatureParamProvider.class)
     public void testNonResolveTranslates(@EnabledFeature int enabledFeature) throws Exception {
+        // Mark the user undecided so we won't resolve the search.
+        mPolicy.overrideDecidedStateForTesting(false);
         // A non-resolving gesture on any word should trigger a forced translation.
         simulateNonResolveSearch("search");
         // Make sure we did try to trigger translate.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTest.java
index 2ccc5c0..b08f478 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTest.java
@@ -57,8 +57,7 @@
 // can be tested too.  Or just remove this whole suite if it's not useful for
 // these experimental triggering changes.
 @Features.DisableFeatures({ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE,
-        ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS,
-        ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP})
+        ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS})
 @Batch(Batch.PER_CLASS)
 public class ContextualSearchTest {
     @ClassRule
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
index 3bd461e..d0d9ef2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -1669,6 +1669,10 @@
     @Features.EnableFeatures({ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES})
     public void testLaunchPartialCustomTabActivity() throws Exception {
         Intent intent = createMinimalCustomTabIntent();
+        CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
+        CustomTabsConnection connection = CustomTabsConnection.getInstance();
+        connection.newSession(token);
+        connection.overridePackageNameForSessionForTesting(token, "org.chromium.testapp");
         intent.putExtra(CustomTabIntentDataProvider.EXTRA_INITIAL_ACTIVITY_HEIGHT_IN_PIXEL, 50);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTaskTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTaskTest.java
deleted file mode 100644
index cec6800..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTaskTest.java
+++ /dev/null
@@ -1,1041 +0,0 @@
-// Copyright 2020 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.
-
-package org.chromium.chrome.browser.offlinepages.measurements;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-
-import androidx.test.filters.MediumTest;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.FeatureList;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
-import org.chromium.chrome.browser.content.ContentUtils;
-import org.chromium.chrome.browser.flags.CachedFeatureFlags;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.components.background_task_scheduler.BackgroundTask;
-import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler;
-import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
-import org.chromium.components.background_task_scheduler.TaskIds;
-import org.chromium.components.background_task_scheduler.TaskInfo;
-import org.chromium.components.background_task_scheduler.TaskParameters;
-import org.chromium.content_public.browser.test.NativeLibraryTestUtils;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.net.test.EmbeddedTestServer;
-
-import java.util.HashMap;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-/** Tests for {@link OfflineMeasurementsBackgroundTask}. */
-@RunWith(BaseJUnit4ClassRunner.class)
-public class OfflineMeasurementsBackgroundTaskTest {
-    /**
-     * Fake of BackgroundTaskScheduler system service.
-     */
-    public static class FakeBackgroundTaskScheduler implements BackgroundTaskScheduler {
-        private HashMap<Integer, TaskInfo> mTaskInfos = new HashMap<>();
-
-        @Override
-        public boolean schedule(Context context, TaskInfo taskInfo) {
-            mTaskInfos.put(taskInfo.getTaskId(), taskInfo);
-            return true;
-        }
-
-        @Override
-        public void cancel(Context context, int taskId) {
-            mTaskInfos.remove(taskId);
-        }
-
-        @Override
-        public boolean isScheduled(Context context, int taskId) {
-            return (mTaskInfos.get(taskId) != null);
-        }
-
-        @Override
-        public void checkForOSUpgrade(Context context) {}
-
-        @Override
-        public void reschedule(Context context) {}
-
-        public TaskInfo getTaskInfo(int taskId) {
-            return mTaskInfos.get(taskId);
-        }
-
-        public Boolean containsTaskId(int taskId) {
-            return mTaskInfos.containsKey(taskId);
-        }
-    }
-
-    private FakeBackgroundTaskScheduler mFakeBackgroundTaskScheduler;
-
-    /**
-     * Fake of OfflineMeasurementsBackgroundTask.Clock that can be used to test the timing parts of
-     * OfflineMeasurementsBackgroundTask.
-     */
-    public static class FakeClock extends OfflineMeasurementsBackgroundTask.Clock {
-        private long mCurrentTimeMillis;
-        private long mElapsedRealtime;
-        private int mLocalHourOfDay;
-
-        public FakeClock() {
-            mCurrentTimeMillis = 0;
-            mElapsedRealtime = 0;
-            mLocalHourOfDay = 0;
-        }
-
-        @Override
-        public long currentTimeMillis() {
-            return mCurrentTimeMillis;
-        }
-
-        @Override
-        public long elapsedRealtime() {
-            return mElapsedRealtime;
-        }
-
-        @Override
-        public int getLocalHourOfDay() {
-            return mLocalHourOfDay;
-        }
-
-        public void setCurrentTimeMillis(long currentTimeMillis) {
-            mCurrentTimeMillis = currentTimeMillis;
-        }
-
-        public void setElapsedRealtime(long elapsedRealtime) {
-            mElapsedRealtime = elapsedRealtime;
-        }
-
-        public void advanceCurrentTimeMillis(long millis) {
-            mCurrentTimeMillis += millis;
-            mElapsedRealtime += millis;
-        }
-
-        public void setLocalHourOfDay(int localHourOfDay) {
-            mLocalHourOfDay = localHourOfDay;
-        }
-    }
-
-    private FakeClock mFakeClock;
-
-    private static final int TIMEOUT_MS = 10000;
-    private Semaphore mSemaphore = new Semaphore(0);
-    private int mNumTaskFinishedCallbacksTriggered;
-
-    @Before
-    public void setUp() {
-        NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess();
-
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            mFakeBackgroundTaskScheduler = new FakeBackgroundTaskScheduler();
-            BackgroundTaskSchedulerFactory.setSchedulerForTesting(mFakeBackgroundTaskScheduler);
-        });
-
-        mFakeClock = new FakeClock();
-        OfflineMeasurementsBackgroundTask.setClockForTesting(mFakeClock);
-
-        // Clears the testing override for the measurement interval.
-        OfflineMeasurementsBackgroundTask.setNewMeasurementIntervalInMinutesForTesting(
-                0); // IN-TEST
-
-        mNumTaskFinishedCallbacksTriggered = 0;
-
-        // Overrides the checks for airplane mode, roaming, screen interactivity, and application
-        // state so that we don't run the full checks in any tests.
-        OfflineMeasurementsBackgroundTask.setIsAirplaneModeEnabledForTesting(false); // IN-TEST
-        OfflineMeasurementsBackgroundTask.setIsRoamingForTesting(false); // IN-TEST
-        OfflineMeasurementsBackgroundTask.setIsInteractiveForTesting(false); // IN-TEST
-        OfflineMeasurementsBackgroundTask.setIsApplicationForegroundForTesting(false); // IN-TEST
-    }
-
-    private void maybeScheduleTask() {
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> { OfflineMeasurementsBackgroundTask.maybeScheduleTask(); });
-    }
-
-    private void reportMetrics() {
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> { OfflineMeasurementsBackgroundTask.reportMetricsToUmaAndClear(); });
-    }
-
-    private void setFeatureStatusForTest(boolean isEnabled) {
-        HashMap<String, Boolean> testFeatures = new HashMap<String, Boolean>();
-        testFeatures.put(ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK, isEnabled);
-        FeatureList.setTestFeatures(testFeatures);
-
-        CachedFeatureFlags.setForTesting(
-                ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK, isEnabled);
-    }
-
-    private void assertTaskScheduledWithCorrectInterval(int expectedIntervalInMinutes) {
-        // Check that the TimingInfo of the scheduled task is: 1) an instance of PeriodicInfo, and
-        // 2) the periodic interval is the default interval specified in
-        // OfflineMeasurementBackgroundTask.
-        TaskInfo thisTaskInfo =
-                mFakeBackgroundTaskScheduler.getTaskInfo(TaskIds.OFFLINE_MEASUREMENT_JOB_ID);
-        TaskInfo.TimingInfo thisTimingInfo = thisTaskInfo.getTimingInfo();
-        assertTrue("Task's TimingInfo should be a PeriodicInfo",
-                thisTimingInfo instanceof TaskInfo.PeriodicInfo);
-
-        TaskInfo.PeriodicInfo thisPeriodicInfo = (TaskInfo.PeriodicInfo) thisTimingInfo;
-        assertEquals("Task should be periodically scheduled with the given interval",
-                TimeUnit.MINUTES.toMillis(expectedIntervalInMinutes),
-                thisPeriodicInfo.getIntervalMs());
-    }
-
-    /**
-     * Tests scheduling the Offline Measurements background task when the feature is disabled.
-     * Checks that task is not scheduled, no samples are recorded to the
-     * OfflineMeasurements.MeasurementInterval histogram and no HTTP probe parameters are written to
-     * prefs.
-     */
-    @Test
-    @SmallTest
-    public void scheduleTaskWhenFeatureDisabled() {
-        // Disable the Offline Measurements feature for this test.
-        setFeatureStatusForTest(false);
-
-        // Tries to schedule task.
-        maybeScheduleTask();
-
-        // Check that mFakeTaskScheduler doesn't have an entry for this task.
-        assertFalse("Task shouldn't be scheduled when feature is disabled",
-                mFakeBackgroundTaskScheduler.containsTaskId(TaskIds.OFFLINE_MEASUREMENT_JOB_ID));
-
-        // Check that there are no entries in Offline.Measurements.MeasurementInterval.
-        assertEquals("No samples should be written to histogram when feature is disabled", 0,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask
-                                .OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL));
-
-        // Check that the HTTP params are not in Prefs
-        SharedPreferencesManager sharedPreferencesManager = SharedPreferencesManager.getInstance();
-        assertFalse("HTTP probe parameters shouldn't be written to prefs when feature is disabled",
-                sharedPreferencesManager.contains(
-                        ChromePreferenceKeys.OFFLINE_MEASUREMENTS_USER_AGENT_STRING));
-        assertFalse("HTTP probe parameters shouldn't be written to prefs when feature is disabled",
-                sharedPreferencesManager.contains(
-                        ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_URL));
-        assertFalse("HTTP probe parameters shouldn't be written to prefs when feature is disabled",
-                sharedPreferencesManager.contains(
-                        ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_TIMEOUT_MS));
-        assertFalse("HTTP probe parameters shouldn't be written to prefs when feature is disabled",
-                sharedPreferencesManager.contains(
-                        ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_METHOD));
-    }
-
-    /**
-     * Tests scheduling the Offline Measurements background task when the feature is enabled. Checks
-     * that the feature is scheduled with the expected parameters, the expected value is recorded to
-     * the OfflineMeasurements.MeasurementInterval histogram, and the default HTTP probe parameters
-     * are used.
-     */
-    @Test
-    @SmallTest
-    public void scheduleTaskWhenFeatureEnabled() {
-        // Enable the Offline Measurements feature for this test.
-        setFeatureStatusForTest(true);
-
-        // Tries to schedule the task.
-        maybeScheduleTask();
-
-        // Check that mFakeTaskScheduler has an entry for this task with the correct taskInfo.
-        assertTrue("Task should be scheduled when the feature is enabled",
-                mFakeBackgroundTaskScheduler.containsTaskId(TaskIds.OFFLINE_MEASUREMENT_JOB_ID));
-
-        // Check that the task is scheduled with the default measurement interval.
-        assertTaskScheduledWithCorrectInterval(
-                OfflineMeasurementsBackgroundTask.DEFAULT_MEASUREMENT_INTERVAL_IN_MINUTES);
-
-        // Check that Offline.Measurements.MeasurementInterval has one entry of the default
-        // interval.
-        assertEquals("Only the default measurement interval should be recorded to the histogram", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask
-                                .OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL));
-        assertEquals("Only the default measurement interval should be recorded to the histogram", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL,
-                        (int) TimeUnit.MINUTES.toMillis(
-                                OfflineMeasurementsBackgroundTask
-                                        .DEFAULT_MEASUREMENT_INTERVAL_IN_MINUTES)));
-
-        // Check that the HTTP params are in prefs
-        SharedPreferencesManager sharedPreferencesManager = SharedPreferencesManager.getInstance();
-        assertEquals("The user agent string should always be written to prefs",
-                ContentUtils.getBrowserUserAgent(),
-                sharedPreferencesManager.readString(
-                        ChromePreferenceKeys.OFFLINE_MEASUREMENTS_USER_AGENT_STRING, ""));
-        assertFalse("HTTP probe parameters shouldn't be written to prefs when using default values",
-                sharedPreferencesManager.contains(
-                        ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_URL));
-        assertFalse("HTTP probe parameters shouldn't be written to prefs when using default values",
-                sharedPreferencesManager.contains(
-                        ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_TIMEOUT_MS));
-        assertFalse("HTTP probe parameters shouldn't be written to prefs when using default values",
-                sharedPreferencesManager.contains(
-                        ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_METHOD));
-    }
-
-    /**
-     * Tests scheduling the Offline Measurements background task when an instance is already
-     * running, but with a different measurement interval. when this happens, we should cancel the
-     * already running task, and schedule a new instance of the task with the new parameter.
-     */
-    @Test
-    @SmallTest
-    public void scheduleTaskWithDifferentInterval() {
-        // Enables the feature for this test.
-        setFeatureStatusForTest(true);
-
-        // Establish test constants.
-        final int measurementInterval1 = 15;
-        final int measurementInterval2 = 30;
-
-        // Schedule the task with the first measurement interval.
-        OfflineMeasurementsBackgroundTask.setNewMeasurementIntervalInMinutesForTesting(
-                measurementInterval1);
-        maybeScheduleTask();
-
-        // Check that task was correctly scheduled with the first measurement interval.
-        assertTrue("Task should be scheduled when the feature is enabled",
-                mFakeBackgroundTaskScheduler.containsTaskId(TaskIds.OFFLINE_MEASUREMENT_JOB_ID));
-        assertTaskScheduledWithCorrectInterval(measurementInterval1);
-
-        assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask
-                                .OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL));
-        assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL,
-                        (int) TimeUnit.MINUTES.toMillis(measurementInterval1)));
-
-        // Try scheduling again with the same measurement interval.
-        maybeScheduleTask();
-
-        // If we schedule again with the same measurement interval, nothing should change.
-        assertTrue("Task should be scheduled when the feature is enabled",
-                mFakeBackgroundTaskScheduler.containsTaskId(TaskIds.OFFLINE_MEASUREMENT_JOB_ID));
-        assertTaskScheduledWithCorrectInterval(measurementInterval1);
-
-        assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask
-                                .OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL));
-
-        // Schedule the task with the second measurement interval.
-        OfflineMeasurementsBackgroundTask.setNewMeasurementIntervalInMinutesForTesting(
-                measurementInterval2);
-        maybeScheduleTask();
-
-        // Check that the task is now scheduled with the second measurement interval
-        assertTrue("Task should be scheduled when the feature is enabled",
-                mFakeBackgroundTaskScheduler.containsTaskId(TaskIds.OFFLINE_MEASUREMENT_JOB_ID));
-        assertTaskScheduledWithCorrectInterval(measurementInterval2);
-
-        assertEquals(2,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask
-                                .OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL));
-        assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL,
-                        (int) TimeUnit.MINUTES.toMillis(measurementInterval1)));
-        assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_MEASUREMENT_INTERVAL,
-                        (int) TimeUnit.MINUTES.toMillis(measurementInterval2)));
-
-        // Disable the feature and try to reschedule.
-        setFeatureStatusForTest(false);
-        maybeScheduleTask();
-
-        // Check that the task is no longer scheduled
-        assertFalse("Task shouldn't be scheduled when feature is disabled",
-                mFakeBackgroundTaskScheduler.containsTaskId(TaskIds.OFFLINE_MEASUREMENT_JOB_ID));
-    }
-
-    /**
-     * Tests running the Offline Measurements background task multiple times in a row. Checks that
-     * we record the expected values to the histograms that track the time between each check and
-     * the result of each HTTP probe.
-     */
-    @Test
-    @MediumTest
-    public void runTask() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters
-        setFeatureStatusForTest(true);
-        maybeScheduleTask();
-
-        // Start the test server, and give the URL to the background task.
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-        String testUrl = testServer.getURL("/nocontent");
-        OfflineMeasurementsBackgroundTask.setHttpProbeUrlForTesting(testUrl);
-
-        // Set task parameters.
-        final long[] intervals = {100000, 200000, 300000, 400000, 500000};
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-            mNumTaskFinishedCallbacksTriggered++;
-        };
-        mFakeClock.setCurrentTimeMillis(100000);
-
-        // Run the initial task.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        for (long interval : intervals) {
-            // Increment clock and run task again.
-            mFakeClock.advanceCurrentTimeMillis(interval);
-            TestThreadUtils.runOnUiThreadBlocking(() -> {
-                OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-                task.onStartTask(null, testParameters, testCallback);
-            });
-            assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-
-        // Report the persisted metrics.
-        reportMetrics();
-
-        // Check that the intervals were reported as expected.
-        assertEquals(
-                "The total number of entries should equal to the number of intervals between tasks",
-                intervals.length,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask
-                                .OFFLINE_MEASUREMENTS_TIME_BETWEEN_CHECKS));
-        for (long interval : intervals) {
-            assertEquals("There should be one entry for each interval between tasks", 1,
-                    RecordHistogram.getHistogramValueCountForTesting(
-                            OfflineMeasurementsBackgroundTask
-                                    .OFFLINE_MEASUREMENTS_TIME_BETWEEN_CHECKS,
-                            (int) interval));
-        }
-
-        // Check HTTP probe results.
-        assertEquals("One entry should be recorded for each time the task ran",
-                intervals.length + 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT));
-        assertEquals("All HTTP probes should have a result of VALIDATED", intervals.length + 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT,
-                        OfflineMeasurementsBackgroundTask.ProbeResult.VALIDATED));
-
-        // Check that the callback was triggered each time the task was run.
-        assertEquals("Each task should have called the task finished callback",
-                intervals.length + 1, mNumTaskFinishedCallbacksTriggered);
-    }
-
-    /** Tests running the HTTP probe with a response with a code of 204. */
-    @Test
-    @MediumTest
-    public void runHttpProbe_ExpectedResponseCode() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters
-        setFeatureStatusForTest(true);
-        maybeScheduleTask();
-
-        // Start the test server, and give the URL to the background task.
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-        String testUrl = testServer.getURL("/nocontent");
-        OfflineMeasurementsBackgroundTask.setHttpProbeUrlForTesting(testUrl);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-            mNumTaskFinishedCallbacksTriggered++;
-        };
-
-        // Run the task.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Report the persisted metrics.
-        reportMetrics();
-
-        // Check HTTP probe results.
-        assertEquals("The HTTP probe should have only been run once", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT));
-        assertEquals("The HTTP probe should have a result of VALIDATED", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT,
-                        OfflineMeasurementsBackgroundTask.ProbeResult.VALIDATED));
-
-        // Check that the callback was triggered.
-        assertEquals("The task should call the task finished callback", 1,
-                mNumTaskFinishedCallbacksTriggered);
-    }
-
-    /**
-     * Tests running the HTTP probe with a response with an unexpected code, but still no content.
-     * This can happen in the case of a broken transparent proxy.
-     */
-    @Test
-    @MediumTest
-    public void runHttpProbe_UnexpectedCodeWithoutContent() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters
-        setFeatureStatusForTest(true);
-        maybeScheduleTask();
-
-        // Start the test server, and give the URL to the background task.
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-        String testUrl = testServer.getURL("/echo?status=200");
-        OfflineMeasurementsBackgroundTask.setHttpProbeUrlForTesting(testUrl);
-
-        // This will cause the test server to return empty content.
-        OfflineMeasurementsBackgroundTask.setHttpProbeMethodForTesting("POST");
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-            mNumTaskFinishedCallbacksTriggered++;
-        };
-
-        // Run the task.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Report the persisted metrics.
-        reportMetrics();
-
-        // Check HTTP probe results.
-        assertEquals("The HTTP probe should have only been run once", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT));
-        assertEquals("The HTTP probe should have a result of UNEXPECTED_RESPONSE", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT,
-                        OfflineMeasurementsBackgroundTask.ProbeResult.UNEXPECTED_RESPONSE));
-
-        // Check that the callback was triggered.
-        assertEquals("The task should call the task finished callback", 1,
-                mNumTaskFinishedCallbacksTriggered);
-    }
-
-    /**
-     * Tests running the HTTP probe with a response with an unexpected code and non-zero content.
-     * This happens in cases with a captive portal.
-     */
-    @Test
-    @MediumTest
-    public void runHttpProbe_UnexpectedCodeWithContent() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-        maybeScheduleTask();
-
-        // Start the test server, and give the URL to the background task.
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-        String testUrl = testServer.getURL("/echo?status=200");
-        OfflineMeasurementsBackgroundTask.setHttpProbeUrlForTesting(testUrl);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-            mNumTaskFinishedCallbacksTriggered++;
-        };
-
-        // Run the task.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Report the persisted metrics.
-        reportMetrics();
-
-        // Check HTTP probe results.
-        assertEquals("The HTTP probe should have only been run once", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT));
-        assertEquals("The HTTP probe should have a result of UNEXPECTED_RESPONSE", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT,
-                        OfflineMeasurementsBackgroundTask.ProbeResult.UNEXPECTED_RESPONSE));
-
-        // Check that the callback was triggered.
-        assertEquals("The task should call the task finished callback", 1,
-                mNumTaskFinishedCallbacksTriggered);
-    }
-
-    /** Tests running the HTTP probe and getting a server error response. */
-    @Test
-    @MediumTest
-    public void runHttpProbe_ServerError() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-        maybeScheduleTask();
-
-        // Start the test server, and give the URL to the background task.
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-        String testUrl = testServer.getURL("/echo?status=500");
-        OfflineMeasurementsBackgroundTask.setHttpProbeUrlForTesting(testUrl);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-            mNumTaskFinishedCallbacksTriggered++;
-        };
-
-        // Run the task.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Report the persisted metrics.
-        reportMetrics();
-
-        // Check HTTP probe results.
-        assertEquals("The HTTP probe should have only been run once", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT));
-        assertEquals("The HTTP probe should have a result of SERVER_ERROR", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT,
-                        OfflineMeasurementsBackgroundTask.ProbeResult.SERVER_ERROR));
-
-        // Check that the callback was triggered.
-        assertEquals("The task should call the task finished callback", 1,
-                mNumTaskFinishedCallbacksTriggered);
-    }
-
-    /** Tests running the HTTP probe and not getting a response from the server. */
-    @Test
-    @MediumTest
-    public void runHttpProbe_NoInternet() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-        maybeScheduleTask();
-
-        // Start the test server, and give the URL to the background task.
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-        String testUrl = testServer.getURL("/hung");
-        OfflineMeasurementsBackgroundTask.setHttpProbeUrlForTesting(testUrl);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-            mNumTaskFinishedCallbacksTriggered++;
-        };
-
-        // Run the task, then immediately cancel it.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Report the persisted metrics.
-        reportMetrics();
-
-        // Check HTTP probe results.
-        assertEquals("The HTTP probe should have only been run once", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT));
-        assertEquals("The HTTP probe should have a result of NO_INTERNET", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT,
-                        OfflineMeasurementsBackgroundTask.ProbeResult.NO_INTERNET));
-
-        // Check that the callback was not triggered.
-        assertEquals("The task should call the task finished callback", 1,
-                mNumTaskFinishedCallbacksTriggered);
-    }
-
-    /** Tests running the HTTP probe and canceling the task before the probe finishes. */
-    @Test
-    @MediumTest
-    public void runHttpProbe_CancelTask() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-        maybeScheduleTask();
-
-        // Start the test server, and give the URL to the background task.
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-        String testUrl = testServer.getURL("/hung");
-        OfflineMeasurementsBackgroundTask.setHttpProbeUrlForTesting(testUrl);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mNumTaskFinishedCallbacksTriggered++;
-        };
-
-        // Run the task, then immediately cancel it.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-            task.onStopTask(null, testParameters);
-        });
-
-        // Report the persisted metrics.
-        reportMetrics();
-
-        // Check HTTP probe results.
-        assertEquals("The HTTP probe should have only been run once", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT));
-        assertEquals("The HTTP probe should have a result of CANCELLED", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_HTTP_PROBE_RESULT,
-                        OfflineMeasurementsBackgroundTask.ProbeResult.CANCELLED));
-
-        // Check that the callback was not triggered.
-        assertEquals("The task should not call the task finished callback", 0,
-                mNumTaskFinishedCallbacksTriggered);
-    }
-
-    /**
-     * Tests running the background task with airplane mode enabled and disabled. Checks that the
-     * expected values are recorded to the UMA histogram Offline.Measurements.IsAirplaneModeEnabled.
-     */
-    @Test
-    @MediumTest
-    public void recordIsAirplaneModeEnabled() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-        };
-
-        // Runs the task with airplane mode disabled, then runs it again with airplane mode enabled.
-        OfflineMeasurementsBackgroundTask.setIsAirplaneModeEnabledForTesting(false);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        OfflineMeasurementsBackgroundTask.setIsAirplaneModeEnabledForTesting(true);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Reports the metrics stored in Prefs.
-        reportMetrics();
-
-        // Check histogram
-        assertEquals("There should be one sample for each time the task was ran", 2,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask
-                                .OFFLINE_MEASUREMENTS_IS_AIRPLANE_MODE_ENABLED));
-
-        assertEquals("There should be one entry where airplane mode is disabled", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask
-                                .OFFLINE_MEASUREMENTS_IS_AIRPLANE_MODE_ENABLED,
-                        /*false*/ 0));
-        assertEquals("There should be one entry where airplane mode is enabled", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask
-                                .OFFLINE_MEASUREMENTS_IS_AIRPLANE_MODE_ENABLED,
-                        /*true*/ 1));
-    }
-
-    /**
-     * Tests running the background task when roaming and not roaming. Checks that the expected
-     * values are recorded to the UMA histogram Offline.Measurements.IsRoaming.
-     */
-    @Test
-    @MediumTest
-    public void recordIsRoaming() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-        };
-
-        // Runs the task while not roaming, then runs it again while roaming.
-        OfflineMeasurementsBackgroundTask.setIsRoamingForTesting(false);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        OfflineMeasurementsBackgroundTask.setIsRoamingForTesting(true);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Reports the metrics stored in Prefs.
-        reportMetrics();
-
-        // Check histogram
-        assertEquals("There should be one sample for each time the task was ran", 2,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_IS_ROAMING));
-
-        assertEquals("There should be one entry where not roaming", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_IS_ROAMING,
-                        /*false*/ 0));
-        assertEquals("There should be one entry where roaming", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_IS_ROAMING,
-                        /*true*/ 1));
-    }
-
-    /**
-     * Tests running the background task when the phone's screen is not interative. Checks that the
-     * expected values are recorded to the UMA histogram Offline.Measurements.UserState.
-     */
-    @Test
-    @MediumTest
-    public void recordUserState_NotUsingPhone() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-        };
-
-        // Tests running the background task when the screen is not interactive. This should record
-        // a value of UserState.NOT_USING_PHONE regardless of whehter Chrome is in the foreground or
-        // not.
-        OfflineMeasurementsBackgroundTask.setIsInteractiveForTesting(false);
-        OfflineMeasurementsBackgroundTask.setIsApplicationForegroundForTesting(false);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        OfflineMeasurementsBackgroundTask.setIsApplicationForegroundForTesting(true);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Reports the metrics stored in Prefs.
-        reportMetrics();
-
-        // Check that the expected values were recorded to Offline.Measurements.UserState.
-        assertEquals("There should be one sample for each time the task was ran", 2,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE));
-        assertEquals("There should be two entries for NOT_USING_PHONE", 2,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE,
-                        OfflineMeasurementsBackgroundTask.UserState.NOT_USING_PHONE));
-    }
-
-    /**
-     * Tests running the background task when the phone screen is interative, but Chrome is not in
-     * the foreground. Checks that the expected values are recorded to the UMA histogram
-     * Offline.Measurements.UserState.
-     */
-    @Test
-    @MediumTest
-    public void recordUserState_UsingPhoneNotChrome() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-        };
-
-        // Tests running the background task when the screen is on and Chrome is not in the
-        // foreground. This should record a value of UserState.USING_PHONE_NOT_CHROME.
-        OfflineMeasurementsBackgroundTask.setIsInteractiveForTesting(true);
-        OfflineMeasurementsBackgroundTask.setIsApplicationForegroundForTesting(false);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Reports the metrics stored in Prefs.
-        reportMetrics();
-
-        // Check that the expected values were recorded to Offline.Measurements.UserState.
-        assertEquals("There should be one sample for each time the task was ran", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE));
-        assertEquals("There should be one entry for USING_PHONE_NOT_CHROME", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE,
-                        OfflineMeasurementsBackgroundTask.UserState.USING_PHONE_NOT_CHROME));
-    }
-
-    /**
-     * Tests running the background task when chrome is in the foreground. Checks that the expected
-     * values are recorded to the UMA histogram Offline.Measurements.UserState.
-     */
-    @Test
-    @MediumTest
-    public void recordUserState_UsingChrome() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-        };
-
-        // Tests running the background task when the screen is on and Chrome is in the foreground.
-        // This should record a value of UserState.USING_CHROME.
-        OfflineMeasurementsBackgroundTask.setIsInteractiveForTesting(true);
-        OfflineMeasurementsBackgroundTask.setIsApplicationForegroundForTesting(true);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Reports the metrics stored in Prefs.
-        reportMetrics();
-
-        // Check that the expected values were recorded to Offline.Measurements.UserState.
-        assertEquals("There should be one sample for each time the task was ran", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE));
-        assertEquals("There should be one entry for USING_CHROME", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE,
-                        OfflineMeasurementsBackgroundTask.UserState.USING_CHROME));
-    }
-
-    /**
-     * Tests running the background task after the device boots up. Checks that the expected values
-     * are recorded to the UMA histogram Offline.Measurements.UserState.
-     */
-    @Test
-    @MediumTest
-    public void recordUserState_PhoneOff() throws Exception {
-        // Enable feature and initialize the HTTP probe parameters.
-        setFeatureStatusForTest(true);
-
-        // Schedule the task, so that we initialize the "lastCheckMillis" timestamp in Prefs.
-        maybeScheduleTask();
-
-        // Set the task parameters.
-        TaskParameters testParameters =
-                TaskParameters.create(TaskIds.OFFLINE_MEASUREMENT_JOB_ID).build();
-        BackgroundTask.TaskFinishedCallback testCallback = needsReschedule -> {
-            mSemaphore.release();
-        };
-
-        OfflineMeasurementsBackgroundTask.setIsInteractiveForTesting(true);
-        OfflineMeasurementsBackgroundTask.setIsApplicationForegroundForTesting(true);
-
-        // Advance the clock then reset elapsed realtime to zero in order to simulate the system
-        // restarting.
-        mFakeClock.advanceCurrentTimeMillis(1000);
-        mFakeClock.setElapsedRealtime(0);
-
-        // Tests running the background task immediately after booting up. Since this is the first
-        // time the task is run, we can't tell if the system just booted up.
-        OfflineMeasurementsBackgroundTask.setIsApplicationForegroundForTesting(true);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Reports the metrics stored in Prefs.
-        reportMetrics();
-
-        // Check that the expected values were recorded to Offline.Measurements.UserState.
-        assertEquals("There should be one sample for each time the task was ran", 1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE));
-        assertEquals("There should be one entry for USING_CHROME", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE,
-                        OfflineMeasurementsBackgroundTask.UserState.USING_CHROME));
-
-        // Simulate the system restarting again.
-        mFakeClock.advanceCurrentTimeMillis(1000);
-        mFakeClock.setElapsedRealtime(0);
-
-        // Run the task again. Since the time since the last check is longer than the time since
-        // last boot up, then we know that system was just restarted.
-        OfflineMeasurementsBackgroundTask.setIsApplicationForegroundForTesting(true);
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflineMeasurementsBackgroundTask task = new OfflineMeasurementsBackgroundTask();
-            task.onStartTask(null, testParameters, testCallback);
-        });
-        assertTrue(mSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Reports the metrics stored in Prefs.
-        reportMetrics();
-
-        // Check that the expected values were recorded to Offline.Measurements.UserState.
-        assertEquals("There should be one sample for each time the task was ran", 2,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE));
-        assertEquals("There should be one entry for PHONE_OFF", 1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        OfflineMeasurementsBackgroundTask.OFFLINE_MEASUREMENTS_USER_STATE,
-                        OfflineMeasurementsBackgroundTask.UserState.PHONE_OFF));
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandlerTest.java
index 124b20ec..33ace7f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandlerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandlerTest.java
@@ -29,16 +29,19 @@
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import org.chromium.base.SysUtils;
+import org.chromium.base.FeatureList;
 import org.chromium.base.jank_tracker.DummyJankTracker;
-import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.supplier.ObservableSupplierImpl;
+import org.chromium.base.test.metrics.HistogramTestRule;
+import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.JniMocker;
@@ -67,8 +70,6 @@
 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.components.metrics.OmniboxEventProtos.OmniboxEventProto.PageClassification;
 import org.chromium.components.omnibox.AutocompleteMatch;
 import org.chromium.components.omnibox.AutocompleteResult;
@@ -93,12 +94,16 @@
  * Tests for {@link VoiceRecognitionHandler}.
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
+@Batch(Batch.PER_CLASS)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 public class VoiceRecognitionHandlerTest {
-    @Rule
-    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
+    @ClassRule
+    public static ChromeTabbedActivityTestRule sActivityTestRule =
+            new ChromeTabbedActivityTestRule();
     @Rule
     public JniMocker mJniMocker = new JniMocker();
+    @Rule
+    public HistogramTestRule mHistograms = new HistogramTestRule();
 
     @Mock
     Intent mIntent;
@@ -128,6 +133,7 @@
     private TestWindowAndroid mWindowAndroid;
     private List<VoiceResult> mAutocompleteVoiceResults;
     private ObservableSupplierImpl<Profile> mProfileSupplier;
+    private FeatureList.TestValues mFeatures;
 
     private static final OnSuggestionsReceivedListener sEmptySuggestionListener =
             new OnSuggestionsReceivedListener() {
@@ -442,7 +448,7 @@
 
         TestDelegate() {
             ViewGroup parent =
-                    (ViewGroup) mActivityTestRule.getActivity().findViewById(android.R.id.content);
+                    (ViewGroup) sActivityTestRule.getActivity().findViewById(android.R.id.content);
             Assert.assertNotNull(parent);
             mAutocompleteCoordinator = new TestAutocompleteCoordinator(parent, null, null, null);
         }
@@ -609,6 +615,12 @@
         }
     }
 
+    @BeforeClass
+    public static void setUpClass() {
+        sActivityTestRule.startMainActivityOnBlankPage();
+        sActivityTestRule.waitForDeferredStartup();
+    }
+
     @Before
     public void setUp() throws InterruptedException, ExecutionException {
         MockitoAnnotations.initMocks(this);
@@ -617,26 +629,17 @@
         doReturn(mMatch).when(mController).classify(any(), anyBoolean());
         doReturn(new GURL("https://www.google.com/search?q=abc")).when(mMatch).getUrl();
         doReturn(true).when(mMatch).isSearchSuggestion();
-        mActivityTestRule.startMainActivityOnBlankPage();
-        mActivityTestRule.waitForActivityNativeInitializationComplete();
-
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            mWindowAndroid = new TestWindowAndroid(mActivityTestRule.getActivity());
-            mProfileSupplier = new ObservableSupplierImpl<>();
-        });
 
         mDataProvider = new TestDataProvider();
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            mDelegate = new TestDelegate();
-            VoiceRecognitionHandler.setIsRecognitionIntentPresentForTesting(true);
-            mHandler = new TestVoiceRecognitionHandler(mDelegate, mProfileSupplier);
-            mHandler.addObserver(mObserver);
-        });
-
         mPermissionDelegate = new TestAndroidPermissionDelegate();
 
         TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mWindowAndroid = new TestWindowAndroid(sActivityTestRule.getActivity());
+            mProfileSupplier = new ObservableSupplierImpl<>();
             mWindowAndroid.setAndroidPermissionDelegate(mPermissionDelegate);
+            mDelegate = new TestDelegate();
+            mHandler = new TestVoiceRecognitionHandler(mDelegate, mProfileSupplier);
+            mHandler.addObserver(mObserver);
         });
 
         doReturn(new GURL(DEFAULT_URL)).when(mTab).getUrl();
@@ -651,11 +654,19 @@
         doReturn("de").when(mTranslateBridgeWrapper).getCurrentLanguage(notNull());
         doReturn("ja").when(mTranslateBridgeWrapper).getTargetLanguage();
         mHandler.setTranslateBridgeWrapper(mTranslateBridgeWrapper);
+
+        // Reset test features and allow fallback values to be taken from defaults.
+        // This achieves a similar objective to EnableFeatures/DisableFeatures, but
+        // is more consistent and prevents re-start of the batched tests.
+        // Note that multiple tests here rely on currently set feature defaults and
+        // any changes done there that drag into test execution produce false failures.
+        mFeatures = new FeatureList.TestValues();
+        FeatureList.setTestValues(mFeatures);
+        FeatureList.setTestCanUseDefaultsForTesting();
     }
 
     @After
     public void tearDown() {
-        SysUtils.resetForTesting();
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             mHandler.removeObserver(mObserver);
             VoiceRecognitionHandler.setIsRecognitionIntentPresentForTesting(null);
@@ -664,6 +675,39 @@
     }
 
     /**
+     * Toggles specific features on.
+     *
+     * @param features Comma-separated list of features to be enabled.
+     */
+    void enableFeatures(String... features) {
+        for (String feature : features) {
+            mFeatures.addFeatureFlagOverride(feature, true);
+        }
+    }
+
+    /**
+     * Toggles specific features off.
+     *
+     * @param features Comma-separated list of features to be disabled.
+     */
+    void disableFeatures(String... features) {
+        for (String feature : features) {
+            mFeatures.addFeatureFlagOverride(feature, false);
+        }
+    }
+
+    /**
+     * Specifies a value for a fieldtrial param.
+     *
+     * @param feature The feature that the parameter is bound to.
+     * @param param The parameter name.
+     * @param value The value of the parameter.
+     */
+    void setFeatureParam(String feature, String param, String value) {
+        mFeatures.addFieldTrialParamOverride(feature, param, value);
+    }
+
+    /**
      * Tests for {@link VoiceRecognitionHandler#isVoiceSearchEnabled}.
      */
     @Test
@@ -705,8 +749,8 @@
     @Test
     @SmallTest
     @Feature("VoiceSearchAudioCapturePolicy")
-    @EnableFeatures({ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY})
     public void testIsVoiceSearchEnabled_AllowedByPolicy() {
+        enableFeatures(ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY);
         setAudioCapturePref(true);
         mPermissionDelegate.setCanRequestPermission(true);
         mPermissionDelegate.setHasPermission(true);
@@ -716,8 +760,8 @@
     @Test
     @SmallTest
     @Feature("VoiceSearchAudioCapturePolicy")
-    @EnableFeatures({ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY})
     public void testIsVoiceSearchEnabled_DisabledByPolicy() {
+        enableFeatures(ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY);
         setAudioCapturePref(false);
         mPermissionDelegate.setCanRequestPermission(true);
         mPermissionDelegate.setHasPermission(true);
@@ -727,8 +771,8 @@
     @Test
     @SmallTest
     @Feature("VoiceSearchAudioCapturePolicy")
-    @EnableFeatures({ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY})
     public void testIsVoiceSearchEnabled_AudioCapturePolicyAllowsByDefault() {
+        enableFeatures(ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY);
         mPermissionDelegate.setCanRequestPermission(true);
         mPermissionDelegate.setHasPermission(true);
         Assert.assertTrue(isVoiceSearchEnabled());
@@ -737,8 +781,8 @@
     @Test
     @SmallTest
     @Feature("VoiceSearchAudioCapturePolicy")
-    @DisableFeatures({ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY})
     public void testIsVoiceSearchEnabled_SkipPolicyCheckWhenDisabled() {
+        disableFeatures(ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY);
         setAudioCapturePref(false);
         mPermissionDelegate.setCanRequestPermission(true);
         mPermissionDelegate.setHasPermission(true);
@@ -748,8 +792,8 @@
     @Test
     @SmallTest
     @Feature("VoiceSearchAudioCapturePolicy")
-    @EnableFeatures({ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY})
     public void testIsVoiceSearchEnabled_UpdateAfterProfileSet() {
+        enableFeatures(ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY);
         setAudioCapturePref(true);
         mPermissionDelegate.setCanRequestPermission(true);
         mPermissionDelegate.setHasPermission(true);
@@ -814,8 +858,8 @@
     @Test
     @SmallTest
     @Feature({"OmniboxAssistantVoiceSearch"})
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH})
     public void testStartVoiceRecognition_StartsAssistantVoiceSearch() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.OMNIBOX);
@@ -835,8 +879,8 @@
     @Test
     @SmallTest
     @Feature({"OmniboxAssistantVoiceSearch"})
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH})
     public void testStartVoiceRecognition_ShouldRequestConditionsFail() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(false).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.OMNIBOX);
@@ -850,13 +894,12 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentExperimentId")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH + "<Study"})
-    @DisableFeatures({ChromeFeatureList.ASSISTANT_INTENT_EXPERIMENT_ID + "<Study"})
-    @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
-            "force-fieldtrial-params=Study.Group:"
-                    + VoiceRecognitionHandler.ASSISTANT_EXPERIMENT_ID_PARAM_NAME + "/test"})
-    public void
-    testStartVoiceRecognition_AssistantExperimentIdDisabled() {
+    public void testStartVoiceRecognition_AssistantExperimentIdDisabled() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH);
+        disableFeatures(ChromeFeatureList.ASSISTANT_INTENT_EXPERIMENT_ID);
+        setFeatureParam(ChromeFeatureList.ASSISTANT_INTENT_EXPERIMENT_ID,
+                VoiceRecognitionHandler.ASSISTANT_EXPERIMENT_ID_PARAM_NAME, "test");
+
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.TOOLBAR);
@@ -869,13 +912,11 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentExperimentId")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH + "<Study",
-            ChromeFeatureList.ASSISTANT_INTENT_EXPERIMENT_ID + "<Study"})
-    @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
-            "force-fieldtrial-params=Study.Group:"
-                    + VoiceRecognitionHandler.ASSISTANT_EXPERIMENT_ID_PARAM_NAME + "/test"})
-    public void
-    testStartVoiceRecognition_IncludeExperimentIdInAssistantIntentFromToolbar() {
+    public void testStartVoiceRecognition_IncludeExperimentIdInAssistantIntentFromToolbar() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
+                ChromeFeatureList.ASSISTANT_INTENT_EXPERIMENT_ID);
+        setFeatureParam(ChromeFeatureList.ASSISTANT_INTENT_EXPERIMENT_ID,
+                VoiceRecognitionHandler.ASSISTANT_EXPERIMENT_ID_PARAM_NAME, "test");
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.TOOLBAR);
@@ -887,13 +928,11 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentExperimentId")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH + "<Study",
-            ChromeFeatureList.ASSISTANT_INTENT_EXPERIMENT_ID + "<Study"})
-    @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
-            "force-fieldtrial-params=Study.Group:"
-                    + VoiceRecognitionHandler.ASSISTANT_EXPERIMENT_ID_PARAM_NAME + "/test"})
-    public void
-    testStartVoiceRecognition_IncludeExperimentIdInAssistantIntentFromNonToolbar() {
+    public void testStartVoiceRecognition_IncludeExperimentIdInAssistantIntentFromNonToolbar() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
+                ChromeFeatureList.ASSISTANT_INTENT_EXPERIMENT_ID);
+        setFeatureParam(ChromeFeatureList.ASSISTANT_INTENT_EXPERIMENT_ID,
+                VoiceRecognitionHandler.ASSISTANT_EXPERIMENT_ID_PARAM_NAME, "test");
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.OMNIBOX);
@@ -905,8 +944,8 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentPageUrl")
-    @EnableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testStartVoiceRecognition_ToolbarButtonIncludesPageUrl() {
+        enableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.TOOLBAR);
@@ -919,8 +958,8 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentPageUrl")
-    @EnableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testStartVoiceRecognition_OmitPageUrlWhenAssistantVoiceSearchDisabled() {
+        enableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(false).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
 
@@ -933,8 +972,8 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentPageUrl")
-    @EnableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testStartVoiceRecognition_OmitPageUrlForNonToolbar() {
+        enableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
 
@@ -946,8 +985,8 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentPageUrl")
-    @EnableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testStartVoiceRecognition_OmitPageUrlForIncognito() {
+        enableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         doReturn(true).when(mTab).isIncognito();
@@ -960,8 +999,8 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentPageUrl")
-    @EnableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testStartVoiceRecognition_OmitPageUrlForInternalPages() {
+        enableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         GURL url = new GURL("chrome://version");
@@ -975,8 +1014,8 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentPageUrl")
-    @EnableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testStartVoiceRecognition_OmitPageUrlForNonHttp() {
+        enableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         GURL url = new GURL("ftp://example.org/");
         doReturn(url).when(mTab).getUrl();
@@ -989,10 +1028,9 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentTranslateInfo")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
-            ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO})
-    public void
-    testStartVoiceRecognition_ToolbarButtonIncludesTranslateInfo() {
+    public void testStartVoiceRecognition_ToolbarButtonIncludesTranslateInfo() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
+                ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.TOOLBAR);
@@ -1008,9 +1046,9 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentTranslateInfo")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH})
-    @DisableFeatures({ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO})
     public void testStartVoiceRecognition_TranslateExtrasDisabled() {
+        disableFeatures(ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO);
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.TOOLBAR);
@@ -1029,10 +1067,9 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentTranslateInfo")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
-            ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO})
-    public void
-    testStartVoiceRecognition_NoTranslateExtrasForNonToolbar() {
+    public void testStartVoiceRecognition_NoTranslateExtrasForNonToolbar() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
+                ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.OMNIBOX);
@@ -1052,10 +1089,9 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentTranslateInfo")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
-            ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO})
-    public void
-    testStartVoiceRecognition_NoTranslateExtrasForNonTranslatePage() {
+    public void testStartVoiceRecognition_NoTranslateExtrasForNonTranslatePage() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
+                ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         doReturn(false).when(mTranslateBridgeWrapper).canManuallyTranslate(notNull());
@@ -1076,10 +1112,9 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentTranslateInfo")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
-            ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO})
-    public void
-    testStartVoiceRecognition_NoTranslateExtrasWhenLanguagesUndetected() {
+    public void testStartVoiceRecognition_NoTranslateExtrasWhenLanguagesUndetected() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
+                ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         doReturn(null).when(mTranslateBridgeWrapper).getSourceLanguage(notNull());
@@ -1100,10 +1135,9 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentTranslateInfo")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
-            ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO})
-    public void
-    testStartVoiceRecognition_TranslateInfoTargetLanguageOptional() {
+    public void testStartVoiceRecognition_TranslateInfoTargetLanguageOptional() {
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH,
+                ChromeFeatureList.ASSISTANT_INTENT_TRANSLATE_INFO);
         doReturn(true).when(mAssistantVoiceSearchService).canRequestAssistantVoiceSearch();
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         doReturn(null).when(mTranslateBridgeWrapper).getTargetLanguage();
@@ -1146,10 +1180,9 @@
     @Test
     @SmallTest
     @Feature("VoiceSearchAudioCapturePolicy")
-    @EnableFeatures({ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY,
-            ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH})
-    public void
-    testStartVoiceRecognition_AudioCaptureAllowedByPolicy() {
+    public void testStartVoiceRecognition_AudioCaptureAllowedByPolicy() {
+        enableFeatures(ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY,
+                ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH);
         setAudioCapturePref(true);
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.TOOLBAR);
@@ -1160,10 +1193,9 @@
     @Test
     @SmallTest
     @Feature("VoiceSearchAudioCapturePolicy")
-    @EnableFeatures({ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY,
-            ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH})
-    public void
-    testStartVoiceRecognition_AudioCaptureDisabledByPolicy() {
+    public void testStartVoiceRecognition_AudioCaptureDisabledByPolicy() {
+        enableFeatures(ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY,
+                ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH);
         setAudioCapturePref(false);
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.TOOLBAR);
@@ -1174,10 +1206,9 @@
     @Test
     @SmallTest
     @Feature("VoiceSearchAudioCapturePolicy")
-    @EnableFeatures({ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY,
-            ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH})
-    public void
-    testStartVoiceRecognition_AudioCapturePolicyAllowsByDefault() {
+    public void testStartVoiceRecognition_AudioCapturePolicyAllowsByDefault() {
+        enableFeatures(ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY,
+                ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH);
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.TOOLBAR);
 
@@ -1187,9 +1218,9 @@
     @Test
     @SmallTest
     @Feature("VoiceSearchAudioCapturePolicy")
-    @EnableFeatures({ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH})
-    @DisableFeatures({ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY})
     public void testStartVoiceRecognition_SkipPolicyWhenFeatureDisabled() {
+        disableFeatures(ChromeFeatureList.VOICE_SEARCH_AUDIO_CAPTURE_POLICY);
+        enableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH);
         setAudioCapturePref(false);
         doReturn(true).when(mAssistantVoiceSearchService).shouldRequestAssistantVoiceSearch();
         startVoiceRecognition(VoiceInteractionSource.TOOLBAR);
@@ -1213,9 +1244,8 @@
         Assert.assertEquals(null, mHandler.getVoiceSearchResult());
         Assert.assertEquals(
                 VoiceInteractionSource.NTP, mHandler.getVoiceSearchFailureEventSource());
-        Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        "VoiceInteraction.QueryDuration.Android"));
+        Assert.assertEquals(
+                0, mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
     }
 
     @Test
@@ -1227,9 +1257,8 @@
         Assert.assertEquals(null, mHandler.getVoiceSearchResult());
         Assert.assertEquals(
                 VoiceInteractionSource.NTP, mHandler.getVoiceSearchDismissedEventSource());
-        Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        "VoiceInteraction.QueryDuration.Android"));
+        Assert.assertEquals(
+                0, mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
     }
 
     @Test
@@ -1240,9 +1269,8 @@
         Assert.assertEquals(
                 VoiceInteractionSource.SEARCH_WIDGET, mHandler.getVoiceSearchStartEventSource());
         Assert.assertEquals(false, mHandler.getVoiceSearchResult());
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        "VoiceInteraction.QueryDuration.Android"));
+        Assert.assertEquals(
+                1, mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
     }
 
     @Test
@@ -1255,8 +1283,7 @@
                     VoiceInteractionSource.OMNIBOX, mHandler.getVoiceSearchStartEventSource());
             Assert.assertEquals(false, mHandler.getVoiceSearchResult());
             Assert.assertEquals(1,
-                    RecordHistogram.getHistogramTotalCountForTesting(
-                            "VoiceInteraction.QueryDuration.Android"));
+                    mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
         });
     }
 
@@ -1279,8 +1306,7 @@
             assertVoiceResultsAreEqual(
                     mAutocompleteVoiceResults, new String[] {"testing"}, new float[] {confidence});
             Assert.assertEquals(1,
-                    RecordHistogram.getHistogramTotalCountForTesting(
-                            "VoiceInteraction.QueryDuration.Android"));
+                    mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
         });
     }
 
@@ -1305,8 +1331,7 @@
                     new float[] {
                             VoiceRecognitionHandler.VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD});
             Assert.assertEquals(1,
-                    RecordHistogram.getHistogramTotalCountForTesting(
-                            "VoiceInteraction.QueryDuration.Android"));
+                    mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
         });
     }
 
@@ -1338,8 +1363,8 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentPageUrl")
-    @EnableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testCallback_nonTranscriptionAction() {
+        enableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             Bundle bundle = new Bundle();
             bundle.putString(VoiceRecognitionHandler.EXTRA_ACTION_PERFORMED, "TRANSLATE");
@@ -1355,19 +1380,17 @@
             Assert.assertEquals(
                     VoiceInteractionSource.TOOLBAR, mHandler.getAssistantActionPerformedSource());
             Assert.assertEquals(1,
-                    RecordHistogram.getHistogramTotalCountForTesting(
-                            "VoiceInteraction.QueryDuration.Android"));
+                    mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
             Assert.assertEquals(1,
-                    RecordHistogram.getHistogramTotalCountForTesting(
-                            "VoiceInteraction.QueryDuration.Android"));
+                    mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
         });
     }
 
     @Test
     @SmallTest
     @Feature("AssistantIntentPageUrl")
-    @EnableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testCallback_defaultToTranscription() {
+        enableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             mWindowAndroid.setVoiceResults(createDummyBundle(
                     "testing", VoiceRecognitionHandler.VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD));
@@ -1386,8 +1409,8 @@
     @Test
     @SmallTest
     @Feature("AssistantIntentPageUrl")
-    @DisableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testCallback_pageUrlExtraDisabled() {
+        disableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             mWindowAndroid.setVoiceResults(createDummyBundle(
                     "testing", VoiceRecognitionHandler.VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD));
@@ -1453,8 +1476,8 @@
 
     @Test
     @SmallTest
-    @DisableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testRecordSuccessMetrics_noActionMetrics() {
+        disableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         mHandler.setQueryStartTimeForTesting(100L);
         mHandler.recordSuccessMetrics(VoiceInteractionSource.OMNIBOX, VoiceIntentTarget.ASSISTANT,
                 AssistantActionPerformed.TRANSCRIPTION);
@@ -1464,19 +1487,18 @@
                 VoiceIntentTarget.ASSISTANT, mHandler.getVoiceSearchFinishEventTarget());
         Assert.assertEquals(-1, mHandler.getAssistantActionPerformed());
         Assert.assertEquals(-1, mHandler.getAssistantActionPerformedSource());
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        "VoiceInteraction.QueryDuration.Android"));
+        Assert.assertEquals(
+                1, mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
         // Split action metrics should not be recorded.
         Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
+                mHistograms.getHistogramTotalCount(
                         "VoiceInteraction.QueryDuration.Android.Transcription"));
     }
 
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL)
     public void testRecordSuccessMetrics_splitActionMetrics() {
+        enableFeatures(ChromeFeatureList.ASSISTANT_INTENT_PAGE_URL);
         mHandler.setQueryStartTimeForTesting(100L);
         mHandler.recordSuccessMetrics(VoiceInteractionSource.OMNIBOX, VoiceIntentTarget.ASSISTANT,
                 AssistantActionPerformed.TRANSLATE);
@@ -1488,14 +1510,13 @@
                 AssistantActionPerformed.TRANSLATE, mHandler.getAssistantActionPerformed());
         Assert.assertEquals(
                 VoiceInteractionSource.OMNIBOX, mHandler.getAssistantActionPerformedSource());
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        "VoiceInteraction.QueryDuration.Android"));
+        Assert.assertEquals(
+                1, mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
         Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
+                mHistograms.getHistogramTotalCount(
                         "VoiceInteraction.QueryDuration.Android.Transcription"));
         Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
+                mHistograms.getHistogramTotalCount(
                         "VoiceInteraction.QueryDuration.Android.Translate"));
     }
 
@@ -1505,11 +1526,10 @@
         mHandler.setQueryStartTimeForTesting(null);
         mHandler.recordSuccessMetrics(VoiceInteractionSource.OMNIBOX, VoiceIntentTarget.SYSTEM,
                 AssistantActionPerformed.TRANSCRIPTION);
+        Assert.assertEquals(
+                0, mHistograms.getHistogramTotalCount("VoiceInteraction.QueryDuration.Android"));
         Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        "VoiceInteraction.QueryDuration.Android"));
-        Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
+                mHistograms.getHistogramTotalCount(
                         "VoiceInteraction.QueryDuration.Android.Transcription"));
     }
 
@@ -1521,8 +1541,7 @@
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { mHandler.startVoiceRecognition(VoiceInteractionSource.OMNIBOX); });
         Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        "VoiceInteraction.AudioPermissionEvent",
+                mHistograms.getHistogramValueCount("VoiceInteraction.AudioPermissionEvent",
                         AudioPermissionState.DENIED_CANNOT_ASK_AGAIN));
     }
 
@@ -1534,8 +1553,7 @@
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { mHandler.startVoiceRecognition(VoiceInteractionSource.OMNIBOX); });
         Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        "VoiceInteraction.AudioPermissionEvent",
+                mHistograms.getHistogramValueCount("VoiceInteraction.AudioPermissionEvent",
                         AudioPermissionState.DENIED_CAN_ASK_AGAIN));
     }
 
@@ -1546,7 +1564,7 @@
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { mHandler.startVoiceRecognition(VoiceInteractionSource.OMNIBOX); });
         Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(
+                mHistograms.getHistogramValueCount(
                         "VoiceInteraction.AudioPermissionEvent", AudioPermissionState.GRANTED));
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/TileMatchers.java b/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/TileMatchers.java
index c29e2744..8b44386 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/TileMatchers.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/TileMatchers.java
@@ -15,9 +15,9 @@
 import org.hamcrest.Matcher;
 
 import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.browser_ui.widget.image_tiles.ImageTile;
 import org.chromium.components.query_tiles.QueryTile;
-import org.chromium.ui.widget.ChipView;
 
 /** Helper {@link Matcher}s to validate the Query Tiles UI. */
 final class TileMatchers {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
index d949da72..25d66c6 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
@@ -36,10 +36,13 @@
 
 import org.chromium.base.IntentUtils;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.browserservices.intents.ColorProvider;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.device.mojom.ScreenOrientationLockType;
 
 import java.util.ArrayList;
@@ -51,6 +54,8 @@
 public class CustomTabIntentDataProviderTest {
     @Rule
     public TestRule mProcessor = new Features.JUnitProcessor();
+    @Rule
+    public TestRule mCommandLineFlagsRule = CommandLineFlags.getTestRule();
 
     private static final String BUTTON_DESCRIPTION = "buttonDescription";
 
@@ -219,6 +224,70 @@
         assertFalse(dataProvider.shouldShowShareMenuItem());
     }
 
+    @Test
+    @EnableFeatures({ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES})
+    public void isAllowedThirdParty_noDefaultPolicy() {
+        Intent intent = new CustomTabsIntent.Builder().build().intent;
+        intent.putExtra(CustomTabIntentDataProvider.EXTRA_INITIAL_ACTIVITY_HEIGHT_IN_PIXEL, 50);
+        CustomTabIntentDataProvider provider =
+                new CustomTabIntentDataProvider(intent, mContext, COLOR_SCHEME_LIGHT);
+        CustomTabIntentDataProvider.DENYLIST_ENTRIES.setForTesting(
+                "com.dc.joker|com.marvel.thanos");
+        // If no default-policy is present, it defaults to use-denylist.
+        assertFalse("Entry in denylist should be rejected",
+                provider.isAllowedThirdParty("com.dc.joker"));
+        assertFalse("Entry in denylist should be rejected",
+                provider.isAllowedThirdParty("com.marvel.thanos"));
+        assertTrue("Entry NOT in denylist should be accepted",
+                provider.isAllowedThirdParty("com.dc.batman"));
+    }
+
+    @Test
+    @EnableFeatures({ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES + "<Study"})
+    @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
+            "force-fieldtrial-params=Study.Group:"
+                    + "default_policy/use-denylist"
+                    + "/denylist_entries/com.dc.joker|com.marvel.thanos"})
+    public void
+    isAllowedThirdParty_denylist() {
+        Intent intent = new CustomTabsIntent.Builder().build().intent;
+        intent.putExtra(CustomTabIntentDataProvider.EXTRA_INITIAL_ACTIVITY_HEIGHT_IN_PIXEL, 50);
+        CustomTabIntentDataProvider provider =
+                new CustomTabIntentDataProvider(intent, mContext, COLOR_SCHEME_LIGHT);
+        CustomTabIntentDataProvider.THIRD_PARTIES_DEFAULT_POLICY.setForTesting("use-denylist");
+        CustomTabIntentDataProvider.DENYLIST_ENTRIES.setForTesting(
+                "com.dc.joker|com.marvel.thanos");
+        assertFalse("Entry in denylist should be rejected",
+                provider.isAllowedThirdParty("com.dc.joker"));
+        assertFalse("Entry in denylist should be rejected",
+                provider.isAllowedThirdParty("com.marvel.thanos"));
+        assertTrue("Entry NOT in denylist should be accepted",
+                provider.isAllowedThirdParty("com.dc.batman"));
+    }
+
+    @Test
+    @EnableFeatures({ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES + "<Study"})
+    @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
+            "force-fieldtrial-params=Study.Group:"
+                    + "default_policy/use-allowlist"
+                    + "/allowlist_entries/com.pixar.woody|com.disney.ariel"})
+    public void
+    isAllowedThirdParty_allowlist() {
+        Intent intent = new CustomTabsIntent.Builder().build().intent;
+        intent.putExtra(CustomTabIntentDataProvider.EXTRA_INITIAL_ACTIVITY_HEIGHT_IN_PIXEL, 50);
+        CustomTabIntentDataProvider provider =
+                new CustomTabIntentDataProvider(intent, mContext, COLOR_SCHEME_LIGHT);
+        CustomTabIntentDataProvider.THIRD_PARTIES_DEFAULT_POLICY.setForTesting("use-allowlist");
+        CustomTabIntentDataProvider.ALLOWLIST_ENTRIES.setForTesting(
+                "com.pixar.woody|com.disney.ariel");
+        assertTrue("Entry in allowlist should be accepted",
+                provider.isAllowedThirdParty("com.pixar.woody"));
+        assertTrue("Entry in allowlist should be accepted",
+                provider.isAllowedThirdParty("com.disney.ariel"));
+        assertFalse("Entry NOT in allowlist should be rejected",
+                provider.isAllowedThirdParty("com.pixar.syndrome"));
+    }
+
     private Bundle createActionButtonInToolbarBundle() {
         Bundle bundle = new Bundle();
         bundle.putInt(CustomTabsIntent.KEY_ID, CustomTabsIntent.TOOLBAR_ACTION_BUTTON_ID);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinatorTest.java
index ca19c15..cb01bd2 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinatorTest.java
@@ -80,8 +80,9 @@
  */
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
-@Features.DisableFeatures({ChromeFeatureList.WEB_FEED, ChromeFeatureList.INTEREST_FEED_V2_AUTOPLAY,
-        ChromeFeatureList.FEED_INTERACTIVE_REFRESH, ChromeFeatureList.FEED_BACK_TO_TOP})
+@Features.DisableFeatures({ChromeFeatureList.WEB_FEED, ChromeFeatureList.WEB_FEED_SORT,
+        ChromeFeatureList.INTEREST_FEED_V2_AUTOPLAY, ChromeFeatureList.FEED_INTERACTIVE_REFRESH,
+        ChromeFeatureList.FEED_BACK_TO_TOP})
 @Features.EnableFeatures({ChromeFeatureList.FEED_RELIABILITY_LOGGING})
 public class FeedSurfaceCoordinatorTest {
     private static final @SurfaceType int SURFACE_TYPE = SurfaceType.NEW_TAB_PAGE;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java
index cb07ae5..58f3365 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java
@@ -41,6 +41,7 @@
 import org.chromium.chrome.browser.feed.sections.SectionHeaderListProperties;
 import org.chromium.chrome.browser.feed.sections.SectionHeaderProperties;
 import org.chromium.chrome.browser.feed.sections.ViewVisibility;
+import org.chromium.chrome.browser.feed.sort_ui.FeedOptionsCoordinator;
 import org.chromium.chrome.browser.feed.webfeed.WebFeedBridge;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate;
@@ -112,6 +113,8 @@
     private FeedSurfaceLifecycleManager mFeedSurfaceLifecycleManager;
     @Mock
     private View mView;
+    @Mock
+    private FeedOptionsCoordinator mOptionsCoordinator;
 
     private Activity mActivity;
     private FeedSurfaceMediator mFeedSurfaceMediator;
@@ -463,7 +466,7 @@
                 .add(SectionHeaderProperties.createSectionHeader("Following"));
         mFeedSurfaceMediator = createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, model);
 
-        when(mForYouStream.getOptionsView()).thenReturn(mView);
+        when(mForYouStream.supportsOptions()).thenReturn(true);
         mFeedSurfaceMediator.setStreamForTesting(
                 FeedSurfaceCoordinator.StreamTabId.FOLLOWING, mForYouStream);
         mFeedSurfaceMediator.setStreamForTesting(
@@ -491,6 +494,7 @@
                 .add(SectionHeaderProperties.createSectionHeader("Following"));
         mFeedSurfaceMediator = createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, model);
 
+        when(mForYouStream.supportsOptions()).thenReturn(false);
         mFeedSurfaceMediator.setStreamForTesting(
                 FeedSurfaceCoordinator.StreamTabId.FOLLOWING, mForYouStream);
         mFeedSurfaceMediator.setStreamForTesting(
@@ -513,13 +517,12 @@
         PropertyModel forYou = SectionHeaderProperties.createSectionHeader("For you");
         model.get(SectionHeaderListProperties.SECTION_HEADERS_KEY).add(forYou);
         forYou.set(SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY, ViewVisibility.GONE);
-        model.set(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY, mView);
 
         model.get(SectionHeaderListProperties.SECTION_HEADERS_KEY)
                 .add(SectionHeaderProperties.createSectionHeader("Following"));
         mFeedSurfaceMediator = createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, model);
 
-        when(mForYouStream.getOptionsView()).thenReturn(mView);
+        when(mForYouStream.supportsOptions()).thenReturn(true);
         mFeedSurfaceMediator.setStreamForTesting(
                 FeedSurfaceCoordinator.StreamTabId.FOLLOWING, mForYouStream);
         mFeedSurfaceMediator.setStreamForTesting(
@@ -531,7 +534,7 @@
 
         assertEquals(ViewVisibility.INVISIBLE,
                 forYou.get(SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY));
-        assertEquals(null, model.get(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY));
+        verify(mOptionsCoordinator, times(1)).ensureGone();
     }
 
     @Test
@@ -540,12 +543,12 @@
         PropertyModel forYou = SectionHeaderProperties.createSectionHeader("For you");
         model.get(SectionHeaderListProperties.SECTION_HEADERS_KEY).add(forYou);
         forYou.set(SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY, ViewVisibility.GONE);
-        model.set(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY, mView);
 
         model.get(SectionHeaderListProperties.SECTION_HEADERS_KEY)
                 .add(SectionHeaderProperties.createSectionHeader("Following"));
         mFeedSurfaceMediator = createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, model);
 
+        when(mForYouStream.supportsOptions()).thenReturn(false);
         mFeedSurfaceMediator.setStreamForTesting(
                 FeedSurfaceCoordinator.StreamTabId.FOLLOWING, mForYouStream);
         mFeedSurfaceMediator.setStreamForTesting(
@@ -557,7 +560,7 @@
 
         assertEquals(ViewVisibility.GONE,
                 forYou.get(SectionHeaderProperties.OPTIONS_INDICATOR_VISIBILITY_KEY));
-        assertEquals(null, model.get(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY));
+        verify(mOptionsCoordinator, times(1)).ensureGone();
     }
 
     @Test
@@ -569,7 +572,7 @@
                 .add(SectionHeaderProperties.createSectionHeader("Following"));
         mFeedSurfaceMediator = createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, model);
 
-        when(mForYouStream.getOptionsView()).thenReturn(mView);
+        when(mForYouStream.supportsOptions()).thenReturn(true);
         mFeedSurfaceMediator.setStreamForTesting(
                 FeedSurfaceCoordinator.StreamTabId.FOLLOWING, mForYouStream);
         mFeedSurfaceMediator.setStreamForTesting(
@@ -577,11 +580,9 @@
 
         OnSectionHeaderSelectedListener listener =
                 mFeedSurfaceMediator.getOrCreateSectionHeaderListenerForTesting();
-        listener.onSectionHeaderReselected(0);
-        assertEquals(mView, model.get(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY));
 
         listener.onSectionHeaderReselected(0);
-        assertEquals(null, model.get(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY));
+        verify(mOptionsCoordinator, times(1)).toggleVisibility();
     }
 
     @Test
@@ -594,6 +595,7 @@
                 .add(SectionHeaderProperties.createSectionHeader("Following"));
         mFeedSurfaceMediator = createMediator(FeedSurfaceCoordinator.StreamTabId.FOLLOWING, model);
 
+        when(mForYouStream.supportsOptions()).thenReturn(false);
         mFeedSurfaceMediator.setStreamForTesting(
                 FeedSurfaceCoordinator.StreamTabId.FOLLOWING, mForYouStream);
         mFeedSurfaceMediator.setStreamForTesting(
@@ -603,7 +605,7 @@
                 mFeedSurfaceMediator.getOrCreateSectionHeaderListenerForTesting();
         listener.onSectionHeaderReselected(0);
 
-        assertEquals(null, model.get(SectionHeaderListProperties.EXPANDING_DRAWER_VIEW_KEY));
+        verify(mOptionsCoordinator, never()).toggleVisibility();
     }
 
     private FeedSurfaceMediator createMediator() {
@@ -614,6 +616,6 @@
     private FeedSurfaceMediator createMediator(
             @FeedSurfaceCoordinator.StreamTabId int tabId, PropertyModel sectionHeaderModel) {
         return new FeedSurfaceMediator(mFeedSurfaceCoordinator, mActivity, null, sectionHeaderModel,
-                tabId, /*actionDelegate=*/null);
+                tabId, /*actionDelegate=*/null, mOptionsCoordinator);
     }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTaskUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTaskUnitTest.java
new file mode 100644
index 0000000..8127753
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsBackgroundTaskUnitTest.java
@@ -0,0 +1,62 @@
+// Copyright 2022 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.
+
+package org.chromium.chrome.browser.offlinepages.measurements;
+
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
+
+/** Unit tests for {@link OfflineMeasurementsBackgroundTask}. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public final class OfflineMeasurementsBackgroundTaskUnitTest {
+    @Test
+    public void cancelTaskAndclearPersistedDataFromPrefs() {
+        // Simulates the task writing data to prefs.
+        SharedPreferencesManager sharedPreferencesManager = SharedPreferencesManager.getInstance();
+        sharedPreferencesManager.writeString(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_LAST_CHECK_MILLIS, "test data");
+        sharedPreferencesManager.writeString(
+                ChromePreferenceKeys
+                        .OFFLINE_MEASUREMENTS_CURRENT_TASK_MEASUREMENT_INTERVAL_IN_MINUTES,
+                "test data");
+        sharedPreferencesManager.writeString(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_USER_AGENT_STRING, "test data");
+        sharedPreferencesManager.writeString(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_URL, "test data");
+        sharedPreferencesManager.writeString(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_TIMEOUT_MS, "test data");
+        sharedPreferencesManager.writeString(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_METHOD, "test data");
+        sharedPreferencesManager.writeString(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_SYSTEM_STATE_LIST, "test data");
+
+        // Clears all data stored in prefs.
+        OfflineMeasurementsBackgroundTask.clearPersistedDataFromPrefs();
+
+        // Checks that all the prefs have been cleared.
+        assertFalse(sharedPreferencesManager.contains(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_LAST_CHECK_MILLIS));
+        assertFalse(sharedPreferencesManager.contains(
+                ChromePreferenceKeys
+                        .OFFLINE_MEASUREMENTS_CURRENT_TASK_MEASUREMENT_INTERVAL_IN_MINUTES));
+        assertFalse(sharedPreferencesManager.contains(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_USER_AGENT_STRING));
+        assertFalse(sharedPreferencesManager.contains(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_URL));
+        assertFalse(sharedPreferencesManager.contains(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_TIMEOUT_MS));
+        assertFalse(sharedPreferencesManager.contains(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_HTTP_PROBE_METHOD));
+        assertFalse(sharedPreferencesManager.contains(
+                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_SYSTEM_STATE_LIST));
+    }
+}
diff --git a/chrome/app/access_code_cast_strings.grdp b/chrome/app/access_code_cast_strings.grdp
index 5f3e2a8d..f1e1e025 100644
--- a/chrome/app/access_code_cast_strings.grdp
+++ b/chrome/app/access_code_cast_strings.grdp
@@ -1,14 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Access Code Cast-specific strings (included from generated_resources.grd). -->
 <grit-part>
+  <message name="IDS_ACCESS_CODE_CAST_ACCESS_CODE_MESSAGE" desc="Text shown in the access code cast dialog that describes that the access code is found on a Chromecast device">
+    Enter the access code shown on the Chromecast or TV.
+  </message>
   <message name="IDS_ACCESS_CODE_CAST_BACK" desc="Label for the 'back' button to return to the previous screen">
     Back
   </message>
   <message name="IDS_ACCESS_CODE_CAST_CAST" desc="Label for the button to start casting">
     Cast
   </message>
-  <message name="IDS_ACCESS_CODE_CAST_DIALOG_TITLE" desc="Title for access code cast dialog">
-    Cast to a new display
+  <message name="IDS_ACCESS_CODE_CAST_DIALOG_TITLE" desc="Title for access code cast dialog, for casting to a display that is managed">
+    Cast to a managed device
   </message>
   <message name="IDS_ACCESS_CODE_CAST_ERROR_ACCESS_CODE" desc="Error message for incorrect access code">
     Access code not recognized
@@ -26,6 +29,6 @@
     Something went wrong. Try again later
   </message>
   <message name="IDS_ACCESS_CODE_CAST_USE_CAMERA" desc="Label for the button to use the device camera to scan a QR code">
-    Use the camera to scan QR code
+    Use QR code instead
   </message>
 </grit-part>
\ No newline at end of file
diff --git a/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_ACCESS_CODE_MESSAGE.png.sha1 b/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_ACCESS_CODE_MESSAGE.png.sha1
new file mode 100644
index 0000000..0f68a9f
--- /dev/null
+++ b/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_ACCESS_CODE_MESSAGE.png.sha1
@@ -0,0 +1 @@
+065951dab6f85059a5990435d4f1857d6d21264e
\ No newline at end of file
diff --git a/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_DIALOG_TITLE.png.sha1 b/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_DIALOG_TITLE.png.sha1
index b49ce48..0f68a9f 100644
--- a/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_DIALOG_TITLE.png.sha1
+++ b/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_DIALOG_TITLE.png.sha1
@@ -1 +1 @@
-cb57fa67c57448a6862dcac40af6059e8a8a20e9
\ No newline at end of file
+065951dab6f85059a5990435d4f1857d6d21264e
\ No newline at end of file
diff --git a/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_USE_CAMERA.png.sha1 b/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_USE_CAMERA.png.sha1
index b49ce48..0f68a9f 100644
--- a/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_USE_CAMERA.png.sha1
+++ b/chrome/app/access_code_cast_strings_grdp/IDS_ACCESS_CODE_CAST_USE_CAMERA.png.sha1
@@ -1 +1 @@
-cb57fa67c57448a6862dcac40af6059e8a8a20e9
\ No newline at end of file
+065951dab6f85059a5990435d4f1857d6d21264e
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index a38c502..7674198 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -11595,8 +11595,8 @@
       <message name="IDS_WEBAUTHN_CABLEV2_2ND_FACTOR_DESCRIPTION" desc="The contents of a dialog shown when the user tries to sign-in using a phone as a security key, or tries to register their phone as a security key for a future sign-in. A security key is traditionally a small USB device that is touched to confirm a sign-in (e.g. a gNubby) and, in this context, the phone is replacing the need for a separate device. The placeholder for the notification title will be replaced with the string that will appear in the notification on the phone. These messages are 4300134428943426639 and 581442427601260656.">
         <ph name="WEBSITE"><ex>accounts.google.com</ex>$1</ph> sent a notification to your phone. To confirm it's you, tap the “<ph name="NOTIFICATIONTITLE"><ex>Verify with this phone</ex>$2</ph>” notification and follow the steps.
       </message>
-      <message name="IDS_WEBAUTHN_CABLEV2_ADD_PHONE" desc="The label on a button-like element in a list of options. Clicking this causes Chrome to show a QR code that the user can scan with their phone to use that phone for signing into a website. Here 'phone' is used as a short hand for smartphone.">
-        Add a new phone
+      <message name="IDS_WEBAUTHN_CABLEV2_ADD_PHONE" desc="The label on a button-like element in a list of options. Clicking this causes Chrome to show a QR code that the user can scan with their phone to use that phone for signing into a website. Here 'phone' is used as a short hand for smartphone. Currently this ability is specific to Android phones.">
+        Add a new Android phone
       </message>
 
       <message name="IDS_WEBAUTHN_CABLE_ACTIVATE_DESCRIPTION_SHORT" desc="Second line of text in an item letting the user know that they can use their phone as a security key. The user needs to check their phone and respond to a notification that will ask them to press a button on the phone's screen to confirm that they're logging in.">
diff --git a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_CABLEV2_ADD_PHONE.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_CABLEV2_ADD_PHONE.png.sha1
index 59eca98..d7d3d8b 100644
--- a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_CABLEV2_ADD_PHONE.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_CABLEV2_ADD_PHONE.png.sha1
@@ -1 +1 @@
-3f19b4f5479ff3238a0307cbaf61b1d8ed868e89
\ No newline at end of file
+8122b2c689bc290777f795143e2142cce10f58af
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index 54851d14..7d83d04b 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -1574,9 +1574,21 @@
   <message name="IDS_SETTINGS_ACCOUNT_MANAGER_LIST_DESCRIPTION" desc="List description for additional account List in Account Manager Settings page.">
     You can add your additional accounts to access websites and apps.
   </message>
+  <message name="IDS_SETTINGS_ACCOUNT_MANAGER_LIST_DESCRIPTION_V2" desc="List description for additional account list in Account Manager Settings page.">
+    You can add additional accounts to your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> to use with websites and Android apps. You can also control which accounts are used with Android apps.
+  </message>
   <message name="IDS_SETTINGS_ACCOUNT_MANAGER_LIST_CHILD_DESCRIPTION" desc="List description for additional account List in Account Manager Settings page for Child users.">
     <ph name="USER_EMAIL">$1<ex>user@example.com</ex></ph> is supervised by Family Link. You can add school accounts to access school resources with parental supervision.
   </message>
+  <message name="IDS_SETTINGS_ACCOUNT_MANAGER_NOT_USED_IN_ARC_LABEL" desc="Per-account label on OS Account Manager page that is shown only if the account is not available in ARC / Android apps. User can change this by clicking 'Use with Android apps button' for the account.">
+    Not used with Android apps
+  </message>
+  <message name="IDS_SETTINGS_ACCOUNT_MANAGER_USE_IN_ARC_BUTTON_LABEL" desc="Per-account button label on OS Account Manager page. Clicking this button makes account available in ARC / Android apps.">
+   Use with Android apps
+  </message>
+  <message name="IDS_SETTINGS_ACCOUNT_MANAGER_STOP_USING_IN_ARC_BUTTON_LABEL" desc="Per-account button label on OS Account Manager page. Clicking this button makes account NOT available in ARC / Android apps.">
+   Stop using with Android apps
+  </message>
   <message name="IDS_SETTINGS_ACCOUNT_MANAGER_REMOVE_ACCOUNT_LABEL" desc="Label of the Remove account button in Account Manager.">
     Remove this account
   </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_LIST_DESCRIPTION_V2.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_LIST_DESCRIPTION_V2.png.sha1
new file mode 100644
index 0000000..a42827a
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_LIST_DESCRIPTION_V2.png.sha1
@@ -0,0 +1 @@
+f1daeb9a910e906f19ee655f739d17e67715f10e
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_NOT_USED_IN_ARC_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_NOT_USED_IN_ARC_LABEL.png.sha1
new file mode 100644
index 0000000..a42827a
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_NOT_USED_IN_ARC_LABEL.png.sha1
@@ -0,0 +1 @@
+f1daeb9a910e906f19ee655f739d17e67715f10e
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_STOP_USING_IN_ARC_BUTTON_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_STOP_USING_IN_ARC_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..9e7d9b3
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_STOP_USING_IN_ARC_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+777df4228e06dd3aa6b6f7b76a4426212ef5e0c0
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_USE_IN_ARC_BUTTON_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_USE_IN_ARC_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..db18dbd6
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ACCOUNT_MANAGER_USE_IN_ARC_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+26a3e76141ad93f8d4949c34127c6f40c5137f1e
\ No newline at end of file
diff --git a/chrome/app/vector_icons/crostini_mascot.icon b/chrome/app/vector_icons/crostini_mascot.icon
index cc417d35..7dc90a58 100644
--- a/chrome/app/vector_icons/crostini_mascot.icon
+++ b/chrome/app/vector_icons/crostini_mascot.icon
@@ -2,51 +2,55 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-CANVAS_DIMENSIONS, 116,
-MOVE_TO, 33.53f, 111.13f,
-CUBIC_TO, 18.69f, 103.15f, 9.13f, 87.46f, 8.81f, 66.72f,
-R_CUBIC_TO, -1.43f, 0.73f, -3.06f, 0.85f, -4.94f, 0.16f,
-R_CUBIC_TO, -5.38f, -1.96f, -4.17f, -8.51f, -2.2f, -14.35f,
-R_CUBIC_TO, 1.63f, -4.83f, 7.21f, -8.36f, 9.94f, -9.1f,
-CUBIC_TO, 17.97f, 19.07f, 32.88f, 0, 58, 0,
-R_CUBIC_TO, 25.42f, 0, 40.43f, 18.29f, 46.61f, 43.5f,
-R_CUBIC_TO, 2.8f, 0.86f, 8.13f, 4.33f, 9.72f, 9.04f,
-R_CUBIC_TO, 1.97f, 5.84f, 3.18f, 12.39f, -2.2f, 14.35f,
-R_CUBIC_TO, -1.88f, 0.69f, -3.51f, 0.56f, -4.94f, -0.16f,
-R_CUBIC_TO, -0.29f, 20.87f, -9.85f, 36.5f, -24.68f, 44.44f,
-R_CUBIC_TO, 0.89f, 0.72f, 1.4f, 1.65f, 1.4f, 2.84f,
-R_CUBIC_TO, 0, 3.87f, 1.88f, 7, -11.91f, 7,
-R_CUBIC_TO, -10.07f, 0, -11.78f, -2.13f, -11.98f, -4.45f,
-R_CUBIC_TO, -0.67f, -0.42f, -1.34f, -1.05f, -2.02f, -1.05f,
-R_CUBIC_TO, -0.68f, 0, -1.35f, 0.68f, -2.02f, 1.1f,
-CUBIC_TO, 55.76f, 118.9f, 53.99f, 121, 44, 121,
-R_CUBIC_TO, -13.79f, 0, -11.91f, -3.13f, -11.91f, -7,
-R_CUBIC_TO, 0, -1.21f, 0.52f, -2.15f, 1.44f, -2.87f,
+CANVAS_DIMENSIONS, 20,
+MOVE_TO, 10, 2,
+R_CUBIC_TO, 3.51f, 0, 5.58f, 2.59f, 6.43f, 6.17f,
+R_CUBIC_TO, 0.39f, 0.12f, 1.12f, 0.61f, 1.34f, 1.28f,
+R_CUBIC_TO, 0.27f, 0.83f, 0.44f, 1.76f, -0.3f, 2.03f,
+R_CUBIC_TO, -0.26f, 0.1f, -0.48f, 0.08f, -0.68f, -0.02f,
+R_CUBIC_TO, -0.04f, 2.89f, -1.3f, 4.53f, -3.26f, 5.34f,
+R_CUBIC_TO, 0.03f, 0.06f, 0.05f, 0.13f, 0.05f, 0.22f,
+R_CUBIC_TO, 0, 0.55f, 0.26f, 0.99f, -1.64f, 0.99f,
+R_CUBIC_TO, -1.39f, 0, -1.63f, -0.3f, -1.65f, -0.63f,
+R_CUBIC_TO, -0.09f, -0.06f, -0.18f, -0.15f, -0.28f, -0.15f,
+R_CUBIC_TO, -0.09f, 0, -0.19f, 0.1f, -0.28f, 0.16f,
+CUBIC_TO, 9.69f, 17.7f, 9.45f, 18, 8.07f, 18,
+R_CUBIC_TO, -1.9f, 0, -1.64f, -0.44f, -1.64f, -0.99f,
+R_ARC_TO, 0.51f, 0.51f, 0, 0, 1, 0.05f, -0.22f,
+R_CUBIC_TO, -1.96f, -0.81f, -3.22f, -2.46f, -3.26f, -5.33f,
+R_CUBIC_TO, -0.2f, 0.1f, -0.42f, 0.12f, -0.68f, 0.02f,
+R_CUBIC_TO, -0.74f, -0.28f, -0.57f, -1.21f, -0.3f, -2.03f,
+R_CUBIC_TO, 0.23f, -0.69f, 0.99f, -1.19f, 1.37f, -1.29f,
+CUBIC_TO, 4.48f, 4.7f, 6.54f, 2, 10, 2,
 CLOSE,
-MOVE_TO, 58, 107,
-R_CUBIC_TO, 28.66f, 0, 39, -20.35f, 39, -47.4f,
-R_CUBIC_TO, 0, -22.44f, -9.4f, -43.06f, -25, -46.5f,
-CUBIC_TO, 67, 12, 63.5f, 24, 58, 24,
-R_CUBIC_TO, -5.5f, 0, -9.5f, -12, -14, -10.9f,
-CUBIC_TO, 28.33f, 16.94f, 19, 38.34f, 19, 59.6f,
-CUBIC_TO, 19, 85.13f, 29.34f, 107, 58, 107,
+R_MOVE_TO, 0, 3.74f,
+R_CUBIC_TO, -0.7f, 0, -1.21f, -1.57f, -1.79f, -1.43f,
+R_CUBIC_TO, -2, 0.5f, -3.19f, 3.31f, -3.19f, 6.1f,
+R_CUBIC_TO, 0, 3.35f, 1.32f, 5.15f, 4.98f, 5.15f,
+R_CUBIC_TO, 3.66f, 0, 4.98f, -1.6f, 4.98f, -5.15f,
+R_CUBIC_TO, 0, -2.94f, -1.2f, -5.65f, -3.19f, -6.1f,
+R_CUBIC_TO, -0.64f, -0.14f, -1.08f, 1.43f, -1.79f, 1.43f,
 CLOSE,
-MOVE_TO, 40, 47,
-R_ARC_TO, 6, 6, 0, 1, 1, 0, -12,
-R_ARC_TO, 6, 6, 0, 0, 1, 0, 12,
+R_MOVE_TO, -0.17f, 3.38f,
+R_ARC_TO, 0.38f, 0.38f, 0, 0, 1, 0.32f, 0,
+R_LINE_TO, 1.14f, 0.51f,
+R_CUBIC_TO, 0.2f, 0.09f, 0.29f, 0.32f, 0.2f, 0.52f,
+R_ARC_TO, 0.4f, 0.4f, 0, 0, 1, -0.07f, 0.11f,
+R_LINE_TO, -1.13f, 1.25f,
+R_ARC_TO, 0.39f, 0.39f, 0, 0, 1, -0.57f, 0,
+R_LINE_TO, -1.13f, -1.25f,
+R_ARC_TO, 0.4f, 0.4f, 0, 0, 1, 0.02f, -0.56f,
+R_ARC_TO, 0.39f, 0.39f, 0, 0, 1, 0.1f, -0.07f,
 CLOSE,
-R_MOVE_TO, 36, 0,
-R_ARC_TO, 6, 6, 0, 1, 1, 0, -12,
-R_ARC_TO, 6, 6, 0, 0, 1, 0, 12,
+R_MOVE_TO, -2.31f, -2.16f,
+R_CUBIC_TO, 0.46f, 0, 0.83f, 0.38f, 0.83f, 0.85f,
+R_CUBIC_TO, 0, 0.47f, -0.37f, 0.85f, -0.83f, 0.85f,
+R_CUBIC_TO, -0.46f, 0, -0.83f, -0.38f, -0.83f, -0.85f,
+R_CUBIC_TO, 0, -0.47f, 0.37f, -0.85f, 0.83f, -0.85f,
 CLOSE,
-R_MOVE_TO, -16.91f, 3.24f,
-R_LINE_TO, 8.23f, 3.61f,
-R_ARC_TO, 2.78f, 2.78f, 0, 0, 1, 0.93f, 4.44f,
-R_LINE_TO, -8.19f, 8.8f,
-R_ARC_TO, 2.85f, 2.85f, 0, 0, 1, -4.17f, -0.01f,
-R_LINE_TO, -8.16f, -8.82f,
-R_ARC_TO, 2.77f, 2.77f, 0, 0, 1, 0.18f, -3.94f,
-R_CUBIC_TO, 0.22f, -0.2f, 0.48f, -0.36f, 0.75f, -0.49f,
-R_LINE_TO, 8.11f, -3.59f,
-R_ARC_TO, 2.86f, 2.86f, 0, 0, 1, 2.3f, 0,
+R_MOVE_TO, 4.97f, 0,
+R_CUBIC_TO, 0.46f, 0, 0.83f, 0.38f, 0.83f, 0.85f,
+R_CUBIC_TO, 0, 0.47f, -0.37f, 0.85f, -0.83f, 0.85f,
+R_CUBIC_TO, -0.46f, 0, -0.83f, -0.38f, -0.83f, -0.85f,
+R_CUBIC_TO, 0, -0.47f, 0.37f, -0.85f, 0.83f, -0.85f,
 CLOSE
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 1c4c344..e88b6514 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -379,8 +379,6 @@
     "data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h",
     "data_reduction_proxy/data_reduction_proxy_tab_helper.cc",
     "data_reduction_proxy/data_reduction_proxy_tab_helper.h",
-    "data_use_measurement/chrome_data_use_measurement.cc",
-    "data_use_measurement/chrome_data_use_measurement.h",
     "defaults.cc",
     "defaults.h",
     "device_reauth/chrome_biometric_authenticator_factory.h",
@@ -962,10 +960,6 @@
     "page_load_metrics/observers/core/amp_page_load_metrics_observer.h",
     "page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc",
     "page_load_metrics/observers/core/ukm_page_load_metrics_observer.h",
-    "page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.cc",
-    "page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.h",
-    "page_load_metrics/observers/data_use_metrics_observer.cc",
-    "page_load_metrics/observers/data_use_metrics_observer.h",
     "page_load_metrics/observers/document_write_page_load_metrics_observer.cc",
     "page_load_metrics/observers/document_write_page_load_metrics_observer.h",
     "page_load_metrics/observers/foreground_duration_ukm_observer.cc",
@@ -2057,7 +2051,6 @@
     "//components/crx_file",
     "//components/custom_handlers",
     "//components/data_reduction_proxy/core/browser",
-    "//components/data_use_measurement/core:ascriber",
     "//components/device_event_log",
     "//components/device_reauth",
     "//components/digital_asset_links",
@@ -2443,6 +2436,7 @@
       "//ash/webui/help_app_ui/search:mojo_bindings",
       "//ash/webui/media_app_ui",
       "//ash/webui/media_app_ui:mojo_bindings",
+      "//ash/webui/multidevice_debug",
       "//ash/webui/personalization_app",
       "//ash/webui/personalization_app/mojom",
       "//ash/webui/print_management",
@@ -2473,7 +2467,6 @@
       "//chromeos/components/local_search_service",
       "//chromeos/components/local_search_service/public/cpp:cpp",
       "//chromeos/components/local_search_service/public/mojom",
-      "//chromeos/components/multidevice/debug_webui",
       "//chromeos/components/onc",
       "//chromeos/components/quick_answers/public/cpp:cpp",
       "//chromeos/components/quick_answers/public/cpp:prefs",
@@ -3201,8 +3194,6 @@
       "page_info/about_this_site_controller_android.cc",
       "page_load_metrics/observers/android_page_load_metrics_observer.cc",
       "page_load_metrics/observers/android_page_load_metrics_observer.h",
-      "page_load_metrics/observers/offline_measurements_page_load_metrics_observer.cc",
-      "page_load_metrics/observers/offline_measurements_page_load_metrics_observer.h",
       "password_check/android/password_check_bridge.cc",
       "password_check/android/password_check_bridge.h",
       "password_check/android/password_check_manager.cc",
@@ -3399,7 +3390,6 @@
       "//chrome/browser/notifications:jni_headers",
       "//chrome/browser/notifications/chime/android",
       "//chrome/browser/notifications/scheduler/public",
-      "//chrome/browser/offline_pages/measurements/proto:offline_measurements_proto",
       "//chrome/browser/optimization_guide/android:jni_headers",
       "//chrome/browser/password_check/android:jni_headers",
       "//chrome/browser/password_check/android:password_check_enums_srcjar",
@@ -5204,6 +5194,8 @@
       "lacros/lacros_startup_infobar_delegate.h",
       "lacros/lacros_url_handling.cc",
       "lacros/lacros_url_handling.h",
+      "lacros/launcher_search/search_controller_lacros.cc",
+      "lacros/launcher_search/search_controller_lacros.h",
       "lacros/metrics_reporting_observer.cc",
       "lacros/metrics_reporting_observer.h",
       "lacros/net/lacros_extension_proxy_tracker.cc",
@@ -5503,7 +5495,6 @@
       "//components/chrome_cleaner/public/constants",
       "//components/crash/core/app",
       "//components/crash/core/app:crash_export_thunk_include",
-      "//components/services/quarantine/public/cpp:features",
       "//google_update",
       "//sandbox/win:sandbox",
       "//services/proxy_resolver_win/public/mojom",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index c6baaa7..c817e92 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -402,6 +402,18 @@
     {"Transform stretch", kElasticOverscrollTransformType,
      base::size(kElasticOverscrollTransformType), nullptr}};
 
+const FeatureEntry::FeatureParam kCCTResizablePolicyParamUseAllowlist[] = {
+    {"default_policy", "use-allowlist"}};
+const FeatureEntry::FeatureParam kCCTResizablePolicyParamUseDenylist[] = {
+    {"default_policy", "use-denylist"}};
+
+const FeatureEntry::FeatureVariation
+    kCCTResizableThirdPartiesDefaultPolicyVariations[] = {
+        {"Use Allowlist", kCCTResizablePolicyParamUseAllowlist,
+         base::size(kCCTResizablePolicyParamUseAllowlist), nullptr},
+        {"Use Denylist", kCCTResizablePolicyParamUseDenylist,
+         base::size(kCCTResizablePolicyParamUseDenylist), nullptr}};
+
 const FeatureEntry::Choice kReaderModeHeuristicsChoices[] = {
     {flags_ui::kGenericExperimentChoiceDefault, "", ""},
     {flag_descriptions::kReaderModeHeuristicsMarkup,
@@ -2805,11 +2817,6 @@
      flag_descriptions::kContextualSearchForceCaptionName,
      flag_descriptions::kContextualSearchForceCaptionDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kContextualSearchForceCaption)},
-    {"contextual-search-literal-search-tap",
-     flag_descriptions::kContextualSearchLiteralSearchTapName,
-     flag_descriptions::kContextualSearchLiteralSearchTapDescription,
-     kOsAndroid,
-     FEATURE_VALUE_TYPE(chrome::android::kContextualSearchLiteralSearchTap)},
     {"contextual-search-longpress-resolve",
      flag_descriptions::kContextualSearchLongpressResolveName,
      flag_descriptions::kContextualSearchLongpressResolveDescription,
@@ -5367,7 +5374,10 @@
     {"cct-resizable-for-third-parties",
      flag_descriptions::kCCTResizableForThirdPartiesName,
      flag_descriptions::kCCTResizableForThirdPartiesDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(chrome::android::kCCTResizableForThirdParties)},
+     FEATURE_WITH_PARAMS_VALUE_TYPE(
+         chrome::android::kCCTResizableForThirdParties,
+         kCCTResizableThirdPartiesDefaultPolicyVariations,
+         "CCTResizableThirdPartiesDefaultPolicy")},
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -6514,11 +6524,6 @@
      flag_descriptions::kCanvas2DLayersDescription, kOsAll,
      SINGLE_VALUE_TYPE(switches::kEnableCanvas2DLayers)},
 
-    {"enable-canvas-context-lost-in-background",
-     flag_descriptions::kEnableCanvasContextLostInBackgroundName,
-     flag_descriptions::kEnableCanvasContextLostInBackgroundDescription, kOsAll,
-     SINGLE_VALUE_TYPE(switches::kEnableCanvasContextLostInBackground)},
-
     {"new-canvas-2d-api", flag_descriptions::kNewCanvas2DAPIName,
      flag_descriptions::kNewCanvas2DAPIDescription, kOsAll,
      SINGLE_VALUE_TYPE(switches::kEnableNewCanvas2DAPI)},
@@ -7786,6 +7791,18 @@
      FEATURE_VALUE_TYPE(chrome::android::kCloseAllTabsModalDialog)},
 #endif  // BUILDFLAG(IS_ANDROID)
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+    {"traffic-counters-handler-enabled",
+     flag_descriptions::kTrafficCountersHandlerEnabledName,
+     flag_descriptions::kTrafficCountersHandlerEnabledDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(ash::features::kTrafficCountersHandlerEnabled)},
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+    {"tailored-security-integration",
+     flag_descriptions::kTailoredSecurityIntegrationName,
+     flag_descriptions::kTailoredSecurityIntegrationDescription, kOsAll,
+     FEATURE_VALUE_TYPE(safe_browsing::kTailoredSecurityIntegration)},
+
     // NOTE: Adding a new flag requires adding a corresponding entry to enum
     // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
     // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc
index e7821ba9..51ef381d 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -1567,6 +1567,8 @@
     app->show_in_management = show;
   }
 
+  app->handles_intents = show;
+
   // TODO(crbug.com/1253250): Add other fields for the App struct.
   return app;
 }
diff --git a/chrome/browser/apps/app_service/publishers/borealis_apps.cc b/chrome/browser/apps/app_service/publishers/borealis_apps.cc
index ebddfb2..aff5ec9 100644
--- a/chrome/browser/apps/app_service/publishers/borealis_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/borealis_apps.cc
@@ -78,6 +78,7 @@
   app.show_in_shelf = allowed;
   app.show_in_search = allowed;
   app.show_in_management = allowed;
+  app.handles_intents = allowed;
 }
 
 std::unique_ptr<apps::App> CreateBorealisLauncher(Profile* profile,
diff --git a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc
index 8359a53..b7919bd 100644
--- a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc
@@ -54,6 +54,7 @@
   app->show_in_launcher = internal_app.show_in_launcher;
   app->show_in_shelf = app->show_in_search = internal_app.searchable;
   app->show_in_management = false;
+  app->handles_intents = app->show_in_launcher;
 
   // TODO(crbug.com/1253250): Add other fields for the App struct.
   return app;
diff --git a/chrome/browser/apps/app_service/publishers/crostini_apps.cc b/chrome/browser/apps/app_service/publishers/crostini_apps.cc
index 67ffbb80..c5c7510 100644
--- a/chrome/browser/apps/app_service/publishers/crostini_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/crostini_apps.cc
@@ -342,6 +342,7 @@
   app->show_in_launcher = crostini_enabled_;
   app->show_in_shelf = crostini_enabled_;
   app->show_in_search = true;
+  app->handles_intents = crostini_enabled_;
   AppPublisher::Publish(std::move(app));
 }
 
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
index 2b18b01..596aced5 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
@@ -193,6 +193,7 @@
   app.show_in_shelf = show;
   app.show_in_search = show;
   app.show_in_management = show;
+  app.handles_intents = show;
 }
 
 void ExtensionAppsBase::SetShowInFields(
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
index 4b9e690cf..a83bb4cf 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -728,9 +728,20 @@
     app.show_in_shelf = should_show;
     app.show_in_search = should_show;
     app.show_in_management = false;
+    app.handles_intents = true;
     return;
   }
   ExtensionAppsBase::SetShowInFields(extension, app);
+
+  // Explicitly mark AudioPlayer and QuickOffice as being able to handle
+  // intents even though they are otherwise hidden from the user. Otherwise,
+  // extensions are only published if they have file_browser_handlers, which
+  // means they need to handle intents.
+  if (extension->id() == file_manager::kAudioPlayerAppId ||
+      extension->id() == extension_misc::kQuickOfficeComponentExtensionId ||
+      extension->is_extension()) {
+    app.handles_intents = true;
+  }
 }
 
 void ExtensionAppsChromeOs::SetShowInFields(
diff --git a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc
index 15b2119..c635987 100644
--- a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc
@@ -79,6 +79,7 @@
   app.show_in_launcher = allowed;
   app.show_in_shelf = allowed;
   app.show_in_search = allowed;
+  app.handles_intents = allowed;
 }
 
 void SetShowInAppManagement(apps::mojom::App* app, bool installed) {
diff --git a/chrome/browser/apps/app_service/publishers/publisher_unittest.cc b/chrome/browser/apps/app_service/publishers/publisher_unittest.cc
index ad228a1..17443b1 100644
--- a/chrome/browser/apps/app_service/publishers/publisher_unittest.cc
+++ b/chrome/browser/apps/app_service/publishers/publisher_unittest.cc
@@ -225,7 +225,8 @@
                  absl::optional<bool> show_in_launcher = absl::nullopt,
                  absl::optional<bool> show_in_shelf = absl::nullopt,
                  absl::optional<bool> show_in_search = absl::nullopt,
-                 absl::optional<bool> show_in_management = absl::nullopt) {
+                 absl::optional<bool> show_in_management = absl::nullopt,
+                 absl::optional<bool> handles_intents = absl::nullopt) {
     AppRegistryCache& cache =
         AppServiceProxyFactory::GetForProfile(profile())->AppRegistryCache();
 
@@ -257,6 +258,7 @@
     VerifyOptionalBool(show_in_search, cache.states_[app_id]->show_in_search);
     VerifyOptionalBool(show_in_management,
                        cache.states_[app_id]->show_in_management);
+    VerifyOptionalBool(handles_intents, cache.states_[app_id]->handles_intents);
   }
 
   void VerifyAppIsRemoved(const std::string& app_id) {
@@ -294,7 +296,8 @@
           apps::Permissions(), /*is_platform_app=*/false,
           /*recommendable=*/true, /*searchable=*/true,
           /*show_in_launcher=*/true, /*show_in_shelf=*/true,
-          /*show_in_search=*/true, /*show_in_management=*/true);
+          /*show_in_search=*/true, /*show_in_management=*/true,
+          /*handles_intents=*/true);
       // Simulate the app is removed.
       RemoveArcApp(app_id);
       VerifyAppIsRemoved(app_id);
@@ -318,7 +321,8 @@
           MakeFakePermissions(), /*is_platform_app=*/false,
           /*recommendable=*/true, /*searchable=*/true,
           /*show_in_launcher=*/true, /*show_in_shelf=*/true,
-          /*show_in_search=*/true, /*show_in_management=*/true);
+          /*show_in_search=*/true, /*show_in_management=*/true,
+          /*handles_intents=*/true);
 
       // Test OnAppLastLaunchTimeUpdated.
       const base::Time before_time = base::Time::Now();
@@ -357,7 +361,8 @@
               apps::Permissions(), /*is_platform_app=*/false,
               internal_app.recommendable, internal_app.searchable,
               internal_app.show_in_launcher, internal_app.searchable,
-              internal_app.searchable, /*show_in_management=*/false);
+              internal_app.searchable, /*show_in_management=*/false,
+              internal_app.show_in_launcher);
   }
 }
 
@@ -405,6 +410,7 @@
     app->show_in_shelf = apps::mojom::OptionalBool::kFalse;
     app->show_in_search = apps::mojom::OptionalBool::kFalse;
     app->show_in_management = apps::mojom::OptionalBool::kFalse;
+    app->handles_intents = apps::mojom::OptionalBool::kFalse;
     apps.push_back(std::move(app));
     chrome_apps->OnApps(std::move(apps));
   }
@@ -429,6 +435,7 @@
     app->show_in_shelf = apps::mojom::OptionalBool::kTrue;
     app->show_in_search = apps::mojom::OptionalBool::kTrue;
     app->show_in_management = apps::mojom::OptionalBool::kTrue;
+    app->handles_intents = apps::mojom::OptionalBool::kTrue;
     apps.push_back(std::move(app));
     web_apps_crosapi->OnApps(std::move(apps));
   }
@@ -445,7 +452,8 @@
             /*is_platform_app=*/false,
             /*recommendable=*/true, /*searchable=*/true,
             /*show_in_launcher=*/true, /*show_in_shelf=*/true,
-            /*show_in_search=*/true, /*show_in_management=*/true);
+            /*show_in_search=*/true, /*show_in_management=*/true,
+            /*handles_intents=*/true);
 }
 
 TEST_F(StandaloneBrowserPublisherTest, StandaloneBrowserExtensionAppsOnApps) {
@@ -456,7 +464,8 @@
             /*is_platform_app=*/true, /*recommendable=*/false,
             /*searchable=*/false,
             /*show_in_launcher=*/false, /*show_in_shelf=*/false,
-            /*show_in_search=*/false, /*show_in_management=*/false);
+            /*show_in_search=*/false, /*show_in_management=*/false,
+            /*handles_intents=*/false);
 }
 
 TEST_F(StandaloneBrowserPublisherTest, WebAppsCrosapiOnApps) {
@@ -467,7 +476,8 @@
             /*is_platform_app=*/false, /*recommendable=*/true,
             /*searchable=*/true,
             /*show_in_launcher=*/true, /*show_in_shelf=*/true,
-            /*show_in_search=*/true, /*show_in_management=*/true);
+            /*show_in_search=*/true, /*show_in_management=*/true,
+            /*handles_intents=*/true);
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -488,7 +498,8 @@
             /*is_platform_app=*/false, /*recommendable=*/true,
             /*searchable=*/true,
             /*show_in_launcher=*/true, /*show_in_shelf=*/true,
-            /*show_in_search=*/true, /*show_in_management=*/true);
+            /*show_in_search=*/true, /*show_in_management=*/true,
+            /*handles_intents=*/true);
 
   // Uninstall the Chrome app.
   service_->UninstallExtension(
@@ -500,7 +511,8 @@
             /*recommendable=*/true,
             /*searchable=*/true,
             /*show_in_launcher=*/true, /*show_in_shelf=*/true,
-            /*show_in_search=*/true, /*show_in_management=*/true);
+            /*show_in_search=*/true, /*show_in_management=*/true,
+            /*handles_intents=*/true);
 
   // Reinstall the Chrome app.
   service_->AddExtension(store.get());
@@ -510,7 +522,8 @@
             /*is_platform_app=*/false, /*recommendable=*/true,
             /*searchable=*/true,
             /*show_in_launcher=*/true, /*show_in_shelf=*/true,
-            /*show_in_search=*/true, /*show_in_management=*/true);
+            /*show_in_search=*/true, /*show_in_management=*/true,
+            /*handles_intents=*/true);
 
   // Test OnExtensionLastLaunchTimeChanged.
   extensions::ExtensionPrefs::Get(profile())->SetLastLaunchTime(
@@ -533,7 +546,8 @@
             /*recommendable=*/true,
             /*searchable=*/true,
             /*show_in_launcher=*/true, /*show_in_shelf=*/true,
-            /*show_in_search=*/true, /*show_in_management=*/true);
+            /*show_in_search=*/true, /*show_in_management=*/true,
+            /*handles_intents=*/true);
 }
 
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/apps/app_service/publishers/remote_apps.cc b/chrome/browser/apps/app_service/publishers/remote_apps.cc
index 258cf38b..07fdcb6 100644
--- a/chrome/browser/apps/app_service/publishers/remote_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/remote_apps.cc
@@ -72,6 +72,7 @@
   app->show_in_management = false;
   app->show_in_search = true;
   app->show_in_shelf = false;
+  app->handles_intents = true;
   return app;
 }
 
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
index e589c0ad..7cbb683 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
@@ -70,6 +70,7 @@
   app->show_in_shelf = true;
   app->show_in_search = true;
   app->show_in_management = true;
+  app->handles_intents = true;
   return app;
 }
 
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
index f6d4b56e..cd08c66 100644
--- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
+++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
@@ -268,8 +268,10 @@
 }
 
 void ArcAppPerformanceTracing::OnSurfaceDestroying(exo::Surface* surface) {
-  if (surface)
-    surface->RemoveSurfaceObserver(this);
+  // |scoped_surface_| might be already reset in case window is destroyed
+  // first.
+  DCHECK(!scoped_surface_ || (scoped_surface_->get() == surface));
+  scoped_surface_.reset();
 }
 
 void ArcAppPerformanceTracing::CancelJankinessTracing() {
@@ -442,18 +444,18 @@
 
   exo::Surface* const surface = exo::GetShellRootSurface(window);
   DCHECK(surface);
-  surface->AddSurfaceObserver(this);
+  // Use scoped surface observer to be safe on the surface
+  // destruction. |exo::GetShellRootSurface| would fail in case
+  // the surface gets destroyed before widget.
+  scoped_surface_ =
+      std::make_unique<exo::ScopedSurface>(surface, this /* observer */);
 }
 
 void ArcAppPerformanceTracing::DetachActiveWindow() {
   if (!arc_active_window_)
     return;
 
-  exo::Surface* const surface = exo::GetShellRootSurface(arc_active_window_);
-  // Surface might be destroyed.
-  if (surface)
-    surface->RemoveSurfaceObserver(this);
-
+  scoped_surface_.reset();
   arc_active_window_->RemoveObserver(this);
   arc_active_window_ = nullptr;
 }
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.h b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.h
index 463e0da..80734628f 100644
--- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.h
+++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.h
@@ -29,6 +29,10 @@
 class BrowserContext;
 }  // namespace content
 
+namespace exo {
+class ScopedSurface;
+}  // namespace exo
+
 namespace arc {
 
 class ArcAppPerformanceTracingSession;
@@ -182,6 +186,9 @@
 
   // Timer for jankiness tracing.
   base::OneShotTimer jankiness_timer_;
+
+  // Used for automatic observer adding/removing.
+  std::unique_ptr<exo::ScopedSurface> scoped_surface_;
 };
 
 }  // namespace arc
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.cc b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.cc
index d44a35a..cab80d1 100644
--- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.cc
+++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.cc
@@ -69,6 +69,9 @@
 
 void ArcAppPerformanceTracingSession::OnSurfaceDestroying(
     exo::Surface* surface) {
+  // |scoped_surface_| might be already reset in case window is destroyed
+  // first.
+  DCHECK(!scoped_surface_ || (scoped_surface_->get() == surface));
   Stop();
 }
 
@@ -95,7 +98,11 @@
 
   exo::Surface* const surface = exo::GetShellRootSurface(window_);
   DCHECK(surface);
-  surface->AddSurfaceObserver(this);
+  // Use scoped surface observer to be safe on the surface
+  // destruction. |exo::GetShellRootSurface| would fail in case
+  // the surface gets destroyed before widget.
+  scoped_surface_ =
+      std::make_unique<exo::ScopedSurface>(surface, this /* observer */);
 
   // Schedule result analyzing at the end of tracing.
   tracing_start_ = base::TimeTicks::Now();
@@ -113,10 +120,7 @@
 void ArcAppPerformanceTracingSession::Stop() {
   tracing_active_ = false;
   tracing_timer_.Stop();
-  exo::Surface* const surface = exo::GetShellRootSurface(window_);
-  // Surface might be destroyed.
-  if (surface)
-    surface->RemoveSurfaceObserver(this);
+  scoped_surface_.reset();
 }
 
 void ArcAppPerformanceTracingSession::HandleCommit(
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.h b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.h
index 5439b20..1277779d 100644
--- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.h
+++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.h
@@ -17,6 +17,7 @@
 }  // namespace aura
 
 namespace exo {
+class ScopedSurface;
 class Surface;
 }  // namespace exo
 
@@ -95,6 +96,9 @@
   ArcAppPerformanceTracing* const owner_;
   aura::Window* const window_;
 
+  // Used for automatic observer adding/removing.
+  std::unique_ptr<exo::ScopedSurface> scoped_surface_;
+
   // Timer to start Surface commit tracing delayed.
   base::OneShotTimer tracing_timer_;
 
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc
index f29ce7d..4e33192 100644
--- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc
+++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc
@@ -85,7 +85,7 @@
   }
 
   void TearDown() override {
-    shell_root_surface_.reset();
+    ResetRootSurface();
     tracing_helper_.TearDown();
     arc_test_.TearDown();
     BrowserWithTestWindowTest::TearDown();
@@ -112,6 +112,8 @@
     return arc_widget;
   }
 
+  void ResetRootSurface() { shell_root_surface_.reset(); }
+
   ArcAppPerformanceTracingTestHelper& tracing_helper() {
     return tracing_helper_;
   }
@@ -298,4 +300,15 @@
   arc_widget->Close();
 }
 
+// This test verifies the case when surface is destroyed before window close.
+TEST_F(ArcAppPerformanceTracingTest, DestroySurface) {
+  views::Widget* const arc_widget = StartArcFocusAppTracing();
+  ASSERT_TRUE(tracing_helper().GetTracingSession());
+  EXPECT_TRUE(tracing_helper().GetTracingSession()->tracing_active());
+  ResetRootSurface();
+  ASSERT_TRUE(tracing_helper().GetTracingSession());
+  EXPECT_FALSE(tracing_helper().GetTracingSession()->tracing_active());
+  arc_widget->Close();
+}
+
 }  // namespace arc
diff --git a/chrome/browser/ash/borealis/borealis_wayland_interface.cc b/chrome/browser/ash/borealis/borealis_wayland_interface.cc
index ae2aa8cf..a3980566 100644
--- a/chrome/browser/ash/borealis/borealis_wayland_interface.cc
+++ b/chrome/browser/ash/borealis/borealis_wayland_interface.cc
@@ -13,9 +13,7 @@
 namespace borealis {
 
 BorealisWaylandInterface::BorealisWaylandInterface(Profile* profile)
-    : profile_(profile), capabilities_(nullptr) {
-  (void)profile_;
-}
+    : profile_(profile) {}
 
 BorealisWaylandInterface::~BorealisWaylandInterface() {
   if (capabilities_ && !server_path_.empty())
diff --git a/chrome/browser/ash/borealis/borealis_wayland_interface.h b/chrome/browser/ash/borealis/borealis_wayland_interface.h
index 35f4bcb7..7ad686d 100644
--- a/chrome/browser/ash/borealis/borealis_wayland_interface.h
+++ b/chrome/browser/ash/borealis/borealis_wayland_interface.h
@@ -46,7 +46,7 @@
 
   Profile* const profile_;
   // This is owned by Exo, once the server is created.
-  BorealisCapabilities* capabilities_;
+  BorealisCapabilities* capabilities_ = nullptr;
   base::FilePath server_path_;
 
   base::WeakPtrFactory<BorealisWaylandInterface> weak_factory_{this};
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
index 1d4ad6c..7eca9d31 100644
--- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc
+++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -121,6 +121,7 @@
 #include "chrome/browser/ash/net/network_throttling_observer.h"
 #include "chrome/browser/ash/net/rollback_network_config/rollback_network_config_service.h"
 #include "chrome/browser/ash/net/system_proxy_manager.h"
+#include "chrome/browser/ash/net/traffic_counters_handler.h"
 #include "chrome/browser/ash/network_change_manager_client.h"
 #include "chrome/browser/ash/note_taking_helper.h"
 #include "chrome/browser/ash/notifications/debugd_notification_handler.h"
@@ -1094,6 +1095,13 @@
               ->GetDiagnosticsRemoteAndBindReceiver();
         }));
 
+    if (features::IsTrafficCountersHandlerEnabled()) {
+      // Initialize the TrafficCountersHandler instance.
+      traffic_counters_handler_ =
+          std::make_unique<ash::traffic_counters::TrafficCountersHandler>();
+      traffic_counters_handler_->Start();
+    }
+
     // Initialize input methods.
     input_method::InputMethodManager* manager =
         input_method::InputMethodManager::Get();
@@ -1178,6 +1186,8 @@
 }
 
 void ChromeBrowserMainPartsAsh::PostBrowserStart() {
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+  // Branded builds are packaged with valid google chrome api keys.
   if (base::FeatureList::IsEnabled(features::kDeviceActiveClient)) {
     device_activity_controller_ =
         std::make_unique<device_activity::DeviceActivityController>();
@@ -1187,6 +1197,7 @@
         g_browser_process->system_network_context_manager()
             ->GetSharedURLLoaderFactory());
   }
+#endif
 
   // Construct a delegate to connect the accessibility component extensions and
   // AccessibilityEventRewriter.
@@ -1384,6 +1395,9 @@
   login_screen_extensions_storage_cleaner_.reset();
   debugd_notification_handler_.reset();
   shortcut_mapping_pref_service_.reset();
+  if (features::IsTrafficCountersHandlerEnabled())
+    traffic_counters_handler_.reset();
+
   if (features::IsBluetoothRevampEnabled())
     bluetooth_pref_state_observer_.reset();
 
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.h b/chrome/browser/ash/chrome_browser_main_parts_ash.h
index 2e80c38c..b5a215c 100644
--- a/chrome/browser/ash/chrome_browser_main_parts_ash.h
+++ b/chrome/browser/ash/chrome_browser_main_parts_ash.h
@@ -115,6 +115,10 @@
 class DarkResumeController;
 }  // namespace system
 
+namespace traffic_counters {
+class TrafficCountersHandler;
+}  // namespace traffic_counters
+
 // ChromeBrowserMainParts implementation for chromeos specific code.
 // NOTE: Chromeos UI (Ash) support should be added to
 // ChromeBrowserMainExtraPartsAsh instead. This class should not depend on
@@ -260,6 +264,9 @@
   // The Accessor is constructed before initialization of FeatureList and should
   // only be used by ChromeFeaturesServiceProvider.
   std::unique_ptr<base::FeatureList::Accessor> feature_list_accessor_;
+
+  std::unique_ptr<ash::traffic_counters::TrafficCountersHandler>
+      traffic_counters_handler_;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/ash/crosapi/BUILD.gn b/chrome/browser/ash/crosapi/BUILD.gn
index fb4d75fd..ed3553d 100644
--- a/chrome/browser/ash/crosapi/BUILD.gn
+++ b/chrome/browser/ash/crosapi/BUILD.gn
@@ -133,6 +133,8 @@
     "resource_manager_ash.h",
     "screen_manager_ash.cc",
     "screen_manager_ash.h",
+    "search_provider_ash.cc",
+    "search_provider_ash.h",
     "select_file_ash.cc",
     "select_file_ash.h",
     "structured_metrics_service_ash.cc",
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc
index 6af435b..26b126e5 100644
--- a/chrome/browser/ash/crosapi/browser_util.cc
+++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -253,7 +253,7 @@
 }
 
 static_assert(
-    crosapi::mojom::Crosapi::Version_ == 61,
+    crosapi::mojom::Crosapi::Version_ == 62,
     "if you add a new crosapi, please add it to kInterfaceVersionEntries");
 
 }  // namespace
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.cc b/chrome/browser/ash/crosapi/crosapi_ash.cc
index 3ffcb38..e510fe5c 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.cc
+++ b/chrome/browser/ash/crosapi/crosapi_ash.cc
@@ -58,6 +58,7 @@
 #include "chrome/browser/ash/crosapi/remoting_ash.h"
 #include "chrome/browser/ash/crosapi/resource_manager_ash.h"
 #include "chrome/browser/ash/crosapi/screen_manager_ash.h"
+#include "chrome/browser/ash/crosapi/search_provider_ash.h"
 #include "chrome/browser/ash/crosapi/select_file_ash.h"
 #include "chrome/browser/ash/crosapi/structured_metrics_service_ash.h"
 #include "chrome/browser/ash/crosapi/system_display_ash.h"
@@ -167,6 +168,7 @@
       remoting_ash_(std::make_unique<RemotingAsh>()),
       resource_manager_ash_(std::make_unique<ResourceManagerAsh>()),
       screen_manager_ash_(std::make_unique<ScreenManagerAsh>()),
+      search_provider_ash_(std::make_unique<SearchProviderAsh>()),
       select_file_ash_(std::make_unique<SelectFileAsh>()),
       stable_video_decoder_factory_ash_(
           std::make_unique<media::StableVideoDecoderFactoryService>()),
@@ -402,6 +404,11 @@
   cert_database_ash_->BindReceiver(std::move(receiver));
 }
 
+void CrosapiAsh::BindSearchControllerRegistry(
+    mojo::PendingReceiver<mojom::SearchControllerRegistry> receiver) {
+  search_provider_ash_->BindReceiver(std::move(receiver));
+}
+
 void CrosapiAsh::BindSystemDisplay(
     mojo::PendingReceiver<mojom::SystemDisplay> receiver) {
   system_display_ash_->BindReceiver(std::move(receiver));
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.h b/chrome/browser/ash/crosapi/crosapi_ash.h
index f27b1c5c..b1bfa052 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.h
+++ b/chrome/browser/ash/crosapi/crosapi_ash.h
@@ -60,6 +60,7 @@
 class RemotingAsh;
 class ResourceManagerAsh;
 class ScreenManagerAsh;
+class SearchProviderAsh;
 class SelectFileAsh;
 class StructuredMetricsServiceAsh;
 class SystemDisplayAsh;
@@ -172,6 +173,8 @@
       mojo::PendingReceiver<mojom::ResourceManager> receiver) override;
   void BindScreenManager(
       mojo::PendingReceiver<mojom::ScreenManager> receiver) override;
+  void BindSearchControllerRegistry(
+      mojo::PendingReceiver<mojom::SearchControllerRegistry> receiver) override;
   void BindSelectFile(
       mojo::PendingReceiver<mojom::SelectFile> receiver) override;
   void BindSensorHalClient(
@@ -239,6 +242,10 @@
     return kiosk_session_service_ash_.get();
   }
 
+  SearchProviderAsh* search_provider_ash() {
+    return search_provider_ash_.get();
+  }
+
   WebPageInfoFactoryAsh* web_page_info_factory_ash() {
     return web_page_info_factory_ash_.get();
   }
@@ -310,6 +317,7 @@
   std::unique_ptr<RemotingAsh> remoting_ash_;
   std::unique_ptr<ResourceManagerAsh> resource_manager_ash_;
   std::unique_ptr<ScreenManagerAsh> screen_manager_ash_;
+  std::unique_ptr<SearchProviderAsh> search_provider_ash_;
   std::unique_ptr<SelectFileAsh> select_file_ash_;
   std::unique_ptr<media::StableVideoDecoderFactoryService>
       stable_video_decoder_factory_ash_;
diff --git a/chrome/browser/ash/crosapi/crosapi_util.cc b/chrome/browser/ash/crosapi/crosapi_util.cc
index 2032d79c..2b2873a4 100644
--- a/chrome/browser/ash/crosapi/crosapi_util.cc
+++ b/chrome/browser/ash/crosapi/crosapi_util.cc
@@ -52,6 +52,7 @@
 #include "chromeos/crosapi/mojom/image_writer.mojom.h"
 #include "chromeos/crosapi/mojom/keystore_service.mojom.h"
 #include "chromeos/crosapi/mojom/kiosk_session_service.mojom.h"
+#include "chromeos/crosapi/mojom/launcher_search.mojom.h"
 #include "chromeos/crosapi/mojom/local_printer.mojom.h"
 #include "chromeos/crosapi/mojom/login_state.mojom.h"
 #include "chromeos/crosapi/mojom/message_center.mojom.h"
@@ -195,6 +196,7 @@
     MakeInterfaceVersionEntry<crosapi::mojom::Remoting>(),
     MakeInterfaceVersionEntry<crosapi::mojom::ResourceManager>(),
     MakeInterfaceVersionEntry<crosapi::mojom::ScreenManager>(),
+    MakeInterfaceVersionEntry<crosapi::mojom::SearchControllerRegistry>(),
     MakeInterfaceVersionEntry<crosapi::mojom::StructuredMetricsService>(),
     MakeInterfaceVersionEntry<crosapi::mojom::SnapshotCapturer>(),
     MakeInterfaceVersionEntry<crosapi::mojom::SystemDisplay>(),
diff --git a/chrome/browser/ash/crosapi/search_provider_ash.cc b/chrome/browser/ash/crosapi/search_provider_ash.cc
new file mode 100644
index 0000000..fbaf456
--- /dev/null
+++ b/chrome/browser/ash/crosapi/search_provider_ash.cc
@@ -0,0 +1,66 @@
+// Copyright 2022 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 "chrome/browser/ash/crosapi/search_provider_ash.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/logging.h"
+
+namespace crosapi {
+
+SearchProviderAsh::SearchProviderAsh() = default;
+SearchProviderAsh::~SearchProviderAsh() = default;
+
+void SearchProviderAsh::BindReceiver(
+    mojo::PendingReceiver<mojom::SearchControllerRegistry> pending_receiver) {
+  registry_receivers_.Add(this, std::move(pending_receiver));
+}
+
+void SearchProviderAsh::Search(const std::u16string& query,
+                               SearchResultsReceivedCallback callback) {
+  if (search_controller_.is_bound() && search_controller_.is_connected()) {
+    search_controller_->Search(
+        query, base::BindOnce(&SearchProviderAsh::BindPublisher,
+                              weak_factory_.GetWeakPtr(), std::move(callback)));
+  }
+}
+
+void SearchProviderAsh::RegisterSearchController(
+    mojo::PendingRemote<mojom::SearchController> search_controller) {
+  if (search_controller_.is_bound() && search_controller_.is_connected()) {
+    LOG(ERROR) << "Search Controller is already connected.";
+    return;
+  }
+
+  search_controller_.reset();
+  search_controller_.Bind(std::move(search_controller));
+}
+
+void SearchProviderAsh::OnSearchResultsReceived(
+    mojom::SearchStatus status,
+    absl::optional<std::vector<mojom::SearchResultPtr>> results) {
+  const bool result_expected = status == mojom::SearchStatus::kInProgress ||
+                               status == mojom::SearchStatus::kDone;
+  const auto& callback = publisher_receivers_.current_context();
+  if (result_expected && results.has_value() && !callback.is_null()) {
+    callback.Run(std::move(results.value()));
+    return;
+  }
+
+  if (status == mojom::SearchStatus::kError) {
+    LOG(ERROR) << "Search failed.";
+    publisher_receivers_.Remove(publisher_receivers_.current_receiver());
+  }
+}
+
+void SearchProviderAsh::BindPublisher(
+    SearchResultsReceivedCallback callback,
+    mojo::PendingAssociatedReceiver<mojom::SearchResultsPublisher> publisher) {
+  publisher_receivers_.Add(this, std::move(publisher), std::move(callback));
+}
+
+}  // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/search_provider_ash.h b/chrome/browser/ash/crosapi/search_provider_ash.h
new file mode 100644
index 0000000..37b3af46
--- /dev/null
+++ b/chrome/browser/ash/crosapi/search_provider_ash.h
@@ -0,0 +1,75 @@
+// Copyright 2022 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 CHROME_BROWSER_ASH_CROSAPI_SEARCH_PROVIDER_ASH_H_
+#define CHROME_BROWSER_ASH_CROSAPI_SEARCH_PROVIDER_ASH_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "chromeos/crosapi/mojom/launcher_search.mojom.h"
+#include "mojo/public/cpp/bindings/associated_receiver_set.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+
+namespace crosapi {
+
+// Implements the crosapi interface for launcher search. Lives ash-chrome on UI
+// thread.
+// IMPORTANT: This search API should only be used by the launcher, because
+// in-flight queries will be cancelled whenever a new query is issued.
+class SearchProviderAsh : public mojom::SearchResultsPublisher,
+                          public mojom::SearchControllerRegistry {
+ public:
+  SearchProviderAsh();
+  SearchProviderAsh(const SearchProviderAsh&) = delete;
+  SearchProviderAsh& operator=(const SearchProviderAsh&) = delete;
+  ~SearchProviderAsh() override;
+
+  void BindReceiver(
+      mojo::PendingReceiver<mojom::SearchControllerRegistry> receiver);
+
+  using SearchResultsReceivedCallback =
+      base::RepeatingCallback<void(std::vector<mojom::SearchResultPtr>)>;
+  // Sends search query to lacros. The callback will be called each time results
+  // are received from lacros via OnSearchResultsReceived().
+  // If a search query is called while there is an in-flight search query, the
+  // in-flight search query will be cancelled (from lacros side) before the new
+  // search query is executed.
+  // When lacros finishes the search, it'll terminate the connection and no more
+  // results will be sent.
+  void Search(const std::u16string& query,
+              SearchResultsReceivedCallback callback);
+
+  // mojom::SearchControllerRegistry overrides:
+  void RegisterSearchController(
+      mojo::PendingRemote<mojom::SearchController> search_controller) override;
+
+  // mojom::SearchResultsPublisher overrides:
+  void OnSearchResultsReceived(
+      mojom::SearchStatus status,
+      absl::optional<std::vector<mojom::SearchResultPtr>> results) override;
+
+ private:
+  void BindPublisher(
+      SearchResultsReceivedCallback callback,
+      mojo::PendingAssociatedReceiver<mojom::SearchResultsPublisher> publisher);
+
+  // Since we only need one connection to fetch the results, we'll only support
+  // one crosapi connection here.
+  mojo::Remote<mojom::SearchController> search_controller_;
+
+  mojo::ReceiverSet<mojom::SearchControllerRegistry> registry_receivers_;
+  mojo::AssociatedReceiverSet<mojom::SearchResultsPublisher,
+                              SearchResultsReceivedCallback>
+      publisher_receivers_;
+
+  base::WeakPtrFactory<SearchProviderAsh> weak_factory_{this};
+};
+
+}  // namespace crosapi
+
+#endif  // CHROME_BROWSER_ASH_CROSAPI_SEARCH_PROVIDER_ASH_H_
diff --git a/chrome/browser/ash/crostini/crostini_terminal.cc b/chrome/browser/ash/crostini/crostini_terminal.cc
index e70ac13..bea56ee 100644
--- a/chrome/browser/ash/crostini/crostini_terminal.cc
+++ b/chrome/browser/ash/crostini/crostini_terminal.cc
@@ -16,7 +16,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
-#include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
+#include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/menu_item_constants.h"
 #include "chrome/browser/apps/app_service/menu_util.h"
@@ -47,7 +47,10 @@
 #include "ui/base/base_window.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/window_open_disposition.h"
+#include "ui/color/color_provider_manager.h"
 #include "ui/gfx/geometry/point.h"
+#include "ui/native_theme/native_theme.h"
+#include "ui/views/image_model_utils.h"
 
 namespace crostini {
 
@@ -150,30 +153,6 @@
   LOG(WARNING) << "Profile becomes invalid. Abort launching terminal.";
 }
 
-// Loads |resource_ids| and appends the gfx::ImageSkia results to |images|.
-// Invokes |callback| with |images| when complete.
-void LoadIconsFromResources(
-    std::vector<int> resource_ids,
-    std::vector<gfx::ImageSkia> images,
-    base::OnceCallback<void(std::vector<gfx::ImageSkia>)> callback) {
-  if (images.size() >= resource_ids.size()) {
-    return std::move(callback).Run(std::move(images));
-  }
-  auto resource_id = resource_ids[images.size()];
-  apps::LoadIconFromResource(
-      apps::IconType::kStandard, apps::kAppShortcutIconSizeDip, resource_id,
-      /*placeholder=*/false, apps::IconEffects::kNone,
-      base::BindOnce(
-          [](std::vector<int> resource_ids, std::vector<gfx::ImageSkia> images,
-             base::OnceCallback<void(std::vector<gfx::ImageSkia>)> callback,
-             apps::IconValuePtr icon) {
-            images.emplace_back(std::move(icon->uncompressed));
-            LoadIconsFromResources(std::move(resource_ids), std::move(images),
-                                   std::move(callback));
-          },
-          std::move(resource_ids), std::move(images), std::move(callback)));
-}
-
 }  // namespace
 
 void LaunchTerminal(Profile* profile,
@@ -429,33 +408,23 @@
     apps::mojom::MenuItemsPtr menu_items,
     apps::mojom::Publisher::GetMenuModelCallback callback,
     std::vector<gfx::ImageSkia> images) {
-  constexpr bool kIconIndexSSH = 0;
-  constexpr bool kIconIndexTerminal = 1;
-  if (images.empty()) {
-    std::vector<int> resource_ids = {IDR_LOGO_CROSTINI_TERMINAL_SSH,
-                                     IDR_CROSTINI_MASCOT};
-    return LoadIconsFromResources(
-        std::move(resource_ids), std::vector<gfx::ImageSkia>(),
-        base::BindOnce(
-            [](Profile* profile, int next_command_id,
-               apps::mojom::MenuItemsPtr menu_items,
-               apps::mojom::Publisher::GetMenuModelCallback callback,
-               std::vector<gfx::ImageSkia> images) {
-              AddTerminalMenuShortcuts(profile, next_command_id,
-                                       std::move(menu_items),
-                                       std::move(callback), std::move(images));
-            },
-            profile, next_command_id, std::move(menu_items),
-            std::move(callback)));
-  }
-
-  DCHECK_EQ(2, images.size());
+  ui::ColorProvider* color_provider =
+      ui::ColorProviderManager::Get().GetColorProviderFor(
+          ui::NativeTheme::GetInstanceForWeb()->GetColorProviderKey(nullptr));
+  auto icon = [color_provider](const gfx::VectorIcon& icon) {
+    return views::GetImageSkiaFromImageModel(
+        ui::ImageModel::FromVectorIcon(icon, ui::kColorMenuIcon,
+                                       apps::kAppShortcutIconSizeDip),
+        color_provider);
+  };
+  gfx::ImageSkia terminal_ssh_icon = icon(kTerminalSshIcon);
+  gfx::ImageSkia crostini_mascot_icon = icon(kCrostiniMascotIcon);
   if (base::FeatureList::IsEnabled(chromeos::features::kTerminalSSH)) {
     apps::AddSeparator(ui::DOUBLE_SEPARATOR, &menu_items);
     apps::AddShortcutCommandItem(
         next_command_id++, ShortcutIdForSSH(),
         l10n_util::GetStringUTF8(IDS_CROSTINI_TERMINAL_CONNECT_TO_SSH),
-        images[kIconIndexSSH], &menu_items);
+        terminal_ssh_icon, &menu_items);
   }
 
   if (!CrostiniFeatures::Get()->IsEnabled(profile)) {
@@ -474,7 +443,7 @@
           std::string label =
               base::StrCat({id.vm_name, ":", id.container_name});
           apps::AddShortcutCommandItem(next_command_id++, shortcut_id, label,
-                                       images[kIconIndexTerminal], &menu_items);
+                                       crostini_mascot_icon, &menu_items);
         }
       }
       return std::move(callback).Run(std::move(menu_items));
@@ -488,7 +457,7 @@
     apps::AddShortcutCommandItem(
         next_command_id++, shortcut_id,
         l10n_util::GetStringUTF8(IDS_CROSTINI_TERMINAL_CONNECT_TO_LINUX),
-        images[kIconIndexTerminal], &menu_items);
+        crostini_mascot_icon, &menu_items);
   }
   std::move(callback).Run(std::move(menu_items));
 }
diff --git a/chrome/browser/ash/login/arc_terms_of_service_browsertest.cc b/chrome/browser/ash/login/arc_terms_of_service_browsertest.cc
index df4e0c7..0cf9d5690 100644
--- a/chrome/browser/ash/login/arc_terms_of_service_browsertest.cc
+++ b/chrome/browser/ash/login/arc_terms_of_service_browsertest.cc
@@ -356,9 +356,7 @@
       {"learnMoreLinkPai", "arcPaiPopup"}};
 
   for (const auto& pair : learn_more_links) {
-    std::string html_element_id;
-    std::string popup_html_element_id;
-    std::tie(html_element_id, popup_html_element_id) = pair;
+    auto [html_element_id, popup_html_element_id] = pair;
     test::OobeJS().ExpectAttributeEQ(
         "open", {kArcTosID, popup_html_element_id}, false);
     test::OobeJS().ClickOnPath({kArcTosID, html_element_id});
diff --git a/chrome/browser/ash/net/traffic_counters_handler.cc b/chrome/browser/ash/net/traffic_counters_handler.cc
new file mode 100644
index 0000000..c811bf0
--- /dev/null
+++ b/chrome/browser/ash/net/traffic_counters_handler.cc
@@ -0,0 +1,228 @@
+// Copyright 2021 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 "chrome/browser/ash/net/traffic_counters_handler.h"
+
+#include <memory>
+#include <string>
+
+#include "ash/public/cpp/network_config_service.h"
+#include "base/values.h"
+#include "chromeos/network/network_event_log.h"
+#include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_metadata_store.h"
+#include "chromeos/services/network_config/public/cpp/cros_network_config_util.h"
+#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
+
+namespace ash {
+
+namespace {
+
+using chromeos::NetworkGuidId;
+
+// Interval duration to determine the auto reset check frequency.
+constexpr base::TimeDelta kResetCheckInterval = base::Hours(6);
+
+base::Time GetValidTime(base::Time::Exploded exploded_time) {
+  base::Time time;
+  while (!base::Time::FromLocalExploded(exploded_time, &time)) {
+    if (exploded_time.day_of_month > 28)
+      --exploded_time.day_of_month;
+    else
+      break;
+  }
+  return time;
+}
+
+// To avoid discrepancies between different times of the same day, set all times
+// to 12:01:00 AM. This is safe to do so because traffic counters will never be
+// automatically reset more than once on any given day.
+void AdjustExplodedTimeValues(base::Time::Exploded* exploded_time) {
+  exploded_time->hour = 0;
+  exploded_time->minute = 1;
+  exploded_time->second = 0;
+  exploded_time->millisecond = 0;
+}
+
+}  // namespace
+
+namespace traffic_counters {
+
+TrafficCountersHandler::TrafficCountersHandler()
+    : time_getter_(base::BindRepeating([]() { return base::Time::Now(); })),
+      timer_(std::make_unique<base::RepeatingTimer>()) {
+  GetNetworkConfigService(
+      remote_cros_network_config_.BindNewPipeAndPassReceiver());
+  remote_cros_network_config_->AddObserver(
+      cros_network_config_observer_receiver_.BindNewPipeAndPassRemote());
+}
+
+TrafficCountersHandler::~TrafficCountersHandler() = default;
+
+void TrafficCountersHandler::Start() {
+  RunAll();
+  timer_->Start(FROM_HERE, kResetCheckInterval, this,
+                &TrafficCountersHandler::RunAll);
+}
+
+void TrafficCountersHandler::RunAll() {
+  RunWithFilter(chromeos::network_config::mojom::FilterType::kAll);
+}
+
+void TrafficCountersHandler::RunWithFilter(
+    chromeos::network_config::mojom::FilterType filter_type) {
+  NET_LOG(EVENT) << "Starting run with filter type " << filter_type
+                 << " at: " << time_getter_.Run();
+  DCHECK(remote_cros_network_config_);
+  remote_cros_network_config_->GetNetworkStateList(
+      chromeos::network_config::mojom::NetworkFilter::New(
+          filter_type, chromeos::network_config::mojom::NetworkType::kAll,
+          chromeos::network_config::mojom::kNoLimit),
+      base::BindOnce(&TrafficCountersHandler::OnNetworkStateListReceived,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void TrafficCountersHandler::OnActiveNetworksChanged(
+    std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
+        active_networks) {
+  RunWithFilter(chromeos::network_config::mojom::FilterType::kActive);
+}
+
+void TrafficCountersHandler::OnNetworkStateListReceived(
+    std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
+        networks) {
+  for (const auto& network : networks) {
+    if (!GetAutoResetEnabled(network->guid)) {
+      continue;
+    }
+    remote_cros_network_config_->GetManagedProperties(
+        network->guid,
+        base::BindOnce(&TrafficCountersHandler::OnManagedPropertiesReceived,
+                       weak_ptr_factory_.GetWeakPtr(), network->guid));
+  }
+}
+
+bool TrafficCountersHandler::GetAutoResetEnabled(std::string guid) {
+  chromeos::NetworkMetadataStore* metadata_store =
+      NetworkHandler::Get()->network_metadata_store();
+  DCHECK(metadata_store);
+  const base::Value* enabled =
+      metadata_store->GetEnableTrafficCountersAutoReset(guid);
+  return enabled && enabled->GetBool();
+}
+
+void TrafficCountersHandler::OnManagedPropertiesReceived(
+    std::string guid,
+    chromeos::network_config::mojom::ManagedPropertiesPtr managed_properties) {
+  if (!managed_properties) {
+    NET_LOG(ERROR) << "Failed to retrive properties for: "
+                   << NetworkGuidId(guid);
+    return;
+  }
+  if (!managed_properties->traffic_counter_properties) {
+    NET_LOG(ERROR) << "Failed to retrieve traffic counter properties for: "
+                   << NetworkGuidId(guid);
+  }
+  bool should_reset;
+  if (!managed_properties->traffic_counter_properties->last_reset_time
+           .has_value()) {
+    // No last reset time, trigger an initial reset.
+    should_reset = true;
+  } else {
+    base::Time last_reset_time = base::Time::FromDeltaSinceWindowsEpoch(
+        managed_properties->traffic_counter_properties->last_reset_time
+            ->ToDeltaSinceWindowsEpoch());
+    should_reset = ShouldReset(guid, last_reset_time);
+  }
+  if (should_reset) {
+    NET_LOG(EVENT) << "Resetting traffic counters for network: "
+                   << NetworkGuidId(guid);
+    remote_cros_network_config_->ResetTrafficCounters(guid);
+  }
+}
+
+// Note that if a user manually resets the traffic counters on the user
+// specified reset day before TrafficCountersHandler runs,
+// TrafficCountersHandler class will not automatically reset the counters until
+// the reset day the following month.
+bool TrafficCountersHandler::ShouldReset(std::string guid,
+                                         base::Time last_reset_time) {
+  chromeos::NetworkMetadataStore* metadata_store =
+      NetworkHandler::Get()->network_metadata_store();
+  DCHECK(metadata_store);
+  const base::Value* reset_day_ptr =
+      metadata_store->GetDayOfTrafficCountersAutoReset(guid);
+  if (!reset_day_ptr) {
+    NET_LOG(ERROR) << "Failed to retrieve auto reset day for network: "
+                   << NetworkGuidId(guid);
+    return false;
+  }
+  auto user_specified_reset_day = reset_day_ptr->GetInt();
+
+  base::Time::Exploded current_time_exploded;
+  time_getter_.Run().LocalExplode(&current_time_exploded);
+  AdjustExplodedTimeValues(&current_time_exploded);
+
+  base::Time::Exploded last_reset_time_exploded;
+  last_reset_time.LocalExplode(&last_reset_time_exploded);
+  AdjustExplodedTimeValues(&last_reset_time_exploded);
+  if (!base::Time::FromLocalExploded(last_reset_time_exploded,
+                                     &last_reset_time)) {
+    NET_LOG(ERROR) << "Failed to set last_reset_time to 12:01:00 AM";
+    return false;
+  }
+
+  bool result = false;
+  base::Time expected_last_reset_time =
+      GetExpectedLastResetTime(current_time_exploded, user_specified_reset_day);
+  if (expected_last_reset_time > last_reset_time) {
+    // If the actual last auto reset occurred before our expected last
+    // auto reset time, traffic counters should be reset.
+    result = true;
+  }
+
+  VLOG(3) << "ShouldReset for: " << guid << " at: " << time_getter_.Run()
+          << " last: " << last_reset_time
+          << " expected_last: " << expected_last_reset_time
+          << " day: " << user_specified_reset_day << " = " << result;
+
+  // expected_last_reset_time.ToDeltaSinceWindowsEpoch() <=
+  // actual_last_reset_time.ToDeltaSinceWindowsEpoch(). Don't reset traffic
+  // counters.
+  return result;
+}
+
+base::Time TrafficCountersHandler::GetExpectedLastResetTime(
+    const base::Time::Exploded& current_time_exploded,
+    int user_specified_reset_day) {
+  base::Time::Exploded exploded = current_time_exploded;
+  exploded.day_of_month = user_specified_reset_day;
+  GetValidTime(exploded).LocalExplode(&exploded);
+
+  // If the user specified reset day is greater than the current day, then the
+  // expected last reset day is on the user specified day of the previous
+  // month. Concretely, if e.g., user_specified_reset_day = 14 and current day
+  // = 13, the last reset day is expected to be on the 14th of the previous
+  // month. Otherwise, we expect that the last reset occurred in the current
+  // month.
+  if (exploded.day_of_month > current_time_exploded.day_of_month) {
+    if (--exploded.month < 1) {
+      exploded.month = 12;
+      exploded.year--;
+    }
+  }
+  return GetValidTime(exploded);
+}
+
+void TrafficCountersHandler::RunForTesting() {
+  RunWithFilter(chromeos::network_config::mojom::FilterType::kAll);
+}
+
+void TrafficCountersHandler::SetTimeGetterForTest(TimeGetter time_getter) {
+  time_getter_ = std::move(time_getter);
+}
+
+}  // namespace traffic_counters
+
+}  // namespace ash
diff --git a/chrome/browser/ash/net/traffic_counters_handler.h b/chrome/browser/ash/net/traffic_counters_handler.h
new file mode 100644
index 0000000..e181ba1
--- /dev/null
+++ b/chrome/browser/ash/net/traffic_counters_handler.h
@@ -0,0 +1,91 @@
+// Copyright 2021 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 CHROME_BROWSER_ASH_NET_TRAFFIC_COUNTERS_HANDLER_H_
+#define CHROME_BROWSER_ASH_NET_TRAFFIC_COUNTERS_HANDLER_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/component_export.h"
+#include "base/memory/weak_ptr.h"
+#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+namespace ash {
+
+namespace traffic_counters {
+
+// TrafficCountersHandler is a singleton, owned by ChromeBrowserMainPartsAsh.
+// This class handles automatically resetting traffic counters in Shill on a
+// date specified by the user. User specified auto reset days that are too
+// large for a given month occur on the last day of that month. For example, if
+// the user specified day was 29, the actual day of reset for the month of
+// February would be February 28th on non-leap years and February 29th on leap
+// years. Similarly, if the user specified day was 31, the actual day of reset
+// for April would be April 30th.
+class COMPONENT_EXPORT(CHROMEOS_NETWORK) TrafficCountersHandler
+    : public chromeos::network_config::mojom::CrosNetworkConfigObserver {
+ public:
+  using TimeGetter = base::RepeatingCallback<base::Time()>;
+
+  TrafficCountersHandler();
+  TrafficCountersHandler(const TrafficCountersHandler&) = delete;
+  TrafficCountersHandler& operator=(const TrafficCountersHandler&) = delete;
+  ~TrafficCountersHandler() override;
+
+  // Runs a check to determine whether traffic counters must be reset and starts
+  // a timer to do so periodically.
+  void Start();
+
+  // CrosNetworkConfigObserver
+  void OnNetworkStateListChanged() override {}
+  void OnDeviceStateListChanged() override {}
+  void OnActiveNetworksChanged(
+      std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
+          active_networks) override;
+  void OnNetworkStateChanged(
+      chromeos::network_config::mojom::NetworkStatePropertiesPtr network_state)
+      override {}
+  void OnVpnProvidersChanged() override {}
+  void OnNetworkCertificatesChanged() override {}
+
+  void SetTimeGetterForTest(TimeGetter time_getter);
+  void RunForTesting();
+
+ private:
+  void RunAll();
+  void RunWithFilter(chromeos::network_config::mojom::FilterType filter_type);
+  void OnNetworkStateListReceived(
+      std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
+          networks);
+  bool GetAutoResetEnabled(std::string guid);
+  void OnManagedPropertiesReceived(
+      std::string guid,
+      chromeos::network_config::mojom::ManagedPropertiesPtr managed_properties);
+  bool ShouldReset(std::string guid, base::Time last_reset_time);
+  base::Time GetExpectedLastResetTime(
+      const base::Time::Exploded& current_time_exploded,
+      int user_specified_reset_day);
+
+  // Callback used to get the time. Mocked out in tests.
+  TimeGetter time_getter_;
+  // Timer used to set the interval at which to run auto reset checks.
+  std::unique_ptr<base::RepeatingTimer> timer_;
+  // Remote for sending requests to the CrosNetworkConfig service.
+  mojo::Remote<chromeos::network_config::mojom::CrosNetworkConfig>
+      remote_cros_network_config_;
+  // Receiver for the CrosNetworkConfigObserver events.
+  mojo::Receiver<chromeos::network_config::mojom::CrosNetworkConfigObserver>
+      cros_network_config_observer_receiver_{this};
+
+  base::WeakPtrFactory<TrafficCountersHandler> weak_ptr_factory_{this};
+};
+
+}  // namespace traffic_counters
+
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_NET_TRAFFIC_COUNTERS_HANDLER_H_
diff --git a/chrome/browser/ash/net/traffic_counters_handler_unittest.cc b/chrome/browser/ash/net/traffic_counters_handler_unittest.cc
new file mode 100644
index 0000000..4bbe879
--- /dev/null
+++ b/chrome/browser/ash/net/traffic_counters_handler_unittest.cc
@@ -0,0 +1,437 @@
+// Copyright 2021 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 <string>
+
+#include "base/bind.h"
+#include "base/test/task_environment.h"
+#include "base/time/clock.h"
+#include "chrome/browser/ash/net/traffic_counters_handler.h"
+#include "chromeos/login/login_state/login_state.h"
+#include "chromeos/network/managed_network_configuration_handler.h"
+#include "chromeos/network/network_configuration_handler.h"
+#include "chromeos/network/network_handler_test_helper.h"
+#include "chromeos/network/network_metadata_store.h"
+#include "chromeos/services/network_config/cros_network_config.h"
+#include "chromeos/services/network_config/in_process_instance.h"
+#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
+
+namespace ash {
+namespace traffic_counters {
+
+namespace {
+
+// TODO(https://crbug.com/1164001): remove when network_config is moved to ash.
+namespace network_config = ::chromeos::network_config;
+
+class TrafficCountersHandlerTest : public ::testing::Test {
+ public:
+  TrafficCountersHandlerTest()
+      : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
+    LoginState::Initialize();
+    helper_ = std::make_unique<NetworkHandlerTestHelper>();
+    helper_->AddDefaultProfiles();
+    helper_->ResetDevicesAndServices();
+    helper_->RegisterPrefs(user_prefs_.registry(), local_state_.registry());
+
+    PrefProxyConfigTrackerImpl::RegisterProfilePrefs(user_prefs_.registry());
+    PrefProxyConfigTrackerImpl::RegisterPrefs(local_state_.registry());
+    helper_->InitializePrefs(&user_prefs_, &local_state_);
+
+    NetworkHandler::Get()->managed_network_configuration_handler()->SetPolicy(
+        ::onc::ONC_SOURCE_DEVICE_POLICY,
+        /*userhash=*/std::string(),
+        /*network_configs_onc=*/base::ListValue(),
+        /*global_network_config=*/base::DictionaryValue());
+
+    cros_network_config_ =
+        std::make_unique<network_config::CrosNetworkConfig>();
+    network_config::OverrideInProcessInstanceForTesting(
+        cros_network_config_.get());
+    task_environment_.RunUntilIdle();
+
+    helper_->service_test()->SetTimeGetterForTest(base::BindRepeating(
+        [](base::test::TaskEnvironment* env) {
+          return env->GetMockClock()->Now();
+        },
+        &task_environment_));
+
+    traffic_counters_handler_ = std::make_unique<TrafficCountersHandler>();
+    traffic_counters_handler_->SetTimeGetterForTest(base::BindRepeating(
+        [](base::test::TaskEnvironment* env) {
+          return env->GetMockClock()->Now();
+        },
+        &task_environment_));
+
+    SetUpWiFi();
+  }
+
+  ~TrafficCountersHandlerTest() override {
+    traffic_counters_handler_.reset();
+    cros_network_config_.reset();
+    helper_.reset();
+    LoginState::Shutdown();
+  }
+
+  base::Time GetTime() { return task_environment_.GetMockClock()->Now(); }
+
+ protected:
+  base::Time SetLastResetTimeAndRun(const std::string& time_str) {
+    base::Time reset_time = GetTimeFromString(time_str);
+    double last_reset_time_ms =
+        reset_time.ToDeltaSinceWindowsEpoch().InMilliseconds();
+    SetServiceProperty(wifi_path_, shill::kTrafficCounterResetTimeProperty,
+                       base::Value(last_reset_time_ms));
+    task_environment_.RunUntilIdle();
+    RunTrafficCountersHandler();
+    return reset_time;
+  }
+
+  base::Time GetLastResetTime() {
+    double traffic_counter_reset_time_ms =
+        helper_
+            ->GetServiceDoubleProperty(wifi_path_,
+                                       shill::kTrafficCounterResetTimeProperty)
+            .value();
+    return base::Time::FromDeltaSinceWindowsEpoch(
+        base::Milliseconds(traffic_counter_reset_time_ms));
+  }
+
+  void SetAutoResetAndDay(bool auto_reset, int user_specified_day) {
+    NetworkHandler::Get()
+        ->network_metadata_store()
+        ->SetEnableTrafficCountersAutoReset(wifi_guid_, auto_reset);
+    NetworkHandler::Get()
+        ->network_metadata_store()
+        ->SetDayOfTrafficCountersAutoReset(wifi_guid_, user_specified_day);
+    task_environment_.RunUntilIdle();
+  }
+
+  base::Time AdvanceClockTo(const std::string& time_str) {
+    base::Time time = GetTimeFromString(time_str);
+    task_environment_.AdvanceClock(
+        time.ToDeltaSinceWindowsEpoch() -
+        task_environment_.GetMockClock()->Now().ToDeltaSinceWindowsEpoch());
+    task_environment_.RunUntilIdle();
+    return task_environment_.GetMockClock()->Now();
+  }
+
+  void RunTrafficCountersHandler() {
+    traffic_counters_handler_->RunForTesting();
+    task_environment_.RunUntilIdle();
+  }
+
+  void FastForwardBy(const base::TimeDelta& days) {
+    task_environment_.FastForwardBy(days);
+  }
+
+  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
+
+  TrafficCountersHandler* traffic_counters_handler() {
+    return traffic_counters_handler_.get();
+  }
+
+  const std::string& wifi_guid() const { return wifi_guid_; }
+
+ private:
+  void SetUpWiFi() {
+    ASSERT_TRUE(wifi_path_.empty());
+    // By default, NetworkStateTestHelper already adds a WiFi device, so, we
+    // do not need to add one here. All that remains to be done is configuring
+    // the WiFi service.
+    wifi_guid_ = "wifi_guid";
+    wifi_path_ = helper_->ConfigureService(
+        R"({"GUID": "wifi_guid", "Type": "wifi", "State": "idle",
+            "SSID": "wifi", "Strength": 100, "AutoConnect": true,
+            "WiFi.HiddenSSID": false,
+            "TrafficCounterResetTime": 0})");
+    SetServiceProperty(wifi_path_, shill::kStateProperty,
+                       base::Value(shill::kStateOnline));
+    helper_->profile_test()->AddService(
+        NetworkProfileHandler::GetSharedProfilePath(), wifi_path_);
+    NetworkHandler::Get()
+        ->network_metadata_store()
+        ->SetEnableTrafficCountersAutoReset(wifi_guid_, false);
+    task_environment_.RunUntilIdle();
+  }
+
+  base::Time GetTimeFromString(const std::string& time_str) {
+    base::Time time;
+    EXPECT_TRUE(base::Time::FromString(time_str.c_str(), &time));
+    return time;
+  }
+
+  void SetServiceProperty(const std::string& service_path,
+                          const std::string& key,
+                          const base::Value& value) {
+    helper_->SetServiceProperty(service_path, key, value);
+  }
+
+  // Member order declaration done in a way so that members outlive those that
+  // are dependent on them.
+  base::test::TaskEnvironment task_environment_;
+  base::RunLoop run_loop_;
+  std::unique_ptr<NetworkHandlerTestHelper> helper_;
+  std::unique_ptr<network_config::CrosNetworkConfig> cros_network_config_;
+  sync_preferences::TestingPrefServiceSyncable user_prefs_;
+  TestingPrefServiceSimple local_state_;
+  std::string wifi_path_;
+  std::string wifi_guid_;
+  std::unique_ptr<TrafficCountersHandler> traffic_counters_handler_;
+};
+
+}  // namespace
+
+TEST_F(TrafficCountersHandlerTest, GetLastResetTime) {
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), base::Time());
+
+  base::Time reset_time =
+      SetLastResetTimeAndRun("Fri, 15 December 2023 10:00:00 UTC");
+  EXPECT_EQ(GetLastResetTime(), reset_time);
+}
+
+TEST_F(TrafficCountersHandlerTest, SetMetadata) {
+  RunTrafficCountersHandler();
+  const base::Value* enabled =
+      NetworkHandler::Get()
+          ->network_metadata_store()
+          ->GetEnableTrafficCountersAutoReset(wifi_guid());
+  ASSERT_TRUE(enabled && enabled->is_bool());
+  EXPECT_FALSE(enabled->GetBool());
+
+  NetworkHandler::Get()
+      ->network_metadata_store()
+      ->SetEnableTrafficCountersAutoReset(wifi_guid(), true);
+  RunUntilIdle();
+  enabled = NetworkHandler::Get()
+                ->network_metadata_store()
+                ->GetEnableTrafficCountersAutoReset(wifi_guid());
+  ASSERT_TRUE(enabled && enabled->is_bool());
+  EXPECT_TRUE(enabled->GetBool());
+
+  NetworkHandler::Get()
+      ->network_metadata_store()
+      ->SetDayOfTrafficCountersAutoReset(wifi_guid(), 13);
+  RunUntilIdle();
+  const base::Value* reset_day_value =
+      NetworkHandler::Get()
+          ->network_metadata_store()
+          ->GetDayOfTrafficCountersAutoReset(wifi_guid());
+  ASSERT_TRUE(reset_day_value && reset_day_value->is_int());
+  EXPECT_EQ(reset_day_value->GetInt(), 13);
+}
+
+TEST_F(TrafficCountersHandlerTest, AutoReset) {
+  base::Time reset_time =
+      SetLastResetTimeAndRun("Fri, 15 December 2023 10:00:00 UTC");
+  EXPECT_EQ(GetLastResetTime(), reset_time);
+
+  SetAutoResetAndDay(true, 1);
+
+  // Advance the clock to Jan 1st, 2024. The counters should get reset.
+  base::Time simulated_time1 =
+      AdvanceClockTo("Mon, 1 January 2024 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time1);
+
+  // Fast forwarding the date by 15 days to Jan 16th should not affect the
+  // last reset time.
+  FastForwardBy(base::Days(15));
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time1);
+
+  // Setting AutoReset to false should prevent auto reset.
+  SetAutoResetAndDay(false, 1);
+  base::Time simulated_time2 =
+      AdvanceClockTo("Fri, 15 March 2024 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time1);
+
+  // Setting AutoReset back to true should auto reset.
+  SetAutoResetAndDay(true, 1);
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time2);
+
+  // Fast forwarding the date by 40 days should auto reset.
+  FastForwardBy(base::Days(40));
+  RunTrafficCountersHandler();
+  EXPECT_GT(GetLastResetTime(), simulated_time2);
+}
+
+TEST_F(TrafficCountersHandlerTest, AutoResetEndOfMonth) {
+  SetLastResetTimeAndRun("Fri, 1 March 2024 07:01:00 UTC");
+  SetAutoResetAndDay(true, 15);
+
+  // Adjust the user specified day to the 15th and ensure that a reset occurs
+  // on March 15th.
+  base::Time simulated_time = AdvanceClockTo("Fri, 15 March 2024 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // Adjust the user specified day to the 14th and fast forward by 1 day to Mar
+  // 16th. Ensure that no reset occurs on March 16th.
+  SetAutoResetAndDay(true, 14);
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+  FastForwardBy(base::Days(1));
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // Adjust the user specified day to the 31st and Fast forward to Mar 31st.
+  // Ensure that a reset occurs.
+  SetAutoResetAndDay(true, 31);
+  simulated_time = AdvanceClockTo("Sun, 31 March 2024 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // Advance the clock to Apr 30th and ensure auto reset occurs on April
+  // 30th since April 31st does not exist.
+  simulated_time = AdvanceClockTo("Tue, 30 Apr 2024 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+  // Fast forward by 1 day to May 1st and ensure no auto reset occurs.
+  FastForwardBy(base::Days(1));
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // Advance the clock to May 31st and ensure reset occurs.
+  simulated_time = AdvanceClockTo("Fri, 31 May 2024 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+}
+
+TEST_F(TrafficCountersHandlerTest, AutoResetLeapYear) {
+  SetLastResetTimeAndRun("Fri, 15 December 2023 10:00:00 UTC");
+  SetAutoResetAndDay(true, 1);
+
+  base::Time simulated_time =
+      AdvanceClockTo("Mon, 1 January 2024 07:01:00 UTC");
+  RunTrafficCountersHandler();
+
+  // The first traffic counters reset is expected on Jan 1st.
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // Fast forwarding the date by 15 days to Jan 16th should not affect the
+  // last reset time.
+  FastForwardBy(base::Days(15));
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // Fast forwarding the date to Feb 1st should update the last reset time.
+  simulated_time = AdvanceClockTo("Thu, 1 February 2024 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // After fast forwarding the date by 28 days to Feb 29th, ensure February
+  // 29th on leap years does not reset traffic counters when the user specified
+  // day is the 1st.
+  FastForwardBy(base::Days(28));
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // After fast forwarding the date to Mar 1st, ensure that two auto
+  // traffic counter resets do not occur on the same day.
+  // First, ensure traffic counters are reset on March 1st.
+  simulated_time = AdvanceClockTo("Fri, 1 March 2024 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+  // Second, run TrafficCountersHandler later on Mar 1st to ensure
+  // that another reset doesn't occur.
+  FastForwardBy(base::Hours(12));
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+}
+
+TEST_F(TrafficCountersHandlerTest, NoLeapYear) {
+  SetLastResetTimeAndRun("Sat, 15 January 2023 10:00:00 UTC");
+  SetAutoResetAndDay(true, 31);
+
+  // Adjust the clock to set the "current time". Use Jan 31st, 2023
+  // to test whether the functionality is correct on non-leap years.
+  base::Time simulated_time =
+      AdvanceClockTo("Tue, 31 January 2023 07:01:00 UTC");
+  RunTrafficCountersHandler();
+
+  // The first traffic counters reset is expected on Jan 31st.
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // After fast forwarding the date to Feb 28th, ensure traffic
+  // counters are reset on February 28th on non-leap years when the user
+  // specified day is the 31st.
+  simulated_time = AdvanceClockTo("Tue, 28 February 2023 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // After fast forwarding the date by 1 day to Mar 1st, ensure traffic
+  // counters are not reset again.
+  FastForwardBy(base::Days(1));
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // After fast forwarding the date by 27 days to March 28th, ensure a
+  // traffic counter reset has not occurred.
+  FastForwardBy(base::Days(27));
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // After fast forwarding by 2 days to March 30th, ensure a traffic counter
+  // reset has not occurred.
+  FastForwardBy(base::Days(2));
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // After fast forwarding the date by 1 day to March 31st, ensure a traffic
+  // counter reset occurs.
+  simulated_time = AdvanceClockTo("Fri, 31 March 2023 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+}
+
+TEST_F(TrafficCountersHandlerTest, ChangeUserSpecifiedDate) {
+  SetAutoResetAndDay(true, 31);
+  SetLastResetTimeAndRun("Sat, 15 January 2023 10:00:00 UTC");
+
+  // Advancing the date to Jan 31st should reset the traffic counters.
+  base::Time simulated_time =
+      AdvanceClockTo("Tue, 31 January 2023 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+
+  // Change user specified auto reset day.
+  SetAutoResetAndDay(true, 5);
+  RunTrafficCountersHandler();
+
+  // After fast forwarding the date to February 5th, ensure traffic counters are
+  // reset.
+  simulated_time = AdvanceClockTo("Sun, 5 February 2023 07:01:00 UTC");
+  RunTrafficCountersHandler();
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+}
+
+TEST_F(TrafficCountersHandlerTest, AutoResetTimer) {
+  // Start the traffic counters timer.
+  traffic_counters_handler()->Start();
+
+  base::Time reset_time =
+      SetLastResetTimeAndRun("Fri, 15 December 2023 10:00:00 UTC");
+  EXPECT_EQ(GetLastResetTime(), reset_time);
+
+  SetAutoResetAndDay(true, 1);
+
+  // Advance the clock to Jan 2nd, 2024. The timer should run and the counters
+  // should get reset.
+  base::Time simulated_time =
+      AdvanceClockTo("Tue, 2 January 2024 07:01:00 UTC");
+  EXPECT_EQ(GetLastResetTime(), simulated_time);
+}
+
+}  // namespace traffic_counters
+
+}  // namespace ash
diff --git a/chrome/browser/ash/pcie_peripheral/ash_usb_detector.cc b/chrome/browser/ash/pcie_peripheral/ash_usb_detector.cc
index 7093793..624c993f 100644
--- a/chrome/browser/ash/pcie_peripheral/ash_usb_detector.cc
+++ b/chrome/browser/ash/pcie_peripheral/ash_usb_detector.cc
@@ -4,19 +4,29 @@
 
 #include "chrome/browser/ash/pcie_peripheral/ash_usb_detector.h"
 
+#include <memory>
+
+#include "ash/components/fwupd/firmware_update_manager.h"
 #include "ash/components/peripheral_notification/peripheral_notification_manager.h"
 #include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "chromeos/dbus/fwupd/fwupd_client.h"
 #include "content/public/browser/device_service.h"
 
 namespace ash {
 
 namespace {
 static AshUsbDetector* g_ash_usb_detector = nullptr;
+
+constexpr int kRequestUpdatesIntervalInSeconds = 5;
+constexpr int kMaxNumRequestUpdatesRetries = 3;
 }  // namespace
 
 AshUsbDetector::AshUsbDetector() {
   DCHECK(!g_ash_usb_detector);
   g_ash_usb_detector = this;
+  fetch_updates_repeating_timer_ = std::make_unique<base::RepeatingTimer>();
 }
 
 AshUsbDetector::~AshUsbDetector() {
@@ -58,10 +68,28 @@
       guid,
       base::BindOnce(&AshUsbDetector::OnDeviceChecked,
                      weak_ptr_factory_.GetWeakPtr(), std::move(device_info)));
+
+  RequestAllUpdatesWithRepeatDelay();
 }
 
 void AshUsbDetector::OnDeviceRemoved(
-    device::mojom::UsbDeviceInfoPtr device_info) {}
+    device::mojom::UsbDeviceInfoPtr device_info) {
+  RequestAllUpdatesWithRepeatDelay();
+}
+
+void AshUsbDetector::RequestAllUpdatesWithRepeatDelay() {
+  if (!fetch_updates_repeating_timer_->IsRunning()) {
+    num_request_updates_repeats_ = kMaxNumRequestUpdatesRetries;
+    fetch_updates_repeating_timer_->Start(
+        FROM_HERE, base::Seconds(kRequestUpdatesIntervalInSeconds),
+        base::BindRepeating(&AshUsbDetector::RequestUpdates,
+                            base::Unretained(this)));
+  } else {
+    // Request to fetch all updates was a called during a current repeat cycle.
+    // Reset the number of requests back to the default.
+    num_request_updates_repeats_ = kMaxNumRequestUpdatesRetries;
+  }
+}
 
 void AshUsbDetector::OnListAttachedDevices(
     std::vector<device::mojom::UsbDeviceInfoPtr> devices) {
@@ -88,6 +116,22 @@
   ConnectToDeviceManager();
 }
 
+void AshUsbDetector::RequestUpdates() {
+  if (is_testing_) {
+    ++num_request_for_fetch_updates_for_testing_;
+  } else {
+    if (FirmwareUpdateManager::IsInitialized()) {
+      FirmwareUpdateManager::Get()->RequestAllUpdates();
+    }
+  }
+
+  --num_request_updates_repeats_;
+
+  if (num_request_updates_repeats_ == 0) {
+    fetch_updates_repeating_timer_->Stop();
+  }
+}
+
 void AshUsbDetector::SetDeviceManagerForTesting(
     mojo::PendingRemote<device::mojom::UsbDeviceManager> device_manager) {
   DCHECK(!device_manager_) << "device_manager_ was already initialized";
@@ -95,4 +139,8 @@
   is_testing_ = true;
 }
 
+void AshUsbDetector::SetFetchUpdatesTimerForTesting(
+    std::unique_ptr<base::RepeatingTimer> timer) {
+  fetch_updates_repeating_timer_ = std::move(timer);
+}
 }  // namespace ash
diff --git a/chrome/browser/ash/pcie_peripheral/ash_usb_detector.h b/chrome/browser/ash/pcie_peripheral/ash_usb_detector.h
index 2e3b7e52..07b5f5c 100644
--- a/chrome/browser/ash/pcie_peripheral/ash_usb_detector.h
+++ b/chrome/browser/ash/pcie_peripheral/ash_usb_detector.h
@@ -5,7 +5,10 @@
 #ifndef CHROME_BROWSER_ASH_PCIE_PERIPHERAL_ASH_USB_DETECTOR_H_
 #define CHROME_BROWSER_ASH_PCIE_PERIPHERAL_ASH_USB_DETECTOR_H_
 
+#include <memory>
+
 #include "ash/public/cpp/ash_public_export.h"
+#include "base/timer/timer.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -45,16 +48,32 @@
                        bool allowed);
   void OnDeviceManagerConnectionError();
 
+  void RequestAllUpdatesWithRepeatDelay();
+  void RequestUpdates();
+
   void SetDeviceManagerForTesting(
       mojo::PendingRemote<device::mojom::UsbDeviceManager> device_manager);
 
+  void SetFetchUpdatesTimerForTesting(
+      std::unique_ptr<base::RepeatingTimer> timer);
+
+  void SetIsTesting(bool is_testing) { is_testing_ = is_testing; }
+
+  int num_request_for_fetch_updates_for_testing() {
+    return num_request_for_fetch_updates_for_testing_;
+  }
+
   mojo::Remote<device::mojom::UsbDeviceManager> device_manager_;
   mojo::AssociatedReceiver<device::mojom::UsbDeviceManagerClient>
       client_receiver_{this};
 
   int32_t on_device_checked_counter_for_testing_ = 0;
+  int32_t num_request_for_fetch_updates_for_testing_ = 0;
   bool is_testing_ = false;
 
+  int num_request_updates_repeats_;
+  std::unique_ptr<base::RepeatingTimer> fetch_updates_repeating_timer_;
+
   // WeakPtrFactory to use for callbacks.
   base::WeakPtrFactory<AshUsbDetector> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/ash/pcie_peripheral/ash_usb_detector_unittest.cc b/chrome/browser/ash/pcie_peripheral/ash_usb_detector_unittest.cc
index 2f95ea7..fe5fee9 100644
--- a/chrome/browser/ash/pcie_peripheral/ash_usb_detector_unittest.cc
+++ b/chrome/browser/ash/pcie_peripheral/ash_usb_detector_unittest.cc
@@ -4,7 +4,12 @@
 
 #include "chrome/browser/ash/pcie_peripheral/ash_usb_detector.h"
 
+#include <memory>
+
+#include "ash/components/fwupd/firmware_update_manager.h"
 #include "ash/components/peripheral_notification/peripheral_notification_manager.h"
+#include "base/timer/mock_timer.h"
+#include "base/timer/timer.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chromeos/dbus/pciguard/pciguard_client.h"
 #include "chromeos/dbus/typecd/typecd_client.h"
@@ -48,6 +53,9 @@
   void TearDown() override {
     BrowserWithTestWindowTest::TearDown();
     ash_usb_detector_.reset();
+    PeripheralNotificationManager::Shutdown();
+    chromeos::PciguardClient::Shutdown();
+    chromeos::TypecdClient::Shutdown();
   }
 
   void ConnectToDeviceManager() {
@@ -58,6 +66,17 @@
     return ash_usb_detector_->GetOnDeviceCheckedCountForTesting();
   }
 
+  int32_t GetNumRequestForUpdates() {
+    return ash_usb_detector_->num_request_for_fetch_updates_for_testing();
+  }
+
+  void SetIsTesting() { ash_usb_detector_->SetIsTesting(/*is_testing=*/true); }
+
+  void SetFetchUpdatesTimerForTesting(
+      std::unique_ptr<base::RepeatingTimer> timer) {
+    ash_usb_detector_->SetFetchUpdatesTimerForTesting(std::move(timer));
+  }
+
   device::FakeUsbDeviceManager device_manager_;
   std::unique_ptr<AshUsbDetector> ash_usb_detector_;
 };
@@ -76,4 +95,81 @@
   EXPECT_EQ(1, GetOnDeviceCheckedCount());
 }
 
+TEST_F(AshUsbDetectorTest, RepeatRequestUpdates) {
+  SetIsTesting();
+  ConnectToDeviceManager();
+  base::RunLoop().RunUntilIdle();
+
+  // Set up mock timer.
+  auto timer = std::make_unique<base::MockRepeatingTimer>();
+  auto* timer_ptr = timer.get();
+  SetFetchUpdatesTimerForTesting(std::move(timer));
+
+  // Add a device.
+  auto device = base::MakeRefCounted<device::FakeUsbDeviceInfo>(
+      /*vendor_id=*/0, /*product_id=*/1, kManufacturerName, kProductName_1,
+      /*serial_number=*/"002");
+
+  device_manager_.AddDevice(device);
+  base::RunLoop().RunUntilIdle();
+
+  // Continue the timer to first iteration.
+  timer_ptr->Fire();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, GetNumRequestForUpdates());
+
+  // Continue the timer to next iteration.
+  timer_ptr->Fire();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(2, GetNumRequestForUpdates());
+
+  // Continue the timer to next iteration.
+  timer_ptr->Fire();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(3, GetNumRequestForUpdates());
+}
+
+TEST_F(AshUsbDetectorTest, RepeatRequestUpdatesWithInterrupts) {
+  SetIsTesting();
+  ConnectToDeviceManager();
+  base::RunLoop().RunUntilIdle();
+
+  // Set up mock timer.
+  auto timer = std::make_unique<base::MockRepeatingTimer>();
+  auto* timer_ptr = timer.get();
+  SetFetchUpdatesTimerForTesting(std::move(timer));
+
+  // Add a device.
+  auto device = base::MakeRefCounted<device::FakeUsbDeviceInfo>(
+      /*vendor_id=*/0, /*product_id=*/1, kManufacturerName, kProductName_1,
+      /*serial_number=*/"002");
+
+  device_manager_.AddDevice(device);
+  base::RunLoop().RunUntilIdle();
+
+  timer_ptr->Fire();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, GetNumRequestForUpdates());
+
+  timer_ptr->Fire();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(2, GetNumRequestForUpdates());
+
+  // Now simulate removing a device. This will reset the repeat counter, expect
+  // 3 more repeats.
+  device_manager_.RemoveDevice(device);
+  base::RunLoop().RunUntilIdle();
+
+  timer_ptr->Fire();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(3, GetNumRequestForUpdates());
+
+  timer_ptr->Fire();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(4, GetNumRequestForUpdates());
+
+  timer_ptr->Fire();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(5, GetNumRequestForUpdates());
+}
 }  // namespace ash
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc
index cee5f6af..9bf2bde 100644
--- a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc
+++ b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc
@@ -135,11 +135,11 @@
   syslog_uploader_.reset();
   status_uploader_.reset();
   managed_session_service_.reset();
+  euicc_status_uploader_.reset();
   external_data_manager_->Disconnect();
   state_keys_update_subscription_ = {};
   CloudPolicyManager::Shutdown();
   signin_profile_forwarding_schema_registry_.reset();
-  euicc_status_uploader_.reset();
 }
 
 // static
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc b/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc
index 7ba8574..243e255 100644
--- a/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc
@@ -298,10 +298,7 @@
                         DlpRulesManager::Component::kDrive)));
 
 TEST_P(DlpFilesExternalDestinationTest, GetDisallowedTransfers_Component) {
-  std::string mount_name;
-  std::string path;
-  DlpRulesManager::Component expected_component;
-  std::tie(mount_name, path, expected_component) = GetParam();
+  auto [mount_name, path, expected_component] = GetParam();
 
   AddFilesToDlpClient();
 
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.cc b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
index 6eb8db4e..e8abe8e 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
@@ -801,6 +801,9 @@
   }
 
   void OnVolumeInfoReceived(const std::vector<em::VolumeInfo>& volume_info) {
+    if (!volume_info.empty()) {
+      SetDeviceStatusReported();
+    }
     response_params_.device_status->clear_volume_infos();
     for (const em::VolumeInfo& info : volume_info)
       *response_params_.device_status->add_volume_infos() = info;
@@ -815,6 +818,9 @@
     DLOG_IF(WARNING, cpu_temp_info.empty())
         << "Unable to read CPU temp information.";
     base::Time timestamp = base::Time::Now();
+    if (!cpu_temp_info.empty()) {
+      SetDeviceStatusReported();
+    }
     for (const em::CPUTempInfo& info : cpu_temp_info) {
       auto* new_info = response_params_.device_status->add_cpu_temp_infos();
       *new_info = info;
@@ -1495,6 +1501,7 @@
         response_params_.device_status->mutable_storage_status()
             ->mutable_lifetime_estimation();
     state->CopyFrom(est);
+    SetDeviceStatusReported();
   }
 
   void OnStatefulPartitionInfoReceived(const em::StatefulPartitionInfo& hdsi) {
@@ -1505,6 +1512,7 @@
     DCHECK_GE(hdsi.available_space(), 0);
     DCHECK_GE(hdsi.total_space(), hdsi.available_space());
     stateful_partition_info->CopyFrom(hdsi);
+    SetDeviceStatusReported();
   }
 
   void OnGraphicsStatusReceived(const em::GraphicsStatus& gs) {
@@ -1677,8 +1685,7 @@
   stats_reporting_pref_subscription_ =
       cros_settings_->AddSettingsObserver(ash::kStatsReportingPref, callback);
 
-  // TODO(b/191986061):: consider using ScopedObservation instead.
-  power_manager_->AddObserver(this);
+  power_manager_observation_.Observe(power_manager_);
 
   // Fetch the current values of the policies.
   UpdateReportingSettings();
@@ -1730,9 +1737,7 @@
           DeviceStatusCollector::GraphicsStatusFetcher(),
           DeviceStatusCollector::CrashReportInfoFetcher()) {}
 
-DeviceStatusCollector::~DeviceStatusCollector() {
-  power_manager_->RemoveObserver(this);
-}
+DeviceStatusCollector::~DeviceStatusCollector() = default;
 
 // static
 constexpr base::TimeDelta DeviceStatusCollector::kIdlePollInterval;
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.h b/chrome/browser/ash/policy/status_collector/device_status_collector.h
index f0d363f..e4392bd 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector.h
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector.h
@@ -18,6 +18,7 @@
 #include "base/containers/circular_deque.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "base/scoped_observation.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/default_clock.h"
@@ -415,6 +416,10 @@
   // Power manager client. Used to listen to power changed events.
   chromeos::PowerManagerClient* const power_manager_;
 
+  base::ScopedObservation<chromeos::PowerManagerClient,
+                          chromeos::PowerManagerClient::Observer>
+      power_manager_observation_{this};
+
   // The most recent CPU readings.
   uint64_t last_cpu_active_ = 0;
   uint64_t last_cpu_idle_ = 0;
diff --git a/chrome/browser/ash/policy/uploading/upload_job_impl.cc b/chrome/browser/ash/policy/uploading/upload_job_impl.cc
index 0d8545a..c3f4561 100644
--- a/chrome/browser/ash/policy/uploading/upload_job_impl.cc
+++ b/chrome/browser/ash/policy/uploading/upload_job_impl.cc
@@ -12,7 +12,6 @@
 
 #include "base/bind.h"
 #include "base/location.h"
-#include "base/metrics/histogram_macros.h"
 #include "base/strings/stringprintf.h"
 #include "base/syslog_logging.h"
 #include "base/task/sequenced_task_runner.h"
@@ -36,7 +35,7 @@
 // Value the "Content-Type" field will be set to in the POST request.
 const char kUploadContentType[] = "multipart/form-data";
 
-// Number of upload attempts. Should not exceed 10 because of the histogram.
+// Number of upload attempts.
 const int kMaxAttempts = 4;
 
 // Max size of MIME boundary according to RFC 1341, section 7.2.1.
@@ -45,9 +44,6 @@
 // Delay after each unsuccessful upload attempt.
 long g_retry_delay_ms = 25000;
 
-// Name of the UploadJobSuccess UMA histogram.
-const char kUploadJobSuccessHistogram[] = "Enterprise.UploadJobSuccess";
-
 }  // namespace
 
 UploadJobImpl::Delegate::~Delegate() {}
@@ -128,22 +124,6 @@
   return data_->size();
 }
 
-// Used in the Enterprise.UploadJobSuccess histogram, shows how many retries
-// we had to do to execute the UploadJob.
-enum UploadJobSuccess {
-  // No retries happened, the upload succeeded for the first try.
-  REQUEST_NO_RETRY = 0,
-
-  // 1..kMaxAttempts-1: number of retries
-
-  // The request failed (too many retries).
-  REQUEST_FAILED = 10,
-  // The request was interrupted.
-  REQUEST_INTERRUPTED,
-
-  REQUEST_MAX
-};
-
 std::string UploadJobImpl::RandomMimeBoundaryGenerator::GenerateBoundary()
     const {
   return net::GenerateMimeMultipartBoundary();
@@ -182,9 +162,6 @@
 UploadJobImpl::~UploadJobImpl() {
   if (state_ != ERROR && state_ != SUCCESS) {
     SYSLOG(ERROR) << "Upload job interrupted.";
-    UMA_HISTOGRAM_ENUMERATION(kUploadJobSuccessHistogram,
-                              UploadJobSuccess::REQUEST_INTERRUPTED,
-                              UploadJobSuccess::REQUEST_MAX);
   }
 }
 
@@ -373,9 +350,6 @@
     access_token_.clear();
     post_data_.reset();
     state_ = ERROR;
-    UMA_HISTOGRAM_ENUMERATION(kUploadJobSuccessHistogram,
-                              UploadJobSuccess::REQUEST_FAILED,
-                              UploadJobSuccess::REQUEST_MAX);
     delegate_->OnFailure(error_code);
   } else {
     if (error_code == AUTHENTICATION_ERROR) {
@@ -418,8 +392,6 @@
     access_token_.clear();
     post_data_.reset();
     state_ = SUCCESS;
-    UMA_HISTOGRAM_EXACT_LINEAR(kUploadJobSuccessHistogram, retry_,
-                               static_cast<int>(UploadJobSuccess::REQUEST_MAX));
     delegate_->OnSuccess();
   } else if (headers->response_code() == net::HTTP_UNAUTHORIZED) {
     SYSLOG(ERROR) << "Unauthorized request.";
diff --git a/chrome/browser/ash/power/ml/smart_dim/download_worker.cc b/chrome/browser/ash/power/ml/smart_dim/download_worker.cc
index a2685ed..0c8a2b76 100644
--- a/chrome/browser/ash/power/ml/smart_dim/download_worker.cc
+++ b/chrome/browser/ash/power/ml/smart_dim/download_worker.cc
@@ -65,8 +65,7 @@
     const ComponentFileContents& contents) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  std::string metadata_json, preprocessor_proto, model_flatbuffer;
-  std::tie(metadata_json, preprocessor_proto, model_flatbuffer) = contents;
+  auto [metadata_json, preprocessor_proto, model_flatbuffer] = contents;
 
   preprocessor_config_ =
       std::make_unique<assist_ranker::ExamplePreprocessorConfig>();
diff --git a/chrome/browser/ash/power/smart_charging/smart_charging_manager_unittest.cc b/chrome/browser/ash/power/smart_charging/smart_charging_manager_unittest.cc
index c72f77a..6ff98f1 100644
--- a/chrome/browser/ash/power/smart_charging/smart_charging_manager_unittest.cc
+++ b/chrome/browser/ash/power/smart_charging/smart_charging_manager_unittest.cc
@@ -342,9 +342,7 @@
   AddEvent(CreateEvent(5, 50, 11, UserChargingEvent::Event::SHUTDOWN));
   AddEvent(CreateEvent(6, 60, 11, UserChargingEvent::Event::PERIODIC_LOG));
 
-  PastEvent plugged_in;
-  PastEvent unplugged;
-  std::tie(plugged_in, unplugged) = GetLastChargeEvents();
+  auto [plugged_in, unplugged] = GetLastChargeEvents();
   EXPECT_FALSE(plugged_in.has_time());
   EXPECT_FALSE(unplugged.has_time());
 }
@@ -379,9 +377,7 @@
   AddEvent(
       CreateEvent(22, 40, 1, UserChargingEvent::Event::CHARGER_PLUGGED_IN));
 
-  PastEvent plugged_in;
-  PastEvent unplugged;
-  std::tie(plugged_in, unplugged) = GetLastChargeEvents();
+  auto [plugged_in, unplugged] = GetLastChargeEvents();
   EXPECT_TRUE(plugged_in.has_time());
   EXPECT_TRUE(unplugged.has_time());
   EXPECT_EQ(plugged_in.time(), 15);
diff --git a/chrome/browser/ash/quick_pair/quick_pair_browser_delegate_impl.cc b/chrome/browser/ash/quick_pair/quick_pair_browser_delegate_impl.cc
index 45ecc1a8..aee3ac6 100644
--- a/chrome/browser/ash/quick_pair/quick_pair_browser_delegate_impl.cc
+++ b/chrome/browser/ash/quick_pair/quick_pair_browser_delegate_impl.cc
@@ -9,8 +9,11 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/notreached.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/image_fetcher/image_decoder_impl.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
+#include "components/image_fetcher/core/image_fetcher.h"
+#include "components/image_fetcher/core/image_fetcher_impl.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/service_process_host.h"
@@ -42,6 +45,20 @@
   return IdentityManagerFactory::GetForProfile(profile);
 }
 
+std::unique_ptr<image_fetcher::ImageFetcher>
+QuickPairBrowserDelegateImpl::GetImageFetcher() {
+  scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory =
+      GetURLLoaderFactory();
+  if (!shared_url_loader_factory) {
+    QP_LOG(WARNING)
+        << "No URL loader factory to provide an image fetcher instance.";
+    return nullptr;
+  }
+
+  return std::make_unique<image_fetcher::ImageFetcherImpl>(
+      std::make_unique<ImageDecoderImpl>(), shared_url_loader_factory);
+}
+
 PrefService* QuickPairBrowserDelegateImpl::GetActivePrefService() {
   Profile* profile = GetActiveProfile();
   if (!profile) {
diff --git a/chrome/browser/ash/quick_pair/quick_pair_browser_delegate_impl.h b/chrome/browser/ash/quick_pair/quick_pair_browser_delegate_impl.h
index 681f55b..2c7ba85e 100644
--- a/chrome/browser/ash/quick_pair/quick_pair_browser_delegate_impl.h
+++ b/chrome/browser/ash/quick_pair/quick_pair_browser_delegate_impl.h
@@ -31,6 +31,7 @@
   // QuickPairBrowserDelegate:
   scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
   signin::IdentityManager* GetIdentityManager() override;
+  std::unique_ptr<image_fetcher::ImageFetcher> GetImageFetcher() override;
   PrefService* GetActivePrefService() override;
   void RequestService(
       mojo::PendingReceiver<mojom::QuickPairService> receiver) override;
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl.cc
index 78e2513..b0fbba0 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl.cc
@@ -101,6 +101,13 @@
   user_image_manager->SaveUserDefaultImageIndex(index);
 }
 
+void PersonalizationAppUserProviderImpl::SelectProfileImage() {
+  ash::UserImageManager* user_image_manager =
+      ash::ChromeUserManager::Get()->GetUserImageManager(
+          GetAccountId(profile_));
+  user_image_manager->SaveUserImageFromProfileImage();
+}
+
 void PersonalizationAppUserProviderImpl::OnUserImageChanged(
     const user_manager::User& user) {
   const user_manager::User* desired_user = GetUser(profile_);
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl.h b/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl.h
index 1c22fb2..ce799747 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl.h
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl.h
@@ -48,6 +48,8 @@
 
   void SelectDefaultImage(int index) override;
 
+  void SelectProfileImage() override;
+
   // user_manager::UserManager::Observer:
   void OnUserImageChanged(const user_manager::User& user) override;
 
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl_unittest.cc
index 4eb91d2b..7b851252 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl_unittest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_user_provider_impl_unittest.cc
@@ -252,3 +252,13 @@
   EXPECT_EQ(GURL(webui::GetBitmapDataUrl(*profile_image.bitmap())),
             current_profile_image());
 }
+
+TEST_F(PersonalizationAppUserProviderImplTest, SelectProfileImage) {
+  SetUserImageObserver();
+
+  const gfx::ImageSkia& profile_image = CreateImage(50, 50);
+  user_image_manager()->SetDownloadedProfileImageForTesting(profile_image);
+  user_provider_remote()->get()->SelectProfileImage();
+  EXPECT_EQ(GURL(webui::GetBitmapDataUrl(*profile_image.bitmap())),
+            current_profile_image());
+}
diff --git a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc
index 8423bf9..cb1e8156 100644
--- a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc
+++ b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc
@@ -7,7 +7,6 @@
 #include <memory>
 
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
 #include "chrome/browser/net/system_network_context_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/network_service_instance.h"
@@ -128,13 +127,7 @@
 void WilcoDtcSupportdNetworkContextImpl::OnDataUseUpdate(
     int32_t network_traffic_annotation_id_hash,
     int64_t recv_bytes,
-    int64_t sent_bytes) {
-  if (auto* data_use =
-          data_use_measurement::ChromeDataUseMeasurement::GetInstance()) {
-    data_use->ReportNetworkServiceDataUse(network_traffic_annotation_id_hash,
-                                          recv_bytes, sent_bytes);
-  }
-}
+    int64_t sent_bytes) {}
 
 void WilcoDtcSupportdNetworkContextImpl::Clone(
     mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver>
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc
index 2832177a..e127d58 100644
--- a/chrome/browser/bookmarks/bookmark_html_writer.cc
+++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
@@ -185,7 +185,7 @@
     DCHECK(roots);
 
     base::Value* root_folder_value =
-        roots->FindDictKey(BookmarkCodec::kRootFolderNameKey);
+        roots->FindDictKey(BookmarkCodec::kBookmarkBarFolderNameKey);
     base::Value* other_folder_value =
         roots->FindDictKey(BookmarkCodec::kOtherBookmarkFolderNameKey);
     base::Value* mobile_folder_value =
diff --git a/chrome/browser/browsing_data/browsing_data_history_observer_service.cc b/chrome/browser/browsing_data/browsing_data_history_observer_service.cc
index 95c3ddbb..6b8c8a7 100644
--- a/chrome/browser/browsing_data/browsing_data_history_observer_service.cc
+++ b/chrome/browser/browsing_data/browsing_data_history_observer_service.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/browsing_data/browsing_data_history_observer_service.h"
 
+#include <tuple>
+
 #include "base/callback_helpers.h"
 #include "build/build_config.h"
 #include "chrome/browser/browsing_data/navigation_entry_remover.h"
@@ -64,7 +66,7 @@
   if (!keywords_model->loaded()) {
     // TODO(https://crbug.com/1288724): Ignoring the return value here is
     // probably a bug.
-    (void)keywords_model->RegisterOnLoadedCallback(
+    std::ignore = keywords_model->RegisterOnLoadedCallback(
         base::BindOnce(&DeleteTemplateUrlsForTimeRange, keywords_model,
                        delete_begin, delete_end));
     keywords_model->Load();
@@ -79,7 +81,7 @@
   if (!keywords_model->loaded()) {
     // TODO(https://crbug.com/1288724): Ignoring the return value here is
     // probably a bug.
-    (void)keywords_model->RegisterOnLoadedCallback(
+    std::ignore = keywords_model->RegisterOnLoadedCallback(
         base::BindOnce(&DeleteTemplateUrlsForDeletedOrigins, keywords_model,
                        std::move(deleted_origins)));
     keywords_model->Load();
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index 1cd4b2f..d374acc 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -92,7 +92,6 @@
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/crash/core/app/crashpad.h"
 #include "components/custom_handlers/protocol_handler_registry.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
 #include "components/device_event_log/device_event_log.h"
@@ -518,21 +517,6 @@
     customtabs::OriginVerifier::ClearBrowsingData();
 #endif
 
-    data_reduction_proxy::DataReductionProxySettings*
-        data_reduction_proxy_settings =
-            DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
-                profile_);
-    // |data_reduction_proxy_settings| is null if |profile_| is off the record.
-    if (data_reduction_proxy_settings) {
-      data_reduction_proxy::DataReductionProxyService*
-          data_reduction_proxy_service =
-              data_reduction_proxy_settings->data_reduction_proxy_service();
-      if (data_reduction_proxy_service) {
-        data_reduction_proxy_service->compression_stats()
-            ->DeleteBrowsingHistory(delete_begin_, delete_end_);
-      }
-    }
-
     heavy_ad_intervention::HeavyAdService* heavy_ad_service =
         HeavyAdServiceFactory::GetForBrowserContext(profile_);
     if (heavy_ad_service && heavy_ad_service->heavy_ad_blocklist()) {
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index f373dfc5e..e28a62d 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -204,6 +204,7 @@
 #include "ash/webui/help_app_ui/search/search.mojom.h"
 #include "ash/webui/media_app_ui/media_app_ui.h"
 #include "ash/webui/media_app_ui/media_app_ui.mojom.h"
+#include "ash/webui/multidevice_debug/proximity_auth_ui.h"
 #include "ash/webui/personalization_app/mojom/personalization_app.mojom.h"
 #include "ash/webui/personalization_app/personalization_app_ui.h"
 #include "ash/webui/print_management/mojom/printing_manager.mojom.h"
@@ -245,7 +246,6 @@
 #include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h"
 #include "chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom.h"
 #include "chromeos/components/local_search_service/public/mojom/index.mojom.h"
-#include "chromeos/components/multidevice/debug_webui/proximity_auth_ui.h"
 #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
 #include "chromeos/services/cellular_setup/public/mojom/cellular_setup.mojom.h"
 #include "chromeos/services/cellular_setup/public/mojom/esim_manager.mojom.h"
@@ -873,7 +873,7 @@
 
   RegisterWebUIControllerInterfaceBinder<
       chromeos::multidevice_setup::mojom::MultiDeviceSetup, chromeos::OobeUI,
-      chromeos::multidevice::ProximityAuthUI,
+      ash::multidevice::ProximityAuthUI,
       chromeos::multidevice_setup::MultiDeviceSetupDialogUI>(map);
 
   RegisterWebUIControllerInterfaceBinder<
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 127fb76..a42f9c8 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -41,7 +41,6 @@
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
-#include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/device_api/device_service_impl.h"
 #include "chrome/browser/device_api/managed_configuration_service.h"
@@ -461,6 +460,10 @@
 #include "components/crash/content/browser/crash_handler_host_linux.h"
 #endif
 
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+#include "chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.h"
+#endif
+
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || \
     BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/enterprise/connectors/device_trust/navigation_throttle.h"
@@ -4284,6 +4287,12 @@
         &throttles);
   }
 
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+  MaybeAddThrottle(
+      WebAppSettingsNavigationThrottle::MaybeCreateThrottleFor(handle),
+      &throttles);
+#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || \
     BUILDFLAG(IS_CHROMEOS_ASH)
   MaybeAddThrottle(enterprise_connectors::DeviceTrustNavigationThrottle::
@@ -5348,9 +5357,6 @@
     local_state = startup_data_.chrome_feature_list_creator()->local_state();
   }
 
-  if (!data_use_measurement::ChromeDataUseMeasurement::GetInstance())
-    data_use_measurement::ChromeDataUseMeasurement::CreateInstance(local_state);
-
   // Create SystemNetworkContextManager if it has not been created yet. We need
   // to set up global NetworkService state before anything else uses it and this
   // is the first opportunity to initialize SystemNetworkContextManager with the
@@ -5791,11 +5797,6 @@
     int32_t network_traffic_annotation_id_hash,
     int64_t recv_bytes,
     int64_t sent_bytes) {
-  if (data_use_measurement::ChromeDataUseMeasurement::GetInstance()) {
-    data_use_measurement::ChromeDataUseMeasurement::GetInstance()
-        ->ReportNetworkServiceDataUse(network_traffic_annotation_id_hash,
-                                      recv_bytes, sent_bytes);
-  }
 #if !BUILDFLAG(IS_ANDROID)
   task_manager::TaskManagerInterface::UpdateAccumulatedStatsNetworkForRoute(
       render_frame_host_id, recv_bytes, sent_bytes);
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index c99b2ea..3aec949 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -254,6 +254,7 @@
     "//chromeos/dbus/dlp:dlp_proto",
     "//chromeos/dbus/easy_unlock",
     "//chromeos/dbus/federated",
+    "//chromeos/dbus/fwupd",
     "//chromeos/dbus/gnubby",
     "//chromeos/dbus/hermes",
     "//chromeos/dbus/hps",
@@ -2307,6 +2308,8 @@
     "../ash/net/secure_dns_manager.h",
     "../ash/net/system_proxy_manager.cc",
     "../ash/net/system_proxy_manager.h",
+    "../ash/net/traffic_counters_handler.cc",
+    "../ash/net/traffic_counters_handler.h",
     "../ash/network_change_manager_client.cc",
     "../ash/network_change_manager_client.h",
     "../ash/night_light/night_light_client.cc",
@@ -4339,6 +4342,7 @@
     "../ash/net/rollback_network_config/rollback_network_config_unittest.cc",
     "../ash/net/secure_dns_manager_unittest.cc",
     "../ash/net/system_proxy_manager_unittest.cc",
+    "../ash/net/traffic_counters_handler_unittest.cc",
     "../ash/network_change_manager_client_unittest.cc",
     "../ash/night_light/night_light_client_unittest.cc",
     "../ash/note_taking_helper_unittest.cc",
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
index 8b7c838..4c21c19f 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
@@ -528,9 +528,7 @@
 
 TEST_P(DlpControllerVMsTest, Allow) {
   ui::DataTransferEndpoint data_src(url::Origin::Create(GURL(kExample1Url)));
-  absl::optional<ui::EndpointType> endpoint_type;
-  bool do_notify;
-  std::tie(endpoint_type, do_notify) = GetParam();
+  auto [endpoint_type, do_notify] = GetParam();
   ASSERT_TRUE(endpoint_type.has_value());
   ui::DataTransferEndpoint data_dst(endpoint_type.value(), do_notify);
 
@@ -637,9 +635,7 @@
 
 TEST_P(DlpControllerVMsTest, Warn_IsClipboardReadAllowed) {
   ui::DataTransferEndpoint data_src(url::Origin::Create(GURL(kExample1Url)));
-  absl::optional<ui::EndpointType> endpoint_type;
-  bool do_notify;
-  std::tie(endpoint_type, do_notify) = GetParam();
+  auto [endpoint_type, do_notify] = GetParam();
   ASSERT_TRUE(endpoint_type.has_value());
   ui::DataTransferEndpoint data_dst(endpoint_type.value(), do_notify);
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc
index 3ff963e..86744970 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc
@@ -232,8 +232,6 @@
         GetConfidentialRestrictions(web_contents)
             .GetRestrictionLevelAndUrl(DlpContentRestriction::kScreenShare);
     info.confidential_contents.Add(web_contents);
-  } else {
-    NOTREACHED();
   }
   return info;
 }
diff --git a/chrome/browser/component_updater/recovery_improved_component_installer_win.cc b/chrome/browser/component_updater/recovery_improved_component_installer_win.cc
index 156ea6f5..b84a6d4 100644
--- a/chrome/browser/component_updater/recovery_improved_component_installer_win.cc
+++ b/chrome/browser/component_updater/recovery_improved_component_installer_win.cc
@@ -129,10 +129,7 @@
 }
 
 void RecoveryComponentActionHandlerWin::RunElevatedInSTA(Callback callback) {
-  bool succeeded = false;
-  int error_code = 0;
-  int extra_code = 0;
-  std::tie(succeeded, error_code, extra_code) = RunRecoveryCRXElevated(
+  auto [succeeded, error_code, extra_code] = RunRecoveryCRXElevated(
       crx_path(), GetBrowserAppId(), GetBrowserVersion(), session_id());
   main_task_runner()->PostTask(
       FROM_HERE,
diff --git a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchChipView.java b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchChipView.java
index c4bdf22f..15e171e 100644
--- a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchChipView.java
+++ b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchChipView.java
@@ -14,7 +14,7 @@
 import androidx.annotation.Px;
 import androidx.core.view.ViewCompat;
 
-import org.chromium.ui.widget.ChipView;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 
 /**
  * View responsible for showing CSN result items.
diff --git a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinder.java b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinder.java
index 6d2f255..506365b 100644
--- a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinder.java
+++ b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinder.java
@@ -14,11 +14,11 @@
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.browser.continuous_search.ContinuousSearchListProperties.ListItemProperties;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.url_formatter.SchemeDisplay;
 import org.chromium.components.url_formatter.UrlFormatter;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.url.GURL;
 
 /**
diff --git a/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinderTest.java b/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinderTest.java
index bd60568..7c65936 100644
--- a/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinderTest.java
+++ b/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinderTest.java
@@ -40,12 +40,12 @@
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.continuous_search.ContinuousSearchListProperties.ListItemProperties;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.url_formatter.SchemeDisplay;
 import org.chromium.components.url_formatter.UrlFormatter;
 import org.chromium.components.url_formatter.UrlFormatterJni;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.url.GURL;
 import org.chromium.url.JUnitTestGURLs;
 
diff --git a/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.cc b/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.cc
index 3a10a3f..0ba1d3d4 100644
--- a/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.cc
+++ b/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.cc
@@ -11,6 +11,7 @@
 #include "base/base64.h"
 #include "base/bind.h"
 #include "base/cxx17_backports.h"
+#include "base/files/file_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_piece.h"
@@ -19,7 +20,6 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -27,10 +27,7 @@
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/pref_names.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
-#include "components/data_reduction_proxy/core/browser/data_store.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
 #include "components/embedder_support/user_agent_utils.h"
 #include "components/prefs/pref_service.h"
@@ -57,6 +54,13 @@
 constexpr base::FilePath::CharType kLiteVideoOptOutDBFilename[] =
     FILE_PATH_LITERAL("lite_video_opt_out.db");
 
+const base::FilePath::CharType kHostDataUseDBName[] =
+    FILE_PATH_LITERAL("data_reduction_proxy_leveldb");
+
+void DeleteHostDataUseDatabaseOnDBThread(const base::FilePath& database_file) {
+  base::DeleteFile(database_file);
+}
+
 // Deletes Previews opt-out database file. Opt-out database is no longer needed
 // since Previews has been turned down.
 void DeletePreviewsOptOutDatabaseOnDBThread(
@@ -218,7 +222,6 @@
 
 void DataReductionProxyChromeSettings::InitDataReductionProxySettings(
     Profile* profile,
-    std::unique_ptr<data_reduction_proxy::DataStore> store,
     const scoped_refptr<base::SequencedTaskRunner>& db_task_runner) {
   profile_ = profile;
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -237,16 +240,9 @@
       base::BindOnce(DeleteLiteVideosOptOutDatabaseOnDBThread,
                      profile_path.Append(kLiteVideoOptOutDBFilename)));
 
-#if BUILDFLAG(IS_ANDROID)
-  // On mobile we write Data Reduction Proxy prefs directly to the pref service.
-  // On desktop we store Data Reduction Proxy prefs in memory, writing to disk
-  // every 60 minutes and on termination. Shutdown hooks must be added for
-  // Android and iOS in order for non-zero delays to be supported.
-  // (http://crbug.com/408264)
-  base::TimeDelta commit_delay = base::TimeDelta();
-#else
-  base::TimeDelta commit_delay = base::Minutes(60);
-#endif
+  db_task_runner->PostTask(
+      FROM_HERE, base::BindOnce(DeleteHostDataUseDatabaseOnDBThread,
+                                profile_path.Append(kHostDataUseDBName)));
 
   PrefService* profile_prefs = profile->GetPrefs();
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
@@ -254,9 +250,7 @@
           ->GetURLLoaderFactoryForBrowserProcess();
   std::unique_ptr<data_reduction_proxy::DataReductionProxyService> service =
       std::make_unique<data_reduction_proxy::DataReductionProxyService>(
-          this, profile_prefs, std::move(store),
-          data_use_measurement::ChromeDataUseMeasurement::GetInstance(),
-          db_task_runner, commit_delay);
+          this, profile_prefs);
   data_reduction_proxy::DataReductionProxySettings::
       InitDataReductionProxySettings(profile_prefs, std::move(service));
 
diff --git a/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h b/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h
index 4b7b906..10d9e18 100644
--- a/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h
+++ b/chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h
@@ -5,8 +5,6 @@
 #ifndef CHROME_BROWSER_DATA_REDUCTION_PROXY_DATA_REDUCTION_PROXY_CHROME_SETTINGS_H_
 #define CHROME_BROWSER_DATA_REDUCTION_PROXY_DATA_REDUCTION_PROXY_CHROME_SETTINGS_H_
 
-#include <memory>
-
 #include "base/memory/raw_ptr.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -18,10 +16,6 @@
 class SequencedTaskRunner;
 }  // namespace base
 
-namespace data_reduction_proxy {
-class DataStore;
-}  // namespace data_reduction_proxy
-
 class PrefService;
 
 // Data reduction proxy settings class suitable for use with a Chrome browser.
@@ -59,11 +53,9 @@
   // Overrides KeyedService::Shutdown:
   void Shutdown() override;
 
-  // Initialize the settings object with the given profile, data store, and db
-  // task runner.
+  // Initialize the settings object.
   void InitDataReductionProxySettings(
       Profile* profile,
-      std::unique_ptr<data_reduction_proxy::DataStore> store,
       const scoped_refptr<base::SequencedTaskRunner>& db_task_runner);
 
   // Public for testing.
diff --git a/chrome/browser/data_use_measurement/DIR_METADATA b/chrome/browser/data_use_measurement/DIR_METADATA
deleted file mode 100644
index 3c8435d..0000000
--- a/chrome/browser/data_use_measurement/DIR_METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-monorail: {
-  component: "Internals>Network>DataUse"
-}
diff --git a/chrome/browser/data_use_measurement/OWNERS b/chrome/browser/data_use_measurement/OWNERS
deleted file mode 100644
index 2783dea..0000000
--- a/chrome/browser/data_use_measurement/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file://components/data_reduction_proxy/OWNERS
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_measurement.cc b/chrome/browser/data_use_measurement/chrome_data_use_measurement.cc
deleted file mode 100644
index a785699..0000000
--- a/chrome/browser/data_use_measurement/chrome_data_use_measurement.cc
+++ /dev/null
@@ -1,167 +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 "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/task/post_task.h"
-#include "base/task/task_traits.h"
-#include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
-#include "components/metrics/data_use_tracker.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/network_service_instance.h"
-
-using content::BrowserThread;
-
-namespace data_use_measurement {
-
-namespace {
-// Global instance to be used when network service is enabled, this will never
-// be deleted. When network service is disabled, this should always be null.
-ChromeDataUseMeasurement* g_chrome_data_use_measurement = nullptr;
-
-DataUseUserData::DataUseContentType GetContentType(const std::string& mime_type,
-                                                   bool is_main_frame_resource,
-                                                   bool is_app_background,
-                                                   bool is_tab_visible) {
-  if (mime_type == "text/html")
-    return is_main_frame_resource ? DataUseUserData::MAIN_FRAME_HTML
-                                  : DataUseUserData::NON_MAIN_FRAME_HTML;
-  if (mime_type == "text/css")
-    return DataUseUserData::CSS;
-  if (base::StartsWith(mime_type, "image/", base::CompareCase::SENSITIVE))
-    return DataUseUserData::IMAGE;
-  if (base::EndsWith(mime_type, "javascript", base::CompareCase::SENSITIVE) ||
-      base::EndsWith(mime_type, "ecmascript", base::CompareCase::SENSITIVE)) {
-    return DataUseUserData::JAVASCRIPT;
-  }
-  if (mime_type.find("font") != std::string::npos)
-    return DataUseUserData::FONT;
-  if (base::StartsWith(mime_type, "audio/", base::CompareCase::SENSITIVE))
-    return is_app_background
-               ? DataUseUserData::AUDIO_APPBACKGROUND
-               : (!is_tab_visible ? DataUseUserData::AUDIO_TABBACKGROUND
-                                  : DataUseUserData::AUDIO);
-  if (base::StartsWith(mime_type, "video/", base::CompareCase::SENSITIVE))
-    return is_app_background
-               ? DataUseUserData::VIDEO_APPBACKGROUND
-               : (!is_tab_visible ? DataUseUserData::VIDEO_TABBACKGROUND
-                                  : DataUseUserData::VIDEO);
-  return DataUseUserData::OTHER;
-}
-
-}  // namespace
-
-// static
-void ChromeDataUseMeasurement::CreateInstance(PrefService* local_state) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
-         !BrowserThread::IsThreadInitialized(BrowserThread::UI));
-
-  DCHECK(!g_chrome_data_use_measurement);
-
-  g_chrome_data_use_measurement = new ChromeDataUseMeasurement(
-      content::GetNetworkConnectionTracker(), local_state);
-}
-
-// static
-ChromeDataUseMeasurement* ChromeDataUseMeasurement::GetInstance() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
-         !BrowserThread::IsThreadInitialized(BrowserThread::UI));
-
-  return g_chrome_data_use_measurement;
-}
-
-// static
-void ChromeDataUseMeasurement::DeleteInstance() {
-  if (g_chrome_data_use_measurement) {
-    delete g_chrome_data_use_measurement;
-    g_chrome_data_use_measurement = nullptr;
-  }
-}
-
-ChromeDataUseMeasurement::ChromeDataUseMeasurement(
-    network::NetworkConnectionTracker* network_connection_tracker,
-    PrefService* local_state)
-    : DataUseMeasurement(local_state, network_connection_tracker),
-      local_state_(local_state) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void ChromeDataUseMeasurement::ReportNetworkServiceDataUse(
-    int32_t network_traffic_annotation_id_hash,
-    int64_t recv_bytes,
-    int64_t sent_bytes) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // Negative byte numbers is not a critical problem (i.e., should have no
-  // security implications) but is not expected. TODO(rajendrant): remove these
-  // DCHECKs or consider using uint in Mojo instead.
-  DCHECK_GE(recv_bytes, 0);
-  DCHECK_GE(sent_bytes, 0);
-
-  bool is_user_request =
-      DataUseMeasurement::IsUserRequest(network_traffic_annotation_id_hash);
-  bool is_metrics_service_request =
-      IsMetricsServiceRequest(network_traffic_annotation_id_hash);
-  UpdateMetricsUsagePrefs(recv_bytes, IsCurrentNetworkCellular(),
-                          is_metrics_service_request);
-  UpdateMetricsUsagePrefs(sent_bytes, IsCurrentNetworkCellular(),
-                          is_metrics_service_request);
-  if (!is_user_request) {
-    ReportDataUsageServices(network_traffic_annotation_id_hash, UPSTREAM,
-                            CurrentAppState(), sent_bytes);
-    ReportDataUsageServices(network_traffic_annotation_id_hash, DOWNSTREAM,
-                            CurrentAppState(), recv_bytes);
-  }
-  if (!is_user_request || DataUseMeasurement::IsUserDownloadsRequest(
-                              network_traffic_annotation_id_hash)) {
-    for (auto& observer : services_data_use_observer_list_)
-      observer.OnServicesDataUse(network_traffic_annotation_id_hash, recv_bytes,
-                                 sent_bytes);
-  }
-  base::UmaHistogramCustomCounts("DataUse.BytesReceived2.Delegate", recv_bytes,
-                                 50, 10 * 1000 * 1000, 50);
-  UMA_HISTOGRAM_COUNTS_1M("DataUse.BytesSent.Delegate", sent_bytes);
-}
-
-void ChromeDataUseMeasurement::ReportUserTrafficDataUse(bool is_tab_visible,
-                                                        int64_t recv_bytes) {
-  RecordDownstreamUserTrafficSizeMetric(is_tab_visible, recv_bytes);
-}
-
-void ChromeDataUseMeasurement::RecordContentTypeMetric(
-    const std::string& mime_type,
-    bool is_main_frame_resource,
-    bool is_tab_visible,
-    int64_t recv_bytes) {
-  DataUseUserData::DataUseContentType content_type = GetContentType(
-      mime_type, is_main_frame_resource,
-      CurrentAppState() == DataUseUserData::BACKGROUND, is_tab_visible);
-  UMA_HISTOGRAM_SCALED_ENUMERATION("DataUse.ContentType.UserTrafficKB",
-                                   content_type, recv_bytes, 1024);
-}
-
-void ChromeDataUseMeasurement::UpdateMetricsUsagePrefs(
-    int64_t total_bytes,
-    bool is_cellular,
-    bool is_metrics_service_usage) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(local_state_);
-  metrics::DataUseTracker::UpdateMetricsUsagePrefs(
-      base::saturated_cast<int>(total_bytes), is_cellular,
-      is_metrics_service_usage, local_state_);
-}
-
-// static
-void ChromeDataUseMeasurement::RegisterPrefs(PrefRegistrySimple* registry) {
-  DataUseMeasurement::RegisterDataUseComponentLocalStatePrefs(registry);
-}
-
-}  // namespace data_use_measurement
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_measurement.h b/chrome/browser/data_use_measurement/chrome_data_use_measurement.h
deleted file mode 100644
index f8f5d9c8..0000000
--- a/chrome/browser/data_use_measurement/chrome_data_use_measurement.h
+++ /dev/null
@@ -1,57 +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 CHROME_BROWSER_DATA_USE_MEASUREMENT_CHROME_DATA_USE_MEASUREMENT_H_
-#define CHROME_BROWSER_DATA_USE_MEASUREMENT_CHROME_DATA_USE_MEASUREMENT_H_
-
-#include <memory>
-
-#include "base/memory/raw_ptr.h"
-#include "base/sequence_checker.h"
-#include "components/data_use_measurement/core/data_use_measurement.h"
-
-class PrefService;
-
-namespace data_use_measurement {
-
-class ChromeDataUseMeasurement : public DataUseMeasurement {
- public:
-  static void CreateInstance(PrefService* local_state);
-  static ChromeDataUseMeasurement* GetInstance();
-  static void DeleteInstance();
-
-  ChromeDataUseMeasurement(
-      network::NetworkConnectionTracker* network_connection_tracker,
-      PrefService* local_state);
-
-  ChromeDataUseMeasurement(const ChromeDataUseMeasurement&) = delete;
-  ChromeDataUseMeasurement& operator=(const ChromeDataUseMeasurement&) = delete;
-
-  // Called when requests complete from NetworkService. Called for all requests
-  // (including service requests and user-initiated requests).
-  void ReportNetworkServiceDataUse(int32_t network_traffic_annotation_id_hash,
-                                   int64_t recv_bytes,
-                                   int64_t sent_bytes);
-  void ReportUserTrafficDataUse(bool is_tab_visible, int64_t recv_bytes);
-
-  void RecordContentTypeMetric(const std::string& mime_type,
-                               bool is_main_frame_resource,
-                               bool is_tab_visible,
-                               int64_t recv_bytes);
-
-  static void RegisterPrefs(PrefRegistrySimple* registry);
-
- private:
-  void UpdateMetricsUsagePrefs(int64_t total_bytes,
-                               bool is_cellular,
-                               bool is_metrics_service_usage);
-
-  raw_ptr<PrefService> local_state_ = nullptr;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-}  // namespace data_use_measurement
-
-#endif  // CHROME_BROWSER_DATA_USE_MEASUREMENT_CHROME_DATA_USE_MEASUREMENT_H_
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_measurement_browsertest.cc b/chrome/browser/data_use_measurement/chrome_data_use_measurement_browsertest.cc
deleted file mode 100644
index 371b783..0000000
--- a/chrome/browser/data_use_measurement/chrome_data_use_measurement_browsertest.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2020 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 <tuple>
-
-#include "base/bind.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/task/thread_pool/thread_pool_instance.h"
-#include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "components/data_use_measurement/core/data_use_pref_names.h"
-#include "components/prefs/pref_service.h"
-#include "content/public/browser/network_service_instance.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/common/network_service_util.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/browser_test_utils.h"
-#include "content/public/test/content_browser_test.h"
-#include "services/network/public/mojom/network_service_test.mojom.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace data_use_measurement {
-
-class ChromeDataUseMeasurementBrowsertestBase : public InProcessBrowserTest {
- protected:
-  void SetUpOnMainThread() override {
-    embedded_test_server()->ServeFilesFromSourceDirectory(
-        GetChromeTestDataDir());
-    ASSERT_TRUE(embedded_test_server()->Start());
-  }
-
-  void SimulateNetworkChange(network::mojom::ConnectionType type) {
-    if (!content::IsInProcessNetworkService()) {
-      mojo::Remote<network::mojom::NetworkServiceTest> network_service_test;
-      content::GetNetworkService()->BindTestInterface(
-          network_service_test.BindNewPipeAndPassReceiver());
-      base::RunLoop run_loop;
-      network_service_test->SimulateNetworkChange(type, run_loop.QuitClosure());
-      run_loop.Run();
-      return;
-    }
-    net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
-        net::NetworkChangeNotifier::ConnectionType(type));
-  }
-
-  size_t GetCountEntriesUserInitiatedDataUsePrefs() const {
-    return local_state()
-               ->GetDictionary(
-                   data_use_measurement::prefs::kDataUsedUserForeground)
-               ->DictSize() +
-           local_state()
-               ->GetDictionary(
-                   data_use_measurement::prefs::kDataUsedUserBackground)
-               ->DictSize();
-  }
-
-  void RetryUntilUserInitiatedDataUsePrefHasEntry() {
-    do {
-      base::ThreadPoolInstance::Get()->FlushForTesting();
-      base::RunLoop().RunUntilIdle();
-    } while (GetCountEntriesUserInitiatedDataUsePrefs() == 0);
-  }
-
-  PrefService* local_state() const { return g_browser_process->local_state(); }
-
- private:
-};
-
-class ChromeDataUseMeasurementBrowsertest
-    : public ChromeDataUseMeasurementBrowsertestBase {
- public:
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    ChromeDataUseMeasurementBrowsertestBase::SetUpCommandLine(command_line);
-  }
-};
-
-// Flaky on Linux (and Linux MSAN) and ChromeOS: https://crbug.com/1141975.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-#define MAYBE_DataUseTrackerPrefsUpdated DISABLED_DataUseTrackerPrefsUpdated
-#else
-#define MAYBE_DataUseTrackerPrefsUpdated DataUseTrackerPrefsUpdated
-#endif
-
-IN_PROC_BROWSER_TEST_F(ChromeDataUseMeasurementBrowsertest,
-                       MAYBE_DataUseTrackerPrefsUpdated) {
-  SimulateNetworkChange(network::mojom::ConnectionType::CONNECTION_3G);
-
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), embedded_test_server()->GetURL("/title1.html")));
-  RetryUntilUserInitiatedDataUsePrefHasEntry();
-
-  EXPECT_EQ(1u, GetCountEntriesUserInitiatedDataUsePrefs());
-}
-
-}  // namespace data_use_measurement
diff --git a/chrome/browser/downgrade/snapshot_manager.cc b/chrome/browser/downgrade/snapshot_manager.cc
index 2aae5a7..f50e63c4 100644
--- a/chrome/browser/downgrade/snapshot_manager.cc
+++ b/chrome/browser/downgrade/snapshot_manager.cc
@@ -153,32 +153,19 @@
         snapshot_dir, move_target_dir.AppendASCII(version.GetString()));
   }
 
-  size_t success_count = 0;
-  size_t error_count = 0;
-  auto record_success_error = [&success_count, &error_count](
-                                  absl::optional<bool> success,
-                                  SnapshotItemId id) {
-    if (!success.has_value())
-      return;
-    if (success.value()) {
-      ++success_count;
-    } else {
-      ++error_count;
+  auto record_item_failure = [](absl::optional<bool> success,
+                                SnapshotItemId id) {
+    if (!success.value_or(true))
       base::UmaHistogramEnumeration("Downgrade.TakeSnapshot.ItemFailure", id);
-    }
   };
 
   // Abort the snapshot if the snapshot directory could not be created.
-  if (!base::CreateDirectory(snapshot_dir)) {
-    base::UmaHistogramEnumeration(
-        "Downgrade.TakeSnapshot.Result",
-        SnapshotOperationResult::kFailedToCreateSnapshotDirectory);
+  if (!base::CreateDirectory(snapshot_dir))
     return;
-  }
 
   // Copy items to be preserved at the top-level of User Data.
   for (const auto& file : GetUserSnapshotItemDetails()) {
-    record_success_error(
+    record_item_failure(
         CopyItemToSnapshotDirectory(base::FilePath(file.path), user_data_dir_,
                                     snapshot_dir, file.is_directory),
         file.id);
@@ -190,40 +177,24 @@
   for (const auto& profile_dir : GetUserProfileDirectories(user_data_dir_)) {
     // Abort the current profile snapshot if the profile directory could not be
     // created. This succeeds almost all the time.
-    if (!base::CreateDirectory(snapshot_dir.Append(profile_dir))) {
-      ++error_count;
+    if (!base::CreateDirectory(snapshot_dir.Append(profile_dir)))
       continue;
-    }
     for (const auto& file : profile_snapshot_item_details) {
-      record_success_error(CopyItemToSnapshotDirectory(
-                               profile_dir.Append(file.path), user_data_dir_,
-                               snapshot_dir, file.is_directory),
-                           file.id);
+      record_item_failure(CopyItemToSnapshotDirectory(
+                              profile_dir.Append(file.path), user_data_dir_,
+                              snapshot_dir, file.is_directory),
+                          file.id);
     }
   }
 
   // Copy the "Last Version" file to the snapshot directory last since it is the
   // file that determines, by its presence in the snapshot directory, if the
   // snapshot is complete.
-  record_success_error(
+  record_item_failure(
       CopyItemToSnapshotDirectory(base::FilePath(kDowngradeLastVersionFile),
                                   user_data_dir_, snapshot_dir,
                                   /*is_directory=*/false),
       SnapshotItemId::kLastVersion);
-
-  auto snapshot_result = SnapshotOperationResult::kFailure;
-  if (error_count == 0)
-    snapshot_result = SnapshotOperationResult::kSuccess;
-  else if (success_count > 0)
-    snapshot_result = SnapshotOperationResult::kPartialSuccess;
-
-  if (error_count > 0) {
-    base::UmaHistogramExactLinear("Downgrade.TakeSnapshot.FailureCount",
-                                  error_count, 100);
-  }
-
-  base::UmaHistogramEnumeration("Downgrade.TakeSnapshot.Result",
-                                snapshot_result);
 }
 
 void SnapshotManager::RestoreSnapshot(const base::Version& version) {
diff --git a/chrome/browser/download/android/available_offline_content_provider_unittest.cc b/chrome/browser/download/android/available_offline_content_provider_unittest.cc
index 98dfad2..5788b25 100644
--- a/chrome/browser/download/android/available_offline_content_provider_unittest.cc
+++ b/chrome/browser/download/android/available_offline_content_provider_unittest.cc
@@ -167,9 +167,7 @@
 };
 
 TEST_F(AvailableOfflineContentTest, NoContent) {
-  bool list_visible_by_prefs;
-  std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions;
-  std::tie(list_visible_by_prefs, suggestions) = ListAndWait();
+  auto [list_visible_by_prefs, suggestions] = ListAndWait();
 
   EXPECT_TRUE(suggestions.empty());
   EXPECT_TRUE(list_visible_by_prefs);
@@ -184,9 +182,7 @@
                                IncompleteItem(), DangerousItem()});
 
   // Call List().
-  bool list_visible_by_prefs;
-  std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions;
-  std::tie(list_visible_by_prefs, suggestions) = ListAndWait();
+  auto [list_visible_by_prefs, suggestions] = ListAndWait();
 
   // As interesting items are below the minimum to show, nothing should be
   // reported.
@@ -204,9 +200,7 @@
       {{SuggestedOfflinePageItem().id, TestThumbnail()}});
 
   // Call List().
-  bool list_visible_by_prefs;
-  std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions;
-  std::tie(list_visible_by_prefs, suggestions) = ListAndWait();
+  auto [list_visible_by_prefs, suggestions] = ListAndWait();
 
   // Check that the right suggestions have been received in order.
   EXPECT_EQ(3ul, suggestions.size());
@@ -250,9 +244,7 @@
   profile()->GetPrefs()->SetBoolean(feed::prefs::kArticlesListVisible, false);
 
   // Call List().
-  bool list_visible_by_prefs;
-  std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions;
-  std::tie(list_visible_by_prefs, suggestions) = ListAndWait();
+  auto [list_visible_by_prefs, suggestions] = ListAndWait();
 
   // Check that suggestions have been received and the list is not visible.
   EXPECT_EQ(3ul, suggestions.size());
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
index 0e1c0c3..4356b30 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -125,10 +125,6 @@
 #include "components/offline_pages/core/client_namespace_constants.h"
 #endif
 
-#if BUILDFLAG(IS_WIN)
-#include "components/services/quarantine/public/cpp/quarantine_features_win.h"
-#endif
-
 using content::BrowserThread;
 using content::DownloadManager;
 using download::DownloadItem;
@@ -1841,15 +1837,12 @@
 void ChromeDownloadManagerDelegate::ConnectToQuarantineService(
     mojo::PendingReceiver<quarantine::mojom::Quarantine> receiver) {
 #if BUILDFLAG(IS_WIN)
-  if (base::FeatureList::IsEnabled(quarantine::kOutOfProcessQuarantine)) {
-    content::ServiceProcessHost::Launch(
-        std::move(receiver), content::ServiceProcessHost::Options()
-                                 .WithDisplayName("Quarantine Service")
-                                 .Pass());
-    return;
-  }
-#endif
-
+  content::ServiceProcessHost::Launch(std::move(receiver),
+                                      content::ServiceProcessHost::Options()
+                                          .WithDisplayName("Quarantine Service")
+                                          .Pass());
+#else   // !BUILDFLAG(IS_WIN)
   mojo::MakeSelfOwnedReceiver(std::make_unique<quarantine::QuarantineImpl>(),
                               std::move(receiver));
+#endif  // !BUILDFLAG(IS_WIN)
 }
diff --git a/chrome/browser/download/download_frame_policy_browsertest.cc b/chrome/browser/download/download_frame_policy_browsertest.cc
index abdec50..f74c721 100644
--- a/chrome/browser/download/download_frame_policy_browsertest.cc
+++ b/chrome/browser/download/download_frame_policy_browsertest.cc
@@ -290,10 +290,7 @@
 // Download that's initiated from / occurs in the same subframe are handled
 // correctly. This test specifically tests sandbox related behaviors.
 IN_PROC_BROWSER_TEST_P(SubframeSameFrameDownloadBrowserTest_Sandbox, Download) {
-  DownloadSource source;
-  SandboxOption sandbox_option;
-  bool is_cross_origin;
-  std::tie(source, sandbox_option, is_cross_origin) = GetParam();
+  auto [source, sandbox_option, is_cross_origin] = GetParam();
   SCOPED_TRACE(::testing::Message()
                << "source = " << source << ", "
                << "sandbox_option = " << sandbox_option << ", "
@@ -361,13 +358,8 @@
 // Download that's initiated from / occurs in the same subframe are handled
 // correctly. This test specifically tests ad related behaviors.
 IN_PROC_BROWSER_TEST_P(SubframeSameFrameDownloadBrowserTest_AdFrame, Download) {
-  DownloadSource source;
-  bool block_downloads_in_ad_frame_without_user_activation;
-  bool is_ad_frame;
-  bool is_cross_origin;
-  bool initiate_with_gesture;
-  std::tie(source, block_downloads_in_ad_frame_without_user_activation,
-           is_ad_frame, is_cross_origin, initiate_with_gesture) = GetParam();
+  auto [source, block_downloads_in_ad_frame_without_user_activation,
+        is_ad_frame, is_cross_origin, initiate_with_gesture] = GetParam();
   SCOPED_TRACE(::testing::Message()
                << "source = " << source << ", "
                << "is_ad_frame = " << is_ad_frame << ", "
@@ -427,9 +419,7 @@
 // only one frame being sandboxed. Also covers the remote frame navigation path.
 IN_PROC_BROWSER_TEST_P(OtherFrameNavigationDownloadBrowserTest_Sandbox,
                        Download) {
-  bool is_cross_origin;
-  OtherFrameNavigationType other_frame_navigation_type;
-  std::tie(is_cross_origin, other_frame_navigation_type) = GetParam();
+  auto [is_cross_origin, other_frame_navigation_type] = GetParam();
   SCOPED_TRACE(::testing::Message()
                << "is_cross_origin = " << is_cross_origin << ", "
                << "other_frame_navigation_type = "
@@ -498,12 +488,8 @@
 // only one frame being ad. Also covers the remote frame navigation path.
 IN_PROC_BROWSER_TEST_P(OtherFrameNavigationDownloadBrowserTest_AdFrame,
                        Download) {
-  bool block_downloads_in_ad_frame_without_user_activation;
-  bool is_cross_origin;
-  bool initiate_with_gesture;
-  OtherFrameNavigationType other_frame_navigation_type;
-  std::tie(block_downloads_in_ad_frame_without_user_activation, is_cross_origin,
-           initiate_with_gesture, other_frame_navigation_type) = GetParam();
+  auto [block_downloads_in_ad_frame_without_user_activation, is_cross_origin,
+        initiate_with_gesture, other_frame_navigation_type] = GetParam();
   SCOPED_TRACE(::testing::Message()
                << "block_downloads_in_ad_frame_without_user_activation = "
                << block_downloads_in_ad_frame_without_user_activation << ", "
@@ -595,9 +581,7 @@
 // Download that's initiated from / occurs in the same top frame are handled
 // correctly.
 IN_PROC_BROWSER_TEST_P(TopFrameSameFrameDownloadBrowserTest, Download) {
-  DownloadSource source;
-  SandboxOption sandbox_option;
-  std::tie(source, sandbox_option) = GetParam();
+  auto [source, sandbox_option] = GetParam();
   SCOPED_TRACE(::testing::Message()
                << "source = " << source << ", "
                << "sandbox_option = " << sandbox_option);
@@ -649,9 +633,7 @@
 IN_PROC_BROWSER_TEST_P(
     DownloadFramePolicyBrowserTest_UpdateIframeSandboxFlags,
     PendingSandboxPolicyUsedForNavigationInstantiatingFrame) {
-  bool is_cross_origin;
-  bool from_allow_to_disallow;
-  std::tie(is_cross_origin, from_allow_to_disallow) = GetParam();
+  auto [is_cross_origin, from_allow_to_disallow] = GetParam();
 
   size_t number_of_downloads = from_allow_to_disallow ? 0u : 1u;
   SandboxOption initial_sandbox_option =
@@ -694,9 +676,7 @@
 // policy for the download intervention.
 IN_PROC_BROWSER_TEST_P(DownloadFramePolicyBrowserTest_UpdateIframeSandboxFlags,
                        EffectiveSandboxPolicyUsedForNavigationInitiatorFrame) {
-  bool is_cross_origin;
-  bool from_allow_to_disallow;
-  std::tie(is_cross_origin, from_allow_to_disallow) = GetParam();
+  auto [is_cross_origin, from_allow_to_disallow] = GetParam();
 
   size_t number_of_downloads = from_allow_to_disallow ? 1u : 0u;
   SandboxOption initial_sandbox_option =
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.cc
index 3ce5e8e..d9b8fdce 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.cc
@@ -20,9 +20,7 @@
     KeyPersistenceDelegate* persistence_delegate) {
   DCHECK(persistence_delegate);
 
-  KeyTrustLevel trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
-  std::vector<uint8_t> wrapped;
-  std::tie(trust_level, wrapped) = persistence_delegate->LoadKeyPair();
+  auto [trust_level, wrapped] = persistence_delegate->LoadKeyPair();
 
   if (wrapped.empty()) {
     // No persisted key pair with a known trust level found.  This is not an
diff --git a/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc b/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc
index 0143280..65fe85526 100644
--- a/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc
+++ b/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc
@@ -79,14 +79,12 @@
 
 void BrowserReportGeneratorDesktop::GenerateBuildStateInfo(
     em::BrowserReport* report) {
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
   const auto* const build_state = g_browser_process->GetBuildState();
   if (build_state->update_type() != BuildState::UpdateType::kNone) {
     const auto& installed_version = build_state->installed_version();
     if (installed_version)
       report->set_installed_browser_version(installed_version->GetString());
   }
-#endif
 }
 
 void BrowserReportGeneratorDesktop::GeneratePluginsIfNeeded(
diff --git a/chrome/browser/enterprise/reporting/browser_report_generator_unittest.cc b/chrome/browser/enterprise/reporting/browser_report_generator_unittest.cc
index 5d10a2a..8975af3 100644
--- a/chrome/browser/enterprise/reporting/browser_report_generator_unittest.cc
+++ b/chrome/browser/enterprise/reporting/browser_report_generator_unittest.cc
@@ -85,8 +85,10 @@
   }
 }
 
-void VerifyBuildState(em::BrowserReport* report) {
-#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+void VerifyBuildState(em::BrowserReport* report, bool with_version_info) {
+#if !BUILDFLAG(IS_ANDROID)
+  if (!with_version_info)
+    return;
   const auto* build_state = g_browser_process->GetBuildState();
   if (build_state->update_type() == BuildState::UpdateType::kNone ||
       !build_state->installed_version()) {
@@ -227,7 +229,7 @@
               bool with_version_info = true;
 #endif  // if BUILDFLAG(IS_CHROMEOS_ASH)
               VerifyBrowserVersionAndChannel(report.get(), with_version_info);
-              VerifyBuildState(report.get());
+              VerifyBuildState(report.get(), with_version_info);
               VerifyExtendedStableChannel(report.get());
               VerifyProfile(report.get());
               VerifyPlugins(report.get());
@@ -251,7 +253,7 @@
 
               VerifyBrowserVersionAndChannel(report.get(),
                                              /*with_version_info=*/true);
-              VerifyBuildState(report.get());
+              VerifyBuildState(report.get(), /*with_version_info=*/true);
               VerifyExtendedStableChannel(report.get());
               EXPECT_LE(0, report->plugins_size());
 
diff --git a/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc b/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc
index 4c17e25..96bcb66 100644
--- a/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc
@@ -564,7 +564,7 @@
                        AllowlistedExtensionForDownloads) {
   ScopedSkipRequestFileSystemDialog dialog_skipper(ui::DIALOG_BUTTON_CANCEL);
   ASSERT_TRUE(RunExtensionTest(
-      "api_test/file_system/request_downloads_whitelisted_extension",
+      "api_test/file_system/request_downloads_allowed_extension",
       {.launch_as_platform_app = true}))
       << message_;
 }
diff --git a/chrome/browser/extensions/extension_security_exploit_browsertest.cc b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
index f9e41a41e..45e2457 100644
--- a/chrome/browser/extensions/extension_security_exploit_browsertest.cc
+++ b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
@@ -307,11 +307,7 @@
           if (captured_render_process_id != matching_process_id)
             return false;
 
-          extensions::PortContext source_context;
-          ExtensionMsg_ExternalConnectionInfo info;
-          std::string channel_name;
-          extensions::PortId port_id;
-          std::tie(source_context, info, channel_name, port_id) = param;
+          auto [source_context, info, channel_name, port_id] = param;
 
           if (info.source_endpoint.extension_id != matching_extension_id)
             return false;
@@ -342,11 +338,7 @@
       "chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
 
   // Capture the IPC.
-  extensions::PortContext source_context;
-  ExtensionMsg_ExternalConnectionInfo info;
-  std::string channel_name;
-  extensions::PortId port_id;
-  std::tie(source_context, info, channel_name, port_id) = WaitForMessage();
+  auto [source_context, info, channel_name, port_id] = WaitForMessage();
 
   // Mutate the IPC payload.
   EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
@@ -377,11 +369,7 @@
       "chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
 
   // Capture the IPC.
-  extensions::PortContext source_context;
-  ExtensionMsg_ExternalConnectionInfo info;
-  std::string channel_name;
-  extensions::PortId port_id;
-  std::tie(source_context, info, channel_name, port_id) = WaitForMessage();
+  auto [source_context, info, channel_name, port_id] = WaitForMessage();
 
   // Mutate the IPC payload.
   EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
@@ -411,11 +399,7 @@
       "chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
 
   // Capture the IPC.
-  extensions::PortContext source_context;
-  ExtensionMsg_ExternalConnectionInfo info;
-  std::string channel_name;
-  extensions::PortId port_id;
-  std::tie(source_context, info, channel_name, port_id) = WaitForMessage();
+  auto [source_context, info, channel_name, port_id] = WaitForMessage();
 
   // Mutate the IPC payload.
   EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
@@ -446,11 +430,7 @@
       "chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
 
   // Capture the IPC.
-  extensions::PortContext source_context;
-  ExtensionMsg_ExternalConnectionInfo info;
-  std::string channel_name;
-  extensions::PortId port_id;
-  std::tie(source_context, info, channel_name, port_id) = WaitForMessage();
+  auto [source_context, info, channel_name, port_id] = WaitForMessage();
 
   // Mutate the IPC payload.
   EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
@@ -482,11 +462,7 @@
       "chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
 
   // Capture the IPC.
-  extensions::PortContext source_context;
-  ExtensionMsg_ExternalConnectionInfo info;
-  std::string channel_name;
-  extensions::PortId port_id;
-  std::tie(source_context, info, channel_name, port_id) = WaitForMessage();
+  auto [source_context, info, channel_name, port_id] = WaitForMessage();
 
   // Mutate the IPC payload.
   EXPECT_TRUE(source_context.is_for_render_frame());
diff --git a/chrome/browser/extensions/options_page_apitest.cc b/chrome/browser/extensions/options_page_apitest.cc
index 678f427..2221c30 100644
--- a/chrome/browser/extensions/options_page_apitest.cc
+++ b/chrome/browser/extensions/options_page_apitest.cc
@@ -53,7 +53,7 @@
     (function() {
       var button = document.querySelector('extensions-manager').
                     shadowRoot.querySelector('extensions-detail-view').
-                    shadowRoot.querySelector('#extensions-options');
+                    shadowRoot.querySelector('#extensionsOptions');
       button.click();
     })();)";
 
diff --git a/chrome/browser/feed/android/BUILD.gn b/chrome/browser/feed/android/BUILD.gn
index 6bf6332..0c6ee3f 100644
--- a/chrome/browser/feed/android/BUILD.gn
+++ b/chrome/browser/feed/android/BUILD.gn
@@ -69,9 +69,9 @@
     "java/src/org/chromium/chrome/browser/feed/sections/ViewVisibility.java",
     "java/src/org/chromium/chrome/browser/feed/settings/FeedAutoplaySettingsFragment.java",
     "java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java",
-    "java/src/org/chromium/chrome/browser/feed/sort_ui/SortChipProperties.java",
-    "java/src/org/chromium/chrome/browser/feed/sort_ui/SortView.java",
-    "java/src/org/chromium/chrome/browser/feed/sort_ui/SortViewBinder.java",
+    "java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsCoordinator.java",
+    "java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsProperties.java",
+    "java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsView.java",
     "java/src/org/chromium/chrome/browser/feed/webfeed/ShadowedClickableTextBubble.java",
     "java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedBridge.java",
     "java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedDialogContents.java",
@@ -288,6 +288,7 @@
     "java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediatorTest.java",
     "java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementCoordinatorTest.java",
     "java/src/org/chromium/chrome/browser/feed/followmanagement/FollowManagementMediatorTest.java",
+    "java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsCoordinatorTest.java",
     "java/src/org/chromium/chrome/browser/feed/webfeed/TestWebFeedFaviconFetcher.java",
     "java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedDialogMediatorTest.java",
     "java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFaviconFetcherTest.java",
diff --git a/chrome/browser/feed/android/java/res/layout/feed_options_panel.xml b/chrome/browser/feed/android/java/res/layout/feed_options_panel.xml
index bd0f454d..b5f3c1a 100644
--- a/chrome/browser/feed/android/java/res/layout/feed_options_panel.xml
+++ b/chrome/browser/feed/android/java/res/layout/feed_options_panel.xml
@@ -4,22 +4,27 @@
      found in the LICENSE file.
 -->
 
-<LinearLayout
+
+<org.chromium.chrome.browser.feed.sort_ui.FeedOptionsView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/options_content"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:paddingHorizontal="@dimen/ntp_header_lateral_paddings_v2"
+    android:paddingVertical="@dimen/feed_options_vertical_margins"
+    android:background="@drawable/new_tab_page_multi_feed_header_background"
+    android:layout_marginBottom="@dimen/feed_options_vertical_margins"
     android:orientation="vertical"
-    android:paddingVertical="@dimen/feed_options_vertical_margins" >
-  <TextView
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      style="@style/TextAppearance.TextAccentMediumThick.Secondary"
-      android:text="@string/sort_by"
-      android:paddingVertical="@dimen/feed_options_vertical_margins"/>
-  <org.chromium.chrome.browser.feed.sort_ui.SortView
-      android:id="@+id/button_bar"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:orientation="horizontal"
-      android:paddingBottom="@dimen/feed_options_vertical_margins" />
-</LinearLayout>
+    android:visibility="gone">
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        style="@style/TextAppearance.TextAccentMediumThick.Secondary"
+        android:text="@string/sort_by"
+        android:paddingVertical="@dimen/feed_options_vertical_margins" />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:id="@+id/chips_container"
+        android:orientation="horizontal" />
+</org.chromium.chrome.browser.feed.sort_ui.FeedOptionsView>
\ No newline at end of file
diff --git a/chrome/browser/feed/android/java/res/layout/new_tab_page_multi_feed_header.xml b/chrome/browser/feed/android/java/res/layout/new_tab_page_multi_feed_header.xml
index 6937d74..71790c2 100644
--- a/chrome/browser/feed/android/java/res/layout/new_tab_page_multi_feed_header.xml
+++ b/chrome/browser/feed/android/java/res/layout/new_tab_page_multi_feed_header.xml
@@ -65,13 +65,4 @@
   </LinearLayout>
 
   <include layout="@layout/horizontal_divider" />
-
-  <FrameLayout
-      android:id="@+id/options_content"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:paddingHorizontal="@dimen/ntp_header_lateral_paddings_v2"
-      android:background="@drawable/new_tab_page_multi_feed_header_background"
-      android:visibility="gone" />
-
 </org.chromium.chrome.browser.feed.sections.SectionHeaderView>
diff --git a/chrome/browser/feed/android/java/res/layout/web_feed_main_menu_item.xml b/chrome/browser/feed/android/java/res/layout/web_feed_main_menu_item.xml
index 11f6857f..192c9c0 100644
--- a/chrome/browser/feed/android/java/res/layout/web_feed_main_menu_item.xml
+++ b/chrome/browser/feed/android/java/res/layout/web_feed_main_menu_item.xml
@@ -41,7 +41,7 @@
             android:ellipsize="end"
             android:singleLine="true" />
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/follow_chip_view"
             style="@style/MenuFooterChip"
             android:layout_width="wrap_content"
@@ -49,7 +49,7 @@
             android:layout_gravity="end"
             android:visibility="gone" />
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/following_chip_view"
             style="@style/MenuFooterChipInverse"
             android:layout_width="wrap_content"
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java
index e3a10749..a689fdcd 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStream.java
@@ -8,14 +8,12 @@
 import android.animation.PropertyValuesHolder;
 import android.app.Activity;
 import android.util.TypedValue;
-import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.widget.FrameLayout;
 
 import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
 import androidx.annotation.VisibleForTesting;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
@@ -33,10 +31,6 @@
 import org.chromium.base.supplier.Supplier;
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.browser.feed.sections.SectionType;
-import org.chromium.chrome.browser.feed.sort_ui.SortChipProperties;
-import org.chromium.chrome.browser.feed.sort_ui.SortView;
-import org.chromium.chrome.browser.feed.sort_ui.SortViewBinder;
-import org.chromium.chrome.browser.feed.v2.ContentOrder;
 import org.chromium.chrome.browser.feed.v2.FeedUserActionType;
 import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncher;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
@@ -65,9 +59,6 @@
 import org.chromium.ui.base.PageTransition;
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.display.DisplayAndroid;
-import org.chromium.ui.modelutil.ListModel;
-import org.chromium.ui.modelutil.ListModelChangeProcessor;
-import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.mojom.WindowOpenDisposition;
 import org.chromium.url.GURL;
 
@@ -444,9 +435,6 @@
     private String mBottomSheetOriginatingSliceId;
     private View mLastFocusedView;
 
-    // Sort options drawer.
-    private View mSortView;
-
     /**
      * Creates a new Feed Stream.
      * @param activity {@link Activity} that this is bound to.
@@ -513,42 +501,12 @@
         // Sort options only available for web feed right now.
         if (!isInterestFeed) {
             mUnreadContentObserver = new UnreadContentObserver(/*isWebFeed=*/true);
-
-            if (ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_FEED_SORT)) {
-                @ContentOrder
-                int currentSort = FeedServiceBridge.getContentOrderForWebFeed();
-
-                mSortView =
-                        LayoutInflater.from(activity).inflate(R.layout.feed_options_panel, null);
-                SortView chipView = mSortView.findViewById(R.id.button_bar);
-                ListModel<PropertyModel> sortModel = new ListModel<>();
-                ListModelChangeProcessor<ListModel<PropertyModel>, SortView, Void> processor =
-                        new ListModelChangeProcessor<>(sortModel, chipView, new SortViewBinder());
-                sortModel.addObserver(processor);
-
-                sortModel.add(
-                        createSortModel(ContentOrder.REVERSE_CHRON, R.string.latest, currentSort));
-
-                sortModel.add(createSortModel(
-                        ContentOrder.GROUPED, R.string.feed_sort_publisher, currentSort));
-            }
         }
     }
 
-    private PropertyModel createSortModel(
-            @ContentOrder int order, @StringRes int stringResource, @ContentOrder int currentSort) {
-        return new PropertyModel.Builder(SortChipProperties.ALL_KEYS)
-                .with(SortChipProperties.NAME_KEY,
-                        mActivity.getResources().getString(stringResource))
-                .with(SortChipProperties.ON_SELECT_CALLBACK_KEY,
-                        () -> FeedServiceBridge.setContentOrderForWebFeed(order))
-                .with(SortChipProperties.IS_INITIALLY_SELECTED_KEY, currentSort == order)
-                .build();
-    }
-
     @Override
-    public View getOptionsView() {
-        return mSortView;
+    public boolean supportsOptions() {
+        return ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_FEED_SORT) && !mIsInterestFeed;
     }
 
     @Override
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStreamTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStreamTest.java
index 7cdbf66f..68cd0e2 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStreamTest.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedStreamTest.java
@@ -10,9 +10,11 @@
 import static org.hamcrest.Matchers.hasEntry;
 import static org.hamcrest.Matchers.instanceOf;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -769,6 +771,62 @@
         FeatureList.setTestFeatures(null);
     }
 
+    @Test
+    @SmallTest
+    public void testSupportsOptions_InterestFeed_sortOff() {
+        Map<String, Boolean> features = new HashMap<>();
+        features.put(ChromeFeatureList.WEB_FEED_SORT, false);
+        FeatureList.setTestFeatures(features);
+        FeedStream stream = new FeedStream(mActivity, mSnackbarManager, mBottomSheetController,
+                /* isPlaceholderShown= */ false, mWindowAndroid, mShareDelegateSupplier,
+                /* isInterestFeed= */ true,
+                /* FeedAutoplaySettingsDelegate= */ null, mActionDelegate,
+                /*helpAndFeedbackLauncher=*/null);
+        assertFalse(stream.supportsOptions());
+    }
+
+    @Test
+    @SmallTest
+    public void testSupportsOptions_InterestFeed_sortOn() {
+        Map<String, Boolean> features = new HashMap<>();
+        features.put(ChromeFeatureList.WEB_FEED_SORT, true);
+        FeatureList.setTestFeatures(features);
+        FeedStream stream = new FeedStream(mActivity, mSnackbarManager, mBottomSheetController,
+                /* isPlaceholderShown= */ false, mWindowAndroid, mShareDelegateSupplier,
+                /* isInterestFeed= */ true,
+                /* FeedAutoplaySettingsDelegate= */ null, mActionDelegate,
+                /*helpAndFeedbackLauncher=*/null);
+        assertFalse(stream.supportsOptions());
+    }
+
+    @Test
+    @SmallTest
+    public void testSupportsOptions_WebFeed_sortOff() {
+        Map<String, Boolean> features = new HashMap<>();
+        features.put(ChromeFeatureList.WEB_FEED_SORT, false);
+        FeatureList.setTestFeatures(features);
+        FeedStream stream = new FeedStream(mActivity, mSnackbarManager, mBottomSheetController,
+                /* isPlaceholderShown= */ false, mWindowAndroid, mShareDelegateSupplier,
+                /* isInterestFeed= */ false,
+                /* FeedAutoplaySettingsDelegate= */ null, mActionDelegate,
+                /*helpAndFeedbackLauncher=*/null);
+        assertFalse(stream.supportsOptions());
+    }
+
+    @Test
+    @SmallTest
+    public void testSupportsOptions_WebFeed_sortOn() {
+        Map<String, Boolean> features = new HashMap<>();
+        features.put(ChromeFeatureList.WEB_FEED_SORT, true);
+        FeatureList.setTestFeatures(features);
+        FeedStream stream = new FeedStream(mActivity, mSnackbarManager, mBottomSheetController,
+                /* isPlaceholderShown= */ false, mWindowAndroid, mShareDelegateSupplier,
+                /* isInterestFeed= */ false,
+                /* FeedAutoplaySettingsDelegate= */ null, mActionDelegate,
+                /*helpAndFeedbackLauncher=*/null);
+        assertTrue(stream.supportsOptions());
+    }
+
     private int getLoadMoreTriggerScrollDistance() {
         return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                 LOAD_MORE_TRIGGER_SCROLL_DISTANCE_DP,
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/Stream.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/Stream.java
index 89bac986..4f8fdbe 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/Stream.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/Stream.java
@@ -4,8 +4,6 @@
 
 package org.chromium.chrome.browser.feed;
 
-import android.view.View;
-
 import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -77,13 +75,6 @@
      */
     void hidePlaceholder();
 
-    /**
-     * Returns the options for this stream if one exists.
-     */
-    default View getOptionsView() {
-        return null;
-    }
-
     /** Record that user tapped ManageInterests. */
     default void recordActionManageInterests() {}
 
@@ -142,6 +133,13 @@
     void unbind(boolean shouldPlaceSpacer);
 
     /**
+     * Whether this stream supports alternate sort options.
+     */
+    default boolean supportsOptions() {
+        return false;
+    }
+
+    /**
      * Returns a value that uniquely identifies the state of the Stream's content. If this value
      * changes, then scroll state won't be restored.
      */
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java
index 665b8fc..accef943 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sections/SectionHeaderView.java
@@ -8,7 +8,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
@@ -17,11 +16,7 @@
 import android.util.AttributeSet;
 import android.view.TouchDelegate;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
-import android.view.animation.Animation;
-import android.view.animation.Transformation;
-import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -34,12 +29,10 @@
 import com.google.android.material.badge.BadgeUtils;
 import com.google.android.material.tabs.TabLayout;
 
-import org.chromium.base.Log;
 import org.chromium.chrome.browser.feed.FeedUma;
 import org.chromium.chrome.browser.feed.R;
 import org.chromium.chrome.browser.user_education.IPHCommandBuilder;
 import org.chromium.chrome.browser.user_education.UserEducationHelper;
-import org.chromium.components.browser_ui.styles.ChromeColors;
 import org.chromium.components.browser_ui.widget.highlight.PulseDrawable;
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightParams;
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightShape;
@@ -137,7 +130,7 @@
     private @Nullable SectionHeaderTabListener mTabListener;
     private @Nullable View mDivider;
     private LinearLayout mContent;
-    private @Nullable FrameLayout mOptionsPanel;
+    private @Nullable View mOptionsPanel;
 
     // Cached the indicator drawables for easy swapping.
     private Drawable mEnabledIndicatorDrawable;
@@ -148,8 +141,6 @@
 
     public SectionHeaderView(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
-        TypedArray attrArray = context.getTheme().obtainStyledAttributes(
-                attrs, R.styleable.SectionHeaderView, 0, 0);
     }
 
     public void setToolbarHeight(@Px int toolbarHeight) {
@@ -166,7 +157,6 @@
         mTabLayout = findViewById(R.id.tab_list_view);
         mDivider = findViewById(R.id.divider);
         mContent = findViewById(R.id.main_content);
-        mOptionsPanel = findViewById(R.id.options_content);
 
         if (mTabLayout != null) {
             mTabListener = new SectionHeaderTabListener();
@@ -174,11 +164,6 @@
             mEnabledIndicatorDrawable = mTabLayout.getTabSelectedIndicator();
         }
 
-        if (mOptionsPanel != null) {
-            mOptionsPanel.setBackgroundColor(
-                    ChromeColors.getSurfaceColor(getContext(), R.dimen.card_elevation));
-        }
-
         int touchSize =
                 getResources().getDimensionPixelSize(R.dimen.feed_v2_header_menu_touch_size);
 
@@ -378,22 +363,14 @@
         });
         animator.setDuration(ANIMATION_DURATION_MS);
         animator.start();
-        if (mOptionsPanel != null && mOptionsPanel.getVisibility() == VISIBLE) {
-            collapseOptionsPanel();
-        }
     }
 
     void setOptionsPanel(View optionsView) {
-        if (mOptionsPanel == null) return;
-        if (optionsView == null && mOptionsPanel.getVisibility() == VISIBLE) {
-            collapseOptionsPanel();
-        } else if (optionsView != null) {
-            if (optionsView.getParent() != null) {
-                ((ViewGroup) optionsView.getParent()).removeView(optionsView);
-            }
-            mOptionsPanel.addView(optionsView);
-            expandOptionsPanel();
+        if (mOptionsPanel != null) {
+            removeView(mOptionsPanel);
         }
+        addView(optionsView);
+        mOptionsPanel = optionsView;
     }
 
     /**
@@ -414,67 +391,6 @@
         mTitleView.setEnabled(enabled);
     }
 
-    private void expandOptionsPanel() {
-        // Width is match_parent and height is wrap_content.
-        int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY);
-        int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        mOptionsPanel.measure(widthMeasureSpec, heightMeasureSpec);
-        int targetHeight = mOptionsPanel.getMeasuredHeight();
-
-        // Older (pre-API21) Android versions cancel animations with height of 0.
-        mOptionsPanel.getLayoutParams().height = 1;
-        mOptionsPanel.setVisibility(VISIBLE);
-
-        Animation animation = new Animation() {
-            @Override
-            protected void applyTransformation(float interpolatedTime, Transformation t) {
-                int height;
-                if (interpolatedTime == 1) {
-                    height = ViewGroup.LayoutParams.WRAP_CONTENT;
-                } else {
-                    height = (int) (targetHeight * interpolatedTime);
-                }
-                mOptionsPanel.getLayoutParams().height = height;
-                mOptionsPanel.requestLayout();
-            }
-
-            @Override
-            public boolean willChangeBounds() {
-                return true;
-            }
-        };
-
-        animation.setDuration(ANIMATION_DURATION_MS);
-        mOptionsPanel.startAnimation(animation);
-    }
-
-    private void collapseOptionsPanel() {
-        int initialHeight = mOptionsPanel.getMeasuredHeight();
-
-        Animation animation = new Animation() {
-            @Override
-            protected void applyTransformation(float interpolatedTime, Transformation t) {
-                if (interpolatedTime == 1) {
-                    mOptionsPanel.setVisibility(GONE);
-                    mOptionsPanel.removeAllViews();
-                } else {
-                    mOptionsPanel.getLayoutParams().height =
-                            initialHeight - (int) (initialHeight * interpolatedTime);
-                    mOptionsPanel.requestLayout();
-                }
-                Log.e(TAG, "drawer height is: " + mOptionsPanel.getLayoutParams().height);
-            }
-
-            @Override
-            public boolean willChangeBounds() {
-                return true;
-            }
-        };
-
-        animation.setDuration(ANIMATION_DURATION_MS);
-        mOptionsPanel.startAnimation(animation);
-    }
-
     /** Shows an IPH on the feed header menu button. */
     public void showMenuIph(UserEducationHelper helper) {
         final ViewRectProvider rectProvider = new ViewRectProvider(mMenuView) {
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsCoordinator.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsCoordinator.java
new file mode 100644
index 0000000..bb2f749
--- /dev/null
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsCoordinator.java
@@ -0,0 +1,127 @@
+// Copyright 2022 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.
+
+package org.chromium.chrome.browser.feed.sort_ui;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.annotation.StringRes;
+import androidx.annotation.VisibleForTesting;
+
+import org.chromium.chrome.browser.feed.FeedServiceBridge;
+import org.chromium.chrome.browser.feed.R;
+import org.chromium.chrome.browser.feed.v2.ContentOrder;
+import org.chromium.components.browser_ui.styles.ChromeColors;
+import org.chromium.components.browser_ui.widget.chips.ChipProperties;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
+import org.chromium.components.browser_ui.widget.chips.ChipViewBinder;
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A coordinator for the feed options panel.
+ */
+public class FeedOptionsCoordinator {
+    /** Method for translating between model changes and corresponding view updates. */
+    static void bind(PropertyModel model, FeedOptionsView view, PropertyKey key) {
+        if (key == FeedOptionsProperties.VISIBILITY_KEY) {
+            view.setVisibility(model.get(FeedOptionsProperties.VISIBILITY_KEY));
+        }
+    }
+
+    private final FeedOptionsView mView;
+    private final Context mContext;
+    private List<PropertyModel> mChipModels;
+    private PropertyModel mModel;
+
+    public FeedOptionsCoordinator(Context context) {
+        // We don't use ChipsCoordinator here because RecyclerView does not play
+        // nicely with the animations used, causing all chips to render with 0 height.
+        this(context,
+                (FeedOptionsView) LayoutInflater.from(context).inflate(
+                        R.layout.feed_options_panel, null, false));
+    }
+
+    @VisibleForTesting
+    FeedOptionsCoordinator(Context context, FeedOptionsView view) {
+        mContext = context;
+        mView = view;
+        mView.setBackgroundColor(ChromeColors.getSurfaceColor(mContext, R.dimen.card_elevation));
+
+        mChipModels = createAndBindChips();
+        mModel = new PropertyModel.Builder(FeedOptionsProperties.getAllKeys())
+                         .with(FeedOptionsProperties.VISIBILITY_KEY, false)
+                         .build();
+        PropertyModelChangeProcessor.create(mModel, mView, FeedOptionsCoordinator::bind);
+    }
+
+    /** Returns the view that this coordinator manages. */
+    public View getView() {
+        return mView;
+    }
+
+    /** Toggles visibility of the options panel. */
+    public void toggleVisibility() {
+        mModel.set(FeedOptionsProperties.VISIBILITY_KEY,
+                !mModel.get(FeedOptionsProperties.VISIBILITY_KEY));
+    }
+
+    /** Ensures that the options panel is completely collapsed. */
+    public void ensureGone() {
+        mModel.set(FeedOptionsProperties.VISIBILITY_KEY, false);
+    }
+
+    @VisibleForTesting
+    void onOptionSelected(PropertyModel selectedOption) {
+        for (PropertyModel model : mChipModels) {
+            if (model.get(ChipProperties.SELECTED)) {
+                model.set(ChipProperties.SELECTED, false);
+            }
+        }
+
+        selectedOption.set(ChipProperties.SELECTED, true);
+        FeedServiceBridge.setContentOrderForWebFeed(selectedOption.get(ChipProperties.ID));
+    }
+
+    private PropertyModel createChipModel(
+            @ContentOrder int id, @StringRes int textId, boolean isSelected) {
+        return new PropertyModel.Builder(ChipProperties.ALL_KEYS)
+                .with(ChipProperties.ID, id)
+                .with(ChipProperties.TEXT, mContext.getResources().getString(textId))
+                .with(ChipProperties.SELECTED, isSelected)
+                .with(ChipProperties.CLICK_HANDLER, this::onOptionSelected)
+                .with(ChipProperties.CONTENT_DESCRIPTION, mContext.getResources().getString(textId))
+                .build();
+    }
+
+    private List<PropertyModel> createAndBindChips() {
+        @ContentOrder
+        int currentSort = FeedServiceBridge.getContentOrderForWebFeed();
+        List<PropertyModel> chipModels = new ArrayList<>();
+        chipModels.add(createChipModel(ContentOrder.GROUPED, R.string.feed_sort_publisher,
+                currentSort == ContentOrder.GROUPED));
+        chipModels.add(createChipModel(ContentOrder.REVERSE_CHRON, R.string.latest,
+                currentSort == ContentOrder.REVERSE_CHRON));
+
+        for (PropertyModel model : chipModels) {
+            ChipView chip = mView.createNewChip();
+            PropertyModelChangeProcessor.create(model, chip, ChipViewBinder::bind);
+        }
+        return chipModels;
+    }
+
+    PropertyModel getModelForTest() {
+        return mModel;
+    }
+
+    List<PropertyModel> getChipModelsForTest() {
+        return mChipModels;
+    }
+}
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsCoordinatorTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsCoordinatorTest.java
new file mode 100644
index 0000000..9087186
--- /dev/null
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsCoordinatorTest.java
@@ -0,0 +1,119 @@
+// Copyright 2022 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.
+
+package org.chromium.chrome.browser.feed.sort_ui;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.Context;
+import android.widget.TextView;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.JniMocker;
+import org.chromium.chrome.browser.feed.FeedServiceBridge;
+import org.chromium.chrome.browser.feed.v2.ContentOrder;
+import org.chromium.components.browser_ui.widget.chips.ChipProperties;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
+import org.chromium.ui.modelutil.PropertyModel;
+
+import java.util.List;
+
+/**
+ * Tests for {@link FeedOptionsCoordinator}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class FeedOptionsCoordinatorTest {
+    @Mock
+    private FeedServiceBridge.Natives mFeedServiceBridgeJniMock;
+    @Mock
+    private FeedOptionsView mView;
+    @Mock
+    private ChipView mChipView;
+    @Mock
+    private TextView mTextView;
+
+    @Rule
+    public JniMocker mMocker = new JniMocker();
+
+    private FeedOptionsCoordinator mCoordinator;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = Robolectric.buildActivity(Activity.class).get();
+        mMocker.mock(FeedServiceBridge.getTestHooksForTesting(), mFeedServiceBridgeJniMock);
+        when(mFeedServiceBridgeJniMock.getContentOrderForWebFeed())
+                .thenReturn(ContentOrder.REVERSE_CHRON);
+        when(mView.createNewChip()).thenReturn(mChipView);
+        when(mChipView.getPrimaryTextView()).thenReturn(mTextView);
+
+        mCoordinator = new FeedOptionsCoordinator(mContext, mView);
+    }
+
+    @Test
+    public void testToggleVisibility_turnoff() {
+        PropertyModel model = mCoordinator.getModelForTest();
+        model.set(FeedOptionsProperties.VISIBILITY_KEY, true);
+
+        mCoordinator.toggleVisibility();
+
+        assertFalse(mCoordinator.getModelForTest().get(FeedOptionsProperties.VISIBILITY_KEY));
+    }
+
+    @Test
+    public void testToggleVisibility_turnon() {
+        PropertyModel model = mCoordinator.getModelForTest();
+        model.set(FeedOptionsProperties.VISIBILITY_KEY, false);
+
+        mCoordinator.toggleVisibility();
+
+        assertTrue(mCoordinator.getModelForTest().get(FeedOptionsProperties.VISIBILITY_KEY));
+    }
+
+    @Test
+    public void testEnsureGone_startOn() {
+        PropertyModel model = mCoordinator.getModelForTest();
+        model.set(FeedOptionsProperties.VISIBILITY_KEY, true);
+
+        mCoordinator.ensureGone();
+
+        assertFalse(mCoordinator.getModelForTest().get(FeedOptionsProperties.VISIBILITY_KEY));
+    }
+
+    @Test
+    public void testEnsureGone_startOff() {
+        PropertyModel model = mCoordinator.getModelForTest();
+        model.set(FeedOptionsProperties.VISIBILITY_KEY, false);
+
+        mCoordinator.ensureGone();
+
+        assertFalse(mCoordinator.getModelForTest().get(FeedOptionsProperties.VISIBILITY_KEY));
+    }
+
+    @Test
+    public void testOptionsSelected() {
+        List<PropertyModel> chipModels = mCoordinator.getChipModelsForTest();
+        chipModels.get(0).set(ChipProperties.SELECTED, false);
+        chipModels.get(1).set(ChipProperties.SELECTED, true);
+
+        mCoordinator.onOptionSelected(chipModels.get(0));
+
+        assertFalse(chipModels.get(1).get(ChipProperties.SELECTED));
+        assertTrue(chipModels.get(0).get(ChipProperties.SELECTED));
+    }
+}
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsProperties.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsProperties.java
new file mode 100644
index 0000000..bcc667d5
--- /dev/null
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsProperties.java
@@ -0,0 +1,18 @@
+// Copyright 2022 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.
+
+package org.chromium.chrome.browser.feed.sort_ui;
+
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel;
+
+/** Represents data for the Feed Options pane. */
+public class FeedOptionsProperties {
+    public static final PropertyModel.WritableBooleanPropertyKey VISIBILITY_KEY =
+            new PropertyModel.WritableBooleanPropertyKey();
+
+    static PropertyKey[] getAllKeys() {
+        return new PropertyKey[] {VISIBILITY_KEY};
+    }
+}
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsView.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsView.java
new file mode 100644
index 0000000..ebfc6895
--- /dev/null
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/FeedOptionsView.java
@@ -0,0 +1,120 @@
+// Copyright 2022 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.
+
+package org.chromium.chrome.browser.feed.sort_ui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+import android.widget.LinearLayout;
+
+import androidx.annotation.Nullable;
+
+import org.chromium.chrome.browser.feed.R;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
+
+/**
+ * View class representing an expandable/collapsible view holding option chips for the feed.
+ */
+public class FeedOptionsView extends LinearLayout {
+    private LinearLayout mChipsContainer;
+    private static final int ANIMATION_DURATION_MS = 200;
+
+    public FeedOptionsView(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mChipsContainer = findViewById(R.id.chips_container);
+    }
+
+    public ChipView createNewChip() {
+        ChipView chip = new ChipView(getContext(), null, 0, R.style.SuggestionChip);
+
+        mChipsContainer.addView(chip);
+        ViewGroup.MarginLayoutParams marginParams =
+                (ViewGroup.MarginLayoutParams) chip.getLayoutParams();
+        marginParams.setMarginEnd(getContext().getResources().getDimensionPixelSize(
+                R.dimen.feed_options_chip_margin));
+        chip.setLayoutParams(marginParams);
+        return chip;
+    }
+
+    void setVisibility(boolean isVisible) {
+        boolean currentVisibility = getVisibility() == VISIBLE;
+        if (currentVisibility == isVisible) return;
+        if (isVisible) {
+            expand();
+        } else {
+            collapse();
+        }
+    }
+
+    /** Expands this view to full height. */
+    private void expand() {
+        // Width is match_parent and height is wrap_content.
+        int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
+                ((ViewGroup) getParent()).getWidth(), View.MeasureSpec.EXACTLY);
+        int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+        measure(widthMeasureSpec, heightMeasureSpec);
+        int targetHeight = getMeasuredHeight();
+
+        // Older (pre-API21) Android versions cancel animations with height of 0.
+        getLayoutParams().height = 1;
+        setVisibility(VISIBLE);
+
+        Animation animation = new Animation() {
+            @Override
+            protected void applyTransformation(float interpolatedTime, Transformation t) {
+                int height;
+                if (interpolatedTime == 1) {
+                    height = ViewGroup.LayoutParams.WRAP_CONTENT;
+                } else {
+                    height = (int) (targetHeight * interpolatedTime);
+                }
+                getLayoutParams().height = height;
+                requestLayout();
+            }
+
+            @Override
+            public boolean willChangeBounds() {
+                return true;
+            }
+        };
+
+        animation.setDuration(ANIMATION_DURATION_MS);
+        startAnimation(animation);
+    }
+
+    /** Collapses this view to 0 height and then marks it GONE. */
+    private void collapse() {
+        int initialHeight = getMeasuredHeight();
+
+        Animation animation = new Animation() {
+            @Override
+            protected void applyTransformation(float interpolatedTime, Transformation t) {
+                if (interpolatedTime == 1) {
+                    setVisibility(GONE);
+                } else {
+                    getLayoutParams().height =
+                            initialHeight - (int) (initialHeight * interpolatedTime);
+                    requestLayout();
+                }
+            }
+
+            @Override
+            public boolean willChangeBounds() {
+                return true;
+            }
+        };
+
+        animation.setDuration(ANIMATION_DURATION_MS);
+        startAnimation(animation);
+    }
+}
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/SortChipProperties.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/SortChipProperties.java
deleted file mode 100644
index bb4f1797..0000000
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/SortChipProperties.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 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.
-package org.chromium.chrome.browser.feed.sort_ui;
-
-import org.chromium.ui.modelutil.PropertyKey;
-import org.chromium.ui.modelutil.PropertyModel;
-
-/** List of properties for a sorting option. */
-public class SortChipProperties {
-    public static final PropertyModel.ReadableObjectPropertyKey<String> NAME_KEY =
-            new PropertyModel.ReadableObjectPropertyKey<>();
-    public static final PropertyModel.ReadableObjectPropertyKey<Runnable> ON_SELECT_CALLBACK_KEY =
-            new PropertyModel.ReadableObjectPropertyKey<>();
-    public static final PropertyModel.ReadableBooleanPropertyKey IS_INITIALLY_SELECTED_KEY =
-            new PropertyModel.ReadableBooleanPropertyKey();
-
-    public static final PropertyKey[] ALL_KEYS =
-            new PropertyKey[] {NAME_KEY, ON_SELECT_CALLBACK_KEY, IS_INITIALLY_SELECTED_KEY};
-}
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/SortView.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/SortView.java
deleted file mode 100644
index 422183b..0000000
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/SortView.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2021 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.
-package org.chromium.chrome.browser.feed.sort_ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.R;
-import org.chromium.ui.widget.ChipView;
-
-/**
- * View class representing sorting options of a feed. This view contains multiple
- * ChipViews, only one of which is ever selected.
- */
-public class SortView extends LinearLayout {
-    private ChipView mCurrentlySelected;
-
-    /** Creates a SortView with Context and attribute set. */
-    public SortView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    void onChipSelected(ChipView chipView) {
-        if (mCurrentlySelected != null) {
-            mCurrentlySelected.setSelected(false);
-        }
-        chipView.setSelected(true);
-        mCurrentlySelected = chipView;
-    }
-
-    void addButton(String text, Runnable onSelectedCallback, boolean isSelected) {
-        ChipView chip = new ChipView(getContext(), null, 0, R.style.SuggestionChip);
-        chip.getPrimaryTextView().setText(text);
-        chip.setOnClickListener((View v) -> {
-            onChipSelected((ChipView) v);
-            onSelectedCallback.run();
-        });
-        addView(chip);
-        MarginLayoutParams marginParams = (MarginLayoutParams) chip.getLayoutParams();
-        marginParams.setMarginEnd(getContext().getResources().getDimensionPixelSize(
-                R.dimen.feed_options_chip_margin));
-        if (isSelected) {
-            onChipSelected(chip);
-        }
-    }
-}
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/SortViewBinder.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/SortViewBinder.java
deleted file mode 100644
index dadad224..0000000
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/sort_ui/SortViewBinder.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2021 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.
-package org.chromium.chrome.browser.feed.sort_ui;
-
-import org.chromium.ui.modelutil.ListModel;
-import org.chromium.ui.modelutil.ListModelChangeProcessor;
-import org.chromium.ui.modelutil.PropertyModel;
-
-/**
- * View binder that links between a property model with {@link SortChipProperties} and a SortView.
- */
-public class SortViewBinder
-        implements ListModelChangeProcessor.ViewBinder<ListModel<PropertyModel>, SortView, Void> {
-    @Override
-    public void onItemsInserted(
-            ListModel<PropertyModel> modelList, SortView view, int index, int count) {
-        // Assumes we are never inserting chips between other pre-existing chips.
-        // This will always add chips at the end.
-        for (int i = index; i < index + count; i++) {
-            PropertyModel model = modelList.get(i);
-            view.addButton(model.get(SortChipProperties.NAME_KEY),
-                    model.get(SortChipProperties.ON_SELECT_CALLBACK_KEY),
-                    model.get(SortChipProperties.IS_INITIALLY_SELECTED_KEY));
-        }
-    }
-
-    @Override
-    public void onItemsRemoved(
-            ListModel<PropertyModel> model, SortView view, int index, int count) {
-        // Does nothing. We don't support removal.
-    }
-
-    @Override
-    public void onItemsChanged(
-            ListModel<PropertyModel> model, SortView view, int index, int count, Void payload) {
-        // Does nothing. Nothing can be changed right now.
-    }
-}
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItem.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItem.java
index 3368b4c..c6e03cf3 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItem.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItem.java
@@ -24,10 +24,10 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.prefs.PrefService;
 import org.chromium.components.url_formatter.UrlFormatter;
 import org.chromium.ui.modaldialog.ModalDialogManager;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.ui.widget.LoadingView;
 import org.chromium.url.GURL;
 
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItemTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItemTest.java
index cae8eaa..127f1e3 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItemTest.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedMainMenuItemTest.java
@@ -41,11 +41,11 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.embedder_support.util.ShadowUrlUtilities;
 import org.chromium.components.url_formatter.UrlFormatter;
 import org.chromium.components.url_formatter.UrlFormatterJni;
 import org.chromium.ui.modaldialog.ModalDialogManager;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.ui.widget.LoadingView;
 import org.chromium.url.GURL;
 import org.chromium.url.JUnitTestGURLs;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 5020eec6..5e5d64f 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -884,11 +884,6 @@
     "expiry_milestone": 99
   },
   {
-    "name": "contextual-search-literal-search-tap",
-    "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/OWNERS", "contextual-search-eng@google.com" ],
-    "expiry_milestone": 95
-  },
-  {
     "name": "contextual-search-longpress-resolve",
     "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/OWNERS", "contextual-search-eng@google.com" ],
     "expiry_milestone": 99
@@ -1035,8 +1030,8 @@
   },
   {
     "name": "darken-websites-checkbox-in-themes-setting",
-    "owners": [ "lazzzis@google.com", "twellington" ],
-    "expiry_milestone": 98
+    "owners": [ "nemco@google.com", "wenyufu@google.com", "twellington" ],
+    "expiry_milestone": 110
   },
   {
     "name": "dcheck-is-fatal",
@@ -1547,11 +1542,6 @@
     "expiry_milestone": 99
   },
   {
-    "name": "enable-canvas-context-lost-in-background",
-    "owners": [ "chrome-canvas@google.com" ],
-    "expiry_milestone": 100
-  },
-  {
     "name": "enable-cascade-layers",
     "owners": [ "xiaochengh" ],
     "expiry_milestone": 99
@@ -3648,11 +3638,6 @@
     "expiry_milestone": 110
   },
   {
-    "name": "ios-persist-crash-restore-infobar",
-    "owners": [ "thegreenfrog", "bling-flags@google.com" ],
-    "expiry_milestone": 98
-  },
-  {
     "name": "ios-shared-highlighting-color-change",
     "owners": [ "cheickcisse@google.com" ],
     "expiry_milestone": 95
@@ -4037,7 +4022,7 @@
   {
     "name": "nearby-sharing-background-scanning",
     "owners": [ "hansenmichael@google.com", "cvandermerwe@google.com", "chromeos-cross-device-eng@google.com" ],
-    "expiry_milestone": 99
+    "expiry_milestone": 101
   },
   {
     "name": "nearby-sharing-one-page-onboarding",
@@ -5426,6 +5411,11 @@
     "expiry_milestone":100
   },
   {
+      "name": "tailored-security-integration",
+      "owners": ["drubery", "chrome-counter-abuse-core@google.com"],
+      "expiry_milestone":102
+  },
+  {
     "name": "terminal-ssh",
     "owners": [ "lxj@google.com", "joelhockey", "//chrome/browser/ash/guest_os/OWNERS" ],
     "expiry_milestone": 100
@@ -5482,6 +5472,11 @@
     "expiry_milestone": 103
   },
   {
+    "name": "traffic-counters-handler-enabled",
+    "owners": ["khegde", "stevenjb"],
+    "expiry_milestone": 102
+  },
+  {
     "name": "traffic-counters-settings-ui",
     "owners": ["khegde", "stevenjb"],
     "expiry_milestone": 101
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 973a6bb..008987c 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1000,11 +1000,6 @@
 const char kDownloadRangeDescription[] =
     "Enables arbitrary download range request support.";
 
-const char kEnableCanvasContextLostInBackgroundName[] =
-    "Enable canvas context to be lost in background";
-const char kEnableCanvasContextLostInBackgroundDescription[] =
-    "Enable canvas context to be cleared when it is running in background";
-
 const char kEnableLazyFrameLoadingName[] = "Enable lazy frame loading";
 const char kEnableLazyFrameLoadingDescription[] =
     "Defers the loading of iframes marked with the attribute 'loading=lazy' "
@@ -2409,6 +2404,12 @@
 const char kTabSearchFuzzySearchDescription[] =
     "Enable fuzzy search for Tab Search.";
 
+const char kTailoredSecurityIntegrationName[] =
+    "Account-level tailored security integration";
+const char kTailoredSecurityIntegrationDescription[] =
+    "Enable the integration between Enhanced Safe Browsing in Chrome and in "
+    "the account";
+
 const char kTFLiteLanguageDetectionName[] = "TFLite-based Language Detection";
 const char kTFLiteLanguageDetectionDescription[] =
     "Uses TFLite for language detection in place of CLD3";
@@ -2975,14 +2976,6 @@
 const char kContextualSearchForceCaptionDescription[] =
     "Forces a caption to always be shown in the Touch to Search Bar.";
 
-const char kContextualSearchLiteralSearchTapName[] =
-    "Contextual Search literal search with tap";
-const char kContextualSearchLiteralSearchTapDescription[] =
-    "Enables Contextual Search to be activated with a single tap and produce "
-    "a literal search. This is intended to be used in conjunction with the "
-    "long-press resolve feature to allow both gestures to trigger a form of "
-    "Touch to Search.";
-
 const char kContextualSearchLongpressResolveName[] =
     "Contextual Search long-press Resolves";
 const char kContextualSearchLongpressResolveDescription[] =
@@ -5148,6 +5141,12 @@
     "If enabled, the user can calibrate the touch screen displays in "
     "chrome://settings/display.";
 
+const char kTrafficCountersHandlerEnabledName[] =
+    "Traffic counters handler enabled";
+const char kTrafficCountersHandlerEnabledDescription[] =
+    "If enabled, the TrafficCountersHandler class will handle traffic counter "
+    "resets.";
+
 const char kTrafficCountersSettingsUiName[] = "Traffic Counters Settings UI";
 const char kTrafficCountersSettingsUiDescription[] =
     "If enabled, the SettingsUI will show data usage for cellular networks";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 28ffb89..e92b9d5 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -622,9 +622,6 @@
 extern const char kDownloadRangeName[];
 extern const char kDownloadRangeDescription[];
 
-extern const char kEnableCanvasContextLostInBackgroundName[];
-extern const char kEnableCanvasContextLostInBackgroundDescription[];
-
 extern const char kEnableFencedFramesName[];
 extern const char kEnableFencedFramesDescription[];
 
@@ -1390,6 +1387,9 @@
 extern const char kTabSearchFuzzySearchName[];
 extern const char kTabSearchFuzzySearchDescription[];
 
+extern const char kTailoredSecurityIntegrationName[];
+extern const char kTailoredSecurityIntegrationDescription[];
+
 extern const char kTFLiteLanguageDetectionName[];
 extern const char kTFLiteLanguageDetectionDescription[];
 
@@ -1696,9 +1696,6 @@
 extern const char kContextualSearchForceCaptionName[];
 extern const char kContextualSearchForceCaptionDescription[];
 
-extern const char kContextualSearchLiteralSearchTapName[];
-extern const char kContextualSearchLiteralSearchTapDescription[];
-
 extern const char kContextualSearchLongpressResolveName[];
 extern const char kContextualSearchLongpressResolveDescription[];
 
@@ -2956,6 +2953,9 @@
 extern const char kTouchscreenCalibrationName[];
 extern const char kTouchscreenCalibrationDescription[];
 
+extern const char kTrafficCountersHandlerEnabledName[];
+extern const char kTrafficCountersHandlerEnabledDescription[];
+
 extern const char kTrafficCountersSettingsUiName[];
 extern const char kTrafficCountersSettingsUiDescription[];
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 0baa546..f61ed30 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -206,7 +206,6 @@
     &kContextualSearchDebug,
     &kContextualSearchDelayedIntelligence,
     &kContextualSearchForceCaption,
-    &kContextualSearchLiteralSearchTap,
     &kContextualSearchLongpressResolve,
     &kContextualSearchMlTapSuppression,
     &KContextualSearchNewSettings,
@@ -246,7 +245,6 @@
     &kLensCameraAssistedSearch,
     &kNewWindowAppMenu,
     &kOfflineIndicatorV2,
-    &kOfflineMeasurementsBackgroundTask,
     &kPageAnnotationsService,
     &kBookmarksImprovedSaveFlow,
     &kBookmarksRefresh,
@@ -491,7 +489,7 @@
     "CCTResizableForFirstParties", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kCCTResizableForThirdParties{
-    "CCTResizableForThirdParties", base::FEATURE_DISABLED_BY_DEFAULT};
+    "CCTResizableForThirdParties", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kCCTResourcePrefetch{"CCTResourcePrefetch",
                                          base::FEATURE_ENABLED_BY_DEFAULT};
@@ -555,9 +553,6 @@
 const base::Feature kContextualSearchForceCaption{
     "ContextualSearchForceCaption", base::FEATURE_DISABLED_BY_DEFAULT};
 
-const base::Feature kContextualSearchLiteralSearchTap{
-    "ContextualSearchLiteralSearchTap", base::FEATURE_DISABLED_BY_DEFAULT};
-
 const base::Feature kContextualSearchLongpressResolve{
     "ContextualSearchLongpressResolve", base::FEATURE_ENABLED_BY_DEFAULT};
 
@@ -686,9 +681,6 @@
 const base::Feature kOfflineIndicatorV2{"OfflineIndicatorV2",
                                         base::FEATURE_ENABLED_BY_DEFAULT};
 
-const base::Feature kOfflineMeasurementsBackgroundTask{
-    "OfflineMeasurementsBackgroundTask", base::FEATURE_DISABLED_BY_DEFAULT};
-
 const base::Feature kPageAnnotationsService{"PageAnnotationsService",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index 1771bb1..ca71cc7 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -68,7 +68,6 @@
 extern const base::Feature kContextualSearchDebug;
 extern const base::Feature kContextualSearchDelayedIntelligence;
 extern const base::Feature kContextualSearchForceCaption;
-extern const base::Feature kContextualSearchLiteralSearchTap;
 extern const base::Feature kContextualSearchLongpressResolve;
 extern const base::Feature kContextualSearchMlTapSuppression;
 extern const base::Feature KContextualSearchNewSettings;
@@ -115,7 +114,6 @@
 extern const base::Feature kLensCameraAssistedSearch;
 extern const base::Feature kNewWindowAppMenu;
 extern const base::Feature kOfflineIndicatorV2;
-extern const base::Feature kOfflineMeasurementsBackgroundTask;
 extern const base::Feature kPageAnnotationsService;
 extern const base::Feature kBookmarksImprovedSaveFlow;
 extern const base::Feature kBookmarksRefresh;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
index c07010d..27e08ce 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -88,7 +88,6 @@
                     .put(ChromeFeatureList.CCT_INCOGNITO_AVAILABLE_TO_THIRD_PARTY, false)
                     .put(ChromeFeatureList.READ_LATER, false)
                     .put(ChromeFeatureList.CCT_REMOVE_REMOTE_VIEW_IDS, true)
-                    .put(ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK, false)
                     .put(ChromeFeatureList.CCT_INCOGNITO, true)
                     .put(ChromeFeatureList.EXPERIMENTS_FOR_AGSA, true)
                     .put(ChromeFeatureList.APP_MENU_MOBILE_SITE_OPTION, false)
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 1844b5be..a392f75 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -284,8 +284,6 @@
     public static final String CONTEXTUAL_SEARCH_DELAYED_INTELLIGENCE =
             "ContextualSearchDelayedIntelligence";
     public static final String CONTEXTUAL_SEARCH_FORCE_CAPTION = "ContextualSearchForceCaption";
-    public static final String CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP =
-            "ContextualSearchLiteralSearchTap";
     public static final String CONTEXTUAL_SEARCH_ML_TAP_SUPPRESSION =
             "ContextualSearchMlTapSuppression";
     public static final String CONTEXTUAL_SEARCH_NEW_SETTINGS = "ContextualSearchNewSettings";
@@ -401,8 +399,6 @@
     public static final String NEW_WINDOW_APP_MENU = "NewWindowAppMenu";
     public static final String OFFLINE_INDICATOR = "OfflineIndicator";
     public static final String OFFLINE_INDICATOR_V2 = "OfflineIndicatorV2";
-    public static final String OFFLINE_MEASUREMENTS_BACKGROUND_TASK =
-            "OfflineMeasurementsBackgroundTask";
     public static final String OFFLINE_PAGES_DESCRIPTIVE_FAIL_STATUS =
             "OfflinePagesDescriptiveFailStatus";
     public static final String OFFLINE_PAGES_DESCRIPTIVE_PENDING_STATUS =
diff --git a/chrome/browser/global_keyboard_shortcuts_mac.mm b/chrome/browser/global_keyboard_shortcuts_mac.mm
index 7a91a0f..eb0dbf9 100644
--- a/chrome/browser/global_keyboard_shortcuts_mac.mm
+++ b/chrome/browser/global_keyboard_shortcuts_mac.mm
@@ -174,7 +174,6 @@
     {true,  false, true,  false, kVK_ANSI_F,            IDC_FULLSCREEN},
 
     // Special shortcuts for Zoom in and out.
-    {true,  false, false, false, kVK_ANSI_Equal,        IDC_ZOOM_PLUS},
     {true,  false, false, false, kVK_ANSI_KeypadPlus,   IDC_ZOOM_PLUS},
     {true,  false, false, false, kVK_ANSI_KeypadMinus,  IDC_ZOOM_MINUS},
   });
diff --git a/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm b/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
index 49f42bf2..a58bc040 100644
--- a/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
+++ b/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
@@ -174,7 +174,4 @@
   const int cmdMinusFromKeypad =
       CommandForKeys(kVK_ANSI_KeypadMinus, CommandKeyState::kDown);
   EXPECT_EQ(cmdMinusFromKeypad, zoomOut);
-
-  const int cmdEquals = CommandForKeys(kVK_ANSI_Equal, CommandKeyState::kDown);
-  EXPECT_EQ(cmdEquals, zoomIn);
 }
diff --git a/chrome/browser/infobars/infobars_browsertest.cc b/chrome/browser/infobars/infobars_browsertest.cc
index 55beec48..4b831c9 100644
--- a/chrome/browser/infobars/infobars_browsertest.cc
+++ b/chrome/browser/infobars/infobars_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <tuple>
 #include <utility>
 
 #include "base/callback_helpers.h"
@@ -224,7 +225,7 @@
       break;
 
     case IBD::EXTENSION_DEV_TOOLS_INFOBAR_DELEGATE:
-      (void)extensions::ExtensionDevToolsInfoBarDelegate::Create(
+      std::ignore = extensions::ExtensionDevToolsInfoBarDelegate::Create(
           "id", "Extension", base::DoNothing());
       break;
 
diff --git a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc
index 487bdbb..8dca009 100644
--- a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc
+++ b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/lacros/lacros_extension_apps_controller.h"
 #include "chrome/browser/lacros/lacros_extension_apps_publisher.h"
 #include "chrome/browser/lacros/lacros_memory_pressure_evaluator.h"
+#include "chrome/browser/lacros/launcher_search/search_controller_lacros.h"
 #include "chrome/browser/lacros/screen_orientation_delegate_lacros.h"
 #include "chrome/browser/lacros/standalone_browser_test_controller.h"
 #include "chrome/browser/lacros/task_manager_lacros.h"
@@ -40,6 +41,7 @@
       std::make_unique<crosapi::WebPageInfoProviderLacros>();
   screen_orientation_delegate_ =
       std::make_unique<ScreenOrientationDelegateLacros>();
+  search_controller_ = std::make_unique<crosapi::SearchControllerLacros>();
 
   memory_pressure::MultiSourceMemoryPressureMonitor* monitor =
       static_cast<memory_pressure::MultiSourceMemoryPressureMonitor*>(
diff --git a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h
index 7a56eac7..ac4dbe7 100644
--- a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h
+++ b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h
@@ -23,6 +23,7 @@
 class StandaloneBrowserTestController;
 
 namespace crosapi {
+class SearchControllerLacros;
 class TaskManagerLacros;
 class WebPageInfoProviderLacros;
 }  // namespace crosapi
@@ -53,6 +54,9 @@
   // Handles browser action requests from ash-chrome.
   std::unique_ptr<BrowserServiceLacros> browser_service_;
 
+  // Handles search queries from ash-chrome.
+  std::unique_ptr<crosapi::SearchControllerLacros> search_controller_;
+
   // Handles task manager crosapi from ash for sending lacros tasks to ash.
   std::unique_ptr<crosapi::TaskManagerLacros> task_manager_provider_;
 
diff --git a/chrome/browser/lacros/launcher_search/OWNERS b/chrome/browser/lacros/launcher_search/OWNERS
new file mode 100644
index 0000000..5b86ca73
--- /dev/null
+++ b/chrome/browser/lacros/launcher_search/OWNERS
@@ -0,0 +1,3 @@
+tby@chromium.org
+thanhdng@chromium.org
+wrong@chromium.org
diff --git a/chrome/browser/lacros/launcher_search/search_controller_lacros.cc b/chrome/browser/lacros/launcher_search/search_controller_lacros.cc
new file mode 100644
index 0000000..c5caefb
--- /dev/null
+++ b/chrome/browser/lacros/launcher_search/search_controller_lacros.cc
@@ -0,0 +1,32 @@
+// Copyright 2022 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 "chrome/browser/lacros/launcher_search/search_controller_lacros.h"
+
+#include <utility>
+
+#include "chromeos/lacros/lacros_service.h"
+
+namespace crosapi {
+
+SearchControllerLacros::SearchControllerLacros() {
+  chromeos::LacrosService* service = chromeos::LacrosService::Get();
+  if (!service->IsAvailable<mojom::SearchControllerRegistry>())
+    return;
+  service->GetRemote<mojom::SearchControllerRegistry>()
+      ->RegisterSearchController(receiver_.BindNewPipeAndPassRemote());
+}
+
+SearchControllerLacros::~SearchControllerLacros() = default;
+
+void SearchControllerLacros::Search(const std::u16string& query,
+                                    SearchCallback callback) {
+  // Reset the remote and send a new pending receiver to ash.
+  publisher_.reset();
+  std::move(callback).Run(publisher_.BindNewEndpointAndPassReceiver());
+
+  // TODO(crbug/1228587): Fill the results here.
+}
+
+}  // namespace crosapi
diff --git a/chrome/browser/lacros/launcher_search/search_controller_lacros.h b/chrome/browser/lacros/launcher_search/search_controller_lacros.h
new file mode 100644
index 0000000..f808429
--- /dev/null
+++ b/chrome/browser/lacros/launcher_search/search_controller_lacros.h
@@ -0,0 +1,37 @@
+// Copyright 2022 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 CHROME_BROWSER_LACROS_LAUNCHER_SEARCH_SEARCH_CONTROLLER_LACROS_H_
+#define CHROME_BROWSER_LACROS_LAUNCHER_SEARCH_SEARCH_CONTROLLER_LACROS_H_
+
+#include <string>
+
+#include "base/memory/weak_ptr.h"
+#include "chromeos/crosapi/mojom/launcher_search.mojom.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+
+namespace crosapi {
+
+// Implements crosapi interface for launcher search controller.
+class SearchControllerLacros : public mojom::SearchController {
+ public:
+  SearchControllerLacros();
+  SearchControllerLacros(const SearchControllerLacros&) = delete;
+  SearchControllerLacros& operator=(const SearchControllerLacros&) = delete;
+  ~SearchControllerLacros() override;
+
+ private:
+  // mojom::SearchController:
+  void Search(const std::u16string& query, SearchCallback callback) override;
+
+  mojo::AssociatedRemote<mojom::SearchResultsPublisher> publisher_;
+  mojo::Receiver<mojom::SearchController> receiver_{this};
+
+  base::WeakPtrFactory<SearchControllerLacros> weak_ptr_factory_{this};
+};
+
+}  // namespace crosapi
+
+#endif  // CHROME_BROWSER_LACROS_LAUNCHER_SEARCH_SEARCH_CONTROLLER_LACROS_H_
diff --git a/chrome/browser/lazyload/lazyload_browsertest.cc b/chrome/browser/lazyload/lazyload_browsertest.cc
deleted file mode 100644
index bd4a761..0000000
--- a/chrome/browser/lazyload/lazyload_browsertest.cc
+++ /dev/null
@@ -1,405 +0,0 @@
-// Copyright 2019 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/bind.h"
-#include "base/run_loop.h"
-#include "base/strings/stringprintf.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/threading/thread_restrictions.h"
-#include "build/build_config.h"
-#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h"
-#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
-#include "chrome/browser/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h"
-#include "chrome/browser/prefetch/no_state_prefetch/prerender_test_utils.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_io_data.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "components/data_use_measurement/core/data_use_user_data.h"
-#include "components/no_state_prefetch/browser/no_state_prefetch_handle.h"
-#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
-#include "components/no_state_prefetch/common/no_state_prefetch_final_status.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_features.h"
-#include "content/public/common/referrer.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/browser_test_base.h"
-#include "content/public/test/browser_test_utils.h"
-#include "net/dns/mock_host_resolver.h"
-#include "net/nqe/effective_connection_type.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "net/test/embedded_test_server/http_request.h"
-#include "net/test/embedded_test_server/http_response.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class LazyLoadBrowserTest : public InProcessBrowserTest {
- protected:
-  void SetUpOnMainThread() override {
-    InProcessBrowserTest::SetUpOnMainThread();
-    host_resolver()->AddRule("*", "127.0.0.1");
-  }
-  void SetUp() override {
-    scoped_feature_list_.InitWithFeaturesAndParameters(
-        {{features::kLazyImageLoading,
-          {{"lazy_image_first_k_fully_load",
-            base::StringPrintf("%s:0,%s:0,%s:0,%s:0,%s:0,%s:0",
-                               net::kEffectiveConnectionTypeUnknown,
-                               net::kEffectiveConnectionTypeOffline,
-                               net::kEffectiveConnectionTypeSlow2G,
-                               net::kEffectiveConnectionType2G,
-                               net::kEffectiveConnectionType3G,
-                               net::kEffectiveConnectionType4G)}}}},
-        {});
-    InProcessBrowserTest::SetUp();
-  }
-
-  void EnableDataSaver(bool enabled) {
-    data_reduction_proxy::DataReductionProxySettings::
-        SetDataSaverEnabledForTesting(browser()->profile()->GetPrefs(),
-                                      enabled);
-    base::RunLoop().RunUntilIdle();
-  }
-
-  content::EvalJsResult WaitForElementLoad(content::WebContents* contents,
-                                           const char* element_id) {
-    return content::EvalJs(contents, base::StringPrintf(R"JS(
-              new Promise((resolve, reject) => {
-                let e = document.getElementById('%s');
-                if (loaded_ids.includes(e.id)) {
-                  resolve(true);
-                } else {
-                  e.addEventListener('load', function() {
-                    resolve(true);
-                  });
-                }
-              });)JS",
-                                                        element_id));
-  }
-
-  content::EvalJsResult ScrollToAndWaitForElementLoad(
-      content::WebContents* contents,
-      const char* element_id) {
-    return content::EvalJs(contents, base::StringPrintf(R"JS(
-              new Promise((resolve, reject) => {
-                let e = document.getElementById('%s');
-                e.scrollIntoView();
-                if (loaded_ids.includes(e.id)) {
-                  resolve(true);
-                } else {
-                  e.addEventListener('load', function() {
-                    resolve(true);
-                  });
-                }
-              });)JS",
-                                                        element_id));
-  }
-
-  content::EvalJsResult IsElementLoaded(content::WebContents* contents,
-                                        const char* element_id) {
-    return content::EvalJs(
-        contents, base::StringPrintf("loaded_ids.includes('%s');", element_id));
-  }
-
-  // Sets up test pages with in-viewport and below-viewport cross-origin frames.
-  void SetUpLazyLoadFrameTestPage() {
-    base::ScopedAllowBlockingForTesting scoped_allow_blocking;
-    cross_origin_server_.ServeFilesFromSourceDirectory(GetChromeTestDataDir());
-    ASSERT_TRUE(cross_origin_server_.Start());
-
-    embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
-        [](uint16_t cross_origin_port,
-           const net::test_server::HttpRequest& request)
-            -> std::unique_ptr<net::test_server::HttpResponse> {
-          auto response =
-              std::make_unique<net::test_server::BasicHttpResponse>();
-          if (request.relative_url == "/mainpage.html") {
-            response->set_content(base::StringPrintf(
-                R"HTML(
-          <body>
-            <script>
-            let loaded_ids = new Array();
-            </script>
-
-            <iframe id="atf_auto" src="http://bar.com:%d/simple.html?auto"
-              width="100" height="100"
-              onload="loaded_ids.push(this.id); console.log(this.id);">
-            </iframe>
-            <iframe id="atf_lazy" src="http://bar.com:%d/simple.html?lazy"
-              width="100" height="100" loading="lazy"
-              onload="loaded_ids.push(this.id); console.log(this.id);">
-            </iframe>
-            <iframe id="atf_eager" src="http://bar.com:%d/simple.html?eager"
-              width="100" height="100" loading="eager"
-              onload="loaded_ids.push(this.id); console.log(this.id);">
-            </iframe>
-
-            <div style="height:11000px;"></div>
-            Below the viewport cross-origin iframes <br>
-            <iframe id="btf_auto" src="http://bar.com:%d/simple.html?auto&belowviewport"
-              width="100" height="100"
-              onload="loaded_ids.push(this.id); console.log(this.id);">
-            </iframe>
-            <iframe id="btf_lazy" src="http://bar.com:%d/simple.html?lazy&belowviewport"
-              width="100" height="100" loading="lazy"
-              onload="loaded_ids.push(this.id); console.log(this.id);">
-            </iframe>
-            <iframe id="btf_eager" src="http://bar.com:%d/simple.html?eager&belowviewport"
-              width="100" height="100" loading="eager"
-              onload="loaded_ids.push(this.id); console.log(this.id);">
-            </iframe>
-          </body>)HTML",
-                cross_origin_port, cross_origin_port, cross_origin_port,
-                cross_origin_port, cross_origin_port, cross_origin_port));
-          }
-          return response;
-        },
-        cross_origin_server_.port()));
-    ASSERT_TRUE(embedded_test_server()->Start());
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-  net::EmbeddedTestServer cross_origin_server_;
-};
-
-IN_PROC_BROWSER_TEST_F(LazyLoadBrowserTest, CSSBackgroundImageDeferred) {
-  EnableDataSaver(true);
-  ASSERT_TRUE(embedded_test_server()->Start());
-  base::HistogramTester histogram_tester;
-  ui_test_utils::NavigateToURLWithDisposition(
-      browser(),
-      embedded_test_server()->GetURL("/lazyload/css-background-image.html"),
-      WindowOpenDisposition::NEW_FOREGROUND_TAB,
-      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
-
-  base::RunLoop().RunUntilIdle();
-  // Navigate away to finish the histogram recording.
-  ASSERT_TRUE(
-      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  // Verify that nothing is recorded for the image bucket.
-  EXPECT_GE(0, histogram_tester.GetBucketCount(
-                   "DataUse.ContentType.UserTrafficKB",
-                   data_use_measurement::DataUseUserData::IMAGE));
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadBrowserTest, CSSPseudoBackgroundImageLoaded) {
-  EnableDataSaver(true);
-  ASSERT_TRUE(embedded_test_server()->Start());
-  base::HistogramTester histogram_tester;
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), embedded_test_server()->GetURL(
-                     "/lazyload/css-pseudo-background-image.html")));
-
-  base::RunLoop().RunUntilIdle();
-  // Navigate away to finish the histogram recording.
-  ASSERT_TRUE(
-      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  // Verify that the image bucket has substantial kilobytes recorded.
-  EXPECT_GE(30 /* KB */, histogram_tester.GetBucketCount(
-                             "DataUse.ContentType.UserTrafficKB",
-                             data_use_measurement::DataUseUserData::IMAGE));
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadBrowserTest,
-                       LazyLoadImage_DeferredAndLoadedOnScroll) {
-  EnableDataSaver(true);
-
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL test_url(embedded_test_server()->GetURL("/lazyload/img.html"));
-
-  auto* contents = browser()->OpenURL(content::OpenURLParams(
-      test_url, content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
-      ui::PAGE_TRANSITION_TYPED, false));
-  ASSERT_TRUE(content::WaitForLoadStop(contents));
-
-  EXPECT_EQ(true, WaitForElementLoad(contents, "atf_auto"));
-  EXPECT_EQ(true, WaitForElementLoad(contents, "atf_lazy"));
-  EXPECT_EQ(true, WaitForElementLoad(contents, "atf_eager"));
-  EXPECT_EQ(true, WaitForElementLoad(contents, "btf_eager"));
-
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(false, IsElementLoaded(contents, "btf_auto"));
-  EXPECT_EQ(false, IsElementLoaded(contents, "btf_lazy"));
-
-  EXPECT_EQ(true, ScrollToAndWaitForElementLoad(contents, "btf_auto"));
-  EXPECT_EQ(true, ScrollToAndWaitForElementLoad(contents, "btf_lazy"));
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadBrowserTest,
-                       LazyLoadFrame_DeferredAndLoadedOnScroll) {
-  EnableDataSaver(true);
-  SetUpLazyLoadFrameTestPage();
-  GURL test_url(embedded_test_server()->GetURL("/mainpage.html"));
-
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
-  auto* contents = browser()->tab_strip_model()->GetActiveWebContents();
-
-  EXPECT_EQ(true, WaitForElementLoad(contents, "atf_auto"));
-  EXPECT_EQ(true, WaitForElementLoad(contents, "atf_lazy"));
-  EXPECT_EQ(true, WaitForElementLoad(contents, "atf_eager"));
-  EXPECT_EQ(true, WaitForElementLoad(contents, "btf_eager"));
-
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(false, IsElementLoaded(contents, "btf_auto"));
-  EXPECT_EQ(false, IsElementLoaded(contents, "btf_lazy"));
-
-  EXPECT_EQ(true, ScrollToAndWaitForElementLoad(contents, "btf_auto"));
-  EXPECT_EQ(true, ScrollToAndWaitForElementLoad(contents, "btf_lazy"));
-}
-
-// Tests that need to verify lazyload should be disabled in certain cases.
-class LazyLoadDisabledBrowserTest : public LazyLoadBrowserTest {
- public:
-  enum class ExpectedLazyLoadAction {
-    kOff,           // All iframes and images should load.
-    kExplicitOnly,  // Only the above viewport elements and below viewport
-                    // explicit lazyload elements will load.
-  };
-
-  content::WebContents* CreateBackgroundWebContents(Browser* browser,
-                                                    const GURL& url) {
-    return browser->OpenURL(content::OpenURLParams(
-        url, content::Referrer(), WindowOpenDisposition::NEW_BACKGROUND_TAB,
-        ui::PAGE_TRANSITION_TYPED, false));
-  }
-
-  void VerifyLazyLoadFrameBehavior(
-      content::WebContents* web_contents,
-      ExpectedLazyLoadAction expected_lazy_load_action) {
-    EXPECT_TRUE(content::WaitForLoadStop(web_contents));
-
-    EXPECT_EQ(true, WaitForElementLoad(web_contents, "atf_auto"));
-    EXPECT_EQ(true, WaitForElementLoad(web_contents, "atf_lazy"));
-    EXPECT_EQ(true, WaitForElementLoad(web_contents, "atf_eager"));
-    EXPECT_EQ(true, WaitForElementLoad(web_contents, "btf_eager"));
-
-    base::RunLoop().RunUntilIdle();
-
-    switch (expected_lazy_load_action) {
-      case ExpectedLazyLoadAction::kOff:
-        EXPECT_EQ(true, IsElementLoaded(web_contents, "btf_auto"));
-        EXPECT_EQ(true, IsElementLoaded(web_contents, "btf_lazy"));
-        break;
-
-      case ExpectedLazyLoadAction::kExplicitOnly:
-        EXPECT_EQ(true, IsElementLoaded(web_contents, "btf_auto"));
-        EXPECT_EQ(false, IsElementLoaded(web_contents, "btf_lazy"));
-        break;
-    }
-  }
-
-  void VerifyLazyLoadImageBehavior(
-      content::WebContents* web_contents,
-      ExpectedLazyLoadAction expected_lazy_load_action) {
-    ASSERT_TRUE(content::WaitForLoadStop(web_contents));
-
-    EXPECT_EQ(true, WaitForElementLoad(web_contents, "atf_auto"));
-    EXPECT_EQ(true, WaitForElementLoad(web_contents, "atf_lazy"));
-    EXPECT_EQ(true, WaitForElementLoad(web_contents, "atf_eager"));
-    EXPECT_EQ(true, WaitForElementLoad(web_contents, "btf_eager"));
-
-    base::RunLoop().RunUntilIdle();
-
-    switch (expected_lazy_load_action) {
-      case ExpectedLazyLoadAction::kOff:
-        EXPECT_EQ(true, IsElementLoaded(web_contents, "btf_auto"));
-        EXPECT_EQ(true, IsElementLoaded(web_contents, "btf_lazy"));
-        break;
-
-      case ExpectedLazyLoadAction::kExplicitOnly:
-        EXPECT_EQ(true, IsElementLoaded(web_contents, "btf_auto"));
-        EXPECT_EQ(false, IsElementLoaded(web_contents, "btf_lazy"));
-        break;
-    }
-  }
-};
-
-IN_PROC_BROWSER_TEST_F(LazyLoadDisabledBrowserTest,
-                       LazyLoadImage_DisabledInBackgroundTab) {
-  EnableDataSaver(true);
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL test_url(embedded_test_server()->GetURL("/lazyload/img.html"));
-  auto* web_contents = CreateBackgroundWebContents(browser(), test_url);
-  VerifyLazyLoadImageBehavior(web_contents, ExpectedLazyLoadAction::kOff);
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadDisabledBrowserTest,
-                       LazyLoadImage_DisabledInIncognito) {
-  EnableDataSaver(true);
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL test_url(embedded_test_server()->GetURL("/lazyload/img.html"));
-  auto* incognito_web_contents = browser()->OpenURL(content::OpenURLParams(
-      test_url, content::Referrer(), WindowOpenDisposition::OFF_THE_RECORD,
-      ui::PAGE_TRANSITION_TYPED, false));
-  VerifyLazyLoadImageBehavior(incognito_web_contents,
-                              ExpectedLazyLoadAction::kExplicitOnly);
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadDisabledBrowserTest,
-                       LazyLoadFrame_DisabledInBackgroundTab) {
-  EnableDataSaver(true);
-  SetUpLazyLoadFrameTestPage();
-  GURL test_url(embedded_test_server()->GetURL("/mainpage.html"));
-  auto* web_contents = CreateBackgroundWebContents(browser(), test_url);
-  VerifyLazyLoadFrameBehavior(web_contents, ExpectedLazyLoadAction::kOff);
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadDisabledBrowserTest,
-                       LazyLoadFrame_DisabledInIncognito) {
-  EnableDataSaver(true);
-  SetUpLazyLoadFrameTestPage();
-  GURL test_url(embedded_test_server()->GetURL("/mainpage.html"));
-  auto* incognito_web_contents = browser()->OpenURL(content::OpenURLParams(
-      test_url, content::Referrer(), WindowOpenDisposition::OFF_THE_RECORD,
-      ui::PAGE_TRANSITION_TYPED, false));
-  VerifyLazyLoadFrameBehavior(incognito_web_contents,
-                              ExpectedLazyLoadAction::kExplicitOnly);
-}
-
-class LazyLoadPrerenderBrowserTest
-    : public prerender::test_utils::PrerenderInProcessBrowserTest {
- public:
-  void SetUpOnMainThread() override {
-    prerender::test_utils::PrerenderInProcessBrowserTest::SetUpOnMainThread();
-  }
-  void EnableDataSaver(bool enabled) {
-    data_reduction_proxy::DataReductionProxySettings::
-        SetDataSaverEnabledForTesting(browser()->profile()->GetPrefs(),
-                                      enabled);
-    base::RunLoop().RunUntilIdle();
-  }
-};
-
-IN_PROC_BROWSER_TEST_F(LazyLoadPrerenderBrowserTest, ImagesIgnored) {
-  EnableDataSaver(true);
-  UseHttpsSrcServer();
-
-  std::unique_ptr<prerender::test_utils::TestPrerender> test_prerender =
-      no_state_prefetch_contents_factory()->ExpectNoStatePrefetchContents(
-          prerender::FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
-
-  std::unique_ptr<prerender::NoStatePrefetchHandle> no_state_prefetch_handle =
-      GetNoStatePrefetchManager()->StartPrefetchingFromOmnibox(
-          src_server()->GetURL("/lazyload/img.html"),
-          GetSessionStorageNamespace(), gfx::Size(640, 480));
-
-  ASSERT_EQ(no_state_prefetch_handle->contents(), test_prerender->contents());
-
-  test_prerender->WaitForStop();
-  for (const auto* url :
-       {"/lazyload/img.html", "/lazyload/images/fruit1.jpg?auto",
-        "/lazyload/images/fruit1.jpg?lazy", "/lazyload/images/fruit1.jpg?eager",
-        "/lazyload/images/fruit2.jpg?auto", "/lazyload/images/fruit2.jpg?lazy",
-        "/lazyload/images/fruit2.jpg?eager"}) {
-    WaitForRequestCount(src_server()->GetURL(url), 1);
-  }
-}
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_media_sink_util.cc b/chrome/browser/media/router/discovery/access_code/access_code_media_sink_util.cc
index 30650ca..3affdb9 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_media_sink_util.cc
+++ b/chrome/browser/media/router/discovery/access_code/access_code_media_sink_util.cc
@@ -11,8 +11,8 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
-#include "chrome/browser/media/router/discovery/mdns/media_sink_util.h"
 #include "components/cast_channel/cast_socket.h"
+#include "components/media_router/common/discovery/media_sink_internal.h"
 #include "components/media_router/common/mojom/media_router.mojom.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/ip_address.h"
@@ -88,9 +88,9 @@
 
   CastSinkExtraData extra_data;
   const std::string& port = discovery_device.network_info().port();
-  int port_value = 0;
+  int port_value = kCastControlPort;
   // Convert port from string to int
-  if (port.empty() || !base::StringToInt(port, &port_value)) {
+  if (!port.empty() && !base::StringToInt(port, &port_value)) {
     return std::make_pair(absl::nullopt,
                           CreateCastMediaSinkResult::kMissingOrInvalidPort);
   }
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_media_sink_util_unittest.cc b/chrome/browser/media/router/discovery/access_code/access_code_media_sink_util_unittest.cc
index fde4f53..f9c5126 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_media_sink_util_unittest.cc
+++ b/chrome/browser/media/router/discovery/access_code/access_code_media_sink_util_unittest.cc
@@ -8,23 +8,17 @@
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
 #include "chrome/browser/media/router/discovery/access_code/access_code_test_util.h"
+#include "chrome/browser/media/router/discovery/mdns/media_sink_util.h"
 #include "chrome/test/base/testing_browser_process.h"
+#include "components/cast_channel/cast_socket.h"
 #include "content/public/test/browser_task_environment.h"
 #include "net/base/ip_address.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using media_router::BuildDiscoveryDeviceProto;
-using media_router::CreateAccessCodeMediaSink;
-using media_router::CreateCastMediaSinkResult;
-using media_router::kExpectedDisplayName;
-using media_router::kExpectedIpV4;
-using media_router::kExpectedIpV6;
-using media_router::kExpectedPort;
-using media_router::kExpectedSinkId;
-using DiscoveryDevice = chrome_browser_media::proto::DiscoveryDevice;
-using media_router::MediaSinkInternal;
+namespace media_router {
 
+using DiscoveryDevice = chrome_browser_media::proto::DiscoveryDevice;
 using testing::FieldsAre;
 
 class AccessCodeMediaSinkUtilTest : public testing::Test {
@@ -106,9 +100,38 @@
 
 TEST_F(AccessCodeMediaSinkUtilTest, MissingPort) {
   DiscoveryDevice discovery_device_proto = BuildDiscoveryDeviceProto();
-  discovery_device_proto.mutable_network_info()->set_port("");
-  EXPECT_EQ(CreateAccessCodeMediaSink(discovery_device_proto).second,
-            CreateCastMediaSinkResult::kMissingOrInvalidPort);
+
+  media_router::MediaSinkInternal expected_sink_internal;
+  media_router::CastSinkExtraData expected_extra_data;
+
+  expected_extra_data.capabilities =
+      cast_channel::VIDEO_OUT | cast_channel::VIDEO_IN |
+      cast_channel::AUDIO_OUT | cast_channel::AUDIO_IN | cast_channel::DEV_MODE;
+  net::IPAddress expected_ip;
+
+  // Must use equality to bypass `warn_unused_result`.
+  EXPECT_EQ(true, expected_ip.AssignFromIPLiteral(kExpectedIpV6));
+
+  discovery_device_proto.mutable_network_info()->clear_port();
+
+  expected_extra_data.ip_endpoint =
+      net::IPEndPoint(expected_ip, kCastControlPort);
+  expected_extra_data.discovered_by_access_code = true;
+
+  media_router::MediaSink expected_sink(
+      base::StringPrintf("cast:<%s>", kExpectedSinkId), kExpectedDisplayName,
+      media_router::GetCastSinkIconType(expected_extra_data.capabilities),
+      media_router::mojom::MediaRouteProviderId::CAST);
+
+  expected_sink_internal.set_sink(expected_sink);
+  expected_sink_internal.set_cast_data(expected_extra_data);
+
+  std::pair<absl::optional<MediaSinkInternal>, CreateCastMediaSinkResult>
+      constructed_pair = CreateAccessCodeMediaSink(discovery_device_proto);
+
+  EXPECT_EQ(constructed_pair.second, CreateCastMediaSinkResult::kOk);
+
+  EXPECT_EQ(constructed_pair.first.value(), expected_sink_internal);
 }
 
 TEST_F(AccessCodeMediaSinkUtilTest, InvalidPort) {
@@ -132,8 +155,9 @@
   media_router::MediaSinkInternal expected_sink_internal;
   media_router::CastSinkExtraData expected_extra_data;
 
-  // This is the equiv to all capabilities = true.
-  expected_extra_data.capabilities = 31;
+  expected_extra_data.capabilities =
+      cast_channel::VIDEO_OUT | cast_channel::VIDEO_IN |
+      cast_channel::AUDIO_OUT | cast_channel::AUDIO_IN | cast_channel::DEV_MODE;
   net::IPAddress expected_ip;
 
   // Must use equality to bypass `warn_unused_result`.
@@ -159,3 +183,5 @@
 
   EXPECT_EQ(constructed_pair.first.value(), expected_sink_internal);
 }
+
+}  // namespace media_router
diff --git a/chrome/browser/media/router/discovery/mdns/media_sink_util.h b/chrome/browser/media/router/discovery/mdns/media_sink_util.h
index eaba2a3..ee40ee7 100644
--- a/chrome/browser/media/router/discovery/mdns/media_sink_util.h
+++ b/chrome/browser/media/router/discovery/mdns/media_sink_util.h
@@ -16,9 +16,6 @@
 // The DNS-SD service type for Cast devices.
 static constexpr char kCastServiceType[] = "_googlecast._tcp.local";
 
-// Default Cast control port to open Cast Socket.
-static constexpr int kCastControlPort = 8009;
-
 // Returns the icon type to use according to |capabilities|. |capabilities| is
 // a bit set of cast_channel::CastDeviceCapabilities in CastSinkExtraData.
 SinkIconType GetCastSinkIconType(uint8_t capabilities);
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
index 157782c..618fcb0 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -596,9 +596,7 @@
   // Register synthetic Finch trials proposed by PartitionAlloc.
   auto pa_trials = base::allocator::ProposeSyntheticFinchTrials(is_enterprise);
   for (auto& trial : pa_trials) {
-    std::string trial_name;
-    std::string group_name;
-    std::tie(trial_name, group_name) = trial;
+    auto [trial_name, group_name] = trial;
     ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(trial_name,
                                                               group_name);
   }
diff --git a/chrome/browser/net/dns_probe_service_factory.cc b/chrome/browser/net/dns_probe_service_factory.cc
index fa346e9..47013d8 100644
--- a/chrome/browser/net/dns_probe_service_factory.cc
+++ b/chrome/browser/net/dns_probe_service_factory.cc
@@ -31,7 +31,6 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
-#include "net/dns/public/dns_over_https_server_config.h"
 #include "net/dns/public/dns_protocol.h"
 #include "net/dns/public/secure_dns_mode.h"
 #include "services/network/public/mojom/network_service.mojom.h"
diff --git a/chrome/browser/net/secure_dns_policy_handler.cc b/chrome/browser/net/secure_dns_policy_handler.cc
index 627f470a..f880be98 100644
--- a/chrome/browser/net/secure_dns_policy_handler.cc
+++ b/chrome/browser/net/secure_dns_policy_handler.cc
@@ -10,7 +10,6 @@
 #include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "chrome/browser/net/secure_dns_config.h"
-#include "chrome/browser/net/secure_dns_util.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/common/pref_names.h"
 #include "components/policy/core/browser/policy_error_map.h"
@@ -18,6 +17,7 @@
 #include "components/policy/policy_constants.h"
 #include "components/prefs/pref_value_map.h"
 #include "components/strings/grit/components_strings.h"
+#include "net/dns/public/dns_over_https_config.h"
 #include "net/dns/public/util.h"
 
 namespace policy {
@@ -64,22 +64,22 @@
                      base::Value::GetTypeName(base::Value::Type::STRING));
     templates_is_applicable = false;
   } else {
-    // Templates is set and is a string.
     const std::string& templates_str = templates->GetString();
 
-    if (templates_str.size() != 0 && !mode) {
-      errors->AddError(key::kDnsOverHttpsTemplates,
-                       IDS_POLICY_SECURE_DNS_TEMPLATES_UNSET_MODE_ERROR);
-    } else if (templates_str.size() != 0 && !mode_is_applicable) {
-      errors->AddError(key::kDnsOverHttpsTemplates,
-                       IDS_POLICY_SECURE_DNS_TEMPLATES_INVALID_MODE_ERROR);
-    } else if (templates_str.size() != 0 &&
-               mode_str == SecureDnsConfig::kModeOff) {
-      errors->AddError(key::kDnsOverHttpsTemplates,
-                       IDS_POLICY_SECURE_DNS_TEMPLATES_IRRELEVANT_MODE_ERROR);
-    } else if (!chrome_browser_net::secure_dns::IsValidGroup(templates_str)) {
-      errors->AddError(key::kDnsOverHttpsTemplates,
-                       IDS_POLICY_SECURE_DNS_TEMPLATES_INVALID_ERROR);
+    if (!templates_str.empty()) {
+      if (!mode) {
+        errors->AddError(key::kDnsOverHttpsTemplates,
+                         IDS_POLICY_SECURE_DNS_TEMPLATES_UNSET_MODE_ERROR);
+      } else if (!mode_is_applicable) {
+        errors->AddError(key::kDnsOverHttpsTemplates,
+                         IDS_POLICY_SECURE_DNS_TEMPLATES_INVALID_MODE_ERROR);
+      } else if (mode_str == SecureDnsConfig::kModeOff) {
+        errors->AddError(key::kDnsOverHttpsTemplates,
+                         IDS_POLICY_SECURE_DNS_TEMPLATES_IRRELEVANT_MODE_ERROR);
+      } else if (!net::DnsOverHttpsConfig::FromString(templates_str)) {
+        errors->AddError(key::kDnsOverHttpsTemplates,
+                         IDS_POLICY_SECURE_DNS_TEMPLATES_INVALID_ERROR);
+      }
     }
   }
 
diff --git a/chrome/browser/net/secure_dns_util.cc b/chrome/browser/net/secure_dns_util.cc
index 778409d..f96ebc49 100644
--- a/chrome/browser/net/secure_dns_util.cc
+++ b/chrome/browser/net/secure_dns_util.cc
@@ -6,7 +6,6 @@
 
 #include <algorithm>
 #include <string>
-#include <utility>
 
 #include "base/containers/contains.h"
 #include "base/feature_list.h"
@@ -19,11 +18,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "net/dns/public/dns_config_overrides.h"
-#include "net/dns/public/dns_over_https_server_config.h"
 #include "net/dns/public/doh_provider_entry.h"
-#include "net/dns/public/util.h"
-#include "net/third_party/uri_template/uri_template.h"
-#include "url/gurl.h"
 
 namespace chrome_browser_net {
 
@@ -110,7 +105,7 @@
 
 net::DohProviderEntry::List RemoveDisabledProviders(
     const net::DohProviderEntry::List& providers,
-    const std::vector<string>& disabled_providers) {
+    const std::vector<std::string>& disabled_providers) {
   net::DohProviderEntry::List filtered_providers;
   std::copy_if(providers.begin(), providers.end(),
                std::back_inserter(filtered_providers),
@@ -120,21 +115,6 @@
   return filtered_providers;
 }
 
-std::vector<base::StringPiece> SplitGroup(base::StringPiece group) {
-  // Templates in a group are whitespace-separated.
-  return SplitStringPiece(group, " ", base::TRIM_WHITESPACE,
-                          base::SPLIT_WANT_NONEMPTY);
-}
-
-bool IsValidGroup(base::StringPiece group) {
-  // All templates must be valid for the group to be considered valid.
-  std::vector<base::StringPiece> templates = SplitGroup(group);
-  return std::all_of(templates.begin(), templates.end(), [](auto t) {
-    return net::DnsOverHttpsServerConfig::FromString(std::string(t))
-        .has_value();
-  });
-}
-
 void UpdateDropdownHistograms(
     const std::vector<const net::DohProviderEntry*>& providers,
     base::StringPiece old_template,
diff --git a/chrome/browser/net/secure_dns_util.h b/chrome/browser/net/secure_dns_util.h
index e8c787b..d87fd60 100644
--- a/chrome/browser/net/secure_dns_util.h
+++ b/chrome/browser/net/secure_dns_util.h
@@ -38,14 +38,6 @@
     const net::DohProviderEntry::List& providers,
     const std::vector<std::string>& disabled_providers);
 
-// Implements the whitespace-delimited group syntax for DoH templates.
-std::vector<base::StringPiece> SplitGroup(base::StringPiece group);
-
-// Returns true if a group of templates are all valid per
-// net::dns_util::IsValidDohTemplate().  This should be checked before updating
-// stored preferences.
-bool IsValidGroup(base::StringPiece group);
-
 // When the selected template changes, call this function to update the
 // Selected, Unselected, and Ignored histograms for all the included providers,
 // and also for the custom provider option.  If the old or new selection is the
diff --git a/chrome/browser/net/secure_dns_util_unittest.cc b/chrome/browser/net/secure_dns_util_unittest.cc
index 579e25f9..b7743625 100644
--- a/chrome/browser/net/secure_dns_util_unittest.cc
+++ b/chrome/browser/net/secure_dns_util_unittest.cc
@@ -15,6 +15,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/testing_pref_service.h"
 #include "net/dns/public/dns_config_overrides.h"
+#include "net/dns/public/dns_over_https_server_config.h"
 #include "net/dns/public/doh_provider_entry.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -71,24 +72,6 @@
   EXPECT_FALSE(prefs.GetBoolean(kAlternateErrorPagesBackup));
 }
 
-TEST(SecureDnsUtil, SplitGroup) {
-  EXPECT_THAT(SplitGroup("a"), ElementsAre("a"));
-  EXPECT_THAT(SplitGroup("a b"), ElementsAre("a", "b"));
-  EXPECT_THAT(SplitGroup("a \tb\nc"), ElementsAre("a", "b\nc"));
-  EXPECT_THAT(SplitGroup(" \ta b\n"), ElementsAre("a", "b"));
-}
-
-TEST(SecureDnsUtil, IsValidGroup) {
-  EXPECT_TRUE(IsValidGroup(""));
-  EXPECT_TRUE(IsValidGroup("https://valid"));
-  EXPECT_TRUE(IsValidGroup("https://valid https://valid2"));
-
-  EXPECT_FALSE(IsValidGroup("https://valid invalid"));
-  EXPECT_FALSE(IsValidGroup("invalid https://valid"));
-  EXPECT_FALSE(IsValidGroup("invalid"));
-  EXPECT_FALSE(IsValidGroup("invalid invalid2"));
-}
-
 TEST(SecureDnsUtil, ApplyDohTemplatePost) {
   std::string post_template("https://valid");
   net::DnsConfigOverrides overrides;
diff --git a/chrome/browser/net/stub_resolver_config_reader.cc b/chrome/browser/net/stub_resolver_config_reader.cc
index c36f9f75..63035047 100644
--- a/chrome/browser/net/stub_resolver_config_reader.cc
+++ b/chrome/browser/net/stub_resolver_config_reader.cc
@@ -31,7 +31,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/network_service_instance.h"
-#include "net/dns/public/dns_over_https_server_config.h"
+#include "net/dns/public/dns_over_https_config.h"
 #include "net/dns/public/secure_dns_mode.h"
 #include "net/dns/public/util.h"
 #include "services/network/public/mojom/host_resolver.mojom.h"
@@ -365,28 +365,18 @@
     }
   }
 
-  std::string doh_templates =
-      local_state_->GetString(prefs::kDnsOverHttpsTemplates);
-  std::vector<net::DnsOverHttpsServerConfig> dns_over_https_servers;
-  if (!doh_templates.empty() && secure_dns_mode != net::SecureDnsMode::kOff) {
-    for (base::StringPiece server_template :
-         chrome_browser_net::secure_dns::SplitGroup(doh_templates)) {
-      auto server_config = net::DnsOverHttpsServerConfig::FromString(
-          std::string(server_template));
-      if (!server_config)
-        continue;
-
-      dns_over_https_servers.push_back(std::move(*server_config));
-    }
+  net::DnsOverHttpsConfig doh_config;
+  if (secure_dns_mode != net::SecureDnsMode::kOff) {
+    doh_config = net::DnsOverHttpsConfig::FromStringLax(
+        local_state_->GetString(prefs::kDnsOverHttpsTemplates));
   }
-
   if (update_network_service) {
     content::GetNetworkService()->ConfigureStubHostResolver(
-        GetInsecureStubResolverEnabled(), secure_dns_mode,
-        dns_over_https_servers, additional_dns_query_types_enabled);
+        GetInsecureStubResolverEnabled(), secure_dns_mode, doh_config.servers(),
+        additional_dns_query_types_enabled);
   }
 
-  return SecureDnsConfig(secure_dns_mode, std::move(dns_over_https_servers),
+  return SecureDnsConfig(secure_dns_mode, doh_config.servers(),
                          forced_management_mode);
 }
 
diff --git a/chrome/browser/offline_pages/android/BUILD.gn b/chrome/browser/offline_pages/android/BUILD.gn
index aad7a57d..32ea448 100644
--- a/chrome/browser/offline_pages/android/BUILD.gn
+++ b/chrome/browser/offline_pages/android/BUILD.gn
@@ -19,21 +19,3 @@
 generate_jni("jni_headers") {
   sources = [ "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchConfiguration.java" ]
 }
-
-generate_jni("native_j_unittests_jni_headers") {
-  testonly = true
-
-  sources = [ "java/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsTestHelper.java" ]
-}
-
-android_library("native_java_unittests") {
-  testonly = true
-
-  deps = [
-    "//base:base_java",
-    "//chrome/browser/preferences:java",
-    "//third_party/android_deps:protobuf_lite_runtime_java",
-  ]
-
-  sources = [ "java/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsTestHelper.java" ]
-}
diff --git a/chrome/browser/offline_pages/android/java/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsTestHelper.java b/chrome/browser/offline_pages/android/java/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsTestHelper.java
deleted file mode 100644
index 6f17199..0000000
--- a/chrome/browser/offline_pages/android/java/src/org/chromium/chrome/browser/offlinepages/measurements/OfflineMeasurementsTestHelper.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2021 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.
-
-package org.chromium.chrome.browser.offlinepages.measurements;
-
-import android.util.Base64;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-
-/**
- * Unit test helper for OfflineMeasurementsPageLoadMetricsObserver.
- */
-public class OfflineMeasurementsTestHelper {
-    @CalledByNative
-    public static void addSystemStateListToPrefs(byte[] encodedSystemStateList) {
-        // Write the encoded system state list directly to prefs.
-        SharedPreferencesManager.getInstance().writeString(
-                ChromePreferenceKeys.OFFLINE_MEASUREMENTS_SYSTEM_STATE_LIST,
-                Base64.encodeToString(encodedSystemStateList, Base64.DEFAULT));
-    }
-}
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.cc b/chrome/browser/offline_pages/android/offline_page_bridge.cc
index 5dc8953..b3940d993 100644
--- a/chrome/browser/offline_pages/android/offline_page_bridge.cc
+++ b/chrome/browser/offline_pages/android/offline_page_bridge.cc
@@ -26,7 +26,6 @@
 #include "base/time/time.h"
 #include "chrome/android/chrome_jni_headers/OfflinePageBridge_jni.h"
 #include "chrome/browser/android/tab_android.h"
-#include "chrome/browser/offline_pages/measurements/proto/system_state.pb.h"
 #include "chrome/browser/offline_pages/offline_page_mhtml_archiver.h"
 #include "chrome/browser/offline_pages/offline_page_model_factory.h"
 #include "chrome/browser/offline_pages/offline_page_tab_helper.h"
@@ -872,28 +871,5 @@
       ConvertUTF8ToJavaString(env, client_id.id));
 }
 
-// static
-offline_measurements_system_state::proto::SystemStateList
-OfflinePageBridge::GetSystemStateListFromOfflineMeasurementsAsString() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-
-  std::string system_state_list_str;
-  JavaByteArrayToString(
-      env,
-      Java_OfflinePageBridge_getSystemStateListFromOfflineMeasurementsAsBytes(
-          env),
-      &system_state_list_str);
-
-  offline_measurements_system_state::proto::SystemStateList system_state_list;
-  system_state_list.ParseFromString(system_state_list_str);
-  return system_state_list;
-}
-
-// static
-void OfflinePageBridge::ReportOfflineMeasurementMetricsToUma() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  Java_OfflinePageBridge_reportOfflineMeasurementMetricsToUmaAndClear(env);
-}
-
 }  // namespace android
 }  // namespace offline_pages
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.h b/chrome/browser/offline_pages/android/offline_page_bridge.h
index 7878038..abaa8b1 100644
--- a/chrome/browser/offline_pages/android/offline_page_bridge.h
+++ b/chrome/browser/offline_pages/android/offline_page_bridge.h
@@ -17,7 +17,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/supports_user_data.h"
-#include "chrome/browser/offline_pages/measurements/proto/system_state.pb.h"
 #include "components/offline_items_collection/core/launch_location.h"
 #include "components/offline_pages/core/background/save_page_request.h"
 #include "components/offline_pages/core/offline_page_item.h"
@@ -54,16 +53,6 @@
   static std::string GetEncodedOriginApp(
       const content::WebContents* web_contents);
 
-  // Gets the persisted metrics created by the
-  // OfflineMeasurementsBackgroundTask.
-  static offline_measurements_system_state::proto::SystemStateList
-  GetSystemStateListFromOfflineMeasurementsAsString();
-
-  // Reports the persisted metrics created by the
-  // OfflineMeasurementsBackgroundTask to UMA. Note that after the metrics are
-  // reported to UMA the persisted state is cleared.
-  static void ReportOfflineMeasurementMetricsToUma();
-
   OfflinePageBridge(JNIEnv* env,
                     SimpleFactoryKey* key,
                     OfflinePageModel* offline_page_model);
diff --git a/chrome/browser/offline_pages/measurements/proto/BUILD.gn b/chrome/browser/offline_pages/measurements/proto/BUILD.gn
deleted file mode 100644
index c069f95..0000000
--- a/chrome/browser/offline_pages/measurements/proto/BUILD.gn
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2021 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.
-
-import("//third_party/protobuf/proto_library.gni")
-
-if (is_android) {
-  import("//build/config/android/rules.gni")
-
-  proto_library("offline_measurements_proto") {
-    sources = [ "system_state.proto" ]
-  }
-
-  proto_java_library("offline_measurements_proto_java") {
-    proto_path = "."
-    sources = [ "system_state.proto" ]
-  }
-}
diff --git a/chrome/browser/offline_pages/measurements/proto/system_state.proto b/chrome/browser/offline_pages/measurements/proto/system_state.proto
deleted file mode 100644
index 80c078da..0000000
--- a/chrome/browser/offline_pages/measurements/proto/system_state.proto
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2021 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.
-
-syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
-option java_package = "org.chromium.chrome.browser.offline_pages.measurements.proto";
-option java_outer_classname = "OfflineMeasurementsProto";
-
-package offline_measurements_system_state.proto;
-
-// This message is used by OfflineMeasurementsBackgroundTask to capture the
-// state of the system for some duration of time.
-message SystemState {
-  // Defined in tools/metrics/histograms/enums.xml. These values are persisted
-  // to logs. Entries should not be renumbered and numeric values should never
-  // be reused. These values are also defined in
-  // OfflineMeasurementsBackgroundTask.
-  enum UserState {
-    INVALID_USER_STATE = 0;
-    PHONE_OFF = 1;
-    NOT_USING_PHONE = 2;
-    USING_PHONE_NOT_CHROME = 3;
-    USING_CHROME = 4;
-  }
-  optional UserState user_state = 1;
-
-  // Defined in tools/metrics/histograms/enums.xml. These values are persisted
-  // to logs. Entries should not be renumbered and numeric values should never
-  // be reused. These values are also defined in
-  // OfflineMeasurementsBackgroundTask.
-  enum ProbeResult {
-    INVALID_PROBE_RESULT = 0;
-    NO_INTERNET = 1;
-    SERVER_ERROR = 2;
-    UNEXPECTED_RESPONSE = 3;
-    VALIDATED = 4;
-    CANCELLED = 5;
-    MULTIPLE_URL_CONNECTIONS_OPEN = 6;
-  }
-  optional ProbeResult probe_result = 2;
-  optional bool is_roaming = 3;
-  optional bool is_airplane_mode_enabled = 4;
-  optional int32 local_hour_of_day_start = 5;
-  optional int64 time_since_last_check_millis = 6;
-}
-
-// This message is used by OfflineMeasurementsBackgroundTask to write a list of
-// SystemStates to Prefs.
-message SystemStateList {
-  repeated SystemState system_states = 1;
-}
diff --git a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
index f4a132e..b2c10b9 100644
--- a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
+++ b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
@@ -22,6 +22,7 @@
 #include "components/optimization_guide/content/mojom/page_text_service.mojom.h"
 #include "components/optimization_guide/core/optimization_guide_enums.h"
 #include "components/optimization_guide/core/optimization_guide_features.h"
+#include "components/optimization_guide/core/optimization_guide_switches.h"
 #include "components/optimization_guide/core/optimization_guide_test_util.h"
 #include "components/optimization_guide/core/test_model_info_builder.h"
 #include "components/optimization_guide/machine_learning_tflite_buildflags.h"
@@ -495,6 +496,7 @@
           {
               {"write_to_history_service", "false"},
               {"annotate_visit_batch_size", "2"},
+              {"annotate_title_instead_of_page_content", "true"},
           }}},
         /*disabled_features=*/{});
   }
@@ -504,14 +506,17 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-// TODO(1289353): Newly added test is flaky.
 IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceBatchVisitTest,
-                       DISABLED_ModelExecutesWithFullBatch) {
+                       ModelExecutesWithFullBatch) {
   base::HistogramTester histogram_tester;
 
   GURL url(embedded_test_server()->GetURL("a.com", "/hello.html"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
 
+  RetryForHistogramUntilCountReached(
+      &histogram_tester,
+      "PageContentAnnotations.AnnotateVisit.AnnotationRequested", 1);
+
   GURL url2(embedded_test_server()->GetURL("b.com", "/hello.html"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url2));
 
@@ -536,9 +541,35 @@
   EXPECT_FALSE(GetContentAnnotationsForURL(url).has_value());
 }
 
-// TODO(https://crbug.com/1289586): Flakes on multiple platforms.
-IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceBatchVisitTest,
-                       DISABLED_QueueFullAndVisitBatchActive) {
+class PageContentAnnotationsServiceBatchVisitNoAnnotateTest
+    : public PageContentAnnotationsServiceBatchVisitTest {
+ public:
+  PageContentAnnotationsServiceBatchVisitNoAnnotateTest() {
+    scoped_feature_list_.InitWithFeaturesAndParameters(
+        {{features::kOptimizationHints, {}},
+         {features::kPageContentAnnotations,
+          {
+              {"write_to_history_service", "false"},
+              {"annotate_visit_batch_size", "2"},
+              {"annotate_title_instead_of_page_content", "true"},
+          }}},
+        /*disabled_features=*/{});
+  }
+  ~PageContentAnnotationsServiceBatchVisitNoAnnotateTest() override = default;
+
+  void SetUpCommandLine(base::CommandLine* cmd) override {
+    // Note: the code after the early return this disables is well tested in
+    // other places.
+    cmd->AppendSwitch(
+        optimization_guide::switches::kStopHistoryVisitBatchAnnotateForTesting);
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceBatchVisitNoAnnotateTest,
+                       QueueFullAndVisitBatchActive) {
   base::HistogramTester histogram_tester;
   HistoryVisit history_visit(base::Time::Now(),
                              GURL("https://probablynotarealurl.com/"), 0);
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/mouseover.html b/chrome/browser/page_load_metrics/integration_tests/data/mouseover.html
index 4d1bcaf4..f291be7 100644
--- a/chrome/browser/page_load_metrics/integration_tests/data/mouseover.html
+++ b/chrome/browser/page_load_metrics/integration_tests/data/mouseover.html
@@ -20,11 +20,10 @@
 // Turn off BFCache to see if it helps with BFCache bot flakes.
 window.addEventListener("unload", () => { console.log("Turn off BFCache"); });
 
-window.image_event_listener = loadImage("100x50");
-image.addEventListener("mouseover", window.image_event_listener);
+image.addEventListener("mouseover", loadImage("100x50"));
 span.addEventListener("mouseover", loadImage("256x256"));
 
-const dispatch_event = () => {
+const dispatch_mouseover = () => {
   span.dispatchEvent(new Event("mouseover"))
 };
 
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
index 567faef..f55935f 100644
--- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -289,7 +289,8 @@
       // currently a second mouse move call is not dispatching the event as it
       // should. So instead, we dispatch the event directly.
       EXPECT_EQ(
-          EvalJs(web_contents()->GetMainFrame(), "dispatch_event()").error, "");
+          EvalJs(web_contents()->GetMainFrame(), "dispatch_mouseover()").error,
+          "");
 
       // Wait for a third image (potentially) to load and for LCP entry to be
       // there.
diff --git a/chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.cc
deleted file mode 100644
index 575f5a9..0000000
--- a/chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.cc
+++ /dev/null
@@ -1,173 +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 "chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.h"
-
-#include "base/metrics/field_trial_params.h"
-#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h"
-#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_features.h"
-#include "url/gurl.h"
-
-DataSaverSiteBreakdownMetricsObserver::DataSaverSiteBreakdownMetricsObserver() =
-    default;
-
-DataSaverSiteBreakdownMetricsObserver::
-    ~DataSaverSiteBreakdownMetricsObserver() = default;
-
-page_load_metrics::PageLoadMetricsObserver::ObservePolicy
-DataSaverSiteBreakdownMetricsObserver::OnCommit(
-    content::NavigationHandle* navigation_handle,
-    ukm::SourceId source_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  Profile* profile = Profile::FromBrowserContext(
-      navigation_handle->GetWebContents()->GetBrowserContext());
-  // Skip if Lite mode is not enabled.
-  if (!profile || !data_reduction_proxy::DataReductionProxySettings::
-                      IsDataSaverEnabledByUser(profile->IsOffTheRecord(),
-                                               profile->GetPrefs())) {
-    return STOP_OBSERVING;
-  }
-
-  // This BrowserContext is valid for the lifetime of
-  // DataReductionProxyMetricsObserver. BrowserContext is always valid and
-  // non-nullptr in NavigationControllerImpl, which is a member of WebContents.
-  // A raw pointer to BrowserContext taken at this point will be valid until
-  // after WebContent's destructor. The latest that PageLoadTracker's destructor
-  // will be called is in MetricsWebContentsObserver's destructor, which is
-  // called in WebContents destructor.
-  browser_context_ = navigation_handle->GetWebContents()->GetBrowserContext();
-
-  // Use the virtual URL that is meant to be displayed to the user, instead of
-  // actual URL, since certain previews redirect to an optimized page that has
-  // different URL than shown in the titlebar.
-  committed_host_ = navigation_handle->GetWebContents()
-                        ->GetLastCommittedURL()
-                        .HostNoBrackets();
-  committed_origin_ = navigation_handle->GetWebContents()
-                          ->GetLastCommittedURL()
-                          .DeprecatedGetOriginAsURL()
-                          .spec();
-  return CONTINUE_OBSERVING;
-}
-
-void DataSaverSiteBreakdownMetricsObserver::OnResourceDataUseObserved(
-    content::RenderFrameHost* rfh,
-    const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>&
-        resources) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  data_reduction_proxy::DataReductionProxySettings*
-      data_reduction_proxy_settings =
-          DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
-              browser_context_);
-  if (data_reduction_proxy_settings &&
-      data_reduction_proxy_settings->data_reduction_proxy_service()) {
-    DCHECK(!committed_host_.empty());
-    DCHECK(!committed_origin_.empty());
-    int64_t received_data_length = 0;
-    int64_t data_reduction_proxy_bytes_saved = 0;
-    for (auto const& resource : resources) {
-      received_data_length += resource->delta_bytes;
-
-      // Estimate savings based on network bytes used.
-      data_reduction_proxy_bytes_saved +=
-          resource->delta_bytes *
-          (resource->data_reduction_proxy_compression_ratio_estimate - 1.0);
-
-      if (resource->is_complete) {
-        // Record the actual data savings based on body length. Remove
-        // previously added savings from network usage.
-        data_reduction_proxy_bytes_saved +=
-            (resource->encoded_body_length - resource->received_data_length) *
-            (resource->data_reduction_proxy_compression_ratio_estimate - 1.0);
-      }
-    }
-    double origin_save_data_savings =
-        data_reduction_proxy_settings->data_reduction_proxy_service()
-            ->GetSaveDataSavingsPercentEstimate(committed_origin_);
-    if (origin_save_data_savings) {
-      data_reduction_proxy_bytes_saved +=
-          received_data_length * origin_save_data_savings / 100;
-    }
-
-    data_reduction_proxy_settings->data_reduction_proxy_service()
-        ->UpdateDataUseForHost(
-            received_data_length,
-            received_data_length + data_reduction_proxy_bytes_saved,
-            committed_host_);
-    // TODO(rajendrant): Fix the |request_type| and |mime_type| sent below or
-    // remove the respective histograms.
-    data_reduction_proxy_settings->data_reduction_proxy_service()
-        ->UpdateContentLengths(
-            received_data_length,
-            received_data_length + data_reduction_proxy_bytes_saved,
-            data_reduction_proxy_settings->IsDataReductionProxyEnabled(),
-            std::string() /* mime_type */, true /*is_user_traffic*/,
-            data_use_measurement::DataUseUserData::OTHER, 0);
-  }
-}
-
-void DataSaverSiteBreakdownMetricsObserver::OnNewDeferredResourceCounts(
-    const page_load_metrics::mojom::DeferredResourceCounts&
-        new_deferred_resource_data) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  data_reduction_proxy::DataReductionProxySettings*
-      data_reduction_proxy_settings =
-          DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
-              browser_context_);
-  if (!data_reduction_proxy_settings ||
-      !data_reduction_proxy_settings->data_reduction_proxy_service()) {
-    return;
-  }
-  DCHECK(!committed_host_.empty());
-  int64_t previously_reported_savings_that_no_longer_apply = 0;
-  int64_t new_reported_savings = 0;
-
-  int typical_frame_savings = base::GetFieldTrialParamByFeatureAsInt(
-      features::kLazyFrameLoading, "typical_frame_size_in_bytes", 50000);
-
-  int typical_image_savings = base::GetFieldTrialParamByFeatureAsInt(
-      features::kLazyFrameLoading, "typical_image_size_in_bytes", 10000);
-
-  new_reported_savings +=
-      new_deferred_resource_data.deferred_frames * typical_frame_savings;
-  new_reported_savings +=
-      new_deferred_resource_data.deferred_images * typical_image_savings;
-
-  previously_reported_savings_that_no_longer_apply +=
-      new_deferred_resource_data.frames_loaded_after_deferral *
-      typical_frame_savings;
-  previously_reported_savings_that_no_longer_apply +=
-      new_deferred_resource_data.images_loaded_after_deferral *
-      typical_image_savings;
-
-  // This can be negative if we previously recorded savings that need to be
-  // undone.
-  int64_t savings_to_report =
-      new_reported_savings - previously_reported_savings_that_no_longer_apply;
-
-  data_reduction_proxy_settings->data_reduction_proxy_service()
-      ->UpdateDataUseForHost(0, savings_to_report, committed_host_);
-  data_reduction_proxy_settings->data_reduction_proxy_service()
-      ->UpdateContentLengths(
-          0, savings_to_report,
-          data_reduction_proxy_settings->IsDataReductionProxyEnabled(),
-          std::string() /* mime_type */, true /*is_user_traffic*/,
-          data_use_measurement::DataUseUserData::OTHER, 0);
-}
-
-page_load_metrics::PageLoadMetricsObserver::ObservePolicy
-DataSaverSiteBreakdownMetricsObserver::ShouldObserveMimeType(
-    const std::string& mime_type) const {
-  // Observe all MIME types. We still only use actual data usage, so strange
-  // cases (e.g., data:// URLs) will still record the right amount of data
-  // usage.
-  return CONTINUE_OBSERVING;
-}
diff --git a/chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.h b/chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.h
deleted file mode 100644
index 804a489..0000000
--- a/chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.h
+++ /dev/null
@@ -1,59 +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 CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_DATA_SAVER_SITE_BREAKDOWN_METRICS_OBSERVER_H_
-#define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_DATA_SAVER_SITE_BREAKDOWN_METRICS_OBSERVER_H_
-
-#include <stdint.h>
-#include <string>
-
-#include "base/memory/raw_ptr.h"
-#include "base/sequence_checker.h"
-#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
-#include "components/page_load_metrics/common/page_load_metrics.mojom-forward.h"
-#include "services/metrics/public/cpp/ukm_source_id.h"
-
-namespace content {
-class BrowserContext;
-class NavigationHandle;
-}  // namespace content
-
-// Observer responsible for recording data usage per site to the data reduction
-// proxy database.
-class DataSaverSiteBreakdownMetricsObserver
-    : public page_load_metrics::PageLoadMetricsObserver {
- public:
-  DataSaverSiteBreakdownMetricsObserver();
-
-  DataSaverSiteBreakdownMetricsObserver(
-      const DataSaverSiteBreakdownMetricsObserver&) = delete;
-  DataSaverSiteBreakdownMetricsObserver& operator=(
-      const DataSaverSiteBreakdownMetricsObserver&) = delete;
-
-  ~DataSaverSiteBreakdownMetricsObserver() override;
-
- private:
-  ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
-                         ukm::SourceId source_id) override;
-
-  void OnResourceDataUseObserved(
-      content::RenderFrameHost* rfh,
-      const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>&
-          resources) override;
-  void OnNewDeferredResourceCounts(
-      const page_load_metrics::mojom::DeferredResourceCounts&
-          new_deferred_resource_data) override;
-  ObservePolicy ShouldObserveMimeType(
-      const std::string& mime_type) const override;
-
-  std::string committed_host_;
-  std::string committed_origin_;
-
-  // The browser context this navigation is operating in.
-  raw_ptr<content::BrowserContext> browser_context_ = nullptr;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-#endif  // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_DATA_SAVER_SITE_BREAKDOWN_METRICS_OBSERVER_H_
diff --git a/chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer_browsertest.cc
deleted file mode 100644
index 6d42fde..0000000
--- a/chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer_browsertest.cc
+++ /dev/null
@@ -1,580 +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 <stdint.h>
-#include <memory>
-#include <string>
-
-#include "base/command_line.h"
-#include "base/run_loop.h"
-#include "base/strings/stringprintf.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h"
-#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
-#include "components/data_reduction_proxy/proto/data_store.pb.h"
-#include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h"
-#include "components/prefs/pref_service.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_features.h"
-#include "content/public/test/back_forward_cache_util.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/browser_test_base.h"
-#include "content/public/test/browser_test_utils.h"
-#include "net/dns/mock_host_resolver.h"
-#include "net/nqe/effective_connection_type.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "net/test/embedded_test_server/http_request.h"
-#include "net/test/embedded_test_server/http_response.h"
-#include "services/network/public/cpp/network_quality_tracker.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// Return a plaintext response.
-std::unique_ptr<net::test_server::HttpResponse>
-HandleResourceRequestWithPlaintextMimeType(
-    const net::test_server::HttpRequest& request) {
-  std::unique_ptr<net::test_server::BasicHttpResponse> response =
-      std::make_unique<net::test_server::BasicHttpResponse>();
-
-  response->set_code(net::HttpStatusCode::HTTP_OK);
-  response->set_content("Some non-HTML content.");
-  response->set_content_type("text/plain");
-
-  return response;
-}
-
-}  // namespace
-
-// Browser tests with Lite mode not enabled.
-class DataSaverSiteBreakdownMetricsObserverBrowserTestBase
-    : public InProcessBrowserTest {
- protected:
-  // Gets the data usage recorded against the host the embedded server runs on.
-  uint64_t GetDataUsage(const std::string& host) {
-    const auto& data_usage_map =
-        DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
-            browser()->profile())
-            ->data_reduction_proxy_service()
-            ->compression_stats()
-            ->DataUsageMapForTesting();
-    const auto& it = data_usage_map.find(host);
-    if (it != data_usage_map.end())
-      return it->second->data_used();
-    return 0;
-  }
-
-  // Gets the data savings recorded against the host the embedded server runs
-  // on.
-  int64_t GetDataSavings(const std::string& host) {
-    const auto& data_usage_map =
-        DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
-            browser()->profile())
-            ->data_reduction_proxy_service()
-            ->compression_stats()
-            ->DataUsageMapForTesting();
-    const auto& it = data_usage_map.find(host);
-    if (it != data_usage_map.end())
-      return it->second->original_size() - it->second->data_used();
-    return 0;
-  }
-
-  void WaitForDBToInitialize() {
-    base::RunLoop run_loop;
-    DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
-        browser()->profile())
-        ->data_reduction_proxy_service()
-        ->GetDBTaskRunnerForTesting()
-        ->PostTask(FROM_HERE, run_loop.QuitClosure());
-    run_loop.Run();
-  }
-};
-
-// Browser tests with Lite mode enabled.
-class DataSaverSiteBreakdownMetricsObserverBrowserTest
-    : public DataSaverSiteBreakdownMetricsObserverBrowserTestBase {
- protected:
-  void SetUpOnMainThread() override {
-    DataSaverSiteBreakdownMetricsObserverBrowserTestBase::SetUpOnMainThread();
-    host_resolver()->AddRule("*", "127.0.0.1");
-
-    PrefService* prefs = browser()->profile()->GetPrefs();
-    prefs->SetBoolean(data_reduction_proxy::prefs::kDataUsageReportingEnabled,
-                      true);
-  }
-
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    command_line->AppendSwitch(
-        data_reduction_proxy::switches::kEnableDataReductionProxy);
-  }
-};
-
-class LazyLoadWithoutLiteModeBrowserTest
-    : public DataSaverSiteBreakdownMetricsObserverBrowserTestBase {
-  void SetUp() override {
-    scoped_feature_list_.InitWithFeaturesAndParameters(
-        {{features::kLazyImageLoading,
-          {{"automatic-lazy-load-images-enabled", "true"},
-           {"lazy_image_first_k_fully_load",
-            base::StringPrintf("%s:0,%s:0,%s:0,%s:0,%s:0,%s:0",
-                               net::kEffectiveConnectionTypeUnknown,
-                               net::kEffectiveConnectionTypeOffline,
-                               net::kEffectiveConnectionTypeSlow2G,
-                               net::kEffectiveConnectionType2G,
-                               net::kEffectiveConnectionType3G,
-                               net::kEffectiveConnectionType4G)}}},
-         {features::kLazyFrameLoading,
-          {{"automatic-lazy-load-frames-enabled", "true"}}}},
-        {});
-    DataSaverSiteBreakdownMetricsObserverBrowserTestBase::SetUp();
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-class LazyLoadWithLiteModeBrowserTest
-    : public DataSaverSiteBreakdownMetricsObserverBrowserTest {
- public:
-  void SetUp() override {
-    scoped_feature_list_.InitWithFeaturesAndParameters(
-        {{features::kLazyImageLoading,
-          {{"automatic-lazy-load-images-enabled", "true"},
-           {"lazy_image_first_k_fully_load",
-            base::StringPrintf("%s:0,%s:0,%s:0,%s:0,%s:0,%s:0",
-                               net::kEffectiveConnectionTypeUnknown,
-                               net::kEffectiveConnectionTypeOffline,
-                               net::kEffectiveConnectionTypeSlow2G,
-                               net::kEffectiveConnectionType2G,
-                               net::kEffectiveConnectionType3G,
-                               net::kEffectiveConnectionType4G)}}},
-         {features::kLazyFrameLoading,
-          {{"automatic-lazy-load-frames-enabled", "true"}}}},
-        {});
-    DataSaverSiteBreakdownMetricsObserverBrowserTest::SetUp();
-  }
-
-  // Navigates to |url| waiting until |expected_resources| are received and then
-  // returns the data savings. |expected_resources| should include main html,
-  // subresources and favicon.
-  int64_t NavigateAndGetDataSavings(const std::string& url,
-                                    int expected_resources) {
-    WaitForDBToInitialize();
-    EXPECT_TRUE(embedded_test_server()->Start());
-
-    GURL test_url(embedded_test_server()->GetURL(url));
-    uint64_t data_savings_before_navigation =
-        GetDataSavings(test_url.HostNoBrackets());
-
-    auto waiter =
-        std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
-            browser()->tab_strip_model()->GetActiveWebContents());
-
-    EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
-
-    waiter->AddMinimumCompleteResourcesExpectation(expected_resources);
-    waiter->Wait();
-
-    // Navigate away to force the histogram recording.
-    EXPECT_TRUE(
-        ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-    return GetDataSavings(test_url.HostNoBrackets()) -
-           data_savings_before_navigation;
-  }
-
-  // Navigates to |url| waiting until |expected_initial_resources| are received.
-  // Then scrolls down the page and waits until |expected_resources_post_scroll|
-  // more resources are received. Finally returns the data savings. The resource
-  // counts should include main html, subresources and favicon.
-  int64_t NavigateAndGetDataSavingsAfterScroll(
-      const std::string& url,
-      size_t expected_initial_resources,
-      size_t expected_resources_post_scroll) {
-    WaitForDBToInitialize();
-    EXPECT_TRUE(embedded_test_server()->Start());
-
-    GURL test_url(embedded_test_server()->GetURL(url));
-    uint64_t data_savings_before_navigation =
-        GetDataSavings(test_url.HostNoBrackets());
-
-    auto waiter =
-        std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
-            browser()->tab_strip_model()->GetActiveWebContents());
-
-    EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
-    waiter->AddMinimumCompleteResourcesExpectation(expected_initial_resources);
-    waiter->Wait();
-
-    // Scroll to remove data savings by loading the images.
-    EXPECT_EQ(nullptr, content::EvalJs(
-                           browser()->tab_strip_model()->GetActiveWebContents(),
-                           "document.body.scrollIntoView({block: 'end'});"));
-
-    waiter->AddMinimumCompleteResourcesExpectation(
-        expected_initial_resources + expected_resources_post_scroll);
-    waiter->Wait();
-
-    // Navigate away to force the histogram recording.
-    EXPECT_TRUE(
-        ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-    return GetDataSavings(test_url.HostNoBrackets()) -
-           data_savings_before_navigation;
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-struct SaveDataSavingsEstimate {
-  std::string host;
-  std::string data_savings_percent;
-};
-
-// Prints readable output on test failures.
-void PrintTo(const SaveDataSavingsEstimate& estimate, std::ostream* os) {
-  *os << "'" << estimate.host << "' : " << estimate.data_savings_percent;
-}
-
-struct SaveDataSingleTestCase {
-  std::string test_host;
-  double expected_savings_percent;
-};
-
-std::string ConvertSaveDataSavingsEstimateToJson(
-    std::vector<SaveDataSavingsEstimate> estimates,
-    const net::EmbeddedTestServer& embedded_test_server) {
-  std::string origin_savings_estimate_json;
-  for (const auto& estimate : estimates) {
-    base::StringAppendF(&origin_savings_estimate_json, "\"%s\": %s,",
-                        embedded_test_server.GetURL(estimate.host, "/")
-                            .DeprecatedGetOriginAsURL()
-                            .spec()
-                            .c_str(),
-                        estimate.data_savings_percent.c_str());
-  }
-  origin_savings_estimate_json.pop_back();
-  return "{" + origin_savings_estimate_json + "}";
-}
-
-struct SaveDataTestCase {
-  // One of the origin_savings_estimate_* fields will be populated.
-  std::string origin_savings_estimate_raw_json;
-  std::vector<SaveDataSavingsEstimate> origin_savings_estimate_list;
-  bool is_valid_json;
-  std::vector<SaveDataSingleTestCase> tests;
-} kSaveDataTestCases[] = {
-    // No savings recorded without field trial config.
-    {"", {}, false, {{"foo.com", 0.0}}},
-
-    // No savings recorded with invalid field trial parameter.
-    {"invalid json", {}, false, {{"foo.com", 0.0}}},
-
-    // JSON not a dictionary
-    {"[\"valid\", \"json\", \"but\", \"an\", \"array\", \"type\"]",
-     {},
-     false,
-     {{"foo.com", 0.0}}},
-
-    {"",
-     {{"saving.com", "10"}},
-     true,
-     {{{"saving.com", 10.0}, {"notsaving.com", 0.0}}}},
-
-    {"",
-     {{"www.saving.com", "20"}, {"m.savingfloatingpoint.edu", "15.7"}},
-     true,
-     {{{"www.saving.com", 20.0},
-       {"m.savingfloatingpoint.edu", 15.7},
-       {"notsaving.com", 0.0}}}}
-
-};
-
-// Prints readable output on test failures.
-void PrintTo(const SaveDataTestCase& test, std::ostream* os) {
-  *os << "{ origin_savings_estimate_raw_json='"
-      << test.origin_savings_estimate_raw_json
-      << "', origin_savings_estimate_list={";
-  for (const auto& estimate : test.origin_savings_estimate_list) {
-    PrintTo(estimate, os);
-    *os << ", ";
-  }
-  *os << " }, is_valid_json=" << test.is_valid_json << " }";
-}
-
-IN_PROC_BROWSER_TEST_F(DataSaverSiteBreakdownMetricsObserverBrowserTest,
-                       NavigateToSimplePage) {
-  // The test assumes pages gets deleted after navigation, triggering histogram
-  // recording. Disable back/forward cache to ensure that pages don't get
-  // preserved in the cache.
-  // TODO(https://crbug.com/1229122): Investigate if this needs further fix.
-  content::DisableBackForwardCacheForTesting(
-      browser()->tab_strip_model()->GetActiveWebContents(),
-      content::BackForwardCache::TEST_REQUIRES_NO_CACHING);
-  const struct {
-    std::string url;
-    size_t expected_min_page_size;
-    size_t expected_max_page_size;
-  } tests[] = {
-      // The range of the pages is calculated approximately from the html size
-      // and the size of the subresources it includes.
-      {"/google/google.html", 5000, 20000},
-      {"/simple.html", 100, 1000},
-      {"/media/youtube.html", 5000, 20000},
-  };
-  ASSERT_TRUE(embedded_test_server()->Start());
-  WaitForDBToInitialize();
-
-  for (const auto& test : tests) {
-    GURL test_url(embedded_test_server()->GetURL(test.url));
-    uint64_t data_usage_before_navigation =
-        GetDataUsage(test_url.HostNoBrackets());
-    ASSERT_TRUE(ui_test_utils::NavigateToURL(
-        browser(), embedded_test_server()->GetURL(test.url)));
-
-    base::RunLoop().RunUntilIdle();
-    // Navigate away to force the histogram recording.
-    ASSERT_TRUE(
-        ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-    EXPECT_LE(
-        test.expected_min_page_size,
-        GetDataUsage(test_url.HostNoBrackets()) - data_usage_before_navigation);
-    EXPECT_GE(
-        test.expected_max_page_size,
-        GetDataUsage(test_url.HostNoBrackets()) - data_usage_before_navigation);
-  }
-}
-
-IN_PROC_BROWSER_TEST_F(DataSaverSiteBreakdownMetricsObserverBrowserTest,
-                       NavigateToPlaintext) {
-  std::unique_ptr<net::EmbeddedTestServer> plaintext_server =
-      std::make_unique<net::EmbeddedTestServer>(
-          net::EmbeddedTestServer::TYPE_HTTPS);
-  plaintext_server->RegisterRequestHandler(
-      base::BindRepeating(&HandleResourceRequestWithPlaintextMimeType));
-  ASSERT_TRUE(plaintext_server->Start());
-  WaitForDBToInitialize();
-
-  GURL test_url(plaintext_server->GetURL("/page"));
-
-  uint64_t data_usage_before_navigation =
-      GetDataUsage(test_url.HostNoBrackets());
-
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
-  base::RunLoop().RunUntilIdle();
-
-  // Navigate away to force the histogram recording.
-  ASSERT_TRUE(
-      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  // Choose reasonable minimum (10 is the content length).
-  EXPECT_LE(10u, GetDataUsage(test_url.HostNoBrackets()) -
-                     data_usage_before_navigation);
-  // Choose reasonable maximum (500 is the most we expect from headers).
-  EXPECT_GE(500u, GetDataUsage(test_url.HostNoBrackets()) -
-                      data_usage_before_navigation);
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadWithLiteModeBrowserTest,
-                       LazyLoadImagesCSSBackgroundImage) {
-  // 2 deferred images.
-  EXPECT_EQ(10000 * 2,
-            NavigateAndGetDataSavings("/lazyload/css-background-image.html",
-                                      2 /* main html, favicon */));
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadWithLiteModeBrowserTest,
-                       LazyLoadImagesCSSBackgroundImageScrollRemovesSavings) {
-  // Scrolling should remove the savings.
-  EXPECT_EQ(0u, NavigateAndGetDataSavingsAfterScroll(
-                    "/lazyload/css-background-image.html", 2,
-                    2 /* lazyloaded images */));
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadWithLiteModeBrowserTest,
-                       LazyLoadImagesImgElement) {
-  // Choose reasonable minimum, any savings is indicative of the mechanism
-  // working.
-  EXPECT_LE(10000, NavigateAndGetDataSavings(
-                       "/lazyload/img.html",
-                       6 /* main html, favicon, 4 images (2 eager, 2 full)*/));
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadWithLiteModeBrowserTest,
-                       LazyLoadImagesImgElementScrollRemovesSavings) {
-  // Choose reasonable minimum, any savings is indicative of the mechanism
-  // working.
-  // TODO(rajendrant): Check why sometimes data savings goes negative.
-  EXPECT_GE(0, NavigateAndGetDataSavingsAfterScroll("/lazyload/img.html", 6,
-                                                    2 /* lazyloaded image */));
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadWithLiteModeBrowserTest,
-                       LazyLoadImagesImgWithDimension) {
-  // 1 deferred image.
-  EXPECT_EQ(10000,
-            NavigateAndGetDataSavings("/lazyload/img-with-dimension.html",
-                                      3 /* main html, favicon, full image */));
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadWithLiteModeBrowserTest,
-                       LazyLoadImagesImgWithDimensionScrollRemovesSavings) {
-  // Scrolling should remove the savings.
-  EXPECT_EQ(0u, NavigateAndGetDataSavingsAfterScroll(
-                    "/lazyload/img-with-dimension.html", 3,
-                    1 /* lazyloaded image */));
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadWithoutLiteModeBrowserTest,
-                       NoSavingsRecordedWithoutLiteMode) {
-  std::vector<std::string> test_urls = {
-      "/google/google.html",
-      "/simple.html",
-      "/media/youtube.html",
-      "/lazyload/img.html",
-      "/lazyload/img-with-dimension.html",
-  };
-  ASSERT_TRUE(embedded_test_server()->Start());
-  WaitForDBToInitialize();
-  for (const auto& url : test_urls) {
-    GURL test_url(embedded_test_server()->GetURL(url));
-    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
-
-    base::RunLoop().RunUntilIdle();
-    // Navigate away to force the histogram recording.
-    ASSERT_TRUE(
-        ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-    EXPECT_EQ(0U, GetDataUsage(test_url.HostNoBrackets()));
-    EXPECT_EQ(0U, GetDataUsage(test_url.HostNoBrackets()));
-  }
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadWithLiteModeBrowserTest,
-                       LazyLoadImageDisabledInReload) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  WaitForDBToInitialize();
-  GURL test_url(
-      embedded_test_server()->GetURL("/lazyload/img-with-dimension.html"));
-
-  {
-    uint64_t data_savings_before_navigation =
-        GetDataSavings(test_url.HostNoBrackets());
-
-    auto waiter =
-        std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
-            browser()->tab_strip_model()->GetActiveWebContents());
-
-    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
-
-    waiter->AddMinimumCompleteResourcesExpectation(3);
-    waiter->Wait();
-    EXPECT_EQ(10000U, GetDataSavings(test_url.HostNoBrackets()) -
-                          data_savings_before_navigation);
-  }
-
-  // Reload will not have any savings.
-  {
-    uint64_t data_savings_before_navigation =
-        GetDataSavings(test_url.HostNoBrackets());
-
-    auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
-    auto waiter =
-        std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
-            web_contents);
-    chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
-
-    waiter->AddMinimumCompleteResourcesExpectation(3);
-    waiter->Wait();
-    base::RunLoop().RunUntilIdle();
-    EXPECT_EQ(0U, GetDataSavings(test_url.HostNoBrackets()) -
-                      data_savings_before_navigation);
-  }
-}
-
-IN_PROC_BROWSER_TEST_F(LazyLoadWithLiteModeBrowserTest,
-                       DISABLED_LazyLoadFrameDisabledInReload) {
-  net::EmbeddedTestServer cross_origin_server;
-  cross_origin_server.ServeFilesFromSourceDirectory(GetChromeTestDataDir());
-  ASSERT_TRUE(cross_origin_server.Start());
-  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
-      [](uint16_t cross_origin_port,
-         const net::test_server::HttpRequest& request)
-          -> std::unique_ptr<net::test_server::HttpResponse> {
-        auto response = std::make_unique<net::test_server::BasicHttpResponse>();
-        if (request.relative_url == "/mainpage.html") {
-          response->set_content(base::StringPrintf(
-              R"HTML(
-              <body>
-                <div style="height:11000px;"></div>
-                Below the viewport croos-origin iframe <br>
-                <iframe src="http://bar.com:%d/simple.html"
-                width="100" height="100"
-                onload="console.log('below-viewport iframe loaded')"></iframe>
-              </body>)HTML",
-              cross_origin_port));
-        }
-        return response;
-      },
-      cross_origin_server.port()));
-  ASSERT_TRUE(embedded_test_server()->Start());
-  WaitForDBToInitialize();
-  GURL test_url(embedded_test_server()->GetURL("foo.com", "/mainpage.html"));
-  auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
-  content::WebContentsConsoleObserver console_observer(web_contents);
-  console_observer.SetPattern("below-viewport iframe loaded");
-
-  {
-    uint64_t data_savings_before_navigation =
-        GetDataSavings(test_url.HostNoBrackets());
-
-    auto waiter =
-        std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
-            web_contents);
-
-    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
-
-    waiter->AddMinimumCompleteResourcesExpectation(2);
-    waiter->Wait();
-    EXPECT_EQ(50000U, GetDataSavings(test_url.HostNoBrackets()) -
-                          data_savings_before_navigation);
-    EXPECT_TRUE(console_observer.messages().empty());
-  }
-
-  // Reload will not have any savings.
-  {
-    uint64_t data_savings_before_navigation =
-        GetDataSavings(test_url.HostNoBrackets());
-
-    auto waiter =
-        std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
-            web_contents);
-    chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
-
-    waiter->AddMinimumCompleteResourcesExpectation(2);
-    waiter->Wait();
-    base::RunLoop().RunUntilIdle();
-    console_observer.Wait();
-    EXPECT_EQ(0U, GetDataSavings(test_url.HostNoBrackets()) -
-                      data_savings_before_navigation);
-    EXPECT_EQ("below-viewport iframe loaded",
-              console_observer.GetMessageAt(0u));
-  }
-}
diff --git a/chrome/browser/page_load_metrics/observers/data_use_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/data_use_metrics_observer.cc
deleted file mode 100644
index a866a1a..0000000
--- a/chrome/browser/page_load_metrics/observers/data_use_metrics_observer.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2019 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 "chrome/browser/page_load_metrics/observers/data_use_metrics_observer.h"
-
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
-#include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
-#include "content/public/browser/navigation_handle.h"
-
-DataUseMetricsObserver::DataUseMetricsObserver() = default;
-
-DataUseMetricsObserver::~DataUseMetricsObserver() = default;
-
-page_load_metrics::PageLoadMetricsObserver::ObservePolicy
-DataUseMetricsObserver::OnCommit(content::NavigationHandle* navigation_handle,
-                                 ukm::SourceId source_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return CONTINUE_OBSERVING;
-}
-
-page_load_metrics::PageLoadMetricsObserver::ObservePolicy
-DataUseMetricsObserver::ShouldObserveMimeType(
-    const std::string& mime_type) const {
-  // Observe all MIME types. We still only use actual data usage, so strange
-  // cases (e.g., data:// URLs) will still record the right amount of data
-  // usage.
-  return CONTINUE_OBSERVING;
-}
-
-void DataUseMetricsObserver::OnResourceDataUseObserved(
-    content::RenderFrameHost* rfh,
-    const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>&
-        resources) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  auto* chrome_data_use_measurement =
-      data_use_measurement::ChromeDataUseMeasurement::GetInstance();
-  if (!chrome_data_use_measurement)
-    return;
-
-  int64_t received_data_length = 0;
-  for (auto const& resource : resources) {
-    received_data_length += resource->delta_bytes;
-    chrome_data_use_measurement->RecordContentTypeMetric(
-        resource->mime_type, resource->is_main_frame_resource,
-        GetDelegate().GetVisibilityTracker().currently_in_foreground(),
-        resource->delta_bytes);
-  }
-  if (!received_data_length)
-    return;
-  chrome_data_use_measurement->ReportUserTrafficDataUse(
-      GetDelegate().GetVisibilityTracker().currently_in_foreground(),
-      received_data_length);
-}
diff --git a/chrome/browser/page_load_metrics/observers/data_use_metrics_observer.h b/chrome/browser/page_load_metrics/observers/data_use_metrics_observer.h
deleted file mode 100644
index a99bec6..0000000
--- a/chrome/browser/page_load_metrics/observers/data_use_metrics_observer.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 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 CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_DATA_USE_METRICS_OBSERVER_H_
-#define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_DATA_USE_METRICS_OBSERVER_H_
-
-#include "base/sequence_checker.h"
-#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
-#include "components/page_load_metrics/common/page_load_metrics.mojom-forward.h"
-#include "components/page_load_metrics/common/page_load_timing.h"
-#include "services/metrics/public/cpp/ukm_source_id.h"
-
-namespace content {
-class NavigationHandle;
-}  // namespace content
-
-// Records the data use of user-initiated traffic broken down by different
-// conditions.
-class DataUseMetricsObserver
-    : public page_load_metrics::PageLoadMetricsObserver {
- public:
-  DataUseMetricsObserver();
-
-  DataUseMetricsObserver(const DataUseMetricsObserver&) = delete;
-  DataUseMetricsObserver& operator=(const DataUseMetricsObserver&) = delete;
-
-  ~DataUseMetricsObserver() override;
-
- private:
-  // page_load_metrics::PageLoadMetricsObserver:
-  ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
-                         ukm::SourceId source_id) override;
-  void OnResourceDataUseObserved(
-      content::RenderFrameHost* rfh,
-      const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>&
-          resources) override;
-  ObservePolicy ShouldObserveMimeType(
-      const std::string& mime_type) const override;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-#endif  // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_DATA_USE_METRICS_OBSERVER_H_
diff --git a/chrome/browser/page_load_metrics/observers/data_use_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/data_use_metrics_observer_browsertest.cc
deleted file mode 100644
index 464fef6c..0000000
--- a/chrome/browser/page_load_metrics/observers/data_use_metrics_observer_browsertest.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2019 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 "chrome/browser/page_load_metrics/observers/data_use_metrics_observer.h"
-
-#include "base/run_loop.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "components/data_use_measurement/core/data_use_user_data.h"
-#include "content/public/test/back_forward_cache_util.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/browser_test_base.h"
-#include "content/public/test/browser_test_utils.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "net/test/embedded_test_server/http_response.h"
-#include "services/network/public/cpp/features.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// Return a plaintext response.
-std::unique_ptr<net::test_server::HttpResponse>
-HandleResourceRequestWithPlaintextMimeType(
-    const net::test_server::HttpRequest& request) {
-  std::unique_ptr<net::test_server::BasicHttpResponse> response =
-      std::make_unique<net::test_server::BasicHttpResponse>();
-
-  response->set_code(net::HttpStatusCode::HTTP_OK);
-  response->set_content("Some non-HTML content.");
-  response->set_content_type("text/plain");
-
-  return response;
-}
-
-}  // namespace
-
-class DataUseMetricsObserverBrowserTest : public InProcessBrowserTest {
-};
-
-IN_PROC_BROWSER_TEST_F(DataUseMetricsObserverBrowserTest,
-                       NavigateToSimplePage) {
-  // The test assumes pages gets deleted after navigation, triggering histogram
-  // recording. Disable back/forward cache to ensure that pages don't get
-  // preserved in the cache.
-  // TODO(https://crbug.com/1229122): Investigate if this needs further fix.
-  content::DisableBackForwardCacheForTesting(
-      browser()->tab_strip_model()->GetActiveWebContents(),
-      content::BackForwardCache::TEST_REQUIRES_NO_CACHING);
-  const struct {
-    std::string url;
-    size_t expected_min_page_size;
-    size_t expected_max_page_size;
-  } tests[] = {
-      // The range of the pages is calculated approximately from the html size
-      // and the size of the subresources it includes.
-      {"/google/google.html", 5000, 20000},
-      {"/simple.html", 100, 1000},
-      {"/media/youtube.html", 5000, 20000},
-  };
-  ASSERT_TRUE(embedded_test_server()->Start());
-
-  for (const auto& test : tests) {
-    base::HistogramTester histogram_tester;
-    ASSERT_TRUE(ui_test_utils::NavigateToURL(
-        browser(), embedded_test_server()->GetURL(test.url)));
-
-    base::RunLoop().RunUntilIdle();
-    // Navigate away to finish the histogram recording.
-    ASSERT_TRUE(
-        ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-    uint64_t total_usage = 0, total_apptabstate_usage = 0;
-    for (const auto& sample : histogram_tester.GetAllSamples(
-             "DataUse.TrafficSize.User.Downstream.Foreground.NotCellular")) {
-      total_usage += sample.min * sample.count;
-    }
-    for (const auto& sample : histogram_tester.GetAllSamples(
-             "DataUse.AppTabState.Downstream.AppForeground.TabForeground")) {
-      total_apptabstate_usage += sample.min * sample.count;
-    }
-
-    EXPECT_LE(test.expected_min_page_size, total_usage);
-    EXPECT_GE(test.expected_max_page_size, total_usage);
-    EXPECT_LE(test.expected_min_page_size, total_apptabstate_usage);
-    EXPECT_GE(test.expected_max_page_size, total_apptabstate_usage);
-  }
-}
-
-IN_PROC_BROWSER_TEST_F(DataUseMetricsObserverBrowserTest, TestContentType) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  base::HistogramTester histogram_tester;
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), embedded_test_server()->GetURL("/google/google.html")));
-
-  base::RunLoop().RunUntilIdle();
-  // Navigate away to finish the histogram recording.
-  ASSERT_TRUE(
-      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  base::HistogramBase::Count main_frame_html_data_use =
-      histogram_tester.GetBucketCount(
-          "DataUse.ContentType.UserTrafficKB",
-          data_use_measurement::DataUseUserData::MAIN_FRAME_HTML);
-  base::HistogramBase::Count image_data_use = histogram_tester.GetBucketCount(
-      "DataUse.ContentType.UserTrafficKB",
-      data_use_measurement::DataUseUserData::IMAGE);
-
-  // Verify that some bytes are recorded for the main frame html and image.
-  EXPECT_LE(1, main_frame_html_data_use);
-  EXPECT_LE(1, image_data_use);
-}
-
-IN_PROC_BROWSER_TEST_F(DataUseMetricsObserverBrowserTest, NavigateToPlaintext) {
-  // The test assumes the previous page gets deleted after navigation,
-  // triggering histogram recording. Disable back/forward cache to ensure that
-  // it doesn't get preserved in the cache.
-  content::DisableBackForwardCacheForTesting(
-      browser()->tab_strip_model()->GetActiveWebContents(),
-      content::BackForwardCache::TEST_REQUIRES_NO_CACHING);
-
-  std::unique_ptr<net::EmbeddedTestServer> plaintext_server =
-      std::make_unique<net::EmbeddedTestServer>(
-          net::EmbeddedTestServer::TYPE_HTTPS);
-  plaintext_server->RegisterRequestHandler(
-      base::BindRepeating(&HandleResourceRequestWithPlaintextMimeType));
-  ASSERT_TRUE(plaintext_server->Start());
-
-  base::HistogramTester histogram_tester;
-  GURL test_url(plaintext_server->GetURL("/page"));
-
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
-  base::RunLoop().RunUntilIdle();
-
-  // Navigate away to force the histogram recording.
-  ASSERT_TRUE(
-      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-
-  uint64_t total_usage = 0, total_apptabstate_usage = 0;
-  for (const auto& sample : histogram_tester.GetAllSamples(
-           "DataUse.TrafficSize.User.Downstream.Foreground.NotCellular")) {
-    total_usage += sample.min * sample.count;
-  }
-  for (const auto& sample : histogram_tester.GetAllSamples(
-           "DataUse.AppTabState.Downstream.AppForeground.TabForeground")) {
-    total_apptabstate_usage += sample.min * sample.count;
-  }
-
-  // Choose reasonable minimums (10 is the content length).
-  EXPECT_LE(10u, total_usage);
-  EXPECT_LE(10u, total_apptabstate_usage);
-  // Choose reasonable maximums, 500 is the most we expect from headers.
-  EXPECT_GE(500u, total_usage);
-  EXPECT_GE(500u, total_apptabstate_usage);
-}
diff --git a/chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer.cc
deleted file mode 100644
index d462e71..0000000
--- a/chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2021 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 "chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer.h"
-
-#include "base/feature_list.h"
-#include "base/logging.h"
-#include "chrome/browser/flags/android/chrome_feature_list.h"
-#include "chrome/browser/offline_pages/android/offline_page_bridge.h"
-#include "chrome/browser/offline_pages/measurements/proto/system_state.pb.h"
-#include "services/metrics/public/cpp/metrics_utils.h"
-#include "services/metrics/public/cpp/ukm_builders.h"
-#include "services/metrics/public/cpp/ukm_recorder.h"
-#include "services/metrics/public/cpp/ukm_source_id.h"
-
-std::unique_ptr<OfflineMeasurementsPageLoadMetricsObserver>
-OfflineMeasurementsPageLoadMetricsObserver::CreateIfNeeded() {
-  // If the OfflineMeasurementsBackgroundTask feature is disabled, then don't
-  // create a OfflineMeasurementsPageLoadMetricsObserver, because then there are
-  // no metrics to record.
-  if (!base::FeatureList::IsEnabled(
-          chrome::android::kOfflineMeasurementsBackgroundTask)) {
-    return nullptr;
-  }
-  return std::make_unique<OfflineMeasurementsPageLoadMetricsObserver>();
-}
-
-OfflineMeasurementsPageLoadMetricsObserver::
-    ~OfflineMeasurementsPageLoadMetricsObserver() = default;
-
-page_load_metrics::PageLoadMetricsObserver::ObservePolicy
-OfflineMeasurementsPageLoadMetricsObserver::OnCommit(
-    content::NavigationHandle* navigation_handle,
-    ukm::SourceId source_id) {
-  // Get the persisted metrics from the OfflineMeasurementsBackgroundTask, and
-  // then log the metrics to UKM.
-  offline_measurements_system_state::proto::SystemStateList system_state_list =
-      offline_pages::android::OfflinePageBridge::
-          GetSystemStateListFromOfflineMeasurementsAsString();
-  ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
-  for (int i = 0; i < system_state_list.system_states_size(); i++) {
-    const auto& system_state = system_state_list.system_states(i);
-
-    ukm::builders::OfflineMeasurements offline_measurements_ukm(
-        ukm::NoURLSourceId());
-
-    offline_measurements_ukm.SetUserState(system_state.user_state())
-        .SetProbeResult(system_state.probe_result())
-        .SetIsAirplaneModeEnabled(system_state.is_airplane_mode_enabled())
-        .SetLocalHourOfDayStart(system_state.local_hour_of_day_start())
-        .SetDurationMillis(ukm::GetExponentialBucketMinForUserTiming(
-            system_state.time_since_last_check_millis()));
-
-    if (system_state.has_is_roaming()) {
-      // There are cases where we encounter a SecurityException while trying to
-      // check whether the network is marked as roaming or not roaming. When
-      // this happens, we do not set the IsRoaming field. See crbug/1246848.
-      offline_measurements_ukm.SetIsRoaming(system_state.is_roaming());
-    }
-
-    offline_measurements_ukm.Record(ukm_recorder);
-  }
-
-  offline_pages::android::OfflinePageBridge::
-      ReportOfflineMeasurementMetricsToUma();
-  return STOP_OBSERVING;
-}
diff --git a/chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer.h
deleted file mode 100644
index 8702cb4..0000000
--- a/chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 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 CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_OFFLINE_MEASUREMENTS_PAGE_LOAD_METRICS_OBSERVER_H_
-#define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_OFFLINE_MEASUREMENTS_PAGE_LOAD_METRICS_OBSERVER_H_
-
-#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
-
-// Observer that triggers the logging of any persisted metrics from the
-// |OfflineMeasurementsBackgroundTask| to both UKM and UMA.
-class OfflineMeasurementsPageLoadMetricsObserver
-    : public page_load_metrics::PageLoadMetricsObserver {
- public:
-  static std::unique_ptr<OfflineMeasurementsPageLoadMetricsObserver>
-  CreateIfNeeded();
-
-  OfflineMeasurementsPageLoadMetricsObserver() = default;
-  ~OfflineMeasurementsPageLoadMetricsObserver() override;
-
-  // page_load_metrics::PageLoadMetricsObserver:
-  ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
-                         ukm::SourceId source_id) override;
-};
-
-#endif  // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_OFFLINE_MEASUREMENTS_PAGE_LOAD_METRICS_OBSERVER_H_
diff --git a/chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer_unittest.cc
deleted file mode 100644
index 060f8a6a..0000000
--- a/chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer_unittest.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2021 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 "chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer.h"
-
-#include "base/android/jni_array.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "chrome/browser/offline_pages/android/native_j_unittests_jni_headers/OfflineMeasurementsTestHelper_jni.h"
-#include "chrome/browser/offline_pages/measurements/proto/system_state.pb.h"
-#include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
-#include "components/page_load_metrics/browser/page_load_tracker.h"
-#include "components/ukm/test_ukm_recorder.h"
-#include "services/metrics/public/cpp/metrics_utils.h"
-#include "services/metrics/public/cpp/ukm_builders.h"
-#include "services/metrics/public/cpp/ukm_source_id.h"
-
-using UkmEntry = ukm::builders::OfflineMeasurements;
-
-class OfflineMeasurementsPageLoadMetricsObserverTest
-    : public page_load_metrics::PageLoadMetricsObserverTestHarness {
- public:
-  void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override {
-    tracker->AddObserver(
-        std::make_unique<OfflineMeasurementsPageLoadMetricsObserver>());
-  }
-
-  void AddSystemStateListToPrefs(
-      offline_measurements_system_state::proto::SystemStateList
-          system_state_list) {
-    std::string encoded_system_state_list;
-    system_state_list.SerializeToString(&encoded_system_state_list);
-
-    JNIEnv* env = base::android::AttachCurrentThread();
-    Java_OfflineMeasurementsTestHelper_addSystemStateListToPrefs(
-        env, base::android::ToJavaByteArray(env, encoded_system_state_list));
-  }
-};
-
-TEST_F(OfflineMeasurementsPageLoadMetricsObserverTest, RecordUkmOnCommit) {
-  // Set up the test data.
-  offline_measurements_system_state::proto::SystemStateList system_state_list;
-
-  // The first time the background task runs, the |time_since_last_check_millis|
-  // value will not be set.
-  offline_measurements_system_state::proto::SystemState* system_state1 =
-      system_state_list.add_system_states();
-  system_state1->set_user_state(
-      offline_measurements_system_state::proto::SystemState::USING_CHROME);
-  system_state1->set_probe_result(
-      offline_measurements_system_state::proto::SystemState::VALIDATED);
-  system_state1->set_is_roaming(false);
-  system_state1->set_is_airplane_mode_enabled(false);
-  system_state1->set_local_hour_of_day_start(5);
-
-  offline_measurements_system_state::proto::SystemState* system_state2 =
-      system_state_list.add_system_states();
-  system_state2->set_user_state(
-      offline_measurements_system_state::proto::SystemState::NOT_USING_PHONE);
-  system_state2->set_probe_result(
-      offline_measurements_system_state::proto::SystemState::NO_INTERNET);
-  system_state2->set_is_roaming(false);
-  system_state2->set_is_airplane_mode_enabled(true);
-  system_state2->set_local_hour_of_day_start(10);
-  system_state2->set_time_since_last_check_millis(1000);
-
-  offline_measurements_system_state::proto::SystemState* system_state3 =
-      system_state_list.add_system_states();
-  system_state3->set_user_state(
-      offline_measurements_system_state::proto::SystemState::PHONE_OFF);
-  system_state3->set_probe_result(
-      offline_measurements_system_state::proto::SystemState::SERVER_ERROR);
-  system_state3->set_is_roaming(true);
-  system_state3->set_is_airplane_mode_enabled(false);
-  system_state3->set_local_hour_of_day_start(15);
-  system_state3->set_time_since_last_check_millis(2000);
-
-  // If the background task is cancelled, then only the |probe_result| value
-  // will be set.
-  offline_measurements_system_state::proto::SystemState* system_state4 =
-      system_state_list.add_system_states();
-  system_state4->set_probe_result(
-      offline_measurements_system_state::proto::SystemState::CANCELLED);
-
-  // In some cases, we can encounter an error while checking whether a network
-  // is roaming or not. When this happens, we do not set the IsRoaming field.
-  offline_measurements_system_state::proto::SystemState* system_state5 =
-      system_state_list.add_system_states();
-  system_state5->set_user_state(offline_measurements_system_state::proto::
-                                    SystemState::USING_PHONE_NOT_CHROME);
-  system_state5->set_probe_result(offline_measurements_system_state::proto::
-                                      SystemState::UNEXPECTED_RESPONSE);
-  system_state5->set_is_airplane_mode_enabled(false);
-  system_state5->set_local_hour_of_day_start(20);
-  system_state5->set_time_since_last_check_millis(4000);
-
-  // Add the test data to prefs.
-  AddSystemStateListToPrefs(system_state_list);
-
-  // Navigate to some page. This should trigger the logging of all persisted
-  // data to UKM.
-  ukm::TestAutoSetUkmRecorder ukm_recorder;
-  NavigateAndCommit(GURL("https://www.example.com"));
-
-  // Checks that the expected values are recorded to UKM.
-  auto ukm_entries = ukm_recorder.GetEntries(
-      UkmEntry::kEntryName,
-      {UkmEntry::kUserStateName, UkmEntry::kProbeResultName,
-       UkmEntry::kIsRoamingName, UkmEntry::kIsAirplaneModeEnabledName,
-       UkmEntry::kLocalHourOfDayStartName, UkmEntry::kDurationMillisName});
-
-  // Check that Source ID used is ukm::NoURLSourceId() and not the source ID of
-  // the page navigated to.
-  std::vector<ukm::TestUkmRecorder::HumanReadableUkmMetrics> ukm_metrics;
-  for (const auto& ukm_entry : ukm_entries) {
-    EXPECT_EQ(ukm_entry.source_id, ukm::NoURLSourceId());
-    ukm_metrics.push_back(ukm_entry.metrics);
-  }
-
-  // Establish the expected metrics logged to UKM.
-  std::vector<ukm::TestUkmRecorder::HumanReadableUkmMetrics>
-      expected_ukm_metrics = {
-          {
-              {UkmEntry::kUserStateName, offline_measurements_system_state::
-                                             proto::SystemState::USING_CHROME},
-              {UkmEntry::kProbeResultName, offline_measurements_system_state::
-                                               proto::SystemState::VALIDATED},
-              {UkmEntry::kIsRoamingName, false},
-              {UkmEntry::kIsAirplaneModeEnabledName, false},
-              {UkmEntry::kLocalHourOfDayStartName, 5},
-              {UkmEntry::kDurationMillisName,
-               ukm::GetExponentialBucketMinForUserTiming(0)},
-          },
-          {
-              {UkmEntry::kUserStateName,
-               offline_measurements_system_state::proto::SystemState::
-                   NOT_USING_PHONE},
-              {UkmEntry::kProbeResultName, offline_measurements_system_state::
-                                               proto::SystemState::NO_INTERNET},
-              {UkmEntry::kIsRoamingName, false},
-              {UkmEntry::kIsAirplaneModeEnabledName, true},
-              {UkmEntry::kLocalHourOfDayStartName, 10},
-              {UkmEntry::kDurationMillisName,
-               ukm::GetExponentialBucketMinForUserTiming(1000)},
-          },
-          {
-              {UkmEntry::kUserStateName, offline_measurements_system_state::
-                                             proto::SystemState::PHONE_OFF},
-              {UkmEntry::kProbeResultName,
-               offline_measurements_system_state::proto::SystemState::
-                   SERVER_ERROR},
-              {UkmEntry::kIsRoamingName, true},
-              {UkmEntry::kIsAirplaneModeEnabledName, false},
-              {UkmEntry::kLocalHourOfDayStartName, 15},
-              {UkmEntry::kDurationMillisName,
-               ukm::GetExponentialBucketMinForUserTiming(2000)},
-          },
-          {
-              {UkmEntry::kUserStateName,
-               offline_measurements_system_state::proto::SystemState::
-                   INVALID_USER_STATE},
-              {UkmEntry::kProbeResultName, offline_measurements_system_state::
-                                               proto::SystemState::CANCELLED},
-              {UkmEntry::kIsAirplaneModeEnabledName, false},
-              {UkmEntry::kLocalHourOfDayStartName, 0},
-              {UkmEntry::kDurationMillisName,
-               ukm::GetExponentialBucketMinForUserTiming(0)},
-          },
-          {
-              {UkmEntry::kUserStateName,
-               offline_measurements_system_state::proto::SystemState::
-                   USING_PHONE_NOT_CHROME},
-              {UkmEntry::kProbeResultName,
-               offline_measurements_system_state::proto::SystemState::
-                   UNEXPECTED_RESPONSE},
-              {UkmEntry::kIsAirplaneModeEnabledName, false},
-              {UkmEntry::kLocalHourOfDayStartName, 20},
-              {UkmEntry::kDurationMillisName,
-               ukm::GetExponentialBucketMinForUserTiming(4000)},
-          },
-      };
-
-  EXPECT_EQ(ukm_metrics, expected_ukm_metrics);
-}
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc
index 3f2e565a..6cedf91 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc
@@ -16,8 +16,6 @@
 #include "chrome/browser/page_load_metrics/observers/ad_metrics/floc_page_load_metrics_observer.h"
 #include "chrome/browser/page_load_metrics/observers/core/amp_page_load_metrics_observer.h"
 #include "chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.h"
-#include "chrome/browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.h"
-#include "chrome/browser/page_load_metrics/observers/data_use_metrics_observer.h"
 #include "chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.h"
 #include "chrome/browser/page_load_metrics/observers/foreground_duration_ukm_observer.h"
 #include "chrome/browser/page_load_metrics/observers/formfill_page_load_metrics_observer.h"
@@ -58,7 +56,6 @@
 
 #if BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/page_load_metrics/observers/android_page_load_metrics_observer.h"
-#include "chrome/browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer.h"
 #else
 #include "chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer.h"
 #endif
@@ -134,8 +131,6 @@
             web_contents()->GetBrowserContext()));
     tracker->AddObserver(std::make_unique<ProtocolPageLoadMetricsObserver>());
     tracker->AddObserver(std::make_unique<TabRestorePageLoadMetricsObserver>());
-    tracker->AddObserver(
-        std::make_unique<DataSaverSiteBreakdownMetricsObserver>());
     std::unique_ptr<page_load_metrics::AdsPageLoadMetricsObserver>
         ads_observer =
             page_load_metrics::AdsPageLoadMetricsObserver::CreateIfNeeded(
@@ -180,7 +175,6 @@
   tracker->AddObserver(
       SecurityStatePageLoadMetricsObserver::MaybeCreateForProfile(
           web_contents()->GetBrowserContext()));
-  tracker->AddObserver(std::make_unique<DataUseMetricsObserver>());
   tracker->AddObserver(
       std::make_unique<PageAnchorsMetricsObserver>(tracker->GetWebContents()));
   std::unique_ptr<TranslatePageLoadMetricsObserver> translate_observer =
@@ -188,14 +182,6 @@
           tracker->GetWebContents());
   if (translate_observer)
     tracker->AddObserver(std::move(translate_observer));
-
-#if BUILDFLAG(IS_ANDROID)
-  std::unique_ptr<OfflineMeasurementsPageLoadMetricsObserver>
-      offline_measurements_observer =
-          OfflineMeasurementsPageLoadMetricsObserver::CreateIfNeeded();
-  if (offline_measurements_observer)
-    tracker->AddObserver(std::move(offline_measurements_observer));
-#endif
 }
 
 bool PageLoadMetricsEmbedder::IsNewTabPageUrl(const GURL& url) {
diff --git a/chrome/browser/payments/android_payment_app_factory_browsertest.cc b/chrome/browser/payments/android_payment_app_factory_browsertest.cc
index 80a8f6a..225b8974 100644
--- a/chrome/browser/payments/android_payment_app_factory_browsertest.cc
+++ b/chrome/browser/payments/android_payment_app_factory_browsertest.cc
@@ -17,7 +17,7 @@
 namespace payments {
 namespace {
 
-struct ScopedTestSupport {
+struct [[maybe_unused]] ScopedTestSupport {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Invoking Play Billing on Chrome OS requires initializing the overlay
   // manager.
@@ -66,7 +66,6 @@
 IN_PROC_BROWSER_TEST_F(AndroidPaymentAppFactoryTest,
                        IgnoreOtherPaymentAppsInTwaWhenHaveAppStoreBilling) {
   ScopedTestSupport scoped_test_support;
-  (void)scoped_test_support;  // Avoid the "unused variable" warning.
 
   std::string method_name = https_server()->GetURL("a.com", "/").spec();
   method_name = method_name.substr(0, method_name.length() - 1);
@@ -105,7 +104,6 @@
 // https://play.google.com/billing payment method.
 IN_PROC_BROWSER_TEST_F(AndroidPaymentAppFactoryTest, PlayBillingPaymentMethod) {
   ScopedTestSupport scoped_test_support;
-  (void)scoped_test_support;  // Avoid the "unused variable" warning.
 
   std::string response = "App store payment method app response for test.";
   test_controller()->SetTwaPackageName("com.example.app");
@@ -131,7 +129,6 @@
 IN_PROC_BROWSER_TEST_F(AndroidPaymentAppFactoryTest,
                        ShowPromiseShouldSkipBrowserPaymentSheet) {
   ScopedTestSupport scoped_test_support;
-  (void)scoped_test_support;  // Avoid the "unused variable" warning.
 
   std::string response = "App store payment method app response for test.";
   test_controller()->SetTwaPackageName("com.example.app");
@@ -159,7 +156,6 @@
 IN_PROC_BROWSER_TEST_F(AndroidPaymentAppFactoryTest,
                        EmptyShowPromiseShouldSkipBrowserPaymentSheet) {
   ScopedTestSupport scoped_test_support;
-  (void)scoped_test_support;  // Avoid the "unused variable" warning.
 
   std::string response = "App store payment method app response for test.";
   test_controller()->SetTwaPackageName("com.example.app");
diff --git a/chrome/browser/permissions/notification_blocked_dialog_controller_android.cc b/chrome/browser/permissions/notification_blocked_dialog_controller_android.cc
index 0a435594c..e92343a9 100644
--- a/chrome/browser/permissions/notification_blocked_dialog_controller_android.cc
+++ b/chrome/browser/permissions/notification_blocked_dialog_controller_android.cc
@@ -28,10 +28,7 @@
     : delegate_(delegate), web_contents_(web_contents) {}
 
 NotificationBlockedDialogController::~NotificationBlockedDialogController() {
-  if (java_object_) {
-    Java_NotificationBlockedDialog_dismissDialog(
-        base::android::AttachCurrentThread(), java_object_);
-  }
+  DismissDialog();
 }
 
 void NotificationBlockedDialogController::ShowDialog(
@@ -73,6 +70,7 @@
 void NotificationBlockedDialogController::OnNegativeButtonClicked(JNIEnv* env) {
   switch (prompt_model_.secondary_button_behavior) {
     case SecondaryButtonBehavior::kShowSettings:
+      delegate_->OnOpenedSettings();
       Java_NotificationBlockedDialog_showSettings(env, GetOrCreateJavaObject());
       return;
     case SecondaryButtonBehavior::kAllowForThisSite:
@@ -86,9 +84,17 @@
 }
 
 void NotificationBlockedDialogController::OnDialogDismissed(JNIEnv* env) {
+  java_object_.Reset();
   delegate_->OnDialogDismissed();
 }
 
+void NotificationBlockedDialogController::DismissDialog() {
+  if (java_object_) {
+    Java_NotificationBlockedDialog_dismissDialog(
+        base::android::AttachCurrentThread(), java_object_);
+  }
+}
+
 base::android::ScopedJavaGlobalRef<jobject>
 NotificationBlockedDialogController::GetOrCreateJavaObject() {
   if (java_object_)
diff --git a/chrome/browser/permissions/notification_blocked_dialog_controller_android.h b/chrome/browser/permissions/notification_blocked_dialog_controller_android.h
index 18b1c74..5ece141 100644
--- a/chrome/browser/permissions/notification_blocked_dialog_controller_android.h
+++ b/chrome/browser/permissions/notification_blocked_dialog_controller_android.h
@@ -29,6 +29,7 @@
     virtual void OnContinueBlocking() = 0;
     virtual void OnAllowForThisSite() = 0;
     virtual void OnLearnMoreClicked() = 0;
+    virtual void OnOpenedSettings() = 0;
     virtual void OnDialogDismissed() = 0;
   };
 
@@ -39,6 +40,7 @@
 
   void ShowDialog(
       permissions::PermissionUiSelector::QuietUiReason quiet_ui_reason);
+  void DismissDialog();
 
   void OnPrimaryButtonClicked(JNIEnv* env);
   void OnNegativeButtonClicked(JNIEnv* env);
diff --git a/chrome/browser/permissions/notification_blocked_message_delegate_android.cc b/chrome/browser/permissions/notification_blocked_message_delegate_android.cc
index e1d47ce7..51f7fc2 100644
--- a/chrome/browser/permissions/notification_blocked_message_delegate_android.cc
+++ b/chrome/browser/permissions/notification_blocked_message_delegate_android.cc
@@ -25,7 +25,9 @@
 NotificationBlockedMessageDelegate::NotificationBlockedMessageDelegate(
     content::WebContents* web_contents,
     std::unique_ptr<Delegate> delegate)
-    : web_contents_(web_contents), delegate_(std::move(delegate)) {
+    : content::WebContentsObserver(web_contents),
+      web_contents_(web_contents),
+      delegate_(std::move(delegate)) {
   message_ = std::make_unique<messages::MessageWrapper>(
       messages::MessageIdentifier::NOTIFICATION_BLOCKED,
       base::BindOnce(
@@ -66,26 +68,52 @@
 }
 
 void NotificationBlockedMessageDelegate::OnLearnMoreClicked() {
+  should_reshow_dialog_on_focus_ = true;
+  dialog_controller_->DismissDialog();
   web_contents_->OpenURL(content::OpenURLParams(
       GetNotificationBlockedLearnMoreUrl(), content::Referrer(),
       WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
       false));
 }
 
+void NotificationBlockedMessageDelegate::OnOpenedSettings() {
+  should_reshow_dialog_on_focus_ = true;
+}
+
 void NotificationBlockedMessageDelegate::OnDialogDismissed() {
   if (!dialog_controller_) {
     // Dismissed by clicking on dialog buttons.
     return;
   }
+  if (should_reshow_dialog_on_focus_) {
+    // When the dialog has been dismissed due to the user clicking on
+    // 'Learn more', do not clean up the dialog instance as the dialog
+    // will be restored when the user navigates back to the original tab.
+    return;
+  }
   dialog_controller_.reset();
   // call Closing destroys the current object.
   delegate_->Closing();
 }
 
-void NotificationBlockedMessageDelegate::HandlePrimaryActionClick() {
-  if (!delegate_ || delegate_->IsPromptDestroyed())
-    return;
+void NotificationBlockedMessageDelegate::OnWebContentsFocused(
+    content::RenderWidgetHost* render_widget_host) {
+  if (should_reshow_dialog_on_focus_ && dialog_controller_) {
+    // This will be true only if the user has been redirected to
+    // a new tab by clicking on 'Learn more' on the dialog.
+    // Upon returning to the original tab from the redirected tab,
+    // the dialog will be restored.
+    should_reshow_dialog_on_focus_ = false;
+    // If the page is navigated to another url, |this| will be destroyed
+    // by the PermissionRequestManager, thereby causing message to be
+    // dismissed and dialog_controller to dismiss the dialog.
+    dialog_controller_->ShowDialog(*delegate_->ReasonForUsingQuietUi());
+    // TODO(crbug.com/1291313): add browser tests to test if
+    // webcontents have been navigated to another page in the meantime.
+  }
+}
 
+void NotificationBlockedMessageDelegate::HandlePrimaryActionClick() {
   DCHECK(delegate_->ShouldUseQuietUI());
   delegate_->Deny();
 }
@@ -94,23 +122,20 @@
   DCHECK(!dialog_controller_);
   dialog_controller_ = std::make_unique<NotificationBlockedDialogController>(
       this, web_contents_);
-  message_->SetSecondaryActionCallback(
-      base::BindOnce(&NotificationBlockedMessageDelegate::HandleManageClick,
-                     base::Unretained(this)));
   dialog_controller_->ShowDialog(*delegate_->ReasonForUsingQuietUi());
+  messages::MessageDispatcherBridge::Get()->DismissMessage(
+      message_.get(), messages::DismissReason::SECONDARY_ACTION);
 }
 
 void NotificationBlockedMessageDelegate::HandleDismissCallback(
     messages::DismissReason reason) {
   // When message is dismissed by secondary action, |permission_prompt_| should
   // be reset when the dialog is dismissed.
-  if (reason != messages::DismissReason::SECONDARY_ACTION && delegate_ &&
-      !delegate_->IsPromptDestroyed()) {
+  if (reason != messages::DismissReason::SECONDARY_ACTION) {
     dialog_controller_.reset();
     // call Closing destroys the current object.
     delegate_->Closing();
   }
-  delegate_.reset();
   message_.reset();
 }
 
@@ -140,10 +165,6 @@
   permission_prompt_.reset();
 }
 
-bool NotificationBlockedMessageDelegate::Delegate::IsPromptDestroyed() {
-  return !permission_prompt_;
-}
-
 bool NotificationBlockedMessageDelegate::Delegate::ShouldUseQuietUI() {
   return permission_prompt_->ShouldCurrentRequestUseQuietUI();
 }
diff --git a/chrome/browser/permissions/notification_blocked_message_delegate_android.h b/chrome/browser/permissions/notification_blocked_message_delegate_android.h
index 1cc0bc55..9ad7880 100644
--- a/chrome/browser/permissions/notification_blocked_message_delegate_android.h
+++ b/chrome/browser/permissions/notification_blocked_message_delegate_android.h
@@ -14,6 +14,7 @@
 #include "components/messages/android/message_enums.h"
 #include "components/messages/android/message_wrapper.h"
 #include "components/permissions/permissions_client.h"
+#include "content/public/browser/web_contents_observer.h"
 
 namespace content {
 class WebContents;
@@ -27,7 +28,8 @@
 // alternative ui to the mini infobar.
 class NotificationBlockedMessageDelegate
     : public NotificationBlockedDialogController::Delegate,
-      public permissions::PermissionsClient::PermissionMessageDelegate {
+      public permissions::PermissionsClient::PermissionMessageDelegate,
+      public content::WebContentsObserver {
  public:
   // Delegate to mock out the |PermissionPromptAndroid| for testing.
   class Delegate {
@@ -39,7 +41,6 @@
     virtual void Accept();
     virtual void Deny();
     virtual void Closing();
-    virtual bool IsPromptDestroyed();
     virtual bool ShouldUseQuietUI();
     virtual absl::optional<permissions::PermissionUiSelector::QuietUiReason>
     ReasonForUsingQuietUi();
@@ -57,8 +58,13 @@
   void OnContinueBlocking() override;
   void OnAllowForThisSite() override;
   void OnLearnMoreClicked() override;
+  void OnOpenedSettings() override;
   void OnDialogDismissed() override;
 
+  // content::WebContentsObserver implementation.
+  void OnWebContentsFocused(
+      content::RenderWidgetHost* render_widget_host) override;
+
  private:
   friend class NotificationBlockedMessageDelegateAndroidTest;
 
@@ -68,10 +74,15 @@
 
   void DismissInternal();
 
+  // `message_` and `dialog_controller_` can not be alive at the same moment,
+  // since message ui and dialog ui won't show together.
   std::unique_ptr<messages::MessageWrapper> message_;
   std::unique_ptr<NotificationBlockedDialogController> dialog_controller_;
   raw_ptr<content::WebContents> web_contents_ = nullptr;
   std::unique_ptr<Delegate> delegate_;
+
+  // Whether we should re-show the dialog to users when users return to the tab.
+  bool should_reshow_dialog_on_focus_ = false;
 };
 
 #endif  // CHROME_BROWSER_PERMISSIONS_NOTIFICATION_BLOCKED_MESSAGE_DELEGATE_ANDROID_H_
diff --git a/chrome/browser/permissions/notification_blocked_message_delegate_android_unittest.cc b/chrome/browser/permissions/notification_blocked_message_delegate_android_unittest.cc
index d8f83c1..0e9c88f6 100644
--- a/chrome/browser/permissions/notification_blocked_message_delegate_android_unittest.cc
+++ b/chrome/browser/permissions/notification_blocked_message_delegate_android_unittest.cc
@@ -25,7 +25,6 @@
   MOCK_METHOD(void, Deny, (), (override));
 
   MOCK_METHOD(void, Closing, (), (override));
-  MOCK_METHOD(bool, IsPromptDestroyed, (), (override));
 
   MOCK_METHOD(bool, ShouldUseQuietUI, (), (override));
   MOCK_METHOD(absl::optional<QuietUiReason>,
@@ -114,8 +113,6 @@
 
 TEST_F(NotificationBlockedMessageDelegateAndroidTest, DismissByTimeout) {
   auto delegate = GetMockDelegate();
-  EXPECT_CALL(*delegate, IsPromptDestroyed)
-      .WillRepeatedly(testing::Return(false));
 
   EXPECT_CALL(*delegate, Closing);
   EXPECT_CALL(*delegate, Accept).Times(0);
@@ -130,8 +127,6 @@
 
 TEST_F(NotificationBlockedMessageDelegateAndroidTest, DismissByPrimaryAction) {
   auto delegate = GetMockDelegate();
-  EXPECT_CALL(*delegate, IsPromptDestroyed)
-      .WillRepeatedly(testing::Return(false));
   EXPECT_CALL(*delegate, ShouldUseQuietUI)
       .WillRepeatedly(testing::Return(true));
 
@@ -147,27 +142,8 @@
 }
 
 TEST_F(NotificationBlockedMessageDelegateAndroidTest,
-       DismissByPrimaryActionWhenPromptDestroyed) {
-  auto delegate = GetMockDelegate();
-  EXPECT_CALL(*delegate, IsPromptDestroyed)
-      .WillRepeatedly(testing::Return(true));
-  EXPECT_CALL(*delegate, ShouldUseQuietUI)
-      .WillRepeatedly(testing::Return(true));
-
-  EXPECT_CALL(*delegate, Closing).Times(0);
-  EXPECT_CALL(*delegate, Accept).Times(0);
-  EXPECT_CALL(*delegate, Deny).Times(0);
-
-  ExpectEnqueued();
-  ShowMessage(std::move(delegate));
-  TriggerPrimaryAction();
-  EXPECT_EQ(nullptr, GetMessageWrapper());
-}
-
-TEST_F(NotificationBlockedMessageDelegateAndroidTest,
        DismissByDialogDismissed) {
   auto delegate = GetMockDelegate();
-  EXPECT_CALL(*delegate, IsPromptDestroyed).WillOnce(testing::Return(true));
   EXPECT_CALL(*delegate, ShouldUseQuietUI)
       .WillRepeatedly(testing::Return(true));
   EXPECT_CALL(*delegate, ReasonForUsingQuietUi)
@@ -183,6 +159,6 @@
   ShowMessage(std::move(delegate));
 
   TriggerManageClick();
+  TriggerDismiss(messages::DismissReason::SECONDARY_ACTION);
   TriggerDialogDismiss();
-  TriggerDismiss(messages::DismissReason::UNKNOWN);
 }
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc
index 0bda00a..0e9e8b1 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor.cc
+++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -180,9 +180,6 @@
   // If the prefetch has already been abandoned, leave it to its own timeout;
   // this normally gets called immediately after OnOmniboxOpenedUrl.
   if (no_state_prefetch_handle_ && !no_state_prefetch_handle_->IsAbandoned()) {
-    UMA_HISTOGRAM_ENUMERATION(
-        "AutocompleteActionPredictor.NoStatePrefetchStatus",
-        PredictionStatus::kCancelled);
     no_state_prefetch_handle_->OnCancel();
     no_state_prefetch_handle_.reset();
   }
@@ -212,7 +209,7 @@
       if (prerender_handle_->GetInitialPrerenderingUrl() == url) {
         return;
       }
-      // `url` does not matched with previously prerendered url. Reset the
+      // `url` does not match with previously prerendered url. Reset the
       // handle to trigger cancellation.
       UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.PrerenderStatus",
                                 PredictionStatus::kCancelled);
@@ -228,10 +225,19 @@
                  features::kOmniboxTriggerForNoStatePrefetch)) {
     content::SessionStorageNamespace* session_storage_namespace =
         web_contents.GetController().GetDefaultSessionStorageNamespace();
-    // Only cancel the old prefetch after starting the new one, so if the URLs
-    // are the same, the underlying prefetcher will be reused.
-    std::unique_ptr<prerender::NoStatePrefetchHandle>
-        old_no_state_prefetch_handle = std::move(no_state_prefetch_handle_);
+    if (no_state_prefetch_handle_) {
+      if (no_state_prefetch_handle_->prerender_url() == url) {
+        // We've already started a prefetch for the target URL. Nothing to do.
+        return;
+      }
+      // `url` does not match with previously prefetched url. Reset the
+      // handle to trigger cancellation.
+      UMA_HISTOGRAM_ENUMERATION(
+          "AutocompleteActionPredictor.NoStatePrefetchStatus",
+          PredictionStatus::kCancelled);
+      no_state_prefetch_handle_->OnCancel();
+      no_state_prefetch_handle_.reset();
+    }
     prerender::NoStatePrefetchManager* no_state_prefetch_manager =
         prerender::NoStatePrefetchManagerFactory::GetForBrowserContext(
             profile_);
@@ -240,8 +246,6 @@
           no_state_prefetch_manager->StartPrefetchingFromOmnibox(
               url, session_storage_namespace, size);
     }
-    if (old_no_state_prefetch_handle)
-      old_no_state_prefetch_handle->OnCancel();
   }
 }
 
@@ -310,9 +314,12 @@
   // Abandon the current prefetch. If it is to be used, it will be used very
   // soon, so use the lower timeout.
   if (no_state_prefetch_handle_) {
-    if (no_state_prefetch_handle_->contents() &&
-        no_state_prefetch_handle_->contents()->prerender_url() == opened_url) {
-      if (no_state_prefetch_handle_->IsFinishedLoading()) {
+    if (no_state_prefetch_handle_->prerender_url() == opened_url) {
+      if (no_state_prefetch_handle_->IsFinishedLoading()
+          // If the handle doesn't have its contents anymore we don't know if it
+          // complete successfully or not, but we know it's no longer active, so
+          // we log this as kHitFinished.
+          || !no_state_prefetch_handle_->contents()) {
         UMA_HISTOGRAM_ENUMERATION(
             "AutocompleteActionPredictor.NoStatePrefetchStatus",
             PredictionStatus::kHitFinished);
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
index 1f21088..5f42d92 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -583,18 +583,13 @@
             "Chrome.OfflineIndicatorV2.NumTimesBackgrounded";
 
     /**
-     * The measurement interval (in minutes) used to schedule the currently running
-     * OfflineMeasureBackgroundTask. This value is zero if the OfflineMeasureBackgroundTask is not
-     * currently running.
+     * Keys used to store data for the OfflineMeasurementsBackgroundTask. The background task has
+     * been removed, and these keys are just used to clear any persisted data.
      */
     public static final String OFFLINE_MEASUREMENTS_CURRENT_TASK_MEASUREMENT_INTERVAL_IN_MINUTES =
             "Chrome.OfflineMeasurements.CurrentTaskMeasurementIntervalInMinutes";
-
-    /** Time of the last OfflineMeasurementsBackgroundTask check. */
     public static final String OFFLINE_MEASUREMENTS_LAST_CHECK_MILLIS =
             "Chrome.OfflineMeasurements.LastCheckMillis";
-
-    /** Parameters that control the HTTP probe of the Offline Measurements Background task */
     public static final String OFFLINE_MEASUREMENTS_USER_AGENT_STRING =
             "Chrome.OfflineMeasurements.UserAgentString";
     public static final String OFFLINE_MEASUREMENTS_HTTP_PROBE_URL =
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 0dd4542..eea4655 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/browser_process_impl.h"
 #include "chrome/browser/chrome_content_browser_client.h"
 #include "chrome/browser/component_updater/component_updater_prefs.h"
-#include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/engagement/important_sites_util.h"
@@ -688,10 +687,6 @@
 const char kStabilitySessionEndCompleted[] =
     "user_experience_metrics.stability.session_end_completed";
 
-// Deprecated 01/2022.
-constexpr char kHasSeenLiteModeInfoBar[] =
-    "litemode.https-image-compression.user-has-seen-infobar";
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Deprecated 12/2021.
 const char kEduCoexistenceSecondaryAccountsInvalidationVersion[] =
@@ -721,6 +716,32 @@
     "search_geolocation_post_disclosure_metrics_recorded";
 #endif  // BUILDFLAG(IS_ANDROID)
 
+// Deprecated 01/2022.
+constexpr char kHasSeenLiteModeInfoBar[] =
+    "litemode.https-image-compression.user-has-seen-infobar";
+const char kDailyHttpContentLengthLastUpdateDate[] =
+    "data_reduction.last_update_date";
+const char kDailyHttpOriginalContentLength[] =
+    "data_reduction.daily_original_length";
+const char kDailyHttpReceivedContentLength[] =
+    "data_reduction.daily_received_length";
+const char kDataUsageReportingEnabled[] = "data_usage_reporting.enabled";
+const char kHttpReceivedContentLength[] = "http_received_content_length";
+const char kHttpOriginalContentLength[] = "http_original_content_length";
+const char kThisWeekNumber[] = "data_reduction.this_week_number";
+const char kThisWeekServicesDownstreamBackgroundKB[] =
+    "data_reduction.this_week_services_downstream_background_kb";
+const char kThisWeekServicesDownstreamForegroundKB[] =
+    "data_reduction.this_week_services_downstream_foreground_kb";
+const char kLastWeekServicesDownstreamBackgroundKB[] =
+    "data_reduction.last_week_services_downstream_background_kb";
+const char kLastWeekServicesDownstreamForegroundKB[] =
+    "data_reduction.last_week_services_downstream_foreground_kb";
+const char kThisWeekUserTrafficContentTypeDownstreamKB[] =
+    "data_reduction.this_week_user_traffic_contenttype_downstream_kb";
+const char kLastWeekUserTrafficContentTypeDownstreamKB[] =
+    "data_reduction.last_week_user_traffic_contenttype_downstream_kb";
+
 // Register local state used only for migration (clearing or moving to a new
 // key).
 void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) {
@@ -942,6 +963,25 @@
 #endif
 
   registry->RegisterBooleanPref(kHasSeenLiteModeInfoBar, false);
+  registry->RegisterInt64Pref(kDailyHttpContentLengthLastUpdateDate, 0L);
+  registry->RegisterListPref(kDailyHttpOriginalContentLength);
+  registry->RegisterListPref(kDailyHttpReceivedContentLength);
+  registry->RegisterBooleanPref(kDataUsageReportingEnabled, false);
+  registry->RegisterInt64Pref(kHttpReceivedContentLength, 0);
+  registry->RegisterInt64Pref(kHttpOriginalContentLength, 0);
+  registry->RegisterIntegerPref(kThisWeekNumber, 0);
+  registry->RegisterDictionaryPref(kThisWeekServicesDownstreamBackgroundKB,
+                                   PrefRegistry::LOSSY_PREF);
+  registry->RegisterDictionaryPref(kThisWeekServicesDownstreamForegroundKB,
+                                   PrefRegistry::LOSSY_PREF);
+  registry->RegisterDictionaryPref(kLastWeekServicesDownstreamBackgroundKB,
+                                   PrefRegistry::LOSSY_PREF);
+  registry->RegisterDictionaryPref(kLastWeekServicesDownstreamForegroundKB,
+                                   PrefRegistry::LOSSY_PREF);
+  registry->RegisterDictionaryPref(kThisWeekUserTrafficContentTypeDownstreamKB,
+                                   PrefRegistry::LOSSY_PREF);
+  registry->RegisterDictionaryPref(kLastWeekUserTrafficContentTypeDownstreamKB,
+                                   PrefRegistry::LOSSY_PREF);
 }
 
 }  // namespace
@@ -952,7 +992,6 @@
   // keep this list alphabetized.
   browser_shutdown::RegisterPrefs(registry);
   data_reduction_proxy::RegisterPrefs(registry);
-  data_use_measurement::ChromeDataUseMeasurement::RegisterPrefs(registry);
   BrowserProcessImpl::RegisterPrefs(registry);
   ChromeContentBrowserClient::RegisterLocalStatePrefs(registry);
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
@@ -1832,9 +1871,20 @@
 
   // Added 01/2022.
   profile_prefs->ClearPref(kHasSeenLiteModeInfoBar);
-
-  // Added 01/2022.
   syncer::SyncTransportDataPrefs::MigrateInvalidationVersions(profile_prefs);
+  profile_prefs->ClearPref(kDailyHttpContentLengthLastUpdateDate);
+  profile_prefs->ClearPref(kDailyHttpOriginalContentLength);
+  profile_prefs->ClearPref(kDailyHttpReceivedContentLength);
+  profile_prefs->ClearPref(kDataUsageReportingEnabled);
+  profile_prefs->ClearPref(kHttpReceivedContentLength);
+  profile_prefs->ClearPref(kHttpOriginalContentLength);
+  profile_prefs->ClearPref(kThisWeekNumber);
+  profile_prefs->ClearPref(kThisWeekServicesDownstreamBackgroundKB);
+  profile_prefs->ClearPref(kThisWeekServicesDownstreamForegroundKB);
+  profile_prefs->ClearPref(kLastWeekServicesDownstreamBackgroundKB);
+  profile_prefs->ClearPref(kLastWeekServicesDownstreamForegroundKB);
+  profile_prefs->ClearPref(kThisWeekUserTrafficContentTypeDownstreamKB);
+  profile_prefs->ClearPref(kLastWeekUserTrafficContentTypeDownstreamKB);
 
   // Please don't delete the following line. It is used by PRESUBMIT.py.
   // END_MIGRATE_OBSOLETE_PROFILE_PREFS
diff --git a/chrome/browser/prerender/payment_request_for_prerender_browsertest.cc b/chrome/browser/prerender/payment_request_for_prerender_browsertest.cc
index 6cddba4..4bc84ea0 100644
--- a/chrome/browser/prerender/payment_request_for_prerender_browsertest.cc
+++ b/chrome/browser/prerender/payment_request_for_prerender_browsertest.cc
@@ -5,8 +5,10 @@
 #include <string>
 
 #include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/scoped_run_loop_timeout.h"
 #include "chrome/test/payments/payment_request_platform_browsertest_base.h"
+#include "content/public/common/content_features.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/prerender_test_util.h"
@@ -40,6 +42,55 @@
 };
 
 IN_PROC_BROWSER_TEST_F(PaymentRequestForPrerenderBrowserTest,
+                       AbortAfterPrerendered) {
+  // Navigate to an initial page.
+  NavigateTo("/payment_request_creator.html");
+
+  // Start a prerender.
+  auto prerender_url =
+      https_server()->GetURL("/payment_request_abort_test.html");
+
+  int prerender_id = prerender_helper_.AddPrerender(prerender_url);
+  auto* prerender_render_frame_host =
+      prerender_helper_.GetPrerenderedMainFrameHost(prerender_id);
+
+  ResetEventWaiterForSingleEvent(TestEvent::kAbortCalled);
+
+  // Try to show PaymentRequest by JS.
+  EXPECT_TRUE(content::ExecJs(prerender_render_frame_host,
+                              "document.getElementById('buy').click();",
+                              content::EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  EXPECT_TRUE(content::ExecJs(prerender_render_frame_host,
+                              "document.getElementById('abort').click();",
+                              content::EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  // Activate the prerendered page.
+  prerender_helper_.NavigatePrimaryPage(prerender_url);
+
+  WaitForObservedEvent();
+
+  ExpectBodyContains({R"(Aborted)"});
+}
+
+class PaymentRequestForPrerenderBrowserBasicCardEnabledTest
+    : public PaymentRequestForPrerenderBrowserTest {
+ public:
+  PaymentRequestForPrerenderBrowserBasicCardEnabledTest(
+      const PaymentRequestForPrerenderBrowserBasicCardEnabledTest&) = delete;
+  PaymentRequestForPrerenderBrowserBasicCardEnabledTest& operator=(
+      const PaymentRequestForPrerenderBrowserBasicCardEnabledTest&) = delete;
+
+ protected:
+  PaymentRequestForPrerenderBrowserBasicCardEnabledTest() {
+    feature_list_.InitAndEnableFeature(::features::kPaymentRequestBasicCard);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(PaymentRequestForPrerenderBrowserBasicCardEnabledTest,
                        ShowAfterPrerendered) {
   // Navigate to an initial page.
   NavigateTo("/payment_request_creator.html");
@@ -72,36 +123,58 @@
   EXPECT_TRUE(is_app_list_ready_fired_);
 }
 
-IN_PROC_BROWSER_TEST_F(PaymentRequestForPrerenderBrowserTest,
-                       AbortAfterPrerendered) {
+class PaymentRequestForPrerenderBrowserBasicCardDisabledTest
+    : public PaymentRequestForPrerenderBrowserTest {
+ public:
+  PaymentRequestForPrerenderBrowserBasicCardDisabledTest(
+      const PaymentRequestForPrerenderBrowserBasicCardDisabledTest&) = delete;
+  PaymentRequestForPrerenderBrowserBasicCardDisabledTest& operator=(
+      const PaymentRequestForPrerenderBrowserBasicCardDisabledTest&) = delete;
+
+ protected:
+  PaymentRequestForPrerenderBrowserBasicCardDisabledTest() {
+    feature_list_.InitAndDisableFeature(::features::kPaymentRequestBasicCard);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(PaymentRequestForPrerenderBrowserBasicCardDisabledTest,
+                       ShowAfterPrerendered) {
+  std::string method;
+  InstallPaymentApp("a.com", "payment_request_success_responder.js", &method);
+
   // Navigate to an initial page.
   NavigateTo("/payment_request_creator.html");
 
   // Start a prerender.
-  auto prerender_url =
-      https_server()->GetURL("/payment_request_abort_test.html");
+  GURL prerender_url =
+      https_server()->GetURL("/payment_request_no_shipping_test.html");
 
   int prerender_id = prerender_helper_.AddPrerender(prerender_url);
-  auto* prerender_render_frame_host =
+  content::RenderFrameHost* prerender_render_frame_host =
       prerender_helper_.GetPrerenderedMainFrameHost(prerender_id);
 
-  ResetEventWaiterForSingleEvent(TestEvent::kAbortCalled);
+  ResetEventWaiterForSingleEvent(TestEvent::kAppListReady);
 
   // Try to show PaymentRequest by JS.
-  EXPECT_TRUE(content::ExecJs(prerender_render_frame_host,
-                              "document.getElementById('buy').click();",
-                              content::EXECUTE_SCRIPT_NO_USER_GESTURE));
+  EXPECT_TRUE(content::ExecJs(
+      prerender_render_frame_host,
+      content::JsReplace("buyWithMethods([{supportedMethods:$1}]);", method),
+      content::EXECUTE_SCRIPT_NO_USER_GESTURE));
 
-  EXPECT_TRUE(content::ExecJs(prerender_render_frame_host,
-                              "document.getElementById('abort').click();",
-                              content::EXECUTE_SCRIPT_NO_USER_GESTURE));
+  // Run the loop to give the test a chance to fail if is_app_list_ready_fired_
+  // is set to true too early.
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(is_app_list_ready_fired_);
 
   // Activate the prerendered page.
   prerender_helper_.NavigatePrimaryPage(prerender_url);
 
   WaitForObservedEvent();
-
-  ExpectBodyContains({R"(Aborted)"});
+  EXPECT_TRUE(is_app_list_ready_fired_);
 }
 
 }  // namespace
diff --git a/chrome/browser/privacy/secure_dns_bridge.cc b/chrome/browser/privacy/secure_dns_bridge.cc
index 3215064..9e9bd43 100644
--- a/chrome/browser/privacy/secure_dns_bridge.cc
+++ b/chrome/browser/privacy/secure_dns_bridge.cc
@@ -27,6 +27,7 @@
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "net/dns/public/dns_over_https_config.h"
 #include "net/dns/public/doh_provider_entry.h"
 #include "net/dns/public/secure_dns_mode.h"
 
@@ -121,7 +122,7 @@
     return true;
   }
 
-  if (secure_dns::IsValidGroup(templates)) {
+  if (net::DnsOverHttpsConfig::FromString(templates).has_value()) {
     local_state->SetString(prefs::kDnsOverHttpsTemplates, templates);
     return true;
   }
@@ -156,7 +157,9 @@
     JNIEnv* env,
     const JavaParamRef<jstring>& jgroup) {
   std::string group = base::android::ConvertJavaStringToUTF8(jgroup);
-  std::vector<base::StringPiece> templates = secure_dns::SplitGroup(group);
+  auto config = net::DnsOverHttpsConfig::FromString(group);
+  DCHECK(config);  // `group` must already have been validated
+  std::vector<base::StringPiece> templates = config->ToStrings();
   std::vector<std::string> templates_copy(templates.begin(), templates.end());
   return base::android::ToJavaArrayOfStrings(env, templates_copy);
 }
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 022dd54a..a106ae0 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -134,7 +134,6 @@
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/pref_names.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
-#include "components/data_reduction_proxy/core/browser/data_store_impl.h"
 #include "components/heavy_ad_intervention/heavy_ad_service.h"
 #include "components/history/core/common/pref_names.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -1591,8 +1590,6 @@
       base::ThreadPool::CreateSequencedTaskRunner(
           {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
            base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
-  std::unique_ptr<data_reduction_proxy::DataStore> store(
-      new data_reduction_proxy::DataStoreImpl(GetPath()));
   DataReductionProxyChromeSettingsFactory::GetForBrowserContext(this)
-      ->InitDataReductionProxySettings(this, std::move(store), db_task_runner);
+      ->InitDataReductionProxySettings(this, db_task_runner);
 }
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index 0c42ba3..26f4502 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -39,8 +39,6 @@
 #include "chrome/browser/browser_features.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
-#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h"
-#include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/download/download_stats.h"
@@ -111,7 +109,6 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/autofill/core/browser/ui/popup_item_ids.h"
 #include "components/autofill/core/common/password_generation_util.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "components/download/public/common/download_url_parameters.h"
 #include "components/google/core/common/google_util.h"
 #include "components/guest_view/browser/guest_view_base.h"
diff --git a/chrome/browser/resources/access_code_cast/access_code_cast.html b/chrome/browser/resources/access_code_cast/access_code_cast.html
index f6bfa129..33cc628 100644
--- a/chrome/browser/resources/access_code_cast/access_code_cast.html
+++ b/chrome/browser/resources/access_code_cast/access_code_cast.html
@@ -1,12 +1,23 @@
 <style include="cr-shared-style">
+  .body-1 {
+    font-size: 14px;
+  }
+
+  .title-1 {
+    font-size: 16px;
+  }
+
   .button-image {
     margin-inline-end: 8px;
   }
 
-  .center {
-    left: 50%;
-    top: 50%;
-    transform: translateY(-50%) translateX(-50%);
+  .center-content {
+    text-align: center;
+    width: 100%;
+  }
+
+  .space {
+    height: 48px;
   }
 
   .text-button:not(:focus) {
@@ -27,23 +38,23 @@
   cr-dialog [slot=body] {
     height: 480px;
   }
-
-  #input-container {
-    text-align: center;
-  }
 </style>
 <cr-dialog id="dialog">
-  <div slot="title">$i18n{dialogTitle}</div>
+  <div slot="title" class="title-1">$i18n{dialogTitle}</div>
   <div slot="body">
     <div id="codeInputView">
-      <div id="input-container">
+      <div class="body-1">$i18n{accessCodeMessage}</div>
+      <div class="space"></div>
+      <div class="center-content">
         <c2c-code-input length="6" value="" id="codeInput"></c2c-code-input>
       </div>
-      <template is="dom-if" if="[[qrScannerEnabled]]">
-        <cr-button on-click="switchToQrInput" class="center text-button">
-          <iron-icon class="button-image" icon="cr:videocam"></iron-icon>
-          $i18n{useCamera}
-        </cr-button>
+      <template is="dom-if" if="[[qrScannerEnabled]]" class="center-content">
+        <div class="center-content">
+          <cr-button on-click="switchToQrInput" class="center text-button">
+            <iron-icon class="button-image" icon="cr:videocam"></iron-icon>
+            $i18n{useCamera}
+          </cr-button>
+        </div>
       </template>
     </div>
     <div id="qrInputView">
diff --git a/chrome/browser/resources/access_code_cast/access_code_cast.ts b/chrome/browser/resources/access_code_cast/access_code_cast.ts
index 0ee49ecd..7e89e14 100644
--- a/chrome/browser/resources/access_code_cast/access_code_cast.ts
+++ b/chrome/browser/resources/access_code_cast/access_code_cast.ts
@@ -13,6 +13,8 @@
 
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js';
+import {WebUIListenerMixin} from 'chrome://resources/js/web_ui_listener_mixin.js';
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 
@@ -41,7 +43,9 @@
   }
 }
 
-class AccessCodeCastElement extends PolymerElement {
+const AccessCodeCastElementBase = WebUIListenerMixin(I18nMixin(PolymerElement));
+
+class AccessCodeCastElement extends AccessCodeCastElementBase {
   static get is() {
     return 'access-code-cast-app';
   }
diff --git a/chrome/browser/resources/access_code_cast/code_input/code_input.ts b/chrome/browser/resources/access_code_cast/code_input/code_input.ts
index a6f59f19..d1d1d12 100644
--- a/chrome/browser/resources/access_code_cast/code_input/code_input.ts
+++ b/chrome/browser/resources/access_code_cast/code_input/code_input.ts
@@ -137,8 +137,9 @@
     if (value.length) {
       this.focusNext(index);
       this.getInput(index).value = value.trim().toUpperCase()[0];
-      this.updateValue();
     }
+
+    this.updateValue();
   }
 
   private handleBackspace(index: number) {
@@ -148,6 +149,8 @@
     } else if (this.getInput(index).inputElement.selectionStart === 0) {
       this.focusPrev(index);
     }
+
+    this.updateValue();
   }
 
   private updateValue() {
diff --git a/chrome/browser/resources/app_settings/app.html b/chrome/browser/resources/app_settings/app.html
index db69863..cc55854 100644
--- a/chrome/browser/resources/app_settings/app.html
+++ b/chrome/browser/resources/app_settings/app.html
@@ -1 +1,64 @@
-<div>$i18n{title}</div>
+<style include="app-management-shared-css">
+  #content {
+    background-color: var(--cr-card-background-color);
+    border-radius: var(--cr-card-border-radius);
+    box-shadow: var(--cr-card-shadow);
+    color: var(--cr-primary-text-color);
+    /* Follows margin used in chrome://history */
+    margin-top: 24px;
+  }
+
+  /* Follows styles in settings_subpage for header and app title */
+  #headerLine {
+    min-height: 40px;
+    padding-bottom: 24px;
+    padding-top: 8px;
+  }
+
+  #title-icon {
+    height: 36px;
+    margin-inline-end: 12px;
+    margin-inline-start: 2px;
+    width: 36px;
+  }
+</style>
+<cr-toolbar page-name="$i18n{title}" show-search="[[showSearch_]]">
+</cr-toolbar>
+<div id="content" class="cr-centered-card-container">
+  <div class="cr-row first" id="headerLine">
+    <img id="title-icon" src="[[iconUrl_]]" aria-hidden="true">
+    <h1 class="cr-title-text">[[app_.title]]</h1>
+  </div>
+  <div class="permission-list">
+    <app-management-permission-item
+        class="permission-card-row separated-row header-text"
+        app="[[app_]]"
+        permission-label="$i18n{appManagementNotificationsLabel}"
+        permission-type="kNotifications">
+    </app-management-permission-item>
+    <div id="permissions-card" class="permission-card-row">
+      <div class="permission-section-header">
+        <div class="header-text">$i18n{appManagementPermissionsLabel}</div>
+      </div>
+      <div class="permission-list indented-permission-block">
+        <app-management-permission-item
+            class="subpermission-row" icon="app-management:location"
+            app="[[app_]]"
+            permission-label="$i18n{appManagementLocationPermissionLabel}"
+            permission-type="kLocation">
+        </app-management-permission-item>
+        <app-management-permission-item class="subpermission-row"
+            icon="app-management:camera"
+            app="[[app_]]"
+            permission-label="$i18n{appManagementCameraPermissionLabel}"
+            permission-type="kCamera">
+        </app-management-permission-item>
+        <app-management-permission-item
+            class="subpermission-row" icon="app-management:microphone"
+            app="[[app_]]"
+            permission-label="$i18n{appManagementMicrophonePermissionLabel}"
+            permission-type="kMicrophone">
+        </app-management-permission-item>
+      </div>
+  </div>
+</div>
diff --git a/chrome/browser/resources/app_settings/app.ts b/chrome/browser/resources/app_settings/app.ts
index ca80e37..236e589 100644
--- a/chrome/browser/resources/app_settings/app.ts
+++ b/chrome/browser/resources/app_settings/app.ts
@@ -2,8 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import './strings.m.js';
+import 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.js';
+import 'chrome://resources/cr_components/app_management/permission_item.js';
+import 'chrome://resources/cr_components/app_management/icons.js';
+
+import {App} from 'chrome://resources/cr_components/app_management/app_management.mojom-webui.js';
+import {BrowserProxy} from 'chrome://resources/cr_components/app_management/browser_proxy.js';
+import {getAppIcon} from 'chrome://resources/cr_components/app_management/util.js';
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+
 export class WebAppSettingsAppElement extends PolymerElement {
   static get is() {
     return 'web-app-settings-app';
@@ -12,6 +21,45 @@
   static get template() {
     return html`{__html_template__}`;
   }
+
+  static get properties() {
+    return {
+      app_: Object,
+      iconUrl_: {type: String, computed: 'getAppIcon_(app_)'},
+      showSearch_: {type: Boolean, value: false, readonly: true},
+    };
+  }
+
+  private appId_: string;
+  private app_: App|null;
+  private iconUrl_: string;
+  private showSearch_: boolean;
+
+  connectedCallback() {
+    super.connectedCallback();
+    const urlPath = new URL(document.URL).pathname;
+    if (urlPath.length <= 1) {
+      return;
+    }
+    const appId = urlPath.substring(1);
+    BrowserProxy.getInstance().handler.getApp(appId).then((result) => {
+      this.app_ = result.app;
+    });
+
+    // Listens to app update.
+    const callbackRouter = BrowserProxy.getInstance().callbackRouter;
+    callbackRouter.onAppChanged.addListener(this.onAppChanged_.bind(this));
+  }
+
+  private onAppChanged_(app: App) {
+    if (this.app_ && app.id === this.app_.id) {
+      this.app_ = app;
+    }
+  }
+
+  private getAppIcon_(app: App|null): string {
+    return app ? getAppIcon(app) : '';
+  }
 }
 
 customElements.define(WebAppSettingsAppElement.is, WebAppSettingsAppElement);
diff --git a/chrome/browser/resources/extensions/code_section.ts b/chrome/browser/resources/extensions/code_section.ts
index bc7110a..ab58b86b 100644
--- a/chrome/browser/resources/extensions/code_section.ts
+++ b/chrome/browser/resources/extensions/code_section.ts
@@ -179,5 +179,12 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'extensions-code-section': ExtensionsCodeSectionElement;
+  }
+}
+
+
 customElements.define(
     ExtensionsCodeSectionElement.is, ExtensionsCodeSectionElement);
diff --git a/chrome/browser/resources/extensions/detail_view.html b/chrome/browser/resources/extensions/detail_view.html
index 181178e..73c5ad7 100644
--- a/chrome/browser/resources/extensions/detail_view.html
+++ b/chrome/browser/resources/extensions/detail_view.html
@@ -397,7 +397,7 @@
         </template>
       </div>
     </template>
-    <cr-link-row class="hr" id="extensions-options"
+    <cr-link-row class="hr" id="extensionsOptions"
         disabled="[[!isEnabled_(data.state)]]"
         hidden="[[!shouldShowOptionsLink_(data.*)]]"
         label="$i18n{itemOptions}" on-click="onExtensionOptionsTap_"
diff --git a/chrome/browser/resources/extensions/detail_view.ts b/chrome/browser/resources/extensions/detail_view.ts
index 6dfb1e83..10eb277 100644
--- a/chrome/browser/resources/extensions/detail_view.ts
+++ b/chrome/browser/resources/extensions/detail_view.ts
@@ -25,7 +25,9 @@
 import './toggle_row.js';
 
 import {CrContainerShadowMixin} from 'chrome://resources/cr_elements/cr_container_shadow_mixin.js';
+import {CrLinkRowElement} from 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import {CrToggleElement} from 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
+import {CrTooltipIconElement} from 'chrome://resources/cr_elements/policy/cr_tooltip_icon.m.js';
 import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {afterNextRender, html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -39,8 +41,12 @@
 export interface ExtensionsDetailViewElement {
   $: {
     closeButton: HTMLElement,
+    description: HTMLElement,
     enableToggle: CrToggleElement,
     extensionsActivityLogLink: HTMLElement,
+    extensionsOptions: CrLinkRowElement,
+    parentDisabledPermissionsToolTip: CrTooltipIconElement,
+    source: HTMLElement,
   };
 }
 
@@ -131,7 +137,7 @@
    * dialog closes.
    */
   focusOptionsButton() {
-    this.shadowRoot!.querySelector<HTMLElement>('#extensions-options')!.focus();
+    this.$.extensionsOptions.focus();
   }
 
   /**
diff --git a/chrome/browser/resources/extensions/error_page.ts b/chrome/browser/resources/extensions/error_page.ts
index 90a1e3c..fbeab87 100644
--- a/chrome/browser/resources/extensions/error_page.ts
+++ b/chrome/browser/resources/extensions/error_page.ts
@@ -75,7 +75,7 @@
   return warn;
 }
 
-interface ExtensionsErrorPageElement {
+export interface ExtensionsErrorPageElement {
   $: {
     closeButton: HTMLElement,
   };
@@ -83,7 +83,7 @@
 
 const ExtensionsErrorPageElementBase = CrContainerShadowMixin(PolymerElement);
 
-class ExtensionsErrorPageElement extends ExtensionsErrorPageElementBase {
+export class ExtensionsErrorPageElement extends ExtensionsErrorPageElementBase {
   static get is() {
     return 'extensions-error-page';
   }
@@ -385,5 +385,11 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'extensions-error-page': ExtensionsErrorPageElement;
+  }
+}
+
 customElements.define(
     ExtensionsErrorPageElement.is, ExtensionsErrorPageElement);
diff --git a/chrome/browser/resources/extensions/extensions.ts b/chrome/browser/resources/extensions/extensions.ts
index 61090b7..a866cd67 100644
--- a/chrome/browser/resources/extensions/extensions.ts
+++ b/chrome/browser/resources/extensions/extensions.ts
@@ -4,12 +4,16 @@
 
 import './manager.js';
 
+export {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
 export {getToastManager} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.js';
 export {ActivityLogExtensionPlaceholder, ExtensionsActivityLogElement} from './activity_log/activity_log.js';
 export {ActivityLogHistoryElement, ActivityLogPageState} from './activity_log/activity_log_history.js';
 export {ActivityGroup, ActivityLogHistoryItemElement} from './activity_log/activity_log_history_item.js';
 export {ActivityLogStreamElement} from './activity_log/activity_log_stream.js';
 export {ActivityLogStreamItemElement, ARG_URL_PLACEHOLDER, StreamItem} from './activity_log/activity_log_stream_item.js';
+export {ExtensionsCodeSectionElement} from './code_section.js';
+export {ExtensionsDetailViewElement} from './detail_view.js';
+export {ErrorPageDelegate, ExtensionsErrorPageElement} from './error_page.js';
 export {ItemDelegate} from './item.js';
 export {UserAction} from './item_util.js';
 // <if expr="chromeos">
diff --git a/chrome/browser/resources/extensions/manager.ts b/chrome/browser/resources/extensions/manager.ts
index 59be9b8..4f2e680 100644
--- a/chrome/browser/resources/extensions/manager.ts
+++ b/chrome/browser/resources/extensions/manager.ts
@@ -675,4 +675,10 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'extensions-manager': ExtensionsManagerElement;
+  }
+}
+
 customElements.define(ExtensionsManagerElement.is, ExtensionsManagerElement);
diff --git a/chrome/browser/resources/read_later/side_panel/bookmarks_list.ts b/chrome/browser/resources/read_later/side_panel/bookmarks_list.ts
index 89cbdbb..d5eab06 100644
--- a/chrome/browser/resources/read_later/side_panel/bookmarks_list.ts
+++ b/chrome/browser/resources/read_later/side_panel/bookmarks_list.ts
@@ -272,7 +272,6 @@
     if (!event.ctrlKey && !event.metaKey) {
       return;
     }
-
     event.preventDefault();
     const eventTarget = event.composedPath()[0] as HTMLElement;
     const bookmarkData = getBookmarkFromElement(eventTarget);
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
index 88154190..05e746b4 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
@@ -77,14 +77,21 @@
     width: 100%;
   }
 
-  .account-list-header-description > .secondary {
-    flex-grow: 1;
+  .account-list-header-description.with-padding {
+    padding-top: 16px;
   }
 
-  .account-list-header-description > .secondary {
+  .account-list-header-description > .secondary,
+  .account-list-header-description > h2 {
+    flex-grow: 1;
     padding-inline-end: 40px;
   }
 
+  .account-list-header-description > h2 {
+    padding-bottom: 16px;
+    padding-top: 16px;
+  }
+
   .secondary-accounts-disabled-tooltip {
     padding-inline-end: 12px;
   }
@@ -253,11 +260,15 @@
 <!-- Secondary Accounts list header -->
 <div class="secondary-accounts-box settings-box first">
   <div id="account-list-header" class="start">
-    <h2>
+    <h2 hidden$="[[isArcAccountRestrictionsEnabled_]]">
       [[getAccountListHeader_(isChildUser_)]]
     </h2>
-    <div class="account-list-header-description">
-      <span class="secondary">
+    <div class$="[[
+        getAccountListHeaderClass_(isArcAccountRestrictionsEnabled_)]]">
+      <h2 hidden$="[[!isArcAccountRestrictionsEnabled_]]">
+        [[getAccountListHeader_(isChildUser_)]]
+      </h2>
+      <span class="secondary" hidden$="[[isArcAccountRestrictionsEnabled_]]">
         [[getAccountListDescription_(isChildUser_)]]
       </span>
       <template is="dom-if" if="[[
@@ -279,6 +290,9 @@
             isSecondaryGoogleAccountSigninAllowed_)]]
       </cr-button>
     </div>
+    <span class="secondary" hidden$="[[!isArcAccountRestrictionsEnabled_]]">
+      [[getAccountListDescription_(isChildUser_)]]
+    </span>
   </div>
 </div>
 <!-- Secondary Accounts list -->
@@ -311,10 +325,9 @@
       </div>
       <!-- Display ARC status -->
       <template is="dom-if" if="[[isArcAccountRestrictionsEnabled_]]">
-        <span class="arc-availability secondary"
-            hidden$="[[item.isAvailableInArc]]">
-          <!-- TODO(crbug.com/1260909): Use real strings -->
-          Not shared with Android apps
+        <span class="arc-availability secondary" id="arc-status-[[index]]"
+            aria-hidden="true" hidden$="[[item.isAvailableInArc]]">
+          $i18n{accountNotUsedInArcLabel}
         </span>
       </template>
       <template is="dom-if"
@@ -330,6 +343,7 @@
           title="[[getMoreActionsTitle_(item)]]"
           aria-label="[[getMoreActionsTitle_(item)]]"
           aria-describedby$="fullName-[[index]]
+                              arc-status-[[index]]
                               edu-account-label-[[index]]"
           on-click="onAccountActionsMenuButtonTap_"
           deep-link-focus-id$="[[Setting.kRemoveAccount]]">
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js
index fc45e7d0..846e6f2 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js
@@ -206,6 +206,16 @@
   },
 
   /**
+   * @return {string} class name for account list header class.
+   * @private
+   */
+  getAccountListHeaderClass_() {
+    return this.isArcAccountRestrictionsEnabled_ ?
+        'account-list-header-description with-padding' :
+        'account-list-header-description';
+  },
+
+  /**
    * @param {string} iconUrl
    * @return {string} A CSS image-set for multiple scale factors.
    * @private
@@ -430,10 +440,9 @@
     if (!this.actionMenuAccount_) {
       return '';
     }
-    // TODO(crbug.com/1260909): Use real strings.
     return this.actionMenuAccount_.isAvailableInArc ?
-        'Don\'t share with Android apps' :
-        'Share with Android apps';
+        this.i18n('accountStopUsingInArcButtonLabel') :
+        this.i18n('accountUseInArcButtonLabel');
   },
 
   /**
diff --git a/chrome/browser/subresource_filter/ad_tagging_browsertest.cc b/chrome/browser/subresource_filter/ad_tagging_browsertest.cc
index 7eb0833..bdb8cc2 100644
--- a/chrome/browser/subresource_filter/ad_tagging_browsertest.cc
+++ b/chrome/browser/subresource_filter/ad_tagging_browsertest.cc
@@ -970,9 +970,7 @@
 };
 
 IN_PROC_BROWSER_TEST_P(AdClickNavigationBrowserTest, UseCounter) {
-  NavigationInitiationType type;
-  bool gesture;
-  std::tie(type, gesture) = GetParam();
+  auto [type, gesture] = GetParam();
   auto web_feature_waiter =
       std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
           GetWebContents());
@@ -1050,9 +1048,7 @@
 // crbug.com/997410. The test is flaky on multiple platforms.
 IN_PROC_BROWSER_TEST_P(AdTaggingEventFromSubframeBrowserTest,
                        DISABLED_WindowOpenFromSubframe) {
-  bool cross_origin;
-  bool from_ad_subframe;
-  std::tie(cross_origin, from_ad_subframe) = GetParam();
+  auto [cross_origin, from_ad_subframe] = GetParam();
   SCOPED_TRACE(::testing::Message()
                << "cross_origin = " << cross_origin << ", "
                << "from_ad_subframe = " << from_ad_subframe);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 68f29921..e3dd9b3f 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2921,6 +2921,7 @@
       "//ash/webui/help_app_ui",
       "//ash/webui/help_app_ui/search:mojo_bindings",
       "//ash/webui/media_app_ui",
+      "//ash/webui/multidevice_debug",
       "//ash/webui/network_ui:network_diagnostics_resource_provider",
       "//ash/webui/network_ui:network_health_resource_provider",
       "//ash/webui/network_ui:traffic_counters_resource_provider",
@@ -2979,7 +2980,6 @@
       "//chromeos/components/local_search_service/public/cpp",
       "//chromeos/components/local_search_service/public/mojom",
       "//chromeos/components/multidevice",
-      "//chromeos/components/multidevice/debug_webui",
       "//chromeos/components/multidevice/logging",
       "//chromeos/components/onc",
       "//chromeos/components/quick_answers",
@@ -3818,6 +3818,8 @@
 
   if (is_win || is_mac || is_linux) {
     sources += [
+      "webui/app_settings/web_app_settings_navigation_throttle.cc",
+      "webui/app_settings/web_app_settings_navigation_throttle.h",
       "webui/app_settings/web_app_settings_ui.cc",
       "webui/app_settings/web_app_settings_ui.h",
     ]
diff --git a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java
index b33f2e73..d4392dc 100644
--- a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java
+++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenu.java
@@ -43,13 +43,13 @@
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.chrome.browser.ui.appmenu.internal.R;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter;
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightParams;
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightShape;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.ModelListAdapter;
 import org.chromium.ui.modelutil.PropertyModel;
-import org.chromium.ui.widget.ChipView;
 import org.chromium.ui.widget.Toast;
 
 import java.util.ArrayList;
diff --git a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuTest.java b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuTest.java
index 9adae1d..1fd08db 100644
--- a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuTest.java
+++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuTest.java
@@ -38,12 +38,12 @@
 import org.chromium.chrome.browser.lifecycle.LifecycleObserver;
 import org.chromium.chrome.browser.ui.appmenu.test.R;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.browser_ui.widget.highlight.ViewHighlighterTestUtils;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.DummyUiActivity;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
 import org.chromium.ui.test.util.UiDisableIf;
-import org.chromium.ui.widget.ChipView;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/chrome/browser/ui/android/appmenu/internal/test/java/res/layout/test_menu_footer.xml b/chrome/browser/ui/android/appmenu/internal/test/java/res/layout/test_menu_footer.xml
index 5be8817e..848a0df 100644
--- a/chrome/browser/ui/android/appmenu/internal/test/java/res/layout/test_menu_footer.xml
+++ b/chrome/browser/ui/android/appmenu/internal/test/java/res/layout/test_menu_footer.xml
@@ -11,7 +11,7 @@
         android:layout_height="match_parent"
         android:text="Menu Footer"
         tools:ignore="HardcodedText" />
-    <org.chromium.ui.widget.ChipView
+    <org.chromium.components.browser_ui.widget.chips.ChipView
         android:id="@+id/menu_footer_chip_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content" />
diff --git a/chrome/browser/ui/android/context_menu_helper.cc b/chrome/browser/ui/android/context_menu_helper.cc
index a9e78b88..981068ca 100644
--- a/chrome/browser/ui/android/context_menu_helper.cc
+++ b/chrome/browser/ui/android/context_menu_helper.cc
@@ -16,7 +16,6 @@
 #include "chrome/android/chrome_jni_headers/ContextMenuHelper_jni.h"
 #include "chrome/browser/performance_hints/performance_hints_observer.h"
 #include "chrome/browser/vr/vr_tab_helper.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "components/embedder_support/android/contextmenu/context_menu_builder.h"
 #include "content/public/browser/context_menu_params.h"
 #include "content/public/browser/render_frame_host.h"
diff --git a/chrome/browser/ui/android/signin/java/res/layout/personalized_signin_promo_view_settings.xml b/chrome/browser/ui/android/signin/java/res/layout/personalized_signin_promo_view_settings.xml
index 6ab56a20..1a0a4ec 100644
--- a/chrome/browser/ui/android/signin/java/res/layout/personalized_signin_promo_view_settings.xml
+++ b/chrome/browser/ui/android/signin/java/res/layout/personalized_signin_promo_view_settings.xml
@@ -18,7 +18,6 @@
             android:id="@+id/signin_promo_view_wrapper"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:theme="@style/ThemeRefactorOverlay.Enabled.SettingsPromo"
             style="@style/MaterialCardStyle">
 
             <org.chromium.chrome.browser.ui.signin.PersonalizedSigninPromoView
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc b/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc
index 301b151..352aa17 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc
@@ -184,7 +184,6 @@
   MaybeCreateAppLaunchHandler();
   DCHECK(app_launch_handler_);
 
-  // TODO: Verify this method works in tests when reading from storage.
   if (launch_template_for_test_) {
     OnGetTemplateForDeskLaunch(
         std::move(callback),
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_client.h b/chrome/browser/ui/ash/desks_templates/desks_templates_client.h
index 32d6a978..6f20409 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_client.h
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_client.h
@@ -52,6 +52,8 @@
   // |""| as the error string with the pointer to the captured desk template,
   // otherwise, |callback| will be invoked with a description of the error as
   // the |error| with a nullptr.
+  // TODO(crbug.com/1286515): This will be removed with the extension. Avoid
+  // further uses of this method.
   void CaptureActiveDeskAndSaveTemplate(
       CaptureActiveDeskAndSaveTemplateCallback callback);
 
@@ -63,6 +65,8 @@
   // storage. If no such existing desk template can be found or the file
   // operation has failed, |callback| will be invoked with a description of the
   // error as the |error|.
+  // TODO(crbug.com/1286515): This will be removed with the extension. Avoid
+  // further uses of this method.
   void UpdateDeskTemplate(const std::string& template_uuid,
                           const std::u16string& template_name,
                           UpdateDeskTemplateCallback callback);
@@ -73,13 +77,17 @@
   // deleted, |callback| will be invoked with a description of the error.
   // If it can be deleted successfully, or there is no such |template_uuid|
   // to be removed,|callback| will be invoked with an empty error string.
+  // TODO(crbug.com/1286515): This will be removed with the extension. Avoid
+  // further uses of this method.
   void DeleteDeskTemplate(const std::string& template_uuid,
                           DeleteDeskTemplateCallback callback);
 
-  using TemplateList = std::vector<ash::DeskTemplate*>;
   using GetDeskTemplatesCallback =
-      base::OnceCallback<void(const TemplateList&, std::string error)>;
+      base::OnceCallback<void(const std::vector<ash::DeskTemplate*>&,
+                              std::string error)>;
   // Returns the current available saved desk templates.
+  // TODO(crbug.com/1286515): This will be removed with the extension. Avoid
+  // further uses of this method.
   void GetDeskTemplates(GetDeskTemplatesCallback callback);
 
   using GetTemplateJsonCallback =
@@ -98,6 +106,8 @@
   // no such id can be found or we are at the max desk limit (currently is 8)
   // so can't create new desk for the desk template, |callback| will be invoked
   // with a description of the error.
+  // TODO(crbug.com/1286515): This will be removed with the extension. Avoid
+  // further uses of this method.
   void LaunchDeskTemplate(const std::string& template_uuid,
                           LaunchDeskTemplateCallback callback);
 
@@ -183,8 +193,8 @@
                          desks_storage::DeskModel::GetTemplateJsonStatus status,
                          const std::string& json_representation);
 
-  // Convenience pointer to ash::DesksController.
-  // Guaranteed to be not null for the duration of `this`.
+  // Convenience pointer to ash::DesksController. Guaranteed to be not null for
+  // the duration of `this`.
   ash::DesksController* const desks_controller_;
 
   Profile* active_profile_ = nullptr;
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc b/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
index 562938b..0693a90 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
@@ -346,6 +346,9 @@
   DesksTemplatesClientTest& operator=(const DesksTemplatesClientTest&) = delete;
   ~DesksTemplatesClientTest() override = default;
 
+  // TODO(crbug.com/1286515): These functions will be removed with the
+  // extension. Avoid further uses of this method and create or launch templates
+  // by mocking clicks on the system UI.
   void SetTemplate(std::unique_ptr<ash::DeskTemplate> launch_template) {
     DesksTemplatesClient::Get()->launch_template_for_test_ =
         std::move(launch_template);
diff --git a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc
index ba70138..b268816 100644
--- a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc
+++ b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc
@@ -104,7 +104,11 @@
 void MediaToolbarButtonView::Enable() {
   SetEnabled(true);
 
-  if (media::IsLiveCaptionFeatureEnabled()) {
+  // Have to check for browser window because this can be called during setup,
+  // before there is a valid widget to anchor anything to. Previously any
+  // attempt to display an IPH at this point would have simply failed, so this
+  // is not a behavioral change (see crbug.com/1291170).
+  if (browser_->window() && media::IsLiveCaptionFeatureEnabled()) {
     // Live Caption multi language is only enabled when SODA is also enabled.
     if (base::FeatureList::IsEnabled(media::kLiveCaptionMultiLanguage)) {
       browser_->window()->MaybeShowFeaturePromo(
@@ -161,6 +165,12 @@
 }
 
 void MediaToolbarButtonView::ClosePromoBubble() {
+  // This can get called during setup before the window is even added to the
+  // browser (and before any bubbles could possibly be shown) so if there is no
+  // window, just bail.
+  if (!browser_->window())
+    return;
+
   browser_->window()->CloseFeaturePromo(
       feature_engagement::kIPHLiveCaptionFeature);
   browser_->window()->CloseFeaturePromo(
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view.cc b/chrome/browser/ui/views/passwords/password_save_update_view.cc
index f83c2357..2bf8a8d 100644
--- a/chrome/browser/ui/views/passwords/password_save_update_view.cc
+++ b/chrome/browser/ui/views/passwords/password_save_update_view.cc
@@ -38,6 +38,7 @@
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/interaction/element_identifier.h"
+#include "ui/base/interaction/element_tracker.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/combobox_model.h"
 #include "ui/base/models/combobox_model_observer.h"
@@ -661,10 +662,16 @@
               IDS_PASSWORD_MANAGER_IPH_BODY_SAVE_REAUTH_FAIL);
       promo_spec.SetBubbleArrow(HelpBubbleArrow::kRightCenter);
 
-      failed_reauth_promo_bubble_ = promo_controller->ShowCriticalPromo(
-          promo_spec,
+      auto* const anchor_element =
           views::ElementTrackerViews::GetInstance()->GetElementForView(
-              destination_dropdown_, true));
+              destination_dropdown_, true);
+      // If the destination dropdown isn't currently visible, there will be no
+      // matching element, and we cannot show the bubble (there wouldn't be
+      // anything to anchor it to). This check avoids crbug.com/1291194.
+      if (anchor_element) {
+        failed_reauth_promo_bubble_ =
+            promo_controller->ShowCriticalPromo(promo_spec, anchor_element);
+      }
       break;
     }
   }
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
index 6bc62bf..07e9fe67 100644
--- a/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
@@ -71,7 +71,25 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(PaymentMethodViewControllerTest, OneCardSelected) {
+class PaymentMethodViewControllerBasicCardTest
+    : public PaymentMethodViewControllerTest {
+ public:
+  PaymentMethodViewControllerBasicCardTest(
+      const PaymentMethodViewControllerBasicCardTest&) = delete;
+  PaymentMethodViewControllerBasicCardTest& operator=(
+      const PaymentMethodViewControllerBasicCardTest&) = delete;
+
+ protected:
+  PaymentMethodViewControllerBasicCardTest() {
+    feature_list_.InitAndEnableFeature(features::kPaymentRequestBasicCard);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(PaymentMethodViewControllerBasicCardTest,
+                       OneCardSelected) {
   NavigateTo("/payment_request_no_shipping_test.html");
   autofill::AutofillProfile billing_profile(autofill::test::GetFullProfile());
   AddAutofillProfile(billing_profile);
@@ -97,7 +115,7 @@
   EXPECT_TRUE(checkmark_view->GetVisible());
 }
 
-IN_PROC_BROWSER_TEST_F(PaymentMethodViewControllerTest,
+IN_PROC_BROWSER_TEST_F(PaymentMethodViewControllerBasicCardTest,
                        OneCardSelectedOutOfMany) {
   NavigateTo("/payment_request_no_shipping_test.html");
   autofill::AutofillProfile billing_profile(autofill::test::GetFullProfile());
@@ -160,7 +178,8 @@
             request->state()->selected_app());
 }
 
-IN_PROC_BROWSER_TEST_F(PaymentMethodViewControllerTest, EditButtonOpensEditor) {
+IN_PROC_BROWSER_TEST_F(PaymentMethodViewControllerBasicCardTest,
+                       EditButtonOpensEditor) {
   NavigateTo("/payment_request_no_shipping_test.html");
   AddCreditCard(autofill::test::GetCreditCard());
 
@@ -201,4 +220,75 @@
   EXPECT_EQ(nullptr, add_card_button);
 }
 
+class PaymentMethodViewControllerPaymentHandlerTest
+    : public PaymentMethodViewControllerTest {
+ public:
+  PaymentMethodViewControllerPaymentHandlerTest(
+      const PaymentMethodViewControllerPaymentHandlerTest&) = delete;
+  PaymentMethodViewControllerPaymentHandlerTest& operator=(
+      const PaymentMethodViewControllerPaymentHandlerTest&) = delete;
+
+ protected:
+  PaymentMethodViewControllerPaymentHandlerTest() {
+    feature_list_.InitAndDisableFeature(features::kPaymentRequestBasicCard);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(PaymentMethodViewControllerPaymentHandlerTest,
+                       OneAppSelectedOutOfMany) {
+  std::string payment_method_a;
+  InstallPaymentApp("a.com", "/nickpay.com/app.js", &payment_method_a);
+  std::string payment_method_b;
+  InstallPaymentApp("b.com", "/nickpay.com/app.js", &payment_method_b);
+
+  NavigateTo("/payment_request_no_shipping_test.html");
+
+  InvokePaymentRequestUIWithJs(content::JsReplace(
+      "buyWithMethods([{supportedMethods:$1},{supportedMethods:$2}])",
+      payment_method_a, payment_method_b));
+  OpenPaymentMethodScreen();
+
+  PaymentRequest* request = GetPaymentRequests().front();
+  EXPECT_EQ(2U, request->state()->available_apps().size());
+  EXPECT_EQ(request->state()->available_apps().front().get(),
+            request->state()->selected_app());
+
+  views::View* list_view = dialog_view()->GetViewByID(
+      static_cast<int>(DialogViewID::PAYMENT_METHOD_SHEET_LIST_VIEW));
+  EXPECT_TRUE(list_view);
+  EXPECT_EQ(2u, list_view->children().size());
+
+  EXPECT_EQ(request->state()->available_apps().front().get(),
+            request->state()->selected_app());
+  views::View* checkmark_view = list_view->children()[0]->GetViewByID(
+      static_cast<int>(DialogViewID::CHECKMARK_VIEW));
+  EXPECT_TRUE(checkmark_view->GetVisible());
+
+  views::View* checkmark_view2 = list_view->children()[1]->GetViewByID(
+      static_cast<int>(DialogViewID::CHECKMARK_VIEW));
+  EXPECT_FALSE(checkmark_view2->GetVisible());
+
+  ResetEventWaiter(DialogEvent::BACK_NAVIGATION);
+  // Simulate selecting the second app.
+  ClickOnDialogViewAndWait(list_view->children()[1]);
+
+  EXPECT_EQ(request->state()->available_apps().back().get(),
+            request->state()->selected_app());
+
+  OpenPaymentMethodScreen();
+  list_view = dialog_view()->GetViewByID(
+      static_cast<int>(DialogViewID::PAYMENT_METHOD_SHEET_LIST_VIEW));
+
+  ResetEventWaiter(DialogEvent::BACK_NAVIGATION);
+  // Clicking on the second app again should not modify any state, and should
+  // return to the main payment sheet.
+  ClickOnDialogViewAndWait(list_view->children()[1]);
+
+  EXPECT_EQ(request->state()->available_apps().back().get(),
+            request->state()->selected_app());
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc
index 303e39c..7352975 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -13,6 +13,7 @@
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/style/color_mode_observer.h"
 #include "ash/public/cpp/style/color_provider.h"
+#include "ash/public/cpp/style/scoped_light_mode_as_default.h"
 #include "ash/public/cpp/tablet_mode.h"
 #include "base/bind.h"
 #include "base/callback.h"
@@ -219,6 +220,7 @@
   void AdjustWidgetInitParams(views::Widget::InitParams* params) override {
     params->shadow_type = views::Widget::InitParams::ShadowType::kDefault;
     auto* color_provider = ash::ColorProvider::Get();
+    ash::ScopedLightModeAsDefault scoped_light_mode_as_default;
     params->init_properties_container.SetProperty(
         chromeos::kFrameActiveColorKey,
         color_provider->GetActiveDialogTitleBarColor());
@@ -550,6 +552,7 @@
                               kFileManagerMinimumHeight};
     dialog_params.title = dialog_title;
     auto* color_provider = ash::ColorProvider::Get();
+    ash::ScopedLightModeAsDefault scoped_light_mode_as_default;
     dialog_params.title_color = color_provider->GetActiveDialogTitleBarColor();
     dialog_params.title_inactive_color =
         color_provider->GetInactiveDialogTitleBarColor();
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
index 5a44b59..cc481e2 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
@@ -10,6 +10,7 @@
 #include "ash/constants/ash_pref_names.h"
 #include "ash/public/cpp/keyboard/keyboard_switches.h"
 #include "ash/public/cpp/style/color_provider.h"
+#include "ash/public/cpp/style/scoped_light_mode_as_default.h"
 #include "ash/public/cpp/test/shell_test_api.h"
 #include "base/callback_helpers.h"
 #include "base/files/file_util.h"
@@ -204,12 +205,9 @@
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     if (GetParam().app_mode == SYSTEM_FILES_APP_MODE) {
-      feature_list_.InitWithFeatures(
-          {chromeos::features::kFilesSWA, chromeos::features::kDarkLightMode},
-          {});
+      feature_list_.InitWithFeatures({chromeos::features::kFilesSWA}, {});
     } else {
-      feature_list_.InitWithFeatures({chromeos::features::kDarkLightMode},
-                                     {chromeos::features::kFilesSWA});
+      feature_list_.InitWithFeatures({}, {chromeos::features::kFilesSWA});
     }
     extensions::ExtensionBrowserTest::SetUpCommandLine(command_line);
   }
@@ -653,6 +651,7 @@
   aura::Window* dialog_window =
       frame_host->GetNativeView()->GetToplevelWindow();
   auto* color_provider = ash::ColorProvider::Get();
+  ash::ScopedLightModeAsDefault scoped_light_mode_as_default;
   EXPECT_EQ(dialog_window->GetProperty(chromeos::kFrameActiveColorKey),
             color_provider->GetActiveDialogTitleBarColor());
   EXPECT_EQ(dialog_window->GetProperty(chromeos::kFrameInactiveColorKey),
@@ -661,7 +660,30 @@
   CloseDialog(DIALOG_BTN_CANCEL, owning_window);
 }
 
-IN_PROC_BROWSER_TEST_P(SelectFileDialogExtensionFlagTest, ColorModeChange) {
+INSTANTIATE_TEST_SUITE_P(Legacy,
+                         SelectFileDialogExtensionFlagTest,
+                         TestMode::LegacyValues());
+INSTANTIATE_TEST_SUITE_P(SystemWebApp,
+                         SelectFileDialogExtensionFlagTest,
+                         TestMode::SystemWebAppValues());
+
+class SelectFileDialogExtensionDarkLightModeEnabledTest
+    : public BaseSelectFileDialogExtensionBrowserTest {
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    if (GetParam().app_mode == SYSTEM_FILES_APP_MODE) {
+      feature_list_.InitWithFeatures(
+          {chromeos::features::kFilesSWA, chromeos::features::kDarkLightMode},
+          {});
+    } else {
+      feature_list_.InitWithFeatures({chromeos::features::kDarkLightMode},
+                                     {chromeos::features::kFilesSWA});
+    }
+    extensions::ExtensionBrowserTest::SetUpCommandLine(command_line);
+  }
+};
+
+IN_PROC_BROWSER_TEST_P(SelectFileDialogExtensionDarkLightModeEnabledTest,
+                       ColorModeChange) {
   gfx::NativeWindow owning_window = browser()->window()->GetNativeWindow();
   ASSERT_NE(nullptr, owning_window);
 
@@ -693,8 +715,8 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(Legacy,
-                         SelectFileDialogExtensionFlagTest,
+                         SelectFileDialogExtensionDarkLightModeEnabledTest,
                          TestMode::LegacyValues());
 INSTANTIATE_TEST_SUITE_P(SystemWebApp,
-                         SelectFileDialogExtensionFlagTest,
+                         SelectFileDialogExtensionDarkLightModeEnabledTest,
                          TestMode::SystemWebAppValues());
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
index 49b11db..b905055 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
@@ -12,14 +12,16 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/side_panel/read_later_side_panel_web_view.h"
 #include "chrome/browser/ui/views/side_panel/side_panel.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/combobox_model.h"
+#include "ui/base/models/simple_combobox_model.h"
 #include "ui/gfx/vector_icon_utils.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/button/image_button_factory.h"
+#include "ui/views/controls/combobox/combobox.h"
 #include "ui/views/controls/highlight_path_generator.h"
 #include "ui/views/controls/separator.h"
 #include "ui/views/layout/flex_layout_view.h"
@@ -27,6 +29,7 @@
 
 namespace {
 constexpr int kSidePanelContentViewId = 42;
+constexpr int kSidePanelContentWrapperViewId = 43;
 
 std::unique_ptr<views::ImageButton> CreateControlButton(
     views::View* host,
@@ -51,6 +54,7 @@
   // TODO(pbos): Consider moving creation of SidePanelEntry into other functions
   // that can easily be unit tested.
   window_registry_.Register(std::make_unique<SidePanelEntry>(
+      SidePanelEntry::Id::kReadingList,
       l10n_util::GetStringUTF16(IDS_READ_LATER_TITLE),
       base::BindRepeating(
           [](SidePanelCoordinator* coordinator,
@@ -60,58 +64,38 @@
                                              base::Unretained(coordinator)));
           },
           this, browser_view->browser())));
+  // TODO(corising): Replace ReadLaterSidePanelWebView with a new WebView for
+  // the bookmarks entry.
+  window_registry_.Register(std::make_unique<SidePanelEntry>(
+      SidePanelEntry::Id::kBookmarks,
+      l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE),
+      base::BindRepeating(
+          [](SidePanelCoordinator* coordinator,
+             Browser* browser) -> std::unique_ptr<views::View> {
+            return std::make_unique<ReadLaterSidePanelWebView>(
+                browser, base::BindRepeating(&SidePanelCoordinator::Close,
+                                             base::Unretained(coordinator)));
+          },
+          this, browser_view->browser())));
 }
 
 SidePanelCoordinator::~SidePanelCoordinator() = default;
 
-void SidePanelCoordinator::Show() {
-  if (GetContentView() != nullptr)
+void SidePanelCoordinator::Show(absl::optional<SidePanelEntry::Id> entry_id) {
+  if (!entry_id.has_value()) {
+    // TODO(corising): Handle reopening to the last seen entry.
+    entry_id = SidePanelEntry::Id::kReadingList;
+  }
+
+  DCHECK_EQ(2u, window_registry_.entries().size());
+  SidePanelEntry* entry = GetEntryForId(entry_id.value());
+  if (!entry)
     return;
-  // TODO(pbos): Make this button observe panel-visibility state instead.
-  browser_view_->toolbar()->side_panel_button()->SetTooltipText(
-      l10n_util::GetStringUTF16(IDS_TOOLTIP_SIDE_PANEL_HIDE));
 
-  // TODO(pbos): Handle multiple entries.
-  DCHECK_EQ(1u, window_registry_.entries().size());
-  SidePanelEntry* const entry = window_registry_.entries().front().get();
+  if (GetContentView() == nullptr)
+    InitializeSidePanel();
 
-  auto container = std::make_unique<views::FlexLayoutView>();
-  // Align views vertically top to bottom.
-  container->SetOrientation(views::LayoutOrientation::kVertical);
-  container->SetMainAxisAlignment(views::LayoutAlignment::kStart);
-  // Stretch views to fill horizontal bounds.
-  container->SetCrossAxisAlignment(views::LayoutAlignment::kStretch);
-  container->SetID(kSidePanelContentViewId);
-
-  container->AddChildView(CreateHeader());
-  auto* separator =
-      container->AddChildView(std::make_unique<views::Separator>());
-  // TODO(pbos): Make sure this separator updates per theme changes and does not
-  // pull color provider from BrowserView directly. This is wrong (wrong
-  // provider, wrong to call this before we know it's added to widget and wrong
-  // not to update as the theme changes).
-  const ui::ThemeProvider* const theme_provider =
-      browser_view_->GetThemeProvider();
-  // TODO(pbos): Stop inlining this color (de-duplicate this, SidePanelBorder
-  // and BrowserView).
-  separator->SetColor(color_utils::GetResultingPaintColor(
-      theme_provider->GetColor(
-          ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR),
-      theme_provider->GetColor(ThemeProperties::COLOR_TOOLBAR)));
-
-  // TODO(pbos): Set some ID on this container so that we can replace the
-  // content in here from the combobox once it exists.
-  auto content_wrapper = std::make_unique<views::View>();
-  content_wrapper->SetUseDefaultFillLayout(true);
-  content_wrapper->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                               views::MaximumFlexSizeRule::kUnbounded));
-  content_wrapper->AddChildView(entry->CreateContent());
-
-  container->AddChildView(std::move(content_wrapper));
-
-  browser_view_->right_aligned_side_panel()->AddChildView(std::move(container));
+  PopulateSidePanel(entry);
 }
 
 void SidePanelCoordinator::Close() {
@@ -139,6 +123,64 @@
       kSidePanelContentViewId);
 }
 
+SidePanelEntry* SidePanelCoordinator::GetEntryForId(
+    SidePanelEntry::Id entry_id) {
+  for (auto const& entry : window_registry_.entries()) {
+    if (entry.get()->id() == entry_id)
+      return entry.get();
+  }
+  return nullptr;
+}
+
+void SidePanelCoordinator::InitializeSidePanel() {
+  // TODO(pbos): Make this button observe panel-visibility state instead.
+  browser_view_->toolbar()->side_panel_button()->SetTooltipText(
+      l10n_util::GetStringUTF16(IDS_TOOLTIP_SIDE_PANEL_HIDE));
+
+  auto container = std::make_unique<views::FlexLayoutView>();
+  // Align views vertically top to bottom.
+  container->SetOrientation(views::LayoutOrientation::kVertical);
+  container->SetMainAxisAlignment(views::LayoutAlignment::kStart);
+  // Stretch views to fill horizontal bounds.
+  container->SetCrossAxisAlignment(views::LayoutAlignment::kStretch);
+  container->SetID(kSidePanelContentViewId);
+
+  container->AddChildView(CreateHeader());
+  auto* separator =
+      container->AddChildView(std::make_unique<views::Separator>());
+  // TODO(pbos): Make sure this separator updates per theme changes and does not
+  // pull color provider from BrowserView directly. This is wrong (wrong
+  // provider, wrong to call this before we know it's added to widget and wrong
+  // not to update as the theme changes).
+  const ui::ThemeProvider* const theme_provider =
+      browser_view_->GetThemeProvider();
+  // TODO(pbos): Stop inlining this color (de-duplicate this, SidePanelBorder
+  // and BrowserView).
+  separator->SetColor(color_utils::GetResultingPaintColor(
+      theme_provider->GetColor(
+          ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR),
+      theme_provider->GetColor(ThemeProperties::COLOR_TOOLBAR)));
+
+  auto content_wrapper = std::make_unique<views::View>();
+  content_wrapper->SetUseDefaultFillLayout(true);
+  content_wrapper->SetProperty(
+      views::kFlexBehaviorKey,
+      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
+                               views::MaximumFlexSizeRule::kUnbounded));
+  content_wrapper->SetID(kSidePanelContentWrapperViewId);
+  container->AddChildView(std::move(content_wrapper));
+
+  browser_view_->right_aligned_side_panel()->AddChildView(std::move(container));
+}
+
+void SidePanelCoordinator::PopulateSidePanel(SidePanelEntry* entry) {
+  views::View* content_wrapper =
+      GetContentView()->GetViewByID(kSidePanelContentWrapperViewId);
+  DCHECK(content_wrapper);
+  content_wrapper->RemoveAllChildViews();
+  content_wrapper->AddChildView(entry->CreateContent());
+}
+
 std::unique_ptr<views::View> SidePanelCoordinator::CreateHeader() {
   auto header = std::make_unique<views::FlexLayoutView>();
   // ChromeLayoutProvider for providing margins.
@@ -159,17 +201,8 @@
   header->SetBackground(views::CreateThemedSolidBackground(
       header.get(), ui::kColorWindowBackground));
 
-  // TODO(pbos): Replace this with a combobox. Note that this combobox will need
-  // to listen to changes to the window registry. This combobox should probably
-  // call SidePanelCoordinator::ShowPanel(panel_id) or similar. This method or
-  // ID does not exist, `panel_id` would probably need to be added to
-  // SidePanelEntry unless we want to use raw pointers. This also implies that
-  // SidePanelCoordinator needs a link to where the SidePanelEntry content is
-  // showing so that it can be replaced (perhaps via a view ID for
-  // `content_wrapper` above).
-  DCHECK_EQ(1u, window_registry_.entries().size());
-  SidePanelEntry* const entry = window_registry_.entries().front().get();
-  header->AddChildView(std::make_unique<views::Label>(entry->name()));
+  DCHECK_EQ(2u, window_registry_.entries().size());
+  header_combobox_ = header->AddChildView(CreateCombobox());
 
   // Create an empty view between branding and buttons to align branding on left
   // without hardcoding margins. This view fills up the empty space between the
@@ -194,3 +227,36 @@
 
   return header;
 }
+
+std::unique_ptr<views::Combobox> SidePanelCoordinator::CreateCombobox() {
+  std::vector<std::u16string> entry_names;
+  for (auto const& entry : window_registry_.entries())
+    entry_names.push_back(entry.get()->name());
+
+  // TODO(corising): Create new ComboboxModel to hold entry id, name, and icon.
+  // Also make it listen to changes to the window registry.
+  combobox_model_ = std::make_unique<ui::SimpleComboboxModel>(
+      std::vector<ui::SimpleComboboxModel::Item>(entry_names.begin(),
+                                                 entry_names.end()));
+  auto combobox = std::make_unique<views::Combobox>(combobox_model_.get());
+
+  // TODO(corising): Update this to use the SidePanelEntry::Id to select the
+  // correct index once a new combobox model is created.
+  combobox->SetSelectedIndex(0);
+  // TODO(corising): Replace this with something appropriate.
+  combobox->SetAccessibleName(
+      combobox_model_->GetItemAt(combobox->GetSelectedIndex()));
+
+  combobox->SetCallback(base::BindRepeating(
+      &SidePanelCoordinator::OnComboboxChanged, base::Unretained(this)));
+  return combobox;
+}
+
+void SidePanelCoordinator::OnComboboxChanged() {
+  std::u16string entry_name =
+      combobox_model_->GetItemAt(header_combobox_->GetSelectedIndex());
+  for (auto const& entry : window_registry_.entries()) {
+    if (entry.get()->name() == entry_name)
+      Show(entry.get()->id());
+  }
+}
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.h b/chrome/browser/ui/views/side_panel/side_panel_coordinator.h
index 0363f020..591a4c3 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.h
+++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.h
@@ -6,11 +6,14 @@
 #define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_COORDINATOR_H_
 
 #include "base/memory/raw_ptr.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
+#include "ui/base/models/simple_combobox_model.h"
 
 class BrowserView;
 
 namespace views {
+class Combobox;
 class View;
 }  // namespace views
 
@@ -27,17 +30,31 @@
   SidePanelCoordinator& operator=(const SidePanelCoordinator&) = delete;
   ~SidePanelCoordinator();
 
-  void Show();
+  void Show(absl::optional<SidePanelEntry::Id> entry_id = absl::nullopt);
   void Close();
   void Toggle();
 
  private:
   views::View* GetContentView();
+  SidePanelEntry* GetEntryForId(SidePanelEntry::Id entry_id);
+
+  // Creates header and SidePanelEntry content container within the side panel.
+  void InitializeSidePanel();
+
+  // Removes existing SidePanelEntry contents from the side panel if any exist
+  // and populates the side panel with the provided SidePanelEntry.
+  void PopulateSidePanel(SidePanelEntry* entry);
+
   std::unique_ptr<views::View> CreateHeader();
+  std::unique_ptr<views::Combobox> CreateCombobox();
+  void OnComboboxChanged();
 
   const raw_ptr<BrowserView> browser_view_;
   SidePanelRegistry window_registry_;
 
+  std::unique_ptr<ui::SimpleComboboxModel> combobox_model_;
+  raw_ptr<views::Combobox> header_combobox_ = nullptr;
+
   // TODO(pbos): Add awareness of tab registries here. This probably needs to
   // know the tab registry it's currently monitoring.
 };
diff --git a/chrome/browser/ui/views/side_panel/side_panel_entry.cc b/chrome/browser/ui/views/side_panel/side_panel_entry.cc
index ae2e9aa8..a325469 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_entry.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_entry.cc
@@ -5,10 +5,12 @@
 #include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
 
 SidePanelEntry::SidePanelEntry(
+    Id id,
     std::u16string name,
     base::RepeatingCallback<std::unique_ptr<views::View>()>
         create_content_callback)
-    : name_(std::move(name)),
+    : id_(id),
+      name_(std::move(name)),
       create_content_callback_(std::move(create_content_callback)) {
   DCHECK(create_content_callback_);
 }
diff --git a/chrome/browser/ui/views/side_panel/side_panel_entry.h b/chrome/browser/ui/views/side_panel/side_panel_entry.h
index 55e7b9d6..8d1197d 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_entry.h
+++ b/chrome/browser/ui/views/side_panel/side_panel_entry.h
@@ -15,8 +15,11 @@
 // SidePanelRegistry (either a per-tab or a per-window registry).
 class SidePanelEntry final {
  public:
+  enum class Id { kReadingList, kBookmarks };
+
   // TODO(pbos): Add an icon ImageModel here.
-  SidePanelEntry(std::u16string name,
+  SidePanelEntry(Id id,
+                 std::u16string name,
                  base::RepeatingCallback<std::unique_ptr<views::View>()>
                      create_content_callback);
   SidePanelEntry(const SidePanelEntry&) = delete;
@@ -27,9 +30,11 @@
   // shown.
   std::unique_ptr<views::View> CreateContent();
 
+  Id id() const { return id_; }
   const std::u16string& name() const { return name_; }
 
  private:
+  const Id id_;
   const std::u16string name_;
 
   base::RepeatingCallback<std::unique_ptr<views::View>()>
diff --git a/chrome/browser/ui/web_applications/web_app_launch_process.cc b/chrome/browser/ui/web_applications/web_app_launch_process.cc
index a696b1e5..802aab2 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_process.cc
+++ b/chrome/browser/ui/web_applications/web_app_launch_process.cc
@@ -78,9 +78,7 @@
   display::ScopedDisplayForNewWindows scoped_display(params_.display_id);
 
   const apps::ShareTarget* share_target = MaybeGetShareTarget();
-  GURL launch_url;
-  bool is_file_handling = false;
-  std::tie(launch_url, is_file_handling) = GetLaunchUrl(share_target);
+  auto [launch_url, is_file_handling] = GetLaunchUrl(share_target);
 
 #if BUILDFLAG(IS_CHROMEOS)
   // TODO(crbug.com/1265381): URL Handlers allows web apps to be opened with
@@ -106,9 +104,7 @@
   if (web_contents)
     return web_contents;
 
-  Browser* browser = nullptr;
-  bool is_new_browser;
-  std::tie(browser, is_new_browser) = EnsureBrowser();
+  auto [browser, is_new_browser] = EnsureBrowser();
 
   NavigateResult navigate_result =
       MaybeNavigateBrowser(browser, is_new_browser, launch_url, share_target);
diff --git a/chrome/browser/ui/webui/access_code_cast/access_code_cast_ui.cc b/chrome/browser/ui/webui/access_code_cast/access_code_cast_ui.cc
index 624857a..93d3720 100644
--- a/chrome/browser/ui/webui/access_code_cast/access_code_cast_ui.cc
+++ b/chrome/browser/ui/webui/access_code_cast/access_code_cast_ui.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/managed_ui.h"
 #include "chrome/browser/ui/media_router/media_cast_mode.h"
 #include "chrome/browser/ui/views/chrome_web_dialog_view.h"
 #include "chrome/browser/ui/webui/webui_util.h"
@@ -119,9 +120,8 @@
     std::vector<content::WebUIMessageHandler*>* handlers) const {}
 
 void AccessCodeCastDialog::GetDialogSize(gfx::Size* size) const {
-  // TODO(b/202529859): Replace these with final values
-  const int kDefaultWidth = 512;
-  const int kDefaultHeight = 480;
+  const int kDefaultWidth = 480;
+  const int kDefaultHeight = 341;
   size->SetSize(kDefaultWidth, kDefaultHeight);
 }
 
@@ -194,6 +194,7 @@
       IDR_ACCESS_CODE_CAST_INDEX_HTML);
 
   static constexpr webui::LocalizedString kStrings[] = {
+      {"accessCodeMessage", IDS_ACCESS_CODE_CAST_ACCESS_CODE_MESSAGE},
       {"back", IDS_ACCESS_CODE_CAST_BACK},
       {"cast", IDS_ACCESS_CODE_CAST_CAST},
       {"close", IDS_CLOSE},
diff --git a/chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.cc b/chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.cc
new file mode 100644
index 0000000..899849c
--- /dev/null
+++ b/chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.cc
@@ -0,0 +1,50 @@
+// Copyright 2022 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 "chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/url_constants.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_contents.h"
+
+// static
+std::unique_ptr<content::NavigationThrottle>
+WebAppSettingsNavigationThrottle::MaybeCreateThrottleFor(
+    content::NavigationHandle* handle) {
+  // Check web app settings feature is enabled.
+  if (!base::FeatureList::IsEnabled(features::kDesktopPWAsWebAppSettingsPage))
+    return nullptr;
+  // Check the current url scheme is chrome://
+  if (!handle->GetURL().SchemeIs(content::kChromeUIScheme))
+    return nullptr;
+  // Check the current url is chrome://app-settings
+  if (handle->GetURL().host_piece() != chrome::kChromeUIWebAppSettingsHost)
+    return nullptr;
+
+  return std::make_unique<WebAppSettingsNavigationThrottle>(handle);
+}
+
+WebAppSettingsNavigationThrottle::WebAppSettingsNavigationThrottle(
+    content::NavigationHandle* navigation_handle)
+    : content::NavigationThrottle(navigation_handle) {}
+
+WebAppSettingsNavigationThrottle::~WebAppSettingsNavigationThrottle() = default;
+
+content::NavigationThrottle::ThrottleCheckResult
+WebAppSettingsNavigationThrottle::WillStartRequest() {
+  content::WebContents* web_contents = navigation_handle()->GetWebContents();
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents->GetBrowserContext());
+  if (!web_app::HasAppSettingsPage(profile, navigation_handle()->GetURL())) {
+    return content::NavigationThrottle::BLOCK_REQUEST;
+  }
+  return content::NavigationThrottle::PROCEED;
+}
+
+const char* WebAppSettingsNavigationThrottle::GetNameForLogging() {
+  return "WebAppSettingsNavigationThrottle";
+}
diff --git a/chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.h b/chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.h
new file mode 100644
index 0000000..a0fa3fd
--- /dev/null
+++ b/chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.h
@@ -0,0 +1,32 @@
+// Copyright 2022 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 CHROME_BROWSER_UI_WEBUI_APP_SETTINGS_WEB_APP_SETTINGS_NAVIGATION_THROTTLE_H_
+#define CHROME_BROWSER_UI_WEBUI_APP_SETTINGS_WEB_APP_SETTINGS_NAVIGATION_THROTTLE_H_
+
+#include "content/public/browser/navigation_throttle.h"
+
+namespace content {
+class NavigationHandle;
+}  // namespace content
+
+// A NavigationThrottle that blocks request when navigating to
+// chrome://app-settings/<app-id> page with an invalid app-id.
+class WebAppSettingsNavigationThrottle : public content::NavigationThrottle {
+ public:
+  // Returns a NavigationThrottle when:
+  // - we are navigating to the new tab page, and
+  // - the main frame is pointed at the new tab URL.
+  static std::unique_ptr<content::NavigationThrottle> MaybeCreateThrottleFor(
+      content::NavigationHandle* handle);
+
+  explicit WebAppSettingsNavigationThrottle(content::NavigationHandle* handle);
+  ~WebAppSettingsNavigationThrottle() override;
+
+  // content::NavigationThrottle:
+  ThrottleCheckResult WillStartRequest() override;
+  const char* GetNameForLogging() override;
+};
+
+#endif  // CHROME_BROWSER_UI_WEBUI_APP_SETTINGS_WEB_APP_SETTINGS_NAVIGATION_THROTTLE_H_
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index c5e57116..35540080 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -172,6 +172,8 @@
 #include "ash/webui/help_app_ui/url_constants.h"
 #include "ash/webui/media_app_ui/media_app_ui.h"
 #include "ash/webui/media_app_ui/url_constants.h"
+#include "ash/webui/multidevice_debug/proximity_auth_ui.h"
+#include "ash/webui/multidevice_debug/url_constants.h"
 #include "ash/webui/os_feedback_ui/os_feedback_ui.h"
 #include "ash/webui/os_feedback_ui/url_constants.h"
 #include "ash/webui/personalization_app/personalization_app_ui.h"
@@ -254,8 +256,6 @@
 #include "chrome/browser/ui/webui/nearby_internals/nearby_internals_ui.h"
 #include "chrome/browser/ui/webui/nearby_share/nearby_share_dialog_ui.h"
 #include "chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h"
-#include "chromeos/components/multidevice/debug_webui/proximity_auth_ui.h"
-#include "chromeos/components/multidevice/debug_webui/url_constants.h"
 #include "chromeos/services/multidevice_setup/multidevice_setup_service.h"
 #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
 #include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom.h"  // nogncheck
@@ -324,7 +324,6 @@
 
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
 #include "chrome/browser/ui/webui/app_settings/web_app_settings_ui.h"
-#include "chrome/browser/web_applications/web_app_utils.h"
 #endif
 
 #if BUILDFLAG(USE_NSS_CERTS) && defined(USE_AURA)
@@ -548,12 +547,11 @@
 
 // Special case for chrome://proximity_auth.
 template <>
-WebUIController* NewWebUI<chromeos::multidevice::ProximityAuthUI>(
-    WebUI* web_ui,
-    const GURL& url) {
+WebUIController* NewWebUI<ash::multidevice::ProximityAuthUI>(WebUI* web_ui,
+                                                             const GURL& url) {
   content::BrowserContext* browser_context =
       web_ui->GetWebContents()->GetBrowserContext();
-  return new chromeos::multidevice::ProximityAuthUI(
+  return new ash::multidevice::ProximityAuthUI(
       web_ui,
       ash::device_sync::DeviceSyncClientFactory::GetForProfile(
           Profile::FromBrowserContext(browser_context)),
@@ -917,9 +915,9 @@
     if (url.host_piece() == ash::kChromeUIFirmwareUpdateAppHost)
       return &NewWebUI<ash::FirmwareUpdateAppUI>;
   }
-  if (url.host_piece() == chromeos::multidevice::kChromeUIProximityAuthHost &&
+  if (url.host_piece() == ash::multidevice::kChromeUIProximityAuthHost &&
       !profile->IsOffTheRecord()) {
-    return &NewWebUI<chromeos::multidevice::ProximityAuthUI>;
+    return &NewWebUI<ash::multidevice::ProximityAuthUI>;
   }
   if (url.host_piece() == chrome::kChromeUIInternetConfigDialogHost)
     return &NewWebUI<chromeos::InternetConfigDialogUI>;
@@ -1142,9 +1140,7 @@
     return &NewWebUI<BrowserSwitchUI>;
   if (base::FeatureList::IsEnabled(features::kDesktopPWAsWebAppSettingsPage) &&
       url.host_piece() == chrome::kChromeUIWebAppSettingsHost) {
-    if (web_app::HasAppSettingsPage(profile, url)) {
-      return &NewWebUI<WebAppSettingsUI>;
-    }
+    return &NewWebUI<WebAppSettingsUI>;
   }
 #endif
   if (IsAboutUI(url))
@@ -1456,7 +1452,7 @@
       GURL(chrome::kChromeUIOSCreditsURL), GURL(chrome::kOsUIOSSettingsURL),
       GURL(chrome::kChromeUIPowerUrl),
       GURL(chrome::kChromeUIPrintManagementUrl),
-      GURL(chromeos::multidevice::kChromeUIProximityAuthURL),
+      GURL(ash::multidevice::kChromeUIProximityAuthURL),
       GURL(chrome::kOsUIRestartURL), GURL(chrome::kChromeUIScanningAppURL),
       GURL(chrome::kOsUIScanningAppURL), GURL(chrome::kChromeUISetTimeURL),
       GURL(chrome::kChromeUIOSSettingsURL), GURL(chrome::kChromeUISettingsURL),
diff --git a/chrome/browser/ui/webui/memory_internals_ui.cc b/chrome/browser/ui/webui/memory_internals_ui.cc
index b5325c1..c793ee0 100644
--- a/chrome/browser/ui/webui/memory_internals_ui.cc
+++ b/chrome/browser/ui/webui/memory_internals_ui.cc
@@ -164,13 +164,19 @@
   void SaveTraceFinished(bool success);
 
   scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
+#if !BUILDFLAG(IS_ANDROID)
   raw_ptr<content::WebUI> web_ui_;  // The WebUI that owns us.
+#endif
 
   base::WeakPtrFactory<MemoryInternalsDOMHandler> weak_factory_{this};
 };
 
 MemoryInternalsDOMHandler::MemoryInternalsDOMHandler(content::WebUI* web_ui)
-    : web_ui_(web_ui) {}
+#if !BUILDFLAG(IS_ANDROID)
+    : web_ui_(web_ui)
+#endif
+{
+}
 
 MemoryInternalsDOMHandler::~MemoryInternalsDOMHandler() {
   if (select_file_dialog_)
@@ -254,8 +260,6 @@
       base::BindOnce(&MemoryInternalsDOMHandler::SaveTraceFinished,
                      weak_factory_.GetWeakPtr()),
       false);
-
-  (void)web_ui_;  // Avoid warning about not using private web_ui_ member.
 #else
   if (select_file_dialog_)
     return;  // Currently running, wait for existing save to complete.
diff --git a/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc b/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc
index 4d114c29..12ea66e2 100644
--- a/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc
+++ b/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc
@@ -6,14 +6,13 @@
 
 #include <memory>
 
-#include "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder.h"
+#include "ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.h"
 #include "ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/i18n/time_formatting.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
-#include "components/image_fetcher/core/image_fetcher.h"
 
 namespace {
 // Keys in the JSON representation of a log message
@@ -3779,8 +3778,8 @@
 QuickPairHandler::QuickPairHandler()
     : fast_pair_notification_controller_(
           std::make_unique<ash::quick_pair::FastPairNotificationController>()),
-      image_decoder_(std::make_unique<ash::quick_pair::FastPairImageDecoder>(
-          std::unique_ptr<image_fetcher::ImageFetcher>())) {}
+      image_decoder_(
+          std::make_unique<ash::quick_pair::FastPairImageDecoderImpl>()) {}
 
 QuickPairHandler::~QuickPairHandler() = default;
 
@@ -3840,6 +3839,7 @@
   base::HexStringToBytes(kImageBytes, &bytes);
   image_decoder_->DecodeImage(
       std::move(bytes),
+      /*resize_to_notification_size=*/true,
       base::BindOnce(&QuickPairHandler::OnImageDecodedFastPairError,
                      weak_ptr_factory_.GetWeakPtr()));
 }
@@ -3854,6 +3854,7 @@
   base::HexStringToBytes(kImageBytes, &bytes);
   image_decoder_->DecodeImage(
       std::move(bytes),
+      /*resize_to_notification_size=*/true,
       base::BindOnce(&QuickPairHandler::OnImageDecodedFastPairDiscovery,
                      weak_ptr_factory_.GetWeakPtr()));
 }
@@ -3869,6 +3870,7 @@
   base::HexStringToBytes(kImageBytes, &bytes);
   image_decoder_->DecodeImage(
       std::move(bytes),
+      /*resize_to_notification_size=*/true,
       base::BindOnce(&QuickPairHandler::OnImageDecodedFastPairPairing,
                      weak_ptr_factory_.GetWeakPtr()));
 }
@@ -3884,6 +3886,7 @@
   base::HexStringToBytes(kImageBytes, &bytes);
   image_decoder_->DecodeImage(
       std::move(bytes),
+      /*resize_to_notification_size=*/true,
       base::BindOnce(
           &QuickPairHandler::OnImageDecodedFastPairAssociateAccountKey,
           weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/sanitized_image_source_unittest.cc b/chrome/browser/ui/webui/sanitized_image_source_unittest.cc
index 72df5cd5..2ef3fa2 100644
--- a/chrome/browser/ui/webui/sanitized_image_source_unittest.cc
+++ b/chrome/browser/ui/webui/sanitized_image_source_unittest.cc
@@ -109,10 +109,7 @@
 
   // Answer requests and check correctness.
   for (size_t i = 0; i < data.size(); i++) {
-    SkColor color;
-    std::string url;
-    std::string body;
-    std::tie(color, url, body) = data[i];
+    auto [color, url, body] = data[i];
     auto* request = test_url_loader_factory_.GetPendingRequest(i);
     EXPECT_EQ(network::mojom::CredentialsMode::kOmit,
               request->request.credentials_mode);
diff --git a/chrome/browser/ui/webui/settings/chromeos/people_section.cc b/chrome/browser/ui/webui/settings/chromeos/people_section.cc
index 8259e3b..9dbd9f3 100644
--- a/chrome/browser/ui/webui/settings/chromeos/people_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/people_section.cc
@@ -202,7 +202,6 @@
        IDS_SETTINGS_ACCOUNT_MANAGER_REAUTHENTICATION_TOOLTIP},
       {"accountManagerMoreActionsTooltip",
        IDS_SETTINGS_ACCOUNT_MANAGER_MORE_ACTIONS_TOOLTIP},
-      {"accountListDescription", IDS_SETTINGS_ACCOUNT_MANAGER_LIST_DESCRIPTION},
       {"addAccountLabel", IDS_SETTINGS_ACCOUNT_MANAGER_ADD_ACCOUNT_LABEL_V2},
       {"accountListHeader", IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER_V2},
       {"accountListHeaderChild",
@@ -219,9 +218,26 @@
        IDS_SETTINGS_ACCOUNT_MANAGER_REMOVE_LACROS_ACCOUNT_DIALOG_REMOVE},
       {"removeLacrosAccountDialogCancel",
        IDS_SETTINGS_ACCOUNT_MANAGER_REMOVE_LACROS_ACCOUNT_DIALOG_CANCEL},
+      {"accountNotUsedInArcLabel",
+       IDS_SETTINGS_ACCOUNT_MANAGER_NOT_USED_IN_ARC_LABEL},
+      {"accountUseInArcButtonLabel",
+       IDS_SETTINGS_ACCOUNT_MANAGER_USE_IN_ARC_BUTTON_LABEL},
+      {"accountStopUsingInArcButtonLabel",
+       IDS_SETTINGS_ACCOUNT_MANAGER_STOP_USING_IN_ARC_BUTTON_LABEL},
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
+  if (ash::AccountAppsAvailability::IsArcAccountRestrictionsEnabled()) {
+    html_source->AddString("accountListDescription",
+                           l10n_util::GetStringFUTF16(
+                               IDS_SETTINGS_ACCOUNT_MANAGER_LIST_DESCRIPTION_V2,
+                               ui::GetChromeOSDeviceName()));
+  } else {
+    html_source->AddLocalizedString(
+        "accountListDescription",
+        IDS_SETTINGS_ACCOUNT_MANAGER_LIST_DESCRIPTION);
+  }
+
   user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile);
   DCHECK(user);
   html_source->AddString(
diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
index 3301322..84ea924 100644
--- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
@@ -21,7 +21,7 @@
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
-#include "net/dns/public/dns_over_https_server_config.h"
+#include "net/dns/public/dns_over_https_config.h"
 #include "net/dns/public/doh_provider_entry.h"
 #include "net/dns/public/secure_dns_mode.h"
 #include "net/dns/public/util.h"
@@ -178,8 +178,10 @@
 
   // Return all templates in the entry, or none if they are not all valid.
   base::Value templates(base::Value::Type::LIST);
-  if (secure_dns::IsValidGroup(custom_entry)) {
-    for (base::StringPiece t : secure_dns::SplitGroup(custom_entry)) {
+  absl::optional<net::DnsOverHttpsConfig> parsed =
+      net::DnsOverHttpsConfig::FromString(custom_entry);
+  if (parsed.has_value()) {
+    for (base::StringPiece t : parsed->ToStrings()) {
       templates.Append(t);
     }
   }
diff --git a/chrome/browser/vr/assets_loader.cc b/chrome/browser/vr/assets_loader.cc
index 073206f..c5f2708 100644
--- a/chrome/browser/vr/assets_loader.cc
+++ b/chrome/browser/vr/assets_loader.cc
@@ -209,10 +209,7 @@
 
   auto sounds_iter = sounds.begin();
   while (status == AssetsLoadStatus::kSuccess && sounds_iter != sounds.end()) {
-    const char* min_version;
-    const base::FilePath::CharType* file_name;
-    std::unique_ptr<std::string>* data;
-    std::tie(min_version, file_name, data) = *sounds_iter;
+    auto [min_version, file_name, data] = *sounds_iter;
     if (component_version >= base::Version(min_version)) {
       status = LoadSound(component_install_dir, file_name, data);
     }
diff --git a/chrome/browser/vr/elements/omnibox_formatting_fuzzer.cc b/chrome/browser/vr/elements/omnibox_formatting_fuzzer.cc
index 2e7a0bf9..d3cb0cf 100644
--- a/chrome/browser/vr/elements/omnibox_formatting_fuzzer.cc
+++ b/chrome/browser/vr/elements/omnibox_formatting_fuzzer.cc
@@ -68,9 +68,7 @@
   gfx::test::RenderTextTestApi render_text_test_api(render_text.get());
   render_text_test_api.SetGlyphWidth(character_width);
 
-  vr::ElisionParameters elision_params = vr::GetElisionParameters(
-      gurl, parsed, render_text.get(), min_path_pixels);
+  vr::GetElisionParameters(gurl, parsed, render_text.get(), min_path_pixels);
 
-  (void)elision_params;
   return 0;
 }
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
index bee381f..eb4bdf7 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -316,6 +316,8 @@
     app.show_in_shelf = app.show_in_search =
         chromeos_data.show_in_search && should_show_app;
     app.show_in_management = chromeos_data.show_in_management;
+    app.handles_intents =
+        chromeos_data.handles_file_open_intents ? true : app.show_in_launcher;
     return;
   }
 
@@ -324,6 +326,7 @@
   app.show_in_shelf = true;
   app.show_in_search = true;
   app.show_in_management = true;
+  app.handles_intents = true;
 }
 
 void WebAppPublisherHelper::SetWebAppShowInFields(apps::mojom::AppPtr& app,
diff --git a/chrome/browser/web_applications/externally_managed_app_manager_impl_unittest.cc b/chrome/browser/web_applications/externally_managed_app_manager_impl_unittest.cc
index 00277089..08ef352 100644
--- a/chrome/browser/web_applications/externally_managed_app_manager_impl_unittest.cc
+++ b/chrome/browser/web_applications/externally_managed_app_manager_impl_unittest.cc
@@ -563,13 +563,11 @@
   externally_managed_app_manager_impl().SetNextInstallationLaunchURL(
       kFooWebAppUrl);
 
-  absl::optional<GURL> url;
-  absl::optional<InstallResultCode> code;
-  std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                       GetInstallOptions(kFooWebAppUrl));
+  auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                    GetInstallOptions(kFooWebAppUrl));
 
-  EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
-  EXPECT_EQ(kFooWebAppUrl, url.value());
+  EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
+  EXPECT_EQ(kFooWebAppUrl, url);
 
   EXPECT_EQ(1u, install_run_count());
   EXPECT_EQ(GetInstallOptions(kFooWebAppUrl), last_install_options());
@@ -589,13 +587,11 @@
   externally_managed_app_manager_impl().SetNextInstallationLaunchURL(
       kFooWebAppUrl);
   {
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                         GetInstallOptions(kFooWebAppUrl));
+    auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                      GetInstallOptions(kFooWebAppUrl));
 
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
-    EXPECT_EQ(kFooWebAppUrl, url.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
+    EXPECT_EQ(kFooWebAppUrl, url);
 
     EXPECT_EQ(1u, install_run_count());
     EXPECT_EQ(GetInstallOptions(kFooWebAppUrl), last_install_options());
@@ -610,14 +606,11 @@
   externally_managed_app_manager_impl().SetNextInstallationLaunchURL(
       kBarWebAppUrl);
   {
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
+    auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                      GetInstallOptions(kBarWebAppUrl));
 
-    std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                         GetInstallOptions(kBarWebAppUrl));
-
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
-    EXPECT_EQ(kBarWebAppUrl, url.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
+    EXPECT_EQ(kBarWebAppUrl, url);
 
     EXPECT_EQ(2u, install_run_count());
     EXPECT_EQ(GetInstallOptions(kBarWebAppUrl), last_install_options());
@@ -914,10 +907,8 @@
   externally_managed_app_manager_impl().SetNextInstallationTaskResult(
       kFooWebAppUrl, InstallResultCode::kSuccessNewInstall);
   {
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                         GetInstallOptions(kFooWebAppUrl));
+    auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                      GetInstallOptions(kFooWebAppUrl));
 
     EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
     EXPECT_EQ(kFooWebAppUrl, url);
@@ -927,10 +918,8 @@
   }
 
   {
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                         GetInstallOptions(kFooWebAppUrl));
+    auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                      GetInstallOptions(kFooWebAppUrl));
 
     EXPECT_EQ(InstallResultCode::kSuccessAlreadyInstalled, code);
     EXPECT_EQ(kFooWebAppUrl, url);
@@ -998,10 +987,8 @@
   };
 
   {
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                         get_force_reinstall_info());
+    auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                      get_force_reinstall_info());
 
     EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
     EXPECT_EQ(kFooWebAppUrl, url);
@@ -1013,10 +1000,8 @@
   externally_managed_app_manager_impl().SetNextInstallationTaskResult(
       kFooWebAppUrl, InstallResultCode::kSuccessNewInstall);
   {
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                         get_force_reinstall_info());
+    auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                      get_force_reinstall_info());
 
     EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
     EXPECT_EQ(kFooWebAppUrl, url);
@@ -1032,10 +1017,8 @@
   externally_managed_app_manager_impl().SetNextInstallationTaskResult(
       kFooWebAppUrl, InstallResultCode::kWebAppDisabled);
 
-  absl::optional<GURL> url;
-  absl::optional<InstallResultCode> code;
-  std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                       GetInstallOptions(kFooWebAppUrl));
+  auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                    GetInstallOptions(kFooWebAppUrl));
 
   EXPECT_EQ(InstallResultCode::kWebAppDisabled, code);
   EXPECT_EQ(kFooWebAppUrl, url);
@@ -1052,9 +1035,7 @@
   auto install_options = GetInstallOptions(kFooWebAppUrl);
   install_options.install_placeholder = true;
 
-  absl::optional<GURL> url;
-  absl::optional<InstallResultCode> code;
-  std::tie(url, code) =
+  auto [url, code] =
       InstallAndWait(&externally_managed_app_manager_impl(), install_options);
 
   EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
@@ -1341,13 +1322,11 @@
   externally_managed_app_manager_impl().SetNextInstallationTaskResult(
       kFooWebAppUrl, InstallResultCode::kSuccessNewInstall);
   {
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                         GetInstallOptions(kFooWebAppUrl));
+    auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                      GetInstallOptions(kFooWebAppUrl));
 
     EXPECT_EQ(1u, install_run_count());
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
   }
 
   absl::optional<AppId> app_id = registrar().LookupExternalAppId(kFooWebAppUrl);
@@ -1358,14 +1337,12 @@
     externally_managed_app_manager_impl().SetNextInstallationTaskResult(
         kFooWebAppUrl, InstallResultCode::kSuccessNewInstall);
 
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                         GetInstallOptions(kFooWebAppUrl));
+    auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                      GetInstallOptions(kFooWebAppUrl));
 
     // The app was uninstalled so a new installation task should run.
     EXPECT_EQ(2u, install_run_count());
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
   }
 }
 
@@ -1374,13 +1351,11 @@
   externally_managed_app_manager_impl().SetNextInstallationTaskResult(
       kFooWebAppUrl, InstallResultCode::kSuccessNewInstall);
   {
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(&externally_managed_app_manager_impl(),
-                                         GetInstallOptions(kFooWebAppUrl));
+    auto [url, code] = InstallAndWait(&externally_managed_app_manager_impl(),
+                                      GetInstallOptions(kFooWebAppUrl));
 
     EXPECT_EQ(1u, install_run_count());
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
   }
 
   // Simulate external app for the app getting uninstalled by the user.
@@ -1393,9 +1368,7 @@
   // or fail depending on whether we set override_previous_user_uninstall. We
   // try with override_previous_user_uninstall false first, true second.
   {
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(
+    auto [url, code] = InstallAndWait(
         &externally_managed_app_manager_impl(),
         GetInstallOptions(kFooWebAppUrl,
                           false /* override_previous_user_uninstall */));
@@ -1403,22 +1376,20 @@
     // The app shouldn't be installed because the user previously uninstalled
     // it, so there shouldn't be any new installation task runs.
     EXPECT_EQ(1u, install_run_count());
-    EXPECT_EQ(InstallResultCode::kPreviouslyUninstalled, code.value());
+    EXPECT_EQ(InstallResultCode::kPreviouslyUninstalled, code);
   }
 
   {
     externally_managed_app_manager_impl().SetNextInstallationTaskResult(
         kFooWebAppUrl, InstallResultCode::kSuccessNewInstall);
 
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) = InstallAndWait(
+    auto [url, code] = InstallAndWait(
         &externally_managed_app_manager_impl(),
         GetInstallOptions(kFooWebAppUrl,
                           true /* override_previous_user_uninstall */));
 
     EXPECT_EQ(2u, install_run_count());
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
   }
 }
 
@@ -1510,11 +1481,9 @@
     externally_managed_app_manager_impl().SetNextInstallationTaskResult(
         kFooWebAppUrl, InstallResultCode::kSuccessNewInstall,
         /*did_install_placeholder=*/true);
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) =
+    auto [url, code] =
         InstallAndWait(&externally_managed_app_manager_impl(), install_options);
-    ASSERT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
+    ASSERT_EQ(InstallResultCode::kSuccessNewInstall, code);
     EXPECT_EQ(1u, install_run_count());
   }
 
@@ -1527,13 +1496,11 @@
     install_finalizer().SetNextUninstallExternalWebAppResult(kFooWebAppUrl,
                                                              true);
 
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) =
+    auto [url, code] =
         InstallAndWait(&externally_managed_app_manager_impl(), install_options);
 
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
-    EXPECT_EQ(kFooWebAppUrl, url.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
+    EXPECT_EQ(kFooWebAppUrl, url);
 
     EXPECT_EQ(2u, install_run_count());
   }
@@ -1550,11 +1517,9 @@
     externally_managed_app_manager_impl().SetNextInstallationTaskResult(
         kFooWebAppUrl, InstallResultCode::kSuccessNewInstall,
         /*did_install_placeholder=*/true);
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) =
+    auto [url, code] =
         InstallAndWait(&externally_managed_app_manager_impl(), install_options);
-    ASSERT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
+    ASSERT_EQ(InstallResultCode::kSuccessNewInstall, code);
     EXPECT_EQ(1u, install_run_count());
   }
 
@@ -1565,13 +1530,11 @@
         kFooWebAppUrl, InstallResultCode::kSuccessNewInstall,
         /*did_install_placeholder=*/true);
 
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) =
+    auto [url, code] =
         InstallAndWait(&externally_managed_app_manager_impl(), install_options);
 
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
-    EXPECT_EQ(kFooWebAppUrl, url.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
+    EXPECT_EQ(kFooWebAppUrl, url);
 
     // Even though the placeholder app is already install, we make a call to
     // WebAppInstallFinalizer. WebAppInstallFinalizer ensures we don't
@@ -1591,11 +1554,9 @@
     externally_managed_app_manager_impl().SetNextInstallationTaskResult(
         kFooWebAppUrl, InstallResultCode::kSuccessNewInstall,
         /*did_install_placeholder=*/true);
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) =
+    auto [url, code] =
         InstallAndWait(&externally_managed_app_manager_impl(), install_options);
-    ASSERT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
+    ASSERT_EQ(InstallResultCode::kSuccessNewInstall, code);
     EXPECT_EQ(1u, install_run_count());
   }
 
@@ -1608,13 +1569,11 @@
         /*did_install_placeholder=*/false);
     ui_manager().SetNumWindowsForApp(GenerateFakeAppId(kFooWebAppUrl), 0);
 
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) =
+    auto [url, code] =
         InstallAndWait(&externally_managed_app_manager_impl(), install_options);
 
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
-    EXPECT_EQ(kFooWebAppUrl, url.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
+    EXPECT_EQ(kFooWebAppUrl, url);
 
     EXPECT_EQ(2u, install_run_count());
   }
@@ -1631,11 +1590,9 @@
     externally_managed_app_manager_impl().SetNextInstallationTaskResult(
         kFooWebAppUrl, InstallResultCode::kSuccessNewInstall,
         /*did_install_placeholder=*/true);
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) =
+    auto [url, code] =
         InstallAndWait(&externally_managed_app_manager_impl(), install_options);
-    ASSERT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
+    ASSERT_EQ(InstallResultCode::kSuccessNewInstall, code);
     EXPECT_EQ(1u, install_run_count());
   }
 
@@ -1650,13 +1607,11 @@
     install_finalizer().SetNextUninstallExternalWebAppResult(kFooWebAppUrl,
                                                              true);
 
-    absl::optional<GURL> url;
-    absl::optional<InstallResultCode> code;
-    std::tie(url, code) =
+    auto [url, code] =
         InstallAndWait(&externally_managed_app_manager_impl(), install_options);
 
-    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code.value());
-    EXPECT_EQ(kFooWebAppUrl, url.value());
+    EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
+    EXPECT_EQ(kFooWebAppUrl, url);
 
     EXPECT_EQ(2u, install_run_count());
   }
diff --git a/chrome/browser/web_applications/test/test_web_app_url_loader.cc b/chrome/browser/web_applications/test/test_web_app_url_loader.cc
index 1711c22..25f67d4 100644
--- a/chrome/browser/web_applications/test/test_web_app_url_loader.cc
+++ b/chrome/browser/web_applications/test/test_web_app_url_loader.cc
@@ -20,10 +20,7 @@
 
 void TestWebAppUrlLoader::ProcessLoadUrlRequests() {
   while (!pending_requests_.empty()) {
-    GURL url;
-    ResultCallback callback;
-
-    std::tie(url, callback) = std::move(pending_requests_.front());
+    auto [url, callback] = std::move(pending_requests_.front());
     pending_requests_.pop();
 
     DCHECK(base::Contains(next_result_map_, url));
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
index 48feaa8..e06b7cd 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
@@ -164,6 +164,7 @@
   using p = AuthenticatorRequestDialogModel::Mechanism::Phone;
   const auto winapi =
       AuthenticatorRequestDialogModel::Mechanism::WindowsAPI(true);
+  const auto add = AuthenticatorRequestDialogModel::Mechanism::AddPhone(false);
   const auto usb_ui = Step::kUsbInsertAndActivate;
   const auto mss = Step::kMechanismSelection;
   const auto plat_ui = Step::kNotStarted;
@@ -203,17 +204,37 @@
 
       // If there are linked phones then AOA doesn't show up, but the phones do,
       // and sorted. The selection sheet should show.
-      {mc, {usb, aoa, cable}, {}, {"a", "b"}, {t(usb), p("a"), p("b")}, mss},
-      {ga, {usb, aoa, cable}, {}, {"a", "b"}, {t(usb), p("a"), p("b")}, mss},
+      {mc,
+       {usb, aoa, cable},
+       {},
+       {"a", "b"},
+       {add, t(usb), p("a"), p("b")},
+       mss},
+      {ga,
+       {usb, aoa, cable},
+       {},
+       {"a", "b"},
+       {add, t(usb), p("a"), p("b")},
+       mss},
 
       // On Windows, if there are linked phones we'll show a selection sheet.
-      {mc, {cable}, {has_winapi}, {"a"}, {winapi, p("a")}, mss},
-      {ga, {cable}, {has_winapi}, {"a"}, {winapi, p("a")}, mss},
+      {mc, {cable}, {has_winapi}, {"a"}, {winapi, add, p("a")}, mss},
+      {ga, {cable}, {has_winapi}, {"a"}, {winapi, add, p("a")}, mss},
       // ... unless the `prefer_native_api` flag is set because Chrome
       // remembered that the last successful security key operation was via the
       // Windows API. In that case we'll still jump directly to the native UI.
-      {mc, {cable}, {has_winapi, native}, {"a"}, {winapi, p("a")}, plat_ui},
-      {ga, {cable}, {has_winapi, native}, {"a"}, {winapi, p("a")}, plat_ui},
+      {mc,
+       {cable},
+       {has_winapi, native},
+       {"a"},
+       {winapi, add, p("a")},
+       plat_ui},
+      {ga,
+       {cable},
+       {has_winapi, native},
+       {"a"},
+       {winapi, add, p("a")},
+       plat_ui},
       // Even without `prefer_native_api`, if there aren't any linked phones
       // we'll still jump directly to the native UI, at least until we enable
       // the "Add phone" option.
@@ -377,6 +398,7 @@
   const auto off = BLEPower::OFF;
   const auto normal = Profile::NORMAL;
   const auto otr___ = Profile::INCOGNITO;
+  const auto mss = Step::kMechanismSelection;
   const auto activate = Step::kCableActivate;
   const auto interstitial = Step::kOffTheRecordInterstitial;
   const auto power = Step::kBlePowerOnAutomatic;
@@ -388,14 +410,14 @@
     std::vector<Step> steps;
   } kTests[] = {
       //               | Expected UI steps in order.
-      {mc, on_, normal, {activate}},
-      {mc, on_, otr___, {interstitial, activate}},
-      {mc, off, normal, {power, activate}},
-      {mc, off, otr___, {interstitial, power, activate}},
-      {ga, on_, normal, {activate}},
-      {ga, on_, otr___, {activate}},
-      {ga, off, normal, {power, activate}},
-      {ga, off, otr___, {power, activate}},
+      {mc, on_, normal, {mss, activate}},
+      {mc, on_, otr___, {mss, interstitial, activate}},
+      {mc, off, normal, {mss, power, activate}},
+      {mc, off, otr___, {mss, interstitial, power, activate}},
+      {ga, on_, normal, {mss, activate}},
+      {ga, on_, otr___, {mss, activate}},
+      {ga, off, normal, {mss, power, activate}},
+      {ga, off, otr___, {mss, power, activate}},
   };
 
   unsigned test_num = 0;
@@ -423,7 +445,7 @@
     model.StartFlow(std::move(transports_info),
                     /*use_location_bar_bubble=*/false,
                     /*prefer_native_api=*/false);
-    ASSERT_EQ(model.mechanisms().size(), 1u);
+    ASSERT_EQ(model.mechanisms().size(), 2u);
 
     for (const auto step : test.steps) {
       ASSERT_EQ(step, model.current_step())
@@ -431,6 +453,18 @@
           << " != " << static_cast<int>(model.current_step());
 
       switch (step) {
+        case Step::kMechanismSelection:
+          // Click the first (and only) phone.
+          for (const auto& mechanism : model.mechanisms()) {
+            if (absl::holds_alternative<
+                    AuthenticatorRequestDialogModel::Mechanism::Phone>(
+                    mechanism.type)) {
+              mechanism.callback.Run();
+              break;
+            }
+          }
+          break;
+
         case Step::kBlePowerOnAutomatic:
           model.OnBluetoothPoweredStateChanged(/*powered=*/true);
           break;
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
index 57204dd5..00f6f2ce 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -740,6 +740,19 @@
     return true;
   }
 
+  // TODO(crbug.com/1052397): Revisit the macro expression once build flag
+  // switch of lacros-chrome is complete. If updating this, also update
+  // kWebAuthCableServerLink.
+#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
+
+  // caBLEv1 is disabled on these platforms. It never launched on them because
+  // it causes problems in bluez. Rather than disabling caBLE completely, which
+  // is what was done prior to Jan 2022, this `return` just disables caBLEv1
+  // on these platforms.
+  return false;
+
+#else
+
   // Because the future of the caBLE extension might be that we transition
   // everything to QR-code or sync-based pairing, we don't want use of the
   // extension to spread without consideration. Therefore it's limited to
@@ -751,6 +764,8 @@
   const GURL test_site("https://webauthndemo.appspot.com");
   DCHECK(test_site.is_valid());
   return origin.IsSameOriginWith(test_site);
+
+#endif
 }
 
 void ChromeAuthenticatorRequestDelegate::HandleCablePairingEvent(
diff --git a/chrome/browser/win/conflicts/BUILD.gn b/chrome/browser/win/conflicts/BUILD.gn
index 8376325..d7c4c630 100644
--- a/chrome/browser/win/conflicts/BUILD.gn
+++ b/chrome/browser/win/conflicts/BUILD.gn
@@ -98,7 +98,6 @@
       "//chrome/browser:browser_process",
       "//chrome/chrome_elf:third_party_shared_defines",
       "//chrome/test:test_support_ui",
-      "//components/services/quarantine/public/cpp:features",
       "//content/test:test_support",
       "//testing/gtest",
     ]
diff --git a/chrome/browser/win/conflicts/incompatible_applications_browsertest.cc b/chrome/browser/win/conflicts/incompatible_applications_browsertest.cc
index 3c76c050..a258495 100644
--- a/chrome/browser/win/conflicts/incompatible_applications_browsertest.cc
+++ b/chrome/browser/win/conflicts/incompatible_applications_browsertest.cc
@@ -28,7 +28,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_service.h"
-#include "components/services/quarantine/public/cpp/quarantine_features_win.h"
 #include "content/public/test/browser_test.h"
 
 // This class allows to wait until the kIncompatibleApplications preference is
@@ -104,10 +103,8 @@
     ASSERT_NO_FATAL_FAILURE(
         registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));
 
-    scoped_feature_list_.InitWithFeatures(
-        {features::kIncompatibleApplicationsWarning,
-         quarantine::kOutOfProcessQuarantine},
-        {});
+    scoped_feature_list_.InitAndEnableFeature(
+        features::kIncompatibleApplicationsWarning);
 
     ASSERT_NO_FATAL_FAILURE(CreateModuleList());
     ASSERT_NO_FATAL_FAILURE(InstallThirdPartyApplication());
diff --git a/chrome/browser/win/conflicts/module_database.cc b/chrome/browser/win/conflicts/module_database.cc
index 42df5e4..6723f343 100644
--- a/chrome/browser/win/conflicts/module_database.cc
+++ b/chrome/browser/win/conflicts/module_database.cc
@@ -28,7 +28,6 @@
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
-#include "components/services/quarantine/public/cpp/quarantine_features_win.h"
 #endif
 
 namespace {
@@ -428,8 +427,6 @@
 
   if (IncompatibleApplicationsUpdater::IsWarningEnabled() ||
       ModuleBlocklistCacheUpdater::IsBlockingEnabled()) {
-    DCHECK(base::FeatureList::IsEnabled(quarantine::kOutOfProcessQuarantine));
-
     third_party_conflicts_manager_ =
         std::make_unique<ThirdPartyConflictsManager>(this);
 
diff --git a/chrome/browser/win/conflicts/third_party_blocking_browsertest.cc b/chrome/browser/win/conflicts/third_party_blocking_browsertest.cc
index b7ebda2..5b228dd1 100644
--- a/chrome/browser/win/conflicts/third_party_blocking_browsertest.cc
+++ b/chrome/browser/win/conflicts/third_party_blocking_browsertest.cc
@@ -24,7 +24,6 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/install_static/install_util.h"
 #include "chrome/test/base/in_process_browser_test.h"
-#include "components/services/quarantine/public/cpp/quarantine_features_win.h"
 #include "content/public/test/browser_test.h"
 
 namespace {
@@ -116,9 +115,8 @@
 
   // InProcessBrowserTest:
   void SetUp() override {
-    scoped_feature_list_.InitWithFeatures({features::kThirdPartyModulesBlocking,
-                                           quarantine::kOutOfProcessQuarantine},
-                                          {});
+    scoped_feature_list_.InitAndEnableFeature(
+        features::kThirdPartyModulesBlocking);
 
     ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
     ASSERT_NO_FATAL_FAILURE(
diff --git a/chrome/build/OWNERS b/chrome/build/OWNERS
index a1b3c20..2cbcb708 100644
--- a/chrome/build/OWNERS
+++ b/chrome/build/OWNERS
@@ -1,7 +1,10 @@
+jeffyoon@google.com
 sebmarchand@chromium.org
 
 per-file linux.pgo.txt=chromium-autoroll@skia-public.iam.gserviceaccount.com
 per-file linux.pgo.txt=chromium-release-autoroll@skia-public.iam.gserviceaccount.com
+per-file mac-arm.pgo.txt=chromium-autoroll@skia-public.iam.gserviceaccount.com
+per-file mac-arm.pgo.txt=chromium-release-autoroll@skia-public.iam.gserviceaccount.com
 per-file mac.pgo.txt=chromium-autoroll@skia-public.iam.gserviceaccount.com
 per-file mac.pgo.txt=chromium-release-autoroll@skia-public.iam.gserviceaccount.com
 per-file win32.pgo.txt=chromium-autoroll@skia-public.iam.gserviceaccount.com
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
new file mode 100644
index 0000000..9735789
--- /dev/null
+++ b/chrome/build/mac-arm.pgo.txt
@@ -0,0 +1 @@
+chrome-mac-arm-main-1643241442-559d26622d9b0d93f5e5d45bcc61e9a6ac75bd43.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 2df868c..4b087325 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1643198168-960034076bd6d48c3dd9d264186271c2fa886837.profdata
+chrome-mac-main-1643241442-206b6f77eafd6fd81e9207ff4f7d588b75ccac02.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 075919a..6193d27 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1643198168-1fec255c0f1a98b8e6ba6fdc66cb3a15b2c5ed93.profdata
+chrome-win32-main-1643252331-8af7cc0df0c5e0184bafc0c734e8bbc45108a009.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 8279c93..56e1cbc 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1643208800-4fdd00ad473eb3d2441ec640c02e37fb2b51c5b3.profdata
+chrome-win64-main-1643219901-644e8aa6a12c8ec61087ffe109cd8e439c295dc6.profdata
diff --git a/chrome/chrome_cleaner/engines/target/libraries_unittest.cc b/chrome/chrome_cleaner/engines/target/libraries_unittest.cc
index 62bb901..be74267 100644
--- a/chrome/chrome_cleaner/engines/target/libraries_unittest.cc
+++ b/chrome/chrome_cleaner/engines/target/libraries_unittest.cc
@@ -5,7 +5,6 @@
 #include "chrome/chrome_cleaner/engines/target/libraries.h"
 
 #include <string>
-#include <tuple>
 
 #include "base/bind.h"
 #include "base/files/file_path.h"
@@ -101,9 +100,7 @@
 }
 
 TEST_P(LoadAndValidateLibrariesTest, RunTest) {
-  std::string test_function;
-  int engine;
-  std::tie(test_function, engine) = GetParam();
+  auto [test_function, engine] = GetParam();
 
   ASSERT_TRUE(Engine::Name_IsValid(engine));
   parent_process_->AppendSwitchNative(chrome_cleaner::kEngineSwitch,
diff --git a/chrome/chrome_cleaner/mojom/BUILD.gn b/chrome/chrome_cleaner/mojom/BUILD.gn
index cc9df6a..6a8c3e07 100644
--- a/chrome/chrome_cleaner/mojom/BUILD.gn
+++ b/chrome/chrome_cleaner/mojom/BUILD.gn
@@ -52,22 +52,6 @@
   ]
 }
 
-chrome_cleaner_mojom("wstring") {
-  sources = [ "wstring.mojom" ]
-  cpp_typemaps = [
-    {
-      types = [
-        {
-          mojom = "chrome_cleaner.mojom.WString"
-          cpp = "::std::wstring"
-        },
-      ]
-      traits_headers = [ "typemaps/wstring_mojom_traits.h" ]
-      traits_sources = [ "typemaps/wstring_mojom_traits.cc" ]
-    },
-  ]
-}
-
 chrome_cleaner_mojom("engine_sandbox_interface") {
   sources = [
     "cleaner_engine_requests.mojom",
@@ -78,11 +62,8 @@
     "windows_handle.mojom",
     "wstring_embedded_nulls.mojom",
   ]
-  deps = [
-    ":footprints_interface",
-    ":wstring",
-    "//mojo/public/mojom/base",
-  ]
+  public_deps = [ "//mojo/public/mojom/base" ]
+  deps = [ ":footprints_interface" ]
   cpp_typemaps = [
     {
       types = [
@@ -135,10 +116,7 @@
 
 chrome_cleaner_mojom("parser_interface") {
   sources = [ "parser_interface.mojom" ]
-  deps = [
-    ":wstring",
-    "//mojo/public/mojom/base",
-  ]
+  public_deps = [ "//mojo/public/mojom/base" ]
 }
 
 chrome_cleaner_mojom("zip_archiver_interface") {
diff --git a/chrome/chrome_cleaner/mojom/cleaner_engine_requests.mojom b/chrome/chrome_cleaner/mojom/cleaner_engine_requests.mojom
index 195fb0c..bcbd3e7 100644
--- a/chrome/chrome_cleaner/mojom/cleaner_engine_requests.mojom
+++ b/chrome/chrome_cleaner/mojom/cleaner_engine_requests.mojom
@@ -5,8 +5,8 @@
 module chrome_cleaner.mojom;
 
 import "chrome/chrome_cleaner/mojom/footprints.mojom";
-import "chrome/chrome_cleaner/mojom/wstring.mojom";
 import "chrome/chrome_cleaner/mojom/wstring_embedded_nulls.mojom";
+import "mojo/public/mojom/base/wstring.mojom";
 
 // Passes requests that can mutate the system from the low-privilege sandbox
 // target process to the high-privilege broker process. It is implemented in
@@ -42,10 +42,10 @@
     => (bool result);
 
   // Deletes the given service.
-  SandboxDeleteService(WString name) => (bool result);
+  SandboxDeleteService(mojo_base.mojom.WString name) => (bool result);
 
   // Deletes the given task.
-  SandboxDeleteTask(WString name) => (bool result);
+  SandboxDeleteTask(mojo_base.mojom.WString name) => (bool result);
 
   // Terminates the given process.
   // The broker process can't be terminated.
diff --git a/chrome/chrome_cleaner/mojom/engine_requests.mojom b/chrome/chrome_cleaner/mojom/engine_requests.mojom
index 6270d154..d6c90ff 100644
--- a/chrome/chrome_cleaner/mojom/engine_requests.mojom
+++ b/chrome/chrome_cleaner/mojom/engine_requests.mojom
@@ -6,9 +6,9 @@
 
 import "chrome/chrome_cleaner/mojom/footprints.mojom";
 import "chrome/chrome_cleaner/mojom/windows_handle.mojom";
-import "chrome/chrome_cleaner/mojom/wstring.mojom";
 import "chrome/chrome_cleaner/mojom/wstring_embedded_nulls.mojom";
 import "mojo/public/mojom/base/process_id.mojom";
+import "mojo/public/mojom/base/wstring.mojom";
 
 enum KnownFolder {
   kWindows = 0,
@@ -18,24 +18,24 @@
 };
 
 struct StringSid {
-  WString value;
+  mojo_base.mojom.WString value;
 };
 
 struct ScheduledTaskAction {
   FilePath path;
   FilePath working_dir;
-  WString arguments;
+  mojo_base.mojom.WString arguments;
 };
 
 struct ScheduledTask {
-  WString name;
-  WString description;
+  mojo_base.mojom.WString name;
+  mojo_base.mojom.WString description;
   array<ScheduledTaskAction> actions;
 };
 
 struct UserInformation {
-  WString name;
-  WString domain;
+  mojo_base.mojom.WString name;
+  mojo_base.mojom.WString domain;
   // User account type (SID_NAME_USE). See
   // https://msdn.microsoft.com/en-us/library/windows/desktop/aa379601(v=vs.85).aspx
   uint32 account_type;
@@ -70,11 +70,11 @@
 
   // Gets all of the modules loaded into memory for the given process.
   SandboxGetLoadedModules(mojo_base.mojom.ProcessId pid) =>
-    (bool result, array<WString> modules);
+    (bool result, array<mojo_base.mojom.WString> modules);
 
   // Gets the command line for the given process.
   SandboxGetProcessCommandLine(mojo_base.mojom.ProcessId pid) =>
-    (bool result, WString command_line);
+    (bool result, mojo_base.mojom.WString command_line);
 
   // Gets the given UserInformation values for |sid|.
   SandboxGetUserInfoFromSID(StringSid sid) => (bool result,
@@ -84,7 +84,7 @@
   // |dw_access| may specify KEY_WOW64_32KEY or KEY_WOW64_64KEY. |root_key| must
   // be non-null, and |sub_key| can't have any null characters.
   SandboxOpenReadOnlyRegistry(WindowsHandle root_key,
-          WString sub_key, uint32 dw_access) =>
+          mojo_base.mojom.WString sub_key, uint32 dw_access) =>
     (uint32 result, WindowsHandle reg_handle);
 
   // Gets a read-only registry key handle to the given key.
diff --git a/chrome/chrome_cleaner/mojom/parser_interface.mojom b/chrome/chrome_cleaner/mojom/parser_interface.mojom
index 74fd295..be690cb 100644
--- a/chrome/chrome_cleaner/mojom/parser_interface.mojom
+++ b/chrome/chrome_cleaner/mojom/parser_interface.mojom
@@ -4,8 +4,8 @@
 
 module chrome_cleaner.mojom;
 
-import "chrome/chrome_cleaner/mojom/wstring.mojom";
 import "mojo/public/mojom/base/values.mojom";
+import "mojo/public/mojom/base/wstring.mojom";
 
 enum LnkParsingResult {
   BAD_FORMAT,
@@ -25,10 +25,10 @@
   // attempted to be parsed, extracting the executable target path and the
   // command line arguments.
   ParseShortcut(handle<platform> lkn_file_handle)
-   => (LnkParsingResult parsing_result, WString? target_path,
-       WString? working_dir,
-       WString? command_line_arguments,
-       WString? icon_location,
+   => (LnkParsingResult parsing_result, mojo_base.mojom.WString? target_path,
+       mojo_base.mojom.WString? working_dir,
+       mojo_base.mojom.WString? command_line_arguments,
+       mojo_base.mojom.WString? icon_location,
        int32 icon_index);
 
   // JSON parser:
diff --git a/chrome/chrome_cleaner/mojom/typemaps/wstring_mojom_traits.cc b/chrome/chrome_cleaner/mojom/typemaps/wstring_mojom_traits.cc
deleted file mode 100644
index cb1ea0e..0000000
--- a/chrome/chrome_cleaner/mojom/typemaps/wstring_mojom_traits.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2020 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 "chrome/chrome_cleaner/mojom/typemaps/wstring_mojom_traits.h"
-
-#include "mojo/public/cpp/bindings/array_data_view.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<chrome_cleaner::mojom::WStringDataView, std::wstring>::Read(
-    chrome_cleaner::mojom::WStringDataView data,
-    std::wstring* out) {
-  ArrayDataView<uint16_t> view;
-  data.GetDataDataView(&view);
-  out->assign(reinterpret_cast<const wchar_t*>(view.data()), view.size());
-  return true;
-}
-
-}  // namespace mojo
diff --git a/chrome/chrome_cleaner/mojom/typemaps/wstring_mojom_traits.h b/chrome/chrome_cleaner/mojom/typemaps/wstring_mojom_traits.h
deleted file mode 100644
index a35619de..0000000
--- a/chrome/chrome_cleaner/mojom/typemaps/wstring_mojom_traits.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2020 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 CHROME_CHROME_CLEANER_MOJOM_TYPEMAPS_WSTRING_MOJOM_TRAITS_H_
-#define CHROME_CHROME_CLEANER_MOJOM_TYPEMAPS_WSTRING_MOJOM_TRAITS_H_
-
-#include <string>
-
-#include "base/containers/span.h"
-#include "chrome/chrome_cleaner/mojom/wstring.mojom-shared.h"
-#include "mojo/public/cpp/bindings/struct_traits.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<chrome_cleaner::mojom::WStringDataView, std::wstring> {
-  static base::span<const uint16_t> data(const std::wstring& str) {
-    return base::make_span(reinterpret_cast<const uint16_t*>(str.data()),
-                           str.size());
-  }
-
-  static bool Read(chrome_cleaner::mojom::WStringDataView data,
-                   std::wstring* out);
-};
-
-}  // namespace mojo
-
-#endif  // CHROME_CHROME_CLEANER_MOJOM_TYPEMAPS_WSTRING_MOJOM_TRAITS_H_
diff --git a/chrome/chrome_cleaner/mojom/wstring.mojom b/chrome/chrome_cleaner/mojom/wstring.mojom
deleted file mode 100644
index 8a4964e..0000000
--- a/chrome/chrome_cleaner/mojom/wstring.mojom
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2020 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.
-
-module chrome_cleaner.mojom;
-
-// Corresponds to std::wstring.
-struct WString {
-  array<uint16> data;
-};
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser_fuzzer.cc b/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser_fuzzer.cc
index 825542d..3c83280 100644
--- a/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser_fuzzer.cc
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/lnk_parser_fuzzer.cc
@@ -5,6 +5,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <windows.h>
+
 #include <memory>
 #include <string>
 
@@ -23,6 +24,6 @@
 
   chrome_cleaner::ParsedLnkFile parsed_shortcut;
 
-  (void)chrome_cleaner::internal::ParseLnkBytes(file_buffer, &parsed_shortcut);
+  chrome_cleaner::internal::ParseLnkBytes(file_buffer, &parsed_shortcut);
   return 0;
 }
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni
index a7db4e4..18c8564b 100644
--- a/chrome/chrome_paks.gni
+++ b/chrome/chrome_paks.gni
@@ -209,6 +209,7 @@
         "$root_gen_dir/ash/ash_firmware_update_app_resources.pak",
         "$root_gen_dir/ash/ash_help_app_resources.pak",
         "$root_gen_dir/ash/ash_media_app_resources.pak",
+        "$root_gen_dir/ash/ash_multidevice_debug_resources.pak",
         "$root_gen_dir/ash/ash_os_feedback_resources.pak",
         "$root_gen_dir/ash/ash_personalization_app_resources.pak",
         "$root_gen_dir/ash/ash_print_management_resources.pak",
@@ -263,6 +264,7 @@
         "//ash/webui/resources:help_app_resources",
         "//ash/webui/resources:media_app_bundle_resources",
         "//ash/webui/resources:media_app_resources",
+        "//ash/webui/resources:multidevice_debug_resources",
         "//ash/webui/resources:os_feedback_resources",
         "//ash/webui/resources:personalization_app_resources",
         "//ash/webui/resources:print_management_resources",
diff --git a/chrome/installer/setup/setup_util_unittest.cc b/chrome/installer/setup/setup_util_unittest.cc
index 0bed46a2..1fdb1b4 100644
--- a/chrome/installer/setup/setup_util_unittest.cc
+++ b/chrome/installer/setup/setup_util_unittest.cc
@@ -580,9 +580,7 @@
   ASSERT_EQ(kExpectedSize, token.length());
   EXPECT_TRUE(installer::StoreDMToken(token));
 
-  base::win::RegKey key;
-  std::wstring name;
-  std::tie(key, name) = InstallUtil::GetCloudManagementDmTokenLocation(
+  auto [key, name] = InstallUtil::GetCloudManagementDmTokenLocation(
       InstallUtil::ReadOnly(true), InstallUtil::BrowserLocation(false));
   ASSERT_TRUE(key.Valid());
 
@@ -653,10 +651,7 @@
   ASSERT_TRUE(installer::RotateDeviceTrustKey(std::move(key_rotation_manager),
                                               dmserver_url, token, nonce));
 
-  base::win::RegKey key;
-  std::wstring signingkey_name;
-  std::wstring tustlevel_name;
-  std::tie(key, signingkey_name, tustlevel_name) =
+  auto [key, signingkey_name, tustlevel_name] =
       InstallUtil::GetDeviceTrustSigningKeyLocation(
           InstallUtil::ReadOnly(true));
   ASSERT_TRUE(key.Valid());
diff --git a/chrome/installer/util/beacons_unittest.cc b/chrome/installer/util/beacons_unittest.cc
index 5e5417f5..046a318 100644
--- a/chrome/installer/util/beacons_unittest.cc
+++ b/chrome/installer/util/beacons_unittest.cc
@@ -5,7 +5,6 @@
 #include "chrome/installer/util/beacons.h"
 
 #include <memory>
-#include <tuple>
 
 #include "base/test/test_reg_util_win.h"
 #include "base/test/test_timeouts.h"
@@ -168,9 +167,7 @@
   void SetUp() override {
     Super::SetUp();
 
-    install_static::InstallConstantIndex mode_index;
-    const char* level;
-    std::tie(mode_index, level) = GetParam();
+    auto [mode_index, level] = GetParam();
 
     system_install_ = (std::string(level) != "user");
 
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 0a2f75d6..b91adcc7 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -72,7 +72,6 @@
 #include "components/contextual_search/buildflags.h"
 #include "components/contextual_search/content/renderer/overlay_js_render_frame_observer.h"
 #include "components/continuous_search/renderer/search_result_extractor_impl.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "components/dom_distiller/content/renderer/distillability_agent.h"
 #include "components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h"
 #include "components/dom_distiller/core/dom_distiller_features.h"
diff --git a/chrome/renderer/chrome_content_renderer_client_unittest.cc b/chrome/renderer/chrome_content_renderer_client_unittest.cc
index e0c31096..a909381 100644
--- a/chrome/renderer/chrome_content_renderer_client_unittest.cc
+++ b/chrome/renderer/chrome_content_renderer_client_unittest.cc
@@ -17,7 +17,6 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/common/privacy_budget/scoped_privacy_budget_config.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/webplugininfo.h"
 #include "extensions/buildflags/buildflags.h"
diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc
index 1d3670b4..2747416 100644
--- a/chrome/renderer/media/chrome_key_systems.cc
+++ b/chrome/renderer/media/chrome_key_systems.cc
@@ -159,6 +159,12 @@
       case media::AudioCodec::kAAC:
         supported_codecs |= media::EME_CODEC_AAC;
         break;
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+      case media::AudioCodec::kDTS:
+        supported_codecs |= media::EME_CODEC_DTS;
+        supported_codecs |= media::EME_CODEC_DTSXP2;
+        break;
+#endif  // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
       default:
         DVLOG(1) << "Unexpected supported codec: " << GetCodecName(codec);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 5e5c008..50914408 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1171,8 +1171,6 @@
       "//components/country_codes",
       "//components/crash/content/browser/error_reporting:mock_crash_endpoint",
       "//components/data_reduction_proxy/core/browser:test_support",
-      "//components/data_use_measurement/core",
-      "//components/data_use_measurement/core:ascriber",
       "//components/dom_distiller/content/browser",
       "//components/dom_distiller/content/browser:test_support",
       "//components/dom_distiller/content/renderer",
@@ -1552,7 +1550,6 @@
       "../browser/data_saver/data_saver_browsertest.cc",
       "../browser/data_saver/data_saver_holdback_browsertest.cc",
       "../browser/data_saver/data_saver_webapis_browsertest.cc",
-      "../browser/data_use_measurement/chrome_data_use_measurement_browsertest.cc",
       "../browser/device_api/managed_configuration_api_browsertest.cc",
       "../browser/devtools/device/adb/adb_client_socket_browsertest.cc",
       "../browser/devtools/device/adb/mock_adb_server.cc",
@@ -1612,7 +1609,6 @@
       "../browser/interest_group/interest_group_permissions_browsertest.cc",
       "../browser/invalidation/profile_invalidation_provider_factory_browsertest.cc",
       "../browser/l10n_util_browsertest.cc",
-      "../browser/lazyload/lazyload_browsertest.cc",
       "../browser/lifetime/browser_close_manager_browsertest.cc",
       "../browser/lifetime/browser_shutdown_browsertest.cc",
       "../browser/loader/signed_exchange_policy_browsertest.cc",
@@ -1743,8 +1739,6 @@
       "../browser/page_load_metrics/observers/back_forward_cache_page_load_metrics_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/core/amp_page_load_metrics_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer_browsertest.cc",
-      "../browser/page_load_metrics/observers/data_saver_site_breakdown_metrics_observer_browsertest.cc",
-      "../browser/page_load_metrics/observers/data_use_metrics_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/foreground_duration_ukm_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/formfill_page_load_metrics_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer_browsertest.cc",
@@ -5291,7 +5285,6 @@
     "//components/custom_handlers",
     "//components/custom_handlers:test_support",
     "//components/data_reduction_proxy/core/browser:test_support",
-    "//components/data_use_measurement/core",
     "//components/download/public/background_service/test:test_support",
     "//components/drive",
     "//components/drive:test_support",
@@ -5806,7 +5799,6 @@
       "../browser/optimization_guide/android/android_push_notification_manager_unittest.cc",
       "../browser/optimization_guide/android/optimization_guide_bridge_unittest.cc",
       "../browser/page_load_metrics/observers/android_page_load_metrics_observer_unittest.cc",
-      "../browser/page_load_metrics/observers/offline_measurements_page_load_metrics_observer_unittest.cc",
       "../browser/permissions/permission_prompt_android_unittest.cc",
       "../browser/permissions/permission_update_message_controller_android_unittest.cc",
       "../browser/policy/browser_dm_token_storage_android_unittest.cc",
@@ -5840,9 +5832,6 @@
       "//chrome/browser/flags:flags_android",
       "//chrome/browser/long_screenshots:services",
       "//chrome/browser/notifications",
-      "//chrome/browser/offline_pages/android:native_j_unittests_jni_headers",
-      "//chrome/browser/offline_pages/android:native_java_unittests",
-      "//chrome/browser/offline_pages/measurements/proto:offline_measurements_proto",
       "//chrome/browser/optimization_guide/android:native_j_unittests_jni_headers",
       "//chrome/browser/optimization_guide/android:native_java_unittests",
       "//chrome/browser/password_check/android:unit_tests",
diff --git a/chrome/test/base/chrome_unit_test_suite.cc b/chrome/test/base/chrome_unit_test_suite.cc
index e5d0213..2d9d4f57 100644
--- a/chrome/test/base/chrome_unit_test_suite.cc
+++ b/chrome/test/base/chrome_unit_test_suite.cc
@@ -14,7 +14,6 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_content_browser_client.h"
-#include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
 #include "chrome/browser/profiles/profile_shortcut_manager.h"
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
 #include "chrome/browser/update_client/chrome_update_query_params_delegate.h"
@@ -98,10 +97,6 @@
   }
 
   void OnTestEnd(const testing::TestInfo& test_info) override {
-    // To ensure that NetworkConnectionTracker doesn't complain in unit_tests
-    // about outstanding listeners.
-    data_use_measurement::ChromeDataUseMeasurement::DeleteInstance();
-
     browser_content_client_.reset();
     utility_content_client_.reset();
     content_client_.reset();
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index 452cfb9..10011cc9 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -15,7 +15,6 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_impl.h"
-#include "chrome/browser/data_use_measurement/chrome_data_use_measurement.h"
 #include "chrome/browser/download/download_request_limiter.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/notifications/notification_platform_bridge.h"
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 2500d249..d8e2c04 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -2083,12 +2083,19 @@
     self._driver.Load(self.GetHttpUrlForFile('/chromedriver/console_log.html'))
     logs = self._driver.GetLog('browser')
 
-    self.assertEqual('javascript', logs[0]['source'])
-    self.assertTrue('TypeError' in logs[0]['message'])
+    # The javascript and network logs can come in any order.
+    if logs[0]['source'] == 'javascript':
+        js_log = logs[0]
+        network_log = logs[1]
+    else:
+        network_log = logs[0]
+        js_log = logs[1]
+    self.assertEqual('javascript', js_log['source'])
+    self.assertTrue('TypeError' in js_log['message'])
 
-    self.assertEqual('network', logs[1]['source'])
-    self.assertTrue('nonexistent.png' in logs[1]['message'])
-    self.assertTrue('404' in logs[1]['message'])
+    self.assertEqual('network', network_log['source'])
+    self.assertTrue('nonexistent.png' in network_log['message'])
+    self.assertTrue('404' in network_log['message'])
 
     # Sometimes, we also get an error for a missing favicon.
     if len(logs) > 2:
diff --git a/chrome/test/data/extensions/api_test/file_system/request_downloads_whitelisted_extension/background.js b/chrome/test/data/extensions/api_test/file_system/request_downloads_allowed_extension/background.js
similarity index 100%
rename from chrome/test/data/extensions/api_test/file_system/request_downloads_whitelisted_extension/background.js
rename to chrome/test/data/extensions/api_test/file_system/request_downloads_allowed_extension/background.js
diff --git a/chrome/test/data/extensions/api_test/file_system/request_downloads_whitelisted_extension/manifest.json b/chrome/test/data/extensions/api_test/file_system/request_downloads_allowed_extension/manifest.json
similarity index 100%
rename from chrome/test/data/extensions/api_test/file_system/request_downloads_whitelisted_extension/manifest.json
rename to chrome/test/data/extensions/api_test/file_system/request_downloads_allowed_extension/manifest.json
diff --git a/chrome/test/data/extensions/api_test/file_system/request_downloads_whitelisted_extension/test.html b/chrome/test/data/extensions/api_test/file_system/request_downloads_allowed_extension/test.html
similarity index 100%
rename from chrome/test/data/extensions/api_test/file_system/request_downloads_whitelisted_extension/test.html
rename to chrome/test/data/extensions/api_test/file_system/request_downloads_allowed_extension/test.html
diff --git a/chrome/test/data/extensions/api_test/file_system/request_downloads_whitelisted_extension/test.js b/chrome/test/data/extensions/api_test/file_system/request_downloads_allowed_extension/test.js
similarity index 100%
rename from chrome/test/data/extensions/api_test/file_system/request_downloads_whitelisted_extension/test.js
rename to chrome/test/data/extensions/api_test/file_system/request_downloads_allowed_extension/test.js
diff --git a/chrome/test/data/extensions/api_test/i18n/test.js b/chrome/test/data/extensions/api_test/i18n/test.js
index 44eef93..bd37cffc 100644
--- a/chrome/test/data/extensions/api_test/i18n/test.js
+++ b/chrome/test/data/extensions/api_test/i18n/test.js
@@ -5,112 +5,81 @@
 // i18n api test
 // browser_tests.exe --gtest_filter=ExtensionApiTest.I18N --lib=browser_tests
 
-const isServiceWorker = ('ServiceWorkerGlobalScope' in self);
 var testCallback = chrome.test.testCallback;
 var callbackPass = chrome.test.callbackPass;
-var testFileUrl;
-
-function getAcceptLanguages() {
-  chrome.i18n.getAcceptLanguages(callbackPass(function(results) {
-    chrome.test.assertEq(results.length, 2);
-    chrome.test.assertEq(results[0], "en-US");
-    chrome.test.assertEq(results[1], "en");
-  }));
-}
-
-function getMessage() {
-  var message = chrome.i18n.getMessage("simple_message");
-  chrome.test.assertEq(message, "Simple message");
-
-  message = chrome.i18n.getMessage("message_with_placeholders",
-                                   ["Cira", "John"]);
-  chrome.test.assertEq(message, "Cira and John work for Google");
-
-  message = chrome.i18n.getMessage("message_with_one_placeholder", "19");
-  chrome.test.assertEq(message, "Number of errors: 19");
-
-  message = chrome.i18n.getMessage("message_with_double_dollar_sign");
-  chrome.test.assertEq(message, "I need $500 please.");
-
-  message = chrome.i18n.getMessage(
-      "message_with_double_dollar_sign_and_placeholders",
-      ["Mitchell", "Chris"]);
-  chrome.test.assertEq(
-      message,
-      "We should really be paying Mitchell and Chris more $$$.");
-
-  chrome.test.succeed();
-}
-
-function getMessageFromContentScript() {
-  chrome.extension.onRequest.addListener(
-      function(request, sender, sendResponse) {
-        chrome.test.assertEq(request, "Number of errors: 19");
-        chrome.test.succeed();
-      }
-  );
-  chrome.test.log("Creating tab...");
-  chrome.tabs.create({
-    url: testFileUrl
-  });
-}
-
-function getUILanguage() {
-  chrome.test.assertEq('en-US', chrome.i18n.getUILanguage());
-  chrome.test.succeed();
-}
-
-function detectLanguageNone() {
-  var text = "";
-  chrome.i18n.detectLanguage(text, function (result) {
-    chrome.test.assertEq([], result.languages);
-    chrome.test.succeed();
-  });
-}
-
-function detectLanguageGreek() {
-  text = "Αυτό το κείμενο είναι γραμμένο στα ελληνικά";
-  chrome.i18n.detectLanguage(text, function (result) {
-    chrome.test.assertEq([{ "language": "el", "percentage": 100 }],
-                         result.languages);
-    chrome.test.succeed();
-  });
-}
-
-function detectLanguageMixed() {
-  text = "Αυτό το κομμάτι του κειμένου είναι γραμμένο στα ελληνικά \
-             ข้อความสั้น Short piece of text in English";
-  chrome.i18n.detectLanguage(text, function (result) {
-    chrome.test.assertEq([{ "language": "el", "percentage": 61 },
-                          { "language": "th", "percentage": 20 },
-                          { "language": "en", "percentage": 18}],
-                         result.languages);
-    chrome.test.succeed();
-  });
-}
-
-var serviceWorkerTests = [
-  getAcceptLanguages,
-  getUILanguage,
-  detectLanguageNone,
-  detectLanguageGreek,
-  detectLanguageMixed
-];
-
-var allTests = [
-  getAcceptLanguages,
-  getMessage,
-  getMessageFromContentScript,
-  getUILanguage,
-  detectLanguageNone,
-  detectLanguageGreek,
-  detectLanguageMixed
-];
 
 chrome.test.getConfig(function(config) {
 
-   testFileUrl = "http://localhost:PORT/extensions/test_file.html"
+  var TEST_FILE_URL = "http://localhost:PORT/extensions/test_file.html"
       .replace(/PORT/, config.testServer.port);
 
-  chrome.test.runTests(isServiceWorker ? serviceWorkerTests : allTests);
+  chrome.test.runTests([
+    function getAcceptLanguages() {
+      chrome.i18n.getAcceptLanguages(callbackPass(function(results) {
+        chrome.test.assertEq(results.length, 2);
+        chrome.test.assertEq(results[0], "en-US");
+        chrome.test.assertEq(results[1], "en");
+      }));
+    },
+    function getMessage() {
+      var message = chrome.i18n.getMessage("simple_message");
+      chrome.test.assertEq(message, "Simple message");
+
+      message = chrome.i18n.getMessage("message_with_placeholders",
+                                       ["Cira", "John"]);
+      chrome.test.assertEq(message, "Cira and John work for Google");
+
+      message = chrome.i18n.getMessage("message_with_one_placeholder", "19");
+      chrome.test.assertEq(message, "Number of errors: 19");
+
+      message = chrome.i18n.getMessage("message_with_double_dollar_sign");
+      chrome.test.assertEq(message, "I need $500 please.");
+
+      message = chrome.i18n.getMessage(
+          "message_with_double_dollar_sign_and_placeholders",
+          ["Mitchell", "Chris"]);
+      chrome.test.assertEq(message,
+          "We should really be paying Mitchell and Chris more $$$.");
+
+      chrome.test.succeed();
+    },
+    function getMessageFromContentScript() {
+      chrome.extension.onRequest.addListener(
+        function(request, sender, sendResponse) {
+          chrome.test.assertEq(request, "Number of errors: 19");
+        }
+      );
+      chrome.test.log("Creating tab...");
+      chrome.tabs.create({
+        url: TEST_FILE_URL
+      });
+      chrome.test.succeed();
+    },
+    function getUILanguage() {
+      chrome.test.assertEq('en-US', chrome.i18n.getUILanguage());
+      chrome.test.succeed();
+    },
+    function detectLanguage() {
+      var text = "";
+      chrome.i18n.detectLanguage(text, function (result) {
+        chrome.test.assertEq([], result.languages);
+      });
+
+      text = "Αυτό το κείμενο είναι γραμμένο στα ελληνικά";
+      chrome.i18n.detectLanguage(text, function (result) {
+        chrome.test.assertEq([{ "language": "el", "percentage": 100 }],
+            result.languages);
+      });
+
+      text = "Αυτό το κομμάτι του κειμένου είναι γραμμένο στα ελληνικά \
+             ข้อความสั้น Short piece of text in English";
+      chrome.i18n.detectLanguage(text, function (result) {
+        chrome.test.assertEq([{ "language": "el", "percentage": 61 },
+            { "language": "th", "percentage": 20 },
+            { "language": "en", "percentage": 18}], result.languages);
+      });
+
+      chrome.test.succeed();
+    }
+  ]);
 });
diff --git a/chrome/test/data/extensions/api_test/permissions/optional/background.js b/chrome/test/data/extensions/api_test/permissions/optional/background.js
index 8d4904b..fc71beb7 100644
--- a/chrome/test/data/extensions/api_test/permissions/optional/background.js
+++ b/chrome/test/data/extensions/api_test/permissions/optional/background.js
@@ -207,29 +207,31 @@
     },
 
     function requestOrigin() {
-      doReq('http://c.com', pass(function(success) { assertFalse(success); }));
+      doReq('http://c.com', pass(function(success) {
+        assertFalse(success);
 
-      chrome.permissions.getAll(pass(function(permissions) {
-        assertTrue(checkPermSetsEq(initialPermissions, permissions));
-      }));
-
-      listenOnce(chrome.permissions.onAdded,
-                 function(permissions) {
-        assertTrue(permissions.permissions.length == 0);
-        assertTrue(permissions.origins.length == 1);
-        assertTrue(permissions.origins[0] == 'http://*.c.com/*');
-      });
-      chrome.permissions.request(
-          {origins: ['http://*.c.com/*']},
-          pass(function(granted) {
-        assertTrue(granted);
         chrome.permissions.getAll(pass(function(permissions) {
-          assertTrue(checkPermSetsEq(permissionsWithOrigin, permissions));
+          assertTrue(checkPermSetsEq(initialPermissions, permissions));
         }));
-        chrome.permissions.contains(
-            {origins:['http://*.c.com/*']},
-            pass(function(result) { assertTrue(result); }));
-        doReq('http://c.com', pass(function(result) { assertTrue(result); }));
+
+        listenOnce(chrome.permissions.onAdded,
+                   function(permissions) {
+          assertTrue(permissions.permissions.length == 0);
+          assertTrue(permissions.origins.length == 1);
+          assertTrue(permissions.origins[0] == 'http://*.c.com/*');
+        });
+        chrome.permissions.request(
+            {origins: ['http://*.c.com/*']},
+            pass(function(granted) {
+          assertTrue(granted);
+          chrome.permissions.getAll(pass(function(permissions) {
+            assertTrue(checkPermSetsEq(permissionsWithOrigin, permissions));
+          }));
+          chrome.permissions.contains(
+              {origins:['http://*.c.com/*']},
+              pass(function(result) { assertTrue(result); }));
+          doReq('http://c.com', pass(function(result) { assertTrue(result); }));
+        }));
       }));
     },
 
diff --git a/chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_whitelisted/background.js b/chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_allowed/background.js
similarity index 100%
rename from chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_whitelisted/background.js
rename to chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_allowed/background.js
diff --git a/chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_whitelisted/index.html b/chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_allowed/index.html
similarity index 100%
rename from chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_whitelisted/index.html
rename to chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_allowed/index.html
diff --git a/chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_whitelisted/manifest.json b/chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_allowed/manifest.json
similarity index 100%
rename from chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_whitelisted/manifest.json
rename to chrome/test/data/extensions/platform_apps/windows_api_ime/has_permissions_allowed/manifest.json
diff --git a/chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_whitelisted/background.js b/chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_allowed/background.js
similarity index 100%
rename from chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_whitelisted/background.js
rename to chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_allowed/background.js
diff --git a/chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_whitelisted/index.html b/chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_allowed/index.html
similarity index 100%
rename from chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_whitelisted/index.html
rename to chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_allowed/index.html
diff --git a/chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_whitelisted/manifest.json b/chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_allowed/manifest.json
similarity index 100%
rename from chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_whitelisted/manifest.json
rename to chrome/test/data/extensions/platform_apps/windows_api_ime/no_permissions_allowed/manifest.json
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index d580ec1..24f439ce 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -55,6 +55,7 @@
     sources = [
       "cr_components/cr_components_mojo_interactive_test.js",
       "new_tab_page/new_tab_page_interactive_test.js",
+      "read_later/side_panel/side_panel_interactive_ui_tests.js",
     ]
 
     gen_include_files = [
diff --git a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_dialog_test.js b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_dialog_test.js
index 9cf2867..e23c944 100644
--- a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_dialog_test.js
+++ b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_dialog_test.js
@@ -101,5 +101,11 @@
         updateDialogElement.shadowRoot.querySelector('#progress')
             .textContent.trim(),
         loadTimeData.getString('restartingFooterText'));
+    // Check that the indeterminate progress is shown.
+    assertTrue(!!updateDialogElement.shadowRoot.querySelector(
+        '#indeterminateProgressBar'));
+    // No percentage progress bar.
+    assertFalse(
+        !!updateDialogElement.shadowRoot.querySelector('#updateProgressBar'));
   });
 }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/avatar_list_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/avatar_list_element_test.ts
index 5e1c04bc..c5b3524 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/avatar_list_element_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/avatar_list_element_test.ts
@@ -53,7 +53,7 @@
     avatarListElement = initElement(AvatarList);
 
     const image =
-        avatarListElement!.shadowRoot!.querySelector(
+        avatarListElement.shadowRoot!.querySelector(
             `img[data-id="${testUserProvider.defaultUserImages[0]!.index}"]`) as
         HTMLImageElement;
 
@@ -86,4 +86,19 @@
         testPersonalizationStore.data.user.profileImage,
         testUserProvider.profileImage);
   });
+
+  test('calls selectProfileImage on click', async () => {
+    testPersonalizationStore.data.user.profileImage =
+        testUserProvider.profileImage;
+    avatarListElement = initElement(AvatarList);
+
+    const image = avatarListElement.shadowRoot!.getElementById(
+                      'profileImage') as HTMLImageElement;
+
+    image.click();
+    await testUserProvider.whenCalled('selectProfileImage');
+    assertDeepEquals(testUserProvider.profileImage, {
+      url: 'data://updated_test_url',
+    });
+  });
 }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_user_interface_provider.ts b/chrome/test/data/webui/chromeos/personalization_app/test_user_interface_provider.ts
index 4061bf9..2e65aa0 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/test_user_interface_provider.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/test_user_interface_provider.ts
@@ -31,6 +31,7 @@
     super([
       'setUserImageObserver',
       'getDefaultUserImages',
+      'selectProfileImage',
       'getUserInfo',
       'selectDefaultImage',
     ]);
@@ -57,4 +58,11 @@
   selectDefaultImage(index: number) {
     this.methodCalled('selectDefaultImage', index);
   }
+
+  async selectProfileImage() {
+    this.methodCalled('selectProfileImage');
+    this.profileImage = {
+      url: 'data://updated_test_url',
+    };
+  }
 }
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_select_components_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_select_components_page_test.js
index 7be3afe..110625dd 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_select_components_page_test.js
+++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_select_components_page_test.js
@@ -112,12 +112,15 @@
         component.shadowRoot.querySelector('#componentTouchpad');
     assertFalse(reworkFlowLink.hidden);
     assertEquals('Camera', cameraComponent.componentName);
+    assertEquals('Camera_XYZ_1', cameraComponent.componentIdentifier);
     assertFalse(cameraComponent.disabled);
     assertFalse(cameraComponent.checked);
     assertEquals('Battery', batteryComponent.componentName);
+    assertEquals('Battery_XYZ_Lithium', batteryComponent.componentIdentifier);
     assertTrue(batteryComponent.disabled);
     assertFalse(batteryComponent.checked);
     assertEquals('Touchpad', touchpadComponent.componentName);
+    assertEquals('Touchpad_XYZ_2', touchpadComponent.componentIdentifier);
     assertFalse(touchpadComponent.disabled);
     assertTrue(touchpadComponent.checked);
   });
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/repair_component_chip_test.js b/chrome/test/data/webui/chromeos/shimless_rma/repair_component_chip_test.js
index ddcb808..62584b4 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/repair_component_chip_test.js
+++ b/chrome/test/data/webui/chromeos/shimless_rma/repair_component_chip_test.js
@@ -22,14 +22,16 @@
 
   /**
    * @param {string} componentName
+   * @param {string} componentIdentifier
    * @return {!Promise}
    */
-  function initializeRepairComponentChip(componentName) {
+  function initializeRepairComponentChip(componentName, componentIdentifier) {
     assertFalse(!!component);
 
     component = /** @type {!RepairComponentChipElement} */ (
         document.createElement('repair-component-chip'));
     component.componentName = componentName;
+    component.componentIdentifier = componentIdentifier;
     assertTrue(!!component);
     document.body.appendChild(component);
 
@@ -46,18 +48,26 @@
   }
 
   test('ComponentRenders', async () => {
-    await initializeRepairComponentChip('cpu');
+    const name = 'cpu';
+    const identifier = 'cpu_123';
+    await initializeRepairComponentChip(name, identifier);
     assertTrue(!!component);
     assertFalse(component.checked);
 
-    const componentNameSpanElement =
-        component.shadowRoot.querySelector('#componentName');
-    assertTrue(!!componentNameSpanElement);
-    assertEquals(componentNameSpanElement.textContent, 'cpu');
+    const nameElement = component.shadowRoot.querySelector('#componentName');
+    assertTrue(!!nameElement);
+    assertEquals(nameElement.textContent, name);
+
+    const identifierElement =
+        component.shadowRoot.querySelector('#componentIdentifier');
+    assertTrue(!!identifierElement);
+    assertEquals(identifierElement.textContent, identifier);
   });
 
   test('ComponentToggleCheckedOnClick', async () => {
-    await initializeRepairComponentChip('cpu');
+    const name = 'cpu';
+    const identifier = 'cpu_123';
+    await initializeRepairComponentChip(name, identifier);
 
     const checkIcon = component.shadowRoot.querySelector('#checkIcon');
 
@@ -71,7 +81,9 @@
   });
 
   test('ComponentNoToggleOnDisabled', async () => {
-    await initializeRepairComponentChip('cpu');
+    const name = 'cpu';
+    const identifier = 'cpu_123';
+    await initializeRepairComponentChip(name, identifier);
     component.disabled = true;
     await flushTasks();
 
diff --git a/chrome/test/data/webui/extensions/BUILD.gn b/chrome/test/data/webui/extensions/BUILD.gn
index 6bec464..787f1b5 100644
--- a/chrome/test/data/webui/extensions/BUILD.gn
+++ b/chrome/test/data/webui/extensions/BUILD.gn
@@ -21,10 +21,10 @@
   "activity_log_stream_item_test.ts",
   "activity_log_stream_test.ts",
   "activity_log_test.ts",
-  "code_section_test.js",
-  "detail_view_test.js",
-  "error_console_test.js",
-  "error_page_test.js",
+  "code_section_test.ts",
+  "detail_view_test.ts",
+  "error_console_test.ts",
+  "error_page_test.ts",
   "extension_options_dialog_test.js",
   "host_permissions_toggle_list_test.js",
   "item_list_test.js",
diff --git a/chrome/test/data/webui/extensions/code_section_test.js b/chrome/test/data/webui/extensions/code_section_test.js
deleted file mode 100644
index b889079..0000000
--- a/chrome/test/data/webui/extensions/code_section_test.js
+++ /dev/null
@@ -1,138 +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.
-
-/** @fileoverview Suite of tests for extensions-code-section. */
-import 'chrome://extensions/extensions.js';
-
-import {assert} from 'chrome://resources/js/assert.m.js';
-import {isChildVisible} from 'chrome://webui-test/test_util.js';
-
-window.extension_code_section_tests = {};
-extension_code_section_tests.suiteName = 'ExtensionCodeSectionTest';
-/** @enum {string} */
-extension_code_section_tests.TestNames = {
-  Layout: 'layout',
-  LongSource: 'long source',
-};
-
-suite(extension_code_section_tests.suiteName, function() {
-  /** @type {ExtensionsCodeSectionElement} */
-  let codeSection;
-
-  const couldNotDisplayCode = 'No code here';
-
-  // Initialize an extension item before each test.
-  setup(function() {
-    document.body.innerHTML = '';
-    codeSection = document.createElement('extensions-code-section');
-    codeSection.couldNotDisplayCode = couldNotDisplayCode;
-    document.body.appendChild(codeSection);
-  });
-
-  test(assert(extension_code_section_tests.TestNames.Layout), function() {
-    /** @type {chrome.developerPrivate.RequestFileSourceResponse} */
-    const code = {
-      beforeHighlight: 'this part before the highlight\nAnd this too\n',
-      highlight: 'highlight this part\n',
-      afterHighlight: 'this part after the highlight',
-      message: 'Highlight message',
-    };
-
-    const testIsVisible = isChildVisible.bind(null, codeSection);
-    expectFalse(!!codeSection.code);
-    expectTrue(
-        codeSection.shadowRoot.querySelector('#scroll-container').hidden);
-    expectFalse(testIsVisible('#main'));
-    expectTrue(testIsVisible('#no-code'));
-
-    codeSection.code = code;
-    codeSection.isActive = true;
-    expectTrue(testIsVisible('#main'));
-    expectFalse(testIsVisible('#no-code'));
-
-    let codeSections =
-        codeSection.shadowRoot.querySelectorAll('#source span span');
-
-    expectEquals(code.beforeHighlight, codeSections[0].textContent);
-    expectEquals(code.highlight, codeSections[1].textContent);
-    expectEquals(code.afterHighlight, codeSections[2].textContent);
-
-    expectEquals(
-        '1\n2\n3\n4',
-        codeSection.shadowRoot.querySelector('#line-numbers span')
-            .textContent.trim());
-  });
-
-  test(assert(extension_code_section_tests.TestNames.LongSource), function() {
-    /** @type {chrome.developerPrivate.RequestFileSourceResponse} */
-    let code;
-    let lineNums;
-
-    function setCodeContent(beforeLineCount, afterLineCount) {
-      code = {
-        beforeHighlight: '',
-        highlight: 'highlight',
-        afterHighlight: '',
-        message: 'Highlight message',
-      };
-      for (let i = 0; i < beforeLineCount; i++) {
-        code.beforeHighlight += 'a\n';
-      }
-      for (let i = 0; i < afterLineCount; i++) {
-        code.afterHighlight += 'a\n';
-      }
-    }
-
-    setCodeContent(0, 2000);
-    codeSection.code = code;
-    lineNums =
-        codeSection.shadowRoot.querySelector('#line-numbers span').textContent;
-    // Length should be 1000 +- 1.
-    expectTrue(lineNums.split('\n').length >= 999);
-    expectTrue(lineNums.split('\n').length <= 1001);
-    expectTrue(!!lineNums.match(/^1\n/));
-    expectTrue(!!lineNums.match(/1000/));
-    expectFalse(!!lineNums.match(/1001/));
-    expectTrue(
-        codeSection.shadowRoot.querySelector('#line-numbers .more-code.before')
-            .hidden);
-    expectFalse(
-        codeSection.shadowRoot.querySelector('#line-numbers .more-code.after')
-            .hidden);
-
-    setCodeContent(1000, 1000);
-    codeSection.code = code;
-    lineNums =
-        codeSection.shadowRoot.querySelector('#line-numbers span').textContent;
-    // Length should be 1000 +- 1.
-    expectTrue(lineNums.split('\n').length >= 999);
-    expectTrue(lineNums.split('\n').length <= 1001);
-    expectFalse(!!lineNums.match(/^1\n/));
-    expectTrue(!!lineNums.match(/1000/));
-    expectFalse(!!lineNums.match(/1999/));
-    expectFalse(
-        codeSection.shadowRoot.querySelector('#line-numbers .more-code.before')
-            .hidden);
-    expectFalse(
-        codeSection.shadowRoot.querySelector('#line-numbers .more-code.after')
-            .hidden);
-
-    setCodeContent(2000, 0);
-    codeSection.code = code;
-    lineNums =
-        codeSection.shadowRoot.querySelector('#line-numbers span').textContent;
-    // Length should be 1000 +- 1.
-    expectTrue(lineNums.split('\n').length >= 999);
-    expectTrue(lineNums.split('\n').length <= 1001);
-    expectFalse(!!lineNums.match(/^1\n/));
-    expectTrue(!!lineNums.match(/1002/));
-    expectTrue(!!lineNums.match(/2000/));
-    expectFalse(
-        codeSection.shadowRoot.querySelector('#line-numbers .more-code.before')
-            .hidden);
-    expectTrue(
-        codeSection.shadowRoot.querySelector('#line-numbers .more-code.after')
-            .hidden);
-  });
-});
diff --git a/chrome/test/data/webui/extensions/code_section_test.ts b/chrome/test/data/webui/extensions/code_section_test.ts
new file mode 100644
index 0000000..7d8195f
--- /dev/null
+++ b/chrome/test/data/webui/extensions/code_section_test.ts
@@ -0,0 +1,145 @@
+// 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.
+
+/** @fileoverview Suite of tests for extensions-code-section. */
+import 'chrome://extensions/extensions.js';
+
+import {ExtensionsCodeSectionElement} from 'chrome://extensions/extensions.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {isChildVisible} from 'chrome://webui-test/test_util.js';
+
+const extension_code_section_tests = {
+  suiteName: 'ExtensionCodeSectionTest',
+  TestNames: {
+    Layout: 'layout',
+    LongSource: 'long source',
+  },
+};
+
+Object.assign(
+    window, {extension_code_section_tests: extension_code_section_tests});
+
+suite(extension_code_section_tests.suiteName, function() {
+  let codeSection: ExtensionsCodeSectionElement;
+
+  const couldNotDisplayCode: string = 'No code here';
+
+  // Initialize an extension item before each test.
+  setup(function() {
+    document.body.innerHTML = '';
+    codeSection = document.createElement('extensions-code-section');
+    codeSection.couldNotDisplayCode = couldNotDisplayCode;
+    document.body.appendChild(codeSection);
+  });
+
+  test(assert(extension_code_section_tests.TestNames.Layout), function() {
+    const code: chrome.developerPrivate.RequestFileSourceResponse = {
+      beforeHighlight: 'this part before the highlight\nAnd this too\n',
+      highlight: 'highlight this part\n',
+      afterHighlight: 'this part after the highlight',
+      message: 'Highlight message',
+      title: '',
+    };
+
+    const testIsVisible = isChildVisible.bind(null, codeSection);
+    assertFalse(!!codeSection.code);
+    assertTrue(
+        codeSection.shadowRoot!.querySelector<HTMLElement>(
+                                   '#scroll-container')!.hidden);
+    assertFalse(testIsVisible('#main'));
+    assertTrue(testIsVisible('#no-code'));
+
+    codeSection.code = code;
+    codeSection.isActive = true;
+    assertTrue(testIsVisible('#main'));
+    assertFalse(testIsVisible('#no-code'));
+
+    let codeSections =
+        codeSection.shadowRoot!.querySelectorAll('#source span span');
+
+    assertEquals(code.beforeHighlight, codeSections[0]!.textContent);
+    assertEquals(code.highlight, codeSections[1]!.textContent);
+    assertEquals(code.afterHighlight, codeSections[2]!.textContent);
+
+    assertEquals(
+        '1\n2\n3\n4',
+        codeSection.shadowRoot!
+            .querySelector<HTMLElement>(
+                '#line-numbers span')!.textContent!.trim());
+  });
+
+  test(assert(extension_code_section_tests.TestNames.LongSource), function() {
+    let lineNums;
+
+    function setCodeContent(beforeLineCount: number, afterLineCount: number):
+        chrome.developerPrivate.RequestFileSourceResponse {
+      const code: chrome.developerPrivate.RequestFileSourceResponse = {
+        beforeHighlight: '',
+        highlight: 'highlight',
+        afterHighlight: '',
+        message: 'Highlight message',
+        title: '',
+      };
+      for (let i = 0; i < beforeLineCount; i++) {
+        code.beforeHighlight += 'a\n';
+      }
+      for (let i = 0; i < afterLineCount; i++) {
+        code.afterHighlight += 'a\n';
+      }
+      return code;
+    }
+
+    codeSection.code = setCodeContent(0, 2000);
+    lineNums =
+        codeSection.shadowRoot!
+            .querySelector<HTMLElement>('#line-numbers span')!.textContent!;
+    // Length should be 1000 +- 1.
+    assertTrue(lineNums.split('\n').length >= 999);
+    assertTrue(lineNums.split('\n').length <= 1001);
+    assertTrue(!!lineNums.match(/^1\n/));
+    assertTrue(!!lineNums.match(/1000/));
+    assertFalse(!!lineNums.match(/1001/));
+    assertTrue(codeSection.shadowRoot!
+                   .querySelector<HTMLElement>(
+                       '#line-numbers .more-code.before')!.hidden);
+    assertFalse(codeSection.shadowRoot!
+                    .querySelector<HTMLElement>(
+                        '#line-numbers .more-code.after')!.hidden);
+
+    codeSection.code = setCodeContent(1000, 1000);
+    lineNums =
+        codeSection.shadowRoot!
+            .querySelector<HTMLElement>('#line-numbers span')!.textContent!;
+    // Length should be 1000 +- 1.
+    assertTrue(lineNums.split('\n').length >= 999);
+    assertTrue(lineNums.split('\n').length <= 1001);
+    assertFalse(!!lineNums.match(/^1\n/));
+    assertTrue(!!lineNums.match(/1000/));
+    assertFalse(!!lineNums.match(/1999/));
+    assertFalse(codeSection.shadowRoot!
+                    .querySelector<HTMLElement>(
+                        '#line-numbers .more-code.before')!.hidden);
+    assertFalse(codeSection.shadowRoot!
+                    .querySelector<HTMLElement>(
+                        '#line-numbers .more-code.after')!.hidden);
+
+    codeSection.code = setCodeContent(2000, 0);
+    lineNums =
+        codeSection.shadowRoot!
+            .querySelector<HTMLElement>('#line-numbers span')!.textContent!;
+    // Length should be 1000 +- 1.
+    assertTrue(lineNums.split('\n').length >= 999);
+    assertTrue(lineNums.split('\n').length <= 1001);
+    assertFalse(!!lineNums.match(/^1\n/));
+    assertTrue(!!lineNums.match(/1002/));
+    assertTrue(!!lineNums.match(/2000/));
+    assertFalse(codeSection.shadowRoot!
+                    .querySelector<HTMLElement>(
+                        '#line-numbers .more-code.before')!.hidden);
+    assertTrue(codeSection.shadowRoot!
+                   .querySelector<HTMLElement>(
+                       '#line-numbers .more-code.after')!.hidden);
+  });
+});
diff --git a/chrome/test/data/webui/extensions/detail_view_test.js b/chrome/test/data/webui/extensions/detail_view_test.js
deleted file mode 100644
index b09c47a..0000000
--- a/chrome/test/data/webui/extensions/detail_view_test.js
+++ /dev/null
@@ -1,517 +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.
-
-/** @fileoverview Suite of tests for extensions-detail-view. */
-
-import {navigation, Page} from 'chrome://extensions/extensions.js';
-import {assert} from 'chrome://resources/js/assert.m.js';
-import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {isChildVisible, isVisible} from 'chrome://webui-test/test_util.js';
-
-import {createExtensionInfo, MockItemDelegate} from './test_util.js';
-
-window.extension_detail_view_tests = {};
-extension_detail_view_tests.suiteName = 'ExtensionDetailViewTest';
-/** @enum {string} */
-extension_detail_view_tests.TestNames = {
-  Layout: 'layout',
-  LayoutSource: 'layout of source section',
-  SupervisedUserDisableReasons: 'supervised user disable reasons',
-  ClickableElements: 'clickable elements',
-  Indicator: 'indicator',
-  Warnings: 'warnings',
-  NoSiteAccessWithEnhancedSiteControls:
-      'no site access with enhanced site controls',
-};
-
-suite(extension_detail_view_tests.suiteName, function() {
-  /**
-   * Extension item created before each test.
-   * @type {Item}
-   */
-  let item;
-
-  /**
-   * Backing extension data for the item.
-   * @type {chrome.developerPrivate.ExtensionInfo}
-   */
-  let extensionData;
-
-  /** @type {MockItemDelegate} */
-  let mockDelegate;
-
-  // Initialize an extension item before each test.
-  setup(function() {
-    document.body.innerHTML = '';
-    extensionData = createExtensionInfo({
-      incognitoAccess: {isEnabled: true, isActive: false},
-      fileAccess: {isEnabled: true, isActive: false},
-      errorCollection: {isEnabled: true, isActive: false},
-    });
-    mockDelegate = new MockItemDelegate();
-    item = document.createElement('extensions-detail-view');
-    item.set('data', extensionData);
-    item.set('delegate', mockDelegate);
-    item.set('inDevMode', false);
-    item.set('incognitoAvailable', true);
-    item.set('showActivityLog', false);
-    item.set('enableEnhancedSiteControls', false);
-    document.body.appendChild(item);
-  });
-
-  test(assert(extension_detail_view_tests.TestNames.Layout), function() {
-    flush();
-
-    const testIsVisible = isChildVisible.bind(null, item);
-    expectTrue(testIsVisible('#closeButton'));
-    expectTrue(testIsVisible('#icon'));
-    expectFalse(testIsVisible('#extensions-options'));
-    expectTrue(
-        item.$.description.textContent.indexOf('This is an extension') !== -1);
-
-    // Check the checkboxes visibility and state. They should be visible
-    // only if the associated option is enabled, and checked if the
-    // associated option is active.
-    const accessOptions = [
-      {key: 'incognitoAccess', id: '#allow-incognito'},
-      {key: 'fileAccess', id: '#allow-on-file-urls'},
-      {key: 'errorCollection', id: '#collect-errors'},
-    ];
-    const isChecked = id => item.shadowRoot.querySelector(id).checked;
-    for (let option of accessOptions) {
-      expectTrue(isChildVisible(item, option.id));
-      expectFalse(isChecked(option.id), option.id);
-      item.set('data.' + option.key + '.isEnabled', false);
-      flush();
-      expectFalse(isChildVisible(item, option.id));
-      item.set('data.' + option.key + '.isEnabled', true);
-      item.set('data.' + option.key + '.isActive', true);
-      flush();
-      expectTrue(isChildVisible(item, option.id));
-      expectTrue(isChecked(option.id));
-    }
-
-    expectFalse(testIsVisible('#dependent-extensions-list'));
-    item.set(
-        'data.dependentExtensions',
-        [{id: 'aaa', name: 'Dependent1'}, {id: 'bbb', name: 'Dependent2'}]);
-    flush();
-    expectTrue(testIsVisible('#dependent-extensions-list'));
-    expectEquals(
-        2,
-        item.shadowRoot.querySelector('#dependent-extensions-list')
-            .querySelectorAll('li')
-            .length);
-
-    expectFalse(testIsVisible('#permissions-list'));
-    expectFalse(testIsVisible('#host-access'));
-    expectFalse(testIsVisible('extensions-runtime-host-permissions'));
-
-    expectTrue(testIsVisible('#no-permissions'));
-    item.set(
-        'data.permissions',
-        {simplePermissions: ['Permission 1', 'Permission 2']});
-    flush();
-    expectTrue(testIsVisible('#permissions-list'));
-    expectEquals(
-        2,
-        item.shadowRoot.querySelector('#permissions-list')
-            .querySelectorAll('li:not([hidden])')
-            .length);
-    expectFalse(testIsVisible('#no-permissions'));
-    expectFalse(testIsVisible('#host-access'));
-    expectFalse(testIsVisible('extensions-runtime-host-permissions'));
-    // Reset state.
-    item.set('data.dependentExtensions', []);
-    item.set('data.permissions', {simplePermissions: []});
-    flush();
-
-    const optionsUrl =
-        'chrome-extension://' + extensionData.id + '/options.html';
-    item.set('data.optionsPage', {openInTab: true, url: optionsUrl});
-    expectTrue(testIsVisible('#extensions-options'));
-
-    expectFalse(testIsVisible('#extensionsActivityLogLink'));
-    item.set('showActivityLog', true);
-    flush();
-    expectTrue(testIsVisible('#extensionsActivityLogLink'));
-
-    item.set('data.manifestHomePageUrl', 'http://example.com');
-    flush();
-    expectTrue(testIsVisible('#extensionWebsite'));
-    item.set('data.manifestHomePageUrl', '');
-    flush();
-    expectFalse(testIsVisible('#extensionWebsite'));
-
-    item.set('data.webStoreUrl', 'http://example.com');
-    flush();
-    expectTrue(testIsVisible('#viewInStore'));
-    item.set('data.webStoreUrl', '');
-    flush();
-    expectFalse(testIsVisible('#viewInStore'));
-
-    expectFalse(testIsVisible('#id-section'));
-    expectFalse(testIsVisible('#inspectable-views'));
-
-    item.set('inDevMode', true);
-    flush();
-    expectTrue(testIsVisible('#id-section'));
-    expectTrue(testIsVisible('#inspectable-views'));
-
-    assertTrue(item.data.incognitoAccess.isEnabled);
-    item.set('incognitoAvailable', false);
-    flush();
-    expectFalse(testIsVisible('#allow-incognito'));
-
-    item.set('incognitoAvailable', true);
-    flush();
-    expectTrue(testIsVisible('#allow-incognito'));
-
-    // Ensure that the "Extension options" button is disabled when the item
-    // itself is disabled.
-    const extensionOptions =
-        item.shadowRoot.querySelector('#extensions-options');
-    assertFalse(extensionOptions.disabled);
-    item.set('data.state', chrome.developerPrivate.ExtensionState.DISABLED);
-    flush();
-    assertTrue(extensionOptions.disabled);
-
-    expectFalse(testIsVisible('.warning-icon'));
-    item.set('data.runtimeWarnings', ['Dummy warning']);
-    flush();
-    expectTrue(testIsVisible('.warning-icon'));
-
-    expectTrue(testIsVisible('#enableToggle'));
-    expectFalse(testIsVisible('#terminated-reload-button'));
-    item.set('data.state', chrome.developerPrivate.ExtensionState.TERMINATED);
-    flush();
-    expectFalse(testIsVisible('#enableToggle'));
-    expectTrue(testIsVisible('#terminated-reload-button'));
-
-    // Ensure that the runtime warning reload button is not visible if there
-    // are runtime warnings and the extension is terminated.
-    item.set('data.runtimeWarnings', ['Dummy warning']);
-    flush();
-    expectFalse(testIsVisible('#warnings-reload-button'));
-    item.set('data.runtimeWarnings', []);
-
-    // Reset item state back to DISABLED.
-    item.set('data.state', chrome.developerPrivate.ExtensionState.DISABLED);
-    flush();
-
-    // Ensure that without runtimeHostPermissions data, the sections are
-    // hidden.
-    expectTrue(testIsVisible('#no-site-access'));
-    expectFalse(testIsVisible('extensions-runtime-host-permissions'));
-    expectFalse(testIsVisible('extensions-host-permissions-toggle-list'));
-
-    // Adding any runtime host permissions should result in the runtime host
-    // controls becoming visible.
-    const allSitesPermissions = {
-      simplePermissions: [],
-      runtimeHostPermissions: {
-        hosts: [{granted: false, host: '<all_urls>'}],
-        hasAllHosts: true,
-        hostAccess: chrome.developerPrivate.HostAccess.ON_CLICK,
-      },
-    };
-    item.set('data.permissions', allSitesPermissions);
-    flush();
-    expectFalse(testIsVisible('#no-site-access'));
-    expectTrue(testIsVisible('extensions-runtime-host-permissions'));
-    expectFalse(testIsVisible('extensions-host-permissions-toggle-list'));
-
-    const someSitesPermissions = {
-      simplePermissions: [],
-      runtimeHostPermissions: {
-        hosts: [
-          {granted: true, host: 'https://chromium.org/*'},
-          {granted: false, host: 'https://example.com/*'}
-        ],
-        hasAllHosts: false,
-        hostAccess: chrome.developerPrivate.HostAccess.ON_SPECIFIC_SITES,
-      },
-    };
-    item.set('data.permissions', someSitesPermissions);
-    flush();
-    expectFalse(testIsVisible('#no-site-access'));
-    expectFalse(testIsVisible('extensions-runtime-host-permissions'));
-    expectTrue(testIsVisible('extensions-host-permissions-toggle-list'));
-  });
-
-  test(assert(extension_detail_view_tests.TestNames.LayoutSource), function() {
-    item.set('data.location', 'FROM_STORE');
-    flush();
-    assertEquals('Chrome Web Store', item.$.source.textContent.trim());
-    assertFalse(isChildVisible(item, '#load-path'));
-
-    item.set('data.location', 'THIRD_PARTY');
-    flush();
-    assertEquals('Added by a third-party', item.$.source.textContent.trim());
-    assertFalse(isChildVisible(item, '#load-path'));
-
-    item.set('data.location', 'UNPACKED');
-    item.set('data.prettifiedPath', 'foo/bar/baz/');
-    flush();
-    assertEquals('Unpacked extension', item.$.source.textContent.trim());
-    // Test whether the load path is displayed for unpacked extensions.
-    assertTrue(isChildVisible(item, '#load-path'));
-
-    item.set('data.location', 'UNKNOWN');
-    item.set('data.prettifiedPath', '');
-    // |locationText| is expected to always be set if location is UNKNOWN.
-    item.set('data.locationText', 'Foo');
-    flush();
-    assertEquals('Foo', item.$.source.textContent.trim());
-    assertFalse(isChildVisible(item, '#load-path'));
-  });
-
-  test(
-      assert(
-          extension_detail_view_tests.TestNames.SupervisedUserDisableReasons),
-      function() {
-        flush();
-        const toggle = item.shadowRoot.querySelector('#enableToggle');
-        const tooltip =
-            item.shadowRoot.querySelector('#parentDisabledPermissionsToolTip');
-        expectTrue(isVisible(toggle));
-        expectFalse(isVisible(tooltip));
-
-        // This section tests that the enable toggle is visible but disabled
-        // when disableReasons.blockedByPolicy is true. This test prevents a
-        // regression to crbug/1003014.
-        item.set('data.disableReasons.blockedByPolicy', true);
-        flush();
-        expectTrue(isVisible(toggle));
-        expectTrue(toggle.disabled);
-        item.set('data.disableReasons.blockedByPolicy', false);
-        flush();
-
-        item.set('data.disableReasons.parentDisabledPermissions', true);
-        flush();
-        expectTrue(isVisible(toggle));
-        expectFalse(toggle.disabled);
-        expectTrue(isVisible(tooltip));
-        item.set('data.disableReasons.parentDisabledPermissions', false);
-        flush();
-
-        item.set('data.disableReasons.custodianApprovalRequired', true);
-        flush();
-        expectTrue(isVisible(toggle));
-        expectFalse(toggle.disabled);
-        item.set('data.disableReasons.custodianApprovalRequired', false);
-        flush();
-      });
-
-  test(
-      assert(extension_detail_view_tests.TestNames.ClickableElements),
-      function() {
-        const optionsUrl =
-            'chrome-extension://' + extensionData.id + '/options.html';
-        item.set('data.optionsPage', {openInTab: true, url: optionsUrl});
-        item.set('data.prettifiedPath', 'foo/bar/baz/');
-        item.set('showActivityLog', true);
-        flush();
-
-        let currentPage = null;
-        navigation.addListener(newPage => {
-          currentPage = newPage;
-        });
-
-        // Even though the command line flag is not set for activity log, we
-        // still expect to navigate to it after clicking the link as the logic
-        // to redirect the page back to the details view is in manager.js. Since
-        // this behavior does not happen in the testing environment, we test the
-        // behavior in manager_test.js.
-        item.shadowRoot.querySelector('#extensionsActivityLogLink').click();
-        expectDeepEquals(
-            currentPage,
-            {page: Page.ACTIVITY_LOG, extensionId: extensionData.id});
-
-        // Reset current page and test delegate calls.
-        navigation.navigateTo(
-            {page: Page.DETAILS, extensionId: extensionData.id});
-        currentPage = null;
-
-        mockDelegate.testClickingCalls(
-            item.shadowRoot.querySelector('#allow-incognito').getLabel(),
-            'setItemAllowedIncognito', [extensionData.id, true]);
-        mockDelegate.testClickingCalls(
-            item.shadowRoot.querySelector('#allow-on-file-urls').getLabel(),
-            'setItemAllowedOnFileUrls', [extensionData.id, true]);
-        mockDelegate.testClickingCalls(
-            item.shadowRoot.querySelector('#collect-errors').getLabel(),
-            'setItemCollectsErrors', [extensionData.id, true]);
-        mockDelegate.testClickingCalls(
-            item.shadowRoot.querySelector('#extensions-options'),
-            'showItemOptionsPage', [extensionData]);
-        mockDelegate.testClickingCalls(
-            item.shadowRoot.querySelector('#remove-extension'), 'deleteItem',
-            [extensionData.id]);
-        mockDelegate.testClickingCalls(
-            item.shadowRoot.querySelector('#load-path > a[is=\'action-link\']'),
-            'showInFolder', [extensionData.id]);
-        mockDelegate.testClickingCalls(
-            item.shadowRoot.querySelector('#warnings-reload-button'),
-            'reloadItem', [extensionData.id], Promise.resolve());
-
-        // Terminate the extension so the reload button appears.
-        item.set(
-            'data.state', chrome.developerPrivate.ExtensionState.TERMINATED);
-        flush();
-        mockDelegate.testClickingCalls(
-            item.shadowRoot.querySelector('#terminated-reload-button'),
-            'reloadItem', [extensionData.id], Promise.resolve());
-      });
-
-  test(assert(extension_detail_view_tests.TestNames.Indicator), function() {
-    const indicator = item.shadowRoot.querySelector('cr-tooltip-icon');
-    expectTrue(indicator.hidden);
-    item.set('data.controlledInfo', {text: 'policy'});
-    flush();
-    expectFalse(indicator.hidden);
-  });
-
-  test(assert(extension_detail_view_tests.TestNames.Warnings), function() {
-    const testWarningVisible = function(id, expectVisible) {
-      const f = expectVisible ? expectTrue : expectFalse;
-      f(isChildVisible(item, id));
-    };
-
-    testWarningVisible('#runtime-warnings', false);
-    testWarningVisible('#corrupted-warning', false);
-    testWarningVisible('#suspicious-warning', false);
-    testWarningVisible('#blacklisted-warning', false);
-    testWarningVisible('#update-required-warning', false);
-
-    item.set('data.runtimeWarnings', ['Dummy warning']);
-    flush();
-    testWarningVisible('#runtime-warnings', true);
-    testWarningVisible('#corrupted-warning', false);
-    testWarningVisible('#suspicious-warning', false);
-    testWarningVisible('#blacklisted-warning', false);
-    testWarningVisible('#update-required-warning', false);
-
-    item.set('data.disableReasons.corruptInstall', true);
-    flush();
-    testWarningVisible('#runtime-warnings', true);
-    testWarningVisible('#corrupted-warning', true);
-    testWarningVisible('#suspicious-warning', false);
-    testWarningVisible('#blacklisted-warning', false);
-    testWarningVisible('#update-required-warning', false);
-    const testIsVisible = isChildVisible.bind(null, item);
-    expectTrue(testIsVisible('#enableToggle'));
-
-    item.set('data.disableReasons.suspiciousInstall', true);
-    flush();
-    testWarningVisible('#runtime-warnings', true);
-    testWarningVisible('#corrupted-warning', true);
-    testWarningVisible('#suspicious-warning', true);
-    testWarningVisible('#blacklisted-warning', false);
-    testWarningVisible('#update-required-warning', false);
-
-    item.set('data.blacklistText', 'This item is blocklisted');
-    flush();
-    testWarningVisible('#runtime-warnings', true);
-    testWarningVisible('#corrupted-warning', true);
-    testWarningVisible('#suspicious-warning', true);
-    testWarningVisible('#blacklisted-warning', true);
-    testWarningVisible('#update-required-warning', false);
-
-    item.set('data.blacklistText', null);
-    flush();
-    testWarningVisible('#runtime-warnings', true);
-    testWarningVisible('#corrupted-warning', true);
-    testWarningVisible('#suspicious-warning', true);
-    testWarningVisible('#blacklisted-warning', false);
-    testWarningVisible('#update-required-warning', false);
-
-    item.set('data.disableReasons.updateRequired', true);
-    flush();
-    testWarningVisible('#runtime-warnings', true);
-    testWarningVisible('#corrupted-warning', true);
-    testWarningVisible('#suspicious-warning', true);
-    testWarningVisible('#blacklisted-warning', false);
-    testWarningVisible('#update-required-warning', true);
-
-    item.set('data.runtimeWarnings', []);
-    item.set('data.disableReasons.corruptInstall', false);
-    item.set('data.disableReasons.suspiciousInstall', false);
-    item.set('data.disableReasons.updateRequired', false);
-    flush();
-    testWarningVisible('#runtime-warnings', false);
-    testWarningVisible('#corrupted-warning', false);
-    testWarningVisible('#suspicious-warning', false);
-    testWarningVisible('#blacklisted-warning', false);
-    testWarningVisible('#update-required-warning', false);
-
-    item.set('data.showSafeBrowsingAllowlistWarning', true);
-    flush();
-    testWarningVisible('#runtime-warnings', false);
-    testWarningVisible('#corrupted-warning', false);
-    testWarningVisible('#suspicious-warning', false);
-    testWarningVisible('#blacklisted-warning', false);
-    testWarningVisible('#update-required-warning', false);
-    testWarningVisible('#allowlist-warning', true);
-
-    item.set('data.disableReasons.suspiciousInstall', true);
-    flush();
-    testWarningVisible('#runtime-warnings', false);
-    testWarningVisible('#corrupted-warning', false);
-    testWarningVisible('#suspicious-warning', true);
-    testWarningVisible('#blacklisted-warning', false);
-    testWarningVisible('#update-required-warning', false);
-    testWarningVisible('#allowlist-warning', true);
-
-    // Test that the allowlist warning is not shown when there is already a
-    // blocklist message. It would be redundant since all blocklisted extension
-    // are necessarily not included in the Safe Browsing allowlist.
-    item.set('data.blacklistText', 'This item is blocklisted');
-    flush();
-    testWarningVisible('#runtime-warnings', false);
-    testWarningVisible('#corrupted-warning', false);
-    testWarningVisible('#suspicious-warning', true);
-    testWarningVisible('#blacklisted-warning', true);
-    testWarningVisible('#update-required-warning', false);
-    testWarningVisible('#allowlist-warning', false);
-  });
-
-  test(
-      assert(extension_detail_view_tests.TestNames
-                 .NoSiteAccessWithEnhancedSiteControls),
-      function() {
-        const testIsVisible = isChildVisible.bind(null, item);
-
-        // Ensure that if the enableEnhancedSiteControls flag is enabled, then
-        // the no site access message is in the permissions section and not in
-        // the site access section.
-        item.set('data.dependentExtensions', []);
-        item.set('data.permissions', {simplePermissions: []});
-        item.enableEnhancedSiteControls = true;
-        flush();
-
-        expectTrue(testIsVisible('#no-permissions'));
-        expectTrue(item.$['no-permissions'].textContent.includes(
-            loadTimeData.getString('itemPermissionsAndSiteAccessEmpty')));
-        expectFalse(testIsVisible('#no-site-access'));
-
-        item.set(
-            'data.permissions',
-            {simplePermissions: ['Permission 1', 'Permission 2']});
-        flush();
-
-        // The permissions list should contain the above 2 permissions as well
-        // as an item for no additional site permissions.
-        expectTrue(testIsVisible('#permissions-list'));
-        expectEquals(
-            3,
-            item.shadowRoot.querySelector('#permissions-list')
-                .querySelectorAll('li:not([hidden])')
-                .length);
-        expectFalse(testIsVisible('#no-permissions'));
-        expectTrue(testIsVisible('#permissions-list li:last-of-type'));
-      });
-});
diff --git a/chrome/test/data/webui/extensions/detail_view_test.ts b/chrome/test/data/webui/extensions/detail_view_test.ts
new file mode 100644
index 0000000..fdb6ecb
--- /dev/null
+++ b/chrome/test/data/webui/extensions/detail_view_test.ts
@@ -0,0 +1,523 @@
+// 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.
+
+/** @fileoverview Suite of tests for extensions-detail-view. */
+
+import {CrCheckboxElement, ExtensionsDetailViewElement, ExtensionsToggleRowElement, navigation, Page} from 'chrome://extensions/extensions.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {isChildVisible, isVisible} from 'chrome://webui-test/test_util.js';
+
+import {createExtensionInfo, MockItemDelegate} from './test_util.js';
+
+const extension_detail_view_tests = {
+  suiteName: 'ExtensionDetailViewTest',
+  TestNames: {
+    Layout: 'layout',
+    LayoutSource: 'layout of source section',
+    SupervisedUserDisableReasons: 'supervised user disable reasons',
+    ClickableElements: 'clickable elements',
+    Indicator: 'indicator',
+    Warnings: 'warnings',
+    NoSiteAccessWithEnhancedSiteControls:
+        'no site access with enhanced site controls',
+  },
+};
+
+Object.assign(
+    window, {extension_detail_view_tests: extension_detail_view_tests});
+
+suite(extension_detail_view_tests.suiteName, function() {
+  /** Extension item created before each test. */
+  let item: ExtensionsDetailViewElement;
+
+  /** Backing extension data for the item. */
+  let extensionData: chrome.developerPrivate.ExtensionInfo;
+
+  let mockDelegate: MockItemDelegate;
+
+  // Initialize an extension item before each test.
+  setup(function() {
+    document.body.innerHTML = '';
+    extensionData = createExtensionInfo({
+      incognitoAccess: {isEnabled: true, isActive: false},
+      fileAccess: {isEnabled: true, isActive: false},
+      errorCollection: {isEnabled: true, isActive: false},
+    });
+    mockDelegate = new MockItemDelegate();
+    item = document.createElement('extensions-detail-view');
+    item.set('data', extensionData);
+    item.set('delegate', mockDelegate);
+    item.set('inDevMode', false);
+    item.set('incognitoAvailable', true);
+    item.set('showActivityLog', false);
+    item.set('enableEnhancedSiteControls', false);
+    document.body.appendChild(item);
+  });
+
+  test(assert(extension_detail_view_tests.TestNames.Layout), function() {
+    flush();
+
+    const testIsVisible: (selector: string) => boolean =
+        isChildVisible.bind(null, item);
+    assertTrue(testIsVisible('#closeButton'));
+    assertTrue(testIsVisible('#icon'));
+    assertFalse(testIsVisible('#extensionsOptions'));
+    assertTrue(
+        item.$.description.textContent!.indexOf('This is an extension') !== -1);
+
+    // Check the checkboxes visibility and state. They should be visible
+    // only if the associated option is enabled, and checked if the
+    // associated option is active.
+    const accessOptions = [
+      {key: 'incognitoAccess', id: '#allow-incognito'},
+      {key: 'fileAccess', id: '#allow-on-file-urls'},
+      {key: 'errorCollection', id: '#collect-errors'},
+    ];
+    const isChecked = (id: string) =>
+        item.shadowRoot!.querySelector<CrCheckboxElement>(id)!.checked;
+    for (let option of accessOptions) {
+      assertTrue(isChildVisible(item, option.id));
+      assertFalse(isChecked(option.id), option.id);
+      item.set('data.' + option.key + '.isEnabled', false);
+      flush();
+      assertFalse(isChildVisible(item, option.id));
+      item.set('data.' + option.key + '.isEnabled', true);
+      item.set('data.' + option.key + '.isActive', true);
+      flush();
+      assertTrue(isChildVisible(item, option.id));
+      assertTrue(isChecked(option.id));
+    }
+
+    assertFalse(testIsVisible('#dependent-extensions-list'));
+    item.set(
+        'data.dependentExtensions',
+        [{id: 'aaa', name: 'Dependent1'}, {id: 'bbb', name: 'Dependent2'}]);
+    flush();
+    assertTrue(testIsVisible('#dependent-extensions-list'));
+    assertEquals(
+        2,
+        item.shadowRoot!.querySelector('#dependent-extensions-list')!
+            .querySelectorAll('li')
+            .length);
+
+    assertFalse(testIsVisible('#permissions-list'));
+    assertFalse(testIsVisible('#host-access'));
+    assertFalse(testIsVisible('extensions-runtime-host-permissions'));
+
+    assertTrue(testIsVisible('#no-permissions'));
+    item.set(
+        'data.permissions',
+        {simplePermissions: ['Permission 1', 'Permission 2']});
+    flush();
+    assertTrue(testIsVisible('#permissions-list'));
+    assertEquals(
+        2,
+        item.shadowRoot!.querySelector('#permissions-list')!
+            .querySelectorAll('li:not([hidden])')
+            .length);
+    assertFalse(testIsVisible('#no-permissions'));
+    assertFalse(testIsVisible('#host-access'));
+    assertFalse(testIsVisible('extensions-runtime-host-permissions'));
+    // Reset state.
+    item.set('data.dependentExtensions', []);
+    item.set('data.permissions', {simplePermissions: []});
+    flush();
+
+    const optionsUrl =
+        'chrome-extension://' + extensionData.id + '/options.html';
+    item.set('data.optionsPage', {openInTab: true, url: optionsUrl});
+    assertTrue(testIsVisible('#extensionsOptions'));
+
+    assertFalse(testIsVisible('#extensionsActivityLogLink'));
+    item.set('showActivityLog', true);
+    flush();
+    assertTrue(testIsVisible('#extensionsActivityLogLink'));
+
+    item.set('data.manifestHomePageUrl', 'http://example.com');
+    flush();
+    assertTrue(testIsVisible('#extensionWebsite'));
+    item.set('data.manifestHomePageUrl', '');
+    flush();
+    assertFalse(testIsVisible('#extensionWebsite'));
+
+    item.set('data.webStoreUrl', 'http://example.com');
+    flush();
+    assertTrue(testIsVisible('#viewInStore'));
+    item.set('data.webStoreUrl', '');
+    flush();
+    assertFalse(testIsVisible('#viewInStore'));
+
+    assertFalse(testIsVisible('#id-section'));
+    assertFalse(testIsVisible('#inspectable-views'));
+
+    item.set('inDevMode', true);
+    flush();
+    assertTrue(testIsVisible('#id-section'));
+    assertTrue(testIsVisible('#inspectable-views'));
+
+    assertTrue(item.data.incognitoAccess.isEnabled);
+    item.set('incognitoAvailable', false);
+    flush();
+    assertFalse(testIsVisible('#allow-incognito'));
+
+    item.set('incognitoAvailable', true);
+    flush();
+    assertTrue(testIsVisible('#allow-incognito'));
+
+    // Ensure that the "Extension options" button is disabled when the item
+    // itself is disabled.
+    const extensionOptions = item.$.extensionsOptions;
+    assertFalse(extensionOptions.disabled);
+    item.set('data.state', chrome.developerPrivate.ExtensionState.DISABLED);
+    flush();
+    assertTrue(extensionOptions.disabled);
+
+    assertFalse(testIsVisible('.warning-icon'));
+    item.set('data.runtimeWarnings', ['Dummy warning']);
+    flush();
+    assertTrue(testIsVisible('.warning-icon'));
+
+    assertTrue(testIsVisible('#enableToggle'));
+    assertFalse(testIsVisible('#terminated-reload-button'));
+    item.set('data.state', chrome.developerPrivate.ExtensionState.TERMINATED);
+    flush();
+    assertFalse(testIsVisible('#enableToggle'));
+    assertTrue(testIsVisible('#terminated-reload-button'));
+
+    // Ensure that the runtime warning reload button is not visible if there
+    // are runtime warnings and the extension is terminated.
+    item.set('data.runtimeWarnings', ['Dummy warning']);
+    flush();
+    assertFalse(testIsVisible('#warnings-reload-button'));
+    item.set('data.runtimeWarnings', []);
+
+    // Reset item state back to DISABLED.
+    item.set('data.state', chrome.developerPrivate.ExtensionState.DISABLED);
+    flush();
+
+    // Ensure that without runtimeHostPermissions data, the sections are
+    // hidden.
+    assertTrue(testIsVisible('#no-site-access'));
+    assertFalse(testIsVisible('extensions-runtime-host-permissions'));
+    assertFalse(testIsVisible('extensions-host-permissions-toggle-list'));
+
+    // Adding any runtime host permissions should result in the runtime host
+    // controls becoming visible.
+    const allSitesPermissions = {
+      simplePermissions: [],
+      runtimeHostPermissions: {
+        hosts: [{granted: false, host: '<all_urls>'}],
+        hasAllHosts: true,
+        hostAccess: chrome.developerPrivate.HostAccess.ON_CLICK,
+      },
+    };
+    item.set('data.permissions', allSitesPermissions);
+    flush();
+    assertFalse(testIsVisible('#no-site-access'));
+    assertTrue(testIsVisible('extensions-runtime-host-permissions'));
+    assertFalse(testIsVisible('extensions-host-permissions-toggle-list'));
+
+    const someSitesPermissions = {
+      simplePermissions: [],
+      runtimeHostPermissions: {
+        hosts: [
+          {granted: true, host: 'https://chromium.org/*'},
+          {granted: false, host: 'https://example.com/*'}
+        ],
+        hasAllHosts: false,
+        hostAccess: chrome.developerPrivate.HostAccess.ON_SPECIFIC_SITES,
+      },
+    };
+    item.set('data.permissions', someSitesPermissions);
+    flush();
+    assertFalse(testIsVisible('#no-site-access'));
+    assertFalse(testIsVisible('extensions-runtime-host-permissions'));
+    assertTrue(testIsVisible('extensions-host-permissions-toggle-list'));
+  });
+
+  test(assert(extension_detail_view_tests.TestNames.LayoutSource), function() {
+    item.set('data.location', 'FROM_STORE');
+    flush();
+    assertEquals('Chrome Web Store', item.$.source.textContent!.trim());
+    assertFalse(isChildVisible(item, '#load-path'));
+
+    item.set('data.location', 'THIRD_PARTY');
+    flush();
+    assertEquals('Added by a third-party', item.$.source.textContent!.trim());
+    assertFalse(isChildVisible(item, '#load-path'));
+
+    item.set('data.location', 'UNPACKED');
+    item.set('data.prettifiedPath', 'foo/bar/baz/');
+    flush();
+    assertEquals('Unpacked extension', item.$.source.textContent!.trim());
+    // Test whether the load path is displayed for unpacked extensions.
+    assertTrue(isChildVisible(item, '#load-path'));
+
+    item.set('data.location', 'UNKNOWN');
+    item.set('data.prettifiedPath', '');
+    // |locationText| is expected to always be set if location is UNKNOWN.
+    item.set('data.locationText', 'Foo');
+    flush();
+    assertEquals('Foo', item.$.source.textContent!.trim());
+    assertFalse(isChildVisible(item, '#load-path'));
+  });
+
+  test(
+      assert(
+          extension_detail_view_tests.TestNames.SupervisedUserDisableReasons),
+      function() {
+        flush();
+        const toggle = item.$.enableToggle;
+        const tooltip = item.$.parentDisabledPermissionsToolTip;
+        assertTrue(isVisible(toggle));
+        assertFalse(isVisible(tooltip));
+
+        // This section tests that the enable toggle is visible but disabled
+        // when disableReasons.blockedByPolicy is true. This test prevents a
+        // regression to crbug/1003014.
+        item.set('data.disableReasons.blockedByPolicy', true);
+        flush();
+        assertTrue(isVisible(toggle));
+        assertTrue(toggle.disabled);
+        item.set('data.disableReasons.blockedByPolicy', false);
+        flush();
+
+        item.set('data.disableReasons.parentDisabledPermissions', true);
+        flush();
+        assertTrue(isVisible(toggle));
+        assertFalse(toggle.disabled);
+        assertTrue(isVisible(tooltip));
+        item.set('data.disableReasons.parentDisabledPermissions', false);
+        flush();
+
+        item.set('data.disableReasons.custodianApprovalRequired', true);
+        flush();
+        assertTrue(isVisible(toggle));
+        assertFalse(toggle.disabled);
+        item.set('data.disableReasons.custodianApprovalRequired', false);
+        flush();
+      });
+
+  test(
+      assert(extension_detail_view_tests.TestNames.ClickableElements),
+      function() {
+        const optionsUrl =
+            'chrome-extension://' + extensionData.id + '/options.html';
+        item.set('data.optionsPage', {openInTab: true, url: optionsUrl});
+        item.set('data.prettifiedPath', 'foo/bar/baz/');
+        item.set('showActivityLog', true);
+        flush();
+
+        let currentPage = null;
+        navigation.addListener(newPage => {
+          currentPage = newPage;
+        });
+
+        // Even though the command line flag is not set for activity log, we
+        // still expect to navigate to it after clicking the link as the logic
+        // to redirect the page back to the details view is in manager.js. Since
+        // this behavior does not happen in the testing environment, we test the
+        // behavior in manager_test.js.
+        item.$.extensionsActivityLogLink.click();
+        assertDeepEquals(
+            currentPage,
+            {page: Page.ACTIVITY_LOG, extensionId: extensionData.id});
+
+        // Reset current page and test delegate calls.
+        navigation.navigateTo(
+            {page: Page.DETAILS, extensionId: extensionData.id});
+        currentPage = null;
+
+        mockDelegate.testClickingCalls(
+            item.shadowRoot!
+                .querySelector<ExtensionsToggleRowElement>(
+                    '#allow-incognito')!.getLabel(),
+            'setItemAllowedIncognito', [extensionData.id, true]);
+        mockDelegate.testClickingCalls(
+            item.shadowRoot!
+                .querySelector<ExtensionsToggleRowElement>(
+                    '#allow-on-file-urls')!.getLabel(),
+            'setItemAllowedOnFileUrls', [extensionData.id, true]);
+        mockDelegate.testClickingCalls(
+            item.shadowRoot!
+                .querySelector<ExtensionsToggleRowElement>(
+                    '#collect-errors')!.getLabel(),
+            'setItemCollectsErrors', [extensionData.id, true]);
+        mockDelegate.testClickingCalls(
+            item.$.extensionsOptions, 'showItemOptionsPage', [extensionData]);
+        mockDelegate.testClickingCalls(
+            item.shadowRoot!.querySelector('#remove-extension')!, 'deleteItem',
+            [extensionData.id]);
+        mockDelegate.testClickingCalls(
+            item.shadowRoot!.querySelector(
+                '#load-path > a[is=\'action-link\']')!,
+            'showInFolder', [extensionData.id]);
+        mockDelegate.testClickingCalls(
+            item.shadowRoot!.querySelector('#warnings-reload-button')!,
+            'reloadItem', [extensionData.id], Promise.resolve());
+
+        // Terminate the extension so the reload button appears.
+        item.set(
+            'data.state', chrome.developerPrivate.ExtensionState.TERMINATED);
+        flush();
+        mockDelegate.testClickingCalls(
+            item.shadowRoot!.querySelector('#terminated-reload-button')!,
+            'reloadItem', [extensionData.id], Promise.resolve());
+      });
+
+  test(assert(extension_detail_view_tests.TestNames.Indicator), function() {
+    const indicator = item.shadowRoot!.querySelector('cr-tooltip-icon')!;
+    assertTrue(indicator.hidden);
+    item.set('data.controlledInfo', {text: 'policy'});
+    flush();
+    assertFalse(indicator.hidden);
+  });
+
+  test(assert(extension_detail_view_tests.TestNames.Warnings), function() {
+    function testWarningVisible(id: string, expectVisible: boolean): void {
+      const f: (arg: boolean) => void =
+          expectVisible ? assertTrue : assertFalse;
+      f(isChildVisible(item, id));
+    }
+
+    testWarningVisible('#runtime-warnings', false);
+    testWarningVisible('#corrupted-warning', false);
+    testWarningVisible('#suspicious-warning', false);
+    testWarningVisible('#blacklisted-warning', false);
+    testWarningVisible('#update-required-warning', false);
+
+    item.set('data.runtimeWarnings', ['Dummy warning']);
+    flush();
+    testWarningVisible('#runtime-warnings', true);
+    testWarningVisible('#corrupted-warning', false);
+    testWarningVisible('#suspicious-warning', false);
+    testWarningVisible('#blacklisted-warning', false);
+    testWarningVisible('#update-required-warning', false);
+
+    item.set('data.disableReasons.corruptInstall', true);
+    flush();
+    testWarningVisible('#runtime-warnings', true);
+    testWarningVisible('#corrupted-warning', true);
+    testWarningVisible('#suspicious-warning', false);
+    testWarningVisible('#blacklisted-warning', false);
+    testWarningVisible('#update-required-warning', false);
+    const testIsVisible = isChildVisible.bind(null, item);
+    assertTrue(testIsVisible('#enableToggle'));
+
+    item.set('data.disableReasons.suspiciousInstall', true);
+    flush();
+    testWarningVisible('#runtime-warnings', true);
+    testWarningVisible('#corrupted-warning', true);
+    testWarningVisible('#suspicious-warning', true);
+    testWarningVisible('#blacklisted-warning', false);
+    testWarningVisible('#update-required-warning', false);
+
+    item.set('data.blacklistText', 'This item is blocklisted');
+    flush();
+    testWarningVisible('#runtime-warnings', true);
+    testWarningVisible('#corrupted-warning', true);
+    testWarningVisible('#suspicious-warning', true);
+    testWarningVisible('#blacklisted-warning', true);
+    testWarningVisible('#update-required-warning', false);
+
+    item.set('data.blacklistText', null);
+    flush();
+    testWarningVisible('#runtime-warnings', true);
+    testWarningVisible('#corrupted-warning', true);
+    testWarningVisible('#suspicious-warning', true);
+    testWarningVisible('#blacklisted-warning', false);
+    testWarningVisible('#update-required-warning', false);
+
+    item.set('data.disableReasons.updateRequired', true);
+    flush();
+    testWarningVisible('#runtime-warnings', true);
+    testWarningVisible('#corrupted-warning', true);
+    testWarningVisible('#suspicious-warning', true);
+    testWarningVisible('#blacklisted-warning', false);
+    testWarningVisible('#update-required-warning', true);
+
+    item.set('data.runtimeWarnings', []);
+    item.set('data.disableReasons.corruptInstall', false);
+    item.set('data.disableReasons.suspiciousInstall', false);
+    item.set('data.disableReasons.updateRequired', false);
+    flush();
+    testWarningVisible('#runtime-warnings', false);
+    testWarningVisible('#corrupted-warning', false);
+    testWarningVisible('#suspicious-warning', false);
+    testWarningVisible('#blacklisted-warning', false);
+    testWarningVisible('#update-required-warning', false);
+
+    item.set('data.showSafeBrowsingAllowlistWarning', true);
+    flush();
+    testWarningVisible('#runtime-warnings', false);
+    testWarningVisible('#corrupted-warning', false);
+    testWarningVisible('#suspicious-warning', false);
+    testWarningVisible('#blacklisted-warning', false);
+    testWarningVisible('#update-required-warning', false);
+    testWarningVisible('#allowlist-warning', true);
+
+    item.set('data.disableReasons.suspiciousInstall', true);
+    flush();
+    testWarningVisible('#runtime-warnings', false);
+    testWarningVisible('#corrupted-warning', false);
+    testWarningVisible('#suspicious-warning', true);
+    testWarningVisible('#blacklisted-warning', false);
+    testWarningVisible('#update-required-warning', false);
+    testWarningVisible('#allowlist-warning', true);
+
+    // Test that the allowlist warning is not shown when there is already a
+    // blocklist message. It would be redundant since all blocklisted extension
+    // are necessarily not included in the Safe Browsing allowlist.
+    item.set('data.blacklistText', 'This item is blocklisted');
+    flush();
+    testWarningVisible('#runtime-warnings', false);
+    testWarningVisible('#corrupted-warning', false);
+    testWarningVisible('#suspicious-warning', true);
+    testWarningVisible('#blacklisted-warning', true);
+    testWarningVisible('#update-required-warning', false);
+    testWarningVisible('#allowlist-warning', false);
+  });
+
+  test(
+      assert(extension_detail_view_tests.TestNames
+                 .NoSiteAccessWithEnhancedSiteControls),
+      function() {
+        const testIsVisible = isChildVisible.bind(null, item);
+
+        // Ensure that if the enableEnhancedSiteControls flag is enabled, then
+        // the no site access message is in the permissions section and not in
+        // the site access section.
+        item.set('data.dependentExtensions', []);
+        item.set('data.permissions', {simplePermissions: []});
+        item.enableEnhancedSiteControls = true;
+        flush();
+
+        assertTrue(testIsVisible('#no-permissions'));
+        assertTrue(
+            item.shadowRoot!.querySelector<HTMLElement>('#no-permissions')!
+                .textContent!.includes(loadTimeData.getString(
+                    'itemPermissionsAndSiteAccessEmpty')));
+        assertFalse(testIsVisible('#no-site-access'));
+
+        item.set(
+            'data.permissions',
+            {simplePermissions: ['Permission 1', 'Permission 2']});
+        flush();
+
+        // The permissions list should contain the above 2 permissions as well
+        // as an item for no additional site permissions.
+        assertTrue(testIsVisible('#permissions-list'));
+        assertEquals(
+            3,
+            item.shadowRoot!.querySelector('#permissions-list')!
+                .querySelectorAll('li:not([hidden])')
+                .length);
+        assertFalse(testIsVisible('#no-permissions'));
+        assertTrue(testIsVisible('#permissions-list li:last-of-type'));
+      });
+});
diff --git a/chrome/test/data/webui/extensions/error_console_test.js b/chrome/test/data/webui/extensions/error_console_test.js
deleted file mode 100644
index 0802583..0000000
--- a/chrome/test/data/webui/extensions/error_console_test.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 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.
-
-import 'chrome://extensions/extensions.js';
-
-import {keyDownOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
-
-import {eventToPromise, waitBeforeNextRender} from 'chrome://webui-test/test_util.js';
-
-import {findMatches} from './test_util.js';
-
-/** @fileoverview Suite of tests for the extensions error console. */
-suite('CrExtensionsErrorConsoleTest', function() {
-  const STACK_ERRORS = 'li';
-  const ACTIVE_ERROR_IN_STACK = 'li[tabindex="0"]';
-
-  // Initialize an extension activity log item before each test.
-  setup(function() {
-    document.body.innerHTML = '';
-    window.history.replaceState(
-        {}, '', '?errors=oehidglfoeondlkoeloailjdmmghacge');
-    const manager = document.createElement('extensions-manager');
-    document.body.appendChild(manager);
-    // Wait for the first view to be active before starting tests.
-    return manager.$.viewManager.querySelector('.active') ?
-        Promise.resolve() :
-        eventToPromise('view-enter-start', manager);
-  });
-
-  test('TestUpDownErrors', function() {
-    let initialFocus = findMatches(document, ACTIVE_ERROR_IN_STACK)[0];
-    assertTrue(!!initialFocus);
-    assertEquals(1, findMatches(document, ACTIVE_ERROR_IN_STACK).length);
-    assertEquals(4, findMatches(document, STACK_ERRORS).length);
-
-    // Pressing up when the first item is focused should NOT change focus.
-    keyDownOn(initialFocus, 38, '', 'ArrowUp');
-    assertEquals(initialFocus, findMatches(document, ACTIVE_ERROR_IN_STACK)[0]);
-
-    // Pressing down when the first item is focused should change focus.
-    keyDownOn(initialFocus, 40, '', 'ArrowDown');
-    assertNotEquals(
-        initialFocus, findMatches(document, ACTIVE_ERROR_IN_STACK)[0]);
-
-    // Pressing up when the second item is focused should focus the first again.
-    keyDownOn(initialFocus, 38, '', 'ArrowUp');
-    assertEquals(initialFocus, findMatches(document, ACTIVE_ERROR_IN_STACK)[0]);
-  });
-});
diff --git a/chrome/test/data/webui/extensions/error_console_test.ts b/chrome/test/data/webui/extensions/error_console_test.ts
new file mode 100644
index 0000000..5128591
--- /dev/null
+++ b/chrome/test/data/webui/extensions/error_console_test.ts
@@ -0,0 +1,50 @@
+// Copyright 2019 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.
+
+import 'chrome://extensions/extensions.js';
+
+import {keyDownOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
+import {assertEquals, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {eventToPromise} from 'chrome://webui-test/test_util.js';
+
+import {findMatches} from './test_util.js';
+
+/** @fileoverview Suite of tests for the extensions error console. */
+suite('CrExtensionsErrorConsoleTest', function() {
+  const STACK_ERRORS: string = 'li';
+  const ACTIVE_ERROR_IN_STACK: string = 'li[tabindex="0"]';
+
+  // Initialize an extension activity log item before each test.
+  setup(function() {
+    document.body.innerHTML = '';
+    window.history.replaceState(
+        {}, '', '?errors=oehidglfoeondlkoeloailjdmmghacge');
+    const manager = document.createElement('extensions-manager');
+    document.body.appendChild(manager);
+    // Wait for the first view to be active before starting tests.
+    return manager.$.viewManager.querySelector('.active') ?
+        Promise.resolve() :
+        eventToPromise('view-enter-start', manager);
+  });
+
+  test('TestUpDownErrors', function() {
+    let initialFocus = findMatches(document, ACTIVE_ERROR_IN_STACK)[0];
+    assertTrue(!!initialFocus);
+    assertEquals(1, findMatches(document, ACTIVE_ERROR_IN_STACK).length);
+    assertEquals(4, findMatches(document, STACK_ERRORS).length);
+
+    // Pressing up when the first item is focused should NOT change focus.
+    keyDownOn(initialFocus, 38, '', 'ArrowUp');
+    assertEquals(initialFocus, findMatches(document, ACTIVE_ERROR_IN_STACK)[0]);
+
+    // Pressing down when the first item is focused should change focus.
+    keyDownOn(initialFocus, 40, '', 'ArrowDown');
+    assertNotEquals(
+        initialFocus, findMatches(document, ACTIVE_ERROR_IN_STACK)[0]);
+
+    // Pressing up when the second item is focused should focus the first again.
+    keyDownOn(initialFocus, 38, '', 'ArrowUp');
+    assertEquals(initialFocus, findMatches(document, ACTIVE_ERROR_IN_STACK)[0]);
+  });
+});
diff --git a/chrome/test/data/webui/extensions/error_page_test.js b/chrome/test/data/webui/extensions/error_page_test.js
deleted file mode 100644
index d055703..0000000
--- a/chrome/test/data/webui/extensions/error_page_test.js
+++ /dev/null
@@ -1,207 +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.
-
-/** @fileoverview Suite of tests for extensions-detail-view. */
-import 'chrome://extensions/extensions.js';
-
-import {assert} from 'chrome://resources/js/assert.m.js';
-import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
-import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {isChildVisible} from 'chrome://webui-test/test_util.js';
-
-import {ClickMock, createExtensionInfo} from './test_util.js';
-
-window.extension_error_page_tests = {};
-extension_error_page_tests.suiteName = 'ExtensionErrorPageTest';
-/** @enum {string} */
-extension_error_page_tests.TestNames = {
-  Layout: 'layout',
-  CodeSection: 'code section',
-  ErrorSelection: 'error selection',
-};
-
-/** @implements {ErrorPageDelegate} */
-class MockErrorPageDelegate extends ClickMock {
-  /** @override */
-  deleteErrors(extensionId, errorIds, type) {}
-
-  /** @override */
-  requestFileSource(args) {
-    this.requestFileSourceArgs = args;
-    this.requestFileSourceResolver = new PromiseResolver();
-    return this.requestFileSourceResolver.promise;
-  }
-}
-
-suite(extension_error_page_tests.suiteName, function() {
-  /** @type {chrome.developerPrivate.ExtensionInfo} */
-  let extensionData;
-
-  /** @type {ExtensionsErrorPageElement} */
-  let errorPage;
-
-  /** @type {MockErrorPageDelegate} */
-  let mockDelegate;
-
-  const extensionId = 'a'.repeat(32);
-
-  // Common data for runtime errors.
-  const runtimeErrorBase = {
-    type: chrome.developerPrivate.ErrorType.RUNTIME,
-    extensionId: extensionId,
-    fromIncognito: false,
-  };
-
-  // Common data for manifest errors.
-  const manifestErrorBase = {
-    type: chrome.developerPrivate.ErrorType.MANIFEST,
-    extensionId: extensionId,
-    fromIncognito: false,
-  };
-
-  // Initialize an extension item before each test.
-  setup(function() {
-    document.body.innerHTML = '';
-    const runtimeError = Object.assign(
-        {
-          source: 'chrome-extension://' + extensionId + '/source.html',
-          message: 'message',
-          id: 1,
-          severity: chrome.developerPrivate.ErrorLevel.ERROR,
-        },
-        runtimeErrorBase);
-    extensionData = createExtensionInfo({
-      runtimeErrors: [runtimeError],
-      manifestErrors: [],
-    });
-    errorPage = document.createElement('extensions-error-page');
-    mockDelegate = new MockErrorPageDelegate();
-    errorPage.delegate = mockDelegate;
-    errorPage.data = extensionData;
-    document.body.appendChild(errorPage);
-  });
-
-  test(assert(extension_error_page_tests.TestNames.Layout), function() {
-    flush();
-
-    const testIsVisible = isChildVisible.bind(null, errorPage);
-    expectTrue(testIsVisible('#closeButton'));
-    expectTrue(testIsVisible('#heading'));
-    expectTrue(testIsVisible('#errorsList'));
-
-    let errorElements = errorPage.shadowRoot.querySelectorAll('.error-item');
-    expectEquals(1, errorElements.length);
-    let error = errorElements[0];
-    expectEquals(
-        'message', error.querySelector('.error-message').textContent.trim());
-    expectTrue(error.querySelector('iron-icon').icon === 'cr:error');
-
-    const manifestError = Object.assign(
-        {
-          source: 'manifest.json',
-          message: 'invalid key',
-          id: 2,
-          manifestKey: 'permissions',
-        },
-        manifestErrorBase);
-    errorPage.set('data.manifestErrors', [manifestError]);
-    flush();
-    errorElements = errorPage.shadowRoot.querySelectorAll('.error-item');
-    expectEquals(2, errorElements.length);
-    error = errorElements[0];
-    expectEquals(
-        'invalid key',
-        error.querySelector('.error-message').textContent.trim());
-    expectTrue(error.querySelector('iron-icon').icon === 'cr:warning');
-
-    mockDelegate.testClickingCalls(
-        error.querySelector('.icon-delete-gray'), 'deleteErrors',
-        [extensionId, [manifestError.id]]);
-  });
-
-  test(
-      assert(extension_error_page_tests.TestNames.CodeSection), function(done) {
-        flush();
-
-        assertTrue(!!mockDelegate.requestFileSourceArgs);
-        const args = mockDelegate.requestFileSourceArgs;
-        expectEquals(extensionId, args.extensionId);
-        expectEquals('source.html', args.pathSuffix);
-        expectEquals('message', args.message);
-
-        expectTrue(!!mockDelegate.requestFileSourceResolver);
-        const code = {
-          beforeHighlight: 'foo',
-          highlight: 'bar',
-          afterHighlight: 'baz',
-          message: 'quu',
-        };
-        mockDelegate.requestFileSourceResolver.resolve(code);
-        mockDelegate.requestFileSourceResolver.promise.then(function() {
-          flush();
-          expectEquals(
-              code,
-              errorPage.shadowRoot.querySelector('extensions-code-section')
-                  .code);
-          done();
-        });
-      });
-
-  test(assert(extension_error_page_tests.TestNames.ErrorSelection), function() {
-    const nextRuntimeError = Object.assign(
-        {
-          source: 'chrome-extension://' + extensionId + '/other_source.html',
-          message: 'Other error',
-          id: 2,
-          severity: chrome.developerPrivate.ErrorLevel.ERROR,
-          renderProcessId: 111,
-          renderViewId: 222,
-          canInspect: true,
-          contextUrl: 'http://test.com',
-          stackTrace: [{url: 'url', lineNumber: 123, columnNumber: 321}],
-        },
-        runtimeErrorBase);
-    // Add a new runtime error to the end.
-    errorPage.push('data.runtimeErrors', nextRuntimeError);
-    flush();
-
-    const errorElements =
-        errorPage.shadowRoot.querySelectorAll('.error-item .start');
-    const ironCollapses =
-        errorPage.shadowRoot.querySelectorAll('iron-collapse');
-    expectEquals(2, errorElements.length);
-    expectEquals(2, ironCollapses.length);
-
-    // The first error should be focused by default, and we should have
-    // requested the source for it.
-    expectEquals(extensionData.runtimeErrors[0], errorPage.getSelectedError());
-    expectTrue(!!mockDelegate.requestFileSourceArgs);
-    let args = mockDelegate.requestFileSourceArgs;
-    expectEquals('source.html', args.pathSuffix);
-    expectTrue(ironCollapses[0].opened);
-    expectFalse(ironCollapses[1].opened);
-    mockDelegate.requestFileSourceResolver.resolve(null);
-
-    mockDelegate.requestFileSourceResolver = new PromiseResolver();
-    mockDelegate.requestFileSourceArgs = undefined;
-
-    // Tap the second error. It should now be selected and we should request
-    // the source for it.
-    errorElements[1].click();
-    expectEquals(nextRuntimeError, errorPage.getSelectedError());
-    expectTrue(!!mockDelegate.requestFileSourceArgs);
-    args = mockDelegate.requestFileSourceArgs;
-    expectEquals('other_source.html', args.pathSuffix);
-    expectTrue(ironCollapses[1].opened);
-    expectFalse(ironCollapses[0].opened);
-
-    expectEquals(
-        'Unknown',
-        ironCollapses[0].querySelector('.context-url').textContent.trim());
-    expectEquals(
-        nextRuntimeError.contextUrl,
-        ironCollapses[1].querySelector('.context-url').textContent.trim());
-  });
-});
diff --git a/chrome/test/data/webui/extensions/error_page_test.ts b/chrome/test/data/webui/extensions/error_page_test.ts
new file mode 100644
index 0000000..d7b9a12
--- /dev/null
+++ b/chrome/test/data/webui/extensions/error_page_test.ts
@@ -0,0 +1,225 @@
+// 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.
+
+/** @fileoverview Suite of tests for extensions-detail-view. */
+import 'chrome://extensions/extensions.js';
+
+import {ErrorPageDelegate, ExtensionsErrorPageElement} from 'chrome://extensions/extensions.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {isChildVisible} from 'chrome://webui-test/test_util.js';
+
+import {ClickMock, createExtensionInfo} from './test_util.js';
+
+const extension_error_page_tests = {
+  suiteName: 'ExtensionErrorPageTest',
+  TestNames: {
+    Layout: 'layout',
+    CodeSection: 'code section',
+    ErrorSelection: 'error selection',
+  },
+};
+
+Object.assign(window, {extension_error_page_tests: extension_error_page_tests});
+
+class MockErrorPageDelegate extends ClickMock implements ErrorPageDelegate {
+  requestFileSourceArgs: chrome.developerPrivate.RequestFileSourceProperties|
+      undefined;
+  requestFileSourceResolver:
+      PromiseResolver<chrome.developerPrivate.RequestFileSourceResponse> =
+          new PromiseResolver();
+
+  deleteErrors(
+      _extensionId: string, _errorIds?: number[],
+      _type?: chrome.developerPrivate.ErrorType) {}
+
+  requestFileSource(args: chrome.developerPrivate.RequestFileSourceProperties) {
+    this.requestFileSourceArgs = args;
+    this.requestFileSourceResolver = new PromiseResolver();
+    return this.requestFileSourceResolver.promise;
+  }
+}
+
+suite(extension_error_page_tests.suiteName, function() {
+  let extensionData: chrome.developerPrivate.ExtensionInfo;
+
+  let errorPage: ExtensionsErrorPageElement;
+
+  let mockDelegate: MockErrorPageDelegate;
+
+  const extensionId: string = 'a'.repeat(32);
+
+  // Common data for runtime errors.
+  const runtimeErrorBase = {
+    occurrences: 1,
+    type: chrome.developerPrivate.ErrorType.RUNTIME,
+    extensionId: extensionId,
+    fromIncognito: false,
+  };
+
+  // Common data for manifest errors.
+  const manifestErrorBase = {
+    type: chrome.developerPrivate.ErrorType.MANIFEST,
+    extensionId: extensionId,
+    fromIncognito: false,
+  };
+
+  // Initialize an extension item before each test.
+  setup(function() {
+    document.body.innerHTML = '';
+    const runtimeError = Object.assign(
+        {
+          contextUrl: 'Unknown',
+          source: 'chrome-extension://' + extensionId + '/source.html',
+          message: 'message',
+          renderProcessId: 0,
+          renderViewId: 0,
+          canInspect: false,
+          id: 1,
+          stackTrace: [],
+          severity: chrome.developerPrivate.ErrorLevel.ERROR,
+        },
+        runtimeErrorBase);
+    extensionData = createExtensionInfo({
+      runtimeErrors: [runtimeError],
+      manifestErrors: [],
+    });
+    errorPage = document.createElement('extensions-error-page');
+    mockDelegate = new MockErrorPageDelegate();
+    errorPage.delegate = mockDelegate;
+    errorPage.data = extensionData;
+    document.body.appendChild(errorPage);
+  });
+
+  test(assert(extension_error_page_tests.TestNames.Layout), function() {
+    flush();
+
+    const testIsVisible = isChildVisible.bind(null, errorPage);
+    assertTrue(testIsVisible('#closeButton'));
+    assertTrue(testIsVisible('#heading'));
+    assertTrue(testIsVisible('#errorsList'));
+
+    let errorElements = errorPage.shadowRoot!.querySelectorAll('.error-item');
+    assertEquals(1, errorElements.length);
+    let error = errorElements[0]!;
+    assertEquals(
+        'message',
+        error.querySelector<HTMLElement>(
+                 '.error-message')!.textContent!.trim());
+    assertTrue(error.querySelector('iron-icon')!.icon === 'cr:error');
+
+    const manifestError = Object.assign(
+        {
+          source: 'manifest.json',
+          message: 'invalid key',
+          id: 2,
+          manifestKey: 'permissions',
+        },
+        manifestErrorBase);
+    errorPage.set('data.manifestErrors', [manifestError]);
+    flush();
+    errorElements = errorPage.shadowRoot!.querySelectorAll('.error-item');
+    assertEquals(2, errorElements.length);
+    error = errorElements[0]!;
+    assertEquals(
+        'invalid key',
+        error.querySelector<HTMLElement>(
+                 '.error-message')!.textContent!.trim());
+    assertTrue(error.querySelector('iron-icon')!.icon === 'cr:warning');
+
+    mockDelegate.testClickingCalls(
+        error.querySelector<HTMLElement>('.icon-delete-gray')!, 'deleteErrors',
+        [extensionId, [manifestError.id]]);
+  });
+
+  test(
+      assert(extension_error_page_tests.TestNames.CodeSection), function(done) {
+        flush();
+
+        assertTrue(!!mockDelegate.requestFileSourceArgs);
+        const args = mockDelegate.requestFileSourceArgs;
+        assertEquals(extensionId, args.extensionId);
+        assertEquals('source.html', args.pathSuffix);
+        assertEquals('message', args.message);
+
+        assertTrue(!!mockDelegate.requestFileSourceResolver);
+        const code = {
+          beforeHighlight: 'foo',
+          highlight: 'bar',
+          afterHighlight: 'baz',
+          message: 'quu',
+          title: '',
+        };
+        mockDelegate.requestFileSourceResolver.resolve(code);
+        mockDelegate.requestFileSourceResolver.promise.then(function() {
+          flush();
+          assertEquals(
+              code,
+              errorPage.shadowRoot!.querySelector(
+                                       'extensions-code-section')!.code);
+          done();
+        });
+      });
+
+  test(assert(extension_error_page_tests.TestNames.ErrorSelection), function() {
+    const nextRuntimeError = Object.assign(
+        {
+          source: 'chrome-extension://' + extensionId + '/other_source.html',
+          message: 'Other error',
+          id: 2,
+          severity: chrome.developerPrivate.ErrorLevel.ERROR,
+          renderProcessId: 111,
+          renderViewId: 222,
+          canInspect: true,
+          contextUrl: 'http://test.com',
+          stackTrace: [{url: 'url', lineNumber: 123, columnNumber: 321}],
+        },
+        runtimeErrorBase);
+    // Add a new runtime error to the end.
+    errorPage.push('data.runtimeErrors', nextRuntimeError);
+    flush();
+
+    const errorElements = errorPage.shadowRoot!.querySelectorAll<HTMLElement>(
+        '.error-item .start');
+    const ironCollapses =
+        errorPage.shadowRoot!.querySelectorAll('iron-collapse');
+    assertEquals(2, errorElements.length);
+    assertEquals(2, ironCollapses.length);
+
+    // The first error should be focused by default, and we should have
+    // requested the source for it.
+    assertEquals(extensionData.runtimeErrors[0], errorPage.getSelectedError());
+    assertTrue(!!mockDelegate.requestFileSourceArgs);
+    let args = mockDelegate.requestFileSourceArgs;
+    assertEquals('source.html', args.pathSuffix);
+    assertTrue(ironCollapses[0]!.opened);
+    assertFalse(ironCollapses[1]!.opened);
+    mockDelegate.requestFileSourceResolver.resolve(undefined);
+
+    mockDelegate.requestFileSourceResolver = new PromiseResolver();
+    mockDelegate.requestFileSourceArgs = undefined;
+
+    // Tap the second error. It should now be selected and we should request
+    // the source for it.
+    errorElements[1]!.click();
+    assertEquals(nextRuntimeError, errorPage.getSelectedError());
+    assertTrue(!!mockDelegate.requestFileSourceArgs);
+    args = mockDelegate.requestFileSourceArgs;
+    assertEquals('other_source.html', args.pathSuffix);
+    assertTrue(ironCollapses[1]!.opened);
+    assertFalse(ironCollapses[0]!.opened);
+
+    assertEquals(
+        'Unknown',
+        ironCollapses[0]!.querySelector<HTMLElement>(
+                             '.context-url')!.textContent!.trim());
+    assertEquals(
+        nextRuntimeError.contextUrl,
+        ironCollapses[1]!.querySelector<HTMLElement>(
+                             '.context-url')!.textContent!.trim());
+  });
+});
diff --git a/chrome/test/data/webui/extensions/test_util.ts b/chrome/test/data/webui/extensions/test_util.ts
index 5d9f43d..7ed0fba 100644
--- a/chrome/test/data/webui/extensions/test_util.ts
+++ b/chrome/test/data/webui/extensions/test_util.ts
@@ -20,7 +20,7 @@
    */
   testClickingCalls(
       element: HTMLElement, callName: string, opt_expectedArgs: any[],
-      opt_returnValue: any) {
+      opt_returnValue?: any) {
     const mock = new MockController();
     const mockMethod = mock.createFunctionMock(this, callName);
     mockMethod.returnValue = opt_returnValue;
@@ -219,7 +219,8 @@
  * Finds all nodes matching |query| under |root|, within self and children's
  * Shadow DOM.
  */
-export function findMatches(root: HTMLElement, query: string): HTMLElement[] {
+export function findMatches(
+    root: HTMLElement|Document, query: string): HTMLElement[] {
   let elements = new Set<HTMLElement>();
   function doSearch(node: Node) {
     if (node.nodeType === Node.ELEMENT_NODE) {
diff --git a/chrome/test/data/webui/read_later/BUILD.gn b/chrome/test/data/webui/read_later/BUILD.gn
index 3c52d05..1634af9a 100644
--- a/chrome/test/data/webui/read_later/BUILD.gn
+++ b/chrome/test/data/webui/read_later/BUILD.gn
@@ -30,6 +30,7 @@
     "read_later_app_test.ts",
     "side_panel/bookmark_folder_test.ts",
     "side_panel/bookmarks_drag_manager_test.ts",
+    "side_panel/bookmarks_list_interactive_ui_test.ts",
     "side_panel/bookmarks_list_test.ts",
     "side_panel/side_panel_app_test.ts",
     "side_panel/test_bookmarks_api_proxy.ts",
diff --git a/chrome/test/data/webui/read_later/side_panel/bookmarks_list_interactive_ui_test.ts b/chrome/test/data/webui/read_later/side_panel/bookmarks_list_interactive_ui_test.ts
new file mode 100644
index 0000000..cc241516
--- /dev/null
+++ b/chrome/test/data/webui/read_later/side_panel/bookmarks_list_interactive_ui_test.ts
@@ -0,0 +1,141 @@
+// Copyright 2022 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.
+
+import 'chrome://webui-test/mojo_webui_test_support.js';
+import 'chrome://read-later.top-chrome/side_panel/bookmarks_list.js';
+
+import {BookmarkFolderElement} from 'chrome://read-later.top-chrome/side_panel/bookmark_folder.js';
+import {BookmarksApiProxyImpl} from 'chrome://read-later.top-chrome/side_panel/bookmarks_api_proxy.js';
+import {BookmarksListElement} from 'chrome://read-later.top-chrome/side_panel/bookmarks_list.js';
+import {keyDownOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
+import {assertEquals} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/test_util.js';
+
+import {TestBookmarksApiProxy} from './test_bookmarks_api_proxy.js';
+
+suite('SidePanelBookmarksListInteractiveUITest', () => {
+  let bookmarksList: BookmarksListElement;
+  let bookmarksApi: TestBookmarksApiProxy;
+
+  const folders: chrome.bookmarks.BookmarkTreeNode[] = [
+    {
+      id: '0',
+      parentId: 'root',
+      title: 'Bookmarks bar',
+      children: [
+        {
+          id: '3',
+          parentId: '0',
+          title: 'Child bookmark',
+          url: 'http://child/bookmark/',
+        },
+        {
+          id: '4',
+          parentId: '0',
+          title: 'Child folder',
+          children: [
+            {
+              id: '5',
+              parentId: '4',
+              title: 'Nested bookmark',
+              url: 'http://nested/bookmark/',
+            },
+          ],
+        }
+      ],
+    },
+    {
+      id: '1',
+      parentId: 'root',
+      title: 'Other bookmarks',
+      children: [],
+    },
+    {
+      id: '2',
+      title: 'Mobile bookmarks',
+      children: [],
+    },
+  ];
+
+  function getFolderElements(root: HTMLElement):
+      NodeListOf<BookmarkFolderElement> {
+    return root.shadowRoot!.querySelectorAll('bookmark-folder');
+  }
+
+  function getBookmarkElements(root: HTMLElement): NodeListOf<HTMLElement> {
+    return root.shadowRoot!.querySelectorAll('.bookmark');
+  }
+
+  setup(async () => {
+    document.body.innerHTML = '';
+
+    bookmarksApi = new TestBookmarksApiProxy();
+    bookmarksApi.setFolders(JSON.parse(JSON.stringify(folders)));
+    BookmarksApiProxyImpl.setInstance(bookmarksApi);
+
+    bookmarksList = document.createElement('bookmarks-list');
+    document.body.appendChild(bookmarksList);
+    await flushTasks();
+  });
+
+  test('MovesFocusBetweenFolders', () => {
+    const folderElements = getFolderElements(bookmarksList);
+
+    function assertActiveElement(index: number) {
+      assertEquals(
+          folderElements[index], bookmarksList.shadowRoot!.activeElement);
+    }
+
+    // Move focus to the first folder.
+    folderElements[0]!.moveFocus(1);
+    assertActiveElement(0);
+
+    // One ArrowDown key should still keep focus in the first folder since the
+    // folder has children.
+    keyDownOn(bookmarksList, 0, [], 'ArrowDown');
+    assertActiveElement(0);
+
+    // Two ArrowsDown to eventually make it to the second folder.
+    keyDownOn(bookmarksList, 0, [], 'ArrowDown');
+    keyDownOn(bookmarksList, 0, [], 'ArrowDown');
+    assertActiveElement(1);
+
+    // One ArrowsDown to eventually make it to the third folder.
+    keyDownOn(bookmarksList, 0, [], 'ArrowDown');
+    assertActiveElement(2);
+
+    // One ArrowsDown to loop back to the first folder.
+    keyDownOn(bookmarksList, 0, [], 'ArrowDown');
+    assertActiveElement(0);
+
+    // One ArrowUp to loop back to the last folder.
+    keyDownOn(bookmarksList, 0, [], 'ArrowUp');
+    assertActiveElement(2);
+
+    // One ArrowUp to loop back to the second folder.
+    keyDownOn(bookmarksList, 0, [], 'ArrowUp');
+    assertActiveElement(1);
+  });
+
+  test('CutsCopyPastesBookmark', async () => {
+    const folderElement = getFolderElements(bookmarksList)[0]!;
+    const bookmarkElement = getBookmarkElements(folderElement)[0]!;
+    bookmarkElement.focus();
+    assertEquals(bookmarkElement, folderElement.shadowRoot!.activeElement);
+
+    keyDownOn(bookmarkElement, 0, ['ctrl'], 'x');
+    const cutId = await bookmarksApi.whenCalled('cutBookmark');
+    assertEquals('3', cutId);
+
+    keyDownOn(bookmarkElement, 0, ['ctrl'], 'c');
+    const copiedId = await bookmarksApi.whenCalled('copyBookmark');
+    assertEquals('3', copiedId);
+
+    keyDownOn(bookmarkElement, 0, ['ctrl'], 'v');
+    let [pastedId, pastedDestinationId] =
+        await bookmarksApi.whenCalled('pasteToBookmark');
+    assertEquals('0', pastedId);
+    assertEquals('3', pastedDestinationId);
+  });
+});
\ No newline at end of file
diff --git a/chrome/test/data/webui/read_later/side_panel/bookmarks_list_test.ts b/chrome/test/data/webui/read_later/side_panel/bookmarks_list_test.ts
index cb45384..46d3930 100644
--- a/chrome/test/data/webui/read_later/side_panel/bookmarks_list_test.ts
+++ b/chrome/test/data/webui/read_later/side_panel/bookmarks_list_test.ts
@@ -237,70 +237,4 @@
         JSON.stringify(['5001']),
         window.localStorage[LOCAL_STORAGE_OPEN_FOLDERS_KEY]);
   });
-
-  test('MovesFocusBetweenFolders', () => {
-    const folderElements = getFolderElements(bookmarksList);
-
-    function dispatchArrowKey(key: string) {
-      bookmarksList.dispatchEvent(new KeyboardEvent('keydown', {key}));
-    }
-
-    function assertActiveElement(index: number) {
-      assertEquals(
-          folderElements[index], bookmarksList.shadowRoot!.activeElement);
-    }
-
-    // Move focus to the first folder.
-    folderElements[0]!.moveFocus(1);
-    assertActiveElement(0);
-
-    // One ArrowDown key should still keep focus in the first folder since the
-    // folder has children.
-    dispatchArrowKey('ArrowDown');
-    assertActiveElement(0);
-
-    // Two ArrowsDown to eventually make it to the second folder.
-    dispatchArrowKey('ArrowDown');
-    dispatchArrowKey('ArrowDown');
-    assertActiveElement(1);
-
-    // One ArrowsDown to eventually make it to the third folder.
-    dispatchArrowKey('ArrowDown');
-    assertActiveElement(2);
-
-    // One ArrowsDown to loop back to the first folder.
-    dispatchArrowKey('ArrowDown');
-    assertActiveElement(0);
-
-    // One ArrowUp to loop back to the last folder.
-    dispatchArrowKey('ArrowUp');
-    assertActiveElement(2);
-
-    // One ArrowUp to loop back to the second folder.
-    dispatchArrowKey('ArrowUp');
-    assertActiveElement(1);
-  });
-
-  test('CutsCopyPastesBookmark', async () => {
-    const folderElement = getFolderElements(bookmarksList)[0]!;
-    const bookmarkElement = getBookmarkElements(folderElement)[0]!;
-    bookmarkElement.focus();
-
-    bookmarkElement.dispatchEvent(new KeyboardEvent(
-        'keydown', {key: 'x', ctrlKey: true, bubbles: true, composed: true}));
-    const cutId = await bookmarksApi.whenCalled('cutBookmark');
-    assertEquals('3', cutId);
-
-    bookmarkElement.dispatchEvent(new KeyboardEvent(
-        'keydown', {key: 'c', ctrlKey: true, bubbles: true, composed: true}));
-    const copiedId = await bookmarksApi.whenCalled('copyBookmark');
-    assertEquals('3', copiedId);
-
-    bookmarkElement.dispatchEvent(new KeyboardEvent(
-        'keydown', {key: 'v', ctrlKey: true, bubbles: true, composed: true}));
-    let [pastedId, pastedDestinationId] =
-        await bookmarksApi.whenCalled('pasteToBookmark');
-    assertEquals('0', pastedId);
-    assertEquals('3', pastedDestinationId);
-  });
 });
diff --git a/chrome/test/data/webui/read_later/side_panel/side_panel_browsertest.js b/chrome/test/data/webui/read_later/side_panel/side_panel_browsertest.js
index a94d4e6..d68e4c9a 100644
--- a/chrome/test/data/webui/read_later/side_panel/side_panel_browsertest.js
+++ b/chrome/test/data/webui/read_later/side_panel/side_panel_browsertest.js
@@ -48,16 +48,9 @@
   }
 };
 
-GEN('#if BUILDFLAG(IS_MAC)');
-GEN('// Flaky, https://crbug.com/1288747');
-GEN('#define MAYBE_All DISABLED_All');
-GEN('#else');
-GEN('#define MAYBE_All All');
-GEN('#endif');
-TEST_F('SidePanelBookmarksListTest', 'MAYBE_All', function() {
+TEST_F('SidePanelBookmarksListTest', 'All', function() {
   mocha.run();
 });
-GEN('#undef MAYBE_All');
 
 
 var SidePanelBookmarkFolderTest = class extends SidePanelBrowserTest {
diff --git a/chrome/test/data/webui/read_later/side_panel/side_panel_interactive_ui_tests.js b/chrome/test/data/webui/read_later/side_panel/side_panel_interactive_ui_tests.js
new file mode 100644
index 0000000..db20c89
--- /dev/null
+++ b/chrome/test/data/webui/read_later/side_panel/side_panel_interactive_ui_tests.js
@@ -0,0 +1,34 @@
+// Copyright 2022 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.
+
+/** @fileoverview Test suite for the WebUI tab search. */
+
+GEN_INCLUDE(['//chrome/test/data/webui/polymer_interactive_ui_test.js']);
+
+GEN('#include "chrome/browser/ui/ui_features.h"');
+GEN('#include "components/reading_list/features/reading_list_switches.h"');
+GEN('#include "content/public/test/browser_test.h"');
+
+// eslint-disable-next-line no-var
+var SidePanelBookmarksListInteractiveUITest =
+    class extends PolymerInteractiveUITest {
+  /** @override */
+  get browsePreload() {
+    return 'chrome://read-later.top-chrome/test_loader.html?module=read_later/side_panel/bookmarks_list_interactive_ui_test.js&host=webui-test';
+  }
+
+  /** @override */
+  get featureList() {
+    return {
+      enabled: [
+        'features::kSidePanel',
+        'reading_list::switches::kReadLater',
+      ]
+    };
+  }
+};
+
+TEST_F('SidePanelBookmarksListInteractiveUITest', 'All', function() {
+  mocha.run();
+});
diff --git a/chrome/test/data/webui/settings/chromeos/internet_detail_menu_test.js b/chrome/test/data/webui/settings/chromeos/internet_detail_menu_test.js
index f36b9fbc..45b0017 100644
--- a/chrome/test/data/webui/settings/chromeos/internet_detail_menu_test.js
+++ b/chrome/test/data/webui/settings/chromeos/internet_detail_menu_test.js
@@ -49,7 +49,7 @@
   /** @param {boolean=} opt_isGuest */
   async function init(opt_isGuest) {
     const isGuest = !!opt_isGuest;
-    loadTimeData.overrideValues({isGuest: isGuest});
+    loadTimeData.overrideValues({esimPolicyEnabled: true, isGuest: isGuest});
 
     const params = new URLSearchParams;
     params.append('guid', 'cellular_guid');
@@ -265,7 +265,8 @@
   });
 
   test('Menu is disabled on managed profile', async function() {
-    addEsimCellularNetwork('100000', '11111111111111111111111111111111', true);
+    addEsimCellularNetwork(
+        '100000', '11111111111111111111111111111111', /*is_managed=*/ true);
     init();
 
     const params = new URLSearchParams;
@@ -276,12 +277,6 @@
     await flushAsync();
     const tripleDot = internetDetailMenu.$$('#moreNetworkDetail');
     assertTrue(!!tripleDot);
-    assertFalse(tripleDot.disabled);
-
-    internetDetailMenu.deviceState = {
-      type: mojom.NetworkType.kCellular,
-      deviceState: chromeos.networkConfig.mojom.DeviceStateType.kEnabled,
-    };
     assertTrue(tripleDot.disabled);
   });
 
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.js b/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.js
index dd26dd4..a83b45e 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.js
@@ -52,9 +52,10 @@
    * @param {!Node} The DOM node for the section.
    */
   function verifySubpagesHidden(section) {
-    // Check if there are sub-pages to verify.
-    const pages = section.firstElementChild.shadowRoot.querySelector(
-        'settings-animated-pages');
+    // Check if there are any sub-pages to verify, being careful to filter out
+    // any dom-if and template noise when we search.
+    const pages = section.querySelector(`:not(dom-if, template)`)
+                      .shadowRoot.querySelector('settings-animated-pages');
     if (!pages) {
       return;
     }
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn
index 0d83da3..3ea70941 100644
--- a/chrome/updater/BUILD.gn
+++ b/chrome/updater/BUILD.gn
@@ -530,6 +530,16 @@
       if (is_win) {
         inputs = [ "$root_build_dir/UpdaterSetup_test.exe" ]
         deps = [ "//chrome/updater/win/installer:installer_test" ]
+
+        if (is_component_build) {
+          inputs += [
+            "$root_build_dir/base.dll",
+            "$root_build_dir/ui_base.dll",
+          ]
+          data = [ "$root_build_dir/ucrtbased.dll" ]
+
+          deps += [ "//ui/base" ]
+        }
       }
     }
   }
@@ -630,6 +640,17 @@
         "test/data/updater.runtime_deps",
         "//chrome/test/data/updater/updater_qualification_app_exe.crx",
       ]
+
+      if (target_cpu == "x64") {
+        data += [
+          "//third_party/updater/chromium_win_x86_64/UpdaterSetup_test.exe",
+        ]
+      }
+
+      if (target_cpu == "x86") {
+        data +=
+            [ "//third_party/updater/chromium_win_x86/UpdaterSetup_test.exe" ]
+      }
     }
 
     if (is_mac) {
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index a055e86..2f3f3c8 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -600,9 +600,11 @@
 }
 #endif  // BUILDFLAG(IS_MAC)
 
-// Windows and Google-branded builds will eventually support this test, but for
-// now only Chromium-branded macOS updaters are available in third_party.
-#if BUILDFLAG(IS_MAC) && BUILDFLAG(CHROMIUM_BRANDING)
+// Google-branded builds will eventually support this test, but for
+// now only Chromium-branded updaters are available in third_party.
+#if BUILDFLAG(CHROMIUM_BRANDING)
+// TODO(crbug.com/1268555): Even on Windows, component builds do not work.
+#if !defined(COMPONENT_BUILD)
 TEST_F(IntegrationTest, SelfUpdateFromOldReal) {
   ScopedServer test_server(test_commands_);
   ExpectRegistrationEvent(&test_server, kUpdaterAppId);
@@ -628,6 +630,7 @@
   Uninstall();
 }
 #endif
+#endif
 
 TEST_F(IntegrationTest, UpdateServiceStress) {
   Install();
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index 328ed6c0..cec8c6f 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -33,6 +33,7 @@
 #include "base/win/registry.h"
 #include "base/win/scoped_bstr.h"
 #include "build/branding_buildflags.h"
+#include "build/build_config.h"
 #include "chrome/updater/app/server/win/updater_idl.h"
 #include "chrome/updater/app/server/win/updater_internal_idl.h"
 #include "chrome/updater/app/server/win/updater_legacy_idl.h"
@@ -817,7 +818,26 @@
 }
 
 void SetupRealUpdaterLowerVersion(UpdaterScope scope) {
-  // TODO(crbug.com/1268555): Implement.
+  base::FilePath source_path;
+  ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_path));
+  base::FilePath old_updater_path =
+      source_path.Append(FILE_PATH_LITERAL("third_party"))
+          .Append(FILE_PATH_LITERAL("updater"));
+#if BUILDFLAG(CHROMIUM_BRANDING)
+#if defined(ARCH_CPU_X86_64)
+  old_updater_path =
+      old_updater_path.Append(FILE_PATH_LITERAL("chromium_win_x86_64"));
+#elif defined(ARCH_CPU_X86)
+  old_updater_path =
+      old_updater_path.Append(FILE_PATH_LITERAL("chromium_win_x86"));
+#endif
+#endif
+  base::CommandLine command_line(
+      old_updater_path.Append(FILE_PATH_LITERAL("UpdaterSetup_test.exe")));
+  command_line.AppendSwitch(kInstallSwitch);
+  int exit_code = -1;
+  ASSERT_TRUE(Run(scope, command_line, &exit_code));
+  ASSERT_EQ(exit_code, 0);
 }
 
 void RunUninstallCmdLine(UpdaterScope scope) {
diff --git a/chrome/updater/win/action_handler.cc b/chrome/updater/win/action_handler.cc
index a97116e6..70a90c4 100644
--- a/chrome/updater/win/action_handler.cc
+++ b/chrome/updater/win/action_handler.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include <string>
-#include <tuple>
 #include <utility>
 
 #include "base/bind.h"
@@ -57,10 +56,7 @@
       base::BindOnce(&ActionHandler::RunCommand, action),
       base::BindOnce(
           [](Callback callback, const Result& result) {
-            bool succeeded = false;
-            int error_code = 0;
-            int extra_code = 0;
-            std::tie(succeeded, error_code, extra_code) = result;
+            auto [succeeded, error_code, extra_code] = result;
             base::SequencedTaskRunnerHandle::Get()->PostTask(
                 FROM_HERE, base::BindOnce(std::move(callback), succeeded,
                                           error_code, extra_code));
diff --git a/chrome/utility/services.cc b/chrome/utility/services.cc
index e0176f00..41d39ef 100644
--- a/chrome/utility/services.cc
+++ b/chrome/utility/services.cc
@@ -34,7 +34,6 @@
 #include "chrome/services/util_win/public/mojom/util_win.mojom.h"
 #include "chrome/services/util_win/util_read_icon.h"
 #include "chrome/services/util_win/util_win_impl.h"
-#include "components/services/quarantine/public/cpp/quarantine_features_win.h"  // nogncheck
 #include "components/services/quarantine/public/mojom/quarantine.mojom.h"  // nogncheck
 #include "components/services/quarantine/quarantine_impl.h"  // nogncheck
 #include "services/proxy_resolver_win/public/mojom/proxy_resolver_win.mojom.h"
@@ -155,7 +154,6 @@
 
 auto RunQuarantineService(
     mojo::PendingReceiver<quarantine::mojom::Quarantine> receiver) {
-  DCHECK(base::FeatureList::IsEnabled(quarantine::kOutOfProcessQuarantine));
   return std::make_unique<quarantine::QuarantineImpl>(std::move(receiver));
 }
 
diff --git a/chromecast/base/bitstream_audio_codecs.h b/chromecast/base/bitstream_audio_codecs.h
index 563a5482..7bb90dc 100644
--- a/chromecast/base/bitstream_audio_codecs.h
+++ b/chromecast/base/bitstream_audio_codecs.h
@@ -16,7 +16,8 @@
 constexpr int kBitstreamAudioCodecEac3 = 0b001000;
 constexpr int kBitstreamAudioCodecPcmSurround = 0b010000;
 constexpr int kBitstreamAudioCodecMpegHAudio = 0b100000;
-constexpr int kBitstreamAudioCodecAll = 0b111111;
+constexpr int kBitstreamAudioCodecDtsXP2 = 0b1000000;
+constexpr int kBitstreamAudioCodecAll = 0b1111111;
 
 // Supported bitstream audio codecs and their associated properties.
 struct BitstreamAudioCodecsInfo {
diff --git a/chromecast/cast_core/runtime/browser/BUILD.gn b/chromecast/cast_core/runtime/browser/BUILD.gn
index ff48340..0b4ee6b 100644
--- a/chromecast/cast_core/runtime/browser/BUILD.gn
+++ b/chromecast/cast_core/runtime/browser/BUILD.gn
@@ -148,15 +148,25 @@
 
 cast_source_set("streaming_receiver_session_client") {
   sources = [
+    "streaming_controller.h",
+    "streaming_controller_base.cc",
+    "streaming_controller_base.h",
+    "streaming_controller_mirroring.cc",
+    "streaming_controller_mirroring.h",
     "streaming_receiver_session_client.cc",
     "streaming_receiver_session_client.h",
   ]
 
+  if (!enable_remoting_for_cwr) {
+    sources += [ "streaming_controller_factory_mirroring.cc" ]
+  }
+
   public_deps = [
     "//base",
     "//chromecast/browser:public",
     "//components/cast/message_port",
     "//components/cast_streaming/browser",
+    "//media/mojo/mojom",
   ]
 
   deps = [
@@ -202,7 +212,6 @@
     "//chromecast/common:feature_constants",
     "//components/cast_streaming/public/mojom",
     "//components/url_rewrite/browser",
-    "//media/mojo/mojom",
     "//third_party/cast_core/public/src/proto/common:application_config_proto",
     "//third_party/cast_core/public/src/proto/core:cast_core_service_proto",
     "//third_party/cast_core/public/src/proto/metrics:metrics_recorder_proto",
diff --git a/chromecast/cast_core/runtime/browser/streaming_controller.h b/chromecast/cast_core/runtime/browser/streaming_controller.h
new file mode 100644
index 0000000..721736d
--- /dev/null
+++ b/chromecast/cast_core/runtime/browser/streaming_controller.h
@@ -0,0 +1,37 @@
+// Copyright 2022 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 CHROMECAST_CAST_CORE_RUNTIME_BROWSER_STREAMING_CONTROLLER_H_
+#define CHROMECAST_CAST_CORE_RUNTIME_BROWSER_STREAMING_CONTROLLER_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "components/cast_streaming/browser/public/receiver_session.h"
+
+namespace chromecast {
+
+// This class is responsible for configuring a Cast Streaming session and
+// beginning its playback.
+class StreamingController {
+ public:
+  using PlaybackStartedCB = base::OnceCallback<void()>;
+
+  virtual ~StreamingController() = default;
+
+  // Creates a new cast_streaming::ReceiverSession to use for this streaming
+  // session.
+  virtual void InitializeReceiverSession(
+      std::unique_ptr<cast_streaming::ReceiverSession::AVConstraints>
+          constraints,
+      cast_streaming::ReceiverSession::Client* client) = 0;
+
+  // Begins playback once all preconditions have been met, at which time |cb| is
+  // called.
+  virtual void StartPlaybackAsync(PlaybackStartedCB cb) = 0;
+};
+
+}  // namespace chromecast
+
+#endif  // CHROMECAST_CAST_CORE_RUNTIME_BROWSER_STREAMING_CONTROLLER_H_
diff --git a/chromecast/cast_core/runtime/browser/streaming_controller_base.cc b/chromecast/cast_core/runtime/browser/streaming_controller_base.cc
new file mode 100644
index 0000000..58ba3b3
--- /dev/null
+++ b/chromecast/cast_core/runtime/browser/streaming_controller_base.cc
@@ -0,0 +1,89 @@
+// Copyright 2022 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 "chromecast/cast_core/runtime/browser/streaming_controller_base.h"
+
+#include "base/bind.h"
+#include "components/cast/message_port/platform_message_port.h"
+#include "components/cast_streaming/browser/public/receiver_session.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/render_frame_host.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+
+namespace chromecast {
+
+StreamingControllerBase::StreamingControllerBase(
+    std::unique_ptr<cast_api_bindings::MessagePort> message_port,
+    CastWebContents* cast_web_contents)
+    : message_port_(std::move(message_port)) {
+  DCHECK(message_port_);
+
+  CastWebContents::Observer::Observe(cast_web_contents);
+}
+
+StreamingControllerBase::~StreamingControllerBase() = default;
+
+void StreamingControllerBase::ProcessAVConstraints(
+    cast_streaming::ReceiverSession::AVConstraints* constraints) {}
+
+void StreamingControllerBase::MainFrameReadyToCommitNavigation(
+    content::NavigationHandle* navigation_handle) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(navigation_handle);
+
+  navigation_handle->GetRenderFrameHost()
+      ->GetRemoteAssociatedInterfaces()
+      ->GetInterface(&cast_streaming_receiver_);
+  navigation_handle->GetRenderFrameHost()
+      ->GetRemoteAssociatedInterfaces()
+      ->GetInterface(&renderer_connection_);
+
+  DCHECK(cast_streaming_receiver_);
+  DCHECK(renderer_connection_);
+
+  TryStartPlayback();
+}
+
+void StreamingControllerBase::InitializeReceiverSession(
+    std::unique_ptr<cast_streaming::ReceiverSession::AVConstraints> constraints,
+    cast_streaming::ReceiverSession::Client* client) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(constraints);
+
+  ProcessAVConstraints(constraints.get());
+  constraints_ = std::move(constraints);
+  client_ = client;
+
+  TryStartPlayback();
+}
+
+void StreamingControllerBase::StartPlaybackAsync(PlaybackStartedCB cb) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!playback_started_cb_);
+  DCHECK(cb);
+
+  playback_started_cb_ = std::move(cb);
+
+  TryStartPlayback();
+}
+
+void StreamingControllerBase::TryStartPlayback() {
+  if (playback_started_cb_ && constraints_ && cast_streaming_receiver_) {
+    cast_streaming::ReceiverSession::MessagePortProvider message_port_provider =
+        base::BindOnce(
+            [](std::unique_ptr<cast_api_bindings::MessagePort> port) {
+              return port;
+            },
+            std::move(message_port_));
+    receiver_session_ = cast_streaming::ReceiverSession::Create(
+        std::move(constraints_), std::move(message_port_provider), client_);
+    DCHECK(receiver_session_);
+
+    StartPlayback(receiver_session_.get(), std::move(cast_streaming_receiver_),
+                  std::move(renderer_connection_));
+    std::move(playback_started_cb_).Run();
+  }
+}
+
+}  // namespace chromecast
diff --git a/chromecast/cast_core/runtime/browser/streaming_controller_base.h b/chromecast/cast_core/runtime/browser/streaming_controller_base.h
new file mode 100644
index 0000000..eca17cc
--- /dev/null
+++ b/chromecast/cast_core/runtime/browser/streaming_controller_base.h
@@ -0,0 +1,104 @@
+// Copyright 2022 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 CHROMECAST_CAST_CORE_RUNTIME_BROWSER_STREAMING_CONTROLLER_BASE_H_
+#define CHROMECAST_CAST_CORE_RUNTIME_BROWSER_STREAMING_CONTROLLER_BASE_H_
+
+#include "chromecast/cast_core/runtime/browser/streaming_controller.h"
+
+#include <memory>
+
+#include "base/sequence_checker.h"
+#include "chromecast/browser/cast_web_contents.h"
+#include "components/cast_streaming/browser/public/receiver_session.h"
+#include "components/cast_streaming/public/mojom/cast_streaming_session.mojom.h"
+#include "components/cast_streaming/public/mojom/renderer_controller.mojom.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+
+namespace cast_api_bindings {
+class MessagePort;
+}  // namespace cast_api_bindings
+
+namespace content {
+class NavigationHandle;
+}  // namespace content
+
+namespace chromecast {
+
+// This class provides an implementation of StreamingController using the types
+// provided in the cast_streaming component.
+class StreamingControllerBase : public StreamingController,
+                                public CastWebContents::Observer {
+ public:
+  static std::unique_ptr<StreamingController> Create(
+      std::unique_ptr<cast_api_bindings::MessagePort> message_port,
+      CastWebContents* cast_web_contents);
+
+  ~StreamingControllerBase() override;
+
+ protected:
+  StreamingControllerBase(
+      std::unique_ptr<cast_api_bindings::MessagePort> message_port,
+      CastWebContents* cast_web_contents);
+
+  // Begins playback of |receiver_session|.
+  virtual void StartPlayback(
+      cast_streaming::ReceiverSession* receiver_session,
+      mojo::AssociatedRemote<cast_streaming::mojom::CastStreamingReceiver>
+          cast_streaming_receiver,
+      mojo::AssociatedRemote<cast_streaming::mojom::RendererController>
+          renderer_connection) = 0;
+
+  // Makes any modifications or validations to |constraints| needed prior to the
+  // initialization of the streaming receiver.
+  virtual void ProcessAVConstraints(
+      cast_streaming::ReceiverSession::AVConstraints* constraints);
+
+ private:
+  // CastWebContents::Observer overrides:
+  void MainFrameReadyToCommitNavigation(
+      content::NavigationHandle* navigation_handle) final;
+
+  // Partial StreamingController overrides:
+  void InitializeReceiverSession(
+      std::unique_ptr<cast_streaming::ReceiverSession::AVConstraints>
+          constraints,
+      cast_streaming::ReceiverSession::Client* client) final;
+  void StartPlaybackAsync(PlaybackStartedCB cb) final;
+
+  // Starts playback if all of the following have occurred:
+  // - CreateReceiverSession() has been called.
+  // - StartPlaybackAsync() has been called.
+  // - The page associated with |cast_web_contents| as provided in the ctor is
+  //   ready to commit navigation.
+  void TryStartPlayback();
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  // Populated in StartPlaybackAsync().
+  PlaybackStartedCB playback_started_cb_;
+
+  // Populated in InitializeReceiverSession()
+  std::unique_ptr<cast_streaming::ReceiverSession::AVConstraints> constraints_;
+  cast_streaming::ReceiverSession::Client* client_;
+
+  // Mojo connections. Initially populated in MainFrameReadyToCommitNavigation()
+  // with connections to the Renderer process, and transferred to
+  // StartPlayback() when it is first called.
+  mojo::AssociatedRemote<cast_streaming::mojom::CastStreamingReceiver>
+      cast_streaming_receiver_;
+  mojo::AssociatedRemote<cast_streaming::mojom::RendererController>
+      renderer_connection_;
+
+  // Populated in the ctor, and used to create |receiver_session_| in
+  // TryStartPlayback().
+  std::unique_ptr<cast_api_bindings::MessagePort> message_port_;
+
+  // Created in CreateReceiverSession().
+  std::unique_ptr<cast_streaming::ReceiverSession> receiver_session_;
+};
+
+}  // namespace chromecast
+
+#endif  // CHROMECAST_CAST_CORE_RUNTIME_BROWSER_STREAMING_CONTROLLER_BASE_H_
diff --git a/chromecast/cast_core/runtime/browser/streaming_controller_factory_mirroring.cc b/chromecast/cast_core/runtime/browser/streaming_controller_factory_mirroring.cc
new file mode 100644
index 0000000..b18e41f9
--- /dev/null
+++ b/chromecast/cast_core/runtime/browser/streaming_controller_factory_mirroring.cc
@@ -0,0 +1,21 @@
+// Copyright 2022 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 <memory>
+
+#include "chromecast/cast_core/runtime/browser/streaming_controller_base.h"
+#include "chromecast/cast_core/runtime/browser/streaming_controller_mirroring.h"
+#include "components/cast/message_port/message_port.h"
+
+namespace chromecast {
+
+// static
+std::unique_ptr<StreamingController> StreamingControllerBase::Create(
+    std::unique_ptr<cast_api_bindings::MessagePort> message_port,
+    CastWebContents* cast_web_contents) {
+  return std::make_unique<StreamingControllerMirroring>(std::move(message_port),
+                                                        cast_web_contents);
+}
+
+}  // namespace chromecast
diff --git a/chromecast/cast_core/runtime/browser/streaming_controller_mirroring.cc b/chromecast/cast_core/runtime/browser/streaming_controller_mirroring.cc
new file mode 100644
index 0000000..b64612bd
--- /dev/null
+++ b/chromecast/cast_core/runtime/browser/streaming_controller_mirroring.cc
@@ -0,0 +1,45 @@
+// Copyright 2022 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 "chromecast/cast_core/runtime/browser/streaming_controller_mirroring.h"
+
+#include "components/cast/message_port/message_port.h"
+#include "components/cast_streaming/browser/public/receiver_session.h"
+
+namespace chromecast {
+
+StreamingControllerMirroring::StreamingControllerMirroring(
+    std::unique_ptr<cast_api_bindings::MessagePort> message_port,
+    CastWebContents* cast_web_contents)
+    : StreamingControllerBase(std::move(message_port), cast_web_contents) {}
+
+StreamingControllerMirroring::~StreamingControllerMirroring() = default;
+
+void StreamingControllerMirroring::StartPlayback(
+    cast_streaming::ReceiverSession* receiver_session,
+    mojo::AssociatedRemote<cast_streaming::mojom::CastStreamingReceiver>
+        cast_streaming_receiver,
+    mojo::AssociatedRemote<cast_streaming::mojom::RendererController>
+        renderer_connection) {
+  receiver_session->SetCastStreamingReceiver(
+      std::move(cast_streaming_receiver));
+
+  renderer_connection_ = std::move(renderer_connection);
+  renderer_connection_->SetPlaybackController(
+      renderer_controls_.BindNewPipeAndPassReceiver());
+  renderer_controls_->StartPlayingFrom(base::Seconds(0));
+  renderer_controls_->SetPlaybackRate(1.0);
+}
+
+void StreamingControllerMirroring::ProcessAVConstraints(
+    cast_streaming::ReceiverSession::AVConstraints* constraints) {
+  DCHECK(constraints);
+
+  // Ensure remoting is disabled for this streaming session.
+  DLOG_IF(INFO, constraints->remoting)
+      << "Remoting configuration removed from received AVConstraints";
+  constraints->remoting.reset();
+}
+
+}  // namespace chromecast
diff --git a/chromecast/cast_core/runtime/browser/streaming_controller_mirroring.h b/chromecast/cast_core/runtime/browser/streaming_controller_mirroring.h
new file mode 100644
index 0000000..45da2c8b
--- /dev/null
+++ b/chromecast/cast_core/runtime/browser/streaming_controller_mirroring.h
@@ -0,0 +1,57 @@
+// Copyright 2022 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 CHROMECAST_CAST_CORE_RUNTIME_BROWSER_STREAMING_CONTROLLER_MIRRORING_H_
+#define CHROMECAST_CAST_CORE_RUNTIME_BROWSER_STREAMING_CONTROLLER_MIRRORING_H_
+
+#include <memory>
+
+#include "chromecast/cast_core/runtime/browser/streaming_controller_base.h"
+#include "components/cast_streaming/public/mojom/cast_streaming_session.mojom.h"
+#include "components/cast_streaming/public/mojom/renderer_controller.mojom.h"
+#include "media/mojo/mojom/renderer.mojom.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+namespace cast_api_bindings {
+class MessagePort;
+}  // namespace cast_api_bindings
+
+namespace cast_streaming {
+class ReceiverSession;
+}  // namespace cast_streaming
+
+namespace chromecast {
+
+class CastWebContents;
+
+// This class provides an implementation of StreamingControllerBase using the
+// mirroring functionality provided in the cast_streaming component (but not its
+// remoting functionality).
+class StreamingControllerMirroring : public StreamingControllerBase {
+ public:
+  StreamingControllerMirroring(
+      std::unique_ptr<cast_api_bindings::MessagePort> message_port,
+      CastWebContents* cast_web_contents);
+  ~StreamingControllerMirroring() override;
+
+ private:
+  // StreamingControllerBase overrides:
+  void StartPlayback(
+      cast_streaming::ReceiverSession* receiver_session,
+      mojo::AssociatedRemote<cast_streaming::mojom::CastStreamingReceiver>
+          cast_streaming_receiver,
+      mojo::AssociatedRemote<cast_streaming::mojom::RendererController>
+          renderer_connection) override;
+  void ProcessAVConstraints(
+      cast_streaming::ReceiverSession::AVConstraints* constraints) override;
+
+  mojo::AssociatedRemote<cast_streaming::mojom::RendererController>
+      renderer_connection_;
+  mojo::Remote<media::mojom::Renderer> renderer_controls_;
+};
+
+}  // namespace chromecast
+
+#endif  // CHROMECAST_CAST_CORE_RUNTIME_BROWSER_STREAMING_CONTROLLER_MIRRORING_H_
diff --git a/chromecast/cast_core/runtime/browser/streaming_receiver_session_client.cc b/chromecast/cast_core/runtime/browser/streaming_receiver_session_client.cc
index 2f074e2..0425669 100644
--- a/chromecast/cast_core/runtime/browser/streaming_receiver_session_client.cc
+++ b/chromecast/cast_core/runtime/browser/streaming_receiver_session_client.cc
@@ -9,15 +9,11 @@
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/task/sequenced_task_runner.h"
+#include "chromecast/cast_core/runtime/browser/streaming_controller_base.h"
 #include "chromecast/shared/platform_info_serializer.h"
 #include "components/cast/message_port/platform_message_port.h"
 #include "components/cast_streaming/public/cast_streaming_url.h"
-#include "components/cast_streaming/public/mojom/cast_streaming_session.mojom.h"
-#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/render_frame_host.h"
 #include "media/base/video_decoder_config.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
-#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 #include "third_party/openscreen/src/cast/streaming/constants.h"
 
 namespace chromecast {
@@ -175,22 +171,6 @@
   return constraints;
 }
 
-std::unique_ptr<cast_streaming::ReceiverSession> CreateReceiverSession(
-    cast_streaming::ReceiverSession::Client* client,
-    std::unique_ptr<cast_api_bindings::MessagePort> message_port,
-    cast_streaming::ReceiverSession::AVConstraints constraints) {
-  cast_streaming::ReceiverSession::MessagePortProvider message_port_provider =
-      base::BindOnce(
-          [](std::unique_ptr<cast_api_bindings::MessagePort> port) {
-            return port;
-          },
-          std::move(message_port));
-  return cast_streaming::ReceiverSession::Create(
-      std::make_unique<cast_streaming::ReceiverSession::AVConstraints>(
-          std::move(constraints)),
-      std::move(message_port_provider), client);
-}
-
 }  // namespace
 
 constexpr base::TimeDelta
@@ -200,13 +180,15 @@
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     cast_streaming::NetworkContextGetter network_context_getter,
     std::unique_ptr<cast_api_bindings::MessagePort> message_port,
+    CastWebContents* cast_web_contents,
     Handler* handler,
     bool supports_audio,
     bool supports_video)
     : StreamingReceiverSessionClient(
           std::move(task_runner),
           std::move(network_context_getter),
-          base::BindOnce(&CreateReceiverSession, this, std::move(message_port)),
+          StreamingControllerBase::Create(std::move(message_port),
+                                          cast_web_contents),
           handler,
           supports_audio,
           supports_video) {}
@@ -214,19 +196,18 @@
 StreamingReceiverSessionClient::StreamingReceiverSessionClient(
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     cast_streaming::NetworkContextGetter network_context_getter,
-    ReceiverSessionFactory receiver_session_factory,
+    std::unique_ptr<StreamingController> streaming_controller,
     Handler* handler,
     bool supports_audio,
     bool supports_video)
     : handler_(handler),
       task_runner_(std::move(task_runner)),
-      receiver_session_factory_(std::move(receiver_session_factory)),
+      streaming_controller_(std::move(streaming_controller)),
       supports_audio_(supports_audio),
       supports_video_(supports_video),
       weak_factory_(this) {
   DCHECK(handler_);
   DCHECK(task_runner_);
-  DCHECK(receiver_session_factory_);
   DCHECK(!network_context_getter.is_null());
 
   cast_streaming::SetNetworkContextGetter(std::move(network_context_getter));
@@ -251,78 +232,37 @@
   DLOG(INFO) << "StreamingReceiverSessionClient state when destroyed"
              << "\n\tIs Healthy: " << is_healthy()
              << "\n\tLaunch called: " << is_streaming_launch_pending()
-             << "\n\tAV Settings Received: " << has_received_av_settings()
-             << "\n\tMojo Handle Acquired: "
-             << !!(streaming_state_ & LaunchState::kMojoHandleAcquired);
+             << "\n\tAV Settings Received: " << has_received_av_settings();
 
   cast_streaming::SetNetworkContextGetter({});
 }
 
 StreamingReceiverSessionClient::Handler::~Handler() = default;
 
-void StreamingReceiverSessionClient::LaunchStreamingReceiverAsync(
-    CastWebContents* cast_web_contents) {
+void StreamingReceiverSessionClient::LaunchStreamingReceiverAsync() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(cast_web_contents);
   DCHECK(!is_streaming_launch_pending());
 
   streaming_state_ |= LaunchState::kLaunchCalled;
-  Observe(cast_web_contents);
-}
-
-void StreamingReceiverSessionClient::MainFrameReadyToCommitNavigation(
-    content::NavigationHandle* navigation_handle) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(is_streaming_launch_pending());
-  DCHECK(navigation_handle);
-
-  // Check whether the mojo handle has been acquired. The page URL cannot be
-  // checked because the receiver app is expected to be loaded as an embedded
-  // video within the page, not as the page itself.
-  if (streaming_state_ & LaunchState::kMojoHandleAcquired) {
-    DLOG(WARNING) << "Mojo handle already acquired before page load: "
-                  << navigation_handle->GetURL();
-    return;
-  }
-
-  navigation_handle->GetRenderFrameHost()
-      ->GetRemoteAssociatedInterfaces()
-      ->GetInterface(&cast_streaming_receiver_);
-  streaming_state_ |= LaunchState::kMojoHandleAcquired;
-  DLOG(INFO) << "CastStreamingReceiver mojo pipe captured.";
-
-  if (!TryStartStreamingSession()) {
-    DCHECK(!has_received_av_settings());
-    DLOG(INFO) << "AV Settings not yet received. Waiting...";
-  }
-}
-
-bool StreamingReceiverSessionClient::TryStartStreamingSession() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!has_streaming_launched());
-  if (streaming_state_ != LaunchState::kReady) {
-    return false;
-  }
-
-  DCHECK(av_constraints_);
-  DCHECK(receiver_session_factory_);
-  receiver_session_ =
-      std::move(receiver_session_factory_).Run(*av_constraints_);
-  DCHECK(receiver_session_);
-  receiver_session_->SetCastStreamingReceiver(
-      std::move(cast_streaming_receiver_));
-
-  streaming_state_ = LaunchState::kLaunched;
-  handler_->OnStreamingSessionStarted();
-  return true;
+  streaming_controller_->StartPlaybackAsync(
+      base::BindOnce(&StreamingReceiverSessionClient::OnPlaybackStarted,
+                     weak_factory_.GetWeakPtr()));
 }
 
 void StreamingReceiverSessionClient::VerifyAVSettingsReceived() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!has_received_av_settings()) {
-    LOG(ERROR) << "AV Settings never received";
-    TriggerError();
+  if (streaming_state_ & LaunchState::kAVSettingsReceived) {
+    return;
   }
+
+  LOG(ERROR) << "AVSettings not received within the allocated amount of time";
+  TriggerError();
+}
+
+void StreamingReceiverSessionClient::OnPlaybackStarted() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  streaming_state_ |= LaunchState::kLaunched;
+  handler_->OnStreamingSessionStarted();
 }
 
 bool StreamingReceiverSessionClient::OnMessage(
@@ -363,7 +303,11 @@
   streaming_state_ |= LaunchState::kAVSettingsReceived;
   if (!has_streaming_launched()) {
     av_constraints_ = std::move(constraints);
-    TryStartStreamingSession();
+
+    streaming_controller_->InitializeReceiverSession(
+        std::make_unique<cast_streaming::ReceiverSession::AVConstraints>(
+            *av_constraints_),
+        this);
     return true;
   }
 
diff --git a/chromecast/cast_core/runtime/browser/streaming_receiver_session_client.h b/chromecast/cast_core/runtime/browser/streaming_receiver_session_client.h
index 67b397a..205cb7c 100644
--- a/chromecast/cast_core/runtime/browser/streaming_receiver_session_client.h
+++ b/chromecast/cast_core/runtime/browser/streaming_receiver_session_client.h
@@ -19,27 +19,26 @@
 class SequencedTaskRunner;
 }  // namespace base
 
-namespace content {
-class NavigationHandle;
-}  // namespace content
-
 namespace gfx {
 class Rect;
 }  // namespace gfx
 
 namespace media {
+class AudioDecoderConfig;
+class VideoDecoderConfig;
 struct VideoTransformation;
 }  // namespace media
 
 namespace chromecast {
 
+class StreamingController;
+
 // This class wraps all //components/cast_streaming functionality, only
 // expecting the caller to supply a MessagePortFactory. Internally, it
 // manages the lifetimes of cast streaming objects, and informs the caller
 // of important events. Methods in this class may not be called in parallel.
 class StreamingReceiverSessionClient
-    : public CastWebContents::Observer,
-      public cast_api_bindings::MessagePort::Receiver,
+    : public cast_api_bindings::MessagePort::Receiver,
       public cast_streaming::ReceiverSession::Client {
  public:
   class Handler {
@@ -76,6 +75,7 @@
       scoped_refptr<base::SequencedTaskRunner> task_runner,
       cast_streaming::NetworkContextGetter network_context_getter,
       std::unique_ptr<cast_api_bindings::MessagePort> message_port,
+      CastWebContents* cast_web_contents,
       Handler* handler,
       bool supports_audio,
       bool supports_video);
@@ -86,14 +86,15 @@
   // be called once. At time of calling, this instance will be set as the
   // observer of |cast_web_contents|, for which streaming will be started
   // following the latter of:
-  // - Navigation to an associated URL by |cast_web_contents|.
+  // - Navigation to an associated URL by |cast_web_contents| as provided in the
+  //   ctor.
   // - Receipt of supported AV Settings.
   // Following this call, the supported AV Settings are expected to remain
   // constant. If valid AV Settings have not been received within
   // |kMaxAVSettingsWaitTime| of this function call, it will be treated as an
   // unrecoverable error, and this instance will be placed in an undefined
   // state.
-  void LaunchStreamingReceiverAsync(CastWebContents* cast_web_contents);
+  void LaunchStreamingReceiverAsync();
 
   bool has_streaming_launched() const {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -118,20 +119,15 @@
  private:
   friend class StreamingReceiverSessionClientTest;
 
-  using ReceiverSessionFactory =
-      base::OnceCallback<std::unique_ptr<cast_streaming::ReceiverSession>(
-          cast_streaming::ReceiverSession::AVConstraints)>;
-
   enum LaunchState : int32_t {
     kStopped = 0x00,
 
-    // The three conditions which must be met for streaming to run.
+    // The two conditions which must be met for streaming to run.
     kLaunchCalled = 0x01 << 0,
     kAVSettingsReceived = 0x01 << 1,
-    kMojoHandleAcquired = 0x01 << 2,
 
     // Signifies that the above conditions have all been met.
-    kReady = kAVSettingsReceived | kLaunchCalled | kMojoHandleAcquired,
+    kReady = kAVSettingsReceived | kLaunchCalled,
 
     // Signifies that streaming has started.
     kLaunched = 0xFF,
@@ -144,7 +140,7 @@
   StreamingReceiverSessionClient(
       scoped_refptr<base::SequencedTaskRunner> task_runner,
       cast_streaming::NetworkContextGetter network_context_getter,
-      ReceiverSessionFactory factory,
+      std::unique_ptr<StreamingController> streaming_controller,
       Handler* handler,
       bool supports_audio,
       bool supports_video);
@@ -169,14 +165,8 @@
     return first = first & second;
   }
 
-  bool TryStartStreamingSession();
-  void VerifyAVSettingsReceived();
   void TriggerError();
 
-  // CastWebContents::Observer overrides.
-  void MainFrameReadyToCommitNavigation(
-      content::NavigationHandle* navigation_handle) override;
-
   // cast_api_bindings::MessagePort::Receiver overrides.
   bool OnMessage(base::StringPiece message,
                  std::vector<std::unique_ptr<cast_api_bindings::MessagePort>>
@@ -189,6 +179,11 @@
   void OnVideoConfigUpdated(
       const ::media::VideoDecoderConfig& video_config) override;
 
+  void VerifyAVSettingsReceived();
+
+  // Callback passed when calling StreamingController::StartPlayback().
+  void OnPlaybackStarted();
+
   // Handler for callbacks associated with this class. May be empty.
   Handler* const handler_;
 
@@ -201,19 +196,12 @@
   absl::optional<cast_streaming::ReceiverSession::AVConstraints>
       av_constraints_;
 
-  // The AssociatedRemote that must be provided when starting the
-  // |receiver_session_|.
-  mojo::AssociatedRemote<cast_streaming::mojom::CastStreamingReceiver>
-      cast_streaming_receiver_;
-
-  // Responsible for managing the streaming session.
-  std::unique_ptr<cast_streaming::ReceiverSession> receiver_session_;
-
   // MessagePort responsible for receiving AV Settings Bindings Messages.
   std::unique_ptr<cast_api_bindings::MessagePort> message_port_;
 
-  // Factory method used to create a receiver session.
-  ReceiverSessionFactory receiver_session_factory_;
+  // Responsible for initiating the streaming session and controlling its
+  // playback state.
+  std::unique_ptr<StreamingController> streaming_controller_;
 
   // Current state in initialization of |receiver_session_|.
   LaunchState streaming_state_ = LaunchState::kStopped;
diff --git a/chromecast/cast_core/runtime/browser/streaming_receiver_session_client_unittest.cc b/chromecast/cast_core/runtime/browser/streaming_receiver_session_client_unittest.cc
index d6307a8..f76dd9b 100644
--- a/chromecast/cast_core/runtime/browser/streaming_receiver_session_client_unittest.cc
+++ b/chromecast/cast_core/runtime/browser/streaming_receiver_session_client_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/test/task_environment.h"
 #include "chromecast/browser/test/mock_cast_web_view.h"
+#include "chromecast/cast_core/runtime/browser/streaming_controller.h"
 #include "chromecast/shared/platform_info_serializer.h"
 #include "components/cast_streaming/browser/public/receiver_session.h"
 #include "components/cast_streaming/public/mojom/cast_streaming_session.mojom.h"
@@ -25,14 +26,16 @@
 namespace chromecast {
 namespace {
 
-class MockReceiverSession : public cast_streaming::ReceiverSession {
+class MockStreamingController : public StreamingController {
  public:
-  ~MockReceiverSession() override = default;
+  ~MockStreamingController() override = default;
 
-  MOCK_METHOD1(SetCastStreamingReceiver,
-               void(mojo::AssociatedRemote<
-                    cast_streaming::mojom::CastStreamingReceiver>));
-  MOCK_METHOD1(SetClient, void(cast_streaming::ReceiverSession::Client*));
+  MOCK_METHOD2(
+      InitializeReceiverSession,
+      void(std::unique_ptr<cast_streaming::ReceiverSession::AVConstraints>,
+           cast_streaming::ReceiverSession::Client*));
+  MOCK_METHOD1(StartPlaybackAsync,
+               void(StreamingController::PlaybackStartedCB));
 };
 
 class MockStreamingReceiverSessionHandler
@@ -57,8 +60,9 @@
     // static function elsewhere in the codebase's tests.
     cast_streaming::ClearNetworkContextGetter();
 
-    auto receiver_session = std::make_unique<StrictMock<MockReceiverSession>>();
-    receiver_session_ = receiver_session.get();
+    auto streaming_controller =
+        std::make_unique<StrictMock<MockStreamingController>>();
+    streaming_controller_ = streaming_controller.get();
     EXPECT_CALL(handler_, StartAvSettingsQuery(_));
 
     // Note: Can't use make_unique<> because the private ctor is needed.
@@ -66,11 +70,12 @@
         task_environment_.GetMainThreadTaskRunner(),
         base::BindRepeating(
             []() -> network::mojom::NetworkContext* { return nullptr; }),
-        base::BindOnce(
-            &StreamingReceiverSessionClientTest::CreateReceiverSession,
-            base::Unretained(this), std::move(receiver_session)),
-        &handler_, true, true);
+        std::move(streaming_controller), &handler_, true, true);
     receiver_session_client_.reset(client);
+
+    ON_CALL(*streaming_controller_, InitializeReceiverSession(_, _))
+        .WillByDefault(Invoke(
+            this, &StreamingReceiverSessionClientTest::CreateReceiverSession));
   }
 
   ~StreamingReceiverSessionClientTest() {
@@ -80,12 +85,6 @@
   }
 
  protected:
-  void SetMojoHandleAcquired() {
-    receiver_session_client_->streaming_state_ =
-        receiver_session_client_->streaming_state_ |
-        StreamingReceiverSessionClient::LaunchState::kMojoHandleAcquired;
-  }
-
   bool PostMessage(base::StringPiece message) {
     return receiver_session_client_->OnMessage(message, {});
   }
@@ -95,36 +94,28 @@
   // create the MessagePort pair.
   void ResetMessagePort() { receiver_session_client_->message_port_.reset(); }
 
+  void CreateReceiverSession(
+      std::unique_ptr<cast_streaming::ReceiverSession::AVConstraints>
+          constraints,
+      cast_streaming::ReceiverSession::Client* client) {
+    session_constraints_ = *constraints;
+  }
+
   base::test::SingleThreadTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
-  MockCastWebView cast_web_view_;
-
   StrictMock<MockStreamingReceiverSessionHandler> handler_;
-  StrictMock<MockReceiverSession>* receiver_session_;
+  StrictMock<MockStreamingController>* streaming_controller_;
   std::unique_ptr<StreamingReceiverSessionClient> receiver_session_client_;
 
   // Set when the session is launched.
   cast_streaming::ReceiverSession::AVConstraints session_constraints_;
-
- private:
-  std::unique_ptr<cast_streaming::ReceiverSession> CreateReceiverSession(
-      std::unique_ptr<cast_streaming::ReceiverSession> ptr,
-      cast_streaming::ReceiverSession::AVConstraints constraints) {
-    session_constraints_ = constraints;
-    return ptr;
-  }
 };
 
 TEST_F(StreamingReceiverSessionClientTest, OnSingleValidMessageEmpty) {
-  receiver_session_client_->LaunchStreamingReceiverAsync(
-      cast_web_view_.cast_web_contents());
-  SetMojoHandleAcquired();
-
   PlatformInfoSerializer serializer;
   EXPECT_FALSE(receiver_session_client_->has_received_av_settings());
-  EXPECT_CALL(*receiver_session_, SetCastStreamingReceiver(_));
-  EXPECT_CALL(handler_, OnStreamingSessionStarted());
+  EXPECT_CALL(*streaming_controller_, InitializeReceiverSession(_, _));
   EXPECT_TRUE(PostMessage(serializer.Serialize()));
   EXPECT_TRUE(receiver_session_client_->has_received_av_settings());
 
@@ -134,15 +125,10 @@
 }
 
 TEST_F(StreamingReceiverSessionClientTest, OnSingleValidMessageNoCodecs) {
-  receiver_session_client_->LaunchStreamingReceiverAsync(
-      cast_web_view_.cast_web_contents());
-  SetMojoHandleAcquired();
-
   PlatformInfoSerializer serializer;
   serializer.SetMaxChannels(9);
   EXPECT_FALSE(receiver_session_client_->has_received_av_settings());
-  EXPECT_CALL(*receiver_session_, SetCastStreamingReceiver(_));
-  EXPECT_CALL(handler_, OnStreamingSessionStarted());
+  EXPECT_CALL(*streaming_controller_, InitializeReceiverSession(_, _));
   EXPECT_TRUE(PostMessage(serializer.Serialize()));
   EXPECT_TRUE(receiver_session_client_->has_received_av_settings());
 
@@ -153,10 +139,6 @@
 }
 
 TEST_F(StreamingReceiverSessionClientTest, OnSingleValidMessageWithCodecs) {
-  receiver_session_client_->LaunchStreamingReceiverAsync(
-      cast_web_view_.cast_web_contents());
-  SetMojoHandleAcquired();
-
   PlatformInfoSerializer serializer;
   std::vector<PlatformInfoSerializer::AudioCodecInfo> audio_infos;
   audio_infos.push_back(PlatformInfoSerializer::AudioCodecInfo{
@@ -184,8 +166,7 @@
   serializer.SetSupportedAudioCodecs(std::move(audio_infos));
   serializer.SetSupportedVideoCodecs(std::move(video_infos));
   EXPECT_FALSE(receiver_session_client_->has_received_av_settings());
-  EXPECT_CALL(*receiver_session_, SetCastStreamingReceiver(_));
-  EXPECT_CALL(handler_, OnStreamingSessionStarted());
+  EXPECT_CALL(*streaming_controller_, InitializeReceiverSession(_, _));
   EXPECT_TRUE(PostMessage(serializer.Serialize()));
   EXPECT_TRUE(receiver_session_client_->has_received_av_settings());
 
@@ -213,18 +194,20 @@
 }
 
 TEST_F(StreamingReceiverSessionClientTest, OnCapabilitiesDecrease) {
-  receiver_session_client_->LaunchStreamingReceiverAsync(
-      cast_web_view_.cast_web_contents());
-  SetMojoHandleAcquired();
-
   PlatformInfoSerializer serializer;
   serializer.SetMaxChannels(9);
   EXPECT_FALSE(receiver_session_client_->has_received_av_settings());
-  EXPECT_CALL(*receiver_session_, SetCastStreamingReceiver(_));
-  EXPECT_CALL(handler_, OnStreamingSessionStarted());
+  EXPECT_CALL(*streaming_controller_, InitializeReceiverSession(_, _));
   EXPECT_TRUE(PostMessage(serializer.Serialize()));
   EXPECT_TRUE(receiver_session_client_->has_received_av_settings());
 
+  EXPECT_CALL(*streaming_controller_, StartPlaybackAsync(_))
+      .WillOnce([](StreamingController::PlaybackStartedCB cb) {
+        std::move(cb).Run();
+      });
+  EXPECT_CALL(handler_, OnStreamingSessionStarted());
+  receiver_session_client_->LaunchStreamingReceiverAsync();
+
   serializer.SetMaxChannels(8);
   EXPECT_CALL(handler_, OnError());
   EXPECT_FALSE(PostMessage(serializer.Serialize()));
@@ -234,8 +217,10 @@
   EXPECT_FALSE(receiver_session_client_->is_streaming_launch_pending());
   EXPECT_FALSE(receiver_session_client_->has_streaming_launched());
   EXPECT_FALSE(receiver_session_client_->has_received_av_settings());
-  receiver_session_client_->LaunchStreamingReceiverAsync(
-      cast_web_view_.cast_web_contents());
+
+  EXPECT_CALL(*streaming_controller_, StartPlaybackAsync(_));
+  receiver_session_client_->LaunchStreamingReceiverAsync();
+
   EXPECT_TRUE(receiver_session_client_->is_streaming_launch_pending());
   EXPECT_FALSE(receiver_session_client_->has_streaming_launched());
   EXPECT_FALSE(receiver_session_client_->has_received_av_settings());
@@ -246,25 +231,4 @@
       StreamingReceiverSessionClient::kMaxAVSettingsWaitTime);
 }
 
-TEST_F(StreamingReceiverSessionClientTest, LaunchWhenAvSettingsReceived) {
-  EXPECT_CALL(handler_, OnStreamingSessionStarted());
-  EXPECT_FALSE(receiver_session_client_->is_streaming_launch_pending());
-  EXPECT_FALSE(receiver_session_client_->has_streaming_launched());
-  EXPECT_FALSE(receiver_session_client_->has_received_av_settings());
-  receiver_session_client_->LaunchStreamingReceiverAsync(
-      cast_web_view_.cast_web_contents());
-
-  EXPECT_TRUE(receiver_session_client_->is_streaming_launch_pending());
-  EXPECT_FALSE(receiver_session_client_->has_streaming_launched());
-  EXPECT_FALSE(receiver_session_client_->has_received_av_settings());
-  SetMojoHandleAcquired();
-
-  EXPECT_CALL(*receiver_session_, SetCastStreamingReceiver(_));
-  PlatformInfoSerializer serializer;
-  EXPECT_TRUE(PostMessage(serializer.Serialize()));
-  EXPECT_TRUE(receiver_session_client_->is_streaming_launch_pending());
-  EXPECT_TRUE(receiver_session_client_->has_streaming_launched());
-  EXPECT_TRUE(receiver_session_client_->has_received_av_settings());
-}
-
 }  // namespace chromecast
diff --git a/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc b/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc
index 9870f19..47037b5 100644
--- a/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc
+++ b/chromecast/cast_core/runtime/browser/streaming_runtime_application.cc
@@ -58,12 +58,7 @@
 
 void StreamingRuntimeApplication::OnStreamingSessionStarted() {
   LOG(INFO) << "Streaming session started for " << *this << "!";
-  has_started_streaming_ = true;
   SetApplicationStarted();
-
-  if (renderer_connection_) {
-    StartRenderer();
-  }
 }
 
 void StreamingRuntimeApplication::OnError() {
@@ -100,16 +95,14 @@
   message_port_service_->ConnectToPort(kCastTransportBindingName,
                                        std::move(client_port));
 
-  // Allow for capturing of the renderer controls mojo pipe.
-  Observe(cast_web_contents);
-
   // Initialize the streaming receiver.
   receiver_session_client_ = std::make_unique<StreamingReceiverSessionClient>(
-      task_runner(), network_context_getter_, std::move(server_port), this,
+      task_runner(), network_context_getter_, std::move(server_port),
+      cast_web_contents, this,
       /* supports_audio= */ app_config().app_id() !=
           openscreen::cast::GetIosAppStreamingAudioVideoAppId(),
       /* supports_video= */ true);
-  receiver_session_client_->LaunchStreamingReceiverAsync(cast_web_contents);
+  receiver_session_client_->LaunchStreamingReceiverAsync();
 
   std::string streaming_url =
       cast_streaming::GetCastStreamingMediaSourceUrl().spec();
@@ -132,34 +125,4 @@
   return true;
 }
 
-void StreamingRuntimeApplication::MainFrameReadyToCommitNavigation(
-    content::NavigationHandle* navigation_handle) {
-  DLOG(INFO)
-      << "Capturing CastStreamingRendererController remote pipe for URL: "
-      << navigation_handle->GetURL() << " in " << *this;
-
-  renderer_connection_.reset();
-  navigation_handle->GetRenderFrameHost()
-      ->GetRemoteAssociatedInterfaces()
-      ->GetInterface(&renderer_connection_);
-  DCHECK(renderer_connection_);
-
-  if (has_started_streaming_) {
-    StartRenderer();
-  }
-}
-
-void StreamingRuntimeApplication::StartRenderer() {
-  DCHECK(has_started_streaming_);
-  DCHECK(renderer_connection_);
-  DCHECK(!renderer_controls_.is_bound());
-
-  renderer_connection_->SetPlaybackController(
-      renderer_controls_.BindNewPipeAndPassReceiver());
-  renderer_controls_->StartPlayingFrom(base::Seconds(0));
-  renderer_controls_->SetPlaybackRate(1.0);
-
-  LOG(INFO) << "Starting CastStreamingRenderer playback for " << *this;
-}
-
 }  // namespace chromecast
diff --git a/chromecast/cast_core/runtime/browser/streaming_runtime_application.h b/chromecast/cast_core/runtime/browser/streaming_runtime_application.h
index 3fffdbb1..360c4fedf 100644
--- a/chromecast/cast_core/runtime/browser/streaming_runtime_application.h
+++ b/chromecast/cast_core/runtime/browser/streaming_runtime_application.h
@@ -9,10 +9,6 @@
 #include "chromecast/cast_core/runtime/browser/runtime_application_base.h"
 #include "chromecast/cast_core/runtime/browser/streaming_receiver_session_client.h"
 #include "components/cast_streaming/browser/public/network_context_getter.h"
-#include "components/cast_streaming/public/mojom/renderer_controller.mojom.h"
-#include "media/mojo/mojom/renderer.mojom.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
 
 namespace chromecast {
 
@@ -24,8 +20,7 @@
 
 class StreamingRuntimeApplication final
     : public RuntimeApplicationBase,
-      public StreamingReceiverSessionClient::Handler,
-      public CastWebContents::Observer {
+      public StreamingReceiverSessionClient::Handler {
  public:
   // |web_service| is expected to exist for the lifetime of this instance.
   StreamingRuntimeApplication(
@@ -54,20 +49,6 @@
       const gfx::Rect& size,
       const ::media::VideoTransformation& transformation) override;
 
-  // CastWebContents::Observer overrides.
-  void MainFrameReadyToCommitNavigation(
-      content::NavigationHandle* navigation_handle) override;
-
-  // Helper method to start playback using |renderer_connection_| and
-  // |renderer_controls_|.
-  void StartRenderer();
-
-  bool has_started_streaming_ = false;
-
-  mojo::AssociatedRemote<cast_streaming::mojom::RendererController>
-      renderer_connection_;
-  mojo::Remote<::media::mojom::Renderer> renderer_controls_;
-
   media::VideoPlaneController* video_plane_controller_;
 
   // Returns the network context used by |receiver_session_client_|.
diff --git a/chromecast/chromecast.gni b/chromecast/chromecast.gni
index 9f637b0..3dd3b9f 100644
--- a/chromecast/chromecast.gni
+++ b/chromecast/chromecast.gni
@@ -125,6 +125,10 @@
   # True to link in alternate build targets for the Cast Media Runtime.
   enable_cast_media_runtime = false
 
+  # True to use the remoting implementation of cast streaming for the cast web
+  # runtime (as opposed to the mirroring-only implementation).
+  enable_remoting_for_cwr = false
+
   # device specific string to append to User string.
   device_user_agent_suffix = ""
 }
diff --git a/chromecast/media/audio/cast_audio_manager_unittest.cc b/chromecast/media/audio/cast_audio_manager_unittest.cc
index 3299b1d0..010c119 100644
--- a/chromecast/media/audio/cast_audio_manager_unittest.cc
+++ b/chromecast/media/audio/cast_audio_manager_unittest.cc
@@ -213,7 +213,6 @@
   EXPECT_TRUE(stream);
   // Only run the rest of the test if the device supports AC3.
   if (stream->Open()) {
-    EXPECT_CALL(*mock_cma_backend_, Start(_)).WillOnce(Return(true));
     EXPECT_CALL(mock_source_callback_, OnMoreData(_, _, _, _))
         .WillRepeatedly(Invoke(OnMoreData));
     EXPECT_CALL(mock_source_callback_, OnError(_)).Times(0);
@@ -225,6 +224,30 @@
   }
   stream->Close();
 }
+
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+TEST_F(CastAudioManagerTest, CanMakeDTSStream) {
+  const ::media::AudioParameters kDTSAudioParams(
+      ::media::AudioParameters::AUDIO_BITSTREAM_DTS,
+      ::media::CHANNEL_LAYOUT_5_1, ::media::AudioParameters::kAudioCDSampleRate,
+      256);
+  ::media::AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream(
+      kDTSAudioParams, "", ::media::AudioManager::LogCallback());
+  EXPECT_TRUE(stream);
+  // Only run the rest of the test if the device supports DTS.
+  if (stream->Open()) {
+    EXPECT_CALL(mock_source_callback_, OnMoreData(_, _, _, _))
+        .WillRepeatedly(Invoke(OnMoreData));
+    EXPECT_CALL(mock_source_callback_, OnError(_)).Times(0);
+    stream->Start(&mock_source_callback_);
+    RunThreadsUntilIdle();
+
+    stream->Stop();
+    RunThreadsUntilIdle();
+  }
+  stream->Close();
+}
+#endif  // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO))
 #endif  // BUILDFLAG(IS_ANDROID)
 
 TEST_F(CastAudioManagerTest, DISABLED_CanMakeStreamProxy) {
diff --git a/chromecast/media/base/media_codec_support.cc b/chromecast/media/base/media_codec_support.cc
index edd24f1..9d1e7308 100644
--- a/chromecast/media/base/media_codec_support.cc
+++ b/chromecast/media/base/media_codec_support.cc
@@ -29,6 +29,10 @@
       return kCodecEAC3;
     case ::media::AudioCodec::kAC3:
       return kCodecAC3;
+    case ::media::AudioCodec::kDTS:
+      return kCodecDTS;
+    case ::media::AudioCodec::kDTSXP2:
+      return kCodecDTSXP2;
     case ::media::AudioCodec::kFLAC:
       return kCodecFLAC;
     case ::media::AudioCodec::kMpegHAudio:
diff --git a/chromecast/media/cma/base/decoder_config_adapter.cc b/chromecast/media/cma/base/decoder_config_adapter.cc
index cd265854..58be50c3 100644
--- a/chromecast/media/cma/base/decoder_config_adapter.cc
+++ b/chromecast/media/cma/base/decoder_config_adapter.cc
@@ -41,6 +41,10 @@
       return kCodecAC3;
     case ::media::AudioCodec::kMpegHAudio:
       return kCodecMpegHAudio;
+    case ::media::AudioCodec::kDTS:
+      return kCodecDTS;
+    case ::media::AudioCodec::kDTSXP2:
+      return kCodecDTSXP2;
     default:
       LOG(ERROR) << "Unsupported audio codec " << audio_codec;
   }
@@ -132,6 +136,10 @@
       return ::media::AudioCodec::kAC3;
     case kCodecMpegHAudio:
       return ::media::AudioCodec::kMpegHAudio;
+    case kCodecDTS:
+      return ::media::AudioCodec::kDTS;
+    case kCodecDTSXP2:
+      return ::media::AudioCodec::kDTSXP2;
     default:
       return ::media::AudioCodec::kUnknown;
   }
diff --git a/chromecast/media/common/base/decoder_config_logging.cc b/chromecast/media/common/base/decoder_config_logging.cc
index 4dd08704..9b1eed2 100644
--- a/chromecast/media/common/base/decoder_config_logging.cc
+++ b/chromecast/media/common/base/decoder_config_logging.cc
@@ -29,6 +29,8 @@
       return stream << "AC3";
     case ::chromecast::media::kCodecDTS:
       return stream << "DTS";
+    case ::chromecast::media::kCodecDTSXP2:
+      return stream << "DTS:X Profile 2";
     case ::chromecast::media::kCodecFLAC:
       return stream << "FLAC";
     case ::chromecast::media::kCodecMpegHAudio:
diff --git a/chromecast/media/mojom/decoder_config_mojom_traits.h b/chromecast/media/mojom/decoder_config_mojom_traits.h
index 6450af6f..9f34977 100644
--- a/chromecast/media/mojom/decoder_config_mojom_traits.h
+++ b/chromecast/media/mojom/decoder_config_mojom_traits.h
@@ -36,6 +36,8 @@
         return chromecast::media::mojom::AudioCodec::kCodecAC3;
       case (chromecast::media::AudioCodec::kCodecDTS):
         return chromecast::media::mojom::AudioCodec::kCodecDTS;
+      case (chromecast::media::AudioCodec::kCodecDTSXP2):
+        return chromecast::media::mojom::AudioCodec::kCodecDTSXP2;
       case (chromecast::media::AudioCodec::kCodecFLAC):
         return chromecast::media::mojom::AudioCodec::kCodecFLAC;
       case (chromecast::media::AudioCodec::kCodecMpegHAudio):
@@ -78,6 +80,9 @@
       case (chromecast::media::mojom::AudioCodec::kCodecDTS):
         *output = chromecast::media::AudioCodec::kCodecDTS;
         return true;
+      case (chromecast::media::mojom::AudioCodec::kCodecDTSXP2):
+        *output = chromecast::media::AudioCodec::kCodecDTSXP2;
+        return true;
       case (chromecast::media::mojom::AudioCodec::kCodecFLAC):
         *output = chromecast::media::AudioCodec::kCodecFLAC;
         return true;
diff --git a/chromecast/media/mojom/media_types.mojom b/chromecast/media/mojom/media_types.mojom
index ba4cfc2..113fabd 100644
--- a/chromecast/media/mojom/media_types.mojom
+++ b/chromecast/media/mojom/media_types.mojom
@@ -15,6 +15,7 @@
   kCodecEAC3,
   kCodecAC3,
   kCodecDTS,
+  kCodecDTSXP2,
   kCodecFLAC,
   kCodecMpegHAudio,
 };
diff --git a/chromecast/public/media/decoder_config.h b/chromecast/public/media/decoder_config.h
index 67479d643..67e572d 100644
--- a/chromecast/public/media/decoder_config.h
+++ b/chromecast/public/media/decoder_config.h
@@ -34,9 +34,10 @@
   kCodecDTS,
   kCodecFLAC,
   kCodecMpegHAudio,
+  kCodecDTSXP2,
 
   kAudioCodecMin = kAudioCodecUnknown,
-  kAudioCodecMax = kCodecMpegHAudio,
+  kAudioCodecMax = kCodecDTSXP2,
 };
 
 enum class ChannelLayout {
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index 7e22d67..2dce735 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -74,6 +74,10 @@
           (kBitstreamAudioCodecAc3 & mask)) ||
          (codec == ::media::AudioCodec::kEAC3 &&
           (kBitstreamAudioCodecEac3 & mask)) ||
+         (codec == ::media::AudioCodec::kDTS &&
+          (kBitstreamAudioCodecDts & mask)) ||
+         (codec == ::media::AudioCodec::kDTSXP2 &&
+          (kBitstreamAudioCodecDtsXP2 & mask)) ||
          (codec == ::media::AudioCodec::kMpegHAudio &&
           (kBitstreamAudioCodecMpegHAudio & mask));
 }
@@ -253,6 +257,14 @@
     return kBitstreamAudioCodecAc3 &
            supported_bitstream_audio_codecs_info_.codecs;
   }
+  if (type.codec == ::media::AudioCodec::kDTS) {
+    return kBitstreamAudioCodecDts &
+           supported_bitstream_audio_codecs_info_.codecs;
+  }
+  if (type.codec == ::media::AudioCodec::kDTSXP2) {
+    return kBitstreamAudioCodecDtsXP2 &
+           supported_bitstream_audio_codecs_info_.codecs;
+  }
   if (type.codec == ::media::AudioCodec::kMpegHAudio) {
     return kBitstreamAudioCodecMpegHAudio &
            supported_bitstream_audio_codecs_info_.codecs;
diff --git a/chromecast/renderer/media/key_systems_cast.cc b/chromecast/renderer/media/key_systems_cast.cc
index 81f9b908..9a6ab97 100644
--- a/chromecast/renderer/media/key_systems_cast.cc
+++ b/chromecast/renderer/media/key_systems_cast.cc
@@ -141,6 +141,10 @@
   codecs |= ::media::EME_CODEC_AC3 | ::media::EME_CODEC_EAC3;
 #endif  // BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
 
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+  codecs |= ::media::EME_CODEC_DTS | ::media::EME_CODEC_DTSXP2;
+#endif  // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+
 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
   codecs |= ::media::EME_CODEC_MPEG_H_AUDIO;
 #endif  // BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
diff --git a/chromecast/ui/media_overlay_impl.cc b/chromecast/ui/media_overlay_impl.cc
index 667a9f5..720b984 100644
--- a/chromecast/ui/media_overlay_impl.cc
+++ b/chromecast/ui/media_overlay_impl.cc
@@ -195,6 +195,8 @@
     const ::media::AudioDecoderConfig& config) {
   if (config.codec() == ::media::AudioCodec::kAC3 ||
       config.codec() == ::media::AudioCodec::kEAC3 ||
+      config.codec() == ::media::AudioCodec::kDTS ||
+      config.codec() == ::media::AudioCodec::kDTSXP2 ||
       config.codec() == ::media::AudioCodec::kMpegHAudio) {
     passthrough_pipelines_.insert(pipeline);
   }
diff --git a/chromeos/components/BUILD.gn b/chromeos/components/BUILD.gn
index 8c8935c..c41601d7 100644
--- a/chromeos/components/BUILD.gn
+++ b/chromeos/components/BUILD.gn
@@ -41,13 +41,3 @@
     "//ui/resources:ui_test_pak_data",
   ]
 }
-
-group("closure_compile") {
-  testonly = true
-
-  # TODO(https://crbug.com/1164001): closure_compile deps should be moved to
-  # the appropriate place during the code migration project.
-  deps = [
-    "//chromeos/components/multidevice/debug_webui/resources:closure_compile",
-  ]
-}
diff --git a/chromeos/components/multidevice/debug_webui/BUILD.gn b/chromeos/components/multidevice/debug_webui/BUILD.gn
deleted file mode 100644
index 2ef0952..0000000
--- a/chromeos/components/multidevice/debug_webui/BUILD.gn
+++ /dev/null
@@ -1,38 +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.
-
-assert(is_chromeos, "Proximity Auth is Chrome OS only")
-
-static_library("debug_webui") {
-  sources = [
-    "proximity_auth_ui.cc",
-    "proximity_auth_ui.h",
-    "proximity_auth_webui_handler.cc",
-    "proximity_auth_webui_handler.h",
-    "url_constants.cc",
-    "url_constants.h",
-  ]
-
-  deps = [
-    "//ash/constants",
-    "//base",
-    "//base:i18n",
-    "//chromeos/components/multidevice/logging",
-    "//chromeos/resources",
-    "//chromeos/services/device_sync/proto",
-    "//chromeos/services/device_sync/proto:util",
-    "//chromeos/services/device_sync/public/cpp",
-    "//chromeos/services/multidevice_setup/public/mojom",
-    "//chromeos/services/secure_channel/public/cpp/client",
-    "//chromeos/services/secure_channel/public/mojom",
-    "//components/prefs",
-    "//components/resources",
-    "//content/public/browser",
-    "//device/bluetooth",
-    "//device/bluetooth/public/cpp",
-    "//ui/resources",
-    "//ui/webui",
-  ]
-  public_deps = [ "//chromeos/services/device_sync/public/mojom" ]
-}
diff --git a/chromeos/components/multidevice/debug_webui/DEPS b/chromeos/components/multidevice/debug_webui/DEPS
deleted file mode 100644
index e937e22c..0000000
--- a/chromeos/components/multidevice/debug_webui/DEPS
+++ /dev/null
@@ -1,7 +0,0 @@
-include_rules = [
-  "+chromeos/grit/chromeos_resources.h",
-  "+chromeos/services/multidevice_setup/public/mojom",
-  "+content/public/browser",
-  "+device/bluetooth",
-  "+ui/webui",
-]
diff --git a/chromeos/components/multidevice/debug_webui/proximity_auth_ui.cc b/chromeos/components/multidevice/debug_webui/proximity_auth_ui.cc
deleted file mode 100644
index 9fbbfdb2f..0000000
--- a/chromeos/components/multidevice/debug_webui/proximity_auth_ui.cc
+++ /dev/null
@@ -1,61 +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 "chromeos/components/multidevice/debug_webui/proximity_auth_ui.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.h"
-#include "chromeos/components/multidevice/debug_webui/url_constants.h"
-#include "chromeos/grit/chromeos_resources.h"
-#include "chromeos/services/device_sync/public/cpp/device_sync_client.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_ui.h"
-#include "content/public/browser/web_ui_data_source.h"
-
-namespace chromeos {
-
-namespace multidevice {
-
-ProximityAuthUI::ProximityAuthUI(
-    content::WebUI* web_ui,
-    device_sync::DeviceSyncClient* device_sync_client,
-    MultiDeviceSetupBinder multidevice_setup_binder)
-    : ui::MojoWebUIController(web_ui, true /* enable_chrome_send */),
-      multidevice_setup_binder_(std::move(multidevice_setup_binder)) {
-  content::WebUIDataSource* source =
-      content::WebUIDataSource::Create(kChromeUIProximityAuthHost);
-  source->SetDefaultResource(IDR_MULTIDEVICE_INDEX_HTML);
-  source->AddResourcePath("common.css", IDR_MULTIDEVICE_COMMON_CSS);
-  source->AddResourcePath("webui.js", IDR_MULTIDEVICE_WEBUI_JS);
-  source->AddResourcePath("logs.js", IDR_MULTIDEVICE_LOGS_JS);
-  source->AddResourcePath("proximity_auth.html",
-                          IDR_MULTIDEVICE_PROXIMITY_AUTH_HTML);
-  source->AddResourcePath("proximity_auth.css",
-                          IDR_MULTIDEVICE_PROXIMITY_AUTH_CSS);
-  source->AddResourcePath("proximity_auth.js",
-                          IDR_MULTIDEVICE_PROXIMITY_AUTH_JS);
-
-  content::BrowserContext* browser_context =
-      web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, source);
-  web_ui->AddMessageHandler(
-      std::make_unique<ProximityAuthWebUIHandler>(device_sync_client));
-}
-
-ProximityAuthUI::~ProximityAuthUI() = default;
-
-void ProximityAuthUI::BindInterface(
-    mojo::PendingReceiver<chromeos::multidevice_setup::mojom::MultiDeviceSetup>
-        receiver) {
-  multidevice_setup_binder_.Run(std::move(receiver));
-}
-
-WEB_UI_CONTROLLER_TYPE_IMPL(ProximityAuthUI)
-
-}  // namespace multidevice
-
-}  // namespace chromeos
diff --git a/chromeos/components/multidevice/debug_webui/proximity_auth_ui.h b/chromeos/components/multidevice/debug_webui/proximity_auth_ui.h
deleted file mode 100644
index faa751e..0000000
--- a/chromeos/components/multidevice/debug_webui/proximity_auth_ui.h
+++ /dev/null
@@ -1,54 +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 CHROMEOS_COMPONENTS_MULTIDEVICE_DEBUG_WEBUI_PROXIMITY_AUTH_UI_H_
-#define CHROMEOS_COMPONENTS_MULTIDEVICE_DEBUG_WEBUI_PROXIMITY_AUTH_UI_H_
-
-#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
-#include "content/public/browser/web_ui_controller.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "ui/webui/mojo_web_ui_controller.h"
-
-namespace chromeos {
-
-namespace device_sync {
-class DeviceSyncClient;
-}  // namespace device_sync
-
-namespace multidevice {
-
-// The WebUI controller for chrome://proximity-auth.
-class ProximityAuthUI : public ui::MojoWebUIController {
- public:
-  using MultiDeviceSetupBinder = base::RepeatingCallback<void(
-      mojo::PendingReceiver<multidevice_setup::mojom::MultiDeviceSetup>)>;
-
-  // Note: |web_ui| is not owned by this instance and must outlive this
-  // instance.
-  ProximityAuthUI(content::WebUI* web_ui,
-                  device_sync::DeviceSyncClient* device_sync_client,
-                  MultiDeviceSetupBinder multidevice_setup_binder);
-
-  ProximityAuthUI(const ProximityAuthUI&) = delete;
-  ProximityAuthUI& operator=(const ProximityAuthUI&) = delete;
-
-  ~ProximityAuthUI() override;
-
-  // Instantiates implementor of the mojom::MultiDeviceSetup mojo interface
-  // passing the pending receiver that will be internally bound.
-  void BindInterface(
-      mojo::PendingReceiver<multidevice_setup::mojom::MultiDeviceSetup>
-          receiver);
-
- private:
-  const MultiDeviceSetupBinder multidevice_setup_binder_;
-
-  WEB_UI_CONTROLLER_TYPE_DECL();
-};
-
-}  // namespace multidevice
-
-}  // namespace chromeos
-
-#endif  // CHROMEOS_COMPONENTS_MULTIDEVICE_DEBUG_WEBUI_PROXIMITY_AUTH_UI_H_
diff --git a/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.cc b/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.cc
deleted file mode 100644
index 5cd1c97..0000000
--- a/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.cc
+++ /dev/null
@@ -1,436 +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 "chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.h"
-
-#include <algorithm>
-#include <memory>
-#include <sstream>
-#include <utility>
-
-#include "base/base64url.h"
-#include "base/bind.h"
-#include "base/i18n/time_formatting.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/default_clock.h"
-#include "base/time/default_tick_clock.h"
-#include "base/values.h"
-#include "chromeos/components/multidevice/logging/logging.h"
-#include "chromeos/components/multidevice/software_feature_state.h"
-#include "chromeos/services/device_sync/proto/enum_util.h"
-#include "components/prefs/pref_service.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/web_ui.h"
-#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
-
-namespace chromeos {
-
-namespace multidevice {
-
-namespace {
-
-constexpr const multidevice::SoftwareFeature kAllSoftareFeatures[] = {
-    multidevice::SoftwareFeature::kBetterTogetherHost,
-    multidevice::SoftwareFeature::kBetterTogetherClient,
-    multidevice::SoftwareFeature::kSmartLockHost,
-    multidevice::SoftwareFeature::kSmartLockClient,
-    multidevice::SoftwareFeature::kInstantTetheringHost,
-    multidevice::SoftwareFeature::kInstantTetheringClient,
-    multidevice::SoftwareFeature::kMessagesForWebHost,
-    multidevice::SoftwareFeature::kMessagesForWebClient,
-    multidevice::SoftwareFeature::kPhoneHubHost,
-    multidevice::SoftwareFeature::kPhoneHubClient,
-    multidevice::SoftwareFeature::kWifiSyncHost,
-    multidevice::SoftwareFeature::kWifiSyncClient,
-    multidevice::SoftwareFeature::kEcheHost,
-    multidevice::SoftwareFeature::kEcheClient,
-    multidevice::SoftwareFeature::kPhoneHubCameraRollHost,
-    multidevice::SoftwareFeature::kPhoneHubCameraRollClient};
-
-// Keys in the JSON representation of a log message.
-const char kLogMessageTextKey[] = "text";
-const char kLogMessageTimeKey[] = "time";
-const char kLogMessageFileKey[] = "file";
-const char kLogMessageLineKey[] = "line";
-const char kLogMessageSeverityKey[] = "severity";
-
-// Keys in the JSON representation of a SyncState object for enrollment or
-// device sync.
-const char kSyncStateLastSuccessTime[] = "lastSuccessTime";
-const char kSyncStateNextRefreshTime[] = "nextRefreshTime";
-const char kSyncStateRecoveringFromFailure[] = "recoveringFromFailure";
-const char kSyncStateOperationInProgress[] = "operationInProgress";
-
-// 9999 days in milliseconds.
-const double kFakeInfinityMillis = 863913600000;
-
-double ConvertNextAttemptTimeToDouble(base::TimeDelta delta) {
-  // If no future attempt is scheduled, the next-attempt time is
-  // base::TimeDelta::Max(), which corresponds to an infinite double value. In
-  // order to store the next-attempt time as a double base::Value,
-  // std::isfinite() must be true. So, here we use 9999 days to represent the
-  // max next-attempt time to allow use with base::Value.
-  if (delta.is_max())
-    return kFakeInfinityMillis;
-
-  return delta.InMillisecondsF();
-}
-
-// Converts |log_message| to a raw dictionary value used as a JSON argument to
-// JavaScript functions.
-std::unique_ptr<base::DictionaryValue> LogMessageToDictionary(
-    const multidevice::LogBuffer::LogMessage& log_message) {
-  std::unique_ptr<base::DictionaryValue> dictionary(
-      new base::DictionaryValue());
-  dictionary->SetString(kLogMessageTextKey, log_message.text);
-  dictionary->SetString(
-      kLogMessageTimeKey,
-      base::TimeFormatTimeOfDayWithMilliseconds(log_message.time));
-  dictionary->SetString(kLogMessageFileKey, log_message.file);
-  dictionary->SetInteger(kLogMessageLineKey, log_message.line);
-  dictionary->SetInteger(kLogMessageSeverityKey,
-                         static_cast<int>(log_message.severity));
-  return dictionary;
-}
-
-// Keys in the JSON representation of an ExternalDeviceInfo proto.
-const char kExternalDevicePublicKey[] = "publicKey";
-const char kExternalDevicePublicKeyTruncated[] = "publicKeyTruncated";
-const char kExternalDeviceFriendlyName[] = "friendlyDeviceName";
-const char kExternalDeviceNoPiiName[] = "noPiiName";
-const char kExternalDeviceUnlockKey[] = "unlockKey";
-const char kExternalDeviceMobileHotspot[] = "hasMobileHotspot";
-const char kExternalDeviceFeatureStates[] = "featureStates";
-
-// Creates a SyncState JSON object that can be passed to the WebUI.
-std::unique_ptr<base::DictionaryValue> CreateSyncStateDictionary(
-    double last_success_time,
-    double next_refresh_time,
-    bool is_recovering_from_failure,
-    bool is_enrollment_in_progress) {
-  std::unique_ptr<base::DictionaryValue> sync_state(
-      new base::DictionaryValue());
-  sync_state->SetDoubleKey(kSyncStateLastSuccessTime, last_success_time);
-  sync_state->SetDoubleKey(kSyncStateNextRefreshTime, next_refresh_time);
-  sync_state->SetBoolean(kSyncStateRecoveringFromFailure,
-                         is_recovering_from_failure);
-  sync_state->SetBoolean(kSyncStateOperationInProgress,
-                         is_enrollment_in_progress);
-  return sync_state;
-}
-
-std::string GenerateFeaturesString(const multidevice::RemoteDeviceRef& device) {
-  std::stringstream ss;
-  ss << "{";
-
-  bool logged_feature = false;
-  for (const auto& software_feature : kAllSoftareFeatures) {
-    multidevice::SoftwareFeatureState state =
-        device.GetSoftwareFeatureState(software_feature);
-
-    // Only log features with values.
-    if (state == multidevice::SoftwareFeatureState::kNotSupported)
-      continue;
-
-    logged_feature = true;
-    ss << software_feature << ": " << state << ", ";
-  }
-
-  if (logged_feature)
-    ss.seekp(-2, ss.cur);  // Remove last ", " from the stream.
-
-  ss << "}";
-  return ss.str();
-}
-
-}  // namespace
-
-ProximityAuthWebUIHandler::ProximityAuthWebUIHandler(
-    device_sync::DeviceSyncClient* device_sync_client)
-    : device_sync_client_(device_sync_client),
-      web_contents_initialized_(false) {}
-
-ProximityAuthWebUIHandler::~ProximityAuthWebUIHandler() {
-  multidevice::LogBuffer::GetInstance()->RemoveObserver(this);
-
-  device_sync_client_->RemoveObserver(this);
-}
-
-void ProximityAuthWebUIHandler::RegisterMessages() {
-  web_ui()->RegisterDeprecatedMessageCallback(
-      "onWebContentsInitialized",
-      base::BindRepeating(&ProximityAuthWebUIHandler::OnWebContentsInitialized,
-                          base::Unretained(this)));
-
-  web_ui()->RegisterDeprecatedMessageCallback(
-      "clearLogBuffer",
-      base::BindRepeating(&ProximityAuthWebUIHandler::ClearLogBuffer,
-                          base::Unretained(this)));
-
-  web_ui()->RegisterDeprecatedMessageCallback(
-      "getLogMessages",
-      base::BindRepeating(&ProximityAuthWebUIHandler::GetLogMessages,
-                          base::Unretained(this)));
-
-  web_ui()->RegisterDeprecatedMessageCallback(
-      "getLocalState",
-      base::BindRepeating(&ProximityAuthWebUIHandler::GetLocalState,
-                          base::Unretained(this)));
-
-  web_ui()->RegisterDeprecatedMessageCallback(
-      "forceEnrollment",
-      base::BindRepeating(&ProximityAuthWebUIHandler::ForceEnrollment,
-                          base::Unretained(this)));
-
-  web_ui()->RegisterDeprecatedMessageCallback(
-      "forceDeviceSync",
-      base::BindRepeating(&ProximityAuthWebUIHandler::ForceDeviceSync,
-                          base::Unretained(this)));
-}
-
-void ProximityAuthWebUIHandler::OnLogMessageAdded(
-    const multidevice::LogBuffer::LogMessage& log_message) {
-  std::unique_ptr<base::DictionaryValue> dictionary =
-      LogMessageToDictionary(log_message);
-  web_ui()->CallJavascriptFunctionUnsafe("LogBufferInterface.onLogMessageAdded",
-                                         *dictionary);
-}
-
-void ProximityAuthWebUIHandler::OnLogBufferCleared() {
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "LogBufferInterface.onLogBufferCleared");
-}
-
-void ProximityAuthWebUIHandler::OnEnrollmentFinished() {
-  // OnGetDebugInfo() will call NotifyOnEnrollmentFinished() with the enrollment
-  // state info.
-  enrollment_update_waiting_for_debug_info_ = true;
-  device_sync_client_->GetDebugInfo(
-      base::BindOnce(&ProximityAuthWebUIHandler::OnGetDebugInfo,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-void ProximityAuthWebUIHandler::OnNewDevicesSynced() {
-  // OnGetDebugInfo() will call NotifyOnSyncFinished() with the device sync
-  // state info.
-  sync_update_waiting_for_debug_info_ = true;
-  device_sync_client_->GetDebugInfo(
-      base::BindOnce(&ProximityAuthWebUIHandler::OnGetDebugInfo,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-void ProximityAuthWebUIHandler::OnWebContentsInitialized(
-    const base::ListValue* args) {
-  if (!web_contents_initialized_) {
-    device_sync_client_->AddObserver(this);
-    multidevice::LogBuffer::GetInstance()->AddObserver(this);
-    web_contents_initialized_ = true;
-  }
-}
-
-void ProximityAuthWebUIHandler::GetLogMessages(const base::ListValue* args) {
-  base::ListValue json_logs;
-  for (const auto& log : *multidevice::LogBuffer::GetInstance()->logs()) {
-    json_logs.Append(LogMessageToDictionary(log));
-  }
-  web_ui()->CallJavascriptFunctionUnsafe("LogBufferInterface.onGotLogMessages",
-                                         json_logs);
-}
-
-void ProximityAuthWebUIHandler::ClearLogBuffer(const base::ListValue* args) {
-  // The OnLogBufferCleared() observer function will be called after the buffer
-  // is cleared.
-  multidevice::LogBuffer::GetInstance()->Clear();
-}
-
-void ProximityAuthWebUIHandler::ForceEnrollment(const base::ListValue* args) {
-  device_sync_client_->ForceEnrollmentNow(
-      base::BindOnce(&ProximityAuthWebUIHandler::OnForceEnrollmentNow,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-void ProximityAuthWebUIHandler::ForceDeviceSync(const base::ListValue* args) {
-  device_sync_client_->ForceSyncNow(
-      base::BindOnce(&ProximityAuthWebUIHandler::OnForceSyncNow,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-void ProximityAuthWebUIHandler::GetLocalState(const base::ListValue* args) {
-  // OnGetDebugInfo() will call NotifyGotLocalState() with the enrollment and
-  // device sync state info.
-  get_local_state_update_waiting_for_debug_info_ = true;
-  device_sync_client_->GetDebugInfo(
-      base::BindOnce(&ProximityAuthWebUIHandler::OnGetDebugInfo,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-std::unique_ptr<base::Value>
-ProximityAuthWebUIHandler::GetTruncatedLocalDeviceId() {
-  absl::optional<multidevice::RemoteDeviceRef> local_device_metadata =
-      device_sync_client_->GetLocalDeviceMetadata();
-
-  std::string device_id =
-      local_device_metadata
-          ? local_device_metadata->GetTruncatedDeviceIdForLogs()
-          : "Missing Device ID";
-
-  return std::make_unique<base::Value>(device_id);
-}
-
-std::unique_ptr<base::ListValue>
-ProximityAuthWebUIHandler::GetRemoteDevicesList() {
-  std::unique_ptr<base::ListValue> devices_list_value(new base::ListValue());
-
-  for (const auto& remote_device : device_sync_client_->GetSyncedDevices())
-    devices_list_value->Append(RemoteDeviceToDictionary(remote_device));
-
-  return devices_list_value;
-}
-
-std::unique_ptr<base::DictionaryValue>
-ProximityAuthWebUIHandler::RemoteDeviceToDictionary(
-    const multidevice::RemoteDeviceRef& remote_device) {
-  // Set the fields in the ExternalDeviceInfo proto.
-  std::unique_ptr<base::DictionaryValue> dictionary(
-      new base::DictionaryValue());
-  dictionary->SetString(kExternalDevicePublicKey, remote_device.GetDeviceId());
-  dictionary->SetString(kExternalDevicePublicKeyTruncated,
-                        remote_device.GetTruncatedDeviceIdForLogs());
-  dictionary->SetString(kExternalDeviceFriendlyName, remote_device.name());
-  dictionary->SetString(kExternalDeviceNoPiiName,
-                        remote_device.pii_free_name());
-  dictionary->SetBoolean(kExternalDeviceUnlockKey,
-                         remote_device.GetSoftwareFeatureState(
-                             multidevice::SoftwareFeature::kSmartLockHost) ==
-                             multidevice::SoftwareFeatureState::kEnabled);
-  dictionary->SetBoolean(
-      kExternalDeviceMobileHotspot,
-      remote_device.GetSoftwareFeatureState(
-          multidevice::SoftwareFeature::kInstantTetheringHost) ==
-          multidevice::SoftwareFeatureState::kSupported);
-  dictionary->SetString(kExternalDeviceFeatureStates,
-                        GenerateFeaturesString(remote_device));
-
-  return dictionary;
-}
-
-void ProximityAuthWebUIHandler::OnForceEnrollmentNow(bool success) {
-  PA_LOG(VERBOSE) << "Force enrollment result: " << success;
-}
-
-void ProximityAuthWebUIHandler::OnForceSyncNow(bool success) {
-  PA_LOG(VERBOSE) << "Force sync result: " << success;
-}
-
-void ProximityAuthWebUIHandler::OnSetSoftwareFeatureState(
-    const std::string public_key,
-    device_sync::mojom::NetworkRequestResult result_code) {
-  std::string device_id = RemoteDevice::GenerateDeviceId(public_key);
-
-  if (result_code == device_sync::mojom::NetworkRequestResult::kSuccess) {
-    PA_LOG(VERBOSE) << "Successfully set SoftwareFeature state for device: "
-                    << device_id;
-  } else {
-    PA_LOG(ERROR) << "Failed to set SoftwareFeature state for device: "
-                  << device_id << ", error code: " << result_code;
-  }
-}
-
-void ProximityAuthWebUIHandler::OnGetDebugInfo(
-    device_sync::mojom::DebugInfoPtr debug_info_ptr) {
-  // If enrollment is not yet complete, no debug information is available.
-  if (!debug_info_ptr)
-    return;
-
-  if (enrollment_update_waiting_for_debug_info_) {
-    enrollment_update_waiting_for_debug_info_ = false;
-    NotifyOnEnrollmentFinished(
-        true /* success */,
-        CreateSyncStateDictionary(
-            debug_info_ptr->last_enrollment_time.ToJsTime(),
-            ConvertNextAttemptTimeToDouble(
-                debug_info_ptr->time_to_next_enrollment_attempt),
-            debug_info_ptr->is_recovering_from_enrollment_failure,
-            debug_info_ptr->is_enrollment_in_progress));
-  }
-
-  if (sync_update_waiting_for_debug_info_) {
-    sync_update_waiting_for_debug_info_ = false;
-    NotifyOnSyncFinished(true /* was_sync_successful */, true /* changed */,
-                         CreateSyncStateDictionary(
-                             debug_info_ptr->last_sync_time.ToJsTime(),
-                             ConvertNextAttemptTimeToDouble(
-                                 debug_info_ptr->time_to_next_sync_attempt),
-                             debug_info_ptr->is_recovering_from_sync_failure,
-                             debug_info_ptr->is_sync_in_progress));
-  }
-
-  if (get_local_state_update_waiting_for_debug_info_) {
-    get_local_state_update_waiting_for_debug_info_ = false;
-    NotifyGotLocalState(
-        GetTruncatedLocalDeviceId(),
-        CreateSyncStateDictionary(
-            debug_info_ptr->last_enrollment_time.ToJsTime(),
-            ConvertNextAttemptTimeToDouble(
-                debug_info_ptr->time_to_next_enrollment_attempt),
-            debug_info_ptr->is_recovering_from_enrollment_failure,
-            debug_info_ptr->is_enrollment_in_progress),
-        CreateSyncStateDictionary(
-            debug_info_ptr->last_sync_time.ToJsTime(),
-            ConvertNextAttemptTimeToDouble(
-                debug_info_ptr->time_to_next_sync_attempt),
-            debug_info_ptr->is_recovering_from_sync_failure,
-            debug_info_ptr->is_sync_in_progress),
-        GetRemoteDevicesList());
-  }
-}
-
-void ProximityAuthWebUIHandler::NotifyOnEnrollmentFinished(
-    bool success,
-    std::unique_ptr<base::DictionaryValue> enrollment_state) {
-  PA_LOG(VERBOSE) << "Enrollment attempt completed with success=" << success
-                  << ":\n"
-                  << *enrollment_state;
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "LocalStateInterface.onEnrollmentStateChanged", *enrollment_state);
-}
-
-void ProximityAuthWebUIHandler::NotifyOnSyncFinished(
-    bool was_sync_successful,
-    bool changed,
-    std::unique_ptr<base::DictionaryValue> device_sync_state) {
-  PA_LOG(VERBOSE) << "Device sync completed with result=" << was_sync_successful
-                  << ":\n"
-                  << *device_sync_state;
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "LocalStateInterface.onDeviceSyncStateChanged", *device_sync_state);
-
-  if (changed) {
-    std::unique_ptr<base::ListValue> synced_devices = GetRemoteDevicesList();
-    PA_LOG(VERBOSE) << "New unlock keys obtained after device sync:\n"
-                    << *synced_devices;
-    web_ui()->CallJavascriptFunctionUnsafe(
-        "LocalStateInterface.onRemoteDevicesChanged", *synced_devices);
-  }
-}
-
-void ProximityAuthWebUIHandler::NotifyGotLocalState(
-    std::unique_ptr<base::Value> truncated_local_device_id,
-    std::unique_ptr<base::DictionaryValue> enrollment_state,
-    std::unique_ptr<base::DictionaryValue> device_sync_state,
-    std::unique_ptr<base::ListValue> synced_devices) {
-  PA_LOG(VERBOSE) << "==== Got Local State ====\n"
-                  << "Device ID (truncated): " << *truncated_local_device_id
-                  << "\nEnrollment State: \n"
-                  << *enrollment_state << "Device Sync State: \n"
-                  << *device_sync_state << "Synced devices: \n"
-                  << *synced_devices;
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "LocalStateInterface.onGotLocalState", *truncated_local_device_id,
-      *enrollment_state, *device_sync_state, *synced_devices);
-}
-
-}  // namespace multidevice
-
-}  // namespace chromeos
diff --git a/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.h b/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.h
deleted file mode 100644
index 65f902b..0000000
--- a/chromeos/components/multidevice/debug_webui/proximity_auth_webui_handler.h
+++ /dev/null
@@ -1,104 +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 CHROMEOS_COMPONENTS_MULTIDEVICE_DEBUG_WEBUI_PROXIMITY_AUTH_WEBUI_HANDLER_H_
-#define CHROMEOS_COMPONENTS_MULTIDEVICE_DEBUG_WEBUI_PROXIMITY_AUTH_WEBUI_HANDLER_H_
-
-#include "base/memory/weak_ptr.h"
-#include "base/values.h"
-#include "chromeos/components/multidevice/logging/log_buffer.h"
-#include "chromeos/components/multidevice/remote_device_ref.h"
-#include "chromeos/services/device_sync/public/cpp/device_sync_client.h"
-#include "content/public/browser/web_ui_message_handler.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-
-namespace base {
-class ListValue;
-}
-
-namespace chromeos {
-
-namespace multidevice {
-
-// Handles messages from the chrome://proximity-auth page.
-class ProximityAuthWebUIHandler
-    : public content::WebUIMessageHandler,
-      public multidevice::LogBuffer::Observer,
-      public device_sync::DeviceSyncClient::Observer {
- public:
-  explicit ProximityAuthWebUIHandler(
-      device_sync::DeviceSyncClient* device_sync_client);
-
-  ProximityAuthWebUIHandler(const ProximityAuthWebUIHandler&) = delete;
-  ProximityAuthWebUIHandler& operator=(const ProximityAuthWebUIHandler&) =
-      delete;
-
-  ~ProximityAuthWebUIHandler() override;
-
-  // content::WebUIMessageHandler:
-  void RegisterMessages() override;
-
- private:
-  // multidevice::LogBuffer::Observer:
-  void OnLogMessageAdded(
-      const multidevice::LogBuffer::LogMessage& log_message) override;
-  void OnLogBufferCleared() override;
-
-  // device_sync::DeviceSyncClient::Observer:
-  void OnEnrollmentFinished() override;
-  void OnNewDevicesSynced() override;
-
-  // Message handler callbacks.
-  void OnWebContentsInitialized(const base::ListValue* args);
-  void GetLogMessages(const base::ListValue* args);
-  void ClearLogBuffer(const base::ListValue* args);
-  void GetLocalState(const base::ListValue* args);
-  void ForceEnrollment(const base::ListValue* args);
-  void ForceDeviceSync(const base::ListValue* args);
-
-  std::unique_ptr<base::DictionaryValue> RemoteDeviceToDictionary(
-      const multidevice::RemoteDeviceRef& remote_device);
-
-  void OnForceEnrollmentNow(bool success);
-  void OnForceSyncNow(bool success);
-  void OnSetSoftwareFeatureState(
-      const std::string public_key,
-      device_sync::mojom::NetworkRequestResult result_code);
-  void OnGetDebugInfo(device_sync::mojom::DebugInfoPtr debug_info_ptr);
-
-  void NotifyOnEnrollmentFinished(
-      bool success,
-      std::unique_ptr<base::DictionaryValue> enrollment_state);
-  void NotifyOnSyncFinished(
-      bool was_sync_successful,
-      bool changed,
-      std::unique_ptr<base::DictionaryValue> device_sync_state);
-  void NotifyGotLocalState(
-      std::unique_ptr<base::Value> truncated_local_device_id,
-      std::unique_ptr<base::DictionaryValue> enrollment_state,
-      std::unique_ptr<base::DictionaryValue> device_sync_state,
-      std::unique_ptr<base::ListValue> synced_devices);
-
-  std::unique_ptr<base::Value> GetTruncatedLocalDeviceId();
-  std::unique_ptr<base::ListValue> GetRemoteDevicesList();
-
-  // The delegate used to fetch dependencies. Must outlive this instance.
-  device_sync::DeviceSyncClient* device_sync_client_;
-
-  // True if we get a message from the loaded WebContents to know that it is
-  // initialized, and we can inject JavaScript.
-  bool web_contents_initialized_;
-
-  bool enrollment_update_waiting_for_debug_info_ = false;
-  bool sync_update_waiting_for_debug_info_ = false;
-  bool get_local_state_update_waiting_for_debug_info_ = false;
-
-  base::WeakPtrFactory<ProximityAuthWebUIHandler> weak_ptr_factory_{this};
-};
-
-}  // namespace multidevice
-
-}  // namespace chromeos
-
-#endif  // CHROMEOS_COMPONENTS_MULTIDEVICE_DEBUG_WEBUI_PROXIMITY_AUTH_WEBUI_HANDLER_H_
diff --git a/chromeos/components/multidevice/debug_webui/resources/BUILD.gn b/chromeos/components/multidevice/debug_webui/resources/BUILD.gn
deleted file mode 100644
index 2f90aaa..0000000
--- a/chromeos/components/multidevice/debug_webui/resources/BUILD.gn
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright 2019 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.
-
-import("//third_party/closure_compiler/compile_js.gni")
-
-assert(is_chromeos, "Proximity Auth is Chrome OS only")
-
-js_type_check("closure_compile") {
-  deps = [
-    ":logs",
-    ":proximity_auth",
-    ":webui",
-  ]
-}
-
-js_library("webui") {
-  externs_list = [ "$externs_path/chrome_send.js" ]
-}
-
-js_library("logs") {
-  deps = [ ":webui" ]
-}
-
-js_library("proximity_auth") {
-  deps = [
-    ":logs",
-    ":webui",
-    "//chromeos/services/multidevice_setup/public/mojom:mojom_js_library_for_compile",
-  ]
-}
diff --git a/chromeos/components/multidevice/debug_webui/resources/logs.js b/chromeos/components/multidevice/debug_webui/resources/logs.js
deleted file mode 100644
index 0fda37e..0000000
--- a/chromeos/components/multidevice/debug_webui/resources/logs.js
+++ /dev/null
@@ -1,160 +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.
- */
-
-/**
- * @typedef {{
- *   text: string,
- *   time: string,
- *   file: string,
- *   line: number,
- *   severity: number,
- *}}
- */
-let Log;
-
-const Logs = {
-  controller_: null,
-
-  /**
-   * Initializes the logs UI.
-   */
-  init: function() {
-    Logs.controller_ = new LogsListController();
-
-    var clearLogsButton = document.getElementById('clear-logs-button');
-    clearLogsButton.onclick = function() {
-      WebUI.clearLogs();
-    };
-
-    var saveLogsButton = document.getElementById('save-logs-button');
-    saveLogsButton.onclick = () => {
-      Logs.saveLogs();
-    };
-
-    WebUI.getLogMessages();
-  },
-
-  saveLogs: function() {
-    var blob = new Blob(
-        [document.getElementById('logs-list').innerText],
-        {type: 'text/plain;charset=utf-8'});
-    var url = URL.createObjectURL(blob);
-
-    var anchorEl = document.createElement('a');
-    anchorEl.href = url;
-    anchorEl.download = 'proximity_auth_logs_' + new Date().toJSON() + '.txt';
-    document.body.appendChild(anchorEl);
-    anchorEl.click();
-
-    window.setTimeout(function() {
-      document.body.removeChild(anchorEl);
-      window.URL.revokeObjectURL(url);
-    }, 0);
-  },
-};
-
-/**
- * Interface with the native WebUI component for LogBuffer events. The functions
- * contained in this object will be invoked by the browser for each operation
- * performed on the native LogBuffer.
- */
-const LogBufferInterface = {
-  /**
-   * Called when a new log message is added.
-   * @param {!Log} log
-   */
-  onLogMessageAdded: function(log) {
-    if (Logs.controller_) {
-      Logs.controller_.add(log);
-    }
-  },
-
-  /**
-   * Called when the log buffer is cleared.
-   */
-  onLogBufferCleared: function() {
-    if (Logs.controller_) {
-      Logs.controller_.clear();
-    }
-  },
-
-  /**
-   * Called in response to chrome.send('getLogMessages') with the log messages
-   * currently in the buffer.
-   * @param {!Array<Log>} messages
-   */
-  onGotLogMessages: function(messages) {
-    if (Logs.controller_) {
-      Logs.controller_.set(messages);
-    }
-  },
-};
-
-/**
- * Controller for the logs list element, updating it based on user input and
- * logs received from native code.
- */
-class LogsListController {
-  constructor() {
-    this.logsList_ = document.getElementById('logs-list');
-    this.itemTemplate_ = document.getElementById('item-template');
-    this.shouldSnapToBottom_ = true;
-
-    this.logsList_.onscroll = this.onScroll_.bind(this);
-  }
-
-  /**
-   * Listener for scroll event of the logs list element, used for snap to bottom
-   * logic.
-   */
-  onScroll_() {
-    const list = this.logsList_;
-    this.shouldSnapToBottom_ =
-        list.scrollTop + list.offsetHeight == list.scrollHeight;
-  }
-
-  /**
-   * Clears all log items from the logs list.
-   */
-  clear() {
-    var items = this.logsList_.querySelectorAll('.log-item');
-    for (var i = 0; i < items.length; ++i) {
-      items[i].remove();
-    }
-    this.shouldSnapToBottom_ = true;
-  }
-
-  /**
-   * Adds a log to the logs list.
-   * @param {!Log} log
-   */
-  add(log) {
-    var directories = log.file.split('/');
-    var source = directories[directories.length - 1] + ':' + log.line;
-
-    var t = this.itemTemplate_.content;
-    t.querySelector('.log-item').attributes.severity.value = log.severity;
-    t.querySelector('.item-time').textContent = log.time;
-    t.querySelector('.item-source').textContent = source;
-    t.querySelector('.item-text').textContent = log.text;
-
-    var newLogItem = document.importNode(this.itemTemplate_.content, true);
-    this.logsList_.appendChild(newLogItem);
-    if (this.shouldSnapToBottom_) {
-      this.logsList_.scrollTop = this.logsList_.scrollHeight;
-    }
-  }
-
-  /**
-   * Initializes the log list from an array of logs.
-   * @param {!Array<!Log>} logs
-   */
-  set(logs) {
-    this.clear();
-    for (var i = 0; i < logs.length; ++i) {
-      this.add(logs[i]);
-    }
-  }
-}
diff --git a/chromeos/components/multidevice/debug_webui/resources/proximity_auth.js b/chromeos/components/multidevice/debug_webui/resources/proximity_auth.js
deleted file mode 100644
index 26618cc..0000000
--- a/chromeos/components/multidevice/debug_webui/resources/proximity_auth.js
+++ /dev/null
@@ -1,356 +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.
- */
-
-/**
- * An object containing information about the Chromebook's latest Enrollment or
- * DeviceSync call to the CryptAuth server.
- * @typedef {{
- *   lastSuccessTime: number,
- *   nextRefreshTime: number,
- *   recoveringFromFailure: boolean,
- *   operationInProgress: boolean,
- * }}
- */
-let SyncState;
-
-/**
- * @typedef {{
- *   userPresent: number,
- *   secureScreenLock: number,
- *   trustAgent: number,
- *}}
- */
-let RemoteState;
-
-/**
- * An object containing data for devices returned by CryptAuth DeviceSync.
- * @typedef {{
- *   publicKey: string,
- *   publicKeyTruncated: string,
- *   friendlyDeviceName: string,
- *   noPiiName: string,
- *   unlockKey: boolean,
- *   hasMobileHotspot: boolean,
- *   connectionStatus: string,
- *   featureStates: string,
- *   remoteState: (!RemoteState|undefined),
- *   isArcPlusPlusEnrollment: (boolean|undefined),
- *   isPixelPhone: (boolean|undefined),
- *   bluetoothAddress: (string|undefined),
- * }}
- */
-let RemoteDevice;
-
-const ProximityAuth = {
-  cryptauthController_: null,
-  remoteDevicesController_: null,
-
-  /**
-   * Initializes all UI elements of the ProximityAuth debug page.
-   */
-  init: function() {
-    ProximityAuth.cryptauthController_ = new CryptAuthController();
-    ProximityAuth.remoteDevicesController_ = new DeviceListController(
-        document.getElementById('remote-devices-control'));
-    WebUI.getLocalState();
-  }
-};
-
-/**
- * Controller for the CryptAuth controls section.
- */
-class CryptAuthController {
-  constructor() {
-    this.elements_ = {
-      localDeviceId: document.getElementById('local-device-id'),
-      gcmRegistration: document.getElementById('gcm-registration'),
-      currentEid: document.getElementById('current-eid'),
-      enrollmentTitle: document.getElementById('enrollment-title'),
-      lastEnrollment: document.getElementById('last-enrollment'),
-      nextEnrollment: document.getElementById('next-enrollment'),
-      enrollmentButton: document.getElementById('force-enrollment'),
-      deviceSyncTitle: document.getElementById('device-sync-title'),
-      lastDeviceSync: document.getElementById('last-device-sync'),
-      nextDeviceSync: document.getElementById('next-device-sync'),
-      deviceSyncButton: document.getElementById('force-device-sync'),
-      newUserNotifButton: document.getElementById('show-new-user-notif'),
-      existingUserNewHostNotifButton:
-          document.getElementById('show-existing-user-new-host-notif'),
-      existingUserNewChromebookNotifButton:
-          document.getElementById('show-existing-user-new-chromebook-notif'),
-    };
-
-    this.elements_.enrollmentButton.onclick = this.forceEnrollment_.bind(this);
-    this.elements_.deviceSyncButton.onclick = this.forceDeviceSync_.bind(this);
-    this.elements_.newUserNotifButton.onclick =
-        this.showNewUserNotification_.bind(this);
-    this.elements_.existingUserNewHostNotifButton.onclick =
-        this.showExistingUserNewHostNotification_.bind(this);
-    this.elements_.existingUserNewChromebookNotifButton.onclick =
-        this.showExistingUserNewChromebookNotification_.bind(this);
-
-    this.multiDeviceSetup =
-        chromeos.multideviceSetup.mojom.MultiDeviceSetup.getRemote();
-  }
-
-  /**
-   * Sets the local device's ID. Note that this value is truncated since the
-   * full value is very long and does not cleanly fit on the screen.
-   * @param {string} deviceIdTruncated
-   */
-  setLocalDeviceId(deviceIdTruncated) {
-    this.elements_.localDeviceId.textContent = deviceIdTruncated;
-  }
-
-  /**
-   * Update the enrollment state in the UI.
-   * @param {!SyncState} state
-   */
-  updateEnrollmentState(state) {
-    this.elements_.lastEnrollment.textContent =
-        this.getLastSyncTimeString_(state, 'Never enrolled');
-    this.elements_.nextEnrollment.textContent =
-        this.getNextRefreshString_(state);
-
-    if (state.recoveringFromFailure) {
-      this.elements_.enrollmentTitle.setAttribute('state', 'failure');
-    } else if (state.operationInProgress) {
-      this.elements_.enrollmentTitle.setAttribute('state', 'in-progress');
-    } else {
-      this.elements_.enrollmentTitle.setAttribute('state', 'synced');
-    }
-  }
-
-  /**
-   * Updates the device sync state in the UI.
-   * @param {!SyncState} state
-   */
-  updateDeviceSyncState(state) {
-    this.elements_.lastDeviceSync.textContent =
-        this.getLastSyncTimeString_(state, 'Never synced');
-    this.elements_.nextDeviceSync.textContent =
-        this.getNextRefreshString_(state);
-
-    if (state.recoveringFromFailure) {
-      this.elements_.deviceSyncTitle.setAttribute('state', 'failure');
-    } else if (state.operationInProgress) {
-      this.elements_.deviceSyncTitle.setAttribute('state', 'in-progress');
-    } else {
-      this.elements_.deviceSyncTitle.setAttribute('state', 'synced');
-    }
-  }
-
-  /**
-   * Returns the formatted string of the time of the last sync to be displayed.
-   * @param {!SyncState} syncState
-   * @return {string}
-   */
-  getLastSyncTimeString_(syncState, neverSyncedString) {
-    if (syncState.lastSuccessTime == 0)
-      return neverSyncedString;
-    var date = new Date(syncState.lastSuccessTime);
-    return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
-  }
-
-  /**
-   * Returns the formatted string of the next time to refresh to be displayed.
-   * @param {!SyncState} syncState
-   * @return {string}
-   */
-  getNextRefreshString_(syncState) {
-    var deltaMillis = syncState.nextRefreshTime;
-    if (deltaMillis == null)
-      return 'unknown';
-    if (deltaMillis == 0)
-      return 'sync in progress...';
-
-    var seconds = deltaMillis / 1000;
-    if (seconds < 60)
-      return Math.round(seconds) + ' seconds to refresh';
-
-    var minutes = seconds / 60;
-    if (minutes < 60)
-      return Math.round(minutes) + ' minutes to refresh';
-
-    var hours = minutes / 60;
-    if (hours < 24)
-      return Math.round(hours) + ' hours to refresh';
-
-    var days = hours / 24;
-    return Math.round(days) + ' days to refresh';
-  }
-
-  /**
-   * Forces a CryptAuth enrollment on button click.
-   */
-  forceEnrollment_() {
-    WebUI.forceEnrollment();
-  }
-
-  /**
-   * Forces a device sync on button click.
-   */
-  forceDeviceSync_() {
-    WebUI.forceDeviceSync();
-  }
-
-  /**
-   * Shows the "new user, potential host exists" notification.
-   */
-  showNewUserNotification_() {
-    this.showMultiDeviceSetupPromoNotification_(
-        chromeos.multideviceSetup.mojom.EventTypeForDebugging.
-            kNewUserPotentialHostExists);
-  }
-
-  /**
-   * Shows the "existing user, new host" notification.
-   */
-  showExistingUserNewHostNotification_() {
-    this.showMultiDeviceSetupPromoNotification_(
-        chromeos.multideviceSetup.mojom.EventTypeForDebugging.
-            kExistingUserConnectedHostSwitched);
-  }
-
-  /**
-   * Shows the "existing user, new Chromebook" notification.
-   */
-  showExistingUserNewChromebookNotification_() {
-    this.showMultiDeviceSetupPromoNotification_(
-        chromeos.multideviceSetup.mojom.EventTypeForDebugging.
-            kExistingUserNewChromebookAdded);
-  }
-
-  /**
-   * Shows a "MultiDevice Setup" notification of the given type.
-   * @param {!chromeos.multideviceSetup.mojom.EventTypeForDebugging} type
-   */
-  showMultiDeviceSetupPromoNotification_(type) {
-    this.multiDeviceSetup.triggerEventForDebugging(type).then(
-        function(responseParams) {
-          if (responseParams.success) {
-            console.log('Successfully triggered notification for type ' +
-                type + '.');
-          } else {
-            console.error('Failed to trigger notification for type ' + type +
-                '; no NotificationPresenter has been registered.');
-          }
-        }).catch(function(error) {
-          console.error('Failed to trigger notification type. ' + error);
-        });
-  }
-};
-
-/**
- * Controller for a list of remote devices. These lists are displayed in a
- * number of locations on the debug page.
- */
-class DeviceListController {
-  constructor(rootElement) {
-    this.rootElement_ = rootElement;
-    this.remoteDeviceTemplate_ =
-        document.getElementById('remote-device-template');
-  }
-
-  /**
-   * Updates the UI with the given remote devices.
-   * @param {!Array<!RemoteDevice>} remoteDevices
-   */
-  updateRemoteDevices(remoteDevices) {
-    var existingItems =
-        this.rootElement_.querySelectorAll('.remote-device');
-    for (var i = 0; i < existingItems.length; ++i) {
-      existingItems[i].remove();
-    }
-
-    for (var i = 0; i < remoteDevices.length; ++i) {
-      this.rootElement_.appendChild(
-          this.createRemoteDeviceItem_(remoteDevices[i]));
-    }
-
-    this.rootElement_.setAttribute('device-count', remoteDevices.length);
-  }
-
-  /**
-   * Creates a DOM element for a given remote device.
-   * @param {!RemoteDevice} remoteDevice
-   * @return {!Node}
-   */
-  createRemoteDeviceItem_(remoteDevice) {
-    var isUnlockKey = !!remoteDevice.unlockKey;
-    var hasMobileHotspot = !!remoteDevice.hasMobileHotspot;
-    var isArcPlusPlusEnrollment = !!remoteDevice.isArcPlusPlusEnrollment;
-    var isPixelPhone = !!remoteDevice.isPixelPhone;
-
-    var t = this.remoteDeviceTemplate_.content;
-    t.querySelector('.device-connection-status').setAttribute(
-        'state', remoteDevice.connectionStatus);
-    t.querySelector('.device-name').textContent =
-        remoteDevice.friendlyDeviceName;
-    t.querySelector('.no-pii-name').textContent =
-        remoteDevice.noPiiName;
-    t.querySelector('.device-id').textContent =
-        remoteDevice.publicKeyTruncated;
-    t.querySelector('.software-features').textContent =
-        remoteDevice.featureStates;
-    t.querySelector('.is-unlock-key').textContent = isUnlockKey;
-    t.querySelector('.supports-mobile-hotspot').textContent = hasMobileHotspot;
-    t.querySelector('.is-arc-plus-plus-enrollment').textContent =
-        isArcPlusPlusEnrollment;
-    t.querySelector('.is-pixel-phone').textContent = isPixelPhone;
-    if (!!remoteDevice.bluetoothAddress) {
-      t.querySelector('.bluetooth-address-row').classList.remove('hidden');
-      t.querySelector('.bluetooth-address').textContent =
-          remoteDevice.bluetoothAddress;
-    }
-
-    return document.importNode(this.remoteDeviceTemplate_.content, true);
-  }
-}
-
-/**
- * Interface for the native WebUI to call into our JS.
- */
-const LocalStateInterface = {
-  /**
-   * @param {string} localDeviceId
-   * @param {!SyncState} enrollmentState
-   * @param {!SyncState} deviceSyncState
-   * @param {!Array<!RemoteDevice>} remoteDevices
-   */
-  onGotLocalState: function(
-      localDeviceId, enrollmentState, deviceSyncState, remoteDevices) {
-    LocalStateInterface.setLocalDeviceId(localDeviceId);
-    LocalStateInterface.onEnrollmentStateChanged(enrollmentState);
-    LocalStateInterface.onDeviceSyncStateChanged(deviceSyncState);
-    LocalStateInterface.onRemoteDevicesChanged(remoteDevices);
-  },
-
-  /** @param {string} localDeviceId */
-  setLocalDeviceId: function(localDeviceId) {
-    ProximityAuth.cryptauthController_.setLocalDeviceId(localDeviceId);
-  },
-
-  /** @param {!SyncState} enrollmentState */
-  onEnrollmentStateChanged: function(enrollmentState) {
-    ProximityAuth.cryptauthController_.updateEnrollmentState(enrollmentState);
-  },
-
-  /** @param {!SyncState} deviceSyncState */
-  onDeviceSyncStateChanged: function(deviceSyncState) {
-    ProximityAuth.cryptauthController_.updateDeviceSyncState(deviceSyncState);
-  },
-
-  /** @param {!Array<!RemoteDevice>} remoteDevices */
-  onRemoteDevicesChanged: function(remoteDevices) {
-    ProximityAuth.remoteDevicesController_.updateRemoteDevices(remoteDevices);
-  }
-};
-
-document.addEventListener('DOMContentLoaded', function() {
-  WebUI.onWebContentsInitialized();
-  Logs.init();
-  ProximityAuth.init();
-});
diff --git a/chromeos/components/multidevice/debug_webui/url_constants.cc b/chromeos/components/multidevice/debug_webui/url_constants.cc
deleted file mode 100644
index 1f1b40e..0000000
--- a/chromeos/components/multidevice/debug_webui/url_constants.cc
+++ /dev/null
@@ -1,16 +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 "chromeos/components/multidevice/debug_webui/url_constants.h"
-
-namespace chromeos {
-
-namespace multidevice {
-
-const char kChromeUIProximityAuthHost[] = "proximity-auth";
-const char kChromeUIProximityAuthURL[] = "chrome://proximity-auth/";
-
-}  // namespace multidevice
-
-}  // namespace chromeos
diff --git a/chromeos/components/multidevice/debug_webui/url_constants.h b/chromeos/components/multidevice/debug_webui/url_constants.h
deleted file mode 100644
index 69ef992..0000000
--- a/chromeos/components/multidevice/debug_webui/url_constants.h
+++ /dev/null
@@ -1,19 +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 CHROMEOS_COMPONENTS_MULTIDEVICE_DEBUG_WEBUI_URL_CONSTANTS_H_
-#define CHROMEOS_COMPONENTS_MULTIDEVICE_DEBUG_WEBUI_URL_CONSTANTS_H_
-
-namespace chromeos {
-
-namespace multidevice {
-
-extern const char kChromeUIProximityAuthHost[];
-extern const char kChromeUIProximityAuthURL[];
-
-}  // namespace multidevice
-
-}  // namespace chromeos
-
-#endif  // CHROMEOS_COMPONENTS_MULTIDEVICE_DEBUG_WEBUI_URL_CONSTANTS_H_
diff --git a/chromeos/components/multidevice/logging/log_buffer.h b/chromeos/components/multidevice/logging/log_buffer.h
index 5bc1a69..b3b366df 100644
--- a/chromeos/components/multidevice/logging/log_buffer.h
+++ b/chromeos/components/multidevice/logging/log_buffer.h
@@ -85,4 +85,11 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when this file is moved to ash.
+namespace ash {
+namespace multidevice {
+using ::chromeos::multidevice::LogBuffer;
+}  // namespace multidevice
+}  // namespace ash
+
 #endif  // CHROMEOS_COMPONENTS_MULTIDEVICE_LOGGING_LOG_BUFFER_H_
diff --git a/chromeos/components/quick_answers/BUILD.gn b/chromeos/components/quick_answers/BUILD.gn
index b711602..4277c2f 100644
--- a/chromeos/components/quick_answers/BUILD.gn
+++ b/chromeos/components/quick_answers/BUILD.gn
@@ -92,6 +92,7 @@
     "//base/test:test_support",
     "//chromeos/components/quick_answers/public/cpp:cpp",
     "//chromeos/components/quick_answers/public/cpp:prefs",
+    "//chromeos/constants:constants",
     "//chromeos/services/assistant/public/shared",
     "//chromeos/services/machine_learning/public/cpp:stub",
     "//chromeos/services/machine_learning/public/mojom",
diff --git a/chromeos/components/quick_answers/search_result_loader.cc b/chromeos/components/quick_answers/search_result_loader.cc
index bc98c67a..7e41cc6 100644
--- a/chromeos/components/quick_answers/search_result_loader.cc
+++ b/chromeos/components/quick_answers/search_result_loader.cc
@@ -29,9 +29,6 @@
 //   "client_id": {
 //     "client_type": "EXPERIMENTAL"
 //   }
-//   "options": {
-//     "page_size": "1"
-//   }
 // }
 //
 // Which is:
@@ -40,17 +37,12 @@
 //      "raw_query": STRING
 //   "client_id": DICT
 //       "client_type": STRING
-//   "options": DICT
-//       "page_size": STRING
 
 constexpr base::StringPiece kQueryKey = "query";
 constexpr base::StringPiece kRawQueryKey = "rawQuery";
 constexpr base::StringPiece kClientTypeKey = "clientType";
 constexpr base::StringPiece kClientIdKey = "clientId";
 constexpr base::StringPiece kClientType = "QUICK_ANSWERS_CROS";
-constexpr base::StringPiece kPageSizeKey = "pageSize";
-constexpr base::StringPiece kOptionsKey = "options";
-constexpr base::StringPiece kPageSize = "1";
 
 std::string BuildSearchRequestPayload(const std::string& selected_text) {
   Value payload(Value::Type::DICTIONARY);
@@ -64,10 +56,6 @@
   client_id.SetKey(kClientTypeKey, Value(kClientType));
   payload.SetKey(kClientIdKey, std::move(client_id));
 
-  Value options(Value::Type::DICTIONARY);
-  options.SetKey(kPageSizeKey, Value(kPageSize));
-  payload.SetKey(kOptionsKey, std::move(options));
-
   std::string request_payload_str;
   base::JSONWriter::Write(payload, &request_payload_str);
 
diff --git a/chromeos/components/quick_answers/understanding/intent_generator.cc b/chromeos/components/quick_answers/understanding/intent_generator.cc
index ee69830..a7260a0 100644
--- a/chromeos/components/quick_answers/understanding/intent_generator.cc
+++ b/chromeos/components/quick_answers/understanding/intent_generator.cc
@@ -6,6 +6,7 @@
 
 #include <map>
 
+#include "base/i18n/break_iterator.h"
 #include "base/i18n/case_conversion.h"
 #include "base/no_destructor.h"
 #include "base/strings/string_split.h"
@@ -136,6 +137,26 @@
 }
 
 void IntentGenerator::GenerateIntent(const QuickAnswersRequest& request) {
+  if (chromeos::features::IsQuickAnswersAlwaysTriggerForSingleWord()) {
+    const std::u16string& u16_text = base::UTF8ToUTF16(request.selected_text);
+    base::i18n::BreakIterator iter(u16_text,
+                                   base::i18n::BreakIterator::BREAK_WORD);
+    if (!iter.Init() || !iter.Advance()) {
+      NOTREACHED() << "Failed to load BreakIterator.";
+
+      std::move(complete_callback_)
+          .Run(IntentInfo(request.selected_text, IntentType::kUnknown));
+      return;
+    }
+
+    // Generate dictionary intent if the selected text is a single word.
+    if (iter.IsWord() && iter.prev() == 0 && iter.pos() == u16_text.length()) {
+      std::move(complete_callback_)
+          .Run(IntentInfo(request.selected_text, IntentType::kDictionary));
+      return;
+    }
+  }
+
   if (QuickAnswersState::Get()->ShouldUseQuickAnswersTextAnnotator()) {
     // Load text classifier.
     chromeos::machine_learning::ServiceConnection::GetInstance()
@@ -151,6 +172,10 @@
       .Run(IntentInfo(request.selected_text, IntentType::kUnknown));
 }
 
+void IntentGenerator::FlushForTesting() {
+  text_classifier_.FlushForTesting();
+}
+
 void IntentGenerator::LoadModelCallback(const QuickAnswersRequest& request,
                                         LoadModelResult result) {
   if (result != LoadModelResult::OK) {
diff --git a/chromeos/components/quick_answers/understanding/intent_generator.h b/chromeos/components/quick_answers/understanding/intent_generator.h
index 1e3fbc7..d0f3c21 100644
--- a/chromeos/components/quick_answers/understanding/intent_generator.h
+++ b/chromeos/components/quick_answers/understanding/intent_generator.h
@@ -39,6 +39,9 @@
   // Generate intent from the |request|. Virtual for testing.
   virtual void GenerateIntent(const QuickAnswersRequest& request);
 
+  // Flush all relevant Mojo pipes.
+  void FlushForTesting();
+
  private:
   FRIEND_TEST_ALL_PREFIXES(IntentGeneratorTest,
                            TextAnnotationIntentNoAnnotation);
diff --git a/chromeos/components/quick_answers/understanding/intent_generator_unittest.cc b/chromeos/components/quick_answers/understanding/intent_generator_unittest.cc
index 59e1f2a..d0e0020 100644
--- a/chromeos/components/quick_answers/understanding/intent_generator_unittest.cc
+++ b/chromeos/components/quick_answers/understanding/intent_generator_unittest.cc
@@ -8,11 +8,13 @@
 #include <string>
 
 #include "base/bind.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h"
 #include "chromeos/components/quick_answers/quick_answers_model.h"
 #include "chromeos/components/quick_answers/test/quick_answers_test_base.h"
 #include "chromeos/components/quick_answers/utils/quick_answers_utils.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "chromeos/services/machine_learning/public/cpp/fake_service_connection.h"
 #include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h"
 #include "chromeos/services/machine_learning/public/mojom/text_classifier.mojom.h"
@@ -62,6 +64,12 @@
     intent_info_ = intent_info;
   }
 
+  // Flush all relevant Mojo pipes.
+  void FlushForTesting() {
+    intent_generator_->FlushForTesting();
+    fake_service_connection_.FlushForTesting();
+  }
+
  protected:
   void UseFakeServiceConnection(
       const std::vector<TextAnnotationPtr>& annotations =
@@ -93,7 +101,7 @@
   request.context.device_properties.preferred_languages = "es";
   intent_generator_->GenerateIntent(request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should generate translation intent.
   EXPECT_EQ(IntentType::kTranslation, intent_info_.intent_type);
@@ -113,7 +121,7 @@
   request.context.device_properties.preferred_languages = "en";
   intent_generator_->GenerateIntent(request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should not generate translation intent since the detected language is the
   // same as system language.
@@ -132,7 +140,7 @@
   request.context.device_properties.preferred_languages = "es,en,zh";
   intent_generator_->GenerateIntent(request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should not generate translation intent since the detected language is in
   // the preferred languages list.
@@ -151,7 +159,7 @@
   request.context.device_properties.preferred_languages = "es-MX,en-US,zh-CN";
   intent_generator_->GenerateIntent(request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should not generate translation intent since the detected language is in
   // the preferred languages list.
@@ -173,7 +181,7 @@
   request.context.device_properties.preferred_languages = "es";
   intent_generator_->GenerateIntent(request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should not generate translation intent since the length of the selected
   // text is above the threshold.
@@ -210,7 +218,7 @@
 
   intent_generator_->GenerateIntent(request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should generate dictionary intent which is prioritized against
   // translation.
@@ -227,7 +235,7 @@
   request.selected_text = "quick answers";
   intent_generator_->GenerateIntent(request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should not generate translation intent since the device language is not
   // set.
@@ -258,7 +266,7 @@
 
   intent_generator_->GenerateIntent(*quick_answers_request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should generate dictionary intent.
   EXPECT_EQ(IntentType::kDictionary, intent_info_.intent_type);
@@ -289,7 +297,7 @@
 
   intent_generator_->GenerateIntent(*quick_answers_request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should generate dictionary intent since the extra characters is below the
   // threshold.
@@ -321,7 +329,7 @@
 
   intent_generator_->GenerateIntent(*quick_answers_request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should not generate dictionary intent since the extra characters is above
   // the threshold.
@@ -352,7 +360,7 @@
 
   intent_generator_->GenerateIntent(*quick_answers_request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should generate unit conversion intent.
   EXPECT_EQ(IntentType::kUnit, intent_info_.intent_type);
@@ -382,7 +390,7 @@
 
   intent_generator_->GenerateIntent(*quick_answers_request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should generate unit conversion intent.
   EXPECT_EQ(IntentType::kUnit, intent_info_.intent_type);
@@ -412,7 +420,7 @@
 
   intent_generator_->GenerateIntent(*quick_answers_request);
 
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should not generate unit conversion intent since the extra characters is
   // above the threshold.
@@ -429,7 +437,7 @@
   UseFakeServiceConnection(annotations);
 
   intent_generator_->GenerateIntent(*quick_answers_request);
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should generate unknown intent since no annotation found.
   EXPECT_EQ(IntentType::kUnknown, intent_info_.intent_type);
@@ -451,7 +459,7 @@
   UseFakeServiceConnection(annotations);
 
   intent_generator_->GenerateIntent(*quick_answers_request);
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should generate unknown intent since no entity found.
   EXPECT_EQ(IntentType::kUnknown, intent_info_.intent_type);
@@ -479,10 +487,55 @@
   UseFakeServiceConnection(annotations);
 
   intent_generator_->GenerateIntent(*quick_answers_request);
-  task_environment_.RunUntilIdle();
+  FlushForTesting();
 
   // Should generate unknown intent unsupported entity is provided.
   EXPECT_EQ(IntentType::kUnknown, intent_info_.intent_type);
   EXPECT_EQ("the unfathomable reaches of space", intent_info_.intent_text);
 }
+
+TEST_F(IntentGeneratorTest, ShouldTriggerForSingleWord) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      chromeos::features::kQuickAnswersAlwaysTriggerForSingleWord);
+
+  // No Annotation provided.
+  std::vector<TextAnnotationPtr> annotations;
+  UseFakeServiceConnection(annotations);
+
+  // Single word selected.
+  std::unique_ptr<QuickAnswersRequest> quick_answers_request =
+      std::make_unique<QuickAnswersRequest>();
+  quick_answers_request->selected_text = "single";
+
+  intent_generator_->GenerateIntent(*quick_answers_request);
+  task_environment_.RunUntilIdle();
+
+  // Should generate dictionary intent for single word.
+  EXPECT_EQ(IntentType::kDictionary, intent_info_.intent_type);
+  EXPECT_EQ("single", intent_info_.intent_text);
+}
+
+TEST_F(IntentGeneratorTest, ShouldNotTriggerForMultipleWords) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      chromeos::features::kQuickAnswersAlwaysTriggerForSingleWord);
+
+  // No Annotation provided.
+  std::vector<TextAnnotationPtr> annotations;
+  UseFakeServiceConnection(annotations);
+
+  // Multiple words selected.
+  std::unique_ptr<QuickAnswersRequest> quick_answers_request =
+      std::make_unique<QuickAnswersRequest>();
+  quick_answers_request->selected_text = "multiple words";
+
+  intent_generator_->GenerateIntent(*quick_answers_request);
+  task_environment_.RunUntilIdle();
+
+  // Should fallback to unknown intent.
+  EXPECT_EQ(IntentType::kUnknown, intent_info_.intent_type);
+  EXPECT_EQ("multiple words", intent_info_.intent_text);
+}
+
 }  // namespace quick_answers
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index 8a9cc785f..d1bc723 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -35,6 +35,11 @@
 const base::Feature kQuickAnswersV2SettingsSubToggle{
     "QuickAnswersV2SettingsSubToggle", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Controls whether to always trigger Quick Answers with single word selection.
+const base::Feature kQuickAnswersAlwaysTriggerForSingleWord{
+    "QuickAnswersAlwaysTriggerForSingleWord",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 bool IsBluetoothAdvertisementMonitoringEnabled() {
   return base::FeatureList::IsEnabled(kBluetoothAdvertisementMonitoring);
 }
@@ -51,5 +56,9 @@
   return base::FeatureList::IsEnabled(kQuickAnswersV2SettingsSubToggle);
 }
 
+bool IsQuickAnswersAlwaysTriggerForSingleWord() {
+  return base::FeatureList::IsEnabled(kQuickAnswersAlwaysTriggerForSingleWord);
+}
+
 }  // namespace features
 }  // namespace chromeos
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h
index 9c939cd..5acdd039 100644
--- a/chromeos/constants/chromeos_features.h
+++ b/chromeos/constants/chromeos_features.h
@@ -31,6 +31,8 @@
 extern const base::Feature kDisableQuickAnswersV2Translation;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kQuickAnswersV2SettingsSubToggle;
+COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
+extern const base::Feature kQuickAnswersAlwaysTriggerForSingleWord;
 
 // Keep alphabetized.
 
@@ -40,6 +42,8 @@
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsQuickAnswersV2TranslationDisabled();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 bool IsQuickAnswersV2SettingsSubToggleEnabled();
+COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
+bool IsQuickAnswersAlwaysTriggerForSingleWord();
 
 }  // namespace features
 }  // namespace chromeos
diff --git a/chromeos/crosapi/mojom/BUILD.gn b/chromeos/crosapi/mojom/BUILD.gn
index d0bc556..095fe31f 100644
--- a/chromeos/crosapi/mojom/BUILD.gn
+++ b/chromeos/crosapi/mojom/BUILD.gn
@@ -39,6 +39,7 @@
     "keystore_error.mojom",
     "keystore_service.mojom",
     "kiosk_session_service.mojom",
+    "launcher_search.mojom",
     "local_printer.mojom",
     "login_state.mojom",
     "message_center.mojom",
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom
index ecb0c74..82120d3 100644
--- a/chromeos/crosapi/mojom/crosapi.mojom
+++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -32,6 +32,7 @@
 import "chromeos/crosapi/mojom/idle_service.mojom";
 import "chromeos/crosapi/mojom/image_writer.mojom";
 import "chromeos/crosapi/mojom/keystore_service.mojom";
+import "chromeos/crosapi/mojom/launcher_search.mojom";
 import "chromeos/crosapi/mojom/local_printer.mojom";
 import "chromeos/crosapi/mojom/login_state.mojom";
 import "chromeos/crosapi/mojom/policy_service.mojom";
@@ -93,8 +94,8 @@
 // please note the milestone when you added it, to help us reason about
 // compatibility between the client applications and older ash-chrome binaries.
 //
-// Next version: 62
-// Next method id: 66
+// Next version: 63
+// Next method id: 67
 [Stable, Uuid="8b79c34f-2bf8-4499-979a-b17cac522c1e",
  RenamedFrom="crosapi.mojom.AshChromeService"]
 interface Crosapi {
@@ -385,6 +386,11 @@
   [MinVersion=36] BindResourceManager@41(
       pending_receiver<ResourceManager> receiver);
 
+  // Binds the search controller which send queries from ash to lacros.
+  // Added in M99.
+  [MinVersion=62] BindSearchControllerRegistry@66(
+      pending_receiver<SearchControllerRegistry> receiver);
+
   // Binds the System Display interface for querying display info.
   // Added in M92.
   [MinVersion=24] BindSystemDisplay@29(
diff --git a/chromeos/crosapi/mojom/launcher_search.mojom b/chromeos/crosapi/mojom/launcher_search.mojom
new file mode 100644
index 0000000..6571d4bb
--- /dev/null
+++ b/chromeos/crosapi/mojom/launcher_search.mojom
@@ -0,0 +1,152 @@
+// Copyright 2021 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.
+
+module crosapi.mojom;
+
+import "mojo/public/mojom/base/string16.mojom";
+import "ui/gfx/image/mojom/image.mojom";
+import "url/mojom/url.mojom";
+
+[Stable, Extensible]
+enum SearchStatus {
+  // Indicates an error with the search. No results will be sent with this
+  // status, and there may or may not be further results sent.
+  [Default] kError = 0,
+  // Search session is complete and no more results will be sent. This
+  // accompanies the final set of results.
+  kDone = 1,
+  // Search session is still in progress and further results may be sent. This
+  // accompanies a set of results.
+  kInProgress = 2,
+  // Search session has been cancelled due to a newer query. No more results
+  // will be sent.
+  kCancelled = 3,
+};
+
+// Enum represents the result type.
+[Stable, Extensible]
+enum SearchResultType {
+  [Default] kUnknown = 0,
+  // This represents the results come from Omnibox's AutocompleteController
+  // of the browser.
+  kOmniboxResult = 1,
+};
+
+// Struct represents search result.
+// Next min ID: 14
+[Stable]
+struct SearchResult {
+  // Type of the result. Used to distinguish between different types of result.
+  SearchResultType type@0;
+  // Relevance of the result. Used for scoring/ranking.
+  double relevance@1;
+  // Destination URL of the result. Used for opening the result.
+  url.mojom.Url? destination_url@2;
+
+  // The following fields represent additional information about search
+  // results. These are optional and will be filled depending on the result.
+
+  // Whether the result is an omnibox search result or not. Used for
+  // kOmniboxResult type results.
+  OptionalBool is_omnibox_search@3;
+  // Whether the result is an answer result or not. Used for kOmniboxResult
+  // type results.
+  OptionalBool is_answer@4;
+  // The Omnibox subtype of the result, used for kOmniboxResult type results.
+  // This defaults to kUnset.
+  OmniboxType omnibox_type@5;
+  // The Omnibox answer subtype of the result, used for Omnibox answer results.
+  // This defaults to kUnset.
+  AnswerType answer_type@6;
+
+  // The image url of the result, if any. Used to download the result image.
+  url.mojom.Url? image_url@7;
+  // Favicon of the result.
+  gfx.mojom.ImageSkia? favicon@8;
+
+  // The contents of the result. Used to display the result.
+  mojo_base.mojom.String16? contents@9;
+  // Additional contents for the result. Used to display the result.
+  mojo_base.mojom.String16? additional_contents@10;
+  // Description of the result. Used to display the result.
+  mojo_base.mojom.String16? description@11;
+  // Additional description for the result. Used to display the result.
+  mojo_base.mojom.String16? additional_description@12;
+  // Text type of the additional description, if any. Defaults to kUnset.
+  TextType additional_description_type@13;
+
+  [Stable, Extensible]
+  enum OptionalBool {
+    kUnset,
+    kFalse,
+    kTrue,
+  };
+
+  // Enum representing the Omnibox result subtype.
+  [Stable, Extensible]
+  enum OmniboxType {
+    [Default] kUnset = 0,
+    kRichImage = 1,
+    kFavicon = 2,
+    kBookmark = 3,
+    kDomain = 4,
+    kSearch = 5,
+    kHistory = 6,
+    kCalculator = 7,
+  };
+
+  // Enum representing the Omnibox answer subtype.
+  [Stable, Extensible]
+  enum AnswerType {
+    [Default] kUnset = 0,
+    kDefaultAnswer = 1,
+    kWeather = 2,
+    kCurrency = 3,
+    kDictionary = 4,
+    kFinance = 5,
+    kSunrise = 6,
+    kTranslation = 7,
+    kWhenIs = 8,
+  };
+
+  // Enum representing special text types.
+  [Stable, Extensible]
+  enum TextType {
+    [Default] kUnset = 0,
+    kPositive = 1,
+    kNegative = 2,
+  };
+};
+
+// Interface to send results from lacros to ash. Implemented in ash.
+// Next min method ID: 1
+[Stable, Uuid="ce797aae-286e-4b63-b7b3-090bf5040818"]
+interface SearchResultsPublisher {
+  // Sends search result from lacros to ash. For each query, this will be called
+  // multiple times, each time it will overwrite the existing results. When all
+  // results for a query are already sent, the connection will be reset and no
+  // more results will be sent.
+  OnSearchResultsReceived@0(SearchStatus status, array<SearchResult>? result);
+};
+
+// Interface to send query from ash to lacros. Implemented in lacros.
+// Next min method ID: 2
+[Stable, Uuid="c2d77467-b04d-4b10-8f54-de52c3cbe30d"]
+interface SearchController {
+  // Sends search queries from ash to lacros. If a search query is called while
+  // there is an in-flight search query, the in-flight search query will be
+  // cancelled before the new search query being executed.
+  Search@0(mojo_base.mojom.String16 query) =>
+      (pending_associated_receiver<SearchResultsPublisher> publisher);
+};
+
+// Interface to register the search controller. Implemented in ash.
+// Next min method ID: 1
+[Stable, Uuid="1dc4306b-50af-4b43-a1f0-552e7010971e"]
+interface SearchControllerRegistry {
+  // Lacros can register the search controller to ash so that ash can
+  // start making calls.
+  RegisterSearchController@0(
+      pending_remote<SearchController> search_controller);
+};
diff --git a/chromeos/dbus/shill/fake_shill_service_client.cc b/chromeos/dbus/shill/fake_shill_service_client.cc
index 04aec98a..e8a3ab6 100644
--- a/chromeos/dbus/shill/fake_shill_service_client.cc
+++ b/chromeos/dbus/shill/fake_shill_service_client.cc
@@ -18,6 +18,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
 #include "chromeos/dbus/shill/shill_device_client.h"
 #include "chromeos/dbus/shill/shill_manager_client.h"
 #include "chromeos/dbus/shill/shill_profile_client.h"
@@ -389,6 +390,10 @@
     base::OnceClosure callback,
     ErrorCallback error_callback) {
   fake_traffic_counters_.ClearList();
+  base::Time reset_time = time_getter_.Run();
+  SetServiceProperty(
+      service_path.value(), shill::kTrafficCounterResetTimeProperty,
+      base::Value(reset_time.ToDeltaSinceWindowsEpoch().InMillisecondsF()));
   base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(callback));
 }
 
@@ -823,4 +828,9 @@
   fake_traffic_counters_ = std::move(fake_traffic_counters);
 }
 
+void FakeShillServiceClient::SetTimeGetterForTest(
+    base::RepeatingCallback<base::Time()> time_getter) {
+  time_getter_ = std::move(time_getter);
+}
+
 }  // namespace chromeos
diff --git a/chromeos/dbus/shill/fake_shill_service_client.h b/chromeos/dbus/shill/fake_shill_service_client.h
index 4e95003..9f4ce92 100644
--- a/chromeos/dbus/shill/fake_shill_service_client.h
+++ b/chromeos/dbus/shill/fake_shill_service_client.h
@@ -13,6 +13,7 @@
 #include "base/callback.h"
 #include "base/component_export.h"
 #include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "chromeos/dbus/shill/shill_service_client.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -126,6 +127,7 @@
   void SetRequireServiceToGetProperties(
       bool require_service_to_get_properties) override;
   void SetFakeTrafficCounters(base::Value fake_traffic_counters) override;
+  void SetTimeGetterForTest(base::RepeatingCallback<base::Time()>) override;
 
  private:
   typedef base::ObserverList<ShillPropertyChangedObserver>::Unchecked
@@ -170,6 +172,9 @@
 
   base::Value fake_traffic_counters_{base::Value::Type::LIST};
 
+  // Gets the mocked time in tests.
+  base::RepeatingCallback<base::Time()> time_getter_;
+
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<FakeShillServiceClient> weak_ptr_factory_{this};
diff --git a/chromeos/dbus/shill/shill_service_client.h b/chromeos/dbus/shill/shill_service_client.h
index d4d619ee..ce54652 100644
--- a/chromeos/dbus/shill/shill_service_client.h
+++ b/chromeos/dbus/shill/shill_service_client.h
@@ -14,6 +14,7 @@
 
 namespace base {
 class Value;
+class Time;
 }
 
 namespace dbus {
@@ -118,6 +119,10 @@
     // Sets a fake traffic counters that can be used in tests.
     virtual void SetFakeTrafficCounters(base::Value fake_traffic_counters) = 0;
 
+    // Sets the callback used to get the mocked time in tests.
+    virtual void SetTimeGetterForTest(
+        base::RepeatingCallback<base::Time()>) = 0;
+
    protected:
     virtual ~TestInterface() {}
   };
diff --git a/chromeos/lacros/lacros_service.cc b/chromeos/lacros/lacros_service.cc
index 2cbc415..7e4fa9b5 100644
--- a/chromeos/lacros/lacros_service.cc
+++ b/chromeos/lacros/lacros_service.cc
@@ -41,6 +41,7 @@
 #include "chromeos/crosapi/mojom/image_writer.mojom.h"
 #include "chromeos/crosapi/mojom/keystore_service.mojom.h"
 #include "chromeos/crosapi/mojom/kiosk_session_service.mojom.h"
+#include "chromeos/crosapi/mojom/launcher_search.mojom.h"
 #include "chromeos/crosapi/mojom/local_printer.mojom.h"
 #include "chromeos/crosapi/mojom/login_state.mojom.h"
 #include "chromeos/crosapi/mojom/message_center.mojom.h"
@@ -330,6 +331,10 @@
                   &crosapi::mojom::Crosapi::BindSelectFile,
                   Crosapi::MethodMinVersions::kBindSelectFileMinVersion>();
   ConstructRemote<
+      crosapi::mojom::SearchControllerRegistry,
+      &crosapi::mojom::Crosapi::BindSearchControllerRegistry,
+      Crosapi::MethodMinVersions::kBindSearchControllerRegistryMinVersion>();
+  ConstructRemote<
       crosapi::mojom::StructuredMetricsService,
       &crosapi::mojom::Crosapi::BindStructuredMetricsService,
       Crosapi::MethodMinVersions::kBindStructuredMetricsServiceMinVersion>();
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc
index 4c6cbd0..3d4eaa334 100644
--- a/chromeos/network/network_state_handler.cc
+++ b/chromeos/network/network_state_handler.cc
@@ -1322,9 +1322,9 @@
   }
 
   UpdateManagedWifiNetworkAvailable();
-  if (features::IsESimPolicyEnabled())
-    UpdateBlockedNetworksInternal(NetworkTypePattern::Cellular());
-
+  if (features::IsESimPolicyEnabled()) {
+    UpdateBlockedCellularNetworks();
+  }
   if (type != ManagedState::ManagedType::MANAGED_TYPE_NETWORK)
     return;
 
@@ -1358,6 +1358,15 @@
   }
 }
 
+void NetworkStateHandler::UpdateBlockedCellularNetworks() {
+  DeviceState* device =
+      GetModifiableDeviceStateByType(NetworkTypePattern::Cellular());
+  if (!device || !device->update_received())
+    return;  // May be null in tests.
+
+  UpdateBlockedNetworksInternal(NetworkTypePattern::Cellular());
+}
+
 void NetworkStateHandler::ProfileListChanged(const base::Value& profile_list) {
   NET_LOG(EVENT) << "ProfileListChanged. Re-Requesting Network Properties";
   ProcessIsUserLoggedIn(profile_list);
@@ -1580,7 +1589,7 @@
       UpdateManagedWifiNetworkAvailable();
     if (device->type() == shill::kTypeCellular && !device->scanning() &&
         features::IsESimPolicyEnabled()) {
-      UpdateBlockedNetworksInternal(NetworkTypePattern::Cellular());
+      UpdateBlockedCellularNetworks();
     }
   }
   if (key == shill::kEapAuthenticationCompletedProperty) {
@@ -1669,7 +1678,7 @@
       NotifyIfActiveNetworksChanged();
       NotifyNetworkListChanged();
       if (features::IsESimPolicyEnabled())
-        UpdateBlockedNetworksInternal(NetworkTypePattern::Cellular());
+        UpdateBlockedCellularNetworks();
       UpdateManagedWifiNetworkAvailable();
       // ManagedStateListChanged only gets executed if all pending updates have
       // completed. Profile networks are loaded if a user is logged in and all
diff --git a/chromeos/network/network_state_handler.h b/chromeos/network/network_state_handler.h
index 840bc13d..e6f29f3 100644
--- a/chromeos/network/network_state_handler.h
+++ b/chromeos/network/network_state_handler.h
@@ -696,6 +696,10 @@
   // availability changed.
   void UpdateManagedWifiNetworkAvailable();
 
+  // Check if the cellular device has received update and calls
+  // |UpdateBlockedNetworksInternal(NetworkTypePattern::Cellular())|
+  void UpdateBlockedCellularNetworks();
+
   // Calls |UpdateBlockedByPolicy()| for each given |network_type| network.
   void UpdateBlockedNetworksInternal(const NetworkTypePattern& network_type);
 
diff --git a/chromeos/network/network_test_helper_base.cc b/chromeos/network/network_test_helper_base.cc
index 9331d34b..9d0bd0b3 100644
--- a/chromeos/network/network_test_helper_base.cc
+++ b/chromeos/network/network_test_helper_base.cc
@@ -123,6 +123,17 @@
   last_created_service_path_ = result.value();
 }
 
+absl::optional<double> NetworkTestHelperBase::GetServiceDoubleProperty(
+    const std::string& service_path,
+    const std::string& key) {
+  const base::Value* properties =
+      service_test_->GetServiceProperties(service_path);
+  if (properties) {
+    return properties->FindDoubleKey(key);
+  }
+  return absl::nullopt;
+}
+
 std::string NetworkTestHelperBase::GetServiceStringProperty(
     const std::string& service_path,
     const std::string& key) {
diff --git a/chromeos/network/network_test_helper_base.h b/chromeos/network/network_test_helper_base.h
index 9e6cf31..1834c568 100644
--- a/chromeos/network/network_test_helper_base.h
+++ b/chromeos/network/network_test_helper_base.h
@@ -54,6 +54,11 @@
   // name of the service if no 'Name' key is provided.
   std::string ConfigureService(const std::string& shill_json_string);
 
+  // Returns a double value for property |key| associated with |service_path|.
+  absl::optional<double> GetServiceDoubleProperty(
+      const std::string& service_path,
+      const std::string& key);
+
   // Returns a string value for property |key| associated with |service_path|.
   // The result will be empty if the service or property do not exist.
   std::string GetServiceStringProperty(const std::string& service_path,
diff --git a/chromeos/resources/multidevice_resources.grdp b/chromeos/resources/multidevice_resources.grdp
index 2b22205..38fdacd 100644
--- a/chromeos/resources/multidevice_resources.grdp
+++ b/chromeos/resources/multidevice_resources.grdp
@@ -31,27 +31,4 @@
       resource_path="mojo/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom-lite.js"
       use_base_dir="false"
       type="BINDATA" />
-
-  <!-- Resources for ProximityAuth debug page. -->
-  <include name="IDR_MULTIDEVICE_INDEX_HTML"
-      file="../components/multidevice/debug_webui/resources/index.html"
-      type="BINDATA" />
-  <include name="IDR_MULTIDEVICE_COMMON_CSS"
-      file="../components/multidevice/debug_webui/resources/common.css"
-      type="BINDATA" />
-  <include name="IDR_MULTIDEVICE_LOGS_JS"
-      file="../components/multidevice/debug_webui/resources/logs.js"
-      type="BINDATA" />
-  <include name="IDR_MULTIDEVICE_WEBUI_JS"
-      file="../components/multidevice/debug_webui/resources/webui.js"
-      type="BINDATA" />
-  <include name="IDR_MULTIDEVICE_PROXIMITY_AUTH_HTML"
-      file="../components/multidevice/debug_webui/resources/proximity_auth.html"
-      type="BINDATA" />
-  <include name="IDR_MULTIDEVICE_PROXIMITY_AUTH_CSS"
-      file="../components/multidevice/debug_webui/resources/proximity_auth.css"
-      type="BINDATA" />
-  <include name="IDR_MULTIDEVICE_PROXIMITY_AUTH_JS"
-      file="../components/multidevice/debug_webui/resources/proximity_auth.js"
-      type="BINDATA" />
 </grit-part>
diff --git a/chromeos/services/bluetooth_config/device_pairing_handler.cc b/chromeos/services/bluetooth_config/device_pairing_handler.cc
index f24c0567..fce93ec3 100644
--- a/chromeos/services/bluetooth_config/device_pairing_handler.cc
+++ b/chromeos/services/bluetooth_config/device_pairing_handler.cc
@@ -116,7 +116,7 @@
   // There should only be one PairDevice request at a time.
   CHECK(current_pairing_device_id_.empty());
 
-  pairing_start_timestamp_ = base::Time();
+  pairing_start_timestamp_ = base::Time::Now();
   pair_device_callback_ = std::move(callback);
 
   delegate_.reset();
@@ -314,9 +314,8 @@
       device ? device->GetType()
              : device::BluetoothTransport::BLUETOOTH_TRANSPORT_INVALID;
 
-  device::RecordPairingResult(
-      failure_reason, GetBluetoothTransport(transport),
-      base::DefaultClock::GetInstance()->Now() - pairing_start_timestamp_);
+  device::RecordPairingResult(failure_reason, GetBluetoothTransport(transport),
+                              base::Time::Now() - pairing_start_timestamp_);
 
   std::move(pair_device_callback_).Run(GetPairingResult(failure_reason));
 }
diff --git a/chromeos/services/bluetooth_config/device_pairing_handler_impl_unittest.cc b/chromeos/services/bluetooth_config/device_pairing_handler_impl_unittest.cc
index 171f039..13bf78a 100644
--- a/chromeos/services/bluetooth_config/device_pairing_handler_impl_unittest.cc
+++ b/chromeos/services/bluetooth_config/device_pairing_handler_impl_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
+#include "base/time/clock.h"
 #include "chromeos/services/bluetooth_config/fake_adapter_state_controller.h"
 #include "chromeos/services/bluetooth_config/fake_device_pairing_delegate.h"
 #include "chromeos/services/bluetooth_config/fake_key_entered_handler.h"
@@ -30,6 +31,7 @@
 const char kDefaultPinCode[] = "132546";
 const uint32_t kDefaultPinCodeNum = 132546u;
 const uint32_t kUninitializedPasskey = std::numeric_limits<uint32_t>::min();
+const base::TimeDelta kTestDuration = base::Milliseconds(1000);
 
 enum class AuthType {
   kNone,
@@ -45,7 +47,10 @@
 
 class DevicePairingHandlerImplTest : public testing::Test {
  protected:
-  DevicePairingHandlerImplTest() = default;
+  DevicePairingHandlerImplTest()
+      : task_environment_(
+            base::test::SingleThreadTaskEnvironment::MainThreadType::UI,
+            base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
   DevicePairingHandlerImplTest(const DevicePairingHandlerImplTest&) = delete;
   DevicePairingHandlerImplTest& operator=(const DevicePairingHandlerImplTest&) =
       delete;
@@ -84,6 +89,25 @@
                                        true, success_count);
   }
 
+  void CheckDurationHistogramMetrics(base::TimeDelta bucket,
+                                     int success_count,
+                                     int failure_count) {
+    histogram_tester.ExpectBucketCount(
+        "Bluetooth.ChromeOS.Pairing.Duration.Success", bucket.InMilliseconds(),
+        success_count);
+    histogram_tester.ExpectBucketCount(
+        "Bluetooth.ChromeOS.Pairing.Duration.Success."
+        "Classic",
+        bucket.InMilliseconds(), success_count);
+    histogram_tester.ExpectBucketCount(
+        "Bluetooth.ChromeOS.Pairing.Duration.Failure", bucket.InMilliseconds(),
+        failure_count);
+    histogram_tester.ExpectBucketCount(
+        "Bluetooth.ChromeOS.Pairing.Duration.Failure."
+        "Classic",
+        bucket.InMilliseconds(), failure_count);
+  }
+
   void AddDevice(std::string* id_out,
                  AuthType auth_type,
                  uint32_t passkey = kDefaultPinCodeNum) {
@@ -186,6 +210,10 @@
     return !connect_callback_.is_null();
   }
 
+  void FastForwardOperation(base::TimeDelta time) {
+    task_environment_.FastForwardBy(time);
+  }
+
   void InvokePendingConnectCallback(bool success) {
     if (success) {
       std::move(connect_callback_).Run(absl::nullopt);
@@ -267,10 +295,14 @@
   std::string device_id2;
   AddDevice(&device_id2, AuthType::kNone);
 
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/0);
+
   std::unique_ptr<FakeDevicePairingDelegate> delegate1 = PairDevice(device_id1);
   EXPECT_TRUE(delegate1->IsMojoPipeConnected());
 
   EXPECT_TRUE(HasPendingConnectCallback());
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/false);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kNonAuthFailure);
   EXPECT_EQ(num_pairing_attempt_finished_calls(), 0u);
@@ -278,11 +310,14 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 
   std::unique_ptr<FakeDevicePairingDelegate> delegate2 = PairDevice(device_id2);
   EXPECT_TRUE(delegate2->IsMojoPipeConnected());
 
   EXPECT_TRUE(HasPendingConnectCallback());
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/true);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kSuccess);
   EXPECT_EQ(num_pairing_attempt_finished_calls(), 1u);
@@ -290,6 +325,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/2, /*failure_count=*/1,
                          /*success_count=*/1);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/1,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, DisableBluetoothBeforePairing) {
@@ -310,6 +347,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kInvalid,
                          /*type_count=*/1, /*failure_count=*/0,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(base::Milliseconds(0), /*success_count=*/0,
+                                /*failure_count=*/0);
 }
 
 TEST_F(DevicePairingHandlerImplTest, DisableBluetoothDuringPairing) {
@@ -318,6 +357,7 @@
 
   std::unique_ptr<FakeDevicePairingDelegate> delegate = PairDevice(device_id);
   EXPECT_TRUE(delegate->IsMojoPipeConnected());
+  FastForwardOperation(kTestDuration);
 
   // Disable Bluetooth before invoking the Connect() callback.
   SetBluetoothSystemState(mojom::BluetoothSystemState::kDisabling);
@@ -330,6 +370,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, DestroyHandlerBeforeConnectFinishes) {
@@ -338,7 +380,6 @@
 
   PairDevice(device_id);
   EXPECT_TRUE(HasPendingConnectCallback());
-
   DestroyHandler();
 
   // CancelPairing() should be called since we had an active pairing.
@@ -349,6 +390,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(base::Milliseconds(0), /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, DestroyHandlerAfterConnectFinishes) {
@@ -359,6 +402,7 @@
   EXPECT_TRUE(delegate->IsMojoPipeConnected());
 
   EXPECT_TRUE(HasPendingConnectCallback());
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/true);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kSuccess);
   EXPECT_EQ(num_pairing_attempt_finished_calls(), 1u);
@@ -373,6 +417,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/0,
                          /*success_count=*/1);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/1,
+                                /*failure_count=*/0);
 }
 
 TEST_F(DevicePairingHandlerImplTest, DisconnectDelegateBeforeConnectFinishes) {
@@ -381,7 +427,7 @@
 
   std::unique_ptr<FakeDevicePairingDelegate> delegate = PairDevice(device_id);
   EXPECT_TRUE(HasPendingConnectCallback());
-
+  FastForwardOperation(kTestDuration);
   delegate->DisconnectMojoPipe();
 
   // CancelPairing() should be called since we had an active pairing.
@@ -393,6 +439,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest,
@@ -404,6 +452,7 @@
   EXPECT_TRUE(HasPendingConnectCallback());
   ClearDevices();
 
+  FastForwardOperation(kTestDuration);
   delegate->DisconnectMojoPipe();
 
   // CancelPairing() won't be called since the device won't be found. We should
@@ -416,6 +465,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kInvalid,
                          /*type_count=*/1, /*failure_count=*/0,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/0);
 }
 
 TEST_F(DevicePairingHandlerImplTest,
@@ -425,6 +476,7 @@
 
   std::unique_ptr<FakeDevicePairingDelegate> delegate = PairDevice(device_id);
   EXPECT_TRUE(HasPendingConnectCallback());
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/false);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kNonAuthFailure);
   EXPECT_EQ(num_pairing_attempt_finished_calls(), 0u);
@@ -439,6 +491,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairDeviceNotFound) {
@@ -449,6 +503,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kInvalid,
                          /*type_count=*/1, /*failure_count=*/0,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(base::Milliseconds(0), /*success_count=*/0,
+                                /*failure_count=*/0);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthRequestPinCode) {
@@ -461,11 +517,14 @@
   delegate->InvokePendingRequestPinCodeCallback(kDefaultPinCode);
   EXPECT_EQ(received_pin_code(), kDefaultPinCode);
 
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/false);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kAuthFailed);
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthRequestPinCodeRemoveDevice) {
@@ -474,7 +533,7 @@
 
   std::unique_ptr<FakeDevicePairingDelegate> delegate = PairDevice(device_id);
   EXPECT_TRUE(delegate->HasPendingRequestPinCodeCallback());
-
+  FastForwardOperation(kTestDuration);
   // Simulate device no longer being available.
   ClearDevices();
 
@@ -486,6 +545,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kInvalid,
                          /*type_count=*/1, /*failure_count=*/0,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/0);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthRequestPasskey) {
@@ -494,7 +555,7 @@
 
   std::unique_ptr<FakeDevicePairingDelegate> delegate = PairDevice(device_id);
   EXPECT_TRUE(delegate->HasPendingRequestPasskeyCallback());
-
+  FastForwardOperation(kTestDuration);
   delegate->InvokePendingRequestPasskeyCallback(kDefaultPinCode);
   EXPECT_EQ(received_passkey(), kDefaultPinCodeNum);
 
@@ -503,6 +564,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthRequestPasskeyRemoveDevice) {
@@ -512,6 +575,7 @@
   std::unique_ptr<FakeDevicePairingDelegate> delegate = PairDevice(device_id);
   EXPECT_TRUE(delegate->HasPendingRequestPasskeyCallback());
 
+  FastForwardOperation(kTestDuration);
   // Simulate device no longer being available.
   ClearDevices();
 
@@ -523,6 +587,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kInvalid,
                          /*type_count=*/1, /*failure_count=*/0,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/0);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthRequestPasskeyInvalidKey) {
@@ -532,6 +598,7 @@
   std::unique_ptr<FakeDevicePairingDelegate> delegate = PairDevice(device_id);
   EXPECT_TRUE(delegate->HasPendingRequestPasskeyCallback());
 
+  FastForwardOperation(kTestDuration);
   delegate->InvokePendingRequestPasskeyCallback("hello_world");
   EXPECT_EQ(received_passkey(), kUninitializedPasskey);
 
@@ -547,6 +614,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthDisplayPinCode) {
@@ -563,11 +632,14 @@
   EnterKeys(device_id, /*num_keys_entered=*/6u);
   EXPECT_EQ(delegate->key_entered_handler()->num_keys_entered(), 6u);
 
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/false);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kAuthFailed);
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthDisplayPinCodeDisconnectHandler) {
@@ -581,6 +653,7 @@
   EnterKeys(device_id, /*num_keys_entered=*/0);
   EXPECT_EQ(delegate->key_entered_handler()->num_keys_entered(), 0);
 
+  FastForwardOperation(kTestDuration);
   delegate->key_entered_handler()->DisconnectMojoPipe();
 
   EnterKeys(device_id, /*num_keys_entered=*/6u);
@@ -591,6 +664,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kInvalid,
                          /*type_count=*/0, /*failure_count=*/0,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/0);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthDisplayPasskey) {
@@ -607,11 +682,14 @@
   EnterKeys(device_id, /*num_keys_entered=*/6u);
   EXPECT_EQ(delegate->key_entered_handler()->num_keys_entered(), 6u);
 
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/false);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kAuthFailed);
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthDisplayPasskeyPadZeroes) {
@@ -624,17 +702,21 @@
   EXPECT_EQ(delegate1->displayed_passkey(), "033333");
   EXPECT_TRUE(delegate1->key_entered_handler()->IsMojoPipeConnected());
 
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/false);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kAuthFailed);
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 
   // Pair a new device.
   std::string device_id2;
   AddDevice(&device_id2, AuthType::kDisplayPasskey, /*passkey=*/0);
 
   std::unique_ptr<FakeDevicePairingDelegate> delegate2 = PairDevice(device_id2);
+  FastForwardOperation(kTestDuration);
 
   // Passkey displayed should be a 6-digit number, padded with zeroes if needed.
   EXPECT_EQ(delegate2->displayed_passkey(), "000000");
@@ -643,6 +725,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthConfirmPasskey) {
@@ -658,11 +742,14 @@
   delegate1->InvokePendingConfirmPasskeyCallback(/*confirmed=*/true);
   EXPECT_EQ(num_confirm_pairing_calls(), 1u);
 
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/false);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kAuthFailed);
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 
   // Pair a new device.
   std::string device_id2;
@@ -677,6 +764,7 @@
   EXPECT_EQ(num_cancel_pairing_calls(), 0u);
 
   // Reject the pairing.
+  FastForwardOperation(kTestDuration);
   delegate2->InvokePendingConfirmPasskeyCallback(/*confirmed=*/false);
   // ConfirmPairing() should not be called again, CancelPairing() should.
   EXPECT_EQ(num_confirm_pairing_calls(), 1u);
@@ -684,6 +772,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/2, /*failure_count=*/2,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/2);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthConfirmPasskeyRemoveDevice) {
@@ -698,6 +788,7 @@
   ClearDevices();
 
   // Confirm the pairing.
+  FastForwardOperation(kTestDuration);
   delegate->InvokePendingConfirmPasskeyCallback(/*confirmed=*/true);
 
   // Failure result should be returned.
@@ -706,6 +797,8 @@
   CheckPairingHistograms(device::BluetoothTransportType::kInvalid,
                          /*type_count=*/1, /*failure_count=*/0,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/0);
 }
 
 TEST_F(DevicePairingHandlerImplTest, PairAuthAuthorizePairing) {
@@ -719,11 +812,14 @@
   delegate->InvokePendingAuthorizePairingCallback(/*confirmed=*/true);
   EXPECT_EQ(num_confirm_pairing_calls(), 1u);
 
+  FastForwardOperation(kTestDuration);
   InvokePendingConnectCallback(/*success=*/false);
   EXPECT_EQ(pairing_result(), mojom::PairingResult::kAuthFailed);
   CheckPairingHistograms(device::BluetoothTransportType::kClassic,
                          /*type_count=*/1, /*failure_count=*/1,
                          /*success_count=*/0);
+  CheckDurationHistogramMetrics(kTestDuration, /*success_count=*/0,
+                                /*failure_count=*/1);
 }
 
 }  // namespace bluetooth_config
diff --git a/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc b/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc
index cc172e1..ef1b8c8 100644
--- a/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc
+++ b/chromeos/services/machine_learning/public/cpp/fake_service_connection.cc
@@ -227,6 +227,21 @@
   pending_calls_.clear();
 }
 
+void FakeServiceConnectionImpl::FlushForTesting() {
+  clone_ml_service_receivers_.FlushForTesting();
+  machine_learning_service_.FlushForTesting();
+  model_receivers_.FlushForTesting();
+  graph_receivers_.FlushForTesting();
+  text_classifier_receivers_.FlushForTesting();
+  handwriting_receivers_.FlushForTesting();
+  web_platform_handwriting_receivers_.FlushForTesting();
+  grammar_checker_receivers_.FlushForTesting();
+  soda_recognizer_receivers_.FlushForTesting();
+  text_suggester_receivers_.FlushForTesting();
+  document_scanner_receivers_.FlushForTesting();
+  soda_client_remotes_.FlushForTesting();
+}
+
 void FakeServiceConnectionImpl::HandleLoadBuiltinModelCall(
     mojo::PendingReceiver<mojom::Model> receiver,
     mojom::MachineLearningService::LoadBuiltinModelCallback callback) {
diff --git a/chromeos/services/machine_learning/public/cpp/fake_service_connection.h b/chromeos/services/machine_learning/public/cpp/fake_service_connection.h
index 7ec45cf7..568ff0f 100644
--- a/chromeos/services/machine_learning/public/cpp/fake_service_connection.h
+++ b/chromeos/services/machine_learning/public/cpp/fake_service_connection.h
@@ -270,6 +270,9 @@
       chromeos::machine_learning::mojom::Rotation rotation,
       mojom::DocumentScanner::DoPostProcessingCallback callback) override;
 
+  // Flush all relevant Mojo pipes.
+  void FlushForTesting();
+
  private:
   void ScheduleCall(base::OnceClosure call);
   void HandleLoadBuiltinModelCall(
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 3c3d70f..74f4b81 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -298,7 +298,6 @@
       "//components/continuous_search/browser:unit_tests",
       "//components/continuous_search/common:unit_tests",
       "//components/custom_handlers:unit_tests",
-      "//components/data_use_measurement/core:unit_tests",
       "//components/digital_asset_links:unit_tests",
       "//components/discardable_memory/client:unit_tests",
       "//components/discardable_memory/common:unit_tests",
diff --git a/components/app_constants/BUILD.gn b/components/app_constants/BUILD.gn
new file mode 100644
index 0000000..3d42d53f
--- /dev/null
+++ b/components/app_constants/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright 2022 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.
+
+component("app_constants") {
+  output_name = "app_constants_lib"
+
+  sources = [
+    "constants.cc",
+    "constants.h",
+  ]
+
+  defines = [ "IS_APP_CONSTANTS_IMPL" ]
+
+  deps = [ "//base" ]
+}
diff --git a/components/app_constants/DIR_METADATA b/components/app_constants/DIR_METADATA
new file mode 100644
index 0000000..0f723e54
--- /dev/null
+++ b/components/app_constants/DIR_METADATA
@@ -0,0 +1 @@
+mixins: "//apps/COMMON_METADATA"
diff --git a/components/app_constants/OWNERS b/components/app_constants/OWNERS
new file mode 100644
index 0000000..6ccbbd6
--- /dev/null
+++ b/components/app_constants/OWNERS
@@ -0,0 +1 @@
+file://apps/OWNERS
diff --git a/components/app_constants/constants.cc b/components/app_constants/constants.cc
new file mode 100644
index 0000000..0153c0c
--- /dev/null
+++ b/components/app_constants/constants.cc
@@ -0,0 +1,18 @@
+// Copyright 2022 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 "components/app_constants/constants.h"
+
+namespace app_constants {
+
+// The following two IDs are duplicated in
+// //extensions/common/constants.h. Don't change these without changing the
+// others.
+
+const char kChromeAppId[] = "mgndgikekgjfcpckkfioiadnlibdjbkf";
+
+// Generated by: echo "lacros-chrome" | sha256sum | head -c32 | tr 0-9a-f a-p
+const char kLacrosAppId[] = "jaimifaeiicidiikhmjedcgdimealfbh";
+
+}  // namespace app_constants
diff --git a/components/app_constants/constants.h b/components/app_constants/constants.h
new file mode 100644
index 0000000..9637d81d
--- /dev/null
+++ b/components/app_constants/constants.h
@@ -0,0 +1,20 @@
+// Copyright 2022 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 COMPONENTS_APP_CONSTANTS_CONSTANTS_H_
+#define COMPONENTS_APP_CONSTANTS_CONSTANTS_H_
+
+#include "base/component_export.h"
+
+namespace app_constants {
+
+// The extension id of the Chrome component application.
+COMPONENT_EXPORT(APP_CONSTANTS) extern const char kChromeAppId[];
+
+// Fake extension ID for the Lacros chrome browser application.
+COMPONENT_EXPORT(APP_CONSTANTS) extern const char kLacrosAppId[];
+
+}  // namespace app_constants
+
+#endif  // COMPONENTS_APP_CONSTANTS_CONSTANTS_H_
diff --git a/components/app_restore/BUILD.gn b/components/app_restore/BUILD.gn
index d04a6628..b037f42 100644
--- a/components/app_restore/BUILD.gn
+++ b/components/app_restore/BUILD.gn
@@ -54,10 +54,11 @@
     "//components/services/app_service/public/cpp:intents",
     "//components/services/app_service/public/mojom",
     "//components/sessions:session_id",
-    "//extensions/common:common_constants",
     "//ui/aura",
     "//ui/views",
   ]
+
+  deps = [ "//components/app_constants" ]
 }
 
 source_set("unit_tests") {
@@ -71,6 +72,7 @@
 
   deps = [
     ":app_restore",
+    "//components/app_constants",
     "//content/test:test_support",
     "//testing/gtest",
     "//ui/aura:test_support",
diff --git a/components/app_restore/DEPS b/components/app_restore/DEPS
index a371940..48bc9b6 100644
--- a/components/app_restore/DEPS
+++ b/components/app_restore/DEPS
@@ -1,10 +1,10 @@
 include_rules = [
   "+ash/constants",
   "+chromeos/ui/base/window_state_type.h",
+  "+components/app_constants/constants.h",
   "+components/account_id/account_id.h",
   "+components/services/app_service/public",
   "+components/sessions/core/session_id.h",
   "+content/public/test",
-  "+extensions/common/constants.h",
   "+ui",
-]
\ No newline at end of file
+]
diff --git a/components/app_restore/full_restore_read_and_save_unittest.cc b/components/app_restore/full_restore_read_and_save_unittest.cc
index 93ad90b..5bd2cad 100644
--- a/components/app_restore/full_restore_read_and_save_unittest.cc
+++ b/components/app_restore/full_restore_read_and_save_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/timer/timer.h"
+#include "components/app_constants/constants.h"
 #include "components/app_restore/app_launch_info.h"
 #include "components/app_restore/app_restore_data.h"
 #include "components/app_restore/features.h"
@@ -24,7 +25,6 @@
 #include "components/app_restore/window_properties.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "content/public/test/browser_task_environment.h"
-#include "extensions/common/constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/test/aura_test_helper.h"
@@ -265,7 +265,7 @@
                             std::vector<GURL> urls,
                             int32_t active_tab_index = 0) {
     auto launch_info = std::make_unique<app_restore::AppLaunchInfo>(
-        extension_misc::kChromeAppId, id);
+        app_constants::kChromeAppId, id);
     launch_info->urls = urls;
     launch_info->active_tab_index = active_tab_index;
     SaveAppLaunchInfo(file_path, std::move(launch_info));
@@ -887,7 +887,7 @@
   ASSERT_TRUE(restore_data);
   const auto& launch_list = restore_data->app_id_to_launch_list();
   EXPECT_EQ(1u, launch_list.size());
-  const auto launch_list_it = launch_list.find(extension_misc::kChromeAppId);
+  const auto launch_list_it = launch_list.find(app_constants::kChromeAppId);
   EXPECT_TRUE(launch_list_it != launch_list.end());
   EXPECT_EQ(1u, launch_list_it->second.size());
   const auto app_restore_data_it = launch_list_it->second.find(kId1);
@@ -955,21 +955,21 @@
                                    /*restored_browser_session_id=*/0);
 
   // Verify the browser window is saved.
-  EXPECT_EQ(extension_misc::kLacrosAppId,
+  EXPECT_EQ(app_constants::kLacrosAppId,
             save_handler->GetAppId(widget->GetNativeWindow()));
   auto window_info = save_handler->GetWindowInfo(
-      GetPath(), extension_misc::kLacrosAppId, kBrowserSessionId);
+      GetPath(), app_constants::kLacrosAppId, kBrowserSessionId);
   EXPECT_EQ(kActivationIndex1, window_info->activation_index.value());
 
   // Modify the window info.
   SaveWindowInfo(window, kActivationIndex2);
   window_info = save_handler->GetWindowInfo(
-      GetPath(), extension_misc::kLacrosAppId, kBrowserSessionId);
+      GetPath(), app_constants::kLacrosAppId, kBrowserSessionId);
   EXPECT_EQ(kActivationIndex2, window_info->activation_index.value());
 
   widget.reset();
   ASSERT_FALSE(save_handler->GetWindowInfo(
-      GetPath(), extension_misc::kLacrosAppId, kBrowserSessionId));
+      GetPath(), app_constants::kLacrosAppId, kBrowserSessionId));
 
   timer->FireNow();
   // Wait for the restore data to be written to the full restore file.
@@ -1004,15 +1004,15 @@
   SaveWindowInfo(window.get(), kActivationIndex1);
 
   // Verify the browser window is saved.
-  EXPECT_EQ(extension_misc::kLacrosAppId, save_handler->GetAppId(window.get()));
+  EXPECT_EQ(app_constants::kLacrosAppId, save_handler->GetAppId(window.get()));
   auto window_info = save_handler->GetWindowInfo(
-      GetPath(), extension_misc::kLacrosAppId, kBrowserSessionId);
+      GetPath(), app_constants::kLacrosAppId, kBrowserSessionId);
   EXPECT_EQ(kActivationIndex1, window_info->activation_index.value());
 
   // Modify the window info.
   SaveWindowInfo(window.get(), kActivationIndex2);
   window_info = save_handler->GetWindowInfo(
-      GetPath(), extension_misc::kLacrosAppId, kBrowserSessionId);
+      GetPath(), app_constants::kLacrosAppId, kBrowserSessionId);
   EXPECT_EQ(kActivationIndex2, window_info->activation_index.value());
 
   window.reset();
diff --git a/components/app_restore/full_restore_read_handler.cc b/components/app_restore/full_restore_read_handler.cc
index bde9a65..f259cc22 100644
--- a/components/app_restore/full_restore_read_handler.cc
+++ b/components/app_restore/full_restore_read_handler.cc
@@ -13,6 +13,7 @@
 #include "base/no_destructor.h"
 #include "base/task/post_task.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "components/app_constants/constants.h"
 #include "components/app_restore/app_launch_info.h"
 #include "components/app_restore/app_restore_utils.h"
 #include "components/app_restore/desk_template_read_handler.h"
@@ -25,7 +26,6 @@
 #include "components/app_restore/window_info.h"
 #include "components/app_restore/window_properties.h"
 #include "components/sessions/core/session_id.h"
-#include "extensions/common/constants.h"
 #include "ui/aura/client/aura_constants.h"
 
 namespace full_restore {
@@ -368,7 +368,7 @@
     const base::FilePath& profile_path) {
   auto session_id = SessionID::NewUnique();
   auto app_launch_info = std::make_unique<app_restore::AppLaunchInfo>(
-      extension_misc::kChromeAppId, session_id.id());
+      app_constants::kChromeAppId, session_id.id());
   app_launch_info->app_type_browser = true;
 
   if (profile_path_to_restore_data_.find(profile_path) ==
@@ -380,7 +380,7 @@
   profile_path_to_restore_data_[profile_path]->AddAppLaunchInfo(
       std::move(app_launch_info));
   window_id_to_app_restore_info_[session_id.id()] =
-      std::make_pair(profile_path, extension_misc::kChromeAppId);
+      std::make_pair(profile_path, app_constants::kChromeAppId);
 }
 
 std::unique_ptr<app_restore::WindowInfo> FullRestoreReadHandler::GetWindowInfo(
@@ -449,7 +449,7 @@
               std::make_pair(profile_path, app_id);
           // TODO(crbug.com/1239984): Remove restore data from
           // `lacros_read_handler_` for ash browser apps.
-          if (lacros_read_handler_ && app_id != extension_misc::kChromeAppId &&
+          if (lacros_read_handler_ && app_id != app_constants::kChromeAppId &&
               primary_profile_path_ == profile_path) {
             lacros_read_handler_->AddRestoreData(app_id, window_id);
           }
diff --git a/components/app_restore/full_restore_save_handler.cc b/components/app_restore/full_restore_save_handler.cc
index 6c076e3..d3c86a0a 100644
--- a/components/app_restore/full_restore_save_handler.cc
+++ b/components/app_restore/full_restore_save_handler.cc
@@ -11,6 +11,7 @@
 #include "base/no_destructor.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
+#include "components/app_constants/constants.h"
 #include "components/app_restore/app_launch_info.h"
 #include "components/app_restore/app_restore_utils.h"
 #include "components/app_restore/features.h"
@@ -23,7 +24,6 @@
 #include "components/app_restore/window_properties.h"
 #include "components/services/app_service/public/cpp/app_registry_cache.h"
 #include "components/sessions/core/session_id.h"
-#include "extensions/common/constants.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/env.h"
 
@@ -132,7 +132,7 @@
     app_launch_info->window_id = window_id;
   } else {
     app_launch_info = std::make_unique<app_restore::AppLaunchInfo>(
-        extension_misc::kChromeAppId, window_id);
+        app_constants::kChromeAppId, window_id);
 
     // If the window is an app type browser window, set `app_type_browser` as
     // true, to call the browser session restore to restore apps for the next
@@ -276,13 +276,13 @@
   const int window_id = app_launch_info->window_id.value();
   std::unique_ptr<app_restore::WindowInfo> window_info;
 
-  if (app_id != extension_misc::kChromeAppId) {
+  if (app_id != app_constants::kChromeAppId) {
     // For browser windows, it could have been saved as
-    // extension_misc::kChromeAppId in OnWindowInitialized. However, for the
+    // app_constants::kChromeAppId in OnWindowInitialized. However, for the
     // system web apps, we need to save as the system web app app id and the
     // launch parameter, because system web apps can't be restored by the
     // browser session restore. So remove the record in
-    // extension_misc::kChromeAppId, save the launch info as the system web
+    // app_constants::kChromeAppId, save the launch info as the system web
     // app id, and move window info to the record of the system web app id.
     auto it = window_id_to_app_restore_info_.find(window_id);
     if (it != window_id_to_app_restore_info_.end()) {
diff --git a/components/app_restore/lacros_save_handler.cc b/components/app_restore/lacros_save_handler.cc
index c58750903..8fd494c 100644
--- a/components/app_restore/lacros_save_handler.cc
+++ b/components/app_restore/lacros_save_handler.cc
@@ -4,11 +4,11 @@
 
 #include "components/app_restore/lacros_save_handler.h"
 
+#include "components/app_constants/constants.h"
 #include "components/app_restore/app_launch_info.h"
 #include "components/app_restore/app_restore_utils.h"
 #include "components/app_restore/full_restore_save_handler.h"
 #include "components/app_restore/window_info.h"
-#include "extensions/common/constants.h"
 #include "ui/aura/window.h"
 
 namespace full_restore {
@@ -39,7 +39,7 @@
         profile_path_, app_id);
     app_launch_info->window_id = window_id;
   } else {
-    app_id = extension_misc::kLacrosAppId;
+    app_id = app_constants::kLacrosAppId;
     app_launch_info =
         std::make_unique<app_restore::AppLaunchInfo>(app_id, window_id);
   }
@@ -85,15 +85,15 @@
                                        it->second.window_id);
   }
 
-  window_candidates_[lacros_window_id].app_id = extension_misc::kLacrosAppId;
+  window_candidates_[lacros_window_id].app_id = app_constants::kLacrosAppId;
   window_candidates_[lacros_window_id].window_id = browser_session_id;
 
   save_handler->AddAppLaunchInfo(
       profile_path_, std::make_unique<app_restore::AppLaunchInfo>(
-                         extension_misc::kLacrosAppId, browser_session_id));
+                         app_constants::kLacrosAppId, browser_session_id));
 
   if (window_info) {
-    save_handler->ModifyWindowInfo(profile_path_, extension_misc::kLacrosAppId,
+    save_handler->ModifyWindowInfo(profile_path_, app_constants::kLacrosAppId,
                                    browser_session_id, *window_info);
   }
 }
diff --git a/components/app_restore/restore_data.cc b/components/app_restore/restore_data.cc
index f02e3c8..8be1dbb5 100644
--- a/components/app_restore/restore_data.cc
+++ b/components/app_restore/restore_data.cc
@@ -9,9 +9,9 @@
 #include "base/i18n/number_formatting.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
+#include "components/app_constants/constants.h"
 #include "components/app_restore/app_launch_info.h"
 #include "components/app_restore/window_info.h"
-#include "extensions/common/constants.h"
 
 namespace app_restore {
 
@@ -78,7 +78,7 @@
 }
 
 bool RestoreData::HasAppTypeBrowser() const {
-  auto it = app_id_to_launch_list_.find(extension_misc::kChromeAppId);
+  auto it = app_id_to_launch_list_.find(app_constants::kChromeAppId);
   if (it == app_id_to_launch_list_.end())
     return false;
 
@@ -92,7 +92,7 @@
 }
 
 bool RestoreData::HasBrowser() const {
-  auto it = app_id_to_launch_list_.find(extension_misc::kChromeAppId);
+  auto it = app_id_to_launch_list_.find(app_constants::kChromeAppId);
   if (it == app_id_to_launch_list_.end())
     return false;
 
diff --git a/components/app_restore/restore_data_unittest.cc b/components/app_restore/restore_data_unittest.cc
index f904dd43..d543bd72 100644
--- a/components/app_restore/restore_data_unittest.cc
+++ b/components/app_restore/restore_data_unittest.cc
@@ -10,11 +10,11 @@
 #include "base/containers/contains.h"
 #include "base/values.h"
 #include "chromeos/ui/base/window_state_type.h"
+#include "components/app_constants/constants.h"
 #include "components/app_restore/app_launch_info.h"
 #include "components/app_restore/app_restore_data.h"
 #include "components/app_restore/window_info.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
-#include "extensions/common/constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/base/window_open_disposition.h"
@@ -693,12 +693,12 @@
 
 TEST_F(RestoreDataTest, HasAppTypeBrowser) {
   std::unique_ptr<AppLaunchInfo> app_launch_info1 =
-      std::make_unique<AppLaunchInfo>(extension_misc::kChromeAppId, kWindowId1);
+      std::make_unique<AppLaunchInfo>(app_constants::kChromeAppId, kWindowId1);
   restore_data().AddAppLaunchInfo(std::move(app_launch_info1));
   EXPECT_FALSE(restore_data().HasAppTypeBrowser());
 
   std::unique_ptr<AppLaunchInfo> app_launch_info2 =
-      std::make_unique<AppLaunchInfo>(extension_misc::kChromeAppId, kWindowId2);
+      std::make_unique<AppLaunchInfo>(app_constants::kChromeAppId, kWindowId2);
   app_launch_info2->app_type_browser = true;
   restore_data().AddAppLaunchInfo(std::move(app_launch_info2));
   EXPECT_TRUE(restore_data().HasAppTypeBrowser());
@@ -706,13 +706,13 @@
 
 TEST_F(RestoreDataTest, HasBrowser) {
   std::unique_ptr<AppLaunchInfo> app_launch_info1 =
-      std::make_unique<AppLaunchInfo>(extension_misc::kChromeAppId, kWindowId1);
+      std::make_unique<AppLaunchInfo>(app_constants::kChromeAppId, kWindowId1);
   app_launch_info1->app_type_browser = true;
   restore_data().AddAppLaunchInfo(std::move(app_launch_info1));
   EXPECT_FALSE(restore_data().HasBrowser());
 
   std::unique_ptr<AppLaunchInfo> app_launch_info2 =
-      std::make_unique<AppLaunchInfo>(extension_misc::kChromeAppId, kWindowId2);
+      std::make_unique<AppLaunchInfo>(app_constants::kChromeAppId, kWindowId2);
   restore_data().AddAppLaunchInfo(std::move(app_launch_info2));
   EXPECT_TRUE(restore_data().HasBrowser());
 }
diff --git a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java
index 797e8b26..9d34079 100644
--- a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java
+++ b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java
@@ -136,8 +136,6 @@
                 return BACKGROUND_TASK_QUERY_TILE;
             case TaskIds.FEEDV2_REFRESH_JOB_ID:
                 return BACKGROUND_TASK_FEEDV2_REFRESH;
-            case TaskIds.OFFLINE_MEASUREMENT_JOB_ID:
-                return BACKGROUND_TASK_OFFLINE_MEASUREMENTS;
             case TaskIds.WEBVIEW_COMPONENT_UPDATE_JOB_ID:
                 return BACKGROUND_TASK_WEBVIEW_COMPONENT_UPDATE;
             case TaskIds.ATTRIBUTION_PROVIDER_FLUSH_JOB_ID:
diff --git a/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUmaTest.java b/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUmaTest.java
index 9e2844f7..0d5fd481 100644
--- a/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUmaTest.java
+++ b/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUmaTest.java
@@ -125,9 +125,6 @@
                 BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(TaskIds.QUERY_TILE_JOB_ID));
         assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_FEEDV2_REFRESH,
                 BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(TaskIds.FEEDV2_REFRESH_JOB_ID));
-        assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_OFFLINE_MEASUREMENTS,
-                BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(
-                        TaskIds.OFFLINE_MEASUREMENT_JOB_ID));
         assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_WEBVIEW_COMPONENT_UPDATE,
                 BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(
                         TaskIds.WEBVIEW_COMPONENT_UPDATE_JOB_ID));
diff --git a/components/background_task_scheduler/task_ids.h b/components/background_task_scheduler/task_ids.h
index 067e111..2881c52 100644
--- a/components/background_task_scheduler/task_ids.h
+++ b/components/background_task_scheduler/task_ids.h
@@ -48,7 +48,6 @@
   PERIODIC_BACKGROUND_SYNC_CHROME_WAKEUP_TASK_JOB_ID = 105,
   QUERY_TILE_JOB_ID = 106,
   FEEDV2_REFRESH_JOB_ID = 107,
-  OFFLINE_MEASUREMENT_JOB_ID = 108,
   WEBFEEDS_REFRESH_JOB_ID = 109,
   WEBVIEW_COMPONENT_UPDATE_JOB_ID = 110,
   ATTRIBUTION_PROVIDER_FLUSH_JOB_ID = 111,
diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmarks/browser/bookmark_codec.cc
index 16b50c5..e64f0a4 100644
--- a/components/bookmarks/browser/bookmark_codec.cc
+++ b/components/bookmarks/browser/bookmark_codec.cc
@@ -29,7 +29,7 @@
 namespace bookmarks {
 
 const char BookmarkCodec::kRootsKey[] = "roots";
-const char BookmarkCodec::kRootFolderNameKey[] = "bookmark_bar";
+const char BookmarkCodec::kBookmarkBarFolderNameKey[] = "bookmark_bar";
 const char BookmarkCodec::kOtherBookmarkFolderNameKey[] = "other";
 // The value is left as 'synced' for historical reasons.
 const char BookmarkCodec::kMobileBookmarkFolderNameKey[] = "synced";
@@ -76,7 +76,7 @@
   guids_reassigned_ = false;
   InitializeChecksum();
   base::Value roots(base::Value::Type::DICTIONARY);
-  roots.SetKey(kRootFolderNameKey, EncodeNode(bookmark_bar_node));
+  roots.SetKey(kBookmarkBarFolderNameKey, EncodeNode(bookmark_bar_node));
   roots.SetKey(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node));
   roots.SetKey(kMobileBookmarkFolderNameKey, EncodeNode(mobile_folder_node));
   if (model_meta_info_map)
@@ -193,14 +193,14 @@
   const base::Value* roots = value.FindDictKey(kRootsKey);
   if (!roots)
     return false;  // No roots, or invalid type for roots.
-  const base::Value* root_folder_value = roots->FindDictKey(kRootFolderNameKey);
+  const base::Value* bb_value = roots->FindDictKey(kBookmarkBarFolderNameKey);
   const base::Value* other_folder_value =
       roots->FindDictKey(kOtherBookmarkFolderNameKey);
-  if (!root_folder_value || !other_folder_value) {
-    return false;  // Invalid type for root folder and/or other
-                   // folder.
-  }
-  DecodeNode(*root_folder_value, nullptr, bb_node);
+
+  if (!bb_value || !other_folder_value)
+    return false;
+
+  DecodeNode(*bb_value, nullptr, bb_node);
   DecodeNode(*other_folder_value, nullptr, other_folder_node);
 
   // Fail silently if we can't deserialize mobile bookmarks. We can't require
diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmarks/browser/bookmark_codec.h
index 3426e6b..4c62ffd0 100644
--- a/components/bookmarks/browser/bookmark_codec.h
+++ b/components/bookmarks/browser/bookmark_codec.h
@@ -89,7 +89,7 @@
 
   // Names of the various keys written to the Value.
   static const char kRootsKey[];
-  static const char kRootFolderNameKey[];
+  static const char kBookmarkBarFolderNameKey[];
   static const char kOtherBookmarkFolderNameKey[];
   static const char kMobileBookmarkFolderNameKey[];
   static const char kVersionKey[];
diff --git a/components/bookmarks/browser/bookmark_codec_unittest.cc b/components/bookmarks/browser/bookmark_codec_unittest.cc
index c1a985c..aa22c84 100644
--- a/components/bookmarks/browser/bookmark_codec_unittest.cc
+++ b/components/bookmarks/browser/bookmark_codec_unittest.cc
@@ -125,7 +125,7 @@
     ASSERT_TRUE(roots);
 
     base::Value* bb_value =
-        roots->FindDictKey(BookmarkCodec::kRootFolderNameKey);
+        roots->FindDictKey(BookmarkCodec::kBookmarkBarFolderNameKey);
     ASSERT_TRUE(bb_value);
 
     base::Value* bb_children_value =
diff --git a/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.cc b/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.cc
index 784328630..2fb1a62 100644
--- a/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.cc
+++ b/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.cc
@@ -321,10 +321,14 @@
 
   const base::TimeDelta time_delta_since_last_write =
       base::TimeTicks::Now() - last_written_time_;
-  // Delay writing the event to disk if an event was just written or if the size
-  // of exisiting breadcrumbs is not yet known.
-  if (time_delta_since_last_write < kMinDelayBetweenWrites ||
-      !current_mapped_file_position_) {
+  if (!current_mapped_file_position_) {
+    // If the size of the existing breadcrumbs is not yet known, try again in
+    // |kMinDelayBetweenWrites|.
+    write_timer_.Start(FROM_HERE, kMinDelayBetweenWrites, this,
+                       &BreadcrumbPersistentStorageManager::WriteEvents);
+  } else if (time_delta_since_last_write < kMinDelayBetweenWrites) {
+    // If an event was just written, delay writing the event to disk in order to
+    // limit overhead.
     write_timer_.Start(FROM_HERE,
                        kMinDelayBetweenWrites - time_delta_since_last_write,
                        this, &BreadcrumbPersistentStorageManager::WriteEvents);
diff --git a/components/browser_ui/contacts_picker/android/java/res/layout/top_view.xml b/components/browser_ui/contacts_picker/android/java/res/layout/top_view.xml
index 7af0502a..f3b4b54 100644
--- a/components/browser_ui/contacts_picker/android/java/res/layout/top_view.xml
+++ b/components/browser_ui/contacts_picker/android/java/res/layout/top_view.xml
@@ -28,35 +28,35 @@
         android:paddingStart="15dp"
         app:horizontalSpacing="8dp">
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/icon_filter"
             android:gravity="center"
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
             style="@style/SuggestionChipContacts" />
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/names_filter"
             android:gravity="center"
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
             style="@style/SuggestionChipContacts" />
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/address_filter"
             android:gravity="center"
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
             style="@style/SuggestionChipContacts" />
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/email_filter"
             android:gravity="center"
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
             style="@style/SuggestionChipContacts" />
 
-        <org.chromium.ui.widget.ChipView
+        <org.chromium.components.browser_ui.widget.chips.ChipView
             android:id="@+id/tel_filter"
             android:gravity="center"
             android:layout_height="wrap_content"
diff --git a/components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/TopView.java b/components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/TopView.java
index 4b41ead..5af8c55 100644
--- a/components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/TopView.java
+++ b/components/browser_ui/contacts_picker/android/java/src/org/chromium/components/browser_ui/contacts_picker/TopView.java
@@ -13,8 +13,8 @@
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.ui.text.SpanApplier;
-import org.chromium.ui.widget.ChipView;
 
 import java.text.NumberFormat;
 
diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd
index bf753ec..498990e 100644
--- a/components/browser_ui/strings/android/browser_ui_strings.grd
+++ b/components/browser_ui/strings/android/browser_ui_strings.grd
@@ -839,6 +839,11 @@
       <message name="IDS_IPH_SNOOZE" desc="Snooze button text within In-Product Help tooltip.">
         Remind me
       </message>
+
+      <!-- ChipView -->
+      <message name="IDS_CHIP_REMOVE_ICON_CONTENT_DESCRIPTION" desc="Accessibility string for X icon on a chip announcing that clicking on this icon will remove this input chip.">
+        Remove '<ph name="CHIP_LABEL">%1$s<ex>News</ex></ph>'
+      </message>
     </messages>
   </release>
 </grit>
diff --git a/ui/android/java/strings/android_ui_strings_grd/IDS_CHIP_REMOVE_ICON_CONTENT_DESCRIPTION.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_CHIP_REMOVE_ICON_CONTENT_DESCRIPTION.png.sha1
similarity index 100%
rename from ui/android/java/strings/android_ui_strings_grd/IDS_CHIP_REMOVE_ICON_CONTENT_DESCRIPTION.png.sha1
rename to components/browser_ui/strings/android/browser_ui_strings_grd/IDS_CHIP_REMOVE_ICON_CONTENT_DESCRIPTION.png.sha1
diff --git a/components/browser_ui/styles/android/BUILD.gn b/components/browser_ui/styles/android/BUILD.gn
index a93ffba..6e88c2e 100644
--- a/components/browser_ui/styles/android/BUILD.gn
+++ b/components/browser_ui/styles/android/BUILD.gn
@@ -23,6 +23,7 @@
 
 android_resources("java_resources") {
   sources = [
+    "java/res/color/chip_text_color_secondary.xml",
     "java/res/color/default_icon_color_accent1_tint_list.xml",
     "java/res/color/default_icon_color_dark_tint_list.xml",
     "java/res/color/default_icon_color_disabled.xml",
diff --git a/ui/android/java/res/color/chip_text_color_secondary.xml b/components/browser_ui/styles/android/java/res/color/chip_text_color_secondary.xml
similarity index 100%
rename from ui/android/java/res/color/chip_text_color_secondary.xml
rename to components/browser_ui/styles/android/java/res/color/chip_text_color_secondary.xml
diff --git a/components/browser_ui/styles/android/java/res/values-night/dimens.xml b/components/browser_ui/styles/android/java/res/values-night/dimens.xml
index c83ce0a..7d8ec347 100644
--- a/components/browser_ui/styles/android/java/res/values-night/dimens.xml
+++ b/components/browser_ui/styles/android/java/res/values-night/dimens.xml
@@ -6,6 +6,7 @@
 <resources>
     <!-- Surface color elevations -->
     <dimen name="dialog_bg_color_elev">@dimen/default_elevation_3</dimen>
+    <dimen name="menu_bg_color_elev">@dimen/default_elevation_5</dimen>
     <dimen name="sheet_bg_color_elev">@dimen/default_elevation_4</dimen>
     <dimen name="snackbar_background_color_elev">@dimen/default_elevation_4</dimen>
 </resources>
diff --git a/components/browser_ui/styles/android/java/res/values/colors.xml b/components/browser_ui/styles/android/java/res/values/colors.xml
index 312a0b1..4b412273 100644
--- a/components/browser_ui/styles/android/java/res/values/colors.xml
+++ b/components/browser_ui/styles/android/java/res/values/colors.xml
@@ -38,4 +38,8 @@
     <!-- Progress Bar colors -->
     <macro name="progress_bar_foreground">@macro/default_control_color_active</macro>
     <color name="progress_bar_secondary">@color/modern_grey_600</color>
+
+    <!-- Chip Colors -->
+    <color name="chip_text_color_selected">@color/default_text_color_on_accent2_container</color>
+    <color name="default_chip_assistive_text_color_secondary">@color/default_text_color_secondary</color>
 </resources>
diff --git a/components/browser_ui/styles/android/java/res/values/styles.xml b/components/browser_ui/styles/android/java/res/values/styles.xml
index 00ab243..b6fd206 100644
--- a/components/browser_ui/styles/android/java/res/values/styles.xml
+++ b/components/browser_ui/styles/android/java/res/values/styles.xml
@@ -290,6 +290,14 @@
         <item name="android:textColor">@color/default_text_color_on_accent1_list</item>
     </style>
 
+    <!-- Chip Text Styles -->
+    <style name="TextAppearance.ChipText" parent="TextAppearance.TextAccentMediumThick">
+        <item name="android:textColor">@color/chip_text_color_secondary</item>
+    </style>
+    <style name="TextAppearance.ChipHint" parent="TextAppearance.TextAccentMediumThick">
+        <item name="android:textColor">@color/chip_text_color_secondary</item>
+    </style>
+
     <!-- Other text styles -->
     <style name="TextAppearance.BlackLink" tools:ignore="UnusedResources">
         <item name="android:textColor">@color/default_text_color_secondary_list</item>
diff --git a/components/browser_ui/styles/android/java/res/values/themes.xml b/components/browser_ui/styles/android/java/res/values/themes.xml
index e252c9f..06f7517 100644
--- a/components/browser_ui/styles/android/java/res/values/themes.xml
+++ b/components/browser_ui/styles/android/java/res/values/themes.xml
@@ -205,16 +205,11 @@
         <item name="divider_line_bg_color_dynamic">?attr/colorSurfaceVariant</item>
     </style>
 
-    <!-- It's logically backward, but this is applied to SettingsActivity when
-         THEME_REFACTOR_ANDROID is disabled. -->
-    <style name="ThemeRefactorOverlay.Disabled.Settings" parent="">
+    <!-- Applied to the SettingsActivity's AppBarLayout to disable the
+         liftOnScroll color-fill effect. -->
+    <style name="ThemeOverlay.Settings.DisableElevationOverlay" parent="">
         <item name="elevationOverlayEnabled">false</item>
     </style>
-    <!-- This is applied to view of MaterialCardViewNoShadow
-        in SettingsActivity. -->
-    <style name="ThemeRefactorOverlay.Enabled.SettingsPromo" parent="">
-        <item name="elevationOverlayEnabled">true</item>
-    </style>
     <style name="ThemeOverlay.BrowserUI.DynamicColors" parent="ThemeOverlay.Material3.DynamicColors.DayNight">
         <item name="elevationOverlayColor">?attr/colorPrimary</item>
         <item name="elevationOverlayAccentColor">@android:color/transparent</item>
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn
index a6d1d055..38368c0 100644
--- a/components/browser_ui/widget/android/BUILD.gn
+++ b/components/browser_ui/widget/android/BUILD.gn
@@ -47,6 +47,7 @@
     "java/src/org/chromium/components/browser_ui/widget/async_image/ForegroundDrawableCompat.java",
     "java/src/org/chromium/components/browser_ui/widget/async_image/ForegroundRoundedCornerImageView.java",
     "java/src/org/chromium/components/browser_ui/widget/chips/ChipProperties.java",
+    "java/src/org/chromium/components/browser_ui/widget/chips/ChipView.java",
     "java/src/org/chromium/components/browser_ui/widget/chips/ChipViewBinder.java",
     "java/src/org/chromium/components/browser_ui/widget/chips/ChipsCoordinator.java",
     "java/src/org/chromium/components/browser_ui/widget/displaystyle/DisplayStyleObserver.java",
@@ -145,6 +146,11 @@
     "java/res/anim/menu_exit_from_bottom.xml",
     "java/res/anim/textbubble_in.xml",
     "java/res/anim/textbubble_out.xml",
+    "java/res/color/chip_background_color.xml",
+    "java/res/color/chip_ripple_color.xml",
+    "java/res/color/chip_stroke_color.xml",
+    "java/res/color/chip_text_color.xml",
+    "java/res/color/menu_chip_background.xml",
     "java/res/drawable-hdpi/btn_delete_24dp.png",
     "java/res/drawable-hdpi/btn_info.png",
     "java/res/drawable-hdpi/ic_arrow_back_white_24dp.png",
@@ -159,6 +165,7 @@
     "java/res/drawable-mdpi/ic_drag_handle_grey600_24dp.png",
     "java/res/drawable-mdpi/ic_more_vert_24dp_on_dark_bg.png",
     "java/res/drawable-mdpi/ic_more_vert_24dp_on_light_bg.png",
+    "java/res/drawable-v24/app_menu_bg.xml",
     "java/res/drawable-v24/oval_surface_1.xml",
     "java/res/drawable-v24/rectangle_surface_1.xml",
     "java/res/drawable-v24/rounded_rectangle_surface_1.xml",
@@ -237,6 +244,7 @@
     "java/res/layout/tile_view_modern.xml",
     "java/res/layout/tile_view_modern_condensed.xml",
     "java/res/values-ldrtl/values.xml",
+    "java/res/values-night/colors.xml",
     "java/res/values-night/dimens.xml",
     "java/res/values-night/drawables.xml",
     "java/res/values-sw600dp/dimens.xml",
diff --git a/ui/android/java/res/color/chip_background_color.xml b/components/browser_ui/widget/android/java/res/color/chip_background_color.xml
similarity index 100%
rename from ui/android/java/res/color/chip_background_color.xml
rename to components/browser_ui/widget/android/java/res/color/chip_background_color.xml
diff --git a/ui/android/java/res/color/chip_ripple_color.xml b/components/browser_ui/widget/android/java/res/color/chip_ripple_color.xml
similarity index 100%
rename from ui/android/java/res/color/chip_ripple_color.xml
rename to components/browser_ui/widget/android/java/res/color/chip_ripple_color.xml
diff --git a/ui/android/java/res/color/chip_stroke_color.xml b/components/browser_ui/widget/android/java/res/color/chip_stroke_color.xml
similarity index 100%
rename from ui/android/java/res/color/chip_stroke_color.xml
rename to components/browser_ui/widget/android/java/res/color/chip_stroke_color.xml
diff --git a/components/browser_ui/widget/android/java/res/color/chip_text_color.xml b/components/browser_ui/widget/android/java/res/color/chip_text_color.xml
new file mode 100644
index 0000000..19d10998
--- /dev/null
+++ b/components/browser_ui/widget/android/java/res/color/chip_text_color.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:ignore="UnusedResources">
+    <item android:alpha="@dimen/default_disabled_alpha"
+        android:color="@color/chip_text_color_selected"
+        android:state_selected="true" android:state_enabled="false"/>
+    <item android:alpha="@dimen/default_disabled_alpha"
+        android:color="@color/default_chip_assistive_text_color" android:state_enabled="false" />
+    <item android:color="@color/chip_text_color_selected" android:state_selected="true" />
+    <item android:color="@color/default_chip_assistive_text_color" />
+</selector>
diff --git a/ui/android/java/res/color/menu_chip_background.xml b/components/browser_ui/widget/android/java/res/color/menu_chip_background.xml
similarity index 100%
rename from ui/android/java/res/color/menu_chip_background.xml
rename to components/browser_ui/widget/android/java/res/color/menu_chip_background.xml
diff --git a/components/browser_ui/widget/android/java/res/drawable-v24/app_menu_bg.xml b/components/browser_ui/widget/android/java/res/drawable-v24/app_menu_bg.xml
new file mode 100644
index 0000000..6af03db
--- /dev/null
+++ b/components/browser_ui/widget/android/java/res/drawable-v24/app_menu_bg.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2022 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. -->
+
+<layer-list
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        android:top="@dimen/app_menu_shadow_length"
+        android:left="@dimen/app_menu_shadow_length"
+        android:bottom="@dimen/app_menu_shadow_length"
+        android:right="@dimen/app_menu_shadow_length">
+        <org.chromium.components.browser_ui.widget.SurfaceColorDrawable
+            android:shape="rectangle"
+            app:surfaceElevation="@dimen/menu_bg_color_elev">
+            <corners android:radius="@dimen/app_menu_corner_size" />
+            <padding
+                android:top="@dimen/app_menu_shadow_length"
+                android:left="@dimen/app_menu_shadow_length"
+                android:bottom="@dimen/app_menu_shadow_length"
+                android:right="@dimen/app_menu_shadow_length" />
+        </org.chromium.components.browser_ui.widget.SurfaceColorDrawable>
+    </item>
+</layer-list>
diff --git a/components/browser_ui/widget/android/java/res/drawable/app_menu_bg.xml b/components/browser_ui/widget/android/java/res/drawable/app_menu_bg.xml
index 06fdf6d..d74bd13 100644
--- a/components/browser_ui/widget/android/java/res/drawable/app_menu_bg.xml
+++ b/components/browser_ui/widget/android/java/res/drawable/app_menu_bg.xml
@@ -13,7 +13,7 @@
         <shape
             android:shape="rectangle">
             <corners android:radius="@dimen/app_menu_corner_size" />
-            <solid android:color="@color/menu_item_bg_color" />
+            <solid android:color="@color/menu_item_bg_color_baseline" />
             <padding
                 android:top="@dimen/app_menu_shadow_length"
                 android:left="@dimen/app_menu_shadow_length"
diff --git a/components/browser_ui/widget/android/java/res/values-night/colors.xml b/components/browser_ui/widget/android/java/res/values-night/colors.xml
new file mode 100644
index 0000000..7e3ca36
--- /dev/null
+++ b/components/browser_ui/widget/android/java/res/values-night/colors.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2022 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. -->
+
+<resources>
+    <!-- Chip colors -->
+    <color name="default_chip_outline_color">@color/default_chip_outline_color_dark</color>
+    <color name="chip_selected_hover">@color/chip_selected_hover_light</color>
+    <color name="chip_selected_focused">@color/chip_selected_focused_light</color>
+    <color name="chip_selected_hover_and_focused">@color/chip_selected_hover_and_focused_light</color>
+    <color name="chip_selected">@color/chip_selected_dark</color>
+    <color name="menu_chip_background_color">@color/menu_chip_background_color_light</color>
+    <color name="menu_chip_background_color_disabled">@color/menu_chip_background_color_disabled_light</color>
+</resources>
diff --git a/components/browser_ui/widget/android/java/res/values-night/dimens.xml b/components/browser_ui/widget/android/java/res/values-night/dimens.xml
index 73d5e205..da9dfe5 100644
--- a/components/browser_ui/widget/android/java/res/values-night/dimens.xml
+++ b/components/browser_ui/widget/android/java/res/values-night/dimens.xml
@@ -5,4 +5,7 @@
 
 <resources>
     <dimen name="sheet_background_elev">@dimen/default_elevation_4</dimen>
+
+    <!-- Chips default measures -->
+    <dimen name="chip_background_selected_alpha">@dimen/chip_background_selected_alpha_dark</dimen>
 </resources>
diff --git a/components/browser_ui/widget/android/java/res/values/attrs.xml b/components/browser_ui/widget/android/java/res/values/attrs.xml
index ceb9da9..bcadf542 100644
--- a/components/browser_ui/widget/android/java/res/values/attrs.xml
+++ b/components/browser_ui/widget/android/java/res/values/attrs.xml
@@ -87,4 +87,26 @@
              to be added or z-order to be adjusted. -->
         <attr name="surfaceElevation" format="dimension"/>
     </declare-styleable>
+
+    <declare-styleable name="ChipView">
+        <attr name="allowMultipleLines" format="boolean"/>
+        <attr name="extendLateralPadding" format="boolean"/>
+        <attr name="reduceEndPadding" format="boolean"/>
+        <attr name="solidColorChip" format="boolean"/>
+        <attr name="textAlignStart" format="boolean"/>
+        <attr name="reduceTextStartPadding" format="boolean"/>
+        <attr name="chipColor" format="color"/>
+        <attr name="chipStrokeColor" format="color"/>
+        <attr name="chipStyle" format="reference"/>
+        <attr name="cornerRadius" format="dimension"/>
+        <attr name="iconWidth" format="reference|dimension"/>
+        <attr name="iconHeight" format="reference|dimension"/>
+        <attr name="useRoundedIcon" format="boolean"/>
+        <attr name="primaryTextAppearance" format="reference"/>
+        <attr name="endIconWidth" format="reference|dimension"/>
+        <attr name="endIconHeight" format="reference|dimension"/>
+        <attr name="secondaryTextAppearance" format="reference"/>
+        <attr name="rippleColor"/>
+        <attr name="verticalInset"/>
+    </declare-styleable>
 </resources>
diff --git a/components/browser_ui/widget/android/java/res/values/colors.xml b/components/browser_ui/widget/android/java/res/values/colors.xml
index 54d9ccc..a0b7e7e 100644
--- a/components/browser_ui/widget/android/java/res/values/colors.xml
+++ b/components/browser_ui/widget/android/java/res/values/colors.xml
@@ -3,9 +3,49 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools">
     <color name="modal_dialog_scrim_color">@color/black_alpha_65</color>
     <color name="toolbar_shadow_color">@color/black_alpha_11</color>
     <color name="toolbar_text_box_background">@color/omnibox_bg_color</color>
     <color name="search_box_hint">@color/default_text_color_secondary</color>
+
+    <!-- Chip Colors -->
+    <color name="default_chip_assistive_text_color">@color/default_text_color_baseline</color>
+    <color name="chip_bg_color">@color/default_bg_color</color>
+    <color name="chip_background_color_disabled">@android:color/transparent</color>
+    <color name="default_chip_ripple_color">@color/default_bg_color_elev_2_baseline</color>
+    <color name="chip_focused">@color/default_bg_color_elev_4_baseline</color>
+    <color name="chip_hover_focused">@color/default_bg_color_elev_4_baseline</color>
+
+    <!-- Same as ?attr/colorOutline. -->
+    <color name="default_chip_outline_color_light">@color/baseline_neutral_variant_200</color>
+    <color name="default_chip_outline_color_dark">@color/baseline_neutral_variant_500</color>
+    <color name="default_chip_outline_color" tools:ignore="UnusedResources">@color/default_chip_outline_color_light</color>
+    <!-- Mix of ?attr/colorSecondaryContainer and ?attr/colorOnSurface. -->
+    <color name="chip_selected_hover_light">@color/baseline_secondary_300_with_neutral_100_alpha_8</color>
+    <color name="chip_selected_hover_dark">@color/baseline_secondary_100_with_neutral_900_alpha_8</color>
+    <color name="chip_selected_hover">@color/chip_selected_hover_dark</color>
+    <!-- Mix of ?attr/colorSecondaryContainer and ?attr/colorOnSurface. -->
+    <color name="chip_selected_focused_light">@color/baseline_secondary_300_with_neutral_100_alpha_24</color>
+    <color name="chip_selected_focused_dark">@color/baseline_secondary_100_with_neutral_900_alpha_24</color>
+    <color name="chip_selected_focused">@color/chip_selected_focused_dark</color>
+    <!-- Mix of ?attr/colorSecondaryContainer and ?attr/colorOnSurface. -->
+    <color name="chip_selected_hover_and_focused_light">@color/baseline_secondary_300_with_neutral_100_alpha_24</color>
+    <color name="chip_selected_hover_and_focused_dark">@color/baseline_secondary_100_with_neutral_900_alpha_24</color>
+    <color name="chip_selected_hover_and_focused">@color/chip_selected_hover_and_focused_dark</color>
+    <!-- Same as ?attr/colorSecondaryContainer -->
+    <color name="chip_selected_light">@color/baseline_secondary_100</color>
+    <color name="chip_selected_dark">@color/baseline_secondary_300</color>
+    <color name="chip_selected">@color/chip_selected_light</color>
+
+    <color name="menu_chip_background_color_dark">@color/modern_blue_600_alpha_6</color>
+    <color name="menu_chip_background_color_light">@color/modern_blue_300_alpha_10</color>
+    <color name="menu_chip_background_color">@color/menu_chip_background_color_dark</color>
+    <color name="menu_chip_background_color_disabled_dark">@color/modern_grey_100_alpha_38</color>
+    <color name="menu_chip_background_color_disabled_light">@color/white_alpha_6</color>
+    <color name="menu_chip_background_color_disabled">@color/menu_chip_background_color_disabled_dark</color>
+    <color name="menu_footer_chip_background_color_dark">@color/modern_blue_600_alpha_10</color>
+    <color name="menu_footer_chip_background_color_light">@color/modern_blue_300_alpha_10</color>
+    <color name="menu_footer_chip_background_color_disabled_dark">@color/modern_grey_100</color>
+    <color name="menu_footer_chip_background_color_disabled_light">@color/white_alpha_6</color>
 </resources>
diff --git a/components/browser_ui/widget/android/java/res/values/dimens.xml b/components/browser_ui/widget/android/java/res/values/dimens.xml
index bedf8c8b..e3038bf 100644
--- a/components/browser_ui/widget/android/java/res/values/dimens.xml
+++ b/components/browser_ui/widget/android/java/res/values/dimens.xml
@@ -139,6 +139,31 @@
     <dimen name="tile_view_padding_landscape">16dp</dimen>
     <dimen name="tile_view_title_margin_top_modern">61dp</dimen>
 
+    <!-- Chips default measures -->
+    <item name="chip_background_selected_alpha_light" format="float" type="dimen">0.06</item>
+    <item name="chip_background_selected_alpha_dark" format="float" type="dimen">1</item>
+
+    <dimen name="chip_solid_border_width">0dp</dimen>
+    <dimen name="chip_border_width">1dp</dimen>
+    <dimen name="chip_corner_radius">8dp</dimen>
+    <dimen name="chip_default_height">32dp</dimen>
+    <dimen name="chip_end_padding">16dp</dimen>
+    <dimen name="chip_reduced_end_padding">12dp</dimen>
+    <dimen name="chip_element_leading_padding">8dp</dimen>
+    <dimen name="chip_element_extended_leading_padding">16dp</dimen>
+    <dimen name="chip_bg_vertical_inset">8dp</dimen>
+    <dimen name="chip_background_selected_alpha" tools:ignore="UnusedResources">@dimen/chip_background_selected_alpha_light</dimen>
+    <dimen name="chip_icon_size">20dp</dimen>
+    <dimen name="chip_loading_view_size">12dp</dimen>
+    <dimen name="chip_end_icon_margin_start">8dp</dimen>
+    <dimen name="chip_end_icon_extended_margin_start">16dp</dimen>
+    <dimen name="chip_end_padding_with_end_icon">6dp</dimen>
+    <dimen name="chip_extended_end_padding_with_end_icon">16dp</dimen>
+    <dimen name="chip_text_multiline_vertical_padding">12dp</dimen>
+    <dimen name="chip_text_reduced_leading_padding">4dp</dimen>
+    <!-- ( listPreferredItemHeightSmall(40dp) - text size(12sp) - top and bottom padding(8dp) ) / 2 -->
+    <dimen name="menu_chip_vertical_inset">10dp</dimen>
+
     <!-- Chips layout dimensions -->
     <dimen name="chip_list_chip_spacing">2.5dp</dimen>
     <dimen name="chip_list_side_padding">16dp</dimen>
@@ -147,4 +172,7 @@
     <dimen name="app_menu_corner_size">8dp</dimen>
     <dimen name="app_menu_shadow_length">@dimen/default_shadow_length_elev_2</dimen>
     <dimen name="app_menu_elevation">@dimen/default_elevation_2</dimen>
+
+    <!-- Surface color elevations -->
+    <dimen name="menu_bg_color_elev">@dimen/default_elevation_0</dimen>
 </resources>
diff --git a/components/browser_ui/widget/android/java/res/values/styles.xml b/components/browser_ui/widget/android/java/res/values/styles.xml
index 34059b4..b423a3b 100644
--- a/components/browser_ui/widget/android/java/res/values/styles.xml
+++ b/components/browser_ui/widget/android/java/res/values/styles.xml
@@ -3,7 +3,7 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools">
     <!-- Card styles -->
     <style name="CardTransparentForDark">
         <item name="android:background">@drawable/incognito_card_bg</item>
@@ -117,4 +117,51 @@
         <item name="android:layout_marginBottom">6dp</item>
     </style>
 
+    <!-- Chips -->
+    <style name="SuggestionChipThemeOverlay">
+        <item name="chipStyle">@style/SuggestionChip</item>
+    </style>
+
+    <style name="Chip">
+        <item name="android:minHeight">@dimen/min_touch_target_size</item>
+        <item name="android:gravity">center_vertical</item>
+        <item name="android:orientation">horizontal</item>
+        <item name="chipColor">@color/chip_background_color</item>
+        <item name="primaryTextAppearance">@style/TextAppearance.ChipText</item>
+        <item name="secondaryTextAppearance">@style/TextAppearance.ChipHint</item>
+        <item name="rippleColor">@color/chip_ripple_color</item>
+        <item name="verticalInset">@dimen/chip_bg_vertical_inset</item>
+    </style>
+    <style name="SuggestionChip" parent="Chip">
+        <item name="primaryTextAppearance">@style/TextAppearance.ChipHint</item>
+        <item name="cornerRadius">@dimen/chip_corner_radius</item>
+    </style>
+    <style name="InputChip" parent="Chip">
+        <item name="cornerRadius">@dimen/chip_default_height</item>
+    </style>
+    <style name="AssistiveChip" parent="Chip">
+        <item name="cornerRadius">@dimen/chip_default_height</item>
+    </style>
+    <style name="InputChipWithRemoveIcon" parent="InputChip" tools:ignore="UnusedResources">
+        <item name="iconWidth">28dp</item>
+        <item name="iconHeight">28dp</item>
+        <item name="useRoundedIcon">true</item>
+        <item name="endIconWidth">18dp</item>
+        <item name="endIconHeight">18dp</item>
+    </style>
+
+    <style name="ChipTextView">
+        <item name="android:gravity">center</item>
+        <item name="android:maxLines">1</item>
+        <item name="android:paddingStart">@dimen/chip_element_leading_padding</item>
+        <item name="android:textAlignment">center</item>
+    </style>
+
+    <style name="MenuChip" parent="Chip" tools:ignore="UnusedResources">
+        <item name="cornerRadius">@dimen/chip_default_height</item>
+        <item name="primaryTextAppearance">@style/TextAppearance.MenuChip.Text.Blue</item>
+        <item name="chipColor">@color/menu_chip_background</item>
+        <item name="solidColorChip">true</item>
+        <item name="verticalInset">@dimen/menu_chip_vertical_inset</item>
+    </style>
 </resources>
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/SurfaceColorDrawable.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/SurfaceColorDrawable.java
index 1fd1d6c..f9128a2 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/SurfaceColorDrawable.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/SurfaceColorDrawable.java
@@ -66,10 +66,28 @@
 
     @Override
     public boolean canApplyTheme() {
+        // Attributes needed for color calculations are in the theme.
         return true;
     }
 
     @Override
+    public ConstantState getConstantState() {
+        // Must hide GradientDrawable's ConstantState, otherwise usage will cause GradientDrawable
+        // objects to be created, instead of this class. Returning null means that these drawables
+        // will not be able to be shared.
+        return null;
+    }
+
+    @Override
+    public Callback getCallback() {
+        // LayerDrawable attempts to do ownership checks by ensuring this callback is null.
+        // Unfortunately it more or less makes it incompatible for classes that return null for
+        // constant state, otherwise warning stack traces are logged. Even when returning null here,
+        // transition animations still seem to play correctly.
+        return null;
+    }
+
+    @Override
     public void applyTheme(@NonNull Theme theme) {
         super.applyTheme(theme);
         onNonNullTheme(theme);
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipProperties.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipProperties.java
index d0753e548..ab8ff54 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipProperties.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipProperties.java
@@ -12,7 +12,6 @@
 import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
 import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey;
 import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
-import org.chromium.ui.widget.ChipView;
 
 /** Properties that describe a single chip in a list/group of chips. */
 public class ChipProperties {
@@ -54,6 +53,6 @@
     /** The max width a chip's text should have in PX. Use {@link #SHOW_WHOLE_TEXT} for no limit. */
     public static final WritableIntPropertyKey TEXT_MAX_WIDTH_PX = new WritableIntPropertyKey();
 
-    static final PropertyKey[] ALL_KEYS = new PropertyKey[] {CLICK_HANDLER, CONTENT_DESCRIPTION,
-            ENABLED, ICON, ID, SELECTED, TEXT, TEXT_MAX_WIDTH_PX};
+    public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {CLICK_HANDLER,
+            CONTENT_DESCRIPTION, ENABLED, ICON, ID, SELECTED, TEXT, TEXT_MAX_WIDTH_PX};
 }
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipView.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipView.java
new file mode 100644
index 0000000..a052ac12
--- /dev/null
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipView.java
@@ -0,0 +1,383 @@
+// Copyright 2019 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.
+package org.chromium.components.browser_ui.widget.chips;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.ContextThemeWrapper;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.AttrRes;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.IdRes;
+import androidx.annotation.Px;
+import androidx.annotation.StyleRes;
+import androidx.appcompat.widget.AppCompatTextView;
+import androidx.core.view.ViewCompat;
+
+import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.components.browser_ui.widget.R;
+import org.chromium.ui.widget.ChromeImageView;
+import org.chromium.ui.widget.LoadingView;
+import org.chromium.ui.widget.RectProvider;
+import org.chromium.ui.widget.RippleBackgroundHelper;
+import org.chromium.ui.widget.ViewRectProvider;
+
+/**
+ * The view responsible for displaying a material chip. The chip has the following components :
+ * - A primary text to be shown.
+ * - An optional start icon that can be rounded as well.
+ * - An optional secondary text view that is shown to the right of the primary text view.
+ * - An optional remove icon at the end, intended for use with input chips.
+ * - An optional boolean (solidColorChip) to remove the default chip border.
+ * - An optional boolean (allowMultipleLines) to avoid longer text strings to wrap to a second line.
+ * - An optional boolean (showLoadingView) to show a loading view in place of the start icon.
+ */
+public class ChipView extends LinearLayout {
+    /** An id to use for {@link #setIcon(int, boolean)} when there is no icon on the chip. */
+    public static final int INVALID_ICON_ID = -1;
+    private static final int MAX_LINES = 2;
+
+    private final RippleBackgroundHelper mRippleBackgroundHelper;
+    private final AppCompatTextView mPrimaryText;
+    private final ChromeImageView mStartIcon;
+    private final boolean mUseRoundedStartIcon;
+    private final LoadingView mLoadingView;
+    private final @IdRes int mSecondaryTextAppearanceId;
+    private final int mEndIconWidth;
+    private final int mEndIconHeight;
+    private final int mEndIconStartPadding;
+    private final int mEndIconEndPadding;
+    private final int mCornerRadius;
+
+    private ViewGroup mEndIconWrapper;
+    private AppCompatTextView mSecondaryText;
+
+    /** Constructor for applying a theme overlay. */
+    public ChipView(Context context, @StyleRes int themeOverlay) {
+        this(new ContextThemeWrapper(context, themeOverlay), null, R.attr.chipStyle, 0);
+    }
+
+    /** Constructor for inflating from XML. */
+    public ChipView(Context context, AttributeSet attrs) {
+        this(new ContextThemeWrapper(context, R.style.SuggestionChipThemeOverlay), attrs,
+                R.attr.chipStyle, 0);
+    }
+
+    /** Constructor for base classes and programmatic creation. */
+    public ChipView(Context context, AttributeSet attrs, @AttrRes int defStyleAttr,
+            @StyleRes int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray a = getContext().obtainStyledAttributes(
+                attrs, R.styleable.ChipView, defStyleAttr, defStyleRes);
+
+        boolean extendLateralPadding =
+                a.getBoolean(R.styleable.ChipView_extendLateralPadding, false);
+        boolean reduceEndPadding = a.getBoolean(R.styleable.ChipView_reduceEndPadding, false);
+
+        @Px
+        int leadingElementPadding = extendLateralPadding
+                ? getResources().getDimensionPixelSize(
+                        R.dimen.chip_element_extended_leading_padding)
+                : getResources().getDimensionPixelSize(R.dimen.chip_element_leading_padding);
+
+        // End padding is already longer so no need to adjust in the 'extendLateralPadding' case.
+        @Px
+        int endPadding = reduceEndPadding
+                ? getResources().getDimensionPixelSize(R.dimen.chip_reduced_end_padding)
+                : getResources().getDimensionPixelSize(R.dimen.chip_end_padding);
+
+        mEndIconStartPadding = extendLateralPadding
+                ? getResources().getDimensionPixelSize(R.dimen.chip_end_icon_extended_margin_start)
+                : getResources().getDimensionPixelSize(R.dimen.chip_end_icon_margin_start);
+
+        mEndIconEndPadding = extendLateralPadding
+                ? getResources().getDimensionPixelSize(
+                        R.dimen.chip_extended_end_padding_with_end_icon)
+                : getResources().getDimensionPixelSize(R.dimen.chip_end_padding_with_end_icon);
+
+        boolean solidColorChip = a.getBoolean(R.styleable.ChipView_solidColorChip, false);
+        int chipBorderWidthId =
+                solidColorChip ? R.dimen.chip_solid_border_width : R.dimen.chip_border_width;
+        int chipColorId =
+                a.getResourceId(R.styleable.ChipView_chipColor, R.color.chip_background_color);
+        int rippleColorId =
+                a.getResourceId(R.styleable.ChipView_rippleColor, R.color.chip_ripple_color);
+        int chipStrokeColorId =
+                a.getResourceId(R.styleable.ChipView_chipStrokeColor, R.color.chip_stroke_color);
+        mCornerRadius = a.getDimensionPixelSize(R.styleable.ChipView_cornerRadius,
+                getContext().getResources().getDimensionPixelSize(R.dimen.chip_corner_radius));
+        int iconWidth = a.getDimensionPixelSize(R.styleable.ChipView_iconWidth,
+                getResources().getDimensionPixelSize(R.dimen.chip_icon_size));
+        int iconHeight = a.getDimensionPixelSize(R.styleable.ChipView_iconHeight,
+                getResources().getDimensionPixelSize(R.dimen.chip_icon_size));
+        mUseRoundedStartIcon = a.getBoolean(R.styleable.ChipView_useRoundedIcon, false);
+        int primaryTextAppearance = a.getResourceId(
+                R.styleable.ChipView_primaryTextAppearance, R.style.TextAppearance_ChipText);
+
+        mEndIconWidth = a.getDimensionPixelSize(R.styleable.ChipView_endIconWidth,
+                getResources().getDimensionPixelSize(R.dimen.chip_icon_size));
+        mEndIconHeight = a.getDimensionPixelSize(R.styleable.ChipView_endIconHeight,
+                getResources().getDimensionPixelSize(R.dimen.chip_icon_size));
+        mSecondaryTextAppearanceId = a.getResourceId(
+                R.styleable.ChipView_secondaryTextAppearance, R.style.TextAppearance_ChipText);
+        int verticalInset = a.getDimensionPixelSize(R.styleable.ChipView_verticalInset,
+                getResources().getDimensionPixelSize(R.dimen.chip_bg_vertical_inset));
+        boolean allowMultipleLines = a.getBoolean(R.styleable.ChipView_allowMultipleLines, false);
+        boolean textAlignStart = a.getBoolean(R.styleable.ChipView_textAlignStart, false);
+        boolean reduceTextStartPadding =
+                a.getBoolean(R.styleable.ChipView_reduceTextStartPadding, false);
+        a.recycle();
+
+        mStartIcon = new ChromeImageView(getContext());
+        mStartIcon.setLayoutParams(new LayoutParams(iconWidth, iconHeight));
+        addView(mStartIcon);
+
+        if (mUseRoundedStartIcon) {
+            int chipHeight = getResources().getDimensionPixelOffset(R.dimen.chip_default_height);
+            leadingElementPadding = (chipHeight - iconHeight) / 2;
+        }
+
+        int loadingViewSize = getResources().getDimensionPixelSize(R.dimen.chip_loading_view_size);
+        int loadingViewHeightPadding = (iconHeight - loadingViewSize) / 2;
+        int loadingViewWidthPadding = (iconWidth - loadingViewSize) / 2;
+        mLoadingView = new LoadingView(getContext());
+        mLoadingView.setVisibility(GONE);
+        mLoadingView.setIndeterminateTintList(ColorStateList.valueOf(ApiCompatibilityUtils.getColor(
+                getResources(), R.color.default_icon_color_accent1_baseline)));
+        mLoadingView.setPaddingRelative(loadingViewWidthPadding, loadingViewHeightPadding,
+                loadingViewWidthPadding, loadingViewHeightPadding);
+        addView(mLoadingView, new LayoutParams(iconWidth, iconHeight));
+
+        // Setting this enforces 16dp padding at the end and 8dp at the start (unless overridden).
+        // For text, the start padding needs to be 16dp which is why a ChipTextView contributes the
+        // remaining 8dp.
+        ViewCompat.setPaddingRelative(this, leadingElementPadding, 0, endPadding, 0);
+
+        mPrimaryText =
+                new AppCompatTextView(new ContextThemeWrapper(getContext(), R.style.ChipTextView));
+        ApiCompatibilityUtils.setTextAppearance(mPrimaryText, primaryTextAppearance);
+
+        // If false fall back to single line defined in XML styles.
+        if (allowMultipleLines) {
+            mPrimaryText.setMaxLines(MAX_LINES);
+            // Vertical padding must be explicitly defined for the text view to create space if text
+            // wrapping causes the chip to increase in size vertically.
+            int minMultilineVerticalTextPadding = getResources().getDimensionPixelSize(
+                    R.dimen.chip_text_multiline_vertical_padding);
+            // TODO(benwgold): Test for non multiline chips to see if 4dp vertical padding can be
+            // safely applied to all chips without affecting styling.
+            mPrimaryText.setPaddingRelative(mPrimaryText.getPaddingStart(),
+                    minMultilineVerticalTextPadding, mPrimaryText.getPaddingEnd(),
+                    minMultilineVerticalTextPadding);
+        }
+        if (textAlignStart) {
+            // Default of 'center' is defined in the ChipTextView style.
+            mPrimaryText.setTextAlignment((View.TEXT_ALIGNMENT_VIEW_START));
+        }
+        if (reduceTextStartPadding) {
+            mPrimaryText.setPaddingRelative(
+                    getResources().getDimensionPixelSize(R.dimen.chip_text_reduced_leading_padding),
+                    mPrimaryText.getPaddingTop(), mPrimaryText.getPaddingEnd(),
+                    mPrimaryText.getPaddingBottom());
+        }
+        addView(mPrimaryText);
+
+        // Reset icon and background:
+        mRippleBackgroundHelper = new RippleBackgroundHelper(this, chipColorId, rippleColorId,
+                mCornerRadius, chipStrokeColorId, chipBorderWidthId, verticalInset);
+        setIcon(INVALID_ICON_ID, false);
+    }
+
+    /**
+     * Unlike setSelected, setEnabled doesn't properly propagate the new state to its subcomponents.
+     * Enforce this so ColorStateLists used for the text appearance apply as intended.
+     * @param enabled The new enabled state for the chip view and the TextViews owned by it.
+     */
+    @Override
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+        getPrimaryTextView().setEnabled(enabled);
+        mStartIcon.setEnabled(enabled);
+        if (mSecondaryText != null) mSecondaryText.setEnabled(enabled);
+    }
+
+    /**
+     * Sets the icon at the start of the chip view.
+     * @param icon The resource id pointing to the icon.
+     */
+    public void setIcon(@DrawableRes int icon, boolean tintWithTextColor) {
+        if (icon == INVALID_ICON_ID) {
+            mStartIcon.setVisibility(ViewGroup.GONE);
+            return;
+        }
+
+        mStartIcon.setVisibility(ViewGroup.VISIBLE);
+        mStartIcon.setImageResource(icon);
+        setTint(tintWithTextColor);
+    }
+
+    /**
+     * Sets the icon at the start of the chip view.
+     * @param drawable Drawable to display.
+     */
+    public void setIcon(Drawable drawable, boolean tintWithTextColor) {
+        mStartIcon.setVisibility(ViewGroup.VISIBLE);
+        mStartIcon.setImageDrawable(drawable);
+        setTint(tintWithTextColor);
+    }
+
+    /**
+     * Shows a {@link LoadingView} at the start of the chip view. This replaces the start icon.
+     * @param loadingViewObserver A {@link LoadingView.Observer} to add to the LoadingView.
+     */
+    public void showLoadingView(LoadingView.Observer loadingViewObserver) {
+        mLoadingView.addObserver(new LoadingView.Observer() {
+            @Override
+            public void onShowLoadingUIComplete() {
+                mStartIcon.setVisibility(GONE);
+            }
+
+            @Override
+            public void onHideLoadingUIComplete() {
+                mStartIcon.setVisibility(VISIBLE);
+            }
+        });
+        mLoadingView.addObserver(loadingViewObserver);
+        mLoadingView.showLoadingUI();
+    }
+
+    /**
+     * Hides the {@link LoadingView} at the start of the chip view.
+     * @param loadingViewObserver A {@link LoadingView.Observer} to add to the LoadingView.
+     */
+    public void hideLoadingView(LoadingView.Observer loadingViewObserver) {
+        mLoadingView.addObserver(loadingViewObserver);
+        mLoadingView.hideLoadingUI();
+    }
+
+    /**
+     * Adds a remove icon (X button) at the trailing end of the chip next to the primary text.
+     */
+    public void addRemoveIcon() {
+        if (mEndIconWrapper != null) return;
+
+        ChromeImageView endIcon = new ChromeImageView(getContext());
+        endIcon.setImageResource(R.drawable.btn_close);
+        ApiCompatibilityUtils.setImageTintList(endIcon, mPrimaryText.getTextColors());
+
+        // Adding a wrapper view around the X icon to make the touch target larger, which would
+        // cover the start and end margin for the X icon, and full height of the chip.
+        mEndIconWrapper = new FrameLayout(getContext());
+        mEndIconWrapper.setId(R.id.chip_cancel_btn);
+
+        FrameLayout.LayoutParams layoutParams =
+                new FrameLayout.LayoutParams(mEndIconWidth, mEndIconHeight);
+        layoutParams.setMarginStart(mEndIconStartPadding);
+        layoutParams.setMarginEnd(mEndIconEndPadding);
+        layoutParams.gravity = Gravity.CENTER_VERTICAL;
+        mEndIconWrapper.addView(endIcon, layoutParams);
+        addView(mEndIconWrapper,
+                new LayoutParams(
+                        ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        // Remove the end padding from the chip to make X icon touch target extend till the end of
+        // the chip.
+        ViewCompat.setPaddingRelative(
+                this, getPaddingStart(), getPaddingTop(), 0, getPaddingBottom());
+    }
+
+    /**
+     * Sets a {@link android.view.View.OnClickListener} for the remove icon.
+     * {@link ChipView#addRemoveIcon()} must be called prior to this method.
+     * @param listener The listener to be invoked on click events.
+     */
+    public void setRemoveIconClickListener(OnClickListener listener) {
+        mEndIconWrapper.setOnClickListener(listener);
+        String chipText = mPrimaryText.getText().toString();
+        assert !TextUtils.isEmpty(chipText);
+        mEndIconWrapper.setContentDescription(mPrimaryText.getContext().getString(
+                R.string.chip_remove_icon_content_description, chipText));
+    }
+
+    /**
+     * Returns the {@link TextView} that contains the label of the chip.
+     * @return A {@link TextView}.
+     */
+    public TextView getPrimaryTextView() {
+        return mPrimaryText;
+    }
+
+    /**
+     * Returns the {@link TextView} that contains the secondary label of the chip. If it wasn't used
+     * until now, this creates the view.
+     * @return A {@link TextView}.
+     */
+    public TextView getSecondaryTextView() {
+        if (mSecondaryText == null) {
+            mSecondaryText = new AppCompatTextView(
+                    new ContextThemeWrapper(getContext(), R.style.ChipTextView));
+            ApiCompatibilityUtils.setTextAppearance(mSecondaryText, mSecondaryTextAppearanceId);
+            // Ensure that basic state changes are aligned with the ChipView. They update
+            // automatically once the view is part of the hierarchy.
+            mSecondaryText.setSelected(isSelected());
+            mSecondaryText.setEnabled(isEnabled());
+            addView(mSecondaryText);
+        }
+        return mSecondaryText;
+    }
+
+    /**
+     * Returns the {@link RectProvider} that contains the start icon for the chip view.
+     * @return A {@link RectProvider}
+     */
+    public RectProvider getStartIconViewRect() {
+        return new ViewRectProvider(mStartIcon);
+    }
+
+    /**
+     * Sets the correct tinting on the Chip's image view.
+     * @param tintWithTextColor If true then the image view will be tinted with the primary text
+     *      color. If not, the tint will be cleared.
+     */
+    private void setTint(boolean tintWithTextColor) {
+        if (mPrimaryText.getTextColors() != null && tintWithTextColor) {
+            ApiCompatibilityUtils.setImageTintList(mStartIcon, mPrimaryText.getTextColors());
+        } else {
+            ApiCompatibilityUtils.setImageTintList(mStartIcon, null);
+        }
+    }
+
+    /**
+     * Sets border around the chip. If width is zero, then no border is drawn.
+     * @param width of the border in pixels.
+     * @param color of the border.
+     */
+    public void setBorder(int width, @ColorInt int color) {
+        mRippleBackgroundHelper.setBorder(width, color);
+    }
+
+    @Override
+    public void setBackgroundColor(@ColorInt int color) {
+        mRippleBackgroundHelper.setBackgroundColor(color);
+    }
+
+    /**
+     * @return The corner radius in pixels of this ChipView.
+     */
+    public @Px int getCornerRadius() {
+        return mCornerRadius;
+    }
+}
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipViewBinder.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipViewBinder.java
index 53e64ce..9cd1f34 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipViewBinder.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipViewBinder.java
@@ -9,11 +9,10 @@
 import org.chromium.components.browser_ui.widget.R;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
-import org.chromium.ui.widget.ChipView;
 
 /** View binder to bind a model to a {@link ChipView}. */
-class ChipViewBinder {
-    static void bind(PropertyModel model, ChipView chip, PropertyKey key) {
+public class ChipViewBinder {
+    public static void bind(PropertyModel model, ChipView chip, PropertyKey key) {
         if (ChipProperties.CLICK_HANDLER == key) {
             chip.setOnClickListener((v) -> model.get(ChipProperties.CLICK_HANDLER).onResult(model));
 
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipsCoordinator.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipsCoordinator.java
index 45e9c2d..d9765ed 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipsCoordinator.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/chips/ChipsCoordinator.java
@@ -22,7 +22,6 @@
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
-import org.chromium.ui.widget.ChipView;
 
 /**
  * The coordinator responsible for managing a list of chips.  To get the {@link View} that
diff --git a/components/cast_streaming/renderer/playback_command_forwarding_renderer.cc b/components/cast_streaming/renderer/playback_command_forwarding_renderer.cc
index b03dc53..dc2fa0f 100644
--- a/components/cast_streaming/renderer/playback_command_forwarding_renderer.cc
+++ b/components/cast_streaming/renderer/playback_command_forwarding_renderer.cc
@@ -7,6 +7,70 @@
 #include "base/notreached.h"
 
 namespace cast_streaming {
+namespace {
+
+constexpr base::TimeDelta kTimeUpdateInterval = base::Milliseconds(250);
+
+}  // namespace
+
+// Class responsible for receiving Renderer commands from a remote source and
+// forwarding them to |owning_renderer| unchanged. This class exists only to
+// avoid intersection of media::Renderer and media::mojom::Renderer methods in
+// PlaybackCommandForwardingRenderer.
+//
+// NOTE: This class CANNOT be declared in an unnamed namespace or the friend
+// declaration in PlaybackCommandForwardingRenderer will no longer function.
+class RendererCommandForwarder : public media::mojom::Renderer {
+ public:
+  // |owning_renderer| is expected to outlive this class.
+  RendererCommandForwarder(
+      PlaybackCommandForwardingRenderer* owning_renderer,
+      mojo::PendingReceiver<media::mojom::Renderer> playback_controller)
+      : owning_renderer_(owning_renderer),
+        playback_controller_(this, std::move(playback_controller)) {
+    DCHECK(owning_renderer_);
+  }
+
+  ~RendererCommandForwarder() override = default;
+
+  // media::mojom::Renderer overrides.
+  void Initialize(
+      ::mojo::PendingAssociatedRemote<media::mojom::RendererClient> client,
+      absl::optional<
+          std::vector<::mojo::PendingRemote<::media::mojom::DemuxerStream>>>
+          streams,
+      media::mojom::MediaUrlParamsPtr media_url_params,
+      InitializeCallback callback) override {
+    owning_renderer_->MojoRendererInitialize(
+        std::move(client), std::move(streams), std::move(media_url_params),
+        std::move(callback));
+  }
+
+  void StartPlayingFrom(::base::TimeDelta time) override {
+    owning_renderer_->MojoRendererStartPlayingFrom(std::move(time));
+  }
+
+  void SetPlaybackRate(double playback_rate) override {
+    owning_renderer_->MojoRendererSetPlaybackRate(playback_rate);
+  }
+
+  void Flush(FlushCallback callback) override {
+    owning_renderer_->MojoRendererFlush(std::move(callback));
+  }
+
+  void SetVolume(float volume) override {
+    owning_renderer_->MojoRendererSetVolume(volume);
+  }
+
+  void SetCdm(const absl::optional<::base::UnguessableToken>& cdm_id,
+              SetCdmCallback callback) override {
+    owning_renderer_->MojoRendererSetCdm(cdm_id, std::move(callback));
+  }
+
+ private:
+  PlaybackCommandForwardingRenderer* const owning_renderer_;
+  mojo::Receiver<media::mojom::Renderer> playback_controller_;
+};
 
 PlaybackCommandForwardingRenderer::PlaybackCommandForwardingRenderer(
     std::unique_ptr<media::Renderer> renderer,
@@ -18,6 +82,12 @@
       weak_factory_(this) {
   DCHECK(real_renderer_);
   DCHECK(pending_renderer_controls_);
+
+  send_timestamp_update_caller_.Start(
+      FROM_HERE, kTimeUpdateInterval,
+      base::BindRepeating(
+          &PlaybackCommandForwardingRenderer::SendTimestampUpdate,
+          weak_factory_.GetWeakPtr()));
 }
 
 PlaybackCommandForwardingRenderer::~PlaybackCommandForwardingRenderer() =
@@ -29,9 +99,10 @@
     media::PipelineStatusCallback init_cb) {
   DCHECK(!init_cb_);
 
+  upstream_renderer_client_ = client;
   init_cb_ = std::move(init_cb);
   real_renderer_->Initialize(
-      media_resource, client,
+      media_resource, this,
       base::BindOnce(&PlaybackCommandForwardingRenderer::
                          OnRealRendererInitializationComplete,
                      weak_factory_.GetWeakPtr()));
@@ -69,9 +140,8 @@
   DCHECK(init_cb_);
   DCHECK(!playback_controller_);
 
-  playback_controller_ = std::make_unique<PlaybackController>(
-      std::move(pending_renderer_controls_), task_runner_,
-      real_renderer_.get());
+  playback_controller_ = std::make_unique<RendererCommandForwarder>(
+      this, std::move(pending_renderer_controls_));
 
   std::move(init_cb_).Run(status);
 }
@@ -81,74 +151,205 @@
 // implementation. Calls must instead be bounced to the correct task runner in
 // each receiver method.
 // TODO(b/205307190): Bind the mojo pipe to the task runner directly.
-PlaybackCommandForwardingRenderer::PlaybackController::PlaybackController(
-    mojo::PendingReceiver<media::mojom::Renderer> pending_renderer_controls,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    media::Renderer* real_renderer)
-    : real_renderer_(real_renderer),
-      task_runner_(std::move(task_runner)),
-      playback_controller_(this, std::move(pending_renderer_controls)),
-      weak_factory_(this) {
-  DCHECK(real_renderer_);
-  DCHECK(task_runner_);
-}
-
-PlaybackCommandForwardingRenderer::PlaybackController::~PlaybackController() =
-    default;
-
-void PlaybackCommandForwardingRenderer::PlaybackController::Initialize(
+void PlaybackCommandForwardingRenderer::MojoRendererInitialize(
     ::mojo::PendingAssociatedRemote<media::mojom::RendererClient> client,
     absl::optional<
         std::vector<::mojo::PendingRemote<::media::mojom::DemuxerStream>>>
         streams,
     media::mojom::MediaUrlParamsPtr media_url_params,
-    InitializeCallback callback) {
-  NOTIMPLEMENTED();
-  std::move(callback).Run(false);
+    media::mojom::Renderer::InitializeCallback callback) {
+  DCHECK(!media_url_params);
+  DCHECK(client);
+
+  // NOTE: To maintain existing functionality, and ensure mirroring continues
+  // working as currently written with or without this Renderer, the mirroring
+  // data stream is provided through the standard Initialize() call, not passed
+  // over the mojo pipe here
+  DCHECK(!streams || streams.value().empty());
+
+  if (!task_runner_->BelongsToCurrentThread()) {
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            &PlaybackCommandForwardingRenderer::MojoRendererInitialize,
+            weak_factory_.GetWeakPtr(), std::move(client), std::move(streams),
+            std::move(media_url_params), std::move(callback)));
+    return;
+  }
+
+  remote_renderer_client_.Bind(std::move(client));
+
+  // |playback_controller_| which forwards the call here is only set following
+  // the completion of real_renderer_->Initialize().
+  std::move(callback).Run(true);
 }
 
-void PlaybackCommandForwardingRenderer::PlaybackController::Flush(
-    FlushCallback callback) {
-  NOTIMPLEMENTED();
-  std::move(callback).Run();
+void PlaybackCommandForwardingRenderer::MojoRendererFlush(
+    media::mojom::Renderer::FlushCallback callback) {
+  if (!task_runner_->BelongsToCurrentThread()) {
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&PlaybackCommandForwardingRenderer::MojoRendererFlush,
+                       weak_factory_.GetWeakPtr(), std::move(callback)));
+    return;
+  }
+
+  real_renderer_->Flush(std::move(callback));
 }
 
-void PlaybackCommandForwardingRenderer::PlaybackController::StartPlayingFrom(
+void PlaybackCommandForwardingRenderer::MojoRendererStartPlayingFrom(
     ::base::TimeDelta time) {
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(&PlaybackCommandForwardingRenderer::
-                                      PlaybackController::StartPlayingFrom,
-                                  weak_factory_.GetWeakPtr(), time));
+        FROM_HERE,
+        base::BindOnce(
+            &PlaybackCommandForwardingRenderer::MojoRendererStartPlayingFrom,
+            weak_factory_.GetWeakPtr(), time));
     return;
   }
 
   real_renderer_->StartPlayingFrom(time);
 }
 
-void PlaybackCommandForwardingRenderer::PlaybackController::SetPlaybackRate(
+void PlaybackCommandForwardingRenderer::MojoRendererSetPlaybackRate(
     double playback_rate) {
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(&PlaybackCommandForwardingRenderer::
-                                      PlaybackController::SetPlaybackRate,
-                                  weak_factory_.GetWeakPtr(), playback_rate));
+        FROM_HERE,
+        base::BindOnce(
+            &PlaybackCommandForwardingRenderer::MojoRendererSetPlaybackRate,
+            weak_factory_.GetWeakPtr(), playback_rate));
     return;
   }
 
   real_renderer_->SetPlaybackRate(playback_rate);
 }
 
-void PlaybackCommandForwardingRenderer::PlaybackController::SetVolume(
-    float volume) {
-  NOTIMPLEMENTED();
+void PlaybackCommandForwardingRenderer::MojoRendererSetVolume(float volume) {
+  if (!task_runner_->BelongsToCurrentThread()) {
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            &PlaybackCommandForwardingRenderer::MojoRendererSetVolume,
+            weak_factory_.GetWeakPtr(), volume));
+    return;
+  }
+
+  real_renderer_->SetVolume(volume);
 }
 
-void PlaybackCommandForwardingRenderer::PlaybackController::SetCdm(
+void PlaybackCommandForwardingRenderer::MojoRendererSetCdm(
     const absl::optional<::base::UnguessableToken>& cdm_id,
-    SetCdmCallback callback) {
-  NOTIMPLEMENTED();
-  std::move(callback).Run(false);
+    media::mojom::Renderer::SetCdmCallback callback) {
+  NOTREACHED() << "Use of a CDM is not supported by the remoting protocol.";
+}
+
+void PlaybackCommandForwardingRenderer::OnError(media::PipelineStatus status) {
+  if (remote_renderer_client_)
+    remote_renderer_client_->OnError(status);
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnError(status);
+}
+
+void PlaybackCommandForwardingRenderer::OnEnded() {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (remote_renderer_client_)
+    remote_renderer_client_->OnEnded();
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnEnded();
+}
+
+void PlaybackCommandForwardingRenderer::OnStatisticsUpdate(
+    const media::PipelineStatistics& stats) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (remote_renderer_client_)
+    remote_renderer_client_->OnStatisticsUpdate(stats);
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnStatisticsUpdate(stats);
+}
+
+void PlaybackCommandForwardingRenderer::OnBufferingStateChange(
+    media::BufferingState state,
+    media::BufferingStateChangeReason reason) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (remote_renderer_client_)
+    remote_renderer_client_->OnBufferingStateChange(state, reason);
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnBufferingStateChange(state, reason);
+}
+
+void PlaybackCommandForwardingRenderer::OnWaiting(media::WaitingReason reason) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (remote_renderer_client_)
+    remote_renderer_client_->OnWaiting(reason);
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnWaiting(reason);
+}
+
+void PlaybackCommandForwardingRenderer::OnAudioConfigChange(
+    const media::AudioDecoderConfig& config) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (remote_renderer_client_)
+    remote_renderer_client_->OnAudioConfigChange(config);
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnAudioConfigChange(config);
+}
+
+void PlaybackCommandForwardingRenderer::OnVideoConfigChange(
+    const media::VideoDecoderConfig& config) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (remote_renderer_client_)
+    remote_renderer_client_->OnVideoConfigChange(config);
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnVideoConfigChange(config);
+}
+
+void PlaybackCommandForwardingRenderer::OnVideoNaturalSizeChange(
+    const gfx::Size& size) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (remote_renderer_client_)
+    remote_renderer_client_->OnVideoNaturalSizeChange(size);
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnVideoNaturalSizeChange(size);
+}
+
+void PlaybackCommandForwardingRenderer::OnVideoOpacityChange(bool opaque) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (remote_renderer_client_)
+    remote_renderer_client_->OnVideoOpacityChange(opaque);
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnVideoOpacityChange(opaque);
+}
+
+void PlaybackCommandForwardingRenderer::OnVideoFrameRateChange(
+    absl::optional<int> fps) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // media::mojom::RendererClient does not support this call.
+  if (upstream_renderer_client_)
+    upstream_renderer_client_->OnVideoFrameRateChange(std::move(fps));
+}
+
+void PlaybackCommandForwardingRenderer::SendTimestampUpdate() {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (!remote_renderer_client_) {
+    return;
+  }
+
+  // Because |remote_renderer_client_| isn't set until |real_renderer_| is
+  // initialized, this call is well defined.
+  base::TimeDelta media_time = real_renderer_->GetMediaTime();
+  remote_renderer_client_->OnTimeUpdate(media_time, media_time,
+                                        base::TimeTicks::Now());
 }
 
 }  // namespace cast_streaming
diff --git a/components/cast_streaming/renderer/playback_command_forwarding_renderer.h b/components/cast_streaming/renderer/playback_command_forwarding_renderer.h
index fcc891b..96ef1b3 100644
--- a/components/cast_streaming/renderer/playback_command_forwarding_renderer.h
+++ b/components/cast_streaming/renderer/playback_command_forwarding_renderer.h
@@ -9,7 +9,9 @@
 
 #include "base/memory/weak_ptr.h"
 #include "media/base/renderer.h"
+#include "media/base/renderer_client.h"
 #include "media/mojo/mojom/renderer.mojom.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 
@@ -17,7 +19,8 @@
 
 // For high-level details, see documentation in
 // PlaybackCommandForwardingRendererFactory.h.
-class PlaybackCommandForwardingRenderer : public media::Renderer {
+class PlaybackCommandForwardingRenderer : public media::Renderer,
+                                          public media::RendererClient {
  public:
   // |renderer| is the Renderer to which the Initialize() call should be
   // delegated.
@@ -59,46 +62,51 @@
   base::TimeDelta GetMediaTime() override;
 
  private:
-  // Class responsible for receiving Renderer commands from a remote source and
-  // acting on |real_renderer_| appropriately. This logic has been separated
-  // from the parent class to avoid the complexity associated with having
-  // both media::Renderer and media::mojo::Renderer implemented side-by-side.
-  class PlaybackController : public media::mojom::Renderer {
-   public:
-    PlaybackController(
-        mojo::PendingReceiver<media::mojom::Renderer> pending_rederer_controls,
-        scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-        media::Renderer* real_renderer);
-    ~PlaybackController() override;
+  // Private namespace function not defined here because its details are not
+  // important.
+  friend class RendererCommandForwarder;
 
-    // media::mojom::Renderer overrides.
-    void StartPlayingFrom(::base::TimeDelta time) override;
-    void SetPlaybackRate(double playback_rate) override;
+  // media::mojom::Renderer implementation, with methods renamed to avoid
+  // intersection with media::Renderer types.
+  //
+  // Calls are all forwarded to |real_renderer_|;
+  void MojoRendererInitialize(
+      ::mojo::PendingAssociatedRemote<media::mojom::RendererClient> client,
+      absl::optional<
+          std::vector<::mojo::PendingRemote<::media::mojom::DemuxerStream>>>
+          streams,
+      media::mojom::MediaUrlParamsPtr media_url_params,
+      media::mojom::Renderer::InitializeCallback callback);
+  void MojoRendererStartPlayingFrom(::base::TimeDelta time);
+  void MojoRendererSetPlaybackRate(double playback_rate);
+  void MojoRendererFlush(media::mojom::Renderer::FlushCallback callback);
+  void MojoRendererSetVolume(float volume);
+  void MojoRendererSetCdm(
+      const absl::optional<::base::UnguessableToken>& cdm_id,
+      media::mojom::Renderer::SetCdmCallback callback);
 
-    // The following overrides are not currently implemented.
-    //
-    // TODO(b/182429524): Implement these methods.
-    void Initialize(
-        ::mojo::PendingAssociatedRemote<media::mojom::RendererClient> client,
-        absl::optional<
-            std::vector<::mojo::PendingRemote<::media::mojom::DemuxerStream>>>
-            streams,
-        media::mojom::MediaUrlParamsPtr media_url_params,
-        InitializeCallback callback) override;
-    void Flush(FlushCallback callback) override;
-    void SetVolume(float volume) override;
-    void SetCdm(const absl::optional<::base::UnguessableToken>& cdm_id,
-                SetCdmCallback callback) override;
-
-   private:
-    media::Renderer* const real_renderer_;
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-    mojo::Receiver<media::mojom::Renderer> playback_controller_;
-    base::WeakPtrFactory<PlaybackController> weak_factory_;
-  };
+  // media::RendererClient overrides.
+  //
+  // Each of these simply forwards the call to both |remote_renderer_client_|
+  // and |upstream_renderer_client_|.
+  void OnError(media::PipelineStatus status) override;
+  void OnEnded() override;
+  void OnStatisticsUpdate(const media::PipelineStatistics& stats) override;
+  void OnBufferingStateChange(
+      media::BufferingState state,
+      media::BufferingStateChangeReason reason) override;
+  void OnWaiting(media::WaitingReason reason) override;
+  void OnAudioConfigChange(const media::AudioDecoderConfig& config) override;
+  void OnVideoConfigChange(const media::VideoDecoderConfig& config) override;
+  void OnVideoNaturalSizeChange(const gfx::Size& size) override;
+  void OnVideoOpacityChange(bool opaque) override;
+  void OnVideoFrameRateChange(absl::optional<int> fps) override;
 
   void OnRealRendererInitializationComplete(media::PipelineStatus status);
 
+  // Sends an OnTimeUpdate() call to |remote_renderer_client_|.
+  void SendTimestampUpdate();
+
   // Renderer to which playback calls should be forwarded.
   std::unique_ptr<media::Renderer> real_renderer_;
 
@@ -114,7 +122,15 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
   // Created as part of OnRealRendererInitializationComplete().
-  std::unique_ptr<PlaybackController> playback_controller_;
+  std::unique_ptr<media::mojom::Renderer> playback_controller_;
+
+  // Channel to provide data back to the remote caller, set during
+  // MojoRendererInitialize().
+  mojo::AssociatedRemote<media::mojom::RendererClient> remote_renderer_client_;
+
+  RendererClient* upstream_renderer_client_;
+
+  base::RepeatingTimer send_timestamp_update_caller_;
 
   base::WeakPtrFactory<PlaybackCommandForwardingRenderer> weak_factory_;
 };
diff --git a/components/cast_streaming/renderer/playback_command_forwarding_renderer_unittest.cc b/components/cast_streaming/renderer/playback_command_forwarding_renderer_unittest.cc
index d7ca94b..fe10c67 100644
--- a/components/cast_streaming/renderer/playback_command_forwarding_renderer_unittest.cc
+++ b/components/cast_streaming/renderer/playback_command_forwarding_renderer_unittest.cc
@@ -7,13 +7,60 @@
 #include "base/test/bind.h"
 #include "base/test/task_environment.h"
 #include "components/cast_streaming/public/mojom/renderer_controller.mojom.h"
+#include "media/base/media_util.h"
 #include "media/base/mock_filters.h"
 #include "media/base/test_helpers.h"
+#include "media/mojo/mojom/renderer.mojom.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
+#include "mojo/public/cpp/bindings/pending_associated_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace cast_streaming {
+namespace {
+
+class MockMojoRendererClient : public media::mojom::RendererClient {
+ public:
+  explicit MockMojoRendererClient(
+      mojo::PendingAssociatedReceiver<media::mojom::RendererClient> receiver)
+      : receiver_(this, std::move(receiver)) {}
+
+  MockMojoRendererClient(const MockMojoRendererClient&) = delete;
+  MockMojoRendererClient& operator=(const MockMojoRendererClient&) = delete;
+
+  ~MockMojoRendererClient() override = default;
+
+  MOCK_METHOD0(FlushCallback, void());
+  MOCK_METHOD1(InitializeCallback, void(bool));
+
+  // mojom::RendererClient implementation.
+  MOCK_METHOD3(OnTimeUpdate,
+               void(base::TimeDelta time,
+                    base::TimeDelta max_time,
+                    base::TimeTicks capture_time));
+  MOCK_METHOD2(OnBufferingStateChange,
+               void(media::BufferingState state,
+                    media::BufferingStateChangeReason reason));
+  MOCK_METHOD0(OnEnded, void());
+  MOCK_METHOD1(OnError, void(const media::PipelineStatus& status));
+  MOCK_METHOD1(OnVideoOpacityChange, void(bool opaque));
+  MOCK_METHOD1(OnAudioConfigChange, void(const media::AudioDecoderConfig&));
+  MOCK_METHOD1(OnVideoConfigChange, void(const media::VideoDecoderConfig&));
+  MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size& size));
+  MOCK_METHOD1(OnStatisticsUpdate,
+               void(const media::PipelineStatistics& stats));
+  MOCK_METHOD1(OnWaiting, void(media::WaitingReason));
+  MOCK_METHOD1(OnDurationChange, void(base::TimeDelta duration));
+  MOCK_METHOD1(OnRemotePlayStateChange, void(media::MediaStatus::State state));
+
+ private:
+  mojo::AssociatedReceiver<media::mojom::RendererClient> receiver_;
+};
+
+}  // namespace
 
 class PlaybackCommandForwardingRendererTest : public testing::Test {
  public:
@@ -24,47 +71,58 @@
     renderer_ = std::make_unique<PlaybackCommandForwardingRenderer>(
         std::move(mock_renderer), task_environment_.GetMainThreadTaskRunner(),
         remote_.BindNewPipeAndPassReceiver());
+
+    mojo_renderer_client_ =
+        std::make_unique<testing::StrictMock<MockMojoRendererClient>>(
+            remote_client_.InitWithNewEndpointAndPassReceiver());
   }
 
   ~PlaybackCommandForwardingRendererTest() override = default;
 
+ protected:
+  void CallInitialize() {
+    auto init_cb = base::BindOnce(
+        &PlaybackCommandForwardingRendererTest::OnInitializationComplete,
+        base::Unretained(this));
+
+    EXPECT_CALL(*mock_renderer_, OnInitialize(&mock_media_resource_,
+                                              renderer_.get(), testing::_))
+        .WillOnce([this](media::MediaResource* media_resource,
+                         media::RendererClient* client,
+                         media::PipelineStatusCallback& init_cb) {
+          task_environment_.GetMainThreadTaskRunner()->PostTask(
+              FROM_HERE,
+              base::BindOnce(std::move(init_cb), media::PIPELINE_OK));
+        });
+
+    renderer_->Initialize(&mock_media_resource_, &mock_renderer_client_,
+                          std::move(init_cb));
+  }
+
+  media::RendererClient* renderer_client() { return renderer_.get(); }
+
   MOCK_METHOD1(OnInitializationComplete, void(media::PipelineStatus));
 
- protected:
   base::test::SingleThreadTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
   mojo::Remote<media::mojom::Renderer> remote_;
+  mojo::PendingAssociatedRemote<media::mojom::RendererClient> remote_client_;
 
   media::MockRenderer* mock_renderer_;
+  testing::StrictMock<media::MockMediaResource> mock_media_resource_;
+  testing::StrictMock<media::MockRendererClient> mock_renderer_client_;
   std::unique_ptr<PlaybackCommandForwardingRenderer> renderer_;
+  std::unique_ptr<testing::StrictMock<MockMojoRendererClient>>
+      mojo_renderer_client_;
 };
 
-TEST_F(PlaybackCommandForwardingRendererTest,
-       RendererInitializeInitializesMojoPipe) {
-  testing::StrictMock<media::MockMediaResource> mock_media_resource;
-  testing::StrictMock<media::MockRendererClient> mock_renderer_client;
-
-  auto init_cb = base::BindOnce(
-      &PlaybackCommandForwardingRendererTest::OnInitializationComplete,
-      base::Unretained(this));
-
-  EXPECT_CALL(*mock_renderer_, OnInitialize(&mock_media_resource,
-                                            &mock_renderer_client, testing::_))
-      .WillOnce([this](media::MediaResource* media_resource,
-                       media::RendererClient* client,
-                       media::PipelineStatusCallback& init_cb) {
-        auto result = base::BindOnce(std::move(init_cb), media::PIPELINE_OK);
-        task_environment_.GetMainThreadTaskRunner()->PostTask(
-            FROM_HERE, std::move(result));
-      });
-
+TEST_F(PlaybackCommandForwardingRendererTest, StartPlaybackAsMirroring) {
   remote_->SetPlaybackRate(1.0);
   remote_->StartPlayingFrom(base::TimeDelta{});
   task_environment_.RunUntilIdle();
 
-  renderer_->Initialize(&mock_media_resource, &mock_renderer_client,
-                        std::move(init_cb));
+  CallInitialize();
 
   EXPECT_CALL(*this, OnInitializationComplete(
                          media::HasStatusCode(media::PIPELINE_OK)));
@@ -73,4 +131,134 @@
   task_environment_.RunUntilIdle();
 }
 
+TEST_F(PlaybackCommandForwardingRendererTest, MojoCallsCorrectlyForwarded) {
+  CallInitialize();
+  EXPECT_CALL(*this, OnInitializationComplete(
+                         media::HasStatusCode(media::PIPELINE_OK)));
+  task_environment_.RunUntilIdle();
+
+  EXPECT_CALL(*mock_renderer_, StartPlayingFrom(base::Seconds(42)));
+  remote_->StartPlayingFrom(base::Seconds(42));
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mock_renderer_);
+
+  EXPECT_CALL(*mock_renderer_, SetPlaybackRate(12.34));
+  remote_->SetPlaybackRate(12.34);
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mock_renderer_);
+
+  EXPECT_CALL(*mock_renderer_, OnFlush(testing::_))
+      .WillOnce([](base::OnceClosure& callback) { std::move(callback).Run(); });
+  EXPECT_CALL(*mojo_renderer_client_, FlushCallback());
+  remote_->Flush(base::BindOnce(&MockMojoRendererClient::FlushCallback,
+                                base::Unretained(mojo_renderer_client_.get())));
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mock_renderer_);
+
+  EXPECT_CALL(*mock_renderer_, SetVolume(43.21));
+  remote_->SetVolume(43.21);
+  task_environment_.RunUntilIdle();
+}
+
+TEST_F(PlaybackCommandForwardingRendererTest, RendererClientCallbacksCalled) {
+  CallInitialize();
+  EXPECT_CALL(*this, OnInitializationComplete(
+                         media::HasStatusCode(media::PIPELINE_OK)));
+  task_environment_.RunUntilIdle();
+
+  EXPECT_CALL(*mojo_renderer_client_, InitializeCallback(true));
+  remote_->Initialize(
+      std::move(remote_client_), absl::nullopt, nullptr,
+      base::BindOnce(&MockMojoRendererClient::InitializeCallback,
+                     base::Unretained(mojo_renderer_client_.get())));
+  task_environment_.RunUntilIdle();
+
+  const auto status = media::PIPELINE_ERROR_NETWORK;
+  EXPECT_CALL(*mojo_renderer_client_, OnError(testing::_));
+  EXPECT_CALL(mock_renderer_client_, OnError(media::HasStatusCode(status)));
+  renderer_client()->OnError(status);
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mojo_renderer_client_.get());
+  testing::Mock::VerifyAndClearExpectations(&mock_renderer_client_);
+
+  EXPECT_CALL(*mojo_renderer_client_, OnEnded());
+  EXPECT_CALL(mock_renderer_client_, OnEnded());
+  renderer_client()->OnEnded();
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mojo_renderer_client_.get());
+  testing::Mock::VerifyAndClearExpectations(&mock_renderer_client_);
+
+  media::PipelineStatistics stats;
+  stats.audio_bytes_decoded = 7;
+  stats.video_memory_usage = 42;
+  EXPECT_CALL(*mojo_renderer_client_, OnStatisticsUpdate(stats));
+  EXPECT_CALL(mock_renderer_client_, OnStatisticsUpdate(stats));
+  renderer_client()->OnStatisticsUpdate(stats);
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mojo_renderer_client_.get());
+  testing::Mock::VerifyAndClearExpectations(&mock_renderer_client_);
+
+  const media::BufferingState state = media::BUFFERING_HAVE_ENOUGH;
+  const media::BufferingStateChangeReason reason = media::DEMUXER_UNDERFLOW;
+  EXPECT_CALL(*mojo_renderer_client_, OnBufferingStateChange(state, reason));
+  EXPECT_CALL(mock_renderer_client_, OnBufferingStateChange(state, reason));
+  renderer_client()->OnBufferingStateChange(state, reason);
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mojo_renderer_client_.get());
+  testing::Mock::VerifyAndClearExpectations(&mock_renderer_client_);
+
+  const auto wait_reason = media::WaitingReason::kDecoderStateLost;
+  EXPECT_CALL(*mojo_renderer_client_, OnWaiting(wait_reason));
+  EXPECT_CALL(mock_renderer_client_, OnWaiting(wait_reason));
+  renderer_client()->OnWaiting(wait_reason);
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mojo_renderer_client_.get());
+  testing::Mock::VerifyAndClearExpectations(&mock_renderer_client_);
+
+  const media::AudioDecoderConfig audio_config(
+      media::AudioCodec::kAAC, media::SampleFormat::kSampleFormatU8,
+      media::CHANNEL_LAYOUT_STEREO, 3, {},
+      media::EncryptionScheme::kUnencrypted);
+  EXPECT_CALL(*mojo_renderer_client_, OnAudioConfigChange(testing::_));
+  EXPECT_CALL(mock_renderer_client_, OnAudioConfigChange(testing::_));
+  renderer_client()->OnAudioConfigChange(audio_config);
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mojo_renderer_client_.get());
+  testing::Mock::VerifyAndClearExpectations(&mock_renderer_client_);
+
+  const media::VideoDecoderConfig video_config(
+      media::VideoCodec::kH264, media::H264PROFILE_MAIN,
+      media::VideoDecoderConfig::AlphaMode::kIsOpaque, media::VideoColorSpace(),
+      media::VideoTransformation(), gfx::Size{1920, 1080},
+      gfx::Rect{1920, 1080}, gfx::Size{1920, 1080}, media::EmptyExtraData(),
+      media::EncryptionScheme::kUnencrypted);
+  EXPECT_CALL(*mojo_renderer_client_, OnVideoConfigChange(testing::_));
+  EXPECT_CALL(mock_renderer_client_, OnVideoConfigChange(testing::_));
+  renderer_client()->OnVideoConfigChange(video_config);
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mojo_renderer_client_.get());
+  testing::Mock::VerifyAndClearExpectations(&mock_renderer_client_);
+
+  const gfx::Size size{123, 456};
+  EXPECT_CALL(*mojo_renderer_client_, OnVideoNaturalSizeChange(size));
+  EXPECT_CALL(mock_renderer_client_, OnVideoNaturalSizeChange(size));
+  renderer_client()->OnVideoNaturalSizeChange(size);
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mojo_renderer_client_.get());
+  testing::Mock::VerifyAndClearExpectations(&mock_renderer_client_);
+
+  const bool opacity = true;
+  EXPECT_CALL(*mojo_renderer_client_, OnVideoOpacityChange(opacity));
+  EXPECT_CALL(mock_renderer_client_, OnVideoOpacityChange(opacity));
+  renderer_client()->OnVideoOpacityChange(opacity);
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(mojo_renderer_client_.get());
+  testing::Mock::VerifyAndClearExpectations(&mock_renderer_client_);
+
+  const absl::optional<int> frame_rate = 123;
+  EXPECT_CALL(mock_renderer_client_, OnVideoFrameRateChange(frame_rate));
+  renderer_client()->OnVideoFrameRateChange(frame_rate);
+  task_environment_.RunUntilIdle();
+}
+
 }  // namespace cast_streaming
diff --git a/components/cdm/browser/cdm_message_filter_android.cc b/components/cdm/browser/cdm_message_filter_android.cc
index 893aa2b..c61eacfd 100644
--- a/components/cdm/browser/cdm_message_filter_android.cc
+++ b/components/cdm/browser/cdm_message_filter_android.cc
@@ -74,6 +74,10 @@
     {media::EME_CODEC_AC3, media::AudioCodec::kAC3},
     {media::EME_CODEC_EAC3, media::AudioCodec::kEAC3},
 #endif
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+    {media::EME_CODEC_DTS, media::AudioCodec::kDTS},
+    {media::EME_CODEC_DTSXP2, media::AudioCodec::kDTSXP2},
+#endif
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 };
 
diff --git a/components/data_reduction_proxy/DEPS b/components/data_reduction_proxy/DEPS
index 8d8a32f..e09f4739 100644
--- a/components/data_reduction_proxy/DEPS
+++ b/components/data_reduction_proxy/DEPS
@@ -1,5 +1,4 @@
 include_rules = [
-  "+components/data_use_measurement/core",
   "+components/pref_registry",
   "+components/prefs",
   "+components/previews/core",
diff --git a/components/data_reduction_proxy/core/browser/BUILD.gn b/components/data_reduction_proxy/core/browser/BUILD.gn
index 90846b2..1d7225f 100644
--- a/components/data_reduction_proxy/core/browser/BUILD.gn
+++ b/components/data_reduction_proxy/core/browser/BUILD.gn
@@ -7,8 +7,6 @@
 }
 
 browser_sources = [
-  "data_reduction_proxy_compression_stats.cc",
-  "data_reduction_proxy_compression_stats.h",
   "data_reduction_proxy_metrics.h",
   "data_reduction_proxy_prefs.cc",
   "data_reduction_proxy_prefs.h",
@@ -16,12 +14,6 @@
   "data_reduction_proxy_service.h",
   "data_reduction_proxy_settings.cc",
   "data_reduction_proxy_settings.h",
-  "data_store.cc",
-  "data_store.h",
-  "data_usage_store.cc",
-  "data_usage_store.h",
-  "db_data_owner.cc",
-  "db_data_owner.h",
 ]
 
 if (is_android) {
@@ -31,9 +23,6 @@
     deps = [
       "//base",
       "//components/data_reduction_proxy/core/common",
-      "//components/data_reduction_proxy/proto:data_reduction_proxy_proto",
-      "//components/data_use_measurement/core",
-      "//components/data_use_measurement/core:ascriber",
       "//components/pref_registry",
       "//components/prefs",
       "//crypto",
@@ -46,19 +35,10 @@
 
 static_library("browser") {
   sources = browser_sources
-  sources += [
-    "data_store_impl.cc",
-    "data_store_impl.h",
-  ]
 
-  public_deps = [
-    "//components/data_reduction_proxy/core/common",
-    "//components/data_reduction_proxy/proto:data_reduction_proxy_proto",
-  ]
+  public_deps = [ "//components/data_reduction_proxy/core/common" ]
   deps = [
     "//base",
-    "//components/data_use_measurement/core",
-    "//components/data_use_measurement/core:ascriber",
     "//components/pref_registry",
     "//components/prefs",
     "//crypto",
@@ -88,8 +68,6 @@
   deps = [
     "//base",
     "//components/data_reduction_proxy/core/common",
-    "//components/data_use_measurement/core",
-    "//components/data_use_measurement/core:ascriber",
     "//components/prefs:test_support",
     "//net",
     "//net:test_support",
@@ -99,41 +77,16 @@
   ]
 }
 
-bundle_data("unit_tests_bundle_data") {
-  visibility = [ ":unit_tests" ]
-  testonly = true
-  sources = [
-    "//components/test/data/data_reduction_proxy/direct/block10.html",
-    "//components/test/data/data_reduction_proxy/direct/block10.html.mock-http-headers",
-    "//components/test/data/data_reduction_proxy/direct/noblock.html",
-    "//components/test/data/data_reduction_proxy/direct/noblock.html.mock-http-headers",
-    "//components/test/data/data_reduction_proxy/proxy/block10.html",
-    "//components/test/data/data_reduction_proxy/proxy/block10.html.mock-http-headers",
-    "//components/test/data/data_reduction_proxy/proxy/noblock.html",
-    "//components/test/data/data_reduction_proxy/proxy/noblock.html.mock-http-headers",
-  ]
-  outputs = [ "{{bundle_resources_dir}}/" +
-              "{{source_root_relative_dir}}/{{source_file_part}}" ]
-}
-
 source_set("unit_tests") {
   testonly = true
-  sources = [
-    "data_reduction_proxy_compression_stats_unittest.cc",
-    "data_reduction_proxy_prefs_unittest.cc",
-    "data_reduction_proxy_settings_unittest.cc",
-    "data_usage_store_unittest.cc",
-  ]
+  sources = [ "data_reduction_proxy_settings_unittest.cc" ]
 
   deps = [
     ":browser",
     ":test_support",
-    ":unit_tests_bundle_data",
     "//base",
     "//base/test:test_support",
     "//build:chromeos_buildflags",
-    "//components/data_reduction_proxy/proto:data_reduction_proxy_proto",
-    "//components/data_use_measurement/core:ascriber",
     "//components/prefs:test_support",
     "//components/variations:test_support",
     "//net:test_support",
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
deleted file mode 100644
index ce830fdc..0000000
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
+++ /dev/null
@@ -1,887 +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 "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
-
-#include <algorithm>
-#include <cmath>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/check_op.h"
-#include "base/command_line.h"
-#include "base/feature_list.h"
-#include "base/location.h"
-#include "base/memory/raw_ptr.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/trace_event/trace_event.h"
-#include "base/values.h"
-#include "build/build_config.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
-#include "components/data_reduction_proxy/core/browser/data_usage_store.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
-#include "components/data_reduction_proxy/proto/data_store.pb.h"
-#include "components/prefs/pref_service.h"
-#include "components/prefs/scoped_user_pref_update.h"
-#include "net/base/mime_util.h"
-
-namespace data_reduction_proxy {
-
-namespace {
-
-#define CONCAT(a, b) a##b
-// CONCAT1 provides extra level of indirection so that __LINE__ macro expands.
-#define CONCAT1(a, b) CONCAT(a, b)
-#define UNIQUE_VARNAME CONCAT1(var_, __LINE__)
-// We need to use a macro instead of a method because UMA_HISTOGRAM_COUNTS_1M
-// requires its first argument to be an inline string and not a variable.
-#define RECORD_INT64PREF_TO_HISTOGRAM(pref, uma)        \
-  int64_t UNIQUE_VARNAME = GetInt64(pref);              \
-  if (UNIQUE_VARNAME > 0) {                             \
-    UMA_HISTOGRAM_COUNTS_1M(uma, UNIQUE_VARNAME >> 10); \
-  }
-
-// Returns the value at |index| of |list_value| as an int64_t.
-int64_t GetInt64PrefValue(const base::Value& list_value, size_t index) {
-  int64_t val = 0;
-  base::Value::ConstListView list_value_view = list_value.GetList();
-  if (index < list_value_view.size() && list_value_view[index].is_string()) {
-    const base::Value& pref_value = list_value_view[index];
-    DCHECK(pref_value.is_string());
-    bool rv = base::StringToInt64(pref_value.GetString(), &val);
-    DCHECK(rv);
-  }
-  return val;
-}
-
-// Ensure list has exactly |length| elements, either by truncating at the
-// front, or appending "0"'s to the back.
-void MaintainContentLengthPrefsWindow(base::Value* list, size_t length) {
-  // Remove data for old days from the front.
-  base::Value::ListView list_view = list->GetList();
-  while (list_view.size() > length)
-    list->EraseListIter(list_view.begin());
-  // Newly added lists are empty. Add entries to back to fill the window,
-  // each initialized to zero.
-  while (list_view.size() < length)
-    list->Append(base::NumberToString(0));
-  DCHECK_EQ(length, list_view.size());
-}
-
-// Increments an int64_t, stored as a string, in a ListPref at the specified
-// index.  The value must already exist and be a string representation of a
-// number.
-void AddInt64ToListPref(size_t index,
-                        int64_t length,
-                        base::Value* list_update) {
-  int64_t value = GetInt64PrefValue(*list_update, index) + length;
-  list_update->GetList()[index] = base::Value(base::NumberToString(value));
-}
-
-void RecordSavingsClearedMetric(DataReductionProxySavingsClearedReason reason) {
-  DCHECK_GT(DataReductionProxySavingsClearedReason::REASON_COUNT, reason);
-  UMA_HISTOGRAM_ENUMERATION(
-      "DataReductionProxy.SavingsCleared.Reason", reason,
-      DataReductionProxySavingsClearedReason::REASON_COUNT);
-}
-
-// TODO(rajendrant): Enable aggregate metrics recording in x86 Android.
-// http://crbug.com/865373
-#if !BUILDFLAG(IS_ANDROID) || !defined(ARCH_CPU_X86)
-const double kSecondsPerWeek =
-    base::Time::kMicrosecondsPerWeek / base::Time::kMicrosecondsPerSecond;
-
-// Returns the week number for the current time. The epoch time is treated as
-// week=0.
-int32_t GetCurrentWeekNumber(const base::Time& now) {
-  double now_in_seconds = now.ToDoubleT();
-  return now_in_seconds / kSecondsPerWeek;
-}
-
-// Adds |value| to the item at |key| in the preference dictionary found at
-// |pref|. If |key| is not found it will be inserted.
-void AddToDictionaryPref(PrefService* pref_service,
-                         const std::string& pref,
-                         int key,
-                         int value) {
-  DictionaryPrefUpdate pref_update(pref_service, pref);
-  base::Value* pref_dict = pref_update.Get();
-  const std::string key_str = base::NumberToString(key);
-  base::Value* dict_value = pref_dict->FindKey(key_str);
-  if (dict_value)
-    value += dict_value->GetInt();
-  pref_dict->SetIntKey(key_str, value);
-}
-
-// Moves the dictionary stored in preference |pref_src| to |pref_dst|, and
-// clears the preference |pref_src|.
-void MoveAndClearDictionaryPrefs(PrefService* pref_service,
-                                 const std::string& pref_dst,
-                                 const std::string& pref_src) {
-  DictionaryPrefUpdate pref_update_dst(pref_service, pref_dst);
-  base::Value* pref_dict_dst = pref_update_dst.Get();
-  DictionaryPrefUpdate pref_update_src(pref_service, pref_src);
-  base::Value* pref_dict_src = pref_update_src.Get();
-  *pref_dict_dst = std::move(*pref_dict_src);
-  *pref_dict_src = base::Value(base::Value::Type::DICTIONARY);
-}
-
-void MaybeInitWeeklyAggregateDataUsePrefs(const base::Time& now,
-                                          PrefService* pref_service) {
-  int saved_week = pref_service->GetInteger(prefs::kThisWeekNumber);
-  int current_week = GetCurrentWeekNumber(now);
-
-  if (saved_week == current_week)
-    return;
-
-  pref_service->SetInteger(prefs::kThisWeekNumber, current_week);
-  if (current_week == saved_week + 1) {
-    // The next week has just started. Move the data use aggregate prefs for
-    // this week to last week, and clear the prefs for this week.
-    MoveAndClearDictionaryPrefs(pref_service,
-                                prefs::kLastWeekServicesDownstreamBackgroundKB,
-                                prefs::kThisWeekServicesDownstreamBackgroundKB);
-    MoveAndClearDictionaryPrefs(pref_service,
-                                prefs::kLastWeekServicesDownstreamForegroundKB,
-                                prefs::kThisWeekServicesDownstreamForegroundKB);
-    MoveAndClearDictionaryPrefs(
-        pref_service, prefs::kLastWeekUserTrafficContentTypeDownstreamKB,
-        prefs::kThisWeekUserTrafficContentTypeDownstreamKB);
-  } else {
-    // Current week is too different than the last time data use aggregate prefs
-    // were updated. This may happen if Chrome was opened after a long time, or
-    // due to system clock being changed backward or forward. Clear all prefs in
-    // this case.
-    pref_service->ClearPref(prefs::kLastWeekServicesDownstreamBackgroundKB);
-    pref_service->ClearPref(prefs::kLastWeekServicesDownstreamForegroundKB);
-    pref_service->ClearPref(prefs::kLastWeekUserTrafficContentTypeDownstreamKB);
-    pref_service->ClearPref(prefs::kThisWeekServicesDownstreamBackgroundKB);
-    pref_service->ClearPref(prefs::kThisWeekServicesDownstreamForegroundKB);
-    pref_service->ClearPref(prefs::kThisWeekUserTrafficContentTypeDownstreamKB);
-  }
-}
-
-// Records the key-value pairs in the dictionary in a sparse histogram.
-void RecordDictionaryToHistogram(const std::string& histogram_name,
-                                 const base::Value* dictionary) {
-  base::HistogramBase* histogram = base::SparseHistogram::FactoryGet(
-      histogram_name, base::HistogramBase::kUmaTargetedHistogramFlag);
-  for (auto entry : dictionary->DictItems()) {
-    int key;
-    int value = entry.second.GetInt();
-    if (value > 0 && base::StringToInt(entry.first, &key)) {
-      histogram->AddCount(key, value);
-    }
-  }
-}
-#endif
-
-}  // namespace
-
-class DataReductionProxyCompressionStats::DailyContentLengthUpdate {
- public:
-  DailyContentLengthUpdate(
-      DataReductionProxyCompressionStats* compression_stats,
-      const char* pref_path)
-      : update_(nullptr),
-        compression_stats_(compression_stats),
-        pref_path_(pref_path) {}
-
-  DailyContentLengthUpdate(const DailyContentLengthUpdate&) = delete;
-  DailyContentLengthUpdate& operator=(const DailyContentLengthUpdate&) = delete;
-
-  void UpdateForDateChange(int days_since_last_update) {
-    if (days_since_last_update) {
-      MaybeInitialize();
-      MaintainContentLengthPrefForDateChange(days_since_last_update);
-    }
-  }
-
-  // Update the lengths for the current day.
-  void Add(int64_t content_length) {
-    if (content_length != 0) {
-      MaybeInitialize();
-      AddInt64ToListPref(kNumDaysInHistory - 1, content_length, update_);
-    }
-  }
-
-  int64_t GetListPrefValue(size_t index) {
-    MaybeInitialize();
-    return std::max(GetInt64PrefValue(*update_, index),
-                    static_cast<int64_t>(0));
-  }
-
- private:
-  void MaybeInitialize() {
-    if (update_)
-      return;
-
-    update_ = compression_stats_->GetList(pref_path_);
-    // New empty lists may have been created. Maintain the invariant that
-    // there should be exactly |kNumDaysInHistory| days in the histories.
-    MaintainContentLengthPrefsWindow(update_, kNumDaysInHistory);
-  }
-
-  // Update the list for date change and ensure the list has exactly |length|
-  // elements. The last entry in the list will be for the current day after
-  // the update.
-  void MaintainContentLengthPrefForDateChange(int days_since_last_update) {
-    if (days_since_last_update == -1) {
-      // The system may go backwards in time by up to a day for legitimate
-      // reasons, such as with changes to the time zone. In such cases, we
-      // keep adding to the current day.
-      // Note: we accept the fact that some reported data is shifted to
-      // the adjacent day if users travel back and forth across time zones.
-      days_since_last_update = 0;
-    } else if (days_since_last_update < -1) {
-      // Erase all entries if the system went backwards in time by more than
-      // a day.
-      update_->ClearList();
-
-      days_since_last_update = kNumDaysInHistory;
-    }
-    DCHECK_GE(days_since_last_update, 0);
-
-    // Add entries for days since last update event. This will make the
-    // lists longer than kNumDaysInHistory. The additional items will be cut off
-    // from the head of the lists by |MaintainContentLengthPrefsWindow|, below.
-    for (int i = 0;
-         i < days_since_last_update && i < static_cast<int>(kNumDaysInHistory);
-         ++i) {
-      update_->Append(base::NumberToString(0));
-    }
-
-    // Entries for new days may have been appended. Maintain the invariant that
-    // there should be exactly |kNumDaysInHistory| days in the histories.
-    MaintainContentLengthPrefsWindow(update_, kNumDaysInHistory);
-  }
-
-  // Non-owned. Lazily initialized, set to nullptr until initialized.
-  raw_ptr<base::Value> update_;
-  // Non-owned pointer.
-  raw_ptr<DataReductionProxyCompressionStats> compression_stats_;
-  // The path of the content length pref for |this|.
-  const char* pref_path_;
-};
-
-// DailyDataSavingUpdate maintains a pair of data saving prefs, original_update_
-// and received_update_. pref_original is a list of |kNumDaysInHistory| elements
-// of daily total original content lengths for the past |kNumDaysInHistory|
-// days. pref_received is the corresponding list of the daily total received
-// content lengths.
-class DataReductionProxyCompressionStats::DailyDataSavingUpdate {
- public:
-  DailyDataSavingUpdate(DataReductionProxyCompressionStats* compression_stats,
-                        const char* original_pref_path,
-                        const char* received_pref_path)
-      : original_(compression_stats, original_pref_path),
-        received_(compression_stats, received_pref_path) {}
-
-  DailyDataSavingUpdate(const DailyDataSavingUpdate&) = delete;
-  DailyDataSavingUpdate& operator=(const DailyDataSavingUpdate&) = delete;
-
-  void UpdateForDateChange(int days_since_last_update) {
-    original_.UpdateForDateChange(days_since_last_update);
-    received_.UpdateForDateChange(days_since_last_update);
-  }
-
-  // Update the lengths for the current day.
-  void Add(int64_t original_content_length, int64_t received_content_length) {
-    original_.Add(original_content_length);
-    received_.Add(received_content_length);
-  }
-
-  int64_t GetOriginalListPrefValue(size_t index) {
-    return original_.GetListPrefValue(index);
-  }
-  int64_t GetReceivedListPrefValue(size_t index) {
-    return received_.GetListPrefValue(index);
-  }
-
- private:
-  DailyContentLengthUpdate original_;
-  DailyContentLengthUpdate received_;
-};
-
-DataReductionProxyCompressionStats::DataReductionProxyCompressionStats(
-    DataReductionProxyService* service,
-    PrefService* prefs,
-    const base::TimeDelta& delay)
-    : service_(service),
-      pref_service_(prefs),
-      delay_(delay),
-      data_usage_map_is_dirty_(false),
-      current_data_usage_load_status_(NOT_LOADED) {
-  DCHECK(service);
-  DCHECK(prefs);
-  DCHECK_GE(delay.InMilliseconds(), 0);
-  Init();
-}
-
-DataReductionProxyCompressionStats::~DataReductionProxyCompressionStats() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  if (current_data_usage_load_status_ == LOADED)
-    PersistDataUsage();
-
-  WritePrefs();
-}
-
-void DataReductionProxyCompressionStats::Init() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  data_usage_reporting_enabled_.Init(
-      prefs::kDataUsageReportingEnabled, pref_service_,
-      base::BindRepeating(
-          &DataReductionProxyCompressionStats::OnDataUsageReportingPrefChanged,
-          weak_factory_.GetWeakPtr()));
-
-  if (data_usage_reporting_enabled_.GetValue()) {
-    current_data_usage_load_status_ = LOADING;
-    service_->LoadCurrentDataUsageBucket(base::BindRepeating(
-        &DataReductionProxyCompressionStats::OnCurrentDataUsageLoaded,
-        weak_factory_.GetWeakPtr()));
-  }
-
-  InitializeWeeklyAggregateDataUse(base::Time::Now());
-
-  if (delay_.is_zero())
-    return;
-
-  // Init all int64_t prefs.
-  InitInt64Pref(prefs::kDailyHttpContentLengthLastUpdateDate);
-  InitInt64Pref(prefs::kHttpReceivedContentLength);
-  InitInt64Pref(prefs::kHttpOriginalContentLength);
-
-  // Init all list prefs.
-  InitListPref(prefs::kDailyHttpOriginalContentLength);
-  InitListPref(prefs::kDailyHttpReceivedContentLength);
-}
-
-void DataReductionProxyCompressionStats::RecordDataUseWithMimeType(
-    int64_t data_used,
-    int64_t original_size,
-    bool data_saver_enabled,
-    const std::string& mime_type,
-    bool is_user_traffic,
-    data_use_measurement::DataUseUserData::DataUseContentType content_type,
-    int32_t service_hash_code) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  TRACE_EVENT0("loading",
-               "DataReductionProxyCompressionStats::RecordDataUseWithMimeType");
-
-  IncreaseInt64Pref(data_reduction_proxy::prefs::kHttpReceivedContentLength,
-                    data_used);
-  IncreaseInt64Pref(data_reduction_proxy::prefs::kHttpOriginalContentLength,
-                    original_size);
-
-  RecordRequestSizePrefs(data_used, original_size, data_saver_enabled,
-                         mime_type, base::Time::Now());
-  RecordWeeklyAggregateDataUse(
-      base::Time::Now(), std::round(static_cast<double>(data_used) / 1024),
-      is_user_traffic, content_type, service_hash_code);
-}
-
-void DataReductionProxyCompressionStats::InitInt64Pref(const char* pref) {
-  int64_t pref_value = pref_service_->GetInt64(pref);
-  pref_map_[pref] = pref_value;
-}
-
-void DataReductionProxyCompressionStats::InitListPref(const char* pref) {
-  base::Value pref_value = pref_service_->GetList(pref)->Clone();
-  list_pref_map_[pref] = std::move(pref_value);
-}
-
-int64_t DataReductionProxyCompressionStats::GetInt64(const char* pref_path) {
-  if (delay_.is_zero())
-    return pref_service_->GetInt64(pref_path);
-
-  auto iter = pref_map_.find(pref_path);
-  return iter->second;
-}
-
-void DataReductionProxyCompressionStats::SetInt64(const char* pref_path,
-                                                  int64_t pref_value) {
-  if (delay_.is_zero()) {
-    pref_service_->SetInt64(pref_path, pref_value);
-    return;
-  }
-
-  DelayedWritePrefs();
-  pref_map_[pref_path] = pref_value;
-}
-
-void DataReductionProxyCompressionStats::IncreaseInt64Pref(
-    const char* pref_path,
-    int64_t delta) {
-  SetInt64(pref_path, GetInt64(pref_path) + delta);
-}
-
-base::Value* DataReductionProxyCompressionStats::GetList(
-    const char* pref_path) {
-  if (delay_.is_zero())
-    return ListPrefUpdate(pref_service_, pref_path).Get();
-
-  DelayedWritePrefs();
-  auto it = list_pref_map_.find(pref_path);
-  if (it == list_pref_map_.end())
-    return nullptr;
-  return &it->second;
-}
-
-void DataReductionProxyCompressionStats::WritePrefs() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (delay_.is_zero())
-    return;
-
-  for (auto iter = pref_map_.begin(); iter != pref_map_.end(); ++iter) {
-    pref_service_->SetInt64(iter->first, iter->second);
-  }
-
-  for (auto iter = list_pref_map_.begin(); iter != list_pref_map_.end();
-       ++iter) {
-    TransferList(iter->second,
-                 ListPrefUpdate(pref_service_, iter->first).Get());
-  }
-}
-
-int64_t DataReductionProxyCompressionStats::GetLastUpdateTime() {
-  int64_t last_update_internal =
-      GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate);
-  base::Time last_update = base::Time::FromInternalValue(last_update_internal);
-  return static_cast<int64_t>(last_update.ToJsTime());
-}
-
-void DataReductionProxyCompressionStats::ResetStatistics() {
-  base::Value* original_update =
-      GetList(prefs::kDailyHttpOriginalContentLength);
-  base::Value* received_update =
-      GetList(prefs::kDailyHttpReceivedContentLength);
-  original_update->ClearList();
-  received_update->ClearList();
-  for (size_t i = 0; i < kNumDaysInHistory; ++i) {
-    original_update->Append(base::NumberToString(0));
-    received_update->Append(base::NumberToString(0));
-  }
-}
-
-int64_t DataReductionProxyCompressionStats::GetHttpReceivedContentLength() {
-  return GetInt64(prefs::kHttpReceivedContentLength);
-}
-
-int64_t DataReductionProxyCompressionStats::GetHttpOriginalContentLength() {
-  return GetInt64(prefs::kHttpOriginalContentLength);
-}
-
-ContentLengthList DataReductionProxyCompressionStats::GetDailyContentLengths(
-    const char* pref_name) {
-  ContentLengthList content_lengths;
-  const base::Value* list_value = GetList(pref_name);
-  if (list_value->GetList().size() == kNumDaysInHistory) {
-    for (size_t i = 0; i < kNumDaysInHistory; ++i)
-      content_lengths.push_back(GetInt64PrefValue(*list_value, i));
-  }
-  return content_lengths;
-}
-
-void DataReductionProxyCompressionStats::GetContentLengths(
-    unsigned int days,
-    int64_t* original_content_length,
-    int64_t* received_content_length,
-    int64_t* last_update_time) {
-  DCHECK_LE(days, kNumDaysInHistory);
-
-  const base::Value* original_list =
-      GetList(prefs::kDailyHttpOriginalContentLength);
-  const base::Value* received_list =
-      GetList(prefs::kDailyHttpReceivedContentLength);
-
-  if (original_list->GetList().size() != kNumDaysInHistory ||
-      received_list->GetList().size() != kNumDaysInHistory) {
-    *original_content_length = 0L;
-    *received_content_length = 0L;
-    *last_update_time = 0L;
-    return;
-  }
-
-  int64_t orig = 0L;
-  int64_t recv = 0L;
-  // Include days from the end of the list going backwards.
-  for (size_t i = kNumDaysInHistory - days;
-       i < kNumDaysInHistory; ++i) {
-    orig += GetInt64PrefValue(*original_list, i);
-    recv += GetInt64PrefValue(*received_list, i);
-  }
-  *original_content_length = orig;
-  *received_content_length = recv;
-  *last_update_time = GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate);
-}
-
-void DataReductionProxyCompressionStats::GetHistoricalDataUsage(
-    HistoricalDataUsageCallback get_data_usage_callback) {
-  GetHistoricalDataUsageImpl(std::move(get_data_usage_callback),
-                             base::Time::Now());
-}
-
-void DataReductionProxyCompressionStats::DeleteBrowsingHistory(
-    const base::Time& start,
-    const base::Time& end) {
-  DCHECK_NE(LOADING, current_data_usage_load_status_);
-
-  if (!data_usage_map_last_updated_.is_null() &&
-      DataUsageStore::BucketOverlapsInterval(data_usage_map_last_updated_,
-                                             start, end)) {
-    data_usage_map_.clear();
-    data_usage_map_last_updated_ = base::Time();
-    data_usage_map_is_dirty_ = false;
-  }
-
-  service_->DeleteBrowsingHistory(start, end);
-
-  RecordSavingsClearedMetric(DataReductionProxySavingsClearedReason::
-                                 USER_ACTION_DELETE_BROWSING_HISTORY);
-}
-
-void DataReductionProxyCompressionStats::OnCurrentDataUsageLoaded(
-    std::unique_ptr<DataUsageBucket> data_usage) {
-  // Exit early if the pref was turned off before loading from storage
-  // completed.
-  if (!data_usage_reporting_enabled_.GetValue()) {
-    DCHECK_EQ(NOT_LOADED, current_data_usage_load_status_);
-    DCHECK(data_usage_map_.empty());
-    current_data_usage_load_status_ = NOT_LOADED;
-    return;
-  } else {
-    DCHECK_EQ(LOADING, current_data_usage_load_status_);
-  }
-
-  DCHECK(data_usage_map_last_updated_.is_null());
-  DCHECK(data_usage_map_.empty());
-
-  // We currently do not break down by connection type. However, we use a schema
-  // that makes it easy to transition to a connection based breakdown without
-  // requiring a data migration.
-  DCHECK(data_usage->connection_usage_size() == 0 ||
-         data_usage->connection_usage_size() == 1);
-  for (const auto& connection_usage : data_usage->connection_usage()) {
-    for (const auto& site_usage : connection_usage.site_usage()) {
-      data_usage_map_[site_usage.hostname()] =
-          std::make_unique<PerSiteDataUsage>(site_usage);
-    }
-  }
-
-  data_usage_map_last_updated_ =
-      base::Time::FromInternalValue(data_usage->last_updated_timestamp());
-  // Record if there was a read error.
-  if (data_usage->had_read_error()) {
-    RecordSavingsClearedMetric(
-        DataReductionProxySavingsClearedReason::PREFS_PARSE_ERROR);
-  }
-
-  current_data_usage_load_status_ = LOADED;
-}
-
-void DataReductionProxyCompressionStats::SetDataUsageReportingEnabled(
-    bool enabled) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (data_usage_reporting_enabled_.GetValue() != enabled) {
-    data_usage_reporting_enabled_.SetValue(enabled);
-    OnDataUsageReportingPrefChanged();
-  }
-}
-
-void DataReductionProxyCompressionStats::ClearDataSavingStatistics(
-    DataReductionProxySavingsClearedReason reason) {
-  DeleteHistoricalDataUsage();
-
-  pref_service_->ClearPref(prefs::kDailyHttpContentLengthLastUpdateDate);
-  pref_service_->ClearPref(prefs::kHttpReceivedContentLength);
-  pref_service_->ClearPref(prefs::kHttpOriginalContentLength);
-
-  pref_service_->ClearPref(prefs::kDailyHttpOriginalContentLength);
-  pref_service_->ClearPref(prefs::kDailyHttpReceivedContentLength);
-
-  for (auto iter = list_pref_map_.begin(); iter != list_pref_map_.end();
-       ++iter) {
-    iter->second.ClearList();
-  }
-
-  RecordSavingsClearedMetric(reason);
-}
-
-void DataReductionProxyCompressionStats::DelayedWritePrefs() {
-  if (pref_writer_timer_.IsRunning())
-    return;
-
-  pref_writer_timer_.Start(FROM_HERE, delay_, this,
-                           &DataReductionProxyCompressionStats::WritePrefs);
-}
-
-void DataReductionProxyCompressionStats::TransferList(
-    const base::Value& from_list,
-    base::Value* to_list) {
-  *to_list = from_list.Clone();
-}
-
-void DataReductionProxyCompressionStats::RecordRequestSizePrefs(
-    int64_t data_used,
-    int64_t original_size,
-    bool with_data_saver_enabled,
-    const std::string& mime_type,
-    const base::Time& now) {
-  // TODO(bengr): Remove this check once the underlying cause of
-  // http://crbug.com/287821 is fixed. For now, only continue if the current
-  // year is reported as being between 1972 and 2970.
-  base::TimeDelta time_since_unix_epoch = now - base::Time::UnixEpoch();
-  const int kMinDaysSinceUnixEpoch = 365 * 2;  // 2 years.
-  const int kMaxDaysSinceUnixEpoch = 365 * 1000;  // 1000 years.
-  if (time_since_unix_epoch.InDays() < kMinDaysSinceUnixEpoch ||
-      time_since_unix_epoch.InDays() > kMaxDaysSinceUnixEpoch) {
-    return;
-  }
-
-  // Determine how many days it has been since the last update.
-  int64_t then_internal = GetInt64(
-      data_reduction_proxy::prefs::kDailyHttpContentLengthLastUpdateDate);
-
-  // Local midnight could have been shifted due to time zone change.
-  // If time is null then don't care if midnight will be wrong shifted due to
-  // time zone change because it's still too much time ago.
-  base::Time then_midnight = base::Time::FromInternalValue(then_internal);
-  if (!then_midnight.is_null()) {
-    then_midnight = then_midnight.LocalMidnight();
-  }
-  base::Time midnight = now.LocalMidnight();
-
-  DailyDataSavingUpdate total(
-      this, data_reduction_proxy::prefs::kDailyHttpOriginalContentLength,
-      data_reduction_proxy::prefs::kDailyHttpReceivedContentLength);
-
-  int days_since_last_update = (midnight - then_midnight).InDays();
-  if (days_since_last_update) {
-    // Record the last update time in microseconds in UTC.
-    SetInt64(data_reduction_proxy::prefs::kDailyHttpContentLengthLastUpdateDate,
-             midnight.ToInternalValue());
-
-    // The system may go backwards in time by up to a day for legitimate
-    // reasons, such as with changes to the time zone. In such cases, we
-    // keep adding to the current day.
-    // (Actually resetting the numbers when we're more than a day off
-    // happens elsewhere.)
-    if (days_since_last_update < -1) {
-      RecordSavingsClearedMetric(
-          DataReductionProxySavingsClearedReason::SYSTEM_CLOCK_MOVED_BACK);
-    }
-  }
-
-  total.UpdateForDateChange(days_since_last_update);
-  total.Add(original_size, data_used);
-}
-
-void DataReductionProxyCompressionStats::RecordDataUseByHost(
-    const std::string& data_usage_host,
-    int64_t data_used,
-    int64_t original_size,
-    const base::Time time) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (current_data_usage_load_status_ != LOADED)
-    return;
-
-  DCHECK(data_usage_reporting_enabled_.GetValue());
-
-  if (!DataUsageStore::AreInSameInterval(data_usage_map_last_updated_, time)) {
-    PersistDataUsage();
-    data_usage_map_.clear();
-    data_usage_map_last_updated_ = base::Time();
-  }
-
-  std::string normalized_host = NormalizeHostname(data_usage_host);
-  auto j = data_usage_map_.insert(
-      std::make_pair(normalized_host, std::make_unique<PerSiteDataUsage>()));
-  PerSiteDataUsage* per_site_usage = j.first->second.get();
-  per_site_usage->set_hostname(normalized_host);
-  per_site_usage->set_original_size(per_site_usage->original_size() +
-                                    original_size);
-  per_site_usage->set_data_used(per_site_usage->data_used() + data_used);
-
-  data_usage_map_last_updated_ = time;
-  data_usage_map_is_dirty_ = true;
-}
-
-void DataReductionProxyCompressionStats::PersistDataUsage() {
-  DCHECK(current_data_usage_load_status_ == LOADED);
-
-  if (data_usage_map_is_dirty_) {
-    std::unique_ptr<DataUsageBucket> data_usage_bucket(new DataUsageBucket());
-    data_usage_bucket->set_last_updated_timestamp(
-        data_usage_map_last_updated_.ToInternalValue());
-    PerConnectionDataUsage* connection_usage =
-        data_usage_bucket->add_connection_usage();
-    for (auto i = data_usage_map_.begin(); i != data_usage_map_.end(); ++i) {
-        PerSiteDataUsage* per_site_usage = connection_usage->add_site_usage();
-        per_site_usage->CopyFrom(*(i->second.get()));
-    }
-    service_->StoreCurrentDataUsageBucket(std::move(data_usage_bucket));
-  }
-
-  data_usage_map_is_dirty_ = false;
-}
-
-void DataReductionProxyCompressionStats::DeleteHistoricalDataUsage() {
-  // This method does not support being called in |LOADING| status since this
-  // means that the in-memory data usage will get populated when data usage
-  // loads, which will undo the clear below. This method is called when users
-  // click on the "Clear Data" button, or when user deletes the extension. In
-  // both cases, enough time has passed since startup to load current data
-  // usage. Technically, this could occur, and will have the effect of not
-  // clearing data from the current bucket.
-  // TODO(kundaji): Use cancellable tasks and remove this DCHECK.
-  DCHECK(current_data_usage_load_status_ != LOADING);
-
-  data_usage_map_.clear();
-  data_usage_map_last_updated_ = base::Time();
-  data_usage_map_is_dirty_ = false;
-
-  service_->DeleteHistoricalDataUsage();
-}
-
-void DataReductionProxyCompressionStats::GetHistoricalDataUsageImpl(
-    HistoricalDataUsageCallback get_data_usage_callback,
-    const base::Time& now) {
-#if !BUILDFLAG(IS_ANDROID)
-  if (current_data_usage_load_status_ != LOADED) {
-    // If current data usage has not yet loaded, we return an empty array. The
-    // extension can retry after a slight delay.
-    // This use case is unlikely to occur in practice since current data usage
-    // should have sufficient time to load before user tries to view data usage.
-    std::move(get_data_usage_callback)
-        .Run(std::make_unique<std::vector<DataUsageBucket>>());
-    return;
-  }
-#endif
-
-  if (current_data_usage_load_status_ == LOADED)
-    PersistDataUsage();
-
-  if (!data_usage_map_last_updated_.is_null() &&
-      !DataUsageStore::AreInSameInterval(data_usage_map_last_updated_, now)) {
-    data_usage_map_.clear();
-    data_usage_map_last_updated_ = base::Time();
-
-    // Force the last bucket to be for the current interval.
-    std::unique_ptr<DataUsageBucket> data_usage_bucket(new DataUsageBucket());
-    data_usage_bucket->set_last_updated_timestamp(now.ToInternalValue());
-    service_->StoreCurrentDataUsageBucket(std::move(data_usage_bucket));
-  }
-
-  service_->LoadHistoricalDataUsage(std::move(get_data_usage_callback));
-}
-
-void DataReductionProxyCompressionStats::OnDataUsageReportingPrefChanged() {
-  if (data_usage_reporting_enabled_.GetValue()) {
-    if (current_data_usage_load_status_ == NOT_LOADED) {
-      current_data_usage_load_status_ = LOADING;
-      service_->LoadCurrentDataUsageBucket(base::BindOnce(
-          &DataReductionProxyCompressionStats::OnCurrentDataUsageLoaded,
-          weak_factory_.GetWeakPtr()));
-    }
-  } else {
-// Don't delete the historical data on Android, but clear the map.
-#if BUILDFLAG(IS_ANDROID)
-    if (current_data_usage_load_status_ == LOADED)
-      PersistDataUsage();
-
-    data_usage_map_.clear();
-    data_usage_map_last_updated_ = base::Time();
-    data_usage_map_is_dirty_ = false;
-#else
-    DeleteHistoricalDataUsage();
-#endif
-    current_data_usage_load_status_ = NOT_LOADED;
-  }
-}
-
-void DataReductionProxyCompressionStats::InitializeWeeklyAggregateDataUse(
-    const base::Time& now) {
-  // TODO(rajendrant): Enable aggregate metrics recording in x86 Android.
-  // http://crbug.com/865373
-#if !BUILDFLAG(IS_ANDROID) || !defined(ARCH_CPU_X86)
-  MaybeInitWeeklyAggregateDataUsePrefs(now, pref_service_);
-  // Record the histograms that will show up in the user feedback.
-  RecordDictionaryToHistogram(
-      "DataReductionProxy.ThisWeekAggregateKB.Services.Downstream.Background",
-      pref_service_->GetDictionary(
-          prefs::kThisWeekServicesDownstreamBackgroundKB));
-  RecordDictionaryToHistogram(
-      "DataReductionProxy.ThisWeekAggregateKB.Services.Downstream.Foreground",
-      pref_service_->GetDictionary(
-          prefs::kThisWeekServicesDownstreamForegroundKB));
-  RecordDictionaryToHistogram(
-      "DataReductionProxy.ThisWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      pref_service_->GetDictionary(
-          prefs::kThisWeekUserTrafficContentTypeDownstreamKB));
-  RecordDictionaryToHistogram(
-      "DataReductionProxy.LastWeekAggregateKB.Services.Downstream.Background",
-      pref_service_->GetDictionary(
-          prefs::kLastWeekServicesDownstreamBackgroundKB));
-  RecordDictionaryToHistogram(
-      "DataReductionProxy.LastWeekAggregateKB.Services.Downstream.Foreground",
-      pref_service_->GetDictionary(
-          prefs::kLastWeekServicesDownstreamForegroundKB));
-  RecordDictionaryToHistogram(
-      "DataReductionProxy.LastWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      pref_service_->GetDictionary(
-          prefs::kLastWeekUserTrafficContentTypeDownstreamKB));
-#endif
-}
-
-void DataReductionProxyCompressionStats::RecordWeeklyAggregateDataUse(
-    const base::Time& now,
-    int32_t data_used_kb,
-    bool is_user_request,
-    data_use_measurement::DataUseUserData::DataUseContentType content_type,
-    int32_t service_hash_code) {
-  // TODO(rajendrant): Enable aggregate metrics recording in x86 Android.
-  // http://crbug.com/865373
-#if !BUILDFLAG(IS_ANDROID) || !defined(ARCH_CPU_X86)
-  // Update the prefs if this is a new week. This can happen when chrome is open
-  // for weeks without being closed.
-  MaybeInitWeeklyAggregateDataUsePrefs(now, pref_service_);
-  if (is_user_request) {
-    AddToDictionaryPref(pref_service_,
-                        prefs::kThisWeekUserTrafficContentTypeDownstreamKB,
-                        content_type, data_used_kb);
-  } else {
-    bool is_app_foreground = true;
-    if (is_app_foreground) {
-      AddToDictionaryPref(pref_service_,
-                          prefs::kThisWeekServicesDownstreamForegroundKB,
-                          service_hash_code, data_used_kb);
-    } else {
-      AddToDictionaryPref(pref_service_,
-                          prefs::kThisWeekServicesDownstreamBackgroundKB,
-                          service_hash_code, data_used_kb);
-    }
-  }
-#endif
-}
-
-// static
-std::string DataReductionProxyCompressionStats::NormalizeHostname(
-    const std::string& host) {
-  size_t pos = host.find("://");
-  if (pos != std::string::npos)
-    return host.substr(pos + 3);
-
-  return host;
-}
-
-}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h
deleted file mode 100644
index 4595582..0000000
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h
+++ /dev/null
@@ -1,305 +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 COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_COMPRESSION_STATS_H_
-#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_COMPRESSION_STATS_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <unordered_map>
-
-#include "base/memory/raw_ptr.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
-#include "components/data_reduction_proxy/core/browser/db_data_owner.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
-#include "components/data_use_measurement/core/data_use_user_data.h"
-#include "components/prefs/pref_member.h"
-
-class PrefService;
-
-namespace base {
-class Value;
-}
-
-namespace data_reduction_proxy {
-class DataReductionProxyService;
-class DataUsageBucket;
-class PerSiteDataUsage;
-
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-//
-// A Java counterpart will be generated for this enum.
-// GENERATED_JAVA_ENUM_PACKAGE: (
-//     org.chromium.chrome.browser.settings.datareduction)
-enum class DataReductionProxySavingsClearedReason {
-  SYSTEM_CLOCK_MOVED_BACK,
-  PREFS_PARSE_ERROR,
-  USER_ACTION_EXTENSION,
-  USER_ACTION_SETTINGS_MENU,
-  USER_ACTION_DELETE_BROWSING_HISTORY,
-  // NOTE: always keep this entry at the end. Add new result types only
-  // immediately above this line. Make sure to update the corresponding
-  // histogram enum accordingly.
-  REASON_COUNT,
-};
-
-// Data reduction proxy delayed pref service reduces the number calls to pref
-// service by storing prefs in memory and writing to the given PrefService after
-// |delay| amount of time. If |delay| is zero, the delayed pref service writes
-// directly to the PrefService and does not store the prefs in memory. All
-// prefs must be stored and read on the UI thread.
-class DataReductionProxyCompressionStats {
- public:
-  typedef std::unordered_map<std::string, std::unique_ptr<PerSiteDataUsage>>
-      SiteUsageMap;
-
-  // Collects and store data usage and compression statistics. Basic data usage
-  // stats are stored in browser preferences. More detailed stats broken down
-  // by site and internet type are stored in |DataReductionProxyStore|.
-  //
-  // To store basic stats, it constructs a data reduction proxy delayed pref
-  // service object using |pref_service|. Writes prefs to |pref_service| after
-  // |delay| and stores them in |pref_map_| and |list_pref_map| between writes.
-  // If |delay| is zero, writes directly to the PrefService and does not store
-  // in the maps.
-  DataReductionProxyCompressionStats(DataReductionProxyService* service,
-                                     PrefService* pref_service,
-                                     const base::TimeDelta& delay);
-
-  DataReductionProxyCompressionStats(
-      const DataReductionProxyCompressionStats&) = delete;
-  DataReductionProxyCompressionStats& operator=(
-      const DataReductionProxyCompressionStats&) = delete;
-
-  ~DataReductionProxyCompressionStats();
-
-  // Records detailed data usage broken down by |mime_type|. Also records daily
-  // data savings statistics to prefs and reports data savings UMA. |data_used|
-  // and |original_size| are measured in bytes.
-  void RecordDataUseWithMimeType(
-      int64_t compressed_size,
-      int64_t original_size,
-      bool data_reduction_proxy_enabled,
-      const std::string& mime_type,
-      bool is_user_traffic,
-      data_use_measurement::DataUseUserData::DataUseContentType content_type,
-      int32_t service_hash_code);
-
-  // Record data usage and original size of request broken down by host.
-  // |original_request_size| and |data_used| are in bytes. |time| is the time at
-  // which the data usage occurred. This method should be called in real time,
-  // so |time| is expected to be |Time::Now()|.
-  void RecordDataUseByHost(const std::string& data_usage_host,
-                           int64_t original_request_size,
-                           int64_t data_used,
-                           const base::Time time);
-
-  // Returns the time in milliseconds since epoch that the last update was made
-  // to the daily original and received content lengths.
-  int64_t GetLastUpdateTime();
-
-  // Resets daily content length statistics.
-  void ResetStatistics();
-
-  // Clears all data saving statistics for the given |reason|.
-  void ClearDataSavingStatistics(DataReductionProxySavingsClearedReason reason);
-
-  // Returns the total size of all HTTP content received from the network.
-  int64_t GetHttpReceivedContentLength();
-
-  // Returns the value the total original size of all HTTP content received from
-  // the network.
-  int64_t GetHttpOriginalContentLength();
-
-  // Returns a list of all the daily content lengths.
-  ContentLengthList GetDailyContentLengths(const char* pref_name);
-
-  // Returns aggregate received and original content lengths over the specified
-  // number of days, as well as the time these stats were last updated.
-  void GetContentLengths(unsigned int days,
-                         int64_t* original_content_length,
-                         int64_t* received_content_length,
-                         int64_t* last_update_time);
-
-  // Calls |get_data_usage_callback| with full data usage history. In-memory
-  // data usage stats are flushed to storage before querying for full history.
-  // An empty vector will be returned if "data_usage_reporting.enabled" pref is
-  // not enabled or if called immediately after enabling the pref before
-  // in-memory stats could be initialized from storage. Data usage is sorted
-  // chronologically with the last entry corresponding to |base::Time::Now()|.
-  void GetHistoricalDataUsage(
-      HistoricalDataUsageCallback get_data_usage_callback);
-
-  // Deletes browsing history from storage and memory for the given time
-  // range. Currently, this method deletes all data usage for the given range.
-  void DeleteBrowsingHistory(const base::Time& start, const base::Time& end);
-
-  // Callback from loading detailed data usage. Initializes in memory data
-  // structures used to collect data usage. |data_usage| contains the data usage
-  // for the last stored interval.
-  void OnCurrentDataUsageLoaded(std::unique_ptr<DataUsageBucket> data_usage);
-
-  // Sets the value of |prefs::kDataUsageReportingEnabled| to |enabled|.
-  // Initializes data usage statistics in memory when pref is enabled and
-  // persists data usage to memory when pref is disabled.
-  void SetDataUsageReportingEnabled(bool enabled);
-
-  // Returns |data_usage_map_|.
-  const DataReductionProxyCompressionStats::SiteUsageMap&
-  DataUsageMapForTesting() const {
-    return data_usage_map_;
-  }
-
- private:
-  // Enum to track the state of loading data usage from storage.
-  enum CurrentDataUsageLoadStatus { NOT_LOADED = 0, LOADING = 1, LOADED = 2 };
-
-  friend class DataReductionProxyCompressionStatsTest;
-
-  typedef std::map<const char*, int64_t> DataReductionProxyPrefMap;
-  typedef std::unordered_map<const char*, base::Value>
-      DataReductionProxyListPrefMap;
-
-  class DailyContentLengthUpdate;
-  class DailyDataSavingUpdate;
-
-  // Loads all data_reduction_proxy::prefs into the |pref_map_| and
-  // |list_pref_map_|.
-  void Init();
-
-  // Gets the value of |pref| from the pref service and adds it to the
-  // |pref_map|.
-  void InitInt64Pref(const char* pref);
-
-  // Gets the value of |pref| from the pref service and adds it to the
-  // |list_pref_map|.
-  void InitListPref(const char* pref);
-
-  void OnUpdateContentLengths();
-
-  // Gets the int64_t pref at |pref_path| from the |DataReductionProxyPrefMap|.
-  int64_t GetInt64(const char* pref_path);
-
-  // Updates the pref value in the |DataReductionProxyPrefMap| map.
-  // The pref is later written to |pref service_|.
-  void SetInt64(const char* pref_path, int64_t pref_value);
-
-  // Increases the pref value in the |DataReductionProxyPrefMap| map.
-  // The pref is later written to |pref service_|.
-  void IncreaseInt64Pref(const char* pref_path, int64_t delta);
-
-  // Gets the pref list at |pref_path| from the |DataReductionProxyPrefMap|.
-  base::Value* GetList(const char* pref_path);
-
-  // Writes the prefs stored in |DataReductionProxyPrefMap| and
-  // |DataReductionProxyListPrefMap| to |pref_service|.
-  void WritePrefs();
-
-  // Starts a timer (if necessary) to write prefs in |kMinutesBetweenWrites| to
-  // the |pref_service|.
-  void DelayedWritePrefs();
-
-  // Copies the values at each index of |from_list| to the same index in
-  // |to_list|.
-  void TransferList(const base::Value& from_list, base::Value* to_list);
-
-  // Records content length updates to prefs.
-  void RecordRequestSizePrefs(int64_t compressed_size,
-                              int64_t original_size,
-                              bool with_data_reduction_proxy_enabled,
-                              const std::string& mime_type,
-                              const base::Time& now);
-
-  void IncrementDailyUmaPrefs(int64_t original_size,
-                              int64_t received_size,
-                              const char* original_size_pref,
-                              const char* received_size_pref,
-                              bool data_reduction_proxy_enabled,
-                              const char* original_size_with_proxy_enabled_pref,
-                              const char* recevied_size_with_proxy_enabled_pref,
-                              bool via_data_reduction_proxy,
-                              const char* original_size_via_proxy_pref,
-                              const char* received_size_via_proxy_pref);
-
-  // Persists the in memory data usage information to storage and clears all
-  // in-memory data usage. Do not call this method unless |data_usage_loaded_|
-  // is |LOADED|.
-  void PersistDataUsage();
-
-  // Deletes all historical data usage from storage and memory. This method
-  // should not be called when |current_data_usage_load_status_| is |LOADING|.
-  void DeleteHistoricalDataUsage();
-
-  // Actual implementation of |GetHistoricalDataUsage|. This helper method
-  // explicitly passes |base::Time::Now()| to make testing easier.
-  void GetHistoricalDataUsageImpl(
-      HistoricalDataUsageCallback get_data_usage_callback,
-      const base::Time& now);
-
-  // Called when |prefs::kDataUsageReportingEnabled| pref values changes.
-  // Initializes data usage statistics in memory when pref is enabled and
-  // persists data usage to memory when pref is disabled.
-  void OnDataUsageReportingPrefChanged();
-
-  // Initialize the weekly data use prefs for the current week, and records the
-  // weekly aggregate data use histograms.
-  void InitializeWeeklyAggregateDataUse(const base::Time& now);
-
-  // Records |data_used_kb| to the current week data use pref. |is_user_request|
-  // indicates if this is user-initiated traffic or chrome services traffic, and
-  // |service_hash_code| uniquely identifies the corresponding chrome service.
-  void RecordWeeklyAggregateDataUse(
-      const base::Time& now,
-      int32_t data_used_kb,
-      bool is_user_request,
-      data_use_measurement::DataUseUserData::DataUseContentType content_type,
-      int32_t service_hash_code);
-
-  // Normalizes the hostname for data usage attribution. Returns a substring
-  // without the protocol.
-  // Example: "http://www.finance.google.com" -> "www.finance.google.com"
-  static std::string NormalizeHostname(const std::string& host);
-
-  raw_ptr<DataReductionProxyService> service_;
-  raw_ptr<PrefService> pref_service_;
-  const base::TimeDelta delay_;
-  DataReductionProxyPrefMap pref_map_;
-  DataReductionProxyListPrefMap list_pref_map_;
-  BooleanPrefMember data_usage_reporting_enabled_;
-
-  // Maintains detailed data usage for current interval.
-  SiteUsageMap data_usage_map_;
-
-  // Time when |data_usage_map_| was last updated. Contains NULL time if
-  // |data_usage_map_| does not have any data. This could happen either because
-  // current data usage has not yet been loaded from storage, or because
-  // no data usage has ever been recorded.
-  base::Time data_usage_map_last_updated_;
-
-  // Tracks whether |data_usage_map_| has changes that have not yet been
-  // persisted to storage.
-  bool data_usage_map_is_dirty_;
-
-  // Tracks state of loading data usage from storage.
-  CurrentDataUsageLoadStatus current_data_usage_load_status_;
-
-  base::OneShotTimer pref_writer_timer_;
-  base::ThreadChecker thread_checker_;
-
-  base::WeakPtrFactory<DataReductionProxyCompressionStats> weak_factory_{this};
-};
-
-}  // namespace data_reduction_proxy
-
-#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_COMPRESSION_STATS_H_
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
deleted file mode 100644
index 73165522..0000000
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
+++ /dev/null
@@ -1,1062 +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 "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/memory/ref_counted.h"
-#include "base/run_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/task_environment.h"
-#include "base/time/time.h"
-#include "base/values.h"
-#include "build/build_config.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
-#include "components/data_reduction_proxy/proto/data_store.pb.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/pref_service.h"
-#include "components/prefs/testing_pref_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const int kWriteDelayMinutes = 60;
-
-// Each bucket holds data usage for a 15 minute interval. History is maintained
-// for 60 days.
-const int kNumExpectedBuckets = 60 * 24 * 60 / 15;
-
-int64_t GetListPrefInt64Value(const base::Value& list_update, size_t index) {
-  std::string string_value;
-  base::Value::ConstListView list_view = list_update.GetList();
-  if (index < list_view.size() && list_view[index].is_string()) {
-    string_value = list_view[index].GetString();
-  } else {
-    ADD_FAILURE() << "invalid index or [index] not a string";
-  }
-
-  int64_t value = 0;
-  EXPECT_TRUE(base::StringToInt64(string_value, &value));
-  return value;
-}
-
-class DataUsageLoadVerifier {
- public:
-  DataUsageLoadVerifier(
-      std::unique_ptr<std::vector<data_reduction_proxy::DataUsageBucket>>
-          expected) {
-    expected_ = std::move(expected);
-  }
-
-  void OnLoadDataUsage(
-      std::unique_ptr<std::vector<data_reduction_proxy::DataUsageBucket>>
-          actual) {
-    EXPECT_EQ(expected_->size(), actual->size());
-
-    // We are iterating through 2 vectors, |actual| and |expected|, so using an
-    // index rather than an iterator.
-    for (size_t i = 0; i < expected_->size(); ++i) {
-      data_reduction_proxy::DataUsageBucket* actual_bucket = &(actual->at(i));
-      data_reduction_proxy::DataUsageBucket* expected_bucket =
-          &(expected_->at(i));
-      EXPECT_EQ(expected_bucket->connection_usage_size(),
-                actual_bucket->connection_usage_size());
-
-      for (int j = 0; j < expected_bucket->connection_usage_size(); ++j) {
-        data_reduction_proxy::PerConnectionDataUsage actual_connection_usage =
-            actual_bucket->connection_usage(j);
-        data_reduction_proxy::PerConnectionDataUsage expected_connection_usage =
-            expected_bucket->connection_usage(j);
-
-        EXPECT_EQ(expected_connection_usage.site_usage_size(),
-                  actual_connection_usage.site_usage_size());
-
-        for (auto expected_site_usage :
-             expected_connection_usage.site_usage()) {
-          data_reduction_proxy::PerSiteDataUsage actual_site_usage;
-          for (auto it = actual_connection_usage.site_usage().begin();
-               it != actual_connection_usage.site_usage().end(); ++it) {
-            if (it->hostname() == expected_site_usage.hostname()) {
-              actual_site_usage = *it;
-            }
-          }
-
-          EXPECT_EQ(expected_site_usage.data_used(),
-                    actual_site_usage.data_used());
-          EXPECT_EQ(expected_site_usage.original_size(),
-                    actual_site_usage.original_size());
-        }
-      }
-    }
-  }
-
- private:
-  std::unique_ptr<std::vector<data_reduction_proxy::DataUsageBucket>> expected_;
-};
-
-}  // namespace
-
-namespace data_reduction_proxy {
-
-// The initial last update time used in test. There is no leap second a few
-// days around this time used in the test.
-// Note: No time zone is specified. Local time will be assumed by
-// base::Time::FromString below.
-const char kLastUpdateTime[] = "Wed, 18 Sep 2013 03:45:26";
-
-class DataReductionProxyCompressionStatsTest : public testing::Test {
- protected:
-  DataReductionProxyCompressionStatsTest()
-      : task_environment_(
-            base::test::SingleThreadTaskEnvironment::MainThreadType::UI) {
-    EXPECT_TRUE(base::Time::FromString(kLastUpdateTime, &now_));
-  }
-
-  void SetUp() override {
-    drp_test_context_ = DataReductionProxyTestContext::Builder().Build();
-
-    compression_stats_ = std::make_unique<DataReductionProxyCompressionStats>(
-        data_reduction_proxy_service(), pref_service(), base::TimeDelta());
-  }
-
-  void ResetCompressionStatsWithDelay(const base::TimeDelta& delay) {
-    compression_stats_ = std::make_unique<DataReductionProxyCompressionStats>(
-        data_reduction_proxy_service(), pref_service(), delay);
-  }
-
-  base::Time FakeNow() const {
-    return now_ + now_delta_;
-  }
-
-  void SetFakeTimeDeltaInHours(int hours) { now_delta_ = base::Hours(hours); }
-
-  void AddFakeTimeDeltaInHours(int hours) { now_delta_ += base::Hours(hours); }
-
-  void SetUpPrefs() {
-    CreatePrefList(prefs::kDailyHttpOriginalContentLength);
-    CreatePrefList(prefs::kDailyHttpReceivedContentLength);
-
-    const int64_t kOriginalLength = 150;
-    const int64_t kReceivedLength = 100;
-
-    compression_stats_->SetInt64(
-        prefs::kHttpOriginalContentLength, kOriginalLength);
-    compression_stats_->SetInt64(
-        prefs::kHttpReceivedContentLength, kReceivedLength);
-
-    base::Value* original_daily_content_length_list =
-        compression_stats_->GetList(prefs::kDailyHttpOriginalContentLength);
-    base::Value* received_daily_content_length_list =
-        compression_stats_->GetList(prefs::kDailyHttpReceivedContentLength);
-
-    for (size_t i = 0; i < kNumDaysInHistory; ++i) {
-      original_daily_content_length_list->GetList()[i] =
-          base::Value(base::NumberToString(i));
-    }
-
-    received_daily_content_length_list->ClearList();
-    for (size_t i = 0; i < kNumDaysInHistory / 2; ++i) {
-      received_daily_content_length_list->Append(base::NumberToString(i));
-    }
-  }
-
-  // Create daily pref list of |kNumDaysInHistory| zero values.
-  void CreatePrefList(const char* pref) {
-    base::Value* update = compression_stats_->GetList(pref);
-    update->ClearList();
-    for (size_t i = 0; i < kNumDaysInHistory; ++i) {
-      update->Append(base::Value(base::NumberToString(0)));
-    }
-  }
-
-  // Verify the pref list values in |pref_service_| are equal to those in
-  // |simple_pref_service| for |pref|.
-  void VerifyPrefListWasWritten(const char* pref) {
-    const base::Value* delayed_list = compression_stats_->GetList(pref);
-    const base::Value* written_list = pref_service()->GetList(pref);
-    ASSERT_EQ(delayed_list->GetList().size(), written_list->GetList().size());
-    size_t count = delayed_list->GetList().size();
-
-    for (size_t i = 0; i < count; ++i) {
-      EXPECT_EQ(GetListPrefInt64Value(*delayed_list, i),
-                GetListPrefInt64Value(*written_list, i));
-    }
-  }
-
-  // Verify the pref value in |pref_service_| are equal to that in
-  // |simple_pref_service|.
-  void VerifyPrefWasWritten(const char* pref) {
-    int64_t delayed_pref = compression_stats_->GetInt64(pref);
-    int64_t written_pref = pref_service()->GetInt64(pref);
-    EXPECT_EQ(delayed_pref, written_pref);
-  }
-
-  // Verify the pref list values are equal to the given values.
-  // If the count of values is less than kNumDaysInHistory, zeros are assumed
-  // at the beginning.
-  void VerifyPrefList(const char* pref,
-                      const int64_t* values,
-                      size_t count,
-                      size_t num_days_in_history) {
-    ASSERT_GE(num_days_in_history, count);
-    base::Value* update = compression_stats_->GetList(pref);
-    ASSERT_EQ(num_days_in_history, update->GetList().size())
-        << "Pref: " << pref;
-
-    for (size_t i = 0; i < count; ++i) {
-      EXPECT_EQ(values[i],
-                GetListPrefInt64Value(*update, num_days_in_history - count + i))
-          << pref << "; index=" << (num_days_in_history - count + i);
-    }
-    for (size_t i = 0; i < num_days_in_history - count; ++i) {
-      EXPECT_EQ(0, GetListPrefInt64Value(*update, i)) << "index=" << i;
-    }
-  }
-
-  // Verify that the pref value is equal to given value.
-  void VerifyPrefInt64(const char* pref, const int64_t value) {
-    EXPECT_EQ(value, compression_stats_->GetInt64(pref));
-  }
-
-  // Verify all daily data saving pref list values.
-  void VerifyDailyDataSavingContentLengthPrefLists(
-      const int64_t* original_values,
-      size_t original_count,
-      const int64_t* received_values,
-      size_t received_count,
-      size_t num_days_in_history) {
-    VerifyPrefList(data_reduction_proxy::prefs::kDailyHttpOriginalContentLength,
-                   original_values, original_count, num_days_in_history);
-    VerifyPrefList(data_reduction_proxy::prefs::kDailyHttpReceivedContentLength,
-                   received_values, received_count, num_days_in_history);
-  }
-
-  int64_t GetInt64(const char* pref_path) {
-    return compression_stats_->GetInt64(pref_path);
-  }
-
-  void SetInt64(const char* pref_path, int64_t pref_value) {
-    compression_stats_->SetInt64(pref_path, pref_value);
-  }
-
-  std::string NormalizeHostname(const std::string& hostname) {
-    return DataReductionProxyCompressionStats::NormalizeHostname(hostname);
-  }
-
-  void RecordContentLengthPrefs(int64_t received_content_length,
-                                int64_t original_content_length,
-                                bool with_data_reduction_proxy_enabled,
-                                const std::string& mime_type,
-                                base::Time now) {
-    compression_stats_->RecordRequestSizePrefs(
-        received_content_length, original_content_length,
-        with_data_reduction_proxy_enabled, mime_type, now);
-  }
-
-  void RecordContentLengthPrefs(int64_t received_content_length,
-                                int64_t original_content_length,
-                                bool with_data_reduction_proxy_enabled,
-                                base::Time now) {
-    RecordContentLengthPrefs(received_content_length, original_content_length,
-                             with_data_reduction_proxy_enabled,
-                             "application/octet-stream", now);
-  }
-
-  void RecordDataUsage(const std::string& data_usage_host,
-                       int64_t data_used,
-                       int64_t original_size,
-                       const base::Time& time) {
-    compression_stats_->RecordDataUseByHost(data_usage_host, data_used,
-                                            original_size, time);
-  }
-
-  void GetHistoricalDataUsage(HistoricalDataUsageCallback on_load_data_usage,
-                              const base::Time& now) {
-    compression_stats_->GetHistoricalDataUsageImpl(
-        std::move(on_load_data_usage), now);
-  }
-
-  void LoadHistoricalDataUsage(HistoricalDataUsageCallback on_load_data_usage) {
-    compression_stats_->service_->LoadHistoricalDataUsage(
-        std::move(on_load_data_usage));
-  }
-
-  void DeleteHistoricalDataUsage() {
-    compression_stats_->DeleteHistoricalDataUsage();
-  }
-
-  void ClearDataSavingStatistics() {
-    compression_stats_->ClearDataSavingStatistics(
-        DataReductionProxySavingsClearedReason::
-            USER_ACTION_DELETE_BROWSING_HISTORY);
-  }
-
-  void DeleteBrowsingHistory(const base::Time& start, const base::Time& end) {
-    compression_stats_->DeleteBrowsingHistory(start, end);
-  }
-
-  void EnableDataUsageReporting() {
-    pref_service()->SetBoolean(prefs::kDataUsageReportingEnabled, true);
-  }
-
-  void DisableDataUsageReporting() {
-    pref_service()->SetBoolean(prefs::kDataUsageReportingEnabled, false);
-  }
-
-  DataReductionProxyCompressionStats* compression_stats() {
-    return compression_stats_.get();
-  }
-
-  void ForceWritePrefs() { compression_stats_->WritePrefs(); }
-
-  bool IsDelayedWriteTimerRunning() const {
-    return compression_stats_->pref_writer_timer_.IsRunning();
-  }
-
-  TestingPrefServiceSimple* pref_service() {
-    return drp_test_context_->pref_service();
-  }
-
-  DataReductionProxyService* data_reduction_proxy_service() {
-    return drp_test_context_->data_reduction_proxy_service();
-  }
-
-  bool IsDataReductionProxyEnabled() {
-    return drp_test_context_->IsDataReductionProxyEnabled();
-  }
-
-  void InitializeWeeklyAggregateDataUse(const base::Time& now) {
-    compression_stats_->InitializeWeeklyAggregateDataUse(now);
-  }
-
-  void RecordWeeklyAggregateDataUse(
-      const base::Time& now,
-      int32_t received_kb,
-      bool is_user_request,
-      data_use_measurement::DataUseUserData::DataUseContentType content_type,
-      int32_t service_hash_code) {
-    compression_stats_->RecordWeeklyAggregateDataUse(
-        now, received_kb, is_user_request, content_type, service_hash_code);
-  }
-
-  void VerifyDictionaryPref(const std::string& pref,
-                            int key,
-                            int expected_value) const {
-    const base::Value* dict =
-        compression_stats_->pref_service_->GetDictionary(pref);
-
-    const base::Value* value = dict->FindKey(base::NumberToString(key));
-    EXPECT_EQ(expected_value != 0, !!value);
-    if (expected_value) {
-      EXPECT_EQ(expected_value,
-                dict->FindKey(base::NumberToString(key))->GetInt());
-    }
-  }
-
- private:
-  base::test::SingleThreadTaskEnvironment task_environment_;
-  std::unique_ptr<DataReductionProxyTestContext> drp_test_context_;
-  std::unique_ptr<DataReductionProxyCompressionStats> compression_stats_;
-  base::Time now_;
-  base::TimeDelta now_delta_;
-};
-
-TEST_F(DataReductionProxyCompressionStatsTest, WritePrefsDirect) {
-  SetUpPrefs();
-
-  VerifyPrefWasWritten(prefs::kHttpOriginalContentLength);
-  VerifyPrefWasWritten(prefs::kHttpReceivedContentLength);
-  VerifyPrefListWasWritten(prefs::kDailyHttpOriginalContentLength);
-  VerifyPrefListWasWritten(prefs::kDailyHttpReceivedContentLength);
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, WritePrefsDelayed) {
-  ResetCompressionStatsWithDelay(base::Minutes(kWriteDelayMinutes));
-
-  EXPECT_EQ(0, pref_service()->GetInt64(prefs::kHttpOriginalContentLength));
-  EXPECT_EQ(0, pref_service()->GetInt64(prefs::kHttpReceivedContentLength));
-  EXPECT_FALSE(IsDelayedWriteTimerRunning());
-
-  SetUpPrefs();
-  EXPECT_TRUE(IsDelayedWriteTimerRunning());
-  ForceWritePrefs();
-
-  VerifyPrefWasWritten(prefs::kHttpOriginalContentLength);
-  VerifyPrefWasWritten(prefs::kHttpReceivedContentLength);
-  VerifyPrefListWasWritten(prefs::kDailyHttpOriginalContentLength);
-  VerifyPrefListWasWritten(prefs::kDailyHttpReceivedContentLength);
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, StatsRestoredOnOnRestart) {
-  base::Value list_value(base::Value::Type::LIST);
-  list_value.Append(base::Value(base::NumberToString(1234)));
-  pref_service()->Set(prefs::kDailyHttpOriginalContentLength, list_value);
-
-  ResetCompressionStatsWithDelay(base::Minutes(kWriteDelayMinutes));
-
-  const base::Value* value =
-      pref_service()->GetList(prefs::kDailyHttpOriginalContentLength);
-  const std::string* string_value = value->GetList()[0].GetIfString();
-  EXPECT_EQ("1234", *string_value);
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, TotalLengths) {
-  const int64_t kOriginalLength = 200;
-  const int64_t kReceivedLength = 100;
-
-  compression_stats()->RecordDataUseWithMimeType(
-      kReceivedLength, kOriginalLength, IsDataReductionProxyEnabled(),
-      std::string(), true, data_use_measurement::DataUseUserData::OTHER, 0);
-
-  EXPECT_EQ(kReceivedLength,
-            GetInt64(data_reduction_proxy::prefs::kHttpReceivedContentLength));
-  EXPECT_FALSE(IsDataReductionProxyEnabled());
-  EXPECT_EQ(kOriginalLength,
-            GetInt64(data_reduction_proxy::prefs::kHttpOriginalContentLength));
-
-  // Record the same numbers again, and total lengths should be doubled.
-  compression_stats()->RecordDataUseWithMimeType(
-      kReceivedLength, kOriginalLength, IsDataReductionProxyEnabled(),
-      std::string(), true, data_use_measurement::DataUseUserData::OTHER, 0);
-
-  EXPECT_EQ(kReceivedLength * 2,
-            GetInt64(data_reduction_proxy::prefs::kHttpReceivedContentLength));
-  EXPECT_FALSE(IsDataReductionProxyEnabled());
-  EXPECT_EQ(kOriginalLength * 2,
-            GetInt64(data_reduction_proxy::prefs::kHttpOriginalContentLength));
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, OneResponse) {
-  const int64_t kOriginalLength = 200;
-  const int64_t kReceivedLength = 100;
-  int64_t original[] = {kOriginalLength};
-  int64_t received[] = {kReceivedLength};
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-
-  VerifyDailyDataSavingContentLengthPrefLists(original, 1, received, 1,
-                                              kNumDaysInHistory);
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, MultipleResponses) {
-  const int64_t kOriginalLength = 150;
-  const int64_t kReceivedLength = 100;
-  int64_t original[] = {kOriginalLength};
-  int64_t received[] = {kReceivedLength};
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, false, FakeNow());
-  VerifyDailyDataSavingContentLengthPrefLists(original, 1, received, 1,
-                                              kNumDaysInHistory);
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  original[0] += kOriginalLength;
-  received[0] += kReceivedLength;
-  VerifyDailyDataSavingContentLengthPrefLists(original, 1, received, 1,
-                                              kNumDaysInHistory);
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  original[0] += kOriginalLength;
-  received[0] += kReceivedLength;
-  VerifyDailyDataSavingContentLengthPrefLists(original, 1, received, 1,
-                                              kNumDaysInHistory);
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  original[0] += kOriginalLength;
-  received[0] += kReceivedLength;
-  VerifyDailyDataSavingContentLengthPrefLists(original, 1, received, 1,
-                                              kNumDaysInHistory);
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, false, FakeNow());
-  original[0] += kOriginalLength;
-  received[0] += kReceivedLength;
-  VerifyDailyDataSavingContentLengthPrefLists(original, 1, received, 1,
-                                              kNumDaysInHistory);
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, ForwardOneDay) {
-  const int64_t kOriginalLength = 200;
-  const int64_t kReceivedLength = 100;
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-
-  // Forward one day.
-  SetFakeTimeDeltaInHours(24);
-
-  // Proxy not enabled. Not via proxy.
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, false, FakeNow());
-
-  int64_t original[] = {kOriginalLength, kOriginalLength};
-  int64_t received[] = {kReceivedLength, kReceivedLength};
-  VerifyDailyDataSavingContentLengthPrefLists(original, 2, received, 2,
-                                              kNumDaysInHistory);
-
-  // Proxy enabled. Not via proxy.
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  original[1] += kOriginalLength;
-  received[1] += kReceivedLength;
-  VerifyDailyDataSavingContentLengthPrefLists(original, 2, received, 2,
-                                              kNumDaysInHistory);
-
-  // Proxy enabled and via proxy.
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  original[1] += kOriginalLength;
-  received[1] += kReceivedLength;
-  VerifyDailyDataSavingContentLengthPrefLists(original, 2, received, 2,
-                                              kNumDaysInHistory);
-
-  // Proxy enabled and via proxy, with content length greater than max int32_t.
-  const int64_t kBigOriginalLength = 0x300000000LL;  // 12G.
-  const int64_t kBigReceivedLength = 0x200000000LL;  // 8G.
-  RecordContentLengthPrefs(kBigReceivedLength, kBigOriginalLength, true,
-                           FakeNow());
-  original[1] += kBigOriginalLength;
-  received[1] += kBigReceivedLength;
-  VerifyDailyDataSavingContentLengthPrefLists(original, 2, received, 2,
-                                              kNumDaysInHistory);
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, PartialDayTimeChange) {
-  const int64_t kOriginalLength = 200;
-  const int64_t kReceivedLength = 100;
-  int64_t original[] = {0, kOriginalLength};
-  int64_t received[] = {0, kReceivedLength};
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  VerifyDailyDataSavingContentLengthPrefLists(original, 2, received, 2,
-                                              kNumDaysInHistory);
-
-  // Forward 10 hours, stay in the same day.
-  // See kLastUpdateTime: "Now" in test is 03:45am.
-  SetFakeTimeDeltaInHours(10);
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  original[1] += kOriginalLength;
-  received[1] += kReceivedLength;
-  VerifyDailyDataSavingContentLengthPrefLists(original, 2, received, 2,
-                                              kNumDaysInHistory);
-
-  // Forward 11 more hours, comes to tomorrow.
-  AddFakeTimeDeltaInHours(11);
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  int64_t original2[] = {kOriginalLength * 2, kOriginalLength};
-  int64_t received2[] = {kReceivedLength * 2, kReceivedLength};
-  VerifyDailyDataSavingContentLengthPrefLists(original2, 2, received2, 2,
-                                              kNumDaysInHistory);
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, BackwardAndForwardOneDay) {
-  base::HistogramTester histogram_tester;
-  const int64_t kOriginalLength = 200;
-  const int64_t kReceivedLength = 100;
-  int64_t original[] = {kOriginalLength};
-  int64_t received[] = {kReceivedLength};
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-
-  // Backward one day, expect no count.
-  SetFakeTimeDeltaInHours(-24);
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  original[0] += kOriginalLength;
-  received[0] += kReceivedLength;
-  VerifyDailyDataSavingContentLengthPrefLists(original, 1, received, 1,
-                                              kNumDaysInHistory);
-  histogram_tester.ExpectTotalCount("DataReductionProxy.SavingsCleared.Reason",
-                                    0);
-
-  // Then forward one day, expect no count.
-  AddFakeTimeDeltaInHours(24);
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  int64_t original2[] = {kOriginalLength * 2, kOriginalLength};
-  int64_t received2[] = {kReceivedLength * 2, kReceivedLength};
-  VerifyDailyDataSavingContentLengthPrefLists(original2, 2, received2, 2,
-                                              kNumDaysInHistory);
-  histogram_tester.ExpectTotalCount("DataReductionProxy.SavingsCleared.Reason",
-                                    0);
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, BackwardTwoDays) {
-  base::HistogramTester histogram_tester;
-  const int64_t kOriginalLength = 200;
-  const int64_t kReceivedLength = 100;
-  int64_t original[] = {kOriginalLength};
-  int64_t received[] = {kReceivedLength};
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-
-  // Backward two days, expect SYSTEM_CLOCK_MOVED_BACK.
-  SetFakeTimeDeltaInHours(-2 * 24);
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  VerifyDailyDataSavingContentLengthPrefLists(original, 1, received, 1,
-                                              kNumDaysInHistory);
-  histogram_tester.ExpectUniqueSample(
-      "DataReductionProxy.SavingsCleared.Reason",
-      DataReductionProxySavingsClearedReason::SYSTEM_CLOCK_MOVED_BACK, 1);
-
-  // Backward another two days, expect SYSTEM_CLOCK_MOVED_BACK.
-  SetFakeTimeDeltaInHours(-4 * 24);
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  histogram_tester.ExpectUniqueSample(
-      "DataReductionProxy.SavingsCleared.Reason",
-      DataReductionProxySavingsClearedReason::SYSTEM_CLOCK_MOVED_BACK, 2);
-
-  // Forward 2 days, expect no change.
-  AddFakeTimeDeltaInHours(2 * 24);
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-  histogram_tester.ExpectUniqueSample(
-      "DataReductionProxy.SavingsCleared.Reason",
-      DataReductionProxySavingsClearedReason::SYSTEM_CLOCK_MOVED_BACK, 2);
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, NormalizeHostname) {
-  EXPECT_EQ("www.foo.com", NormalizeHostname("http://www.foo.com"));
-  EXPECT_EQ("foo.com", NormalizeHostname("https://foo.com"));
-  EXPECT_EQ("bar.co.uk", NormalizeHostname("http://bar.co.uk"));
-  EXPECT_EQ("http.www.co.in", NormalizeHostname("http://http.www.co.in"));
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, RecordDataUsageSingleSite) {
-  EnableDataUsageReporting();
-  base::RunLoop().RunUntilIdle();
-
-  base::Time now = base::Time::Now();
-  RecordDataUsage("https://www.foo.com", 1000, 1250, now);
-
-  auto expected_data_usage =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  data_reduction_proxy::PerConnectionDataUsage* connection_usage =
-      expected_data_usage->at(kNumExpectedBuckets - 1).add_connection_usage();
-  data_reduction_proxy::PerSiteDataUsage* site_usage =
-      connection_usage->add_site_usage();
-  site_usage->set_hostname("www.foo.com");
-  site_usage->set_data_used(1000);
-  site_usage->set_original_size(1250);
-
-  DataUsageLoadVerifier verifier(std::move(expected_data_usage));
-
-  GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage,
-                                        base::Unretained(&verifier)),
-                         now);
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, DisableDataUsageRecording) {
-  EnableDataUsageReporting();
-  base::RunLoop().RunUntilIdle();
-
-  base::Time now = base::Time::Now();
-  RecordDataUsage("https://www.foo.com", 1000, 1250, now);
-
-  DisableDataUsageReporting();
-  base::RunLoop().RunUntilIdle();
-
-#if !BUILDFLAG(IS_ANDROID)
-  // Data usage on disk must be deleted.
-  auto expected_data_usage1 =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  DataUsageLoadVerifier verifier1(std::move(expected_data_usage1));
-  LoadHistoricalDataUsage(base::BindOnce(
-      &DataUsageLoadVerifier::OnLoadDataUsage, base::Unretained(&verifier1)));
-
-  // Public API must return an empty array.
-  auto expected_data_usage2 =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>();
-  DataUsageLoadVerifier verifier2(std::move(expected_data_usage2));
-  GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage,
-                                        base::Unretained(&verifier2)),
-                         now);
-#else
-  // For Android don't delete data usage.
-  auto expected_data_usage =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  data_reduction_proxy::PerConnectionDataUsage* connection_usage =
-      expected_data_usage->at(kNumExpectedBuckets - 1).add_connection_usage();
-  data_reduction_proxy::PerSiteDataUsage* site_usage =
-      connection_usage->add_site_usage();
-  site_usage->set_hostname("www.foo.com");
-  site_usage->set_data_used(1000);
-  site_usage->set_original_size(1250);
-
-  DataUsageLoadVerifier verifier(std::move(expected_data_usage));
-
-  GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage,
-                                        base::Unretained(&verifier)),
-                         now);
-#endif
-
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, RecordDataUsageMultipleSites) {
-  EnableDataUsageReporting();
-  base::RunLoop().RunUntilIdle();
-
-  base::Time now = base::Time::Now();
-  RecordDataUsage("https://www.foo.com", 1000, 1250, now);
-  RecordDataUsage("https://bar.com", 1001, 1251, now);
-  RecordDataUsage("http://foobar.com", 1002, 1252, now);
-
-  auto expected_data_usage =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  data_reduction_proxy::PerConnectionDataUsage* connection_usage =
-      expected_data_usage->at(kNumExpectedBuckets - 1).add_connection_usage();
-  data_reduction_proxy::PerSiteDataUsage* site_usage =
-      connection_usage->add_site_usage();
-  site_usage->set_hostname("www.foo.com");
-  site_usage->set_data_used(1000);
-  site_usage->set_original_size(1250);
-
-  site_usage = connection_usage->add_site_usage();
-  site_usage->set_hostname("bar.com");
-  site_usage->set_data_used(1001);
-  site_usage->set_original_size(1251);
-
-  site_usage = connection_usage->add_site_usage();
-  site_usage->set_hostname("foobar.com");
-  site_usage->set_data_used(1002);
-  site_usage->set_original_size(1252);
-
-  DataUsageLoadVerifier verifier(std::move(expected_data_usage));
-
-  GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage,
-                                        base::Unretained(&verifier)),
-                         now);
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest,
-       RecordDataUsageConsecutiveBuckets) {
-  EnableDataUsageReporting();
-  base::RunLoop().RunUntilIdle();
-
-  base::Time now = base::Time::Now();
-  base::Time fifteen_mins_ago = now - base::Minutes(15);
-
-  RecordDataUsage("https://www.foo.com", 1000, 1250, fifteen_mins_ago);
-
-  RecordDataUsage("https://bar.com", 1001, 1251, now);
-
-  auto expected_data_usage =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  data_reduction_proxy::PerConnectionDataUsage* connection_usage =
-      expected_data_usage->at(kNumExpectedBuckets - 2).add_connection_usage();
-  data_reduction_proxy::PerSiteDataUsage* site_usage =
-      connection_usage->add_site_usage();
-  site_usage->set_hostname("www.foo.com");
-  site_usage->set_data_used(1000);
-  site_usage->set_original_size(1250);
-
-  connection_usage =
-      expected_data_usage->at(kNumExpectedBuckets - 1).add_connection_usage();
-  site_usage = connection_usage->add_site_usage();
-  site_usage->set_hostname("bar.com");
-  site_usage->set_data_used(1001);
-  site_usage->set_original_size(1251);
-
-  DataUsageLoadVerifier verifier(std::move(expected_data_usage));
-
-  GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage,
-                                        base::Unretained(&verifier)),
-                         now);
-  base::RunLoop().RunUntilIdle();
-}
-
-// Test that the last entry in data usage bucket vector is for the current
-// interval even when current interval does not have any data usage.
-TEST_F(DataReductionProxyCompressionStatsTest,
-       RecordDataUsageEmptyCurrentInterval) {
-  EnableDataUsageReporting();
-  base::RunLoop().RunUntilIdle();
-
-  base::Time now = base::Time::Now();
-  base::Time fifteen_mins_ago = now - base::Minutes(15);
-
-  RecordDataUsage("https://www.foo.com", 1000, 1250, fifteen_mins_ago);
-
-  auto expected_data_usage =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  data_reduction_proxy::PerConnectionDataUsage* connection_usage =
-      expected_data_usage->at(kNumExpectedBuckets - 2).add_connection_usage();
-  data_reduction_proxy::PerSiteDataUsage* site_usage =
-      connection_usage->add_site_usage();
-  site_usage->set_hostname("www.foo.com");
-  site_usage->set_data_used(1000);
-  site_usage->set_original_size(1250);
-
-  DataUsageLoadVerifier verifier(std::move(expected_data_usage));
-
-  GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage,
-                                        base::Unretained(&verifier)),
-                         now);
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, DeleteHistoricalDataUsage) {
-  EnableDataUsageReporting();
-  base::RunLoop().RunUntilIdle();
-
-  base::Time now = base::Time::Now();
-  base::Time fifteen_mins_ago = now - base::Minutes(15);
-  // Fake record to be from 15 minutes ago so that it is flushed to storage.
-  RecordDataUsage("https://www.bar.com", 900, 1100, fifteen_mins_ago);
-
-  RecordDataUsage("https://www.foo.com", 1000, 1250, now);
-
-  DeleteHistoricalDataUsage();
-  base::RunLoop().RunUntilIdle();
-
-  auto expected_data_usage =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  DataUsageLoadVerifier verifier(std::move(expected_data_usage));
-
-  GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage,
-                                        base::Unretained(&verifier)),
-                         now);
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, DeleteBrowsingHistory) {
-  EnableDataUsageReporting();
-  base::RunLoop().RunUntilIdle();
-
-  base::Time now = base::Time::Now();
-  base::Time fifteen_mins_ago = now - base::Minutes(15);
-
-  // Fake record to be from 15 minutes ago so that it is flushed to storage.
-  RecordDataUsage("https://www.bar.com", 900, 1100, fifteen_mins_ago);
-
-  // This data usage will be in kept in memory.
-  RecordDataUsage("https://www.foo.com", 1000, 1250, now);
-
-  // This should only delete in-memory usage.
-  DeleteBrowsingHistory(now, now);
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_TRUE(compression_stats()->DataUsageMapForTesting().empty());
-
-  auto expected_data_usage =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  data_reduction_proxy::PerConnectionDataUsage* connection_usage =
-      expected_data_usage->at(kNumExpectedBuckets - 1).add_connection_usage();
-  data_reduction_proxy::PerSiteDataUsage* site_usage =
-      connection_usage->add_site_usage();
-  site_usage->set_hostname("www.bar.com");
-  site_usage->set_data_used(900);
-  site_usage->set_original_size(1100);
-  DataUsageLoadVerifier verifier1(std::move(expected_data_usage));
-
-  LoadHistoricalDataUsage(base::BindOnce(
-      &DataUsageLoadVerifier::OnLoadDataUsage, base::Unretained(&verifier1)));
-  base::RunLoop().RunUntilIdle();
-
-  // This should delete in-storage usage as well.
-  DeleteBrowsingHistory(fifteen_mins_ago, now);
-  base::RunLoop().RunUntilIdle();
-
-  expected_data_usage =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  DataUsageLoadVerifier verifier2(std::move(expected_data_usage));
-  LoadHistoricalDataUsage(base::BindOnce(
-      &DataUsageLoadVerifier::OnLoadDataUsage, base::Unretained(&verifier2)));
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(DataReductionProxyCompressionStatsTest, ClearDataSavingStatistics) {
-  EnableDataUsageReporting();
-  base::RunLoop().RunUntilIdle();
-
-  base::Time now = base::Time::Now();
-  base::Time fifteen_mins_ago = now - base::Minutes(15);
-  // Fake record to be from 15 minutes ago so that it is flushed to storage.
-  RecordDataUsage("https://www.bar.com", 900, 1100, fifteen_mins_ago);
-
-  RecordDataUsage("https://www.foo.com", 1000, 1250, now);
-
-  const int64_t kOriginalLength = 200;
-  const int64_t kReceivedLength = 100;
-  int64_t original[] = {kOriginalLength};
-  int64_t received[] = {kReceivedLength};
-
-  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true, FakeNow());
-
-  VerifyDailyDataSavingContentLengthPrefLists(original, 1, received, 1,
-                                              kNumDaysInHistory);
-
-  ClearDataSavingStatistics();
-  base::RunLoop().RunUntilIdle();
-
-  auto expected_data_usage =
-      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
-          kNumExpectedBuckets);
-  DataUsageLoadVerifier verifier(std::move(expected_data_usage));
-
-  GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage,
-                                        base::Unretained(&verifier)),
-                         now);
-  base::RunLoop().RunUntilIdle();
-
-  VerifyDailyDataSavingContentLengthPrefLists(nullptr, 0, nullptr, 0, 0);
-}
-
-// Aggregate metrics recording was disabled on Android x86 in crbug.com/865373.
-#if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_X86)
-#define MAYBE_WeeklyAggregateDataUse DISABLED_WeeklyAggregateDataUse
-#else
-#define MAYBE_WeeklyAggregateDataUse WeeklyAggregateDataUse
-#endif
-TEST_F(DataReductionProxyCompressionStatsTest, MAYBE_WeeklyAggregateDataUse) {
-  const int32_t kDataUseKB = 100;
-  base::HistogramTester histogram_tester;
-
-  InitializeWeeklyAggregateDataUse(base::Time::Now());
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.ThisWeekAggregateKB.Services.Downstream.Background",
-      0);
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.ThisWeekAggregateKB.Services.Downstream.Foreground",
-      0);
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.LastWeekAggregateKB.Services.Downstream.Background",
-      0);
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.LastWeekAggregateKB.Services.Downstream.Foreground",
-      0);
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.ThisWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      0);
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.LastWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      0);
-
-  RecordWeeklyAggregateDataUse(
-      base::Time::Now(), kDataUseKB, true,
-      data_use_measurement::DataUseUserData::MAIN_FRAME_HTML, 0);
-  VerifyDictionaryPref(prefs::kThisWeekUserTrafficContentTypeDownstreamKB,
-                       data_use_measurement::DataUseUserData::MAIN_FRAME_HTML,
-                       kDataUseKB);
-
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.ThisWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      0);
-
-  InitializeWeeklyAggregateDataUse(base::Time::Now());
-  histogram_tester.ExpectBucketCount(
-      "DataReductionProxy.ThisWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      data_use_measurement::DataUseUserData::MAIN_FRAME_HTML, kDataUseKB);
-  histogram_tester.ExpectBucketCount(
-      "DataReductionProxy.LastWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      data_use_measurement::DataUseUserData::MAIN_FRAME_HTML, 0);
-}
-
-// Aggregate metrics recording was disabled on Android x86 in crbug.com/865373.
-#if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_X86)
-#define MAYBE_AggregateDataUseForwardWeeks DISABLED_AggregateDataUseForwardWeeks
-#else
-#define MAYBE_AggregateDataUseForwardWeeks AggregateDataUseForwardWeeks
-#endif
-TEST_F(DataReductionProxyCompressionStatsTest,
-       MAYBE_AggregateDataUseForwardWeeks) {
-  const int32_t kMainFrameKB = 100;
-  const int32_t kNonMainFrameKB = 101;
-  base::HistogramTester histogram_tester;
-
-  base::Time fake_time_now = base::Time::Now();
-
-  InitializeWeeklyAggregateDataUse(fake_time_now);
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.ThisWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      0);
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.LastWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      0);
-
-  RecordWeeklyAggregateDataUse(
-      fake_time_now, kMainFrameKB, true,
-      data_use_measurement::DataUseUserData::MAIN_FRAME_HTML, 0);
-  VerifyDictionaryPref(prefs::kThisWeekUserTrafficContentTypeDownstreamKB,
-                       data_use_measurement::DataUseUserData::MAIN_FRAME_HTML,
-                       kMainFrameKB);
-  RecordWeeklyAggregateDataUse(
-      fake_time_now, kNonMainFrameKB, true,
-      data_use_measurement::DataUseUserData::NON_MAIN_FRAME_HTML, 0);
-  VerifyDictionaryPref(
-      prefs::kThisWeekUserTrafficContentTypeDownstreamKB,
-      data_use_measurement::DataUseUserData::NON_MAIN_FRAME_HTML,
-      kNonMainFrameKB);
-
-  // Fast forward 7 days, and verify that the last week histograms are recorded.
-  fake_time_now += base::Days(7);
-  InitializeWeeklyAggregateDataUse(fake_time_now);
-  VerifyDictionaryPref(prefs::kLastWeekUserTrafficContentTypeDownstreamKB,
-                       data_use_measurement::DataUseUserData::MAIN_FRAME_HTML,
-                       kMainFrameKB);
-  VerifyDictionaryPref(
-      prefs::kLastWeekUserTrafficContentTypeDownstreamKB,
-      data_use_measurement::DataUseUserData::NON_MAIN_FRAME_HTML,
-      kNonMainFrameKB);
-
-  histogram_tester.ExpectBucketCount(
-      "DataReductionProxy.LastWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      data_use_measurement::DataUseUserData::MAIN_FRAME_HTML, kMainFrameKB);
-  histogram_tester.ExpectBucketCount(
-      "DataReductionProxy.LastWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      data_use_measurement::DataUseUserData::NON_MAIN_FRAME_HTML,
-      kNonMainFrameKB);
-  histogram_tester.ExpectTotalCount(
-      "DataReductionProxy.ThisWeekAggregateKB.UserTraffic.Downstream."
-      "ContentType",
-      0);
-
-  // Subsequent data use should be recorded to the current week prefs.
-  RecordWeeklyAggregateDataUse(
-      fake_time_now, kMainFrameKB, true,
-      data_use_measurement::DataUseUserData::MAIN_FRAME_HTML, 0);
-  VerifyDictionaryPref(prefs::kThisWeekUserTrafficContentTypeDownstreamKB,
-                       data_use_measurement::DataUseUserData::MAIN_FRAME_HTML,
-                       kMainFrameKB);
-
-  // Fast forward by more than two weeks, and the prefs will be cleared.
-  fake_time_now += base::Days(15);
-  InitializeWeeklyAggregateDataUse(fake_time_now);
-  VerifyDictionaryPref(prefs::kLastWeekUserTrafficContentTypeDownstreamKB,
-                       data_use_measurement::DataUseUserData::MAIN_FRAME_HTML,
-                       0);
-  VerifyDictionaryPref(
-      prefs::kLastWeekUserTrafficContentTypeDownstreamKB,
-      data_use_measurement::DataUseUserData::NON_MAIN_FRAME_HTML, 0);
-  VerifyDictionaryPref(prefs::kThisWeekUserTrafficContentTypeDownstreamKB,
-                       data_use_measurement::DataUseUserData::MAIN_FRAME_HTML,
-                       0);
-  VerifyDictionaryPref(
-      prefs::kThisWeekUserTrafficContentTypeDownstreamKB,
-      data_use_measurement::DataUseUserData::NON_MAIN_FRAME_HTML, 0);
-}
-
-}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc
index 8c495b7..c319332 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc
@@ -22,40 +22,12 @@
                                 false);
 
   registry->RegisterInt64Pref(prefs::kDataReductionProxyLastEnabledTime, 0L);
-
-  registry->RegisterBooleanPref(prefs::kDataUsageReportingEnabled, false);
-
-  registry->RegisterInt64Pref(prefs::kHttpReceivedContentLength, 0);
-  registry->RegisterInt64Pref(prefs::kHttpOriginalContentLength, 0);
-
-  registry->RegisterListPref(prefs::kDailyHttpOriginalContentLength);
-
-  registry->RegisterListPref(prefs::kDailyHttpReceivedContentLength);
-
-  registry->RegisterInt64Pref(prefs::kDailyHttpContentLengthLastUpdateDate, 0L);
-
-  registry->RegisterIntegerPref(prefs::kThisWeekNumber, 0);
-  registry->RegisterDictionaryPref(
-      prefs::kThisWeekServicesDownstreamBackgroundKB, PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kThisWeekServicesDownstreamForegroundKB, PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kLastWeekServicesDownstreamBackgroundKB, PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kLastWeekServicesDownstreamForegroundKB, PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kThisWeekUserTrafficContentTypeDownstreamKB,
-      PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kLastWeekUserTrafficContentTypeDownstreamKB,
-      PrefRegistry::LOSSY_PREF);
 }
 
 void RegisterSimpleProfilePrefs(PrefRegistrySimple* registry) {
   registry->RegisterBooleanPref(
       prefs::kDataReductionProxyWasEnabledBefore, false);
 
-  registry->RegisterBooleanPref(prefs::kDataUsageReportingEnabled, false);
   RegisterPrefs(registry);
 }
 
@@ -63,30 +35,6 @@
 // |list_pref_map_| in Init() of DataReductionProxyCompressionStats.
 void RegisterPrefs(PrefRegistrySimple* registry) {
   registry->RegisterInt64Pref(prefs::kDataReductionProxyLastEnabledTime, 0L);
-  registry->RegisterInt64Pref(prefs::kHttpReceivedContentLength, 0);
-  registry->RegisterInt64Pref(
-      prefs::kHttpOriginalContentLength, 0);
-  registry->RegisterListPref(
-      prefs::kDailyHttpOriginalContentLength);
-  registry->RegisterListPref(prefs::kDailyHttpReceivedContentLength);
-  registry->RegisterInt64Pref(
-      prefs::kDailyHttpContentLengthLastUpdateDate, 0L);
-
-  registry->RegisterIntegerPref(prefs::kThisWeekNumber, 0);
-  registry->RegisterDictionaryPref(
-      prefs::kThisWeekServicesDownstreamBackgroundKB, PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kThisWeekServicesDownstreamForegroundKB, PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kLastWeekServicesDownstreamBackgroundKB, PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kLastWeekServicesDownstreamForegroundKB, PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kThisWeekUserTrafficContentTypeDownstreamKB,
-      PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(
-      prefs::kLastWeekUserTrafficContentTypeDownstreamKB,
-      PrefRegistry::LOSSY_PREF);
 }
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc
deleted file mode 100644
index b749cf6..0000000
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc
+++ /dev/null
@@ -1,81 +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 "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
-
-#include <stdint.h>
-
-#include "base/strings/string_number_conversions.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/pref_service.h"
-#include "components/prefs/scoped_user_pref_update.h"
-#include "components/prefs/testing_pref_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace data_reduction_proxy {
-
-class DataReductionProxyPrefsTest : public testing::Test {
- public:
-  void SetUp() override {
-    RegisterPrefs(local_state_prefs_.registry());
-    PrefRegistrySimple* profile_registry = profile_prefs_.registry();
-    RegisterPrefs(profile_registry);
-  }
-
-  PrefService* local_state_prefs() {
-    return &local_state_prefs_;
-  }
-
-  PrefService* profile_prefs() {
-    return &profile_prefs_;
-  }
-
-  // Initializes a list with ten string representations of successive int64_t
-  // values, starting with |starting_value|.
-  void InitializeList(const char* pref_name,
-                      int64_t starting_value,
-                      PrefService* pref_service) {
-    ListPrefUpdate list(local_state_prefs(), pref_name);
-    for (int64_t i = 0; i < 10L; ++i) {
-      list->Append(base::NumberToString(i + starting_value));
-    }
-  }
-
-  // Verifies that ten string repreentations of successive int64_t values
-  // starting with |starting_value| are found in the |ListValue| with the
-  // associated |pref_name|.
-  void VerifyList(const char* pref_name,
-                  int64_t starting_value,
-                  PrefService* pref_service) {
-    const base::Value* list_value = pref_service->GetList(pref_name);
-    base::Value::ConstListView list_view = list_value->GetList();
-    for (int64_t i = 0; i < 10L; ++i) {
-      std::string string_value;
-      int64_t value;
-      if (static_cast<size_t>(i) < list_view.size() &&
-          list_view[i].is_string()) {
-        string_value = list_view[i].GetString();
-      }
-      base::StringToInt64(string_value, &value);
-      EXPECT_EQ(i + starting_value, value);
-    }
-  }
-
- private:
-  void RegisterPrefs(PrefRegistrySimple* registry) {
-    registry->RegisterInt64Pref(prefs::kHttpReceivedContentLength, 0);
-    registry->RegisterInt64Pref(prefs::kHttpOriginalContentLength, 0);
-
-    registry->RegisterListPref(prefs::kDailyHttpOriginalContentLength);
-    registry->RegisterListPref(prefs::kDailyHttpReceivedContentLength);
-    registry->RegisterInt64Pref(
-        prefs::kDailyHttpContentLengthLastUpdateDate, 0L);
-  }
-
-  TestingPrefServiceSimple local_state_prefs_;
-  TestingPrefServiceSimple profile_prefs_;
-};
-
-}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
index 7674156..9ddd68a 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
@@ -18,93 +18,28 @@
 #include "base/task/task_runner_util.h"
 #include "base/time/default_clock.h"
 #include "base/time/time.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
-#include "components/data_reduction_proxy/core/browser/data_store.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
-#include "components/data_reduction_proxy/proto/data_store.pb.h"
-#include "components/data_use_measurement/core/data_use_measurement.h"
 #include "components/prefs/pref_service.h"
 
 namespace data_reduction_proxy {
 
-namespace {
-
-// Hostname used for the other bucket which consists of chrome-services traffic.
-// This should be in sync with the same in DataReductionSiteBreakdownView.java
-const char kOtherHostName[] = "Other";
-
-}  // namespace
-
 DataReductionProxyService::DataReductionProxyService(
     DataReductionProxySettings* settings,
-    PrefService* prefs,
-    std::unique_ptr<DataStore> store,
-    data_use_measurement::DataUseMeasurement* data_use_measurement,
-    const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
-    const base::TimeDelta& commit_delay)
-    : settings_(settings),
-      prefs_(prefs),
-      db_data_owner_(new DBDataOwner(std::move(store))),
-      db_task_runner_(db_task_runner),
-      data_use_measurement_(data_use_measurement) {
-  DCHECK(data_use_measurement_);
+    PrefService* prefs)
+    : settings_(settings), prefs_(prefs) {
   DCHECK(settings);
-
-  db_task_runner_->PostTask(FROM_HERE,
-                            base::BindOnce(&DBDataOwner::InitializeOnDBThread,
-                                           db_data_owner_->GetWeakPtr()));
-  if (prefs_) {
-    compression_stats_ = std::make_unique<DataReductionProxyCompressionStats>(
-        this, prefs_, commit_delay);
-  }
-  if (data_use_measurement_) {  // null in unit tests.
-    data_use_measurement_->AddServicesDataUseObserver(this);
-  }
 }
 
 DataReductionProxyService::~DataReductionProxyService() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  compression_stats_.reset();
-  db_task_runner_->DeleteSoon(FROM_HERE, db_data_owner_.release());
-  if (data_use_measurement_) {  // null in unit tests.
-    data_use_measurement_->RemoveServicesDataUseObserver(this);
-  }
 }
 
-
 void DataReductionProxyService::Shutdown() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   weak_factory_.InvalidateWeakPtrs();
 }
 
-void DataReductionProxyService::UpdateDataUseForHost(int64_t network_bytes,
-                                                     int64_t original_bytes,
-                                                     const std::string& host) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (compression_stats_) {
-    compression_stats_->RecordDataUseByHost(host, network_bytes, original_bytes,
-                                            base::Time::Now());
-  }
-}
-
-void DataReductionProxyService::UpdateContentLengths(
-    int64_t data_used,
-    int64_t original_size,
-    bool data_reduction_proxy_enabled,
-    const std::string& mime_type,
-    bool is_user_traffic,
-    data_use_measurement::DataUseUserData::DataUseContentType content_type,
-    int32_t service_hash_code) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (compression_stats_) {
-    compression_stats_->RecordDataUseWithMimeType(
-        data_used, original_size, data_reduction_proxy_enabled, mime_type,
-        is_user_traffic, content_type, service_hash_code);
-  }
-}
-
 void DataReductionProxyService::SetUnreachable(bool unreachable) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   settings_->SetUnreachable(unreachable);
@@ -122,81 +57,12 @@
     prefs_->SetString(pref_path, value);
 }
 
-
-
-void DataReductionProxyService::LoadHistoricalDataUsage(
-    HistoricalDataUsageCallback load_data_usage_callback) {
-  std::unique_ptr<std::vector<DataUsageBucket>> data_usage(
-      new std::vector<DataUsageBucket>());
-  std::vector<DataUsageBucket>* data_usage_ptr = data_usage.get();
-  db_task_runner_->PostTaskAndReply(
-      FROM_HERE,
-      base::BindOnce(&DBDataOwner::LoadHistoricalDataUsage,
-                     db_data_owner_->GetWeakPtr(),
-                     base::Unretained(data_usage_ptr)),
-      base::BindOnce(std::move(load_data_usage_callback),
-                     std::move(data_usage)));
-}
-
-void DataReductionProxyService::LoadCurrentDataUsageBucket(
-    LoadCurrentDataUsageCallback load_current_data_usage_callback) {
-  std::unique_ptr<DataUsageBucket> bucket(new DataUsageBucket());
-  DataUsageBucket* bucket_ptr = bucket.get();
-  db_task_runner_->PostTaskAndReply(
-      FROM_HERE,
-      base::BindOnce(&DBDataOwner::LoadCurrentDataUsageBucket,
-                     db_data_owner_->GetWeakPtr(),
-                     base::Unretained(bucket_ptr)),
-      base::BindOnce(std::move(load_current_data_usage_callback),
-                     std::move(bucket)));
-}
-
-void DataReductionProxyService::StoreCurrentDataUsageBucket(
-    std::unique_ptr<DataUsageBucket> current) {
-  db_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&DBDataOwner::StoreCurrentDataUsageBucket,
-                     db_data_owner_->GetWeakPtr(), std::move(current)));
-}
-
-void DataReductionProxyService::DeleteHistoricalDataUsage() {
-  db_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&DBDataOwner::DeleteHistoricalDataUsage,
-                                db_data_owner_->GetWeakPtr()));
-}
-
-void DataReductionProxyService::DeleteBrowsingHistory(const base::Time& start,
-                                                      const base::Time& end) {
-  DCHECK_LE(start, end);
-  db_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&DBDataOwner::DeleteBrowsingHistory,
-                                db_data_owner_->GetWeakPtr(), start, end));
-}
-
 base::WeakPtr<DataReductionProxyService>
 DataReductionProxyService::GetWeakPtr() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return weak_factory_.GetWeakPtr();
 }
 
-void DataReductionProxyService::OnServicesDataUse(int32_t service_hash_code,
-                                                  int64_t recv_bytes,
-                                                  int64_t sent_bytes) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (compression_stats_) {
-    // Record non-content initiated traffic to the Other bucket for data saver
-    // site-breakdown.
-    compression_stats_->RecordDataUseByHost(kOtherHostName, sent_bytes,
-                                            sent_bytes, base::Time::Now());
-    compression_stats_->RecordDataUseByHost(kOtherHostName, recv_bytes,
-                                            recv_bytes, base::Time::Now());
-    compression_stats_->RecordDataUseWithMimeType(
-        recv_bytes, recv_bytes, settings_->IsDataReductionProxyEnabled(),
-        std::string(), false, data_use_measurement::DataUseUserData::OTHER,
-        service_hash_code);
-  }
-}
-
 double DataReductionProxyService::GetSaveDataSavingsPercentEstimate(
     const std::string& origin) const {
   return 0;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
index 83b9f299..0d7f5c0 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
@@ -11,6 +11,7 @@
 #include <string>
 
 #include "base/callback.h"
+#include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
@@ -18,26 +19,17 @@
 #include "base/sequence_checker.h"
 #include "base/values.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
-#include "components/data_reduction_proxy/core/browser/db_data_owner.h"
-#include "components/data_use_measurement/core/data_use_measurement.h"
 #include "net/nqe/effective_connection_type.h"
 
 class PrefService;
 
-namespace base {
-class SequencedTaskRunner;
-class TimeDelta;
-}  // namespace base
-
 namespace data_reduction_proxy {
 
-class DataReductionProxyCompressionStats;
 class DataReductionProxySettings;
 
 // Contains and initializes all Data Reduction Proxy objects that have a
 // lifetime based on the UI thread.
-class DataReductionProxyService
-    : public data_use_measurement::DataUseMeasurement::ServicesDataUseObserver {
+class DataReductionProxyService {
  public:
   // The caller must ensure that |settings|, |prefs|, |request_context|, and
   // |io_task_runner| remain alive for the lifetime of the
@@ -45,13 +37,8 @@
   // will take ownership of |compression_stats|.
   // TODO(jeremyim): DataReductionProxyService should own
   // DataReductionProxySettings and not vice versa.
-  DataReductionProxyService(
-      DataReductionProxySettings* settings,
-      PrefService* prefs,
-      std::unique_ptr<DataStore> store,
-      data_use_measurement::DataUseMeasurement* data_use_measurement,
-      const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
-      const base::TimeDelta& commit_delay);
+  DataReductionProxyService(DataReductionProxySettings* settings,
+                            PrefService* prefs);
 
   DataReductionProxyService(const DataReductionProxyService&) = delete;
   DataReductionProxyService& operator=(const DataReductionProxyService&) =
@@ -61,23 +48,6 @@
 
   void Shutdown();
 
-  // Records data usage per host.
-  // Virtual for testing.
-  virtual void UpdateDataUseForHost(int64_t network_bytes,
-                                    int64_t original_bytes,
-                                    const std::string& host);
-
-  // Records daily data savings statistics in |compression_stats_|.
-  // Virtual for testing.
-  virtual void UpdateContentLengths(
-      int64_t data_used,
-      int64_t original_size,
-      bool data_reduction_proxy_enabled,
-      const std::string& mime_type,
-      bool is_user_traffic,
-      data_use_measurement::DataUseUserData::DataUseContentType content_type,
-      int32_t service_hash_code);
-
   // Records whether the Data Reduction Proxy is unreachable or not.
   void SetUnreachable(bool unreachable);
 
@@ -87,14 +57,6 @@
   // Stores a string value in |prefs_|.
   void SetStringPref(const std::string& pref_path, const std::string& value);
 
-  void LoadHistoricalDataUsage(
-      HistoricalDataUsageCallback load_data_usage_callback);
-  void LoadCurrentDataUsageBucket(
-      LoadCurrentDataUsageCallback load_current_data_usage_callback);
-  void StoreCurrentDataUsageBucket(std::unique_ptr<DataUsageBucket> current);
-  void DeleteHistoricalDataUsage();
-  void DeleteBrowsingHistory(const base::Time& start, const base::Time& end);
-
   void SetSettingsForTesting(DataReductionProxySettings* settings) {
     settings_ = settings;
   }
@@ -103,44 +65,19 @@
   // an origin.
   double GetSaveDataSavingsPercentEstimate(const std::string& origin) const;
 
-  // Accessor methods.
-  DataReductionProxyCompressionStats* compression_stats() const {
-    return compression_stats_.get();
-  }
-
   base::WeakPtr<DataReductionProxyService> GetWeakPtr();
 
-  base::SequencedTaskRunner* GetDBTaskRunnerForTesting() const {
-    return db_task_runner_.get();
-  }
-
  private:
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigServiceClientTest,
                            MultipleAuthFailures);
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigServiceClientTest,
                            ValidatePersistedClientConfig);
 
-  void OnServicesDataUse(int32_t service_hash_code,
-                         int64_t recv_bytes,
-                         int64_t sent_bytes) override;
-
-  // Tracks compression statistics to be displayed to the user.
-  std::unique_ptr<DataReductionProxyCompressionStats> compression_stats_;
-
   raw_ptr<DataReductionProxySettings> settings_;
 
   // A prefs service for storing data.
   raw_ptr<PrefService> prefs_;
 
-  std::unique_ptr<DBDataOwner> db_data_owner_;
-
-  // Used to post tasks to |db_data_owner_|.
-  scoped_refptr<base::SequencedTaskRunner> db_task_runner_;
-
-  // Must be accessed on UI thread. Guaranteed to be non-null during the
-  // lifetime of |this|.
-  raw_ptr<data_use_measurement::DataUseMeasurement> data_use_measurement_;
-
   SEQUENCE_CHECKER(sequence_checker_);
 
   base::WeakPtrFactory<DataReductionProxyService> weak_factory_{this};
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
index 5c027770..2c337bf 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -77,13 +77,6 @@
       prefs::kDataSaverEnabled,
       base::BindRepeating(&DataReductionProxySettings::OnProxyEnabledPrefChange,
                           base::Unretained(this)));
-
-#if BUILDFLAG(IS_ANDROID)
-  if (IsDataSaverEnabledByUser(is_off_the_record_profile_, prefs_)) {
-    data_reduction_proxy_service_->compression_stats()
-        ->SetDataUsageReportingEnabled(true);
-  }
-#endif  // BUILDFLAG(IS_ANDROID)
 }
 
 void DataReductionProxySettings::SetCallbackToRegisterSyntheticFieldTrial(
@@ -145,41 +138,13 @@
 
 void DataReductionProxySettings::SetDataReductionProxyEnabled(bool enabled) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(data_reduction_proxy_service_->compression_stats());
   if (GetOriginalProfilePrefs()->GetBoolean(prefs::kDataSaverEnabled) !=
       enabled) {
     GetOriginalProfilePrefs()->SetBoolean(prefs::kDataSaverEnabled, enabled);
     OnProxyEnabledPrefChange();
-#if BUILDFLAG(IS_ANDROID)
-    data_reduction_proxy_service_->compression_stats()
-        ->SetDataUsageReportingEnabled(enabled);
-#endif  // BUILDFLAG(IS_ANDROID)
   }
 }
 
-int64_t DataReductionProxySettings::GetDataReductionLastUpdateTime() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(data_reduction_proxy_service_->compression_stats());
-  return data_reduction_proxy_service_->compression_stats()
-      ->GetLastUpdateTime();
-}
-
-void DataReductionProxySettings::ClearDataSavingStatistics(
-    DataReductionProxySavingsClearedReason reason) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(data_reduction_proxy_service_->compression_stats());
-  data_reduction_proxy_service_->compression_stats()->ClearDataSavingStatistics(
-      reason);
-}
-
-int64_t DataReductionProxySettings::GetTotalHttpContentLengthSaved() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  return data_reduction_proxy_service_->compression_stats()
-             ->GetHttpOriginalContentLength() -
-         data_reduction_proxy_service_->compression_stats()
-             ->GetHttpReceivedContentLength();
-}
-
 void DataReductionProxySettings::SetUnreachable(bool unreachable) {
   unreachable_ = unreachable;
 }
@@ -221,12 +186,6 @@
     observer.OnDataSaverEnabledChanged(enabled);
 }
 
-void DataReductionProxySettings::ResetDataReductionStatistics() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(data_reduction_proxy_service_->compression_stats());
-  data_reduction_proxy_service_->compression_stats()->ResetStatistics();
-}
-
 void DataReductionProxySettings::MaybeActivateDataReductionProxy(
     bool at_startup) {
   DCHECK(thread_checker_.CalledOnValidThread());
@@ -252,7 +211,6 @@
   if (enabled &&
       !prefs->GetBoolean(prefs::kDataReductionProxyWasEnabledBefore)) {
     prefs->SetBoolean(prefs::kDataReductionProxyWasEnabledBefore, true);
-    ResetDataReductionStatistics();
   }
   if (!at_startup) {
     if (IsDataReductionProxyEnabled()) {
@@ -287,7 +245,6 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   RecordStartupState(IsDataReductionProxyEnabled() ? PROXY_ENABLED
                                                    : PROXY_DISABLED);
-  RecordStartupSavings();
 }
 
 void DataReductionProxySettings::RecordStartupState(
@@ -296,56 +253,4 @@
                             PROXY_STARTUP_STATE_COUNT);
 }
 
-void DataReductionProxySettings::RecordStartupSavings() const {
-  // Minimum bytes the user should have browsed, for the data savings percent
-  // UMA to be recorded at startup.
-  const unsigned int kMinOriginalContentLengthBytes =
-      10 * 1024 * 1024;  // 10 MB.
-
-  if (!IsDataReductionProxyEnabled())
-    return;
-
-  DCHECK(data_reduction_proxy_service_->compression_stats());
-  int64_t original_content_length =
-      data_reduction_proxy_service_->compression_stats()
-          ->GetHttpOriginalContentLength();
-  int64_t received_content_length =
-      data_reduction_proxy_service_->compression_stats()
-          ->GetHttpReceivedContentLength();
-  if (original_content_length < kMinOriginalContentLengthBytes)
-    return;
-  int savings_percent =
-      static_cast<int>(((original_content_length - received_content_length) /
-                        (float)original_content_length) *
-                       100.0);
-  if (savings_percent >= 0) {
-    UMA_HISTOGRAM_PERCENTAGE("DataReductionProxy.StartupSavingsPercent",
-                             savings_percent > 0 ? savings_percent : 0);
-  }
-  if (savings_percent < 0) {
-    UMA_HISTOGRAM_PERCENTAGE("DataReductionProxy.StartupNegativeSavingsPercent",
-                             -savings_percent);
-  }
-}
-
-ContentLengthList DataReductionProxySettings::GetDailyContentLengths(
-    const char* pref_name) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(data_reduction_proxy_service_->compression_stats());
-  return data_reduction_proxy_service_->compression_stats()
-      ->GetDailyContentLengths(pref_name);
-}
-
-void DataReductionProxySettings::GetContentLengths(
-    unsigned int days,
-    int64_t* original_content_length,
-    int64_t* received_content_length,
-    int64_t* last_update_time) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(data_reduction_proxy_service_->compression_stats());
-
-  data_reduction_proxy_service_->compression_stats()->GetContentLengths(
-      days, original_content_length, received_content_length, last_update_time);
-}
-
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
index 982e668..914b0806 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
@@ -15,7 +15,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "base/threading/thread_checker.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_member.h"
@@ -31,7 +30,6 @@
 namespace data_reduction_proxy {
 
 class DataReductionProxyService;
-class DataReductionProxyCompressionStats;
 
 // Values of the UMA DataReductionProxy.StartupState histogram.
 // This enum must remain synchronized with DataReductionProxyStartupState
@@ -120,24 +118,6 @@
   // Enables or disables the data reduction proxy.
   void SetDataReductionProxyEnabled(bool enabled);
 
-  // Returns the time in microseconds that the last update was made to the
-  // daily original and received content lengths.
-  int64_t GetDataReductionLastUpdateTime();
-
-  // Clears all data saving statistics for the given |reason|.
-  void ClearDataSavingStatistics(DataReductionProxySavingsClearedReason reason);
-
-  // Returns the difference between the total original size of all HTTP content
-  // received from the network and the actual size of the HTTP content received.
-  int64_t GetTotalHttpContentLengthSaved();
-
-  // Returns aggregate received and original content lengths over the specified
-  // number of days, as well as the time these stats were last updated.
-  void GetContentLengths(unsigned int days,
-                         int64_t* original_content_length,
-                         int64_t* received_content_length,
-                         int64_t* last_update_time);
-
   // Records that the data reduction proxy is unreachable or not.
   void SetUnreachable(bool unreachable);
 
@@ -146,8 +126,6 @@
   // some of them should have.
   bool IsDataReductionProxyUnreachable();
 
-  ContentLengthList GetDailyContentLengths(const char* pref_name);
-
   // Configures data reduction proxy. |at_startup| is true when this method is
   // called in response to creating or loading a new profile.
   void MaybeActivateDataReductionProxy(bool at_startup);
@@ -226,24 +204,8 @@
 
   void OnProxyEnabledPrefChange();
 
-  // Records data savings percentage histogram at chrome startup, for users who
-  // have browsed a reasonable amount. Positive and negative savings are
-  // recorded in a separate histogram.
-  void RecordStartupSavings() const;
-
-  void ResetDataReductionStatistics();
-
   bool unreachable_;
 
-  // The number of requests to reload the page with images from the Lo-Fi
-  // UI until Lo-Fi is disabled for the remainder of the session.
-  int lo_fi_user_requests_for_images_per_session_;
-
-  // The number of consecutive sessions where Lo-Fi was disabled for
-  // Lo-Fi to be disabled until the next implicit opt out epoch, which may be in
-  // a later session, or never.
-  int lo_fi_consecutive_session_disables_;
-
   std::unique_ptr<DataReductionProxyService> data_reduction_proxy_service_;
 
   raw_ptr<PrefService> prefs_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
index b7943b2..a0ede42 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
@@ -10,7 +10,6 @@
 #include "base/command_line.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
@@ -45,25 +44,10 @@
 
   test_context_->SetDataReductionProxyEnabled(false);
   TestingPrefServiceSimple* pref_service = test_context_->pref_service();
-  pref_service->SetInt64(prefs::kDailyHttpContentLengthLastUpdateDate, 0L);
   pref_service->registry()->RegisterDictionaryPref(kProxy);
   pref_service->SetBoolean(prefs::kDataReductionProxyWasEnabledBefore, false);
 
   ResetSettings(nullptr);
-
-  ListPrefUpdate original_update(test_context_->pref_service(),
-                                 prefs::kDailyHttpOriginalContentLength);
-  ListPrefUpdate received_update(test_context_->pref_service(),
-                                 prefs::kDailyHttpReceivedContentLength);
-  for (int64_t i = 0; i < kNumDaysInHistory; i++) {
-    original_update->Insert(original_update->GetList().begin(),
-                            base::Value(base::NumberToString(2 * i)));
-    received_update->Insert(received_update->GetList().begin(),
-                            base::Value(base::NumberToString(i)));
-  }
-  last_update_time_ = base::Time::Now().LocalMidnight();
-  pref_service->SetInt64(prefs::kDailyHttpContentLengthLastUpdateDate,
-                         last_update_time_.ToInternalValue());
 }
 
 template <class C>
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
index 913e8209..939bf810 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
@@ -66,7 +66,6 @@
   base::SingleThreadTaskExecutor io_task_executor_{base::MessagePumpType::IO};
   std::unique_ptr<DataReductionProxyTestContext> test_context_;
   std::unique_ptr<DataReductionProxySettings> settings_;
-  base::Time last_update_time_;
   std::map<std::string, std::string> synthetic_field_trials_;
 };
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
index cf0d517..b65659fd 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
@@ -16,7 +16,6 @@
 #include "base/test/task_environment.h"
 #include "base/time/clock.h"
 #include "base/time/default_clock.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
@@ -46,70 +45,6 @@
   }
 };
 
-TEST_F(DataReductionProxySettingsTest, TestResetDataReductionStatistics) {
-  int64_t original_content_length;
-  int64_t received_content_length;
-  int64_t last_update_time;
-  settings_->ResetDataReductionStatistics();
-  settings_->GetContentLengths(kNumDaysInHistory,
-                               &original_content_length,
-                               &received_content_length,
-                               &last_update_time);
-  EXPECT_EQ(0L, original_content_length);
-  EXPECT_EQ(0L, received_content_length);
-  EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time);
-}
-
-TEST_F(DataReductionProxySettingsTest, TestContentLengths) {
-  int64_t original_content_length;
-  int64_t received_content_length;
-  int64_t last_update_time;
-
-  // Request |kNumDaysInHistory| days.
-  settings_->GetContentLengths(kNumDaysInHistory,
-                               &original_content_length,
-                               &received_content_length,
-                               &last_update_time);
-  const unsigned int days = kNumDaysInHistory;
-  // Received content length history values are 0 to |kNumDaysInHistory - 1|.
-  int64_t expected_total_received_content_length = (days - 1L) * days / 2;
-  // Original content length history values are 0 to
-  // |2 * (kNumDaysInHistory - 1)|.
-  long expected_total_original_content_length = (days - 1L) * days;
-  EXPECT_EQ(expected_total_original_content_length, original_content_length);
-  EXPECT_EQ(expected_total_received_content_length, received_content_length);
-  EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time);
-
-  // Request |kNumDaysInHistory - 1| days.
-  settings_->GetContentLengths(kNumDaysInHistory - 1,
-                               &original_content_length,
-                               &received_content_length,
-                               &last_update_time);
-  expected_total_received_content_length -= (days - 1);
-  expected_total_original_content_length -= 2 * (days - 1);
-  EXPECT_EQ(expected_total_original_content_length, original_content_length);
-  EXPECT_EQ(expected_total_received_content_length, received_content_length);
-
-  // Request 0 days.
-  settings_->GetContentLengths(0,
-                               &original_content_length,
-                               &received_content_length,
-                               &last_update_time);
-  expected_total_received_content_length = 0;
-  expected_total_original_content_length = 0;
-  EXPECT_EQ(expected_total_original_content_length, original_content_length);
-  EXPECT_EQ(expected_total_received_content_length, received_content_length);
-
-  // Request 1 day. First day had 0 bytes so should be same as 0 days.
-  settings_->GetContentLengths(1,
-                               &original_content_length,
-                               &received_content_length,
-                               &last_update_time);
-  EXPECT_EQ(expected_total_original_content_length, original_content_length);
-  EXPECT_EQ(expected_total_received_content_length, received_content_length);
-}
-
-
 TEST(DataReductionProxySettingsStandaloneTest, TestIsProxyEnabledOrManaged) {
   base::test::SingleThreadTaskEnvironment task_environment{
       base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
@@ -330,18 +265,4 @@
                    prefs::kDataReductionProxyLastEnabledTime));
 }
 
-TEST_F(DataReductionProxySettingsTest, TestGetDailyContentLengths) {
-  ContentLengthList result =
-      settings_->GetDailyContentLengths(prefs::kDailyHttpOriginalContentLength);
-
-  ASSERT_FALSE(result.empty());
-  ASSERT_EQ(kNumDaysInHistory, result.size());
-
-  for (size_t i = 0; i < kNumDaysInHistory; ++i) {
-    long expected_length =
-        static_cast<long>((kNumDaysInHistory - 1 - i) * 2);
-    ASSERT_EQ(expected_length, result[i]);
-  }
-}
-
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
index acb527a..62d990b 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -14,10 +14,8 @@
 #include "base/run_loop.h"
 #include "base/strings/string_piece.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
-#include "components/data_reduction_proxy/core/browser/data_store.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -48,75 +46,25 @@
 namespace data_reduction_proxy {
 
 MockDataReductionProxyService::MockDataReductionProxyService(
-    data_use_measurement::DataUseMeasurement* data_use_measurement,
     DataReductionProxySettings* settings,
     PrefService* prefs,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
-    : DataReductionProxyService(settings,
-                                prefs,
-                                std::make_unique<TestDataStore>(),
-                                data_use_measurement,
-                                task_runner,
-                                base::TimeDelta()) {}
+    : DataReductionProxyService(settings, prefs) {}
 
 MockDataReductionProxyService::~MockDataReductionProxyService() {}
 
 TestDataReductionProxyService::TestDataReductionProxyService(
-    data_use_measurement::DataUseMeasurement* data_use_measurement,
     DataReductionProxySettings* settings,
     PrefService* prefs,
     const scoped_refptr<base::SequencedTaskRunner>& db_task_runner)
-    : DataReductionProxyService(settings,
-                                prefs,
-                                std::make_unique<TestDataStore>(),
-                                data_use_measurement,
-                                db_task_runner,
-                                base::TimeDelta()) {}
+    : DataReductionProxyService(settings, prefs) {}
 
 TestDataReductionProxyService::~TestDataReductionProxyService() {}
 
-TestDataStore::TestDataStore() {}
-
-TestDataStore::~TestDataStore() {}
-
-DataStore::Status TestDataStore::Get(base::StringPiece key,
-                                     std::string* value) {
-  auto value_iter = map_.find(std::string(key));
-  if (value_iter == map_.end())
-    return NOT_FOUND;
-
-  value->assign(value_iter->second);
-  return OK;
-}
-
-DataStore::Status TestDataStore::Put(
-    const std::map<std::string, std::string>& map) {
-  for (auto iter = map.begin(); iter != map.end(); ++iter)
-    map_[iter->first] = iter->second;
-
-  return OK;
-}
-
-DataStore::Status TestDataStore::Delete(base::StringPiece key) {
-  map_.erase(std::string(key));
-
-  return OK;
-}
-
-DataStore::Status TestDataStore::RecreateDB() {
-  map_.clear();
-
-  return OK;
-}
-
 DataReductionProxyTestContext::Builder::Builder()
     : use_mock_config_(false),
       use_mock_service_(false),
-      skip_settings_initialization_(false),
-      data_use_measurement_(
-          std::make_unique<data_use_measurement::DataUseMeasurement>(
-              nullptr,
-              network::TestNetworkConnectionTracker::GetInstance())) {}
+      skip_settings_initialization_(false) {}
 
 DataReductionProxyTestContext::Builder::~Builder() {}
 
@@ -174,19 +122,16 @@
   if (use_mock_service_) {
     test_context_flags |= USE_MOCK_SERVICE;
     service = std::make_unique<MockDataReductionProxyService>(
-        data_use_measurement_.get(), settings_.get(), pref_service.get(),
-        task_runner);
+        settings_.get(), pref_service.get(), task_runner);
   } else {
     service = std::make_unique<TestDataReductionProxyService>(
-        data_use_measurement_.get(), settings_.get(), pref_service.get(),
-        task_runner);
+        settings_.get(), pref_service.get(), task_runner);
   }
 
   std::unique_ptr<DataReductionProxyTestContext> test_context(
       new DataReductionProxyTestContext(
-          std::move(data_use_measurement_), task_runner,
-          std::move(pref_service), std::move(settings_), std::move(service),
-          test_context_flags));
+          task_runner, std::move(pref_service), std::move(settings_),
+          std::move(service), test_context_flags));
 
   if (!skip_settings_initialization_)
     test_context->InitSettingsWithoutCheck();
@@ -195,21 +140,16 @@
 }
 
 DataReductionProxyTestContext::DataReductionProxyTestContext(
-    std::unique_ptr<data_use_measurement::DataUseMeasurement>
-        data_use_measurement,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
     std::unique_ptr<TestingPrefServiceSimple> simple_pref_service,
     std::unique_ptr<DataReductionProxySettings> settings,
     std::unique_ptr<DataReductionProxyService> service,
     unsigned int test_context_flags)
-    : data_use_measurement_(std::move(data_use_measurement)),
-      test_context_flags_(test_context_flags),
+    : test_context_flags_(test_context_flags),
       task_runner_(task_runner),
       simple_pref_service_(std::move(simple_pref_service)),
       settings_(std::move(settings)),
       service_(std::move(service)) {
-  DCHECK(data_use_measurement_);
-
   if (service_)
     data_reduction_proxy_service_ = service_.get();
   else
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
index 9561ae1..6e58728 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
@@ -19,8 +19,6 @@
 #include "base/time/tick_clock.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h"
-#include "components/data_reduction_proxy/core/browser/data_store.h"
-#include "components/data_use_measurement/core/data_use_measurement.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/testing_pref_service.h"
 #include "net/base/backoff_entry.h"
@@ -39,26 +37,12 @@
 class MockDataReductionProxyService : public DataReductionProxyService {
  public:
   MockDataReductionProxyService(
-      data_use_measurement::DataUseMeasurement* data_use_measurement,
       DataReductionProxySettings* settings,
       PrefService* prefs,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
   ~MockDataReductionProxyService() override;
 
   MOCK_METHOD2(SetProxyPrefs, void(bool enabled, bool at_startup));
-  MOCK_METHOD7(UpdateContentLengths,
-               void(int64_t data_used,
-                    int64_t original_size,
-                    bool data_reduction_proxy_enabled,
-                    const std::string& mime_type,
-                    bool is_user_traffic,
-                    data_use_measurement::DataUseUserData::DataUseContentType
-                        content_type,
-                    int32_t service_hash_code));
-  MOCK_METHOD3(UpdateDataUseForHost,
-               void(int64_t network_bytes,
-                    int64_t original_bytes,
-                    const std::string& host));
 };
 
 // Test version of |DataReductionProxyService|, which bypasses initialization in
@@ -67,45 +51,12 @@
 class TestDataReductionProxyService : public DataReductionProxyService {
  public:
   TestDataReductionProxyService(
-      data_use_measurement::DataUseMeasurement* data_use_measurement,
       DataReductionProxySettings* settings,
       PrefService* prefs,
       const scoped_refptr<base::SequencedTaskRunner>& db_task_runner);
   ~TestDataReductionProxyService() override;
-
-  bool ignore_blocklist() const { return ignore_blocklist_; }
-
- private:
-  // Whether the long term blocklist rules should be ignored.
-  bool ignore_blocklist_ = false;
 };
 
-// Test version of |DataStore|. Uses an in memory hash map to store data.
-class TestDataStore : public data_reduction_proxy::DataStore {
- public:
-  TestDataStore();
-
-  ~TestDataStore() override;
-
-  void InitializeOnDBThread() override {}
-
-  DataStore::Status Get(base::StringPiece key, std::string* value) override;
-
-  DataStore::Status Put(const std::map<std::string, std::string>& map) override;
-
-  DataStore::Status Delete(base::StringPiece key) override;
-
-  DataStore::Status RecreateDB() override;
-
-  std::map<std::string, std::string>* map() { return &map_; }
-
- private:
-  std::map<std::string, std::string> map_;
-};
-
-// Builds a test version of the Data Reduction Proxy stack for use in tests.
-// Takes in various |TestContextOptions| which controls the behavior of the
-// underlying objects.
 class DataReductionProxyTestContext {
  public:
   // Allows for a fluent builder interface to configure what kind of objects
@@ -138,8 +89,6 @@
     bool use_mock_service_;
     bool skip_settings_initialization_;
     std::unique_ptr<DataReductionProxySettings> settings_;
-    std::unique_ptr<data_use_measurement::DataUseMeasurement>
-        data_use_measurement_;
   };
 
   DataReductionProxyTestContext(const DataReductionProxyTestContext&) = delete;
@@ -201,17 +150,12 @@
 
  private:
   DataReductionProxyTestContext(
-      std::unique_ptr<data_use_measurement::DataUseMeasurement>
-          data_use_measurement,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
       std::unique_ptr<TestingPrefServiceSimple> simple_pref_service,
       std::unique_ptr<DataReductionProxySettings> settings,
       std::unique_ptr<DataReductionProxyService> service,
       unsigned int test_context_flags);
 
-  std::unique_ptr<data_use_measurement::DataUseMeasurement>
-      data_use_measurement_;
-
   unsigned int test_context_flags_;
 
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/components/data_reduction_proxy/core/browser/data_store.cc b/components/data_reduction_proxy/core/browser/data_store.cc
deleted file mode 100644
index 782a194..0000000
--- a/components/data_reduction_proxy/core/browser/data_store.cc
+++ /dev/null
@@ -1,35 +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 "components/data_reduction_proxy/core/browser/data_store.h"
-
-namespace data_reduction_proxy {
-
-DataStore::DataStore() {
-}
-
-DataStore::~DataStore() {
-}
-
-void DataStore::InitializeOnDBThread() {
-}
-
-DataStore::Status DataStore::Get(base::StringPiece key, std::string* value) {
-  return DataStore::Status::NOT_FOUND;
-}
-
-DataStore::Status DataStore::Put(
-    const std::map<std::string, std::string>& map) {
-  return DataStore::Status::OK;
-}
-
-DataStore::Status DataStore::Delete(base::StringPiece key) {
-  return DataStore::Status::OK;
-}
-
-DataStore::Status DataStore::RecreateDB() {
-  return DataStore::Status::OK;
-}
-
-}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_store.h b/components/data_reduction_proxy/core/browser/data_store.h
deleted file mode 100644
index 7b90f1bc..0000000
--- a/components/data_reduction_proxy/core/browser/data_store.h
+++ /dev/null
@@ -1,48 +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 COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_STORE_H_
-#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_STORE_H_
-
-#include <map>
-#include <string>
-
-#include "base/strings/string_piece.h"
-
-namespace data_reduction_proxy {
-
-// Interface for a permanent key/value store used by the Data Reduction Proxy
-// component. This class has no-op methods for clients that do not want to
-// support a permanent store.
-class DataStore {
- public:
-  // Values are used in UMA. Do not change existing values; only append to the
-  // end. STATUS_MAX should always be last element.
-  enum Status { OK, NOT_FOUND, CORRUPTED, IO_ERROR, MISC_ERROR, STATUS_MAX };
-
-  DataStore();
-
-  DataStore(const DataStore&) = delete;
-  DataStore& operator=(const DataStore&) = delete;
-
-  virtual ~DataStore();
-
-  // Initializes the store on DB sequenced task runner.
-  virtual void InitializeOnDBThread();
-
-  // Gets the value from the store for the provided key.
-  virtual Status Get(base::StringPiece key, std::string* value);
-
-  // Persists the provided keys and values into the store.
-  virtual Status Put(const std::map<std::string, std::string>& map);
-
-  virtual Status Delete(base::StringPiece key);
-
-  // Deletes the LevelDB and recreates it.
-  virtual Status RecreateDB();
-};
-
-}  // namespace data_reduction_proxy
-
-#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_STORE_H_
diff --git a/components/data_reduction_proxy/core/browser/data_store_impl.cc b/components/data_reduction_proxy/core/browser/data_store_impl.cc
deleted file mode 100644
index 043ed02..0000000
--- a/components/data_reduction_proxy/core/browser/data_store_impl.cc
+++ /dev/null
@@ -1,159 +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 "components/data_reduction_proxy/core/browser/data_store_impl.h"
-
-#include <stdint.h>
-
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/metrics/histogram_macros.h"
-#include "components/data_reduction_proxy/proto/data_store.pb.h"
-#include "third_party/leveldatabase/env_chromium.h"
-#include "third_party/leveldatabase/leveldb_chrome.h"
-#include "third_party/leveldatabase/src/include/leveldb/db.h"
-#include "third_party/leveldatabase/src/include/leveldb/options.h"
-#include "third_party/leveldatabase/src/include/leveldb/status.h"
-#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
-
-namespace {
-
-const base::FilePath::CharType kDBName[] =
-    FILE_PATH_LITERAL("data_reduction_proxy_leveldb");
-
-data_reduction_proxy::DataStore::Status LevelDbToDRPStoreStatus(
-    leveldb::Status leveldb_status) {
-  if (leveldb_status.ok())
-    return data_reduction_proxy::DataStore::Status::OK;
-  if (leveldb_status.IsNotFound())
-    return data_reduction_proxy::DataStore::Status::NOT_FOUND;
-  if (leveldb_status.IsCorruption())
-    return data_reduction_proxy::DataStore::Status::CORRUPTED;
-  if (leveldb_status.IsIOError())
-    return data_reduction_proxy::DataStore::Status::IO_ERROR;
-
-  return data_reduction_proxy::DataStore::Status::MISC_ERROR;
-}
-
-}  // namespace
-
-namespace data_reduction_proxy {
-
-DataStoreImpl::DataStoreImpl(const base::FilePath& profile_path)
-    : profile_path_(profile_path) {
-  sequence_checker_.DetachFromSequence();
-}
-
-DataStoreImpl::~DataStoreImpl() {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-}
-
-void DataStoreImpl::InitializeOnDBThread() {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-  DCHECK(!db_);
-
-  DataStore::Status status = OpenDB();
-  if (status == CORRUPTED)
-    RecreateDB();
-}
-
-DataStore::Status DataStoreImpl::Get(base::StringPiece key,
-                                     std::string* value) {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  if (!db_)
-    return MISC_ERROR;
-
-  leveldb::ReadOptions read_options;
-  read_options.verify_checksums = true;
-  leveldb::Slice slice(key.data(), key.size());
-  leveldb::Status status = db_->Get(read_options, slice, value);
-  if (status.IsCorruption())
-    RecreateDB();
-
-  return LevelDbToDRPStoreStatus(status);
-}
-
-DataStore::Status DataStoreImpl::Put(
-    const std::map<std::string, std::string>& map) {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  if (!db_)
-    return MISC_ERROR;
-
-  leveldb::WriteBatch batch;
-  for (const auto& iter : map) {
-    batch.Put(iter.first, iter.second);
-  }
-
-  leveldb::WriteOptions write_options;
-  leveldb::Status status = db_->Write(write_options, &batch);
-  if (status.IsCorruption())
-    RecreateDB();
-
-  return LevelDbToDRPStoreStatus(status);
-}
-
-DataStore::Status DataStoreImpl::Delete(base::StringPiece key) {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  if (!db_)
-    return MISC_ERROR;
-
-  leveldb::Slice slice(key.data(), key.size());
-  leveldb::WriteOptions write_options;
-  leveldb::Status status = db_->Delete(write_options, slice);
-  if (status.IsCorruption())
-    RecreateDB();
-
-  return LevelDbToDRPStoreStatus(status);
-}
-
-DataStore::Status DataStoreImpl::OpenDB() {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  leveldb_env::Options options;
-  options.create_if_missing = true;
-  options.paranoid_checks = true;
-  // Deletes to buckets not found are stored in the log. Use a new log so that
-  // these log entries are deleted.
-  options.reuse_logs = false;
-  std::string db_name = profile_path_.Append(kDBName).AsUTF8Unsafe();
-  db_.reset();
-  Status status =
-      LevelDbToDRPStoreStatus(leveldb_env::OpenDB(options, db_name, &db_));
-  UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.LevelDBOpenStatus", status,
-                            STATUS_MAX);
-
-  if (status != OK)
-    LOG(ERROR) << "Failed to open Data Reduction Proxy DB: " << status;
-
-  if (db_) {
-    leveldb::Range range;
-    uint64_t size;
-    // We try to capture the size of the entire DB by using the highest and
-    // lowest keys.
-    range.start = "";
-    range.limit = "z";  // Keys starting with 'z' will not be included.
-    db_->GetApproximateSizes(&range, 1, &size);
-    UMA_HISTOGRAM_MEMORY_KB("DataReductionProxy.LevelDBSize", size / 1024);
-  }
-
-  return status;
-}
-
-DataStore::Status DataStoreImpl::RecreateDB() {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  db_.reset();
-  const base::FilePath db_path = profile_path_.Append(kDBName);
-  leveldb::Status s = leveldb_chrome::DeleteDB(db_path, leveldb::Options());
-  if (!s.ok())
-    return LevelDbToDRPStoreStatus(s);
-
-  return OpenDB();
-}
-
-}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_store_impl.h b/components/data_reduction_proxy/core/browser/data_store_impl.h
deleted file mode 100644
index fc5f253..0000000
--- a/components/data_reduction_proxy/core/browser/data_store_impl.h
+++ /dev/null
@@ -1,61 +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 COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_STORE_IMPL_H_
-#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_STORE_IMPL_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/files/file_path.h"
-#include "base/sequence_checker.h"
-#include "base/strings/string_piece.h"
-#include "components/data_reduction_proxy/core/browser/data_store.h"
-
-namespace leveldb {
-class DB;
-}
-
-namespace data_reduction_proxy {
-
-// Implementation of |DataStore| using LevelDB.
-class DataStoreImpl : public DataStore {
- public:
-  explicit DataStoreImpl(const base::FilePath& profile_path);
-
-  DataStoreImpl(const DataStoreImpl&) = delete;
-  DataStoreImpl& operator=(const DataStoreImpl&) = delete;
-
-  ~DataStoreImpl() override;
-
-  // Overrides of DataStore.
-  void InitializeOnDBThread() override;
-
-  Status Get(base::StringPiece key, std::string* value) override;
-
-  Status Put(const std::map<std::string, std::string>& map) override;
-
-  Status Delete(base::StringPiece key) override;
-
-  // Deletes the LevelDB and recreates it. This method is called if any DB call
-  // returns a |CORRUPTED| status or the database is cleared.
-  Status RecreateDB() override;
-
- private:
-  // Opens the underlying LevelDB for read and write.
-  Status OpenDB();
-
-  // The underlying LevelDB used by this implementation.
-  std::unique_ptr<leveldb::DB> db_;
-
-  // Path to the profile using this store.
-  const base::FilePath profile_path_;
-
-  base::SequenceChecker sequence_checker_;
-};
-
-}  // namespace data_reduction_proxy
-
-#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_STORE_IMPL_H_
diff --git a/components/data_reduction_proxy/core/browser/data_usage_store.cc b/components/data_reduction_proxy/core/browser/data_usage_store.cc
deleted file mode 100644
index e0a2844..0000000
--- a/components/data_reduction_proxy/core/browser/data_usage_store.cc
+++ /dev/null
@@ -1,302 +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.
-
-// Each |DataUsageBucket| corresponds to data usage for an interval of
-// |kDataUsageBucketLengthMins| minutes. We store data usage for the past
-// |kNumDataUsageBuckets| buckets. Buckets are maintained as a circular array
-// with indexes from 0 to (kNumDataUsageBuckets - 1). To store the circular
-// array in a key-value store, we convert each index to a unique key. The latest
-// bucket persisted to DB overwrites the oldest.
-
-#include "components/data_reduction_proxy/core/browser/data_usage_store.h"
-
-#include <algorithm>
-#include <string>
-#include <utility>
-
-#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/time.h"
-#include "components/data_reduction_proxy/proto/data_store.pb.h"
-
-namespace data_reduction_proxy {
-
-namespace {
-
-const char kCurrentBucketIndexKey[] = "current_bucket_index";
-const char kBucketKeyPrefix[] = "data_usage_bucket:";
-
-const int kMinutesInHour = 60;
-const int kMinutesInDay = 24 * kMinutesInHour;
-
-static_assert(data_reduction_proxy::kDataUsageBucketLengthInMinutes > 0,
-              "Length of time should be positive");
-static_assert(kMinutesInHour %
-                      data_reduction_proxy::kDataUsageBucketLengthInMinutes ==
-                  0,
-              "kDataUsageBucketLengthMins must be a factor of kMinsInHour");
-
-// Total number of buckets persisted to DB.
-const int kNumDataUsageBuckets =
-    kDataUsageHistoryNumDays * kMinutesInDay / kDataUsageBucketLengthInMinutes;
-
-std::string DbKeyForBucketIndex(int index) {
-  DCHECK_GE(index, 0);
-  DCHECK_LT(index, kNumDataUsageBuckets);
-
-  return base::StringPrintf("%s%d", kBucketKeyPrefix, index);
-}
-
-base::Time BucketLowerBoundary(base::Time time) {
-  base::Time::Exploded exploded;
-  time.UTCExplode(&exploded);
-  exploded.minute -= exploded.minute % kDataUsageBucketLengthInMinutes;
-  exploded.second = 0;
-  exploded.millisecond = 0;
-
-  base::Time out_time;
-  bool conversion_success = base::Time::FromUTCExploded(exploded, &out_time);
-  DCHECK(conversion_success);
-  return out_time;
-}
-
-}  // namespace
-
-DataUsageStore::DataUsageStore(DataStore* db)
-    : db_(db), current_bucket_index_(-1) {
-  sequence_checker_.DetachFromSequence();
-}
-
-DataUsageStore::~DataUsageStore() {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-}
-
-void DataUsageStore::LoadDataUsage(std::vector<DataUsageBucket>* data_usage) {
-  SCOPED_UMA_HISTOGRAM_TIMER("DataReductionProxy.HistoricalDataUsageLoadTime");
-
-  DCHECK(data_usage);
-
-  DataUsageBucket empty_bucket;
-  data_usage->clear();
-  data_usage->resize(kNumDataUsageBuckets, empty_bucket);
-
-  for (int i = 0; i < kNumDataUsageBuckets; ++i) {
-    int circular_array_index =
-        (i + current_bucket_index_ + 1) % kNumDataUsageBuckets;
-    LoadBucketAtIndex(circular_array_index, &data_usage->at(i));
-  }
-}
-
-void DataUsageStore::LoadCurrentDataUsageBucket(DataUsageBucket* current) {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-  DCHECK(current);
-
-  std::string current_index_string;
-  DataStore::Status index_read_status =
-      db_->Get(kCurrentBucketIndexKey, &current_index_string);
-
-  if (index_read_status != DataStore::Status::OK ||
-      !base::StringToInt(current_index_string, &current_bucket_index_)) {
-    current_bucket_index_ = 0;
-  }
-
-  DCHECK_GE(current_bucket_index_, 0);
-  DCHECK_LT(current_bucket_index_, kNumDataUsageBuckets);
-
-  DataStore::Status status = LoadBucketAtIndex(current_bucket_index_, current);
-  bool bucket_read_ok = status == DataStore::Status::OK;
-  current->set_had_read_error(!bucket_read_ok);
-  if (bucket_read_ok) {
-    current_bucket_last_updated_ =
-        base::Time::FromInternalValue(current->last_updated_timestamp());
-  }
-}
-
-void DataUsageStore::StoreCurrentDataUsageBucket(
-    const DataUsageBucket& current) {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-  DCHECK(current_bucket_index_ >= 0 &&
-         current_bucket_index_ < kNumDataUsageBuckets);
-
-  // If current bucket does not have any information, we skip writing to DB.
-  if (!current.has_last_updated_timestamp() ||
-      (current.has_had_read_error() && current.had_read_error()))
-    return;
-
-  int prev_current_bucket_index = current_bucket_index_;
-  base::Time prev_current_bucket_last_updated_ = current_bucket_last_updated_;
-  // We might have skipped saving buckets because Chrome was not being used.
-  // Write empty buckets to those slots to overwrite outdated information.
-  base::Time last_updated =
-      base::Time::FromInternalValue(current.last_updated_timestamp());
-  std::map<std::string, std::string> buckets_to_save;
-  int num_buckets_since_last_saved = BucketOffsetFromLastSaved(last_updated);
-  for (int i = 0; i < num_buckets_since_last_saved - 1; ++i)
-    GenerateKeyAndAddToMap(DataUsageBucket(), &buckets_to_save, true);
-
-  GenerateKeyAndAddToMap(current, &buckets_to_save,
-                         num_buckets_since_last_saved > 0);
-
-  current_bucket_last_updated_ =
-      base::Time::FromInternalValue(current.last_updated_timestamp());
-
-  buckets_to_save.insert(std::pair<std::string, std::string>(
-      kCurrentBucketIndexKey, base::NumberToString(current_bucket_index_)));
-
-  DataStore::Status status = db_->Put(buckets_to_save);
-  if (status != DataStore::Status::OK) {
-    current_bucket_index_ = prev_current_bucket_index;
-    current_bucket_last_updated_ = prev_current_bucket_last_updated_;
-    LOG(WARNING) << "Failed to write data usage buckets to LevelDB" << status;
-  }
-}
-
-void DataUsageStore::DeleteHistoricalDataUsage() {
-  std::string current_index_string;
-  DataStore::Status index_read_status =
-      db_->Get(kCurrentBucketIndexKey, &current_index_string);
-
-  // If the index doesn't exist, then no buckets have been written and the
-  // data usage doesn't need to be deleted.
-  if (index_read_status != DataStore::Status::OK)
-    return;
-
-  db_->RecreateDB();
-}
-
-void DataUsageStore::DeleteBrowsingHistory(const base::Time& start,
-                                           const base::Time& end) {
-  DCHECK_LE(start, end);
-  if (current_bucket_last_updated_.is_null())
-    return;
-
-  base::Time begin_current_interval =
-      BucketLowerBoundary(current_bucket_last_updated_);
-  // Data usage is stored for the past |kDataUsageHistoryNumDays| days. Compute
-  // the begin time for data usage.
-  base::Time begin_history = begin_current_interval -
-                             base::Days(kDataUsageHistoryNumDays) +
-                             base::Minutes(kDataUsageBucketLengthInMinutes);
-
-  // Nothing to do if there is no overlap between given interval and the
-  // interval for which data usage history is maintained.
-  if (begin_history > end || start > current_bucket_last_updated_)
-    return;
-
-  base::Time start_delete = start > begin_history ? start : begin_history;
-  base::Time end_delete =
-      end < current_bucket_last_updated_ ? end : current_bucket_last_updated_;
-
-  int first_index_to_delete = ComputeBucketIndex(start_delete);
-  int num_buckets_to_delete =
-      1 +
-      (BucketLowerBoundary(end_delete) - BucketLowerBoundary(start_delete))
-              .InMinutes() /
-          kDataUsageBucketLengthInMinutes;
-  for (int i = 0; i < num_buckets_to_delete; ++i) {
-    int index_to_delete = (first_index_to_delete + i) % kNumDataUsageBuckets;
-    db_->Delete(DbKeyForBucketIndex(index_to_delete));
-  }
-  UMA_HISTOGRAM_COUNTS_10000(
-      "DataReductionProxy.DeleteBrowsingHistory.NumBuckets",
-      num_buckets_to_delete);
-}
-
-int DataUsageStore::ComputeBucketIndex(const base::Time& time) const {
-  int offset = BucketOffsetFromLastSaved(time);
-
-  int index = current_bucket_index_ + offset;
-  if (index < 0) {
-    index += kNumDataUsageBuckets;
-  } else if (index >= kNumDataUsageBuckets) {
-    index -= kNumDataUsageBuckets;
-  }
-  DCHECK_GE(index, 0);
-  DCHECK_LT(index, kNumDataUsageBuckets);
-  return index;
-}
-
-// static
-bool DataUsageStore::AreInSameInterval(const base::Time& time1,
-                                       const base::Time& time2) {
-  if (time1.is_null() || time2.is_null())
-    return true;
-
-  return BucketLowerBoundary(time1) == BucketLowerBoundary(time2);
-}
-
-// static
-bool DataUsageStore::BucketOverlapsInterval(
-    const base::Time& bucket_last_updated,
-    const base::Time& start_interval,
-    const base::Time& end_interval) {
-  DCHECK(!bucket_last_updated.is_null());
-  DCHECK(!end_interval.is_null());
-  DCHECK_LE(start_interval, end_interval);
-
-  base::Time bucket_start = BucketLowerBoundary(bucket_last_updated);
-  base::Time bucket_end =
-      bucket_start + base::Minutes(kDataUsageBucketLengthInMinutes);
-  DCHECK_LE(bucket_start, bucket_end);
-  return bucket_end >= start_interval && end_interval >= bucket_start;
-}
-
-void DataUsageStore::GenerateKeyAndAddToMap(
-    const DataUsageBucket& bucket,
-    std::map<std::string, std::string>* map,
-    bool increment_current_index) {
-  if (increment_current_index) {
-    current_bucket_index_++;
-    DCHECK(current_bucket_index_ <= kNumDataUsageBuckets);
-    if (current_bucket_index_ == kNumDataUsageBuckets)
-      current_bucket_index_ = 0;
-  }
-
-  std::string bucket_key = DbKeyForBucketIndex(current_bucket_index_);
-
-  std::string bucket_value;
-  bool success = bucket.SerializeToString(&bucket_value);
-  DCHECK(success);
-
-  map->insert(std::pair<std::string, std::string>(std::move(bucket_key),
-                                                  std::move(bucket_value)));
-}
-
-int DataUsageStore::BucketOffsetFromLastSaved(
-    const base::Time& new_last_updated_timestamp) const {
-  if (current_bucket_last_updated_.is_null())
-    return 0;
-
-  base::TimeDelta time_delta =
-      BucketLowerBoundary(new_last_updated_timestamp) -
-      BucketLowerBoundary(current_bucket_last_updated_);
-  int offset_from_last_saved =
-      (time_delta.InMinutes() / kDataUsageBucketLengthInMinutes);
-  return offset_from_last_saved > 0
-             ? std::min(offset_from_last_saved, kNumDataUsageBuckets)
-             : std::max(offset_from_last_saved, -kNumDataUsageBuckets);
-}
-
-DataStore::Status DataUsageStore::LoadBucketAtIndex(int index,
-                                                    DataUsageBucket* bucket) {
-  DCHECK(index >= 0 && index < kNumDataUsageBuckets);
-
-  std::string bucket_as_string;
-  DataStore::Status bucket_read_status =
-      db_->Get(DbKeyForBucketIndex(index), &bucket_as_string);
-  if ((bucket_read_status != DataStore::Status::OK &&
-       bucket_read_status != DataStore::NOT_FOUND)) {
-    LOG(WARNING) << "Failed to read data usage bucket from LevelDB: "
-                 << bucket_read_status;
-  }
-  if (bucket_read_status == DataStore::Status::OK) {
-    bool parse_successful = bucket->ParseFromString(bucket_as_string);
-    DCHECK(parse_successful);
-  }
-  return bucket_read_status;
-}
-
-}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_usage_store.h b/components/data_reduction_proxy/core/browser/data_usage_store.h
deleted file mode 100644
index 19da8b9..0000000
--- a/components/data_reduction_proxy/core/browser/data_usage_store.h
+++ /dev/null
@@ -1,117 +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 COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_USAGE_STORE_H_
-#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_USAGE_STORE_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/memory/raw_ptr.h"
-#include "base/sequence_checker.h"
-#include "base/time/time.h"
-#include "components/data_reduction_proxy/core/browser/data_store.h"
-
-namespace data_reduction_proxy {
-class DataStore;
-class DataUsageBucket;
-
-// Time interval for each DataUsageBucket.
-constexpr int kDataUsageBucketLengthInMinutes = 15;
-
-// Number of days for which to maintain data usage history.
-constexpr int kDataUsageHistoryNumDays = 60;
-
-// Store for detailed data usage stats. Data usage from every
-// |kDataUsageBucketLengthMins| interval is stored in a DataUsageBucket.
-class DataUsageStore {
- public:
-  explicit DataUsageStore(DataStore* db);
-
-  DataUsageStore(const DataUsageStore&) = delete;
-  DataUsageStore& operator=(const DataUsageStore&) = delete;
-
-  ~DataUsageStore();
-
-  // Loads the historic data usage into |data_usage|.
-  void LoadDataUsage(std::vector<DataUsageBucket>* data_usage);
-
-  // Loads the data usage bucket for the current interval into |current_bucket|.
-  // This method must be called at least once before any calls to
-  // |StoreCurrentDataUsageBucket|.
-  void LoadCurrentDataUsageBucket(DataUsageBucket* bucket);
-
-  // Stores the data usage bucket for the current interval. This will overwrite
-  // the current data usage bucket in the |db_| if they are for the same
-  // interval. It will also backfill any missed intervals with empty data.
-  // Intervals might be missed because Chrome was not running, or there was no
-  // network activity during an interval.
-  void StoreCurrentDataUsageBucket(const DataUsageBucket& current_bucket);
-
-  // Deletes all historical data usage from storage.
-  void DeleteHistoricalDataUsage();
-
-  // Deletes historical data usage from storage.
-  void DeleteBrowsingHistory(const base::Time& start, const base::Time& end);
-
-  // Returns whether |time1| and |time2| are in the same interval. Each hour is
-  // divided into |kDataUsageBucketLengthMins| minute long intervals. Returns
-  // true if either |time1| or |time2| has NULL time since an uninitialized
-  // bucket can be assigned to any interval.
-  static bool AreInSameInterval(const base::Time& time1,
-                                const base::Time& time2);
-
-  // Returns whether the bucket that was last updated at |bucket_last_updated|
-  // overlaps in time with the interval [|start_interval|, |end_interval|].
-  static bool BucketOverlapsInterval(const base::Time& bucket_last_updated,
-                                     const base::Time& start_interval,
-                                     const base::Time& end_interval);
-
- private:
-  friend class DataUsageStoreTest;
-
-  // Converts the given |bucket| into a string format for persistance to
-  // |DataReductionProxyStore| and adds it to the map. The key is generated
-  // based on |current_bucket_index_|.
-  // |current_bucket_index_| will be incremented before generating the key if
-  // |increment_current_index| is true.
-  void GenerateKeyAndAddToMap(const DataUsageBucket& bucket,
-                              std::map<std::string, std::string>* map,
-                              bool increment_current_index);
-
-  // Returns the offset between the bucket for |current| time and the last
-  // bucket that was persisted to the store. Eg: Returns 0 if |current| is in
-  // the last persisted bucket. Returns 1 if |current| belongs to the bucket
-  // immediately after the last persisted bucket.
-  int BucketOffsetFromLastSaved(const base::Time& current) const;
-
-  // Computes the index of the bucket for the given |time| relative to
-  // |current_bucket_index_| and |current_bucket_last_updated_|.
-  // |current_bucket_last_updated_| belongs at |current_bucket_index_| and
-  // bucket index is computed by going backwards or forwards from current index
-  // by one position for every |kDataUsageBucketLengthInMinutes| minutes.
-  int ComputeBucketIndex(const base::Time& time) const;
-
-  // Loads the data usage bucket at the given index.
-  DataStore::Status LoadBucketAtIndex(int index, DataUsageBucket* current);
-
-  // The store to persist data usage information.
-  raw_ptr<DataStore> db_;
-
-  // The index of the last bucket persisted in the |db_|. |DataUsageBucket| is
-  // stored in the |db_| as a circular array. This index points to the array
-  // position corresponding to the current bucket.
-  int current_bucket_index_;
-
-  // The time when the current bucket was last written to |db_|. This field is
-  // used to determine if a DataUsageBucket to be saved belongs to the same
-  // interval, or a more recent interval.
-  base::Time current_bucket_last_updated_;
-
-  base::SequenceChecker sequence_checker_;
-};
-
-}  // namespace data_reduction_proxy
-#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_USAGE_STORE_H_
diff --git a/components/data_reduction_proxy/core/browser/data_usage_store_unittest.cc b/components/data_reduction_proxy/core/browser/data_usage_store_unittest.cc
deleted file mode 100644
index 508a57a..0000000
--- a/components/data_reduction_proxy/core/browser/data_usage_store_unittest.cc
+++ /dev/null
@@ -1,518 +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 "components/data_reduction_proxy/core/browser/data_usage_store.h"
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/strings/stringprintf.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/time/time.h"
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
-#include "components/data_reduction_proxy/core/browser/data_store.h"
-#include "components/data_reduction_proxy/proto/data_store.pb.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-// Each bucket holds data usage for a 15 minute interval. History is maintained
-// for 60 days.
-const unsigned kNumExpectedBuckets = 60 * 24 * 60 / 15;
-const int kBucketsInHour = 60 / 15;
-const int kTestCurrentBucketIndex = 2880;
-
-base::Time::Exploded TestExplodedTime() {
-  base::Time::Exploded exploded;
-  exploded.year = 2001;
-  exploded.month = 12;
-  exploded.day_of_month = 31;
-  exploded.day_of_week = 1;
-  exploded.hour = 12;
-  exploded.minute = 1;
-  exploded.second = 0;
-  exploded.millisecond = 0;
-
-  return exploded;
-}
-}
-
-namespace data_reduction_proxy {
-
-class DataUsageStoreTest : public testing::Test {
- protected:
-  void SetUp() override {
-    store_ = std::make_unique<TestDataStore>();
-    data_usage_store_ = std::make_unique<DataUsageStore>(store_.get());
-  }
-
-  int current_bucket_index() const {
-    return data_usage_store_->current_bucket_index_;
-  }
-
-  int64_t current_bucket_last_updated() const {
-    return data_usage_store_->current_bucket_last_updated_.ToInternalValue();
-  }
-
-  int ComputeBucketIndex(const base::Time& time) const {
-    return data_usage_store_->ComputeBucketIndex(time);
-  }
-
-  TestDataStore* store() const { return store_.get(); }
-
-  DataUsageStore* data_usage_store() const { return data_usage_store_.get(); }
-
-  void PopulateStore() {
-    base::Time::Exploded exploded = TestExplodedTime();
-    base::Time current_time;
-    EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &current_time));
-
-    std::map<std::string, std::string> map;
-    map.insert(
-        std::pair<std::string, std::string>("current_bucket_index", "2880"));
-    for (int i = 0; i < static_cast<int>(kNumExpectedBuckets); ++i) {
-      base::Time time = current_time - base::Minutes(i * 5);
-      DataUsageBucket bucket;
-      bucket.set_last_updated_timestamp(time.ToInternalValue());
-      bucket.set_had_read_error(false);
-      int index = kTestCurrentBucketIndex - i;
-      if (index < 0)
-        index += kNumExpectedBuckets;
-
-      std::string bucket_value;
-      ASSERT_TRUE(bucket.SerializeToString(&bucket_value));
-      map.insert(std::pair<std::string, std::string>(
-          base::StringPrintf("data_usage_bucket:%d", index), bucket_value));
-    }
-    store()->Put(map);
-  }
-
- private:
-  std::unique_ptr<TestDataStore> store_;
-  std::unique_ptr<DataUsageStore> data_usage_store_;
-};
-
-TEST_F(DataUsageStoreTest, LoadEmpty) {
-  ASSERT_NE(0, current_bucket_index());
-
-  DataUsageBucket bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&bucket);
-
-  ASSERT_EQ(0, current_bucket_index());
-  ASSERT_EQ(0, current_bucket_last_updated());
-  ASSERT_FALSE(bucket.has_last_updated_timestamp());
-
-  std::vector<DataUsageBucket> data_usage;
-  data_usage_store()->LoadDataUsage(&data_usage);
-
-  ASSERT_EQ(kNumExpectedBuckets, data_usage.size());
-  ASSERT_FALSE(data_usage[0].has_last_updated_timestamp());
-}
-
-TEST_F(DataUsageStoreTest, LoadAndStoreToSameBucket) {
-  DataUsageBucket bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&bucket);
-
-  base::Time now = base::Time::Now();
-  bucket.set_last_updated_timestamp(now.ToInternalValue());
-  bucket.set_had_read_error(false);
-
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket);
-  ASSERT_EQ(2u, store()->map()->size());
-
-  DataUsageBucket stored_bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&stored_bucket);
-  ASSERT_EQ(now.ToInternalValue(), stored_bucket.last_updated_timestamp());
-  ASSERT_FALSE(stored_bucket.had_read_error());
-
-  std::vector<DataUsageBucket> data_usage;
-  data_usage_store()->LoadDataUsage(&data_usage);
-
-  ASSERT_EQ(kNumExpectedBuckets, data_usage.size());
-  ASSERT_FALSE(data_usage[0].has_last_updated_timestamp());
-  ASSERT_FALSE(
-      data_usage[kNumExpectedBuckets - 2].has_last_updated_timestamp());
-  ASSERT_EQ(now.ToInternalValue(),
-            data_usage[kNumExpectedBuckets - 1].last_updated_timestamp());
-  ASSERT_FALSE(data_usage[kNumExpectedBuckets - 1].had_read_error());
-}
-
-TEST_F(DataUsageStoreTest, StoreSameBucket) {
-  base::Time::Exploded exploded = TestExplodedTime();
-
-  exploded.minute = 0;
-  exploded.second = 0;
-  exploded.millisecond = 0;
-  base::Time time1;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time1));
-
-  exploded.minute = 14;
-  exploded.second = 59;
-  exploded.millisecond = 999;
-  base::Time time2;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time2));
-
-  DataUsageBucket bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&bucket);
-
-  bucket.set_last_updated_timestamp(time1.ToInternalValue());
-  bucket.set_had_read_error(false);
-
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket);
-  ASSERT_EQ(2u, store()->map()->size());
-
-  bucket.set_last_updated_timestamp(time2.ToInternalValue());
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket);
-  ASSERT_EQ(2u, store()->map()->size());
-
-  std::vector<DataUsageBucket> data_usage;
-  data_usage_store()->LoadDataUsage(&data_usage);
-
-  ASSERT_EQ(kNumExpectedBuckets, data_usage.size());
-  ASSERT_FALSE(data_usage[0].has_last_updated_timestamp());
-  ASSERT_FALSE(
-      data_usage[kNumExpectedBuckets - 2].has_last_updated_timestamp());
-  ASSERT_EQ(time2.ToInternalValue(),
-            data_usage[kNumExpectedBuckets - 1].last_updated_timestamp());
-  ASSERT_FALSE(data_usage[kNumExpectedBuckets - 1].had_read_error());
-}
-
-TEST_F(DataUsageStoreTest, StoreConsecutiveBuckets) {
-  base::Time::Exploded exploded = TestExplodedTime();
-
-  exploded.minute = 0;
-  exploded.second = 59;
-  exploded.millisecond = 999;
-  base::Time time1;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time1));
-
-  exploded.minute = 15;
-  exploded.second = 0;
-  exploded.millisecond = 0;
-  base::Time time2;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time2));
-
-  DataUsageBucket bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&bucket);
-
-  bucket.set_last_updated_timestamp(time1.ToInternalValue());
-  bucket.set_had_read_error(false);
-
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket);
-  ASSERT_EQ(2u, store()->map()->size());
-
-  bucket.set_last_updated_timestamp(time2.ToInternalValue());
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket);
-  ASSERT_EQ(3u, store()->map()->size());
-
-  std::vector<DataUsageBucket> data_usage;
-  data_usage_store()->LoadDataUsage(&data_usage);
-
-  ASSERT_EQ(kNumExpectedBuckets, data_usage.size());
-  ASSERT_FALSE(data_usage[0].has_last_updated_timestamp());
-  ASSERT_FALSE(
-      data_usage[kNumExpectedBuckets - 3].has_last_updated_timestamp());
-  ASSERT_EQ(time1.ToInternalValue(),
-            data_usage[kNumExpectedBuckets - 2].last_updated_timestamp());
-  ASSERT_FALSE(data_usage[kNumExpectedBuckets - 2].had_read_error());
-  ASSERT_EQ(time2.ToInternalValue(),
-            data_usage[kNumExpectedBuckets - 1].last_updated_timestamp());
-  ASSERT_FALSE(data_usage[kNumExpectedBuckets - 1].had_read_error());
-}
-
-TEST_F(DataUsageStoreTest, StoreMultipleBuckets) {
-  DataUsageBucket bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&bucket);
-
-  // Comments indicate time expressed as day.hour.min.sec.millis relative to
-  // each other beginning at 0.0.0.0.0.
-  // The first bucket range is 0.0.0.0.0 - 0.0.14.59.999 and
-  // the second bucket range is 0.0.5.0.0 - 0.0.29.59.999, etc.
-  base::Time first_bucket_time = base::Time::Now();  // 0.0.0.0.0.
-  base::Time last_bucket_time = first_bucket_time    // 59.23.55.0.0
-                                + base::Days(60) - base::Minutes(15);
-  base::Time before_history_time =  // 0.0.-5.0.0
-      first_bucket_time - base::Minutes(15);
-  base::Time tenth_bucket_time =  // 0.2.15.0.0
-      first_bucket_time + base::Hours(2) + base::Minutes(15);
-  base::Time second_last_bucket_time =  // 59.23.45.0.0
-      last_bucket_time - base::Minutes(15);
-
-  // This bucket will be discarded when the |last_bucket| is stored.
-  DataUsageBucket bucket_before_history;
-  bucket_before_history.set_last_updated_timestamp(
-      before_history_time.ToInternalValue());
-  bucket_before_history.set_had_read_error(false);
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket_before_history);
-  // Only one bucket has been stored, so store should have 2 entries, one for
-  // current index and one for the bucket itself.
-  ASSERT_EQ(2u, store()->map()->size());
-
-  // Calling |StoreCurrentDataUsageBucket| with the same last updated timestamp
-  // should not cause number of stored buckets to increase and current bucket
-  // should be overwritten.
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket_before_history);
-  // Only one bucket has been stored, so store should have 2 entries, one for
-  // current index and one for the bucket itself.
-  ASSERT_EQ(2u, store()->map()->size());
-
-  // This will be the very first bucket once |last_bucket| is stored.
-  DataUsageBucket first_bucket;
-  first_bucket.set_last_updated_timestamp(first_bucket_time.ToInternalValue());
-  first_bucket.set_had_read_error(false);
-  data_usage_store()->StoreCurrentDataUsageBucket(first_bucket);
-  // A new bucket has been stored, so entires in map should increase by one.
-  ASSERT_EQ(3u, store()->map()->size());
-
-  // This will be the 10th bucket when |last_bucket| is stored. We skipped
-  // calling |StoreCurrentDataUsageBucket| on 10 buckets.
-  DataUsageBucket tenth_bucket;
-  tenth_bucket.set_last_updated_timestamp(tenth_bucket_time.ToInternalValue());
-  tenth_bucket.set_had_read_error(false);
-  data_usage_store()->StoreCurrentDataUsageBucket(tenth_bucket);
-  // 9 more (empty) buckets should have been added to the store.
-  ASSERT_EQ(12u, store()->map()->size());
-
-  // This will be the last but one bucket when |last_bucket| is stored.
-  DataUsageBucket second_last_bucket;
-  second_last_bucket.set_last_updated_timestamp(
-      second_last_bucket_time.ToInternalValue());
-  second_last_bucket.set_had_read_error(false);
-  data_usage_store()->StoreCurrentDataUsageBucket(second_last_bucket);
-  // Max number of buckets we store to DB plus one for the current index.
-  ASSERT_EQ(kNumExpectedBuckets + 1, store()->map()->size());
-
-  // This bucket should simply overwrite oldest bucket, so number of entries in
-  // store should be unchanged.
-  DataUsageBucket last_bucket;
-  last_bucket.set_last_updated_timestamp(last_bucket_time.ToInternalValue());
-  last_bucket.set_had_read_error(false);
-  data_usage_store()->StoreCurrentDataUsageBucket(last_bucket);
-  ASSERT_EQ(kNumExpectedBuckets + 1, store()->map()->size());
-
-  std::vector<DataUsageBucket> data_usage;
-  data_usage_store()->LoadDataUsage(&data_usage);
-
-  ASSERT_EQ(kNumExpectedBuckets, data_usage.size());
-  ASSERT_EQ(first_bucket_time.ToInternalValue(),
-            data_usage[0].last_updated_timestamp());
-  ASSERT_EQ(tenth_bucket_time.ToInternalValue(),
-            data_usage[9].last_updated_timestamp());
-  ASSERT_EQ(second_last_bucket_time.ToInternalValue(),
-            data_usage[kNumExpectedBuckets - 2].last_updated_timestamp());
-  ASSERT_EQ(last_bucket_time.ToInternalValue(),
-            data_usage[kNumExpectedBuckets - 1].last_updated_timestamp());
-
-  ASSERT_FALSE(data_usage[0].had_read_error());
-  ASSERT_FALSE(data_usage[9].had_read_error());
-  ASSERT_FALSE(data_usage[kNumExpectedBuckets - 2].had_read_error());
-  ASSERT_FALSE(data_usage[kNumExpectedBuckets - 1].had_read_error());
-}
-
-TEST_F(DataUsageStoreTest, DeleteHistoricalDataUsage) {
-  DataUsageBucket bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&bucket);
-
-  bucket.set_last_updated_timestamp(base::Time::Now().ToInternalValue());
-  bucket.set_had_read_error(false);
-
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket);
-  ASSERT_EQ(2u, store()->map()->size());
-
-  data_usage_store()->DeleteHistoricalDataUsage();
-  ASSERT_EQ(0u, store()->map()->size());
-}
-
-TEST_F(DataUsageStoreTest, BucketOverlapsInterval) {
-  base::Time::Exploded exploded = TestExplodedTime();
-  base::Time time1;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time1));
-
-  exploded.minute = 16;
-  base::Time time16;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time16));
-
-  exploded.minute = 17;
-  base::Time time17;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time17));
-
-  exploded.minute = 18;
-  base::Time time18;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time18));
-
-  exploded.minute = 33;
-  base::Time time33;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time33));
-
-  exploded.minute = 34;
-  base::Time time34;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time34));
-
-  exploded.minute = 46;
-  base::Time time46;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &time46));
-
-  ASSERT_FALSE(DataUsageStore::BucketOverlapsInterval(time1, time17, time33));
-  ASSERT_TRUE(DataUsageStore::BucketOverlapsInterval(time16, time17, time33));
-  ASSERT_TRUE(DataUsageStore::BucketOverlapsInterval(time18, time17, time33));
-  ASSERT_TRUE(DataUsageStore::BucketOverlapsInterval(time34, time17, time33));
-  ASSERT_FALSE(DataUsageStore::BucketOverlapsInterval(time46, time17, time33));
-}
-
-TEST_F(DataUsageStoreTest, ComputeBucketIndex) {
-  PopulateStore();
-
-  base::Time::Exploded exploded = TestExplodedTime();
-
-  DataUsageBucket current_bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&current_bucket);
-
-  base::Time out_time;
-
-  exploded.minute = 0;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  ASSERT_EQ(kTestCurrentBucketIndex, ComputeBucketIndex(out_time));
-
-  exploded.minute = 14;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  ASSERT_EQ(kTestCurrentBucketIndex, ComputeBucketIndex(out_time));
-
-  exploded.minute = 15;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  ASSERT_EQ(kTestCurrentBucketIndex + 1, ComputeBucketIndex(out_time));
-
-  exploded.hour = 11;
-  exploded.minute = 59;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  ASSERT_EQ(kTestCurrentBucketIndex - 1, ComputeBucketIndex(out_time));
-
-  exploded.minute = 0;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  ASSERT_EQ(kTestCurrentBucketIndex - kBucketsInHour,
-            ComputeBucketIndex(out_time));
-
-  exploded.hour = 1;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  ASSERT_EQ(kTestCurrentBucketIndex - kBucketsInHour * 11,
-            ComputeBucketIndex(out_time));
-
-  exploded.day_of_month = 1;
-  exploded.hour = 12;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  ASSERT_EQ(kTestCurrentBucketIndex - kBucketsInHour * 30 * 24,
-            ComputeBucketIndex(out_time));
-
-  exploded.hour = 11;
-  exploded.minute = 45;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  ASSERT_EQ(kTestCurrentBucketIndex - kBucketsInHour * 30 * 24 - 1 +
-                static_cast<int>(kNumExpectedBuckets),
-            ComputeBucketIndex(out_time));
-
-  exploded.minute = 30;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
-  ASSERT_EQ(kTestCurrentBucketIndex - kBucketsInHour * 30 * 24 - 2 +
-                static_cast<int>(kNumExpectedBuckets),
-            ComputeBucketIndex(out_time));
-}
-
-TEST_F(DataUsageStoreTest, DeleteBrowsingHistory) {
-  PopulateStore();
-  DataUsageBucket current_bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&current_bucket);
-  base::HistogramTester histogram_tester;
-
-  ASSERT_EQ(kNumExpectedBuckets + 1, store()->map()->size());
-
-  base::Time::Exploded exploded = TestExplodedTime();
-  exploded.minute = 0;
-  base::Time now;
-  EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &now));
-  base::Time fifteen_mins_from_now = now + base::Minutes(15);
-
-  // Deleting browsing from the future should be a no-op.
-  data_usage_store()->DeleteBrowsingHistory(fifteen_mins_from_now,
-                                            fifteen_mins_from_now);
-  ASSERT_EQ(kNumExpectedBuckets + 1, store()->map()->size());
-
-  ASSERT_TRUE(store()->map()->find(base::StringPrintf(
-                  "data_usage_bucket:%d", kTestCurrentBucketIndex)) !=
-              store()->map()->end());
-
-  // Delete the current bucket.
-  data_usage_store()->DeleteBrowsingHistory(now, now);
-  ASSERT_EQ(kNumExpectedBuckets, store()->map()->size());
-  ASSERT_TRUE(store()->map()->find(base::StringPrintf(
-                  "data_usage_bucket:%d", kTestCurrentBucketIndex)) ==
-              store()->map()->end());
-  histogram_tester.ExpectUniqueSample(
-      "DataReductionProxy.DeleteBrowsingHistory.NumBuckets", 1, 1);
-
-  // Delete the current bucket + the last 5 minutes, so two buckets.
-  data_usage_store()->DeleteBrowsingHistory(now - base::Minutes(5), now);
-  ASSERT_EQ(kNumExpectedBuckets - 1, store()->map()->size());
-  ASSERT_TRUE(store()->map()->find(base::StringPrintf(
-                  "data_usage_bucket:%d", kTestCurrentBucketIndex - 1)) ==
-              store()->map()->end());
-  histogram_tester.ExpectBucketCount(
-      "DataReductionProxy.DeleteBrowsingHistory.NumBuckets", 2, 1);
-
-  // Delete 30 days of browsing history.
-  data_usage_store()->DeleteBrowsingHistory(now - base::Days(30), now);
-  ASSERT_EQ(kNumExpectedBuckets - kBucketsInHour * 30 * 24,
-            store()->map()->size());
-  ASSERT_TRUE(store()->map()->find("data_usage_bucket:0") ==
-              store()->map()->end());
-  ASSERT_TRUE(store()->map()->find(base::StringPrintf(
-                  "data_usage_bucket:%d", kNumExpectedBuckets - 1)) !=
-              store()->map()->end());
-  histogram_tester.ExpectBucketCount(
-      "DataReductionProxy.DeleteBrowsingHistory.NumBuckets",
-      kBucketsInHour * 30 * 24, 1);
-
-  // Delete wraps around and removes the last element which is at position
-  // (|kNumExpectedBuckets| - 1).
-  data_usage_store()->DeleteBrowsingHistory(
-      now - base::Days(30) - base::Minutes(5), now);
-  ASSERT_EQ(kNumExpectedBuckets - kBucketsInHour * 30 * 24 - 1,
-            store()->map()->size());
-  ASSERT_TRUE(store()->map()->find(base::StringPrintf(
-                  "data_usage_bucket:%d", kNumExpectedBuckets - 1)) ==
-              store()->map()->end());
-  ASSERT_TRUE(store()->map()->find(base::StringPrintf(
-                  "data_usage_bucket:%d", kNumExpectedBuckets - 2)) !=
-              store()->map()->end());
-
-  data_usage_store()->DeleteBrowsingHistory(now - base::Days(60), now);
-  ASSERT_EQ(1u, store()->map()->size());
-  histogram_tester.ExpectBucketCount(
-      "DataReductionProxy.DeleteBrowsingHistory.NumBuckets",
-      kBucketsInHour * 30 * 24 - 1, 2);
-}
-
-TEST_F(DataUsageStoreTest, DontStoreReadError) {
-  DataUsageBucket bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&bucket);
-
-  base::Time now = base::Time::Now();
-  bucket.set_last_updated_timestamp(now.ToInternalValue());
-  bucket.set_had_read_error(true);
-
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket);
-  ASSERT_EQ(0u, store()->map()->size());
-}
-
-TEST_F(DataUsageStoreTest, DontStoreNoTimestamp) {
-  DataUsageBucket bucket;
-  data_usage_store()->LoadCurrentDataUsageBucket(&bucket);
-
-  bucket.set_had_read_error(false);
-
-  data_usage_store()->StoreCurrentDataUsageBucket(bucket);
-  ASSERT_EQ(0u, store()->map()->size());
-}
-
-}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/db_data_owner.cc b/components/data_reduction_proxy/core/browser/db_data_owner.cc
deleted file mode 100644
index 49e42fb..0000000
--- a/components/data_reduction_proxy/core/browser/db_data_owner.cc
+++ /dev/null
@@ -1,68 +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 "components/data_reduction_proxy/core/browser/db_data_owner.h"
-
-#include <utility>
-
-#include "base/check.h"
-#include "components/data_reduction_proxy/core/browser/data_store.h"
-#include "components/data_reduction_proxy/core/browser/data_usage_store.h"
-#include "components/data_reduction_proxy/proto/data_store.pb.h"
-
-namespace data_reduction_proxy {
-
-DBDataOwner::DBDataOwner(std::unique_ptr<DataStore> store)
-    : store_(std::move(store)), data_usage_(new DataUsageStore(store_.get())) {
-  sequence_checker_.DetachFromSequence();
-}
-
-DBDataOwner::~DBDataOwner() {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-}
-
-void DBDataOwner::InitializeOnDBThread() {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  store_->InitializeOnDBThread();
-}
-
-void DBDataOwner::LoadHistoricalDataUsage(
-    std::vector<DataUsageBucket>* data_usage) {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  data_usage_->LoadDataUsage(data_usage);
-}
-
-void DBDataOwner::LoadCurrentDataUsageBucket(DataUsageBucket* bucket) {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  data_usage_->LoadCurrentDataUsageBucket(bucket);
-}
-
-void DBDataOwner::StoreCurrentDataUsageBucket(
-    std::unique_ptr<DataUsageBucket> current) {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  data_usage_->StoreCurrentDataUsageBucket(*current);
-}
-
-void DBDataOwner::DeleteHistoricalDataUsage() {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  data_usage_->DeleteHistoricalDataUsage();
-}
-
-void DBDataOwner::DeleteBrowsingHistory(const base::Time& start,
-                                        const base::Time& end) {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-
-  data_usage_->DeleteBrowsingHistory(start, end);
-}
-
-base::WeakPtr<DBDataOwner> DBDataOwner::GetWeakPtr() {
-  return weak_factory_.GetWeakPtr();
-}
-
-}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/db_data_owner.h b/components/data_reduction_proxy/core/browser/db_data_owner.h
deleted file mode 100644
index a21a3fe..0000000
--- a/components/data_reduction_proxy/core/browser/db_data_owner.h
+++ /dev/null
@@ -1,72 +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 COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DB_DATA_OWNER_H_
-#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DB_DATA_OWNER_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/callback_forward.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-
-namespace base {
-class Time;
-}
-
-namespace data_reduction_proxy {
-class DataStore;
-class DataUsageBucket;
-class DataUsageStore;
-
-// Callback for loading the historical data usage.
-using HistoricalDataUsageCallback =
-    base::OnceCallback<void(std::unique_ptr<std::vector<DataUsageBucket>>)>;
-
-// Callback for loading data usage for the current bucket.
-using LoadCurrentDataUsageCallback =
-    base::OnceCallback<void(std::unique_ptr<DataUsageBucket>)>;
-
-// Contains and initializes all Data Reduction Proxy objects that have a
-// lifetime based on the DB task runner.
-class DBDataOwner {
- public:
-  explicit DBDataOwner(std::unique_ptr<DataStore> store);
-
-  DBDataOwner(const DBDataOwner&) = delete;
-  DBDataOwner& operator=(const DBDataOwner&) = delete;
-
-  virtual ~DBDataOwner();
-
-  // Initializes all the DB objects. Must be called on the DB task runner.
-  void InitializeOnDBThread();
-
-  // Loads data usage history stored in |DataStore|.
-  void LoadHistoricalDataUsage(std::vector<DataUsageBucket>* data_usage);
-
-  // Loads the last stored data usage bucket from |DataStore| into |bucket|.
-  void LoadCurrentDataUsageBucket(DataUsageBucket* bucket);
-
-  // Stores |current| to |DataStore|.
-  void StoreCurrentDataUsageBucket(std::unique_ptr<DataUsageBucket> current);
-
-  // Deletes all historical data usage from storage.
-  void DeleteHistoricalDataUsage();
-
-  // Deletes browsing history for the given data range from storage.
-  void DeleteBrowsingHistory(const base::Time& start, const base::Time& end);
-
-  // Returns a weak pointer to self for use on UI thread.
-  base::WeakPtr<DBDataOwner> GetWeakPtr();
-
- private:
-  std::unique_ptr<DataStore> store_;
-  std::unique_ptr<DataUsageStore> data_usage_;
-  base::SequenceChecker sequence_checker_;
-  base::WeakPtrFactory<DBDataOwner> weak_factory_{this};
-};
-
-}  // namespace data_reduction_proxy
-#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DB_DATA_OWNER_H_
diff --git a/components/data_reduction_proxy/core/common/BUILD.gn b/components/data_reduction_proxy/core/common/BUILD.gn
index 7eb0e541..78f88dd 100644
--- a/components/data_reduction_proxy/core/common/BUILD.gn
+++ b/components/data_reduction_proxy/core/common/BUILD.gn
@@ -2,25 +2,19 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/util/process_version.gni")
-
 # Variables:
 #   deps: Extra dependencies.
 template("common_tmpl") {
   static_library(target_name) {
     sources = [
-      "data_reduction_proxy_headers.cc",
-      "data_reduction_proxy_headers.h",
       "data_reduction_proxy_pref_names.cc",
       "data_reduction_proxy_pref_names.h",
       "data_reduction_proxy_switches.cc",
       "data_reduction_proxy_switches.h",
     ]
 
-    public_deps = [ ":version_header" ]
     deps = [
       "//base",
-      "//components/data_reduction_proxy/proto:data_reduction_proxy_proto",
       "//google_apis",
       "//services/network/public/cpp",
     ]
@@ -39,13 +33,3 @@
     "//url",
   ]
 }
-
-process_version("version_header") {
-  template_file = "version.h.in"
-  sources = [ "//chrome/VERSION" ]
-  output = "$target_gen_dir/version.h"
-  extra_args = [
-    "-e",
-    "VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)",
-  ]
-}
diff --git a/components/data_reduction_proxy/core/common/chrome_proxy_header.txt b/components/data_reduction_proxy/core/common/chrome_proxy_header.txt
deleted file mode 100644
index 5a6a81c..0000000
--- a/components/data_reduction_proxy/core/common/chrome_proxy_header.txt
+++ /dev/null
@@ -1,114 +0,0 @@
-The Chrome-Proxy header is used to convey client credentials and capabilities
-to the Data Reduction Proxy and to receive instructions from it.
-
-Background
-----------
-
-The Data Reduction Proxy is operated by Google for Chrome. Chrome is
-configured to connect to it via TLS at proxy.googlezip.net:443 and via HTTP
-at compress.googlezip.net:80. The Data Reduction Proxy only proxies HTTP
-traffic from non-incognito tabs.
-
-Chrome-Proxy Response Header
-----------------------------
-
-The Data Reduction Proxy uses the Chrome-Proxy response header to instruct
-Chrome to bypass the proxy for a period of time and retry the request directly.
-It may do so to shed load, when the requested URL is on a blacklist of
-malicious or illegal resources, or when the request is for video, which the
-proxy does not currently serve. Bypasses may be issued for other reasons as
-well.
-
-In order to bypass a proxy and make decisions about when requests should be
-proxied and which proxy they should use, some proxies serve PAC scripts
-themselves with a low HTTP cache timeout, and dynamically update the scripts
-to direct users. This is the current state of the art, but the approach has many
-drawbacks. Some clients ignore the HTTP caching headers for the PAC script. The
-client's performance suffers because new PAC scripts must be interpreted after
-every invalidation. Clients must also store (large) blacklists. Server design is
-complicated by needing to decouple a request from the mechanism that would
-bypass it (a PAC). Bypass fidelity is coarse meaning that bypass decisions can't
-be made on a per-request basis. And bypass decisions must be made before the
-request is sent, which isn't always possible, e.g., for domains the proxy hasn't
-served before.
-
-Instead, the Data Reduction Proxy sends one of a set of bypass directives in the
-"Chrome-Proxy" header if it wants the client not to use it. Upon reception of
-this header, the client may decide to retry the request with the proxy disabled
-or cancel the request. Chrome cancels instead of retrying  non-idempotent
-requests.
-
-The "Chrome-Proxy" response header has the following format:
-
-chrome-proxy           = "Chrome-Proxy" ":" 1#chrome-proxy-directive
-chrome-proxy-directive = token [ "=" ( token / quoted-string ) ]
-
-The header uses the definition of 'token' and 'quoted-string' from
-https://datatracker.ietf.org/doc/rfc7230/
-
-The directives have the following meanings:
-
-bypass:     Argument syntax: delta-seconds
-                             delta-seconds = 1*DIGIT (see: 1.2.1 of rfc7234)
-            Bypass the currently configured proxy for specified number of
-            seconds. If zero is specified, Chrome should use its default
-            proxy bypass timeout, which is a random duration between 1 and 5
-            minutes. If the TLS proxy is bypassed, Chrome will downgrade to
-            using HTTP to connect to the Data Reduction Proxy. If the HTTP
-            proxy is bypassed, Chrome will downgrade to using a DIRECT
-            connection.
-block:      Argument syntax: delta-seconds
-            Bypass all Data Reduction Proxies for the specified number of
-            seconds. If zero is specified, Chrome will use the default block
-            timeout, which is a random time between 1 and 5 minutes.
-block-once: Bypass all Data Reductions Proxies for this request only.
-
-Currently, the directives are mutually exclusive, but the header format does
-not require this. With "block-once", no token is expected.
-
-If more than one directive is contained the header, then Chrome reacts to only
-the highest priority directive. Priorities from highest to lowest are:
-block > bypass > block-once.
-
-
-Examples that respectively bypass the current proxy for seven seconds, bypass
-both the TLS and HTTP proxies for Chrome's default proxy bypass duration, and
-bypass the TLS and HTTP proxies only for the current request:
-
-Chrome-Proxy: bypass=7
-Chrome-Proxy: block=0
-Chrome-Proxy: block-once
-
-
-The Chrome-Proxy header is NOT hop-by-hop, and thus transparent proxies and
-other intermediaries should not modify it. Further, only the Data Reduction
-Proxy should add this header to responses.
-
-Chrome-Proxy Request Header
----------------------------
-
-The Chrome-Proxy request header is used to specify client capabilities and
-credentials. It has the same form as the response header. The directives have
-the following names and meanings:
-
-ps:          Argument syntax: token
-             A User-Agent-selected pseudorandom session ID.
-sid:         Argument syntax: token
-             A credential string.
-b:           Argument syntax: 1*DIGIT
-             The Chrome build number of the client
-p:           Argument syntax: 1*DIGIT
-             The Chrome patch number of the client
-c:           Argument syntax: "android" / "ios" / "mac" / "win" / "linux" /
-                              "chromeos" / "webview" 
-             The type of client.
-
-The values of the 'b', 'p', and 'c' directives can often be gleaned from the
-user agent string, but not always, so they are sent explicitly. Each request
-sent from Chrome to a Data Reduction Proxy contains a Chrome-Proxy header with
-values for all five of these directives.
-
-For example, for Chrome 38 on Android with a version 38.0.2125.114 (note the
-'ps' and 'sid' values are representative):
-
-Chrome-Proxy: ps=484343-123-4-9484, sid=he9wj3gjd03, b=2125, p=114, c=android
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
deleted file mode 100644
index 06fd8c5a..0000000
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
+++ /dev/null
@@ -1,94 +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 "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <string>
-#include <utility>
-
-#include "base/metrics/field_trial_params.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/time/time.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_status_code.h"
-#include "net/http/http_util.h"
-#include "services/network/public/mojom/url_response_head.mojom.h"
-
-namespace {
-
-const char kChromeProxyHeader[] = "chrome-proxy";
-
-const char kActionValueDelimiter = '=';
-
-bool StartsWithActionPrefix(base::StringPiece header_value,
-                            base::StringPiece action_prefix) {
-  DCHECK(!action_prefix.empty());
-  // A valid action does not include a trailing '='.
-  DCHECK(action_prefix.back() != kActionValueDelimiter);
-
-  return header_value.size() > action_prefix.size() + 1 &&
-         header_value[action_prefix.size()] == kActionValueDelimiter &&
-         base::StartsWith(header_value, action_prefix,
-                          base::CompareCase::INSENSITIVE_ASCII);
-}
-
-bool GetDataReductionProxyActionValue(const net::HttpResponseHeaders* headers,
-                                      base::StringPiece action_prefix,
-                                      std::string* action_value) {
-  DCHECK(headers);
-  size_t iter = 0;
-  std::string value;
-
-  while (headers->EnumerateHeader(&iter, kChromeProxyHeader, &value)) {
-    if (StartsWithActionPrefix(value, action_prefix)) {
-      if (action_value)
-        *action_value = value.substr(action_prefix.size() + 1);
-      return true;
-    }
-  }
-  return false;
-}
-
-}  // namespace
-
-namespace data_reduction_proxy {
-
-const char* chrome_proxy_header() {
-  return kChromeProxyHeader;
-}
-
-int64_t GetDataReductionProxyOFCL(const net::HttpResponseHeaders* headers) {
-  std::string ofcl_str;
-  int64_t ofcl;
-  if (GetDataReductionProxyActionValue(headers, "ofcl", &ofcl_str) &&
-      base::StringToInt64(ofcl_str, &ofcl) && ofcl >= 0) {
-    return ofcl;
-  }
-  return -1;
-}
-
-double EstimateCompressionRatioFromHeaders(
-    const network::mojom::URLResponseHead* response_head) {
-  if (!response_head->network_accessed || !response_head->headers ||
-      response_head->headers->GetContentLength() <= 0 ||
-      response_head->proxy_server.is_direct()) {
-    return 1.0;  // No compression
-  }
-
-  int64_t original_content_length =
-      GetDataReductionProxyOFCL(response_head->headers.get());
-  if (original_content_length > 0) {
-    return static_cast<double>(original_content_length) /
-           static_cast<double>(response_head->headers->GetContentLength());
-  }
-  return 1.0;  // No compression
-}
-
-}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
deleted file mode 100644
index cf3f26e..0000000
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
+++ /dev/null
@@ -1,39 +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 COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_HEADERS_H_
-#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_HEADERS_H_
-
-#include "base/strings/string_piece.h"
-#include "net/http/http_request_headers.h"
-#include "net/http/http_response_headers.h"
-#include "net/proxy_resolution/proxy_resolution_service.h"
-#include "services/network/public/mojom/url_response_head.mojom-forward.h"
-#include "url/gurl.h"
-
-namespace net {
-class HttpResponseHeaders;
-}  // namespace net
-
-namespace data_reduction_proxy {
-
-// Gets the header used for data reduction proxy requests and responses.
-const char* chrome_proxy_header();
-
-// Returns the Original-Full-Content-Length(OFCL) value in the Chrome-Proxy
-// header. Returns -1 in case of of error or if OFCL does not exist. |headers|
-// must be non-null.
-int64_t GetDataReductionProxyOFCL(const net::HttpResponseHeaders* headers);
-
-// Returns an estimate of the compression ratio from the Content-Length and
-// Chrome-Proxy Original-Full-Content-Length(OFCL) response headers. These may
-// not be populated for responses which are streamed from the origin which will
-// be treated as a no compression case. Notably, only the response body size is
-// used to compute the ratio, and headers are excluded, since this is only an
-// estimate for response that is beginning to arrive.
-double EstimateCompressionRatioFromHeaders(
-    const network::mojom::URLResponseHead* response_head);
-
-}  // namespace data_reduction_proxy
-#endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_HEADERS_H_
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc
index bc0d21eb..3448abf 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc
@@ -9,21 +9,6 @@
 namespace data_reduction_proxy {
 namespace prefs {
 
-// An int64_t pref that contains an internal representation of midnight on the
-// date of the last update to |kDailyHttp{Original,Received}ContentLength|.
-const char kDailyHttpContentLengthLastUpdateDate[] =
-    "data_reduction.last_update_date";
-
-// A List pref that contains daily totals of the original size of all HTTP/HTTPS
-// content received from the network.
-const char kDailyHttpOriginalContentLength[] =
-    "data_reduction.daily_original_length";
-
-// A List pref that contains daily totals of the size of all HTTP/HTTPS content
-// received from the network.
-const char kDailyHttpReceivedContentLength[] =
-    "data_reduction.daily_received_length";
-
 // A boolean specifying whether the DataSaver feature is enabled for this
 // client. Note that this preference key name is a legacy string for the sdpy
 // proxy.
@@ -33,9 +18,6 @@
 // consult the OWNERS.
 const char kDataSaverEnabled[] = "spdy_proxy.enabled";
 
-// A boolean specifying whether data usage should be collected for reporting.
-const char kDataUsageReportingEnabled[] = "data_usage_reporting.enabled";
-
 // A boolean specifying whether the data reduction proxy was ever enabled
 // before.
 const char kDataReductionProxyWasEnabledBefore[] =
@@ -47,35 +29,5 @@
 const char kDataReductionProxyLastEnabledTime[] =
     "data_reduction.last_enabled_time";
 
-// An int64_t pref that contains the total size of all HTTP content received
-// from the network.
-const char kHttpReceivedContentLength[] = "http_received_content_length";
-
-// An int64_t pref that contains the total original size of all HTTP content
-// received over the network.
-const char kHttpOriginalContentLength[] = "http_original_content_length";
-
-// An integer pref that stores the number of the week when the weekly data use
-// prefs were updated.
-const char kThisWeekNumber[] = "data_reduction.this_week_number";
-
-// Dictionary pref that stores the data use of services. The key will be the
-// service hash code, and the value will be the KB that service used.
-const char kThisWeekServicesDownstreamBackgroundKB[] =
-    "data_reduction.this_week_services_downstream_background_kb";
-const char kThisWeekServicesDownstreamForegroundKB[] =
-    "data_reduction.this_week_services_downstream_foreground_kb";
-const char kLastWeekServicesDownstreamBackgroundKB[] =
-    "data_reduction.last_week_services_downstream_background_kb";
-const char kLastWeekServicesDownstreamForegroundKB[] =
-    "data_reduction.last_week_services_downstream_foreground_kb";
-
-// Dictionary pref that stores the content-type of user-initiated traffic. The
-// key will be the content-type, and the value will be the data usage in KB.
-const char kThisWeekUserTrafficContentTypeDownstreamKB[] =
-    "data_reduction.this_week_user_traffic_contenttype_downstream_kb";
-const char kLastWeekUserTrafficContentTypeDownstreamKB[] =
-    "data_reduction.last_week_user_traffic_contenttype_downstream_kb";
-
 }  // namespace prefs
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h
index 7b54603..50bc5f1 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h
@@ -11,24 +11,9 @@
 // Alphabetical list of preference names specific to the data_reduction_proxy
 // component. Keep alphabetized, and document each in the .cc file.
 
-extern const char kDailyHttpContentLengthLastUpdateDate[];
-extern const char kDailyHttpOriginalContentLength[];
-extern const char kDailyHttpReceivedContentLength[];
-
 extern const char kDataSaverEnabled[];
-extern const char kDataUsageReportingEnabled[];
 extern const char kDataReductionProxyWasEnabledBefore[];
 extern const char kDataReductionProxyLastEnabledTime[];
-extern const char kHttpOriginalContentLength[];
-extern const char kHttpReceivedContentLength[];
-
-extern const char kThisWeekNumber[];
-extern const char kThisWeekServicesDownstreamBackgroundKB[];
-extern const char kThisWeekServicesDownstreamForegroundKB[];
-extern const char kLastWeekServicesDownstreamBackgroundKB[];
-extern const char kLastWeekServicesDownstreamForegroundKB[];
-extern const char kThisWeekUserTrafficContentTypeDownstreamKB[];
-extern const char kLastWeekUserTrafficContentTypeDownstreamKB[];
 
 }  // namespace prefs
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
index 49d7f6d..e853209 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
@@ -10,14 +10,5 @@
 // Enable the data reduction proxy.
 const char kEnableDataReductionProxy[] = "enable-spdy-proxy-auth";
 
-// Enables a 1 MB savings promo for the data reduction proxy.
-const char kEnableDataReductionProxySavingsPromo[] =
-    "enable-data-reduction-proxy-savings-promo";
-
-// Override the one-time InfoBar to not needed to be shown before triggering
-// https image compression for the page load.
-const char kOverrideHttpsImageCompressionInfobar[] =
-    "override-https-image-compression-infobar";
-
 }  // namespace switches
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
index ea977b3..51e1ce9 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
@@ -12,8 +12,6 @@
 // alongside the definition of their values in the .cc file.
 
 extern const char kEnableDataReductionProxy[];
-extern const char kEnableDataReductionProxySavingsPromo[];
-extern const char kOverrideHttpsImageCompressionInfobar[];
 
 }  // namespace switches
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/version.h.in b/components/data_reduction_proxy/core/common/version.h.in
deleted file mode 100644
index 24772b4..0000000
--- a/components/data_reduction_proxy/core/common/version.h.in
+++ /dev/null
@@ -1,12 +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.
-
-// version.h is generated from version.h.in.  Edit the source!
-
-#ifndef DATA_REDUCTION_PROXY_CORE_COMMON_VERSION_INFO_H_
-#define DATA_REDUCTION_PROXY_CORE_COMMON_VERSION_INFO_H_
-
-#define PRODUCT_VERSION "@VERSION_FULL@"
-
-#endif  // DATA_REDUCTION_PROXY_CORE_COMMON_VERSION_INFO_H_
diff --git a/components/data_reduction_proxy/proto/BUILD.gn b/components/data_reduction_proxy/proto/BUILD.gn
deleted file mode 100644
index 2d5b4e2..0000000
--- a/components/data_reduction_proxy/proto/BUILD.gn
+++ /dev/null
@@ -1,9 +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.
-
-import("//third_party/protobuf/proto_library.gni")
-
-proto_library("data_reduction_proxy_proto") {
-  sources = [ "data_store.proto" ]
-}
diff --git a/components/data_reduction_proxy/proto/data_store.proto b/components/data_reduction_proxy/proto/data_store.proto
deleted file mode 100644
index 0c67b97..0000000
--- a/components/data_reduction_proxy/proto/data_store.proto
+++ /dev/null
@@ -1,41 +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.
-//
-// Protocol buffer definitions for Data Reduction Proxy data stored in LevelDB.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package data_reduction_proxy;
-
-// Contains data usage for an interval of time.
-message DataUsageBucket {
-  repeated PerConnectionDataUsage connection_usage = 1;
-
-  // Timestamp of the last update that was included in this bucket.
-  optional int64 last_updated_timestamp = 2;
-
-  // True if there was an error while parsing this from disk.
-  optional bool had_read_error = 3;
-}
-
-message PerConnectionDataUsage {
-  repeated PerSiteDataUsage site_usage = 1;
-}
-
-// Data usage for a specific site.
-message PerSiteDataUsage {
-  // Full hostname of the site without scheme, port, and trailing slashes.
-  // Eg: For page "http://www.finance.google.com/index.html?a=b", hostname will
-  // be "www.finance.google.com".
-  required string hostname = 1;
-
-  // Total data used in bytes when browsing this site.
-  required int64 data_used = 2;
-
-  // Amount of data that would have been used to browse this site without
-  // employing any data saving techniques.
-  required int64 original_size = 3;
-}
diff --git a/components/data_use_measurement/DIR_METADATA b/components/data_use_measurement/DIR_METADATA
deleted file mode 100644
index 3d3ad0779..0000000
--- a/components/data_use_measurement/DIR_METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-monorail {
-  component: "Internals>Network>DataUse"
-}
diff --git a/components/data_use_measurement/OWNERS b/components/data_use_measurement/OWNERS
deleted file mode 100644
index 2783dea..0000000
--- a/components/data_use_measurement/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file://components/data_reduction_proxy/OWNERS
diff --git a/components/data_use_measurement/core/BUILD.gn b/components/data_use_measurement/core/BUILD.gn
deleted file mode 100644
index 775b77a..0000000
--- a/components/data_use_measurement/core/BUILD.gn
+++ /dev/null
@@ -1,52 +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.
-
-static_library("core") {
-  sources = [
-    "data_use_user_data.cc",
-    "data_use_user_data.h",
-  ]
-  deps = [
-    "//base",
-    "//net",
-  ]
-}
-
-static_library("ascriber") {
-  sources = [
-    "data_use.cc",
-    "data_use.h",
-    "data_use_measurement.cc",
-    "data_use_measurement.h",
-    "data_use_pref_names.h",
-    "data_use_tracker_prefs.cc",
-    "data_use_tracker_prefs.h",
-  ]
-  deps = [
-    ":core",
-    "//base",
-    "//components/metrics",
-    "//components/prefs",
-    "//net",
-    "//services/network/public/cpp:cpp",
-  ]
-}
-
-source_set("unit_tests") {
-  sources = [
-    "data_use_measurement_unittest.cc",
-    "data_use_tracker_prefs_unittest.cc",
-  ]
-  testonly = true
-  deps = [
-    ":ascriber",
-    ":core",
-    "//base/test:test_support",
-    "//components/metrics:metrics",
-    "//components/prefs:test_support",
-    "//net:test_support",
-    "//services/network:test_support",
-    "//testing/gtest",
-  ]
-}
diff --git a/components/data_use_measurement/core/DEPS b/components/data_use_measurement/core/DEPS
deleted file mode 100644
index c620476..0000000
--- a/components/data_use_measurement/core/DEPS
+++ /dev/null
@@ -1,7 +0,0 @@
-include_rules = [
-  "+net",
-  "+components/metrics",
-  "+components/prefs",
-  "+services/network/public/cpp",
-  "+services/network/test",
-]
diff --git a/components/data_use_measurement/core/data_use.cc b/components/data_use_measurement/core/data_use.cc
deleted file mode 100644
index 8750f45..0000000
--- a/components/data_use_measurement/core/data_use.cc
+++ /dev/null
@@ -1,23 +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 "components/data_use_measurement/core/data_use.h"
-
-namespace data_use_measurement {
-
-DataUse::DataUse(TrafficType traffic_type)
-    : traffic_type_(traffic_type),
-      total_bytes_sent_(0),
-      total_bytes_received_(0) {}
-
-DataUse::~DataUse() {}
-
-void DataUse::IncrementTotalBytes(int64_t bytes_received, int64_t bytes_sent) {
-  total_bytes_received_ += bytes_received;
-  total_bytes_sent_ += bytes_sent;
-  DCHECK_LE(0, total_bytes_received_);
-  DCHECK_LE(0, total_bytes_sent_);
-}
-
-}  // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use.h b/components/data_use_measurement/core/data_use.h
deleted file mode 100644
index ef6c1934..0000000
--- a/components/data_use_measurement/core/data_use.h
+++ /dev/null
@@ -1,77 +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 COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_H_
-#define COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_H_
-
-#include <stdint.h>
-
-#include <string>
-
-#include "base/supports_user_data.h"
-#include "url/gurl.h"
-
-namespace data_use_measurement {
-
-// Class to store total network data used by some entity.
-class DataUse : public base::SupportsUserData {
- public:
-  enum class TrafficType {
-    // Unknown type. URLRequests for arbitrary scheme such as blob, file,
-    // extensions, chrome URLs fall under this bucket - url/url_constants.cc
-    // TODO(rajendrant): Record metrics on the distribution of these type. It is
-    // also possible to remove this UNKNOWN type altogether by skipping the URL
-    // schemes that do not make use of network.
-    UNKNOWN,
-
-    // User initiated traffic.
-    USER_TRAFFIC,
-
-    // Chrome services.
-    SERVICES,
-
-    // Fetch from ServiceWorker.
-    SERVICE_WORKER,
-  };
-
-  explicit DataUse(TrafficType traffic_type);
-
-  DataUse(const DataUse&) = delete;
-  DataUse& operator=(const DataUse&) = delete;
-
-  ~DataUse() override;
-
-  // Returns the page URL.
-  const GURL& url() const { return url_; }
-
-  void set_url(const GURL& url) { url_ = url; }
-
-  const std::string& description() const { return description_; }
-
-  void set_description(const std::string& description) {
-    description_ = description;
-  }
-
-  // Increments the total received and sent byte counts. Can be used to
-  // decrement the byte counts as well.
-  void IncrementTotalBytes(int64_t bytes_received, int64_t bytes_sent);
-
-  int64_t total_bytes_received() const { return total_bytes_received_; }
-
-  int64_t total_bytes_sent() const { return total_bytes_sent_; }
-
-  TrafficType traffic_type() const { return traffic_type_; }
-
- private:
-  GURL url_;
-  std::string description_;
-  const TrafficType traffic_type_;
-
-  int64_t total_bytes_sent_;
-  int64_t total_bytes_received_;
-};
-
-}  // namespace data_use_measurement
-
-#endif  // COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_H_
diff --git a/components/data_use_measurement/core/data_use_measurement.cc b/components/data_use_measurement/core/data_use_measurement.cc
deleted file mode 100644
index 873c4ab0..0000000
--- a/components/data_use_measurement/core/data_use_measurement.cc
+++ /dev/null
@@ -1,380 +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 "components/data_use_measurement/core/data_use_measurement.h"
-
-#include <set>
-
-#include "base/bind.h"
-#include "base/feature_list.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/clock.h"
-#include "base/time/default_clock.h"
-#include "build/build_config.h"
-#include "components/data_use_measurement/core/data_use_user_data.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/network/public/cpp/features.h"
-
-#if BUILDFLAG(IS_ANDROID)
-#include "net/android/traffic_stats.h"
-#endif
-
-namespace data_use_measurement {
-
-namespace {
-
-#if BUILDFLAG(IS_ANDROID)
-bool IsInForeground(base::android::ApplicationState state) {
-  switch (state) {
-    case base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES:
-      return true;
-    case base::android::APPLICATION_STATE_UNKNOWN:
-    case base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES:
-    case base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES:
-    case base::android::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES:
-      return false;
-  }
-}
-#endif
-
-// Records the occurrence of |sample| in |name| histogram. Conventional UMA
-// histograms are not used because the |name| is not static.
-void RecordUMAHistogramCount(const std::string& name, int64_t sample) {
-  base::HistogramBase* histogram_pointer = base::Histogram::FactoryGet(
-      name,
-      1,        // Minimum sample size in bytes.
-      1000000,  // Maximum sample size in bytes. Should cover most of the
-                // requests by services.
-      50,       // Bucket count.
-      base::HistogramBase::kUmaTargetedHistogramFlag);
-  histogram_pointer->Add(sample);
-}
-
-}  // namespace
-
-DataUseMeasurement::DataUseMeasurement(
-    PrefService* pref_service,
-    network::NetworkConnectionTracker* network_connection_tracker)
-    : network_connection_tracker_(network_connection_tracker),
-      data_use_tracker_prefs_(base::DefaultClock::GetInstance(), pref_service) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(network_connection_tracker_);
-
-#if BUILDFLAG(IS_ANDROID)
-  int64_t bytes = 0;
-  // Query Android traffic stats.
-  if (net::android::traffic_stats::GetCurrentUidRxBytes(&bytes))
-    rx_bytes_os_ = bytes;
-
-  if (net::android::traffic_stats::GetCurrentUidTxBytes(&bytes))
-    tx_bytes_os_ = bytes;
-#endif
-
-  network_connection_tracker_->AddLeakyNetworkConnectionObserver(this);
-
-  network_connection_tracker_->GetConnectionType(
-      &connection_type_,
-      base::BindOnce(&DataUseMeasurement::OnConnectionChanged,
-                     weak_ptr_factory_.GetWeakPtr()));
-
-#if BUILDFLAG(IS_ANDROID)
-  app_state_ = base::android::ApplicationStatusListener::GetState();
-
-  app_listener_ = base::android::ApplicationStatusListener::New(
-      base::BindRepeating(&DataUseMeasurement::OnApplicationStateChange,
-                          base::Unretained(this)));
-#endif
-}
-
-DataUseMeasurement::~DataUseMeasurement() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-#if BUILDFLAG(IS_ANDROID)
-  if (app_listener_)
-    app_listener_.reset();
-#endif
-  network_connection_tracker_->RemoveNetworkConnectionObserver(this);
-  DCHECK(services_data_use_observer_list_.empty());
-}
-
-void DataUseMeasurement::RecordDownstreamUserTrafficSizeMetric(
-    bool is_tab_visible,
-    int64_t bytes) {
-  RecordUMAHistogramCount(
-      GetHistogramName("DataUse.TrafficSize.User", DOWNSTREAM,
-                       CurrentAppState(), IsCurrentNetworkCellular()),
-      bytes);
-  RecordTabStateHistogram(DOWNSTREAM, CurrentAppState(), is_tab_visible, bytes);
-  bytes_transferred_since_last_traffic_stats_query_ += bytes;
-  MaybeRecordNetworkBytesOS(/*force_record_metrics=*/false);
-
-  data_use_tracker_prefs_.ReportNetworkServiceDataUse(
-      IsCurrentNetworkCellular(),
-      CurrentAppState() == DataUseUserData::FOREGROUND,
-      /*is_user_traffic=*/true, bytes);
-}
-
-#if BUILDFLAG(IS_ANDROID)
-void DataUseMeasurement::OnApplicationStateChangeForTesting(
-    base::android::ApplicationState application_state) {
-  OnApplicationStateChange(application_state);
-}
-#endif
-
-DataUseUserData::AppState DataUseMeasurement::CurrentAppState() const {
-#if BUILDFLAG(IS_ANDROID)
-  return IsInForeground(app_state_) ? DataUseUserData::FOREGROUND
-                                    : DataUseUserData::BACKGROUND;
-#else
-  // If the OS is not Android, all the requests are considered Foreground.
-  return DataUseUserData::FOREGROUND;
-#endif
-}
-
-// static
-std::string DataUseMeasurement::GetHistogramNameWithConnectionType(
-    const char* prefix,
-    TrafficDirection dir,
-    DataUseUserData::AppState app_state) {
-  return base::StringPrintf(
-      "%s.%s.%s", prefix, dir == UPSTREAM ? "Upstream" : "Downstream",
-      app_state == DataUseUserData::UNKNOWN
-          ? "Unknown"
-          : (app_state == DataUseUserData::FOREGROUND ? "Foreground"
-                                                      : "Background"));
-}
-
-// static
-std::string DataUseMeasurement::GetHistogramName(
-    const char* prefix,
-    TrafficDirection dir,
-    DataUseUserData::AppState app_state,
-    bool is_connection_cellular) {
-  return base::StringPrintf(
-      "%s.%s.%s.%s", prefix, dir == UPSTREAM ? "Upstream" : "Downstream",
-      app_state == DataUseUserData::UNKNOWN
-          ? "Unknown"
-          : (app_state == DataUseUserData::FOREGROUND ? "Foreground"
-                                                      : "Background"),
-      is_connection_cellular ? "Cellular" : "NotCellular");
-}
-
-#if BUILDFLAG(IS_ANDROID)
-void DataUseMeasurement::OnApplicationStateChange(
-    base::android::ApplicationState application_state) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (app_state_ == application_state)
-    return;
-  MaybeRecordNetworkBytesOS(/*force_record_metrics=*/true);
-  app_state_ = application_state;
-}
-#endif
-
-void DataUseMeasurement::MaybeRecordNetworkBytesOS(bool force_record_metrics) {
-#if BUILDFLAG(IS_ANDROID)
-  // Minimum number of bytes that should be reported by the network delegate
-  // before Android's TrafficStats API is queried (if Chrome is not in
-  // background). This reduces the overhead of repeatedly calling the API.
-  static const int64_t kMinDelegateBytes = 25000;
-
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!force_record_metrics &&
-      bytes_transferred_since_last_traffic_stats_query_ < kMinDelegateBytes &&
-      CurrentAppState() == DataUseUserData::FOREGROUND) {
-    return;
-  }
-  bytes_transferred_since_last_traffic_stats_query_ = 0;
-  int64_t bytes = 0;
-  // Query Android traffic stats directly instead of registering with the
-  // DataUseAggregator since the latter does not provide notifications for
-  // the incognito traffic.
-  if (net::android::traffic_stats::GetCurrentUidRxBytes(&bytes)) {
-    if (rx_bytes_os_ != 0) {
-      DCHECK_GE(bytes, rx_bytes_os_);
-      if (bytes > rx_bytes_os_) {
-        int64_t incremental_bytes = bytes - rx_bytes_os_;
-        // Do not record samples with value 0.
-        base::UmaHistogramCustomCounts("DataUse.BytesReceived2.OS",
-                                       incremental_bytes, 50, 10 * 1000 * 1000,
-                                       50);
-        if (IsInForeground(app_state_)) {
-          base::UmaHistogramCustomCounts("DataUse.BytesReceived2.OS.Foreground",
-                                         incremental_bytes, 50,
-                                         10 * 1000 * 1000, 50);
-        } else {
-          base::UmaHistogramCustomCounts("DataUse.BytesReceived2.OS.Background",
-                                         incremental_bytes, 50,
-                                         10 * 1000 * 1000, 50);
-        }
-      }
-    }
-    rx_bytes_os_ = bytes;
-  }
-
-  if (net::android::traffic_stats::GetCurrentUidTxBytes(&bytes)) {
-    if (tx_bytes_os_ != 0) {
-      DCHECK_GE(bytes, tx_bytes_os_);
-      if (bytes > tx_bytes_os_) {
-        int64_t incremental_bytes = bytes - tx_bytes_os_;
-        // Do not record samples with value 0.
-        UMA_HISTOGRAM_COUNTS_1M("DataUse.BytesSent.OS", incremental_bytes);
-        if (IsInForeground(app_state_)) {
-          UMA_HISTOGRAM_COUNTS_1M("DataUse.BytesSent.OS.Foreground",
-                                  incremental_bytes);
-        } else {
-          UMA_HISTOGRAM_COUNTS_1M("DataUse.BytesSent.OS.Background",
-                                  incremental_bytes);
-        }
-      }
-    }
-    tx_bytes_os_ = bytes;
-  }
-#endif
-}
-
-void DataUseMeasurement::ReportDataUsageServices(
-    int32_t traffic_annotation_hash,
-    TrafficDirection dir,
-    DataUseUserData::AppState app_state,
-    int64_t message_size_bytes) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (message_size_bytes <= 0)
-    return;
-
-  // Conventional UMA histograms are not used because name is not static.
-  base::HistogramBase* histogram = base::SparseHistogram::FactoryGet(
-      GetHistogramNameWithConnectionType("DataUse.AllServicesKB", dir,
-                                         app_state),
-      base::HistogramBase::kUmaTargetedHistogramFlag);
-  // AddKiB method takes value in bytes.
-  histogram->AddKiB(traffic_annotation_hash,
-                    base::saturated_cast<int>(message_size_bytes));
-
-  bytes_transferred_since_last_traffic_stats_query_ += message_size_bytes;
-  MaybeRecordNetworkBytesOS(/*force_record_metrics=*/false);
-
-  data_use_tracker_prefs_.ReportNetworkServiceDataUse(
-      IsCurrentNetworkCellular(),
-      CurrentAppState() == DataUseUserData::FOREGROUND,
-      /*is_user_traffic=*/false, message_size_bytes);
-}
-
-void DataUseMeasurement::RecordTabStateHistogram(
-    TrafficDirection dir,
-    DataUseUserData::AppState app_state,
-    bool is_tab_visible,
-    int64_t bytes) const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (app_state == DataUseUserData::UNKNOWN)
-    return;
-
-  std::string histogram_name = "DataUse.AppTabState.";
-  histogram_name.append(dir == UPSTREAM ? "Upstream." : "Downstream.");
-  if (app_state == DataUseUserData::BACKGROUND) {
-    histogram_name.append("AppBackground");
-  } else if (is_tab_visible) {
-    histogram_name.append("AppForeground.TabForeground");
-  } else {
-    histogram_name.append("AppForeground.TabBackground");
-  }
-  RecordUMAHistogramCount(histogram_name, bytes);
-}
-
-// static
-bool DataUseMeasurement::IsUserRequest(
-    int32_t network_traffic_annotation_hash_id) {
-  static const std::set<int32_t> kUserInitiatedTrafficAnnotations = {
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(
-          "blink_extension_resource_loader"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("blink_resource_loader"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("parallel_download_job"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("renderer_initiated_download"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("drag_download_file"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(
-          "download_web_contents_frame"), /*save page action*/
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(
-          "render_view_context_menu"), /* save link as*/
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("webstore_installer"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("pdf_plugin_placeholder"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(
-          "downloads_api_run_async"), /* Can be user request or
-                                         autonomous request from extensions*/
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("resource_dispatcher_host"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("navigation_url_loader"),
-  };
-  return kUserInitiatedTrafficAnnotations.find(
-             network_traffic_annotation_hash_id) !=
-         kUserInitiatedTrafficAnnotations.end();
-}
-
-// static
-bool DataUseMeasurement::IsUserDownloadsRequest(
-    int32_t network_traffic_annotation_hash_id) {
-  static const std::set<int32_t> kUserDownloadsTrafficAnnotations = {
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("parallel_download_job"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("renderer_initiated_download"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("drag_download_file"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("download_web_contents_frame"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("downloads_api_run_async"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("resumed_downloads"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("download_via_context_menu"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("offline_pages_download_file"),
-  };
-  return kUserDownloadsTrafficAnnotations.find(
-             network_traffic_annotation_hash_id) !=
-         kUserDownloadsTrafficAnnotations.end();
-}
-
-// static
-bool DataUseMeasurement::IsMetricsServiceRequest(
-    int32_t network_traffic_annotation_hash_id) {
-  static const std::set<int32_t> kMetricsServiceTrafficAnnotations = {
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("metrics_report_uma"),
-      COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("metrics_report_ukm"),
-  };
-  return kMetricsServiceTrafficAnnotations.find(
-             network_traffic_annotation_hash_id) !=
-         kMetricsServiceTrafficAnnotations.end();
-}
-
-bool DataUseMeasurement::IsCurrentNetworkCellular() const {
-  return network::NetworkConnectionTracker::IsConnectionCellular(
-      connection_type_);
-}
-
-void DataUseMeasurement::OnConnectionChanged(
-    network::mojom::ConnectionType type) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (connection_type_ != network::mojom::ConnectionType::CONNECTION_UNKNOWN)
-    MaybeRecordNetworkBytesOS(/*force_record_metrics=*/true);
-
-  connection_type_ = type;
-}
-
-void DataUseMeasurement::AddServicesDataUseObserver(
-    ServicesDataUseObserver* observer) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  services_data_use_observer_list_.AddObserver(observer);
-}
-
-void DataUseMeasurement::RemoveServicesDataUseObserver(
-    ServicesDataUseObserver* observer) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  services_data_use_observer_list_.RemoveObserver(observer);
-}
-
-// static
-void DataUseMeasurement::RegisterDataUseComponentLocalStatePrefs(
-    PrefRegistrySimple* registry) {
-  DataUseTrackerPrefs::RegisterDataUseTrackerLocalStatePrefs(registry);
-}
-
-}  // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use_measurement.h b/components/data_use_measurement/core/data_use_measurement.h
deleted file mode 100644
index fa36dfc..0000000
--- a/components/data_use_measurement/core/data_use_measurement.h
+++ /dev/null
@@ -1,202 +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 COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_MEASUREMENT_H_
-#define COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_MEASUREMENT_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-
-#include "base/callback.h"
-#include "base/memory/raw_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/observer_list.h"
-#include "base/sequence_checker.h"
-#include "build/build_config.h"
-#include "components/data_use_measurement/core/data_use_tracker_prefs.h"
-#include "components/data_use_measurement/core/data_use_user_data.h"
-#include "services/network/public/cpp/network_connection_tracker.h"
-
-#if BUILDFLAG(IS_ANDROID)
-#include "base/android/application_status_listener.h"
-#endif
-
-class PrefService;
-
-namespace data_use_measurement {
-
-// Records the data use of user traffic and various services in UMA histograms.
-// The UMA is broken down by network technology used (Wi-Fi vs cellular). On
-// Android, the UMA is further broken down by whether the application was in the
-// background or foreground during the request.
-// TODO(amohammadkhan): Complete the layered architecture.
-// http://crbug.com/527460
-class DataUseMeasurement
-    : public network::NetworkConnectionTracker::NetworkConnectionObserver {
- public:
-  class ServicesDataUseObserver {
-   public:
-    // Called when services data use is reported.
-    virtual void OnServicesDataUse(int32_t service_hash_code,
-                                   int64_t recv_bytes,
-                                   int64_t sent_bytes) = 0;
-  };
-
-  // Returns true if the NTA hash is initiated by user traffic.
-  static bool IsUserRequest(int32_t network_traffic_annotation_hash_id);
-
-  // Returns true if the NTA hash is one used by Chrome downloads.
-  static bool IsUserDownloadsRequest(
-      int32_t network_traffic_annotation_hash_id);
-
-  // Returns true if the NTA hash is one used by metrics (UMA, UKM) component.
-  static bool IsMetricsServiceRequest(
-      int32_t network_traffic_annotation_hash_id);
-
-  // |pref_service| can be used for accessing local state prefs. Can be null.
-  // |network_connection_tracker| is guaranteed to be non-null.
-  DataUseMeasurement(
-      PrefService* pref_service,
-      network::NetworkConnectionTracker* network_connection_tracker);
-
-  DataUseMeasurement(const DataUseMeasurement&) = delete;
-  DataUseMeasurement& operator=(const DataUseMeasurement&) = delete;
-
-  ~DataUseMeasurement() override;
-
-#if BUILDFLAG(IS_ANDROID)
-  // This function should just be used for testing purposes. A change in
-  // application state can be simulated by calling this function.
-  void OnApplicationStateChangeForTesting(
-      base::android::ApplicationState application_state);
-#endif
-
-  void AddServicesDataUseObserver(ServicesDataUseObserver* observer);
-  void RemoveServicesDataUseObserver(ServicesDataUseObserver* observer);
-
-  // Should be called to record downstream data used by user-initiated trafffic
-  // requests. |is_tab_visible| is set to true if the traffic was initiated from
-  // a tab that was visible in foreground when the data use was observed.
-  void RecordDownstreamUserTrafficSizeMetric(bool is_tab_visible,
-                                             int64_t bytes);
-
- protected:
-  // Specifies that data is received or sent, respectively.
-  enum TrafficDirection { DOWNSTREAM, UPSTREAM };
-
-  // Returns the current application state (Foreground or Background). It always
-  // returns Foreground if Chrome is not running on Android.
-  DataUseUserData::AppState CurrentAppState() const;
-
-  // Records data use histograms of services. It gets the size of exchanged
-  // message, its direction (which is upstream or downstream) and reports to the
-  // histogram DataUse.Services.{Dimensions} with, services as the buckets.
-  // |app_state| indicates the app state which can be foreground, or background.
-  void ReportDataUsageServices(int32_t traffic_annotation_hash,
-                               TrafficDirection dir,
-                               DataUseUserData::AppState app_state,
-                               int64_t message_size_bytes);
-
-  // Returns if the current network connection type is cellular.
-  bool IsCurrentNetworkCellular() const;
-
-  static void RegisterDataUseComponentLocalStatePrefs(
-      PrefRegistrySimple* registry);
-
-  base::ObserverList<ServicesDataUseObserver>::Unchecked
-      services_data_use_observer_list_;
-
- private:
-  friend class DataUseMeasurementTest;
-
-  // Records the count of bytes received and sent by Chrome on the network as
-  // reported by the operating system. If |force_record_metrics| is true, the
-  // data use metrics are always recorded. If |force_record_metrics| is false,
-  // data use may be recorded only if it's expected to be high.
-  void MaybeRecordNetworkBytesOS(bool force_record_metrics);
-
-  // Makes the full name of the histogram. It is made from |prefix| and suffix
-  // which is made based on network and application status. suffix is a string
-  // representing whether the data use was on the send ("Upstream") or receive
-  // ("Downstream") path, and whether the app was in the "Foreground" or
-  // "Background".
-  static std::string GetHistogramNameWithConnectionType(
-      const char* prefix,
-      TrafficDirection dir,
-      DataUseUserData::AppState app_state);
-
-  // Makes the full name of the histogram. It is made from |prefix| and suffix
-  // which is made based on network and application status. suffix is a string
-  // representing whether the data use was on the send ("Upstream") or receive
-  // ("Downstream") path, whether the app was in the "Foreground" or
-  // "Background", and whether a "Cellular" or "WiFi" network was use. For
-  // example, "Prefix.Upstream.Foreground.Cellular" is a possible output.
-  // |app_state| indicates the app state which can be foreground, background, or
-  // unknown.
-  static std::string GetHistogramName(const char* prefix,
-                                      TrafficDirection dir,
-                                      DataUseUserData::AppState app_state,
-                                      bool is_connection_cellular);
-
-#if BUILDFLAG(IS_ANDROID)
-  // Called whenever the application transitions from foreground to background
-  // and vice versa.
-  void OnApplicationStateChange(
-      base::android::ApplicationState application_state);
-#endif
-
-  // Records data use histograms split on TrafficDirection, AppState and
-  // TabState.
-  void RecordTabStateHistogram(TrafficDirection dir,
-                               DataUseUserData::AppState app_state,
-                               bool is_tab_visible,
-                               int64_t bytes) const;
-
-  // NetworkConnectionObserver overrides
-  void OnConnectionChanged(
-      network::mojom::ConnectionType connection_type) override;
-
-#if BUILDFLAG(IS_ANDROID)
-  // Application listener store the last known state of the application in this
-  // field.
-  base::android::ApplicationState app_state_ =
-      base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
-
-  // ApplicationStatusListener used to monitor whether the application is in the
-  // foreground or in the background. It is owned by DataUseMeasurement.
-  std::unique_ptr<base::android::ApplicationStatusListener> app_listener_;
-#endif
-
-  // Number of bytes received and sent by Chromium as reported by the operating
-  // system when it was last queried for traffic statistics. Set to 0 if the
-  // operating system was never queried.
-  int64_t rx_bytes_os_ = 0;
-  int64_t tx_bytes_os_ = 0;
-
-  // Watches for network connection changes. Global singleton object and
-  // outlives |this|
-  raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_;
-
-  // The current connection type.
-  network::mojom::ConnectionType connection_type_ =
-      network::mojom::ConnectionType::CONNECTION_UNKNOWN;
-
-  // Number of bytes received and sent by Chromium as reported by the network
-  // delegate since the operating system was last queried for traffic
-  // statistics.
-  int64_t bytes_transferred_since_last_traffic_stats_query_ = 0;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  // Records the data usage in prefs.
-  DataUseTrackerPrefs data_use_tracker_prefs_;
-
-  base::WeakPtrFactory<DataUseMeasurement> weak_ptr_factory_{this};
-};
-
-}  // namespace data_use_measurement
-
-#endif  // COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_MEASUREMENT_H_
diff --git a/components/data_use_measurement/core/data_use_measurement_unittest.cc b/components/data_use_measurement/core/data_use_measurement_unittest.cc
deleted file mode 100644
index ca28b1e5..0000000
--- a/components/data_use_measurement/core/data_use_measurement_unittest.cc
+++ /dev/null
@@ -1,113 +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 "components/data_use_measurement/core/data_use_measurement.h"
-
-#include <memory>
-#include <string>
-
-#include "base/run_loop.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/task_environment.h"
-#include "build/build_config.h"
-#include "components/data_use_measurement/core/data_use_pref_names.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/testing_pref_service.h"
-#include "net/base/network_change_notifier.h"
-#include "services/network/test/test_network_connection_tracker.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if BUILDFLAG(IS_ANDROID)
-#include "base/android/application_status_listener.h"
-#endif
-
-namespace data_use_measurement {
-
-class DataUseMeasurementTest {
- public:
-  explicit DataUseMeasurementTest(TestingPrefServiceSimple* test_prefs_)
-      : data_use_measurement_(
-            test_prefs_,
-            network::TestNetworkConnectionTracker::GetInstance()) {
-    // During the test it is expected to not have cellular connection.
-    DCHECK(!net::NetworkChangeNotifier::IsConnectionCellular(
-        net::NetworkChangeNotifier::GetConnectionType()));
-  }
-
-  DataUseMeasurementTest(const DataUseMeasurementTest&) = delete;
-  DataUseMeasurementTest& operator=(const DataUseMeasurementTest&) = delete;
-
-  // This function makes a user request and confirms that its effect is
-  // reflected in proper histograms.
-  void TestForAUserRequest(const std::string& target_dimension) {
-    base::HistogramTester histogram_tester;
-    data_use_measurement_.RecordDownstreamUserTrafficSizeMetric(
-        true /* is_tab_visible */, 5 /* bytest */);
-    data_use_measurement_.RecordDownstreamUserTrafficSizeMetric(
-        true /* is_tab_visible */, 5 /* bytest */);
-    histogram_tester.ExpectTotalCount("DataUse.TrafficSize.User.Downstream." +
-                                          target_dimension + kConnectionType,
-                                      2);
-  }
-
-
-  DataUseMeasurement* data_use_measurement() { return &data_use_measurement_; }
-
- protected:
-  // Required to register a NetworkConnectionObserver from the constructor of
-  // DataUseMeasurement.
-  base::test::TaskEnvironment task_environment_;
-
-  DataUseMeasurement data_use_measurement_;
-  const std::string kConnectionType = "NotCellular";
-};
-
-// This test function tests recording of data use information in UMA histogram
-// when packet is originated from user or services when the app is in the
-// foreground or the OS is not Android.
-// TODO(amohammadkhan): Add tests for Cellular/non-cellular connection types
-// when support for testing is provided in its class.
-TEST(DataUseMeasurementTest, UserNotUserTest) {
-  TestingPrefServiceSimple test_prefs;
-
-  test_prefs.registry()->RegisterDictionaryPref(prefs::kDataUsedUserForeground);
-  test_prefs.registry()->RegisterDictionaryPref(prefs::kDataUsedUserBackground);
-  test_prefs.registry()->RegisterDictionaryPref(
-      prefs::kDataUsedServicesForeground);
-  test_prefs.registry()->RegisterDictionaryPref(
-      prefs::kDataUsedServicesBackground);
-
-  DataUseMeasurementTest data_use_measurement_test(&test_prefs);
-#if BUILDFLAG(IS_ANDROID)
-  data_use_measurement_test.data_use_measurement()
-      ->OnApplicationStateChangeForTesting(
-          base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES);
-#endif
-  data_use_measurement_test.TestForAUserRequest("Foreground.");
-}
-
-#if BUILDFLAG(IS_ANDROID)
-// This test function tests recording of data use information in UMA histogram
-// when packet is originated from user or services when the app is in the
-// background and OS is Android.
-TEST(DataUseMeasurementTest, ApplicationStateTest) {
-  TestingPrefServiceSimple test_prefs;
-
-  test_prefs.registry()->RegisterDictionaryPref(prefs::kDataUsedUserForeground);
-  test_prefs.registry()->RegisterDictionaryPref(prefs::kDataUsedUserBackground);
-  test_prefs.registry()->RegisterDictionaryPref(
-      prefs::kDataUsedServicesForeground);
-  test_prefs.registry()->RegisterDictionaryPref(
-      prefs::kDataUsedServicesBackground);
-
-  DataUseMeasurementTest data_use_measurement_test(&test_prefs);
-
-  data_use_measurement_test.data_use_measurement()
-      ->OnApplicationStateChangeForTesting(
-          base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES);
-  data_use_measurement_test.TestForAUserRequest("Background.");
-}
-#endif
-
-}  // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use_pref_names.h b/components/data_use_measurement/core/data_use_pref_names.h
deleted file mode 100644
index ef74cb3..0000000
--- a/components/data_use_measurement/core/data_use_pref_names.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2020 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 COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_PREF_NAMES_H_
-#define COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_PREF_NAMES_H_
-
-namespace data_use_measurement {
-
-namespace prefs {
-// Dictionary prefs for measuring cellular data used. |key| is
-// the date of data usage (stored as string using exploded format). |value|
-// stores the data used for that date as a double in kilobytes.
-const char kDataUsedUserForeground[] =
-    "data_use_measurement.data_used.user.foreground";
-const char kDataUsedUserBackground[] =
-    "data_use_measurement.data_used.user.background";
-const char kDataUsedServicesForeground[] =
-    "data_use_measurement.data_used.services.foreground";
-const char kDataUsedServicesBackground[] =
-    "data_use_measurement.data_used.services.background";
-}  // namespace prefs
-
-}  // namespace data_use_measurement
-
-#endif  // COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_PREF_NAMES_H_
diff --git a/components/data_use_measurement/core/data_use_tracker_prefs.cc b/components/data_use_measurement/core/data_use_tracker_prefs.cc
deleted file mode 100644
index a7fa288..0000000
--- a/components/data_use_measurement/core/data_use_tracker_prefs.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2020 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 "components/data_use_measurement/core/data_use_tracker_prefs.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/callback_helpers.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/strings/stringprintf.h"
-#include "base/task/post_task.h"
-#include "base/task/task_traits.h"
-#include "base/time/clock.h"
-#include "base/time/time.h"
-#include "base/values.h"
-#include "build/build_config.h"
-#include "components/data_use_measurement/core/data_use_pref_names.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/scoped_user_pref_update.h"
-
-namespace data_use_measurement {
-
-DataUseTrackerPrefs::DataUseTrackerPrefs(const base::Clock* time_clock,
-                                         PrefService* pref_service)
-    : time_clock_(time_clock), pref_service_(pref_service) {
-  DCHECK(time_clock_);
-
-  RemoveExpiredEntriesForPref(prefs::kDataUsedUserForeground);
-  RemoveExpiredEntriesForPref(prefs::kDataUsedUserBackground);
-  RemoveExpiredEntriesForPref(prefs::kDataUsedServicesForeground);
-  RemoveExpiredEntriesForPref(prefs::kDataUsedServicesBackground);
-}
-
-void DataUseTrackerPrefs::ReportNetworkServiceDataUse(
-    bool is_metered_connection,
-    bool is_app_foreground,
-    bool is_user_traffic,
-    int64_t sent_or_recv_bytes) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (!is_metered_connection)
-    return;
-
-  if (sent_or_recv_bytes <= 0)
-    return;
-
-  if (is_user_traffic && is_app_foreground) {
-    UpdateUsagePref(prefs::kDataUsedUserForeground, sent_or_recv_bytes);
-  } else if (is_user_traffic && !is_app_foreground) {
-    UpdateUsagePref(prefs::kDataUsedUserBackground, sent_or_recv_bytes);
-  } else if (!is_user_traffic && is_app_foreground) {
-    UpdateUsagePref(prefs::kDataUsedServicesForeground, sent_or_recv_bytes);
-  } else {
-    UpdateUsagePref(prefs::kDataUsedServicesBackground, sent_or_recv_bytes);
-  }
-}
-
-base::Time DataUseTrackerPrefs::GetCurrentMeasurementDate() const {
-  return time_clock_->Now().LocalMidnight();
-}
-
-void DataUseTrackerPrefs::RemoveExpiredEntriesForPref(
-    const std::string& pref_name) {
-  if (!pref_service_)
-    return;
-
-  const base::Value* user_pref_dict = pref_service_->GetDictionary(pref_name);
-  const base::Time current_date = GetCurrentMeasurementDate();
-  const base::Time last_date = current_date - base::Days(60);
-
-  base::DictionaryValue user_pref_new_dict;
-  for (auto it : user_pref_dict->DictItems()) {
-    base::Time key_date;
-    if (base::Time::FromUTCString(it.first.c_str(), &key_date) &&
-        key_date > last_date) {
-      user_pref_new_dict.Set(it.first,
-                             base::Value::ToUniquePtrValue(it.second.Clone()));
-    }
-  }
-  pref_service_->Set(pref_name, user_pref_new_dict);
-}
-
-std::string DataUseTrackerPrefs::GetCurrentMeasurementDateAsString() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  base::Time::Exploded today_exploded;
-  GetCurrentMeasurementDate().LocalExplode(&today_exploded);
-  std::string date =
-      base::StringPrintf("%04d-%02d-%02d", today_exploded.year,
-                         today_exploded.month, today_exploded.day_of_month);
-  return date;
-}
-
-void DataUseTrackerPrefs::UpdateUsagePref(const std::string& pref_name,
-                                          int64_t message_size_bytes) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (!pref_service_)
-    return;
-
-  DictionaryPrefUpdate pref_updater(pref_service_, pref_name);
-  std::string todays_key = GetCurrentMeasurementDateAsString();
-
-  const base::Value* user_pref_dict = pref_service_->GetDictionary(pref_name);
-  double todays_traffic = user_pref_dict->FindDoubleKey(todays_key).value_or(0);
-  pref_updater->SetDoubleKey(
-      todays_key,
-      todays_traffic + (static_cast<double>(message_size_bytes) / 1024.0));
-}
-
-// static
-void DataUseTrackerPrefs::RegisterDataUseTrackerLocalStatePrefs(
-    PrefRegistrySimple* registry) {
-  registry->RegisterDictionaryPref(prefs::kDataUsedUserForeground,
-                                   PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(prefs::kDataUsedUserBackground,
-                                   PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(prefs::kDataUsedServicesForeground,
-                                   PrefRegistry::LOSSY_PREF);
-  registry->RegisterDictionaryPref(prefs::kDataUsedServicesBackground,
-                                   PrefRegistry::LOSSY_PREF);
-}
-
-}  // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use_tracker_prefs.h b/components/data_use_measurement/core/data_use_tracker_prefs.h
deleted file mode 100644
index f0bd3a9..0000000
--- a/components/data_use_measurement/core/data_use_tracker_prefs.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2020 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 COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_TRACKER_PREFS_H_
-#define COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_TRACKER_PREFS_H_
-
-#include <memory>
-
-#include "base/memory/raw_ptr.h"
-#include "base/sequence_checker.h"
-#include "base/time/clock.h"
-#include "base/time/time.h"
-
-class PrefRegistrySimple;
-class PrefService;
-
-namespace data_use_measurement {
-
-// DataUseTrackerPrefs keeps track of the data used over last 60 days. The data
-// used is recorded separately based on whether the data use was initiated by a
-// Chrome service or a user-initiated request.
-class DataUseTrackerPrefs {
- public:
-  // |pref_service| may be null in tests.
-  DataUseTrackerPrefs(const base::Clock* time_clock, PrefService* pref_service);
-
-  // Move-only class.
-  DataUseTrackerPrefs(const DataUseTrackerPrefs&) = delete;
-  DataUseTrackerPrefs& operator=(const DataUseTrackerPrefs&) = delete;
-
-  // Report data used by a service or a user-initiated request.
-  // |is_metered_connection| should be true if data consumption happened on a
-  // metered connection. |is_app_foreground| should be true if data was used
-  // when Chrome app was in foregorund. |is_user_traffic| should be true if data
-  // was used by a user-initiated request. |sent_or_recv_bytes| should be set to
-  // the data consumed (in bytes).
-  void ReportNetworkServiceDataUse(bool is_metered_connection,
-                                   bool is_app_foreground,
-                                   bool is_user_traffic,
-                                   int64_t sent_or_recv_bytes);
-
-  // Register local state prefs.
-  static void RegisterDataUseTrackerLocalStatePrefs(
-      PrefRegistrySimple* registry);
-
- private:
-  // Returns the current date for measurement.
-  base::Time GetCurrentMeasurementDate() const;
-
-  // Removes entries from the given |pref_name| if they are too old.
-  void RemoveExpiredEntriesForPref(const std::string& pref_name);
-
-  // Returns the current date as a string with a proper formatting.
-  std::string GetCurrentMeasurementDateAsString() const;
-
-  // Updates provided |pref_name| for a current date with the given message
-  // size.
-  void UpdateUsagePref(const std::string& pref_name,
-                       int64_t message_size_bytes);
-
-  raw_ptr<const base::Clock> time_clock_;
-  raw_ptr<PrefService> pref_service_ = nullptr;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-}  // namespace data_use_measurement
-
-#endif  // COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_TRACKER_PREFS_H_
diff --git a/components/data_use_measurement/core/data_use_tracker_prefs_unittest.cc b/components/data_use_measurement/core/data_use_tracker_prefs_unittest.cc
deleted file mode 100644
index 6dfee5b3..0000000
--- a/components/data_use_measurement/core/data_use_tracker_prefs_unittest.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2020 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 "components/data_use_measurement/core/data_use_tracker_prefs.h"
-
-#include <string>
-
-#include "base/run_loop.h"
-#include "base/test/simple_test_clock.h"
-#include "components/data_use_measurement/core/data_use_pref_names.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/testing_pref_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace data_use_measurement {
-
-void RegisterPrefs(TestingPrefServiceSimple* test_prefs) {
-  test_prefs->registry()->RegisterDictionaryPref(
-      prefs::kDataUsedUserForeground);
-  test_prefs->registry()->RegisterDictionaryPref(
-      prefs::kDataUsedUserBackground);
-  test_prefs->registry()->RegisterDictionaryPref(
-      prefs::kDataUsedServicesForeground);
-  test_prefs->registry()->RegisterDictionaryPref(
-      prefs::kDataUsedServicesBackground);
-}
-
-class DataUseTrackerPrefsTest {
- public:
-  DataUseTrackerPrefsTest(base::SimpleTestClock* clock,
-                          TestingPrefServiceSimple* test_prefs)
-      : data_use_tracker_prefs_(clock, test_prefs) {
-    // Register the prefs before accessing them.
-  }
-
-  DataUseTrackerPrefsTest(const DataUseTrackerPrefsTest&) = delete;
-  DataUseTrackerPrefsTest& operator=(const DataUseTrackerPrefsTest&) = delete;
-
-  DataUseTrackerPrefs* data_use_tracker_prefs() {
-    return &data_use_tracker_prefs_;
-  }
-
- private:
-  DataUseTrackerPrefs data_use_tracker_prefs_;
-};
-
-// Verifies that the prefs are stored correctly: The date is used as the key
-// in the pref and the expired keys are removed.
-TEST(DataUseTrackerPrefsTest, PrefsOnMeteredConnection) {
-  base::SimpleTestClock clock;
-  clock.SetNow(base::Time::Now());
-  TestingPrefServiceSimple test_prefs;
-  RegisterPrefs(&test_prefs);
-
-  // Report 2 data uses for the same day.
-  DataUseTrackerPrefsTest tracker_prefs_test_1(&clock, &test_prefs);
-  tracker_prefs_test_1.data_use_tracker_prefs()->ReportNetworkServiceDataUse(
-      true, true, true, 10);
-  EXPECT_EQ(
-      1u, test_prefs.GetDictionary(prefs::kDataUsedUserForeground)->DictSize());
-  tracker_prefs_test_1.data_use_tracker_prefs()->ReportNetworkServiceDataUse(
-      true, true, true, 10);
-  EXPECT_EQ(
-      1u, test_prefs.GetDictionary(prefs::kDataUsedUserForeground)->DictSize());
-
-  // Verify other prefs are not set.
-  EXPECT_TRUE(
-      test_prefs.GetDictionary(prefs::kDataUsedUserBackground)->DictEmpty());
-  EXPECT_TRUE(
-      test_prefs.GetDictionary(prefs::kDataUsedServicesForeground)->DictEmpty());
-  EXPECT_TRUE(
-      test_prefs.GetDictionary(prefs::kDataUsedServicesBackground)->DictEmpty());
-
-  // Move clock forward 10 days. New data use reported must go in a separate
-  // entry in the dictionary pref.
-  clock.Advance(base::Days(10));
-  DataUseTrackerPrefsTest tracker_prefs_test_2(&clock, &test_prefs);
-  EXPECT_EQ(
-      1u, test_prefs.GetDictionary(prefs::kDataUsedUserForeground)->DictSize());
-  tracker_prefs_test_2.data_use_tracker_prefs()->ReportNetworkServiceDataUse(
-      true, true, true, 10);
-  EXPECT_EQ(
-      2u, test_prefs.GetDictionary(prefs::kDataUsedUserForeground)->DictSize());
-
-  // Move clock forward 55 days. This should clean up the first entry since they
-  // are now 65 days older (i.e., more than 60 days old). New data use reported
-  // must go in a separate entry in the dictionary pref.
-  clock.Advance(base::Days(55));
-  DataUseTrackerPrefsTest tracker_prefs_test_3(&clock, &test_prefs);
-  EXPECT_EQ(
-      1u, test_prefs.GetDictionary(prefs::kDataUsedUserForeground)->DictSize());
-  tracker_prefs_test_2.data_use_tracker_prefs()->ReportNetworkServiceDataUse(
-      true, true, true, 10);
-  EXPECT_EQ(
-      2u, test_prefs.GetDictionary(prefs::kDataUsedUserForeground)->DictSize());
-}
-
-// Verifies that the prefs are not updated on unmetered connections.
-TEST(DataUseTrackerPrefsTest, PrefsOnUnmeteredConnection) {
-  base::SimpleTestClock clock;
-  clock.SetNow(base::Time::Now());
-  TestingPrefServiceSimple test_prefs;
-  RegisterPrefs(&test_prefs);
-
-  // Report 2 data uses for the same day.
-  DataUseTrackerPrefsTest tracker_prefs_test_1(&clock, &test_prefs);
-  tracker_prefs_test_1.data_use_tracker_prefs()->ReportNetworkServiceDataUse(
-      /*is_metered_connection=*/false, true, true, 10);
-  tracker_prefs_test_1.data_use_tracker_prefs()->ReportNetworkServiceDataUse(
-      /*is_metered_connection=*/false, true, true, 10);
-
-  // Verify prefs are not set.
-  EXPECT_TRUE(
-      test_prefs.GetDictionary(prefs::kDataUsedUserForeground)->DictEmpty());
-  EXPECT_TRUE(
-      test_prefs.GetDictionary(prefs::kDataUsedUserBackground)->DictEmpty());
-  EXPECT_TRUE(
-      test_prefs.GetDictionary(prefs::kDataUsedServicesForeground)->DictEmpty());
-  EXPECT_TRUE(
-      test_prefs.GetDictionary(prefs::kDataUsedServicesBackground)->DictEmpty());
-}
-
-TEST(DataUseTrackerPrefsTest, TestBasicUserForeground) {
-  base::SimpleTestClock clock;
-  clock.SetNow(base::Time::Now());
-  TestingPrefServiceSimple test_prefs;
-  RegisterPrefs(&test_prefs);
-
-  // Report 2 data uses for the same day.
-  DataUseTrackerPrefsTest tracker_prefs_test(&clock, &test_prefs);
-
-  const struct {
-    bool foreground;
-    bool user_initiated;
-    std::string pref_expected_as_non_empty;
-  } tests[] = {
-      {false, false, prefs::kDataUsedServicesBackground},
-      {false, true, prefs::kDataUsedUserBackground},
-      {true, false, prefs::kDataUsedServicesForeground},
-      {true, true, prefs::kDataUsedUserForeground},
-  };
-
-  for (const auto& test : tests) {
-    test_prefs.ClearPref(prefs::kDataUsedServicesBackground);
-    test_prefs.ClearPref(prefs::kDataUsedUserBackground);
-    test_prefs.ClearPref(prefs::kDataUsedServicesForeground);
-    test_prefs.ClearPref(prefs::kDataUsedServicesForeground);
-
-    tracker_prefs_test.data_use_tracker_prefs()->ReportNetworkServiceDataUse(
-        true, test.foreground, test.user_initiated, 10);
-    // Verify that the expected pref has an entry.
-    EXPECT_FALSE(
-        test_prefs.GetDictionary(test.pref_expected_as_non_empty)->DictEmpty());
-
-    // Verify other prefs are not set.
-    EXPECT_TRUE(
-        test.pref_expected_as_non_empty == prefs::kDataUsedUserForeground ||
-        test_prefs.GetDictionary(prefs::kDataUsedUserForeground)->DictEmpty());
-    EXPECT_TRUE(
-        test.pref_expected_as_non_empty == prefs::kDataUsedUserBackground ||
-        test_prefs.GetDictionary(prefs::kDataUsedUserBackground)->DictEmpty());
-    EXPECT_TRUE(
-        test.pref_expected_as_non_empty == prefs::kDataUsedServicesForeground ||
-        test_prefs.GetDictionary(prefs::kDataUsedServicesForeground)->DictEmpty());
-    EXPECT_TRUE(
-        test.pref_expected_as_non_empty == prefs::kDataUsedServicesBackground ||
-        test_prefs.GetDictionary(prefs::kDataUsedServicesBackground)->DictEmpty());
-  }
-}
-
-}  // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use_user_data.cc b/components/data_use_measurement/core/data_use_user_data.cc
deleted file mode 100644
index 1f17c13..0000000
--- a/components/data_use_measurement/core/data_use_user_data.cc
+++ /dev/null
@@ -1,27 +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 "components/data_use_measurement/core/data_use_user_data.h"
-
-#include <memory>
-
-#include "build/build_config.h"
-#include "net/url_request/url_fetcher.h"
-
-#if BUILDFLAG(IS_ANDROID)
-#include "base/android/application_status_listener.h"
-#endif
-
-namespace data_use_measurement {
-
-DataUseUserData::DataUseUserData(AppState app_state)
-    : app_state_(app_state), content_type_(DataUseContentType::OTHER) {}
-
-DataUseUserData::~DataUseUserData() {}
-
-// static
-const void* const DataUseUserData::kUserDataKey =
-    &DataUseUserData::kUserDataKey;
-
-}  // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use_user_data.h b/components/data_use_measurement/core/data_use_user_data.h
deleted file mode 100644
index 7d092652..0000000
--- a/components/data_use_measurement/core/data_use_user_data.h
+++ /dev/null
@@ -1,70 +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 COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_USER_DATA_H_
-#define COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_USER_DATA_H_
-
-#include "base/supports_user_data.h"
-
-namespace data_use_measurement {
-
-// Used to annotate URLRequests with the service name if the URLRequest is used
-// by a service.
-class DataUseUserData : public base::SupportsUserData::Data {
- public:
-  // Data use broken by content type. This enum must remain synchronized
-  // with the enum of the same name in metrics/histograms/histograms.xml.
-  // These values are written to logs.  New enum values can be added, but
-  // existing enums must never be renumbered or deleted and reused.
-  enum DataUseContentType {
-    OTHER = 0,
-    MAIN_FRAME_HTML = 1,
-    NON_MAIN_FRAME_HTML = 2,
-    CSS = 3,
-    IMAGE = 4,
-    JAVASCRIPT = 5,
-    FONT = 6,
-    AUDIO_APPBACKGROUND = 7,
-    AUDIO_TABBACKGROUND = 8,
-    AUDIO = 9,
-    VIDEO_APPBACKGROUND = 10,
-    VIDEO_TABBACKGROUND = 11,
-    VIDEO = 12,
-    kMaxValue = 13,
-  };
-
-  // The state of the application. Only available on Android and on other
-  // platforms it is always FOREGROUND.
-  enum AppState { UNKNOWN, BACKGROUND, FOREGROUND };
-
-  explicit DataUseUserData(AppState app_state);
-
-  DataUseUserData(const DataUseUserData&) = delete;
-  DataUseUserData& operator=(const DataUseUserData&) = delete;
-
-  ~DataUseUserData() override;
-
-  AppState app_state() const { return app_state_; }
-
-  void set_app_state(AppState app_state) { app_state_ = app_state; }
-
-  DataUseContentType content_type() { return content_type_; }
-
-  void set_content_type(DataUseContentType content_type) {
-    content_type_ = content_type;
-  }
-
-  // The key for retrieving back this type of user data.
-  static const void* const kUserDataKey;
-
- private:
-  // App state when network access was performed for the request previously.
-  AppState app_state_;
-
-  DataUseContentType content_type_;
-};
-
-}  // namespace data_use_measurement
-
-#endif  // COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_USER_DATA_H_
diff --git a/components/desks_storage/BUILD.gn b/components/desks_storage/BUILD.gn
index df019b5..27c9a7d 100644
--- a/components/desks_storage/BUILD.gn
+++ b/components/desks_storage/BUILD.gn
@@ -28,6 +28,7 @@
     "//components/sync/model",
     "//components/sync/protocol",
     "//components/version_info:channel",
+    "//extensions/common:common_constants",
     "//third_party/re2",
     "//ui/gfx/geometry",
   ]
@@ -51,6 +52,7 @@
     "//base",
     "//base/test:test_support",
     "//components/sync:test_support",
+    "//extensions/common:common_constants",
     "//testing/gtest",
   ]
 }
diff --git a/components/download/internal/common/BUILD.gn b/components/download/internal/common/BUILD.gn
index 2069d2b8..1ddc494 100644
--- a/components/download/internal/common/BUILD.gn
+++ b/components/download/internal/common/BUILD.gn
@@ -90,10 +90,6 @@
     deps += [ "//components/safe_browsing/content/common:file_type_policies" ]
   }
 
-  if (is_win) {
-    deps += [ "//components/services/quarantine/public/cpp:features" ]
-  }
-
   if (is_android) {
     sources += [
       "android/download_collection_bridge.cc",
diff --git a/components/download/internal/common/DEPS b/components/download/internal/common/DEPS
index 248ecbe..eaa0849 100644
--- a/components/download/internal/common/DEPS
+++ b/components/download/internal/common/DEPS
@@ -8,7 +8,6 @@
   "+components/leveldb_proto",
   "+components/safe_browsing/buildflags.h",
   "+components/safe_browsing/content/common",
-  "+components/services/quarantine/public/cpp/quarantine_features_win.h",
   "+components/services/quarantine/quarantine.h",
   "+components/ukm/test_ukm_recorder.h",
   "+crypto",
diff --git a/components/download/internal/common/base_file.cc b/components/download/internal/common/base_file.cc
index 772f7e1..e589914 100644
--- a/components/download/internal/common/base_file.cc
+++ b/components/download/internal/common/base_file.cc
@@ -25,10 +25,6 @@
 #include "components/services/quarantine/quarantine.h"
 #include "crypto/secure_hash.h"
 
-#if BUILDFLAG(IS_WIN)
-#include "components/services/quarantine/public/cpp/quarantine_features_win.h"
-#endif  // BUILDFLAG(IS_WIN)
-
 #if BUILDFLAG(IS_ANDROID)
 #include "base/android/content_uri_utils.h"
 #include "components/download/internal/common/android/download_collection_bridge.h"
@@ -618,15 +614,12 @@
 void BaseFile::OnQuarantineServiceError(const GURL& source_url,
                                         const GURL& referrer_url) {
 #if BUILDFLAG(IS_WIN)
-  if (base::FeatureList::IsEnabled(quarantine::kOutOfProcessQuarantine)) {
-    OnFileQuarantined(/*connection_error=*/true,
-                      quarantine::SetInternetZoneIdentifierDirectly(
-                          full_path_, source_url, referrer_url));
-    return;
-  }
-#endif  // BUILDFLAG(IS_WIN)
-
+  OnFileQuarantined(/*connection_error=*/true,
+                    quarantine::SetInternetZoneIdentifierDirectly(
+                        full_path_, source_url, referrer_url));
+#else   // !BUILDFLAG(IS_WIN)
   CHECK(false) << "In-process quarantine service should not have failed.";
+#endif  // !BUILDFLAG(IS_WIN)
 }
 
 void BaseFile::AnnotateWithSourceInformation(
diff --git a/components/embedder_support/user_agent_utils.cc b/components/embedder_support/user_agent_utils.cc
index a001f60..a651a8fa 100644
--- a/components/embedder_support/user_agent_utils.cc
+++ b/components/embedder_support/user_agent_utils.cc
@@ -221,6 +221,7 @@
 
 const blink::UserAgentBrandList GetUserAgentBrandMajorVersionList(
     bool enable_updated_grease_by_policy) {
+  // TODO(crbug.com/1290902): Respect #force-major-version-to-minor here.
   return GetUserAgentBrandList(version_info::GetMajorVersionNumber(),
                                enable_updated_grease_by_policy,
                                version_info::GetVersionNumber(),
@@ -236,6 +237,7 @@
 
 blink::UserAgentBrandList GetUserAgentBrandFullVersionList(
     bool enable_updated_grease_by_policy) {
+  // TODO(crbug.com/1290902): Respect #force-major-version-to-minor here.
   return GetUserAgentBrandList(version_info::GetMajorVersionNumber(),
                                enable_updated_grease_by_policy,
                                version_info::GetVersionNumber(),
@@ -317,10 +319,23 @@
   return content::GetReducedUserAgent(
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kUseMobileUserAgent),
-      base::FeatureList::IsEnabled(
-          blink::features::kForceMajorVersion100InUserAgent)
-          ? kVersion100
-          : version_info::GetMajorVersionNumber());
+          GetMajorVersionForUserAgentString());
+}
+
+std::string GetMajorVersionForUserAgentString() {
+  // Priority 1: force major version to 99.
+  if (base::FeatureList::IsEnabled(
+    blink::features::kForceMajorVersionInMinorPositionInUserAgent))
+    // TODO(crbug.com/1287531): Consider enterprise policy for
+    // #force-major-to-minor here as well.
+    return kVersion99;
+
+  // Priority 2: Force major version to 100.
+  if (base::FeatureList::IsEnabled(
+    blink::features::kForceMajorVersion100InUserAgent))
+    return kVersion100;
+
+  return version_info::GetMajorVersionNumber();
 }
 
 std::string GetFullUserAgent() {
diff --git a/components/embedder_support/user_agent_utils.h b/components/embedder_support/user_agent_utils.h
index 70946d1..fec27fb 100644
--- a/components/embedder_support/user_agent_utils.h
+++ b/components/embedder_support/user_agent_utils.h
@@ -28,6 +28,10 @@
 // flag-enabled overrides.
 std::string GetProduct(bool allow_override = false);
 
+// Returns a string representing the major version number of the user agent
+// string for Chrome, potentially overridden by policy.
+std::string GetMajorVersionForUserAgentString();
+
 // Returns the user agent string for Chrome.
 std::string GetFullUserAgent();
 
diff --git a/components/embedder_support/user_agent_utils_unittest.cc b/components/embedder_support/user_agent_utils_unittest.cc
index 3b5c2ca..c869d85 100644
--- a/components/embedder_support/user_agent_utils_unittest.cc
+++ b/components/embedder_support/user_agent_utils_unittest.cc
@@ -383,6 +383,21 @@
                                  content::GetUnifiedPlatform().c_str(),
                                  major_version, device_compat.c_str()));
   }
+
+  // Verify that the reduced user agent string respects
+  // --force-major-version-to-minor
+  scoped_feature_list.Reset();
+  scoped_feature_list.InitWithFeatures(
+      {blink::features::kReduceUserAgent,
+      blink::features::kForceMajorVersionInMinorPositionInUserAgent}, {});
+  {
+    std::string buffer = GetReducedUserAgent();
+    std::string device_compat = "Mobile ";
+    EXPECT_EQ(buffer,
+              base::StringPrintf(content::frozen_user_agent_strings::kAndroid,
+                                content::GetUnifiedPlatform().c_str(), "99",
+                                device_compat.c_str()));
+  }
 #else
   {
     std::string buffer = GetUserAgent();
@@ -393,6 +408,19 @@
                               ? "100"
                               : version_info::GetMajorVersionNumber().c_str()));
   }
+
+  // Verify that the reduced user agent string respects
+  // --force-major-version-to-minor
+  scoped_feature_list.Reset();
+  scoped_feature_list.InitWithFeatures(
+      {blink::features::kReduceUserAgent,
+      blink::features::kForceMajorVersionInMinorPositionInUserAgent}, {});
+  {
+    std::string buffer = GetReducedUserAgent();
+    EXPECT_EQ(buffer,
+              base::StringPrintf(content::frozen_user_agent_strings::kDesktop,
+                                content::GetUnifiedPlatform().c_str(), "99"));
+  }
 #endif
 
   EXPECT_EQ(GetUserAgent(), GetReducedUserAgent());
diff --git a/components/exo/wayland/zcr_remote_shell.cc b/components/exo/wayland/zcr_remote_shell.cc
index 9495622..a3e6365 100644
--- a/components/exo/wayland/zcr_remote_shell.cc
+++ b/components/exo/wayland/zcr_remote_shell.cc
@@ -134,7 +134,6 @@
     ZCR_REMOTE_SHELL_V1_DEFAULT_DEVICE_SCALE_FACTOR_SINCE_VERSION,
     ZCR_REMOTE_SURFACE_V1_CHANGE_ZOOM_LEVEL_SINCE_VERSION,
     ZCR_REMOTE_SHELL_V1_WORKSPACE_INFO_SINCE_VERSION,
-    ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGED_IN_OUTPUT_SINCE_VERSION,
     ZCR_REMOTE_SHELL_V1_SET_USE_DEFAULT_DEVICE_SCALE_CANCELLATION_SINCE_VERSION,
 };
 
diff --git a/components/exo/wayland/zcr_remote_shell_event_mapping.h b/components/exo/wayland/zcr_remote_shell_event_mapping.h
index c01faf8a..e5f6e79 100644
--- a/components/exo/wayland/zcr_remote_shell_event_mapping.h
+++ b/components/exo/wayland/zcr_remote_shell_event_mapping.h
@@ -100,7 +100,6 @@
   int default_device_scale_factor_since_version;
   int change_zoom_level_since_version;
   int send_workspace_info_since_version;
-  int send_bounds_changed_since_version;
   int set_use_default_scale_cancellation_since_version;
 };
 
diff --git a/components/exo/wayland/zcr_remote_shell_impl.cc b/components/exo/wayland/zcr_remote_shell_impl.cc
index 253a073..2283c6b 100644
--- a/components/exo/wayland/zcr_remote_shell_impl.cc
+++ b/components/exo/wayland/zcr_remote_shell_impl.cc
@@ -773,33 +773,15 @@
     }
   }
 
-  if (wl_resource_get_version(resource) >=
-      event_mapping_.send_bounds_changed_since_version) {
-    if (needs_send_display_metrics_) {
-      // We store only the latest bounds for each |resource|.
-      pending_bounds_changes_.insert_or_assign(
-          std::move(resource),
-          BoundsChangeData(display_id, bounds_in_display, reason));
-      return;
-    }
-    SendBoundsChanged(resource, display_id, bounds_in_display, reason);
-  } else {
-    gfx::Rect bounds_in_screen = gfx::Rect(bounds_in_display);
-    display::Display display;
-    display::Screen::GetScreen()->GetDisplayWithDisplayId(display_id, &display);
-    // The display ID should be valid.
-    DCHECK(display.is_valid());
-    if (display.is_valid())
-      bounds_in_screen.Offset(display.bounds().OffsetFromOrigin());
-    else
-      LOG(ERROR) << "Invalid Display in send_bounds_changed:" << display_id;
-
-    event_mapping_.send_bounds_changed(
-        resource, static_cast<uint32_t>(display_id >> 32),
-        static_cast<uint32_t>(display_id), bounds_in_screen.x(),
-        bounds_in_screen.y(), bounds_in_screen.width(),
-        bounds_in_screen.height(), reason);
+  if (needs_send_display_metrics_) {
+    // We store only the latest bounds for each |resource|.
+    pending_bounds_changes_.insert_or_assign(
+        std::move(resource),
+        BoundsChangeData(display_id, bounds_in_display, reason));
+    return;
   }
+  SendBoundsChanged(resource, display_id, bounds_in_display, reason);
+
   wl_client_flush(wl_resource_get_client(resource));
 }
 
diff --git a/components/exo/wayland/zcr_remote_shell_impl_unittest.cc b/components/exo/wayland/zcr_remote_shell_impl_unittest.cc
index 35ecd34..90735092 100644
--- a/components/exo/wayland/zcr_remote_shell_impl_unittest.cc
+++ b/components/exo/wayland/zcr_remote_shell_impl_unittest.cc
@@ -175,7 +175,6 @@
       /*default_device_scale_factor_since_version=*/0,
       /*change_zoom_level_since_version=*/0,
       /*send_workspace_info_since_version=*/0,
-      /*send_bounds_changed_since_version=*/0,
       /*set_use_default_scale_cancellation_since_version=*/0,
   };
 };
diff --git a/components/exo/wayland/zcr_remote_shell_v2.cc b/components/exo/wayland/zcr_remote_shell_v2.cc
index 8d7196f..132e9d3c 100644
--- a/components/exo/wayland/zcr_remote_shell_v2.cc
+++ b/components/exo/wayland/zcr_remote_shell_v2.cc
@@ -60,7 +60,6 @@
     1,
     1,
     1,
-    1,
 };
 
 const struct zcr_remote_surface_v2_interface remote_surface_implementation_v2 =
diff --git a/components/media_router/common/discovery/media_sink_internal.h b/components/media_router/common/discovery/media_sink_internal.h
index d75f136..f68ea89 100644
--- a/components/media_router/common/discovery/media_sink_internal.h
+++ b/components/media_router/common/discovery/media_sink_internal.h
@@ -14,6 +14,9 @@
 
 namespace media_router {
 
+// Default Cast control port to open Cast Socket.
+static constexpr int kCastControlPort = 8009;
+
 // Extra data for DIAL media sink.
 struct DialSinkExtraData {
   net::IPAddress ip_address;
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_handle.cc b/components/no_state_prefetch/browser/no_state_prefetch_handle.cc
index 8220693..5dffd2e9 100644
--- a/components/no_state_prefetch/browser/no_state_prefetch_handle.cc
+++ b/components/no_state_prefetch/browser/no_state_prefetch_handle.cc
@@ -8,6 +8,7 @@
 
 #include "base/check_op.h"
 #include "components/no_state_prefetch/browser/no_state_prefetch_contents.h"
+#include "components/no_state_prefetch/common/no_state_prefetch_final_status.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 
@@ -63,6 +64,10 @@
   return prefetch_data_ ? prefetch_data_->contents() : nullptr;
 }
 
+const GURL& NoStatePrefetchHandle::prerender_url() const {
+  return prerender_url_;
+}
+
 NoStatePrefetchHandle::NoStatePrefetchHandle(
     NoStatePrefetchManager::NoStatePrefetchData* prefetch_data)
     : observer_(nullptr) {
@@ -70,6 +75,9 @@
   if (prefetch_data) {
     prefetch_data_ = prefetch_data->AsWeakPtr();
     prefetch_data->OnHandleCreated(this);
+    if (prefetch_data->contents()) {
+      prerender_url_ = prefetch_data->contents()->prerender_url();
+    }
   }
 }
 
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_handle.h b/components/no_state_prefetch/browser/no_state_prefetch_handle.h
index 82442566..b245bb5 100644
--- a/components/no_state_prefetch/browser/no_state_prefetch_handle.h
+++ b/components/no_state_prefetch/browser/no_state_prefetch_handle.h
@@ -8,6 +8,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
+#include "url/gurl.h"
 
 namespace prerender {
 
@@ -68,6 +69,8 @@
 
   NoStatePrefetchContents* contents() const;
 
+  const GURL& prerender_url() const;
+
   // Returns whether this NoStatePrefetchHandle represents the same prefetch as
   // the other NoStatePrefetchHandle object specified.
   bool RepresentingSamePrefetchAs(NoStatePrefetchHandle* other) const;
@@ -86,6 +89,9 @@
 
   raw_ptr<Observer> observer_;
 
+  // The prerendered URL for this handle.
+  GURL prerender_url_;
+
   base::WeakPtr<NoStatePrefetchManager::NoStatePrefetchData> prefetch_data_;
   base::WeakPtrFactory<NoStatePrefetchHandle> weak_ptr_factory_{this};
 };
diff --git a/components/optimization_guide/content/browser/page_content_annotations_service.cc b/components/optimization_guide/content/browser/page_content_annotations_service.cc
index 8e04547..48e2b09 100644
--- a/components/optimization_guide/content/browser/page_content_annotations_service.cc
+++ b/components/optimization_guide/content/browser/page_content_annotations_service.cc
@@ -19,6 +19,7 @@
 #include "components/optimization_guide/core/optimization_guide_enums.h"
 #include "components/optimization_guide/core/optimization_guide_features.h"
 #include "components/optimization_guide/core/optimization_guide_model_provider.h"
+#include "components/optimization_guide/core/optimization_guide_switches.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
 #include "services/metrics/public/cpp/metrics_utils.h"
@@ -139,9 +140,13 @@
 #if BUILDFLAG(BUILD_WITH_TFLITE_LIB)
   if (!visit.text_to_annotate)
     return;
+  // Used for testing.
+  LOCAL_HISTOGRAM_BOOLEAN(
+      "PageContentAnnotations.AnnotateVisit.AnnotationRequested", true);
   visits_to_annotate_.emplace_back(visit);
   if (visits_to_annotate_.size() >= features::AnnotateVisitBatchSize()) {
     if (current_visit_annotation_batch_.empty()) {
+      // Used for testing.
       LOCAL_HISTOGRAM_BOOLEAN(
           "PageContentAnnotations.AnnotateVisit.BatchAnnotationStarted", true);
       current_visit_annotation_batch_ = std::move(visits_to_annotate_);
@@ -151,9 +156,11 @@
     // The queue is full and an batch annotation is actively being done so
     // we will remove the "oldest" visit.
     visits_to_annotate_.erase(visits_to_annotate_.begin());
+    // Used for testing.
     LOCAL_HISTOGRAM_BOOLEAN(
         "PageContentAnnotations.AnnotateVisit.QueueFullVisitDropped", true);
   }
+  // Used for testing.
   LOCAL_HISTOGRAM_BOOLEAN(
       "PageContentAnnotations.AnnotateVisit.AnnotationRequestQueued", true);
 #endif
@@ -163,8 +170,11 @@
 void PageContentAnnotationsService::AnnotateVisitBatch() {
   DCHECK(!current_visit_annotation_batch_.empty());
 
-  // if (pause_execution_for_testing_)
-  // return;
+  if (switches::StopHistoryVisitBatchAnnotateForTesting()) {
+    // Code beyond this is tested in multiple places. This just ensures the
+    // calls up to this point can be more easily configured.
+    return;
+  }
 
   if (current_visit_annotation_batch_.empty()) {
     return;
diff --git a/components/optimization_guide/content/browser/page_content_annotations_web_contents_observer.cc b/components/optimization_guide/content/browser/page_content_annotations_web_contents_observer.cc
index 9f1074a6..e2c3b164 100644
--- a/components/optimization_guide/content/browser/page_content_annotations_web_contents_observer.cc
+++ b/components/optimization_guide/content/browser/page_content_annotations_web_contents_observer.cc
@@ -11,6 +11,7 @@
 #include "components/optimization_guide/content/browser/optimization_guide_decider.h"
 #include "components/optimization_guide/content/browser/page_content_annotations_service.h"
 #include "components/optimization_guide/core/optimization_guide_features.h"
+#include "components/optimization_guide/core/optimization_guide_switches.h"
 #include "components/optimization_guide/proto/page_entities_metadata.pb.h"
 #include "components/search_engines/template_url_service.h"
 #include "content/public/browser/navigation_entry.h"
@@ -158,6 +159,13 @@
       history_visit.text_to_annotate =
           base::UTF16ToUTF8(normalized_search_query);
       page_content_annotations_service_->Annotate(history_visit);
+
+      if (switches::ShouldLogPageContentAnnotationsInput()) {
+        LOG(ERROR) << "Annotating search terms: \n"
+                   << "URL: " << navigation_handle->GetURL() << "\n"
+                   << "Text: " << *(history_visit.text_to_annotate);
+      }
+
       return;
     }
   }
@@ -172,6 +180,12 @@
     history_visit.text_to_annotate =
         base::UTF16ToUTF8(web_contents()->GetTitle());
     page_content_annotations_service_->Annotate(history_visit);
+
+    if (switches::ShouldLogPageContentAnnotationsInput()) {
+      LOG(ERROR) << "Annotating same document navigation: \n"
+                 << "URL: " << navigation_handle->GetURL() << "\n"
+                 << "Text: " << *(history_visit.text_to_annotate);
+    }
   }
 }
 
@@ -196,6 +210,12 @@
   history_visit.text_to_annotate =
       base::UTF16ToUTF8(entry->GetTitleForDisplay());
   page_content_annotations_service_->Annotate(history_visit);
+
+  if (switches::ShouldLogPageContentAnnotationsInput()) {
+    LOG(ERROR) << "Annotating main frame navigation: \n"
+               << "URL: " << entry->GetURL() << "\n"
+               << "Text: " << *(history_visit.text_to_annotate);
+  }
 }
 
 std::unique_ptr<PageTextObserver::ConsumerTextDumpRequest>
@@ -246,10 +266,20 @@
   if (result.GetAMPTextContent()) {
     visit.text_to_annotate = *result.GetAMPTextContent();
     page_content_annotations_service_->Annotate(visit);
+    if (switches::ShouldLogPageContentAnnotationsInput()) {
+      LOG(ERROR) << "Annotating AMP text content: \n"
+                 << "URL: " << visit.url << "\n"
+                 << "Text: " << *(visit.text_to_annotate);
+    }
     return;
   }
   visit.text_to_annotate = *result.GetMainFrameTextContent();
   page_content_annotations_service_->Annotate(visit);
+  if (switches::ShouldLogPageContentAnnotationsInput()) {
+    LOG(ERROR) << "Annotating main frame text content: \n"
+               << "URL: " << visit.url << "\n"
+               << "Text: " << *(visit.text_to_annotate);
+  }
 }
 
 void PageContentAnnotationsWebContentsObserver::OnRemotePageEntitiesReceived(
diff --git a/components/optimization_guide/core/optimization_guide_switches.cc b/components/optimization_guide/core/optimization_guide_switches.cc
index 42b1e556..3145c7a 100644
--- a/components/optimization_guide/core/optimization_guide_switches.cc
+++ b/components/optimization_guide/core/optimization_guide_switches.cc
@@ -87,6 +87,14 @@
 // Triggers validation of the model. Used for manual testing.
 const char kModelValidate[] = "optimization-guide-model-validate";
 
+// Prevents any models from being executing when in annotating a batch
+// of visits. This is used for testing only.
+const char kStopHistoryVisitBatchAnnotateForTesting[] =
+    "stop-history-visit-batch-annotate";
+
+const char kPageContentAnnotationsLoggingEnabled[] =
+    "enable-page-content-annotations-logging";
+
 bool IsHintComponentProcessingDisabled() {
   return base::CommandLine::ForCurrentProcess()->HasSwitch(kHintsProtoOverride);
 }
@@ -206,5 +214,17 @@
 #endif
 }
 
+bool StopHistoryVisitBatchAnnotateForTesting() {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(kStopHistoryVisitBatchAnnotateForTesting))
+    return true;
+  return false;
+}
+
+bool ShouldLogPageContentAnnotationsInput() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      kPageContentAnnotationsLoggingEnabled);
+}
+
 }  // namespace switches
 }  // namespace optimization_guide
diff --git a/components/optimization_guide/core/optimization_guide_switches.h b/components/optimization_guide/core/optimization_guide_switches.h
index 188d06c..604fa18 100644
--- a/components/optimization_guide/core/optimization_guide_switches.h
+++ b/components/optimization_guide/core/optimization_guide_switches.h
@@ -34,6 +34,8 @@
 extern const char kModelOverride[];
 extern const char kDebugLoggingEnabled[];
 extern const char kModelValidate[];
+extern const char kStopHistoryVisitBatchAnnotateForTesting[];
+extern const char kPageContentAnnotationsLoggingEnabled[];
 
 // Returns whether the hint component should be processed.
 // Available hint components are only processed if a proto override isn't being
@@ -92,6 +94,13 @@
 // Returns true if debug logs are enabled for the optimization guide.
 bool IsDebugLogsEnabled();
 
+// Whether to prevent annotations from happening when in a batch. For testing
+// purposes only.
+bool StopHistoryVisitBatchAnnotateForTesting();
+
+// Returns true if page content annotations input should be logged.
+bool ShouldLogPageContentAnnotationsInput();
+
 }  // namespace switches
 }  // namespace optimization_guide
 
diff --git a/components/page_load_metrics/common/page_load_metrics.mojom b/components/page_load_metrics/common/page_load_metrics.mojom
index d09e28c..7f2f30f 100644
--- a/components/page_load_metrics/common/page_load_metrics.mojom
+++ b/components/page_load_metrics/common/page_load_metrics.mojom
@@ -237,10 +237,6 @@
   // Whether this resource load has completed.
   bool is_complete;
 
-  // Compression ratio estimated from the response headers if data saver was
-  // used.
-  double data_reduction_proxy_compression_ratio_estimate;
-
   // Whether this resource was tagged as an ad in the renderer. This flag can
   // be set to true at any point during a resource load. A more recent
   // ResourceDataUpdate can have a different flag than the previous update.
diff --git a/components/page_load_metrics/renderer/page_resource_data_use.cc b/components/page_load_metrics/renderer/page_resource_data_use.cc
index 53a47e9..8d30de0 100644
--- a/components/page_load_metrics/renderer/page_resource_data_use.cc
+++ b/components/page_load_metrics/renderer/page_resource_data_use.cc
@@ -4,7 +4,6 @@
 
 #include "components/page_load_metrics/renderer/page_resource_data_use.h"
 
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "services/network/public/cpp/url_loader_completion_status.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
 #include "third_party/blink/public/common/loader/resource_type_util.h"
@@ -14,7 +13,6 @@
 
 PageResourceDataUse::PageResourceDataUse()
     : resource_id_(-1),
-      data_reduction_proxy_compression_ratio_estimate_(1.0),
       total_received_bytes_(0),
       last_update_bytes_(0),
       is_complete_(false),
@@ -37,8 +35,6 @@
     const network::mojom::URLResponseHead& response_head,
     network::mojom::RequestDestination request_destination) {
   resource_id_ = resource_id;
-  data_reduction_proxy_compression_ratio_estimate_ =
-      data_reduction_proxy::EstimateCompressionRatioFromHeaders(&response_head);
 
   proxy_used_ = !response_head.proxy_server.is_direct();
   mime_type_ = response_head.mime_type;
@@ -121,8 +117,6 @@
   resource_data_update->received_data_length = total_received_bytes_;
   resource_data_update->delta_bytes = CalculateNewlyReceivedBytes();
   resource_data_update->is_complete = is_complete_;
-  resource_data_update->data_reduction_proxy_compression_ratio_estimate =
-      data_reduction_proxy_compression_ratio_estimate_;
   resource_data_update->reported_as_ad_resource = reported_as_ad_resource_;
   resource_data_update->is_main_frame_resource = is_main_frame_resource_;
   resource_data_update->mime_type = mime_type_;
diff --git a/components/page_load_metrics/renderer/page_resource_data_use.h b/components/page_load_metrics/renderer/page_resource_data_use.h
index 9fed70f..5b873ed 100644
--- a/components/page_load_metrics/renderer/page_resource_data_use.h
+++ b/components/page_load_metrics/renderer/page_resource_data_use.h
@@ -73,10 +73,6 @@
 
   int resource_id_;
 
-  // Compression ratio estimated from the response headers if data saver was
-  // used.
-  double data_reduction_proxy_compression_ratio_estimate_;
-
   uint64_t total_received_bytes_ = 0;
   uint64_t last_update_bytes_ = 0;
   uint64_t encoded_body_length_ = 0;
diff --git a/components/reporting/storage/storage_queue_unittest.cc b/components/reporting/storage/storage_queue_unittest.cc
index 972a42db..021d233 100644
--- a/components/reporting/storage/storage_queue_unittest.cc
+++ b/components/reporting/storage/storage_queue_unittest.cc
@@ -838,15 +838,23 @@
 
   ResetTestStorageQueue();
 
-  // Delete all metadata files.
-  base::FileEnumerator dir_enum(
-      options.directory(),
-      /*recursive=*/false, base::FileEnumerator::FILES,
-      base::StrCat({METADATA_NAME, FILE_PATH_LITERAL(".2")}));
-  base::FilePath full_name = dir_enum.Next();
-  ASSERT_FALSE(full_name.empty());
-  base::DeleteFile(full_name);
-  ASSERT_TRUE(dir_enum.Next().empty());
+  // Delete the last metadata file.
+  {  // scoping this block so that dir_enum is not used later.
+    const auto last_metadata_file_pattern =
+        base::StrCat({METADATA_NAME, FILE_PATH_LITERAL(".2")});
+    base::FileEnumerator dir_enum(options.directory(),
+                                  /*recursive=*/false,
+                                  base::FileEnumerator::FILES,
+                                  last_metadata_file_pattern);
+    base::FilePath full_name = dir_enum.Next();
+    ASSERT_FALSE(full_name.empty())
+        << "No file matches " << last_metadata_file_pattern;
+    ASSERT_TRUE(dir_enum.Next().empty())
+        << full_name << " is not the last metadata file in "
+        << options.directory();
+    ASSERT_TRUE(base::DeleteFile(full_name))
+        << "Failed to delete " << full_name;
+  }
 
   // Reopen, starting a new generation.
   CreateTestStorageQueueOrDie(BuildStorageQueueOptionsPeriodic());
diff --git a/components/services/app_service/public/cpp/app_types.cc b/components/services/app_service/public/cpp/app_types.cc
index 24479b44..26589122 100644
--- a/components/services/app_service/public/cpp/app_types.cc
+++ b/components/services/app_service/public/cpp/app_types.cc
@@ -40,6 +40,7 @@
   app->show_in_shelf = show_in_shelf;
   app->show_in_search = show_in_search;
   app->show_in_management = show_in_management;
+  app->handles_intents = handles_intents;
 
   return app;
 }
@@ -227,6 +228,7 @@
   app->show_in_shelf = GetOptionalBool(mojom_app->show_in_shelf);
   app->show_in_search = GetOptionalBool(mojom_app->show_in_search);
   app->show_in_management = GetOptionalBool(mojom_app->show_in_management);
+  app->handles_intents = GetOptionalBool(mojom_app->handles_intents);
 
   return app;
 }
diff --git a/components/services/app_service/public/cpp/app_types.h b/components/services/app_service/public/cpp/app_types.h
index 0021e966..53f3da8 100644
--- a/components/services/app_service/public/cpp/app_types.h
+++ b/components/services/app_service/public/cpp/app_types.h
@@ -156,6 +156,10 @@
   absl::optional<bool> show_in_search;
   absl::optional<bool> show_in_management;
 
+  // True if the app is able to handle intents and should be shown in intent
+  // surfaces.
+  absl::optional<bool> handles_intents;
+
   // TODO(crbug.com/1253250): Add other App struct fields.
 
   // When adding new fields to the App type, the `Clone` function and the
diff --git a/components/services/app_service/public/cpp/app_update.cc b/components/services/app_service/public/cpp/app_update.cc
index 0a33c21..44a86d7 100644
--- a/components/services/app_service/public/cpp/app_update.cc
+++ b/components/services/app_service/public/cpp/app_update.cc
@@ -212,6 +212,7 @@
   SET_OPTIONAL_VALUE(show_in_shelf);
   SET_OPTIONAL_VALUE(show_in_search);
   SET_OPTIONAL_VALUE(show_in_management);
+  SET_OPTIONAL_VALUE(handles_intents);
 
   // When adding new fields to the App type, this function should also be
   // updated.
@@ -757,6 +758,10 @@
   return apps::mojom::OptionalBool::kUnknown;
 }
 
+absl::optional<bool> AppUpdate::GetHandlesIntents() const {
+  GET_VALUE_WITH_FALLBACK(handles_intents, absl::nullopt)
+}
+
 bool AppUpdate::HandlesIntentsChanged() const {
   return mojom_delta_ &&
          (mojom_delta_->handles_intents !=
diff --git a/components/services/app_service/public/cpp/app_update.h b/components/services/app_service/public/cpp/app_update.h
index 847fb1e..2eb7cf2c 100644
--- a/components/services/app_service/public/cpp/app_update.h
+++ b/components/services/app_service/public/cpp/app_update.h
@@ -173,6 +173,7 @@
   bool ShowInManagementChanged() const;
 
   apps::mojom::OptionalBool HandlesIntents() const;
+  absl::optional<bool> GetHandlesIntents() const;
   bool HandlesIntentsChanged() const;
 
   apps::mojom::OptionalBool AllowUninstall() const;
diff --git a/components/services/app_service/public/cpp/app_update_unittest.cc b/components/services/app_service/public/cpp/app_update_unittest.cc
index 6347d40..be14ac7 100644
--- a/components/services/app_service/public/cpp/app_update_unittest.cc
+++ b/components/services/app_service/public/cpp/app_update_unittest.cc
@@ -93,6 +93,8 @@
 
   absl::optional<bool> expect_show_in_management_;
 
+  absl::optional<bool> expect_handles_intents_;
+
   AccountId account_id_ = AccountId::FromUserEmail("test@gmail.com");
 
   void CheckExpects(const AppUpdate& u) {
@@ -144,6 +146,8 @@
 
     EXPECT_EQ(expect_show_in_management_, u.GetShowInManagement());
 
+    EXPECT_EQ(expect_handles_intents_, u.GetHandlesIntents());
+
     EXPECT_EQ(account_id_, u.AccountId());
   }
 
@@ -175,6 +179,7 @@
     expect_show_in_shelf_ = absl::nullopt;
     expect_show_in_search_ = absl::nullopt;
     expect_show_in_management_ = absl::nullopt;
+    expect_handles_intents_ = absl::nullopt;
     CheckExpects(u);
 
     if (delta) {
@@ -620,6 +625,26 @@
       EXPECT_EQ(expect_show_in_management_, state->show_in_management);
       CheckExpects(u);
     }
+
+    // HandlesIntents tests.
+
+    if (state) {
+      state->handles_intents = false;
+      expect_handles_intents_ = false;
+      CheckExpects(u);
+    }
+
+    if (delta) {
+      delta->handles_intents = true;
+      expect_handles_intents_ = true;
+      CheckExpects(u);
+    }
+
+    if (state) {
+      apps::AppUpdate::Merge(state, delta);
+      EXPECT_EQ(expect_handles_intents_, state->handles_intents);
+      CheckExpects(u);
+    }
   }
 };
 
diff --git a/components/services/quarantine/BUILD.gn b/components/services/quarantine/BUILD.gn
index 4411ebb..d8d69e69 100644
--- a/components/services/quarantine/BUILD.gn
+++ b/components/services/quarantine/BUILD.gn
@@ -27,7 +27,6 @@
 
   if (is_win) {
     sources += [ "quarantine_win.cc" ]
-    deps += [ "//components/services/quarantine/public/cpp:features" ]
   }
 
   if (is_mac) {
@@ -136,7 +135,6 @@
 
   if (is_win) {
     sources += [ "quarantine_win_unittest.cc" ]
-    deps += [ "//components/services/quarantine/public/cpp:features" ]
   }
 
   if (is_mac) {
diff --git a/components/services/quarantine/README.md b/components/services/quarantine/README.md
index 8caf099c..b23584c 100644
--- a/components/services/quarantine/README.md
+++ b/components/services/quarantine/README.md
@@ -1,6 +1,4 @@
 Quarantine service to scan/mark a downloaded file with a mark-of-the-web.
 
-The service will run in browser process except for Windows
-with kOutOfProcessQuarantine flag set, where will run in a utility process
-
-TODO: Implement, add call sites, and refactor components/download/quarantine.
+The service will run in browser process except for Windows, where will run in a
+utility process
diff --git a/components/services/quarantine/public/cpp/BUILD.gn b/components/services/quarantine/public/cpp/BUILD.gn
deleted file mode 100644
index 40fab13..0000000
--- a/components/services/quarantine/public/cpp/BUILD.gn
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2019 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.
-
-import("//mojo/public/tools/bindings/mojom.gni")
-
-if (is_win) {
-  source_set("features") {
-    sources = [
-      "quarantine_features_win.cc",
-      "quarantine_features_win.h",
-    ]
-
-    public_deps = [ "//base" ]
-  }
-}
diff --git a/components/services/quarantine/public/cpp/quarantine_features_win.cc b/components/services/quarantine/public/cpp/quarantine_features_win.cc
deleted file mode 100644
index 47bf5a47..0000000
--- a/components/services/quarantine/public/cpp/quarantine_features_win.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2019 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 "components/services/quarantine/public/cpp/quarantine_features_win.h"
-
-namespace quarantine {
-
-// This feature controls whether the quarantine service should run in
-// the browser process or a new utility process.
-// Unused until quarantine service is fully implemented.
-const base::Feature kOutOfProcessQuarantine{"OutOfProcessQuarantine",
-                                            base::FEATURE_ENABLED_BY_DEFAULT};
-
-}  // namespace quarantine
diff --git a/components/services/quarantine/public/cpp/quarantine_features_win.h b/components/services/quarantine/public/cpp/quarantine_features_win.h
deleted file mode 100644
index b97fd1e6..0000000
--- a/components/services/quarantine/public/cpp/quarantine_features_win.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2019 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 COMPONENTS_SERVICES_QUARANTINE_PUBLIC_CPP_QUARANTINE_FEATURES_WIN_H_
-#define COMPONENTS_SERVICES_QUARANTINE_PUBLIC_CPP_QUARANTINE_FEATURES_WIN_H_
-
-#include "base/feature_list.h"
-
-namespace quarantine {
-
-extern const base::Feature kOutOfProcessQuarantine;
-
-}  // namespace quarantine
-
-#endif  // COMPONENTS_SERVICES_QUARANTINE_PUBLIC_CPP_QUARANTINE_FEATURES_WIN_H_
diff --git a/components/services/quarantine/quarantine_win.cc b/components/services/quarantine/quarantine_win.cc
index e4cd1da3..010bb33 100644
--- a/components/services/quarantine/quarantine_win.cc
+++ b/components/services/quarantine/quarantine_win.cc
@@ -29,7 +29,6 @@
 #include "base/win/windows_version.h"
 #include "components/services/quarantine/common.h"
 #include "components/services/quarantine/common_win.h"
-#include "components/services/quarantine/public/cpp/quarantine_features_win.h"
 #include "url/gurl.h"
 
 namespace quarantine {
diff --git a/components/services/quarantine/quarantine_win_unittest.cc b/components/services/quarantine/quarantine_win_unittest.cc
index 3c38a6c2..12540ae 100644
--- a/components/services/quarantine/quarantine_win_unittest.cc
+++ b/components/services/quarantine/quarantine_win_unittest.cc
@@ -19,7 +19,6 @@
 #include "base/win/scoped_com_initializer.h"
 #include "base/win/win_util.h"
 #include "base/win/windows_version.h"
-#include "components/services/quarantine/public/cpp/quarantine_features_win.h"
 #include "components/services/quarantine/quarantine.h"
 #include "components/services/quarantine/test_support.h"
 #include "net/base/filename_util.h"
diff --git a/components/sync/driver/BUILD.gn b/components/sync/driver/BUILD.gn
index d78908a..3608ed36 100644
--- a/components/sync/driver/BUILD.gn
+++ b/components/sync/driver/BUILD.gn
@@ -92,7 +92,6 @@
     "//base",
     "//base:i18n",
     "//build:chromeos_buildflags",
-    "//components/data_use_measurement/core",
     "//components/invalidation/impl:feature_list",
     "//components/keyed_service/core",
     "//components/metrics",
diff --git a/components/test/data/data_reduction_proxy/DIR_METADATA b/components/test/data/data_reduction_proxy/DIR_METADATA
deleted file mode 100644
index eb96fa3..0000000
--- a/components/test/data/data_reduction_proxy/DIR_METADATA
+++ /dev/null
@@ -1 +0,0 @@
-mixins: "//components/data_reduction_proxy/COMMON_METADATA"
diff --git a/components/test/data/data_reduction_proxy/OWNERS b/components/test/data/data_reduction_proxy/OWNERS
deleted file mode 100644
index 2783dea..0000000
--- a/components/test/data/data_reduction_proxy/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file://components/data_reduction_proxy/OWNERS
diff --git a/components/test/data/data_reduction_proxy/direct/block10.html b/components/test/data/data_reduction_proxy/direct/block10.html
deleted file mode 100644
index ce01362..0000000
--- a/components/test/data/data_reduction_proxy/direct/block10.html
+++ /dev/null
@@ -1 +0,0 @@
-hello
diff --git a/components/test/data/data_reduction_proxy/direct/block10.html.mock-http-headers b/components/test/data/data_reduction_proxy/direct/block10.html.mock-http-headers
deleted file mode 100644
index be8f7b5..0000000
--- a/components/test/data/data_reduction_proxy/direct/block10.html.mock-http-headers
+++ /dev/null
@@ -1,3 +0,0 @@
-HTTP/1.1 200 OK
-Content-Type: text/html
-Content-Length: 5
diff --git a/components/test/data/data_reduction_proxy/direct/noblock.html b/components/test/data/data_reduction_proxy/direct/noblock.html
deleted file mode 100644
index 3e00020..0000000
--- a/components/test/data/data_reduction_proxy/direct/noblock.html
+++ /dev/null
@@ -1 +0,0 @@
-wrong server
diff --git a/components/test/data/data_reduction_proxy/direct/noblock.html.mock-http-headers b/components/test/data/data_reduction_proxy/direct/noblock.html.mock-http-headers
deleted file mode 100644
index 15c92bd0..0000000
--- a/components/test/data/data_reduction_proxy/direct/noblock.html.mock-http-headers
+++ /dev/null
@@ -1,3 +0,0 @@
-HTTP/1.1 200 OK
-Content-Type: text/html
-Content-Length: 12
diff --git a/components/test/data/data_reduction_proxy/proxy/block10.html b/components/test/data/data_reduction_proxy/proxy/block10.html
deleted file mode 100644
index 7d70e80..0000000
--- a/components/test/data/data_reduction_proxy/proxy/block10.html
+++ /dev/null
@@ -1 +0,0 @@
-proxy sent bypass
diff --git a/components/test/data/data_reduction_proxy/proxy/block10.html.mock-http-headers b/components/test/data/data_reduction_proxy/proxy/block10.html.mock-http-headers
deleted file mode 100644
index d43d505..0000000
--- a/components/test/data/data_reduction_proxy/proxy/block10.html.mock-http-headers
+++ /dev/null
@@ -1,5 +0,0 @@
-HTTP/1.1 502 Bad Gateway
-Content-Type: text/html
-Chrome-Proxy: block=10
-Content-Length: 17
-Via: 1.1 Chrome-Compression-Proxy
diff --git a/components/test/data/data_reduction_proxy/proxy/noblock.html b/components/test/data/data_reduction_proxy/proxy/noblock.html
deleted file mode 100644
index ce01362..0000000
--- a/components/test/data/data_reduction_proxy/proxy/noblock.html
+++ /dev/null
@@ -1 +0,0 @@
-hello
diff --git a/components/test/data/data_reduction_proxy/proxy/noblock.html.mock-http-headers b/components/test/data/data_reduction_proxy/proxy/noblock.html.mock-http-headers
deleted file mode 100644
index e6bf989..0000000
--- a/components/test/data/data_reduction_proxy/proxy/noblock.html.mock-http-headers
+++ /dev/null
@@ -1,4 +0,0 @@
-HTTP/1.1 200 OK
-Content-Type: text/html
-Content-Length: 5
-Via: 1.1 Chrome-Compression-Proxy
diff --git a/components/viz/service/display/overlay_processor_using_strategy.h b/components/viz/service/display/overlay_processor_using_strategy.h
index a4220a74..eb9b728 100644
--- a/components/viz/service/display/overlay_processor_using_strategy.h
+++ b/components/viz/service/display/overlay_processor_using_strategy.h
@@ -314,7 +314,8 @@
   void LogCheckOverlaySupportMetrics();
 
   struct ProposedCandidateKey {
-    OverlayCandidate::TrackingId tracking_id;
+    OverlayCandidate::TrackingId tracking_id =
+        OverlayCandidate::kDefaultTrackingId;
     OverlayStrategy strategy_id = OverlayStrategy::kUnknown;
 
     bool operator==(const ProposedCandidateKey& other) const {
diff --git a/components/viz/service/display_embedder/output_presenter.h b/components/viz/service/display_embedder/output_presenter.h
index e06f81b..f7314a2 100644
--- a/components/viz/service/display_embedder/output_presenter.h
+++ b/components/viz/service/display_embedder/output_presenter.h
@@ -111,7 +111,9 @@
   virtual void ScheduleOverlays(SkiaOutputSurface::OverlayList overlays,
                                 std::vector<ScopedOverlayAccess*> accesses) = 0;
   virtual void ScheduleBackground(Image* image);
+#if BUILDFLAG(IS_MAC)
   virtual void SetCALayerErrorCode(gfx::CALayerResult ca_layer_error_code) {}
+#endif
 };
 
 }  // namespace viz
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 908856b..11e16f0b 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2394,7 +2394,9 @@
     deps += [
       "//third_party/abseil-cpp:absl",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics",
+      "//third_party/fuchsia-sdk/sdk/pkg/inspect",
       "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
+      "//third_party/fuchsia-sdk/sdk/pkg/sys_inspect_cpp",
       "//third_party/fuchsia-sdk/sdk/pkg/zx",
       "//ui/accessibility",
     ]
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm b/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm
index e1976cc..6f610fb8 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm
+++ b/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm
@@ -644,4 +644,22 @@
 )~~");
 }
 
+IN_PROC_BROWSER_TEST_F(AccessibilityTreeFormatterMacBrowserTest,
+                       Script_Accessibility_API) {
+  TestScript(R"~~(data:text/html,
+                    <button id='b'></button>)~~",
+             {"b.accessibilityRole"},
+             R"~~(b.accessibilityRole='AXButton'
+)~~");
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityTreeFormatterMacBrowserTest,
+                       Script_Accessibility_API_With_Argument) {
+  TestScript(R"~~(data:text/html,
+                    <button id='b'></button>)~~",
+             {"b.accessibilityAttributeValue(AXRole)"},
+             R"~~(b.accessibilityAttributeValue(AXRole)='AXButton'
+)~~");
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index 62c3bbae..cbeaa1d 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -4470,8 +4470,8 @@
   Microsoft::WRL::ComPtr<IAccessible> document(GetRendererAccessible());
   std::vector<base::win::ScopedVariant> document_children =
       GetAllAccessibleChildren(document.Get());
-  // There are two treegrids in this test file. Use only the first one.
-  ASSERT_EQ(2u, document_children.size());
+  // There are three treegrids in this test file. Use only the first one.
+  ASSERT_EQ(3u, document_children.size());
 
   Microsoft::WRL::ComPtr<IAccessible2> table;
   ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index 5842382..d7e376b 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -260,14 +260,6 @@
       wcax->AnnounceLiveRegionText(text);
       break;
     }
-    case ui::AXEventGenerator::Event::LOAD_COMPLETE:
-      if (node->manager() == GetRootManager()) {
-        auto* android_focused =
-            static_cast<BrowserAccessibilityAndroid*>(GetFocus());
-        if (android_focused)
-          wcax->HandlePageLoaded(android_focused->unique_id());
-      }
-      break;
     case ui::AXEventGenerator::Event::RANGE_VALUE_CHANGED:
       DCHECK(android_node->GetData().IsRangeValueSupported());
       if (android_node->IsSlider())
@@ -330,6 +322,7 @@
     case ui::AXEventGenerator::Event::LIVE_REGION_CREATED:
     case ui::AXEventGenerator::Event::LIVE_RELEVANT_CHANGED:
     case ui::AXEventGenerator::Event::LIVE_STATUS_CHANGED:
+    case ui::AXEventGenerator::Event::LOAD_COMPLETE:
     case ui::AXEventGenerator::Event::LOAD_START:
     case ui::AXEventGenerator::Event::MENU_POPUP_END:
     case ui::AXEventGenerator::Event::MENU_POPUP_START:
diff --git a/content/browser/accessibility/browser_accessibility_manager_fuchsia.cc b/content/browser/accessibility/browser_accessibility_manager_fuchsia.cc
index aa25401..d3c8c9b 100644
--- a/content/browser/accessibility/browser_accessibility_manager_fuchsia.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_fuchsia.cc
@@ -4,6 +4,8 @@
 
 #include "content/browser/accessibility/browser_accessibility_manager_fuchsia.h"
 
+#include <lib/sys/inspect/cpp/component.h>
+
 #include "content/browser/accessibility/browser_accessibility_fuchsia.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_registry.h"
@@ -29,6 +31,20 @@
     BrowserAccessibilityDelegate* delegate)
     : BrowserAccessibilityManager(delegate) {
   Initialize(initial_tree);
+
+  ui::AccessibilityBridgeFuchsia* accessibility_bridge =
+      GetAccessibilityBridge();
+  if (accessibility_bridge) {
+    inspect_node_ = accessibility_bridge->GetInspectNode();
+    tree_dump_node_ = inspect_node_.CreateLazyNode("tree-data", [this]() {
+      inspect::Inspector inspector;
+
+      inspector.GetRoot().CreateString(ax_tree_id().ToString(),
+                                       ax_tree()->ToString(), &inspector);
+
+      return fit::make_ok_promise(inspector);
+    });
+  }
 }
 
 BrowserAccessibilityManagerFuchsia::~BrowserAccessibilityManagerFuchsia() =
diff --git a/content/browser/accessibility/browser_accessibility_manager_fuchsia.h b/content/browser/accessibility/browser_accessibility_manager_fuchsia.h
index 39968707..0aa00763 100644
--- a/content/browser/accessibility/browser_accessibility_manager_fuchsia.h
+++ b/content/browser/accessibility/browser_accessibility_manager_fuchsia.h
@@ -5,6 +5,8 @@
 #ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_FUCHSIA_H_
 #define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_FUCHSIA_H_
 
+#include <lib/inspect/cpp/vmo/types.h>
+
 #include "content/browser/accessibility/browser_accessibility_manager.h"
 #include "content/common/content_export.h"
 #include "ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h"
@@ -48,6 +50,12 @@
  private:
   // Accessibility bridge instance to use for tests, if set.
   ui::AccessibilityBridgeFuchsia* accessibility_bridge_for_test_ = nullptr;
+
+  // Node to hold this object fuchsia inspect data.
+  inspect::Node inspect_node_;
+
+  // Node to output a dump of this object's AXTree.
+  inspect::LazyNode tree_dump_node_;
 };
 
 }  // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_manager_fuchsia_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_fuchsia_unittest.cc
index af85fa0..31c39fc 100644
--- a/content/browser/accessibility/browser_accessibility_manager_fuchsia_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_fuchsia_unittest.cc
@@ -77,6 +77,8 @@
     root_node_id_ = root_node_id;
   }
 
+  inspect::Node GetInspectNode() override { return inspect::Node(); }
+
   float GetDeviceScaleFactor() override { return device_scale_factor_; }
 
   void SetDeviceScaleFactor(float device_scale_factor) {
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc
index ace8e70..674d6db 100644
--- a/content/browser/accessibility/web_contents_accessibility_android.cc
+++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -363,14 +363,6 @@
   return Java_WebContentsAccessibilityImpl_shouldExposePasswordText(env, obj);
 }
 
-void WebContentsAccessibilityAndroid::HandlePageLoaded(int32_t unique_id) {
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
-  if (obj.is_null())
-    return;
-  Java_WebContentsAccessibilityImpl_handlePageLoaded(env, obj, unique_id);
-}
-
 void WebContentsAccessibilityAndroid::HandleContentChanged(int32_t unique_id) {
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index 6fb7fc1..6c171c6 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -289,6 +289,8 @@
   RFH_INACTIVE_CHECK_FROM_PENDING_COMMIT_RFH = 262,
   MSDH_INVALID_STREAM_TYPE_COMBINATION = 263,
   AUTH_INVALID_FENCED_FRAME = 264,
+  BIBI_BIND_GAMEPAD_MONITOR_FOR_FENCED_FRAME = 265,
+  BIBI_BIND_GAMEPAD_HAPTICS_MANAGER_FOR_FENCED_FRAME = 266,
 
   // Please add new elements here. The naming convention is abbreviated class
   // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index 8c797ba2..9c238de 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -676,6 +676,35 @@
                              std::move(receiver));
 }
 
+void BindGamepadMonitor(
+    RenderFrameHostImpl* frame,
+    mojo::PendingReceiver<device::mojom::GamepadMonitor> receiver) {
+  // TODO(https://crbug.com/1011006): Remove fenced frame specific code when
+  // permission policy implements the Gamepad API support.
+  if (frame->IsNestedWithinFencedFrame()) {
+    bad_message::ReceivedBadMessage(
+        frame->GetProcess(), bad_message::BadMessageReason::
+                                 BIBI_BIND_GAMEPAD_MONITOR_FOR_FENCED_FRAME);
+    return;
+  }
+  device::GamepadMonitor::Create(std::move(receiver));
+}
+
+void BindGamepadHapticsManager(
+    RenderFrameHostImpl* frame,
+    mojo::PendingReceiver<device::mojom::GamepadHapticsManager> receiver) {
+  // TODO(https://crbug.com/1011006): Remove fenced frame specific code when
+  // permission policy implements the Gamepad API support.
+  if (frame->IsNestedWithinFencedFrame()) {
+    bad_message::ReceivedBadMessage(
+        frame->GetProcess(),
+        bad_message::BadMessageReason::
+            BIBI_BIND_GAMEPAD_HAPTICS_MANAGER_FOR_FENCED_FRAME);
+    return;
+  }
+  device::GamepadHapticsManager::Create(std::move(receiver));
+}
+
 }  // namespace
 
 // Documents/frames
@@ -736,7 +765,7 @@
   }
 
   map->Add<device::mojom::GamepadHapticsManager>(
-      base::BindRepeating(&device::GamepadHapticsManager::Create));
+      base::BindRepeating(&BindGamepadHapticsManager, base::Unretained(host)));
 
   map->Add<blink::mojom::GeolocationService>(base::BindRepeating(
       &RenderFrameHostImpl::GetGeolocationService, base::Unretained(host)));
@@ -847,7 +876,7 @@
           {base::MayBlock(), base::TaskPriority::USER_VISIBLE}));
 
   map->Add<device::mojom::GamepadMonitor>(
-      base::BindRepeating(&device::GamepadMonitor::Create));
+      base::BindRepeating(&BindGamepadMonitor, base::Unretained(host)));
 
   map->Add<device::mojom::SensorProvider>(base::BindRepeating(
       &RenderFrameHostImpl::GetSensorProvider, base::Unretained(host)));
diff --git a/content/browser/cross_origin_opener_policy_browsertest.cc b/content/browser/cross_origin_opener_policy_browsertest.cc
index dee5ff87..0d878b5 100644
--- a/content/browser/cross_origin_opener_policy_browsertest.cc
+++ b/content/browser/cross_origin_opener_policy_browsertest.cc
@@ -65,9 +65,18 @@
   return coop;
 }
 
+network::CrossOriginOpenerPolicy CoopSameOriginAllowPopupsPlusCoep() {
+  network::CrossOriginOpenerPolicy coop;
+  coop.value = network::mojom::CrossOriginOpenerPolicyValue::
+      kSameOriginAllowPopupsPlusCoep;
+  coop.soap_by_default_value = network::mojom::CrossOriginOpenerPolicyValue::
+      kSameOriginAllowPopupsPlusCoep;
+  return coop;
+}
+
 // This is the value of COOP when navigating to a page without COOP set:
 //  - value is kUnsafeNone
-//  - soap_by_default_value is kSameOriginPlusCoep
+//  - soap_by_default_value is kSameOriginAllowPopups
 network::CrossOriginOpenerPolicy CoopUnsafeNoneWithSoapByDefault() {
   network::CrossOriginOpenerPolicy coop;
   coop.soap_by_default_value =
@@ -199,6 +208,20 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
+// Same as CrossOriginOpenerPolicyBrowserTest, but enable COOP:SOAPPC.
+// See https://crbug.com/1221127.
+class SameOriginAllowPopupsPlusCoepBrowserTest
+    : public CrossOriginOpenerPolicyBrowserTest {
+ public:
+  SameOriginAllowPopupsPlusCoepBrowserTest() {
+    feature_list_.InitWithFeatures(
+        {network::features::kCoopSameOriginAllowPopupsPlusCoep}, {});
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
 using VirtualBrowsingContextGroupTest = CrossOriginOpenerPolicyBrowserTest;
 using SoapByDefaultVirtualBrowsingContextGroupTest =
     CrossOriginOpenerPolicyBrowserTest;
@@ -3333,6 +3356,9 @@
 INSTANTIATE_TEST_SUITE_P(All,
                          SoapByDefaultVirtualBrowsingContextGroupTest,
                          kTestParams);
+INSTANTIATE_TEST_SUITE_P(All,
+                         SameOriginAllowPopupsPlusCoepBrowserTest,
+                         kTestParams);
 
 IN_PROC_BROWSER_TEST_P(NoSharedArrayBufferByDefault, BaseCase) {
   GURL url = https_server()->GetURL("a.test", "/empty.html");
@@ -4201,4 +4227,20 @@
   EXPECT_NE(group_4, group_1);
 }
 
+IN_PROC_BROWSER_TEST_P(SameOriginAllowPopupsPlusCoepBrowserTest,
+                       CoopSameOriginAllowPopupsPlusCoepIsParsed) {
+  GURL starting_page(https_server()->GetURL(
+      "a.test",
+      "/set-header"
+      "?cross-origin-opener-policy: same-origin-allow-popups"
+      "&cross-origin-embedder-policy: require-corp"));
+  EXPECT_TRUE(NavigateToURL(shell(), starting_page));
+
+  // Verify that COOP:SOAPPC was parsed, and that it correctly enabled cross
+  // origin isolation.
+  EXPECT_EQ(current_frame_host()->cross_origin_opener_policy(),
+            CoopSameOriginAllowPopupsPlusCoep());
+  EXPECT_TRUE(current_frame_host()->GetSiteInstance()->IsCrossOriginIsolated());
+}
+
 }  // namespace content
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
index b89325c..2eca04b7 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -2737,6 +2737,10 @@
     case network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep:
       return protocol::Network::CrossOriginOpenerPolicyValueEnum::
           SameOriginPlusCoep;
+    case network::mojom::CrossOriginOpenerPolicyValue::
+        kSameOriginAllowPopupsPlusCoep:
+      return protocol::Network::CrossOriginOpenerPolicyValueEnum::
+          SameOriginAllowPopupsPlusCoep;
   }
 }
 protocol::Network::CrossOriginEmbedderPolicyValue
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc
index de833914..6346977 100644
--- a/content/browser/interest_group/auction_runner_unittest.cc
+++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -108,7 +108,7 @@
           interestGroupName + 'Signals') {
         throw new Error("wrong perBuyerSignals");
       }
-      if (!auctionSignals.isAuctionSignals)
+      if (auctionSignals !== "auctionSignalsFor " + seller)
         throw new Error("wrong auctionSignals");
       if (hasSignals) {
         if ('extra' in trustedBiddingSignals)
@@ -141,7 +141,7 @@
 
     function reportWin(auctionSignals, perBuyerSignals, sellerSignals,
                        browserSignals) {
-      if (!auctionSignals.isAuctionSignals)
+      if (auctionSignals !== "auctionSignalsFor " + seller)
         throw new Error("wrong auctionSignals");
       if (perBuyerSignals[seller + 'Signals'] !==
           interestGroupName + 'Signals') {
@@ -177,7 +177,7 @@
       if (browserSignals.seller != seller)
          throw new Error("wrong seller");
 
-      sendReportTo("https://buyer-reporting.example.com");
+      sendReportTo("https://buyer-reporting.example.com/" + bid);
     }
   )";
   return base::StringPrintf(
@@ -234,9 +234,8 @@
                         JSON.stringify(adMetadata) + "/" +
                         browserSignals.adComponents);
       }
-      if (auctionConfig.decisionLogicUrl !== decisionLogicUrl) {
+      if (auctionConfig.decisionLogicUrl !== decisionLogicUrl)
         throw new Error("wrong decisionLogicUrl in auctionConfig");
-      }
       // Check `perBuyerSignals` for the first bidder.
       let signals1 = auctionConfig.perBuyerSignals['https://adplatform.com'];
       if (signals1[auctionConfig.seller + 'Signals'] !== 'Ad PlatformSignals')
@@ -260,14 +259,12 @@
       let signals1 = auctionConfig.perBuyerSignals['https://adplatform.com'];
       if (signals1[auctionConfig.seller + 'Signals'] !== 'Ad PlatformSignals')
         throw new Error("Wrong perBuyerSignals in auctionConfig");
-      if (auctionConfig.decisionLogicUrl
-          !== decisionLogicUrl) {
+      if (auctionConfig.decisionLogicUrl !== decisionLogicUrl)
         throw new Error("wrong decisionLogicUrl in auctionConfig");
-      }
       if (browserSignals.topWindowHostname !== 'publisher1.com')
         throw new Error("wrong topWindowHostname in browserSignals");
       if (sendReportUrl)
-        sendReportTo(sendReportUrl);
+        sendReportTo(sendReportUrl + browserSignals.bid);
       return browserSignals;
     }
   )";
@@ -301,7 +298,7 @@
 
 const char kBasicReportResult[] = R"(
   function reportResult(auctionConfig, browserSignals) {
-    sendReportTo("https://reporting.example.com/");
+    sendReportTo("https://reporting.example.com/" + browserSignals.bid);
     return browserSignals;
   }
 )";
@@ -901,6 +898,10 @@
     auction_config->auction_ad_config_non_shared_params->per_buyer_signals =
         std::move(per_buyer_signals);
 
+    auction_config->auction_ad_config_non_shared_params->auction_signals =
+        base::StringPrintf(R"("auctionSignalsFor %s")",
+                           auction_config->seller.Serialize().c_str());
+
     return auction_config;
   }
 
@@ -913,8 +914,7 @@
   // wins will be added in order, with chronologically increasing times within
   // each InterestGroup.
   void StartAuction(const GURL& seller_decision_logic_url,
-                    std::vector<StorageInterestGroup> bidders,
-                    const std::string& auction_signals_json) {
+                    std::vector<StorageInterestGroup> bidders) {
     auction_complete_ = false;
 
     blink::mojom::AuctionAdConfigPtr auction_config =
@@ -922,9 +922,6 @@
 
     auction_config->trusted_scoring_signals_url = trusted_scoring_signals_url_;
 
-    auction_config->auction_ad_config_non_shared_params->auction_signals =
-        auction_signals_json;
-
     interest_group_manager_ = std::make_unique<InterestGroupManagerImpl>(
         base::FilePath(), /*in_memory=*/true,
         /*url_loader_factory=*/nullptr);
@@ -970,10 +967,8 @@
   }
 
   const Result& RunAuctionAndWait(const GURL& seller_decision_logic_url,
-                                  std::vector<StorageInterestGroup> bidders,
-                                  const std::string& auction_signals_json) {
-    StartAuction(seller_decision_logic_url, std::move(bidders),
-                 auction_signals_json);
+                                  std::vector<StorageInterestGroup> bidders) {
+    StartAuction(seller_decision_logic_url, std::move(bidders));
     auction_run_loop_->Run();
     return result_;
   }
@@ -1100,8 +1095,7 @@
         std::vector<GURL>{GURL("https://ad2.com-component1.com"),
                           GURL("https://ad2.com-component2.com")}));
 
-    StartAuction(kSellerUrl, std::move(bidders),
-                 /*auction_signals_json=*/R"({"isAuctionSignals": true})");
+    StartAuction(kSellerUrl, std::move(bidders));
   }
 
   const Result& RunStandardAuction() {
@@ -1285,8 +1279,7 @@
 // Runs the standard auction, but without adding any interest groups to the
 // manager.
 TEST_F(AuctionRunnerTest, NoInterestGroups) {
-  RunAuctionAndWait(kSellerUrl, std::vector<StorageInterestGroup>(),
-                    /*auction_signals_json=*/R"({"isAuctionSignals": true})");
+  RunAuctionAndWait(kSellerUrl, std::vector<StorageInterestGroup>());
 
   EXPECT_FALSE(result_.ad_url);
   EXPECT_FALSE(result_.ad_component_urls);
@@ -1308,8 +1301,7 @@
       kBidder1, kBidder1Name, kBidder1Url, kBidder1TrustedSignalsUrl,
       {"k1", "k2"}, /*ad_url=*/absl::nullopt));
 
-  RunAuctionAndWait(kSellerUrl, std::move(bidders),
-                    /*auction_signals_json=*/R"({"isAuctionSignals": true})");
+  RunAuctionAndWait(kSellerUrl, std::move(bidders));
 
   EXPECT_FALSE(result_.ad_url);
   EXPECT_FALSE(result_.ad_component_urls);
@@ -1331,8 +1323,7 @@
       kBidder1, kBidder1Name, /*bidding_url=*/absl::nullopt,
       kBidder1TrustedSignalsUrl, {"k1", "k2"}, GURL("https://ad1.com")));
 
-  RunAuctionAndWait(kSellerUrl, std::move(bidders),
-                    /*auction_signals_json=*/R"({"isAuctionSignals": true})");
+  RunAuctionAndWait(kSellerUrl, std::move(bidders));
 
   EXPECT_FALSE(result_.ad_url);
   EXPECT_FALSE(result_.ad_component_urls);
@@ -1366,15 +1357,14 @@
       kBidder1, kBidder1Name, kBidder1Url, kBidder1TrustedSignalsUrl,
       {"k1", "k2"}, GURL("https://ad1.com")));
 
-  RunAuctionAndWait(kSellerUrl, std::move(bidders),
-                    /*auction_signals_json=*/R"({"isAuctionSignals": true})");
+  RunAuctionAndWait(kSellerUrl, std::move(bidders));
 
   EXPECT_EQ(GURL("https://ad1.com/"), result_.ad_url);
   EXPECT_FALSE(result_.ad_component_urls);
   EXPECT_THAT(result_.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/1"),
+                  GURL("https://buyer-reporting.example.com/1")));
   EXPECT_EQ(6, result_.bidder1_bid_count);
   ASSERT_EQ(4u, result_.bidder1_prev_wins.size());
   EXPECT_EQ(R"({"render_url":"https://ad1.com/","metadata":{"ads": true}})",
@@ -1423,8 +1413,8 @@
             res.ad_component_urls);
   EXPECT_THAT(res.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/2"),
+                  GURL("https://buyer-reporting.example.com/2")));
   EXPECT_EQ(6, res.bidder1_bid_count);
   EXPECT_EQ(3u, res.bidder1_prev_wins.size());
   EXPECT_EQ(6, res.bidder2_bid_count);
@@ -1576,8 +1566,8 @@
     EXPECT_EQ(GURL("https://ad2.com/"), result_.ad_url);
     EXPECT_THAT(result_.report_urls,
                 testing::UnorderedElementsAre(
-                    GURL("https://reporting.example.com/"),
-                    GURL("https://buyer-reporting.example.com/")));
+                    GURL("https://reporting.example.com/2"),
+                    GURL("https://buyer-reporting.example.com/2")));
   }
 }
 
@@ -1630,8 +1620,8 @@
             result_.ad_component_urls);
   EXPECT_THAT(result_.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/2"),
+                  GURL("https://buyer-reporting.example.com/2")));
   EXPECT_THAT(result_.errors, testing::ElementsAre());
 }
 
@@ -1680,8 +1670,8 @@
             result_.ad_component_urls);
   EXPECT_THAT(result_.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/2"),
+                  GURL("https://buyer-reporting.example.com/2")));
   EXPECT_THAT(result_.errors, testing::ElementsAre());
 }
 
@@ -1760,8 +1750,8 @@
             result_.ad_component_urls);
   EXPECT_THAT(result_.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/1"),
+                  GURL("https://buyer-reporting.example.com/1")));
   EXPECT_EQ(6, result_.bidder1_bid_count);
   ASSERT_EQ(4u, result_.bidder1_prev_wins.size());
   EXPECT_EQ(R"({"render_url":"https://ad1.com/","metadata":{"ads": true}})",
@@ -1837,8 +1827,8 @@
             res.ad_component_urls);
   EXPECT_THAT(res.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/1"),
+                  GURL("https://buyer-reporting.example.com/1")));
   EXPECT_EQ(6, res.bidder1_bid_count);
   ASSERT_EQ(4u, res.bidder1_prev_wins.size());
   EXPECT_EQ(R"({"render_url":"https://ad1.com/","metadata":{"ads": true}})",
@@ -1895,8 +1885,8 @@
             res.ad_component_urls);
   EXPECT_THAT(res.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/1"),
+                  GURL("https://buyer-reporting.example.com/1")));
   EXPECT_EQ(6, res.bidder1_bid_count);
   ASSERT_EQ(4u, res.bidder1_prev_wins.size());
   EXPECT_EQ(R"({"render_url":"https://ad1.com/","metadata":{"ads": true}})",
@@ -2051,8 +2041,8 @@
             res.ad_component_urls);
   EXPECT_THAT(res.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/1"),
+                  GURL("https://buyer-reporting.example.com/1")));
   EXPECT_EQ(6, res.bidder1_bid_count);
   ASSERT_EQ(4u, res.bidder1_prev_wins.size());
   EXPECT_EQ(R"({"render_url":"https://ad1.com/","metadata":{"ads": true}})",
@@ -2110,16 +2100,14 @@
                                          absl::nullopt, {"l1", "l2"},
                                          GURL("https://ad2.com")));
 
-  const Result& res = RunAuctionAndWait(
-      kSellerUrl, std::move(bidders),
-      /*auction_signals_json=*/R"({"isAuctionSignals": true})");
+  const Result& res = RunAuctionAndWait(kSellerUrl, std::move(bidders));
 
   EXPECT_EQ(GURL("https://ad2.com/"), res.ad_url);
   EXPECT_FALSE(result_.ad_component_urls);
   EXPECT_THAT(res.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/2"),
+                  GURL("https://buyer-reporting.example.com/2")));
   EXPECT_EQ(6, res.bidder1_bid_count);
   EXPECT_EQ(3u, res.bidder1_prev_wins.size());
   EXPECT_EQ(6, res.bidder2_bid_count);
@@ -2158,8 +2146,8 @@
             res.ad_component_urls);
   EXPECT_THAT(res.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/2"),
+                  GURL("https://buyer-reporting.example.com/2")));
   EXPECT_EQ(6, res.bidder1_bid_count);
   EXPECT_EQ(3u, res.bidder1_prev_wins.size());
   EXPECT_EQ(6, res.bidder2_bid_count);
@@ -2207,7 +2195,7 @@
   EXPECT_EQ(std::vector<GURL>{GURL("https://ad2.com-component1.com")},
             res.ad_component_urls);
   EXPECT_THAT(res.report_urls, testing::UnorderedElementsAre(GURL(
-                                   "https://buyer-reporting.example.com/")));
+                                   "https://buyer-reporting.example.com/2")));
   EXPECT_EQ(6, res.bidder1_bid_count);
   EXPECT_EQ(3u, res.bidder1_prev_wins.size());
   EXPECT_EQ(6, res.bidder2_bid_count);
@@ -2249,7 +2237,7 @@
   EXPECT_EQ(std::vector<GURL>{GURL("https://ad2.com-component1.com")},
             res.ad_component_urls);
   EXPECT_THAT(res.report_urls, testing::UnorderedElementsAre(
-                                   GURL("https://reporting.example.com/")));
+                                   GURL("https://reporting.example.com/2")));
   EXPECT_EQ(6, res.bidder1_bid_count);
   EXPECT_EQ(3u, res.bidder1_prev_wins.size());
   EXPECT_EQ(6, res.bidder2_bid_count);
@@ -2412,8 +2400,8 @@
             result_.ad_component_urls);
   EXPECT_THAT(result_.report_urls,
               testing::UnorderedElementsAre(
-                  GURL("https://reporting.example.com/"),
-                  GURL("https://buyer-reporting.example.com/")));
+                  GURL("https://reporting.example.com/1"),
+                  GURL("https://buyer-reporting.example.com/1")));
   EXPECT_EQ(6, result_.bidder1_bid_count);
   EXPECT_EQ(4u, result_.bidder1_prev_wins.size());
   EXPECT_EQ(R"({"render_url":"https://ad1.com/","metadata":{"ads": true}})",
@@ -2553,8 +2541,8 @@
                 result_.ad_component_urls);
       EXPECT_THAT(result_.report_urls,
                   testing::UnorderedElementsAre(
-                      GURL("https://reporting.example.com/"),
-                      GURL("https://buyer-reporting.example.com/")));
+                      GURL("https://reporting.example.com/2"),
+                      GURL("https://buyer-reporting.example.com/2")));
       EXPECT_EQ(6, result_.bidder1_bid_count);
       EXPECT_EQ(3u, result_.bidder1_prev_wins.size());
       EXPECT_EQ(6, result_.bidder2_bid_count);
@@ -2676,8 +2664,7 @@
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          kSellerScript);
 
-  StartAuction(kSellerUrl, std::move(bidders),
-               /*auction_signals_json=*/"null");
+  StartAuction(kSellerUrl, std::move(bidders));
   auction_run_loop_->Run();
   EXPECT_TRUE(auction_complete_);
 
@@ -3016,8 +3003,7 @@
                           kBidder1TrustedSignalsUrl, {"k1", "k2"}, kRenderUrl,
                           /*ad_component_urls=*/absl::nullopt));
 
-    StartAuction(kSellerUrl, std::move(bidders),
-                 /*auction_signals_json=*/"{}");
+    StartAuction(kSellerUrl, std::move(bidders));
 
     mock_auction_process_manager_->WaitForWorklets(/*num_bidders=*/1);
 
@@ -3098,8 +3084,7 @@
         kBidder1, kBidder1Name, kBidder1Url, kBidder1TrustedSignalsUrl,
         {"k1", "k2"}, kRenderUrl, ad_component_urls));
 
-    StartAuction(kSellerUrl, std::move(bidders),
-                 /*auction_signals_json=*/"{}");
+    StartAuction(kSellerUrl, std::move(bidders));
 
     mock_auction_process_manager_->WaitForWorklets(/*num_bidders=*/1);
 
diff --git a/content/browser/media/media_internals.cc b/content/browser/media/media_internals.cc
index 033120d..164e040 100644
--- a/content/browser/media/media_internals.cc
+++ b/content/browser/media/media_internals.cc
@@ -102,6 +102,12 @@
       return "ac3";
     case media::AudioParameters::AUDIO_BITSTREAM_EAC3:
       return "eac3";
+    case media::AudioParameters::AUDIO_BITSTREAM_DTS:
+      return "dts";
+    case media::AudioParameters::AUDIO_BITSTREAM_DTS_HD:
+      return "dtshd";
+    case media::AudioParameters::AUDIO_BITSTREAM_IEC61937:
+      return "iec61937";
     case media::AudioParameters::AUDIO_FAKE:
       return "fake";
   }
diff --git a/content/browser/net/cross_origin_opener_policy_reporter.cc b/content/browser/net/cross_origin_opener_policy_reporter.cc
index 812bde9..10619bd 100644
--- a/content/browser/net/cross_origin_opener_policy_reporter.cc
+++ b/content/browser/net/cross_origin_opener_policy_reporter.cc
@@ -54,6 +54,9 @@
       return "same-origin-allow-popups";
     case network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep:
       return "same-origin-plus-coep";
+    case network::mojom::CrossOriginOpenerPolicyValue::
+        kSameOriginAllowPopupsPlusCoep:
+      return "same-origin-allow-popups-plus-coep";
   }
 }
 
diff --git a/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc b/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
index 9d7543d1..8eb2316 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
+++ b/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
@@ -5,6 +5,7 @@
 #include "base/bind.h"
 #include "base/run_loop.h"
 #include "base/task/post_task.h"
+#include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
@@ -100,6 +101,27 @@
     navigation_ids_.push_back(navigation_handle->GetNavigationId());
   }
 
+  void NavigateAndWaitForDisablingFeature(
+      const GURL& url,
+      blink::scheduler::WebSchedulerTrackedFeature feature) {
+    base::RunLoop run_loop;
+    current_frame_host()
+        ->SetBackForwardCacheDisablingFeaturesCallbackForTesting(
+            base::BindLambdaForTesting(
+                [&run_loop, feature](
+                    blink::scheduler::WebSchedulerTrackedFeatures features) {
+                  if (features.Has(feature))
+                    run_loop.Quit();
+                }));
+    EXPECT_TRUE(NavigateToURL(shell(), url));
+    run_loop.Run();
+
+    EXPECT_EQ(base::Difference(
+                  current_frame_host()->GetBackForwardCacheDisablingFeatures(),
+                  kFeaturesToIgnore),
+              blink::scheduler::WebSchedulerTrackedFeatures(feature));
+  }
+
   std::vector<int64_t> navigation_ids_;
 
  private:
@@ -614,16 +636,9 @@
   const GURL url(embedded_test_server()->GetURL(
       "/back_forward_cache/page_with_dedicated_worker.html"));
 
-  EXPECT_TRUE(NavigateToURL(shell(), url));
-
-  EXPECT_EQ(
-      base::Difference(static_cast<WebContentsImpl*>(shell()->web_contents())
-                           ->GetMainFrame()
-                           ->GetBackForwardCacheDisablingFeatures(),
-                       kFeaturesToIgnore),
-      blink::scheduler::WebSchedulerTrackedFeatures(
-          blink::scheduler::WebSchedulerTrackedFeature::
-              kDedicatedWorkerOrWorklet));
+  NavigateAndWaitForDisablingFeature(
+      url,
+      blink::scheduler::WebSchedulerTrackedFeature::kDedicatedWorkerOrWorklet);
 }
 
 // TODO(https://crbug.com/154571): Shared workers are not available on Android.
@@ -636,15 +651,8 @@
   const GURL url(embedded_test_server()->GetURL(
       "/back_forward_cache/page_with_shared_worker.html"));
 
-  EXPECT_TRUE(NavigateToURL(shell(), url));
-
-  EXPECT_EQ(
-      base::Difference(static_cast<WebContentsImpl*>(shell()->web_contents())
-                           ->GetMainFrame()
-                           ->GetBackForwardCacheDisablingFeatures(),
-                       kFeaturesToIgnore),
-      blink::scheduler::WebSchedulerTrackedFeatures(
-          blink::scheduler::WebSchedulerTrackedFeature::kSharedWorker));
+  NavigateAndWaitForDisablingFeature(
+      url, blink::scheduler::WebSchedulerTrackedFeature::kSharedWorker);
 }
 
 IN_PROC_BROWSER_TEST_P(BackForwardCacheMetricsBrowserTest, Geolocation) {
diff --git a/content/browser/renderer_host/cross_origin_opener_policy_status.cc b/content/browser/renderer_host/cross_origin_opener_policy_status.cc
index b6cf54c..76e23f6 100644
--- a/content/browser/renderer_host/cross_origin_opener_policy_status.cc
+++ b/content/browser/renderer_host/cross_origin_opener_policy_status.cc
@@ -390,8 +390,15 @@
     network::mojom::URLResponseHead* response_head) const {
   network::CrossOriginOpenerPolicy& coop =
       response_head->parsed_headers->cross_origin_opener_policy;
+
+  // Base COOP class cannot include feature checking due to circular
+  // dependencies. Instead we check it from content and pass it back to the
+  // AugmentCoopWithCoep function.
+  bool is_coop_soap_plus_coep_enabled = base::FeatureList::IsEnabled(
+      network::features::kCoopSameOriginAllowPopupsPlusCoep);
   network::AugmentCoopWithCoep(
-      &coop, response_head->parsed_headers->cross_origin_embedder_policy);
+      &coop, response_head->parsed_headers->cross_origin_embedder_policy,
+      is_coop_soap_plus_coep_enabled);
 
   if (coop == network::CrossOriginOpenerPolicy())
     return;
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index 60db659..02bd332 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -2843,6 +2843,8 @@
     case network::mojom::CrossOriginOpenerPolicyValue::kSameOrigin:
     case network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep:
     case network::mojom::CrossOriginOpenerPolicyValue::kSameOriginAllowPopups:
+    case network::mojom::CrossOriginOpenerPolicyValue::
+        kSameOriginAllowPopupsPlusCoep:
       should_header_value_trigger_isolation = true;
       break;
     case network::mojom::CrossOriginOpenerPolicyValue::kUnsafeNone:
@@ -7313,8 +7315,11 @@
 
   // We consider navigations to be cross-origin isolated if the response
   // asserts proper COOP and COEP headers.
-  if (coop_status().current_coop().value !=
-      network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep) {
+  if ((coop_status().current_coop().value !=
+       network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep) &&
+      (coop_status().current_coop().value !=
+       network::mojom::CrossOriginOpenerPolicyValue::
+           kSameOriginAllowPopupsPlusCoep)) {
     return WebExposedIsolationInfo::CreateNonIsolated();
   }
 
diff --git a/content/browser/renderer_host/navigator.cc b/content/browser/renderer_host/navigator.cc
index bd3bc53..a460f46 100644
--- a/content/browser/renderer_host/navigator.cc
+++ b/content/browser/renderer_host/navigator.cc
@@ -78,6 +78,7 @@
     case CrossOriginOpenerPolicyValue::kSameOriginAllowPopups:
       return WebFeature::kCrossOriginOpenerPolicySameOriginAllowPopups;
     case CrossOriginOpenerPolicyValue::kSameOriginPlusCoep:
+    case CrossOriginOpenerPolicyValue::kSameOriginAllowPopupsPlusCoep:
       return WebFeature::kCoopAndCoepIsolated;
   }
 }
@@ -94,6 +95,7 @@
       return WebFeature::
           kCrossOriginOpenerPolicySameOriginAllowPopupsReportOnly;
     case CrossOriginOpenerPolicyValue::kSameOriginPlusCoep:
+    case CrossOriginOpenerPolicyValue::kSameOriginAllowPopupsPlusCoep:
       return WebFeature::kCoopAndCoepIsolatedReportOnly;
   }
 }
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 5e7eee28..9930040 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -3940,6 +3940,11 @@
       BackForwardCacheDisablingFeatures::FromEnumBitmask(features_mask);
 
   MaybeEvictFromBackForwardCache();
+
+  if (back_forward_cache_disabling_features_callback_for_testing_) {
+    back_forward_cache_disabling_features_callback_for_testing_.Run(
+        renderer_reported_bfcache_disabling_features_);
+  }
 }
 
 using BackForwardCacheDisablingFeatureHandle =
@@ -6694,6 +6699,8 @@
       // See regression: https://crbug.com/1181673
       case network::mojom::CrossOriginOpenerPolicyValue::kUnsafeNone:
       case network::mojom::CrossOriginOpenerPolicyValue::kSameOriginAllowPopups:
+      case network::mojom::CrossOriginOpenerPolicyValue::
+          kSameOriginAllowPopupsPlusCoep:
         break;
 
       // See https://html.spec.whatwg.org/#browsing-context-names (step 8)
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index 0ec77ee..b7726c68 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -1578,6 +1578,13 @@
   BackForwardCacheDisablingFeatures GetBackForwardCacheDisablingFeatures()
       const;
 
+  using BackForwardCacheDisablingFeaturesCallback =
+      base::RepeatingCallback<void(BackForwardCacheDisablingFeatures)>;
+  void SetBackForwardCacheDisablingFeaturesCallbackForTesting(
+      BackForwardCacheDisablingFeaturesCallback callback) {
+    back_forward_cache_disabling_features_callback_for_testing_ = callback;
+  }
+
   // Returns a PrefetchedSignedExchangeCache which is attached to |this|.
   scoped_refptr<PrefetchedSignedExchangeCache>
   EnsurePrefetchedSignedExchangeCache();
@@ -4111,6 +4118,9 @@
   raw_ptr<WebBluetoothServiceImpl> last_web_bluetooth_service_for_testing_ =
       nullptr;
 
+  BackForwardCacheDisablingFeaturesCallback
+      back_forward_cache_disabling_features_callback_for_testing_;
+
   // WeakPtrFactories are the last members, to ensure they are destroyed before
   // all other fields of `this`.
   base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_{this};
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 950fbd61..5cf4fd6 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -183,7 +183,7 @@
  private:
   static const void* UserDataKey() { return &kUserDataKey; }
 
-  static constexpr int kUserDataKey = 0;
+  static const int kUserDataKey = 0;
 
   std::unordered_set<const RenderViewHostImpl*> render_view_host_instances_;
 };
diff --git a/content/browser/scheduler/responsiveness/OWNERS b/content/browser/scheduler/responsiveness/OWNERS
index 987c0c88..3b8e198 100644
--- a/content/browser/scheduler/responsiveness/OWNERS
+++ b/content/browser/scheduler/responsiveness/OWNERS
@@ -1 +1,3 @@
 erikchen@chromium.org
+etienneb@chromium.org
+gab@chromium.org
diff --git a/content/browser/scheduler/responsiveness/calculator.cc b/content/browser/scheduler/responsiveness/calculator.cc
index 7f3c4f68..1f707ea 100644
--- a/content/browser/scheduler/responsiveness/calculator.cc
+++ b/content/browser/scheduler/responsiveness/calculator.cc
@@ -136,9 +136,8 @@
 
 void Calculator::OnFirstIdle() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DCHECK(startup_stage_ == StartupStage::kMessageLoopJustStarted ||
-         startup_stage_ == StartupStage::kFirstIntervalDoneWithoutFirstIdle);
-  startup_stage_ = StartupStage::kPastFirstIdle;
+  DCHECK(!past_first_idle_);
+  past_first_idle_ = true;
 }
 
 void Calculator::EmitResponsiveness(JankType jank_type,
@@ -153,11 +152,13 @@
       UMA_HISTOGRAM_COUNTS_1000(
           "Browser.Responsiveness.JankyIntervalsPerThirtySeconds",
           janky_slices);
-      if (startup_stage_ == StartupStage::kMessageLoopJustStarted) {
+      // Only kFirstInterval and kPeriodic are reported with a suffix, stages
+      // in between are only part of the unsuffixed histogram.
+      if (startup_stage_ == StartupStage::kFirstInterval) {
         UMA_HISTOGRAM_COUNTS_1000(
             "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial",
             janky_slices);
-      } else if (startup_stage_ == StartupStage::kRecordingPastFirstIdle) {
+      } else if (startup_stage_ == StartupStage::kPeriodic) {
         UMA_HISTOGRAM_COUNTS_1000(
             "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic",
             janky_slices);
@@ -165,14 +166,21 @@
       break;
     }
     case JankType::kQueueAndExecution: {
-      // TODO(gab): Remove JankyIntervalsPerThirtySeconds2 once
-      // JankyIntervalsPerThirtySeconds3 has fully replaced it.
+      // Queuing jank doesn't count before OnFirstIdle().
+      if (startup_stage_ == StartupStage::kFirstInterval ||
+          startup_stage_ == StartupStage::kFirstIntervalDoneWithoutFirstIdle) {
+        break;
+      }
       UMA_HISTOGRAM_CUSTOM_COUNTS(
-          "Browser.Responsiveness.JankyIntervalsPerThirtySeconds2",
+          "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3",
           janky_slices, 1, kMaxJankySlices, 50);
-      if (startup_stage == StartupStage::kRecordingPastFirstIdle) {
+      if (startup_stage_ == StartupStage::kFirstIntervalAfterFirstIdle) {
         UMA_HISTOGRAM_CUSTOM_COUNTS(
-            "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3",
+            "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial",
+            janky_slices, 1, kMaxJankySlices, 50);
+      } else if (startup_stage_ == StartupStage::kPeriodic) {
+        UMA_HISTOGRAM_CUSTOM_COUNTS(
+            "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic",
             janky_slices, 1, kMaxJankySlices, 50);
       }
       break;
@@ -312,10 +320,15 @@
       std::move(queue_and_execution_janks_from_multiple_threads),
       last_calculation_time_, new_calculation_time);
 
-  if (startup_stage_ == StartupStage::kMessageLoopJustStarted)
+  if (startup_stage_ == StartupStage::kFirstInterval)
     startup_stage_ = StartupStage::kFirstIntervalDoneWithoutFirstIdle;
-  else if (startup_stage_ == StartupStage::kPastFirstIdle)
-    startup_stage_ = StartupStage::kRecordingPastFirstIdle;
+
+  if (startup_stage_ == StartupStage::kFirstIntervalDoneWithoutFirstIdle &&
+      past_first_idle_) {
+    startup_stage_ = StartupStage::kFirstIntervalAfterFirstIdle;
+  } else if (startup_stage_ == StartupStage::kFirstIntervalAfterFirstIdle) {
+    startup_stage_ = StartupStage::kPeriodic;
+  }
 
   last_calculation_time_ = new_calculation_time;
 }
@@ -357,7 +370,8 @@
     TRACE_EVENT_CATEGORY_GROUP_ENABLED(kLatencyEventCategory,
                                        &latency_category_enabled);
     if (latency_category_enabled &&
-        startup_stage_ == StartupStage::kRecordingPastFirstIdle) {
+        (startup_stage_ == StartupStage::kFirstIntervalAfterFirstIdle ||
+         startup_stage_ == StartupStage::kPeriodic)) {
       EmitResponsivenessTraceEvents(jank_type, start_time,
                                     current_interval_end_time, janky_slices);
     }
diff --git a/content/browser/scheduler/responsiveness/calculator.h b/content/browser/scheduler/responsiveness/calculator.h
index 19242385..6a667e2 100644
--- a/content/browser/scheduler/responsiveness/calculator.h
+++ b/content/browser/scheduler/responsiveness/calculator.h
@@ -78,17 +78,18 @@
     kQueueAndExecution,
   };
 
-  // Stages of startup used by this Calculator. Public for testing.
+  // Stages of startup used by this Calculator. Stages are defined in
+  // chronological order, some can be skipped. Public for
+  // testing.
   enum class StartupStage {
-    // Initial value.
-    kMessageLoopJustStarted,
-    // First kMeasurementInterval completed but haven't reached OnFirstIdle()
-    // yet.
+    // Monitoring the first interval.
+    kFirstInterval,
+    // First interval completed but it didn't capture OnFirstIdle().
     kFirstIntervalDoneWithoutFirstIdle,
-    // From OnFirstIdle() to the end of the kMeasurementInterval including it.
-    kPastFirstIdle,
-    // From the first kMeasurementInterval after OnFirstIdle() onward.
-    kRecordingPastFirstIdle,
+    // Monitoring the first interval after OnFirstIdle().
+    kFirstIntervalAfterFirstIdle,
+    // All intervals after kFirstIntervalAfterFirstIdle.
+    kPeriodic
   };
 
  protected:
@@ -179,7 +180,8 @@
   bool is_application_visible_ = false;
 #endif
 
-  StartupStage startup_stage_ = StartupStage::kMessageLoopJustStarted;
+  StartupStage startup_stage_ = StartupStage::kFirstInterval;
+  bool past_first_idle_ = false;
 
   // We expect there to be low contention and this lock to cause minimal
   // overhead. If performance of this lock proves to be a problem, we can move
diff --git a/content/browser/scheduler/responsiveness/calculator_unittest.cc b/content/browser/scheduler/responsiveness/calculator_unittest.cc
index d318d59c..f19a849 100644
--- a/content/browser/scheduler/responsiveness/calculator_unittest.cc
+++ b/content/browser/scheduler/responsiveness/calculator_unittest.cc
@@ -4,10 +4,12 @@
 
 #include "content/browser/scheduler/responsiveness/calculator.h"
 
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
 namespace responsiveness {
@@ -23,11 +25,19 @@
 
 class FakeCalculator : public Calculator {
  public:
-  MOCK_METHOD3(EmitResponsiveness,
+  MOCK_METHOD3(EmitResponsivenessMock,
                void(JankType jank_type,
                     size_t janky_slices,
                     StartupStage startup_stage));
 
+  void EmitResponsiveness(JankType jank_type,
+                          size_t janky_slices,
+                          StartupStage startup_stage) override {
+    EmitResponsivenessMock(jank_type, janky_slices, startup_stage);
+    // Emit the histograms anyways for verification in some tests.
+    Calculator::EmitResponsiveness(jank_type, janky_slices, startup_stage);
+  }
+
   MOCK_METHOD3(EmitJankyIntervalsMeasurementTraceEvent,
                void(base::TimeTicks start_time,
                     base::TimeTicks end_time,
@@ -89,12 +99,13 @@
   base::TimeTicks last_calculation_time_;
 };
 
-#define EXPECT_EXECUTION_JANKY_SLICES(num_slices, phase) \
-  EXPECT_CALL(*calculator_,                              \
-              EmitResponsiveness(JankType::kExecution, num_slices, phase));
-#define EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(num_slices, phase)           \
-  EXPECT_CALL(*calculator_, EmitResponsiveness(JankType::kQueueAndExecution, \
-                                               num_slices, phase));
+#define EXPECT_EXECUTION_JANKY_SLICES(num_slices, phase)                 \
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(JankType::kExecution, \
+                                                   num_slices, phase));
+#define EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(num_slices, phase)             \
+  EXPECT_CALL(*calculator_,                                                    \
+              EmitResponsivenessMock(JankType::kQueueAndExecution, num_slices, \
+                                     phase));
 
 // A single event executing slightly longer than kJankThresholdInMs.
 TEST_F(ResponsivenessCalculatorTest, ShortExecutionJank) {
@@ -103,9 +114,8 @@
   constexpr int kFinishTime = kStartTime + kJankThresholdInMs + 5;
 
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
-  EXPECT_EXECUTION_JANKY_SLICES(1u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      1u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -116,9 +126,8 @@
   constexpr int kFinishTime = kStartTime + 5;
 
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
-  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      1u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -130,9 +139,8 @@
   constexpr int kFinishTime = kStartTime + (kJankThresholdInMs / 2) + 1;
 
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
-  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      1u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -143,9 +151,8 @@
   constexpr int kFinishTime = kStartTime + 10 * kJankThresholdInMs + 5;
 
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
-  EXPECT_EXECUTION_JANKY_SLICES(10, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      10u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(10, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(10u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -156,9 +163,8 @@
   constexpr int kFinishTime = kStartTime + 5;
 
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
-  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      10u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(10u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -174,9 +180,8 @@
     AddEventUI(base_time + i, base_time + i, base_time + 2 * i);
   }
 
-  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      0u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -193,9 +198,8 @@
     AddEventUI(base_time + i, base_time + 2 * i, base_time + 2 * i);
   }
 
-  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      0u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -212,9 +216,8 @@
     AddEventUI(queue_time, start_time, finish_time);
   }
 
-  EXPECT_EXECUTION_JANKY_SLICES(1u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      1u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -231,9 +234,8 @@
     AddEventUI(queue_time, start_time, finish_time);
   }
 
-  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      1u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -257,9 +259,8 @@
     AddEventIO(queue_time, start_time, finish_time);
   }
 
-  EXPECT_EXECUTION_JANKY_SLICES(5u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      5u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(5u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(5u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -283,9 +284,8 @@
     AddEventIO(queue_time, start_time, finish_time);
   }
 
-  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      5u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(5u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -309,9 +309,8 @@
     base_time += 10 * kJankThresholdInMs;
   }
 
-  EXPECT_EXECUTION_JANKY_SLICES(6u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      6u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(6u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(6u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -335,9 +334,8 @@
     base_time += 10 * kJankThresholdInMs;
   }
 
-  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      6u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(6u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
@@ -352,10 +350,10 @@
     }
 
     EXPECT_EXECUTION_JANKY_SLICES(
-        9u, i == 0 ? StartupStage::kMessageLoopJustStarted
+        9u, i == 0 ? StartupStage::kFirstInterval
                    : StartupStage::kFirstIntervalDoneWithoutFirstIdle);
     EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-        9u, i == 0 ? StartupStage::kMessageLoopJustStarted
+        9u, i == 0 ? StartupStage::kFirstInterval
                    : StartupStage::kFirstIntervalDoneWithoutFirstIdle);
     TriggerCalculation();
     testing::Mock::VerifyAndClear(calculator_.get());
@@ -369,7 +367,7 @@
   base_time += 10 * kMeasurementIntervalInMs;
   AddEventUI(base_time, base_time, base_time + 1);
 
-  EXPECT_CALL(*calculator_, EmitResponsiveness(_, _, _)).Times(0);
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(_, _, _)).Times(0);
 }
 
 // A long event means that the machine likely went to sleep.
@@ -377,7 +375,7 @@
   int base_time = 105;
   AddEventUI(base_time, base_time, base_time + 10 * kMeasurementIntervalInMs);
 
-  EXPECT_CALL(*calculator_, EmitResponsiveness(_, _, _)).Times(0);
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(_, _, _)).Times(0);
 }
 
 #if BUILDFLAG(IS_ANDROID)
@@ -393,7 +391,7 @@
   base::RunLoop().RunUntilIdle();
 
   AddEventUI(kQueueTime, kStartTime + 1, kFinishTime + 1);
-  EXPECT_CALL(*calculator_, EmitResponsiveness(_, _, _)).Times(0);
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(_, _, _)).Times(0);
   TriggerCalculation();
 }
 #endif
@@ -403,67 +401,150 @@
   constexpr int kStartTime = kQueueTime + 10 * kJankThresholdInMs + 5;
   constexpr int kFinishTime = kStartTime + 5;
 
+  absl::optional<base::HistogramTester> histograms;
+
   // Queue jank event during the first kMeasurementInterval.
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
   EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kExecution, 0,
-                                 StartupStage::kMessageLoopJustStarted));
+              EmitResponsivenessMock(JankType::kExecution, 0,
+                                     StartupStage::kFirstInterval));
   EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kQueueAndExecution, 10u,
-                                 StartupStage::kMessageLoopJustStarted));
+              EmitResponsivenessMock(JankType::kQueueAndExecution, 10u,
+                                     StartupStage::kFirstInterval));
+  histograms.emplace();
   TriggerCalculation();
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds", 0, 1);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial", 0, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic", 0);
 
   // Queue jank event during a few kMeasurementInterval (without having seen
-  // OnFirstIdle()).
+  // OnFirstIdle()). Neither .Initial nor .Periodic
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
   EXPECT_CALL(
       *calculator_,
-      EmitResponsiveness(JankType::kExecution, 0,
-                         StartupStage::kFirstIntervalDoneWithoutFirstIdle));
+      EmitResponsivenessMock(JankType::kExecution, 0,
+                             StartupStage::kFirstIntervalDoneWithoutFirstIdle));
   EXPECT_CALL(
       *calculator_,
-      EmitResponsiveness(JankType::kQueueAndExecution, 10u,
-                         StartupStage::kFirstIntervalDoneWithoutFirstIdle));
+      EmitResponsivenessMock(JankType::kQueueAndExecution, 10u,
+                             StartupStage::kFirstIntervalDoneWithoutFirstIdle));
+  histograms.emplace();
   TriggerCalculation();
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds", 0, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic", 0);
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
   EXPECT_CALL(
       *calculator_,
-      EmitResponsiveness(JankType::kExecution, 0,
-                         StartupStage::kFirstIntervalDoneWithoutFirstIdle));
+      EmitResponsivenessMock(JankType::kExecution, 0,
+                             StartupStage::kFirstIntervalDoneWithoutFirstIdle));
   EXPECT_CALL(
       *calculator_,
-      EmitResponsiveness(JankType::kQueueAndExecution, 10u,
-                         StartupStage::kFirstIntervalDoneWithoutFirstIdle));
+      EmitResponsivenessMock(JankType::kQueueAndExecution, 10u,
+                             StartupStage::kFirstIntervalDoneWithoutFirstIdle));
+  histograms.emplace();
   TriggerCalculation();
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds", 0, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic", 0);
 
-  // OnFirstIdle() eventually during a kMeasurementInterval.
+  // OnFirstIdle() eventually during a kMeasurementInterval. Same as above, last
+  // one of these.
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
   calculator_->OnFirstIdle();
-  EXPECT_CALL(*calculator_, EmitResponsiveness(JankType::kExecution, 0,
-                                               StartupStage::kPastFirstIdle));
-  EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kQueueAndExecution, 10u,
-                                 StartupStage::kPastFirstIdle));
+  EXPECT_CALL(
+      *calculator_,
+      EmitResponsivenessMock(JankType::kExecution, 0,
+                             StartupStage::kFirstIntervalDoneWithoutFirstIdle));
+  EXPECT_CALL(
+      *calculator_,
+      EmitResponsivenessMock(JankType::kQueueAndExecution, 10u,
+                             StartupStage::kFirstIntervalDoneWithoutFirstIdle));
+  histograms.emplace();
   TriggerCalculation();
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds", 0, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic", 0);
 
-  // Events in intervals after OnFirstIdle();
+  // Events in intervals after OnFirstIdle(). Janky3.Initial still no .Periodic.
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
-  EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kExecution, 0,
-                                 StartupStage::kRecordingPastFirstIdle));
-  EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kQueueAndExecution, 10u,
-                                 StartupStage::kRecordingPastFirstIdle));
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(
+                                JankType::kExecution, 0,
+                                StartupStage::kFirstIntervalAfterFirstIdle));
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(
+                                JankType::kQueueAndExecution, 10u,
+                                StartupStage::kFirstIntervalAfterFirstIdle));
+  histograms.emplace();
   TriggerCalculation();
-  AddEventUI(kQueueTime, kStartTime, kFinishTime);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds", 0, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic", 0);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3", 10, 1);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial", 10, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic", 0);
 
+  AddEventUI(kQueueTime, kStartTime, kFinishTime);
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(JankType::kExecution, 0,
+                                                   StartupStage::kPeriodic));
   EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kExecution, 0,
-                                 StartupStage::kRecordingPastFirstIdle));
-  EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kQueueAndExecution, 10u,
-                                 StartupStage::kRecordingPastFirstIdle));
+              EmitResponsivenessMock(JankType::kQueueAndExecution, 10u,
+                                     StartupStage::kPeriodic));
+  histograms.emplace();
   TriggerCalculation();
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds", 0, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial", 0);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic", 0, 1);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3", 10, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial", 0);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic", 10, 1);
 }
 
 TEST_F(ResponsivenessCalculatorTest, FastStartupStages) {
@@ -471,25 +552,76 @@
   constexpr int kStartTime = kQueueTime + 10 * kJankThresholdInMs + 5;
   constexpr int kFinishTime = kStartTime + 5;
 
-  // OnFirstIdle() right away during the first kMeasurementInterval.
+  absl::optional<base::HistogramTester> histograms;
+
+  // OnFirstIdle() right away during the first kMeasurementInterval. Still
+  // considered as kFirstInterval, but second interval will go straight
+  // to kFirstIntervalAfterFirstIdle.
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
   calculator_->OnFirstIdle();
-  EXPECT_CALL(*calculator_, EmitResponsiveness(JankType::kExecution, 0,
-                                               StartupStage::kPastFirstIdle));
   EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kQueueAndExecution, 10u,
-                                 StartupStage::kPastFirstIdle));
+              EmitResponsivenessMock(JankType::kExecution, 0,
+                                     StartupStage::kFirstInterval));
+  EXPECT_CALL(*calculator_,
+              EmitResponsivenessMock(JankType::kQueueAndExecution, 10u,
+                                     StartupStage::kFirstInterval));
+  histograms.emplace();
   TriggerCalculation();
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds", 0, 1);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial", 0, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic", 0);
 
-  // Events in intervals after OnFirstIdle();
   AddEventUI(kQueueTime, kStartTime, kFinishTime);
-  EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kExecution, 0,
-                                 StartupStage::kRecordingPastFirstIdle));
-  EXPECT_CALL(*calculator_,
-              EmitResponsiveness(JankType::kQueueAndExecution, 10u,
-                                 StartupStage::kRecordingPastFirstIdle));
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(
+                                JankType::kExecution, 0,
+                                StartupStage::kFirstIntervalAfterFirstIdle));
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(
+                                JankType::kQueueAndExecution, 10u,
+                                StartupStage::kFirstIntervalAfterFirstIdle));
+  histograms.emplace();
   TriggerCalculation();
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds", 0, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial", 0);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic", 0);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3", 10, 1);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial", 10, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic", 0);
+
+  AddEventUI(kQueueTime, kStartTime, kFinishTime);
+  EXPECT_CALL(*calculator_, EmitResponsivenessMock(JankType::kExecution, 0,
+                                                   StartupStage::kPeriodic));
+  EXPECT_CALL(*calculator_,
+              EmitResponsivenessMock(JankType::kQueueAndExecution, 10u,
+                                     StartupStage::kPeriodic));
+  histograms.emplace();
+  TriggerCalculation();
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds", 0, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Initial", 0);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds.Periodic", 0, 1);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3", 10, 1);
+  histograms->ExpectTotalCount(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Initial", 0);
+  histograms->ExpectUniqueSample(
+      "Browser.Responsiveness.JankyIntervalsPerThirtySeconds3.Periodic", 10, 1);
 }
 
 // An event execution that crosses a measurement interval boundary should count
@@ -504,9 +636,8 @@
   // The event goes from [29801, 30150]. It should count as 1 jank in the first
   // measurement interval and 2 in the second.
   {
-    EXPECT_EXECUTION_JANKY_SLICES(1u, StartupStage::kMessageLoopJustStarted);
-    EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-        1u, StartupStage::kMessageLoopJustStarted);
+    EXPECT_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
+    EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
     const int queue_time =
         kMeasurementIntervalInMs - 2 * kJankThresholdInMs + 1;
     const int start_time = queue_time;
@@ -542,9 +673,8 @@
   // The event goes from [29801, 30150]. It should count as 1 jank in the first
   // measurement interval and 2 in the second.
   {
-    EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kMessageLoopJustStarted);
-    EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-        1u, StartupStage::kMessageLoopJustStarted);
+    EXPECT_EXECUTION_JANKY_SLICES(0u, StartupStage::kFirstInterval);
+    EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(1u, StartupStage::kFirstInterval);
     const int queue_time =
         kMeasurementIntervalInMs - 2 * kJankThresholdInMs + 1;
     const int start_time = kMeasurementIntervalInMs + 1.5 * kJankThresholdInMs;
@@ -593,9 +723,8 @@
   AddEventUI(1050, 1200, 1201);
   AddEventUI(1050, 1390, 1391);
 
-  EXPECT_EXECUTION_JANKY_SLICES(3u, StartupStage::kMessageLoopJustStarted);
-  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(
-      6u, StartupStage::kMessageLoopJustStarted);
+  EXPECT_EXECUTION_JANKY_SLICES(3u, StartupStage::kFirstInterval);
+  EXPECT_QUEUE_AND_EXECUTION_JANKY_SLICES(6u, StartupStage::kFirstInterval);
   TriggerCalculation();
 }
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index d89e1c2..9105069 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2652,10 +2652,6 @@
   prefs.canvas_2d_layers_enabled =
       command_line.HasSwitch(switches::kEnableCanvas2DLayers) ||
       base::FeatureList::IsEnabled(features::kEnableCanvas2DLayers);
-  prefs.canvas_context_lost_in_background_enabled =
-      command_line.HasSwitch(switches::kEnableCanvasContextLostInBackground) ||
-      base::FeatureList::IsEnabled(
-          features::kEnableCanvasContextLostInBackground);
   prefs.new_canvas_2d_api_enabled =
       command_line.HasSwitch(switches::kEnableNewCanvas2DAPI) ||
       base::FeatureList::IsEnabled(features::kEnableNewCanvas2DAPI);
diff --git a/content/browser/webid/idp_network_request_manager.cc b/content/browser/webid/idp_network_request_manager.cc
index f2246fe..37efb34 100644
--- a/content/browser/webid/idp_network_request_manager.cc
+++ b/content/browser/webid/idp_network_request_manager.cc
@@ -103,24 +103,28 @@
         })");
 }
 
+void AddCsrfHeader(network::ResourceRequest* request) {
+  // Using a random 64-bit header value. This is just to keep service
+  // implementations from assuming any particular static value.
+  const int kBytes = 64 / 8;
+  std::string webid_header_value;
+  base::Base64Encode(base::RandBytesAsString(kBytes), &webid_header_value);
+  request->headers.SetHeader(kSecFedCmCsrfHeader, webid_header_value);
+}
+
 std::unique_ptr<network::ResourceRequest> CreateCredentialedResourceRequest(
     GURL target_url,
     url::Origin initiator) {
   auto resource_request = std::make_unique<network::ResourceRequest>();
   auto target_origin = url::Origin::Create(target_url);
   auto site_for_cookies = net::SiteForCookies::FromOrigin(target_origin);
+  AddCsrfHeader(resource_request.get());
   resource_request->request_initiator = initiator;
   resource_request->url = target_url;
   resource_request->site_for_cookies = site_for_cookies;
   resource_request->headers.SetHeader(net::HttpRequestHeaders::kAccept,
                                       kRequestBodyContentType);
 
-  // Using a random 64-bit header value. This is just to keep service
-  // implementations from assuming any particular static value.
-  const int kBytes = 64 / 8;
-  std::string webid_header_value;
-  base::Base64Encode(base::RandBytesAsString(kBytes), &webid_header_value);
-  resource_request->headers.SetHeader(kSecFedCmCsrfHeader, webid_header_value);
   resource_request->credentials_mode =
       network::mojom::CredentialsMode::kInclude;
   resource_request->trusted_params = network::ResourceRequest::TrustedParams();
@@ -835,6 +839,7 @@
       network::mojom::CredentialsMode::kInclude;
   resource_request->headers.SetHeader(net::HttpRequestHeaders::kAccept,
                                       kRequestBodyContentType);
+  AddCsrfHeader(resource_request.get());
   // TODO(kenrb): Not following redirects is important for security because
   // this bypasses CORB. Ensure there is a test added.
   // https://crbug.com/1155312.
diff --git a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
index 4b9d988c..f2ca9c3 100644
--- a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
+++ b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
@@ -194,11 +194,9 @@
   DCHECK(index);
   DCHECK(exists);
   TRACE_EVENT0("dwrite,fonts", "FontProxy::FindFamilyName");
-  base::AutoLock families_lock(families_lock_);
 
   HRESULT hr = S_OK;
-  if (absl::optional<UINT32> family_index =
-          FindFamilyIndexLockRequired(family_name, &hr)) {
+  if (absl::optional<UINT32> family_index = FindFamilyIndex(family_name, &hr)) {
     DCHECK_EQ(hr, S_OK);
     DCHECK_NE(*family_index, UINT32_MAX);
     *index = *family_index;
@@ -211,22 +209,28 @@
   return hr;
 }
 
-absl::optional<UINT32> DWriteFontCollectionProxy::FindFamilyIndexLockRequired(
+absl::optional<UINT32> DWriteFontCollectionProxy::FindFamilyIndex(
     const std::u16string& family_name,
     HRESULT* hresult_out) {
-  auto iter = family_names_.find(family_name);
-  if (iter != family_names_.end()) {
-    if (iter->second != UINT_MAX)
-      return iter->second;
-    return absl::nullopt;
+  {
+    base::AutoLock families_lock(families_lock_);
+    auto iter = family_names_.find(family_name);
+    if (iter != family_names_.end()) {
+      if (iter->second != UINT_MAX)
+        return iter->second;
+      return absl::nullopt;
+    }
+
+    if (base::FeatureList::IsEnabled(kLimitFontFamilyNamesPerRenderer) &&
+        family_names_.size() > kFamilyNamesLimit &&
+        !IsLastResortFontName(family_name)) {
+      return absl::nullopt;
+    }
   }
 
-  if (base::FeatureList::IsEnabled(kLimitFontFamilyNamesPerRenderer) &&
-      family_names_.size() > kFamilyNamesLimit &&
-      !IsLastResortFontName(family_name)) {
-    return absl::nullopt;
-  }
-
+  // Release the lock while making the |FindFamily| sync mojo call. Crash logs
+  // indicate that this may hang, or take long, for offscreen canvas. Releasing
+  // the lock protects the main thread in such case. crbug.com/1289576
   uint32_t family_index = 0;
   if (!GetFontProxy().FindFamily(family_name, &family_index)) {
     LogFontProxyError(FIND_FAMILY_SEND_FAILED);
@@ -234,27 +238,32 @@
       *hresult_out = E_FAIL;
     return absl::nullopt;
   }
-  family_names_[family_name] = family_index;
-  if (UNLIKELY(family_index == UINT32_MAX))
+
+  {
+    base::AutoLock families_lock(families_lock_);
+    DCHECK(family_names_.find(family_name) == family_names_.end() ||
+           family_names_[family_name] == family_index);
+    family_names_[family_name] = family_index;
+    if (UNLIKELY(family_index == UINT32_MAX))
+      return absl::nullopt;
+
+    if (DWriteFontFamilyProxy* family =
+            GetOrCreateFamilyLockRequired(family_index)) {
+      family->SetName(family_name);
+      return family_index;
+    }
+
+    if (hresult_out)
+      *hresult_out = E_FAIL;
     return absl::nullopt;
-
-  if (DWriteFontFamilyProxy* family =
-          GetOrCreateFamilyLockRequired(family_index)) {
-    family->SetName(family_name);
-    return family_index;
   }
-
-  if (hresult_out)
-    *hresult_out = E_FAIL;
-  return absl::nullopt;
 }
 
 DWriteFontFamilyProxy* DWriteFontCollectionProxy::FindFamily(
     const std::u16string& family_name) {
-  base::AutoLock families_lock(families_lock_);
   if (const absl::optional<UINT32> family_index =
-          FindFamilyIndexLockRequired(family_name)) {
-    if (DWriteFontFamilyProxy* family = GetFamilyLockRequired(*family_index))
+          FindFamilyIndex(family_name)) {
+    if (DWriteFontFamilyProxy* family = GetFamily(*family_index))
       return family;
   }
   return nullptr;
diff --git a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
index db496ca..fb066bc 100644
--- a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
+++ b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
@@ -128,15 +128,14 @@
       EXCLUSIVE_LOCKS_REQUIRED(families_lock_);
   DWriteFontFamilyProxy* GetOrCreateFamilyLockRequired(UINT32 family_index)
       EXCLUSIVE_LOCKS_REQUIRED(families_lock_);
-  absl::optional<UINT32> FindFamilyIndexLockRequired(
-      const std::u16string& family_name,
-      HRESULT* hresult_out = nullptr) EXCLUSIVE_LOCKS_REQUIRED(families_lock_);
+  absl::optional<UINT32> FindFamilyIndex(const std::u16string& family_name,
+                                         HRESULT* hresult_out = nullptr)
+      LOCKS_EXCLUDED(families_lock_);
 
   HRESULT FindFamilyName(const std::u16string& family_name,
                          UINT32* index,
-                         BOOL* exists) LOCKS_EXCLUDED(families_lock_);
-  DWriteFontFamilyProxy* FindFamily(const std::u16string& family_name)
-      LOCKS_EXCLUDED(families_lock_);
+                         BOOL* exists);
+  DWriteFontFamilyProxy* FindFamily(const std::u16string& family_name);
 
   void PrewarmFamilyOnWorker(const std::u16string family_name);
 
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 4d41494..f0f594f2 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -352,6 +352,8 @@
            kSetOnlyIfOverridden},
           {"DesktopPWAsSubApps", blink::features::kDesktopPWAsSubApps},
           {"DocumentTransition", blink::features::kDocumentTransition},
+          {"DocumentTransitionRenderer",
+           blink::features::kDocumentTransitionRenderer},
           // TODO(crbug.com/649162): Remove DialogFocusNewSpecBehavior after
           // the feature is in stable with no issues.
           {"DialogFocusNewSpecBehavior",
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
index 6c81b497..3dec8bf 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -413,6 +413,11 @@
             mEventDispatcher.updateRelevantEventTypes(convertMaskToEventTypes(serviceEventMask));
             mEventDispatcher.setOnDemandEnabled(true);
         }
+
+        // Set whether image descriptions should be enabled for this instance. We do not want
+        // the feature to run in certain cases (e.g. WebView or Chrome Custom Tab).
+        WebContentsAccessibilityImplJni.get().setAllowImageDescriptions(
+                mNativeObj, WebContentsAccessibilityImpl.this, mAllowImageDescriptions);
     }
 
     @CalledByNative
@@ -811,9 +816,6 @@
     @Override
     public void setShouldFocusOnPageLoad(boolean on) {
         mShouldFocusOnPageLoad = on;
-
-        // If focus on page load is true, we will allow the image descriptions feature.
-        mAllowImageDescriptions = on;
     }
 
     @Override
@@ -1529,18 +1531,6 @@
     }
 
     @CalledByNative
-    private void handlePageLoaded(int id) {
-        // Set whether image descriptions should be enabled for this instance. We do not want
-        // the feature to run in certain cases (e.g. WebView or Chrome Custom Tab).
-        WebContentsAccessibilityImplJni.get().setAllowImageDescriptions(
-                mNativeObj, WebContentsAccessibilityImpl.this, mAllowImageDescriptions);
-
-        if (!mShouldFocusOnPageLoad) return;
-        if (mUserHasTouchExplored) return;
-        moveAccessibilityFocusToIdAndRefocusIfNeeded(id);
-    }
-
-    @CalledByNative
     private void handleFocusChanged(int id) {
         // If |mShouldFocusOnPageLoad| is false, that means this is a WebView and
         // we should avoid moving accessibility focus when the page loads, but more
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 27da085bc..3257eca 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -286,10 +286,6 @@
 const base::Feature kEnableCanvas2DLayers{"EnableCanvas2DLayers",
                                           base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Enables canvas context to clear context when it's running in background.
-const base::Feature kEnableCanvasContextLostInBackground{
-    "EnableCanvasContextLostInBackground", base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Enables new canvas 2d api features. Enabled either with either
 // enable-experimental-canvas-features or new-canvas-2d-api runtime flags
 const base::Feature kEnableNewCanvas2DAPI{"EnableNewCanvas2DAPI",
@@ -1038,17 +1034,8 @@
 // Controls whether CTAP2 devices can communicate via the WebAuthentication API
 // using pairingless BLE protocol.
 // https://w3c.github.io/webauthn
-const base::Feature kWebAuthCable {
-  "WebAuthenticationCable",
-// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
-// of lacros-chrome is complete.
-// If updating this, also update kWebAuthCableServerLink.
-#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
-      base::FEATURE_DISABLED_BY_DEFAULT
-#else
-      base::FEATURE_ENABLED_BY_DEFAULT
-#endif
-};
+const base::Feature kWebAuthCable{"WebAuthenticationCable",
+                                  base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Controls whether WebAuthn conditional UI requests are supported.
 const base::Feature kWebAuthConditionalUI{"WebAuthenticationConditionalUI",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 618b0604..1e91cc91 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -74,7 +74,6 @@
 CONTENT_EXPORT extern const base::Feature kEarlyHintsPreloadForNavigation;
 CONTENT_EXPORT extern const base::Feature kEmbeddingRequiresOptIn;
 CONTENT_EXPORT extern const base::Feature kEnableCanvas2DLayers;
-CONTENT_EXPORT extern const base::Feature kEnableCanvasContextLostInBackground;
 CONTENT_EXPORT extern const base::Feature kEnableNewCanvas2DAPI;
 CONTENT_EXPORT extern const base::Feature kEnumerateDevicesHideDeviceIDs;
 CONTENT_EXPORT extern const base::Feature kExperimentalAccessibilityLabels;
diff --git a/content/public/common/content_switch_dependent_feature_overrides.cc b/content/public/common/content_switch_dependent_feature_overrides.cc
index 307e11d..ef0e158 100644
--- a/content/public/common/content_switch_dependent_feature_overrides.cc
+++ b/content/public/common/content_switch_dependent_feature_overrides.cc
@@ -51,9 +51,6 @@
      std::cref(features::kOriginIsolationHeader),
      base::FeatureList::OVERRIDE_ENABLE_FEATURE},
     {switches::kEnableExperimentalWebPlatformFeatures,
-     std::cref(features::kEnableCanvasContextLostInBackground),
-     base::FeatureList::OVERRIDE_ENABLE_FEATURE},
-    {switches::kEnableExperimentalWebPlatformFeatures,
      std::cref(features::kEnableNewCanvas2DAPI),
      base::FeatureList::OVERRIDE_ENABLE_FEATURE},
     {switches::kEnableExperimentalWebPlatformFeatures,
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index c05622f..8fdace1 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -89,10 +89,6 @@
 // Enable in-progress canvas 2d API methods BeginLayer and EndLayer.
 const char kEnableCanvas2DLayers[] = "canvas-2d-layers";
 
-// Enables canvas to clear its context when it is running in background.
-const char kEnableCanvasContextLostInBackground[] =
-    "enable-canvas-context-lost-in-background";
-
 // Enable in-progress canvas 2d API features.
 const char kEnableNewCanvas2DAPI[] = "new-canvas-2d-api";
 
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 8d488c7..c61c834 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -116,7 +116,6 @@
 CONTENT_EXPORT extern const char kEnableLogging[];
 CONTENT_EXPORT extern const char kEnableNetworkInformationDownlinkMax[];
 CONTENT_EXPORT extern const char kEnableCanvas2DLayers[];
-CONTENT_EXPORT extern const char kEnableCanvasContextLostInBackground[];
 CONTENT_EXPORT extern const char kEnableNewCanvas2DAPI[];
 CONTENT_EXPORT extern const char kDisableNv12DxgiVideo[];
 CONTENT_EXPORT extern const char kEnablePluginPlaceholderTesting[];
diff --git a/content/public/test/dump_accessibility_test_helper.cc b/content/public/test/dump_accessibility_test_helper.cc
index 98dd298..25448895 100644
--- a/content/public/test/dump_accessibility_test_helper.cc
+++ b/content/public/test/dump_accessibility_test_helper.cc
@@ -137,6 +137,15 @@
   return mapping;
 }
 
+#if BUILDFLAG(USE_ATK)
+bool is_atk_version_supported() {
+  // Trusty is an older platform, based on the older ATK 2.10 version. Disable
+  // accessibility testing on it as it requires significant maintenance effort.
+  return atk_get_major_version() > 2 ||
+         (atk_get_major_version() == 2 && atk_get_minor_version() > 10);
+}
+#endif
+
 }  // namespace
 
 DumpAccessibilityTestHelper::DumpAccessibilityTestHelper(
@@ -211,34 +220,39 @@
 
 // static
 std::vector<ui::AXApiType::Type> DumpAccessibilityTestHelper::TreeTestPasses() {
-  return
-#if !BUILDFLAG(HAS_PLATFORM_ACCESSIBILITY_SUPPORT)
-      {ui::AXApiType::kBlink};
+#if BUILDFLAG(USE_ATK)
+  if (is_atk_version_supported())
+    return {ui::AXApiType::kBlink, ui::AXApiType::kLinux};
+  return {ui::AXApiType::kBlink};
+#elif !BUILDFLAG(HAS_PLATFORM_ACCESSIBILITY_SUPPORT)
+  return {ui::AXApiType::kBlink};
 #elif BUILDFLAG(IS_WIN)
-      {ui::AXApiType::kBlink, ui::AXApiType::kWinIA2, ui::AXApiType::kWinUIA};
+  return {ui::AXApiType::kBlink, ui::AXApiType::kWinIA2,
+          ui::AXApiType::kWinUIA};
 #elif BUILDFLAG(IS_MAC)
-      {ui::AXApiType::kBlink, ui::AXApiType::kMac};
+  return {ui::AXApiType::kBlink, ui::AXApiType::kMac};
 #elif BUILDFLAG(IS_ANDROID)
-      {ui::AXApiType::kAndroid};
+  return {ui::AXApiType::kAndroid};
 #elif BUILDFLAG(IS_FUCHSIA)
-      {ui::AXApiType::kFuchsia};
-#else  // linux
-      {ui::AXApiType::kBlink, ui::AXApiType::kLinux};
+  return {ui::AXApiType::kFuchsia};
+#else  // fallback
+  return {ui::AXApiType::kBlink};
 #endif
 }
 
 // static
 std::vector<ui::AXApiType::Type>
 DumpAccessibilityTestHelper::EventTestPasses() {
-  return
-#if BUILDFLAG(IS_WIN)
-      {ui::AXApiType::kWinIA2, ui::AXApiType::kWinUIA};
+#if BUILDFLAG(USE_ATK)
+  if (is_atk_version_supported())
+    return {ui::AXApiType::kLinux};
+  return {};
+#elif BUILDFLAG(IS_WIN)
+  return {ui::AXApiType::kWinIA2, ui::AXApiType::kWinUIA};
 #elif BUILDFLAG(IS_MAC)
-      {ui::AXApiType::kMac};
-#elif BUILDFLAG(USE_ATK)
-      {ui::AXApiType::kLinux};
+  return {ui::AXApiType::kMac};
 #else
-      {};
+  return {};
 #endif
 }
 
@@ -360,16 +374,11 @@
 #if BUILDFLAG(USE_ATK)
   if (expectation_type_ == "linux") {
     FilePath::StringType version_name;
-    switch (atk_get_minor_version()) {
-      case 10:
-        version_name = FILE_PATH_LITERAL("trusty");
-        break;
-      case 18:
-        version_name = FILE_PATH_LITERAL("xenial");
-        break;
-      default:
-        return FILE_PATH_LITERAL("");
-    }
+    if (atk_get_major_version() == 2 && atk_get_minor_version() == 18)
+      version_name = FILE_PATH_LITERAL("xenial");
+
+    if (version_name.empty())
+      return FILE_PATH_LITERAL("");
 
     FilePath::StringType suffix;
     if (!expectations_qualifier.empty())
diff --git a/content/public/test/web_ui_browsertest_util.cc b/content/public/test/web_ui_browsertest_util.cc
index 3ba3cd56..dfa0130 100644
--- a/content/public/test/web_ui_browsertest_util.cc
+++ b/content/public/test/web_ui_browsertest_util.cc
@@ -153,6 +153,8 @@
           break;
         case network::mojom::CrossOriginOpenerPolicyValue::
             kSameOriginAllowPopups:
+        case network::mojom::CrossOriginOpenerPolicyValue::
+            kSameOriginAllowPopupsPlusCoep:
           NOTIMPLEMENTED();
           break;
       }
diff --git a/content/renderer/media/win/dcomp_texture_factory.h b/content/renderer/media/win/dcomp_texture_factory.h
index ba19d78e..4304f87 100644
--- a/content/renderer/media/win/dcomp_texture_factory.h
+++ b/content/renderer/media/win/dcomp_texture_factory.h
@@ -13,6 +13,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/unguessable_token.h"
 #include "cc/layers/video_frame_provider.h"
+#include "content/common/content_export.h"
 #include "content/renderer/media/win/dcomp_texture_host.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/ipc/common/gpu_channel.mojom.h"
@@ -33,7 +34,7 @@
 // Threading Model: This class is created/constructed on the render main thread,
 // IsLost() is also called on the main task runner. Other than that, the class
 // lives and is destructed on the media task runner.
-class DCOMPTextureFactory
+class CONTENT_EXPORT DCOMPTextureFactory
     : public base::RefCountedThreadSafe<DCOMPTextureFactory> {
  public:
   static scoped_refptr<DCOMPTextureFactory> Create(
@@ -52,14 +53,16 @@
 
   gpu::SharedImageInterface* SharedImageInterface();
 
- private:
-  friend class base::RefCountedThreadSafe<DCOMPTextureFactory>;
+ protected:
   DCOMPTextureFactory(
       scoped_refptr<gpu::GpuChannelHost> channel,
       scoped_refptr<base::SingleThreadTaskRunner> media_task_runner);
   DCOMPTextureFactory(const DCOMPTextureFactory&) = delete;
   DCOMPTextureFactory& operator=(const DCOMPTextureFactory&) = delete;
-  ~DCOMPTextureFactory();
+  virtual ~DCOMPTextureFactory();
+
+ private:
+  friend class base::RefCountedThreadSafe<DCOMPTextureFactory>;
 
   scoped_refptr<gpu::GpuChannelHost> channel_;
   scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
diff --git a/content/renderer/media/win/dcomp_texture_wrapper_impl.cc b/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
index 2faa3ff..9332d099 100644
--- a/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
+++ b/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
@@ -10,6 +10,7 @@
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/shared_image_interface.h"
 #include "gpu/command_buffer/common/shared_image_usage.h"
+#include "gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/base/win/mf_helpers.h"
 
@@ -185,6 +186,60 @@
   std::move(create_video_frame_cb).Run(frame);
 }
 
+void DCOMPTextureWrapperImpl::CreateVideoFrame(
+    const gfx::Size& natural_size,
+    gfx::GpuMemoryBufferHandle dx_handle,
+    const base::UnguessableToken& token,
+    CreateDXVideoFrameCB create_video_frame_cb) {
+  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  gpu::SharedImageInterface* sii = factory_->SharedImageInterface();
+
+  uint32_t usage = gpu::SHARED_IMAGE_USAGE_RASTER |
+                   gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION |
+                   gpu::SHARED_IMAGE_USAGE_DISPLAY |
+                   gpu::SHARED_IMAGE_USAGE_SCANOUT;
+
+  std::unique_ptr<gfx::GpuMemoryBuffer> gmb =
+      gpu::GpuMemoryBufferImplDXGI::CreateFromHandle(
+          std::move(dx_handle), natural_size, gfx::BufferFormat::RGBA_8888,
+          gfx::BufferUsage::GPU_READ, base::NullCallback(), nullptr, nullptr);
+
+  // The VideoFrame object requires a 4 array mailbox holder because some
+  // formats can have 4 separate planes that can have 4 different GPU
+  // memories and even though in our case we are using only the first plane we
+  // still need to provide the video frame creation with a 4 array mailbox
+  // holder.
+  gpu::MailboxHolder holder[media::VideoFrame::kMaxPlanes];
+  gpu::Mailbox mailbox = sii->CreateSharedImage(
+      gmb.get(), nullptr, gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin,
+      kPremul_SkAlphaType, usage);
+  gpu::SyncToken sync_token = sii->GenVerifiedSyncToken();
+  holder[0] = gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D);
+
+  scoped_refptr<media::VideoFrame> video_frame_texture =
+      media::VideoFrame::WrapExternalGpuMemoryBuffer(
+          gfx::Rect(natural_size), natural_size, std::move(gmb), holder,
+          base::NullCallback(), base::TimeDelta::Min());
+  video_frame_texture->metadata().wants_promotion_hint = true;
+  video_frame_texture->metadata().allow_overlay = true;
+
+  video_frame_texture->AddDestructionObserver(base::BindPostTask(
+      media_task_runner_,
+      base::BindOnce(&DCOMPTextureWrapperImpl::OnDXVideoFrameDestruction,
+                     weak_factory_.GetWeakPtr(), sync_token, mailbox),
+      FROM_HERE));
+
+  std::move(create_video_frame_cb).Run(video_frame_texture, token);
+}
+
+void DCOMPTextureWrapperImpl::OnDXVideoFrameDestruction(
+    const gpu::SyncToken& sync_token,
+    const gpu::Mailbox& image_mailbox) {
+  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  gpu::SharedImageInterface* sii = factory_->SharedImageInterface();
+  sii->DestroySharedImage(sync_token, image_mailbox);
+}
+
 void DCOMPTextureWrapperImpl::OnSharedImageMailboxBound(gpu::Mailbox mailbox) {
   DVLOG_FUNC(1);
   DCHECK(media_task_runner_->BelongsToCurrentThread());
diff --git a/content/renderer/media/win/dcomp_texture_wrapper_impl.h b/content/renderer/media/win/dcomp_texture_wrapper_impl.h
index 5f710bb2..eddf670 100644
--- a/content/renderer/media/win/dcomp_texture_wrapper_impl.h
+++ b/content/renderer/media/win/dcomp_texture_wrapper_impl.h
@@ -7,6 +7,7 @@
 
 #include "base/task/single_thread_task_runner.h"
 #include "base/unguessable_token.h"
+#include "content/common/content_export.h"
 #include "content/renderer/media/win/dcomp_texture_factory.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "media/base/video_frame.h"
@@ -31,8 +32,9 @@
 // - We create a SharedImage mailbox representing the DCOMPTexture at a given
 //   size.
 // - We create a VideoFrame which takes ownership of this SharedImage mailbox.
-class DCOMPTextureWrapperImpl : public media::DCOMPTextureWrapper,
-                                public DCOMPTextureHost::Listener {
+class CONTENT_EXPORT DCOMPTextureWrapperImpl
+    : public media::DCOMPTextureWrapper,
+      public DCOMPTextureHost::Listener {
  public:
   static std::unique_ptr<media::DCOMPTextureWrapper> Create(
       scoped_refptr<DCOMPTextureFactory> factory,
@@ -52,6 +54,10 @@
       SetDCOMPSurfaceHandleCB set_dcomp_surface_handle_cb) override;
   void CreateVideoFrame(const gfx::Size& natural_size,
                         CreateVideoFrameCB create_video_frame_cb) override;
+  void CreateVideoFrame(const gfx::Size& natural_size,
+                        gfx::GpuMemoryBufferHandle dx_handle,
+                        const base::UnguessableToken& token,
+                        CreateDXVideoFrameCB create_video_frame_cb) override;
 
  private:
   DCOMPTextureWrapperImpl(
@@ -64,6 +70,9 @@
   void OnSharedImageMailboxBound(gpu::Mailbox mailbox) override;
   void OnOutputRectChange(gfx::Rect output_rect) override;
 
+  void OnDXVideoFrameDestruction(const gpu::SyncToken& sync_token,
+                                 const gpu::Mailbox& image_mailbox);
+
   scoped_refptr<DCOMPTextureFactory> factory_;
   scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
 
diff --git a/content/renderer/media/win/dcomp_texture_wrapper_unittest.cc b/content/renderer/media/win/dcomp_texture_wrapper_unittest.cc
new file mode 100644
index 0000000..27f485d5
--- /dev/null
+++ b/content/renderer/media/win/dcomp_texture_wrapper_unittest.cc
@@ -0,0 +1,149 @@
+// Copyright (c) 2022 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/run_loop.h"
+#include "base/test/mock_callback.h"
+#include "base/test/task_environment.h"
+#include "content/renderer/media/win/dcomp_texture_factory.h"
+#include "content/renderer/media/win/dcomp_texture_wrapper_impl.h"
+#include "gpu/ipc/client/client_shared_image_interface.h"
+#include "gpu/ipc/client/gpu_channel_host.h"
+#include "media/base/mock_filters.h"
+#include "media/base/test_helpers.h"
+#include "media/base/win/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include <d3d11.h>
+#include <dxgi1_2.h>
+#include <wrl/client.h>
+
+using base::RunLoop;
+using Microsoft::WRL::ComPtr;
+
+class StubClientSharedImageInterface : public gpu::ClientSharedImageInterface {
+ public:
+  StubClientSharedImageInterface() : gpu::ClientSharedImageInterface(nullptr) {}
+  gpu::SyncToken GenVerifiedSyncToken() override { return gpu::SyncToken(); }
+
+  gpu::Mailbox CreateSharedImage(viz::ResourceFormat format,
+                                 const gfx::Size& size,
+                                 const gfx::ColorSpace& color_space,
+                                 GrSurfaceOrigin surface_origin,
+                                 SkAlphaType alpha_type,
+                                 uint32_t usage,
+                                 gpu::SurfaceHandle surface_handle) override {
+    return gpu::Mailbox();
+  }
+
+  gpu::Mailbox CreateSharedImage(
+      viz::ResourceFormat format,
+      const gfx::Size& size,
+      const gfx::ColorSpace& color_space,
+      GrSurfaceOrigin surface_origin,
+      SkAlphaType alpha_type,
+      uint32_t usage,
+      base::span<const uint8_t> pixel_data) override {
+    return gpu::Mailbox();
+  }
+
+  gpu::Mailbox CreateSharedImage(
+      gfx::GpuMemoryBuffer* gpu_memory_buffer,
+      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+      gfx::BufferPlane plane,
+      const gfx::ColorSpace& color_space,
+      GrSurfaceOrigin surface_origin,
+      SkAlphaType alpha_type,
+      uint32_t usage) override {
+    return gpu::Mailbox();
+  }
+};
+
+class TestGpuChannelHost : public gpu::GpuChannelHost {
+ public:
+  TestGpuChannelHost()
+      : gpu::GpuChannelHost(
+            0 /* channel_id */,
+            gpu::GPUInfo(),
+            gpu::GpuFeatureInfo(),
+            mojo::ScopedMessagePipeHandle(
+                mojo::MessagePipeHandle(mojo::kInvalidHandleValue))) {}
+
+  std::unique_ptr<gpu::ClientSharedImageInterface>
+  CreateClientSharedImageInterface() override {
+    return std::make_unique<StubClientSharedImageInterface>();
+  }
+
+ protected:
+  ~TestGpuChannelHost() override {}
+};
+
+class StubDCOMPTextureFactory : public content::DCOMPTextureFactory {
+ public:
+  StubDCOMPTextureFactory(
+      scoped_refptr<base::SingleThreadTaskRunner> media_task_runner)
+      : DCOMPTextureFactory(base::MakeRefCounted<TestGpuChannelHost>(),
+                            media_task_runner) {}
+
+ protected:
+  ~StubDCOMPTextureFactory() override {}
+};
+
+class DCOMPTextureWrapperTest : public testing::Test {
+ public:
+  DCOMPTextureWrapperTest() {
+    mock_factory_ = base::MakeRefCounted<StubDCOMPTextureFactory>(
+        task_environment_.GetMainThreadTaskRunner());
+  }
+
+  static void CreateDXBackedVideoFrameTestTask(
+      std::unique_ptr<media::DCOMPTextureWrapper> dcomp_texture_wrapper,
+      base::OnceClosure closure);
+
+ protected:
+  base::test::TaskEnvironment task_environment_;
+  scoped_refptr<StubDCOMPTextureFactory> mock_factory_;
+};
+
+void DCOMPTextureWrapperTest::CreateDXBackedVideoFrameTestTask(
+    std::unique_ptr<media::DCOMPTextureWrapper> dcomp_texture_wrapper,
+    base::OnceClosure closure) {
+  gfx::GpuMemoryBufferHandle dx_handle;
+  base::WaitableEvent wait_event;
+  dx_handle.dxgi_handle =
+      base::win::ScopedHandle(CreateEvent(nullptr, FALSE, FALSE, nullptr));
+  dx_handle.dxgi_token = gfx::DXGIHandleToken();
+  dx_handle.type = gfx::GpuMemoryBufferType::DXGI_SHARED_HANDLE;
+  base::UnguessableToken token = base::UnguessableToken::Create();
+  gfx::Size frame_size(1920, 1080);
+
+  dcomp_texture_wrapper->CreateVideoFrame(
+      frame_size, std::move(dx_handle), token,
+      base::BindRepeating(
+          [](gfx::Size orig_frame_size, base::UnguessableToken orig_token,
+             base::WaitableEvent* wait_event,
+             scoped_refptr<media::VideoFrame> frame,
+             const base::UnguessableToken& token) {
+            EXPECT_EQ(frame->coded_size().width(), orig_frame_size.width());
+            EXPECT_EQ(frame->coded_size().height(), orig_frame_size.height());
+            EXPECT_EQ(token, orig_token);
+            wait_event->Signal();
+          },
+          frame_size, token, &wait_event));
+  wait_event.Wait();
+  std::move(closure).Run();
+}
+
+TEST_F(DCOMPTextureWrapperTest, CreateDXBackedVideoFrame) {
+  std::unique_ptr<media::DCOMPTextureWrapper> dcomp_texture_wrapper =
+      content::DCOMPTextureWrapperImpl::Create(
+          mock_factory_, task_environment_.GetMainThreadTaskRunner());
+  RunLoop run_loop;
+
+  task_environment_.GetMainThreadTaskRunner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&DCOMPTextureWrapperTest::CreateDXBackedVideoFrameTestTask,
+                     std::move(dcomp_texture_wrapper), run_loop.QuitClosure()));
+
+  run_loop.Run();
+}
diff --git a/content/services/auction_worklet/public/mojom/seller_worklet.mojom b/content/services/auction_worklet/public/mojom/seller_worklet.mojom
index e6db4915..91995cc 100644
--- a/content/services/auction_worklet/public/mojom/seller_worklet.mojom
+++ b/content/services/auction_worklet/public/mojom/seller_worklet.mojom
@@ -14,11 +14,11 @@
 // Manages the auction workflow for one loaded FLEDGE seller worklet.
 // See https://github.com/WICG/turtledove/blob/main/FLEDGE.md
 //
-// The SellerWorklet is functionally stateless apart from the requirement,
-// ScoreAd() complete once before any ReportResult() call, so methods are
-// idempotent and can be called multiple times, in any order, for
-// multiple auctions using the same worklet. There is no need to wait
-// for one callback to be invoked before calling another method.
+// The SellerWorklet is functionally stateless, so methods are idempotent
+// and can be called multiple times, in any order, for multiple auctions
+// using the same worklet. There is no need to wait for one callback to be
+// invoked before calling another method. There is no guarantee methods will
+// complete in the order they are invoked.
 interface SellerWorklet {
   // Calls the Javascript scoreAd() function to evaluate a bid. No data is
   // leaked between consecutive invocations of this method, or between
diff --git a/content/services/auction_worklet/seller_worklet.cc b/content/services/auction_worklet/seller_worklet.cc
index 19972c6..d6b2075 100644
--- a/content/services/auction_worklet/seller_worklet.cc
+++ b/content/services/auction_worklet/seller_worklet.cc
@@ -227,16 +227,25 @@
     double browser_signal_desirability,
     ReportResultCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_);
-  CHECK(IsCodeReady());
 
-  v8_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&SellerWorklet::V8State::ReportResult,
-                     base::Unretained(v8_state_.get()),
-                     std::move(auction_ad_config_non_shared_params),
-                     browser_signal_interest_group_owner,
-                     browser_signal_render_url, browser_signal_bid,
-                     browser_signal_desirability, std::move(callback)));
+  report_result_tasks_.emplace_front();
+
+  auto report_result_task = report_result_tasks_.begin();
+
+  report_result_task->auction_ad_config_non_shared_params =
+      std::move(auction_ad_config_non_shared_params);
+  report_result_task->browser_signal_interest_group_owner =
+      browser_signal_interest_group_owner;
+  report_result_task->browser_signal_render_url = browser_signal_render_url;
+  report_result_task->browser_signal_bid = browser_signal_bid;
+  report_result_task->browser_signal_desirability = browser_signal_desirability;
+  report_result_task->callback = std::move(callback);
+
+  // If not yet ready, need to wait for load to complete.
+  if (!IsCodeReady())
+    return;
+
+  RunReportResult(report_result_task);
 }
 
 void SellerWorklet::ConnectDevToolsAgent(
@@ -251,6 +260,9 @@
 SellerWorklet::ScoreAdTask::ScoreAdTask() = default;
 SellerWorklet::ScoreAdTask::~ScoreAdTask() = default;
 
+SellerWorklet::ReportResultTask::ReportResultTask() = default;
+SellerWorklet::ReportResultTask::~ReportResultTask() = default;
+
 SellerWorklet::V8State::V8State(
     scoped_refptr<AuctionV8Helper> v8_helper,
     scoped_refptr<AuctionV8Helper::DebugId> debug_id,
@@ -387,7 +399,7 @@
     const GURL& browser_signal_render_url,
     double browser_signal_bid,
     double browser_signal_desirability,
-    ReportResultCallback callback) {
+    ReportResultCallbackInternal callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_);
   AuctionV8Helper::FullIsolateScope isolate_scope(v8_helper_.get());
   v8::Isolate* isolate = v8_helper_->isolate();
@@ -494,19 +506,15 @@
 }
 
 void SellerWorklet::V8State::PostReportResultCallbackToUserThread(
-    ReportResultCallback callback,
+    ReportResultCallbackInternal callback,
     absl::optional<std::string> signals_for_winner,
     absl::optional<GURL> report_url,
     std::vector<std::string> errors) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_);
-  // `parent` being a weak pointer takes care of the case where the
-  // SellerWorklet proper is destroyed.
   user_thread_->PostTask(
       FROM_HERE,
-      base::BindOnce(&SellerWorklet::DeliverReportResultCallbackOnUserThread,
-                     parent_, std::move(callback),
-                     std::move(signals_for_winner), std::move(report_url),
-                     std::move(errors)));
+      base::BindOnce(std::move(callback), std::move(signals_for_winner),
+                     std::move(report_url), std::move(errors)));
 }
 
 void SellerWorklet::ResumeIfPaused() {
@@ -555,6 +563,11 @@
        score_ad_task != score_ad_tasks_.end(); ++score_ad_task) {
     ScoreAdIfReady(score_ad_task);
   }
+
+  for (auto report_result_task = report_result_tasks_.begin();
+       report_result_task != report_result_tasks_.end(); ++report_result_task) {
+    RunReportResult(report_result_task);
+  }
 }
 
 void SellerWorklet::OnTrustedScoringSignalsDownloaded(
@@ -603,22 +616,39 @@
   if (task->trusted_scoring_signals_error_msg)
     errors.insert(errors.begin(), *task->trusted_scoring_signals_error_msg);
 
-  std::move(task->callback).Run(score, std::move(errors));
+  std::move(task->callback).Run(score, errors);
   score_ad_tasks_.erase(task);
 }
 
+void SellerWorklet::RunReportResult(ReportResultTaskList::iterator task) {
+  DCHECK(IsCodeReady());
+
+  v8_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          &SellerWorklet::V8State::ReportResult,
+          base::Unretained(v8_state_.get()),
+          std::move(task->auction_ad_config_non_shared_params),
+          std::move(task->browser_signal_interest_group_owner),
+          std::move(task->browser_signal_render_url), task->browser_signal_bid,
+          task->browser_signal_desirability,
+          base::BindOnce(
+              &SellerWorklet::DeliverReportResultCallbackOnUserThread,
+              weak_ptr_factory_.GetWeakPtr(), task)));
+}
+
 void SellerWorklet::DeliverReportResultCallbackOnUserThread(
-    ReportResultCallback callback,
-    absl::optional<std::string> signals_for_winner,
-    absl::optional<GURL> report_url,
+    ReportResultTaskList::iterator task,
+    const absl::optional<std::string> signals_for_winner,
+    const absl::optional<GURL> report_url,
     std::vector<std::string> errors) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_);
 
   if (load_script_error_msg_)
     errors.insert(errors.begin(), load_script_error_msg_.value());
 
-  std::move(callback).Run(std::move(signals_for_winner), std::move(report_url),
-                          std::move(errors));
+  std::move(task->callback).Run(signals_for_winner, report_url, errors);
+  report_result_tasks_.erase(task);
 }
 
 bool SellerWorklet::IsCodeReady() const {
diff --git a/content/services/auction_worklet/seller_worklet.h b/content/services/auction_worklet/seller_worklet.h
index debe447..819bee6 100644
--- a/content/services/auction_worklet/seller_worklet.h
+++ b/content/services/auction_worklet/seller_worklet.h
@@ -128,16 +128,41 @@
 
   using ScoreAdTaskList = std::list<ScoreAdTask>;
 
+  // Contains all data needed for a ReportResult() call. Destroyed only when its
+  // `callback` is invoked.
+  struct ReportResultTask {
+    ReportResultTask();
+    ~ReportResultTask();
+
+    // These fields all correspond to the arguments of ReportResult(). They're
+    // std::move()ed when calling out to V8State to run Javascript, so are not
+    // safe to access after that happens.
+    blink::mojom::AuctionAdConfigNonSharedParamsPtr
+        auction_ad_config_non_shared_params;
+    url::Origin browser_signal_interest_group_owner;
+    GURL browser_signal_render_url;
+    double browser_signal_bid;
+    double browser_signal_desirability;
+
+    ReportResultCallback callback;
+  };
+
+  using ReportResultTaskList = std::list<ReportResultTask>;
+
   // Portion of SellerWorklet that deals with V8 execution, and therefore lives
   // on the v8 thread --- everything except the constructor must be run there.
   class V8State {
    public:
-    // Matches auction_worklet::mojom::SellerWorklet::ScoreAdCallback,
-    // except the errors vectors are passed by value. Must be invoked on the
-    // user thread. Different signitures also protects against passing the
-    // wrong callback to V8State.
+    // Match corresponding auction_worklet::mojom::SellerWorklet callback types,
+    // except arguments are passed by value. Must be invoked on the user thread.
+    // Different signatures protect against passing the wrong callback to
+    // V8State, and avoids having to make a copy of the errors vector.
     using ScoreAdCallbackInternal =
         base::OnceCallback<void(double score, std::vector<std::string> errors)>;
+    using ReportResultCallbackInternal =
+        base::OnceCallback<void(absl::optional<std::string> signals_for_winner,
+                                absl::optional<GURL> report_url,
+                                std::vector<std::string> errors)>;
 
     V8State(scoped_refptr<AuctionV8Helper> v8_helper,
             scoped_refptr<AuctionV8Helper::DebugId> debug_id,
@@ -164,7 +189,7 @@
                       const GURL& browser_signal_render_url,
                       double browser_signal_bid,
                       double browser_signal_desirability,
-                      ReportResultCallback callback);
+                      ReportResultCallbackInternal callback);
 
     void ConnectDevToolsAgent(
         mojo::PendingReceiver<blink::mojom::DevToolsAgent> agent);
@@ -180,7 +205,7 @@
                                          std::vector<std::string> errors);
 
     void PostReportResultCallbackToUserThread(
-        ReportResultCallback callback,
+        ReportResultCallbackInternal callback,
         absl::optional<std::string> signals_for_winner,
         absl::optional<GURL> report_url,
         std::vector<std::string> errors);
@@ -227,8 +252,12 @@
                                           double score,
                                           std::vector<std::string> errors);
 
+  // Runs the specified queued ReportWinTask. All code must already be loaded by
+  // the time this is invoked.
+  void RunReportResult(ReportResultTaskList::iterator task);
+
   void DeliverReportResultCallbackOnUserThread(
-      ReportResultCallback callback,
+      ReportResultTaskList::iterator task,
       absl::optional<std::string> signals_for_winner,
       absl::optional<GURL> report_url,
       std::vector<std::string> errors);
@@ -256,6 +285,7 @@
   // to the v8 thread, so it needs to be an std::lists rather than an
   // std::vector.
   ScoreAdTaskList score_ad_tasks_;
+  ReportResultTaskList report_result_tasks_;
 
   // Deleted once load has completed.
   std::unique_ptr<WorkletLoader> worklet_loader_;
diff --git a/content/services/auction_worklet/seller_worklet_unittest.cc b/content/services/auction_worklet/seller_worklet_unittest.cc
index 9c710d4..75d37ee 100644
--- a/content/services/auction_worklet/seller_worklet_unittest.cc
+++ b/content/services/auction_worklet/seller_worklet_unittest.cc
@@ -294,6 +294,19 @@
             std::move(done_closure)));
   }
 
+  void RunReportResultExpectingCallbackNeverInvoked(
+      mojom::SellerWorklet* seller_worklet) {
+    seller_worklet->ReportResult(
+        auction_ad_config_non_shared_params_.Clone(),
+        browser_signal_interest_group_owner_, browser_signal_render_url_, bid_,
+        browser_signal_desireability_,
+        base::BindOnce([](const absl::optional<std::string>& signals_for_winner,
+                          const absl::optional<GURL>& report_url,
+                          const std::vector<std::string>& errors) {
+          ADD_FAILURE() << "This should not be invoked";
+        }));
+  }
+
   // Loads and runs a report_result() script, expecting the supplied result.
   // Runs ScoreAd() first, expecting a score of 1, since that's required before
   // calling ReportResult.
@@ -665,8 +678,7 @@
 // Test the case of a bunch of ScoreAd() calls in parallel, all started before
 // the worklet script has loaded.
 TEST_F(SellerWorkletTest, ScoreAdParallelBeforeLoadComplete) {
-  mojo::Remote<mojom::SellerWorklet> seller_worklet =
-      CreateWorklet(/*pause_for_debugger_on_start=*/false);
+  auto seller_worklet = CreateWorklet(/*pause_for_debugger_on_start=*/false);
 
   const size_t kNumWorklets = 10;
   size_t num_completed_worklets = 0;
@@ -724,7 +736,7 @@
 // Test the case of a bunch of ScoreAd() calls in parallel, all started before
 // the worklet script fails to load.
 TEST_F(SellerWorkletTest, ScoreAdParallelLoadFails) {
-  mojo::Remote<mojom::SellerWorklet> seller_worklet = CreateWorklet();
+  auto seller_worklet = CreateWorklet();
 
   for (size_t i = 0; i < 10; ++i) {
     browser_signal_render_url_ = GURL(base::StringPrintf("https://foo/%zu", i));
@@ -875,7 +887,7 @@
 TEST_F(SellerWorkletTest, ScoreAdParallelTrustedScoringSignalsBatched2) {
   trusted_scoring_signals_url_ =
       GURL("https://url.test/trusted_scoring_signals");
-  mojo::Remote<mojom::SellerWorklet> seller_worklet = CreateWorklet();
+  auto seller_worklet = CreateWorklet();
 
   // Start scoring a bunch of worklets. Don't provide JSON responses, to make
   // sure they all reside in the worklet's task list at once.
@@ -936,7 +948,7 @@
 TEST_F(SellerWorkletTest, ScoreAdParallelTrustedScoringSignalsBatched3) {
   trusted_scoring_signals_url_ =
       GURL("https://url.test/trusted_scoring_signals");
-  mojo::Remote<mojom::SellerWorklet> seller_worklet = CreateWorklet();
+  auto seller_worklet = CreateWorklet();
 
   // Start scoring a bunch of worklets. Don't provide JSON responses, to make
   // sure they all reside in the worklet's task list at once.
@@ -992,6 +1004,73 @@
   run_loop.Run();
 }
 
+// Test multiple ReportWin() calls on a single worklet, in parallel. Do this
+// twice, once before the worklet has loaded its Javascript, and once after, to
+// make sure both cases work.
+TEST_F(SellerWorkletTest, ReportResultParallel) {
+  auto seller_worklet = CreateWorklet();
+
+  // For the first loop iteration, call ReportResult() repeatedly before
+  // providing the seller script, then provide the seller script. For the second
+  // loop iteration, reuse the seller worklet from the first iteration, so the
+  // Javascript is loaded from the start.
+  for (bool report_result_invoked_before_worklet_script_loaded :
+       {false, true}) {
+    SCOPED_TRACE(report_result_invoked_before_worklet_script_loaded);
+
+    base::RunLoop run_loop;
+    const size_t kNumReportResultCalls = 10;
+    size_t num_report_result_calls = 0;
+    for (size_t i = 0; i < kNumReportResultCalls; ++i) {
+      // Differentiate each call based on the bid.
+      bid_ = i + 1;
+      RunReportResultExpectingResultAsync(
+          seller_worklet.get(),
+          /*expected_signals_for_winner=*/base::NumberToString(bid_),
+          /*expected_report_url=*/
+          GURL("https://" + base::NumberToString(bid_)),
+          /*expected_errors=*/{},
+          base::BindLambdaForTesting([&run_loop, &num_report_result_calls]() {
+            ++num_report_result_calls;
+            if (num_report_result_calls == kNumReportResultCalls)
+              run_loop.Quit();
+          }));
+    }
+
+    // If this is the first loop iteration, wait for all the Mojo calls to
+    // settle, and then provide the Javascript response body.
+    if (report_result_invoked_before_worklet_script_loaded == false) {
+      task_environment_.RunUntilIdle();
+      EXPECT_FALSE(run_loop.AnyQuitCalled());
+      AddJavascriptResponse(
+          &url_loader_factory_, decision_logic_url_,
+          CreateReportToScript(
+              /*raw_return_value=*/"browserSignals.bid",
+              /*extra_code=*/
+              R"(sendReportTo("https://" + browserSignals.bid))"));
+    }
+
+    run_loop.Run();
+    EXPECT_EQ(kNumReportResultCalls, num_report_result_calls);
+  }
+}
+
+// Test multiple ReportResult() calls on a single worklet, in parallel, in the
+// case the worklet script fails to load.
+TEST_F(SellerWorkletTest, ReportResultParallelLoadFails) {
+  auto seller_worklet = CreateWorklet();
+
+  for (size_t i = 0; i < 10; ++i) {
+    RunReportResultExpectingCallbackNeverInvoked(seller_worklet.get());
+  }
+
+  url_loader_factory_.AddResponse(decision_logic_url_.spec(), "Response body",
+                                  net::HTTP_NOT_FOUND);
+
+  EXPECT_EQ("Failed to load https://url.test/ HTTP status = 404 Not Found.",
+            WaitForDisconnect());
+}
+
 // Tests parsing of return values.
 TEST_F(SellerWorkletTest, ReportResult) {
   RunReportResultCreatedScriptExpectingResult(
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index fc46388..7adfc61 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -2675,6 +2675,7 @@
       "../child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc",
       "../child/dwrite_font_proxy/font_fallback_win_unittest.cc",
       "../child/font_warmup_win_unittest.cc",
+      "../renderer/media/win/dcomp_texture_wrapper_unittest.cc",
     ]
     deps += [
       "//sandbox/policy:sandbox_test_utils",
diff --git a/content/test/data/accessibility/aria/aria-posinset-expected-android.txt b/content/test/data/accessibility/aria/aria-posinset-expected-android.txt
index ce325e3..5377113 100644
--- a/content/test/data/accessibility/aria/aria-posinset-expected-android.txt
+++ b/content/test/data/accessibility/aria/aria-posinset-expected-android.txt
@@ -29,8 +29,8 @@
 ++++++android.view.View name='red'
 ++++++android.view.View name='<newline>'
 ++++++android.widget.RadioButton role_description='radio button' checkable clickable focusable name='blue'
-++android.widget.GridView role_description='tree grid' clickable collection row_count=1 column_count=1
-++++android.view.View
+++android.widget.GridView role_description='tree grid' clickable collection item_count=100 row_count=100 column_count=1
+++++android.view.View item_index=1 row_index=1
 ++++++android.view.View collection_item name='content' row_span=1 column_span=1
 ++android.widget.GridView role_description='table' collection row_count=1 column_count=1
 ++++android.view.View
diff --git a/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt b/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt
index 88df8a3..135cb458 100644
--- a/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt
@@ -33,7 +33,7 @@
 ++++++++AXStaticText AXRoleDescription='text' AXValue='red'
 ++++++AXGroup AXRoleDescription='group' AXTitle='<newline>'
 ++++++AXRadioButton AXARIAPosInSet=1 AXARIASetSize=1 AXRoleDescription='radio button' AXTitle='blue' AXValue=0
-++AXTable AXRoleDescription='table'
+++AXTable AXARIASetSize=100 AXRoleDescription='table'
 ++++AXRow AXRoleDescription='row'
 ++++++AXCell AXRoleDescription='cell'
 ++++++++AXStaticText AXRoleDescription='text' AXValue='content'
diff --git a/content/test/data/accessibility/aria/aria-treegrid-expected-android-external.txt b/content/test/data/accessibility/aria/aria-treegrid-expected-android-external.txt
index fd66bef8b..17ce87e 100644
--- a/content/test/data/accessibility/aria/aria-treegrid-expected-android-external.txt
+++ b/content/test/data/accessibility/aria/aria-treegrid-expected-android-external.txt
@@ -1,10 +1,51 @@
 WebView focusable focused scrollable actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chromeRole="rootWebArea"]
-++GridView clickable CollectionInfo:[rows=2, cols=1] actions:[CLICK, AX_FOCUS] bundle:[chromeRole="treeGrid", roleDescription="tree grid"]
-++++View actions:[AX_FOCUS] bundle:[chromeRole="row"]
-++++++View text:"Cell at level 1" CollectionItemInfo:[rowIndex=0, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
-++++View actions:[AX_FOCUS] bundle:[chromeRole="row"]
-++++++View text:"Cell at level 2" CollectionItemInfo:[rowIndex=1, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
-++GridView clickable CollectionInfo:[rows=1, cols=1] actions:[CLICK, AX_FOCUS] bundle:[chromeRole="treeGrid", roleDescription="tree grid"]
+++GridView clickable CollectionInfo:[rows=3, cols=2] actions:[CLICK, AX_FOCUS] bundle:[chromeRole="treeGrid", roleDescription="tree grid"]
+++++View text:"Cell 1, row 1, level 1 Cell 2, row 1, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 1, level 1" CollectionItemInfo:[rowIndex=0, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++View text:"Cell 2, row 1, level 1" CollectionItemInfo:[rowIndex=0, rowSpan=1, colIndex=1, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++View text:"Cell 1, row 2, level 1 Cell 2, row 2, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 2, level 1" CollectionItemInfo:[rowIndex=1, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++View text:"Cell 2, row 2, level 1" CollectionItemInfo:[rowIndex=1, rowSpan=1, colIndex=1, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++View text:"Cell 1, row 3, level 1 Cell 2, row 3, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 3, level 1" CollectionItemInfo:[rowIndex=2, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++View text:"Cell 2, row 3, level 1" CollectionItemInfo:[rowIndex=2, rowSpan=1, colIndex=1, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++View text:"Cell 1, row 1, level 2" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 1, level 2" CollectionItemInfo:[rowIndex=3, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++View text:"Cell 1, row 2, level 2" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 2, level 2" CollectionItemInfo:[rowIndex=4, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++View text:"Cell 1, row 3, level 2" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 3, level 2" CollectionItemInfo:[rowIndex=5, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++View text:"Cell 1, row 4, level 2" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 4, level 2" CollectionItemInfo:[rowIndex=6, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++View text:"Cell 1, row 2, level 2" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 2, level 2" CollectionItemInfo:[rowIndex=7, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++GridView clickable CollectionInfo:[rows=0, cols=3] actions:[CLICK, AX_FOCUS] bundle:[chromeRole="treeGrid", roleDescription="tree grid"]
 ++++View actions:[AX_FOCUS] bundle:[chromeRole="rowGroup"]
-++++++View actions:[AX_FOCUS] bundle:[chromeRole="row"]
-++++++++View text:"Cell at level 1" CollectionItemInfo:[rowIndex=0, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
\ No newline at end of file
+++++++View text:"Cell 1, row 1, rowgroup 1, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++++View text:"Cell 1, row 1, rowgroup 1, level 1" CollectionItemInfo:[rowIndex=0, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++View text:"Cell 1, row 2, rowgroup 1, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++++View text:"Cell 1, row 2, rowgroup 1, level 1" CollectionItemInfo:[rowIndex=1, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++View text:"Cell 1, row 3, rowgroup 1, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++++View text:"Cell 1, row 3, rowgroup 1, level 1" CollectionItemInfo:[rowIndex=2, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++View text:"Cell 1, row 1, rowgroup 1, level 2" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++++View text:"Cell 1, row 1, rowgroup 1, level 2" CollectionItemInfo:[rowIndex=3, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++View text:"Cell 1, row 1, rowgroup 1, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++++View text:"Cell 1, row 1, rowgroup 1, level 1" CollectionItemInfo:[rowIndex=4, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++View actions:[AX_FOCUS] bundle:[chromeRole="rowGroup"]
+++++++View text:"Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++++View text:"Cell 1, row 1, rowgroup 2, level 1" CollectionItemInfo:[rowIndex=5, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++++View text:"Cell 2, row 1, rowgroup 2, level 1" CollectionItemInfo:[rowIndex=5, rowSpan=1, colIndex=1, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++View text:"Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++++View text:"Cell 1, row 1, rowgroup 2, level 2" CollectionItemInfo:[rowIndex=6, rowSpan=1, colIndex=0, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++++View text:"Cell 2, row 1, rowgroup 2, level 2" CollectionItemInfo:[rowIndex=6, rowSpan=1, colIndex=1, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++++++++View text:"Cell 3, row 1, rowgroup 2, level 2" CollectionItemInfo:[rowIndex=6, rowSpan=1, colIndex=2, colSpan=1] actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="cell"]
+++GridView clickable CollectionInfo:[rows=0, cols=0] actions:[CLICK, AX_FOCUS] bundle:[chromeRole="treeGrid", roleDescription="tree grid"]
+++++View actions:[AX_FOCUS] bundle:[chromeRole="rowGroup"]
+++++++View text:"Cell 1, row 1, rowgroup 1, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 2, rowgroup 1, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 3, rowgroup 1, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 1, rowgroup 1, level 2" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 1, rowgroup 1, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++View actions:[AX_FOCUS] bundle:[chromeRole="rowGroup"]
+++++++View text:"Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
+++++++View text:"Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="row"]
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria/aria-treegrid-expected-android.txt b/content/test/data/accessibility/aria/aria-treegrid-expected-android.txt
index 8a3d42a..ec41fd2 100644
--- a/content/test/data/accessibility/aria/aria-treegrid-expected-android.txt
+++ b/content/test/data/accessibility/aria/aria-treegrid-expected-android.txt
@@ -1,10 +1,51 @@
 android.webkit.WebView focusable focused scrollable
-++android.widget.GridView role_description='tree grid' clickable collection row_count=2 column_count=1
+++android.widget.GridView role_description='tree grid' clickable collection item_count=3 row_count=3 column_count=2
+++++android.view.View focusable name='Cell 1, row 1, level 1 Cell 2, row 1, level 1'
+++++++android.view.View collection_item name='Cell 1, row 1, level 1' row_span=1 column_span=1
+++++++android.view.View collection_item name='Cell 2, row 1, level 1' row_span=1 column_index=1 column_span=1
+++++android.view.View focusable name='Cell 1, row 2, level 1 Cell 2, row 2, level 1' item_index=1 row_index=1
+++++++android.view.View collection_item name='Cell 1, row 2, level 1' row_index=1 row_span=1 column_span=1
+++++++android.view.View collection_item name='Cell 2, row 2, level 1' row_index=1 row_span=1 column_index=1 column_span=1
+++++android.view.View focusable name='Cell 1, row 3, level 1 Cell 2, row 3, level 1' item_index=2 row_index=2
+++++++android.view.View collection_item name='Cell 1, row 3, level 1' row_index=2 row_span=1 column_span=1
+++++++android.view.View collection_item name='Cell 2, row 3, level 1' row_index=2 row_span=1 column_index=1 column_span=1
+++++android.view.View focusable name='Cell 1, row 1, level 2'
+++++++android.view.View collection_item name='Cell 1, row 1, level 2' row_index=3 row_span=1 column_span=1
+++++android.view.View focusable name='Cell 1, row 2, level 2' item_index=1 row_index=1
+++++++android.view.View collection_item name='Cell 1, row 2, level 2' row_index=4 row_span=1 column_span=1
+++++android.view.View focusable name='Cell 1, row 3, level 2' item_index=2 row_index=2
+++++++android.view.View collection_item name='Cell 1, row 3, level 2' row_index=5 row_span=1 column_span=1
+++++android.view.View focusable name='Cell 1, row 4, level 2' item_index=3 row_index=3
+++++++android.view.View collection_item name='Cell 1, row 4, level 2' row_index=6 row_span=1 column_span=1
+++++android.view.View focusable name='Cell 1, row 2, level 2'
+++++++android.view.View collection_item name='Cell 1, row 2, level 2' row_index=7 row_span=1 column_span=1
+++android.widget.GridView role_description='tree grid' clickable collection column_count=3
 ++++android.view.View
-++++++android.view.View collection_item name='Cell at level 1' row_span=1 column_span=1
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++android.view.View collection_item name='Cell 1, row 1, rowgroup 1, level 1' row_span=1 column_span=1
+++++++android.view.View focusable name='Cell 1, row 2, rowgroup 1, level 1' item_index=1 row_index=1
+++++++++android.view.View collection_item name='Cell 1, row 2, rowgroup 1, level 1' row_index=1 row_span=1 column_span=1
+++++++android.view.View focusable name='Cell 1, row 3, rowgroup 1, level 1' item_index=2 row_index=2
+++++++++android.view.View collection_item name='Cell 1, row 3, rowgroup 1, level 1' row_index=2 row_span=1 column_span=1
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 1, level 2'
+++++++++android.view.View collection_item name='Cell 1, row 1, rowgroup 1, level 2' row_index=3 row_span=1 column_span=1
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 1, level 1' item_index=3 row_index=3
+++++++++android.view.View collection_item name='Cell 1, row 1, rowgroup 1, level 1' row_index=4 row_span=1 column_span=1
 ++++android.view.View
-++++++android.view.View collection_item name='Cell at level 2' row_index=1 row_span=1 column_span=1
-++android.widget.GridView role_description='tree grid' clickable collection row_count=1 column_count=1
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1'
+++++++++android.view.View collection_item name='Cell 1, row 1, rowgroup 2, level 1' row_index=5 row_span=1 column_span=1
+++++++++android.view.View collection_item name='Cell 2, row 1, rowgroup 2, level 1' row_index=5 row_span=1 column_index=1 column_span=1
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2'
+++++++++android.view.View collection_item name='Cell 1, row 1, rowgroup 2, level 2' row_index=6 row_span=1 column_span=1
+++++++++android.view.View collection_item name='Cell 2, row 1, rowgroup 2, level 2' row_index=6 row_span=1 column_index=1 column_span=1
+++++++++android.view.View collection_item name='Cell 3, row 1, rowgroup 2, level 2' row_index=6 row_span=1 column_index=2 column_span=1
+++android.widget.GridView role_description='tree grid' clickable collection
 ++++android.view.View
-++++++android.view.View
-++++++++android.view.View collection_item name='Cell at level 1' row_span=1 column_span=1
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 1, level 1'
+++++++android.view.View focusable name='Cell 1, row 2, rowgroup 1, level 1' item_index=1 row_index=1
+++++++android.view.View focusable name='Cell 1, row 3, rowgroup 1, level 1' item_index=2 row_index=2
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 1, level 2'
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 1, level 1' item_index=3 row_index=3
+++++android.view.View
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1'
+++++++android.view.View focusable name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria/aria-treegrid-expected-auralinux.txt b/content/test/data/accessibility/aria/aria-treegrid-expected-auralinux.txt
index e9ed847..121434b9f 100644
--- a/content/test/data/accessibility/aria/aria-treegrid-expected-auralinux.txt
+++ b/content/test/data/accessibility/aria/aria-treegrid-expected-auralinux.txt
@@ -1,13 +1,79 @@
 [document web]
-++[tree table] xml-roles:treegrid cols=1 headers=(NONE); rows=2 headers=(NONE); caption=false; spans=(all: 1x1)
-++++[table row] level:1 xml-roles:row
-++++++[table cell] name='Cell at level 1' xml-roles:gridcell (row=0, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
-++++++++[static] name='Cell at level 1'
-++++[table row] level:2 xml-roles:row
-++++++[table cell] name='Cell at level 2' xml-roles:gridcell (row=1, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
-++++++++[static] name='Cell at level 2'
-++[tree table] xml-roles:treegrid cols=1 headers=(NONE); rows=1 headers=(NONE); caption=false; spans=(all: 1x1)
-++++[panel] xml-roles:rowgroup
-++++++[table row] level:1 xml-roles:row
-++++++++[table cell] name='Cell at level 1' xml-roles:gridcell (row=0, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
-++++++++++[static] name='Cell at level 1'
+++[tree table] xml-roles:treegrid cols=2 headers=(NONE); rows=8 headers=(NONE); caption=false; spans=(cell at 3,1: 0x0, cell at 4,1: 0x0, cell at 5,1: 0x0, cell at 6,1: 0x0, cell at 7,1: 0x0)
+++++[table row] name='Cell 1, row 1, level 1 Cell 2, row 1, level 1' level:1 xml-roles:row
+++++++[table cell] name='Cell 1, row 1, level 1' xml-roles:gridcell (row=0, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 1, row 1, level 1'
+++++++[table cell] name='Cell 2, row 1, level 1' xml-roles:gridcell (row=0, col=1, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 2, row 1, level 1'
+++++[table row] name='Cell 1, row 2, level 1 Cell 2, row 2, level 1' level:1 xml-roles:row
+++++++[table cell] name='Cell 1, row 2, level 1' xml-roles:gridcell (row=1, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 1, row 2, level 1'
+++++++[table cell] name='Cell 2, row 2, level 1' xml-roles:gridcell (row=1, col=1, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 2, row 2, level 1'
+++++[table row] name='Cell 1, row 3, level 1 Cell 2, row 3, level 1' level:1 xml-roles:row
+++++++[table cell] name='Cell 1, row 3, level 1' xml-roles:gridcell (row=2, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 1, row 3, level 1'
+++++++[table cell] name='Cell 2, row 3, level 1' xml-roles:gridcell (row=2, col=1, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 2, row 3, level 1'
+++++[table row] name='Cell 1, row 1, level 2' level:2 xml-roles:row
+++++++[table cell] name='Cell 1, row 1, level 2' xml-roles:gridcell (row=3, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 1, row 1, level 2'
+++++[table row] name='Cell 1, row 2, level 2' level:2 xml-roles:row
+++++++[table cell] name='Cell 1, row 2, level 2' xml-roles:gridcell (row=4, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 1, row 2, level 2'
+++++[table row] name='Cell 1, row 3, level 2' level:2 xml-roles:row
+++++++[table cell] name='Cell 1, row 3, level 2' xml-roles:gridcell (row=5, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 1, row 3, level 2'
+++++[table row] name='Cell 1, row 4, level 2' level:2 xml-roles:row
+++++++[table cell] name='Cell 1, row 4, level 2' xml-roles:gridcell (row=6, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 1, row 4, level 2'
+++++[table row] name='Cell 1, row 2, level 2' level:3 xml-roles:row
+++++++[table cell] name='Cell 1, row 2, level 2' xml-roles:gridcell (row=7, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++[static] name='Cell 1, row 2, level 2'
+++[tree table] xml-roles:treegrid cols=3 headers=(NONE); rows=7 headers=(NONE); caption=false; spans=(cell at 0,1: 0x0, cell at 0,2: 0x0, cell at 1,1: 0x0, cell at 1,2: 0x0, cell at 2,1: 0x0, cell at 2,2: 0x0, cell at 3,1: 0x0, cell at 3,2: 0x0, cell at 4,1: 0x0, cell at 4,2: 0x0, cell at 5,2: 0x0)
+++++[panel] setsize:4 xml-roles:rowgroup
+++++++[table row] name='Cell 1, row 1, rowgroup 1, level 1' level:1 xml-roles:row
+++++++++[table cell] name='Cell 1, row 1, rowgroup 1, level 1' xml-roles:gridcell (row=0, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 1, row 1, rowgroup 1, level 1'
+++++++[table row] name='Cell 1, row 2, rowgroup 1, level 1' level:1 xml-roles:row
+++++++++[table cell] name='Cell 1, row 2, rowgroup 1, level 1' xml-roles:gridcell (row=1, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 1, row 2, rowgroup 1, level 1'
+++++++[table row] name='Cell 1, row 3, rowgroup 1, level 1' level:1 xml-roles:row
+++++++++[table cell] name='Cell 1, row 3, rowgroup 1, level 1' xml-roles:gridcell (row=2, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 1, row 3, rowgroup 1, level 1'
+++++++[table row] name='Cell 1, row 1, rowgroup 1, level 2' level:2 xml-roles:row
+++++++++[table cell] name='Cell 1, row 1, rowgroup 1, level 2' xml-roles:gridcell (row=3, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 1, row 1, rowgroup 1, level 2'
+++++++[table row] name='Cell 1, row 1, rowgroup 1, level 1' level:1 xml-roles:row
+++++++++[table cell] name='Cell 1, row 1, rowgroup 1, level 1' xml-roles:gridcell (row=4, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 1, row 1, rowgroup 1, level 1'
+++++[panel] setsize:1 xml-roles:rowgroup
+++++++[table row] name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1' level:1 xml-roles:row
+++++++++[table cell] name='Cell 1, row 1, rowgroup 2, level 1' xml-roles:gridcell (row=5, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 1, row 1, rowgroup 2, level 1'
+++++++++[table cell] name='Cell 2, row 1, rowgroup 2, level 1' xml-roles:gridcell (row=5, col=1, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 2, row 1, rowgroup 2, level 1'
+++++++[table row] name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2' level:2 xml-roles:row
+++++++++[table cell] name='Cell 1, row 1, rowgroup 2, level 2' xml-roles:gridcell (row=6, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 1, row 1, rowgroup 2, level 2'
+++++++++[table cell] name='Cell 2, row 1, rowgroup 2, level 2' xml-roles:gridcell (row=6, col=1, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 2, row 1, rowgroup 2, level 2'
+++++++++[table cell] name='Cell 3, row 1, rowgroup 2, level 2' xml-roles:gridcell (row=6, col=2, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
+++++++++++[static] name='Cell 3, row 1, rowgroup 2, level 2'
+++[tree table] xml-roles:treegrid cols=0 headers=(NONE); rows=0 headers=(NONE); caption=false; spans=(all: 1x1)
+++++[panel] setsize:4 xml-roles:rowgroup
+++++++[table row] name='Cell 1, row 1, rowgroup 1, level 1' level:1 xml-roles:row
+++++++++[static] name='Cell 1, row 1, rowgroup 1, level 1'
+++++++[table row] name='Cell 1, row 2, rowgroup 1, level 1' level:1 xml-roles:row
+++++++++[static] name='Cell 1, row 2, rowgroup 1, level 1'
+++++++[table row] name='Cell 1, row 3, rowgroup 1, level 1' level:1 xml-roles:row
+++++++++[static] name='Cell 1, row 3, rowgroup 1, level 1'
+++++++[table row] name='Cell 1, row 1, rowgroup 1, level 2' level:2 xml-roles:row
+++++++++[static] name='Cell 1, row 1, rowgroup 1, level 2'
+++++++[table row] name='Cell 1, row 1, rowgroup 1, level 1' level:1 xml-roles:row
+++++++++[static] name='Cell 1, row 1, rowgroup 1, level 1'
+++++[panel] setsize:1 xml-roles:rowgroup
+++++++[table row] name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1' level:1 xml-roles:row
+++++++++[static] name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1'
+++++++[table row] name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2' level:2 xml-roles:row
+++++++++[static] name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria/aria-treegrid-expected-blink.txt b/content/test/data/accessibility/aria/aria-treegrid-expected-blink.txt
index 4a93b74..4808002 100644
--- a/content/test/data/accessibility/aria/aria-treegrid-expected-blink.txt
+++ b/content/test/data/accessibility/aria/aria-treegrid-expected-blink.txt
@@ -3,17 +3,109 @@
 ++++genericContainer ignored
 ++++++treeGrid
 ++++++++rowGroup ignored
-++++++++++row hierarchicalLevel=1
-++++++++++++cell name='Cell at level 1'
-++++++++++++++staticText name='Cell at level 1'
-++++++++++++++++inlineTextBox name='Cell at level 1'
-++++++++++row hierarchicalLevel=2
-++++++++++++cell name='Cell at level 2'
-++++++++++++++staticText name='Cell at level 2'
-++++++++++++++++inlineTextBox name='Cell at level 2'
+++++++++++row name='Cell 1, row 1, level 1 Cell 2, row 1, level 1' hierarchicalLevel=1
+++++++++++++cell name='Cell 1, row 1, level 1'
+++++++++++++++staticText name='Cell 1, row 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, level 1'
+++++++++++++cell name='Cell 2, row 1, level 1'
+++++++++++++++staticText name='Cell 2, row 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 2, row 1, level 1'
+++++++++++row name='Cell 1, row 2, level 1 Cell 2, row 2, level 1' hierarchicalLevel=1
+++++++++++++cell name='Cell 1, row 2, level 1'
+++++++++++++++staticText name='Cell 1, row 2, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 2, level 1'
+++++++++++++cell name='Cell 2, row 2, level 1'
+++++++++++++++staticText name='Cell 2, row 2, level 1'
+++++++++++++++++inlineTextBox name='Cell 2, row 2, level 1'
+++++++++++row name='Cell 1, row 3, level 1 Cell 2, row 3, level 1' hierarchicalLevel=1
+++++++++++++cell name='Cell 1, row 3, level 1'
+++++++++++++++staticText name='Cell 1, row 3, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 3, level 1'
+++++++++++++cell name='Cell 2, row 3, level 1'
+++++++++++++++staticText name='Cell 2, row 3, level 1'
+++++++++++++++++inlineTextBox name='Cell 2, row 3, level 1'
+++++++++++row name='Cell 1, row 1, level 2' hierarchicalLevel=2
+++++++++++++cell name='Cell 1, row 1, level 2'
+++++++++++++++staticText name='Cell 1, row 1, level 2'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, level 2'
+++++++++++row name='Cell 1, row 2, level 2' hierarchicalLevel=2
+++++++++++++cell name='Cell 1, row 2, level 2'
+++++++++++++++staticText name='Cell 1, row 2, level 2'
+++++++++++++++++inlineTextBox name='Cell 1, row 2, level 2'
+++++++++++row name='Cell 1, row 3, level 2' hierarchicalLevel=2
+++++++++++++cell name='Cell 1, row 3, level 2'
+++++++++++++++staticText name='Cell 1, row 3, level 2'
+++++++++++++++++inlineTextBox name='Cell 1, row 3, level 2'
+++++++++++row name='Cell 1, row 4, level 2' hierarchicalLevel=2
+++++++++++++cell name='Cell 1, row 4, level 2'
+++++++++++++++staticText name='Cell 1, row 4, level 2'
+++++++++++++++++inlineTextBox name='Cell 1, row 4, level 2'
+++++++++++row name='Cell 1, row 2, level 2' hierarchicalLevel=3
+++++++++++++cell name='Cell 1, row 2, level 2'
+++++++++++++++staticText name='Cell 1, row 2, level 2'
+++++++++++++++++inlineTextBox name='Cell 1, row 2, level 2'
 ++++++treeGrid
-++++++++rowGroup
-++++++++++row hierarchicalLevel=1
-++++++++++++cell name='Cell at level 1'
-++++++++++++++staticText name='Cell at level 1'
-++++++++++++++++inlineTextBox name='Cell at level 1'
+++++++++rowGroup setSize=4
+++++++++++row name='Cell 1, row 1, rowgroup 1, level 1' hierarchicalLevel=1
+++++++++++++cell name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++++row name='Cell 1, row 2, rowgroup 1, level 1' hierarchicalLevel=1
+++++++++++++cell name='Cell 1, row 2, rowgroup 1, level 1'
+++++++++++++++staticText name='Cell 1, row 2, rowgroup 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 2, rowgroup 1, level 1'
+++++++++++row name='Cell 1, row 3, rowgroup 1, level 1' hierarchicalLevel=1
+++++++++++++cell name='Cell 1, row 3, rowgroup 1, level 1'
+++++++++++++++staticText name='Cell 1, row 3, rowgroup 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 3, rowgroup 1, level 1'
+++++++++++row name='Cell 1, row 1, rowgroup 1, level 2' hierarchicalLevel=2
+++++++++++++cell name='Cell 1, row 1, rowgroup 1, level 2'
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 1, level 2'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 1, level 2'
+++++++++++row name='Cell 1, row 1, rowgroup 1, level 1' hierarchicalLevel=1
+++++++++++++cell name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++rowGroup setSize=1
+++++++++++row name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1' hierarchicalLevel=1
+++++++++++++cell name='Cell 1, row 1, rowgroup 2, level 1'
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 2, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 2, level 1'
+++++++++++++cell name='Cell 2, row 1, rowgroup 2, level 1'
+++++++++++++++staticText name='Cell 2, row 1, rowgroup 2, level 1'
+++++++++++++++++inlineTextBox name='Cell 2, row 1, rowgroup 2, level 1'
+++++++++++row name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2' hierarchicalLevel=2
+++++++++++++cell name='Cell 1, row 1, rowgroup 2, level 2'
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 2, level 2'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 2, level 2'
+++++++++++++cell name='Cell 2, row 1, rowgroup 2, level 2'
+++++++++++++++staticText name='Cell 2, row 1, rowgroup 2, level 2'
+++++++++++++++++inlineTextBox name='Cell 2, row 1, rowgroup 2, level 2'
+++++++++++++cell name='Cell 3, row 1, rowgroup 2, level 2'
+++++++++++++++staticText name='Cell 3, row 1, rowgroup 2, level 2'
+++++++++++++++++inlineTextBox name='Cell 3, row 1, rowgroup 2, level 2'
+++++++treeGrid
+++++++++genericContainer ignored
+++++++++++rowGroup setSize=4
+++++++++++++row name='Cell 1, row 1, rowgroup 1, level 1' hierarchicalLevel=1
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++++++row name='Cell 1, row 2, rowgroup 1, level 1' hierarchicalLevel=1
+++++++++++++++staticText name='Cell 1, row 2, rowgroup 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 2, rowgroup 1, level 1'
+++++++++++++row name='Cell 1, row 3, rowgroup 1, level 1' hierarchicalLevel=1
+++++++++++++++staticText name='Cell 1, row 3, rowgroup 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 3, rowgroup 1, level 1'
+++++++++++++row name='Cell 1, row 1, rowgroup 1, level 2' hierarchicalLevel=2
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 1, level 2'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 1, level 2'
+++++++++++++row name='Cell 1, row 1, rowgroup 1, level 1' hierarchicalLevel=1
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 1, level 1'
+++++++++++rowGroup setSize=1
+++++++++++++row name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1' hierarchicalLevel=1
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1'
+++++++++++++row name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2' hierarchicalLevel=2
+++++++++++++++staticText name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2'
+++++++++++++++++inlineTextBox name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria/aria-treegrid-expected-mac.txt b/content/test/data/accessibility/aria/aria-treegrid-expected-mac.txt
index d4d0a70..9245977 100644
--- a/content/test/data/accessibility/aria/aria-treegrid-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-treegrid-expected-mac.txt
@@ -1,23 +1,129 @@
 AXWebArea
-++AXTable
-++++AXRow AXDisclosureLevel=0 AXIndex=0
+++AXTable AXARIASetSize=3
+++++AXRow AXIndex=0 AXTitle='Cell 1, row 1, level 1 Cell 2, row 1, level 1'
 ++++++AXCell
-++++++++AXStaticText AXValue='Cell at level 1'
-++++AXRow AXDisclosureLevel=1 AXIndex=1
+++++++++AXStaticText AXValue='Cell 1, row 1, level 1'
 ++++++AXCell
-++++++++AXStaticText AXValue='Cell at level 2'
+++++++++AXStaticText AXValue='Cell 2, row 1, level 1'
+++++AXRow AXIndex=1 AXTitle='Cell 1, row 2, level 1 Cell 2, row 2, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 2, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 2, row 2, level 1'
+++++AXRow AXIndex=2 AXTitle='Cell 1, row 3, level 1 Cell 2, row 3, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 3, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 2, row 3, level 1'
+++++AXRow AXIndex=3 AXTitle='Cell 1, row 1, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 1, level 2'
+++++AXRow AXIndex=4 AXTitle='Cell 1, row 2, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 2, level 2'
+++++AXRow AXIndex=5 AXTitle='Cell 1, row 3, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 3, level 2'
+++++AXRow AXIndex=6 AXTitle='Cell 1, row 4, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 4, level 2'
+++++AXRow AXIndex=7 AXTitle='Cell 1, row 2, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 2, level 2'
 ++++AXColumn AXIndex=0
 ++++++AXCell
-++++++++AXStaticText AXValue='Cell at level 1'
+++++++++AXStaticText AXValue='Cell 1, row 1, level 1'
 ++++++AXCell
-++++++++AXStaticText AXValue='Cell at level 2'
+++++++++AXStaticText AXValue='Cell 1, row 2, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 3, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 1, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 2, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 3, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 4, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 2, level 2'
+++++AXColumn AXIndex=1
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 2, row 1, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 2, row 2, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 2, row 3, level 1'
 ++++AXGroup
-++AXTable
+++AXTable AXARIASetSize=0
 ++++AXGroup
-++++++AXRow AXDisclosureLevel=0 AXIndex=0
+++++++AXRow AXIndex=0 AXTitle='Cell 1, row 1, rowgroup 1, level 1'
 ++++++++AXCell
-++++++++++AXStaticText AXValue='Cell at level 1'
+++++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 1, level 1'
+++++++AXRow AXIndex=1 AXTitle='Cell 1, row 2, rowgroup 1, level 1'
+++++++++AXCell
+++++++++++AXStaticText AXValue='Cell 1, row 2, rowgroup 1, level 1'
+++++++AXRow AXIndex=2 AXTitle='Cell 1, row 3, rowgroup 1, level 1'
+++++++++AXCell
+++++++++++AXStaticText AXValue='Cell 1, row 3, rowgroup 1, level 1'
+++++++AXRow AXIndex=3 AXTitle='Cell 1, row 1, rowgroup 1, level 2'
+++++++++AXCell
+++++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 1, level 2'
+++++++AXRow AXIndex=4 AXTitle='Cell 1, row 1, rowgroup 1, level 1'
+++++++++AXCell
+++++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 1, level 1'
+++++AXGroup
+++++++AXRow AXIndex=5 AXTitle='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1'
+++++++++AXCell
+++++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 2, level 1'
+++++++++AXCell
+++++++++++AXStaticText AXValue='Cell 2, row 1, rowgroup 2, level 1'
+++++++AXRow AXIndex=6 AXTitle='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2'
+++++++++AXCell
+++++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 2, level 2'
+++++++++AXCell
+++++++++++AXStaticText AXValue='Cell 2, row 1, rowgroup 2, level 2'
+++++++++AXCell
+++++++++++AXStaticText AXValue='Cell 3, row 1, rowgroup 2, level 2'
 ++++AXColumn AXIndex=0
 ++++++AXCell
-++++++++AXStaticText AXValue='Cell at level 1'
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 1, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 2, rowgroup 1, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 3, rowgroup 1, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 1, level 2'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 1, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 2, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 2, level 2'
+++++AXColumn AXIndex=1
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 2, row 1, rowgroup 2, level 1'
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 2, row 1, rowgroup 2, level 2'
+++++AXColumn AXIndex=2
+++++++AXCell
+++++++++AXStaticText AXValue='Cell 3, row 1, rowgroup 2, level 2'
+++++AXGroup
+++AXTable AXARIASetSize=0
+++++AXGroup
+++++++AXRow AXIndex=0 AXTitle='Cell 1, row 1, rowgroup 1, level 1'
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 1, level 1'
+++++++AXRow AXIndex=1 AXTitle='Cell 1, row 2, rowgroup 1, level 1'
+++++++++AXStaticText AXValue='Cell 1, row 2, rowgroup 1, level 1'
+++++++AXRow AXIndex=2 AXTitle='Cell 1, row 3, rowgroup 1, level 1'
+++++++++AXStaticText AXValue='Cell 1, row 3, rowgroup 1, level 1'
+++++++AXRow AXIndex=3 AXTitle='Cell 1, row 1, rowgroup 1, level 2'
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 1, level 2'
+++++++AXRow AXIndex=4 AXTitle='Cell 1, row 1, rowgroup 1, level 1'
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 1, level 1'
+++++AXGroup
+++++++AXRow AXIndex=5 AXTitle='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1'
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1'
+++++++AXRow AXIndex=6 AXTitle='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2'
+++++++++AXStaticText AXValue='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2'
 ++++AXGroup
diff --git a/content/test/data/accessibility/aria/aria-treegrid-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-treegrid-expected-uia-win.txt
new file mode 100644
index 0000000..abf0b00
--- /dev/null
+++ b/content/test/data/accessibility/aria/aria-treegrid-expected-uia-win.txt
@@ -0,0 +1,79 @@
+Document PositionInSet=0 SizeOfSet=0 Level=0
+++DataGrid PositionInSet=0 SizeOfSet=3 Level=0 Grid.ColumnCount=2 Grid.RowCount=8 Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Table.RowOrColumnMajor='RowMajor'
+++++TreeItem Name='Cell 1, row 1, level 1 Cell 2, row 1, level 1' PositionInSet=1 SizeOfSet=3 Level=1
+++++++DataItem Name='Cell 1, row 1, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
+++++++++Text Name='Cell 1, row 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++DataItem Name='Cell 2, row 1, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
+++++++++Text Name='Cell 2, row 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++TreeItem Name='Cell 1, row 2, level 1 Cell 2, row 2, level 1' PositionInSet=2 SizeOfSet=3 Level=1
+++++++DataItem Name='Cell 1, row 2, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
+++++++++Text Name='Cell 1, row 2, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++DataItem Name='Cell 2, row 2, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
+++++++++Text Name='Cell 2, row 2, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++TreeItem Name='Cell 1, row 3, level 1 Cell 2, row 3, level 1' PositionInSet=3 SizeOfSet=3 Level=1
+++++++DataItem Name='Cell 1, row 3, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
+++++++++Text Name='Cell 1, row 3, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++DataItem Name='Cell 2, row 3, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
+++++++++Text Name='Cell 2, row 3, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++TreeItem Name='Cell 1, row 1, level 2' PositionInSet=1 SizeOfSet=4 Level=2
+++++++DataItem Name='Cell 1, row 1, level 2' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=3 GridItem.RowSpan=1
+++++++++Text Name='Cell 1, row 1, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++TreeItem Name='Cell 1, row 2, level 2' PositionInSet=2 SizeOfSet=4 Level=2
+++++++DataItem Name='Cell 1, row 2, level 2' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=4 GridItem.RowSpan=1
+++++++++Text Name='Cell 1, row 2, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++TreeItem Name='Cell 1, row 3, level 2' PositionInSet=3 SizeOfSet=4 Level=2
+++++++DataItem Name='Cell 1, row 3, level 2' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=5 GridItem.RowSpan=1
+++++++++Text Name='Cell 1, row 3, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++TreeItem Name='Cell 1, row 4, level 2' PositionInSet=4 SizeOfSet=4 Level=2
+++++++DataItem Name='Cell 1, row 4, level 2' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=6 GridItem.RowSpan=1
+++++++++Text Name='Cell 1, row 4, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++TreeItem Name='Cell 1, row 2, level 2' PositionInSet=1 SizeOfSet=1 Level=3
+++++++DataItem Name='Cell 1, row 2, level 2' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=7 GridItem.RowSpan=1
+++++++++Text Name='Cell 1, row 2, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++DataGrid PositionInSet=0 SizeOfSet=0 Level=0 Grid.ColumnCount=3 Grid.RowCount=7 Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Table.RowOrColumnMajor='RowMajor'
+++++Group PositionInSet=0 SizeOfSet=4 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 1, level 1' PositionInSet=1 SizeOfSet=4 Level=1
+++++++++DataItem Name='Cell 1, row 1, rowgroup 1, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
+++++++++++Text Name='Cell 1, row 1, rowgroup 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 2, rowgroup 1, level 1' PositionInSet=2 SizeOfSet=4 Level=1
+++++++++DataItem Name='Cell 1, row 2, rowgroup 1, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
+++++++++++Text Name='Cell 1, row 2, rowgroup 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 3, rowgroup 1, level 1' PositionInSet=3 SizeOfSet=4 Level=1
+++++++++DataItem Name='Cell 1, row 3, rowgroup 1, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
+++++++++++Text Name='Cell 1, row 3, rowgroup 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 1, level 2' PositionInSet=1 SizeOfSet=1 Level=2
+++++++++DataItem Name='Cell 1, row 1, rowgroup 1, level 2' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=3 GridItem.RowSpan=1
+++++++++++Text Name='Cell 1, row 1, rowgroup 1, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 1, level 1' PositionInSet=4 SizeOfSet=4 Level=1
+++++++++DataItem Name='Cell 1, row 1, rowgroup 1, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=4 GridItem.RowSpan=1
+++++++++++Text Name='Cell 1, row 1, rowgroup 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++Group PositionInSet=0 SizeOfSet=1 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1' PositionInSet=1 SizeOfSet=1 Level=1
+++++++++DataItem Name='Cell 1, row 1, rowgroup 2, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=5 GridItem.RowSpan=1
+++++++++++Text Name='Cell 1, row 1, rowgroup 2, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++++DataItem Name='Cell 2, row 1, rowgroup 2, level 1' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=5 GridItem.RowSpan=1
+++++++++++Text Name='Cell 2, row 1, rowgroup 2, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2' PositionInSet=1 SizeOfSet=1 Level=2
+++++++++DataItem Name='Cell 1, row 1, rowgroup 2, level 2' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=6 GridItem.RowSpan=1
+++++++++++Text Name='Cell 1, row 1, rowgroup 2, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++++DataItem Name='Cell 2, row 1, rowgroup 2, level 2' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=6 GridItem.RowSpan=1
+++++++++++Text Name='Cell 2, row 1, rowgroup 2, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++++DataItem Name='Cell 3, row 1, rowgroup 2, level 2' PositionInSet=0 SizeOfSet=0 Level=0 GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=6 GridItem.RowSpan=1
+++++++++++Text Name='Cell 3, row 1, rowgroup 2, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++DataGrid PositionInSet=0 SizeOfSet=0 Level=0 Grid.ColumnCount=0 Grid.RowCount=0 Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Table.RowOrColumnMajor='RowMajor'
+++++Group PositionInSet=0 SizeOfSet=4 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 1, level 1' PositionInSet=1 SizeOfSet=4 Level=1
+++++++++Text Name='Cell 1, row 1, rowgroup 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 2, rowgroup 1, level 1' PositionInSet=2 SizeOfSet=4 Level=1
+++++++++Text Name='Cell 1, row 2, rowgroup 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 3, rowgroup 1, level 1' PositionInSet=3 SizeOfSet=4 Level=1
+++++++++Text Name='Cell 1, row 3, rowgroup 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 1, level 2' PositionInSet=1 SizeOfSet=1 Level=2
+++++++++Text Name='Cell 1, row 1, rowgroup 1, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 1, level 1' PositionInSet=4 SizeOfSet=4 Level=1
+++++++++Text Name='Cell 1, row 1, rowgroup 1, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++Group PositionInSet=0 SizeOfSet=1 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1' PositionInSet=1 SizeOfSet=1 Level=1
+++++++++Text Name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
+++++++TreeItem Name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2' PositionInSet=1 SizeOfSet=1 Level=2
+++++++++Text Name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2' IsControlElement=false PositionInSet=0 SizeOfSet=0 Level=0
diff --git a/content/test/data/accessibility/aria/aria-treegrid-expected-win.txt b/content/test/data/accessibility/aria/aria-treegrid-expected-win.txt
index 1b2c2c7..b6b3677 100644
--- a/content/test/data/accessibility/aria/aria-treegrid-expected-win.txt
+++ b/content/test/data/accessibility/aria/aria-treegrid-expected-win.txt
@@ -1,13 +1,79 @@
 ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
 ++ROLE_SYSTEM_OUTLINE xml-roles:treegrid
-++++ROLE_SYSTEM_OUTLINEITEM xml-roles:row level:1
-++++++ROLE_SYSTEM_CELL name='Cell at level 1' xml-roles:gridcell
-++++++++ROLE_SYSTEM_STATICTEXT name='Cell at level 1'
-++++ROLE_SYSTEM_OUTLINEITEM xml-roles:row level:2
-++++++ROLE_SYSTEM_CELL name='Cell at level 2' xml-roles:gridcell
-++++++++ROLE_SYSTEM_STATICTEXT name='Cell at level 2'
+++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, level 1 Cell 2, row 1, level 1' FOCUSABLE xml-roles:row level:1
+++++++ROLE_SYSTEM_CELL name='Cell 1, row 1, level 1' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, level 1'
+++++++ROLE_SYSTEM_CELL name='Cell 2, row 1, level 1' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 2, row 1, level 1'
+++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 2, level 1 Cell 2, row 2, level 1' FOCUSABLE xml-roles:row level:1
+++++++ROLE_SYSTEM_CELL name='Cell 1, row 2, level 1' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 2, level 1'
+++++++ROLE_SYSTEM_CELL name='Cell 2, row 2, level 1' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 2, row 2, level 1'
+++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 3, level 1 Cell 2, row 3, level 1' FOCUSABLE xml-roles:row level:1
+++++++ROLE_SYSTEM_CELL name='Cell 1, row 3, level 1' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 3, level 1'
+++++++ROLE_SYSTEM_CELL name='Cell 2, row 3, level 1' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 2, row 3, level 1'
+++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, level 2' FOCUSABLE xml-roles:row level:2
+++++++ROLE_SYSTEM_CELL name='Cell 1, row 1, level 2' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, level 2'
+++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 2, level 2' FOCUSABLE xml-roles:row level:2
+++++++ROLE_SYSTEM_CELL name='Cell 1, row 2, level 2' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 2, level 2'
+++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 3, level 2' FOCUSABLE xml-roles:row level:2
+++++++ROLE_SYSTEM_CELL name='Cell 1, row 3, level 2' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 3, level 2'
+++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 4, level 2' FOCUSABLE xml-roles:row level:2
+++++++ROLE_SYSTEM_CELL name='Cell 1, row 4, level 2' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 4, level 2'
+++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 2, level 2' FOCUSABLE xml-roles:row level:3
+++++++ROLE_SYSTEM_CELL name='Cell 1, row 2, level 2' xml-roles:gridcell
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 2, level 2'
 ++ROLE_SYSTEM_OUTLINE xml-roles:treegrid
-++++ROLE_SYSTEM_GROUPING xml-roles:rowgroup
-++++++ROLE_SYSTEM_OUTLINEITEM xml-roles:row level:1
-++++++++ROLE_SYSTEM_CELL name='Cell at level 1' xml-roles:gridcell
-++++++++++ROLE_SYSTEM_STATICTEXT name='Cell at level 1'
+++++ROLE_SYSTEM_GROUPING xml-roles:rowgroup setsize:4
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 1, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_CELL name='Cell 1, row 1, rowgroup 1, level 1' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 1, level 1'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 2, rowgroup 1, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_CELL name='Cell 1, row 2, rowgroup 1, level 1' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 2, rowgroup 1, level 1'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 3, rowgroup 1, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_CELL name='Cell 1, row 3, rowgroup 1, level 1' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 3, rowgroup 1, level 1'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 1, level 2' FOCUSABLE xml-roles:row level:2
+++++++++ROLE_SYSTEM_CELL name='Cell 1, row 1, rowgroup 1, level 2' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 1, level 2'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 1, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_CELL name='Cell 1, row 1, rowgroup 1, level 1' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 1, level 1'
+++++ROLE_SYSTEM_GROUPING xml-roles:rowgroup setsize:1
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_CELL name='Cell 1, row 1, rowgroup 2, level 1' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 2, level 1'
+++++++++ROLE_SYSTEM_CELL name='Cell 2, row 1, rowgroup 2, level 1' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 2, row 1, rowgroup 2, level 1'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2' FOCUSABLE xml-roles:row level:2
+++++++++ROLE_SYSTEM_CELL name='Cell 1, row 1, rowgroup 2, level 2' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 2, level 2'
+++++++++ROLE_SYSTEM_CELL name='Cell 2, row 1, rowgroup 2, level 2' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 2, row 1, rowgroup 2, level 2'
+++++++++ROLE_SYSTEM_CELL name='Cell 3, row 1, rowgroup 2, level 2' xml-roles:gridcell
+++++++++++ROLE_SYSTEM_STATICTEXT name='Cell 3, row 1, rowgroup 2, level 2'
+++ROLE_SYSTEM_OUTLINE xml-roles:treegrid
+++++ROLE_SYSTEM_GROUPING xml-roles:rowgroup setsize:4
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 1, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 1, level 1'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 2, rowgroup 1, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 2, rowgroup 1, level 1'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 3, rowgroup 1, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 3, rowgroup 1, level 1'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 1, level 2' FOCUSABLE xml-roles:row level:2
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 1, level 2'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 1, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 1, level 1'
+++++ROLE_SYSTEM_GROUPING xml-roles:rowgroup setsize:1
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1' FOCUSABLE xml-roles:row level:1
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 2, level 1 Cell 2, row 1, rowgroup 2, level 1'
+++++++ROLE_SYSTEM_OUTLINEITEM name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2' FOCUSABLE xml-roles:row level:2
+++++++++ROLE_SYSTEM_STATICTEXT name='Cell 1, row 1, rowgroup 2, level 2 Cell 2, row 1, rowgroup 2, level 2 Cell 3, row 1, rowgroup 2, level 2'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria/aria-treegrid.html b/content/test/data/accessibility/aria/aria-treegrid.html
index bff5ed27..a225d30 100644
--- a/content/test/data/accessibility/aria/aria-treegrid.html
+++ b/content/test/data/accessibility/aria/aria-treegrid.html
@@ -1,30 +1,119 @@
 <!--
+@AURALINUX-ALLOW:level*
+@AURALINUX-ALLOW:xml-roles:*
+@AURALINUX-ALLOW:setsize*
+@AURALINUX-ALLOW:posinset*
 @BLINK-ALLOW:hierarchicalLevel*
+@BLINK-ALLOW:setSize*
+@BLINK-ALLOW:posInSet*
+@MAC-ALLOW:AXARIASetSize
+@MAC-ALLOW:AXARIAPosInSet
 @MAC-ALLOW:AXIndex
 @MAC-ALLOW:AXRole=*
-@MAC-ALLOW:AXDisclosureLevel
-@WIN-ALLOW:xml-roles:*
+@MAC-ALLOW:
+@UIA-WIN-ALLOW:Level*
+@UIA-WIN-ALLOW:PositionInSet*
+@UIA-WIN-ALLOW:SizeOfSet*
 @WIN-ALLOW:level*
-@AURALINUX-ALLOW:xml-roles:*
-@AURALINUX-ALLOW:level*
+@WIN-ALLOW:setsize*
+@WIN-ALLOW:posinset*
+@WIN-ALLOW:xml-roles:*
 -->
 <!DOCTYPE html>
 <html>
+
 <body>
   <table role="treegrid">
-  <tr role="row" aria-level="1">
-    <td role="gridcell">Cell at level 1</td>
-  </tr>
-  <tr role="row" aria-level="2">
-    <td role="gridcell">Cell at level 2</td>
-  </tr>
+    <tr role="row" aria-level="1" tabindex=-1>
+      <td role="gridcell">Cell 1, row 1, level 1</td>
+      <td role="gridcell">Cell 2, row 1, level 1</td>
+    </tr>
+    <tr role="row" aria-level="1" tabindex=-1>
+      <td role="gridcell">Cell 1, row 2, level 1</td>
+      <td role="gridcell">Cell 2, row 2, level 1</td>
+    </tr>
+    <tr role="row" aria-level="1" tabindex=-1>
+      <td role="gridcell">Cell 1, row 3, level 1</td>
+      <td role="gridcell">Cell 2, row 3, level 1</td>
+    </tr>
+    <tr role="row" aria-level="2" tabindex=-1>
+      <td role="gridcell">Cell 1, row 1, level 2</td>
+    </tr>
+    <tr role="row" aria-level="2" tabindex=-1>
+      <td role="gridcell">Cell 1, row 2, level 2</td>
+    </tr>
+    <tr role="row" aria-level="2" tabindex=-1>
+      <td role="gridcell">Cell 1, row 3, level 2</td>
+    </tr>
+    <tr role="row" aria-level="2" tabindex=-1>
+      <td role="gridcell">Cell 1, row 4, level 2</td>
+    </tr>
+    <tr role="row" aria-level="3" tabindex=-1>
+      <td role="gridcell">Cell 1, row 2, level 2</td>
+    </tr>
   </table>
   <table role="treegrid">
     <tbody role="rowgroup">
-      <tr role="row" aria-level="1">
-        <td role="gridcell">Cell at level 1</td>
+      <tr role="row" aria-level="1" tabindex=-1>
+        <td role="gridcell">Cell 1, row 1, rowgroup 1, level 1</td>
+      </tr>
+      <tr role="row" aria-level="1" tabindex=-1>
+        <td role="gridcell">Cell 1, row 2, rowgroup 1, level 1</td>
+      </tr>
+      <tr role="row" aria-level="1" tabindex=-1>
+        <td role="gridcell">Cell 1, row 3, rowgroup 1, level 1</td>
+      </tr>
+      <tr role="row" aria-level="2" tabindex=-1>
+        <td role="gridcell">Cell 1, row 1, rowgroup 1, level 2</td>
+      </tr>
+      <tr role="row" aria-level="1" tabindex=-1>
+        <td role="gridcell">Cell 1, row 1, rowgroup 1, level 1</td>
+      </tr>
+    </tbody>
+    <tbody role="rowgroup">
+      <tr role="row" aria-level="1" tabindex=-1>
+        <td role="gridcell">Cell 1, row 1, rowgroup 2, level 1</td>
+        <td role="gridcell">Cell 2, row 1, rowgroup 2, level 1</td>
+      </tr>
+      <tr role="row" aria-level="2" tabindex=-1>
+        <td role="gridcell">Cell 1, row 1, rowgroup 2, level 2</td>
+        <td role="gridcell">Cell 2, row 1, rowgroup 2, level 2</td>
+        <td role="gridcell">Cell 3, row 1, rowgroup 2, level 2</td>
       </tr>
     </tbody>
   </table>
+  <div role="treegrid">
+    <div>
+      <div role="rowgroup">
+        <div role="row" aria-level="1" tabindex=-1>
+          <td role="gridcell">Cell 1, row 1, rowgroup 1, level 1</td>
+        </div>
+        <div role="row" aria-level="1" tabindex=-1>
+          <td role="gridcell">Cell 1, row 2, rowgroup 1, level 1</td>
+        </div>
+        <div role="row" aria-level="1" tabindex=-1>
+          <td role="gridcell">Cell 1, row 3, rowgroup 1, level 1</td>
+        </div>
+        <div role="row" aria-level="2" tabindex=-1>
+          <td role="gridcell">Cell 1, row 1, rowgroup 1, level 2</td>
+        </div>
+        <div role="row" aria-level="1" tabindex=-1>
+          <td role="gridcell">Cell 1, row 1, rowgroup 1, level 1</td>
+        </div>
+      </div>
+      <div role="rowgroup">
+        <div role="row" aria-level="1" tabindex=-1>
+          <td role="gridcell">Cell 1, row 1, rowgroup 2, level 1</td>
+          <td role="gridcell">Cell 2, row 1, rowgroup 2, level 1</td>
+        </div>
+        <div role="row" aria-level="2" tabindex=-1>
+          <td role="gridcell">Cell 1, row 1, rowgroup 2, level 2</td>
+          <td role="gridcell">Cell 2, row 1, rowgroup 2, level 2</td>
+          <td role="gridcell">Cell 3, row 1, rowgroup 2, level 2</td>
+        </div>
+      </div>
+    </div>
+  </div>
 </body>
-</html>
+
+</html>
\ No newline at end of file
diff --git a/content/test/data/accessibility/mac/attributes/ax-invalid-expected.txt b/content/test/data/accessibility/mac/attributes/ax-invalid-expected.txt
index b0fb44cd..a8b8f013 100644
--- a/content/test/data/accessibility/mac/attributes/ax-invalid-expected.txt
+++ b/content/test/data/accessibility/mac/attributes/ax-invalid-expected.txt
@@ -2,5 +2,8 @@
 focusable_invalid.AXInvalid='false'
 focusable_invalid_true.AXInvalid='true'
 focusable_invalid_false.AXInvalid='false'
+focusable_invalid_false.accessibilityAttributeValue(AXInvalid)='false'
 div_invalid_true.AXInvalid=n/a
+div_invalid_true.accessibilityAttributeValue(AXInvalid)='true'
 not_applicable.AXInvalid=n/a
+not_applicable.accessibilityAttributeValue(AXInvalid)='false'
diff --git a/content/test/data/accessibility/mac/attributes/ax-invalid.html b/content/test/data/accessibility/mac/attributes/ax-invalid.html
index ffe7007..d605bc7 100644
--- a/content/test/data/accessibility/mac/attributes/ax-invalid.html
+++ b/content/test/data/accessibility/mac/attributes/ax-invalid.html
@@ -4,8 +4,11 @@
   focusable_invalid.AXInvalid
   focusable_invalid_true.AXInvalid
   focusable_invalid_false.AXInvalid
+  focusable_invalid_false.accessibilityAttributeValue(AXInvalid)
   div_invalid_true.AXInvalid
+  div_invalid_true.accessibilityAttributeValue(AXInvalid)
   not_applicable.AXInvalid
+  not_applicable.accessibilityAttributeValue(AXInvalid)
 -->
 <!DOCTYPE html>
 <input id="focusable">
diff --git a/content/test/data/accessibility/mac/attributes/ax-url-expected.txt b/content/test/data/accessibility/mac/attributes/ax-url-expected.txt
index ec2ad64..ea78f07 100644
--- a/content/test/data/accessibility/mac/attributes/ax-url-expected.txt
+++ b/content/test/data/accessibility/mac/attributes/ax-url-expected.txt
@@ -1,4 +1,4 @@
 a.accessibilityAttributeNames.has(AXURL)='yes'
-a.AXURL='https://example.com/'
+a.accessibilityAttributeValue(AXURL)='https://example.com/'
 not_applicable.accessibilityAttributeNames.has(AXURL)='no'
-not_applicable.AXURL=n/a
+not_applicable.accessibilityAttributeValue(AXURL)=NULL
diff --git a/content/test/data/accessibility/mac/attributes/ax-url.html b/content/test/data/accessibility/mac/attributes/ax-url.html
index e1c16819..24082306 100644
--- a/content/test/data/accessibility/mac/attributes/ax-url.html
+++ b/content/test/data/accessibility/mac/attributes/ax-url.html
@@ -1,9 +1,9 @@
 <!--
 @SCRIPT:
   a.accessibilityAttributeNames.has(AXURL)
-  a.AXURL
+  a.accessibilityAttributeValue(AXURL)
   not_applicable.accessibilityAttributeNames.has(AXURL)
-  not_applicable.AXURL
+  not_applicable.accessibilityAttributeValue(AXURL)
 -->
 <!DOCTYPE html>
 <a id="a" href="https://example.com">link</a>
diff --git a/content/test/data/accessibility/readme.md b/content/test/data/accessibility/readme.md
index 4658bb25..2da80cb2 100644
--- a/content/test/data/accessibility/readme.md
+++ b/content/test/data/accessibility/readme.md
@@ -79,7 +79,6 @@
 Supported platforms are:
 * `android` -- expected Android AccessibilityNodeInfo output
 * `auralinux` -- expected Linux ATK output
-* `auralinux-trusty` -- expected Linux ATK output (Version Specific Expected File)
 * `auralinux-xenial` -- expected Linux ATK output (Version Specific Expected File)
 * `blink` -- representation of internal accessibility tree
 * `blink-cros` -- representation of internal accessibility tree
@@ -120,16 +119,14 @@
 In the case of Linux, the tests are run on several LTS
 [releases](https://releases.ubuntu.com/) of Ubuntu:
 
-* "Trusty Tahr": Ubuntu 14.04 LTS, ATK version 2.10 (bot: "linux-trusty-rel")
 * "Xenial Xerus": Ubuntu 16.04, ATK version 2.18 (bot: "linux-xenial-rel")
 * "Bionic Beaver": Ubuntu 18.04, ATK version 2.28 (runs on multiple bots)
 
 In many cases the expected results for `foo.html` will be the same for all
 versions of Ubuntu, in which case `foo-expected-auralinux.txt` is all that is
 needed. However, if the `foo.html` test passes on the Linux release build
-("linux-rel"), but fails on "linux-trusty-rel", you will need an additional
-`foo-expected-auralinux-trusty.txt` file. If it also fails on "linux-xenial-rel",
-create `foo-expected-auralinux-xenial.txt`.
+("linux-rel"), but fails on "linux-xenial-rel", you will need an additional
+`foo-expected-auralinux-xenial.txt` file.
 
 At the present time there is no version-specific support for Bionic Beaver,
 which is the current version run on "linux-rel".
diff --git a/content/test/gpu/gather_power_measurement_results.py b/content/test/gpu/gather_power_measurement_results.py
index 4c5ce024..f31ad50a 100755
--- a/content/test/gpu/gather_power_measurement_results.py
+++ b/content/test/gpu/gather_power_measurement_results.py
@@ -163,7 +163,9 @@
       test_name = tokens[1]
       if tokens[2] != 'passed':
         logging.warning('Wrong format for test passed line: %s', line)
+      # pylint: disable=unsupported-assignment-operation
       my_results['name'] = test_name
+      # pylint: enable=unsupported-assignment-operation
       entry['tests'].append(my_results)
     elif line.startswith('Chrome Env: '):
       chrome_env = ast.literal_eval(line[len('Chrome Env: '):])
diff --git a/content/test/gpu/gpu_tests/color_profile_manager_mac.py b/content/test/gpu/gpu_tests/color_profile_manager_mac.py
index 93d4a030..cf045cc 100644
--- a/content/test/gpu/gpu_tests/color_profile_manager_mac.py
+++ b/content/test/gpu/gpu_tests/color_profile_manager_mac.py
@@ -2,11 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# The Foundation and Quartz modules are opaque and will trigger no-member
-# warnings on Mac. They will not exist on other platforms and will trigger
-# import-error warnings.
-# pylint: disable=no-member
-# pylint: disable=import-error
 # Variables will be pulled into globals() from the ColorSync framework, and will
 # trigger undefined-variables.
 # pylint: disable=undefined-variable
@@ -14,9 +9,11 @@
 
 import sys
 if sys.platform.startswith('darwin'):
+  # pylint: disable=import-error
   import Foundation
   import Quartz
   import objc
+  # pylint: enable=import-error
   # There is no module for the ColorSync framework, so synthesize one using
   # bridge # support.
   color_sync_framework = '/System/Library/Frameworks/ApplicationServices.' \
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index 0a9e1a4..6f9a0c9 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -489,6 +489,13 @@
 crbug.com/1288586 [ android android-pixel-6 no-passthrough skia-renderer-gl android-webview-instrumentation ] Pixel_OffscreenCanvasWebGLDefault [ Failure ]
 crbug.com/1289884 [ android android-pixel-6 skia-renderer-vulkan android-webview-instrumentation ] * [ Failure ]
 
+crbug.com/1290953 [ android android-nexus-5x android-webview-instrumentation ] Pixel_CanvasLowLatency2D [ Failure ]
+crbug.com/1290953 [ android android-nexus-5x android-webview-instrumentation ] Pixel_CanvasLowLatency2DDrawImage [ Failure ]
+crbug.com/1290953 [ android android-nexus-5x android-webview-instrumentation ] Pixel_CanvasLowLatency2DImageData [ Failure ]
+crbug.com/1290953 [ android android-pixel-4 android-webview-instrumentation ] Pixel_CanvasLowLatency2D [ Failure ]
+crbug.com/1290953 [ android android-pixel-4 android-webview-instrumentation ] Pixel_CanvasLowLatency2DDrawImage [ Failure ]
+crbug.com/1290953 [ android android-pixel-4 android-webview-instrumentation ] Pixel_CanvasLowLatency2DImageData [ Failure ]
+
 #######################################################################
 # Automated Entries After This Point - Do Not Manually Add Below Here #
 #######################################################################
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index de31aa4..140822c 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -295,11 +295,6 @@
 # ========================
 # Fails on all platforms
 
-crbug.com/1082533 [ mac intel ] conformance/textures/misc/texture-copying-and-deletion.html [ Failure ]
-# TODO(crbug.com/1136231): Uncomment suppressions for s3tc-and-rgtc.html below
-# under crbug.com/963205 and crbug.com/964321 once these two failures are fixed.
-crbug.com/1136231 [ win passthrough ] conformance/extensions/s3tc-and-rgtc.html [ Failure ]
-crbug.com/1136231 [ linux passthrough ] conformance/extensions/s3tc-and-rgtc.html [ Failure ]
 # The validating command decoder suppressions here will not be fixed.
 crbug.com/angleproject/6245 [ no-passthrough ] conformance/extensions/ext-texture-compression-bptc.html [ Failure ]
 crbug.com/angleproject/6245 [ no-passthrough ] conformance/extensions/ext-texture-compression-rgtc.html [ Failure ]
@@ -308,7 +303,7 @@
 
 # Failing on most platforms. Only runs with passthrough.
 crbug.com/1175371 [ android ] conformance/extensions/khr-parallel-shader-compile.html [ Failure ]
-crbug.com/1175371 [ chromeos ] conformance/extensions/khr-parallel-shader-compile.html [ Failure ]
+crbug.com/1175371 [ chromeos ] conformance/extensions/khr-parallel-shader-compile.html [ Failure ]  # finder:disable May still be relevant once WebGL is run with passthrough on ChromeOS
 crbug.com/1175371 [ linux ] conformance/extensions/khr-parallel-shader-compile.html [ Failure ]
 crbug.com/1175371 [ mac ] conformance/extensions/khr-parallel-shader-compile.html [ Failure ]
 crbug.com/1175371 [ win ] conformance/extensions/khr-parallel-shader-compile.html [ Failure ]
@@ -326,6 +321,7 @@
 crbug.com/849572 [ win angle-d3d11 passthrough ] conformance/extensions/angle-instanced-arrays-out-of-bounds.html [ Failure ]
 crbug.com/849572 [ angle-opengl passthrough ] conformance/extensions/angle-instanced-arrays-out-of-bounds.html [ Failure ]
 crbug.com/849572 [ angle-vulkan passthrough ] conformance/extensions/angle-instanced-arrays-out-of-bounds.html [ Failure ]
+crbug.com/849572 [ angle-swiftshader passthrough ] conformance/extensions/angle-instanced-arrays-out-of-bounds.html [ Failure ]
 
 # Nvidia bugs fixed in latest driver
 # TODO(http://crbug.com/887241): Upgrade the drivers on the bots.
@@ -337,23 +333,13 @@
 
 crbug.com/953120 conformance/programs/program-handling.html [ Failure ]
 
-crbug.com/1163292 [ win nvidia angle-d3d9 ] conformance/textures/misc/texture-corner-case-videos.html [ RetryOnFailure ]
-
-# TODO(crbug.com/1097338): simplify this expectation once fuchsia case is fixed
-crbug.com/1105129 [ linux ] conformance/context/context-creation.html [ RetryOnFailure ]
-crbug.com/1105129 [ win ] conformance/context/context-creation.html [ RetryOnFailure ]
-
 # Temporary suppression while we wait for a spec update.
 # TODO(jmadill): Remove when possible.
 crbug.com/angleproject/6358 conformance/programs/program-test.html [ Failure ]
 
 # Win / AMD / Passthrough command decoder / D3D11
-crbug.com/772037 [ win amd angle-d3d11 passthrough ] conformance/textures/misc/texture-sub-image-cube-maps.html [ RetryOnFailure ]
 crbug.com/1282819 [ win amd-0x6613 angle-d3d11 passthrough ] conformance/canvas/canvas-test.html [ Failure ]
 
-# Vulkan / Passthrough command decoder
-crbug.com/angleproject/4931 [ win nvidia angle-vulkan passthrough ] conformance/textures/misc/texture-mips.html [ Failure ]
-
 # Win / Intel / Vulkan / Passthrough command decoder
 # Technically flaky, but flake rate is too high for RetryOnFailure.
 # TODO(crbug.com/1276153) uncomment after fix for updated part of test applies
@@ -371,8 +357,6 @@
 crbug.com/1145858 [ fuchsia fuchsia-board-astro ] conformance/extensions/ext-disjoint-timer-query.html [ Failure ]
 crbug.com/1145861 [ fuchsia fuchsia-board-astro ] conformance/extensions/oes-texture-float-with-video.html [ Failure ]
 crbug.com/1145861 [ fuchsia fuchsia-board-astro ] conformance/extensions/oes-texture-half-float-with-video.html [ Failure ]
-crbug.com/1145926 [ fuchsia fuchsia-board-astro ] conformance/ogles/GL/faceforward/faceforward_001_to_006.html [ Failure ]
-crbug.com/1145926 [ fuchsia fuchsia-board-astro ] conformance/ogles/GL/step/step_001_to_006.html [ Failure ]
 crbug.com/1261867 [ fuchsia fuchsia-board-astro ] conformance/rendering/color-mask-preserved-during-implicit-clears.html [ Failure ]
 crbug.com/1261867 [ fuchsia fuchsia-board-astro ] conformance/rendering/scissor-rect-repeated-rendering.html [ Failure ]
 crbug.com/1145861 [ fuchsia fuchsia-board-astro ] conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
@@ -392,14 +376,8 @@
 crbug.com/1145861 [ fuchsia fuchsia-board-astro ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Failure ]
 crbug.com/1145861 [ fuchsia fuchsia-board-astro ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Failure ]
 # OOM on hardware devices
-crbug.com/1145951 [ fuchsia fuchsia-board-astro ] conformance/rendering/multisample-corruption.html [ Failure ]
 crbug.com/1145951 [ fuchsia fuchsia-board-astro ] conformance/rendering/preservedrawingbuffer-leak.html [ Failure ]
-# Specific build issue
-crbug.com/1146483 [ fuchsia fuchsia-board-astro ] conformance/textures/misc/tex-video-using-tex-unit-non-zero.html [ Failure ]
-crbug.com/1146483 [ fuchsia fuchsia-board-astro ] conformance/textures/misc/texture-upload-size.html [ Failure ]
 crbug.com/1146483 [ fuchsia fuchsia-board-astro ] conformance/textures/misc/texture-video-transparent.html [ Failure ]
-crbug.com/1146483 [ fuchsia fuchsia-board-astro ] conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html [ Failure ]
-crbug.com/1146483 [ fuchsia fuchsia-board-astro ] conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html [ Failure ]
 # Flaky tests
 [ fuchsia fuchsia-board-astro ] WebglExtension_EXT_float_blend [ Failure ]
 [ fuchsia fuchsia-board-sherlock ] WebglExtension_EXT_float_blend [ Failure ]
@@ -407,9 +385,9 @@
 [ fuchsia fuchsia-board-astro ] conformance/canvas/drawingbuffer-static-canvas-test.html [ Failure ]
 crbug.com/1145861 [ fuchsia fuchsia-board-astro ] conformance/textures/misc/texture-corner-case-videos.html [ Failure ]
 crbug.com/1145861 [ fuchsia fuchsia-board-astro ] conformance/textures/misc/texture-npot-video.html [ Failure ]
-crbug.com/1210953 [ fuchsia fuchsia-board-astro ] conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ Failure ]
+crbug.com/1210953 [ fuchsia fuchsia-board-astro ] conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ]
 crbug.com/1210953 [ fuchsia fuchsia-board-astro ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ]
-crbug.com/1210953 [ fuchsia fuchsia-board-astro ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Failure ]
+crbug.com/1210953 [ fuchsia fuchsia-board-astro ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
 crbug.com/1210953 [ fuchsia fuchsia-board-astro ] conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html [ RetryOnFailure ]
 crbug.com/1210953 [ fuchsia fuchsia-board-astro ] conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ]
 crbug.com/1210953 [ fuchsia fuchsia-board-astro ] conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html [ RetryOnFailure ]
@@ -417,7 +395,7 @@
 # Flaky tests
 crbug.com/1136414 [ fuchsia fuchsia-board-qemu-x64 ] conformance/glsl/functions/glsl-function* [ Failure ]
 crbug.com/1136414 [ fuchsia fuchsia-board-qemu-x64 ] conformance/ogles/GL/fract/fract_001_to_006.html [ Failure ]
-crbug.com/1136414 [ fuchsia fuchsia-board-qemu-x64 ] conformance/ogles/GL/build/build_009_to_016.html [ Failure ]
+crbug.com/1136414 [ fuchsia fuchsia-board-qemu-x64 ] conformance/ogles/GL/build/build_009_to_016.html [ RetryOnFailure ]
 crbug.com/1136414 [ fuchsia fuchsia-board-qemu-x64 ] conformance/ogles/GL/mat/mat_009_to_016.html [ Failure ]
 
 # Anti-aliasing disabled on Fuchsia
@@ -456,42 +434,16 @@
 # Win failures     #
 ####################
 
-# Intel flaky issues
-crbug.com/929009 [ win intel ] conformance/glsl/misc/shader-with-non-reserved-words.html [ RetryOnFailure ]
-crbug.com/1111652 [ win intel angle-vulkan passthrough ] conformance/context/context-size-change.html [ Failure ]
-crbug.com/1219015 [ win angle-d3d11 intel ] conformance/textures/misc/video-rotation.html [ Failure ]
-
-# Intel driver issues
-crbug.com/854100 [ win intel angle-opengl passthrough intel_lt_25.20.100.6577 ] conformance/glsl/variables/gl-pointcoord.html [ Failure ]
-crbug.com/angleproject/2909 [ win intel angle-vulkan passthrough intel_lt_26.20.100.7000 ] conformance/ogles/GL/faceforward/faceforward_001_to_006.html [ Failure ]
-crbug.com/angleproject/2722 [ win intel angle-vulkan passthrough intel_lt_26.20.100.7323 ] conformance/rendering/clipping-wide-points.html [ Failure ]
-crbug.com/1082565 [ win intel angle-opengl passthrough intel_lt_26.20.100.8141 ] conformance/canvas/webgl-to-2d-canvas.html [ Failure ]
-
 # Intel OpenGL driver issue, fixed in 27.20.100.9126
 crbug.com/angleproject/5543 [ win intel angle-opengl passthrough ] conformance/extensions/webgl-compressed-texture-s3tc-srgb.html [ Failure ]
 
-# This is an OpenGL driver bug on Intel platform and it is fixed in
-# Intel Driver 25.20.100.6444.
-# Case no-over-optimization-on-uniform-array-09 always fail if run
-# case biuDepthRange_001_to_002 first.
-# Temporarily skip these two cases now because this issue blocks
-# WEBGL_video_texture implementation.
-crbug.com/907195 [ win intel angle-opengl passthrough intel_lt_25.20.100.6444 ] conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html [ Failure ]
-crbug.com/907195 [ win intel angle-opengl passthrough intel_lt_25.20.100.6444 ] conformance/uniforms/no-over-optimization-on-uniform-array-09.html [ Failure ]
-
 # Note that the following test seems to pass, but it may still be flaky.
 crbug.com/478572 [ win angle-d3d9 passthrough ] deqp/data/gles2/shaders/functions.html [ Failure ]
 
 # Win NVIDIA failures
-crbug.com/1045339 [ win10 debug-x64 nvidia ] conformance/extensions/oes-texture-half-float-with-video.html [ Failure ]
-crbug.com/1143392 [ win nvidia passthrough ] conformance/glsl/misc/shader-with-non-reserved-words.html [ Failure ]
 crbug.com/angleproject/5536 [ win nvidia angle-opengl passthrough oop-c ] conformance/glsl/samplers/glsl-function-texture2dprojlod.html [ Failure ]
 
-# Win10 / NVIDIA Quadro P400 / D3D9 failures
-crbug.com/750896 [ win10 nvidia-0x1cb3 angle-d3d9 ] conformance/textures/video/* [ RetryOnFailure ]
-
 # Win / AMD D3D11 (default) failures
-crbug.com/878780 [ win amd ] conformance/textures/webgl_canvas/* [ RetryOnFailure ]
 crbug.com/1043773 [ win amd ] conformance/renderbuffers/depth-renderbuffer-initialization.html [ RetryOnFailure ]
 
 # Win / AMD D3D9 failures
@@ -501,71 +453,28 @@
 crbug.com/1152597 [ win amd-0x7340 angle-d3d11 ] conformance/renderbuffers/framebuffer-state-restoration.html [ Failure ]
 crbug.com/1152599 [ win amd-0x7340 angle-d3d11 ] conformance/rendering/polygon-offset.html [ Failure ]
 crbug.com/1152602 [ win amd-0x7340 angle-d3d11 ] conformance/canvas/drawingbuffer-static-canvas-test.html [ RetryOnFailure ]
-crbug.com/1152619 [ win10 amd-0x7340 angle-d3d9 ] conformance/textures/misc/texture-corner-case-videos.html [ Failure ]
-crbug.com/1152619 [ win amd-0x7340 angle-d3d9 ] conformance/textures/misc/texture-npot-video.html [ Failure ]
-crbug.com/1152621 [ win amd-0x7340 angle-vulkan ] conformance/attribs/gl-vertexattribpointer-offsets.html [ Failure ]
-crbug.com/1152623 [ win amd-0x7340 angle-vulkan ] conformance/extensions/webgl-draw-buffers.html [ Failure ]
 
 # Win / D3D9 failures
 # Skipping these two tests because they're causing assertion failures.
-crbug.com/angleproject/896 [ win angle-d3d9 no-passthrough ] conformance/extensions/oes-texture-float-with-canvas.html [ Failure ]
-crbug.com/angleproject/896 [ win angle-d3d9 no-passthrough ] conformance/extensions/oes-texture-half-float-with-canvas.html [ Failure ]
 
 # The functions test have been persistently flaky on D3D9
-crbug.com/674572 [ win angle-d3d9 ] conformance/glsl/misc/large-loop-compile.html [ Failure ]
 crbug.com/956134 [ win angle-d3d9 ] conformance/extensions/webgl-depth-texture.html [ Failure ]
 
-# WIN / OpenGL / NVIDIA failures
-crbug.com/715001 [ win nvidia angle-opengl passthrough ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
-# crbug.com/963205 [ win nvidia angle-opengl passthrough ] conformance/extensions/s3tc-and-rgtc.html [ RetryOnFailure ]
-crbug.com/963205 [ win nvidia angle-opengl passthrough ] conformance/extensions/webgl-compressed-texture-s3tc-srgb.html [ RetryOnFailure ]
-
 # Mark ANGLE's OpenGL as flaky on Windows Nvidia
 crbug.com/582083 [ win nvidia angle-opengl ] conformance/* [ RetryOnFailure ]
 
 # D3D9 / Passthrough command decoder
-crbug.com/angleproject/1179 [ win angle-d3d9 passthrough ] conformance/glsl/bugs/floor-div-cos-should-not-truncate.html [ Failure ]
 crbug.com/angleproject/2192 [ win angle-d3d9 passthrough ] conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
 crbug.com/angleproject/2192 [ win angle-d3d9 passthrough ] conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
-crbug.com/angleproject/2192 [ win angle-d3d9 passthrough ] conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
-crbug.com/angleproject/2192 [ win angle-d3d9 passthrough ] conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
-crbug.com/angleproject/2192 [ win angle-d3d9 passthrough ] conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
-crbug.com/angleproject/2192 [ win angle-d3d9 passthrough ] conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
-crbug.com/angleproject/2192 [ win angle-d3d9 passthrough ] conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
-crbug.com/angleproject/2192 [ win angle-d3d9 passthrough ] conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
-crbug.com/1191456 [ win angle-d3d9 passthrough ] conformance/textures/misc/video-rotation.html [ Failure ]
-crbug.com/1248121 [ win angle-d3d9 passthrough ] conformance/extensions/oes-texture-float-linear.html [ RetryOnFailure ]
-
-# Win D3D11 / Passthrough / Intel+AMD
-crbug.com/1215624 [ win angle-d3d11 passthrough intel ] conformance/textures/video/* [ RetryOnFailure ]
-crbug.com/1215624 [ win angle-d3d11 passthrough amd   ] conformance/textures/video/* [ RetryOnFailure ]
 
 # D3D9 / AMD RX 5500 XT / Passthrough command decoder
 crbug.com/1159126 [ win amd-0x7340 angle-d3d9 passthrough ] conformance/more/glsl/uniformOutOfBounds.html [ RetryOnFailure ]
-crbug.com/1159126 [ win amd-0x7340 angle-d3d9 passthrough ] conformance/more/glsl/arrayOutOfBounds.html [ RetryOnFailure ]
-crbug.com/1159126 [ win amd-0x7340 angle-d3d9 passthrough ] conformance/ogles/GL/abs/abs_001_to_006.html [ RetryOnFailure ]
-
-# Vulkan / Win / Passthrough command decoder
-crbug.com/angleproject/2921 [ win angle-vulkan passthrough ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ Failure ]
-crbug.com/angleproject/3111 [ win angle-vulkan passthrough ] deqp/data/gles2/shaders/swizzles.html [ Failure ]
-crbug.com/angleproject/4334 [ win angle-vulkan passthrough ] conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html [ Failure ]
 
 # Vulkan / Win (32-bit) / Passthrough command decoder
 crbug.com/1216686 [ win angle-vulkan passthrough ] conformance/glsl/bugs/complex-glsl-does-not-crash.html [ Failure ]
 crbug.com/1216686 [ win angle-vulkan passthrough ] conformance/glsl/misc/shader-uniform-packing-restrictions.html [ Failure ]
-crbug.com/1216686 [ win angle-swiftshader passthrough ] conformance/glsl/bugs/complex-glsl-does-not-crash.html [ Failure ]
-crbug.com/1216686 [ win angle-swiftshader passthrough ] conformance/glsl/misc/shader-uniform-packing-restrictions.html [ Failure ]
 
 # Vulkan / Win / NVIDIA / Passthrough command decoder
-crbug.com/angleproject/3469 [ win angle-vulkan passthrough nvidia ] conformance/extensions/webgl-draw-buffers.html [ Failure ]
-crbug.com/963205 [ win nvidia angle-vulkan passthrough ] conformance/extensions/webgl-compressed-texture-s3tc-srgb.html [ Failure ]
-# crbug.com/964321 [ win nvidia angle-vulkan passthrough ] conformance/extensions/s3tc-and-rgtc.html [ RetryOnFailure ]
-crbug.com/1051576 [ win nvidia angle-vulkan passthrough ] conformance/extensions/webgl-compressed-texture-size-limit.html [ Failure ]
-crbug.com/963217 [ win nvidia angle-vulkan passthrough ] conformance/glsl/samplers/glsl-function-texture2dprojlod.html [ Failure ]
-crbug.com/angleproject/3883 [ win nvidia angle-vulkan passthrough ] conformance/misc/uninitialized-test.html [ Failure ]
-crbug.com/963223 [ win nvidia angle-vulkan passthrough ] conformance/rendering/out-of-bounds-array-buffers.html [ Failure ]
-crbug.com/angleproject/2930 [ win nvidia angle-vulkan passthrough ] conformance/textures/misc/texture-size-cube-maps.html [ Failure ]
-crbug.com/1082826 [ win nvidia angle-vulkan passthrough ] conformance/buffers/buffer-data-dynamic-delay.html [ Failure ]
 crbug.com/1209189 [ win nvidia angle-vulkan passthrough ] conformance/glsl/constructors/glsl-construct-vec-mat-index.html [ Failure ]
 crbug.com/angleproject/6281 [ win nvidia angle-vulkan passthrough ] conformance/misc/shader-precision-format.html [ Failure ]
 crbug.com/1242454 [ win nvidia angle-vulkan passthrough ] conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html [ Failure ]
@@ -573,11 +482,7 @@
 crbug.com/1259977 [ win nvidia-0x2184 angle-vulkan passthrough ] conformance/glsl/functions/glsl-function-ceil.html [ Failure ]
 crbug.com/1259977 [ win nvidia-0x2184 angle-vulkan passthrough ] conformance/glsl/functions/glsl-function-faceforward.html [ Failure ]
 
-# Flaky since crbug.com/1017162
-crbug.com/1017162 [ win nvidia angle-vulkan passthrough ] conformance/extensions/angle-instanced-arrays.html [ Failure ]
-crbug.com/1017162 [ win nvidia angle-vulkan passthrough ] conformance/ogles/GL/* [ Failure ]
-crbug.com/1017162 [ win nvidia angle-vulkan passthrough ] conformance/context/context-attribute-preserve-drawing-buffer.html [ Failure ]
-crbug.com/1017162 [ win nvidia angle-vulkan passthrough ] conformance/extensions/oes-fbo-render-mipmap.html [ Failure ]
+crbug.com/1291276 [ win nvidia angle-vulkan passthrough ] conformance/ogles/GL/mod/mod_001_to_008.html [ Failure ]
 
 ####################
 # Mac failures     #
@@ -587,10 +492,6 @@
 
 # Mac AMD failures
 crbug.com/642822 [ mac amd ] conformance/rendering/clipping-wide-points.html [ Failure ]
-crbug.com/1203167 [ mac amd angle-disabled ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
-crbug.com/1203167 [ mac amd angle-opengl ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
-crbug.com/1203167 [ mac amd angle-metal ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
-crbug.com/1230781 [ mac amd-0x6821 ] conformance/canvas/to-data-url-test.html [ Failure ]
 crbug.com/1230781 [ mac amd-0x679e ] conformance/canvas/to-data-url-test.html [ Failure ]
 crbug.com/1236072 [ mac amd-0x679e angle-opengl ] conformance/renderbuffers/stencil-renderbuffer-initialization.html [ Failure ]
 crbug.com/1227774 [ mac amd angle-opengl ] conformance/glsl/misc/shader-with-non-reserved-words.html [ RetryOnFailure ]
@@ -603,57 +504,31 @@
 # Mac Intel ANGLE and native OpenGL
 crbug.com/1144247 [ mac intel-0x3e9b angle-disabled ] conformance/extensions/angle-instanced-arrays.html [ Failure ]
 crbug.com/1144207 [ mac intel-0x3e9b angle-disabled ] conformance/extensions/webgl-multi-draw.html [ Failure ]
-crbug.com/1018028 [ mac intel angle-disabled ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ]
-crbug.com/886970 [ mac intel-0xa2e angle-disabled ] conformance/rendering/canvas-alpha-bug.html [ Failure ]
-crbug.com/782317 [ mac intel angle-opengl ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
-crbug.com/782317 [ mac intel angle-disabled ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
-crbug.com/1092734 [ mac passthrough intel angle-opengl ] conformance/textures/webgl_canvas/tex-2d-rgba-rgba* [ Failure ]
 
 # Mac Retina NVidia failures
-crbug.com/635081 [ mac nvidia-0xfe9 ] conformance/attribs/gl-disabled-vertex-attrib.html [ Failure ]
 crbug.com/996344 [ mac nvidia-0xfe9 ] conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html [ Failure ]
 crbug.com/635081 [ mac nvidia-0xfe9 no-passthrough ] conformance/renderbuffers/framebuffer-object-attachment.html [ Failure ]
 crbug.com/635081 [ mac nvidia-0xfe9 no-passthrough ] conformance/textures/misc/tex-input-validation.html [ Failure ]
 crbug.com/784817 [ mac nvidia-0xfe9 ] conformance/glsl/bugs/init-array-with-loop.html [ Failure ]
 crbug.com/1136231 [ mac nvidia-0xfe9 passthrough ] conformance/extensions/s3tc-and-rgtc.html [ Failure ]
 
-# Mac / Passthrough command decoder
-crbug.com/angleproject/4986 [ mac passthrough ] conformance/textures/misc/gl-teximage.html [ Failure ]
-
-# Mac / Passthrough command decoder / OpenGL
-crbug.com/989194 [ mac passthrough angle-opengl ] conformance/extensions/oes-texture-half-float.html [ Failure ]
-
 # Mac / Passthrough command decoder / OpenGL / NVIDIA
 crbug.com/982294 [ mac passthrough nvidia angle-opengl ] conformance/renderbuffers/framebuffer-object-attachment.html [ Failure ]
 crbug.com/982294 [ mac passthrough nvidia angle-opengl ] conformance/textures/misc/tex-input-validation.html [ Failure ]
-crbug.com/982294 [ mac passthrough nvidia angle-opengl ] conformance/textures/misc/texture-corner-case-videos.html [ Failure ]
 
 # Mac / Passthrough command decoder / Metal
 crbug.com/angleproject/4846 [ mac angle-metal passthrough ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ Failure ]
-crbug.com/angleproject/5505 [ mac angle-metal passthrough ] conformance/extensions/webgl-debug-shaders.html [ Failure ]
 crbug.com/angleproject/5505 [ mac angle-metal passthrough ] conformance/ogles/GL/acos/acos_001_to_006.html [ Failure ]
 crbug.com/angleproject/5505 [ mac angle-metal passthrough ] conformance/ogles/GL/asin/asin_001_to_006.html [ Failure ]
-crbug.com/1227129 [ mac angle-metal passthrough ] conformance/glsl/misc/ternary-operators-in-initializers.html [ Failure ]
-crbug.com/1227767 [ bigsur angle-metal passthrough ] conformance/ogles/GL/discard/discard_001_to_002.html [ Failure ]
 crbug.com/angleproject/6489 [ mac angle-metal passthrough ] conformance/ogles/GL/build/build_009_to_016.html [ Failure ]
 crbug.com/angleproject/6489 [ mac angle-metal passthrough ] conformance/ogles/GL/build/build_017_to_024.html [ Failure ]
 crbug.com/angleproject/6486 [ mac angle-metal passthrough ] conformance/glsl/misc/shader-with-non-reserved-words.html [ Failure ]
 
 # Mac / Passthrough command decoder / Metal / Intel
-crbug.com/1144258 [ mac angle-metal passthrough intel-0x3e9b ] conformance/glsl/functions/glsl-function-atan-xy.html [ Failure ]
-crbug.com/angleproject/4846 [ mac angle-metal passthrough intel ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
-crbug.com/1144258 [ mac angle-metal passthrough intel-0x3e9b ] conformance/ogles/GL/atan/atan_009_to_012.html [ Failure ]
 crbug.com/angleproject/4846 [ mac angle-metal passthrough intel ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
-crbug.com/angleproject/4846 [ mac angle-metal passthrough intel ] conformance/textures/misc/texture-size.html [ Failure ]
-crbug.com/angleproject/4846 [ mac angle-metal passthrough intel ] deqp/data/gles2/shaders/conversions.html [ Failure ]
-crbug.com/angleproject/4846 [ mac angle-metal passthrough intel ] deqp/data/gles2/shaders/swizzles.html [ Failure ]
 crbug.com/1291005 [ mac angle-metal no-swiftshader-gl intel ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html [ RetryOnFailure ]
 crbug.com/1291005 [ mac angle-metal no-swiftshader-gl intel ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ]
 
-# Mac / Passthrough command decoder / Metal / NVIDIA
-crbug.com/angleproject/4846 [ mac angle-metal passthrough nvidia ] conformance/rendering/clipping-wide-points.html [ Failure ]
-crbug.com/angleproject/4846 [ mac angle-metal passthrough nvidia ] conformance/rendering/more-than-65536-indices.html [ Failure ]
-
 # Mac / M1 / OpenGL
 crbug.com/1130703 [ mac apple-apple-m1 passthrough angle-opengl ] conformance/textures/misc/texture-copying-and-deletion.html [ Failure ]
 crbug.com/1130703 [ mac apple-apple-m1 no-passthrough ] conformance/textures/misc/texture-copying-and-deletion.html [ Failure ]
@@ -663,10 +538,7 @@
 crbug.com/1240443 [ mac apple-apple-m1 passthrough angle-opengl ] conformance/renderbuffers/stencil-renderbuffer-initialization.html [ RetryOnFailure ]
 
 # Mac / M1 / Metal
-crbug.com/1130758 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/extensions/webgl-depth-texture.html [ Failure ]
 crbug.com/1130759 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
-crbug.com/1130760 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/extensions/webgl-draw-buffers.html [ Failure ]
-crbug.com/1130760 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/ogles/GL/discard/discard_001_to_002.html [ Failure ]
 # Introduced by upstreaming Apple's direct-to-metal backend
 # TODO(crbug.com/1276153) uncomment after fix for updated part of test applies
 # crbug.com/angleproject/5505 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/context/context-attributes-alpha-depth-stencil-antialias.html [ Failure ]
@@ -681,24 +553,6 @@
 # Linux / Vulkan / Passthrough command decoder
 crbug.com/1021428 [ linux angle-vulkan passthrough intel ] WebglExtension_WEBGL_depth_texture [ Failure ]  # finder:disable Not tested in Chromium, but tested by Intel.
 
-# NVIDIA P400 OpenGL
-crbug.com/715001 [ linux nvidia-0x1cb3 ] conformance/limits/gl-max-texture-dimensions.html [ Failure ]
-crbug.com/913969 [ linux nvidia-0x1cb3 ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
-crbug.com/913969 [ linux nvidia-0x1cb3 ] conformance/extensions/oes-texture-half-float-with-video.html [ RetryOnFailure ]
-
-# AMD
-crbug.com/642822 [ linux amd ] conformance/rendering/clipping-wide-points.html [ Failure ]
-crbug.com/1018028 [ linux amd-0x6613 ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ]
-
-# Linux passthrough AMD
-crbug.com/1143392 [ linux amd passthrough ] conformance/glsl/misc/shader-with-non-reserved-words.html [ Failure ]
-crbug.com/998498 [ linux amd passthrough ] conformance/textures/misc/tex-input-validation.html [ Failure ]
-
-# Linux passthrough AMD OpenGL
-crbug.com/965594 [ linux amd angle-opengl passthrough ] conformance/more/conformance/quickCheckAPI-S_V.html [ RetryOnFailure ]
-crbug.com/angleproject/5213 [ linux amd-0x6613 angle-opengl passthrough ] conformance/context/deleted-object-behavior.html [ Failure ]
-crbug.com/angleproject/5213 [ linux amd-0x6613 angle-opengl passthrough ] conformance/renderbuffers/renderbuffer-initialization.html [ Failure ]
-
 # Linux AMD RX 5500 XT
 crbug.com/1147232 [ linux amd-0x7340 angle-opengl passthrough ] conformance/textures/misc/texture-size-limit.html [ Failure ]
 
@@ -710,10 +564,8 @@
 crbug.com/478572 [ android qualcomm ] conformance/glsl/bugs/sequence-operator-evaluation-order.html [ Failure ]
 
 # Was too difficult to suppress these failures on individual bots.
-crbug.com/1165751 [ android-lollipop ] conformance/glsl/bugs/vector-matrix-constructor-scalarization.html [ Failure ]
 crbug.com/1165751 [ android-marshmallow ] conformance/glsl/bugs/vector-matrix-constructor-scalarization.html [ Failure ]
 crbug.com/1165751 [ android-nougat ] conformance/glsl/bugs/vector-matrix-constructor-scalarization.html [ Failure ]
-crbug.com/1165751 [ android-r ] conformance/glsl/bugs/vector-matrix-constructor-scalarization.html [ Failure ]
 
 crbug.com/679697 [ android qualcomm no-passthrough ] conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html [ Failure ]
 
@@ -742,8 +594,6 @@
 crbug.com/678850 [ android android-nexus-5 ] conformance/more/functions/vertexAttribPointerBadArgs.html [ Failure ]
 crbug.com/678850 [ android android-nexus-5 ] conformance/attribs/gl-vertexattribpointer.html [ Failure ]
 
-crbug.com/891456 [ android android-nexus-5 ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
-
 # Started failing after the upgrade to Marshmallow.
 crbug.com/1264880 [ android-marshmallow android-nexus-5 ] conformance/extensions/webgl-multi-draw.html [ Failure ]
 crbug.com/1264882 [ android-marshmallow android-nexus-5 ] conformance/glsl/bugs/sketchfab-lighting-shader-crash.html [ Failure ]
@@ -752,10 +602,7 @@
 # Was timing out randomly on android_optional_gpu_tests_rel, but became so
 # flaky (2018-09-10) that it had to be upgraded to Fail.
 crbug.com/882323 [ android android-nexus-5x ] deqp/data/gles2/shaders/conversions.html [ Failure ]
-crbug.com/609883 [ android android-nexus-5x ] conformance/extensions/oes-texture-half-float-with-video.html [ Failure ]
-crbug.com/784817 [ android android-nexus-5x ] conformance/glsl/bugs/init-array-with-loop.html [ Failure ]
 crbug.com/609883 [ android android-nexus-5x ] conformance/glsl/bugs/sampler-struct-function-arg.html [ Failure ]
-crbug.com/609883 [ android android-nexus-5x no-passthrough ] conformance/glsl/misc/shader-with-non-reserved-words.html [ Failure ]
 crbug.com/1043431 [ android android-nexus-5x ] conformance/limits/gl-max-texture-dimensions.html [ RetryOnFailure ]
 crbug.com/951628 [ android android-nexus-5x no-passthrough no-swiftshader-gl ] conformance/rendering/blending.html [ Failure ]
 crbug.com/1083320 [ android android-nexus-5x ] conformance/misc/uninitialized-test.html [ Failure ]
@@ -763,33 +610,18 @@
 # Timing out on this device for unknown reasons.
 crbug.com/1099148 [ android android-nexus-5x ] deqp/data/gles2/shaders/swizzles.html [ Failure ]
 crbug.com/1122644 [ android android-nexus-5x ] conformance/textures/misc/texture-upload-size.html [ Failure ]
-crbug.com/1163306 [ android android-nexus-5x ] conformance/textures/image_bitmap_from_video/* [ RetryOnFailure ]
-crbug.com/1203167 [ android android-nexus-5x ] conformance/extensions/oes-texture-float-with-video.html [ RetryOnFailure ]
 crbug.com/1270815 [ android android-nexus-5x ] conformance/textures/misc/texture-size.html [ RetryOnFailure ]
 
 # Android NVIDIA: Nexus 9 and/or Shield TV
 crbug.com/798117 [ android android-nexus-9 ] conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html [ Failure ]
 crbug.com/606096 [ android android-nexus-9 ] conformance/glsl/bugs/multiplication-assignment.html [ Failure ]
-crbug.com/891456 [ android android-nexus-9 ] conformance/extensions/oes-texture-half-float-with-video.html [ Failure ]
-crbug.com/1025790 [ android android-nexus-9 ] conformance/textures/misc/tex-image-canvas-corruption.html [ Failure ]
 crbug.com/478572 [ android android-nexus-9 ] deqp/data/gles2/shaders/functions.html [ Failure ]
-crbug.com/891456 [ android android-shield-android-tv ] conformance/extensions/oes-texture-float-with-video.html [ Failure ]
-crbug.com/891456 [ android android-shield-android-tv ] conformance/extensions/oes-texture-half-float-with-video.html [ Failure ]
-crbug.com/891456 [ android android-shield-android-tv ] conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ]
-crbug.com/1025790 [ android android-shield-android-tv ] conformance/textures/misc/tex-image-canvas-corruption.html [ Failure ]
 # Texture tests found to generate intermittent GL errors in the GPU process
 crbug.com/1090407 [ android android-nexus-9 ] conformance/textures/* [ RetryOnFailure ]
-crbug.com/1090407 [ android android-shield-android-tv ] conformance/textures/* [ RetryOnFailure ]
-
-# Failing webgl video tests on nexus 5.
-crbug.com/1178518 [ android android-nexus-5 android-chromium ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html [ Failure ]
-crbug.com/1178518 [ android android-nexus-5 android-chromium ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Failure ]
-crbug.com/1178518 [ android android-nexus-5 android-chromium ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Failure ]
 
 # Pixel 4
 crbug.com/1175223 [ android android-pixel-4 angle-opengles passthrough ] conformance/extensions/angle-instanced-arrays-out-of-bounds.html [ Failure ]
 crbug.com/1175226 [ android android-pixel-4 no-passthrough no-swiftshader-gl ] conformance/rendering/blending.html [ Failure ]
-crbug.com/1179432 [ android android-pixel-4 no-passthrough ] conformance/rendering/polygon-offset.html [ RetryOnFailure ]
 crbug.com/1191030 [ android android-pixel-4 ] conformance/textures/misc/video-rotation.html [ Failure ]
 crbug.com/1187332 [ android android-pixel-4 ] conformance/textures/misc/texture-corner-case-videos.html [ RetryOnFailure ]
 crbug.com/1278904 [ android android-pixel-4 android-chromium ] conformance/textures/misc/texture-npot-video.html [ RetryOnFailure ]
@@ -836,7 +668,6 @@
 crbug.com/1209254 [ android android-nexus-5x android-chromium passthrough ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
 crbug.com/1209254 [ android android-nexus-5x android-chromium passthrough ] conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html [ RetryOnFailure ]
 crbug.com/1209254 [ android android-nexus-5x android-chromium passthrough ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html [ RetryOnFailure ]
-crbug.com/1209254 [ android android-nexus-5x android-chromium passthrough ] conformance/textures/misc/texture-corner-case-videos.html [ RetryOnFailure ]
 
 # Failing test in passthrough mode when experiment DrDc is enabled via fieldtrial_testing_config.json.
 crbug.com/1276552 [ android passthrough ] conformance/canvas/render-after-resize-test.html [ Failure ]
@@ -852,18 +683,14 @@
 # TODO(crbug.com/1276153) uncomment after fix for updated part of test applies
 # crbug.com/957807 [ chromeos ] conformance/context/context-attributes-alpha-depth-stencil-antialias.html [ Failure ]
 crbug.com/957807 [ chromeos ] conformance/rendering/clipping-wide-points.html [ Failure ]
-crbug.com/957807 [ chromeos ] conformance/rendering/line-rendering-quality.html [ Failure ]
 crbug.com/957807 [ chromeos ] conformance/uniforms/uniform-samplers-test.html [ Failure ]
 crbug.com/957807 [ chromeos ] deqp/data/gles2/shaders/conversions.html [ Failure ]
 crbug.com/957807 [ chromeos ] deqp/data/gles2/shaders/swizzles.html [ Failure ]
-# There is a crash, likely in this test, causing the root partition to become
-# read-only.
-crbug.com/1043953 [ chromeos chromeos-board-kevin ] conformance/textures/misc/texture-size-limit.html [ RetryOnFailure ]
 
-crbug.com/1237319 [ chromeos chromeos-board-eve passthrough ] conformance/textures/misc/texture-size-limit.html [ Failure ]
-crbug.com/1237319 [ chromeos angle-opengles passthrough ] conformance/extensions/angle-instanced-arrays-out-of-bounds.html [ Failure ]
-
-crbug.com/1197243 [ chromeos chromeos-board-amd64-generic ] conformance/extensions/oes-texture-half-float.html [ Failure ]
+# finder:disable Reported by Intel but not currently testable in Chromium
+crbug.com/1237319 [ chromeos chromeos-board-eve passthrough intel ] conformance/textures/misc/texture-size-limit.html [ Failure ]
+crbug.com/1237319 [ chromeos angle-opengles passthrough intel ] conformance/extensions/angle-instanced-arrays-out-of-bounds.html [ Failure ]
+# finder:enable
 
 # Arm-based issues.
 crbug.com/1080400 [ chromeos chromeos-board-kevin ] WebglExtension_EXT_color_buffer_half_float [ Failure ]
@@ -878,11 +705,7 @@
 crbug.com/1080380 [ chromeos chromeos-board-kevin ] conformance/offscreencanvas/context-lost-restored.html [ Failure ]
 crbug.com/1108368 [ chromeos chromeos-board-kevin ] conformance/misc/shader-precision-format.html [ Failure ]
 
-# Flaky driver crash on AMD.
-crbug.com/1186499 [ chromeos chromeos-board-amd64-generic ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
-
 # Flaky test on chromeos-amd64-generic-rel.
-crbug.com/1202015 [ chromeos chromeos-board-amd64-generic ] conformance/glsl/constructors/glsl-construct-vec3.html [ RetryOnFailure ]
 crbug.com/1227774 [ chromeos chromeos-board-amd64-generic ] conformance/glsl/misc/shader-with-non-reserved-words.html [ RetryOnFailure ]
 
 # Failing on chromeos-amd64-generic-rel.
@@ -909,27 +732,6 @@
 crbug.com/1099959 [ swiftshader-gl no-passthrough ] WebglExtension_EXT_sRGB [ Failure ]
 crbug.com/1099959 [ swiftshader-gl no-passthrough ] WebglExtension_EXT_texture_compression_rgtc [ Failure ]
 
-# All platforms, Vulkan backend
-crbug.com/1114284 [ linux angle-swiftshader passthrough google-0xffff ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ RetryOnFailure ]
-crbug.com/1114284 [ mac angle-swiftshader passthrough google-0xffff ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ RetryOnFailure ]
-
-# Mac. GL backend.
-crbug.com/1099977 [ mac swiftshader-gl no-passthrough ] conformance/context/context-attribute-preserve-drawing-buffer.html [ Failure ]
-crbug.com/1099977 [ mac swiftshader-gl no-passthrough ] conformance/glsl/bugs/sampler-array-struct-function-arg.html [ Failure ]
-crbug.com/1099960 [ mac swiftshader-gl no-passthrough ] conformance/context/context-no-alpha-fbo-with-alpha.html [ Failure ]
-crbug.com/1099960 [ mac swiftshader-gl no-passthrough ] conformance/rendering/color-mask-preserved-during-implicit-clears.html [ Failure ]
-crbug.com/1099960 [ mac swiftshader-gl no-passthrough ] conformance/rendering/scissor-rect-repeated-rendering.html [ Failure ]
-
-crbug.com/1237561 [ mac swiftshader-gl no-passthrough ] conformance/extensions/oes-texture-half-float-with-video.html [ Failure ]
-crbug.com/1237561 [ mac swiftshader-gl no-passthrough ] conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html [ Failure ]
-crbug.com/1237561 [ mac swiftshader-gl no-passthrough ] conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
-crbug.com/1237561 [ mac swiftshader-gl no-passthrough ] conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
-crbug.com/1237561 [ mac swiftshader-gl no-passthrough ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html [ Failure ]
-crbug.com/1237561 [ mac swiftshader-gl no-passthrough ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ Failure ]
-crbug.com/1237561 [ mac swiftshader-gl no-passthrough ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html [ Failure ]
-crbug.com/1237561 [ mac swiftshader-gl no-passthrough ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Failure ]
-crbug.com/1237561 [ mac swiftshader-gl no-passthrough ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Failure ]
-
 #######################################################################
 # Automated Entries After This Point - Do Not Manually Add Below Here #
 #######################################################################
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
index 86927b15..536a6a6 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
@@ -60,7 +60,7 @@
 
 if sys.version_info[0] == 3:
   # cmp no longer exists in Python 3
-  def cmp(a, b):  # pylint: disable=redefined-builtin
+  def cmp(a, b):
     return int(a > b) - int(a < b)
 
 
diff --git a/content/test/gpu/pylintrc b/content/test/gpu/pylintrc
index 8aedc7e..94b3bb5 100644
--- a/content/test/gpu/pylintrc
+++ b/content/test/gpu/pylintrc
@@ -24,7 +24,6 @@
         missing-docstring,
         too-few-public-methods,
         too-many-instance-attributes,
-        unsupported-assignment-operation
 
 # Pylint, or at least v1.5.6, does not properly handle adding comments between
 # lines of disable= entries, nor does it allow multiple disable= lines, so
@@ -78,11 +77,214 @@
 
 [REPORTS]
 
-# Don't write out full reports, just messages.
+# Set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html
+output-format=text
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# Tells whether to display a full report or only the messages
+# CHANGED:
 reports=no
 
+# Activate the evaluation score.
+score=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+
+[VARIABLES]
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# A regular expression matching the beginning of the name of dummy variables
+# (i.e. not used).
+dummy-variables-rgx=_|dummy
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+
+[TYPECHECK]
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of classes names for which member attributes should not be checked
+# (useful for classes with attributes dynamically set).
+ignored-classes=SQLObject,
+                twisted.internet.reactor,
+                hashlib,
+                google.appengine.api.memcache
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E0201 when accessed. Python regular
+# expressions are accepted.
+generated-members=REQUEST,
+                  acl_users,
+                  aq_parent,
+                  multiprocessing.managers.SyncManager
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,
+      XXX,
+      TODO
+
+
+[SIMILARITIES]
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
 
 [FORMAT]
 
-# We use two spaces for indents, instead of the usual four spaces or tab.
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+# CHANGED: We use two spaces for indents instead of the usual four or tab.
 indent-string='  '
+
+
+[BASIC]
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=map,
+              filter,
+              apply,
+              input
+
+# Regular expression which should only match correct module names
+module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+
+# Regular expression which should only match correct module level names
+const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
+
+# Regular expression which should only match correct class names
+class-rgx=[A-Z_][a-zA-Z0-9]+$
+
+# Regular expression which should only match correct function names
+function-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct method names
+method-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct instance attribute names
+attr-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct argument names
+argument-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct variable names
+variable-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# Regular expression which should only match functions or classes name which do
+# not require a docstring
+no-docstring-rgx=__.*__
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method
+max-args=5
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of branch for function / method body
+max-branchs=12
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+
+[IMPORTS]
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,
+                   string,
+                   TERMIOS,
+                   Bastion,
+                   rexec
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=Exception
diff --git a/content/test/gpu/unexpected_passes/gpu_queries.py b/content/test/gpu/unexpected_passes/gpu_queries.py
index f81db6f7..c7a4749 100644
--- a/content/test/gpu/unexpected_passes/gpu_queries.py
+++ b/content/test/gpu/unexpected_passes/gpu_queries.py
@@ -65,6 +65,16 @@
     builder_type=constants.BuilderTypes.CI),
            final_selector_query=FINAL_SELECTOR_QUERY)
 
+SUBMITTED_BUILDS_SUBQUERY = """\
+  submitted_builds AS (
+{chromium_builds}
+    UNION ALL
+{angle_builds}
+  ),""".format(chromium_builds=queries_module.SUBMITTED_BUILDS_TEMPLATE.format(
+    project_view='chromium'),
+               angle_builds=queries_module.SUBMITTED_BUILDS_TEMPLATE.format(
+                   project_view='angle'))
+
 # Same as GPU_CI_BQ_QUERY_TEMPLATE, but for tryjobs. Only data from builds that
 # were used for CL submission is considered.
 GPU_TRY_BQ_QUERY_TEMPLATE = """\
@@ -86,7 +96,7 @@
   ),
 {results_subquery}
 {final_selector_query}
-""".format(submitted_builds_subquery=queries_module.SUBMITTED_BUILDS_SUBQUERY,
+""".format(submitted_builds_subquery=SUBMITTED_BUILDS_SUBQUERY,
            results_subquery=RESULTS_SUBQUERY.format(
                builder_type=constants.BuilderTypes.TRY),
            final_selector_query=FINAL_SELECTOR_QUERY)
diff --git a/content/test/gpu/unexpected_passes/gpu_queries_unittest.py b/content/test/gpu/unexpected_passes/gpu_queries_unittest.py
index 4f7ae04..87e6488 100755
--- a/content/test/gpu/unexpected_passes/gpu_queries_unittest.py
+++ b/content/test/gpu/unexpected_passes/gpu_queries_unittest.py
@@ -402,6 +402,18 @@
       AND unnested_changes.submit_status = "SUCCESS"
       AND start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(),
                                      INTERVAL 30 DAY)
+    UNION ALL
+    SELECT
+      CONCAT("build-", CAST(unnested_builds.id AS STRING)) as id
+    FROM
+      `commit-queue.angle.attempts`,
+      UNNEST(builds) as unnested_builds,
+      UNNEST(gerrit_changes) as unnested_changes
+    WHERE
+      unnested_builds.host = "cr-buildbucket.appspot.com"
+      AND unnested_changes.submit_status = "SUCCESS"
+      AND start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(),
+                                     INTERVAL 30 DAY)
   ),
   builds AS (
     SELECT
@@ -469,6 +481,18 @@
       AND unnested_changes.submit_status = "SUCCESS"
       AND start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(),
                                      INTERVAL 30 DAY)
+    UNION ALL
+    SELECT
+      CONCAT("build-", CAST(unnested_builds.id AS STRING)) as id
+    FROM
+      `commit-queue.angle.attempts`,
+      UNNEST(builds) as unnested_builds,
+      UNNEST(gerrit_changes) as unnested_changes
+    WHERE
+      unnested_builds.host = "cr-buildbucket.appspot.com"
+      AND unnested_changes.submit_status = "SUCCESS"
+      AND start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(),
+                                     INTERVAL 30 DAY)
   ),
   builds AS (
     SELECT
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc
index 8354bea4..20ce04c 100644
--- a/content/test/test_blink_web_unit_test_support.cc
+++ b/content/test/test_blink_web_unit_test_support.cc
@@ -18,6 +18,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
 #include "base/test/null_task_runner.h"
+#include "base/test/task_environment.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
@@ -141,8 +142,8 @@
     main_thread_scheduler_ =
         blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler(
             base::MessagePump::Create(base::MessagePumpType::DEFAULT));
-    base::ThreadPoolInstance::CreateAndStartWithDefaultParams(
-        "BlinkTestSupport");
+    base::test::TaskEnvironment::CreateThreadPool();
+    base::ThreadPoolInstance::Get()->StartWithDefaultParams();
   }
 
   // Initialize mojo firstly to enable Blink initialization to use it.
diff --git a/courgette/courgette_tool.cc b/courgette/courgette_tool.cc
index e310c2e..00f13f26 100644
--- a/courgette/courgette_tool.cc
+++ b/courgette/courgette_tool.cc
@@ -9,6 +9,7 @@
 #include <initializer_list>
 #include <memory>
 #include <string>
+#include <tuple>
 #include <vector>
 
 #include "base/at_exit.h"
@@ -408,7 +409,7 @@
     settings.logging_dest = logging::LOG_TO_ALL;
     settings.log_file_path = FILE_PATH_LITERAL("courgette.log");
   }
-  (void)logging::InitLogging(settings);
+  std::ignore = logging::InitLogging(settings);
   logging::SetMinLogLevel(logging::LOG_VERBOSE);
 
   bool cmd_sup = command_line.HasSwitch("supported");
diff --git a/crypto/unexportable_key_win.cc b/crypto/unexportable_key_win.cc
index 6ca4dcb..c13f43d 100644
--- a/crypto/unexportable_key_win.cc
+++ b/crypto/unexportable_key_win.cc
@@ -7,6 +7,7 @@
 #include <ncrypt.h>
 
 #include <string>
+#include <tuple>
 #include <vector>
 
 #include "base/logging.h"
@@ -350,7 +351,7 @@
             MS_PLATFORM_CRYPTO_PROVIDER, /*flags=*/0))) {
       // If the operation failed then |provider| doesn't have a valid handle in
       // it and we shouldn't try to free it.
-      (void)provider.release();
+      std::ignore = provider.release();
       return absl::nullopt;
     }
 
@@ -369,7 +370,7 @@
             MS_PLATFORM_CRYPTO_PROVIDER, /*flags=*/0))) {
       // If the operation failed when |provider| doesn't have a valid handle in
       // it and we shouldn't try to free it.
-      (void)provider.release();
+      std::ignore = provider.release();
       return nullptr;
     }
 
@@ -387,7 +388,7 @@
             /*dwLegacyKeySpec=*/0, /*dwFlags=*/0))) {
       // If the operation failed then |key| doesn't have a valid handle in it
       // and we shouldn't try and free it.
-      (void)key.release();
+      std::ignore = key.release();
       return nullptr;
     }
 
@@ -435,7 +436,7 @@
             MS_PLATFORM_CRYPTO_PROVIDER, /*flags=*/0))) {
       // If the operation failed when |provider| doesn't have a valid handle in
       // it and we shouldn't try to free it.
-      (void)provider.release();
+      std::ignore = provider.release();
       return nullptr;
     }
 
@@ -447,7 +448,7 @@
             /*dwFlags=*/NCRYPT_SILENT_FLAG))) {
       // If the operation failed then |key| doesn't have a valid handle in it
       // and we shouldn't try and free it.
-      (void)key.release();
+      std::ignore = key.release();
       return nullptr;
     }
 
diff --git a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
index c181770f..9d6cf9b3 100644
--- a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
+++ b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
@@ -1398,6 +1398,8 @@
   if (is_now_connected) {
     device::BluetoothConnectionLogger::RecordDeviceConnected(
         device->GetIdentifier(), device->GetDeviceType());
+  } else {
+    device::RecordDeviceDisconnect(device->GetDeviceType());
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
 
diff --git a/device/bluetooth/bluez/bluetooth_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
index 3f3e8d4..8f4c2b26 100644
--- a/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
+++ b/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
@@ -2850,11 +2850,14 @@
   EXPECT_FALSE(device->IsConnected());
 
 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
-  histogram_tester_.ExpectBucketCount("Bluetooth.ChromeOS.Disconnect.Result",
-                                      device::DisconnectResult::kSuccess, 1);
   histogram_tester_.ExpectBucketCount(
-      "Bluetooth.ChromeOS.Disconnect.Result.Classic",
+      "Bluetooth.ChromeOS.UserInitiatedDisconnect.Result",
       device::DisconnectResult::kSuccess, 1);
+  histogram_tester_.ExpectBucketCount(
+      "Bluetooth.ChromeOS.UserInitiatedDisconnect.Result.Classic",
+      device::DisconnectResult::kSuccess, 1);
+  histogram_tester_.ExpectBucketCount("Bluetooth.ChromeOS.DeviceDisconnect",
+                                      device->GetDeviceType(), 1);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
 }
 
diff --git a/device/bluetooth/bluez/bluetooth_device_bluez.cc b/device/bluetooth/bluez/bluetooth_device_bluez.cc
index 062007cd..ae070070 100644
--- a/device/bluetooth/bluez/bluetooth_device_bluez.cc
+++ b/device/bluetooth/bluez/bluetooth_device_bluez.cc
@@ -1189,8 +1189,9 @@
 
 void BluetoothDeviceBlueZ::OnDisconnect(base::OnceClosure callback) {
 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
-  device::RecordDisconnectResult(device::DisconnectResult::kSuccess,
-                                 /*transport=*/GetType());
+  device::RecordUserInitiatedDisconnectResult(
+      device::DisconnectResult::kSuccess,
+      /*transport=*/GetType());
 #endif
   BLUETOOTH_LOG(EVENT) << object_path_.value() << ": Disconnected";
   std::move(callback).Run();
@@ -1200,8 +1201,9 @@
                                              const std::string& error_name,
                                              const std::string& error_message) {
 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
-  device::RecordDisconnectResult(device::DisconnectResult::kFailure,
-                                 /*transport=*/GetType());
+  device::RecordUserInitiatedDisconnectResult(
+      device::DisconnectResult::kFailure,
+      /*transport=*/GetType());
 #endif
   BLUETOOTH_LOG(ERROR) << object_path_.value()
                        << ": Failed to disconnect device: " << error_name
diff --git a/device/bluetooth/chromeos/bluetooth_utils.cc b/device/bluetooth/chromeos/bluetooth_utils.cc
index cd400cf4..321a170 100644
--- a/device/bluetooth/chromeos/bluetooth_utils.cc
+++ b/device/bluetooth/chromeos/bluetooth_utils.cc
@@ -348,18 +348,24 @@
                                 forget_result);
 }
 
-void RecordDisconnectResult(DisconnectResult disconnect_result,
-                            BluetoothTransport transport) {
+void RecordDeviceDisconnect(BluetoothDeviceType device_type) {
+  base::UmaHistogramEnumeration("Bluetooth.ChromeOS.DeviceDisconnect",
+                                device_type);
+}
+
+void RecordUserInitiatedDisconnectResult(DisconnectResult disconnect_result,
+                                         BluetoothTransport transport) {
   std::string transport_name = GetTransportName(transport);
 
   if (transport_name.empty()) {
     return;
   }
 
-  base::UmaHistogramEnumeration("Bluetooth.ChromeOS.Disconnect.Result",
-                                disconnect_result);
   base::UmaHistogramEnumeration(
-      base::StrCat({"Bluetooth.ChromeOS.Disconnect.Result.", transport_name}),
+      "Bluetooth.ChromeOS.UserInitiatedDisconnect.Result", disconnect_result);
+  base::UmaHistogramEnumeration(
+      base::StrCat({"Bluetooth.ChromeOS.UserInitiatedDisconnect.Result.",
+                    transport_name}),
       disconnect_result);
 }
 
diff --git a/device/bluetooth/chromeos/bluetooth_utils.h b/device/bluetooth/chromeos/bluetooth_utils.h
index d1ec8ae..6529a73 100644
--- a/device/bluetooth/chromeos/bluetooth_utils.h
+++ b/device/bluetooth/chromeos/bluetooth_utils.h
@@ -151,8 +151,12 @@
 // Record each time a device forget attempt completes.
 DEVICE_BLUETOOTH_EXPORT void RecordForgetResult(ForgetResult forget_result);
 
-// Record the result of each bluetooth device disconnect attempt.
-DEVICE_BLUETOOTH_EXPORT void RecordDisconnectResult(
+// Records each bluetooth device disconnect.
+DEVICE_BLUETOOTH_EXPORT void RecordDeviceDisconnect(
+    BluetoothDeviceType device_type);
+
+// Record the result of each user initiated bluetooth device disconnect attempt.
+DEVICE_BLUETOOTH_EXPORT void RecordUserInitiatedDisconnectResult(
     DisconnectResult disconnect_result,
     BluetoothTransport transport);
 
diff --git a/device/bluetooth/chromeos/bluetooth_utils_unittest.cc b/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
index 02f2ea8..62402bcf 100644
--- a/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
+++ b/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
@@ -272,4 +272,10 @@
       2000, 1);
 }
 
+TEST_F(BluetoothUtilsTest, TestDisconnectMetric) {
+  RecordDeviceDisconnect(BluetoothDeviceType::MOUSE);
+  histogram_tester.ExpectBucketCount("Bluetooth.ChromeOS.DeviceDisconnect",
+                                     BluetoothDeviceType::MOUSE, 1);
+}
+
 }  // namespace device
diff --git a/device/fido/features.cc b/device/fido/features.cc
index b12b4796..68adc413 100644
--- a/device/fido/features.cc
+++ b/device/fido/features.cc
@@ -19,20 +19,11 @@
                                             base::FEATURE_ENABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(IS_WIN)
 
-extern const base::Feature kWebAuthCableSecondFactor {
-  "WebAuthenticationCableSecondFactor",
-// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
-// of lacros-chrome is complete.
-// If updating this, also update kWebAuthCableServerLink.
-#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
-      base::FEATURE_DISABLED_BY_DEFAULT
-#else
-      base::FEATURE_ENABLED_BY_DEFAULT
-#endif
-};
+extern const base::Feature kWebAuthCableSecondFactor{
+    "WebAuthenticationCableSecondFactor", base::FEATURE_ENABLED_BY_DEFAULT};
 
 extern const base::Feature kWebAuthPhoneSupport{
-    "WebAuthenticationPhoneSupport", base::FEATURE_DISABLED_BY_DEFAULT};
+    "WebAuthenticationPhoneSupport", base::FEATURE_ENABLED_BY_DEFAULT};
 
 extern const base::Feature kWebAuthCableDisco{
     "WebAuthenticationCableDisco", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/device/gamepad/gamepad_id_list.cc b/device/gamepad/gamepad_id_list.cc
index 758a353..0388471 100644
--- a/device/gamepad/gamepad_id_list.cc
+++ b/device/gamepad/gamepad_id_list.cc
@@ -589,7 +589,7 @@
     {0x28de, 0x1106, kXInputTypeNone},
     {0x28de, 0x1142, kXInputTypeNone},
     {0x28de, 0x11fc, kXInputTypeNone},
-    {0x28de, 0x11ff, kXInputTypeNone},
+    {0x28de, 0x11ff, kXInputTypeXbox360},
     {0x28de, 0x1201, kXInputTypeNone},
     {0x28de, 0x1202, kXInputTypeNone},
     {0x2c22, 0x2000, kXInputTypeNone},
diff --git a/device/gamepad/public/cpp/gamepad_features.cc b/device/gamepad/public/cpp/gamepad_features.cc
index d942501..9010e7a3 100644
--- a/device/gamepad/public/cpp/gamepad_features.cc
+++ b/device/gamepad/public/cpp/gamepad_features.cc
@@ -24,6 +24,9 @@
 const base::Feature kEnableWindowsGamingInputDataFetcher{
     "EnableWindowsGamingInputDataFetcher", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// TODO(https://crbug.com/1011006): When we enable this feature and enable the
+// permission policy of the Gamepad API, remove the fenced frame specific code
+// introduced by crrev.com/c/3403761.
 const base::Feature kRestrictGamepadAccess{"RestrictGamepadAccess",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/docs/security/mojo.md b/docs/security/mojo.md
index 969689afd..ba45ae2 100644
--- a/docs/security/mojo.md
+++ b/docs/security/mojo.md
@@ -848,6 +848,15 @@
 interface is used relatively frequently, connecting once and reusing the
 interface pointer is probably a good idea.
 
+## Copy data out of BigBuffer before parsing
+
+[BigBuffer](mojo/public/mojom/base/big_buffer.mojom) uses shared memory to make
+passing large messages fast. When shmem is backing the message, it may be
+writable in the sending process while being read in the receiving process. If a
+BigBuffer is received from an untrustworthy process, you should make a copy of
+the data before processing it to avoid time-of-check time-of-use (TOCTOU) bugs.
+The |size()| of the data cannot be manipulated.
+
 
 ## Ensure An Explicit Grant For WebUI Bindings
 
diff --git a/extensions/browser/api/app_window/app_window_apitest.cc b/extensions/browser/api/app_window/app_window_apitest.cc
index 24ccc6a..8783307 100644
--- a/extensions/browser/api/app_window/app_window_apitest.cc
+++ b/extensions/browser/api/app_window/app_window_apitest.cc
@@ -215,9 +215,9 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(AppWindowApiTest, ImeWindowHasPermissions) {
-  EXPECT_TRUE(RunExtensionTest(
-      "platform_apps/windows_api_ime/has_permissions_whitelisted", {},
-      {.load_as_component = true}))
+  EXPECT_TRUE(
+      RunExtensionTest("platform_apps/windows_api_ime/has_permissions_allowed",
+                       {}, {.load_as_component = true}))
       << message_;
 
   EXPECT_TRUE(RunExtensionTest(
@@ -227,9 +227,9 @@
 }
 
 IN_PROC_BROWSER_TEST_F(AppWindowApiTest, ImeWindowNoPermissions) {
-  EXPECT_TRUE(RunExtensionTest(
-      "platform_apps/windows_api_ime/no_permissions_whitelisted", {},
-      {.load_as_component = true}))
+  EXPECT_TRUE(
+      RunExtensionTest("platform_apps/windows_api_ime/no_permissions_allowed",
+                       {}, {.load_as_component = true}))
       << message_;
 
   EXPECT_TRUE(RunExtensionTest(
diff --git a/extensions/browser/api/bluetooth/bluetooth_apitest.cc b/extensions/browser/api/bluetooth/bluetooth_apitest.cc
index f2c99ed0..b5ba0f9 100644
--- a/extensions/browser/api/bluetooth/bluetooth_apitest.cc
+++ b/extensions/browser/api/bluetooth/bluetooth_apitest.cc
@@ -5,6 +5,7 @@
 #include <string.h>
 
 #include <memory>
+#include <tuple>
 
 #include "base/memory/raw_ptr.h"
 #include "base/strings/utf_string_conversions.h"
@@ -213,8 +214,8 @@
   FailNextCall();
   scoped_refptr<api::BluetoothStopDiscoveryFunction> stop_function;
   stop_function = setupFunction(new api::BluetoothStopDiscoveryFunction);
-  (void)utils::RunFunctionAndReturnSingleResult(stop_function.get(), "[]",
-                                                browser());
+  std::ignore = utils::RunFunctionAndReturnSingleResult(stop_function.get(),
+                                                        "[]", browser());
   SetUpMockAdapter();
 }
 
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json
index 002bcb5a..87381229 100644
--- a/extensions/common/api/_api_features.json
+++ b/extensions/common/api/_api_features.json
@@ -254,9 +254,6 @@
     "contexts": ["blessed_extension", "unblessed_extension", "content_script",
                  "lock_screen_extension"]
   },
-  "i18n.getMessage": {
-    "disallow_for_service_workers": true
-  },
   "idle": {
     "dependencies": ["permission:idle"],
     "contexts": ["blessed_extension"]
@@ -341,7 +338,8 @@
       "chrome://sync-confirmation/*",
       "chrome://tab-search.top-chrome/*",
       "chrome://tab-strip.top-chrome/*",
-      "chrome://welcome/*"
+      "chrome://welcome/*",
+      "chrome://app-settings/*"
     ]
   }, {
     "channel": "stable",
diff --git a/extensions/common/constants.cc b/extensions/common/constants.cc
index f6e8647f..fb87a6a 100644
--- a/extensions/common/constants.cc
+++ b/extensions/common/constants.cc
@@ -138,9 +138,6 @@
 const char kQuickOfficeExtensionId[] = "gbkeegbaiigmenfmjfclcdgdpimamgkj";
 const char kMimeHandlerPrivateTestExtensionId[] =
     "oickdpebdnfbgkcaoklfcdhjniefkcji";
-const char kChromeAppId[] = "mgndgikekgjfcpckkfioiadnlibdjbkf";
-// Generated by: echo "lacros-chrome" | sha256sum | head -c32 | tr 0-9a-f a-p
-const char kLacrosAppId[] = "jaimifaeiicidiikhmjedcgdimealfbh";
 const char kFilesManagerAppId[] = "hhaomjibdihmijegdhdafkllkbggdgoj";
 const char kCalculatorAppId[] = "joodangkbfjnajiiifokapkpmhfnpleo";
 const char kCalendarDemoAppId[] = "fpgfohogebplgnamlafljlcidjedbdeb";
@@ -222,4 +219,10 @@
 
 const char kCryptotokenDeprecationTrialName[] = "U2FSecurityKeyAPI";
 
+// The following two IDs are duplicated in
+// //components/app_constants/constants.h. Don't change these without changing
+// the others.
+const char kChromeAppId[] = "mgndgikekgjfcpckkfioiadnlibdjbkf";
+const char kLacrosAppId[] = "jaimifaeiicidiikhmjedcgdimealfbh";
+
 }  // namespace extension_misc
diff --git a/extensions/common/constants.h b/extensions/common/constants.h
index dd15849..7a6345b 100644
--- a/extensions/common/constants.h
+++ b/extensions/common/constants.h
@@ -255,12 +255,6 @@
 // The extension id used for testing mimeHandlerPrivate.
 EXTENSIONS_EXPORT extern const char kMimeHandlerPrivateTestExtensionId[];
 
-// The extension id of the Chrome component application.
-EXTENSIONS_EXPORT extern const char kChromeAppId[];
-
-// Fake extension ID for the Lacros chrome browser application.
-EXTENSIONS_EXPORT extern const char kLacrosAppId[];
-
 // The extension id of the Files Manager application.
 EXTENSIONS_EXPORT extern const char kFilesManagerAppId[];
 
@@ -386,6 +380,12 @@
 // TODO(1224886): Delete together with CryptoToken code.
 EXTENSIONS_EXPORT extern const char kCryptotokenDeprecationTrialName[];
 
+// DEPRECATED.
+// The following two identifiers are being moved to
+// //components/app_constants/constants.[h|cc]. Please use those instead.
+EXTENSIONS_EXPORT extern const char kChromeAppId[];
+EXTENSIONS_EXPORT extern const char kLacrosAppId[];
+
 }  // namespace extension_misc
 
 #endif  // EXTENSIONS_COMMON_CONSTANTS_H_
diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc
index f10a7a9..4a7f1f1 100644
--- a/extensions/renderer/extension_frame_helper.cc
+++ b/extensions/renderer/extension_frame_helper.cc
@@ -338,6 +338,8 @@
   if (!delayed_main_world_script_initialization_)
     return;
 
+  base::AutoReset<bool> auto_reset(&is_initializing_main_world_script_context_,
+                                   true);
   delayed_main_world_script_initialization_ = false;
   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
   v8::Local<v8::Context> context =
@@ -371,6 +373,11 @@
     v8::Local<v8::Context> context,
     int32_t world_id) {
   if (world_id == blink::kMainDOMWorldId) {
+    // Accessing MainWorldScriptContext() in ReadyToCommitNavigation() may
+    // trigger the script context initializing, so we don't want to initialize a
+    // second time here.
+    if (is_initializing_main_world_script_context_)
+      return;
     if (render_frame()->IsBrowserSideNavigationPending()) {
       // Defer initializing the extensions script context now because it depends
       // on having the URL of the provisional load which isn't available at this
diff --git a/extensions/renderer/extension_frame_helper.h b/extensions/renderer/extension_frame_helper.h
index ffc4d99..7c3322b3 100644
--- a/extensions/renderer/extension_frame_helper.h
+++ b/extensions/renderer/extension_frame_helper.h
@@ -219,6 +219,8 @@
   bool has_started_first_navigation_ = false;
 
   bool did_create_script_context_ = false;
+  // Whether we are currently initializing the main world script context.
+  bool is_initializing_main_world_script_context_ = false;
 
   mojo::AssociatedRemote<mojom::LocalFrameHost> local_frame_host_remote_;
 
diff --git a/extensions/renderer/i18n_hooks_delegate.cc b/extensions/renderer/i18n_hooks_delegate.cc
index 64c139b..840dc27 100644
--- a/extensions/renderer/i18n_hooks_delegate.cc
+++ b/extensions/renderer/i18n_hooks_delegate.cc
@@ -20,6 +20,7 @@
 #include "extensions/renderer/get_script_context.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/shared_l10n_map.h"
+#include "extensions/renderer/worker_thread_dispatcher.h"
 #include "gin/converter.h"
 #include "gin/data_object_builder.h"
 #include "third_party/cld_3/src/src/nnet_language_identifier.h"
@@ -149,12 +150,12 @@
                                     const std::string& extension_id,
                                     v8::Local<v8::Value> v8_substitutions,
                                     v8::Local<v8::Value> v8_options,
-                                    content::RenderFrame* render_frame,
+                                    IPC::Sender* message_sender,
                                     v8::Local<v8::Context> context) {
   v8::Isolate* isolate = context->GetIsolate();
 
   std::string message = SharedL10nMap::GetInstance().GetMessage(
-      extension_id, message_name, render_frame);
+      extension_id, message_name, message_sender);
 
   std::vector<std::string> substitutions;
   // For now, we just suppress all errors, but that's really not the best.
@@ -284,10 +285,18 @@
   DCHECK_EQ(binding::AsyncResponseType::kNone, parse_result.async_type);
   DCHECK(script_context->extension());
   DCHECK(arguments[0]->IsString());
+
+  IPC::Sender* message_sender = nullptr;
+  if (script_context->IsForServiceWorker()) {
+    message_sender = WorkerThreadDispatcher::Get();
+  } else {
+    message_sender = script_context->GetRenderFrame();
+  }
+
   v8::Local<v8::Value> message = GetI18nMessage(
       gin::V8ToString(script_context->isolate(), arguments[0]),
       script_context->extension()->id(), arguments[1], arguments[2],
-      script_context->GetRenderFrame(), script_context->v8_context());
+      message_sender, script_context->v8_context());
 
   RequestResult result(RequestResult::HANDLED);
   result.return_value = message;
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_raw_draw.cc b/gpu/command_buffer/service/shared_image_backing_factory_raw_draw.cc
index c42ad7f..b675ad57 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_raw_draw.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_raw_draw.cc
@@ -377,7 +377,7 @@
     SkAlphaType alpha_type,
     uint32_t usage,
     bool is_thread_safe) {
-  DCHECK(!is_thread_safe);
+  DCHECK(is_thread_safe);
   auto texture = std::make_unique<RawDrawBacking>(
       mailbox, format, size, color_space, surface_origin, alpha_type, usage);
   return texture;
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc
index bd8e525a..5866c49 100644
--- a/gpu/command_buffer/service/shared_image_factory.cc
+++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -554,6 +554,12 @@
 bool SharedImageFactory::IsSharedBetweenThreads(uint32_t usage) {
   // Ignore for mipmap usage.
   usage &= ~SHARED_IMAGE_USAGE_MIPMAP;
+
+  // Raw Draw backings will be write accessed on the GPU main thread, and
+  // be read accessed on the compositor thread.
+  if (usage & SHARED_IMAGE_USAGE_RAW_DRAW)
+    return true;
+
   // If |shared_image_manager_| is thread safe, it means the display is
   // running on a separate thread (which uses a separate GL context or
   // VkDeviceQueue).
diff --git a/gpu/ipc/client/gpu_channel_host.h b/gpu/ipc/client/gpu_channel_host.h
index d5cbaa8b..e4a7105 100644
--- a/gpu/ipc/client/gpu_channel_host.h
+++ b/gpu/ipc/client/gpu_channel_host.h
@@ -126,7 +126,8 @@
   // running tests and is otherwise ignored.
   void TerminateGpuProcessForTesting();
 
-  std::unique_ptr<ClientSharedImageInterface>
+  // Virtual for testing.
+  virtual std::unique_ptr<ClientSharedImageInterface>
   CreateClientSharedImageInterface();
 
   ImageDecodeAcceleratorProxy* image_decode_accelerator_proxy() {
diff --git a/headless/test/headless_browser_browsertest.cc b/headless/test/headless_browser_browsertest.cc
index 1275fec0..18ae2d0 100644
--- a/headless/test/headless_browser_browsertest.cc
+++ b/headless/test/headless_browser_browsertest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <memory>
+#include <tuple>
 
 #include "base/bind.h"
 #include "base/command_line.h"
@@ -693,15 +694,12 @@
   // Create a new renderer process, and verify that callback was executed.
   HeadlessBrowserContext* browser_context =
       browser()->CreateBrowserContextBuilder().Build();
-  HeadlessWebContents* web_contents =
-      browser_context->CreateWebContentsBuilder()
-          .SetInitialURL(GURL("about:blank"))
-          .Build();
+  // Used only for lifetime, thus std::ignore.
+  std::ignore = browser_context->CreateWebContentsBuilder()
+                    .SetInitialURL(GURL("about:blank"))
+                    .Build();
 
   EXPECT_TRUE(callback_was_run_);
-
-  // Used only for lifetime.
-  (void)web_contents;
 }
 
 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, ServerWantsClientCertificate) {
diff --git a/infra/config/chops-weetbix-dev.cfg b/infra/config/chops-weetbix-dev.cfg
index 2e0ce04f..a1b11ea5 100644
--- a/infra/config/chops-weetbix-dev.cfg
+++ b/infra/config/chops-weetbix-dev.cfg
@@ -10,8 +10,9 @@
 clustering {
   test_name_rules {
     name: "Blink Web Tests"
-    pattern: "^ninja://:blink_web_tests/(virtual/[^/]+/)?(?P<testname>([^/]+/)+[^/]+\\.[a-zA-Z]+).*$"
-    like_template: "ninja://:blink\\_web\\_tests/%${testname}%"
+    # To match blink_web_tests as well as webgpu_blink_web_tests and any others.
+    pattern: "^ninja://:(?P<target>\\w*blink_web_tests)/(virtual/[^/]+/)?(?P<testname>([^/]+/)+[^/]+\\.[a-zA-Z]+).*$"
+    like_template: "ninja://:${target}/%${testname}%"
   }
   test_name_rules {
     name: "Google Test (Value-parameterized)"
diff --git a/infra/config/chops-weetbix.cfg b/infra/config/chops-weetbix.cfg
index 5365c824..adc0d733 100644
--- a/infra/config/chops-weetbix.cfg
+++ b/infra/config/chops-weetbix.cfg
@@ -2,16 +2,17 @@
 # https://luci-config.appspot.com/schemas/projects:chops-weetbix.cfg
 
 bug_filing_threshold {
-  unexpected_failures_1d: 1000
-  unexpected_failures_3d: 3000
-  unexpected_failures_7d: 7000
+  presubmit_runs_failed {
+    seven_day: 3
+  }
 }
 
 clustering {
   test_name_rules {
     name: "Blink Web Tests"
-    pattern: "^ninja://:blink_web_tests/(virtual/[^/]+/)?(?P<testname>([^/]+/)+[^/]+\\.[a-zA-Z]+).*$"
-    like_template: "ninja://:blink\\_web\\_tests/%${testname}%"
+    # To match blink_web_tests as well as webgpu_blink_web_tests and any others.
+    pattern: "^ninja://:(?P<target>\\w*blink_web_tests)/(virtual/[^/]+/)?(?P<testname>([^/]+/)+[^/]+\\.[a-zA-Z]+).*$"
+    like_template: "ninja://:${target}/%${testname}%"
   }
   test_name_rules {
     name: "Google Test (Value-parameterized)"
@@ -36,28 +37,38 @@
   priorities {
     priority: "0"
     threshold {
-      unexpected_failures_1d: 1000
+      presubmit_runs_failed {
+        one_day: 20
+      }
     }
   }
   priorities {
     priority: "1"
     threshold {
-      unexpected_failures_1d: 500
+      presubmit_runs_failed {
+        one_day: 10
+      }
     }
   }
   priorities {
     priority: "2"
     threshold {
-      unexpected_failures_1d: 100
+      presubmit_runs_failed {
+        one_day: 2
+      }
     }
   }
   priorities {
     priority: "3"
     threshold {
       # Clusters which fail to meet this threshold will be closed.
-      unexpected_failures_1d: 2
-      unexpected_failures_3d: 6
-      unexpected_failures_7d: 14
+      test_results_failed {
+        one_day: 2
+      }
+      presubmit_runs_failed {
+        one_day: 1
+        seven_day: 1
+      }
     }
   }
   priority_hysteresis_percent: 50
diff --git a/infra/config/generated/luci/chops-weetbix-dev.cfg b/infra/config/generated/luci/chops-weetbix-dev.cfg
index 2e0ce04f..a1b11ea5 100644
--- a/infra/config/generated/luci/chops-weetbix-dev.cfg
+++ b/infra/config/generated/luci/chops-weetbix-dev.cfg
@@ -10,8 +10,9 @@
 clustering {
   test_name_rules {
     name: "Blink Web Tests"
-    pattern: "^ninja://:blink_web_tests/(virtual/[^/]+/)?(?P<testname>([^/]+/)+[^/]+\\.[a-zA-Z]+).*$"
-    like_template: "ninja://:blink\\_web\\_tests/%${testname}%"
+    # To match blink_web_tests as well as webgpu_blink_web_tests and any others.
+    pattern: "^ninja://:(?P<target>\\w*blink_web_tests)/(virtual/[^/]+/)?(?P<testname>([^/]+/)+[^/]+\\.[a-zA-Z]+).*$"
+    like_template: "ninja://:${target}/%${testname}%"
   }
   test_name_rules {
     name: "Google Test (Value-parameterized)"
diff --git a/infra/config/generated/luci/chops-weetbix.cfg b/infra/config/generated/luci/chops-weetbix.cfg
index 5365c824..adc0d733 100644
--- a/infra/config/generated/luci/chops-weetbix.cfg
+++ b/infra/config/generated/luci/chops-weetbix.cfg
@@ -2,16 +2,17 @@
 # https://luci-config.appspot.com/schemas/projects:chops-weetbix.cfg
 
 bug_filing_threshold {
-  unexpected_failures_1d: 1000
-  unexpected_failures_3d: 3000
-  unexpected_failures_7d: 7000
+  presubmit_runs_failed {
+    seven_day: 3
+  }
 }
 
 clustering {
   test_name_rules {
     name: "Blink Web Tests"
-    pattern: "^ninja://:blink_web_tests/(virtual/[^/]+/)?(?P<testname>([^/]+/)+[^/]+\\.[a-zA-Z]+).*$"
-    like_template: "ninja://:blink\\_web\\_tests/%${testname}%"
+    # To match blink_web_tests as well as webgpu_blink_web_tests and any others.
+    pattern: "^ninja://:(?P<target>\\w*blink_web_tests)/(virtual/[^/]+/)?(?P<testname>([^/]+/)+[^/]+\\.[a-zA-Z]+).*$"
+    like_template: "ninja://:${target}/%${testname}%"
   }
   test_name_rules {
     name: "Google Test (Value-parameterized)"
@@ -36,28 +37,38 @@
   priorities {
     priority: "0"
     threshold {
-      unexpected_failures_1d: 1000
+      presubmit_runs_failed {
+        one_day: 20
+      }
     }
   }
   priorities {
     priority: "1"
     threshold {
-      unexpected_failures_1d: 500
+      presubmit_runs_failed {
+        one_day: 10
+      }
     }
   }
   priorities {
     priority: "2"
     threshold {
-      unexpected_failures_1d: 100
+      presubmit_runs_failed {
+        one_day: 2
+      }
     }
   }
   priorities {
     priority: "3"
     threshold {
       # Clusters which fail to meet this threshold will be closed.
-      unexpected_failures_1d: 2
-      unexpected_failures_3d: 6
-      unexpected_failures_7d: 14
+      test_results_failed {
+        one_day: 2
+      }
+      presubmit_runs_failed {
+        one_day: 1
+        seven_day: 1
+      }
     }
   }
   priority_hysteresis_percent: 50
diff --git a/ios/chrome/browser/crash_report/crash_restore_helper.mm b/ios/chrome/browser/crash_report/crash_restore_helper.mm
index 7305e83..1e38cd1 100644
--- a/ios/chrome/browser/crash_report/crash_restore_helper.mm
+++ b/ios/chrome/browser/crash_report/crash_restore_helper.mm
@@ -222,11 +222,7 @@
 
 bool SessionCrashedInfoBarDelegate::ShouldExpire(
     const NavigationDetails& details) const {
-  if (base::FeatureList::IsEnabled(kIOSPersistCrashRestore)) {
-    return false;
-  } else {
-    return InfoBarDelegate::ShouldExpire(details);
-  }
+  return false;
 }
 
 int SessionCrashedInfoBarDelegate::GetIconId() const {
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index aedfbfe3..d862850 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -544,10 +544,6 @@
      flag_descriptions::kIOSSharedHighlightingV2Name,
      flag_descriptions::kIOSSharedHighlightingV2Description, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(shared_highlighting::kIOSSharedHighlightingV2)},
-    {"ios-persist-crash-restore-infobar",
-     flag_descriptions::kIOSPersistCrashRestoreName,
-     flag_descriptions::kIOSPersistCrashRestoreDescription, flags_ui::kOsIos,
-     FEATURE_VALUE_TYPE(kIOSPersistCrashRestore)},
     {"omnibox-new-textfield-implementation",
      flag_descriptions::kOmniboxNewImplementationName,
      flag_descriptions::kOmniboxNewImplementationDescription, flags_ui::kOsIos,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index e4b66ae..5c36358e 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -295,11 +295,6 @@
 const char kIOSEnablePasswordManagerBrandingUpdateDescription[] =
     "Updates icons, strings, and views for Google Password Manager.";
 
-const char kIOSPersistCrashRestoreName[] = "Persist Crash Restore Infobar";
-const char kIOSPersistCrashRestoreDescription[] =
-    "When enabled, the Crash Restore Infobar will persist through navigations "
-    "instead of dismissing.";
-
 const char kIOSSharedHighlightingColorChangeName[] =
     "IOS Shared Highlighting color change";
 const char kIOSSharedHighlightingColorChangeDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index 0bab78f..2e477e5 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -265,11 +265,6 @@
 extern const char kIOSEnablePasswordManagerBrandingUpdateName[];
 extern const char kIOSEnablePasswordManagerBrandingUpdateDescription[];
 
-// Title and description for the flag to persist the Crash Restore Infobar
-// across navigations.
-extern const char kIOSPersistCrashRestoreName[];
-extern const char kIOSPersistCrashRestoreDescription[];
-
 // Title and description for the flag to enable Shared Highlighting color
 // change in iOS.
 extern const char kIOSSharedHighlightingColorChangeName[];
diff --git a/ios/chrome/browser/tabs_search/BUILD.gn b/ios/chrome/browser/tabs_search/BUILD.gn
index aca4c85d..274e50ec 100644
--- a/ios/chrome/browser/tabs_search/BUILD.gn
+++ b/ios/chrome/browser/tabs_search/BUILD.gn
@@ -23,7 +23,7 @@
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/tabs",
     "//ios/chrome/browser/ui/history:history_driver",
-    "//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui",
+    "//ios/chrome/browser/ui/recent_tabs:synced_sessions",
     "//ios/chrome/browser/web_state_list",
     "//ios/web/public",
   ]
diff --git a/ios/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
index e23792bf..676131d1 100644
--- a/ios/chrome/browser/ui/recent_tabs/BUILD.gn
+++ b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -18,6 +18,7 @@
   ]
   deps = [
     ":recent_tabs_ui",
+    ":synced_sessions",
     "resources:show_history",
     "//base",
     "//components/sessions",
@@ -67,11 +68,10 @@
     "recent_tabs_transitioning_delegate.h",
     "recent_tabs_transitioning_delegate.mm",
     "sessions_sync_user_state.h",
-    "synced_sessions.h",
-    "synced_sessions.mm",
   ]
   deps = [
     ":recent_tabs_ui_constants",
+    ":synced_sessions",
     "resources:recent_tabs_other_devices_empty",
     "//base",
     "//components/prefs",
@@ -113,6 +113,15 @@
     "//ios/public/provider/chrome/browser/modals:modals_api",
     "//ui/base",
   ]
+}
+
+source_set("synced_sessions") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "synced_sessions.h",
+    "synced_sessions.mm",
+  ]
+  deps = [ "//ios/chrome/browser/sync" ]
   public_deps = [ "//components/sync_sessions" ]
 }
 
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
index 257a8ee..bf4e35d 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -134,7 +134,13 @@
                                              TableViewURLDragDataSource,
                                              UIContextMenuInteractionDelegate,
                                              UIGestureRecognizerDelegate> {
+  // The instance which owns the DistantTabs to display.
   std::unique_ptr<synced_sessions::SyncedSessions> _syncedSessions;
+  // The displayed sessions and tabs. The sessions and tabs are owned by
+  // |_syncedSessions|, but |_displayedTabs| allows for filtering to display
+  // only particular tabs.
+  std::vector<synced_sessions::DistantTabsSet> _displayedTabs;
+
   std::unique_ptr<SyncObserverBridge> _syncObserver;
 }
 // The service that manages the recently closed tabs
@@ -409,7 +415,7 @@
   TableViewModel* model = self.tableViewModel;
   for (NSUInteger i = 0; i < [self numberOfSessions]; i++) {
     synced_sessions::DistantSession const* session =
-        _syncedSessions->GetSession(i);
+        _syncedSessions->GetSessionWithTag(_displayedTabs[i].session_tag);
     NSInteger sessionIdentifier = [self sectionIdentifierForSession:session];
     [model addSectionWithIdentifier:sessionIdentifier];
     NSString* sessionCollapsedKey = base::SysUTF8ToNSString(session->tag);
@@ -429,27 +435,49 @@
 }
 
 - (void)addItemsForSession:(synced_sessions::DistantSession const*)session {
-  TableViewModel* model = self.tableViewModel;
-  NSInteger numberOfTabs = base::checked_cast<NSInteger>(session->tabs.size());
-  for (int i = 0; i < numberOfTabs; i++) {
-    synced_sessions::DistantTab const* sessionTab = session->tabs[i].get();
-    NSString* title = base::SysUTF16ToNSString(sessionTab->title);
+  const synced_sessions::DistantTabsSet* session_tabs_set =
+      [self distantTabsSetForSessionWithTag:session->tag];
 
-    TableViewURLItem* sessionTabItem =
-        [[TableViewURLItem alloc] initWithType:ItemTypeSessionTabData];
-    sessionTabItem.title = title;
-    sessionTabItem.URL = [[CrURL alloc] initWithGURL:sessionTab->virtual_url];
-    [model addItem:sessionTabItem
-        toSectionWithIdentifier:[self sectionIdentifierForSession:session]];
+  if (!session_tabs_set) {
+    return;
   }
+
+  NSInteger sectionIdentifier = [self sectionIdentifierForSession:session];
+  if (session_tabs_set->filtered_tabs) {
+    // Only add the items from |filtered_tabs|.
+    for (synced_sessions::DistantTab* sessionTab :
+         session_tabs_set->filtered_tabs.value()) {
+      [self addItemForDistantTab:sessionTab
+          toSectionWithIdentifier:sectionIdentifier];
+    }
+  } else {
+    // When |filtered_tabs| is null, all tabs in the session are included
+    // in the set.
+    for (auto&& sessionTab : session->tabs) {
+      [self addItemForDistantTab:sessionTab.get()
+          toSectionWithIdentifier:sectionIdentifier];
+    }
+  }
+}
+
+- (void)addItemForDistantTab:(synced_sessions::DistantTab*)sessionTab
+     toSectionWithIdentifier:(NSInteger)sectionIdentifier {
+  NSString* title = base::SysUTF16ToNSString(sessionTab->title);
+
+  TableViewURLItem* sessionTabItem =
+      [[TableViewURLItem alloc] initWithType:ItemTypeSessionTabData];
+  sessionTabItem.title = title;
+  sessionTabItem.URL = [[CrURL alloc] initWithGURL:sessionTab->virtual_url];
+  [self.tableViewModel addItem:sessionTabItem
+       toSectionWithIdentifier:sectionIdentifier];
 }
 
 // Remove all SessionSections from |self.tableViewModel| and |self.tableView|
 // Needs to be called inside a [UITableView beginUpdates] block on iOS10, or
 // performBatchUpdates on iOS11+.
 - (void)removeSessionSections {
-  // |_syncedSessions| has been updated by now, that means that
-  // |self.tableViewModel| does not reflect |_syncedSessions| data.
+  // |_displayedTabs| has been updated by now, that means that
+  // |self.tableViewModel| does not reflect |_displayedTabs| data.
   NSInteger sectionIdentifierToRemove = kFirstSessionSectionIdentifier;
   NSInteger sectionToDelete = kNumberOfSectionsBeforeSessions;
   while ([self.tableViewModel numberOfSections] >
@@ -652,9 +680,7 @@
 - (NSInteger)sectionIdentifierForSession:
     (synced_sessions::DistantSession const*)distantSession {
   for (NSUInteger i = 0; i < [self numberOfSessions]; i++) {
-    synced_sessions::DistantSession const* session =
-        _syncedSessions->GetSession(i);
-    if (session->tag == distantSession->tag)
+    if (_displayedTabs[i].session_tag == distantSession->tag)
       return i + kFirstSessionSectionIdentifier;
   }
   NOTREACHED();
@@ -685,7 +711,9 @@
   NSInteger section =
       [self.tableViewModel sectionForSectionIdentifier:sectionIdentifer];
   DCHECK([self isSessionSectionIdentifier:sectionIdentifer]);
-  return _syncedSessions->GetSession(section - kNumberOfSectionsBeforeSessions);
+  const synced_sessions::DistantTabsSet& tabsSet =
+      _displayedTabs[section - kNumberOfSectionsBeforeSessions];
+  return _syncedSessions->GetSessionWithTag(tabsSet.session_tag);
 }
 
 - (void)removeSessionAtTableSectionWithIdentifier:(NSInteger)sectionIdentifier {
@@ -701,7 +729,7 @@
   __weak __typeof(self) weakSelf = self;
   [self.tableView
       performBatchUpdates:^{
-        [weakSelf removeSection:sectionIdentifier];
+        [weakSelf removeSection:sectionIdentifier forSessionWithTag:sessionTag];
       }
       completion:^(BOOL) {
         [weakSelf deleteSession:sessionTag];
@@ -709,11 +737,20 @@
 }
 
 // Helper for removeSessionAtTableSectionWithIdentifier
-- (void)removeSection:(NSInteger)sectionIdentifier {
+- (void)removeSection:(NSInteger)sectionIdentifier
+    forSessionWithTag:(std::string)sessionTag {
   NSInteger sectionIndex =
       [self.tableViewModel sectionForSectionIdentifier:sectionIdentifier];
   [self.tableViewModel removeSectionWithIdentifier:sectionIdentifier];
-  _syncedSessions->EraseSession(sectionIndex - kNumberOfSectionsBeforeSessions);
+
+  for (NSUInteger i = 0; i < _displayedTabs.size(); i++) {
+    if (sessionTag == _displayedTabs[i].session_tag) {
+      _displayedTabs.erase(_displayedTabs.begin() + i);
+      break;
+    }
+  }
+  _syncedSessions->EraseSessionWithTag(sessionTag);
+
   [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                 withRowAnimation:UITableViewRowAnimationLeft];
 }
@@ -747,9 +784,22 @@
     // won't change.
     return;
   }
+
   sync_sessions::SessionSyncService* syncService =
       SessionSyncServiceFactory::GetForBrowserState(self.browserState);
-  _syncedSessions.reset(new synced_sessions::SyncedSessions(syncService));
+  _syncedSessions =
+      std::make_unique<synced_sessions::SyncedSessions>(syncService);
+
+  // Reset |_displayedTabs| to contain all sessions and tabs.
+  _displayedTabs = std::vector<synced_sessions::DistantTabsSet>();
+  for (size_t s = 0; s < _syncedSessions->GetSessionCount(); s++) {
+    const synced_sessions::DistantSession* session =
+        _syncedSessions->GetSession(s);
+
+    synced_sessions::DistantTabsSet distant_tabs;
+    distant_tabs.session_tag = session->tag;
+    _displayedTabs.push_back(distant_tabs);
+  }
 
   if (!self.preventUpdates) {
     // Update the TableView and TableViewModel sections to match the new
@@ -1047,7 +1097,7 @@
 - (NSUInteger)numberOfSessions {
   if (!_syncedSessions)
     return 0;
-  return _syncedSessions->GetSessionCount();
+  return _displayedTabs.size();
 }
 
 // Returns the Session Index for a given Session Tab |indexPath|.
@@ -1060,14 +1110,15 @@
   // Get the index of this sectionIdentifier.
   size_t indexOfSession = [[self allSessionSectionIdentifiers]
       indexOfObject:sectionIdentifierForIndexPath];
-  DCHECK_LT(indexOfSession, _syncedSessions->GetSessionCount());
+  DCHECK_LT(indexOfSession, _displayedTabs.size());
   return indexOfSession;
 }
 
 - (synced_sessions::DistantSession const*)sessionForTabAtIndexPath:
     (NSIndexPath*)indexPath {
-  return _syncedSessions->GetSession(
-      [self indexOfSessionForTabAtIndexPath:indexPath]);
+  const synced_sessions::DistantTabsSet& tabs_set =
+      _displayedTabs[[self indexOfSessionForTabAtIndexPath:indexPath]];
+  return _syncedSessions->GetSessionWithTag(tabs_set.session_tag);
 }
 
 - (synced_sessions::DistantTab const*)distantTabAtIndexPath:
@@ -1077,10 +1128,28 @@
   size_t indexOfDistantTab = indexPath.row;
   synced_sessions::DistantSession const* session =
       [self sessionForTabAtIndexPath:indexPath];
+  const synced_sessions::DistantTabsSet* tabs_set =
+      [self distantTabsSetForSessionWithTag:session->tag];
+  if (tabs_set->filtered_tabs) {
+    DCHECK_LT(indexOfDistantTab, tabs_set->filtered_tabs->size());
+    return tabs_set->filtered_tabs.value()[indexOfDistantTab];
+  }
+
+  // If filtered_tabs is null, all tabs in |session| should be used.
   DCHECK_LT(indexOfDistantTab, session->tabs.size());
   return session->tabs[indexOfDistantTab].get();
 }
 
+- (const synced_sessions::DistantTabsSet*)distantTabsSetForSessionWithTag:
+    (const std::string&)sessionTag {
+  for (const synced_sessions::DistantTabsSet& tabs_set : _displayedTabs) {
+    if (sessionTag == tabs_set.session_tag) {
+      return &tabs_set;
+    }
+  }
+  return nullptr;
+}
+
 - (NSString*)lastSyncStringForSesssion:
     (synced_sessions::DistantSession const*)session {
   base::Time time = session->modified_time;
diff --git a/ios/chrome/browser/ui/recent_tabs/synced_sessions.h b/ios/chrome/browser/ui/recent_tabs/synced_sessions.h
index 2aa2caf..4cc56ac 100644
--- a/ios/chrome/browser/ui/recent_tabs/synced_sessions.h
+++ b/ios/chrome/browser/ui/recent_tabs/synced_sessions.h
@@ -45,6 +45,22 @@
   size_t hashOfUserVisibleProperties();
 };
 
+// Data holder that contains a set of distant tabs to show in the UI.
+struct DistantTabsSet {
+  DistantTabsSet();
+  ~DistantTabsSet();
+
+  DistantTabsSet(const DistantTabsSet&);
+
+  // The tag of the DistantSession which owns the tabs referenced in |tabs|.
+  std::string session_tag;
+  // A selection of |DistantTab|s from the session with tag |session_tag|. A
+  // null value for |filtered_tabs| represents that the session's tabs are
+  // not filtered. This shortcut representation prevents having to copy over
+  // pointers to each tab within a session when every tab is included.
+  absl::optional<std::vector<DistantTab*>> filtered_tabs;
+};
+
 // Data holder that contains the data of the distant sessions and their tabs to
 // show in the UI.
 
@@ -90,7 +106,7 @@
   DistantSession const* GetSession(size_t index) const;
   DistantSession const* GetSessionWithTag(const std::string& tag) const;
   size_t GetSessionCount() const;
-  void EraseSession(size_t index);
+  void EraseSessionWithTag(const std::string& tag);
 
   // Used by tests only.
   void AddDistantSessionForTest(
diff --git a/ios/chrome/browser/ui/recent_tabs/synced_sessions.mm b/ios/chrome/browser/ui/recent_tabs/synced_sessions.mm
index 3371af4..c9bef90 100644
--- a/ios/chrome/browser/ui/recent_tabs/synced_sessions.mm
+++ b/ios/chrome/browser/ui/recent_tabs/synced_sessions.mm
@@ -66,6 +66,12 @@
   return std::hash<std::string>()(ss.str());
 }
 
+DistantTabsSet::DistantTabsSet() = default;
+
+DistantTabsSet::~DistantTabsSet() = default;
+
+DistantTabsSet::DistantTabsSet(const DistantTabsSet&) = default;
+
 DistantSession::DistantSession() = default;
 
 DistantSession::DistantSession(sync_sessions::SessionSyncService* sync_service,
@@ -149,7 +155,15 @@
 }
 
 // Deletes the session at index |index|.
-void SyncedSessions::EraseSession(size_t index) {
+void SyncedSessions::EraseSessionWithTag(const std::string& tag) {
+  size_t index = GetSessionCount();
+  for (size_t i = 0; i < GetSessionCount(); i++) {
+    if (GetSession(i)->tag == tag) {
+      index = i;
+      break;
+    }
+  }
+
   DCHECK_LE(index, GetSessionCount());
   sessions_.erase(sessions_.begin() + index);
 }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
index 61b9efc..db9bff27 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
@@ -57,6 +57,7 @@
     "//ios/chrome/browser/ui/menu:context_menu_delegate",
     "//ios/chrome/browser/ui/recent_tabs",
     "//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui",
+    "//ios/chrome/browser/ui/recent_tabs:synced_sessions",
     "//ios/chrome/browser/ui/sharing",
     "//ios/chrome/browser/ui/snackbar",
     "//ios/chrome/browser/ui/tab_switcher",
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc
index caa8d01..e481004 100644
--- a/ios/chrome/browser/ui/ui_feature_flags.cc
+++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -46,9 +46,6 @@
 const base::Feature kIOSLocationBarUseNativeContextMenu{
     "IOSLocationBarUseNativeContextMenu", base::FEATURE_ENABLED_BY_DEFAULT};
 
-const base::Feature kIOSPersistCrashRestore{"IOSPersistCrashRestore",
-                                            base::FEATURE_ENABLED_BY_DEFAULT};
-
 const base::Feature kSearchHistoryLinkIOS{"SearchHistoryLinkIOS",
                                           base::FEATURE_ENABLED_BY_DEFAULT};
 
diff --git a/ios/chrome/browser/ui/ui_feature_flags.h b/ios/chrome/browser/ui/ui_feature_flags.h
index 9822f5de..8308893 100644
--- a/ios/chrome/browser/ui/ui_feature_flags.h
+++ b/ios/chrome/browser/ui/ui_feature_flags.h
@@ -55,10 +55,6 @@
 // Feature flag that fixes omnibox behavior when using iOS native dictation
 extern const base::Feature kIOSOmniboxAllowEditsDuringDictation;
 
-// Feature flag that enables persisting the Crash Restore Infobar across
-// navigations.
-extern const base::Feature kIOSPersistCrashRestore;
-
 // Enables the Search History Link in Clear Browsing Data for iOS.
 extern const base::Feature kSearchHistoryLinkIOS;
 
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index 02810f9..725b6cf 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-19e9b716ec0f2f5558f2fbfc13efaefecc6d1ba2
\ No newline at end of file
+051eb1c0368aa9c7ddf8badab17579c1e60b1240
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index 1ad0cc61..9a8c252 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-6fbd1260eaf8de9eee783f03fbb4e5fe8cdbb1af
\ No newline at end of file
+34fda378ac7c0673d28fba21f88a11a99445b313
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index 214f2daa..edc04dee 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-17b928e2df4f569d00191cbbdc06b92ce5deca73
\ No newline at end of file
+5c6c763bed8624b1dfda940a3d1f078e7f6cbdcf
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index b50b208..79f4e01 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-d2a40ca436ed98218fbdf8b414a2e76c5ed1eedd
\ No newline at end of file
+b08a4696710b68ef82ea285e4c372900fdb48519
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
index 1b2340bb..529e4f2 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-7601dd7f8efd4eeccae238de7f4af813eba0f7db
\ No newline at end of file
+d2fbb75e5099db6aae897155258b5fc0cccba401
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
index 3ad33fa..5ff5569 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-b35201ee563a0a9c013886c23f90a40e68ca4c2a
\ No newline at end of file
+62ea1af4fa82e7edccf88b55509410ed324acbc5
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index bd1ed147..9e6bee1 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-36a37a0ef7f97125199249ff76b93f4711284a2e
\ No newline at end of file
+c46c9a43a7260bd807e2a3735caeb58e5135727b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 03e4c4f..f5d53f5d 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-d6aaaa5566a5c1074031aa43c9f63d9e3b92cfc9
\ No newline at end of file
+2723fe046b5634d1c12397de8cc18e91460d6b0e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index 31a0361..99ba09d2 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-a5d228039092933b41e6b46fd3bdda99b292e613
\ No newline at end of file
+8faf8172f18f165237cdad5724e351fc4d39f42e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 82daf431..7814fc9c 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-d9584c5b0dd363093f3399f4365befed0995ec7d
\ No newline at end of file
+efeb8835abbe3c30801629080907c48fe2384744
\ No newline at end of file
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc
index 6ef348a..497dc8f 100644
--- a/media/audio/audio_manager_base.cc
+++ b/media/audio/audio_manager_base.cc
@@ -228,6 +228,9 @@
       break;
     case AudioParameters::AUDIO_BITSTREAM_AC3:
     case AudioParameters::AUDIO_BITSTREAM_EAC3:
+    case AudioParameters::AUDIO_BITSTREAM_DTS:
+    case AudioParameters::AUDIO_BITSTREAM_DTS_HD:
+    case AudioParameters::AUDIO_BITSTREAM_IEC61937:
       stream = MakeBitstreamOutputStream(params, device_id, log_callback);
       break;
     case AudioParameters::AUDIO_FAKE:
diff --git a/media/base/android/media_codec_util.cc b/media/base/android/media_codec_util.cc
index b02e582..34bcdbd3 100644
--- a/media/base/android/media_codec_util.cc
+++ b/media/base/android/media_codec_util.cc
@@ -47,6 +47,8 @@
 const char kVp8MimeType[] = "video/x-vnd.on2.vp8";
 const char kVp9MimeType[] = "video/x-vnd.on2.vp9";
 const char kAv1MimeType[] = "video/av01";
+const char kDtsMimeType[] = "audio/vnd.dts";
+const char kDtsxP2MimeType[] = "audio/vnd.dts.uhd;profile=p2";
 }  // namespace
 
 static CodecProfileLevel MediaCodecProfileLevelToChromiumProfileLevel(
@@ -134,6 +136,10 @@
       return kAc3MimeType;
     case AudioCodec::kEAC3:
       return kEac3MimeType;
+    case AudioCodec::kDTS:
+      return kDtsMimeType;
+    case AudioCodec::kDTSXP2:
+      return kDtsxP2MimeType;
     default:
       return std::string();
   }
@@ -269,7 +275,16 @@
 
 // static
 bool MediaCodecUtil::IsPassthroughAudioFormat(AudioCodec codec) {
-  return codec == AudioCodec::kAC3 || codec == AudioCodec::kEAC3;
+  switch (codec) {
+    case AudioCodec::kAC3:
+    case AudioCodec::kEAC3:
+    case AudioCodec::kDTS:
+    case AudioCodec::kDTSXP2:
+    case AudioCodec::kMpegHAudio:
+      return true;
+    default:
+      return false;
+  }
 }
 
 // static
diff --git a/media/base/audio_parameters.cc b/media/base/audio_parameters.cc
index 73660ae..8b07177 100644
--- a/media/base/audio_parameters.cc
+++ b/media/base/audio_parameters.cc
@@ -20,6 +20,12 @@
       return "BITSTREAM_AC3";
     case AudioParameters::AUDIO_BITSTREAM_EAC3:
       return "BITSTREAM_EAC3";
+    case AudioParameters::AUDIO_BITSTREAM_DTS:
+      return "BITSTREAM_DTS";
+    case AudioParameters::AUDIO_BITSTREAM_DTS_HD:
+      return "BITSTREAM_DTS_HD";
+    case AudioParameters::AUDIO_BITSTREAM_IEC61937:
+      return "BITSTREAM_IEC61937";
     case AudioParameters::AUDIO_FAKE:
       return "FAKE";
   }
@@ -176,7 +182,16 @@
 }
 
 bool AudioParameters::IsBitstreamFormat() const {
-  return format_ == AUDIO_BITSTREAM_AC3 || format_ == AUDIO_BITSTREAM_EAC3;
+  switch (format_) {
+    case AUDIO_BITSTREAM_AC3:
+    case AUDIO_BITSTREAM_EAC3:
+    case AUDIO_BITSTREAM_DTS:
+    case AUDIO_BITSTREAM_DTS_HD:
+    case AUDIO_BITSTREAM_IEC61937:
+      return true;
+    default:
+      return false;
+  }
 }
 
 // static
diff --git a/media/base/audio_parameters.h b/media/base/audio_parameters.h
index 5f61f80..cc82c20 100644
--- a/media/base/audio_parameters.h
+++ b/media/base/audio_parameters.h
@@ -131,6 +131,9 @@
     AUDIO_PCM_LOW_LATENCY,           // Linear PCM, low latency requested.
     AUDIO_BITSTREAM_AC3,             // Compressed AC3 bitstream.
     AUDIO_BITSTREAM_EAC3,            // Compressed E-AC3 bitstream.
+    AUDIO_BITSTREAM_DTS,             // Compressed DTS bitstream.
+    AUDIO_BITSTREAM_DTS_HD,          // Compressed DTS-HD bitstream.
+    AUDIO_BITSTREAM_IEC61937,        // Compressed IEC61937 bitstream.
     AUDIO_FAKE,                      // Creates a fake AudioOutputStream object.
     AUDIO_FORMAT_LAST = AUDIO_FAKE,  // Only used for validation of format.
   };
diff --git a/media/base/demuxer_memory_limit_cast.cc b/media/base/demuxer_memory_limit_cast.cc
index 3020f48..addbf15 100644
--- a/media/base/demuxer_memory_limit_cast.cc
+++ b/media/base/demuxer_memory_limit_cast.cc
@@ -19,6 +19,9 @@
   switch (audio_config->codec()) {
     case AudioCodec::kEAC3:
     case AudioCodec::kAC3:
+    case AudioCodec::kDTS:
+    case AudioCodec::kDTSXP2:
+    case AudioCodec::kMpegHAudio:
       return internal::kDemuxerStreamAudioMemoryLimitMedium;
     case AudioCodec::kAAC:
       if (ChannelLayoutToChannelCount(audio_config->channel_layout()) >= 5) {
diff --git a/media/base/demuxer_memory_limit_cast_unittest.cc b/media/base/demuxer_memory_limit_cast_unittest.cc
index 2f150da..76444445 100644
--- a/media/base/demuxer_memory_limit_cast_unittest.cc
+++ b/media/base/demuxer_memory_limit_cast_unittest.cc
@@ -47,6 +47,34 @@
       EmptyExtraData(), EncryptionScheme::kUnencrypted);
   EXPECT_EQ(GetDemuxerStreamAudioMemoryLimit(&audio_config_aac_2),
             internal::kDemuxerStreamAudioMemoryLimitLow);
+
+  AudioDecoderConfig audio_config_dts_20(
+      AudioCodec::kDTS, SampleFormat::kSampleFormatS16,
+      ChannelLayout::CHANNEL_LAYOUT_STEREO, 5000 /* samples_per_second */,
+      EmptyExtraData(), EncryptionScheme::kUnencrypted);
+  EXPECT_EQ(GetDemuxerStreamAudioMemoryLimit(&audio_config_dts_20),
+            internal::kDemuxerStreamAudioMemoryLimitMedium);
+
+  AudioDecoderConfig audio_config_dts_51(
+      AudioCodec::kDTS, SampleFormat::kSampleFormatS16,
+      ChannelLayout::CHANNEL_LAYOUT_5_1, 5000 /* samples_per_second */,
+      EmptyExtraData(), EncryptionScheme::kUnencrypted);
+  EXPECT_EQ(GetDemuxerStreamAudioMemoryLimit(&audio_config_dts_51),
+            internal::kDemuxerStreamAudioMemoryLimitMedium);
+
+  AudioDecoderConfig audio_config_dtsxp2_20(
+      AudioCodec::kDTSXP2, SampleFormat::kSampleFormatS16,
+      ChannelLayout::CHANNEL_LAYOUT_STEREO, 5000 /* samples_per_second */,
+      EmptyExtraData(), EncryptionScheme::kUnencrypted);
+  EXPECT_EQ(GetDemuxerStreamAudioMemoryLimit(&audio_config_dtsxp2_20),
+            internal::kDemuxerStreamAudioMemoryLimitMedium);
+
+  AudioDecoderConfig audio_config_dtsxp2_51(
+      AudioCodec::kDTSXP2, SampleFormat::kSampleFormatS16,
+      ChannelLayout::CHANNEL_LAYOUT_5_1, 5000 /* samples_per_second */,
+      EmptyExtraData(), EncryptionScheme::kUnencrypted);
+  EXPECT_EQ(GetDemuxerStreamAudioMemoryLimit(&audio_config_dtsxp2_51),
+            internal::kDemuxerStreamAudioMemoryLimitMedium);
 }
 
 TEST(DemuxerMemoryLimitCastTest, GetDemuxerStreamVideoMemoryLimit) {
diff --git a/media/base/eme_constants.h b/media/base/eme_constants.h
index 6e47c0e..31918a7 100644
--- a/media/base/eme_constants.h
+++ b/media/base/eme_constants.h
@@ -40,6 +40,8 @@
   EME_CODEC_FLAC = 1 << 13,
   EME_CODEC_AV1 = 1 << 14,
   EME_CODEC_HEVC_PROFILE_MAIN10 = 1 << 15,
+  EME_CODEC_DTS = 1 << 16,
+  EME_CODEC_DTSXP2 = 1 << 17,
 };
 
 // *_ALL values should only be used for masking, do not use them to specify
@@ -56,6 +58,9 @@
 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
   codecs |= EME_CODEC_AC3 | EME_CODEC_EAC3;
 #endif  // BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+  codecs |= EME_CODEC_DTS | EME_CODEC_DTSXP2;
+#endif  // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
   codecs |= EME_CODEC_MPEG_H_AUDIO;
 #endif  // BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc
index 66ab78f..872f3b0 100644
--- a/media/base/key_systems.cc
+++ b/media/base/key_systems.cc
@@ -79,6 +79,10 @@
       return EME_CODEC_AC3;
     case AudioCodec::kMpegHAudio:
       return EME_CODEC_MPEG_H_AUDIO;
+    case AudioCodec::kDTS:
+      return EME_CODEC_DTS;
+    case AudioCodec::kDTSXP2:
+      return EME_CODEC_DTSXP2;
     default:
       DVLOG(1) << "Unsupported AudioCodec " << codec;
       return EME_CODEC_NONE;
diff --git a/media/base/mime_util_internal.cc b/media/base/mime_util_internal.cc
index 66035706..5aaa7a1 100644
--- a/media/base/mime_util_internal.cc
+++ b/media/base/mime_util_internal.cc
@@ -91,6 +91,12 @@
       {"vp8", MimeUtil::VP8},
       {"vp8.0", MimeUtil::VP8},
       {"theora", MimeUtil::THEORA},
+      {"dtsc", MimeUtil::DTS},
+      {"mp4a.a9", MimeUtil::DTS},
+      {"mp4a.A9", MimeUtil::DTS},
+      {"dtsx", MimeUtil::DTSXP2},
+      {"mp4a.b2", MimeUtil::DTSXP2},
+      {"mp4a.B2", MimeUtil::DTSXP2},
   });
 
   return *kStringToCodecMap;
@@ -183,6 +189,10 @@
       return AudioCodec::kOpus;
     case MimeUtil::FLAC:
       return AudioCodec::kFLAC;
+    case MimeUtil::DTS:
+      return AudioCodec::kDTS;
+    case MimeUtil::DTSXP2:
+      return AudioCodec::kDTSXP2;
     default:
       break;
   }
@@ -341,6 +351,11 @@
   mp4_video_codecs.emplace(AV1);
 #endif
 
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+  mp4_audio_codecs.emplace(DTS);
+  mp4_audio_codecs.emplace(DTSXP2);
+#endif  // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+
   CodecSet mp4_codecs(mp4_audio_codecs);
   mp4_codecs.insert(mp4_video_codecs.begin(), mp4_video_codecs.end());
 
@@ -651,6 +666,14 @@
 #else
       return false;
 #endif
+
+    case DTS:
+    case DTSXP2:
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+      return true;
+#else
+      return false;
+#endif
   }
 
   return false;
diff --git a/media/base/mime_util_internal.h b/media/base/mime_util_internal.h
index c8f2a81..8890b25 100644
--- a/media/base/mime_util_internal.h
+++ b/media/base/mime_util_internal.h
@@ -51,7 +51,9 @@
     DOLBY_VISION,
     AV1,
     MPEG_H_AUDIO,
-    LAST_CODEC = MPEG_H_AUDIO
+    DTS,
+    DTSXP2,
+    LAST_CODEC = DTSXP2
   };
 
   // Platform configuration structure.  Controls which codecs are supported at
diff --git a/media/base/mime_util_unittest.cc b/media/base/mime_util_unittest.cc
index 37fcd0ae..7ebc357 100644
--- a/media/base/mime_util_unittest.cc
+++ b/media/base/mime_util_unittest.cc
@@ -588,6 +588,11 @@
           case MimeUtil::AV1:
             EXPECT_EQ(BUILDFLAG(ENABLE_AV1_DECODER), result);
             break;
+
+          case MimeUtil::DTS:
+          case MimeUtil::DTSXP2:
+            EXPECT_EQ(BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO), result);
+            break;
         }
       });
 }
@@ -649,6 +654,11 @@
           case MimeUtil::AV1:
             EXPECT_EQ(BUILDFLAG(ENABLE_AV1_DECODER), result);
             break;
+
+          case MimeUtil::DTS:
+          case MimeUtil::DTSXP2:
+            EXPECT_EQ(BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO), result);
+            break;
         }
       });
 }
diff --git a/media/base/supported_types_unittest.cc b/media/base/supported_types_unittest.cc
index 987c5e190..e0ad092 100644
--- a/media/base/supported_types_unittest.cc
+++ b/media/base/supported_types_unittest.cc
@@ -236,6 +236,14 @@
   EXPECT_FALSE(IsSupportedAudioType({AudioCodec::kMpegHAudio,
                                      AudioCodecProfile::kUnknown,
                                      is_spatial_rendering}));
+#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+  EXPECT_FALSE(IsSupportedAudioType(
+      {AudioCodec::kDTS, AudioCodecProfile::kUnknown, is_spatial_rendering}));
+  EXPECT_FALSE(
+      IsSupportedAudioType({AudioCodec::kDTSXP2, AudioCodecProfile::kUnknown,
+                            is_spatial_rendering}));
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS) &&
+        // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
   EXPECT_FALSE(
       IsSupportedAudioType({AudioCodec::kUnknown, AudioCodecProfile::kUnknown,
                             is_spatial_rendering}));
diff --git a/media/base/win/BUILD.gn b/media/base/win/BUILD.gn
index bcc1f9d5..558334a8 100644
--- a/media/base/win/BUILD.gn
+++ b/media/base/win/BUILD.gn
@@ -48,7 +48,10 @@
 
 source_set("dcomp_texture_wrapper") {
   sources = [ "dcomp_texture_wrapper.h" ]
-  deps = [ "//base" ]
+  deps = [
+    "//base",
+    "//ui/gfx:memory_buffer",
+  ]
 }
 
 source_set("test_support") {
diff --git a/media/base/win/dcomp_texture_wrapper.h b/media/base/win/dcomp_texture_wrapper.h
index f14b39c4..93eee077 100644
--- a/media/base/win/dcomp_texture_wrapper.h
+++ b/media/base/win/dcomp_texture_wrapper.h
@@ -7,6 +7,7 @@
 
 #include "base/callback.h"
 #include "base/unguessable_token.h"
+#include "ui/gfx/gpu_memory_buffer.h"
 
 namespace gfx {
 class Rect;
@@ -42,6 +43,14 @@
       base::OnceCallback<void(scoped_refptr<VideoFrame>)>;
   virtual void CreateVideoFrame(const gfx::Size& natural_size,
                                 CreateVideoFrameCB create_video_frame_cb) = 0;
+
+  using CreateDXVideoFrameCB =
+      base::OnceCallback<void(scoped_refptr<VideoFrame>,
+                              const base::UnguessableToken& token)>;
+  virtual void CreateVideoFrame(const gfx::Size& natural_size,
+                                gfx::GpuMemoryBufferHandle dx_handle,
+                                const base::UnguessableToken& token,
+                                CreateDXVideoFrameCB create_video_frame_cb) = 0;
 };
 
 }  // namespace media
diff --git a/media/filters/stream_parser_factory.cc b/media/filters/stream_parser_factory.cc
index 9e60cc8..eb834b0 100644
--- a/media/filters/stream_parser_factory.cc
+++ b/media/filters/stream_parser_factory.cc
@@ -215,6 +215,27 @@
                                           CodecInfo::HISTOGRAM_EAC3};
 #endif  // BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
 
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+// The 'dtsc' and 'dtsx' are mime codec ids for DTS and DTSX according to
+// http://mp4ra.org/#/codecs
+// The object types for DTS and DTSX in MP4 container are 0xa9 and 0xb2, so
+// according to RFC 6381 this corresponds to codec ids 'mp4a.A9' and 'mp4a.B2'.
+// Codec ids with lower case oti (mp4a.a9 and mp4a.b2) are supported for
+// backward compatibility.
+static const CodecInfo kDTSCodecInfo1 = {"dtsc", CodecInfo::AUDIO, nullptr,
+                                         CodecInfo::HISTOGRAM_DTS};
+static const CodecInfo kDTSCodecInfo2 = {"mp4a.a9", CodecInfo::AUDIO, nullptr,
+                                         CodecInfo::HISTOGRAM_DTS};
+static const CodecInfo kDTSCodecInfo3 = {"mp4a.A9", CodecInfo::AUDIO, nullptr,
+                                         CodecInfo::HISTOGRAM_DTS};
+static const CodecInfo kDTSXCodecInfo1 = {"dtsx", CodecInfo::AUDIO, nullptr,
+                                          CodecInfo::HISTOGRAM_DTSXP2};
+static const CodecInfo kDTSXCodecInfo2 = {"mp4a.b2", CodecInfo::AUDIO, nullptr,
+                                          CodecInfo::HISTOGRAM_DTSXP2};
+static const CodecInfo kDTSXCodecInfo3 = {"mp4a.B2", CodecInfo::AUDIO, nullptr,
+                                          CodecInfo::HISTOGRAM_DTSXP2};
+#endif  // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+
 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
 static const CodecInfo kMpegHAudioCodecInfo1 = {
     "mhm1.*", CodecInfo::AUDIO, nullptr, CodecInfo::HISTOGRAM_MPEG_H_AUDIO};
@@ -285,6 +306,14 @@
                                                    &kEAC3CodecInfo2,
                                                    &kEAC3CodecInfo3,
 #endif  // BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+                                                   &kDTSCodecInfo1,
+                                                   &kDTSCodecInfo2,
+                                                   &kDTSCodecInfo3,
+                                                   &kDTSXCodecInfo1,
+                                                   &kDTSXCodecInfo2,
+                                                   &kDTSXCodecInfo3,
+#endif  // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
                                                    nullptr};
 
@@ -328,6 +357,16 @@
                base::MatchPattern(codec_id, kEAC3CodecInfo3.pattern)) {
       audio_object_types.insert(mp4::kEAC3);
 #endif  // BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+    } else if (base::MatchPattern(codec_id, kDTSCodecInfo1.pattern) ||
+               base::MatchPattern(codec_id, kDTSCodecInfo2.pattern) ||
+               base::MatchPattern(codec_id, kDTSCodecInfo3.pattern)) {
+      audio_object_types.insert(mp4::kDTS);
+    } else if (base::MatchPattern(codec_id, kDTSXCodecInfo1.pattern) ||
+               base::MatchPattern(codec_id, kDTSXCodecInfo2.pattern) ||
+               base::MatchPattern(codec_id, kDTSXCodecInfo3.pattern)) {
+      audio_object_types.insert(mp4::kDTSX);
+#endif  // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
     }
   }
diff --git a/media/formats/dts/dts_util.h b/media/formats/dts/dts_util.h
index 64e8f42f..c917ed2 100644
--- a/media/formats/dts/dts_util.h
+++ b/media/formats/dts/dts_util.h
@@ -8,7 +8,6 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "base/macros.h"
 #include "media/base/audio_codecs.h"
 #include "media/base/media_export.h"
 
diff --git a/media/formats/hls/items.cc b/media/formats/hls/items.cc
index eda3ed9..14e3cfd 100644
--- a/media/formats/hls/items.cc
+++ b/media/formats/hls/items.cc
@@ -37,6 +37,7 @@
       {"-X-I-FRAMES-ONLY", TagKind::kXIFramesOnly},
       {"-X-DISCONTINUITY", TagKind::kXDiscontinuity},
       {"-X-GAP", TagKind::kXGap},
+      {"-X-DEFINE:", TagKind::kXDefine},
   };
 
   for (const auto& tag : kTagKindPrefixes) {
diff --git a/media/formats/hls/items.h b/media/formats/hls/items.h
index 39c1e22..3dfb94ab 100644
--- a/media/formats/hls/items.h
+++ b/media/formats/hls/items.h
@@ -28,7 +28,8 @@
   kXIFramesOnly,
   kXDiscontinuity,
   kXGap,
-  kMaxValue = kXGap,
+  kXDefine,
+  kMaxValue = kXDefine,
 };
 
 // An item which has been determined to of a known or unknown tag type, but not
diff --git a/media/formats/hls/parse_status.h b/media/formats/hls/parse_status.h
index 8e67285..4140922 100644
--- a/media/formats/hls/parse_status.h
+++ b/media/formats/hls/parse_status.h
@@ -20,6 +20,7 @@
   kInvalidPlaylistVersion,
   kMalformedAttributeList,
   kAttributeListHasDuplicateNames,
+  kMalformedVariableName,
   kPlaylistMissingM3uTag,
   kMediaSegmentMissingInfTag,
 };
diff --git a/media/formats/hls/tags.cc b/media/formats/hls/tags.cc
index e4758804..c9bb4da 100644
--- a/media/formats/hls/tags.cc
+++ b/media/formats/hls/tags.cc
@@ -5,6 +5,9 @@
 #include "media/formats/hls/tags.h"
 
 #include <cstddef>
+#include <type_traits>
+#include <utility>
+#include "base/notreached.h"
 #include "media/formats/hls/parse_status.h"
 
 namespace media {
@@ -22,6 +25,110 @@
   return T{};
 }
 
+// Quoted strings in EXT-X-DEFINE tags are unique in that they aren't subject to
+// variable substitution. To simplify things, we define a special quoted-string
+// extraction function here.
+ParseStatus::Or<SourceString> ParseXDefineTagQuotedString(
+    SourceString source_str) {
+  if (source_str.Str().size() < 2) {
+    return ParseStatusCode::kMalformedTag;
+  }
+
+  if (*source_str.Str().begin() != '"') {
+    return ParseStatusCode::kMalformedTag;
+  }
+
+  if (*source_str.Str().rbegin() != '"') {
+    return ParseStatusCode::kMalformedTag;
+  }
+
+  return source_str.Substr(1, source_str.Str().size() - 2);
+}
+
+// Attributes expected in `EXT-X-DEFINE` tag contents.
+// These must remain sorted alphabetically.
+enum class XDefineTagAttribute {
+  kImport,
+  kName,
+  kValue,
+  kMaxValue = kValue,
+};
+
+constexpr base::StringPiece GetAttributeName(XDefineTagAttribute attribute) {
+  switch (attribute) {
+    case XDefineTagAttribute::kImport:
+      return "IMPORT";
+    case XDefineTagAttribute::kName:
+      return "NAME";
+    case XDefineTagAttribute::kValue:
+      return "VALUE";
+  }
+
+  NOTREACHED();
+  return "";
+}
+
+template <typename T, size_t kLast>
+constexpr bool IsAttributeEnumSorted(std::index_sequence<kLast>) {
+  return true;
+}
+
+template <typename T, size_t kLHS, size_t kRHS, size_t... kRest>
+constexpr bool IsAttributeEnumSorted(
+    std::index_sequence<kLHS, kRHS, kRest...>) {
+  const auto lhs = GetAttributeName(static_cast<T>(kLHS));
+  const auto rhs = GetAttributeName(static_cast<T>(kRHS));
+  return lhs < rhs &&
+         IsAttributeEnumSorted<T>(std::index_sequence<kRHS, kRest...>{});
+}
+
+// Wraps `AttributeMap::MakeStorage` by mapping the (compile-time) sequence
+// of size_t's to a sequence of the corresponding attribute enum names.
+template <typename T, std::size_t... Indices>
+constexpr std::array<types::AttributeMap::Item, sizeof...(Indices)>
+MakeTypedAttributeMapStorage(std::index_sequence<Indices...> seq) {
+  static_assert(IsAttributeEnumSorted<T>(seq),
+                "Enum keys must be sorted alphabetically");
+  return types::AttributeMap::MakeStorage(
+      GetAttributeName(static_cast<T>(Indices))...);
+}
+
+// Helper for using AttributeMap with an enum of keys.
+// The result of running `GetAttributeName` across `0..T::kMaxValue` (inclusive)
+// must produced an ordered set of strings.
+template <typename T>
+struct TypedAttributeMap {
+  static_assert(std::is_enum<T>::value, "T must be an enum");
+  static_assert(std::is_same<decltype(GetAttributeName(std::declval<T>())),
+                             base::StringPiece>::value,
+                "GetAttributeName must be overloaded for T to return a "
+                "base::StringPiece");
+  static constexpr size_t kNumKeys = static_cast<size_t>(T::kMaxValue) + 1;
+
+  TypedAttributeMap()
+      : attributes_(MakeTypedAttributeMapStorage<T>(
+            std::make_index_sequence<kNumKeys>())) {}
+
+  // Wraps `AttributeMap::FillUntilError` using the built-in storage object.
+  ParseStatus FillUntilError(types::AttributeListIterator* iter) {
+    types::AttributeMap map(attributes_);
+    return map.FillUntilError(iter);
+  }
+
+  // Returns whether the entry corresponding to the given key has a value.
+  bool HasValue(T key) const {
+    return attributes_[static_cast<size_t>(key)].second.has_value();
+  }
+
+  // Returns the value stored in the entry for the given key.
+  SourceString GetValue(T key) const {
+    return attributes_[static_cast<size_t>(key)].second.value();
+  }
+
+ private:
+  std::array<types::AttributeMap::Item, kNumKeys> attributes_;
+};
+
 }  // namespace
 
 ParseStatus::Or<M3uTag> M3uTag::Parse(TagItem tag) {
@@ -93,5 +200,74 @@
   return ParseEmptyTag<XGapTag>(tag);
 }
 
+XDefineTag XDefineTag::CreateDefinition(types::VariableName name,
+                                        base::StringPiece value) {
+  return XDefineTag{.name = name, .value = value};
+}
+
+XDefineTag XDefineTag::CreateImport(types::VariableName name) {
+  return XDefineTag{.name = name, .value = absl::nullopt};
+}
+
+ParseStatus::Or<XDefineTag> XDefineTag::Parse(TagItem tag) {
+  // Parse the attribute-list
+  TypedAttributeMap<XDefineTagAttribute> map;
+  types::AttributeListIterator iter(tag.content);
+  auto result = map.FillUntilError(&iter);
+
+  if (result.code() != ParseStatusCode::kReachedEOF) {
+    return ParseStatus(ParseStatusCode::kMalformedTag)
+        .AddCause(std::move(result));
+  }
+
+  // "NAME" and "IMPORT" are mutually exclusive
+  if (map.HasValue(XDefineTagAttribute::kName) &&
+      map.HasValue(XDefineTagAttribute::kImport)) {
+    return ParseStatusCode::kMalformedTag;
+  }
+
+  if (map.HasValue(XDefineTagAttribute::kName)) {
+    auto var_name =
+        ParseXDefineTagQuotedString(map.GetValue(XDefineTagAttribute::kName))
+            .MapValue(types::ParseVariableName);
+    if (var_name.has_error()) {
+      return ParseStatus(ParseStatusCode::kMalformedTag)
+          .AddCause(std::move(var_name).error());
+    }
+
+    // If "NAME" is defined, "VALUE" must also be defined
+    if (!map.HasValue(XDefineTagAttribute::kValue)) {
+      return ParseStatusCode::kMalformedTag;
+    }
+
+    auto value =
+        ParseXDefineTagQuotedString(map.GetValue(XDefineTagAttribute::kValue));
+    if (value.has_error()) {
+      return ParseStatus(ParseStatusCode::kMalformedTag);
+    }
+
+    return XDefineTag::CreateDefinition(std::move(var_name).value(),
+                                        std::move(value).value().Str());
+  }
+
+  if (map.HasValue(XDefineTagAttribute::kImport)) {
+    auto var_name =
+        ParseXDefineTagQuotedString(map.GetValue(XDefineTagAttribute::kImport))
+            .MapValue(types::ParseVariableName);
+    if (var_name.has_error()) {
+      return ParseStatus(ParseStatusCode::kMalformedTag)
+          .AddCause(std::move(var_name).error());
+    }
+
+    // "VALUE" doesn't make any sense here, but the spec doesn't explicitly
+    // forbid it. It may be used in the future to provide a default value for
+    // undefined imported variables, so we won't error on it.
+    return XDefineTag::CreateImport(std::move(var_name).value());
+  }
+
+  // Without "NAME" or "IMPORT", the tag is malformed
+  return ParseStatusCode::kMalformedTag;
+}
+
 }  // namespace hls
 }  // namespace media
diff --git a/media/formats/hls/tags.h b/media/formats/hls/tags.h
index 10c69c2..537ced69e 100644
--- a/media/formats/hls/tags.h
+++ b/media/formats/hls/tags.h
@@ -9,6 +9,7 @@
 #include "media/formats/hls/items.h"
 #include "media/formats/hls/parse_status.h"
 #include "media/formats/hls/types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace media {
 namespace hls {
@@ -69,6 +70,26 @@
   static MEDIA_EXPORT ParseStatus::Or<XGapTag> Parse(TagItem);
 };
 
+// Represents the contents of the #EXT-X-DEFINE tag
+struct XDefineTag {
+  static constexpr TagKind kKind = TagKind::kXDefine;
+  static MEDIA_EXPORT ParseStatus::Or<XDefineTag> Parse(TagItem);
+
+  // Constructs an XDefineTag representing a variable definition.
+  static MEDIA_EXPORT XDefineTag CreateDefinition(types::VariableName name,
+                                                  base::StringPiece value);
+
+  // Constructs an XDefineTag representing an imported variable definition.
+  static MEDIA_EXPORT XDefineTag CreateImport(types::VariableName name);
+
+  // The name of the variable being defined.
+  types::VariableName name;
+
+  // The value of the variable. If this is `nullopt`, then the value
+  // is being IMPORT-ed and must be defined in the parent playlist.
+  absl::optional<base::StringPiece> value;
+};
+
 }  // namespace hls
 }  // namespace media
 
diff --git a/media/formats/hls/tags_unittest.cc b/media/formats/hls/tags_unittest.cc
index b1ee53c..e9602fce 100644
--- a/media/formats/hls/tags_unittest.cc
+++ b/media/formats/hls/tags_unittest.cc
@@ -170,5 +170,61 @@
   RunEmptyTagTest<XGapTag>();
 }
 
+TEST(HlsFormatParserTest, ParseXDefineTagTest) {
+  RunTagIdenficationTest<XDefineTag>(
+      "#EXT-X-DEFINE:NAME=\"FOO\",VALUE=\"Bar\",\n",
+      "NAME=\"FOO\",VALUE=\"Bar\",");
+
+  // Test some valid inputs
+  auto tag = OkTest<XDefineTag>(R"(NAME="Foo",VALUE="bar",)");
+  EXPECT_EQ(tag.name.name, "Foo");
+  EXPECT_TRUE(tag.value.has_value());
+  EXPECT_EQ(tag.value.value(), "bar");
+
+  tag = OkTest<XDefineTag>(R"(VALUE="90/12#%)(zx./",NAME="Hello12_-")");
+  EXPECT_EQ(tag.name.name, "Hello12_-");
+  EXPECT_TRUE(tag.value.has_value());
+  EXPECT_EQ(tag.value.value(), "90/12#%)(zx./");
+
+  tag = OkTest<XDefineTag>(R"(IMPORT="-F90_Baz")");
+  EXPECT_EQ(tag.name.name, "-F90_Baz");
+  EXPECT_FALSE(tag.value.has_value());
+
+  // IMPORT and VALUE are not currently considered an error
+  tag = OkTest<XDefineTag>(R"(IMPORT="F00_Bar",VALUE="Test")");
+  EXPECT_EQ(tag.name.name, "F00_Bar");
+  EXPECT_FALSE(tag.value.has_value());
+
+  // NAME with empty value is allowed
+  tag = OkTest<XDefineTag>(R"(NAME="HELLO",VALUE="")");
+  EXPECT_EQ(tag.name.name, "HELLO");
+  EXPECT_TRUE(tag.value.has_value());
+  EXPECT_EQ(tag.value.value(), "");
+
+  // Empty content is not allowed
+  ErrorTest<XDefineTag>("", ParseStatusCode::kMalformedTag);
+
+  // NAME and IMPORT are NOT allowed
+  ErrorTest<XDefineTag>(R"(NAME="Foo",IMPORT="Foo")",
+                        ParseStatusCode::kMalformedTag);
+
+  // Name without VALUE is NOT allowed
+  ErrorTest<XDefineTag>(R"(NAME="Foo",)", ParseStatusCode::kMalformedTag);
+
+  // Empty NAME is not allowed
+  ErrorTest<XDefineTag>(R"(NAME="",VALUE="Foo")",
+                        ParseStatusCode::kMalformedTag);
+
+  // Non-valid NAME is not allowed
+  ErrorTest<XDefineTag>(R"(NAME=".FOO",VALUE="Foo")",
+                        ParseStatusCode::kMalformedTag);
+  ErrorTest<XDefineTag>(R"(NAME="F++OO",VALUE="Foo")",
+                        ParseStatusCode::kMalformedTag);
+  ErrorTest<XDefineTag>(R"(NAME=" FOO",VALUE="Foo")",
+                        ParseStatusCode::kMalformedTag);
+  ErrorTest<XDefineTag>(R"(NAME="FOO ",VALUE="Foo")",
+                        ParseStatusCode::kMalformedTag);
+}
+
 }  // namespace hls
 }  // namespace media
diff --git a/media/formats/hls/types.cc b/media/formats/hls/types.cc
index 960d04c..abb33022 100644
--- a/media/formats/hls/types.cc
+++ b/media/formats/hls/types.cc
@@ -21,6 +21,10 @@
   return re2::StringPiece(str.data(), str.size());
 }
 
+re2::StringPiece to_re2(SourceString str) {
+  return to_re2(str.Str());
+}
+
 // Returns the substring matching a valid AttributeName, advancing `source_str`
 // to the following character. If no such substring exists, returns
 // `absl::nullopt` and leaves `source_str` untouched. This is like matching the
@@ -307,6 +311,18 @@
   }
 }
 
+ParseStatus::Or<VariableName> ParseVariableName(SourceString source_str) {
+  static const base::NoDestructor<re2::RE2> variable_name_regex(
+      "[a-zA-Z0-9_-]+");
+
+  // This source_str must match completely
+  if (!re2::RE2::FullMatch(to_re2(source_str), *variable_name_regex)) {
+    return ParseStatusCode::kMalformedVariableName;
+  }
+
+  return VariableName{.name = source_str.Str()};
+}
+
 }  // namespace types
 }  // namespace hls
 }  // namespace media
diff --git a/media/formats/hls/types.h b/media/formats/hls/types.h
index 3ca99e9..292ae2b 100644
--- a/media/formats/hls/types.h
+++ b/media/formats/hls/types.h
@@ -91,7 +91,7 @@
   // Helper for creating backing storage for an AttributeMap on the stack.
   // `keys` must be a set of unique key strings sorted in alphabetical order.
   template <typename... T>
-  static std::array<Item, sizeof...(T)> MakeStorage(T... keys) {
+  static constexpr std::array<Item, sizeof...(T)> MakeStorage(T... keys) {
     return {{{keys, absl::nullopt}...}};
   }
 
@@ -99,6 +99,15 @@
   base::span<Item> items_;
 };
 
+// Represents a string that is guaranteed to be a non-empty, and consisting only
+// of characters in the set {[a-z], [A-Z], [0-9], _, -}.
+struct VariableName {
+  base::StringPiece name;
+};
+
+ParseStatus::Or<VariableName> MEDIA_EXPORT
+ParseVariableName(SourceString source_str);
+
 }  // namespace types
 }  // namespace hls
 }  // namespace media
diff --git a/media/formats/hls/types_unittest.cc b/media/formats/hls/types_unittest.cc
index 96f4d5f..901bdfe 100644
--- a/media/formats/hls/types_unittest.cc
+++ b/media/formats/hls/types_unittest.cc
@@ -408,5 +408,48 @@
   }
 }
 
+TEST(HlsFormatParserTest, ParseVariableNameTest) {
+  auto const ok_test = [](base::StringPiece input,
+                          const base::Location& from =
+                              base::Location::Current()) {
+    auto result =
+        types::ParseVariableName(SourceString::CreateForTesting(input));
+    ASSERT_TRUE(result.has_value()) << from.ToString();
+    EXPECT_EQ(std::move(result).value().name, input);
+  };
+
+  auto const error_test = [](base::StringPiece input,
+                             const base::Location& from =
+                                 base::Location::Current()) {
+    auto result =
+        types::ParseVariableName(SourceString::CreateForTesting(input));
+    ASSERT_TRUE(result.has_error()) << from.ToString();
+    EXPECT_EQ(std::move(result).error().code(),
+              ParseStatusCode::kMalformedVariableName);
+  };
+
+  // Variable names may not be empty
+  error_test("");
+
+  // Variable names may not have whitespace
+  error_test(" Hello");
+  error_test("He llo");
+  error_test("Hello ");
+
+  // Variable names may not have characters outside the allowed set
+  error_test("He*llo");
+  error_test("!Hello");
+  error_test("He$o");
+  error_test("He=o");
+
+  // Test some valid variable names
+  ok_test("Hello");
+  ok_test("HE-LLO");
+  ok_test("__H3LL0__");
+  ok_test("12345");
+  ok_test("-1_2-3_4-5_");
+  ok_test("______-___-__---");
+}
+
 }  // namespace hls
 }  // namespace media
diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc
index 069f22b..1bf9717 100644
--- a/media/formats/mp4/box_definitions.cc
+++ b/media/formats/mp4/box_definitions.cc
@@ -1438,6 +1438,49 @@
   return true;
 }
 
+#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+DtsSpecificBox::DtsSpecificBox() {}
+
+DtsSpecificBox::DtsSpecificBox(const DtsSpecificBox& other) = default;
+
+DtsSpecificBox::~DtsSpecificBox() = default;
+
+FourCC DtsSpecificBox::BoxType() const {
+  return FOURCC_DDTS;
+}
+
+bool DtsSpecificBox::Parse(BoxReader* reader) {
+  // Read ddts into buffer.
+  std::vector<uint8_t> dts_data;
+
+  RCHECK(reader->ReadVec(&dts_data, reader->box_size() - reader->pos()));
+  RCHECK(dts.Parse(dts_data, reader->media_log()));
+
+  return true;
+}
+
+DtsUhdSpecificBox::DtsUhdSpecificBox() {}
+
+DtsUhdSpecificBox::DtsUhdSpecificBox(const DtsUhdSpecificBox& other) = default;
+
+DtsUhdSpecificBox::~DtsUhdSpecificBox() = default;
+
+FourCC DtsUhdSpecificBox::BoxType() const {
+  return FOURCC_UDTS;
+}
+
+bool DtsUhdSpecificBox::Parse(BoxReader* reader) {
+  // Read udts into buffer.
+  std::vector<uint8_t> dtsx_data;
+
+  RCHECK(reader->ReadVec(&dtsx_data, reader->box_size() - reader->pos()));
+  RCHECK(dtsx.Parse(dtsx_data, reader->media_log()));
+
+  return true;
+}
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS) &&
+        // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+
 AudioSampleEntry::AudioSampleEntry()
     : format(FOURCC_NULL),
       data_reference_index(0),
@@ -1489,6 +1532,17 @@
                         "OpusSpecificBox STREAMINFO channel count");
   }
 
+#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+  if (format == FOURCC_DTSC) {
+    RCHECK_MEDIA_LOGGED(reader->ReadChild(&ddts), reader->media_log(),
+                        "Failure parsing DtsSpecificBox (ddts)");
+  } else if (format == FOURCC_DTSX) {
+    RCHECK_MEDIA_LOGGED(reader->ReadChild(&udts), reader->media_log(),
+                        "Failure parsing DtsUhdSpecificBox (udts)");
+  }
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS) &&
+        // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+
   // Read the FLACSpecificBox, even if CENC is signalled.
   if (format == FOURCC_FLAC ||
       (format == FOURCC_ENCA && sinf.format.format == FOURCC_FLAC)) {
diff --git a/media/formats/mp4/box_definitions.h b/media/formats/mp4/box_definitions.h
index 5a307f0..336a74d 100644
--- a/media/formats/mp4/box_definitions.h
+++ b/media/formats/mp4/box_definitions.h
@@ -19,6 +19,8 @@
 #include "media/formats/mp4/aac.h"
 #include "media/formats/mp4/avc.h"
 #include "media/formats/mp4/box_reader.h"
+#include "media/formats/mp4/dts.h"
+#include "media/formats/mp4/dtsx.h"
 #include "media/formats/mp4/fourccs.h"
 #include "media/media_buildflags.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -378,6 +380,19 @@
   uint32_t sample_rate;
 };
 
+#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+struct MEDIA_EXPORT DtsSpecificBox : Box {
+  DECLARE_BOX_METHODS(DtsSpecificBox);
+  DTS dts;
+};
+
+struct MEDIA_EXPORT DtsUhdSpecificBox : Box {
+  DECLARE_BOX_METHODS(DtsUhdSpecificBox);
+  DTSX dtsx;
+};
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS) &&
+        // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+
 struct MEDIA_EXPORT AudioSampleEntry : Box {
   DECLARE_BOX_METHODS(AudioSampleEntry);
 
@@ -391,6 +406,11 @@
   ElementaryStreamDescriptor esds;
   FlacSpecificBox dfla;
   OpusSpecificBox dops;
+#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+  DtsSpecificBox ddts;
+  DtsUhdSpecificBox udts;
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS) &&
+        // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
 };
 
 struct MEDIA_EXPORT SampleDescription : Box {
diff --git a/media/formats/mp4/es_descriptor.h b/media/formats/mp4/es_descriptor.h
index 90662914..6f546d7 100644
--- a/media/formats/mp4/es_descriptor.h
+++ b/media/formats/mp4/es_descriptor.h
@@ -24,7 +24,9 @@
   kISO_14496_3 = 0x40,         // MPEG4 AAC
   kISO_13818_7_AAC_LC = 0x67,  // MPEG2 AAC-LC
   kAC3 = 0xa5,                 // AC3
-  kEAC3 = 0xa6                 // EAC3 / Dolby Digital Plus
+  kEAC3 = 0xa6,                // EAC3 / Dolby Digital Plus
+  kDTS = 0xa9,                 // DTS
+  kDTSX = 0xb2                 // DTS:X
 };
 
 // This class parse object type and decoder specific information from an
diff --git a/media/formats/mp4/fourccs.h b/media/formats/mp4/fourccs.h
index 41b85ce5..bba3cd0 100644
--- a/media/formats/mp4/fourccs.h
+++ b/media/formats/mp4/fourccs.h
@@ -133,6 +133,13 @@
   FOURCC_VP09 = 0x76703039,
   FOURCC_VPCC = 0x76706343,
   FOURCC_WIDE = 0x77696465,
+#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+  FOURCC_DTSC = 0x64747363,  // "dtsc"
+  FOURCC_DTSX = 0x64747378,  // "dtsx"
+  FOURCC_DDTS = 0x64647473,  // "ddts"
+  FOURCC_UDTS = 0x75647473,  // "udts"
+#endif                       // BUILDFLAG(USE_PROPRIETARY_CODECS) &&
+                             // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
 };
 
 const inline std::string FourCCToString(FourCC fourcc) {
diff --git a/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.cc b/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.cc
index 3b463a2..ae3750b 100644
--- a/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.cc
+++ b/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.cc
@@ -125,10 +125,14 @@
         }
         new_active_pps_id = pps->pic_parameter_set_id;
         new_active_sps_id = sps->seq_parameter_set_id;
-        if (new_active_sps_id != active_sps_id_ ||
-            new_active_pps_id != active_pps_id_) {
-          pps_to_include.insert(new_active_pps_id);
-          sps_to_include.insert(new_active_sps_id);
+        pps_to_include.insert(new_active_pps_id);
+        sps_to_include.insert(new_active_sps_id);
+
+        if (new_active_sps_id != active_sps_id_) {
+          if (!config_changed) {
+            DCHECK(nalu.nal_unit_type == H264NALU::kIDRSlice)
+                << "SPS shouldn't change in non-IDR slice";
+          }
           config_changed = true;
         }
       }
diff --git a/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter_unittest.cc b/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter_unittest.cc
index 82c9c648..d04b9d2 100644
--- a/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter_unittest.cc
+++ b/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter_unittest.cc
@@ -80,6 +80,50 @@
   }
 }
 
+// Tests that stream can contain multiple picture parameter sets and switch
+// between them without having to reconfigure the decoder.
+TEST(H264AnnexBToAvcBitstreamConverterTest, PPS_SwitchWithoutReconfig) {
+  std::vector<uint8_t> sps{0x00, 0x00, 0x00, 0x01, 0x27, 0x42, 0x00, 0x1E,
+                           0x89, 0x8A, 0x12, 0x05, 0x01, 0x7F, 0xCA, 0x80};
+  std::vector<uint8_t> pps1{0x00, 0x00, 0x00, 0x01, 0x28, 0xce, 0x3c, 0x80};
+  std::vector<uint8_t> pps2{0x00, 0x00, 0x00, 0x01, 0x28, 0x53, 0x8f, 0x20};
+  std::vector<uint8_t> pps3{0x00, 0x00, 0x00, 0x01, 0x28, 0x73, 0x8F, 0x20};
+  std::vector<uint8_t> first_frame_idr{
+      0x00, 0x00, 0x00, 0x01, 0x25, 0xb4, 0x00, 0x10, 0x00, 0x24, 0xff,
+      0xff, 0xf8, 0x7a, 0x28, 0x00, 0x08, 0x0a, 0x7b, 0xdd
+      // Encoded data omitted here, it's not important for NALU parsing
+  };
+
+  std::vector<uint8_t> first_chunk;
+  first_chunk.insert(first_chunk.end(), sps.begin(), sps.end());
+  first_chunk.insert(first_chunk.end(), pps1.begin(), pps1.end());
+  first_chunk.insert(first_chunk.end(), pps2.begin(), pps2.end());
+  first_chunk.insert(first_chunk.end(), pps3.begin(), pps3.end());
+  first_chunk.insert(first_chunk.end(), first_frame_idr.begin(),
+                     first_frame_idr.end());
+
+  std::vector<uint8_t> second_non_idr_chunk{
+      0x00, 0x00, 0x00, 0x01, 0x21, 0xd8, 0x00, 0x80, 0x04,
+      0x95, 0x9d, 0x45, 0x70, 0xd9, 0xbe, 0x21, 0xff, 0x87,
+      0x20, 0x03, 0x9c, 0x66, 0x84, 0xe1
+      // Encoded data omitted here, it's not important for NALU parsing
+  };
+
+  H264AnnexBToAvcBitstreamConverter converter;
+  std::vector<uint8_t> output(10000);
+  bool config_changed = false;
+
+  auto status =
+      converter.ConvertChunk(first_chunk, output, &config_changed, nullptr);
+  EXPECT_TRUE(status.is_ok()) << status.message();
+  EXPECT_TRUE(config_changed);
+
+  status = converter.ConvertChunk(second_non_idr_chunk, output, &config_changed,
+                                  nullptr);
+  EXPECT_TRUE(status.is_ok()) << status.message();
+  EXPECT_FALSE(config_changed);
+}
+
 TEST(H264AnnexBToAvcBitstreamConverterTest, Failure) {
   H264AnnexBToAvcBitstreamConverter converter;
 
diff --git a/media/formats/mp4/mp4_stream_parser.cc b/media/formats/mp4/mp4_stream_parser.cc
index 827f6804..3bb9f6e 100644
--- a/media/formats/mp4/mp4_stream_parser.cc
+++ b/media/formats/mp4/mp4_stream_parser.cc
@@ -335,6 +335,10 @@
 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
           audio_format != FOURCC_AC3 && audio_format != FOURCC_EAC3 &&
 #endif
+#if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+          audio_format != FOURCC_DTSC && audio_format != FOURCC_DTSX &&
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS) &&
+        // BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
           audio_format != FOURCC_MHM1 && audio_format != FOURCC_MHA1 &&
 #endif
@@ -396,6 +400,14 @@
             audio_type = kEAC3;
         }
 #endif
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+        if (audio_type == kForbidden) {
+          if (audio_format == FOURCC_DTSC)
+            audio_type = kDTS;
+          if (audio_format == FOURCC_DTSX)
+            audio_type = kDTSX;
+        }
+#endif
         DVLOG(1) << "audio_type 0x" << std::hex << static_cast<int>(audio_type);
         if (audio_object_types_.find(audio_type) == audio_object_types_.end()) {
           MEDIA_LOG(ERROR, media_log_)
@@ -430,6 +442,16 @@
           channel_layout = GuessChannelLayout(entry.channelcount);
           sample_per_second = entry.samplerate;
 #endif
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+        } else if (audio_type == kDTS) {
+          codec = AudioCodec::kDTS;
+          channel_layout = GuessChannelLayout(entry.channelcount);
+          sample_per_second = entry.samplerate;
+        } else if (audio_type == kDTSX) {
+          codec = AudioCodec::kDTSXP2;
+          channel_layout = GuessChannelLayout(entry.channelcount);
+          sample_per_second = entry.samplerate;
+#endif
         } else {
           MEDIA_LOG(ERROR, media_log_)
               << "Unsupported audio object type 0x" << std::hex
diff --git a/media/gpu/test/video_encoder/decoder_buffer_validator.cc b/media/gpu/test/video_encoder/decoder_buffer_validator.cc
index 57b5994..c25aa4b7 100644
--- a/media/gpu/test/video_encoder/decoder_buffer_validator.cc
+++ b/media/gpu/test/video_encoder/decoder_buffer_validator.cc
@@ -42,8 +42,9 @@
 }
 }  // namespace
 
-DecoderBufferValidator::DecoderBufferValidator(const gfx::Rect& visible_rect)
-    : visible_rect_(visible_rect) {}
+DecoderBufferValidator::DecoderBufferValidator(const gfx::Rect& visible_rect,
+                                               size_t num_temporal_layers)
+    : visible_rect_(visible_rect), num_temporal_layers_(num_temporal_layers) {}
 
 DecoderBufferValidator::~DecoderBufferValidator() = default;
 
@@ -62,11 +63,10 @@
                              const gfx::Rect& visible_rect,
                              size_t num_temporal_layers,
                              absl::optional<uint8_t> level)
-    : DecoderBufferValidator(visible_rect),
+    : DecoderBufferValidator(visible_rect, num_temporal_layers),
       cur_pic_(new H264Picture),
       profile_(VideoCodecProfileToH264ProfileIDC(profile)),
-      level_(level),
-      num_temporal_layers_(num_temporal_layers) {}
+      level_(level) {}
 
 H264Validator::~H264Validator() = default;
 
@@ -246,8 +246,9 @@
   return true;
 }
 
-VP8Validator::VP8Validator(const gfx::Rect& visible_rect)
-    : DecoderBufferValidator(visible_rect) {}
+VP8Validator::VP8Validator(const gfx::Rect& visible_rect,
+                           size_t num_temporal_layers)
+    : DecoderBufferValidator(visible_rect, num_temporal_layers) {}
 
 VP8Validator::~VP8Validator() = default;
 
@@ -263,6 +264,11 @@
     return false;
   }
 
+  if (!header.show_frame) {
+    LOG(ERROR) << "|show_frame| should be always true";
+    return false;
+  }
+
   if (header.IsKeyframe()) {
     seen_keyframe_ = true;
     if (gfx::Rect(header.width, header.height) != visible_rect_) {
@@ -273,19 +279,87 @@
     }
   }
 
-  return seen_keyframe_ && header.show_frame;
+  if (!seen_keyframe_) {
+    LOG(ERROR) << "Bitstream cannot start with a delta frame";
+    return false;
+  }
+
+  if (num_temporal_layers_ == 1)
+    return true;
+
+  if (!metadata.vp8) {
+    LOG(ERROR) << "Metadata must be populated if temporal scalability is used.";
+    return false;
+  }
+
+  const uint8_t temporal_idx = metadata.vp8->temporal_idx;
+  if (temporal_idx >= num_temporal_layers_) {
+    LOG(ERROR) << "Invalid temporal id: "
+               << base::strict_cast<int>(temporal_idx);
+    return false;
+  }
+
+  if (header.IsKeyframe()) {
+    if (temporal_idx != 0) {
+      LOG(ERROR) << "Temporal id must be 0 on keyframe";
+      return false;
+    }
+    return true;
+  }
+
+  if (header.copy_buffer_to_golden != Vp8FrameHeader::NO_GOLDEN_REFRESH ||
+      header.copy_buffer_to_alternate != Vp8FrameHeader::NO_ALT_REFRESH) {
+    LOG(ERROR) << "Each reference frame is either updated by the current "
+               << "frame or unchanged in temporal layer encoding.";
+    return false;
+  }
+
+  const bool update_reference = header.refresh_last ||
+                                header.refresh_golden_frame ||
+                                header.refresh_alternate_frame;
+  if (metadata.vp8->non_reference != !update_reference) {
+    LOG(ERROR) << "|non_reference| must be true iff the frame does not update"
+               << "any reference buffer.";
+    return false;
+  }
+
+  if (num_temporal_layers_ == temporal_idx + 1) {
+    if (update_reference) {
+      LOG(ERROR) << "The frame in top temporal layer must not update "
+                    "reference frame.";
+      return false;
+    }
+  } else {
+    // TL0 can update last frame only and TL1 can update golden frame only when
+    // it is not top temporal layer.
+    if (temporal_idx == 0) {
+      if (!header.refresh_last || header.refresh_golden_frame ||
+          header.refresh_alternate_frame) {
+        LOG(ERROR) << "|refresh_last| only must be set on temporal layer 0";
+        return false;
+      }
+    } else if (temporal_idx == 1) {
+      if (header.refresh_last || !header.refresh_golden_frame ||
+          header.refresh_alternate_frame) {
+        LOG(ERROR) << "|refresh_golden_frame| only must be set on temporal "
+                   << "layer 1";
+        return false;
+      }
+    }
+  }
+
+  return true;
 }
 
 VP9Validator::VP9Validator(VideoCodecProfile profile,
                            const gfx::Rect& visible_rect,
                            size_t max_num_spatial_layers,
                            size_t num_temporal_layers)
-    : DecoderBufferValidator(visible_rect),
+    : DecoderBufferValidator(visible_rect, num_temporal_layers),
       parser_(/*parsing_compressed_header=*/false),
       profile_(VideoCodecProfileToVP9Profile(profile)),
       max_num_spatial_layers_(max_num_spatial_layers),
       cur_num_spatial_layers_(max_num_spatial_layers_),
-      num_temporal_layers_(num_temporal_layers),
       next_picture_id_(0) {}
 
 VP9Validator::~VP9Validator() = default;
diff --git a/media/gpu/test/video_encoder/decoder_buffer_validator.h b/media/gpu/test/video_encoder/decoder_buffer_validator.h
index 625065bd..933a351 100644
--- a/media/gpu/test/video_encoder/decoder_buffer_validator.h
+++ b/media/gpu/test/video_encoder/decoder_buffer_validator.h
@@ -22,7 +22,8 @@
 namespace test {
 class DecoderBufferValidator : public BitstreamProcessor {
  public:
-  explicit DecoderBufferValidator(const gfx::Rect& visible_rect);
+  DecoderBufferValidator(const gfx::Rect& visible_rect,
+                         size_t num_temporal_layers);
   ~DecoderBufferValidator() override;
 
   // BitstreamProcessor implementation.
@@ -37,6 +38,8 @@
 
   // The expected visible rectangle that |decoder_buffer| has.
   const gfx::Rect visible_rect_;
+  // The number of temporal layers.
+  const size_t num_temporal_layers_;
 
  private:
   // The number of detected errors by Validate().
@@ -86,7 +89,7 @@
 
 class VP8Validator : public DecoderBufferValidator {
  public:
-  explicit VP8Validator(const gfx::Rect& visible_rect);
+  VP8Validator(const gfx::Rect& visible_rect, size_t num_temporal_layers);
   ~VP8Validator() override;
 
  private:
@@ -124,7 +127,6 @@
   const size_t max_num_spatial_layers_;
   size_t cur_num_spatial_layers_;
   std::vector<gfx::Size> spatial_layer_resolutions_;
-  const size_t num_temporal_layers_;
   int next_picture_id_;
 
   // An optional state for each specified VP9 reference buffer.
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
index 403db214..675d8a1 100644
--- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -288,22 +288,24 @@
     if (supports_requests_) {
       decoder_ = std::make_unique<H264Decoder>(
           std::make_unique<V4L2VideoDecoderDelegateH264>(this, device_.get()),
-          video_profile_);
+          video_profile_, config.container_color_space);
     } else {
       decoder_ = std::make_unique<H264Decoder>(
           std::make_unique<V4L2VideoDecoderDelegateH264Legacy>(this,
                                                                device_.get()),
-          video_profile_);
+          video_profile_, config.container_color_space);
     }
   } else if (video_profile_ >= VP8PROFILE_MIN &&
              video_profile_ <= VP8PROFILE_MAX) {
     if (supports_requests_) {
       decoder_ = std::make_unique<VP8Decoder>(
-          std::make_unique<V4L2VideoDecoderDelegateVP8>(this, device_.get()));
+          std::make_unique<V4L2VideoDecoderDelegateVP8>(this, device_.get()),
+          config.container_color_space);
     } else {
       decoder_ = std::make_unique<VP8Decoder>(
           std::make_unique<V4L2VideoDecoderDelegateVP8Legacy>(this,
-                                                              device_.get()));
+                                                              device_.get()),
+          config.container_color_space);
     }
   } else if (video_profile_ >= VP9PROFILE_MIN &&
              video_profile_ <= VP9PROFILE_MAX) {
@@ -311,12 +313,12 @@
       decoder_ = std::make_unique<VP9Decoder>(
           std::make_unique<V4L2VideoDecoderDelegateVP9Chromium>(this,
                                                                 device_.get()),
-          video_profile_);
+          video_profile_, config.container_color_space);
     } else {
       decoder_ = std::make_unique<VP9Decoder>(
           std::make_unique<V4L2VideoDecoderDelegateVP9Legacy>(this,
                                                               device_.get()),
-          video_profile_);
+          video_profile_, config.container_color_space);
     }
   } else {
     NOTREACHED() << "Unsupported profile " << GetProfileName(video_profile_);
@@ -1981,11 +1983,12 @@
     scoped_refptr<V4L2DecodeSurface> dec_surface,
     int32_t bitstream_id,
     const gfx::Rect& visible_rect,
-    const VideoColorSpace& /* color_space */) {
+    const VideoColorSpace& color_space) {
   DVLOGF(4);
   DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
 
   dec_surface->SetVisibleRect(visible_rect);
+  dec_surface->SetColorSpace(color_space);
   decoder_display_queue_.push(std::make_pair(bitstream_id, dec_surface));
   TryOutputSurfaces();
 }
@@ -2032,10 +2035,9 @@
   DCHECK_NE(output_record.picture_id, -1);
   ++output_record.num_times_sent_to_client;
 
-  // TODO(hubbe): Insert correct color space. http://crbug.com/647725
-  Picture picture(output_record.picture_id, bitstream_id,
-                  dec_surface->visible_rect(), gfx::ColorSpace(),
-                  true /* allow_overlay */);
+  Picture picture(
+      output_record.picture_id, bitstream_id, dec_surface->visible_rect(),
+      dec_surface->color_space().ToGfxColorSpace(), true /* allow_overlay */);
   DVLOGF(4) << dec_surface->ToString()
             << ", bitstream_id: " << picture.bitstream_buffer_id()
             << ", picture_id: " << picture.picture_buffer_id()
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
index 059ffe04..06fda6d6 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -268,6 +268,8 @@
   if (!config_result)
     return;
 
+  container_color_space_ = config.container_color_space;
+
   frame_splitter_ =
       v4l2_vda_helpers::InputBufferFragmentSplitter::CreateFromProfile(
           config.profile);
@@ -2541,9 +2543,10 @@
   buffers_at_client_.emplace(
       output_record.picture_id,
       std::make_pair(std::move(vda_buffer), std::move(frame)));
-  // TODO(hubbe): Insert correct color space. http://crbug.com/647725
+  // TODO(b/214190092): Get color space from the v4l2 buffer.
   const Picture picture(output_record.picture_id, bitstream_buffer_id,
-                        gfx::Rect(visible_size_), gfx::ColorSpace(), false);
+                        gfx::Rect(visible_size_),
+                        container_color_space_.ToGfxColorSpace(), false);
   pending_picture_ready_.emplace(output_record.cleared, picture);
   SendPictureReady();
   // This picture will be cleared next time we see it.
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
index 24bf356..1639071 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.h
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
@@ -534,6 +534,9 @@
   // workaround is necessary for the V4L2VideoDecodeAccelerator.
   std::vector<std::unique_ptr<V4L2StatefulWorkaround>> workarounds_;
 
+  // Color space passed in from Initialize().
+  VideoColorSpace container_color_space_;
+
   //
   // Hardware state and associated queues.  Since decoder_thread_ services
   // the hardware, decoder_thread_ owns these too.
diff --git a/media/gpu/vaapi/vaapi_unittest.cc b/media/gpu/vaapi/vaapi_unittest.cc
index b03cd32..d8e362f 100644
--- a/media/gpu/vaapi/vaapi_unittest.cc
+++ b/media/gpu/vaapi/vaapi_unittest.cc
@@ -458,14 +458,7 @@
 }
 
 // This test checks the supported SVC scalability mode.
-#if BUILDFLAG(IS_CHROMEOS)
-#define MAYBE_CheckSupportedSVCScalabilityModes \
-  DISABLED_CheckSupportedSVCScalabilityModes
-#else
-#define MAYBE_CheckSupportedSVCScalabilityModes \
-  CheckSupportedSVCScalabilityModes
-#endif
-TEST_F(VaapiTest, MAYBE_CheckSupportedSVCScalabilityModes) {
+TEST_F(VaapiTest, CheckSupportedSVCScalabilityModes) {
 #if BUILDFLAG(IS_CHROMEOS)
   const std::vector<SVCScalabilityMode> kSupportedTemporalSVC = {
       SVCScalabilityMode::kL1T2, SVCScalabilityMode::kL1T3};
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc
index c1d385ff..844df94 100644
--- a/media/gpu/vaapi/vaapi_wrapper.cc
+++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -13,6 +13,7 @@
 #include <va/va_drmcommon.h>
 #include <va/va_str.h>
 #include <va/va_version.h>
+#include <xf86drm.h>
 
 #include <algorithm>
 #include <string>
@@ -37,6 +38,7 @@
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/pattern.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "base/system/sys_info.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
@@ -553,12 +555,30 @@
 
 // static
 void VADisplayState::PreSandboxInitialization() {
-  const char kDriRenderNode0Path[] = "/dev/dri/renderD128";
-  base::File drm_file = base::File(
-      base::FilePath::FromUTF8Unsafe(kDriRenderNode0Path),
-      base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE);
-  if (drm_file.IsValid())
+  constexpr char kRenderNodeFilePattern[] = "/dev/dri/renderD%d";
+  // This loop ends on either the first card that does not exist or the first
+  // render node that is not vgem.
+  for (int i = 128;; i++) {
+    base::FilePath dev_path(FILE_PATH_LITERAL(
+        base::StringPrintf(kRenderNodeFilePattern, i).c_str()));
+    base::File drm_file =
+        base::File(dev_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
+                                 base::File::FLAG_WRITE);
+    if (!drm_file.IsValid())
+      return;
+    // Skip the virtual graphics memory manager device.
+    drmVersionPtr version = drmGetVersion(drm_file.GetPlatformFile());
+    if (!version)
+      continue;
+    std::string version_name(
+        version->name,
+        base::checked_cast<std::string::size_type>(version->name_len));
+    drmFreeVersion(version);
+    if (base::LowerCaseEqualsASCII(version_name, "vgem"))
+      continue;
     VADisplayState::Get()->SetDrmFd(drm_file.GetPlatformFile());
+    return;
+  }
 }
 
 VADisplayState::VADisplayState()
@@ -2199,7 +2219,7 @@
     VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateSurfaces_Importing,
                          nullptr);
   }
-  DVLOG(2) << __func__ << " " << va_surface_id;
+  DVLOG(3) << __func__ << " " << va_surface_id;
   // VASurface shares an ownership of the buffer referred by the passed file
   // descriptor. We can release |pixmap| here.
   return new VASurface(va_surface_id, size, va_format,
@@ -3221,7 +3241,7 @@
         sequence_checker_.CalledOnValidSequence());
   if (va_surface_id == VA_INVALID_SURFACE)
     return;
-  DVLOG(2) << __func__ << " " << va_surface_id;
+  DVLOG(3) << __func__ << " " << va_surface_id;
   base::AutoLockMaybe auto_lock(va_lock_);
   const VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1);
   VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroySurfaces);
diff --git a/media/gpu/video_encode_accelerator_tests.cc b/media/gpu/video_encode_accelerator_tests.cc
index 22aee3e..658b688 100644
--- a/media/gpu/video_encode_accelerator_tests.cc
+++ b/media/gpu/video_encode_accelerator_tests.cc
@@ -270,7 +270,8 @@
             config.output_profile, visible_rect, config.num_temporal_layers));
         break;
       case VideoCodec::kVP8:
-        bitstream_processors.emplace_back(new VP8Validator(visible_rect));
+        bitstream_processors.emplace_back(
+            new VP8Validator(visible_rect, config.num_temporal_layers));
         break;
       case VideoCodec::kVP9:
         bitstream_processors.emplace_back(new VP9Validator(
diff --git a/media/media_options.gni b/media/media_options.gni
index a23d408..18669be 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -209,7 +209,8 @@
   ]
   _default_mojo_media_host = "gpu"
 } else if (is_chromeos_ash || is_mac || is_win ||
-           ((is_linux || is_chromeos_lacros) && use_vaapi)) {
+           ((is_linux || is_chromeos_lacros) &&
+            (use_vaapi || use_v4l2_codec))) {
   _default_mojo_media_services = [ "video_decoder" ]
   _default_mojo_media_host = "gpu"
 }
diff --git a/media/mojo/services/cdm_service.cc b/media/mojo/services/cdm_service.cc
index 5982305..4ececfad 100644
--- a/media/mojo/services/cdm_service.cc
+++ b/media/mojo/services/cdm_service.cc
@@ -163,10 +163,9 @@
   if (!client_)
     return;
 
-  cdm_factory_receivers_.AddReceiver(
-      std::make_unique<CdmFactoryImpl>(client_.get(),
-                                       std::move(frame_interfaces)),
-      std::move(receiver));
+  cdm_factory_receivers_.Add(std::make_unique<CdmFactoryImpl>(
+                                 client_.get(), std::move(frame_interfaces)),
+                             std::move(receiver));
 }
 
 }  // namespace media
diff --git a/media/mojo/services/deferred_destroy_unique_receiver_set.h b/media/mojo/services/deferred_destroy_unique_receiver_set.h
index 6c0fb24..41f941e 100644
--- a/media/mojo/services/deferred_destroy_unique_receiver_set.h
+++ b/media/mojo/services/deferred_destroy_unique_receiver_set.h
@@ -75,8 +75,8 @@
   DeferredDestroyUniqueReceiverSet& operator=(
       const DeferredDestroyUniqueReceiverSet&) = delete;
 
-  void AddReceiver(std::unique_ptr<DeferredDestroy<Interface>> impl,
-                   mojo::PendingReceiver<Interface> receiver) {
+  void Add(std::unique_ptr<DeferredDestroy<Interface>> impl,
+           mojo::PendingReceiver<Interface> receiver) {
     // Wrap the pointer into a unique_ptr with a deleter.
     Deleter deleter(base::BindRepeating(
         &DeferredDestroyUniqueReceiverSet::OnReceiverRemoved,
diff --git a/media/mojo/services/deferred_destroy_unique_receiver_set_unittest.cc b/media/mojo/services/deferred_destroy_unique_receiver_set_unittest.cc
index 246dddcc..1f1dd77 100644
--- a/media/mojo/services/deferred_destroy_unique_receiver_set_unittest.cc
+++ b/media/mojo/services/deferred_destroy_unique_receiver_set_unittest.cc
@@ -48,8 +48,7 @@
     mojo::PendingRemote<PingService>* ptr) {
   auto impl = std::make_unique<DeferredDestroyPingImpl>();
   DeferredDestroyPingImpl* impl_ptr = impl.get();
-  receivers->AddReceiver(std::move(impl),
-                         ptr->InitWithNewPipeAndPassReceiver());
+  receivers->Add(std::move(impl), ptr->InitWithNewPipeAndPassReceiver());
   return impl_ptr;
 }
 
diff --git a/media/mojo/services/gpu_mojo_media_client_cros.cc b/media/mojo/services/gpu_mojo_media_client_cros.cc
index 41d8d8f..559a98f3 100644
--- a/media/mojo/services/gpu_mojo_media_client_cros.cc
+++ b/media/mojo/services/gpu_mojo_media_client_cros.cc
@@ -23,7 +23,8 @@
     const VideoDecoderTraits& traits) {
   switch (GetPlatformDecoderImplementationType(
       *traits.gpu_workarounds, traits.gpu_preferences, traits.gpu_info)) {
-    case VideoDecoderType::kVaapi: {
+    case VideoDecoderType::kVaapi:
+    case VideoDecoderType::kV4L2: {
       auto frame_pool = std::make_unique<PlatformVideoFramePool>(
           traits.gpu_memory_buffer_factory);
       auto frame_converter = MailboxVideoFrameConverter::Create(
@@ -56,13 +57,14 @@
       GetPlatformDecoderImplementationType(gpu_workarounds, gpu_preferences,
                                            gpu_info);
 #if BUILDFLAG(IS_LINUX)
-  base::UmaHistogramEnumeration("Media.VaapiLinux.Supported",
+  base::UmaHistogramEnumeration("Media.VaapiLinux.SupportedVideoDecoder",
                                 decoder_implementation);
 #endif
   switch (decoder_implementation) {
     case VideoDecoderType::kVda:
       return std::move(get_vda_configs).Run();
     case VideoDecoderType::kVaapi:
+    case VideoDecoderType::kV4L2:
       return VideoDecoderPipeline::GetSupportedConfigs(gpu_workarounds);
     default:
       return absl::nullopt;
@@ -74,8 +76,13 @@
     gpu::GpuPreferences gpu_preferences,
     const gpu::GPUInfo& gpu_info) {
 #if BUILDFLAG(IS_CHROMEOS)
-  if (gpu_preferences.enable_chromeos_direct_video_decoder)
+  if (gpu_preferences.enable_chromeos_direct_video_decoder) {
+#if BUILDFLAG(USE_VAAPI)
     return VideoDecoderType::kVaapi;
+#elif BUILDFLAG(USE_V4L2_CODEC)
+    return VideoDecoderType::kV4L2;
+#endif
+  }
   return VideoDecoderType::kVda;
 #elif BUILDFLAG(ENABLE_VULKAN)
   if (!base::FeatureList::IsEnabled(kVaapiVideoDecodeLinux))
diff --git a/media/mojo/services/media_foundation_service.h b/media/mojo/services/media_foundation_service.h
index a1df8ee73..1b316597 100644
--- a/media/mojo/services/media_foundation_service.h
+++ b/media/mojo/services/media_foundation_service.h
@@ -10,12 +10,12 @@
 #include "media/mojo/mojom/frame_interface_factory.mojom.h"
 #include "media/mojo/mojom/interface_factory.mojom.h"
 #include "media/mojo/mojom/media_foundation_service.mojom.h"
+#include "media/mojo/services/deferred_destroy_unique_receiver_set.h"
 #include "media/mojo/services/media_foundation_mojo_media_client.h"
 #include "media/mojo/services/media_mojo_export.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/unique_receiver_set.h"
 
 namespace media {
 
@@ -43,7 +43,8 @@
  private:
   mojo::Receiver<mojom::MediaFoundationService> receiver_;
   MediaFoundationMojoMediaClient mojo_media_client_;
-  mojo::UniqueReceiverSet<mojom::InterfaceFactory> interface_factory_receivers_;
+  DeferredDestroyUniqueReceiverSet<mojom::InterfaceFactory>
+      interface_factory_receivers_;
 };
 
 }  // namespace media
diff --git a/media/mojo/services/media_service.h b/media/mojo/services/media_service.h
index cd540b7b..cca6f2f7 100644
--- a/media/mojo/services/media_service.h
+++ b/media/mojo/services/media_service.h
@@ -11,11 +11,11 @@
 #include "media/mojo/mojom/frame_interface_factory.mojom.h"
 #include "media/mojo/mojom/interface_factory.mojom.h"
 #include "media/mojo/mojom/media_service.mojom.h"
+#include "media/mojo/services/deferred_destroy_unique_receiver_set.h"
 #include "media/mojo/services/media_mojo_export.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/unique_receiver_set.h"
 
 namespace media {
 
@@ -49,7 +49,8 @@
   // |mojo_media_client_| must be destructed before |ref_factory_|.
   std::unique_ptr<MojoMediaClient> mojo_media_client_;
 
-  mojo::UniqueReceiverSet<mojom::InterfaceFactory> interface_factory_receivers_;
+  DeferredDestroyUniqueReceiverSet<mojom::InterfaceFactory>
+      interface_factory_receivers_;
 };
 
 }  // namespace media
diff --git a/media/video/video_encode_accelerator_adapter.cc b/media/video/video_encode_accelerator_adapter.cc
index d6043a53..001a6d93 100644
--- a/media/video/video_encode_accelerator_adapter.cc
+++ b/media/video/video_encode_accelerator_adapter.cc
@@ -486,55 +486,56 @@
       output_handle_holder_->GetMapping();
   DCHECK_LE(result.size, mapping.size());
 
+  if (result.size > 0) {
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
-  if (h264_converter_) {
-    uint8_t* src = static_cast<uint8_t*>(mapping.memory());
-    size_t dst_size = result.size;
-    size_t actual_output_size = 0;
-    bool config_changed = false;
-    std::unique_ptr<uint8_t[]> dst(new uint8_t[dst_size]);
+    if (h264_converter_) {
+      uint8_t* src = static_cast<uint8_t*>(mapping.memory());
+      size_t dst_size = result.size;
+      size_t actual_output_size = 0;
+      bool config_changed = false;
+      std::unique_ptr<uint8_t[]> dst(new uint8_t[dst_size]);
 
-    auto status =
-        h264_converter_->ConvertChunk(base::span<uint8_t>(src, result.size),
-                                      base::span<uint8_t>(dst.get(), dst_size),
-                                      &config_changed, &actual_output_size);
-    if (status.code() == StatusCode::kH264BufferTooSmall) {
-      // Between AnnexB and AVCC bitstream formats, the start code length and
-      // the nal size length can be different. See H.264 specification at
-      // http://www.itu.int/rec/T-REC-H.264. Retry the conversion if the output
-      // buffer size is too small.
-      dst_size = actual_output_size;
-      dst.reset(new uint8_t[dst_size]);
-      status = h264_converter_->ConvertChunk(
+      auto status = h264_converter_->ConvertChunk(
           base::span<uint8_t>(src, result.size),
           base::span<uint8_t>(dst.get(), dst_size), &config_changed,
           &actual_output_size);
-    }
+      if (status.code() == StatusCode::kH264BufferTooSmall) {
+        // Between AnnexB and AVCC bitstream formats, the start code length and
+        // the nal size length can be different. See H.264 specification at
+        // http://www.itu.int/rec/T-REC-H.264. Retry the conversion if the
+        // output buffer size is too small.
+        dst_size = actual_output_size;
+        dst.reset(new uint8_t[dst_size]);
+        status = h264_converter_->ConvertChunk(
+            base::span<uint8_t>(src, result.size),
+            base::span<uint8_t>(dst.get(), dst_size), &config_changed,
+            &actual_output_size);
+      }
 
-    if (!status.is_ok()) {
-      LOG(ERROR) << status.message();
-      NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
-      return;
-    }
-    result.size = actual_output_size;
-    result.data = std::move(dst);
-
-    if (config_changed) {
-      const auto& config = h264_converter_->GetCurrentConfig();
-      desc = CodecDescription();
-      if (!config.Serialize(desc.value())) {
+      if (!status.is_ok()) {
+        LOG(ERROR) << status.message();
         NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
         return;
       }
-    }
-  } else {
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-    result.data.reset(new uint8_t[result.size]);
-    memcpy(result.data.get(), mapping.memory(), result.size);
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-  }
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+      result.size = actual_output_size;
+      result.data = std::move(dst);
 
+      if (config_changed) {
+        const auto& config = h264_converter_->GetCurrentConfig();
+        desc = CodecDescription();
+        if (!config.Serialize(desc.value())) {
+          NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
+          return;
+        }
+      }
+    } else {
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+      result.data.reset(new uint8_t[result.size]);
+      memcpy(result.data.get(), mapping.memory(), result.size);
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+    }
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+  }
   // Give the buffer back to |accelerator_|
   const base::UnsafeSharedMemoryRegion& region =
       output_handle_holder_->GetRegion();
@@ -552,7 +553,11 @@
     }
   }
   DCHECK(erased_active_encode);
-  output_cb_.Run(std::move(result), std::move(desc));
+  if (result.size > 0) {
+    // Size = 0 means that frame was dropped by the platform encoder, we don't
+    // need to call the output callback in such cases.
+    output_cb_.Run(std::move(result), std::move(desc));
+  }
   if (active_encodes_.empty() && !flush_support_.value()) {
     // Manually call FlushCompleted(), since |accelerator_| won't do it for us.
     FlushCompleted(true);
diff --git a/media/video/video_encode_accelerator_adapter_test.cc b/media/video/video_encode_accelerator_adapter_test.cc
index 3e79edd..05c052e4 100644
--- a/media/video/video_encode_accelerator_adapter_test.cc
+++ b/media/video/video_encode_accelerator_adapter_test.cc
@@ -458,6 +458,40 @@
   EXPECT_EQ(outputs_count, frames_to_encode);
 }
 
+TEST_F(VideoEncodeAcceleratorAdapterTest, DroppedFrame) {
+  VideoEncoder::Options options;
+  options.frame_size = gfx::Size(640, 480);
+  auto pixel_format = PIXEL_FORMAT_I420;
+  std::vector<base::TimeDelta> output_timestamps;
+  VideoEncoder::OutputCB output_cb = base::BindLambdaForTesting(
+      [&](VideoEncoderOutput output,
+          absl::optional<VideoEncoder::CodecDescription>) {
+        output_timestamps.push_back(output.timestamp);
+      });
+
+  vea()->SetEncodingCallback(base::BindLambdaForTesting(
+      [&](BitstreamBuffer&, bool keyframe, scoped_refptr<VideoFrame> frame) {
+        size_t size = keyframe ? 1 : 0;  // Drop non-key frame
+        return BitstreamBufferMetadata(size, keyframe, frame->timestamp());
+      }));
+  adapter()->Initialize(profile_, options, std::move(output_cb),
+                        ValidatingStatusCB());
+
+  auto frame1 =
+      CreateGreenFrame(options.frame_size, pixel_format, base::Milliseconds(1));
+  auto frame2 =
+      CreateGreenFrame(options.frame_size, pixel_format, base::Milliseconds(2));
+  auto frame3 =
+      CreateGreenFrame(options.frame_size, pixel_format, base::Milliseconds(3));
+  adapter()->Encode(frame1, true, ValidatingStatusCB());
+  adapter()->Encode(frame2, false, ValidatingStatusCB());
+  adapter()->Encode(frame3, true, ValidatingStatusCB());
+  RunUntilIdle();
+  ASSERT_EQ(output_timestamps.size(), 2u);
+  EXPECT_EQ(output_timestamps[0], base::Milliseconds(1));
+  EXPECT_EQ(output_timestamps[1], base::Milliseconds(3));
+}
+
 INSTANTIATE_TEST_SUITE_P(VideoEncodeAcceleratorAdapterTest,
                          VideoEncodeAcceleratorAdapterTest,
                          ::testing::Values(PIXEL_FORMAT_I420,
diff --git a/mojo/public/cpp/base/BUILD.gn b/mojo/public/cpp/base/BUILD.gn
index 471a4a4..f943a8a 100644
--- a/mojo/public/cpp/base/BUILD.gn
+++ b/mojo/public/cpp/base/BUILD.gn
@@ -58,6 +58,8 @@
     sources += [
       "logfont_win_mojom_traits.cc",
       "logfont_win_mojom_traits.h",
+      "wstring_mojom_traits.cc",
+      "wstring_mojom_traits.h",
     ]
   }
 
diff --git a/mojo/public/cpp/base/big_buffer.h b/mojo/public/cpp/base/big_buffer.h
index 9f172e3a..4f8c53f1 100644
--- a/mojo/public/cpp/base/big_buffer.h
+++ b/mojo/public/cpp/base/big_buffer.h
@@ -64,6 +64,12 @@
 // exposes simple |data()| and |size()| accessors akin to what common container
 // types provide. Users do not need to be concerned with the actual backing
 // storage used to implement this interface.
+//
+// SECURITY NOTE: When shmem is backing the message, it may be writable in the
+// sending process while being read in the receiving process. If a BigBuffer is
+// received from an untrustworthy process, you should make a copy of the data
+// before processing it to avoid time-of-check time-of-use (TOCTOU) bugs.
+// The |size()| of the data cannot be manipulated.
 class COMPONENT_EXPORT(MOJO_BASE) BigBuffer {
  public:
   static constexpr size_t kMaxInlineBytes = 64 * 1024;
diff --git a/mojo/public/cpp/base/wstring_mojom_traits.cc b/mojo/public/cpp/base/wstring_mojom_traits.cc
new file mode 100644
index 0000000..7a03c4c
--- /dev/null
+++ b/mojo/public/cpp/base/wstring_mojom_traits.cc
@@ -0,0 +1,21 @@
+// Copyright 2020 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 "mojo/public/cpp/base/wstring_mojom_traits.h"
+
+#include "mojo/public/cpp/bindings/array_data_view.h"
+
+namespace mojo {
+
+// static
+bool StructTraits<mojo_base::mojom::WStringDataView, std::wstring>::Read(
+    mojo_base::mojom::WStringDataView data,
+    std::wstring* out) {
+  ArrayDataView<uint16_t> view;
+  data.GetDataDataView(&view);
+  out->assign(reinterpret_cast<const wchar_t*>(view.data()), view.size());
+  return true;
+}
+
+}  // namespace mojo
diff --git a/mojo/public/cpp/base/wstring_mojom_traits.h b/mojo/public/cpp/base/wstring_mojom_traits.h
new file mode 100644
index 0000000..b5d5c4b3
--- /dev/null
+++ b/mojo/public/cpp/base/wstring_mojom_traits.h
@@ -0,0 +1,29 @@
+// Copyright 2020 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 MOJO_PUBLIC_CPP_BASE_WSTRING_MOJOM_TRAITS_H_
+#define MOJO_PUBLIC_CPP_BASE_WSTRING_MOJOM_TRAITS_H_
+
+#include <string>
+
+#include "base/containers/span.h"
+#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "mojo/public/mojom/base/wstring.mojom-shared.h"
+
+namespace mojo {
+
+template <>
+struct COMPONENT_EXPORT(MOJO_BASE_TRAITS)
+    StructTraits<mojo_base::mojom::WStringDataView, std::wstring> {
+  static base::span<const uint16_t> data(const std::wstring& str) {
+    return base::make_span(reinterpret_cast<const uint16_t*>(str.data()),
+                           str.size());
+  }
+
+  static bool Read(mojo_base::mojom::WStringDataView data, std::wstring* out);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_PUBLIC_CPP_BASE_WSTRING_MOJOM_TRAITS_H_
diff --git a/mojo/public/mojom/base/BUILD.gn b/mojo/public/mojom/base/BUILD.gn
index 073ea27..2c6af6e7 100644
--- a/mojo/public/mojom/base/BUILD.gn
+++ b/mojo/public/mojom/base/BUILD.gn
@@ -37,7 +37,10 @@
   ]
 
   if (is_win) {
-    sources += [ "logfont_win.mojom" ]
+    sources += [
+      "logfont_win.mojom",
+      "wstring.mojom",
+    ]
   }
   enabled_features = []
   if (is_win) {
@@ -501,6 +504,20 @@
           "//mojo/public/cpp/base:typemap_traits",
         ]
       },
+      {
+        types = [
+          {
+            mojom = "mojo_base.mojom.WString"
+            cpp = "::std::wstring"
+          },
+        ]
+        traits_headers = [ "//mojo/public/cpp/base/wstring_mojom_traits.h" ]
+        traits_public_deps = [
+          "//base",
+          "//mojo/public/cpp/base",
+          "//mojo/public/cpp/base:typemap_traits",
+        ]
+      },
     ]
   }
 
diff --git a/mojo/public/mojom/base/big_buffer.mojom b/mojo/public/mojom/base/big_buffer.mojom
index ea11c66..78aac5e 100644
--- a/mojo/public/mojom/base/big_buffer.mojom
+++ b/mojo/public/mojom/base/big_buffer.mojom
@@ -16,6 +16,12 @@
 // by the sender and the contents of the buffer would be too large to inline,
 // this will instead take on the value of |invalid_buffer=true| indicating that
 // the buffer does not represent any contents intended by the sender.
+//
+// SECURITY NOTE: When shmem is backing the message, it may be writable in the
+// sending process while being read in the receiving process. If a BigBuffer is
+// received from an untrustworthy process, you should make a copy of the data
+// before processing it to avoid time-of-check time-of-use (TOCTOU) bugs.
+// The |size()| of the data cannot be manipulated.
 [Stable]
 union BigBuffer {
   array<uint8> bytes;
diff --git a/mojo/public/mojom/base/wstring.mojom b/mojo/public/mojom/base/wstring.mojom
new file mode 100644
index 0000000..85c9a79
--- /dev/null
+++ b/mojo/public/mojom/base/wstring.mojom
@@ -0,0 +1,11 @@
+// Copyright 2022 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.
+
+module mojo_base.mojom;
+
+// Corresponds to std::wstring.
+[EnableIf=is_win]
+struct WString {
+  array<uint16> data;
+};
diff --git a/mojo/public/rust/BUILD.gn b/mojo/public/rust/BUILD.gn
new file mode 100644
index 0000000..2d4a2b0
--- /dev/null
+++ b/mojo/public/rust/BUILD.gn
@@ -0,0 +1,89 @@
+# Copyright 2021 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.
+
+import("//build/config/rust.gni")
+import("//build/rust/rust_source_set.gni")
+import("//build/rust/rust_unit_test.gni")
+
+# Meta target to build everything
+group("rust") {
+  deps = [ ":mojo_rust" ]
+}
+
+# Meta target to build test binaries, if supported.
+group("tests") {
+  testonly = true
+  deps = []
+  if (build_rust_unit_tests) {
+    deps += [ ":mojo_rust_unittests" ]
+  }
+  if (rustc_can_link) {
+    deps += [ ":mojo_rust_extra_tests" ]
+  }
+}
+
+static_library("c_support") {
+  sources = [ "support.cc" ]
+  deps = [
+    "//mojo/public/c/system",
+    "//mojo/public/cpp/system",
+  ]
+}
+
+static_library("c_test_support") {
+  testonly = true
+  sources = [ "test_support.cc" ]
+  deps = [
+    "//base",
+    "//mojo/core/embedder",
+    "//mojo/public/cpp/bindings/tests:mojo_public_bindings_test_utils",
+  ]
+}
+
+rust_source_set("mojo_rust") {
+  crate_root = "lib.rs"
+  unit_test_target =
+      "mojo_rust_unittests"  # avoids conflict with C++ target elsewhere
+  crate_name = "mojo"
+  edition = "2018"
+  sources = [
+    "bindings/decoding.rs",
+    "bindings/encoding.rs",
+    "bindings/macros.rs",
+    "bindings/message.rs",
+    "bindings/mod.rs",
+    "bindings/mojom.rs",
+    "bindings/run_loop.rs",
+    "bindings/util.rs",
+    "lib.rs",
+    "system/core.rs",
+    "system/data_pipe.rs",
+    "system/ffi.rs",
+    "system/handle.rs",
+    "system/message_pipe.rs",
+    "system/mod.rs",
+    "system/mojo_types.rs",
+    "system/shared_buffer.rs",
+    "system/wait_set.rs",
+  ]
+
+  deps = [ ":c_support" ]
+}
+
+if (rustc_can_link) {
+  rust_unit_test("mojo_rust_extra_tests") {
+    testonly = true
+    crate_root = "tests/lib.rs"
+    edition = "2018"
+    sources = [
+      "tests/integration.rs",
+      "tests/lib.rs",
+    ]
+    deps = [
+      ":c_test_support",
+      ":mojo_rust",
+      "//mojo/public/c/system",
+    ]
+  }
+}
diff --git a/mojo/public/rust/DEPS b/mojo/public/rust/DEPS
new file mode 100644
index 0000000..0d23bc5
--- /dev/null
+++ b/mojo/public/rust/DEPS
@@ -0,0 +1,10 @@
+specific_include_rules = {
+  # Our rust tests are built in a separate binary than other Mojo unit tests.
+  # We need to initialize Mojo, so allow references to Mojo embedder code. This
+  # is fine since this file is only used in tests. Hopefully this won't always
+  # needed, e.g. if we can build Rust and C++ tests into the same binary or
+  # otherwise share initialization code.
+  "test_support.cc": [
+    "+mojo/core/embedder",
+  ]
+}
diff --git a/mojo/public/rust/bindings/decoding.rs b/mojo/public/rust/bindings/decoding.rs
index 304817b..bd6629e4 100644
--- a/mojo/public/rust/bindings/decoding.rs
+++ b/mojo/public/rust/bindings/decoding.rs
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use bindings::encoding::{
+use crate::bindings::encoding::{
     Bits, Context, DataHeader, DataHeaderValue, MojomNumeric, DATA_HEADER_SIZE,
 };
-use bindings::mojom::{MojomEncodable, MOJOM_NULL_POINTER, UNION_SIZE};
-use bindings::util;
+use crate::bindings::mojom::{MojomEncodable, MOJOM_NULL_POINTER, UNION_SIZE};
+use crate::bindings::util;
 
 use std::mem;
 use std::ptr;
 use std::vec::Vec;
 
-use system;
-use system::{CastHandle, Handle, UntypedHandle};
+use crate::system;
+use crate::system::{CastHandle, Handle, UntypedHandle};
 
 #[derive(Debug, Eq, PartialEq)]
 pub enum ValidationError {
@@ -151,7 +151,7 @@
         if ptr == MOJOM_NULL_POINTER {
             self.offset += 8;
         }
-        (ptr == MOJOM_NULL_POINTER)
+        ptr == MOJOM_NULL_POINTER
     }
 
     /// If we encounter a null union, increment past it.
@@ -164,7 +164,7 @@
         if size == 0 {
             self.offset += UNION_SIZE;
         }
-        (size == 0)
+        size == 0
     }
 
     /// If we encounter a null handle, increment past it.
@@ -177,7 +177,7 @@
         if index < 0 {
             self.offset += 4;
         }
-        (index < 0)
+        index < 0
     }
 
     /// If we encounter a null interface, increment past it.
@@ -190,7 +190,7 @@
         if index < 0 {
             self.offset += 8;
         }
-        (index < 0)
+        index < 0
     }
 
     /// Decode a pointer from the buffer as a global offset into the buffer.
diff --git a/mojo/public/rust/bindings/encoding.rs b/mojo/public/rust/bindings/encoding.rs
index 39e0744..79b6442 100644
--- a/mojo/public/rust/bindings/encoding.rs
+++ b/mojo/public/rust/bindings/encoding.rs
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use bindings::mojom::MOJOM_NULL_POINTER;
-use bindings::util;
+use crate::bindings::mojom::MOJOM_NULL_POINTER;
+use crate::bindings::util;
 
 use std::mem;
 use std::ops::{Add, AddAssign, Div, Mul, Rem, Sub};
 use std::ptr;
 use std::vec::Vec;
 
-use system::UntypedHandle;
+use crate::system::UntypedHandle;
 
 /// Represents some count of bits.
 ///
diff --git a/mojo/public/rust/bindings/macros.rs b/mojo/public/rust/bindings/macros.rs
index 63848a5..0fa2154 100644
--- a/mojo/public/rust/bindings/macros.rs
+++ b/mojo/public/rust/bindings/macros.rs
@@ -76,11 +76,7 @@
         fn embed_size(
             context: &$crate::bindings::encoding::Context,
         ) -> $crate::bindings::encoding::Bits {
-            if context.is_union() {
-                Self::nested_embed_size()
-            } else {
-                Self::inline_embed_size()
-            }
+            if context.is_union() { Self::nested_embed_size() } else { Self::inline_embed_size() }
         }
         fn encode(
             self,
@@ -151,9 +147,8 @@
                 let mut state = decoder.get_mut(&context);
                 (state.decode::<i32>(), state.decode::<u32>())
             };
-            let handle =
-                try!(decoder
-                    .claim_handle::<$crate::system::message_pipe::MessageEndpoint>(handle_index));
+            let handle = decoder
+                .claim_handle::<$crate::system::message_pipe::MessageEndpoint>(handle_index)?;
             Ok(Self::with_version(handle, version))
         }
     };
diff --git a/mojo/public/rust/bindings/message.rs b/mojo/public/rust/bindings/message.rs
index 9e1a830..3e218b3 100644
--- a/mojo/public/rust/bindings/message.rs
+++ b/mojo/public/rust/bindings/message.rs
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use bindings::decoding::{Decoder, ValidationError};
-use bindings::encoding;
-use bindings::encoding::{Context, DataHeaderValue, Encoder, DATA_HEADER_SIZE};
-use bindings::mojom::{MojomEncodable, MojomPointer, MojomStruct};
+use crate::bindings::decoding::{Decoder, ValidationError};
+use crate::bindings::encoding;
+use crate::bindings::encoding::{Context, DataHeaderValue, Encoder, DATA_HEADER_SIZE};
+use crate::bindings::mojom::{MojomEncodable, MojomPointer, MojomStruct};
 
 /// A flag for the message header indicating that no flag has been set.
 pub const MESSAGE_HEADER_NO_FLAG: u32 = 0;
@@ -61,7 +61,7 @@
     }
 
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
-        let mut state = decoder.get_mut(&context);
+        let state = decoder.get_mut(&context);
         let version = match state.decode_struct_header(&MESSAGE_HEADER_VERSIONS) {
             Ok(header) => header.data(),
             Err(err) => return Err(err),
diff --git a/mojo/public/rust/bindings/mojom.rs b/mojo/public/rust/bindings/mojom.rs
index 9ea3f99..01c081b8 100644
--- a/mojo/public/rust/bindings/mojom.rs
+++ b/mojo/public/rust/bindings/mojom.rs
@@ -2,10 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use bindings::decoding::{Decoder, ValidationError};
-use bindings::encoding;
-use bindings::encoding::{Bits, Context, DataHeader, DataHeaderValue, Encoder, DATA_HEADER_SIZE};
-use bindings::message::MessageHeader;
+use crate::bindings::decoding::{Decoder, ValidationError};
+use crate::bindings::encoding;
+use crate::bindings::encoding::{
+    Bits, Context, DataHeader, DataHeaderValue, Encoder, DATA_HEADER_SIZE,
+};
+use crate::bindings::message::MessageHeader;
 
 use std::cmp::Eq;
 use std::collections::HashMap;
@@ -15,11 +17,10 @@
 use std::ptr;
 use std::vec::Vec;
 
-use system::data_pipe;
-use system::message_pipe;
-use system::shared_buffer;
-use system::wait_set;
-use system::{CastHandle, Handle, MojoResult, UntypedHandle};
+use crate::system::data_pipe;
+use crate::system::message_pipe;
+use crate::system::shared_buffer;
+use crate::system::{CastHandle, Handle, MojoResult, UntypedHandle};
 
 /// The size of a Mojom map plus header in bytes.
 const MAP_SIZE: usize = 24;
@@ -164,14 +165,14 @@
     /// The encoding routine for when the union is inlined into the current context.
     fn inline_encode(self, encoder: &mut Encoder, context: Context) {
         {
-            let mut state = encoder.get_mut(&context);
+            let state = encoder.get_mut(&context);
             state.align_to_bytes(8);
             state.encode(UNION_SIZE as u32);
             state.encode(self.get_tag());
         }
         self.encode_value(encoder, context.clone());
         {
-            let mut state = encoder.get_mut(&context);
+            let state = encoder.get_mut(&context);
             state.align_to_bytes(8);
             state.align_to_byte();
         }
@@ -180,13 +181,13 @@
     /// The decoding routine for when the union is inlined into the current context.
     fn inline_decode(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             state.align_to_byte();
             state.align_to_bytes(8);
         }
         let value = Self::decode_value(decoder, context.clone());
         {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             state.align_to_byte();
             state.align_to_bytes(8);
         }
@@ -359,10 +360,10 @@
         buffer: Vec<u8>,
         handles: Vec<UntypedHandle>,
     ) -> Result<(u64, Self), ValidationError> {
-        let header = try!(MessageHeader::deserialize(&buffer[..], Vec::new()));
+        let header = MessageHeader::deserialize(&buffer[..], Vec::new())?;
         let payload_buffer = &buffer[header.serialized_size(&Default::default())..];
         let req_id = header.request_id;
-        let ret = try!(Self::decode_payload(header, payload_buffer, handles));
+        let ret = Self::decode_payload(header, payload_buffer, handles)?;
         Ok((req_id, ret))
     }
 }
@@ -388,11 +389,11 @@
                 0 // Indicates that this type is inlined and it adds nothing external to the size
             }
             fn encode(self, encoder: &mut Encoder, context: Context) {
-                let mut state = encoder.get_mut(&context);
+                let state = encoder.get_mut(&context);
                 state.encode(self);
             }
             fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
-                let mut state = decoder.get_mut(&context);
+                let state = decoder.get_mut(&context);
                 Ok(state.decode::<Self>())
             }
         }
@@ -416,11 +417,11 @@
         0 // Indicates that this type is inlined and it adds nothing external to the size
     }
     fn encode(self, encoder: &mut Encoder, context: Context) {
-        let mut state = encoder.get_mut(&context);
+        let state = encoder.get_mut(&context);
         state.encode_bool(self);
     }
     fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
-        let mut state = decoder.get_mut(&context);
+        let state = decoder.get_mut(&context);
         Ok(state.decode_bool())
     }
 }
@@ -448,7 +449,7 @@
         match self {
             Some(value) => value.encode(encoder, context),
             None => {
-                let mut state = encoder.get_mut(&context);
+                let state = encoder.get_mut(&context);
                 match T::mojom_type() {
                     MojomType::Pointer => state.encode_null_pointer(),
                     MojomType::Union => state.encode_null_union(),
@@ -464,7 +465,7 @@
     }
     fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let skipped = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match T::mojom_type() {
                 MojomType::Pointer => state.skip_if_null_pointer(),
                 MojomType::Union => state.skip_if_null_union(),
@@ -518,7 +519,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Vec<T>, ValidationError> {
         let elems = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_array_header::<T>() {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -539,126 +540,129 @@
     impl_encodable_for_array!();
 }
 
-macro_rules! impl_encodable_for_fixed_array {
-    ($($len:expr),*) => {
-        $(
-        impl<T: MojomEncodable> MojomPointer for [T; $len] {
-            impl_pointer_for_array!();
-            fn encode_value(mut self, encoder: &mut Encoder, context: Context) {
-                let mut panic_error = None;
-                let mut moves = 0;
+impl<T: MojomEncodable, const N: usize> MojomPointer for [T; N] {
+    impl_pointer_for_array!();
+    fn encode_value(mut self, encoder: &mut Encoder, context: Context) {
+        let mut panic_error = None;
+        let mut moves = 0;
+        unsafe {
+            // In order to move elements out of an array we need to replace the
+            // value with uninitialized memory.
+            for elem in self.iter_mut() {
+                let owned_elem = mem::replace(elem, mem::MaybeUninit::uninit().assume_init());
+                // We need to handle if an unwinding panic happens to prevent use of
+                // uninitialized memory...
+                let next_context = context.clone();
+                // We assert everything going into this closure is unwind safe. If anything
+                // is added, PLEASE make sure it is also unwind safe...
+                let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+                    owned_elem.encode(encoder, next_context);
+                }));
+                if let Err(err) = result {
+                    panic_error = Some(err);
+                    break;
+                }
+                moves += 1;
+            }
+            if let Some(err) = panic_error {
+                for i in moves..self.len() {
+                    ptr::drop_in_place(&mut self[i] as *mut T);
+                }
+                // Forget the array to prevent a drop
+                mem::forget(self);
+                // Continue unwinding
+                panic::resume_unwind(err);
+            }
+            // We cannot risk drop() getting run on the array values, so we just
+            // forget self.
+            mem::forget(self);
+        }
+    }
+    fn decode_value(decoder: &mut Decoder, context: Context) -> Result<[T; N], ValidationError> {
+        let elems = {
+            let state = decoder.get_mut(&context);
+            match state.decode_array_header::<T>() {
+                Ok(header) => header.data(),
+                Err(err) => return Err(err),
+            }
+        };
+        if elems as usize != N {
+            return Err(ValidationError::UnexpectedArrayHeader);
+        }
+
+        // Since we don't force Clone to be implemented on Mojom types
+        // (mainly due to handles) we need to create this array as uninitialized
+        // and initialize it manually.
+        let mut array_uninit: [mem::MaybeUninit<T>; N] = unsafe {
+            // We call assume_init() for a MaybeUninit<[MaybeUnint]> which drops the outer
+            // MaybeUninit, producing a "initialized" array of MaybeUnint elements. This is
+            // fine since MaybeUninit does not actually store whether it's initialized and
+            // our code hereafter continues to assume the elements are not initialized yet.
+            // See https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#initializing-an-array-element-by-element
+            mem::MaybeUninit::uninit().assume_init()
+        };
+
+        let mut panic_error = None;
+        let mut inits = 0;
+        let mut error = None;
+        for elem in &mut array_uninit[..] {
+            // When a panic unwinds it may try to read and drop uninitialized memory, so we
+            // need to catch this. However, we pass mutable state! This could be bad as we
+            // could observe a broken invariant inside of decoder and access it as usual,
+            // but we do NOT access decoder here, nor do we ever unwind through one of
+            // decoder's methods. Therefore, it should be safe to assert that decoder is
+            // unwind safe.
+            let next_context = context.clone();
+            // We assert everything going into this closure is unwind safe. If anything
+            // is added, PLEASE make sure it is also unwind safe...
+            let result =
+                panic::catch_unwind(panic::AssertUnwindSafe(|| T::decode(decoder, next_context)));
+            match result {
+                Ok(non_panic_value) => match non_panic_value {
+                    Ok(value) => elem.write(value),
+                    Err(err) => {
+                        error = Some(err);
+                        break;
+                    }
+                },
+                Err(err) => {
+                    panic_error = Some(err);
+                    break;
+                }
+            };
+            inits += 1;
+        }
+        if panic_error.is_some() || error.is_some() {
+            // Drop everything that was initialized
+            for i in 0..inits {
+                // In the previous for loop, we initialized the first `inits` array values.
+                // It is safe to get a mutable reference to these.
                 unsafe {
-                    // In order to move elements out of an array we need to replace the
-                    // value with uninitialized memory.
-                    for elem in self.iter_mut() {
-                        let owned_elem = mem::replace(elem, mem::uninitialized());
-                        // We need to handle if an unwinding panic happens to prevent use of
-                        // uninitialized memory...
-                        let next_context = context.clone();
-                        // We assert everything going into this closure is unwind safe. If anything
-                        // is added, PLEASE make sure it is also unwind safe...
-                        let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-                            owned_elem.encode(encoder, next_context);
-                        }));
-                        if let Err(err) = result {
-                            panic_error = Some(err);
-                            break;
-                        }
-                        moves += 1;
-                    }
-                    if let Some(err) = panic_error {
-                        for i in moves..self.len() {
-                            ptr::drop_in_place(&mut self[i] as *mut T);
-                        }
-                        // Forget the array to prevent a drop
-                        mem::forget(self);
-                        // Continue unwinding
-                        panic::resume_unwind(err);
-                    }
-                    // We cannot risk drop() getting run on the array values, so we just
-                    // forget self.
-                    mem::forget(self);
+                    // Drop by pointer since we can't move out of an array.
+                    ptr::drop_in_place(array_uninit[i].as_mut_ptr());
                 }
             }
-            fn decode_value(decoder: &mut Decoder, context: Context) -> Result<[T; $len], ValidationError> {
-                let elems = {
-                    let mut state = decoder.get_mut(&context);
-                    match state.decode_array_header::<T>() {
-                        Ok(header) => header.data(),
-                        Err(err) => return Err(err),
-                    }
-                };
-                if elems != $len {
-                    return Err(ValidationError::UnexpectedArrayHeader);
-                }
-                let mut array: [T; $len];
-                let mut panic_error = None;
-                let mut inits = 0;
-                let mut error = None;
-                unsafe {
-                    // Since we don't force Clone to be implemented on Mojom types
-                    // (mainly due to handles) we need to create this array as uninitialized
-                    // and initialize it manually.
-                    array = mem::uninitialized();
-                    for elem in &mut array[..] {
-                        // When a panic unwinds it may try to read and drop uninitialized
-                        // memory, so we need to catch this. However, we pass mutable state!
-                        // This could be bad as we could observe a broken invariant inside
-                        // of decoder and access it as usual, but we do NOT access decoder
-                        // here, nor do we ever unwind through one of decoder's methods.
-                        // Therefore, it should be safe to assert that decoder is unwind safe.
-                        let next_context = context.clone();
-                        // We assert everything going into this closure is unwind safe. If anything
-                        // is added, PLEASE make sure it is also unwind safe...
-                        let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-                            T::decode(decoder, next_context)
-                        }));
-                        match result {
-                            Ok(non_panic_value) => match non_panic_value {
-                                Ok(value) => ptr::write(elem, value),
-                                Err(err) => {
-                                    error = Some(err);
-                                    break;
-                                },
-                            },
-                            Err(err) => {
-                                panic_error = Some(err);
-                                break;
-                            },
-                        }
-                        inits += 1;
-                    }
-                    if panic_error.is_some() || error.is_some() {
-                        // Drop everything that was initialized
-                        for i in 0..inits {
-                            ptr::drop_in_place(&mut array[i] as *mut T);
-                        }
-                        // Forget the array to prevent a drop
-                        mem::forget(array);
-                        if let Some(err) = panic_error {
-                            panic::resume_unwind(err);
-                        }
-                        return Err(error.take().expect("Corrupted stack?"));
-                    }
-                }
-                Ok(array)
+            if let Some(err) = panic_error {
+                panic::resume_unwind(err);
             }
+            Err(error.take().expect("Corrupted stack?"))
+        } else {
+            // This is safe since [T; N] and [MaybeUninit<T>; N] are
+            // layout-equivalent, every value is initialized, and MaybeInit<T> never calls
+            // drop on its inner value.
+            //
+            // Unfortunately regular transmute doesn't work: it can't handle types
+            // parameterized by generic T, even though the arrays are the same size. Known
+            // issue: https://github.com/rust-lang/rust/issues/47966
+            let array =
+                unsafe { mem::transmute_copy::<[mem::MaybeUninit<T>; N], [T; N]>(&array_uninit) };
+            Ok(array)
         }
-        impl<T: MojomEncodable> MojomEncodable for [T; $len] {
-            impl_encodable_for_array!();
-        }
-        )*
     }
 }
-
-// Unfortunately, we cannot be generic over the length of a fixed array
-// even though its part of the type (this will hopefully be added in the
-// future) so for now we implement encodable for only the first 33 fixed
-// size array types.
-impl_encodable_for_fixed_array!(
-    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
-    26, 27, 28, 29, 30, 31, 32
-);
+impl<T: MojomEncodable, const N: usize> MojomEncodable for [T; N] {
+    impl_encodable_for_array!();
+}
 
 impl<T: MojomEncodable> MojomPointer for Box<[T]> {
     impl_pointer_for_array!();
@@ -694,7 +698,7 @@
         }
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<String, ValidationError> {
-        let mut state = decoder.get_mut(&context);
+        let state = decoder.get_mut(&context);
         let elems = match state.decode_array_header::<u8>() {
             Ok(header) => header.data(),
             Err(err) => return Err(err),
@@ -872,7 +876,7 @@
         }
         fn encode(self, encoder: &mut Encoder, context: Context) {
             let pos = encoder.add_handle(self.as_untyped());
-            let mut state = encoder.get_mut(&context);
+            let state = encoder.get_mut(&context);
             state.encode(pos as i32);
         }
         fn decode(
@@ -880,7 +884,7 @@
             context: Context,
         ) -> Result<$handle_type, ValidationError> {
             let handle_index = {
-                let mut state = decoder.get_mut(&context);
+                let state = decoder.get_mut(&context);
                 state.decode::<i32>()
             };
             decoder.claim_handle::<$handle_type>(handle_index)
@@ -907,7 +911,3 @@
 impl<T> MojomEncodable for data_pipe::Producer<T> {
     impl_encodable_for_handle!(data_pipe::Producer<T>);
 }
-
-impl MojomEncodable for wait_set::WaitSet {
-    impl_encodable_for_handle!(wait_set::WaitSet);
-}
diff --git a/mojo/public/rust/bindings/run_loop.rs b/mojo/public/rust/bindings/run_loop.rs
index 1f50e03..e2d081d9 100644
--- a/mojo/public/rust/bindings/run_loop.rs
+++ b/mojo/public/rust/bindings/run_loop.rs
@@ -27,10 +27,10 @@
 use std::u32;
 use std::vec::Vec;
 
-use system;
-use system::core;
-use system::wait_set;
-use system::{Handle, MojoResult, MOJO_INDEFINITE};
+use crate::system;
+use crate::system::core;
+use crate::system::wait_set;
+use crate::system::{Handle, MojoResult, MOJO_INDEFINITE};
 
 /// Define the equivalent of MOJO_INDEFINITE for absolute deadlines
 const MOJO_INDEFINITE_ABSOLUTE: system::MojoTimeTicks = 0;
@@ -44,7 +44,7 @@
 /// Maximum size of the result buffer.
 const MAXIMUM_WAIT_SET_NUM_RESULTS: usize = 256;
 
-/// Thread-local data structure for keeping track of handles to wait on.
+// Thread-local data structure for keeping track of handles to wait on.
 thread_local!(static TL_RUN_LOOP: RefCell<RunLoop<'static, 'static>> = RefCell::new(RunLoop::new()));
 
 /// Token representing handle/callback to wait on for this thread only. This
@@ -101,7 +101,7 @@
     /// used in a callback, we must take ownership to avoid mutability
     /// cycles. The easiest way to do this is to take() from the Option then
     /// put it back.
-    handler: Option<Box<Handler + 'h>>,
+    handler: Option<Box<dyn Handler + 'h>>,
 
     /// An absolute deadline in terms of time ticks.
     ///
@@ -113,12 +113,12 @@
 
 impl<'h> HandlerInfo<'h> {
     /// Take the handler out of its Option type.
-    pub fn take(&mut self) -> Option<Box<Handler + 'h>> {
+    pub fn take(&mut self) -> Option<Box<dyn Handler + 'h>> {
         self.handler.take()
     }
 
     /// Put a new handler into the Option type.
-    pub fn give(&mut self, handler: Box<Handler + 'h>) {
+    pub fn give(&mut self, handler: Box<dyn Handler + 'h>) {
         self.handler = Some(handler);
     }
 
@@ -142,7 +142,7 @@
 /// it.
 struct TaskInfo<'t> {
     /// The task, boxed up.
-    closure: Box<FnMut(&mut RunLoop) + 't>,
+    closure: Box<dyn FnMut(&mut RunLoop) + 't>,
 
     /// An absolute deadline in terms of time ticks.
     ///
@@ -264,23 +264,6 @@
     converted
 }
 
-/// Convert an absolute deadline to a mojo deadline which is relative to some
-/// notion of "now".
-///
-/// If the deadline is earlier than "now", this routine rounds up to "now".
-fn relative_deadline(
-    deadline: system::MojoTimeTicks,
-    now: system::MojoTimeTicks,
-) -> system::MojoDeadline {
-    if deadline == MOJO_INDEFINITE_ABSOLUTE {
-        MOJO_INDEFINITE
-    } else if now >= deadline {
-        0
-    } else {
-        (deadline - now) as system::MojoDeadline
-    }
-}
-
 /// This structure contains all information necessary to wait on handles
 /// asynchronously.
 ///
@@ -341,7 +324,7 @@
     /// Adds a new entry to the runloop queue.
     pub fn register<H>(
         &mut self,
-        handle: &Handle,
+        handle: &dyn Handle,
         signals: system::HandleSignals,
         deadline: system::MojoDeadline,
         handler: H,
@@ -413,7 +396,8 @@
         match self.handlers.remove(&token) {
             Some(_) => {
                 let _result = self.handle_set.remove(token.as_cookie());
-                debug_assert_eq!(_result, MojoResult::Okay);
+                // Handles are auto-removed if they are closed. Ignore this error.
+                debug_assert!(_result == MojoResult::Okay || _result == MojoResult::NotFound);
                 true
             }
             None => false,
@@ -471,7 +455,7 @@
     /// out of the HashMap, and returns it when manipulation has completed.
     fn get_handler_with<F>(&mut self, token: &Token, invoker: F)
     where
-        F: FnOnce(&mut Self, &mut Box<Handler + 'h>, Token, system::MojoTimeTicks),
+        F: FnOnce(&mut Self, &mut Box<dyn Handler + 'h>, Token, system::MojoTimeTicks),
     {
         // Logic for pulling out the handler as well as its current deadline.
         //
@@ -610,23 +594,27 @@
         if self.handlers.is_empty() || self.should_quit {
             return;
         }
+
         let deadline = self.get_next_deadline();
-        let until_deadline = relative_deadline(deadline, core::get_time_ticks_now());
+        // Deadlines no longer supported. TODO(collinbaker): update run_loop
+        // for no deadlines
+        // let until_deadline = relative_deadline(deadline, core::get_time_ticks_now());
         // Perform the wait
-        match self.handle_set.wait_on_set(until_deadline, results_buffer) {
-            Ok(max_results) => {
+        match self.handle_set.wait_on_set(results_buffer) {
+            MojoResult::Okay => {
+                let num_results = results_buffer.len();
                 self.notify_of_results(results_buffer);
+
                 // Clear the buffer since we don't need the results anymore.
                 // Helps prevent a copy if we resize the buffer.
                 results_buffer.clear();
-                // Increase the size of the buffer if there are more results
-                // we could be holding.
+                // If we reached the capcity of `results_buffer` there's a chance there were more handles available. Grow the buffer.
                 let capacity = results_buffer.capacity();
-                if capacity < MAXIMUM_WAIT_SET_NUM_RESULTS && capacity < (max_results) as usize {
+                if capacity < MAXIMUM_WAIT_SET_NUM_RESULTS && capacity == num_results {
                     results_buffer.reserve(capacity);
                 }
             }
-            Err(result) => {
+            result => {
                 assert_eq!(result, MojoResult::DeadlineExceeded);
                 self.notify_of_expired(deadline);
             }
diff --git a/mojo/public/rust/bindings/util.rs b/mojo/public/rust/bindings/util.rs
index 208a5d7..81621acb 100644
--- a/mojo/public/rust/bindings/util.rs
+++ b/mojo/public/rust/bindings/util.rs
@@ -17,7 +17,7 @@
 /// Converts some number of bits into however many bytes are needed to
 /// represent that bit size.
 pub fn bits_to_bytes(bits: usize) -> usize {
-    ((bits + 7) >> 3)
+    (bits + 7) >> 3
 }
 
 #[cfg(test)]
diff --git a/mojo/public/rust/lib.rs b/mojo/public/rust/lib.rs
index f28143d..b349e88 100644
--- a/mojo/public/rust/lib.rs
+++ b/mojo/public/rust/lib.rs
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Workaround for linkage bug for rust binary -> C++ component -> rust component
+// dependency. TOOD(https://crbug.com/1289742): remove this after fix.
+extern crate base_rs;
+
 #[macro_use]
 mod macros {
     /// This macro must be used at the top-level in any
@@ -140,4 +144,4 @@
 pub mod bindings;
 pub mod system;
 
-pub use system::MojoResult;
+pub use crate::system::MojoResult;
diff --git a/mojo/public/rust/support.cc b/mojo/public/rust/support.cc
new file mode 100644
index 0000000..4384254f
--- /dev/null
+++ b/mojo/public/rust/support.cc
@@ -0,0 +1,145 @@
+// Copyright 2021 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.
+
+// The old Mojo SDK had a different API than Chromium's Mojo right now. The Rust
+// bindings refer to several functions that no longer exist in the core C API.
+// However, most of the functionality exists, albeit in a different form, in the
+// C++ bindings. This file re-implements the old C API functions in terms of the
+// new C++ helpers to ease the transition. In the long term, the Rust bindings
+// must be updated properly for the changes to Mojo.
+
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "mojo/public/c/system/types.h"
+#include "mojo/public/cpp/system/handle.h"
+#include "mojo/public/cpp/system/wait.h"
+#include "mojo/public/cpp/system/wait_set.h"
+
+extern "C" {
+
+// These functions support waiting on handle signal changes, e.g. to wait for
+// a pipe to become readable. They used to be in the C API, but now the C API
+// only exposes more primitive building blocks such as traps.
+//
+// We re-implement these functions in terms of the C++ API functions.
+
+MojoResult MojoWait(MojoHandle handle,
+                    MojoHandleSignals signals,
+                    struct MojoHandleSignalsState* signals_state) {
+  return mojo::Wait(mojo::Handle(handle), signals, signals_state);
+}
+
+MojoResult MojoWaitMany(const MojoHandle* raw_handles,
+                        const MojoHandleSignals* signals,
+                        std::size_t num_handles,
+                        std::size_t* result_index,
+                        MojoHandleSignalsState* signals_states) {
+  std::vector<mojo::Handle> handles(num_handles);
+  for (std::size_t i = 0; i < handles.size(); ++i)
+    handles[i] = mojo::Handle(raw_handles[i]);
+  return mojo::WaitMany(handles.data(), signals, num_handles, result_index,
+                        signals_states);
+}
+
+namespace {
+
+// These structs no longer exist in Mojo.
+struct MojoCreateWaitSetOptions;
+struct MojoWaitSetAddOptions;
+
+struct MOJO_ALIGNAS(8) MojoWaitSetResult {
+  std::uint64_t cookie;
+  MojoResult wait_result;
+  std::uint32_t reserved;
+  struct MojoHandleSignalsState signals_state;
+};
+
+struct WaitSetAdapter {
+  mojo::WaitSet wait_set;
+  std::unordered_map<MojoHandle, std::uint64_t> handle_to_cookie;
+  std::unordered_map<std::uint64_t, MojoHandle> cookie_to_handle;
+};
+
+}  // namespace
+
+// Similar to the above, wait sets could wait for one of several handles to be
+// signalled. Unlike WaitMany they maintained a set of handles in their state.
+// They are long gone as first-class objects of the Mojo API. Previously they
+// were owned through MojoHandle just like pipes and buffers. Here this is
+// changed to support casting between wait set handles and pointers.
+//
+// Reimplementing these was a bit more complex since the new C++ API is similar
+// but different in many respects. For example, the old API referred to handles
+// in the set by 64-bit integer handles. The C++ WaitSet does not, so we need to
+// maintain maps in both directions.
+MojoResult MojoCreateWaitSet(const MojoCreateWaitSetOptions*,
+                             std::size_t* handle) {
+  auto adapter = std::make_unique<WaitSetAdapter>();
+  *handle = reinterpret_cast<std::size_t>(adapter.release());
+  return MOJO_RESULT_OK;
+}
+
+MojoResult MojoWaitSetAdd(std::size_t wait_set_handle,
+                          MojoHandle handle,
+                          MojoHandleSignals signals,
+                          std::uint64_t cookie,
+                          const MojoWaitSetAddOptions*) {
+  auto* adapter = reinterpret_cast<WaitSetAdapter*>(wait_set_handle);
+  MojoResult result =
+      adapter->wait_set.AddHandle(mojo::Handle(handle), signals);
+  if (result != MOJO_RESULT_OK)
+    return result;
+  adapter->handle_to_cookie[handle] = cookie;
+  adapter->cookie_to_handle[cookie] = handle;
+  return MOJO_RESULT_OK;
+}
+
+MojoResult MojoWaitSetRemove(std::size_t wait_set_handle,
+                             std::uint64_t cookie) {
+  auto* adapter = reinterpret_cast<WaitSetAdapter*>(wait_set_handle);
+  auto handle_it = adapter->cookie_to_handle.find(cookie);
+  if (handle_it == adapter->cookie_to_handle.end())
+    return MOJO_RESULT_NOT_FOUND;
+
+  MojoResult result =
+      adapter->wait_set.RemoveHandle(mojo::Handle(handle_it->second));
+  if (result != MOJO_RESULT_OK)
+    return result;
+
+  adapter->handle_to_cookie.erase(handle_it->second);
+  adapter->cookie_to_handle.erase(handle_it);
+  return MOJO_RESULT_OK;
+}
+
+MojoResult MojoWaitSetWait(std::size_t wait_set_handle,
+                           std::uint32_t* num_results,
+                           MojoWaitSetResult* results) {
+  std::size_t max_results = *num_results;
+  std::vector<mojo::Handle> ready_handles(max_results);
+  std::vector<MojoResult> ready_results(max_results);
+  std::vector<MojoHandleSignalsState> signals_states(max_results);
+
+  std::size_t num_ready_handles = max_results;
+
+  auto* adapter = reinterpret_cast<WaitSetAdapter*>(wait_set_handle);
+  adapter->wait_set.Wait(nullptr, &num_ready_handles, ready_handles.data(),
+                         ready_results.data(), signals_states.data());
+
+  for (std::size_t i = 0; i < num_ready_handles; ++i) {
+    results[i].cookie = adapter->handle_to_cookie.at(ready_handles[i].value());
+    results[i].wait_result = ready_results[i];
+    results[i].reserved = 0;
+    results[i].signals_state = signals_states[i];
+  }
+
+  *num_results = num_ready_handles;
+
+  return MOJO_RESULT_OK;
+}
+
+}  // extern "C"
diff --git a/mojo/public/rust/system/core.rs b/mojo/public/rust/system/core.rs
index 9a958ea2..3d21627 100644
--- a/mojo/public/rust/system/core.rs
+++ b/mojo/public/rust/system/core.rs
@@ -3,13 +3,12 @@
 // found in the LICENSE file.
 
 use std::ptr;
-use std::u32;
 use std::vec;
 
-use system::ffi;
+use crate::system::ffi;
 // This full import is intentional; nearly every type in mojo_types needs to be used.
-use system::handle;
-use system::mojo_types::*;
+use crate::system::handle;
+use crate::system::mojo_types::*;
 
 /// Get the time ticks now according to the Mojo IPC. As
 /// can be seen in the documentation for the Mojo C API,
@@ -25,29 +24,21 @@
 /// are triggered, waiting for a maximum global time of 'deadline'.
 /// This function blocks.
 pub fn wait_many(
-    handles: &[&handle::Handle],
+    handles: &[&dyn handle::Handle],
     signals: &[HandleSignals],
     states: &mut [SignalsState],
-    deadline: MojoDeadline,
-) -> (i32, MojoResult) {
+) -> (isize, MojoResult) {
     assert_eq!(handles.len(), signals.len());
     assert!(states.len() == handles.len() || states.len() == 0);
     let num_inputs = handles.len();
     if num_inputs == 0 {
         let result = MojoResult::from_code(unsafe {
-            ffi::MojoWaitMany(
-                ptr::null(),
-                ptr::null(),
-                0,
-                deadline,
-                ptr::null_mut(),
-                ptr::null_mut(),
-            )
+            ffi::MojoWaitMany(ptr::null(), ptr::null(), 0, ptr::null_mut(), ptr::null_mut())
         });
         return (-1, result);
     }
     let states_ptr = if states.len() != 0 { states.as_mut_ptr() } else { ptr::null_mut() };
-    let mut index: u32 = u32::MAX;
+    let mut index: usize = usize::MAX;
     let result = unsafe {
         let mut raw_handles: vec::Vec<MojoHandle> = vec::Vec::with_capacity(num_inputs);
         for handle in handles.iter() {
@@ -56,11 +47,10 @@
         MojoResult::from_code(ffi::MojoWaitMany(
             raw_handles.as_ptr(),
             signals.as_ptr(),
-            num_inputs as u32,
-            deadline,
-            &mut index as *mut u32,
+            num_inputs,
+            &mut index as *mut usize,
             states_ptr,
         ))
     };
-    (index as i32, result)
+    (index as isize, result)
 }
diff --git a/mojo/public/rust/system/data_pipe.rs b/mojo/public/rust/system/data_pipe.rs
index d9a4061d..ce466ef 100644
--- a/mojo/public/rust/system/data_pipe.rs
+++ b/mojo/public/rust/system/data_pipe.rs
@@ -9,11 +9,11 @@
 use std::slice;
 use std::vec;
 
-use system::ffi;
+use crate::system::ffi;
 // This full import is intentional; nearly every type in mojo_types needs to be used.
-use system::handle;
-use system::handle::{CastHandle, Handle};
-use system::mojo_types::*;
+use crate::system::handle;
+use crate::system::handle::{CastHandle, Handle};
+use crate::system::mojo_types::*;
 
 #[repr(u32)]
 /// Create flags for data pipes
@@ -74,11 +74,7 @@
     /// commit, consumes self, otherwise returns self to try again.
     pub fn commit(self, bytes_read: usize) -> Option<(Self, MojoResult)> {
         let result = unsafe { self.parent.end_read(bytes_read) };
-        if result == MojoResult::Okay {
-            None
-        } else {
-            Some((self, result))
-        }
+        if result == MojoResult::Okay { None } else { Some((self, result)) }
     }
 
     /// Returns the length of the underlying buffer
@@ -128,11 +124,7 @@
     /// commit, consumes self, otherwise returns self to try again.
     pub fn commit(self, bytes_written: usize) -> Option<(Self, MojoResult)> {
         let result = unsafe { self.parent.end_write(bytes_written) };
-        if result == MojoResult::Okay {
-            None
-        } else {
-            Some((self, result))
-        }
+        if result == MojoResult::Okay { None } else { Some((self, result)) }
     }
 
     /// Returns the length of the underlying buffer
@@ -184,13 +176,7 @@
     capacity: u32,
 ) -> Result<(Consumer<T>, Producer<T>), MojoResult> {
     let elem_size = mem::size_of::<T>() as u32;
-    let opts = ffi::MojoCreateDataPipeOptions {
-        struct_size: mem::size_of::<ffi::MojoCreateDataPipeOptions>() as u32,
-        flags: flags,
-        element_num_bytes: elem_size,
-        capacity_num_bytes: capacity * elem_size,
-        _align: [],
-    };
+    let opts = ffi::MojoCreateDataPipeOptions::new(flags, elem_size, capacity * elem_size);
     // TODO(mknyszek): Make sure handles are valid
     let mut chandle: MojoHandle = 0;
     let mut phandle: MojoHandle = 0;
@@ -240,41 +226,40 @@
     /// Perform a read operation on the consumer end of the data pipe. As
     /// a result, we get an std::vec::Vec filled with whatever was written.
     pub fn read(&self, flags: ReadFlags) -> Result<vec::Vec<T>, MojoResult> {
+        let mut options = ffi::MojoReadDataOptions::new(Read::Query as ReadFlags);
         let mut num_bytes: u32 = 0;
         let r_prelim = unsafe {
             ffi::MojoReadData(
                 self.handle.get_native_handle(),
+                &options as *const _,
                 ptr::null_mut() as *mut ffi::c_void,
                 &mut num_bytes as *mut u32,
-                1 << 2 as ReadFlags,
             )
         };
         if r_prelim != 0 || num_bytes == 0 {
             return Err(MojoResult::from_code(r_prelim));
         }
+
+        options.flags = flags;
         let elem_size: u32 = mem::size_of::<T>() as u32;
         // TODO(mknyszek): make sure elem_size divides into num_bytes
         let mut buf: vec::Vec<T> = vec::Vec::with_capacity((num_bytes / elem_size) as usize);
         let r = MojoResult::from_code(unsafe {
             ffi::MojoReadData(
                 self.handle.get_native_handle(),
+                &options as *const _,
                 buf.as_mut_ptr() as *const ffi::c_void,
                 &mut num_bytes as *mut u32,
-                flags,
             )
         });
         unsafe { buf.set_len((num_bytes / elem_size) as usize) }
-        if r != MojoResult::Okay {
-            Err(r)
-        } else {
-            Ok(buf)
-        }
+        if r != MojoResult::Okay { Err(r) } else { Ok(buf) }
     }
 
     /// Start two-phase read and return a ReadDataBuffer to perform
     /// read and commit.
-    pub fn begin(&self, flags: ReadFlags) -> Result<ReadDataBuffer<T>, MojoResult> {
-        let wrapped_result = unsafe { self.begin_read(flags) };
+    pub fn begin(&self) -> Result<ReadDataBuffer<T>, MojoResult> {
+        let wrapped_result = unsafe { self.begin_read() };
         match wrapped_result {
             Ok(arr) => Ok(ReadDataBuffer::<T> { buffer: arr, parent: self }),
             Err(r) => Err(r),
@@ -284,14 +269,14 @@
     /// A private function that performs the first half of two-phase reading.
     /// Kept private because it is unsafe to use (the array received may not
     /// be valid if end_read is performed).
-    unsafe fn begin_read(&self, flags: ReadFlags) -> Result<&[T], MojoResult> {
+    unsafe fn begin_read(&self) -> Result<&[T], MojoResult> {
         let mut buf_num_bytes: u32 = 0;
-        let mut pbuf: *mut ffi::c_void = mem::uninitialized();
+        let mut pbuf: *mut ffi::c_void = ptr::null_mut();
         let r = MojoResult::from_code(ffi::MojoBeginReadData(
             self.handle.get_native_handle(),
+            ptr::null(),
             &mut pbuf,
             &mut buf_num_bytes as *mut u32,
-            flags,
         ));
         if r != MojoResult::Okay {
             Err(r)
@@ -315,6 +300,7 @@
         MojoResult::from_code(ffi::MojoEndReadData(
             self.handle.get_native_handle(),
             (elems_read * elem_size) as u32,
+            ptr::null(),
         ))
     }
 }
@@ -359,19 +345,16 @@
     /// Returns the number of elements actually written.
     pub fn write(&self, data: &[T], flags: WriteFlags) -> Result<usize, MojoResult> {
         let mut num_bytes = (data.len() * mem::size_of::<T>()) as u32;
+        let options = ffi::MojoWriteDataOptions::new(flags);
         let r = MojoResult::from_code(unsafe {
             ffi::MojoWriteData(
                 self.handle.get_native_handle(),
                 data.as_ptr() as *const ffi::c_void,
                 &mut num_bytes as *mut u32,
-                flags,
+                &options as *const _,
             )
         });
-        if r != MojoResult::Okay {
-            Err(r)
-        } else {
-            Ok(num_bytes as usize)
-        }
+        if r != MojoResult::Okay { Err(r) } else { Ok(num_bytes as usize) }
     }
 
     /// Start two-phase write and return a WriteDataBuffer to perform
@@ -379,8 +362,8 @@
     ///
     /// Borrows self as mutable so that no other operation may happen on
     /// the producer until the two-phase write is committed.
-    pub fn begin(&self, flags: WriteFlags) -> Result<WriteDataBuffer<T>, MojoResult> {
-        let wrapped_result = unsafe { self.begin_write(flags) };
+    pub fn begin(&self) -> Result<WriteDataBuffer<T>, MojoResult> {
+        let wrapped_result = unsafe { self.begin_write() };
         match wrapped_result {
             Ok(arr) => Ok(WriteDataBuffer::<T> { buffer: arr, parent: self }),
             Err(r) => Err(r),
@@ -390,14 +373,14 @@
     /// A private function that performs the first half of two-phase writing.
     /// Kept private because it is unsafe to use (the array received may not
     /// be valid if end_write is performed).
-    unsafe fn begin_write(&self, flags: WriteFlags) -> Result<&mut [T], MojoResult> {
+    unsafe fn begin_write(&self) -> Result<&mut [T], MojoResult> {
         let mut buf_num_bytes: u32 = 0;
-        let mut pbuf: *mut ffi::c_void = mem::uninitialized();
+        let mut pbuf: *mut ffi::c_void = ptr::null_mut();
         let r = MojoResult::from_code(ffi::MojoBeginWriteData(
             self.handle.get_native_handle(),
+            ptr::null(),
             &mut pbuf,
             &mut buf_num_bytes as *mut u32,
-            flags,
         ));
         if r != MojoResult::Okay {
             Err(r)
@@ -421,6 +404,7 @@
         MojoResult::from_code(ffi::MojoEndWriteData(
             self.handle.get_native_handle(),
             (elems_written * elem_size) as u32,
+            ptr::null(),
         ))
     }
 }
diff --git a/mojo/public/rust/system/ffi.rs b/mojo/public/rust/system/ffi.rs
index 12615bf0..8de038d 100644
--- a/mojo/public/rust/system/ffi.rs
+++ b/mojo/public/rust/system/ffi.rs
@@ -13,9 +13,14 @@
 //! elaborating on these all again here.
 //!
 //! [1] https://github.com/domokit/mojo
+//!
+//! TODO(https://crbug.com/1274864):
+//! * Remove references to the now-nonexistent mojo Github
+//! * Automatically generate these FFI bindings, or at least add validation
+//!   (a la cxx)
 
 // This full import is intentional; nearly every type in mojo_types needs to be used.
-use system::mojo_types::*;
+use crate::system::mojo_types::*;
 
 #[allow(bad_style)]
 /// This empty enum is used solely to provide
@@ -34,13 +39,20 @@
 
     pub type MojoCreateSharedBufferOptionsFlags = u32;
     pub type MojoDuplicateBufferHandleOptionsFlags = u32;
-    pub type MojoBufferInfoFlags = u32;
+    pub type MojoGetBufferInfoFlags = u32;
     pub type MojoMapBufferFlags = u32;
     pub type MojoCreateDataPipeOptionsFlags = u32;
     pub type MojoWriteDataFlags = u32;
+    pub type MojoBeginWriteDataFlags = u32;
+    pub type MojoEndWriteDataFlags = u32;
     pub type MojoReadDataFlags = u32;
+    pub type MojoBeginReadDataFlags = u32;
+    pub type MojoEndReadDataFlags = u32;
     pub type MojoHandleSignals = u32;
     pub type MojoCreateMessagePipeOptionsFlags = u32;
+    pub type MojoCreateMessageFlags = u32;
+    pub type MojoAppendMessageDataFlags = u32;
+    pub type MojoGetMessageDataFlags = u32;
     pub type MojoWriteMessageFlags = u32;
     pub type MojoReadMessageFlags = u32;
     pub type MojoCreateWaitSetOptionsFlags = u32;
@@ -48,66 +60,67 @@
     pub type MojoResultCode = u32;
 }
 
-use system::ffi::types::*;
+use crate::system::ffi::types::*;
 
-#[repr(C)]
-pub struct MojoCreateSharedBufferOptions {
-    pub struct_size: u32,
-    pub flags: MojoCreateSharedBufferOptionsFlags,
-    pub _align: [u64; 0], // Hack to align struct to 8 byte boundary
+// Most FFI functions take an options struct as input. Each one contains a `struct_size` member for versioning. To reduce boilerplate, make a macro to define each struct with a `new` function that fills in the size.
+// The macro is used as follows: declare_mojo_options!(<struct name>, <struct member 1>, <struct member 2>, ...)
+macro_rules! declare_mojo_options {
+    ($name:ident, $( $mem:ident : $t:ty ),*) => {
+        // Mojo requires each options struct to be 8-byte aligned.
+        #[repr(C, align(8))]
+        pub struct $name {
+            // This field is intentionally private.
+            struct_size: u32,
+            $(pub $mem : $t),*
+        }
+
+        impl $name {
+            // Avoid a warning if nobody ever uses this function.
+            #[allow(dead_code)]
+            pub fn new($($mem : $t),*) -> $name {
+                $name {
+                    struct_size: ::std::mem::size_of::<$name>() as u32,
+                    $($mem : $mem),*
+                }
+            }
+        }
+    }
 }
 
-#[repr(C)]
-pub struct MojoDuplicateBufferHandleOptions {
-    pub struct_size: u32,
-    pub flags: MojoDuplicateBufferHandleOptionsFlags,
-    pub _align: [u64; 0], // Hack to align struct to 8 byte boundary
-}
+declare_mojo_options!(MojoCreateSharedBufferOptions, flags: MojoCreateSharedBufferOptionsFlags);
+declare_mojo_options!(MojoGetBufferInfoOptions, flags: MojoGetBufferInfoFlags);
+declare_mojo_options!(MojoMapBufferOptions, flags: MojoMapBufferFlags);
+declare_mojo_options!(
+    MojoDuplicateBufferHandleOptions,
+    flags: MojoDuplicateBufferHandleOptionsFlags
+);
+declare_mojo_options!(MojoSharedBufferInfo, size: u64);
+declare_mojo_options!(
+    MojoCreateDataPipeOptions,
+    flags: MojoCreateDataPipeOptionsFlags,
+    element_num_bytes: u32,
+    capacity_num_bytes: u32
+);
+declare_mojo_options!(MojoWriteDataOptions, flags: MojoWriteDataFlags);
+declare_mojo_options!(MojoBeginWriteDataOptions, flags: MojoBeginWriteDataFlags);
+declare_mojo_options!(MojoEndWriteDataOptions, flags: MojoEndWriteDataFlags);
+declare_mojo_options!(MojoReadDataOptions, flags: MojoReadDataFlags);
+declare_mojo_options!(MojoBeginReadDataOptions, flags: MojoBeginReadDataFlags);
+declare_mojo_options!(MojoEndReadDataOptions, flags: MojoEndReadDataFlags);
+declare_mojo_options!(MojoCreateMessagePipeOptions, flags: MojoCreateMessagePipeOptionsFlags);
+declare_mojo_options!(MojoWriteMessageOptions, flags: MojoWriteMessageFlags);
+declare_mojo_options!(MojoReadMessageOptions, flags: MojoReadMessageFlags);
+declare_mojo_options!(MojoCreateMessageOptions, flags: MojoCreateMessageFlags);
+declare_mojo_options!(MojoAppendMessageDataOptions, flags: MojoAppendMessageDataFlags);
+declare_mojo_options!(MojoGetMessageDataOptions, flags: MojoGetMessageDataFlags);
+declare_mojo_options!(MojoCreateWaitSetOptions, flags: MojoCreateWaitSetOptionsFlags);
+declare_mojo_options!(MojoWaitSetAddOptions, flags: MojoWaitSetAddOptionsFlags);
 
-#[repr(C)]
-pub struct MojoBufferInformation {
-    pub struct_size: u32,
-    pub flags: MojoBufferInfoFlags,
-    pub num_bytes: u64,
-    pub _align: [u64; 0], // Hack to align struct to 8 byte boundary
-}
-
-#[repr(C)]
-pub struct MojoCreateDataPipeOptions {
-    pub struct_size: u32,
-    pub flags: MojoCreateDataPipeOptionsFlags,
-    pub element_num_bytes: u32,
-    pub capacity_num_bytes: u32,
-    pub _align: [u64; 0], // Hack to align struct to 8 byte boundary
-}
-
-#[repr(C)]
-pub struct MojoCreateMessagePipeOptions {
-    pub struct_size: u32,
-    pub flags: MojoCreateMessagePipeOptionsFlags,
-    pub _align: [u64; 0], // Hack to align struct to 8 byte boundary
-}
-
-#[repr(C)]
-pub struct MojoCreateWaitSetOptions {
-    pub struct_size: u32,
-    pub flags: MojoCreateWaitSetOptionsFlags,
-    pub _align: [u64; 0], // Hack to align struct to 8 byte boundary
-}
-
-#[repr(C)]
-pub struct MojoWaitSetAddOptions {
-    pub struct_size: u32,
-    pub flags: MojoWaitSetAddOptionsFlags,
-    pub _align: [u64; 0], // Hack to align struct to 8 byte boundary
-}
-
-#[link]
 extern "C" {
     // From //mojo/public/c/include/mojo/system/buffer.h
     pub fn MojoCreateSharedBuffer(
-        options: *const MojoCreateSharedBufferOptions,
         num_bytes: u64,
+        options: *const MojoCreateSharedBufferOptions,
         shared_buffer_handle: *mut MojoHandle,
     ) -> MojoResultCode;
 
@@ -117,18 +130,18 @@
         new_buffer_handle: *mut MojoHandle,
     ) -> MojoResultCode;
 
-    pub fn MojoGetBufferInformation(
+    pub fn MojoGetBufferInfo(
         buffer_handle: MojoHandle,
-        info: *mut MojoBufferInformation,
-        info_num_bytes: u32,
+        options: *const MojoGetBufferInfoOptions,
+        info: *mut MojoSharedBufferInfo,
     ) -> MojoResultCode;
 
     pub fn MojoMapBuffer(
         buffer_handle: MojoHandle,
         offset: u64,
         num_bytes: u64,
+        options: *const MojoMapBufferOptions,
         buffer: *mut *mut c_void,
-        flags: MojoMapBufferFlags,
     ) -> MojoResultCode;
 
     pub fn MojoUnmapBuffer(buffer: *const c_void) -> MojoResultCode;
@@ -144,38 +157,40 @@
         data_pipe_producer_handle: MojoHandle,
         elements: *const c_void,
         num_bytes: *mut u32,
-        flags: MojoWriteDataFlags,
+        options: *const MojoWriteDataOptions,
     ) -> MojoResultCode;
 
     pub fn MojoBeginWriteData(
         data_pipe_producer_handle: MojoHandle,
+        options: *const MojoBeginWriteDataOptions,
         buffer: *mut *mut c_void,
         buffer_num_bytes: *mut u32,
-        flags: MojoWriteDataFlags,
     ) -> MojoResultCode;
 
     pub fn MojoEndWriteData(
         data_pipe_producer_handle: MojoHandle,
         num_bytes_written: u32,
+        options: *const MojoEndWriteDataOptions,
     ) -> MojoResultCode;
 
     pub fn MojoReadData(
         data_pipe_consumer_handle: MojoHandle,
+        options: *const MojoReadDataOptions,
         elements: *const c_void,
         num_bytes: *mut u32,
-        flags: MojoReadDataFlags,
     ) -> MojoResultCode;
 
     pub fn MojoBeginReadData(
         data_pipe_consumer_handle: MojoHandle,
+        options: *const MojoBeginReadDataOptions,
         buffer: *mut *mut c_void,
         buffer_num_bytes: *mut u32,
-        flags: MojoReadDataFlags,
     ) -> MojoResultCode;
 
     pub fn MojoEndReadData(
         data_pipe_consumer_handle: MojoHandle,
         num_bytes_written: u32,
+        options: *const MojoEndReadDataOptions,
     ) -> MojoResultCode;
 
     // From //mojo/public/c/include/mojo/system/handle.h
@@ -190,20 +205,40 @@
 
     pub fn MojoWriteMessage(
         message_pipe_handle: MojoHandle,
-        bytes: *const c_void,
-        num_bytes: u32,
-        handles: *const MojoHandle,
-        num_handles: u32,
-        flags: MojoWriteMessageFlags,
+        message_handle: MojoMessageHandle,
+        options: *const MojoWriteMessageOptions,
     ) -> MojoResultCode;
 
     pub fn MojoReadMessage(
         message_pipe_handle: MojoHandle,
-        bytes: *mut c_void,
+        options: *const MojoReadMessageOptions,
+        message_handle: *mut MojoMessageHandle,
+    ) -> MojoResultCode;
+
+    pub fn MojoCreateMessage(
+        options: *const MojoCreateMessageOptions,
+        message_handle: *mut MojoMessageHandle,
+    ) -> MojoResultCode;
+
+    pub fn MojoDestroyMessage(message_handle: MojoMessageHandle) -> MojoResultCode;
+
+    pub fn MojoAppendMessageData(
+        message_handle: MojoMessageHandle,
+        payload_size: u32,
+        handles: *const MojoHandle,
+        num_handles: u32,
+        options: *const MojoAppendMessageDataOptions,
+        buffer: *mut *mut c_void,
+        buffer_size: *mut u32,
+    ) -> MojoResultCode;
+
+    pub fn MojoGetMessageData(
+        message_handle: MojoMessageHandle,
+        options: *const MojoGetMessageDataOptions,
+        buffer: *mut *const c_void,
         num_bytes: *mut u32,
         handles: *mut MojoHandle,
         num_handles: *mut u32,
-        flags: MojoWriteMessageFlags,
     ) -> MojoResultCode;
 
     // From //mojo/public/c/include/mojo/system/time.h
@@ -213,40 +248,36 @@
     pub fn MojoWait(
         handle: MojoHandle,
         signals: HandleSignals,
-        deadline: MojoDeadline,
         signals_state: *mut SignalsState,
     ) -> MojoResultCode;
 
     pub fn MojoWaitMany(
         handles: *const MojoHandle,
         signals: *const HandleSignals,
-        num_handles: u32,
-        deadline: MojoDeadline,
-        result_index: *mut u32,
+        num_handles: usize,
+        result_index: *mut usize,
         signals_states: *mut SignalsState,
     ) -> MojoResultCode;
 
     // From //mojo/public/c/include/mojo/system/wait_set.h
     pub fn MojoCreateWaitSet(
         options: *const MojoCreateWaitSetOptions,
-        handle: *mut MojoHandle,
+        handle: *mut MojoWaitSetHandle,
     ) -> MojoResultCode;
 
     pub fn MojoWaitSetAdd(
-        wait_set_handle: MojoHandle,
+        wait_set_handle: MojoWaitSetHandle,
         handle: MojoHandle,
         signals: HandleSignals,
         cookie: u64,
         options: *const MojoWaitSetAddOptions,
     ) -> MojoResultCode;
 
-    pub fn MojoWaitSetRemove(wait_set_handle: MojoHandle, cookie: u64) -> MojoResultCode;
+    pub fn MojoWaitSetRemove(wait_set_handle: MojoWaitSetHandle, cookie: u64) -> MojoResultCode;
 
     pub fn MojoWaitSetWait(
-        wait_set_handle: MojoHandle,
-        deadline: MojoDeadline,
+        wait_set_handle: MojoWaitSetHandle,
         num_results: *mut u32,
         results: *mut WaitSetResult,
-        max_results: *mut u32,
     ) -> MojoResultCode;
 }
diff --git a/mojo/public/rust/system/handle.rs b/mojo/public/rust/system/handle.rs
index 7cd8e3a..2fd39fb 100644
--- a/mojo/public/rust/system/handle.rs
+++ b/mojo/public/rust/system/handle.rs
@@ -13,9 +13,9 @@
 //! data pipes, and shared buffers. Typed handles wrap untyped handles
 //! but act much the same as untyped handles.
 
-use system::ffi;
+use crate::system::ffi;
 // This full import is intentional; nearly every type in mojo_types needs to be used.
-use system::mojo_types::*;
+use crate::system::mojo_types::*;
 
 /// The CastHandle trait defines an interface to convert between
 /// typed and untyped handles. These are only used internally for
@@ -42,20 +42,14 @@
     fn get_native_handle(&self) -> MojoHandle;
 
     /// Waits on the handle wrapped in the current struct until the signals
-    /// declared in 'signals' are triggered, waiting for a maximum time of
-    /// 'deadline'. This method blocks.
+    /// declared in 'signals' are triggered.
     ///
     /// Returns the satisfied and satisfiable signals respectively for this
     /// handle when waiting is done.
-    fn wait(&self, signals: HandleSignals, deadline: MojoDeadline) -> (SignalsState, MojoResult) {
+    fn wait(&self, signals: HandleSignals) -> (SignalsState, MojoResult) {
         let mut state: SignalsState = Default::default();
         let r = unsafe {
-            ffi::MojoWait(
-                self.get_native_handle(),
-                signals,
-                deadline,
-                &mut state as *mut SignalsState,
-            )
+            ffi::MojoWait(self.get_native_handle(), signals, &mut state as *mut SignalsState)
         };
         (state, MojoResult::from_code(r))
     }
diff --git a/mojo/public/rust/system/message_pipe.rs b/mojo/public/rust/system/message_pipe.rs
index 19f46c2..6e2f5bdd 100644
--- a/mojo/public/rust/system/message_pipe.rs
+++ b/mojo/public/rust/system/message_pipe.rs
@@ -2,15 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use std::mem;
 use std::ptr;
 use std::vec;
 
-use system::ffi;
-use system::handle;
-use system::handle::{CastHandle, Handle};
+use std::convert::TryInto;
+
+use crate::system::ffi;
+use crate::system::handle;
+use crate::system::handle::{CastHandle, Handle};
 // This full import is intentional; nearly every type in mojo_types needs to be used.
-use system::mojo_types::*;
+use crate::system::mojo_types::*;
+
+use ffi::c_void;
 
 #[repr(u32)]
 /// Create flags for message pipes
@@ -28,11 +31,38 @@
 /// Read flags for message pipes
 pub enum Read {
     None = 0,
+}
 
-    /// If the message is unable to be
-    /// read for whatever reason, dequeue
-    /// it anyway
-    MayDiscard = 1 << 0,
+#[repr(u32)]
+/// Create message flags
+pub enum CreateMessage {
+    None = 0,
+
+    /// Do not enforce size restrictions on this message, allowing its serialized
+    /// payload to grow arbitrarily large. If this flag is NOT specified, Mojo will
+    /// throw an assertion failure at serialization time when the message exceeds a
+    /// globally configured maximum size.
+    UnlimitedSize = 1 << 0,
+}
+
+#[repr(u32)]
+/// Append message flags
+pub enum AppendMessage {
+    None = 0,
+
+    /// If set, this comments the resulting (post-append) message size as the final
+    /// size of the message payload, in terms of both bytes and attached handles.
+    CommitSize = 1 << 0,
+}
+
+#[repr(u32)]
+/// Read message flags
+pub enum ReadMessage {
+    None = 0,
+
+    /// Ignores attached handles when retrieving message data. This leaves any
+    /// attached handles intact and owned by the message object.
+    IgnoreHandles = 1 << 0,
 }
 
 /// Creates a message pipe in Mojo and gives back two
@@ -41,11 +71,7 @@
 pub fn create(flags: CreateFlags) -> Result<(MessageEndpoint, MessageEndpoint), MojoResult> {
     let mut handle0: MojoHandle = 0;
     let mut handle1: MojoHandle = 0;
-    let opts = ffi::MojoCreateMessagePipeOptions {
-        struct_size: mem::size_of::<ffi::MojoCreateMessagePipeOptions>() as u32,
-        flags: flags,
-        _align: [],
-    };
+    let opts = ffi::MojoCreateMessagePipeOptions::new(flags);
     let raw_opts = &opts as *const ffi::MojoCreateMessagePipeOptions;
     let r = MojoResult::from_code(unsafe {
         ffi::MojoCreateMessagePipe(
@@ -86,49 +112,71 @@
     /// is received, it will show up as an Err() containing MojoResult::Okay.
     pub fn read(
         &self,
-        flags: ReadFlags,
+        _flags: ReadFlags,
     ) -> Result<(vec::Vec<u8>, vec::Vec<handle::UntypedHandle>), MojoResult> {
+        // Read the message, yielding a message object we can copy data from.
+        let message_handle = {
+            let mut h = 0;
+            let result = MojoResult::from_code(unsafe {
+                ffi::MojoReadMessage(self.handle.get_native_handle(), ptr::null(), &mut h as *mut _)
+            });
+            if result != MojoResult::Okay {
+                return Err(result);
+            }
+            h
+        };
+
+        let mut buffer: *const c_void = ptr::null();
         let mut num_bytes: u32 = 0;
         let mut num_handles: u32 = 0;
         let result_prelim = MojoResult::from_code(unsafe {
-            ffi::MojoReadMessage(
-                self.handle.get_native_handle(),
+            ffi::MojoGetMessageData(
+                message_handle,
+                ptr::null(),
+                &mut buffer as *mut _,
+                &mut num_bytes as *mut _,
                 ptr::null_mut(),
-                &mut num_bytes as *mut u32,
-                ptr::null_mut(),
-                &mut num_handles as *mut u32,
-                flags,
+                &mut num_handles as *mut _,
             )
         });
-        if result_prelim != MojoResult::ResourceExhausted {
+        if result_prelim != MojoResult::Okay && result_prelim != MojoResult::ResourceExhausted {
             return Err(result_prelim);
         }
-        let mut buf: vec::Vec<u8> = vec::Vec::with_capacity(num_bytes as usize);
+
         let mut raw_handles: vec::Vec<MojoHandle> = vec::Vec::with_capacity(num_handles as usize);
-        let buf_ptr;
-        if num_bytes == 0 {
-            buf_ptr = ptr::null_mut();
-        } else {
-            buf_ptr = buf.as_mut_ptr() as *mut ffi::c_void;
+        if num_handles > 0 {
+            let raw_handles_ptr = raw_handles.as_mut_ptr();
+            let result = MojoResult::from_code(unsafe {
+                ffi::MojoGetMessageData(
+                    message_handle,
+                    ptr::null(),
+                    &mut buffer as *mut _,
+                    &mut num_bytes as *mut _,
+                    raw_handles_ptr,
+                    &mut num_handles as *mut _,
+                )
+            });
+            if result != MojoResult::Okay {
+                return Err(result);
+            }
         }
-        let raw_handles_ptr;
-        if num_handles == 0 {
-            raw_handles_ptr = ptr::null_mut();
+
+        let data: Vec<u8> = if num_bytes > 0 {
+            assert_ne!(buffer, ptr::null());
+            // Will not panic if usize has at least 32 bits, which is true for our targets
+            let buffer_size: usize = num_bytes.try_into().unwrap();
+            // MojoGetMessageData points us to the data with a c_void pointer and a length. This
+            // is only available until we destroy the message. We want to copy this into our own
+            // Vec. Read the buffer as a slice, which is safe.
+            unsafe {
+                let buffer_slice = std::slice::from_raw_parts(buffer.cast(), buffer_size);
+                buffer_slice.to_vec()
+            }
         } else {
-            raw_handles_ptr = raw_handles.as_mut_ptr();
-        }
-        let r = MojoResult::from_code(unsafe {
-            ffi::MojoReadMessage(
-                self.handle.get_native_handle(),
-                buf_ptr,
-                &mut num_bytes as *mut u32,
-                raw_handles_ptr,
-                &mut num_handles as *mut u32,
-                flags,
-            )
-        });
+            Vec::new()
+        };
+
         unsafe {
-            buf.set_len(num_bytes as usize);
             raw_handles.set_len(num_handles as usize);
         }
         let mut handles: vec::Vec<handle::UntypedHandle> =
@@ -136,11 +184,12 @@
         for raw_handle in raw_handles.iter() {
             handles.push(unsafe { handle::acquire(*raw_handle) });
         }
-        if r != MojoResult::Okay {
-            Err(r)
-        } else {
-            Ok((buf, handles))
+
+        unsafe {
+            ffi::MojoDestroyMessage(message_handle);
         }
+
+        Ok((data, handles))
     }
 
     /// Write a message to the endpoint. Messages in Mojo
@@ -164,12 +213,15 @@
         mut handles: vec::Vec<handle::UntypedHandle>,
         flags: WriteFlags,
     ) -> MojoResult {
-        let bytes_ptr;
-        if bytes.len() == 0 {
-            bytes_ptr = ptr::null();
-        } else {
-            bytes_ptr = bytes.as_ptr() as *const ffi::c_void;
-        }
+        // Create the message object we will write data into then send.
+        let message_handle = unsafe {
+            let mut h = 0;
+            let result_code = ffi::MojoCreateMessage(std::ptr::null(), &mut h as *mut _);
+            assert_eq!(MojoResult::Okay, MojoResult::from_code(result_code));
+            h
+        };
+
+        // "Append" to the message, getting a buffer to copy our data to.
         let mut raw_handles: vec::Vec<MojoHandle> = vec::Vec::with_capacity(handles.len());
         for handle in handles.iter_mut() {
             unsafe {
@@ -177,20 +229,60 @@
                 handle.invalidate();
             }
         }
+
         let raw_handles_ptr;
         if raw_handles.len() == 0 {
             raw_handles_ptr = ptr::null();
         } else {
             raw_handles_ptr = raw_handles.as_ptr();
         }
-        return MojoResult::from_code(unsafe {
-            ffi::MojoWriteMessage(
-                self.handle.get_native_handle(),
-                bytes_ptr,
+
+        let mut buffer_ptr: *mut c_void = std::ptr::null_mut();
+        let mut buffer_size: u32 = 0;
+
+        let append_message_options =
+            ffi::MojoAppendMessageDataOptions::new(AppendMessage::CommitSize as u32);
+
+        let result = MojoResult::from_code(unsafe {
+            ffi::MojoAppendMessageData(
+                message_handle,
                 bytes.len() as u32,
                 raw_handles_ptr,
                 raw_handles.len() as u32,
-                flags,
+                &append_message_options as *const _,
+                &mut buffer_ptr as *mut _,
+                &mut buffer_size as *mut _,
+            )
+        });
+
+        if result != MojoResult::Okay {
+            return result;
+        }
+
+        // Copy into the message storage
+        if bytes.len() > 0 {
+            // Will not panic if usize has at least 32 bits, which is true for our targets
+            let buffer_size: usize = buffer_size.try_into().unwrap();
+            assert!(bytes.len() <= buffer_size);
+            assert_ne!(buffer_ptr, ptr::null_mut());
+            // MojoAppendMessageData tells us where to write with a c_void pointer and a length.
+            // This is only available until we destroy or send the message. We can view this
+            // through a slice and copy our `bytes` into it.
+            unsafe {
+                // We know `bytes.len() <= buffer_size`, and `buffer_size` is the limit of the
+                // provided buffer.
+                let buffer_slice = std::slice::from_raw_parts_mut(buffer_ptr.cast(), bytes.len());
+                buffer_slice.copy_from_slice(bytes);
+            }
+        }
+
+        // Send the message. This takes ownership of the message object.
+        let write_message_options = ffi::MojoWriteMessageOptions::new(flags);
+        return MojoResult::from_code(unsafe {
+            ffi::MojoWriteMessage(
+                self.handle.get_native_handle(),
+                message_handle,
+                &write_message_options as *const _,
             )
         });
     }
diff --git a/mojo/public/rust/system/mod.rs b/mojo/public/rust/system/mod.rs
index 0258e79..906e8722 100644
--- a/mojo/public/rust/system/mod.rs
+++ b/mojo/public/rust/system/mod.rs
@@ -14,5 +14,5 @@
 
 // In order to keep the interface clean, we re-export basic Mojo and handle
 // types and traits here in the system module.
-pub use system::handle::*;
-pub use system::mojo_types::*;
+pub use crate::system::handle::*;
+pub use crate::system::mojo_types::*;
diff --git a/mojo/public/rust/system/mojo_types.rs b/mojo/public/rust/system/mojo_types.rs
index 1e9a67b..d71609b 100644
--- a/mojo/public/rust/system/mojo_types.rs
+++ b/mojo/public/rust/system/mojo_types.rs
@@ -14,13 +14,19 @@
 //! a whole because it is intended to be used that way. It contains
 //! all of the basic types needed by all system-level Mojo bindings.
 
+use crate::system::ffi::types::*;
 use std::fmt;
 use std::u64;
-use system::ffi::types::*;
 
 /// A MojoHandle is represented as a plain 32-bit unsigned int.
 pub type MojoHandle = u32;
 
+/// An opaque pointer to a wait set. Since the C bindings no longer have wait sets, our glue code creates a C++ mojo::WaitSet object and returns it as an opaque pointer.
+pub type MojoWaitSetHandle = usize;
+
+/// From //mojo/public/c/system/message_pipe.h. Represents a message object.
+pub type MojoMessageHandle = usize;
+
 /// Represents time ticks as specified by Mojo. A time tick value
 /// is meaningless when not used relative to another time tick.
 pub type MojoTimeTicks = i64;
@@ -35,6 +41,9 @@
 pub type MapFlags = u32;
 pub type WriteFlags = u32;
 pub type ReadFlags = u32;
+pub type CreateMessageFlags = u32;
+pub type AppendMessageFlags = u32;
+pub type GetMessageFlags = u32;
 pub type AddFlags = u32;
 
 /// MojoResult represents anything that can happen
@@ -46,24 +55,24 @@
 #[derive(Copy, Clone, Debug, PartialEq)]
 #[repr(u32)]
 pub enum MojoResult {
-    Okay = 0x0,
-    Cancelled = 0x1,
-    Unknown = 0x2,
-    InvalidArgument = 0x3,
-    DeadlineExceeded = 0x4,
-    NotFound = 0x5,
-    AlreadyExists = 0x6,
-    PermissionDenied = 0x7,
-    ResourceExhausted = 0x8,
-    FailedPrecondition = 0x9,
-    Aborted = 0xa,
-    OutOfRange = 0xb,
-    Unimplemented = 0xc,
-    Internal = 0xd,
-    Unavailable = 0xe,
-    DataLoss = 0xf,
-    Busy = 0x0019,
-    ShouldWait = 0x001e,
+    Okay = 0,
+    Cancelled = 1,
+    Unknown = 2,
+    InvalidArgument = 3,
+    DeadlineExceeded = 4,
+    NotFound = 5,
+    AlreadyExists = 6,
+    PermissionDenied = 7,
+    ResourceExhausted = 8,
+    FailedPrecondition = 9,
+    Aborted = 10,
+    OutOfRange = 11,
+    Unimplemented = 12,
+    Internal = 13,
+    Unavailable = 14,
+    DataLoss = 15,
+    Busy = 16,
+    ShouldWait = 17,
     InvalidResult,
 }
 
@@ -72,24 +81,24 @@
     /// into a MojoResult.
     pub fn from_code(code: MojoResultCode) -> MojoResult {
         match code as u32 {
-            0x0 => MojoResult::Okay,
-            0x1 => MojoResult::Cancelled,
-            0x2 => MojoResult::Unknown,
-            0x3 => MojoResult::InvalidArgument,
-            0x4 => MojoResult::DeadlineExceeded,
-            0x5 => MojoResult::NotFound,
-            0x6 => MojoResult::AlreadyExists,
-            0x7 => MojoResult::PermissionDenied,
-            0x8 => MojoResult::ResourceExhausted,
-            0x9 => MojoResult::FailedPrecondition,
-            0xa => MojoResult::Aborted,
-            0xb => MojoResult::OutOfRange,
-            0xc => MojoResult::Unimplemented,
-            0xd => MojoResult::Internal,
-            0xe => MojoResult::Unavailable,
-            0xf => MojoResult::DataLoss,
-            0x0019 => MojoResult::Busy,
-            0x001e => MojoResult::ShouldWait,
+            0 => MojoResult::Okay,
+            1 => MojoResult::Cancelled,
+            2 => MojoResult::Unknown,
+            3 => MojoResult::InvalidArgument,
+            4 => MojoResult::DeadlineExceeded,
+            5 => MojoResult::NotFound,
+            6 => MojoResult::AlreadyExists,
+            7 => MojoResult::PermissionDenied,
+            8 => MojoResult::ResourceExhausted,
+            9 => MojoResult::FailedPrecondition,
+            10 => MojoResult::Aborted,
+            11 => MojoResult::OutOfRange,
+            12 => MojoResult::Unimplemented,
+            13 => MojoResult::Internal,
+            14 => MojoResult::Unavailable,
+            15 => MojoResult::DataLoss,
+            16 => MojoResult::Busy,
+            17 => MojoResult::ShouldWait,
             _ => MojoResult::InvalidResult,
         }
     }
@@ -158,16 +167,6 @@
         (self.0 & (Signals::PeerClosed as u32)) != 0
     }
 
-    /// Check if the read threshold flag is set
-    pub fn is_read_threshold(&self) -> bool {
-        (self.0 & (Signals::ReadThreshold as u32)) != 0
-    }
-
-    /// Check if the write threshold flag is set
-    pub fn is_write_threshold(&self) -> bool {
-        (self.0 & (Signals::WriteThreshold as u32)) != 0
-    }
-
     /// Pull the raw MojoHandleSignals out of the data structure
     pub fn get_bits(&self) -> MojoHandleSignals {
         self.0
@@ -181,18 +180,20 @@
 ///     sizeof(SignalsState) == sizeof(MojoSignalsState) (defined in handle.h)
 /// If this is ever not the case or there is a way in Rust to ensure that,
 /// this data structure must be updated to reflect that.
-#[repr(C)]
+///
+
+// The Mojo API requires this to be 4-byte aligned.
+#[repr(C, align(4))]
 #[derive(Default)]
 pub struct SignalsState {
     satisfied: HandleSignals,
     satisfiable: HandleSignals,
-    _align: [u32; 0], // Hack to align to a 4-byte boundary
 }
 
 impl SignalsState {
     /// Generates a new SignalsState
     pub fn new(satisfied: HandleSignals, satisfiable: HandleSignals) -> SignalsState {
-        SignalsState { satisfied: satisfied, satisfiable: satisfiable, _align: [] }
+        SignalsState { satisfied: satisfied, satisfiable: satisfiable }
     }
     /// Gets a reference to the satisfied signals
     pub fn satisfied(&self) -> &HandleSignals {
@@ -231,11 +232,13 @@
 
     /// Wait for the handle to have at least some
     /// readable data
-    ReadThreshold = 1 << 3,
+    NewDataReadable = 1 << 3,
 
-    /// Wait for the handle to allow for at least
-    /// some data to be writable
-    WriteThreshold = 1 << 4,
+    /// ???
+    PeerRemote = 1 << 4,
+
+    // ???
+    QuotaExceeded = 1 << 5,
 }
 
 /// The result struct used by the wait_set module
@@ -245,13 +248,12 @@
 ///
 /// This struct should never be constructed by anything
 /// but the Mojo system in MojoWaitSetWait.
-#[repr(C)]
+#[repr(C, align(8))]
 pub struct WaitSetResult {
     cookie: u64,
     result: MojoResultCode,
     reserved: u32,
     signals_state: SignalsState,
-    _align: [u64; 0], // Hack to align struct to 8 byte boundary
 }
 
 impl WaitSetResult {
diff --git a/mojo/public/rust/system/shared_buffer.rs b/mojo/public/rust/system/shared_buffer.rs
index 1b893772..21b1f56 100644
--- a/mojo/public/rust/system/shared_buffer.rs
+++ b/mojo/public/rust/system/shared_buffer.rs
@@ -2,15 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use std::mem;
 use std::ptr;
 use std::slice;
 
-use system::ffi;
+use crate::system::ffi;
 // This full import is intentional; nearly every type in mojo_types needs to be used.
-use system::handle;
-use system::handle::{CastHandle, Handle};
-use system::mojo_types::*;
+use crate::system::handle;
+use crate::system::handle::{CastHandle, Handle};
+use crate::system::mojo_types::*;
 
 #[repr(u32)]
 /// Create flags for shared buffers
@@ -117,15 +116,11 @@
 /// Creates a shared buffer in Mojo and returns a SharedBuffer
 /// structure which represents a handle to the shared buffer.
 pub fn create(flags: CreateFlags, num_bytes: u64) -> Result<SharedBuffer, MojoResult> {
-    let opts = ffi::MojoCreateSharedBufferOptions {
-        struct_size: mem::size_of::<ffi::MojoCreateSharedBufferOptions>() as u32,
-        flags: flags,
-        _align: [],
-    };
+    let opts = ffi::MojoCreateSharedBufferOptions::new(flags);
     let raw_opts = &opts as *const ffi::MojoCreateSharedBufferOptions;
     let mut h: MojoHandle = 0;
     let r = MojoResult::from_code(unsafe {
-        ffi::MojoCreateSharedBuffer(raw_opts, num_bytes, &mut h as *mut MojoHandle)
+        ffi::MojoCreateSharedBuffer(num_bytes, raw_opts, &mut h as *mut MojoHandle)
     });
     if r != MojoResult::Okay {
         Err(r)
@@ -148,11 +143,7 @@
     /// buffer handle (though the handle itself may not be represented by
     /// the same number) that maps to the same shared buffer as the original.
     pub fn duplicate(&self, flags: DuplicateFlags) -> Result<SharedBuffer, MojoResult> {
-        let opts = ffi::MojoDuplicateBufferHandleOptions {
-            struct_size: mem::size_of::<ffi::MojoDuplicateBufferHandleOptions>() as u32,
-            flags: flags,
-            _align: [],
-        };
+        let opts = ffi::MojoDuplicateBufferHandleOptions::new(flags);
         let raw_opts = &opts as *const ffi::MojoDuplicateBufferHandleOptions;
         let mut dup_h: MojoHandle = 0;
         let r = MojoResult::from_code(unsafe {
@@ -178,18 +169,19 @@
         flags: MapFlags,
     ) -> Result<MappedBuffer<'a>, MojoResult> {
         unsafe {
-            let mut ptr: *mut ffi::c_void = mem::uninitialized();
+            let options = ffi::MojoMapBufferOptions::new(flags);
+            let mut ptr: *mut ffi::c_void = ptr::null_mut();
             let r = MojoResult::from_code(ffi::MojoMapBuffer(
                 self.handle.get_native_handle(),
                 offset,
                 num_bytes,
+                &options as *const _,
                 &mut ptr,
-                flags,
             ));
             if r != MojoResult::Okay {
                 Err(r)
             } else {
-                let mut buf = slice::from_raw_parts_mut(ptr as *mut u8, num_bytes as usize);
+                let buf = slice::from_raw_parts_mut(ptr as *mut u8, num_bytes as usize);
                 Ok(MappedBuffer { buffer: buf })
             }
         }
@@ -198,26 +190,16 @@
     /// Retrieves information about a shared buffer the this handle. The return
     /// value is a set of flags (a bit vector in a u32) representing different
     /// aspects of the shared buffer and the size of the shared buffer.
-    pub fn get_info(&self) -> Result<(InfoFlags, u64), MojoResult> {
-        let info_size = mem::size_of::<ffi::MojoBufferInformation>() as u32;
-        let mut info = ffi::MojoBufferInformation {
-            struct_size: info_size,
-            flags: 0,
-            num_bytes: 0,
-            _align: [],
-        };
+    pub fn get_info(&self) -> Result<u64, MojoResult> {
+        let mut info = ffi::MojoSharedBufferInfo::new(0);
         let r = MojoResult::from_code(unsafe {
-            ffi::MojoGetBufferInformation(
+            ffi::MojoGetBufferInfo(
                 self.handle.get_native_handle(),
-                &mut info as *mut ffi::MojoBufferInformation,
-                info_size,
+                ptr::null(),
+                &mut info as *mut _,
             )
         });
-        if r != MojoResult::Okay {
-            Err(r)
-        } else {
-            Ok((info.flags, info.num_bytes))
-        }
+        if r != MojoResult::Okay { Err(r) } else { Ok(info.size) }
     }
 }
 
diff --git a/mojo/public/rust/system/wait_set.rs b/mojo/public/rust/system/wait_set.rs
index 27117838..aab648b 100644
--- a/mojo/public/rust/system/wait_set.rs
+++ b/mojo/public/rust/system/wait_set.rs
@@ -2,14 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use std::mem;
 use std::ptr;
 
-use system::ffi;
-use system::handle;
-use system::handle::{CastHandle, Handle};
-use system::mojo_types;
-use system::mojo_types::MojoResult;
+use crate::system::ffi;
+use crate::system::handle::Handle;
+use crate::system::mojo_types;
+use crate::system::mojo_types::MojoResult;
 
 #[repr(u32)]
 /// Create flags for wait sets
@@ -29,28 +27,20 @@
 /// efficiently waiting asynchronously (and cooperatively) on a set of
 /// handles which are registered with it.
 pub struct WaitSet {
-    handle: handle::UntypedHandle,
+    handle: mojo_types::MojoWaitSetHandle,
 }
 
 impl WaitSet {
     /// Creates a new WaitSet object in the Mojo system, and returns a wrapper
     /// for it. If creation fails, returns the result code.
     pub fn new(flags: mojo_types::CreateFlags) -> Result<WaitSet, MojoResult> {
-        let mut raw_handle: mojo_types::MojoHandle = 0;
-        let opts = ffi::MojoCreateWaitSetOptions {
-            struct_size: mem::size_of::<ffi::MojoCreateWaitSetOptions>() as u32,
-            flags: flags,
-            _align: [],
-        };
+        let mut handle = 0;
+        let opts = ffi::MojoCreateWaitSetOptions::new(flags);
         let raw_opts = &opts as *const ffi::MojoCreateWaitSetOptions;
         let r = MojoResult::from_code(unsafe {
-            ffi::MojoCreateWaitSet(raw_opts, &mut raw_handle as *mut mojo_types::MojoHandle)
+            ffi::MojoCreateWaitSet(raw_opts, &mut handle as *mut _)
         });
-        if r != MojoResult::Okay {
-            Err(r)
-        } else {
-            Ok(WaitSet { handle: unsafe { handle::acquire(raw_handle) } })
-        }
+        if r != MojoResult::Okay { Err(r) } else { Ok(WaitSet { handle: handle }) }
     }
 
     /// Adds a handle to the underlying wait set.
@@ -63,31 +53,21 @@
     /// but the argument is kept for future usage.
     pub fn add(
         &mut self,
-        handle: &Handle,
+        handle: &dyn Handle,
         signals: mojo_types::HandleSignals,
         cookie: u64,
         flags: mojo_types::AddFlags,
     ) -> MojoResult {
-        let opts = ffi::MojoWaitSetAddOptions {
-            struct_size: mem::size_of::<ffi::MojoWaitSetAddOptions>() as u32,
-            flags: flags,
-            _align: [],
-        };
+        let opts = ffi::MojoWaitSetAddOptions::new(flags);
         let raw_opts = &opts as *const ffi::MojoWaitSetAddOptions;
         MojoResult::from_code(unsafe {
-            ffi::MojoWaitSetAdd(
-                self.handle.get_native_handle(),
-                handle.get_native_handle(),
-                signals,
-                cookie,
-                raw_opts,
-            )
+            ffi::MojoWaitSetAdd(self.handle, handle.get_native_handle(), signals, cookie, raw_opts)
         })
     }
 
     /// Removes a handle from the underlying wait set by cookie value.
     pub fn remove(&mut self, cookie: u64) -> MojoResult {
-        MojoResult::from_code(unsafe { ffi::MojoWaitSetRemove(self.get_native_handle(), cookie) })
+        MojoResult::from_code(unsafe { ffi::MojoWaitSetRemove(self.handle, cookie) })
     }
 
     /// Waits on this wait set.
@@ -105,57 +85,19 @@
     /// that completed waiting.
     ///
     /// On a failed wait, we return the result code.
-    pub fn wait_on_set(
-        &self,
-        deadline: mojo_types::MojoDeadline,
-        output: &mut Vec<mojo_types::WaitSetResult>,
-    ) -> Result<u32, MojoResult> {
+    pub fn wait_on_set(&self, output: &mut Vec<mojo_types::WaitSetResult>) -> MojoResult {
         assert!((output.capacity() as u64) <= ((1 as u64) << 32));
         let mut num_results = output.capacity() as u32;
-        let mut max_results: u32 = 0;
         let mut output_ptr = output.as_mut_ptr();
         if num_results == 0 {
             output_ptr = ptr::null_mut();
         }
         let r = MojoResult::from_code(unsafe {
-            ffi::MojoWaitSetWait(
-                self.handle.get_native_handle(),
-                deadline,
-                &mut num_results as *mut u32,
-                output_ptr,
-                &mut max_results as *mut u32,
-            )
+            ffi::MojoWaitSetWait(self.handle, &mut num_results as *mut u32, output_ptr)
         });
         unsafe {
             output.set_len(num_results as usize);
         }
-        if r == MojoResult::Okay {
-            Ok(max_results)
-        } else {
-            Err(r)
-        }
-    }
-}
-
-impl CastHandle for WaitSet {
-    /// Generates a WaitSet from an untyped handle wrapper
-    /// See mojo::system::handle for information on untyped vs. typed
-    unsafe fn from_untyped(handle: handle::UntypedHandle) -> Self {
-        WaitSet { handle: handle }
-    }
-
-    /// Consumes this object and produces a plain handle wrapper
-    /// See mojo::system::handle for information on untyped vs. typed
-    fn as_untyped(self) -> handle::UntypedHandle {
-        self.handle
-    }
-}
-
-impl Handle for WaitSet {
-    /// Returns the native handle wrapped by this structure.
-    ///
-    /// See mojo::system::handle for information on handle wrappers
-    fn get_native_handle(&self) -> mojo_types::MojoHandle {
-        self.handle.get_native_handle()
+        r
     }
 }
diff --git a/mojo/public/rust/test_support.cc b/mojo/public/rust/test_support.cc
new file mode 100644
index 0000000..c4cb61d5
--- /dev/null
+++ b/mojo/public/rust/test_support.cc
@@ -0,0 +1,55 @@
+// Copyright 2021 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.
+
+// Similar to support.cc, this patches over changes from the old Mojo SDK to
+// Mojo now. Test-specific helpers are here.
+
+#include <cstdint>
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include "base/check.h"
+#include "base/command_line.h"
+#include "mojo/core/embedder/embedder.h"
+#include "mojo/public/cpp/bindings/tests/validation_test_input_parser.h"
+
+extern "C" {
+
+// Only for the standalone Rust tests. When Rust Mojo code is integrated into
+// the wider Chrome build, this will not be used since Chrome initializes Mojo
+// itself.
+void InitializeMojoEmbedder(std::uint32_t argc, const char* const* argv) {
+  // Some mojo internals check command line flags, so we must initialize it
+  // here.
+  base::CommandLine::Init(argc, argv);
+  mojo::core::Init();
+}
+
+// Parses test data for Mojo message validation tests. Used for
+// encoding/decoding tests. See `mojo::test::ParseValidationTestInput` for more
+// details.
+//
+// Replacement for function removed from core C API. Wraps the equivalent C++
+// API function.
+const char* ParseValidationTest(const char* input,
+                                std::size_t* num_handles,
+                                std::uint8_t** data,
+                                std::size_t* data_len) {
+  std::vector<std::uint8_t> data_vec;
+  std::string error;
+  if (!mojo::test::ParseValidationTestInput(std::string(input), &data_vec,
+                                            num_handles, &error)) {
+    char* error_c_str = reinterpret_cast<char*>(malloc(error.size() + 1));
+    strncpy(error_c_str, error.c_str(), error.size() + 1);
+    return error_c_str;
+  }
+
+  *data_len = data_vec.size();
+  *data = reinterpret_cast<std::uint8_t*>(malloc(data_vec.size()));
+  memcpy(*data, data_vec.data(), data_vec.size());
+  return nullptr;
+}
+
+}  // extern "C"
diff --git a/mojo/public/rust/tests/encoding.rs b/mojo/public/rust/tests/encoding.rs
index 45d2f3b7..ef91a79 100644
--- a/mojo/public/rust/tests/encoding.rs
+++ b/mojo/public/rust/tests/encoding.rs
@@ -8,9 +8,6 @@
 //! and the result being caught in the test! macro. If a test function
 //! returns without panicking, it is assumed to pass.
 
-#[macro_use]
-extern crate mojo;
-
 use mojo::bindings::encoding::Context;
 use mojo::bindings::message::MessageHeader;
 use mojo::bindings::mojom::{MojomInterface, MojomPointer, MojomStruct, MojomUnion};
@@ -20,10 +17,8 @@
 
 use std::collections::HashMap;
 
-#[macro_use]
-mod util;
-
-use util::mojom_validation::*;
+use crate::util;
+use crate::util::mojom_validation::*;
 
 /// This macro is a wrapper for the tests! macro as it takes advantage of the
 /// shared code between tests.
diff --git a/mojo/public/rust/tests/integration.rs b/mojo/public/rust/tests/integration.rs
index 3f551f8..788cca5 100644
--- a/mojo/public/rust/tests/integration.rs
+++ b/mojo/public/rust/tests/integration.rs
@@ -8,19 +8,13 @@
 //! and the result being caught in the test! macro. If a test function
 //! returns without panicking, it is assumed to pass.
 
-#[macro_use]
-extern crate mojo;
-
-#[macro_use]
-mod util;
-
 use mojo::bindings::mojom::{MojomInterface, MojomInterfaceRecv, MojomInterfaceSend};
 use mojo::system::message_pipe;
-use mojo::system::{Handle, MOJO_INDEFINITE};
+use mojo::system::Handle;
 
 use std::thread;
 
-use util::mojom_validation::*;
+use crate::util::mojom_validation::*;
 
 tests! {
     // Tests basic client and server interaction over a thread
@@ -38,7 +32,7 @@
                 },
             }).unwrap();
             // Wait for response
-            client.pipe().wait(signals!(Signals::Readable), MOJO_INDEFINITE);
+            client.pipe().wait(signals!(Signals::Readable));
             // Decode response
             let (req_id, options) = client.recv_response().unwrap();
             assert_eq!(req_id, 5);
@@ -49,7 +43,7 @@
             }
         });
         // Wait for request
-        server.pipe().wait(signals!(Signals::Readable), MOJO_INDEFINITE);
+        server.pipe().wait(signals!(Signals::Readable));
         // Decode request
         let (req_id, options) = server.recv_response().unwrap();
         assert_eq!(req_id, 5);
diff --git a/mojo/public/rust/tests/lib.rs b/mojo/public/rust/tests/lib.rs
new file mode 100644
index 0000000..1803b58
--- /dev/null
+++ b/mojo/public/rust/tests/lib.rs
@@ -0,0 +1,29 @@
+// Copyright 2021 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.
+
+#[macro_use]
+extern crate mojo;
+
+#[macro_use]
+mod util;
+
+// These test suites work more or less. They still rely on some old Mojo
+// behavior such as wait sets (see https://codereview.chromium.org/2744943002).
+// These are temporarily replaced in support.cc.
+mod integration;
+mod run_loop;
+mod system;
+
+// Has one broken test that panics during a panic. It's disabled for now.
+mod regression;
+
+// These tests have two problems:
+// * lots of test data from the Mojo SDK doesn't exist / has changed
+// * the mojom encoding has changed since this code was written
+//
+// The code in crate/bindings/{encoding,decoding}.rs needs to be updated and
+// the tests must be updated to use the available test data
+//
+// mod encoding;
+// mod validation;
diff --git a/mojo/public/rust/tests/regression.rs b/mojo/public/rust/tests/regression.rs
index 9b10159..7814076 100644
--- a/mojo/public/rust/tests/regression.rs
+++ b/mojo/public/rust/tests/regression.rs
@@ -8,9 +8,6 @@
 //! and the result being caught in the test! macro. If a test function
 //! returns without panicking, it is assumed to pass.
 
-#[macro_use]
-extern crate mojo;
-
 use mojo::bindings::decoding::{Decoder, ValidationError};
 use mojo::bindings::encoding;
 use mojo::bindings::encoding::{Context, DataHeaderValue, Encoder};
@@ -18,9 +15,6 @@
 use mojo::system;
 use mojo::system::UntypedHandle;
 
-#[macro_use]
-mod util;
-
 const STRUCT_A_VERSIONS: [(u32, u32); 1] = [(0, 16)];
 
 struct StructA<T: MojomEncodable> {
@@ -39,7 +33,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let _version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&STRUCT_A_VERSIONS) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -88,6 +82,8 @@
     // random number which is potentially a valid handle. When on
     // drop() we try to close it, we should panic.
     #[should_panic]
+    // Ignore this test, it panics while panicking
+    #[ignore]
     fn regression_fixed_size_array_verify_drop() {
         let handle1 = unsafe { system::acquire(42) };
         let handle2 = unsafe { system::acquire(0) };
diff --git a/mojo/public/rust/tests/run_loop.rs b/mojo/public/rust/tests/run_loop.rs
index 47aed22..5c46175 100644
--- a/mojo/public/rust/tests/run_loop.rs
+++ b/mojo/public/rust/tests/run_loop.rs
@@ -8,12 +8,6 @@
 //! and the result being caught in the test! macro. If a test function
 //! returns without panicking, it is assumed to pass.
 
-#[macro_use]
-extern crate mojo;
-
-#[macro_use]
-mod util;
-
 use mojo::bindings::run_loop;
 use mojo::bindings::run_loop::{Handler, RunLoop, Token, WaitError};
 use mojo::system::message_pipe;
@@ -289,15 +283,6 @@
         });
     }
 
-    // Verifies that the handler's "on_timeout" function is called.
-    fn notify_timeout() {
-        let (_endpt0, endpt1) = message_pipe::create(mpflags!(Create::None)).unwrap();
-        run_loop::with_current(|runloop| {
-            let _ = runloop.register(&endpt1, signals!(Signals::Readable), 0, HandlerExpectTimeout {});
-            runloop.run();
-        });
-    }
-
     // Verifies that the handler's "on_error" function is called.
     fn notify_error() {
         // Drop the first endpoint immediately
@@ -327,6 +312,7 @@
     }
 
     // Tests reregistering.
+    #[ignore]
     fn reregister() {
         let (_endpt0, endpt1) = message_pipe::create(mpflags!(Create::None)).unwrap();
         run_loop::with_current(|runloop| {
@@ -336,6 +322,7 @@
     }
 
     // Tests nesting run loops by having a handler create a new one.
+    #[ignore]
     fn nesting() {
         let (_endpt0, endpt1) = message_pipe::create(mpflags!(Create::None)).unwrap();
         run_loop::with_current(|runloop| {
@@ -346,6 +333,7 @@
 
     // Tests to make sure nesting with the SAME runloop fails.
     #[should_panic]
+    #[ignore]
     fn bad_nesting() {
         let (_endpt0, endpt1) = message_pipe::create(mpflags!(Create::None)).unwrap();
         run_loop::with_current(|runloop| {
diff --git a/mojo/public/rust/tests/system.rs b/mojo/public/rust/tests/system.rs
index bf4f1f7c..36d0b5f9 100644
--- a/mojo/public/rust/tests/system.rs
+++ b/mojo/public/rust/tests/system.rs
@@ -8,12 +8,6 @@
 //! and the result being caught in the test! macro. If a test function
 //! returns without panicking, it is assumed to pass.
 
-#[macro_use]
-extern crate mojo;
-
-#[macro_use]
-mod util;
-
 use mojo::system;
 use mojo::system::core;
 use mojo::system::data_pipe;
@@ -63,8 +57,7 @@
                 buf = sb.map(0, bufsize, sbflags!(Map::None)).unwrap();
                 assert_eq!(buf.len(), bufsize as usize);
                 // Test get info
-                let (flags, size) = sb.get_info().unwrap();
-                assert_eq!(flags, sbflags!(Info::None));
+                let size = sb.get_info().unwrap();
                 assert_eq!(size, bufsize);
                 buf.write(50, 34);
                 // Test duplicate
@@ -93,15 +86,7 @@
             let endpt0 = unsafe { message_pipe::MessageEndpoint::from_untyped(endpt_u) };
             assert_eq!(endpt0.get_native_handle(), endpt_h);
             {
-                let (s, r) = endpt0.wait(signals!(Signals::Readable), 0);
-                assert_eq!(r, mojo::MojoResult::DeadlineExceeded);
-                assert!(s.satisfied().is_writable());
-                assert!(s.satisfiable().is_readable());
-                assert!(s.satisfiable().is_writable());
-                assert!(s.satisfiable().is_peer_closed());
-            }
-            {
-                let (s, r) = endpt0.wait(signals!(Signals::Writable), system::MOJO_INDEFINITE);
+                let (s, r) = endpt0.wait(signals!(Signals::Writable));
                 assert_eq!(r, mojo::MojoResult::Okay);
                 assert!(s.satisfied().is_writable());
                 assert!(s.satisfiable().is_readable());
@@ -116,9 +101,10 @@
             let write_result = endpt1.write(&hello, Vec::new(), mpflags!(Write::None));
             assert_eq!(write_result, mojo::MojoResult::Okay);
             {
-                let (s, r) = endpt0.wait(signals!(Signals::Readable), system::MOJO_INDEFINITE);
+                let (s, r) = endpt0.wait(signals!(Signals::Readable));
                 assert_eq!(r, mojo::MojoResult::Okay);
-                assert!(s.satisfied().is_readable(), s.satisfied().is_writable());
+                assert!(s.satisfied().is_readable());
+                assert!(s.satisfied().is_writable());
                 assert!(s.satisfiable().is_readable());
                 assert!(s.satisfiable().is_writable());
                 assert!(s.satisfiable().is_peer_closed());
@@ -129,25 +115,12 @@
                 Err(r) => panic!("Failed to read message on endpt0, error: {}", r),
             }
             assert_eq!(String::from_utf8(hello_data).unwrap(), "hello".to_string());
-            {
-                let handles: Vec<&Handle> = vec![&endpt0];
-                let signals: Vec<system::HandleSignals> = vec![signals!(Signals::Readable)];
-                let mut states: Vec<system::SignalsState> = vec![Default::default()];
-                let (idx, r) = core::wait_many(&handles, &signals, &mut states, 10);
-                assert_eq!(r, mojo::MojoResult::DeadlineExceeded);
-                assert_eq!(idx, -1);
-                assert_eq!(states.len(), 1);
-                assert!(states[0].satisfied().is_writable());
-                assert!(states[0].satisfiable().is_readable());
-                assert!(states[0].satisfiable().is_writable());
-                assert!(states[0].satisfiable().is_peer_closed());
-            }
         }
-        let (s, r) = endpt1.wait(signals!(Signals::Readable, Signals::Writable),
-                                 system::MOJO_INDEFINITE);
+        let (s, r) = endpt1.wait(signals!(Signals::Readable, Signals::Writable));
         assert_eq!(r, mojo::MojoResult::FailedPrecondition);
         assert!(s.satisfied().is_peer_closed());
-        assert_eq!(s.satisfiable().get_bits(), system::Signals::PeerClosed as u32);
+        // For some reason QuotaExceeded is also set. TOOD(collinbaker): investigate.
+        assert!(s.satisfiable().get_bits() & (system::Signals::PeerClosed as u32) > 0);
     }
 
     fn data_pipe() {
@@ -164,14 +137,9 @@
         let prod = unsafe { data_pipe::Producer::<u8>::from_untyped(prod_u) };
         assert_eq!(cons.get_native_handle(), cons_h);
         assert_eq!(prod.get_native_handle(), prod_h);
-        // Test waiting on consumer
-        {
-            let (_s, r) = cons.wait(signals!(Signals::Readable), 0);
-            assert_eq!(r, mojo::MojoResult::DeadlineExceeded);
-        }
         // Test waiting on producer
         {
-            let (_s, r) = prod.wait(signals!(Signals::Writable), system::MOJO_INDEFINITE);
+            let (_s, r) = prod.wait(signals!(Signals::Writable));
             assert_eq!(r, mojo::MojoResult::Okay);
         }
         // Test one-phase read/write.
@@ -181,7 +149,7 @@
         assert_eq!(bytes_written, hello.len());
         // Reading.
         {
-            let (_s, r) = cons.wait(signals!(Signals::Readable), system::MOJO_INDEFINITE);
+            let (_s, r) = cons.wait(signals!(Signals::Readable));
             assert_eq!(r, mojo::MojoResult::Okay);
         }
         let data_string = String::from_utf8(cons.read(dpflags!(Read::None)).unwrap()).unwrap();
@@ -190,7 +158,7 @@
             // Test two-phase read/write.
             // Writing.
             let goodbye = "goodbye".to_string().into_bytes();
-            let mut write_buf = match prod.begin(dpflags!(Write::None)) {
+            let mut write_buf = match prod.begin() {
                 Ok(buf) => buf,
                 Err(err) => panic!("Error on write begin: {}", err),
             };
@@ -198,22 +166,18 @@
             for i in 0..goodbye.len() {
                 write_buf[i] = goodbye[i];
             }
-            {
-                let (_s, r) = cons.wait(signals!(Signals::Readable), 0);
-                assert_eq!(r, mojo::MojoResult::DeadlineExceeded);
-            }
             match write_buf.commit(goodbye.len()) {
                 Some((_buf, _err)) => assert!(false),
                 None => (),
             }
             // Reading.
             {
-                let (_s, r) = cons.wait(signals!(Signals::Readable), system::MOJO_INDEFINITE);
+                let (_s, r) = cons.wait(signals!(Signals::Readable));
                 assert_eq!(r, mojo::MojoResult::Okay);
             }
             let mut data_goodbye: Vec<u8> = Vec::with_capacity(goodbye.len());
             {
-                let read_buf = match cons.begin(dpflags!(Read::None)) {
+                let read_buf = match cons.begin() {
                     Ok(buf) => buf,
                     Err(err) => panic!("Error on read begin: {}", err),
                 };
@@ -235,11 +199,7 @@
     }
 
     fn wait_set() {
-        let set0 = wait_set::WaitSet::new(wsflags!(Create::None)).unwrap();
-        let set_h = set0.get_native_handle();
-        let set_u = set0.as_untyped();
-        assert_eq!(set_u.get_native_handle(), set_h);
-        let mut set = unsafe { wait_set::WaitSet::from_untyped(set_u) };
+        let mut set = wait_set::WaitSet::new(wsflags!(Create::None)).unwrap();
         let (endpt0, endpt1) = message_pipe::create(mpflags!(Create::None)).unwrap();
         let signals = signals!(Signals::Readable);
         let flags = wsflags!(Add::None);
@@ -253,12 +213,12 @@
             let write_result = endpt1.write(&hello, Vec::new(), mpflags!(Write::None));
             assert_eq!(write_result, mojo::MojoResult::Okay);
         });
-        let mut output = Vec::with_capacity(1);
-        let max = set.wait_on_set(system::MOJO_INDEFINITE, &mut output).unwrap();
+        let mut output = Vec::with_capacity(2);
+        let result = set.wait_on_set(&mut output);
+        assert_eq!(result, mojo::MojoResult::Okay);
         assert_eq!(output.len(), 1);
         assert_eq!(output[0].cookie(), 123);
         assert_eq!(output[0].result(), mojo::MojoResult::Okay);
         assert!(output[0].state().satisfied().is_readable());
-        assert_eq!(max, 1);
     }
 }
diff --git a/mojo/public/rust/tests/util/mod.rs b/mojo/public/rust/tests/util/mod.rs
index cb1b719..fdb2fd8 100644
--- a/mojo/public/rust/tests/util/mod.rs
+++ b/mojo/public/rust/tests/util/mod.rs
@@ -6,46 +6,64 @@
 
 pub mod mojom_validation;
 
+use std::env;
 use std::ffi::{CStr, CString};
 use std::os::raw::c_char;
 use std::ptr;
 use std::slice;
+use std::vec::Vec;
 
 /// This macro sets up tests by adding in Mojo embedder
 /// initialization.
 macro_rules! tests {
     ( $( $( #[ $attr:meta ] )* fn $i:ident() $b:block)* ) => {
-        use std::sync::{Once, ONCE_INIT};
-        static START: Once = ONCE_INIT;
         $(
             #[test]
             $(
             #[ $attr ]
             )*
             fn $i() {
-                START.call_once(|| unsafe {
-                    util::InitializeMojoEmbedder();
-                });
+                $crate::util::init();
                 $b
             }
         )*
     }
 }
 
-#[link(name = "stdc++")]
-extern "C" {}
+/// Calls Mojo initialization code on first call. Can be called multiple times.
+/// Has no effect after the first call.
+pub fn init() {
+    // The initialization below must only be done once. For ease of safety, we
+    // want to allow this function to be called multiple times. Wrap the inner
+    // initialization code and only call it the first time.
+    use std::sync::Once;
+    static START: Once = Once::new();
 
-#[link(name = "c")]
+    START.call_once(|| {
+        let mut raw_args: Vec<*const c_char> = Vec::new();
+        for a in env::args() {
+            let cstr = CString::new(a).unwrap();
+            raw_args.push(cstr.into_raw())
+        }
+        let argc = raw_args.len() as u32;
+        let argv = raw_args.leak().as_ptr();
+
+        // `InitializeMojoEmbedder` is safe to call only once. We ensure this
+        // by using `std::sync::Once::call_once` above.
+        unsafe {
+            InitializeMojoEmbedder(argc, argv);
+        }
+    });
+}
+
 extern "C" {
     fn free(ptr: *mut u8);
 }
 
-#[link(name = "rust_embedder")]
 extern "C" {
-    pub fn InitializeMojoEmbedder();
+    pub fn InitializeMojoEmbedder(argc: u32, argv: *const *const c_char);
 }
 
-#[link(name = "validation_parser")]
 extern "C" {
     #[allow(dead_code)]
     fn ParseValidationTest(
diff --git a/mojo/public/rust/tests/util/mojom_validation.rs b/mojo/public/rust/tests/util/mojom_validation.rs
index 00d3f0c..d2ec36d 100644
--- a/mojo/public/rust/tests/util/mojom_validation.rs
+++ b/mojo/public/rust/tests/util/mojom_validation.rs
@@ -50,7 +50,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&StructAVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -97,7 +97,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&StructBVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -144,7 +144,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&StructCVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -191,7 +191,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&StructDVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -241,7 +241,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&StructEVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -294,7 +294,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&StructFVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -347,7 +347,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&StructGVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -429,7 +429,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&StructHVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -496,7 +496,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&BasicStructVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -547,7 +547,7 @@
     fn encode_value(self, encoder: &mut Encoder, context: Context) {}
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&StructWithEnumVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -630,7 +630,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let tag = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             let bytes = state.decode::<u32>();
             if (bytes as usize) != UNION_SIZE {
                 return Err(ValidationError::UnexpectedNullUnion);
@@ -762,7 +762,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let tag = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             let bytes = state.decode::<u32>();
             if (bytes as usize) != UNION_SIZE {
                 return Err(ValidationError::UnexpectedNullUnion);
@@ -1190,7 +1190,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&BoundsCheckTestInterfaceMethod0RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -1251,7 +1251,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&BoundsCheckTestInterfaceMethod0ResponseVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -1317,7 +1317,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&BoundsCheckTestInterfaceMethod1RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -1771,7 +1771,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod3RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -1839,7 +1839,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod4RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -1912,7 +1912,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod5RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -1985,7 +1985,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod7RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2056,7 +2056,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod12RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2117,7 +2117,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod12ResponseVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2183,7 +2183,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod14RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2249,7 +2249,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod15RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2315,7 +2315,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod1RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2383,7 +2383,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod2RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2454,7 +2454,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod6RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2520,7 +2520,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod8RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2586,7 +2586,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod10RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2652,7 +2652,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod11RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2718,7 +2718,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod0RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2784,7 +2784,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod9RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -2857,7 +2857,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&ConformanceTestInterfaceMethod13RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -3115,7 +3115,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&IntegrationTestInterfaceMethod0RequestVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
@@ -3176,7 +3176,7 @@
     }
     fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, ValidationError> {
         let version = {
-            let mut state = decoder.get_mut(&context);
+            let state = decoder.get_mut(&context);
             match state.decode_struct_header(&IntegrationTestInterfaceMethod0ResponseVersions) {
                 Ok(header) => header.data(),
                 Err(err) => return Err(err),
diff --git a/mojo/public/rust/tests/validation.rs b/mojo/public/rust/tests/validation.rs
index 5b85582..a8f5ebe 100644
--- a/mojo/public/rust/tests/validation.rs
+++ b/mojo/public/rust/tests/validation.rs
@@ -8,16 +8,11 @@
 //! and the result being caught in the test! macro. If a test function
 //! returns without panicking, it is assumed to pass.
 
-#[macro_use]
-extern crate mojo;
-
 use mojo::bindings::mojom::MojomMessageOption;
 use mojo::system;
 
-#[macro_use]
-mod util;
-
-use util::mojom_validation::*;
+use crate::util;
+use crate::util::mojom_validation::*;
 
 /// This macro is a wrapper for the tests! macro as it takes advantage of the
 /// shared code between tests.
@@ -74,11 +69,11 @@
     conformance_mthd11_num_bytes_version_mismatch_1 => ConformanceTestInterfaceRequestOption;
     conformance_mthd11_num_bytes_version_mismatch_2 => ConformanceTestInterfaceRequestOption;
     conformance_mthd12_invalid_request_flags => ConformanceTestInterfaceRequestOption;
-    conformance_mthd14_unexpected_null_array_in_union => ConformanceTestInterfaceRequestOption;
-    conformance_mthd14_unexpected_null_map_in_union => ConformanceTestInterfaceRequestOption;
-    conformance_mthd14_unexpected_null_struct_in_union => ConformanceTestInterfaceRequestOption;
-    conformance_mthd14_unexpected_null_union_in_union => ConformanceTestInterfaceRequestOption;
-    conformance_mthd15_unexpected_null_union_in_array => ConformanceTestInterfaceRequestOption;
+    // conformance_mthd14_unexpected_null_array_in_union => ConformanceTestInterfaceRequestOption;
+    // conformance_mthd14_unexpected_null_map_in_union => ConformanceTestInterfaceRequestOption;
+    // conformance_mthd14_unexpected_null_struct_in_union => ConformanceTestInterfaceRequestOption;
+    // conformance_mthd14_unexpected_null_union_in_union => ConformanceTestInterfaceRequestOption;
+    // conformance_mthd15_unexpected_null_union_in_array => ConformanceTestInterfaceRequestOption;
     conformance_mthd1_misaligned_struct => ConformanceTestInterfaceRequestOption;
     conformance_mthd1_struct_pointer_overflow => ConformanceTestInterfaceRequestOption;
     conformance_mthd1_unexpected_null_struct => ConformanceTestInterfaceRequestOption;
diff --git a/net/dns/dns_config.cc b/net/dns/dns_config.cc
index 9b53ce8..6dd4028 100644
--- a/net/dns/dns_config.cc
+++ b/net/dns/dns_config.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/values.h"
+#include "net/dns/public/dns_over_https_config.h"
 
 namespace net {
 
@@ -109,13 +110,8 @@
   dict.SetBoolKey("rotate", rotate);
   dict.SetBoolKey("use_local_ipv6", use_local_ipv6);
   dict.SetIntKey("num_hosts", hosts.size());
-  list = base::Value(base::Value::Type::LIST);
-  for (auto& server : dns_over_https_servers) {
-    base::Value val(base::Value::Type::DICTIONARY);
-    val.SetStringKey("server_template", server.server_template());
-    list.Append(std::move(val));
-  }
-  dict.SetKey("doh_servers", std::move(list));
+  dict.SetKey("doh_servers",
+              DnsOverHttpsConfig(dns_over_https_servers).ToValue());
   dict.SetIntKey("secure_dns_mode", static_cast<int>(secure_dns_mode));
   dict.SetBoolKey("allow_dns_over_https_upgrade", allow_dns_over_https_upgrade);
 
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc
index b26496a..1535e1b 100644
--- a/net/dns/dns_test_util.cc
+++ b/net/dns/dns_test_util.cc
@@ -785,16 +785,4 @@
       null_random_callback, nullptr /* net_log */);
 }
 
-std::vector<DnsOverHttpsServerConfig> ParseDohTemplates(
-    std::vector<std::string> server_templates) {
-  std::vector<DnsOverHttpsServerConfig> out;
-  out.reserve(server_templates.size());
-  base::ranges::transform(server_templates, std::back_inserter(out),
-                          [](std::string& server_template) {
-                            return *DnsOverHttpsServerConfig::FromString(
-                                std::move(server_template));
-                          });
-  return out;
-}
-
 }  // namespace net
diff --git a/net/dns/dns_test_util.h b/net/dns/dns_test_util.h
index b69eb9b..5a37f5d 100644
--- a/net/dns/dns_test_util.h
+++ b/net/dns/dns_test_util.h
@@ -461,11 +461,6 @@
   absl::optional<AddressList> preset_addrs_;
 };
 
-// Convert a list of templates into a list of server configs.
-// All templates in the list must be valid.
-std::vector<DnsOverHttpsServerConfig> ParseDohTemplates(
-    std::vector<std::string> server_templates);
-
 }  // namespace net
 
 #endif  // NET_DNS_DNS_TEST_UTIL_H_
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
index f560d1c..c67f641 100644
--- a/net/dns/dns_transaction.cc
+++ b/net/dns/dns_transaction.cc
@@ -55,6 +55,7 @@
 #include "net/dns/dns_udp_tracker.h"
 #include "net/dns/dns_util.h"
 #include "net/dns/host_cache.h"
+#include "net/dns/public/dns_over_https_config.h"
 #include "net/dns/public/dns_over_https_server_config.h"
 #include "net/dns/public/dns_protocol.h"
 #include "net/dns/public/dns_query_type.h"
@@ -1252,7 +1253,7 @@
     absl::optional<std::string> doh_provider_id;
     if (secure_ && result.attempt) {
       size_t server_index = result.attempt->server_index();
-      doh_provider_id = GetDohProviderIdForHistogramFromDohConfig(
+      doh_provider_id = GetDohProviderIdForHistogramFromServerConfig(
           session_->config().dns_over_https_servers[server_index]);
     }
 
diff --git a/net/dns/dns_util.cc b/net/dns/dns_util.cc
index 435b1b9..9b269f9d 100644
--- a/net/dns/dns_util.cc
+++ b/net/dns/dns_util.cc
@@ -26,7 +26,6 @@
 #include "net/dns/public/util.h"
 #include "net/third_party/uri_template/uri_template.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
-#include "url/url_canon.h"
 
 #if BUILDFLAG(IS_POSIX)
 #include <netinet/in.h>
@@ -315,7 +314,7 @@
   return doh_servers;
 }
 
-std::string GetDohProviderIdForHistogramFromDohConfig(
+std::string GetDohProviderIdForHistogramFromServerConfig(
     const DnsOverHttpsServerConfig& doh_server) {
   const auto& entries = DohProviderEntry::GetList();
   const auto it =
diff --git a/net/dns/dns_util.h b/net/dns/dns_util.h
index f72a1da6..233697d 100644
--- a/net/dns/dns_util.h
+++ b/net/dns/dns_util.h
@@ -126,7 +126,7 @@
 
 // Returns the provider id to use in UMA histogram names. If there is no
 // provider id that matches |doh_server|, returns "Other".
-NET_EXPORT_PRIVATE std::string GetDohProviderIdForHistogramFromDohConfig(
+NET_EXPORT_PRIVATE std::string GetDohProviderIdForHistogramFromServerConfig(
     const DnsOverHttpsServerConfig& doh_server);
 
 // Returns the provider id to use in UMA histogram names. If there is no
diff --git a/net/dns/dns_util_unittest.cc b/net/dns/dns_util_unittest.cc
index 52342d4..3d20ddea 100644
--- a/net/dns/dns_util_unittest.cc
+++ b/net/dns/dns_util_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/cxx17_backports.h"
 #include "base/numerics/safe_conversions.h"
 #include "net/dns/dns_test_util.h"
+#include "net/dns/public/dns_over_https_config.h"
 #include "net/dns/public/dns_protocol.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -487,11 +488,11 @@
 
   doh_servers = GetDohUpgradeServersFromNameservers(nameservers,
                                                     std::vector<std::string>());
-  EXPECT_EQ(ParseDohTemplates(
-                {"https://chrome.cloudflare-dns.com/dns-query",
-                 "https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
-                 "https://doh.cleanbrowsing.org/doh/security-filter{?dns}"}),
-            doh_servers);
+  auto expected_config = *DnsOverHttpsConfig::FromStrings(
+      {"https://chrome.cloudflare-dns.com/dns-query",
+       "https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
+       "https://doh.cleanbrowsing.org/doh/security-filter{?dns}"});
+  EXPECT_EQ(expected_config.servers(), doh_servers);
 
   doh_servers = GetDohUpgradeServersFromNameservers(
       nameservers, std::vector<std::string>(
@@ -501,12 +502,12 @@
                   "https://doh.cleanbrowsing.org/doh/family-filter{?dns}")));
 }
 
-TEST_F(DNSUtilTest, GetDohProviderIdForHistogramFromDohConfig) {
+TEST_F(DNSUtilTest, GetDohProviderIdForHistogramFromServerConfig) {
   EXPECT_EQ("Cloudflare",
-            GetDohProviderIdForHistogramFromDohConfig(
+            GetDohProviderIdForHistogramFromServerConfig(
                 *DnsOverHttpsServerConfig::FromString(
                     "https://chrome.cloudflare-dns.com/dns-query")));
-  EXPECT_EQ("Other", GetDohProviderIdForHistogramFromDohConfig(
+  EXPECT_EQ("Other", GetDohProviderIdForHistogramFromServerConfig(
                          *DnsOverHttpsServerConfig::FromString(
                              "https://unexpected.dohserver.com/dns-query")));
 }
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc
index d2ac352..859e2fb7 100644
--- a/net/dns/host_resolver_manager_unittest.cc
+++ b/net/dns/host_resolver_manager_unittest.cc
@@ -63,6 +63,7 @@
 #include "net/dns/mock_mdns_client.h"
 #include "net/dns/mock_mdns_socket_factory.h"
 #include "net/dns/public/dns_config_overrides.h"
+#include "net/dns/public/dns_over_https_config.h"
 #include "net/dns/public/dns_over_https_server_config.h"
 #include "net/dns/public/dns_protocol.h"
 #include "net/dns/public/dns_query_type.h"
@@ -7890,23 +7891,15 @@
 
   std::string server("https://dnsserver.example.net/dns-query{?dns}");
   DnsConfigOverrides overrides;
-  overrides.dns_over_https_servers.emplace(ParseDohTemplates({server}));
+  overrides.dns_over_https_servers.emplace(
+      {*DnsOverHttpsServerConfig::FromString(server)});
   overrides.secure_dns_mode = SecureDnsMode::kAutomatic;
   resolver_->SetDnsConfigOverrides(overrides);
-  base::Value config = resolver_->GetDnsConfigAsValue();
-  base::Value* doh_servers = config.FindListKey("doh_servers");
-  EXPECT_TRUE(doh_servers);
-  if (!doh_servers)
-    return;
-  EXPECT_EQ(doh_servers->GetList().size(), 1u);
-  base::Value& server_method = doh_servers->GetList()[0];
-  EXPECT_TRUE(server_method.is_dict());
-  const std::string* server_template =
-      server_method.FindStringKey("server_template");
-  EXPECT_TRUE(server_template);
-  EXPECT_EQ(*server_template, server);
-  EXPECT_EQ(config.FindKey("secure_dns_mode")->GetInt(),
-            static_cast<int>(SecureDnsMode::kAutomatic));
+  const auto* config = dns_client_->GetEffectiveConfig();
+  ASSERT_TRUE(config);
+  DnsOverHttpsConfig doh_config(config->dns_over_https_servers);
+  EXPECT_EQ(DnsOverHttpsConfig::FromString(server), doh_config);
+  EXPECT_EQ(SecureDnsMode::kAutomatic, config->secure_dns_mode);
 }
 
 TEST_F(HostResolverManagerDnsTest, AddDnsOverHttpsServerBeforeConfig) {
@@ -7915,7 +7908,8 @@
   CreateSerialResolver();  // To guarantee order of resolutions.
   std::string server("https://dnsserver.example.net/dns-query{?dns}");
   DnsConfigOverrides overrides;
-  overrides.dns_over_https_servers.emplace(ParseDohTemplates({server}));
+  overrides.dns_over_https_servers.emplace(
+      {*DnsOverHttpsServerConfig::FromString(server)});
   overrides.secure_dns_mode = SecureDnsMode::kAutomatic;
   resolver_->SetDnsConfigOverrides(overrides);
 
@@ -7923,20 +7917,11 @@
       NetworkChangeNotifier::CONNECTION_WIFI);
   ChangeDnsConfig(CreateValidDnsConfig());
 
-  base::Value config = resolver_->GetDnsConfigAsValue();
-  base::Value* doh_servers = config.FindListKey("doh_servers");
-  EXPECT_TRUE(doh_servers);
-  if (!doh_servers)
-    return;
-  EXPECT_EQ(doh_servers->GetList().size(), 1u);
-  base::Value& server_method = doh_servers->GetList()[0];
-  EXPECT_TRUE(server_method.is_dict());
-  const std::string* server_template =
-      server_method.FindStringKey("server_template");
-  EXPECT_TRUE(server_template);
-  EXPECT_EQ(*server_template, server);
-  EXPECT_EQ(config.FindKey("secure_dns_mode")->GetInt(),
-            static_cast<int>(SecureDnsMode::kAutomatic));
+  const auto* config = dns_client_->GetEffectiveConfig();
+  ASSERT_TRUE(config);
+  DnsOverHttpsConfig doh_config(config->dns_over_https_servers);
+  EXPECT_EQ(DnsOverHttpsConfig::FromString(server), doh_config);
+  EXPECT_EQ(SecureDnsMode::kAutomatic, config->secure_dns_mode);
 }
 
 TEST_F(HostResolverManagerDnsTest, AddDnsOverHttpsServerBeforeClient) {
@@ -7945,7 +7930,8 @@
   CreateSerialResolver();  // To guarantee order of resolutions.
   std::string server("https://dnsserver.example.net/dns-query{?dns}");
   DnsConfigOverrides overrides;
-  overrides.dns_over_https_servers.emplace(ParseDohTemplates({server}));
+  overrides.dns_over_https_servers.emplace(
+      {*DnsOverHttpsServerConfig::FromString(server)});
   overrides.secure_dns_mode = SecureDnsMode::kAutomatic;
   resolver_->SetDnsConfigOverrides(overrides);
 
@@ -7953,20 +7939,11 @@
       NetworkChangeNotifier::CONNECTION_WIFI);
   ChangeDnsConfig(CreateValidDnsConfig());
 
-  base::Value config = resolver_->GetDnsConfigAsValue();
-  base::Value* doh_servers = config.FindListKey("doh_servers");
-  EXPECT_TRUE(doh_servers);
-  if (!doh_servers)
-    return;
-  EXPECT_EQ(doh_servers->GetList().size(), 1u);
-  base::Value& server_method = doh_servers->GetList()[0];
-  EXPECT_TRUE(server_method.is_dict());
-  const std::string* server_template =
-      server_method.FindStringKey("server_template");
-  EXPECT_TRUE(server_template);
-  EXPECT_EQ(*server_template, server);
-  EXPECT_EQ(config.FindKey("secure_dns_mode")->GetInt(),
-            static_cast<int>(SecureDnsMode::kAutomatic));
+  const auto* config = dns_client_->GetEffectiveConfig();
+  ASSERT_TRUE(config);
+  DnsOverHttpsConfig doh_config(config->dns_over_https_servers);
+  EXPECT_EQ(DnsOverHttpsConfig::FromString(server), doh_config);
+  EXPECT_EQ(SecureDnsMode::kAutomatic, config->secure_dns_mode);
 }
 
 TEST_F(HostResolverManagerDnsTest, AddDnsOverHttpsServerAndThenRemove) {
@@ -7975,7 +7952,8 @@
   CreateSerialResolver();  // To guarantee order of resolutions.
   std::string server("https://dns.example.com/");
   DnsConfigOverrides overrides;
-  overrides.dns_over_https_servers.emplace(ParseDohTemplates({server}));
+  overrides.dns_over_https_servers.emplace(
+      {*DnsOverHttpsServerConfig::FromString(server)});
   overrides.secure_dns_mode = SecureDnsMode::kAutomatic;
   resolver_->SetDnsConfigOverrides(overrides);
 
@@ -7985,30 +7963,17 @@
   network_dns_config.dns_over_https_servers.clear();
   ChangeDnsConfig(network_dns_config);
 
-  base::Value config = resolver_->GetDnsConfigAsValue();
-  base::Value* doh_servers = config.FindListKey("doh_servers");
-  EXPECT_TRUE(doh_servers);
-  if (!doh_servers)
-    return;
-  EXPECT_EQ(doh_servers->GetList().size(), 1u);
-  base::Value& server_method = doh_servers->GetList()[0];
-  EXPECT_TRUE(server_method.is_dict());
-  const std::string* server_template =
-      server_method.FindStringKey("server_template");
-  EXPECT_TRUE(server_template);
-  EXPECT_EQ(*server_template, server);
-  EXPECT_EQ(config.FindKey("secure_dns_mode")->GetInt(),
-            static_cast<int>(SecureDnsMode::kAutomatic));
+  const auto* config = dns_client_->GetEffectiveConfig();
+  ASSERT_TRUE(config);
+  DnsOverHttpsConfig doh_config(config->dns_over_https_servers);
+  EXPECT_EQ(DnsOverHttpsConfig::FromString(server), doh_config);
+  EXPECT_EQ(SecureDnsMode::kAutomatic, config->secure_dns_mode);
 
   resolver_->SetDnsConfigOverrides(DnsConfigOverrides());
-  config = resolver_->GetDnsConfigAsValue();
-  doh_servers = config.FindListKey("doh_servers");
-  EXPECT_TRUE(doh_servers);
-  if (!doh_servers)
-    return;
-  EXPECT_EQ(doh_servers->GetList().size(), 0u);
-  EXPECT_EQ(config.FindKey("secure_dns_mode")->GetInt(),
-            static_cast<int>(SecureDnsMode::kOff));
+  config = dns_client_->GetEffectiveConfig();
+  ASSERT_TRUE(config);
+  EXPECT_EQ(0u, config->dns_over_https_servers.size());
+  EXPECT_EQ(SecureDnsMode::kOff, config->secure_dns_mode);
 }
 
 // Basic test socket factory that allows creation of UDP sockets, but those
@@ -8073,8 +8038,8 @@
   overrides.doh_attempts = doh_attempts;
   overrides.rotate = true;
   overrides.use_local_ipv6 = true;
-  const auto dns_over_https_servers =
-      ParseDohTemplates({"https://dns.example.com/"});
+  const std::vector<DnsOverHttpsServerConfig> dns_over_https_servers = {
+      *DnsOverHttpsServerConfig::FromString("https://dns.example.com/")};
   overrides.dns_over_https_servers = dns_over_https_servers;
   const SecureDnsMode secure_dns_mode = SecureDnsMode::kSecure;
   overrides.secure_dns_mode = secure_dns_mode;
@@ -8362,10 +8327,12 @@
 
   const DnsConfig* fetched_config = client_ptr->GetEffectiveConfig();
   EXPECT_EQ(original_config.nameservers, fetched_config->nameservers);
-  auto expected_doh_servers = ParseDohTemplates(
-      {"https://chrome.cloudflare-dns.com/dns-query",
-       "https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
-       "https://doh.cleanbrowsing.org/doh/security-filter{?dns}"});
+  auto expected_doh_servers =
+      DnsOverHttpsConfig::FromStrings(
+          {"https://chrome.cloudflare-dns.com/dns-query",
+           "https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
+           "https://doh.cleanbrowsing.org/doh/security-filter{?dns}"})
+          ->servers();
   EXPECT_EQ(expected_doh_servers, fetched_config->dns_over_https_servers);
 }
 
@@ -8454,8 +8421,10 @@
   // only for permitted providers.
   const DnsConfig* fetched_config = client_ptr->GetEffectiveConfig();
   EXPECT_EQ(original_config.nameservers, fetched_config->nameservers);
-  const auto expected_doh_servers = ParseDohTemplates(
-      {"https://doh.cleanbrowsing.org/doh/family-filter{?dns}"});
+  const auto expected_doh_servers =
+      DnsOverHttpsConfig::FromString(
+          "https://doh.cleanbrowsing.org/doh/family-filter{?dns}")
+          ->servers();
   EXPECT_EQ(expected_doh_servers, fetched_config->dns_over_https_servers);
 }
 
@@ -8477,7 +8446,8 @@
   // If the overrides contains DoH servers, no DoH upgrade should be attempted.
   DnsConfigOverrides overrides;
   const auto dns_over_https_servers_overrides =
-      ParseDohTemplates({"https://doh.server.override.com/"});
+      DnsOverHttpsConfig::FromString("https://doh.server.override.com/")
+          ->servers();
   overrides.dns_over_https_servers = dns_over_https_servers_overrides;
   resolver_->SetDnsConfigOverrides(overrides);
   const DnsConfig* fetched_config = client_ptr->GetEffectiveConfig();
@@ -8506,7 +8476,8 @@
   // If the overrides contains DoH servers, no DoH upgrade should be attempted.
   DnsConfigOverrides overrides;
   const auto dns_over_https_servers_overrides =
-      ParseDohTemplates({"https://doh.server.override.com/"});
+      DnsOverHttpsConfig::FromString("https://doh.server.override.com/")
+          ->servers();
   overrides.dns_over_https_servers = dns_over_https_servers_overrides;
   resolver_->SetDnsConfigOverrides(overrides);
   const DnsConfig* fetched_config = client_ptr->GetEffectiveConfig();
@@ -8535,10 +8506,12 @@
 
   const DnsConfig* fetched_config = client_ptr->GetEffectiveConfig();
   EXPECT_EQ(original_config.nameservers, fetched_config->nameservers);
-  auto expected_doh_servers = ParseDohTemplates(
-      {"https://chrome.cloudflare-dns.com/dns-query",
-       "https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
-       "https://doh.cleanbrowsing.org/doh/security-filter{?dns}"});
+  auto expected_doh_servers =
+      DnsOverHttpsConfig::FromStrings(
+          {"https://chrome.cloudflare-dns.com/dns-query",
+           "https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
+           "https://doh.cleanbrowsing.org/doh/security-filter{?dns}"})
+          ->servers();
   EXPECT_EQ(expected_doh_servers, fetched_config->dns_over_https_servers);
 }
 
@@ -8563,8 +8536,9 @@
   ChangeDnsConfig(original_config);
   const DnsConfig* fetched_config = client_ptr->GetEffectiveConfig();
   EXPECT_EQ(original_config.nameservers, fetched_config->nameservers);
-  const auto expected_doh_servers =
-      ParseDohTemplates({"https://dns.google/dns-query{?dns}"});
+  auto expected_doh_servers =
+      DnsOverHttpsConfig::FromString("https://dns.google/dns-query{?dns}")
+          ->servers();
   EXPECT_EQ(expected_doh_servers, fetched_config->dns_over_https_servers);
 }
 
diff --git a/net/dns/public/BUILD.gn b/net/dns/public/BUILD.gn
index 92d865ed..844b39c 100644
--- a/net/dns/public/BUILD.gn
+++ b/net/dns/public/BUILD.gn
@@ -20,6 +20,8 @@
   sources = [
     "dns_config_overrides.cc",
     "dns_config_overrides.h",
+    "dns_over_https_config.cc",
+    "dns_over_https_config.h",
     "dns_over_https_server_config.cc",
     "dns_over_https_server_config.h",
     "dns_protocol.h",
@@ -67,9 +69,9 @@
 source_set("tests") {
   testonly = true
   sources = [
+    "dns_over_https_config_unittest.cc",
     "dns_over_https_server_config_unittest.cc",
     "doh_provider_entry_unittest.cc",
-    "util_unittest.cc",
   ]
 
   if (is_posix && !is_android) {
@@ -82,6 +84,7 @@
 
   deps = [
     "//net",
+    "//testing/gmock",
     "//testing/gtest",
   ]
 }
diff --git a/net/dns/public/dns_over_https_config.cc b/net/dns/public/dns_over_https_config.cc
new file mode 100644
index 0000000..6792400
--- /dev/null
+++ b/net/dns/public/dns_over_https_config.cc
@@ -0,0 +1,115 @@
+// Copyright 2022 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 "net/dns/public/dns_over_https_config.h"
+
+#include <iterator>
+#include <string>
+#include <vector>
+
+#include "base/ranges/algorithm.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "net/dns/public/dns_over_https_server_config.h"
+#include "net/dns/public/util.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace net {
+
+namespace {
+
+std::vector<std::string> SplitGroup(base::StringPiece group) {
+  // Templates in a group are whitespace-separated.
+  return SplitString(group, " ", base::TRIM_WHITESPACE,
+                     base::SPLIT_WANT_NONEMPTY);
+}
+
+std::vector<absl::optional<DnsOverHttpsServerConfig>> ParseServers(
+    std::vector<std::string> servers) {
+  std::vector<absl::optional<DnsOverHttpsServerConfig>> parsed;
+  parsed.reserve(servers.size());
+  base::ranges::transform(servers, std::back_inserter(parsed), [](auto& s) {
+    return DnsOverHttpsServerConfig::FromString(std::move(s));
+  });
+  return parsed;
+}
+
+}  // namespace
+
+DnsOverHttpsConfig::DnsOverHttpsConfig() = default;
+DnsOverHttpsConfig::~DnsOverHttpsConfig() = default;
+DnsOverHttpsConfig::DnsOverHttpsConfig(const DnsOverHttpsConfig& other) =
+    default;
+DnsOverHttpsConfig& DnsOverHttpsConfig::operator=(
+    const DnsOverHttpsConfig& other) = default;
+DnsOverHttpsConfig::DnsOverHttpsConfig(DnsOverHttpsConfig&& other) = default;
+DnsOverHttpsConfig& DnsOverHttpsConfig::operator=(DnsOverHttpsConfig&& other) =
+    default;
+
+DnsOverHttpsConfig::DnsOverHttpsConfig(
+    std::vector<DnsOverHttpsServerConfig> servers)
+    : servers_(std::move(servers)) {}
+
+// static
+absl::optional<DnsOverHttpsConfig> DnsOverHttpsConfig::FromStrings(
+    std::vector<std::string> server_strings) {
+  // All templates must be valid for the group to be considered valid.
+  std::vector<DnsOverHttpsServerConfig> servers;
+  for (auto& server_config : ParseServers(server_strings)) {
+    if (!server_config)
+      return absl::nullopt;
+    servers.push_back(std::move(*server_config));
+  }
+  return DnsOverHttpsConfig(std::move(servers));
+}
+
+// static
+absl::optional<DnsOverHttpsConfig> DnsOverHttpsConfig::FromString(
+    base::StringPiece doh_config) {
+  // TODO(crbug.com/1200908): Also accept JSON-formatted input.
+  std::vector<std::string> server_strings = SplitGroup(doh_config);
+  if (server_strings.empty())
+    return absl::nullopt;  // `doh_config` must contain at least one server.
+  return FromStrings(std::move(server_strings));
+}
+
+// static
+DnsOverHttpsConfig DnsOverHttpsConfig::FromStringLax(
+    base::StringPiece doh_config) {
+  auto parsed = ParseServers(SplitGroup(doh_config));
+  std::vector<DnsOverHttpsServerConfig> servers;
+  for (auto& server_config : parsed) {
+    if (server_config)
+      servers.push_back(std::move(*server_config));
+  }
+  return DnsOverHttpsConfig(std::move(servers));
+}
+
+bool DnsOverHttpsConfig::operator==(const DnsOverHttpsConfig& other) const {
+  return servers() == other.servers();
+}
+
+std::vector<base::StringPiece> DnsOverHttpsConfig::ToStrings() const {
+  std::vector<base::StringPiece> strings;
+  strings.reserve(servers().size());
+  base::ranges::transform(servers(), std::back_inserter(strings),
+                          &DnsOverHttpsServerConfig::server_template_piece);
+  return strings;
+}
+
+std::string DnsOverHttpsConfig::ToString() const {
+  // TODO(crbug.com/1200908): Return JSON for complex configurations.
+  return base::JoinString(ToStrings(), " ");
+}
+
+base::Value DnsOverHttpsConfig::ToValue() const {
+  base::Value::ListStorage list;
+  list.reserve(servers().size());
+  base::ranges::transform(servers(), std::back_inserter(list),
+                          &DnsOverHttpsServerConfig::ToValue);
+  return base::Value(std::move(list));
+}
+
+}  // namespace net
diff --git a/net/dns/public/dns_over_https_config.h b/net/dns/public/dns_over_https_config.h
new file mode 100644
index 0000000..fb030d6c
--- /dev/null
+++ b/net/dns/public/dns_over_https_config.h
@@ -0,0 +1,70 @@
+// Copyright 2022 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 NET_DNS_PUBLIC_DNS_OVER_HTTPS_CONFIG_H_
+#define NET_DNS_PUBLIC_DNS_OVER_HTTPS_CONFIG_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string_piece.h"
+#include "base/values.h"
+#include "net/base/net_export.h"
+#include "net/dns/public/dns_over_https_server_config.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace net {
+
+// Represents a collection of DnsOverHttpsServerConfig.  The string
+// representation is a whitespace-separated list of DoH URI templates.
+// The Value representation is a list of dictionaries.
+class NET_EXPORT DnsOverHttpsConfig {
+ public:
+  DnsOverHttpsConfig();
+  ~DnsOverHttpsConfig();
+  DnsOverHttpsConfig(const DnsOverHttpsConfig& other);
+  DnsOverHttpsConfig& operator=(const DnsOverHttpsConfig& other);
+  DnsOverHttpsConfig(DnsOverHttpsConfig&& other);
+  DnsOverHttpsConfig& operator=(DnsOverHttpsConfig&& other);
+
+  explicit DnsOverHttpsConfig(std::vector<DnsOverHttpsServerConfig> servers);
+
+  // Constructs a Config from textual representations of zero or more servers.
+  // Returns `nullopt` if any string is invalid.
+  static absl::optional<DnsOverHttpsConfig> FromStrings(
+      std::vector<std::string> servers);
+
+  // Constructs a Config from its text form if valid.  Returns `nullopt` if the
+  // input is empty or invalid (even partly invalid).
+  static absl::optional<DnsOverHttpsConfig> FromString(
+      base::StringPiece doh_config);
+
+  // Constructs a DnsOverHttpsConfig from its text form, skipping any invalid
+  // templates.  The result may be empty.
+  static DnsOverHttpsConfig FromStringLax(base::StringPiece doh_config);
+
+  bool operator==(const DnsOverHttpsConfig& other) const;
+
+  // The servers that comprise this config.  May be empty.
+  const std::vector<DnsOverHttpsServerConfig>& servers() const {
+    return servers_;
+  }
+
+  // Returns string representations of the individual DnsOverHttpsServerConfigs.
+  // The return value will be invalidated if this object is destroyed or moved.
+  std::vector<base::StringPiece> ToStrings() const;
+
+  // Inverse of FromString().
+  std::string ToString() const;
+
+  // Encodes the config as a Value.  Currently only used for NetLog.
+  base::Value ToValue() const;
+
+ private:
+  std::vector<DnsOverHttpsServerConfig> servers_;
+};
+
+}  // namespace net
+
+#endif  // NET_DNS_PUBLIC_DNS_OVER_HTTPS_CONFIG_H_
diff --git a/net/dns/public/dns_over_https_config_unittest.cc b/net/dns/public/dns_over_https_config_unittest.cc
new file mode 100644
index 0000000..9badafcf
--- /dev/null
+++ b/net/dns/public/dns_over_https_config_unittest.cc
@@ -0,0 +1,141 @@
+// Copyright 2022 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 "net/dns/public/dns_over_https_config.h"
+
+#include "base/values.h"
+#include "net/dns/public/dns_over_https_server_config.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+const DnsOverHttpsServerConfig kServerConfig1 =
+    *DnsOverHttpsServerConfig::FromString("https://example1.test");
+const DnsOverHttpsServerConfig kServerConfig2 =
+    *DnsOverHttpsServerConfig::FromString("https://example2.test");
+
+TEST(DnsOverHttpsConfigTest, SingleValue) {
+  DnsOverHttpsConfig config({kServerConfig1});
+  EXPECT_THAT(config.servers(), testing::ElementsAre(kServerConfig1));
+
+  base::Value expected_value(base::Value::Type::LIST);
+  expected_value.Append(kServerConfig1.ToValue());
+  EXPECT_EQ(expected_value, config.ToValue());
+
+  EXPECT_EQ(config, config);
+}
+
+TEST(DnsOverHttpsConfigTest, MultiValue) {
+  std::vector<DnsOverHttpsServerConfig> servers{kServerConfig1, kServerConfig2};
+  DnsOverHttpsConfig config(servers);
+  EXPECT_EQ(servers, config.servers());
+
+  EXPECT_THAT(config.ToStrings(),
+              testing::ElementsAre(kServerConfig1.server_template(),
+                                   kServerConfig2.server_template()));
+  EXPECT_EQ(
+      kServerConfig1.server_template() + " " + kServerConfig2.server_template(),
+      config.ToString());
+
+  base::Value expected_value(base::Value::Type::LIST);
+  expected_value.Append(kServerConfig1.ToValue());
+  expected_value.Append(kServerConfig2.ToValue());
+  EXPECT_EQ(expected_value, config.ToValue());
+
+  EXPECT_EQ(config, config);
+}
+
+TEST(DnsOverHttpsConfigTest, Equal) {
+  DnsOverHttpsConfig a({kServerConfig1});
+  DnsOverHttpsConfig a2({kServerConfig1});
+  DnsOverHttpsConfig b({kServerConfig1, kServerConfig2});
+  DnsOverHttpsConfig b2({kServerConfig1, kServerConfig2});
+
+  EXPECT_EQ(a, a2);
+  EXPECT_EQ(b, b2);
+}
+
+TEST(DnsOverHttpsConfigTest, NotEqual) {
+  DnsOverHttpsConfig a({kServerConfig1});
+  DnsOverHttpsConfig b({kServerConfig2});
+  DnsOverHttpsConfig c({kServerConfig1, kServerConfig2});
+  DnsOverHttpsConfig d({kServerConfig2, kServerConfig1});
+
+  EXPECT_FALSE(a == b);
+  EXPECT_FALSE(a == c);
+  EXPECT_FALSE(a == d);
+  EXPECT_FALSE(c == d);
+}
+
+TEST(DnsOverHttpsConfigTest, FromStringSingleValue) {
+  auto config =
+      DnsOverHttpsConfig::FromString(kServerConfig1.server_template());
+  EXPECT_THAT(config, testing::Optional(DnsOverHttpsConfig({kServerConfig1})));
+}
+
+TEST(DnsOverHttpsConfigTest, FromStringMultiValue) {
+  auto config =
+      DnsOverHttpsConfig::FromString(kServerConfig1.server_template() + " " +
+                                     kServerConfig2.server_template());
+  EXPECT_THAT(
+      config,
+      testing::Optional(DnsOverHttpsConfig({kServerConfig1, kServerConfig2})));
+}
+
+TEST(DnsOverHttpsConfigTest, FromStrings) {
+  EXPECT_THAT(DnsOverHttpsConfig::FromStrings({}),
+              testing::Optional(DnsOverHttpsConfig()));
+  EXPECT_THAT(
+      DnsOverHttpsConfig::FromStrings({kServerConfig1.server_template()}),
+      testing::Optional(DnsOverHttpsConfig({kServerConfig1})));
+  EXPECT_THAT(
+      DnsOverHttpsConfig::FromStrings(
+          {kServerConfig1.server_template(), kServerConfig2.server_template()}),
+      testing::Optional(DnsOverHttpsConfig({kServerConfig1, kServerConfig2})));
+}
+
+TEST(DnsOverHttpsConfigTest, FromStringExtraWhitespace) {
+  auto config = DnsOverHttpsConfig::FromString(
+      "  \t" + kServerConfig1.server_template() + "    " +
+      kServerConfig2.server_template() + "\n ");
+  EXPECT_THAT(
+      config,
+      testing::Optional(DnsOverHttpsConfig({kServerConfig1, kServerConfig2})));
+
+  EXPECT_FALSE(
+      DnsOverHttpsConfig::FromString(kServerConfig1.server_template() + "\t" +
+                                     kServerConfig2.server_template()));
+}
+
+TEST(DnsOverHttpsConfigTest, FromStringEmpty) {
+  EXPECT_FALSE(DnsOverHttpsConfig::FromString(""));
+  EXPECT_EQ(DnsOverHttpsConfig(), DnsOverHttpsConfig::FromStringLax(""));
+}
+
+TEST(DnsOverHttpsConfigTest, FromStringAllInvalid) {
+  EXPECT_FALSE(DnsOverHttpsConfig::FromString("foo"));
+  EXPECT_FALSE(DnsOverHttpsConfig::FromStrings({"foo"}));
+  EXPECT_EQ(DnsOverHttpsConfig(), DnsOverHttpsConfig::FromStringLax("foo"));
+
+  EXPECT_FALSE(DnsOverHttpsConfig::FromString("foo bar"));
+  EXPECT_FALSE(DnsOverHttpsConfig::FromStrings({"foo", "bar"}));
+  EXPECT_EQ(DnsOverHttpsConfig(), DnsOverHttpsConfig::FromStringLax("foo bar"));
+}
+
+TEST(DnsOverHttpsConfigTest, FromStringSomeInvalid) {
+  EXPECT_FALSE(DnsOverHttpsConfig::FromStrings(
+      {"foo", kServerConfig1.server_template(), "bar"}));
+
+  std::string some_invalid = "foo " + kServerConfig1.server_template() +
+                             " bar " + kServerConfig2.server_template() +
+                             " baz";
+  EXPECT_FALSE(DnsOverHttpsConfig::FromString(some_invalid));
+  EXPECT_EQ(DnsOverHttpsConfig({kServerConfig1, kServerConfig2}),
+            DnsOverHttpsConfig::FromStringLax(some_invalid));
+}
+
+}  // namespace
+}  // namespace net
diff --git a/net/dns/public/dns_over_https_server_config.cc b/net/dns/public/dns_over_https_server_config.cc
index 5a4e0ecb..51aa35e 100644
--- a/net/dns/public/dns_over_https_server_config.cc
+++ b/net/dns/public/dns_over_https_server_config.cc
@@ -4,21 +4,80 @@
 
 #include "net/dns/public/dns_over_https_server_config.h"
 
+#include <set>
 #include <string>
+#include <unordered_map>
 
-#include "net/dns/public/util.h"
+#include "base/strings/string_piece.h"
+#include "base/values.h"
+#include "net/third_party/uri_template/uri_template.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "url/url_canon.h"
+#include "url/url_canon_stdstring.h"
+#include "url/url_constants.h"
+
+namespace {
+
+absl::optional<std::string> GetHttpsHost(const std::string& url) {
+  // This code is used to compute a static initializer, so it runs before GURL's
+  // scheme registry is initialized.  Since GURL is not ready yet, we need to
+  // duplicate some of its functionality here.
+  url::Parsed parsed;
+  url::ParseStandardURL(url.data(), url.size(), &parsed);
+  std::string canonical;
+  url::StdStringCanonOutput output(&canonical);
+  url::Parsed canonical_parsed;
+  bool is_valid =
+      url::CanonicalizeStandardURL(url.data(), url.size(), parsed,
+                                   url::SchemeType::SCHEME_WITH_HOST_AND_PORT,
+                                   nullptr, &output, &canonical_parsed);
+  if (!is_valid)
+    return absl::nullopt;
+  const url::Component& scheme_range = canonical_parsed.scheme;
+  base::StringPiece scheme =
+      base::StringPiece(canonical).substr(scheme_range.begin, scheme_range.len);
+  if (scheme != url::kHttpsScheme)
+    return absl::nullopt;
+  const url::Component& host_range = canonical_parsed.host;
+  return canonical.substr(host_range.begin, host_range.len);
+}
+
+bool IsValidDohTemplate(const std::string& server_template, bool* use_post) {
+  std::string url_string;
+  std::string test_query = "this_is_a_test_query";
+  std::unordered_map<std::string, std::string> template_params(
+      {{"dns", test_query}});
+  std::set<std::string> vars_found;
+  bool valid_template = uri_template::Expand(server_template, template_params,
+                                             &url_string, &vars_found);
+  if (!valid_template) {
+    // The URI template is malformed.
+    return false;
+  }
+  absl::optional<std::string> host = GetHttpsHost(url_string);
+  if (!host) {
+    // The expanded template must be a valid HTTPS URL.
+    return false;
+  }
+  if (host->find(test_query) != std::string::npos) {
+    // The dns variable must not be part of the hostname.
+    return false;
+  }
+  // If the template contains a dns variable, use GET, otherwise use POST.
+  *use_post = vars_found.find("dns") == vars_found.end();
+  return true;
+}
+
+}  // namespace
 
 namespace net {
 
 absl::optional<DnsOverHttpsServerConfig> DnsOverHttpsServerConfig::FromString(
     std::string doh_template) {
-  std::string server_method;
-  if (!dns_util::IsValidDohTemplate(doh_template, &server_method)) {
+  bool use_post;
+  if (!IsValidDohTemplate(doh_template, &use_post))
     return absl::nullopt;
-  }
-  return DnsOverHttpsServerConfig(std::move(doh_template),
-                                  server_method == "POST");
+  return DnsOverHttpsServerConfig(std::move(doh_template), use_post);
 }
 
 bool DnsOverHttpsServerConfig::operator==(
@@ -36,8 +95,18 @@
   return server_template_;
 }
 
+base::StringPiece DnsOverHttpsServerConfig::server_template_piece() const {
+  return server_template_;
+}
+
 bool DnsOverHttpsServerConfig::use_post() const {
   return use_post_;
 }
 
+base::Value DnsOverHttpsServerConfig::ToValue() const {
+  base::Value value(base::Value::Type::DICTIONARY);
+  value.SetStringKey("server_template", server_template());
+  return value;
+}
+
 }  // namespace net
diff --git a/net/dns/public/dns_over_https_server_config.h b/net/dns/public/dns_over_https_server_config.h
index 945ad17..75bdd01 100644
--- a/net/dns/public/dns_over_https_server_config.h
+++ b/net/dns/public/dns_over_https_server_config.h
@@ -7,6 +7,8 @@
 
 #include <string>
 
+#include "base/strings/string_piece.h"
+#include "base/values.h"
 #include "net/base/net_export.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -27,8 +29,11 @@
   bool operator<(const DnsOverHttpsServerConfig& other) const;
 
   const std::string& server_template() const;
+  base::StringPiece server_template_piece() const;
   bool use_post() const;
 
+  base::Value ToValue() const;
+
  private:
   DnsOverHttpsServerConfig(std::string server_template, bool use_post)
       : server_template_(std::move(server_template)), use_post_(use_post) {}
diff --git a/net/dns/public/dns_over_https_server_config_unittest.cc b/net/dns/public/dns_over_https_server_config_unittest.cc
index edc6e019..39f8e47 100644
--- a/net/dns/public/dns_over_https_server_config_unittest.cc
+++ b/net/dns/public/dns_over_https_server_config_unittest.cc
@@ -6,36 +6,65 @@
 
 #include <string>
 
+#include "net/dns/public/dns_over_https_config.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace net {
 namespace {
 
 TEST(DnsOverHttpsServerConfigTest, ValidWithGet) {
-  const std::string input = "https://example/{?dns}";
-  const auto parsed = net::DnsOverHttpsServerConfig::FromString(input);
-  ASSERT_TRUE(parsed.has_value());
-  EXPECT_EQ(input, parsed->server_template());
-  EXPECT_FALSE(parsed->use_post());
+  auto parsed = DnsOverHttpsServerConfig::FromString(
+      "https://dnsserver.example.net/dns-query{?dns}");
+  EXPECT_THAT(parsed, testing::Optional(testing::Property(
+                          &DnsOverHttpsServerConfig::use_post, false)));
+
+  parsed = DnsOverHttpsServerConfig::FromString(
+      "https://dnsserver.example.net/dns-query{?dns,extra}");
+  EXPECT_THAT(parsed, testing::Optional(testing::Property(
+                          &DnsOverHttpsServerConfig::use_post, false)));
+
+  parsed = DnsOverHttpsServerConfig::FromString(
+      "https://query:{dns}@dnsserver.example.net");
+  EXPECT_THAT(parsed, testing::Optional(testing::Property(
+                          &DnsOverHttpsServerConfig::use_post, false)));
+
+  parsed = DnsOverHttpsServerConfig::FromString(
+      "https://dnsserver.example.net{/dns}");
+  EXPECT_THAT(parsed, testing::Optional(testing::Property(
+                          &DnsOverHttpsServerConfig::use_post, false)));
 }
 
 TEST(DnsOverHttpsServerConfigTest, ValidWithPost) {
-  const std::string input = "https://example/";
-  const auto parsed = net::DnsOverHttpsServerConfig::FromString(input);
-  ASSERT_TRUE(parsed.has_value());
-  EXPECT_EQ(input, parsed->server_template());
-  EXPECT_TRUE(parsed->use_post());
+  auto parsed = DnsOverHttpsServerConfig::FromString(
+      "https://dnsserver.example.net/dns-query{?query}");
+  EXPECT_THAT(parsed, testing::Optional(testing::Property(
+                          &DnsOverHttpsServerConfig::use_post, true)));
+
+  parsed = DnsOverHttpsServerConfig::FromString(
+      "https://dnsserver.example.net/dns-query");
+  EXPECT_THAT(parsed, testing::Optional(testing::Property(
+                          &DnsOverHttpsServerConfig::use_post, true)));
 }
 
 TEST(DnsOverHttpsServerConfigTest, Invalid) {
-  const std::string input = "http://example/{?dns}";
-  const auto parsed = net::DnsOverHttpsServerConfig::FromString(input);
-  EXPECT_FALSE(parsed.has_value());
+  // Invalid template format
+  EXPECT_FALSE(DnsOverHttpsServerConfig::FromString(
+      "https://dnsserver.example.net/dns-query{{?dns}}"));
+  // Must be HTTPS
+  EXPECT_FALSE(DnsOverHttpsServerConfig::FromString(
+      "http://dnsserver.example.net/dns-query"));
+  EXPECT_FALSE(DnsOverHttpsServerConfig::FromString(
+      "http://dnsserver.example.net/dns-query{?dns}"));
+  // Template must expand to a valid URL
+  EXPECT_FALSE(DnsOverHttpsServerConfig::FromString("https://{?dns}"));
+  // The hostname must not contain the dns variable
+  EXPECT_FALSE(
+      DnsOverHttpsServerConfig::FromString("https://{dns}.dnsserver.net"));
 }
 
 TEST(DnsOverHttpsServerConfigTest, Empty) {
-  const auto parsed = net::DnsOverHttpsServerConfig::FromString("");
-  EXPECT_FALSE(parsed.has_value());
+  EXPECT_FALSE(net::DnsOverHttpsServerConfig::FromString(""));
 }
 
 }  // namespace
diff --git a/net/dns/public/util.cc b/net/dns/public/util.cc
index 48c16ac..c7cedc3 100644
--- a/net/dns/public/util.cc
+++ b/net/dns/public/util.cc
@@ -4,21 +4,11 @@
 
 #include "net/dns/public/util.h"
 
-#include <set>
-#include <unordered_map>
-
 #include "base/check.h"
 #include "base/notreached.h"
-#include "base/strings/string_piece.h"
 #include "build/build_config.h"
 #include "net/base/ip_address.h"
 #include "net/dns/public/dns_protocol.h"
-#include "net/third_party/uri_template/uri_template.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-#include "url/third_party/mozilla/url_parse.h"
-#include "url/url_canon.h"
-#include "url/url_canon_stdstring.h"
-#include "url/url_constants.h"
 
 namespace net {
 
@@ -32,64 +22,10 @@
                     dns_protocol::kDefaultPortMulticast);
 }
 
-absl::optional<std::string> GetHttpsHost(const std::string& url) {
-  // This code is used to compute a static initializer, so it runs before GURL's
-  // scheme registry is initialized.  Since GURL is not ready yet, we need to
-  // duplicate some of its functionality here.
-  url::Parsed parsed;
-  url::ParseStandardURL(url.data(), url.size(), &parsed);
-  std::string canonical;
-  url::StdStringCanonOutput output(&canonical);
-  url::Parsed canonical_parsed;
-  bool is_valid =
-      url::CanonicalizeStandardURL(url.data(), url.size(), parsed,
-                                   url::SchemeType::SCHEME_WITH_HOST_AND_PORT,
-                                   nullptr, &output, &canonical_parsed);
-  if (!is_valid)
-    return absl::nullopt;
-  const url::Component& scheme_range = canonical_parsed.scheme;
-  base::StringPiece scheme =
-      base::StringPiece(canonical).substr(scheme_range.begin, scheme_range.len);
-  if (scheme != url::kHttpsScheme)
-    return absl::nullopt;
-  const url::Component& host_range = canonical_parsed.host;
-  return canonical.substr(host_range.begin, host_range.len);
-}
-
 }  // namespace
 
 namespace dns_util {
 
-bool IsValidDohTemplate(base::StringPiece server_template,
-                        std::string* server_method) {
-  std::string url_string;
-  std::string test_query = "this_is_a_test_query";
-  std::unordered_map<std::string, std::string> template_params(
-      {{"dns", test_query}});
-  std::set<std::string> vars_found;
-  bool valid_template = uri_template::Expand(
-      std::string(server_template), template_params, &url_string, &vars_found);
-  if (!valid_template) {
-    // The URI template is malformed.
-    return false;
-  }
-  absl::optional<std::string> host = GetHttpsHost(url_string);
-  if (!host) {
-    // The expanded template must be a valid HTTPS URL.
-    return false;
-  }
-  if (host->find(test_query) != std::string::npos) {
-    // The dns variable may not be part of the hostname.
-    return false;
-  }
-  // If the template contains a dns variable, use GET, otherwise use POST.
-  if (server_method) {
-    *server_method =
-        (vars_found.find("dns") == vars_found.end()) ? "POST" : "GET";
-  }
-  return true;
-}
-
 IPEndPoint GetMdnsGroupEndPoint(AddressFamily address_family) {
   switch (address_family) {
     case ADDRESS_FAMILY_IPV4:
diff --git a/net/dns/public/util.h b/net/dns/public/util.h
index 53f26ea..12f27a86 100644
--- a/net/dns/public/util.h
+++ b/net/dns/public/util.h
@@ -5,9 +5,6 @@
 #ifndef NET_DNS_PUBLIC_UTIL_H_
 #define NET_DNS_PUBLIC_UTIL_H_
 
-#include <string>
-
-#include "base/strings/string_piece.h"
 #include "net/base/address_family.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_export.h"
@@ -17,13 +14,6 @@
 // Basic utility functions for interaction with MDNS and host resolution.
 namespace dns_util {
 
-// Returns true if the URI template is acceptable for sending requests. If so,
-// the |server_method| is set to "GET" if the template contains a "dns" variable
-// and to "POST" otherwise. Any "dns" variable may not be part of the hostname,
-// and the expanded template must parse to a valid HTTPS URL.
-NET_EXPORT_PRIVATE bool IsValidDohTemplate(base::StringPiece server_template,
-                                           std::string* server_method);
-
 // Gets the endpoint for the multicast group a socket should join to receive
 // MDNS messages. Such sockets should also bind to the endpoint from
 // GetMDnsReceiveEndPoint().
diff --git a/net/dns/public/util_unittest.cc b/net/dns/public/util_unittest.cc
deleted file mode 100644
index e68982d2..0000000
--- a/net/dns/public/util_unittest.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2020 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 "net/dns/public/util.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-namespace dns_util {
-
-TEST(DnsPublicUtilTest, IsValidDohTemplate) {
-  std::string server_method;
-  EXPECT_TRUE(IsValidDohTemplate(
-      "https://dnsserver.example.net/dns-query{?dns}", &server_method));
-  EXPECT_EQ("GET", server_method);
-
-  EXPECT_TRUE(IsValidDohTemplate(
-      "https://dnsserver.example.net/dns-query{?dns,extra}", &server_method));
-  EXPECT_EQ("GET", server_method);
-
-  EXPECT_TRUE(IsValidDohTemplate(
-      "https://dnsserver.example.net/dns-query{?query}", &server_method));
-  EXPECT_EQ("POST", server_method);
-
-  EXPECT_TRUE(IsValidDohTemplate("https://dnsserver.example.net/dns-query",
-                                 &server_method));
-  EXPECT_EQ("POST", server_method);
-
-  EXPECT_TRUE(IsValidDohTemplate("https://query:{dns}@dnsserver.example.net",
-                                 &server_method));
-  EXPECT_EQ("GET", server_method);
-
-  EXPECT_TRUE(IsValidDohTemplate("https://dnsserver.example.net{/dns}",
-                                 &server_method));
-  EXPECT_EQ("GET", server_method);
-
-  // Invalid template format
-  EXPECT_FALSE(IsValidDohTemplate(
-      "https://dnsserver.example.net/dns-query{{?dns}}", &server_method));
-  // Must be HTTPS
-  EXPECT_FALSE(IsValidDohTemplate("http://dnsserver.example.net/dns-query",
-                                  &server_method));
-  EXPECT_FALSE(IsValidDohTemplate(
-      "http://dnsserver.example.net/dns-query{?dns}", &server_method));
-  // Template must expand to a valid URL
-  EXPECT_FALSE(IsValidDohTemplate("https://{?dns}", &server_method));
-  // The hostname must not contain the dns variable
-  EXPECT_FALSE(
-      IsValidDohTemplate("https://{dns}.dnsserver.net", &server_method));
-}
-
-}  // namespace dns_util
-
-}  // namespace net
diff --git a/net/dns/resolve_context.cc b/net/dns/resolve_context.cc
index 5374565..ce109381 100644
--- a/net/dns/resolve_context.cc
+++ b/net/dns/resolve_context.cc
@@ -529,7 +529,7 @@
   DCHECK(IsCurrentSession(session));
 
   if (is_doh_server) {
-    return GetDohProviderIdForHistogramFromDohConfig(
+    return GetDohProviderIdForHistogramFromServerConfig(
         session->config().dns_over_https_servers[server_index]);
   }
 
@@ -544,7 +544,7 @@
 
   DohProviderEntry::List matching_entries;
   if (is_doh_server) {
-    DnsOverHttpsServerConfig server_config =
+    const DnsOverHttpsServerConfig& server_config =
         session->config().dns_over_https_servers[server_index];
     matching_entries = FindDohProvidersMatchingServerConfig(server_config);
   } else {
diff --git a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
index 110d1d3..21fca6e 100644
--- a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
+++ b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
@@ -80,6 +80,12 @@
     "ReportingAndNEL.NumberOfLoadedReportingEndpoints";
 const char kNumberOfLoadedReportingEndpointGroupsHistogramName[] =
     "ReportingAndNEL.NumberOfLoadedReportingEndpointGroups";
+const char kNumberOfLoadedNelPolicies2HistogramName[] =
+    "ReportingAndNEL.NumberOfLoadedNELPolicies2";
+const char kNumberOfLoadedReportingEndpoints2HistogramName[] =
+    "ReportingAndNEL.NumberOfLoadedReportingEndpoints2";
+const char kNumberOfLoadedReportingEndpointGroups2HistogramName[] =
+    "ReportingAndNEL.NumberOfLoadedReportingEndpointGroups2";
 }  // namespace
 
 base::TaskPriority GetReportingAndNelStoreBackgroundSequencePriority() {
@@ -1526,6 +1532,8 @@
     RecordNumberOfLoadedNelPolicies(size_t count) {
   // The NetworkErrorLoggingService stores up to 1000 policies.
   UMA_HISTOGRAM_COUNTS_1000(kNumberOfLoadedNelPoliciesHistogramName, count);
+  // TODO(crbug.com/1165308): Remove this metric once the investigation is done.
+  UMA_HISTOGRAM_COUNTS_10000(kNumberOfLoadedNelPolicies2HistogramName, count);
 }
 
 void SQLitePersistentReportingAndNelStore::Backend::
@@ -1533,6 +1541,9 @@
   // The ReportingCache stores up to 1000 endpoints.
   UMA_HISTOGRAM_COUNTS_1000(kNumberOfLoadedReportingEndpointsHistogramName,
                             count);
+  // TODO(crbug.com/1165308): Remove this metric once the investigation is done.
+  UMA_HISTOGRAM_COUNTS_10000(kNumberOfLoadedReportingEndpoints2HistogramName,
+                             count);
 }
 
 void SQLitePersistentReportingAndNelStore::Backend::
@@ -1541,6 +1552,9 @@
   // endpoint per group.
   UMA_HISTOGRAM_COUNTS_1000(kNumberOfLoadedReportingEndpointGroupsHistogramName,
                             count);
+  // TODO(crbug.com/1165308): Remove this metric once the investigation is done.
+  UMA_HISTOGRAM_COUNTS_10000(
+      kNumberOfLoadedReportingEndpointGroups2HistogramName, count);
 }
 
 SQLitePersistentReportingAndNelStore::SQLitePersistentReportingAndNelStore(
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index aadbb4e..3c2eae1 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -9314,7 +9314,7 @@
   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   SSLSocketDataProvider ssl1(ASYNC, OK);
   // When creating the second connection, only HTTP/1.1 should be allowed.
-  ssl1.next_protos_expected_in_ssl_config = NextProtoVector{};
+  ssl1.next_protos_expected_in_ssl_config = NextProtoVector{kProtoHTTP11};
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
 
   session_deps_.enable_websocket_over_http2 = true;
diff --git a/net/http/http_stream_factory_job.cc b/net/http/http_stream_factory_job.cc
index a831772..a01b633 100644
--- a/net/http/http_stream_factory_job.cc
+++ b/net/http/http_stream_factory_job.cc
@@ -831,8 +831,17 @@
   if (is_websocket_) {
     DCHECK(request_info_.socket_tag == SocketTag());
     DCHECK_EQ(SecureDnsPolicy::kAllow, request_info_.secure_dns_policy);
+    // Only offer HTTP/1.1 for WebSockets. Although RFC 8441 defines WebSockets
+    // over HTTP/2, a single WSS/HTTPS origin may support HTTP over HTTP/2
+    // without supporting WebSockets over HTTP/2. Offering HTTP/2 for a fresh
+    // connection would break such origins.
+    //
+    // However, still offer HTTP/1.1 rather than skipping ALPN entirely. While
+    // this will not change the application protocol (HTTP/1.1 is default), it
+    // provides hardens against cross-protocol attacks and allows for the False
+    // Start (RFC 7918) optimization.
     SSLConfig websocket_server_ssl_config = server_ssl_config_;
-    websocket_server_ssl_config.alpn_protos.clear();
+    websocket_server_ssl_config.alpn_protos = {kProtoHTTP11};
     return InitSocketHandleForWebSocketRequest(
         destination_, request_info_.load_flags, priority_, session_,
         proxy_info_, websocket_server_ssl_config, proxy_ssl_config_,
diff --git a/net/socket/transport_client_socket_pool_test_util.cc b/net/socket/transport_client_socket_pool_test_util.cc
index 6c299ff..297aa7a 100644
--- a/net/socket/transport_client_socket_pool_test_util.cc
+++ b/net/socket/transport_client_socket_pool_test_util.cc
@@ -85,10 +85,13 @@
   NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
   bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
   void GetConnectionAttempts(ConnectionAttempts* out) const override {
-    out->clear();
+    *out = connection_attempts_;
   }
-  void ClearConnectionAttempts() override {}
-  void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+  void ClearConnectionAttempts() override { connection_attempts_.clear(); }
+  void AddConnectionAttempts(const ConnectionAttempts& attempts) override {
+    connection_attempts_.insert(connection_attempts_.begin(), attempts.begin(),
+                                attempts.end());
+  }
   int64_t GetTotalReceivedBytes() const override {
     NOTIMPLEMENTED();
     return 0;
@@ -114,6 +117,7 @@
   bool connected_;
   const AddressList addrlist_;
   NetLogWithSource net_log_;
+  ConnectionAttempts connection_attempts_;
 };
 
 class MockFailingClientSocket : public TransportClientSocket {
@@ -133,6 +137,10 @@
 
   // StreamSocket implementation.
   int Connect(CompletionOnceCallback callback) override {
+    for (const auto& addr : addrlist_) {
+      connection_attempts_.push_back(
+          ConnectionAttempt(addr, ERR_CONNECTION_FAILED));
+    }
     return ERR_CONNECTION_FAILED;
   }
 
@@ -153,12 +161,13 @@
   NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
   bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
   void GetConnectionAttempts(ConnectionAttempts* out) const override {
-    out->clear();
-    for (const auto& addr : addrlist_)
-      out->push_back(ConnectionAttempt(addr, ERR_CONNECTION_FAILED));
+    *out = connection_attempts_;
   }
-  void ClearConnectionAttempts() override {}
-  void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+  void ClearConnectionAttempts() override { connection_attempts_.clear(); }
+  void AddConnectionAttempts(const ConnectionAttempts& attempts) override {
+    connection_attempts_.insert(connection_attempts_.begin(), attempts.begin(),
+                                attempts.end());
+  }
   int64_t GetTotalReceivedBytes() const override {
     NOTIMPLEMENTED();
     return 0;
@@ -184,6 +193,7 @@
  private:
   const AddressList addrlist_;
   NetLogWithSource net_log_;
+  ConnectionAttempts connection_attempts_;
 };
 
 class MockTriggerableClientSocket : public TransportClientSocket {
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index 901ec85..92a64f2 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -8719,8 +8719,8 @@
   StaticSocketDataProvider data2(reads2, writes2);
 
   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
-  // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled.
-  ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{};
+  // Test that the request has HTTP/2 disabled.
+  ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
   // Force socket to use HTTP/1.1, the default protocol without ALPN.
   ssl_provider2->next_proto = kProtoHTTP11;
   ssl_provider2->ssl_info.cert =
@@ -8842,8 +8842,8 @@
   SequencedSocketData data2(MockConnect(ASYNC, ERR_IO_PENDING), reads2,
                             writes2);
   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
-  // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled.
-  ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{};
+  // Test that the request has HTTP/2 disabled.
+  ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
   // Force socket to use HTTP/1.1, the default protocol without ALPN.
   ssl_provider2->next_proto = kProtoHTTP11;
   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
@@ -9118,8 +9118,8 @@
       &tunnel_ssl_data2);
 
   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
-  // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled.
-  ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{};
+  // Test that the request has HTTP/2 disabled.
+  ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
   // Force socket to use HTTP/1.1, the default protocol without ALPN.
   ssl_provider2->next_proto = kProtoHTTP11;
   helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2));
@@ -9384,8 +9384,8 @@
                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
   StaticSocketDataProvider data2(reads2, writes2);
   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
-  // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled.
-  ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{};
+  // Test that the request has HTTP/2 disabled.
+  ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
   // Force socket to use HTTP/1.1, the default protocol without ALPN.
   ssl_provider2->next_proto = kProtoHTTP11;
   ssl_provider2->ssl_info.cert =
@@ -9493,8 +9493,8 @@
   StaticSocketDataProvider data;
 
   auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
-  // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled.
-  ssl_provider->next_protos_expected_in_ssl_config = NextProtoVector{};
+  // Test that the request has HTTP/2 disabled.
+  ssl_provider->next_protos_expected_in_ssl_config = {kProtoHTTP11};
   // Force socket to use HTTP/2, which should never happen (TLS implementation
   // should fail TLS handshake if server chooses HTTP/2 without client
   // advertising support).
@@ -9584,8 +9584,8 @@
                "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
   StaticSocketDataProvider data2(reads2, writes2);
   auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
-  // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled.
-  ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{};
+  // Test that the request has HTTP/2 disabled.
+  ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11};
   // Force socket to use HTTP/1.1, the default protocol without ALPN.
   ssl_provider2->next_proto = kProtoHTTP11;
   ssl_provider2->ssl_info.cert =
@@ -9757,7 +9757,7 @@
   ssl_provider.ssl_info.cert =
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
   // A WebSocket request should not advertise HTTP/2 support.
-  ssl_provider.next_protos_expected_in_ssl_config = NextProtoVector{};
+  ssl_provider.next_protos_expected_in_ssl_config = {kProtoHTTP11};
   // This test uses WebSocket over HTTP/1.1.
   ssl_provider.next_proto = kProtoHTTP11;
   helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
@@ -9817,7 +9817,7 @@
   ssl_provider.ssl_info.cert =
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
   // A WebSocket request should not advertise HTTP/2 support.
-  ssl_provider.next_protos_expected_in_ssl_config = NextProtoVector{};
+  ssl_provider.next_protos_expected_in_ssl_config = {kProtoHTTP11};
   // The server should not negotiate HTTP/2 over the tunnelled connection,
   // but it must be handled gracefully if it does.
   ssl_provider.next_proto = kProtoHTTP2;
diff --git a/pdf/pdfium/pdfium_permissions.cc b/pdf/pdfium/pdfium_permissions.cc
index 22d0eece..6f0f24d1 100644
--- a/pdf/pdfium/pdfium_permissions.cc
+++ b/pdf/pdfium/pdfium_permissions.cc
@@ -4,21 +4,29 @@
 
 #include "pdf/pdfium/pdfium_permissions.h"
 
+#include <stdint.h>
+
+#include "base/numerics/safe_conversions.h"
+
 namespace chrome_pdf {
 
 // static
 PDFiumPermissions PDFiumPermissions::CreateForTesting(
     int permissions_handler_revision,
-    unsigned long permission_bits) {
+    uint32_t permission_bits) {
   return PDFiumPermissions(permissions_handler_revision, permission_bits);
 }
 
+// Note that `FPDF_GetDocPermissions()` returns `unsigned long`, but is
+// specified to return a 32-bit integer. The implementation also uses `uint32_t`
+// internally.
 PDFiumPermissions::PDFiumPermissions(FPDF_DOCUMENT doc)
     : permissions_handler_revision_(FPDF_GetSecurityHandlerRevision(doc)),
-      permission_bits_(FPDF_GetDocPermissions(doc)) {}
+      permission_bits_(
+          base::checked_cast<uint32_t>(FPDF_GetDocPermissions(doc))) {}
 
 PDFiumPermissions::PDFiumPermissions(int permissions_handler_revision,
-                                     unsigned long permission_bits)
+                                     uint32_t permission_bits)
     : permissions_handler_revision_(permissions_handler_revision),
       permission_bits_(permission_bits) {}
 
@@ -37,25 +45,25 @@
       case DocumentPermission::kCopy:
       case DocumentPermission::kCopyAccessible:
         // Check the same copy bit for all copying permissions.
-        return (permission_bits_ & kPDFPermissionCopyMask) != 0;
+        return HasPermissionBits(kPDFPermissionCopyMask);
       case DocumentPermission::kPrintLowQuality:
       case DocumentPermission::kPrintHighQuality:
         // Check the same printing bit for all printing permissions.
-        return (permission_bits_ & kPDFPermissionPrintMask) != 0;
+        return HasPermissionBits(kPDFPermissionPrintMask);
     }
   } else {
     // Security handler revision 3+ have different rules for interpreting the
     // bits in `permission_bits_`.
     switch (permission) {
       case DocumentPermission::kCopy:
-        return (permission_bits_ & kPDFPermissionCopyMask) != 0;
+        return HasPermissionBits(kPDFPermissionCopyMask);
       case DocumentPermission::kCopyAccessible:
-        return (permission_bits_ & kPDFPermissionCopyAccessibleMask) != 0;
+        return HasPermissionBits(kPDFPermissionCopyAccessibleMask);
       case DocumentPermission::kPrintLowQuality:
-        return (permission_bits_ & kPDFPermissionPrintMask) != 0;
+        return HasPermissionBits(kPDFPermissionPrintMask);
       case DocumentPermission::kPrintHighQuality:
-        return (permission_bits_ & kPDFPermissionPrintMask) != 0 &&
-               (permission_bits_ & kPDFPermissionPrintHighQualityMask) != 0;
+        return HasPermissionBits(kPDFPermissionPrintMask |
+                                 kPDFPermissionPrintHighQualityMask);
     }
   }
 }
diff --git a/pdf/pdfium/pdfium_permissions.h b/pdf/pdfium/pdfium_permissions.h
index 58986b2d..c4c0ce7 100644
--- a/pdf/pdfium/pdfium_permissions.h
+++ b/pdf/pdfium/pdfium_permissions.h
@@ -5,6 +5,8 @@
 #ifndef PDF_PDFIUM_PDFIUM_PERMISSIONS_H_
 #define PDF_PDFIUM_PDFIUM_PERMISSIONS_H_
 
+#include <stdint.h>
+
 #include "pdf/pdf_engine.h"
 #include "third_party/pdfium/public/fpdfview.h"
 
@@ -21,7 +23,7 @@
 class PDFiumPermissions final {
  public:
   static PDFiumPermissions CreateForTesting(int permissions_handler_revision,
-                                            unsigned long permission_bits);
+                                            uint32_t permission_bits);
 
   explicit PDFiumPermissions(FPDF_DOCUMENT doc);
 
@@ -29,14 +31,17 @@
 
  private:
   // For unit tests.
-  PDFiumPermissions(int permissions_handler_revision,
-                    unsigned long permission_bits);
+  PDFiumPermissions(int permissions_handler_revision, uint32_t permission_bits);
+
+  bool HasPermissionBits(uint32_t mask) const {
+    return (permission_bits_ & mask) == mask;
+  }
 
   // Permissions security handler revision number. -1 for unknown.
   const int permissions_handler_revision_;
 
   // Permissions bitfield.
-  const unsigned long permission_bits_;
+  const uint32_t permission_bits_;
 };
 
 }  // namespace chrome_pdf
diff --git a/printing/backend/print_backend.cc b/printing/backend/print_backend.cc
index 4c71279..46513bf9 100644
--- a/printing/backend/print_backend.cc
+++ b/printing/backend/print_backend.cc
@@ -115,7 +115,7 @@
 
 PrinterCapsAndDefaults::~PrinterCapsAndDefaults() = default;
 
-PrintBackend::PrintBackend(const std::string& locale) : locale_(locale) {}
+PrintBackend::PrintBackend() = default;
 
 PrintBackend::~PrintBackend() = default;
 
@@ -125,20 +125,9 @@
   return g_print_backend_for_test
              ? g_print_backend_for_test
              : PrintBackend::CreateInstanceImpl(
-                   /*print_backend_settings=*/nullptr, locale,
-                   /*for_cloud_print=*/false);
+                   /*print_backend_settings=*/nullptr, locale);
 }
 
-#if defined(USE_CUPS)
-// static
-scoped_refptr<PrintBackend> PrintBackend::CreateInstanceForCloudPrint(
-    const base::DictionaryValue* print_backend_settings) {
-  return PrintBackend::CreateInstanceImpl(print_backend_settings,
-                                          /*locale=*/std::string(),
-                                          /*for_cloud_print=*/true);
-}
-#endif  // defined(USE_CUPS)
-
 // static
 void PrintBackend::SetPrintBackendForTesting(PrintBackend* backend) {
   g_print_backend_for_test = backend;
diff --git a/printing/backend/print_backend.h b/printing/backend/print_backend.h
index 84d5ba6e3..d42a1d30 100644
--- a/printing/backend/print_backend.h
+++ b/printing/backend/print_backend.h
@@ -217,34 +217,19 @@
   // Allocates a print backend.
   static scoped_refptr<PrintBackend> CreateInstance(const std::string& locale);
 
-#if defined(USE_CUPS)
-  // TODO(crbug.com/1062136): Remove this static function when Cloud Print is
-  // supposed to stop working. Follow up after Jan 1, 2021.
-  // Similar to CreateInstance(), but ensures that the CUPS PPD backend is used
-  // instead of the CUPS IPP backend.
-  static scoped_refptr<PrintBackend> CreateInstanceForCloudPrint(
-      const base::DictionaryValue* print_backend_settings);
-#endif  // defined(USE_CUPS)
-
   // Test method to override the print backend for testing.  Caller should
   // retain ownership.
   static void SetPrintBackendForTesting(PrintBackend* print_backend);
 
  protected:
   friend class base::RefCountedThreadSafe<PrintBackend>;
-  explicit PrintBackend(const std::string& locale);
+  PrintBackend();
   virtual ~PrintBackend();
 
   // Provide the actual backend for CreateInstance().
   static scoped_refptr<PrintBackend> CreateInstanceImpl(
       const base::DictionaryValue* print_backend_settings,
-      const std::string& locale,
-      bool for_cloud_print);
-
-  const std::string& locale() const { return locale_; }
-
- private:
-  const std::string locale_;
+      const std::string& locale);
 };
 
 }  // namespace printing
diff --git a/printing/backend/print_backend_chromeos.cc b/printing/backend/print_backend_chromeos.cc
index 974fc20..2223e726 100644
--- a/printing/backend/print_backend_chromeos.cc
+++ b/printing/backend/print_backend_chromeos.cc
@@ -20,7 +20,7 @@
 // implementation for use on ChromeOS.
 class PrintBackendChromeOS : public PrintBackend {
  public:
-  explicit PrintBackendChromeOS(const std::string& locale);
+  PrintBackendChromeOS() = default;
 
   // PrintBackend implementation.
   mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override;
@@ -42,9 +42,6 @@
   ~PrintBackendChromeOS() override = default;
 };
 
-PrintBackendChromeOS::PrintBackendChromeOS(const std::string& locale)
-    : PrintBackend(locale) {}
-
 mojom::ResultCode PrintBackendChromeOS::EnumeratePrinters(
     PrinterList* printer_list) {
   return mojom::ResultCode::kSuccess;
@@ -90,13 +87,12 @@
 // static
 scoped_refptr<PrintBackend> PrintBackend::CreateInstanceImpl(
     const base::DictionaryValue* print_backend_settings,
-    const std::string& locale,
-    bool /*for_cloud_print*/) {
+    const std::string& /*locale*/) {
 #if defined(USE_CUPS)
   return base::MakeRefCounted<PrintBackendCupsIpp>(
-      CreateConnection(print_backend_settings), locale);
+      CreateConnection(print_backend_settings));
 #else
-  return base::MakeRefCounted<PrintBackendChromeOS>(locale);
+  return base::MakeRefCounted<PrintBackendChromeOS>();
 #endif  // defined(USE_CUPS)
 }
 
diff --git a/printing/backend/print_backend_cups.cc b/printing/backend/print_backend_cups.cc
index 9893a26..61625323 100644
--- a/printing/backend/print_backend_cups.cc
+++ b/printing/backend/print_backend_cups.cc
@@ -61,7 +61,7 @@
                                    http_encryption_t encryption,
                                    bool blocking,
                                    const std::string& locale)
-    : PrintBackend(locale),
+    : locale_(locale),
       print_server_url_(print_server_url),
       cups_encryption_(encryption),
       blocking_(blocking) {}
@@ -248,7 +248,7 @@
     return result_code;
 
   ScopedDestination dest = GetNamedDest(printer_name);
-  return ParsePpdCapabilities(dest.get(), locale(), info.printer_capabilities,
+  return ParsePpdCapabilities(dest.get(), locale_, info.printer_capabilities,
                               printer_info)
              ? mojom::ResultCode::kSuccess
              : mojom::ResultCode::kFailed;
@@ -305,13 +305,11 @@
 #if !BUILDFLAG(IS_CHROMEOS)
 scoped_refptr<PrintBackend> PrintBackend::CreateInstanceImpl(
     const base::DictionaryValue* print_backend_settings,
-    const std::string& locale,
-    bool for_cloud_print) {
+    const std::string& locale) {
 #if BUILDFLAG(IS_MAC)
-  if (!for_cloud_print &&
-      base::FeatureList::IsEnabled(features::kCupsIppPrintingBackend)) {
+  if (base::FeatureList::IsEnabled(features::kCupsIppPrintingBackend)) {
     return base::MakeRefCounted<PrintBackendCupsIpp>(
-        CreateConnection(print_backend_settings), locale);
+        CreateConnection(print_backend_settings));
   }
 #endif  // BUILDFLAG(IS_MAC)
   std::string print_server_url_str, cups_blocking;
diff --git a/printing/backend/print_backend_cups.h b/printing/backend/print_backend_cups.h
index 71395cfa..707a55675 100644
--- a/printing/backend/print_backend_cups.h
+++ b/printing/backend/print_backend_cups.h
@@ -67,9 +67,10 @@
   // Wrapper around cupsGetNamedDest().
   ScopedDestination GetNamedDest(const std::string& printer_name);
 
-  GURL print_server_url_;
+  const std::string locale_;
+  const GURL print_server_url_;
   http_encryption_t cups_encryption_;
-  bool blocking_;
+  const bool blocking_;
 };
 
 }  // namespace printing
diff --git a/printing/backend/print_backend_cups_ipp.cc b/printing/backend/print_backend_cups_ipp.cc
index 10d8ccb7..571f0ee 100644
--- a/printing/backend/print_backend_cups_ipp.cc
+++ b/printing/backend/print_backend_cups_ipp.cc
@@ -23,9 +23,8 @@
 namespace printing {
 
 PrintBackendCupsIpp::PrintBackendCupsIpp(
-    std::unique_ptr<CupsConnection> cups_connection,
-    const std::string& locale)
-    : PrintBackend(locale), cups_connection_(std::move(cups_connection)) {}
+    std::unique_ptr<CupsConnection> cups_connection)
+    : cups_connection_(std::move(cups_connection)) {}
 
 PrintBackendCupsIpp::~PrintBackendCupsIpp() = default;
 
diff --git a/printing/backend/print_backend_cups_ipp.h b/printing/backend/print_backend_cups_ipp.h
index ceb021a..554601e1 100644
--- a/printing/backend/print_backend_cups_ipp.h
+++ b/printing/backend/print_backend_cups_ipp.h
@@ -16,8 +16,7 @@
 
 class PrintBackendCupsIpp : public PrintBackend {
  public:
-  PrintBackendCupsIpp(std::unique_ptr<CupsConnection> connection,
-                      const std::string& locale);
+  explicit PrintBackendCupsIpp(std::unique_ptr<CupsConnection> connection);
 
  private:
   ~PrintBackendCupsIpp() override;
diff --git a/printing/backend/print_backend_dummy.cc b/printing/backend/print_backend_dummy.cc
index f888d92..97f9619 100644
--- a/printing/backend/print_backend_dummy.cc
+++ b/printing/backend/print_backend_dummy.cc
@@ -15,8 +15,7 @@
 
 class DummyPrintBackend : public PrintBackend {
  public:
-  explicit DummyPrintBackend(const std::string& locale)
-      : PrintBackend(locale) {}
+  DummyPrintBackend() = default;
   DummyPrintBackend(const DummyPrintBackend&) = delete;
   DummyPrintBackend& operator=(const DummyPrintBackend&) = delete;
 
@@ -63,9 +62,8 @@
 // static
 scoped_refptr<PrintBackend> PrintBackend::CreateInstanceImpl(
     const base::DictionaryValue* print_backend_settings,
-    const std::string& locale,
-    bool /*for_cloud_print*/) {
-  return base::MakeRefCounted<DummyPrintBackend>(locale);
+    const std::string& /*locale*/) {
+  return base::MakeRefCounted<DummyPrintBackend>();
 }
 
 }  // namespace printing
diff --git a/printing/backend/print_backend_win.cc b/printing/backend/print_backend_win.cc
index 86f74f4..5c4e856 100644
--- a/printing/backend/print_backend_win.cc
+++ b/printing/backend/print_backend_win.cc
@@ -182,7 +182,7 @@
 
 class PrintBackendWin : public PrintBackend {
  public:
-  explicit PrintBackendWin(const std::string& locale) : PrintBackend(locale) {}
+  PrintBackendWin() = default;
 
   // PrintBackend implementation.
   mojom::ResultCode EnumeratePrinters(PrinterList* printer_list) override;
@@ -452,9 +452,8 @@
 // static
 scoped_refptr<PrintBackend> PrintBackend::CreateInstanceImpl(
     const base::DictionaryValue* print_backend_settings,
-    const std::string& locale,
-    bool /*for_cloud_print*/) {
-  return base::MakeRefCounted<PrintBackendWin>(locale);
+    const std::string& /*locale*/) {
+  return base::MakeRefCounted<PrintBackendWin>();
 }
 
 }  // namespace printing
diff --git a/printing/backend/test_print_backend.cc b/printing/backend/test_print_backend.cc
index 4f0d680..0c17a26 100644
--- a/printing/backend/test_print_backend.cc
+++ b/printing/backend/test_print_backend.cc
@@ -41,7 +41,7 @@
 
 }  // namespace
 
-TestPrintBackend::TestPrintBackend() : PrintBackend(/*locale=*/std::string()) {}
+TestPrintBackend::TestPrintBackend() = default;
 
 TestPrintBackend::~TestPrintBackend() = default;
 
diff --git a/printing/metafile_skia.cc b/printing/metafile_skia.cc
index c0b2a6ff..b7335b4 100644
--- a/printing/metafile_skia.cc
+++ b/printing/metafile_skia.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <map>
+#include <tuple>
 #include <utility>
 #include <vector>
 
@@ -329,7 +330,8 @@
       return false;
     size_t length = data_->data_stream->getLength();
     std::vector<uint8_t> buffer(length);
-    (void)WriteAssetToBuffer(data_->data_stream.get(), &buffer[0], length);
+    std::ignore =
+        WriteAssetToBuffer(data_->data_stream.get(), &buffer[0], length);
     data_->pdf_cg.InitFromData(buffer);
   }
   return data_->pdf_cg.RenderPage(page_number, context, rect, autorotate,
diff --git a/printing/printing_utils.cc b/printing/printing_utils.cc
index a8ce454..9c62ed328 100644
--- a/printing/printing_utils.cc
+++ b/printing/printing_utils.cc
@@ -4,28 +4,36 @@
 
 #include "printing/printing_utils.h"
 
-#include <unicode/ulocdata.h>
-
 #include <algorithm>
-#include <cmath>
 #include <string>
 
 #include "base/logging.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
-#include "printing/units.h"
+#include "build/chromeos_buildflags.h"
 #include "third_party/icu/source/common/unicode/uchar.h"
-#include "ui/gfx/geometry/size.h"
 #include "ui/gfx/text_elider.h"
 
+#if defined(USE_CUPS) && !BUILDFLAG(IS_CHROMEOS_ASH)
+#include <unicode/ulocdata.h>
+
+#include <cmath>
+
+#include "base/strings/string_piece.h"
+#include "printing/units.h"
+#include "ui/gfx/geometry/size.h"
+#endif
+
 namespace printing {
 
 namespace {
 
 constexpr size_t kMaxDocumentTitleLength = 80;
+
+#if defined(USE_CUPS) && !BUILDFLAG(IS_CHROMEOS_ASH)
 constexpr gfx::Size kIsoA4Microns = gfx::Size(210000, 297000);
+#endif
 
 }  // namespace
 
@@ -76,6 +84,7 @@
                                                kMaxDocumentTitleLength);
 }
 
+#if defined(USE_CUPS) && !BUILDFLAG(IS_CHROMEOS_ASH)
 gfx::Size GetDefaultPaperSizeFromLocaleMicrons(base::StringPiece locale) {
   if (locale.empty())
     return kIsoA4Microns;
@@ -106,6 +115,7 @@
   return std::abs(lhs.width() - rhs.width()) <= epsilon &&
          std::abs(lhs.height() - rhs.height()) <= epsilon;
 }
+#endif  // defined(USE_CUPS) && !BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_WIN)
 gfx::Rect GetCenteredPageContentRect(const gfx::Size& paper_size,
diff --git a/printing/printing_utils.h b/printing/printing_utils.h
index d2bc5813..196f15a 100644
--- a/printing/printing_utils.h
+++ b/printing/printing_utils.h
@@ -10,8 +10,12 @@
 #include <string>
 
 #include "base/component_export.h"
-#include "base/strings/string_piece.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
+
+#if defined(USE_CUPS) && !BUILDFLAG(IS_CHROMEOS_ASH)
+#include "base/strings/string_piece.h"
+#endif
 
 #if BUILDFLAG(IS_WIN)
 #include "ui/gfx/geometry/rect.h"
@@ -41,6 +45,7 @@
     const std::u16string& title,
     size_t length);
 
+#if defined(USE_CUPS) && !BUILDFLAG(IS_CHROMEOS_ASH)
 // Returns the paper size (microns) most common in the locale to the nearest
 // millimeter. Defaults to ISO A4 for an empty or invalid locale.
 COMPONENT_EXPORT(PRINTING_BASE)
@@ -52,6 +57,7 @@
 bool SizesEqualWithinEpsilon(const gfx::Size& lhs,
                              const gfx::Size& rhs,
                              int epsilon);
+#endif
 
 #if BUILDFLAG(IS_WIN)
 // Get page content rect adjusted based on
diff --git a/printing/printing_utils_unittest.cc b/printing/printing_utils_unittest.cc
index a4b954d..91586413 100644
--- a/printing/printing_utils_unittest.cc
+++ b/printing/printing_utils_unittest.cc
@@ -11,6 +11,7 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -23,8 +24,11 @@
 namespace {
 
 constexpr size_t kTestLength = 8;
+
+#if defined(USE_CUPS) && !BUILDFLAG(IS_CHROMEOS_ASH)
 constexpr gfx::Size kIsoA4Microns(210000, 297000);
 constexpr gfx::Size kNaLetterMicrons(216000, 279000);
+#endif
 
 std::string Simplify(const std::string& title) {
   return base::UTF16ToUTF8(
@@ -61,6 +65,7 @@
   EXPECT_EQ("ab...j: ", Format("abcdefghij", "0123456789"));
 }
 
+#if defined(USE_CUPS) && !BUILDFLAG(IS_CHROMEOS_ASH)
 TEST(PrintingUtilsTest, GetDefaultPaperSizeFromLocaleMicrons) {
   // Valid locales
   EXPECT_EQ(kNaLetterMicrons, GetDefaultPaperSizeFromLocaleMicrons("en-US"));
@@ -103,6 +108,7 @@
   EXPECT_TRUE(
       SizesEqualWithinEpsilon(kIsoA4Microns, gfx::Size(210500, 296500), 500));
 }
+#endif  // defined(USE_CUPS) && !BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_WIN)
 TEST(PrintingUtilsTest, GetCenteredPageContentRect) {
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn
index 46a9990..eb76bc6 100644
--- a/remoting/host/BUILD.gn
+++ b/remoting/host/BUILD.gn
@@ -407,7 +407,7 @@
     "//remoting/signaling:signaling",
     "//services/network:network_service",
     "//services/network/public/cpp:cpp",
-    "//third_party/libjingle_xmpp",
+    "//third_party/libjingle_xmpp:rtc_xmllite",
     "//third_party/webrtc_overrides:webrtc_component",
     "//ui/events:events",
 
@@ -633,7 +633,7 @@
     ":common",
     "//remoting/base:test_support",
     "//remoting/host/file_transfer:test_support",
-    "//third_party/libjingle_xmpp",
+    "//third_party/libjingle_xmpp:rtc_xmllite",
     "//third_party/protobuf:protobuf_lite",
     "//third_party/webrtc_overrides:webrtc_component",
   ]
@@ -925,7 +925,7 @@
       "//remoting/protocol:protocol",
       "//remoting/signaling:signaling",
       "//services/network/public/cpp:cpp",
-      "//third_party/libjingle_xmpp",
+      "//third_party/libjingle_xmpp:rtc_xmllite",
       "//third_party/webrtc_overrides:webrtc_component",
     ]
 
diff --git a/remoting/host/chromoting_messages.h b/remoting/host/chromoting_messages.h
index b635ef8c..f5e863e 100644
--- a/remoting/host/chromoting_messages.h
+++ b/remoting/host/chromoting_messages.h
@@ -215,26 +215,6 @@
 //-----------------------------------------------------------------------------
 // Chromoting messages sent from the network to the desktop process.
 
-// Passes the client session data to the desktop session agent and starts it.
-// This must be the first message received from the host.
-IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_StartSessionAgent,
-                    std::string /* authenticated_jid */,
-                    remoting::ScreenResolution /* resolution */,
-                    remoting::DesktopEnvironmentOptions /* options */)
-
-IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_CaptureFrame)
-
-IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_SelectSource,
-                    int /* desktop_display_id */)
-
-// Changes the screen resolution in the desktop session.
-IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_SetScreenResolution,
-                    remoting::ScreenResolution /* resolution */)
-
-// Carries an action request event from the client to the desktop session agent.
-IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_ExecuteActionRequest,
-                    remoting::protocol::ActionRequest /* request */)
-
 // Requests that the desktop process create a new file for writing with the
 // provided file name, which will be identified by |file_id|. The desktop
 // process will respond with a FileResult message.
diff --git a/remoting/host/chromoting_param_traits.cc b/remoting/host/chromoting_param_traits.cc
index 75e6b6c..8d67131 100644
--- a/remoting/host/chromoting_param_traits.cc
+++ b/remoting/host/chromoting_param_traits.cc
@@ -201,107 +201,6 @@
                                p.dpi().x(), p.dpi().y()));
 }
 
-// remoting::DesktopEnvironmentOptions
-
-// static
-void ParamTraits<remoting::DesktopEnvironmentOptions>::Write(
-    base::Pickle* m,
-    const remoting::DesktopEnvironmentOptions& p) {
-  m->WriteBool(p.enable_curtaining());
-  m->WriteBool(p.enable_user_interface());
-  m->WriteBool(p.desktop_capture_options()->use_update_notifications());
-  m->WriteBool(p.desktop_capture_options()->disable_effects());
-  m->WriteBool(p.desktop_capture_options()->detect_updated_region());
-#if defined(WEBRTC_WIN)
-  m->WriteBool(p.desktop_capture_options()->allow_use_magnification_api());
-  m->WriteBool(p.desktop_capture_options()->allow_directx_capturer());
-#endif  // defined(WEBRTC_WIN)
-}
-
-// static
-bool ParamTraits<remoting::DesktopEnvironmentOptions>::Read(
-    const base::Pickle* m,
-    base::PickleIterator* iter,
-    remoting::DesktopEnvironmentOptions* r) {
-  *r = remoting::DesktopEnvironmentOptions::CreateDefault();
-  bool enable_curtaining;
-  bool enable_user_interface;
-  bool use_update_notifications;
-  bool disable_effects;
-  bool detect_updated_region;
-
-  if (!iter->ReadBool(&enable_curtaining) ||
-      !iter->ReadBool(&enable_user_interface) ||
-      !iter->ReadBool(&use_update_notifications) ||
-      !iter->ReadBool(&disable_effects) ||
-      !iter->ReadBool(&detect_updated_region)) {
-    return false;
-  }
-
-  r->set_enable_curtaining(enable_curtaining);
-  r->set_enable_user_interface(enable_user_interface);
-  r->desktop_capture_options()->set_use_update_notifications(
-      use_update_notifications);
-  r->desktop_capture_options()->set_detect_updated_region(
-      detect_updated_region);
-  r->desktop_capture_options()->set_disable_effects(disable_effects);
-
-#if defined(WEBRTC_WIN)
-  bool allow_use_magnification_api;
-  bool allow_directx_capturer;
-
-  if (!iter->ReadBool(&allow_use_magnification_api) ||
-      !iter->ReadBool(&allow_directx_capturer)) {
-    return false;
-  }
-
-  r->desktop_capture_options()->set_allow_use_magnification_api(
-      allow_use_magnification_api);
-  r->desktop_capture_options()->set_allow_directx_capturer(
-      allow_directx_capturer);
-#endif  // defined(WEBRTC_WIN)
-
-  return true;
-}
-
-// static
-void ParamTraits<remoting::DesktopEnvironmentOptions>::Log(
-    const remoting::DesktopEnvironmentOptions& p,
-    std::string* l) {
-  l->append("DesktopEnvironmentOptions()");
-}
-
-// remoting::protocol::ActionRequest
-
-// static
-void ParamTraits<remoting::protocol::ActionRequest>::Write(
-    base::Pickle* m,
-    const param_type& p) {
-  std::string serialized_action_request;
-  bool result = p.SerializeToString(&serialized_action_request);
-  DCHECK(result);
-  m->WriteString(serialized_action_request);
-}
-
-// static
-bool ParamTraits<remoting::protocol::ActionRequest>::Read(
-    const base::Pickle* m,
-    base::PickleIterator* iter,
-    param_type* p) {
-  std::string serialized_action_request;
-  if (!iter->ReadString(&serialized_action_request))
-    return false;
-
-  return p->ParseFromString(serialized_action_request);
-}
-
-// static
-void ParamTraits<remoting::protocol::ActionRequest>::Log(const param_type& p,
-                                                         std::string* l) {
-  l->append(base::StringPrintf("ActionRequest action: %d, id: %u", p.action(),
-                               p.request_id()));
-}
-
 // remoting::protocol::VideoLayout
 
 // static
diff --git a/remoting/host/chromoting_param_traits.h b/remoting/host/chromoting_param_traits.h
index c3240d7..e018b0ac 100644
--- a/remoting/host/chromoting_param_traits.h
+++ b/remoting/host/chromoting_param_traits.h
@@ -72,26 +72,6 @@
 };
 
 template <>
-struct ParamTraits<remoting::DesktopEnvironmentOptions> {
-  typedef remoting::DesktopEnvironmentOptions param_type;
-  static void Write(base::Pickle* m, const param_type& p);
-  static bool Read(const base::Pickle* m,
-                   base::PickleIterator* iter,
-                   param_type* p);
-  static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct ParamTraits<remoting::protocol::ActionRequest> {
-  typedef remoting::protocol::ActionRequest param_type;
-  static void Write(base::Pickle* m, const param_type& p);
-  static bool Read(const base::Pickle* m,
-                   base::PickleIterator* iter,
-                   param_type* p);
-  static void Log(const param_type& p, std::string* l);
-};
-
-template <>
 struct ParamTraits<remoting::protocol::VideoLayout> {
   typedef remoting::protocol::VideoLayout param_type;
   static void Write(base::Pickle* m, const param_type& p);
diff --git a/remoting/host/desktop_process.cc b/remoting/host/desktop_process.cc
index d779a22..6db1cd30 100644
--- a/remoting/host/desktop_process.cc
+++ b/remoting/host/desktop_process.cc
@@ -150,9 +150,9 @@
       new DesktopSessionAgent(audio_task_runner, caller_task_runner_,
                               input_task_runner_, io_task_runner_);
 
-  // Start the agent and create an IPC channel to talk to it.
+  // Initialize the agent and create an IPC channel to talk to it.
   mojo::ScopedMessagePipeHandle desktop_pipe =
-      desktop_agent_->Start(weak_factory_.GetWeakPtr());
+      desktop_agent_->Initialize(weak_factory_.GetWeakPtr());
 
   // Connect to the daemon.
   daemon_channel_ = IPC::ChannelProxy::Create(
diff --git a/remoting/host/desktop_process_unittest.cc b/remoting/host/desktop_process_unittest.cc
index 87110d4..6889e537 100644
--- a/remoting/host/desktop_process_unittest.cc
+++ b/remoting/host/desktop_process_unittest.cc
@@ -21,7 +21,7 @@
 #include "ipc/ipc_channel.h"
 #include "ipc/ipc_channel_proxy.h"
 #include "ipc/ipc_listener.h"
-#include "ipc/ipc_message.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
 #include "remoting/base/auto_thread.h"
 #include "remoting/base/auto_thread_task_runner.h"
 #include "remoting/host/base/host_exit_codes.h"
@@ -175,6 +175,12 @@
   // Requests the desktop process to start the desktop session agent.
   void SendStartSessionAgent();
 
+  // Receives the DesktopSessionControl remote used to inject input and control
+  // A/V capture in the test.
+  void OnDesktopSessionAgentStarted(
+      mojo::PendingAssociatedRemote<mojom::DesktopSessionControl>
+          pending_remote);
+
  protected:
   // The daemon's end of the daemon-to-desktop channel.
   std::unique_ptr<IPC::ChannelProxy> daemon_channel_;
@@ -182,8 +188,8 @@
   // Delegate that is passed to |daemon_channel_|.
   MockDaemonListener daemon_listener_;
 
-  mojo::AssociatedRemote<mojom::DesktopSessionRequestHandler>
-      desktop_session_request_handler_;
+  mojo::AssociatedRemote<mojom::DesktopSessionAgent> desktop_session_agent_;
+  mojo::AssociatedRemote<mojom::DesktopSessionControl> desktop_session_control_;
 
   // Runs the daemon's end of the channel.
   base::test::SingleThreadTaskEnvironment task_environment_{
@@ -273,6 +279,8 @@
   daemon_channel_.reset();
   desktop_pipe_handle_.reset();
   daemon_listener_.Disconnect();
+  desktop_session_agent_.reset();
+  desktop_session_control_.reset();
 
   network_channel_.reset();
   io_task_runner_ = nullptr;
@@ -339,9 +347,22 @@
 }
 
 void DesktopProcessTest::SendStartSessionAgent() {
-  network_channel_->Send(new ChromotingNetworkDesktopMsg_StartSessionAgent(
+  desktop_session_agent_.reset();
+  network_channel_->GetRemoteAssociatedInterface(&desktop_session_agent_);
+
+  desktop_session_agent_->Start(
       "user@domain/rest-of-jid", ScreenResolution(),
-      DesktopEnvironmentOptions()));
+      DesktopEnvironmentOptions(),
+      base::BindOnce(&DesktopProcessTest::OnDesktopSessionAgentStarted,
+                     base::Unretained(this)));
+  task_environment_.RunUntilIdle();
+}
+
+void DesktopProcessTest::OnDesktopSessionAgentStarted(
+    mojo::PendingAssociatedRemote<mojom::DesktopSessionControl>
+        pending_remote) {
+  desktop_session_control_.reset();
+  desktop_session_control_.Bind(std::move(pending_remote));
 }
 
 // Launches the desktop process and then disconnects immediately.
diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc
index 85e7327..80256a9 100644
--- a/remoting/host/desktop_session_agent.cc
+++ b/remoting/host/desktop_session_agent.cc
@@ -235,45 +235,30 @@
 
 bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
 
   bool handled = true;
-  if (started_) {
-    IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message)
-      IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_CaptureFrame,
-                          OnCaptureFrame)
-      IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SelectSource,
-                          OnSelectSource)
-      IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_ExecuteActionRequest,
-                          OnExecuteActionRequestEvent)
-      IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SetScreenResolution,
-                          SetScreenResolution)
-      IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_ReadFile,
-                          &*session_file_operations_handler_,
-                          SessionFileOperationsHandler::ReadFile)
-      IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_ReadFileChunk,
-                          &*session_file_operations_handler_,
-                          SessionFileOperationsHandler::ReadChunk)
-      IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_WriteFile,
-                          &*session_file_operations_handler_,
-                          SessionFileOperationsHandler::WriteFile)
-      IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_WriteFileChunk,
-                          &*session_file_operations_handler_,
-                          SessionFileOperationsHandler::WriteChunk)
-      IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_CloseFile,
-                          &*session_file_operations_handler_,
-                          SessionFileOperationsHandler::Close)
-      IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_CancelFile,
-                          &*session_file_operations_handler_,
-                          SessionFileOperationsHandler::Cancel)
-      IPC_MESSAGE_UNHANDLED(handled = false)
-    IPC_END_MESSAGE_MAP()
-  } else {
-    IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message)
-      IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_StartSessionAgent,
-                          OnStartSessionAgent)
-      IPC_MESSAGE_UNHANDLED(handled = false)
-    IPC_END_MESSAGE_MAP()
-  }
+  IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message)
+    IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_ReadFile,
+                        &*session_file_operations_handler_,
+                        SessionFileOperationsHandler::ReadFile)
+    IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_ReadFileChunk,
+                        &*session_file_operations_handler_,
+                        SessionFileOperationsHandler::ReadChunk)
+    IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_WriteFile,
+                        &*session_file_operations_handler_,
+                        SessionFileOperationsHandler::WriteFile)
+    IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_WriteFileChunk,
+                        &*session_file_operations_handler_,
+                        SessionFileOperationsHandler::WriteChunk)
+    IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_CloseFile,
+                        &*session_file_operations_handler_,
+                        SessionFileOperationsHandler::Close)
+    IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_CancelFile,
+                        &*session_file_operations_handler_,
+                        SessionFileOperationsHandler::Cancel)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
 
   CHECK(handled) << "Received unexpected IPC type: " << message.type();
   return handled;
@@ -301,16 +286,16 @@
     mojo::ScopedInterfaceEndpointHandle handle) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
-  if (interface_name == mojom::DesktopSessionControl::Name_) {
-    if (desktop_session_control_.is_bound()) {
+  if (interface_name == mojom::DesktopSessionAgent::Name_) {
+    if (desktop_session_agent_.is_bound()) {
       LOG(ERROR) << "Receiver already bound for associated interface: "
-                 << mojom::DesktopSessionControl::Name_;
+                 << mojom::DesktopSessionAgent::Name_;
       delegate_->CrashNetworkProcess(base::Location::Current());
     }
 
-    mojo::PendingAssociatedReceiver<mojom::DesktopSessionControl>
+    mojo::PendingAssociatedReceiver<mojom::DesktopSessionAgent>
         pending_receiver(std::move(handle));
-    desktop_session_control_.Bind(std::move(pending_receiver));
+    desktop_session_agent_.Bind(std::move(pending_receiver));
   } else {
     LOG(ERROR) << "Unknown associated interface requested: " << interface_name
                << ", crashing the network process";
@@ -370,12 +355,12 @@
       *layout.get()));
 }
 
-void DesktopSessionAgent::OnStartSessionAgent(
+void DesktopSessionAgent::Start(
     const std::string& authenticated_jid,
     const ScreenResolution& resolution,
-    const remoting::DesktopEnvironmentOptions& options) {
+    const remoting::DesktopEnvironmentOptions& options,
+    StartCallback callback) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
-  DCHECK(!started_);
   DCHECK(!audio_capturer_);
   DCHECK(!desktop_environment_);
   DCHECK(!input_injector_);
@@ -383,6 +368,15 @@
   DCHECK(!video_capturer_);
   DCHECK(!session_file_operations_handler_);
 
+  if (started_) {
+    LOG(ERROR) << __func__ << " called more than once for the current process.";
+    delegate_->CrashNetworkProcess(base::Location::Current());
+    // No need to run the callback since it just calls into the process we are
+    // asking the daemon process to crash.
+    callback.Reset();
+    return;
+  }
+
   started_ = true;
   client_jid_ = authenticated_jid;
 
@@ -456,6 +450,9 @@
   // Check and report the initial URL forwarder setup state.
   url_forwarder_configurator_->IsUrlForwarderSetUp(base::BindOnce(
       &DesktopSessionAgent::OnCheckUrlForwarderSetUpResult, this));
+
+  std::move(callback).Run(
+      desktop_session_control_.BindNewEndpointAndPassRemote());
 }
 
 void DesktopSessionAgent::OnCaptureResult(
@@ -552,7 +549,7 @@
       file_id, std::move(result)));
 }
 
-mojo::ScopedMessagePipeHandle DesktopSessionAgent::Start(
+mojo::ScopedMessagePipeHandle DesktopSessionAgent::Initialize(
     const base::WeakPtr<Delegate>& delegate) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
   DCHECK(delegate);
@@ -569,7 +566,6 @@
 
 void DesktopSessionAgent::Stop() {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
-
   delegate_.reset();
 
   // Make sure the channel is closed.
@@ -584,6 +580,7 @@
 
     desktop_session_event_handler_.reset();
     desktop_session_control_.reset();
+    desktop_session_agent_.reset();
 
     url_forwarder_configurator_.reset();
 
@@ -613,8 +610,9 @@
   }
 }
 
-void DesktopSessionAgent::OnCaptureFrame() {
+void DesktopSessionAgent::CaptureFrame() {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
 
   mouse_cursor_monitor_->Capture();
 
@@ -626,14 +624,17 @@
   video_capturer_->CaptureFrame();
 }
 
-void DesktopSessionAgent::OnSelectSource(int id) {
+void DesktopSessionAgent::SelectSource(int id) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
+
   video_capturer_->SelectSource(id);
 }
 
 void DesktopSessionAgent::InjectClipboardEvent(
     const protocol::ClipboardEvent& event) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
 
   // InputStub implementations must verify events themselves, so we don't need
   // verification here. This matches HostEventDispatcher.
@@ -642,6 +643,7 @@
 
 void DesktopSessionAgent::InjectKeyEvent(const protocol::KeyEvent& event) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
 
   // InputStub implementations must verify events themselves, so we need only
   // basic verification here. This matches HostEventDispatcher.
@@ -655,6 +657,7 @@
 
 void DesktopSessionAgent::InjectTextEvent(const protocol::TextEvent& event) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
 
   // InputStub implementations must verify events themselves, so we need only
   // basic verification here. This matches HostEventDispatcher.
@@ -668,6 +671,7 @@
 
 void DesktopSessionAgent::InjectMouseEvent(const protocol::MouseEvent& event) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
 
   if (video_capturer_)
     video_capturer_->SetComposeEnabled(event.has_delta_x() ||
@@ -680,14 +684,26 @@
 
 void DesktopSessionAgent::InjectTouchEvent(const protocol::TouchEvent& event) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
 
   remote_input_filter_->InjectTouchEvent(event);
 }
 
-void DesktopSessionAgent::OnExecuteActionRequestEvent(
-    const protocol::ActionRequest& request) {
+void DesktopSessionAgent::InjectSendAttentionSequence() {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
 
+  protocol::ActionRequest request;
+  request.set_action(protocol::ActionRequest::SEND_ATTENTION_SEQUENCE);
+  action_executor_->ExecuteAction(request);
+}
+
+void DesktopSessionAgent::LockWorkstation() {
+  DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
+
+  protocol::ActionRequest request;
+  request.set_action(protocol::ActionRequest::LOCK_WORKSTATION);
   action_executor_->ExecuteAction(request);
 }
 
@@ -702,6 +718,7 @@
 void DesktopSessionAgent::SetScreenResolution(
     const ScreenResolution& resolution) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
 
   if (screen_controls_)
     screen_controls_->SetScreenResolution(resolution);
@@ -737,6 +754,8 @@
 
 void DesktopSessionAgent::SetUpUrlForwarder() {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
+  CHECK(started_);
+
   url_forwarder_configurator_->SetUpUrlForwarder(base::BindRepeating(
       &DesktopSessionAgent::OnUrlForwarderSetUpStateChanged, this));
 }
diff --git a/remoting/host/desktop_session_agent.h b/remoting/host/desktop_session_agent.h
index fe585c5c..56dd0b6 100644
--- a/remoting/host/desktop_session_agent.h
+++ b/remoting/host/desktop_session_agent.h
@@ -60,7 +60,6 @@
 class UrlForwarderConfigurator;
 
 namespace protocol {
-class ActionRequest;
 class InputEventTracker;
 }  // namespace protocol
 
@@ -73,6 +72,7 @@
       public webrtc::MouseCursorMonitor::Callback,
       public ClientSessionControl,
       public IpcFileOperations::ResultHandler,
+      public mojom::DesktopSessionAgent,
       public mojom::DesktopSessionControl {
  public:
   class Delegate {
@@ -131,7 +131,18 @@
   void OnDataResult(std::uint64_t file_id,
                     ResultHandler::DataResult result) override;
 
+  // mojom::DesktopSessionAgent implementation.
+  void Start(const std::string& authenticated_jid,
+             const ScreenResolution& resolution,
+             const DesktopEnvironmentOptions& options,
+             StartCallback callback) override;
+
   // mojom::DesktopSessionControl implementation.
+  void CaptureFrame() override;
+  void SelectSource(int id) override;
+  void SetScreenResolution(const ScreenResolution& resolution) override;
+  void LockWorkstation() override;
+  void InjectSendAttentionSequence() override;
   void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
   void InjectKeyEvent(const protocol::KeyEvent& event) override;
   void InjectMouseEvent(const protocol::MouseEvent& event) override;
@@ -141,7 +152,8 @@
 
   // Creates desktop integration components and a connected IPC channel to be
   // used to access them. The client end of the channel is returned.
-  mojo::ScopedMessagePipeHandle Start(const base::WeakPtr<Delegate>& delegate);
+  mojo::ScopedMessagePipeHandle Initialize(
+      const base::WeakPtr<Delegate>& delegate);
 
   // Stops the agent asynchronously.
   void Stop();
@@ -161,27 +173,9 @@
   void OnDesktopDisplayChanged(
       std::unique_ptr<protocol::VideoLayout> layout) override;
 
-  // Handles StartSessionAgent request from the client.
-  void OnStartSessionAgent(const std::string& authenticated_jid,
-                           const ScreenResolution& resolution,
-                           const DesktopEnvironmentOptions& options);
-
-  // Handles CaptureFrame requests from the client.
-  void OnCaptureFrame();
-
-  // Handles desktop display selection requests from the client.
-  void OnSelectSource(int id);
-
-  // Handles event executor requests from the client.
-  void OnExecuteActionRequestEvent(const protocol::ActionRequest& request);
-
   // Handles keyboard layout changes.
   void OnKeyboardLayoutChange(const protocol::KeyboardLayout& layout);
 
-  // Handles ChromotingNetworkDesktopMsg_SetScreenResolution request from
-  // the client.
-  void SetScreenResolution(const ScreenResolution& resolution);
-
   // Sends a message to the network process.
   void SendToNetwork(std::unique_ptr<IPC::Message> message);
 
@@ -266,6 +260,8 @@
 
   mojo::AssociatedRemote<mojom::DesktopSessionEventHandler>
       desktop_session_event_handler_;
+  mojo::AssociatedReceiver<mojom::DesktopSessionAgent> desktop_session_agent_{
+      this};
   mojo::AssociatedReceiver<mojom::DesktopSessionControl>
       desktop_session_control_{this};
 
diff --git a/remoting/host/desktop_session_agent_unittest.cc b/remoting/host/desktop_session_agent_unittest.cc
index bdc0a7d3..442c4e0 100644
--- a/remoting/host/desktop_session_agent_unittest.cc
+++ b/remoting/host/desktop_session_agent_unittest.cc
@@ -14,14 +14,15 @@
 #include "base/memory/weak_ptr.h"
 #include "base/run_loop.h"
 #include "base/task/single_thread_task_runner.h"
+#include "base/test/bind.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "ipc/ipc_channel_proxy.h"
 #include "ipc/ipc_listener.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
 #include "remoting/base/auto_thread_task_runner.h"
 #include "remoting/host/base/desktop_environment_options.h"
 #include "remoting/host/base/screen_resolution.h"
-#include "remoting/host/chromoting_messages.h"
 #include "remoting/host/fake_desktop_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -114,22 +115,39 @@
 TEST_F(DesktopSessionAgentTest, StartDesktopSessionAgent) {
   std::unique_ptr<FakeDelegate> delegate(new FakeDelegate(task_runner_));
   std::unique_ptr<IPC::ChannelProxy> proxy;
-  FakeListener listener(base::BindRepeating(
-      [](DesktopSessionAgentTest* test, std::unique_ptr<FakeDelegate>* delegate,
-         std::unique_ptr<IPC::ChannelProxy>* proxy) {
-        test->Shutdown();
-        delegate->reset();
-        proxy->reset();
-      },
-      base::Unretained(this), base::Unretained(&delegate),
-      base::Unretained(&proxy)));
+  bool session_started = false;
+  FakeListener listener(base::BindLambdaForTesting([&]() {
+    session_started = true;
+    Shutdown();
+    delegate.reset();
+    proxy.reset();
+  }));
   proxy = IPC::ChannelProxy::Create(
-      agent_->Start(delegate->GetWeakPtr()).release(),
+      agent_->Initialize(delegate->GetWeakPtr()).release(),
       IPC::Channel::MODE_CLIENT, &listener, task_runner_,
       base::ThreadTaskRunnerHandle::Get());
-  ASSERT_TRUE(proxy->Send(new ChromotingNetworkDesktopMsg_StartSessionAgent(
-      "jid", ScreenResolution(), DesktopEnvironmentOptions())));
+
+  mojo::AssociatedRemote<mojom::DesktopSessionAgent> desktop_session_agent;
+  proxy->GetRemoteAssociatedInterface(&desktop_session_agent);
+  // Let the IPC machinery finish up the interface request before using it.
+  task_environment_.RunUntilIdle();
+
+  bool remote_received = false;
+  desktop_session_agent->Start(
+      "jid", ScreenResolution(), DesktopEnvironmentOptions(),
+      base::BindLambdaForTesting(
+          [&](mojo::PendingAssociatedRemote<mojom::DesktopSessionControl>
+                  pending_remote) {
+            // Indicate that we received the desktop_session_control remote.
+            remote_received = true;
+            // Release any references to the other IPC classes.
+            desktop_session_agent.reset();
+          }));
+
   run_loop_.Run();
+
+  ASSERT_TRUE(remote_received);
+  ASSERT_TRUE(session_started);
 }
 
 }  // namespace remoting
diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc
index 43534a44..e074599 100644
--- a/remoting/host/desktop_session_proxy.cc
+++ b/remoting/host/desktop_session_proxy.cc
@@ -267,6 +267,11 @@
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
   VLOG(1) << "IPC: network <- desktop (" << peer_pid << ")";
+
+  desktop_session_agent_->Start(
+      client_session_control_->client_jid(), screen_resolution_, options_,
+      base::BindOnce(&DesktopSessionProxy::OnDesktopSessionAgentStarted,
+                     base::Unretained(this)));
 }
 
 void DesktopSessionProxy::OnChannelError() {
@@ -303,12 +308,7 @@
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
   DCHECK(!desktop_channel_);
 
-  if (client_session_events_) {
-    client_session_events_->OnDesktopAttached(session_id);
-  }
-
-  // Ignore the attach notification if the client session has been disconnected
-  // already.
+  // Ignore the attach event if the client session has already disconnected.
   if (!client_session_control_.get())
     return false;
 
@@ -317,12 +317,12 @@
       desktop_pipe, IPC::Channel::MODE_CLIENT, this, io_task_runner_.get(),
       base::ThreadTaskRunnerHandle::Get());
 
-  // Pass ID of the client (which is authenticated at this point) to the desktop
-  // session agent and start the agent.
-  SendToDesktop(new ChromotingNetworkDesktopMsg_StartSessionAgent(
-      client_session_control_->client_jid(), screen_resolution_, options_));
-
-  desktop_channel_->GetRemoteAssociatedInterface(&desktop_session_control_);
+  // Reset the associated remote to allow us to connect to the new desktop
+  // process. This is needed as the desktop may crash and the daemon process
+  // will restart it however the remote will still be bound to the previous
+  // process since DetachFromDesktop() will not be called.
+  desktop_session_agent_.reset();
+  desktop_channel_->GetRemoteAssociatedInterface(&desktop_session_agent_);
 
   desktop_session_id_ = session_id;
 
@@ -333,6 +333,7 @@
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
   desktop_channel_.reset();
+  desktop_session_agent_.reset();
   desktop_session_control_.reset();
   desktop_session_event_handler_.reset();
   desktop_session_id_ = UINT32_MAX;
@@ -355,6 +356,21 @@
   }
 }
 
+void DesktopSessionProxy::OnDesktopSessionAgentStarted(
+    mojo::PendingAssociatedRemote<mojom::DesktopSessionControl>
+        pending_remote) {
+  // Reset the associated remote to allow us to connect to the new desktop
+  // process. This is needed as the desktop may crash and the daemon process
+  // will restart it however the remote will still be bound to the previous
+  // process since DetachFromDesktop() will not be called.
+  desktop_session_control_.reset();
+  desktop_session_control_.Bind(std::move(pending_remote));
+
+  if (client_session_events_) {
+    client_session_events_->OnDesktopAttached(desktop_session_id_);
+  }
+}
+
 void DesktopSessionProxy::SetAudioCapturer(
     const base::WeakPtr<IpcAudioCapturer>& audio_capturer) {
   DCHECK(audio_capture_task_runner_->BelongsToCurrentThread());
@@ -365,9 +381,9 @@
 void DesktopSessionProxy::CaptureFrame() {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
-  if (desktop_channel_) {
+  if (desktop_session_control_) {
     ++pending_capture_frame_requests_;
-    SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame());
+    desktop_session_control_->CaptureFrame();
   } else {
     video_capturer_->OnCaptureResult(
         webrtc::DesktopCapturer::Result::ERROR_TEMPORARY, nullptr);
@@ -376,7 +392,9 @@
 
 bool DesktopSessionProxy::SelectSource(webrtc::DesktopCapturer::SourceId id) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
-  SendToDesktop(new ChromotingNetworkDesktopMsg_SelectSource(id));
+  if (desktop_session_control_) {
+    desktop_session_control_->SelectSource(id);
+  }
   return true;
 }
 
@@ -492,15 +510,29 @@
 
   // Passing an empty |screen_resolution_| value to the desktop process
   // indicates that the original resolution, if one exists, should be restored.
-  SendToDesktop(
-      new ChromotingNetworkDesktopMsg_SetScreenResolution(screen_resolution_));
+  if (desktop_session_control_) {
+    desktop_session_control_->SetScreenResolution(screen_resolution_);
+  }
 }
 
 void DesktopSessionProxy::ExecuteAction(
     const protocol::ActionRequest& request) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
-  SendToDesktop(new ChromotingNetworkDesktopMsg_ExecuteActionRequest(request));
+  if (!desktop_session_control_) {
+    return;
+  }
+
+  switch (request.action()) {
+    case protocol::ActionRequest::LOCK_WORKSTATION:
+      desktop_session_control_->LockWorkstation();
+      break;
+    case protocol::ActionRequest::SEND_ATTENTION_SEQUENCE:
+      desktop_session_control_->InjectSendAttentionSequence();
+      break;
+    default:
+      LOG(WARNING) << "Unknown action requested: " << request.action();
+  }
 }
 
 void DesktopSessionProxy::ReadFile(std::uint64_t file_id) {
@@ -565,7 +597,7 @@
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
   DCHECK(!set_up_url_forwarder_callback_);
 
-  if (!desktop_session_control_.is_connected()) {
+  if (!desktop_session_control_) {
     LOG(ERROR) << "The UrlForwarderConfigurator remote is not connected. Setup "
                << "request ignored.";
     callback.Run(SetUpUrlForwarderResponse::FAILED);
diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h
index bda9f06f..396efd8 100644
--- a/remoting/host/desktop_session_proxy.h
+++ b/remoting/host/desktop_session_proxy.h
@@ -204,6 +204,12 @@
   // Returns a shared buffer from the list of known buffers.
   scoped_refptr<IpcSharedBufferCore> GetSharedBufferCore(int id);
 
+  // Called when the desktop agent has started and provides the remote used to
+  // inject input events and control A/V capture.
+  void OnDesktopSessionAgentStarted(
+      mojo::PendingAssociatedRemote<mojom::DesktopSessionControl>
+          pending_remote);
+
   // Handles AudioPacket notification from the desktop session agent.
   void OnAudioPacket(const std::string& serialized_packet);
 
@@ -295,6 +301,10 @@
   // is called on IpcKeyboardLayoutMonitor.
   absl::optional<protocol::KeyboardLayout> keyboard_layout_;
 
+  // |desktop_session_agent_| is only valid when |desktop_channel_| is
+  // connected.
+  mojo::AssociatedRemote<mojom::DesktopSessionAgent> desktop_session_agent_;
+
   // |desktop_session_control_| is only valid when |desktop_channel_| is
   // connected. The desktop process can be detached and reattached several times
   // during a session (e.g. transitioning between the login screen and user
diff --git a/remoting/host/ipc_desktop_environment_unittest.cc b/remoting/host/ipc_desktop_environment_unittest.cc
index 193e8bcc..3c85b70 100644
--- a/remoting/host/ipc_desktop_environment_unittest.cc
+++ b/remoting/host/ipc_desktop_environment_unittest.cc
@@ -232,7 +232,7 @@
   void CreateDesktopProcess();
 
   // Destroys the desktop process object created by CreateDesktopProcess().
-  void DestoyDesktopProcess();
+  void DestroyDesktopProcess();
 
   // Creates a new remote URL forwarder configurator for the desktop process.
   void ResetRemoteUrlForwarderConfigurator();
@@ -246,6 +246,10 @@
   // loop has been run are no-op.
   void RunMainLoopUntilDone();
 
+  // Some tests require |setup_run_loop_| to be reset so we need a method which
+  // can be bound that will quit the current run loop.
+  void QuitSetupRunLoop();
+
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::MainThreadType::UI};
 
@@ -345,8 +349,8 @@
       });
   EXPECT_CALL(desktop_listener_, OnChannelError())
       .Times(AnyNumber())
-      .WillOnce(Invoke(this,
-                       &IpcDesktopEnvironmentTest::DestoyDesktopProcess));
+      .WillOnce(
+          Invoke(this, &IpcDesktopEnvironmentTest::DestroyDesktopProcess));
 
   // Intercept requests to connect and disconnect a terminal.
   EXPECT_CALL(daemon_channel_, ConnectTerminal(_, _, _))
@@ -369,6 +373,12 @@
   EXPECT_CALL(client_session_control_, SetDisableInputs(_))
       .Times(0);
 
+  // Most tests will only call this once but reattach will call multiple times.
+  EXPECT_CALL(client_session_events_, OnDesktopAttached(_))
+      .Times(AnyNumber())
+      .WillRepeatedly(InvokeWithoutArgs(
+          this, &IpcDesktopEnvironmentTest::QuitSetupRunLoop));
+
   // Create a desktop environment instance.
   desktop_environment_factory_ = std::make_unique<IpcDesktopEnvironmentFactory>(
       task_runner_, task_runner_, io_task_runner_, &daemon_channel_);
@@ -428,6 +438,8 @@
       .Times(AtMost(1))
       .WillOnce(Invoke(
           this, &IpcDesktopEnvironmentTest::CreateVideoCapturer));
+  EXPECT_CALL(*desktop_environment, CreateActionExecutorPtr()).Times(AtMost(1));
+  EXPECT_CALL(*desktop_environment, CreateFileOperationsPtr()).Times(AtMost(1));
   EXPECT_CALL(*desktop_environment, CreateMouseCursorMonitorPtr())
       .Times(AtMost(1))
       .WillOnce(Invoke(
@@ -446,10 +458,6 @@
       .WillOnce(
           Return(ByMove(std::move(owned_remote_url_forwarder_configurator_))));
 
-  // Let tests know that the remote desktop environment is created.
-  task_environment_.GetMainThreadTaskRunner()->PostTask(
-      FROM_HERE, setup_run_loop_->QuitClosure());
-
   return desktop_environment;
 }
 
@@ -517,7 +525,7 @@
   EXPECT_TRUE(desktop_process_->Start(std::move(desktop_environment_factory)));
 }
 
-void IpcDesktopEnvironmentTest::DestoyDesktopProcess() {
+void IpcDesktopEnvironmentTest::DestroyDesktopProcess() {
   desktop_channel_.reset();
   if (desktop_process_) {
     desktop_process_->OnChannelError();
@@ -556,6 +564,10 @@
   }
 }
 
+void IpcDesktopEnvironmentTest::QuitSetupRunLoop() {
+  setup_run_loop_->Quit();
+}
+
 // Runs until the desktop is attached and exits immediately after that.
 TEST_F(IpcDesktopEnvironmentTest, Basic) {
   std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
@@ -641,7 +653,7 @@
 
   // Create and start a new desktop process object.
   setup_run_loop_ = std::make_unique<base::RunLoop>();
-  DestoyDesktopProcess();
+  DestroyDesktopProcess();
   ResetRemoteUrlForwarderConfigurator();
   CreateDesktopProcess();
   setup_run_loop_->Run();
diff --git a/remoting/host/linux/linux_me2me_host.py b/remoting/host/linux/linux_me2me_host.py
index 65fb4935..cfb5d3c 100755
--- a/remoting/host/linux/linux_me2me_host.py
+++ b/remoting/host/linux/linux_me2me_host.py
@@ -14,6 +14,7 @@
   print("This script requires Python version 3.3")
   sys.exit(1)
 
+import abc
 import argparse
 import atexit
 import errno
@@ -427,44 +428,37 @@
         sys.stdout.flush()
 
 
-class Desktop:
+class Desktop(abc.ABC):
   """Manage a single virtual desktop"""
 
-  def __init__(self, sizes):
-    self.x_proc = None
+  def __init__(self, sizes, server_inhibitor=None, session_inhibitor=None,
+               host_inhibitor=None):
+    self.sizes = sizes
+    self.server_proc = None
     self.pre_session_proc = None
     self.session_proc = None
     self.host_proc = None
     self.child_env = None
-    self.sizes = sizes
-    self.xorg_conf = None
-    self.pulseaudio_pipe = None
-    self.server_supports_exact_resize = False
-    self.server_supports_randr = False
-    self.randr_add_sizes = False
     self.host_ready = False
-    self.ssh_auth_sockname = None
-    global g_desktop
-    assert(g_desktop is None)
-    g_desktop = self
-
-  @staticmethod
-  def get_unused_display_number():
-    """Return a candidate display number for which there is currently no
-    X Server lock file"""
-    display = FIRST_X_DISPLAY_NUMBER
-    while os.path.exists(X_LOCK_FILE_TEMPLATE % display):
-      display += 1
-    return display
+    self.server_supports_exact_resize = False
+    self.server_inhibitor = server_inhibitor
+    self.session_inhibitor = session_inhibitor
+    self.host_inhibitor = host_inhibitor
+    if self.server_inhibitor is None:
+      self.server_inhibitor = RelaunchInhibitor("Display server")
+    if self.session_inhibitor is None:
+      self.session_inhibitor = RelaunchInhibitor("session")
+    if self.host_inhibitor is None:
+      self.host_inhibitor = RelaunchInhibitor("host")
+    self.inhibitors = {
+        self.server_inhibitor: HOST_OFFLINE_REASON_X_SERVER_RETRIES_EXCEEDED,
+        self.session_inhibitor: HOST_OFFLINE_REASON_SESSION_RETRIES_EXCEEDED,
+        self.host_inhibitor: HOST_OFFLINE_REASON_HOST_RETRIES_EXCEEDED
+    }
 
   def _init_child_env(self):
     self.child_env = dict(os.environ)
 
-    # Force GDK to use the X11 backend, as otherwise parts of the host that use
-    # GTK can end up connecting to an active Wayland display instead of the
-    # CRD X11 session.
-    self.child_env["GDK_BACKEND"] = "x11"
-
     # Ensure that the software-rendering GL drivers are loaded by the desktop
     # session, instead of any hardware GL drivers installed on the system.
     library_path = (
@@ -479,8 +473,292 @@
 
     self.child_env["LD_LIBRARY_PATH"] = library_path
 
+  def _setup_gnubby(self):
+    self.ssh_auth_sockname = ("/tmp/chromoting.%s.ssh_auth_sock" %
+                              os.environ["USER"])
+
+  def _launch_pre_session(self):
+    # Launch the pre-session script, if it exists. Returns true if the script
+    # was launched, false if it didn't exist.
+    if os.path.exists(SYSTEM_PRE_SESSION_FILE_PATH):
+      pre_session_command = bash_invocation_for_script(
+          SYSTEM_PRE_SESSION_FILE_PATH)
+
+      logging.info("Launching pre-session: %s" % pre_session_command)
+      self.pre_session_proc = subprocess.Popen(pre_session_command,
+                                               stdin=subprocess.DEVNULL,
+                                               stdout=subprocess.PIPE,
+                                               stderr=subprocess.STDOUT,
+                                               cwd=HOME_DIR,
+                                               env=self.child_env)
+
+      if not self.pre_session_proc.pid:
+        raise Exception("Could not start pre-session")
+
+      output_filter_thread = SessionOutputFilterThread(
+          self.pre_session_proc.stdout, "Pre-session output: ", None)
+      output_filter_thread.start()
+
+      return True
+    return False
+
+  def launch_session(self, server_args, backoff_time):
+    """Launches process required for session and records the backoff time
+    for inhibitors so that process restarts are not attempted again until
+    that time has passed."""
+    self._init_child_env()
+    self.setup_audio()
+    self._setup_gnubby()
+    self._launch_server(server_args)
+    if not self._launch_pre_session():
+      # If there was no pre-session script, launch the session immediately.
+      self.launch_desktop_session()
+    self.server_inhibitor.record_started(MINIMUM_PROCESS_LIFETIME,
+                                      backoff_time)
+    self.session_inhibitor.record_started(MINIMUM_PROCESS_LIFETIME,
+                                     backoff_time)
+
+
+  def launch_host(self, host_config, extra_start_host_args, backoff_time):
+    # Start remoting host
+    args = [HOST_BINARY_PATH, "--host-config=-"]
+    if self.audio_pipe:
+      args.append("--audio-pipe-name=%s" % self.audio_pipe)
+    if self.server_supports_exact_resize:
+      args.append("--server-supports-exact-resize")
+    if self.ssh_auth_sockname:
+      args.append("--ssh-auth-sockname=%s" % self.ssh_auth_sockname)
+
+    args.extend(extra_start_host_args)
+
+    # Have the host process use SIGUSR1 to signal a successful start.
+    def sigusr1_handler(signum, frame):
+      _ = signum, frame
+      logging.info("Host ready to receive connections.")
+      self.host_ready = True
+      ParentProcessLogger.release_parent_if_connected(True)
+
+    signal.signal(signal.SIGUSR1, sigusr1_handler)
+    args.append("--signal-parent")
+
+    logging.info(args)
+    self.host_proc = subprocess.Popen(args, env=self.child_env,
+                                      stdin=subprocess.PIPE)
+    if not self.host_proc.pid:
+      raise Exception("Could not start Chrome Remote Desktop host")
+
+    try:
+      self.host_proc.stdin.write(json.dumps(host_config.data).encode('UTF-8'))
+      self.host_proc.stdin.flush()
+    except IOError as e:
+      # This can occur in rare situations, for example, if the machine is
+      # heavily loaded and the host process dies quickly (maybe if the X
+      # connection failed), the host process might be gone before this code
+      # writes to the host's stdin. Catch and log the exception, allowing
+      # the process to be retried instead of exiting the script completely.
+      logging.error("Failed writing to host's stdin: " + str(e))
+    finally:
+      self.host_proc.stdin.close()
+    self.host_inhibitor.record_started(MINIMUM_PROCESS_LIFETIME, backoff_time)
+
+  def shutdown_all_procs(self):
+    """Send SIGTERM to all procs and wait for them to exit. Will fallback to
+    SIGKILL if a process doesn't exit within 10 seconds.
+    """
+    for proc, name in [(self.host_proc, "host"),
+                       (self.session_proc, "session"),
+                       (self.pre_session_proc, "pre-session"),
+                       (self.server_proc, "display server")]:
+      logging.info("Shutting down %s: %s", name, proc and proc.pid)
+      if proc is not None:
+        logging.info("Sending SIGTERM to %s proc.", name)
+        try:
+          psutil_proc = psutil.Process(proc.pid)
+          psutil_proc.terminate()
+
+          # Use a short timeout, to avoid delaying service shutdown if the
+          # process refuses to die for some reason.
+          psutil_proc.wait(timeout=10)
+        except psutil.TimeoutExpired:
+          logging.error("Timed out - sending SIGKILL")
+          psutil_proc.kill()
+        except psutil.Error:
+          logging.error("Error terminating process")
+    self.server_proc = None
+    self.pre_session_proc = None
+    self.session_proc = None
+    self.host_proc = None
+
+  def report_offline_reason(self, host_config, reason):
+    """Attempt to report the specified offline reason to the registry. This
+    is best effort, and requires a valid host config.
+    """
+    logging.info("Attempting to report offline reason: " + reason)
+    args = [HOST_BINARY_PATH, "--host-config=-",
+            "--report-offline-reason=" + reason]
+    proc = subprocess.Popen(args, env=self.child_env, stdin=subprocess.PIPE)
+    proc.communicate(json.dumps(host_config.data).encode('UTF-8'))
+
+  def on_process_exit(self, pid, status):
+    """Checks for which process has exited and whether or not the exit was
+    expected. Returns a boolean indicating whether or not tear down of the
+    processes is needed."""
+    tear_down = False
+    if self.server_proc is not None and pid == self.server_proc.pid:
+      logging.info("Display server process terminated")
+      self.server_proc = None
+      self.server_inhibitor.record_stopped(expected=False)
+      tear_down = True
+
+    if (self.pre_session_proc is not None and
+        pid == self.pre_session_proc.pid):
+      self.pre_session_proc = None
+      if status == 0:
+        logging.info("Pre-session terminated successfully. Starting session.")
+        self.launch_desktop_session()
+      else:
+        logging.info("Pre-session failed. Tearing down.")
+        # The pre-session may have exited on its own or been brought down by
+        # the display server dying. Check if the display server is still running
+        # so we know whom to penalize.
+        if self.check_server_responding():
+          # Pre-session and session use the same inhibitor.
+          self.session_inhibitor.record_stopped(expected=False)
+        else:
+          self.server_inhibitor.record_stopped(expected=False)
+        # Either way, we want to tear down the session.
+        tear_down = True
+
+    if self.session_proc is not None and pid == self.session_proc.pid:
+      logging.info("Session process terminated")
+      self.session_proc = None
+      # The session may have exited on its own or been brought down by the
+      # display server dying. Check if the display server is still running so we
+      # know whom to penalize.
+      if self.check_server_responding():
+        self.session_inhibitor.record_stopped(expected=False)
+      else:
+        self.server_inhibitor.record_stopped(expected=False)
+      # Either way, we want to tear down the session.
+      tear_down = True
+
+    if self.host_proc is not None and pid == self.host_proc.pid:
+      logging.info("Host process terminated")
+      self.host_proc = None
+      self.host_ready = False
+
+      # These exit-codes must match the ones used by the host.
+      # See remoting/host/base/host_exit_codes.h.
+      # Delete the host or auth configuration depending on the returned error
+      # code, so the next time this script is run, a new configuration
+      # will be created and registered.
+      if os.WIFEXITED(status):
+        if os.WEXITSTATUS(status) == 100:
+          logging.info("Host configuration is invalid - exiting.")
+          return 0
+        elif os.WEXITSTATUS(status) == 101:
+          logging.info("Host ID has been deleted - exiting.")
+          host_config.clear()
+          host_config.save_and_log_errors()
+          return 0
+        elif os.WEXITSTATUS(status) == 102:
+          logging.info("OAuth credentials are invalid - exiting.")
+          return 0
+        elif os.WEXITSTATUS(status) == 103:
+          logging.info("Host domain is blocked by policy - exiting.")
+          return 0
+        # Nothing to do for Mac-only status 104 (login screen unsupported)
+        elif os.WEXITSTATUS(status) == 105:
+          logging.info("Username is blocked by policy - exiting.")
+          return 0
+        elif os.WEXITSTATUS(status) == 106:
+          logging.info("Host has been deleted - exiting.")
+          return 0
+        elif os.WEXITSTATUS(status) == 107:
+          logging.info("Remote access is disallowed by policy - exiting.")
+          return 0
+        elif os.WEXITSTATUS(status) == 108:
+          logging.info("This CPU is not supported - exiting.")
+          return 0
+        else:
+          logging.info("Host exited with status %s." % os.WEXITSTATUS(status))
+      elif os.WIFSIGNALED(status):
+        logging.info("Host terminated by signal %s." % os.WTERMSIG(status))
+
+      # The host may have exited on it's own or been brought down by the display
+      # server dying. Check if the display server is still running so we know
+      # whom to penalize.
+      if self.check_server_responding():
+        self.host_inhibitor.record_stopped(expected=False)
+      else:
+        self.server_inhibitor.record_stopped(expected=False)
+        # Only tear down if the display server isn't responding.
+        tear_down = True
+    return tear_down
+
+  def aggregate_failure_count(self):
+    failure_count = 0
+    for inhibitor in self.inhibitors:
+      if inhibitor.running:
+        inhibitor.record_stopped(True)
+      failure_count += inhibitor.failures
+    return failure_count
+
+  @abc.abstractmethod
+  def setup_audio(self):
+    pass
+
+  @abc.abstractmethod
+  def launch_desktop_session(self):
+    """Start desktop session."""
+    pass
+
+  @abc.abstractmethod
+  def check_server_responding(self):
+    """Checks if the display server is responding to connections."""
+    return False
+
+
+class XDesktop(Desktop):
+  """Manage a single virtual X desktop"""
+
+  def __init__(self, sizes):
+    super(XDesktop, self).__init__(sizes)
+    self.xorg_conf = None
+    self.audio_pipe = None
+    self.server_supports_randr = False
+    self.randr_add_sizes = False
+    self.ssh_auth_sockname = None
+    global g_desktop
+    assert(g_desktop is None)
+    g_desktop = self
+
+  @staticmethod
+  def get_unused_display_number():
+    """Return a candidate display number for which there is currently no
+    X Server lock file"""
+    display = FIRST_X_DISPLAY_NUMBER
+    while os.path.exists(X_LOCK_FILE_TEMPLATE % display):
+      display += 1
+    return display
+
+  def _init_child_env(self):
+    super(XDesktop, self)._init_child_env()
+    # Force GDK to use the X11 backend, as otherwise parts of the host that use
+    # GTK can end up connecting to an active Wayland display instead of the
+    # CRD X11 session.
+    self.child_env["GDK_BACKEND"] = "x11"
+
+
+  def launch_session(self, *args, **kwargs):
+    logging.info("Launching X server and X session.")
+    super(XDesktop, self).launch_session(*args, **kwargs)
+
+  def setup_audio(self):
+    self._setup_pulseaudio()
+
   def _setup_pulseaudio(self):
-    self.pulseaudio_pipe = None
+    self.audio_pipe = None
 
     # pulseaudio uses UNIX sockets for communication. Length of UNIX socket
     # name is limited to 108 characters, so audio will not work properly if
@@ -525,14 +803,10 @@
     self.child_env["PULSE_RUNTIME_PATH"] = pulse_path
     self.child_env["PULSE_STATE_PATH"] = pulse_path
     self.child_env["PULSE_SINK"] = sink_name
-    self.pulseaudio_pipe = pipe_name
+    self.audio_pipe = pipe_name
 
     return True
 
-  def _setup_gnubby(self):
-    self.ssh_auth_sockname = ("/tmp/chromoting.%s.ssh_auth_sock" %
-                              os.environ["USER"])
-
   # Returns child environment not containing TMPDIR.
   # Certain values of TMPDIR can break the X server (crbug.com/672684), so we
   # want to make sure it isn't set in the envirionment we use to start the
@@ -545,7 +819,7 @@
       del env_copy["TMPDIR"]
       return env_copy
 
-  def check_x_responding(self):
+  def check_server_responding(self):
     """Checks if the X server is responding to connections."""
     exit_code = subprocess.call("xdpyinfo", env=self.child_env,
                                 stdout=subprocess.DEVNULL)
@@ -554,7 +828,7 @@
   def _wait_for_x(self):
     # Wait for X to be active.
     for _test in range(20):
-      if self.check_x_responding():
+      if self.check_server_responding():
         logging.info("X server is active.")
         return
       time.sleep(0.5)
@@ -567,14 +841,14 @@
 
     logging.info("Starting Xvfb on display :%d" % display)
     screen_option = "%dx%dx24" % (max_width, max_height)
-    self.x_proc = subprocess.Popen(
+    self.server_proc = subprocess.Popen(
         ["Xvfb", ":%d" % display,
          "-auth", x_auth_file,
          "-nolisten", "tcp",
          "-noreset",
          "-screen", "0", screen_option
         ] + extra_x_args, env=self._x_env())
-    if not self.x_proc.pid:
+    if not self.server_proc.pid:
       raise Exception("Could not start Xvfb.")
 
     self._wait_for_x()
@@ -606,7 +880,7 @@
     # LD_LIBRARY_PATH.
     # Note: This prevents any environment variable the user has set from
     # affecting the Xorg server.
-    self.x_proc = subprocess.Popen(
+    self.server_proc = subprocess.Popen(
         ["Xorg", ":%d" % display,
          "-auth", x_auth_file,
          "-nolisten", "tcp",
@@ -617,11 +891,11 @@
          "-verbose", "3",
          "-config", config_file.name
         ] + extra_x_args, env=self._x_env())
-    if not self.x_proc.pid:
+    if not self.server_proc.pid:
       raise Exception("Could not start Xorg.")
     self._wait_for_x()
 
-  def _launch_x_server(self, extra_x_args):
+  def _launch_server(self, extra_x_args):
     x_auth_file = os.path.expanduser("~/.Xauthority")
     self.child_env["XAUTHORITY"] = x_auth_file
     display = self.get_unused_display_number()
@@ -724,32 +998,7 @@
     subprocess.Popen(args, env=self.child_env, stdout=subprocess.DEVNULL,
                      stderr=subprocess.DEVNULL)
 
-  def _launch_pre_session(self):
-    # Launch the pre-session script, if it exists. Returns true if the script
-    # was launched, false if it didn't exist.
-    if os.path.exists(SYSTEM_PRE_SESSION_FILE_PATH):
-      pre_session_command = bash_invocation_for_script(
-          SYSTEM_PRE_SESSION_FILE_PATH)
-
-      logging.info("Launching pre-session: %s" % pre_session_command)
-      self.pre_session_proc = subprocess.Popen(pre_session_command,
-                                               stdin=subprocess.DEVNULL,
-                                               stdout=subprocess.PIPE,
-                                               stderr=subprocess.STDOUT,
-                                               cwd=HOME_DIR,
-                                               env=self.child_env)
-
-      if not self.pre_session_proc.pid:
-        raise Exception("Could not start pre-session")
-
-      output_filter_thread = SessionOutputFilterThread(
-          self.pre_session_proc.stdout, "Pre-session output: ", None)
-      output_filter_thread.start()
-
-      return True
-    return False
-
-  def launch_x_session(self):
+  def launch_desktop_session(self):
     # Start desktop session.
     # The /dev/null input redirection is necessary to prevent the X session
     # reading from stdin.  If this code runs as a shell background job in a
@@ -775,94 +1024,6 @@
         "Session output: ", SESSION_OUTPUT_TIME_LIMIT_SECONDS)
     output_filter_thread.start()
 
-  def launch_session(self, x_args):
-    self._init_child_env()
-    self._setup_pulseaudio()
-    self._setup_gnubby()
-    self._launch_x_server(x_args)
-    if not self._launch_pre_session():
-      # If there was no pre-session script, launch the session immediately.
-      self.launch_x_session()
-
-  def launch_host(self, host_config, extra_start_host_args):
-    # Start remoting host
-    args = [HOST_BINARY_PATH, "--host-config=-"]
-    if self.pulseaudio_pipe:
-      args.append("--audio-pipe-name=%s" % self.pulseaudio_pipe)
-    if self.server_supports_exact_resize:
-      args.append("--server-supports-exact-resize")
-    if self.ssh_auth_sockname:
-      args.append("--ssh-auth-sockname=%s" % self.ssh_auth_sockname)
-
-    args.extend(extra_start_host_args)
-
-    # Have the host process use SIGUSR1 to signal a successful start.
-    def sigusr1_handler(signum, frame):
-      _ = signum, frame
-      logging.info("Host ready to receive connections.")
-      self.host_ready = True
-      ParentProcessLogger.release_parent_if_connected(True)
-
-    signal.signal(signal.SIGUSR1, sigusr1_handler)
-    args.append("--signal-parent")
-
-    logging.info(args)
-    self.host_proc = subprocess.Popen(args, env=self.child_env,
-                                      stdin=subprocess.PIPE)
-    if not self.host_proc.pid:
-      raise Exception("Could not start Chrome Remote Desktop host")
-
-    try:
-      self.host_proc.stdin.write(json.dumps(host_config.data).encode('UTF-8'))
-      self.host_proc.stdin.flush()
-    except IOError as e:
-      # This can occur in rare situations, for example, if the machine is
-      # heavily loaded and the host process dies quickly (maybe if the X
-      # connection failed), the host process might be gone before this code
-      # writes to the host's stdin. Catch and log the exception, allowing
-      # the process to be retried instead of exiting the script completely.
-      logging.error("Failed writing to host's stdin: " + str(e))
-    finally:
-      self.host_proc.stdin.close()
-
-  def shutdown_all_procs(self):
-    """Send SIGTERM to all procs and wait for them to exit. Will fallback to
-    SIGKILL if a process doesn't exit within 10 seconds.
-    """
-    for proc, name in [(self.host_proc, "host"),
-                       (self.session_proc, "session"),
-                       (self.pre_session_proc, "pre-session"),
-                       (self.x_proc, "X server")]:
-      logging.info("Shutting down %s: %s", name, proc and proc.pid)
-      if proc is not None:
-        logging.info("Sending SIGTERM to %s proc.", name)
-        try:
-          psutil_proc = psutil.Process(proc.pid)
-          psutil_proc.terminate()
-
-          # Use a short timeout, to avoid delaying service shutdown if the
-          # process refuses to die for some reason.
-          psutil_proc.wait(timeout=10)
-        except psutil.TimeoutExpired:
-          logging.error("Timed out - sending SIGKILL")
-          psutil_proc.kill()
-        except psutil.Error:
-          logging.error("Error terminating process")
-    self.x_proc = None
-    self.pre_session_proc = None
-    self.session_proc = None
-    self.host_proc = None
-
-  def report_offline_reason(self, host_config, reason):
-    """Attempt to report the specified offline reason to the registry. This
-    is best effort, and requires a valid host config.
-    """
-    logging.info("Attempting to report offline reason: " + reason)
-    args = [HOST_BINARY_PATH, "--host-config=-",
-            "--report-offline-reason=" + reason]
-    proc = subprocess.Popen(args, env=self.child_env, stdin=subprocess.PIPE)
-    proc.communicate(json.dumps(host_config.data).encode('UTF-8'))
-
 
 def parse_config_arg(args):
   """Parses only the --config option from a given command-line.
@@ -1483,8 +1644,8 @@
       break
 
 
-def main():
-  EPILOG = """This script is not intended for use by end-users.  To configure
+def setup_argument_parser():
+  EPILOG = """This script is not intended for use by end-users. To configure
 Chrome Remote Desktop, please install the app from the Chrome
 Web Store: https://chrome.google.com/remotedesktop"""
   parser = argparse.ArgumentParser(
@@ -1538,6 +1699,11 @@
                       type=int, nargs=2, default=False, action="store",
                       help=argparse.SUPPRESS)
   parser.add_argument(dest="args", nargs="*", help=argparse.SUPPRESS)
+  return parser
+
+
+def main():
+  parser = setup_argument_parser()
   options = parser.parse_args()
 
   # Determine the filename of the host configuration.
@@ -1754,41 +1920,21 @@
   if host.host_id:
     logging.info("Using host_id: " + host.host_id)
 
-  desktop = Desktop(sizes)
+  desktop = XDesktop(sizes)
 
-  # Keep track of the number of consecutive failures of any child process to
-  # run for longer than a set period of time. The script will exit after a
-  # threshold is exceeded.
-  # There is no point in tracking the X session process separately, since it is
-  # launched at (roughly) the same time as the X server, and the termination of
-  # one of these triggers the termination of the other.
-  x_server_inhibitor = RelaunchInhibitor("X server")
-  session_inhibitor = RelaunchInhibitor("session")
-  host_inhibitor = RelaunchInhibitor("host")
-  all_inhibitors = [
-      (x_server_inhibitor, HOST_OFFLINE_REASON_X_SERVER_RETRIES_EXCEEDED),
-      (session_inhibitor, HOST_OFFLINE_REASON_SESSION_RETRIES_EXCEEDED),
-      (host_inhibitor, HOST_OFFLINE_REASON_HOST_RETRIES_EXCEEDED)
-  ]
-
-  # Whether we are tearing down because the X server and/or session exited.
-  # This keeps us from counting processes exiting because we've terminated them
-  # as errors.
+  # Whether we are tearing down because the display server and/or session
+  # exited. This keeps us from counting processes exiting because we've
+  # terminated them as errors.
   tear_down = False
 
   while True:
-    # If the session process or X server stops running (e.g. because the user
-    # logged out), terminate all processes. The session will be restarted once
-    # everything has exited.
+    # If the session process or display server stops running (e.g. because the
+    # user logged out), terminate all processes. The session will be restarted
+    # once everything has exited.
     if tear_down:
       desktop.shutdown_all_procs()
 
-      failure_count = 0
-      for inhibitor, _ in all_inhibitors:
-        if inhibitor.running:
-          inhibitor.record_stopped(True)
-        failure_count += inhibitor.failures
-
+      failure_count = desktop.aggregate_failure_count()
       tear_down = False
 
       if (failure_count == 0):
@@ -1807,7 +1953,7 @@
 
     # Set the backoff interval and exit if a process failed too many times.
     backoff_time = SHORT_BACKOFF_TIME
-    for inhibitor, offline_reason in all_inhibitors:
+    for inhibitor, offline_reason in desktop.inhibitors.items():
       if inhibitor.failures >= MAX_LAUNCH_FAILURES:
         logging.error("Too many launch failures of '%s', exiting."
                       % inhibitor.label)
@@ -1824,24 +1970,16 @@
       # launching things in the wrong order due to differing relaunch times.
       logging.info("Waiting before relaunching")
     else:
-      if (desktop.x_proc is None and desktop.pre_session_proc is None and
+      if (desktop.server_proc is None and desktop.pre_session_proc is None and
           desktop.session_proc is None):
-        logging.info("Launching X server and X session.")
-        desktop.launch_session(options.args)
-        x_server_inhibitor.record_started(MINIMUM_PROCESS_LIFETIME,
-                                          backoff_time)
-        session_inhibitor.record_started(MINIMUM_PROCESS_LIFETIME,
-                                         backoff_time)
+        desktop.launch_session(options.args, backoff_time)
       if desktop.host_proc is None:
         logging.info("Launching host process")
-
         extra_start_host_args = []
         if HOST_EXTRA_PARAMS_ENV_VAR in os.environ:
             extra_start_host_args = \
                 re.split('\s+', os.environ[HOST_EXTRA_PARAMS_ENV_VAR].strip())
-        desktop.launch_host(host_config, extra_start_host_args)
-
-        host_inhibitor.record_started(MINIMUM_PROCESS_LIFETIME, backoff_time)
+        desktop.launch_host(host_config, extra_start_host_args, backoff_time)
 
     deadline = max(relaunch_times) if relaunch_times else 0
     pid, status = waitpid_handle_exceptions(-1, deadline)
@@ -1853,97 +1991,7 @@
     # When a process has terminated, and we've reaped its exit-code, any Popen
     # instance for that process is no longer valid. Reset any affected instance
     # to None.
-    if desktop.x_proc is not None and pid == desktop.x_proc.pid:
-      logging.info("X server process terminated")
-      desktop.x_proc = None
-      x_server_inhibitor.record_stopped(False)
-      tear_down = True
-
-    if (desktop.pre_session_proc is not None and
-        pid == desktop.pre_session_proc.pid):
-      desktop.pre_session_proc = None
-      if status == 0:
-        logging.info("Pre-session terminated successfully. Starting session.")
-        desktop.launch_x_session()
-      else:
-        logging.info("Pre-session failed. Tearing down.")
-        # The pre-session may have exited on its own or been brought down by the
-        # X server dying. Check if the X server is still running so we know whom
-        # to penalize.
-        if desktop.check_x_responding():
-          # Pre-session and session use the same inhibitor.
-          session_inhibitor.record_stopped(False)
-        else:
-          x_server_inhibitor.record_stopped(False)
-        # Either way, we want to tear down the session.
-        tear_down = True
-
-    if desktop.session_proc is not None and pid == desktop.session_proc.pid:
-      logging.info("Session process terminated")
-      desktop.session_proc = None
-      # The session may have exited on its own or been brought down by the X
-      # server dying. Check if the X server is still running so we know whom
-      # to penalize.
-      if desktop.check_x_responding():
-        session_inhibitor.record_stopped(False)
-      else:
-        x_server_inhibitor.record_stopped(False)
-      # Either way, we want to tear down the session.
-      tear_down = True
-
-    if desktop.host_proc is not None and pid == desktop.host_proc.pid:
-      logging.info("Host process terminated")
-      desktop.host_proc = None
-      desktop.host_ready = False
-
-      # These exit-codes must match the ones used by the host.
-      # See remoting/host/base/host_exit_codes.h.
-      # Delete the host or auth configuration depending on the returned error
-      # code, so the next time this script is run, a new configuration
-      # will be created and registered.
-      if os.WIFEXITED(status):
-        if os.WEXITSTATUS(status) == 100:
-          logging.info("Host configuration is invalid - exiting.")
-          return 0
-        elif os.WEXITSTATUS(status) == 101:
-          logging.info("Host ID has been deleted - exiting.")
-          host_config.clear()
-          host_config.save_and_log_errors()
-          return 0
-        elif os.WEXITSTATUS(status) == 102:
-          logging.info("OAuth credentials are invalid - exiting.")
-          return 0
-        elif os.WEXITSTATUS(status) == 103:
-          logging.info("Host domain is blocked by policy - exiting.")
-          return 0
-        # Nothing to do for Mac-only status 104 (login screen unsupported)
-        elif os.WEXITSTATUS(status) == 105:
-          logging.info("Username is blocked by policy - exiting.")
-          return 0
-        elif os.WEXITSTATUS(status) == 106:
-          logging.info("Host has been deleted - exiting.")
-          return 0
-        elif os.WEXITSTATUS(status) == 107:
-          logging.info("Remote access is disallowed by policy - exiting.")
-          return 0
-        elif os.WEXITSTATUS(status) == 108:
-          logging.info("This CPU is not supported - exiting.")
-          return 0
-        else:
-          logging.info("Host exited with status %s." % os.WEXITSTATUS(status))
-      elif os.WIFSIGNALED(status):
-        logging.info("Host terminated by signal %s." % os.WTERMSIG(status))
-
-      # The host may have exited on it's own or been brought down by the X
-      # server dying. Check if the X server is still running so we know whom to
-      # penalize.
-      if desktop.check_x_responding():
-        host_inhibitor.record_stopped(False)
-      else:
-        x_server_inhibitor.record_stopped(False)
-        # Only tear down if the X server isn't responding.
-        tear_down = True
-
+    tear_down = desktop.on_process_exit(pid, status)
 
 if __name__ == "__main__":
   logging.basicConfig(level=logging.DEBUG,
diff --git a/remoting/host/mojom/BUILD.gn b/remoting/host/mojom/BUILD.gn
index 23781de..74404623 100644
--- a/remoting/host/mojom/BUILD.gn
+++ b/remoting/host/mojom/BUILD.gn
@@ -14,6 +14,7 @@
     "remoting_host.mojom",
     "testing.mojom",
     "webauthn_proxy.mojom",
+    "webrtc_types.mojom",
     "wrapped_primitives.mojom",
   ]
 
@@ -31,6 +32,22 @@
           cpp = "::remoting::protocol::ClipboardEvent"
         },
         {
+          mojom = "remoting.mojom.DesktopCaptureOptions"
+          cpp = "::webrtc::DesktopCaptureOptions"
+        },
+        {
+          mojom = "remoting.mojom.DesktopEnvironmentOptions"
+          cpp = "::remoting::DesktopEnvironmentOptions"
+        },
+        {
+          mojom = "remoting.mojom.DesktopSize"
+          cpp = "::webrtc::DesktopSize"
+        },
+        {
+          mojom = "remoting.mojom.DesktopVector"
+          cpp = "::webrtc::DesktopVector"
+        },
+        {
           mojom = "remoting.mojom.KeyEvent"
           cpp = "::remoting::protocol::KeyEvent"
         },
@@ -43,6 +60,10 @@
           cpp = "::remoting::protocol::MouseEvent"
         },
         {
+          mojom = "remoting.mojom.ScreenResolution"
+          cpp = "::remoting::ScreenResolution"
+        },
+        {
           mojom = "remoting.mojom.TextEvent"
           cpp = "::remoting::protocol::TextEvent"
         },
@@ -64,7 +85,9 @@
       traits_public_deps = [
         "//mojo/public/cpp/base:shared_typemap_traits",
         "//mojo/public/cpp/bindings",
+        "//remoting/host/base",
         "//remoting/proto",
+        "//third_party/webrtc_overrides:webrtc_component",
       ]
     },
   ]
diff --git a/remoting/host/mojom/desktop_session.mojom b/remoting/host/mojom/desktop_session.mojom
index bcee3fa..671cb4d 100644
--- a/remoting/host/mojom/desktop_session.mojom
+++ b/remoting/host/mojom/desktop_session.mojom
@@ -5,6 +5,7 @@
 module remoting.mojom;
 
 import "mojo/public/mojom/base/byte_string.mojom";
+import "remoting/host/mojom/webrtc_types.mojom";
 import "remoting/host/mojom/wrapped_primitives.mojom";
 import "ui/gfx/geometry/mojom/geometry.mojom";
 
@@ -172,11 +173,80 @@
   CrashNetworkProcess();
 };
 
+// A set of options used to customize the desktop session behavior.
+struct DesktopEnvironmentOptions {
+  // True if the curtain mode should be enabled.
+  bool enable_curtaining;
+
+  // True if a user-interactive windows should be displayed on the desktop.
+  bool enable_user_interface;
+
+  // True if a notification should be shown when a remote user is connected.
+  bool enable_notifications;
+
+  // True if the session should be terminated when local input is detected.
+  bool terminate_upon_input;
+
+  // True if this host has file transfer enabled.
+  bool enable_file_transfer;
+
+  // True if this host has the remote open URL feature enabled.
+  bool enable_remote_open_url;
+
+  // True if this host has the remote WebAuthn feature enabled.
+  bool enable_remote_webauthn;
+
+  // If set, this value is used to constrain the amount of data that can be
+  // transferred using ClipboardEvents. A value of 0 will effectively disable
+  // clipboard sharing.
+  UInt32? clipboard_size;
+
+  // The DesktopCaptureOptions to initialize DesktopCapturer.
+  DesktopCaptureOptions desktop_capture_options;
+};
+
+// Describes a screen's dimensions and DPI.
+struct ScreenResolution {
+  // Dimensions of the screen in pixels.
+  DesktopSize dimensions;
+
+  // The vertical and horizontal DPI of the screen.
+  DesktopVector dpi;
+};
+
+// Starts the agent in the desktop session and returns an interface to allow the
+// caller to inject input events and control A/V capture.
+// The remote for this interface is owned in the low-privilege network process
+// and the receiver is bound in the high-privilege desktop integration process.
+interface DesktopSessionAgent {
+  // Passes the client session data to the desktop session agent and starts it.
+  // Note: This must only be called once per desktop process instance.
+  Start(string authenticated_jid, ScreenResolution resolution,
+        DesktopEnvironmentOptions options) =>
+      (pending_associated_remote<DesktopSessionControl>
+             desktop_session_control);
+};
+
 // Allows the network process to inject input events and control A/V capture in
 // the desktop session.
 // The remote for this interface is owned in the low-privilege network process
 // and the receiver is bound in the high-privilege desktop integration process.
 interface DesktopSessionControl {
+  // Requests that a new frame be captured.
+  CaptureFrame();
+
+  // Selects a display source in a multi-monitor system.
+  SelectSource(int32 desktop_display_id);
+
+  // Changes the screen resolution in the desktop session.
+  SetScreenResolution(ScreenResolution new_resolution);
+
+  // Locks the current desktop session.
+  LockWorkstation();
+
+  // Asks the desktop session to inject the send attention sequence (SAS).
+  InjectSendAttentionSequence();
+
   // Used to inject clipboard events received from the client.
   InjectClipboardEvent(ClipboardEvent event);
 
diff --git a/remoting/host/mojom/remoting_mojom_traits.cc b/remoting/host/mojom/remoting_mojom_traits.cc
index bd1df61..21314dc 100644
--- a/remoting/host/mojom/remoting_mojom_traits.cc
+++ b/remoting/host/mojom/remoting_mojom_traits.cc
@@ -25,6 +25,69 @@
 }
 
 // static
+bool mojo::StructTraits<remoting::mojom::DesktopCaptureOptionsDataView,
+                        ::webrtc::DesktopCaptureOptions>::
+    Read(remoting::mojom::DesktopCaptureOptionsDataView data_view,
+         ::webrtc::DesktopCaptureOptions* out_options) {
+  out_options->set_use_update_notifications(
+      data_view.use_update_notifications());
+  out_options->set_detect_updated_region(data_view.detect_updated_region());
+
+#if BUILDFLAG(IS_WIN)
+  out_options->set_allow_directx_capturer(data_view.allow_directx_capturer());
+#endif  // BUILDFLAG(IS_WIN)
+
+  return true;
+}
+
+// static
+bool mojo::StructTraits<remoting::mojom::DesktopEnvironmentOptionsDataView,
+                        ::remoting::DesktopEnvironmentOptions>::
+    Read(remoting::mojom::DesktopEnvironmentOptionsDataView data_view,
+         ::remoting::DesktopEnvironmentOptions* out_options) {
+  out_options->set_enable_curtaining(data_view.enable_curtaining());
+  out_options->set_enable_user_interface(data_view.enable_user_interface());
+  out_options->set_enable_notifications(data_view.enable_notifications());
+  out_options->set_terminate_upon_input(data_view.terminate_upon_input());
+  out_options->set_enable_file_transfer(data_view.enable_file_transfer());
+  out_options->set_enable_remote_open_url(data_view.enable_remote_open_url());
+  out_options->set_enable_remote_webauthn(data_view.enable_remote_webauthn());
+
+  absl::optional<uint32_t> clipboard_size;
+  if (!data_view.ReadClipboardSize(&clipboard_size)) {
+    return false;
+  }
+  if (clipboard_size.has_value()) {
+    out_options->set_clipboard_size(std::move(clipboard_size));
+  }
+
+  if (!data_view.ReadDesktopCaptureOptions(
+          out_options->desktop_capture_options())) {
+    return false;
+  }
+
+  return true;
+}
+
+// static
+bool mojo::StructTraits<
+    remoting::mojom::DesktopSizeDataView,
+    ::webrtc::DesktopSize>::Read(remoting::mojom::DesktopSizeDataView data_view,
+                                 ::webrtc::DesktopSize* out_size) {
+  out_size->set(data_view.width(), data_view.height());
+  return true;
+}
+
+// static
+bool mojo::StructTraits<remoting::mojom::DesktopVectorDataView,
+                        ::webrtc::DesktopVector>::
+    Read(remoting::mojom::DesktopVectorDataView data_view,
+         ::webrtc::DesktopVector* out_vector) {
+  out_vector->set(data_view.x(), data_view.y());
+  return true;
+}
+
+// static
 bool mojo::StructTraits<remoting::mojom::KeyEventDataView,
                         ::remoting::protocol::KeyEvent>::
     Read(remoting::mojom::KeyEventDataView data_view,
@@ -143,6 +206,27 @@
 }
 
 // static
+bool mojo::StructTraits<remoting::mojom::ScreenResolutionDataView,
+                        ::remoting::ScreenResolution>::
+    Read(remoting::mojom::ScreenResolutionDataView data_view,
+         ::remoting::ScreenResolution* out_resolution) {
+  ::webrtc::DesktopSize desktop_size;
+  if (!data_view.ReadDimensions(&desktop_size)) {
+    return false;
+  }
+
+  ::webrtc::DesktopVector dpi;
+  if (!data_view.ReadDpi(&dpi)) {
+    return false;
+  }
+
+  *out_resolution =
+      ::remoting::ScreenResolution(std::move(desktop_size), std::move(dpi));
+
+  return true;
+}
+
+// static
 bool mojo::StructTraits<remoting::mojom::TextEventDataView,
                         ::remoting::protocol::TextEvent>::
     Read(remoting::mojom::TextEventDataView data_view,
diff --git a/remoting/host/mojom/remoting_mojom_traits.h b/remoting/host/mojom/remoting_mojom_traits.h
index c65bef9..bb260641 100644
--- a/remoting/host/mojom/remoting_mojom_traits.h
+++ b/remoting/host/mojom/remoting_mojom_traits.h
@@ -8,14 +8,20 @@
 #include <stddef.h>
 #include <string>
 
+#include "base/numerics/safe_conversions.h"
+#include "build/build_config.h"
 #include "mojo/public/cpp/base/byte_string_mojom_traits.h"
 #include "mojo/public/cpp/bindings/array_traits_protobuf.h"
 #include "mojo/public/cpp/bindings/enum_traits.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
+#include "remoting/host/base/desktop_environment_options.h"
+#include "remoting/host/base/screen_resolution.h"
 #include "remoting/host/mojom/desktop_session.mojom-shared.h"
+#include "remoting/host/mojom/webrtc_types.mojom-shared.h"
 #include "remoting/host/mojom/wrapped_primitives.mojom-shared.h"
 #include "remoting/proto/event.pb.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 #include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
 
 namespace mojo {
@@ -55,6 +61,131 @@
 };
 
 template <>
+class mojo::StructTraits<remoting::mojom::UInt32DataView, uint32_t> {
+ public:
+  static uint32_t value(uint32_t value) { return value; }
+
+  static bool Read(remoting::mojom::UInt32DataView data_view,
+                   uint32_t* out_value) {
+    *out_value = data_view.value();
+    return true;
+  }
+};
+
+template <>
+class mojo::StructTraits<remoting::mojom::DesktopCaptureOptionsDataView,
+                         ::webrtc::DesktopCaptureOptions> {
+ public:
+  static bool use_update_notifications(
+      const ::webrtc::DesktopCaptureOptions& options) {
+    return options.use_update_notifications();
+  }
+
+  static bool detect_updated_region(
+      const ::webrtc::DesktopCaptureOptions& options) {
+    return options.detect_updated_region();
+  }
+
+#if BUILDFLAG(IS_WIN)
+  static bool allow_directx_capturer(
+      const ::webrtc::DesktopCaptureOptions& options) {
+    return options.allow_directx_capturer();
+  }
+#endif  // BUILDFLAG(IS_WIN)
+
+  static bool Read(remoting::mojom::DesktopCaptureOptionsDataView data_view,
+                   ::webrtc::DesktopCaptureOptions* out_options);
+};
+
+template <>
+class mojo::StructTraits<remoting::mojom::DesktopEnvironmentOptionsDataView,
+                         ::remoting::DesktopEnvironmentOptions> {
+ public:
+  static bool enable_curtaining(
+      const ::remoting::DesktopEnvironmentOptions& options) {
+    return options.enable_curtaining();
+  }
+
+  static bool enable_user_interface(
+      const ::remoting::DesktopEnvironmentOptions& options) {
+    return options.enable_user_interface();
+  }
+
+  static bool enable_notifications(
+      const ::remoting::DesktopEnvironmentOptions& options) {
+    return options.enable_notifications();
+  }
+
+  static bool terminate_upon_input(
+      const ::remoting::DesktopEnvironmentOptions& options) {
+    return options.terminate_upon_input();
+  }
+
+  static bool enable_file_transfer(
+      const ::remoting::DesktopEnvironmentOptions& options) {
+    return options.enable_file_transfer();
+  }
+
+  static bool enable_remote_open_url(
+      const ::remoting::DesktopEnvironmentOptions& options) {
+    return options.enable_remote_open_url();
+  }
+
+  static bool enable_remote_webauthn(
+      const ::remoting::DesktopEnvironmentOptions& options) {
+    return options.enable_remote_webauthn();
+  }
+
+  static absl::optional<uint32_t> clipboard_size(
+      const ::remoting::DesktopEnvironmentOptions& options) {
+    if (!options.clipboard_size().has_value()) {
+      return absl::nullopt;
+    }
+
+    size_t clipboard_size = options.clipboard_size().value();
+    return base::IsValueInRangeForNumericType<int>(clipboard_size)
+               ? clipboard_size
+               : INT_MAX;
+  }
+
+  static const webrtc::DesktopCaptureOptions& desktop_capture_options(
+      const ::remoting::DesktopEnvironmentOptions& options) {
+    return *options.desktop_capture_options();
+  }
+
+  static bool Read(remoting::mojom::DesktopEnvironmentOptionsDataView data_view,
+                   ::remoting::DesktopEnvironmentOptions* out_options);
+};
+
+template <>
+class mojo::StructTraits<remoting::mojom::DesktopSizeDataView,
+                         ::webrtc::DesktopSize> {
+ public:
+  static int32_t width(const ::webrtc::DesktopSize& size) {
+    return size.width();
+  }
+
+  static int32_t height(const ::webrtc::DesktopSize& size) {
+    return size.height();
+  }
+
+  static bool Read(remoting::mojom::DesktopSizeDataView data_view,
+                   ::webrtc::DesktopSize* out_size);
+};
+
+template <>
+class mojo::StructTraits<remoting::mojom::DesktopVectorDataView,
+                         ::webrtc::DesktopVector> {
+ public:
+  static int32_t x(const ::webrtc::DesktopVector& vector) { return vector.x(); }
+
+  static int32_t y(const ::webrtc::DesktopVector& vector) { return vector.y(); }
+
+  static bool Read(remoting::mojom::DesktopVectorDataView data_view,
+                   ::webrtc::DesktopVector* out_vector);
+};
+
+template <>
 struct EnumTraits<remoting::mojom::MouseButton,
                   ::remoting::protocol::MouseEvent::MouseButton> {
   static remoting::mojom::MouseButton ToMojom(
@@ -252,6 +383,24 @@
 };
 
 template <>
+class mojo::StructTraits<remoting::mojom::ScreenResolutionDataView,
+                         ::remoting::ScreenResolution> {
+ public:
+  static const ::webrtc::DesktopSize& dimensions(
+      const ::remoting::ScreenResolution& resolution) {
+    return resolution.dimensions();
+  }
+
+  static const ::webrtc::DesktopVector& dpi(
+      const ::remoting::ScreenResolution& resolution) {
+    return resolution.dpi();
+  }
+
+  static bool Read(remoting::mojom::ScreenResolutionDataView data_view,
+                   ::remoting::ScreenResolution* out_resolution);
+};
+
+template <>
 class mojo::StructTraits<remoting::mojom::TextEventDataView,
                          ::remoting::protocol::TextEvent> {
  public:
diff --git a/remoting/host/mojom/webauthn_proxy.mojom b/remoting/host/mojom/webauthn_proxy.mojom
index 8ed55423a..a25a181 100644
--- a/remoting/host/mojom/webauthn_proxy.mojom
+++ b/remoting/host/mojom/webauthn_proxy.mojom
@@ -18,6 +18,16 @@
   string response_data;
 };
 
+// An interface for the client (CRD WebAuthn Native Messaging Host) to cancel
+// an ongoing remote Create or Get request.
+interface WebAuthnRequestCanceller {
+  // Cancels the ongoing Create or Get request.
+  //
+  // Returns a boolean indicating whether the request has been successfully
+  // canceled.
+  Cancel() => (bool was_canceled);
+};
+
 // An interface for the host-side chromoting extension to pass intercepted Web
 // Authentication API requests to the client side chromoting security extension
 // through a chromoting host process.
@@ -44,10 +54,17 @@
   IsUserVerifyingPlatformAuthenticatorAvailable() => (bool is_available);
 
   // Handles a navigator.credentials.create() call remotely.
-  // |request_data| is the string-serialized representation of the parameters
-  // passed to the create() call. It is opaque to chromoting host processes and
-  // will be passed verbatim to the client.
+  //
+  // |request_data|: the string-serialized representation of the parameters
+  //     passed to the create() call. It is opaque to chromoting host processes
+  //     and will be passed verbatim to the client.
+  // |request_canceller|: interface for the caller to cancel the Create request
+  //     before it has been resolved. The receiver will be closed once the
+  //     cancelation has succeeded, or a CreateResponse has been returned.
+  //
   // If |response| is null, it means that the remote create() call has yielded
   // `null`, which is still a valid response according to the spec.
-  Create(string request_data) => (WebAuthnCreateResponse? response);
+  Create(string request_data,
+         pending_receiver<WebAuthnRequestCanceller> request_canceller) =>
+      (WebAuthnCreateResponse? response);
 };
diff --git a/remoting/host/mojom/webrtc_types.mojom b/remoting/host/mojom/webrtc_types.mojom
new file mode 100644
index 0000000..3b63223
--- /dev/null
+++ b/remoting/host/mojom/webrtc_types.mojom
@@ -0,0 +1,26 @@
+// Copyright 2022 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.
+
+module remoting.mojom;
+
+// WebRTC structures which are shared over IPC between chromoting processes.
+
+// A subset of the desktop capture options used by CRD.
+struct DesktopCaptureOptions {
+  bool use_update_notifications;
+  bool detect_updated_region;
+
+  [EnableIf=is_win]
+  bool allow_directx_capturer;
+};
+
+struct DesktopSize {
+  int32 width;
+  int32 height;
+};
+
+struct DesktopVector {
+  int32 x;
+  int32 y;
+};
diff --git a/remoting/host/mojom/wrapped_primitives.mojom b/remoting/host/mojom/wrapped_primitives.mojom
index 4d63ae73..d08c649e 100644
--- a/remoting/host/mojom/wrapped_primitives.mojom
+++ b/remoting/host/mojom/wrapped_primitives.mojom
@@ -22,3 +22,7 @@
 struct Int32 {
   int32 value;
 };
+
+struct UInt32 {
+  uint32 value;
+};
diff --git a/remoting/host/setup/BUILD.gn b/remoting/host/setup/BUILD.gn
index 4678df9d..14da0a2 100644
--- a/remoting/host/setup/BUILD.gn
+++ b/remoting/host/setup/BUILD.gn
@@ -108,7 +108,7 @@
     "//remoting/host/setup:start_host_main_headers",
     "//services/network:network_service",
     "//services/network/public/cpp:cpp",
-    "//third_party/libjingle_xmpp",
+    "//third_party/libjingle_xmpp:rtc_xmllite",
     "//third_party/webrtc_overrides:webrtc_component",
   ]
 
diff --git a/remoting/host/webauthn/remote_webauthn_constants.cc b/remoting/host/webauthn/remote_webauthn_constants.cc
index 0fd4073..4f720d4 100644
--- a/remoting/host/webauthn/remote_webauthn_constants.cc
+++ b/remoting/host/webauthn/remote_webauthn_constants.cc
@@ -11,9 +11,11 @@
 const char kIsUvpaaMessageType[] = "isUvpaa";
 const char kGetRemoteStateMessageType[] = "getRemoteState";
 const char kCreateMessageType[] = "create";
+const char kCancelMessageType[] = "cancel";
 
 const char kIsUvpaaResponseIsAvailableKey[] = "isAvailable";
 const char kGetRemoteStateResponseIsRemotedKey[] = "isRemoted";
+const char kCancelResponseWasCanceledKey[] = "wasCanceled";
 const char kCreateRequestDataKey[] = "requestData";
 const char kCreateResponseErrorNameKey[] = "errorName";
 const char kCreateResponseDataKey[] = "responseData";
diff --git a/remoting/host/webauthn/remote_webauthn_constants.h b/remoting/host/webauthn/remote_webauthn_constants.h
index 2194881..63d79b00 100644
--- a/remoting/host/webauthn/remote_webauthn_constants.h
+++ b/remoting/host/webauthn/remote_webauthn_constants.h
@@ -13,10 +13,12 @@
 extern const char kIsUvpaaMessageType[];
 extern const char kGetRemoteStateMessageType[];
 extern const char kCreateMessageType[];
+extern const char kCancelMessageType[];
 
 // NMH message keys.
 extern const char kIsUvpaaResponseIsAvailableKey[];
 extern const char kGetRemoteStateResponseIsRemotedKey[];
+extern const char kCancelResponseWasCanceledKey[];
 extern const char kCreateRequestDataKey[];
 extern const char kCreateResponseErrorNameKey[];
 extern const char kCreateResponseDataKey[];
diff --git a/remoting/host/webauthn/remote_webauthn_message_handler.cc b/remoting/host/webauthn/remote_webauthn_message_handler.cc
index a22567f..a9a28bc 100644
--- a/remoting/host/webauthn/remote_webauthn_message_handler.cc
+++ b/remoting/host/webauthn/remote_webauthn_message_handler.cc
@@ -4,25 +4,31 @@
 
 #include "remoting/host/webauthn/remote_webauthn_message_handler.h"
 
+#include <stdint.h>
+
+#include <limits>
+
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/containers/contains.h"
 #include "base/logging.h"
 #include "base/notreached.h"
+#include "remoting/host/mojom/webauthn_proxy.mojom.h"
 #include "remoting/proto/remote_webauthn.pb.h"
 #include "remoting/protocol/message_serialization.h"
 
 namespace {
 
-template <typename CallbackType, typename ResponseType>
+template <typename CallbackType, typename... ResponseType>
 void FindAndRunCallback(base::flat_map<uint64_t, CallbackType>& callback_map,
                         uint64_t id,
-                        ResponseType response) {
+                        ResponseType&&... response) {
   auto it = callback_map.find(id);
   if (it == callback_map.end()) {
     LOG(WARNING) << "No callback found associated with ID: " << id;
     return;
   }
-  std::move(it->second).Run(std::move(response));
+  std::move(it->second).Run(std::forward<ResponseType>(response)...);
   callback_map.erase(it);
 }
 
@@ -37,6 +43,9 @@
   receiver_set_.set_disconnect_handler(
       base::BindRepeating(&RemoteWebAuthnMessageHandler::OnReceiverDisconnected,
                           base::Unretained(this)));
+  request_cancellers_.set_disconnect_handler(base::BindRepeating(
+      &RemoteWebAuthnMessageHandler::OnRequestCancellerDisconnected,
+      base::Unretained(this)));
 }
 
 RemoteWebAuthnMessageHandler::~RemoteWebAuthnMessageHandler() {
@@ -69,6 +78,10 @@
       OnCreateResponse(remote_webauthn->id(),
                        remote_webauthn->create_response());
       break;
+    case protocol::RemoteWebAuthn::kCancelResponse:
+      OnCancelResponse(remote_webauthn->id(),
+                       remote_webauthn->cancel_response());
+      break;
     default:
       LOG(ERROR) << "Unknown message case: " << remote_webauthn->message_case();
   }
@@ -104,12 +117,16 @@
   Send(remote_webauthn, base::DoNothing());
 }
 
-void RemoteWebAuthnMessageHandler::Create(const std::string& request_data,
-                                          CreateCallback callback) {
+void RemoteWebAuthnMessageHandler::Create(
+    const std::string& request_data,
+    mojo::PendingReceiver<mojom::WebAuthnRequestCanceller> request_canceller,
+    CreateCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   uint64_t id = AssignNextMessageId();
   create_callbacks_[id] = std::move(callback);
+  message_id_to_request_canceller_[id] = request_cancellers_.Add(
+      this, std::move(request_canceller), /* context= */ id);
 
   protocol::RemoteWebAuthn remote_webauthn;
   remote_webauthn.set_id(id);
@@ -118,6 +135,28 @@
   Send(remote_webauthn, base::DoNothing());
 }
 
+void RemoteWebAuthnMessageHandler::Cancel(CancelCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  uint64_t id = request_cancellers_.current_context();
+
+  // TODO(yuweih): Check |get_callbacks_| here.
+  if (!base::Contains(create_callbacks_, id)) {
+    LOG(ERROR) << "No ongoing request is associated with message ID " << id;
+    std::move(callback).Run(false);
+    RemoveRequestCancellerByMessageId(id);
+    return;
+  }
+
+  cancel_callbacks_[id] = std::move(callback);
+
+  protocol::RemoteWebAuthn remote_webauthn;
+  remote_webauthn.set_id(id);
+  // This creates an empty cancel request.
+  remote_webauthn.mutable_cancel_request();
+  Send(remote_webauthn, base::DoNothing());
+}
+
 void RemoteWebAuthnMessageHandler::AddReceiver(
     mojo::PendingReceiver<mojom::WebAuthnProxy> receiver) {
   if (!connected()) {
@@ -133,6 +172,11 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   receiver_set_.Clear();
+  request_cancellers_.Clear();
+  message_id_to_request_canceller_.clear();
+  is_uvpaa_callbacks_.clear();
+  create_callbacks_.clear();
+  cancel_callbacks_.clear();
 }
 
 void RemoteWebAuthnMessageHandler::NotifyWebAuthnStateChange() {
@@ -183,13 +227,62 @@
       NOTREACHED() << "Unknown create result case: " << response.result_case();
   }
 
+  RemoveRequestCancellerByMessageId(id);
   FindAndRunCallback(create_callbacks_, id, std::move(mojo_response));
 }
 
+void RemoteWebAuthnMessageHandler::OnCancelResponse(
+    uint64_t id,
+    const protocol::RemoteWebAuthn_CancelResponse& response) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (!response.was_canceled()) {
+    LOG(WARNING) << "Client failed to cancel request with ID " << id;
+    FindAndRunCallback(cancel_callbacks_, id, /* was_canceled= */ false);
+    // Don't remove request canceller here since cancelation might succeed after
+    // retrying.
+    return;
+  }
+
+  if (base::Contains(create_callbacks_, id)) {
+    FindAndRunCallback(cancel_callbacks_, id, /* was_canceled= */ true);
+    FindAndRunCallback(
+        create_callbacks_, id,
+        mojom::WebAuthnCreateResponse::NewErrorName("AbortError"));
+    RemoveRequestCancellerByMessageId(id);
+    return;
+  }
+
+  // TODO(yuweih): Check |get_callbacks_| here.
+
+  LOG(WARNING) << "Can't find cancelable request associated with ID " << id;
+  FindAndRunCallback(cancel_callbacks_, id, /* was_canceled= */ false);
+  RemoveRequestCancellerByMessageId(id);
+}
+
 uint64_t RemoteWebAuthnMessageHandler::AssignNextMessageId() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   return current_message_id_++;
 }
 
+void RemoteWebAuthnMessageHandler::RemoveRequestCancellerByMessageId(
+    uint64_t message_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  auto it = message_id_to_request_canceller_.find(message_id);
+  if (it != message_id_to_request_canceller_.end()) {
+    request_cancellers_.Remove(it->second);
+    message_id_to_request_canceller_.erase(it);
+  } else {
+    LOG(WARNING) << "Cannot find receiver for message ID " << message_id;
+  }
+}
+
+void RemoteWebAuthnMessageHandler::OnRequestCancellerDisconnected() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  message_id_to_request_canceller_.erase(request_cancellers_.current_context());
+}
+
 }  // namespace remoting
diff --git a/remoting/host/webauthn/remote_webauthn_message_handler.h b/remoting/host/webauthn/remote_webauthn_message_handler.h
index ff405bfdc4..44420c2 100644
--- a/remoting/host/webauthn/remote_webauthn_message_handler.h
+++ b/remoting/host/webauthn/remote_webauthn_message_handler.h
@@ -22,12 +22,14 @@
 namespace remoting {
 
 namespace protocol {
+class RemoteWebAuthn_CancelResponse;
 class RemoteWebAuthn_CreateResponse;
 class RemoteWebAuthn_IsUvpaaResponse;
 }  // namespace protocol
 
 class RemoteWebAuthnMessageHandler final
     : public mojom::WebAuthnProxy,
+      public mojom::WebAuthnRequestCanceller,
       public protocol::NamedMessagePipeHandler {
  public:
   RemoteWebAuthnMessageHandler(const std::string& name,
@@ -45,8 +47,13 @@
   // mojom::WebAuthnProxy implementation.
   void IsUserVerifyingPlatformAuthenticatorAvailable(
       IsUserVerifyingPlatformAuthenticatorAvailableCallback callback) override;
-  void Create(const std::string& request_data,
-              CreateCallback callback) override;
+  void Create(
+      const std::string& request_data,
+      mojo::PendingReceiver<mojom::WebAuthnRequestCanceller> request_canceller,
+      CreateCallback callback) override;
+
+  // mojom::WebAuthnRequestCanceller implementation.
+  void Cancel(CancelCallback callback) override;
 
   void AddReceiver(mojo::PendingReceiver<mojom::WebAuthnProxy> receiver);
   void ClearReceivers();
@@ -68,9 +75,15 @@
   void OnCreateResponse(
       uint64_t id,
       const protocol::RemoteWebAuthn_CreateResponse& response);
+  void OnCancelResponse(
+      uint64_t id,
+      const protocol::RemoteWebAuthn_CancelResponse& response);
 
   uint64_t AssignNextMessageId();
 
+  void RemoveRequestCancellerByMessageId(uint64_t message_id);
+  void OnRequestCancellerDisconnected();
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   RemoteWebAuthnExtensionNotifier extension_notifier_;
@@ -81,6 +94,15 @@
       is_uvpaa_callbacks_ GUARDED_BY_CONTEXT(sequence_checker_);
   CallbackMap<CreateCallback> create_callbacks_
       GUARDED_BY_CONTEXT(sequence_checker_);
+  CallbackMap<CancelCallback> cancel_callbacks_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // The receiver context is the message ID associated with the request to be
+  // canceled.
+  mojo::ReceiverSet<mojom::WebAuthnRequestCanceller, uint64_t>
+      request_cancellers_ GUARDED_BY_CONTEXT(sequence_checker_);
+  base::flat_map<uint64_t, mojo::ReceiverId> message_id_to_request_canceller_
+      GUARDED_BY_CONTEXT(sequence_checker_);
 
   uint64_t current_message_id_ GUARDED_BY_CONTEXT(sequence_checker_) = 0u;
 
diff --git a/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc b/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
index b4eee0b..c885174 100644
--- a/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
+++ b/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
@@ -4,6 +4,7 @@
 
 #include "remoting/host/webauthn/remote_webauthn_native_messaging_host.h"
 
+#include <algorithm>
 #include <memory>
 
 #include "base/bind.h"
@@ -14,6 +15,7 @@
 #include "mojo/public/cpp/platform/named_platform_channel.h"
 #include "mojo/public/cpp/system/isolated_connection.h"
 #include "remoting/host/chromoting_host_services_client.h"
+#include "remoting/host/mojom/webauthn_proxy.mojom.h"
 #include "remoting/host/native_messaging/native_messaging_constants.h"
 #include "remoting/host/native_messaging/native_messaging_helpers.h"
 #include "remoting/host/webauthn/remote_webauthn_constants.h"
@@ -31,7 +33,11 @@
     std::unique_ptr<ChromotingHostServicesProvider> host_service_api_client,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
     : task_runner_(task_runner),
-      host_service_api_client_(std::move(host_service_api_client)) {}
+      host_service_api_client_(std::move(host_service_api_client)) {
+  request_cancellers_.set_disconnect_handler(base::BindRepeating(
+      &RemoteWebAuthnNativeMessagingHost::OnRequestCancellerDisconnected,
+      base::Unretained(this)));
+}
 
 RemoteWebAuthnNativeMessagingHost::~RemoteWebAuthnNativeMessagingHost() {
   DCHECK(task_runner_->BelongsToCurrentThread());
@@ -59,6 +65,8 @@
     ProcessGetRemoteState(std::move(response));
   } else if (type == kCreateMessageType) {
     ProcessCreate(request, std::move(response));
+  } else if (type == kCancelMessageType) {
+    ProcessCancel(request, std::move(response));
   } else {
     LOG(ERROR) << "Unsupported request type: " << type;
   }
@@ -122,23 +130,76 @@
     return;
   }
 
-  const std::string* request_data =
-      request.FindStringKey(kCreateRequestDataKey);
-  if (!request_data) {
-    LOG(ERROR) << "Request data not found in create request.";
-    // navigator.credentials.create() throws NotSupportedError if the parameter
-    // is unexpected.
+  // navigator.credentials.create() throws NotSupportedError if it is called
+  // with unexpected parameters.
+
+  const base::Value* message_id = request.FindKey(kMessageId);
+  if (!message_id) {
+    LOG(ERROR) << "Message ID not found in create request.";
     response.SetStringKey(kCreateResponseErrorNameKey, "NotSupportedError");
     SendMessageToClient(std::move(response));
     return;
   }
 
+  const std::string* request_data =
+      request.FindStringKey(kCreateRequestDataKey);
+  if (!request_data) {
+    LOG(ERROR) << "Request data not found in create request.";
+    response.SetStringKey(kCreateResponseErrorNameKey, "NotSupportedError");
+    SendMessageToClient(std::move(response));
+    return;
+  }
+
+  mojo::PendingRemote<mojom::WebAuthnRequestCanceller>
+      pending_request_canceller;
+  auto request_canceller_receiver =
+      pending_request_canceller.InitWithNewPipeAndPassReceiver();
+  id_to_request_canceller_.emplace(
+      message_id->Clone(),
+      request_cancellers_.Add(std::move(pending_request_canceller)));
+
   remote_->Create(
-      *request_data,
+      *request_data, std::move(request_canceller_receiver),
       base::BindOnce(&RemoteWebAuthnNativeMessagingHost::OnCreateResponse,
                      base::Unretained(this), std::move(response)));
 }
 
+void RemoteWebAuthnNativeMessagingHost::ProcessCancel(
+    const base::Value& request,
+    base::Value response) {
+  // Cancel request: {id: string, type: 'cancel'}
+  // Create response:
+  //   {id: string, type: 'cancelResponse', wasCanceled: boolean}
+
+  if (!EnsureIpcConnection()) {
+    response.SetBoolKey(kCancelResponseWasCanceledKey, false);
+    SendMessageToClient(std::move(response));
+    return;
+  }
+
+  const base::Value* message_id = request.FindKey(kMessageId);
+  if (!message_id) {
+    LOG(ERROR) << "Message ID not found in cancel request.";
+    response.SetBoolKey(kCancelResponseWasCanceledKey, false);
+    SendMessageToClient(std::move(response));
+    return;
+  }
+
+  auto it = id_to_request_canceller_.find(*message_id);
+  if (it == id_to_request_canceller_.end()) {
+    LOG(ERROR) << "No cancelable request found for message ID " << *message_id;
+    response.SetBoolKey(kCancelResponseWasCanceledKey, false);
+    SendMessageToClient(std::move(response));
+    return;
+  }
+
+  auto* canceller = request_cancellers_.Get(it->second);
+  CHECK(canceller);
+  canceller->Cancel(
+      base::BindOnce(&RemoteWebAuthnNativeMessagingHost::OnCancelResponse,
+                     base::Unretained(this), std::move(response)));
+}
+
 void RemoteWebAuthnNativeMessagingHost::ProcessGetRemoteState(
     base::Value response) {
   // GetRemoteState request: {id: string, type: 'getRemoteState'}
@@ -205,6 +266,24 @@
     }
   }
 
+  const base::Value* message_id = response.FindKey(kMessageId);
+  if (message_id) {
+    RemoveRequestCancellerByMessageId(*message_id);
+  }
+
+  SendMessageToClient(std::move(response));
+}
+
+void RemoteWebAuthnNativeMessagingHost::OnCancelResponse(base::Value response,
+                                                         bool was_canceled) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  const base::Value* message_id = response.FindKey(kMessageId);
+  if (message_id) {
+    RemoveRequestCancellerByMessageId(*message_id);
+  }
+
+  response.SetBoolKey(kCancelResponseWasCanceledKey, was_canceled);
   SendMessageToClient(std::move(response));
 }
 
@@ -270,4 +349,35 @@
   client_->PostMessageFromNativeHost(message_json);
 }
 
+void RemoteWebAuthnNativeMessagingHost::RemoveRequestCancellerByMessageId(
+    const base::Value& message_id) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  auto it = id_to_request_canceller_.find(message_id);
+  if (it != id_to_request_canceller_.end()) {
+    request_cancellers_.Remove(it->second);
+    id_to_request_canceller_.erase(it);
+  } else {
+    LOG(WARNING) << "Cannot find receiver for message ID " << message_id;
+  }
+}
+
+void RemoteWebAuthnNativeMessagingHost::OnRequestCancellerDisconnected(
+    mojo::RemoteSetElementId disconnecting_canceller) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  auto it = std::find_if(id_to_request_canceller_.begin(),
+                         id_to_request_canceller_.end(),
+                         [disconnecting_canceller](const auto& pair) {
+                           return pair.second == disconnecting_canceller;
+                         });
+  if (it != id_to_request_canceller_.end()) {
+    id_to_request_canceller_.erase(it);
+  }
+
+  if (on_request_canceller_disconnected_for_testing_) {
+    on_request_canceller_disconnected_for_testing_.Run();
+  }
+}
+
 }  // namespace remoting
diff --git a/remoting/host/webauthn/remote_webauthn_native_messaging_host.h b/remoting/host/webauthn/remote_webauthn_native_messaging_host.h
index b16cf37..9a6e884 100644
--- a/remoting/host/webauthn/remote_webauthn_native_messaging_host.h
+++ b/remoting/host/webauthn/remote_webauthn_native_messaging_host.h
@@ -7,11 +7,15 @@
 
 #include <memory>
 
+#include "base/callback.h"
+#include "base/callback_forward.h"
+#include "base/containers/flat_map.h"
 #include "base/containers/queue.h"
 #include "base/memory/raw_ptr.h"
 #include "base/values.h"
 #include "extensions/browser/api/messaging/native_message_host.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "mojo/public/cpp/bindings/remote_set.h"
 #include "remoting/host/chromoting_host_services_provider.h"
 #include "remoting/host/mojom/webauthn_proxy.mojom.h"
 
@@ -45,12 +49,14 @@
   void ProcessGetRemoteState(base::Value response);
   void ProcessIsUvpaa(const base::Value& request, base::Value response);
   void ProcessCreate(const base::Value& request, base::Value response);
+  void ProcessCancel(const base::Value& request, base::Value response);
 
   void OnQueryVersionResult(uint32_t version);
   void OnIpcDisconnected();
   void OnIsUvpaaResponse(base::Value response, bool is_available);
   void OnCreateResponse(base::Value response,
                         mojom::WebAuthnCreateResponsePtr remote_response);
+  void OnCancelResponse(base::Value response, bool was_canceled);
 
   void QueryNextRemoteState();
   void SendNextRemoteState(bool is_remoted);
@@ -61,10 +67,19 @@
   bool EnsureIpcConnection();
   void SendMessageToClient(base::Value message);
 
+  void RemoveRequestCancellerByMessageId(const base::Value& message_id);
+  void OnRequestCancellerDisconnected(
+      mojo::RemoteSetElementId disconnecting_canceller);
+
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   raw_ptr<extensions::NativeMessageHost::Client> client_ = nullptr;
   std::unique_ptr<ChromotingHostServicesProvider> host_service_api_client_;
   mojo::Remote<mojom::WebAuthnProxy> remote_;
+  mojo::RemoteSet<mojom::WebAuthnRequestCanceller> request_cancellers_;
+  base::flat_map<base::Value, mojo::RemoteSetElementId>
+      id_to_request_canceller_;
+
+  base::RepeatingClosure on_request_canceller_disconnected_for_testing_;
 
   // Pending getRemoteStateResponses to be sent.
   base::queue<base::Value> get_remote_state_responses_;
diff --git a/remoting/host/webauthn/remote_webauthn_native_messaging_host_unittest.cc b/remoting/host/webauthn/remote_webauthn_native_messaging_host_unittest.cc
index 505ae7cb..95a14df 100644
--- a/remoting/host/webauthn/remote_webauthn_native_messaging_host_unittest.cc
+++ b/remoting/host/webauthn/remote_webauthn_native_messaging_host_unittest.cc
@@ -4,6 +4,7 @@
 
 #include <memory>
 
+#include "base/callback.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/memory/ptr_util.h"
@@ -55,7 +56,17 @@
               IsUserVerifyingPlatformAuthenticatorAvailable,
               (IsUserVerifyingPlatformAuthenticatorAvailableCallback),
               (override));
-  MOCK_METHOD(void, Create, (const std::string&, CreateCallback), (override));
+  MOCK_METHOD(void,
+              Create,
+              (const std::string&,
+               mojo::PendingReceiver<mojom::WebAuthnRequestCanceller>,
+               CreateCallback),
+              (override));
+};
+
+class MockWebAuthnRequestCanceller : public mojom::WebAuthnRequestCanceller {
+ public:
+  MOCK_METHOD(void, Cancel, (CancelCallback), (override));
 };
 
 }  // namespace
@@ -83,6 +94,9 @@
   testing::Expectation ExpectBindWebAuthnProxy(
       bool should_bind_receiver = true);
 
+  void SetOnRequestCancellerDisconnectedSpy(
+      const base::RepeatingClosure& spy_callback);
+
   // Sends a message to the native messaging host.
   void SendMessage(const base::Value& message);
 
@@ -152,6 +166,12 @@
   return EXPECT_CALL(api_, BindWebAuthnProxy(_)).WillOnce(Return());
 }
 
+void RemoteWebAuthnNativeMessagingHostTest::
+    SetOnRequestCancellerDisconnectedSpy(
+        const base::RepeatingClosure& spy_callback) {
+  host_->on_request_canceller_disconnected_for_testing_ = spy_callback;
+}
+
 void RemoteWebAuthnNativeMessagingHostTest::SendMessage(
     const base::Value& message) {
   std::string serialized_message;
@@ -242,12 +262,13 @@
   ASSERT_EQ(*response_2.FindBoolKey(kIsUvpaaResponseIsAvailableKey), false);
 }
 
-TEST_F(RemoteWebAuthnNativeMessagingHostTest, Create_MalformedRequest_Error) {
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, Create_RequestMissingData_Error) {
   ExpectGetSessionServices();
   ExpectBindWebAuthnProxy();
 
   // Request message missing |requestData| field.
-  SendMessage(CreateRequestMessage(kCreateMessageType));
+  auto request = CreateRequestMessage(kCreateMessageType);
+  SendMessage(std::move(request));
 
   const base::Value& response = ReadMessage();
 
@@ -260,7 +281,7 @@
        Create_IpcConnectionFailed_Error) {
   ExpectGetSessionServices(false);
   auto request = CreateRequestMessage(kCreateMessageType);
-  request.SetStringKey(kCreateRequestDataKey, "dummy");
+  request.SetStringKey(kCreateRequestDataKey, "fake");
   SendMessage(std::move(request));
 
   const base::Value& response = ReadMessage();
@@ -273,10 +294,10 @@
 TEST_F(RemoteWebAuthnNativeMessagingHostTest, Create_EmptyResponse) {
   ExpectGetSessionServices();
   ExpectBindWebAuthnProxy();
-  EXPECT_CALL(webauthn_proxy_, Create("dummy", _))
-      .WillOnce(base::test::RunOnceCallback<1>(nullptr));
+  EXPECT_CALL(webauthn_proxy_, Create("fake", _, _))
+      .WillOnce(base::test::RunOnceCallback<2>(nullptr));
   auto request = CreateRequestMessage(kCreateMessageType);
-  request.SetStringKey(kCreateRequestDataKey, "dummy");
+  request.SetStringKey(kCreateRequestDataKey, "fake");
   SendMessage(std::move(request));
 
   const base::Value& response = ReadMessage();
@@ -291,10 +312,10 @@
   ExpectBindWebAuthnProxy();
   auto mojo_response =
       mojom::WebAuthnCreateResponse::NewErrorName("NotSupportedError");
-  EXPECT_CALL(webauthn_proxy_, Create("dummy", _))
-      .WillOnce(base::test::RunOnceCallback<1>(std::move(mojo_response)));
+  EXPECT_CALL(webauthn_proxy_, Create("fake", _, _))
+      .WillOnce(base::test::RunOnceCallback<2>(std::move(mojo_response)));
   auto request = CreateRequestMessage(kCreateMessageType);
-  request.SetStringKey(kCreateRequestDataKey, "dummy");
+  request.SetStringKey(kCreateRequestDataKey, "fake");
   SendMessage(std::move(request));
 
   const base::Value& response = ReadMessage();
@@ -309,18 +330,145 @@
   ExpectGetSessionServices();
   ExpectBindWebAuthnProxy();
   auto mojo_response =
-      mojom::WebAuthnCreateResponse::NewResponseData("dummy response");
-  EXPECT_CALL(webauthn_proxy_, Create("dummy", _))
-      .WillOnce(base::test::RunOnceCallback<1>(std::move(mojo_response)));
+      mojom::WebAuthnCreateResponse::NewResponseData("fake response");
+  EXPECT_CALL(webauthn_proxy_, Create("fake", _, _))
+      .WillOnce(base::test::RunOnceCallback<2>(std::move(mojo_response)));
   auto request = CreateRequestMessage(kCreateMessageType);
-  request.SetStringKey(kCreateRequestDataKey, "dummy");
+  request.SetStringKey(kCreateRequestDataKey, "fake");
   SendMessage(std::move(request));
 
   const base::Value& response = ReadMessage();
 
   VerifyResponseMessage(response, kCreateMessageType);
-  ASSERT_EQ(*response.FindStringKey(kCreateResponseDataKey), "dummy response");
+  ASSERT_EQ(*response.FindStringKey(kCreateResponseDataKey), "fake response");
   ASSERT_EQ(response.FindStringKey(kCreateResponseErrorNameKey), nullptr);
 }
 
+TEST_F(RemoteWebAuthnNativeMessagingHostTest,
+       Cancel_IpcConnectionFailed_Failure) {
+  ExpectGetSessionServices(false);
+
+  SendMessage(CreateRequestMessage(kCancelMessageType));
+
+  const base::Value& response = ReadMessage();
+
+  VerifyResponseMessage(response, kCancelMessageType);
+  ASSERT_EQ(*response.FindBoolKey(kCancelResponseWasCanceledKey), false);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, Cancel_NonexistentId_Failure) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+
+  // No cancelable message with message_id = 1.
+  SendMessage(CreateRequestMessage(kCancelMessageType, /* message_id= */ 1));
+
+  const base::Value& response = ReadMessage();
+
+  VerifyResponseMessage(response, kCancelMessageType);
+  ASSERT_EQ(*response.FindBoolKey(kCancelResponseWasCanceledKey), false);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest, CancelCreateRequest) {
+  MockWebAuthnRequestCanceller mock_canceller_impl;
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+  mojo::Receiver<mojom::WebAuthnRequestCanceller> request_canceller{
+      &mock_canceller_impl};
+  mojom::WebAuthnProxy::CreateCallback create_cb;
+  base::RunLoop webauthn_proxy_create_runloop;
+  EXPECT_CALL(webauthn_proxy_, Create("fake", _, _))
+      .WillOnce([&](const std::string&,
+                    mojo::PendingReceiver<mojom::WebAuthnRequestCanceller>
+                        pending_receiver,
+                    mojom::WebAuthnProxy::CreateCallback cb) {
+        request_canceller.Bind(std::move(pending_receiver));
+        create_cb = std::move(cb);
+        webauthn_proxy_create_runloop.Quit();
+      });
+  EXPECT_CALL(mock_canceller_impl, Cancel(_))
+      .WillOnce(base::test::RunOnceCallback<0>(true));
+
+  auto request = CreateRequestMessage(kCreateMessageType, /* message_id= */ 1);
+  request.SetStringKey(kCreateRequestDataKey, "fake");
+  SendMessage(std::move(request));
+  webauthn_proxy_create_runloop.Run();
+
+  request = CreateRequestMessage(kCancelMessageType, /* message_id= */ 1);
+  SendMessage(std::move(request));
+  const base::Value& response_1 = ReadMessage();
+
+  VerifyResponseMessage(response_1, kCancelMessageType);
+  ASSERT_EQ(*response_1.FindBoolKey(kCancelResponseWasCanceledKey), true);
+
+  // Do it again and verify that it should fail this time.
+  request = CreateRequestMessage(kCancelMessageType, /* message_id= */ 1);
+  SendMessage(std::move(request));
+  const base::Value& response_2 = ReadMessage();
+
+  VerifyResponseMessage(response_2, kCancelMessageType);
+  ASSERT_EQ(*response_2.FindBoolKey(kCancelResponseWasCanceledKey), false);
+
+  // |create_cb| must be run before it gets disposed.
+  std::move(create_cb).Run(nullptr);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest,
+       CancelWithDisconnectedCanceller_Failure) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+  mojo::PendingReceiver<mojom::WebAuthnRequestCanceller> request_canceller;
+  mojom::WebAuthnProxy::CreateCallback create_cb;
+  base::RunLoop webauthn_proxy_create_runloop;
+  EXPECT_CALL(webauthn_proxy_, Create("fake", _, _))
+      .WillOnce([&](const std::string&,
+                    mojo::PendingReceiver<mojom::WebAuthnRequestCanceller>
+                        pending_receiver,
+                    mojom::WebAuthnProxy::CreateCallback cb) {
+        request_canceller = std::move(pending_receiver);
+        create_cb = std::move(cb);
+        webauthn_proxy_create_runloop.Quit();
+      });
+
+  auto request = CreateRequestMessage(kCreateMessageType, /* message_id= */ 1);
+  request.SetStringKey(kCreateRequestDataKey, "fake");
+  SendMessage(std::move(request));
+  webauthn_proxy_create_runloop.Run();
+
+  base::RunLoop request_canceller_disconnected_run_loop;
+  SetOnRequestCancellerDisconnectedSpy(
+      request_canceller_disconnected_run_loop.QuitClosure());
+  request_canceller.reset();
+  request_canceller_disconnected_run_loop.Run();
+
+  request = CreateRequestMessage(kCancelMessageType, /* message_id= */ 1);
+  SendMessage(std::move(request));
+  const base::Value& response = ReadMessage();
+  // |create_cb| must be run before it gets disposed.
+  std::move(create_cb).Run(nullptr);
+
+  VerifyResponseMessage(response, kCancelMessageType);
+  ASSERT_EQ(*response.FindBoolKey(kCancelResponseWasCanceledKey), false);
+}
+
+TEST_F(RemoteWebAuthnNativeMessagingHostTest,
+       CancelAlreadyRespondedRequest_Failure) {
+  ExpectGetSessionServices();
+  ExpectBindWebAuthnProxy();
+
+  EXPECT_CALL(webauthn_proxy_, Create("fake", _, _))
+      .WillOnce(base::test::RunOnceCallback<2>(nullptr));
+
+  auto request = CreateRequestMessage(kCreateMessageType, /* message_id= */ 1);
+  request.SetStringKey(kCreateRequestDataKey, "fake");
+  SendMessage(std::move(request));
+  const base::Value& response_1 = ReadMessage();
+  VerifyResponseMessage(response_1, kCreateMessageType);
+
+  SendMessage(CreateRequestMessage(kCancelMessageType, /* message_id= */ 1));
+  const base::Value& response_2 = ReadMessage();
+  VerifyResponseMessage(response_2, kCancelMessageType);
+  ASSERT_EQ(*response_2.FindBoolKey(kCancelResponseWasCanceledKey), false);
+}
+
 }  // namespace remoting
diff --git a/remoting/host/xmpp_register_support_host_request.cc b/remoting/host/xmpp_register_support_host_request.cc
index 6a756d5..a540952 100644
--- a/remoting/host/xmpp_register_support_host_request.cc
+++ b/remoting/host/xmpp_register_support_host_request.cc
@@ -22,8 +22,8 @@
 #include "remoting/signaling/signal_strategy.h"
 #include "remoting/signaling/signaling_address.h"
 #include "remoting/signaling/signaling_id_util.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 using jingle_xmpp::QName;
 using jingle_xmpp::XmlElement;
@@ -83,8 +83,7 @@
     // remoting bot JID.
     std::string host_jid = signal_strategy_->GetLocalAddress().id();
     request_ = iq_sender_->SendIq(
-        jingle_xmpp::STR_SET, directory_bot_jid_,
-        CreateRegistrationRequest(host_jid),
+        kIqTypeSet, directory_bot_jid_, CreateRegistrationRequest(host_jid),
         base::BindOnce(&XmppRegisterSupportHostRequest::ProcessResponse,
                        base::Unretained(this)));
     if (!request_) {
@@ -169,8 +168,8 @@
     return;
   }
 
-  std::string type = response->Attr(jingle_xmpp::QN_TYPE);
-  if (type == jingle_xmpp::STR_ERROR) {
+  std::string type = response->Attr(kQNameType);
+  if (type == kIqTypeError) {
     LOG(ERROR) << "Received error in response to heartbeat: "
                << response->Str();
     *error_code = ErrorCode::HOST_REGISTRATION_ERROR;
@@ -178,7 +177,7 @@
   }
 
   // This method must only be called for error or result stanzas.
-  if (type != jingle_xmpp::STR_RESULT) {
+  if (type != kIqTypeResult) {
     LOG(ERROR) << "Received unexpect stanza of type \"" << type << "\"";
     *error_code = ErrorCode::HOST_REGISTRATION_ERROR;
     return;
diff --git a/remoting/host/xmpp_register_support_host_request_unittest.cc b/remoting/host/xmpp_register_support_host_request_unittest.cc
index 357f7d4..fd0bee9 100644
--- a/remoting/host/xmpp_register_support_host_request_unittest.cc
+++ b/remoting/host/xmpp_register_support_host_request_unittest.cc
@@ -21,10 +21,10 @@
 #include "remoting/signaling/iq_sender.h"
 #include "remoting/signaling/mock_signal_strategy.h"
 #include "remoting/signaling/signaling_address.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 using jingle_xmpp::QName;
 using jingle_xmpp::XmlElement;
@@ -159,7 +159,7 @@
   // Generate response and verify that callback is called.
   EXPECT_CALL(callback_, Run(kSupportId, base::Seconds(300), ErrorCode::OK));
 
-  std::unique_ptr<XmlElement> response(new XmlElement(jingle_xmpp::QN_IQ));
+  std::unique_ptr<XmlElement> response(new XmlElement(kQNameIq));
   response->AddAttr(QName(std::string(), "from"), kTestBotJid);
   response->AddAttr(QName(std::string(), "type"), "result");
   response->AddAttr(QName(std::string(), "id"), kStanzaId);
diff --git a/remoting/proto/remote_webauthn.proto b/remoting/proto/remote_webauthn.proto
index 0d56f74..a7f460f0 100644
--- a/remoting/proto/remote_webauthn.proto
+++ b/remoting/proto/remote_webauthn.proto
@@ -10,7 +10,7 @@
 
 // Composite message type for messages sent over the remote-webauthn data
 // channel.
-// Next ID: 6
+// Next ID: 8
 message RemoteWebAuthn {
   // Requests the client to handle a call to
   // PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable().
@@ -44,7 +44,21 @@
     }
   }
 
-  // Unique ID used to multiplex requests.
+  // Requests the client to abort an ongoing Create or Get request.
+  // The |id| field of this message should be set to the same value as the
+  // to-be-canceled GetRequest/CreateRequest's |id| field.
+  message CancelRequest {}
+
+  // Response for CancelRequest.
+  // Next ID: 2
+  message CancelResponse {
+    // Boolean indicating whether the request has been successfully canceled.
+    // If this is true, no future CreateResponse/GetResponse will be delivered
+    // for the same |id|.
+    optional bool was_canceled = 1;
+  }
+
+  // ID used to multiplex requests.
   optional uint64 id = 1;
 
   oneof message {
@@ -53,5 +67,8 @@
 
     CreateRequest create_request = 4;
     CreateResponse create_response = 5;
+
+    CancelRequest cancel_request = 6;
+    CancelResponse cancel_response = 7;
   }
 }
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn
index 0cb3b3f..4c15088 100644
--- a/remoting/protocol/BUILD.gn
+++ b/remoting/protocol/BUILD.gn
@@ -431,6 +431,5 @@
     "//testing/gmock",
     "//testing/gtest",
     "//third_party/libjingle_xmpp:rtc_xmllite",
-    "//third_party/libjingle_xmpp:rtc_xmpp",
   ]
 }
diff --git a/remoting/protocol/jingle_messages_unittest.cc b/remoting/protocol/jingle_messages_unittest.cc
index a4b78a35..0251b59 100644
--- a/remoting/protocol/jingle_messages_unittest.cc
+++ b/remoting/protocol/jingle_messages_unittest.cc
@@ -9,10 +9,10 @@
 #include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "remoting/protocol/content_description.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 using jingle_xmpp::QName;
 using jingle_xmpp::XmlAttr;
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc
index 757f517..54606c0 100644
--- a/remoting/protocol/jingle_session.cc
+++ b/remoting/protocol/jingle_session.cc
@@ -26,8 +26,8 @@
 #include "remoting/protocol/session_plugin.h"
 #include "remoting/protocol/transport.h"
 #include "remoting/signaling/iq_sender.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 #include "third_party/webrtc/api/candidate.h"
 
 using jingle_xmpp::XmlElement;
@@ -349,7 +349,7 @@
   AddPluginAttachments(message.get());
 
   std::unique_ptr<jingle_xmpp::XmlElement> stanza = message->ToXml();
-  stanza->AddAttr(jingle_xmpp::QN_ID, GetNextOutgoingId());
+  stanza->AddAttr(kQNameId, GetNextOutgoingId());
 
   auto request = session_manager_->iq_sender()->SendIq(
       std::move(stanza), base::BindOnce(&JingleSession::OnTransportInfoResponse,
@@ -429,7 +429,7 @@
     AddPluginAttachments(message.get());
   }
   std::unique_ptr<jingle_xmpp::XmlElement> stanza = message->ToXml();
-  stanza->AddAttr(jingle_xmpp::QN_ID, GetNextOutgoingId());
+  stanza->AddAttr(kQNameId, GetNextOutgoingId());
 
   auto request = session_manager_->iq_sender()->SendIq(
       std::move(stanza),
diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc
index d5acae9..41141c8 100644
--- a/remoting/protocol/jingle_session_manager.cc
+++ b/remoting/protocol/jingle_session_manager.cc
@@ -14,8 +14,8 @@
 #include "remoting/protocol/transport.h"
 #include "remoting/signaling/iq_sender.h"
 #include "remoting/signaling/signal_strategy.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 #include "third_party/webrtc/rtc_base/socket_address.h"
 
 using jingle_xmpp::QName;
@@ -87,7 +87,7 @@
             signal_strategy_->GetLocalAddress().id(), message->from.id());
 
     JingleSession* session = new JingleSession(this);
-    session->InitializeIncomingConnection(stanza->Attr(jingle_xmpp::QN_ID), *message,
+    session->InitializeIncomingConnection(stanza->Attr(kQNameId), *message,
                                           std::move(authenticator));
     sessions_[session->session_id_] = session;
 
@@ -135,7 +135,7 @@
   }
 
   it->second->OnIncomingMessage(
-      stanza->Attr(jingle_xmpp::QN_ID), std::move(message),
+      stanza->Attr(kQNameId), std::move(message),
       base::BindOnce(&JingleSessionManager::SendReply, base::Unretained(this),
                      std::move(stanza_copy)));
   return true;
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc
index 4ae5f7d..fbc8190 100644
--- a/remoting/protocol/jingle_session_unittest.cc
+++ b/remoting/protocol/jingle_session_unittest.cc
@@ -31,9 +31,9 @@
 #include "remoting/protocol/transport.h"
 #include "remoting/protocol/transport_context.h"
 #include "remoting/signaling/fake_signal_strategy.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 using testing::_;
 using testing::AtLeast;
@@ -148,7 +148,7 @@
 std::unique_ptr<jingle_xmpp::XmlElement> CreateTransportInfo(const std::string& id) {
   std::unique_ptr<jingle_xmpp::XmlElement> result(
       jingle_xmpp::XmlElement::ForStr("<transport xmlns='google:remoting:ice'/>"));
-  result->AddAttr(jingle_xmpp::QN_ID, id);
+  result->AddAttr(kQNameId, id);
   return result;
 }
 
@@ -411,8 +411,8 @@
   base::RunLoop().RunUntilIdle();
 
   ASSERT_EQ(client_transport_.received_messages().size(), 2U);
-  EXPECT_EQ("1", client_transport_.received_messages()[0]->Attr(jingle_xmpp::QN_ID));
-  EXPECT_EQ("2", client_transport_.received_messages()[1]->Attr(jingle_xmpp::QN_ID));
+  EXPECT_EQ("1", client_transport_.received_messages()[0]->Attr(kQNameId));
+  EXPECT_EQ("2", client_transport_.received_messages()[1]->Attr(kQNameId));
 }
 
 // Verify that out-of-order messages are handled correctly when the session is
@@ -433,7 +433,7 @@
   base::RunLoop().RunUntilIdle();
 
   ASSERT_EQ(client_transport_.received_messages().size(), 1U);
-  EXPECT_EQ("1", client_transport_.received_messages()[0]->Attr(jingle_xmpp::QN_ID));
+  EXPECT_EQ("1", client_transport_.received_messages()[0]->Attr(kQNameId));
 }
 
 // Verify that connection is terminated when single-step auth fails.
@@ -591,7 +591,7 @@
   // Verify that transport-info that the first transport-info message was
   // received.
   ASSERT_EQ(client_transport_.received_messages().size(), 1U);
-  EXPECT_EQ("1", client_transport_.received_messages()[0]->Attr(jingle_xmpp::QN_ID));
+  EXPECT_EQ("1", client_transport_.received_messages()[0]->Attr(kQNameId));
 }
 
 TEST_F(JingleSessionTest, TestSessionPlugin) {
diff --git a/remoting/signaling/BUILD.gn b/remoting/signaling/BUILD.gn
index aa1c2e9..a1bd351 100644
--- a/remoting/signaling/BUILD.gn
+++ b/remoting/signaling/BUILD.gn
@@ -39,6 +39,8 @@
     "signaling_id_util.cc",
     "signaling_id_util.h",
     "signaling_tracker.h",
+    "xmpp_constants.cc",
+    "xmpp_constants.h",
     "xmpp_log_to_server.cc",
     "xmpp_log_to_server.h",
   ]
@@ -51,7 +53,7 @@
   public_deps = [
     "//remoting/proto",
     "//remoting/proto/remoting/v1:telemetry_messages",
-    "//third_party/libjingle_xmpp",
+    "//third_party/libjingle_xmpp:rtc_xmllite",
     "//third_party/webrtc_overrides:webrtc_component",
   ]
 
diff --git a/remoting/signaling/delegating_signal_strategy.cc b/remoting/signaling/delegating_signal_strategy.cc
index d142ef1..2f61447 100644
--- a/remoting/signaling/delegating_signal_strategy.cc
+++ b/remoting/signaling/delegating_signal_strategy.cc
@@ -10,8 +10,8 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 namespace remoting {
 
diff --git a/remoting/signaling/fake_signal_strategy.cc b/remoting/signaling/fake_signal_strategy.cc
index 09c091ca..35b25094 100644
--- a/remoting/signaling/fake_signal_strategy.cc
+++ b/remoting/signaling/fake_signal_strategy.cc
@@ -13,8 +13,8 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "remoting/signaling/signaling_id_util.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 namespace remoting {
 
diff --git a/remoting/signaling/ftl_signal_strategy.cc b/remoting/signaling/ftl_signal_strategy.cc
index 9029f3a0..bf47c266 100644
--- a/remoting/signaling/ftl_signal_strategy.cc
+++ b/remoting/signaling/ftl_signal_strategy.cc
@@ -22,9 +22,9 @@
 #include "remoting/signaling/ftl_messaging_client.h"
 #include "remoting/signaling/ftl_registration_manager.h"
 #include "remoting/signaling/signaling_address.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 namespace remoting {
 
@@ -201,9 +201,9 @@
   DCHECK(to_error.empty());
 
   // Synthesizing the from attribute in the message.
-  stanza->SetAttr(jingle_xmpp::QN_FROM, local_address_.id());
+  stanza->SetAttr(kQNameFrom, local_address_.id());
 
-  std::string stanza_id = stanza->Attr(jingle_xmpp::QN_ID);
+  std::string stanza_id = stanza->Attr(kQNameId);
 
   ftl::ChromotingMessage crd_message;
   crd_message.mutable_xmpp()->set_stanza(stanza->Str());
@@ -404,11 +404,11 @@
   }
 
   // Fake an error message so JingleSession will take it as PEER_IS_OFFLINE.
-  auto error_iq = std::make_unique<jingle_xmpp::XmlElement>(jingle_xmpp::QN_IQ);
-  error_iq->SetAttr(jingle_xmpp::QN_TYPE, jingle_xmpp::STR_ERROR);
-  error_iq->SetAttr(jingle_xmpp::QN_ID, stanza_id);
-  error_iq->SetAttr(jingle_xmpp::QN_FROM, receiver.id());
-  error_iq->SetAttr(jingle_xmpp::QN_TO, local_address_.id());
+  auto error_iq = std::make_unique<jingle_xmpp::XmlElement>(kQNameIq);
+  error_iq->SetAttr(kQNameType, kIqTypeError);
+  error_iq->SetAttr(kQNameId, stanza_id);
+  error_iq->SetAttr(kQNameFrom, receiver.id());
+  error_iq->SetAttr(kQNameTo, local_address_.id());
   OnStanza(receiver, std::move(error_iq));
 }
 
@@ -441,18 +441,18 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // Validate the schema and FTL IDs.
-  if (stanza->Name() != jingle_xmpp::QN_IQ) {
+  if (stanza->Name() != kQNameIq) {
     LOG(DFATAL) << "Received unexpected non-IQ packet " << stanza->Str();
     return;
   }
-  if (SignalingAddress(stanza->Attr(jingle_xmpp::QN_FROM)) != sender_address) {
+  if (SignalingAddress(stanza->Attr(kQNameFrom)) != sender_address) {
     LOG(DFATAL) << "Expected sender: " << sender_address.id()
-                << ", but received: " << stanza->Attr(jingle_xmpp::QN_FROM);
+                << ", but received: " << stanza->Attr(kQNameFrom);
     return;
   }
-  if (SignalingAddress(stanza->Attr(jingle_xmpp::QN_TO)) != local_address_) {
+  if (SignalingAddress(stanza->Attr(kQNameTo)) != local_address_) {
     LOG(DFATAL) << "Expected receiver: " << local_address_.id()
-                << ", but received: " << stanza->Attr(jingle_xmpp::QN_TO);
+                << ", but received: " << stanza->Attr(kQNameTo);
     return;
   }
 
diff --git a/remoting/signaling/ftl_signal_strategy_unittest.cc b/remoting/signaling/ftl_signal_strategy_unittest.cc
index 967b898b1..7e0545a 100644
--- a/remoting/signaling/ftl_signal_strategy_unittest.cc
+++ b/remoting/signaling/ftl_signal_strategy_unittest.cc
@@ -19,10 +19,10 @@
 #include "remoting/signaling/messaging_client.h"
 #include "remoting/signaling/registration_manager.h"
 #include "remoting/signaling/signaling_address.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 namespace remoting {
 
@@ -60,13 +60,13 @@
       "</iq>";
   auto stanza = base::WrapUnique<jingle_xmpp::XmlElement>(
       jingle_xmpp::XmlElement::ForStr(kStanzaTemplate));
-  stanza->SetAttr(jingle_xmpp::QN_ID, id);
+  stanza->SetAttr(kQNameId, id);
   if (direction == Direction::OUTGOING) {
-    stanza->SetAttr(jingle_xmpp::QN_FROM, kFakeLocalFtlId);
-    stanza->SetAttr(jingle_xmpp::QN_TO, kFakeRemoteFtlId);
+    stanza->SetAttr(kQNameFrom, kFakeLocalFtlId);
+    stanza->SetAttr(kQNameTo, kFakeRemoteFtlId);
   } else {
-    stanza->SetAttr(jingle_xmpp::QN_FROM, kFakeRemoteFtlId);
-    stanza->SetAttr(jingle_xmpp::QN_TO, kFakeLocalFtlId);
+    stanza->SetAttr(kQNameFrom, kFakeRemoteFtlId);
+    stanza->SetAttr(kQNameTo, kFakeLocalFtlId);
   }
   return stanza;
 }
@@ -435,10 +435,10 @@
 
   ASSERT_EQ(1u, received_messages_.size());
   auto& error_message = received_messages_[0];
-  ASSERT_EQ(jingle_xmpp::STR_ERROR, error_message->Attr(jingle_xmpp::QN_TYPE));
-  ASSERT_EQ(stanza_id, error_message->Attr(jingle_xmpp::QN_ID));
-  ASSERT_EQ(kFakeRemoteFtlId, error_message->Attr(jingle_xmpp::QN_FROM));
-  ASSERT_EQ(kFakeLocalFtlId, error_message->Attr(jingle_xmpp::QN_TO));
+  ASSERT_EQ(kIqTypeError, error_message->Attr(kQNameType));
+  ASSERT_EQ(stanza_id, error_message->Attr(kQNameId));
+  ASSERT_EQ(kFakeRemoteFtlId, error_message->Attr(kQNameFrom));
+  ASSERT_EQ(kFakeLocalFtlId, error_message->Attr(kQNameTo));
 }
 
 TEST_F(FtlSignalStrategyTest, ReceiveStanza_Success) {
diff --git a/remoting/signaling/iq_sender.cc b/remoting/signaling/iq_sender.cc
index 329bdd0..9262918 100644
--- a/remoting/signaling/iq_sender.cc
+++ b/remoting/signaling/iq_sender.cc
@@ -16,8 +16,8 @@
 #include "base/time/time.h"
 #include "remoting/signaling/signal_strategy.h"
 #include "remoting/signaling/signaling_id_util.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 namespace remoting {
 
@@ -26,10 +26,11 @@
     const std::string& type,
     const std::string& addressee,
     std::unique_ptr<jingle_xmpp::XmlElement> iq_body) {
-  std::unique_ptr<jingle_xmpp::XmlElement> stanza(new jingle_xmpp::XmlElement(jingle_xmpp::QN_IQ));
-  stanza->AddAttr(jingle_xmpp::QN_TYPE, type);
+  std::unique_ptr<jingle_xmpp::XmlElement> stanza(
+      new jingle_xmpp::XmlElement(kQNameIq));
+  stanza->AddAttr(kQNameType, type);
   if (!addressee.empty())
-    stanza->AddAttr(jingle_xmpp::QN_TO, addressee);
+    stanza->AddAttr(kQNameTo, addressee);
   stanza->AddElement(iq_body.release());
   return stanza;
 }
@@ -46,11 +47,11 @@
 std::unique_ptr<IqRequest> IqSender::SendIq(
     std::unique_ptr<jingle_xmpp::XmlElement> stanza,
     ReplyCallback callback) {
-  std::string addressee = stanza->Attr(jingle_xmpp::QN_TO);
-  std::string id = stanza->Attr(jingle_xmpp::QN_ID);
+  std::string addressee = stanza->Attr(kQNameTo);
+  std::string id = stanza->Attr(kQNameId);
   if (id.empty()) {
     id = signal_strategy_->GetNextId();
-    stanza->AddAttr(jingle_xmpp::QN_ID, id);
+    stanza->AddAttr(kQNameId, id);
   }
   if (!signal_strategy_->SendStanza(std::move(stanza))) {
     return nullptr;
@@ -89,12 +90,12 @@
 }
 
 bool IqSender::OnSignalStrategyIncomingStanza(const jingle_xmpp::XmlElement* stanza) {
-  if (stanza->Name() != jingle_xmpp::QN_IQ) {
+  if (stanza->Name() != kQNameIq) {
     LOG(WARNING) << "Received unexpected non-IQ packet " << stanza->Str();
     return false;
   }
 
-  const std::string& type = stanza->Attr(jingle_xmpp::QN_TYPE);
+  const std::string& type = stanza->Attr(kQNameType);
   if (type.empty()) {
     LOG(WARNING) << "IQ packet missing type " << stanza->Str();
     return false;
@@ -104,13 +105,13 @@
     return false;
   }
 
-  const std::string& id = stanza->Attr(jingle_xmpp::QN_ID);
+  const std::string& id = stanza->Attr(kQNameId);
   if (id.empty()) {
     LOG(WARNING) << "IQ packet missing id " << stanza->Str();
     return false;
   }
 
-  std::string from = stanza->Attr(jingle_xmpp::QN_FROM);
+  std::string from = stanza->Attr(kQNameFrom);
 
   auto it = requests_.find(id);
   if (it == requests_.end()) {
diff --git a/remoting/signaling/iq_sender_unittest.cc b/remoting/signaling/iq_sender_unittest.cc
index 2a35ce0..0234e651 100644
--- a/remoting/signaling/iq_sender_unittest.cc
+++ b/remoting/signaling/iq_sender_unittest.cc
@@ -14,10 +14,10 @@
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
 #include "remoting/signaling/mock_signal_strategy.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 using ::testing::_;
 using ::testing::DeleteArg;
@@ -81,7 +81,7 @@
 
   bool FormatAndDeliverResponse(const std::string& from,
                                 std::unique_ptr<XmlElement>* response_out) {
-    std::unique_ptr<XmlElement> response(new XmlElement(jingle_xmpp::QN_IQ));
+    std::unique_ptr<XmlElement> response(new XmlElement(kQNameIq));
     response->AddAttr(QName(std::string(), "type"), "result");
     response->AddAttr(QName(std::string(), "id"), kStanzaId);
     response->AddAttr(QName(std::string(), "from"), from);
diff --git a/remoting/signaling/xmpp_constants.cc b/remoting/signaling/xmpp_constants.cc
new file mode 100644
index 0000000..08ba867d
--- /dev/null
+++ b/remoting/signaling/xmpp_constants.cc
@@ -0,0 +1,19 @@
+// Copyright 2022 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 "remoting/signaling/xmpp_constants.h"
+
+namespace remoting {
+
+const char kIqTypeSet[] = "set";
+const char kIqTypeResult[] = "result";
+const char kIqTypeError[] = "error";
+
+const jingle_xmpp::StaticQName kQNameIq = {"jabber:client", "iq"};
+const jingle_xmpp::StaticQName kQNameId = {"", "id"};
+const jingle_xmpp::StaticQName kQNameType = {"", "type"};
+const jingle_xmpp::StaticQName kQNameTo = {"", "to"};
+const jingle_xmpp::StaticQName kQNameFrom = {"", "from"};
+
+}  // namespace remoting
diff --git a/remoting/signaling/xmpp_constants.h b/remoting/signaling/xmpp_constants.h
new file mode 100644
index 0000000..83cf3da4
--- /dev/null
+++ b/remoting/signaling/xmpp_constants.h
@@ -0,0 +1,27 @@
+// Copyright 2022 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.
+//
+// Contains constants for the IQ stanzas inherited by the signaling protocol
+// from XMPP.
+
+#ifndef REMOTING_SIGNALING_XMPP_CONSTANTS_H_
+#define REMOTING_SIGNALING_XMPP_CONSTANTS_H_
+
+#include "third_party/libjingle_xmpp/xmllite/qname.h"
+
+namespace remoting {
+
+extern const char kIqTypeSet[];
+extern const char kIqTypeResult[];
+extern const char kIqTypeError[];
+
+extern const jingle_xmpp::StaticQName kQNameIq;
+extern const jingle_xmpp::StaticQName kQNameId;
+extern const jingle_xmpp::StaticQName kQNameType;
+extern const jingle_xmpp::StaticQName kQNameTo;
+extern const jingle_xmpp::StaticQName kQNameFrom;
+
+}  // namespace remoting
+
+#endif  // REMOTING_SIGNALING_XMPP_CONSTANTS_H_
diff --git a/remoting/signaling/xmpp_log_to_server.cc b/remoting/signaling/xmpp_log_to_server.cc
index 8f65b6c..f5fc3cd 100644
--- a/remoting/signaling/xmpp_log_to_server.cc
+++ b/remoting/signaling/xmpp_log_to_server.cc
@@ -11,8 +11,8 @@
 #include "remoting/base/constants.h"
 #include "remoting/signaling/iq_sender.h"
 #include "remoting/signaling/signal_strategy.h"
+#include "remoting/signaling/xmpp_constants.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
 
 using jingle_xmpp::QName;
 using jingle_xmpp::XmlElement;
@@ -83,8 +83,8 @@
     pending_entries_.pop_front();
   }
   // Send the stanza to the server and ignore the response.
-  iq_sender_->SendIq(jingle_xmpp::STR_SET, directory_bot_jid_,
-                     std::move(stanza), IqSender::ReplyCallback());
+  iq_sender_->SendIq(kIqTypeSet, directory_bot_jid_, std::move(stanza),
+                     IqSender::ReplyCallback());
 }
 
 ServerLogEntry::Mode XmppLogToServer::mode() const {
diff --git a/services/network/first_party_sets/first_party_sets.cc b/services/network/first_party_sets/first_party_sets.cc
index 5db5533d4..49a089f8 100644
--- a/services/network/first_party_sets/first_party_sets.cc
+++ b/services/network/first_party_sets/first_party_sets.cc
@@ -104,11 +104,13 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!enabled_ || component_sets_parse_progress_ != Progress::kNotStarted) {
     if (sets_file.IsValid()) {
-      auto delete_file =
-          base::BindOnce([](base::File) {}, std::move(sets_file));
       base::ThreadPool::PostTask(
           FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-          std::move(delete_file));
+          base::BindOnce(
+              [](base::File sets_file) {
+                // Run `sets_file`'s dtor in the threadpool.
+              },
+              std::move(sets_file)));
     }
     return;
   }
diff --git a/services/network/public/cpp/cross_origin_opener_policy.cc b/services/network/public/cpp/cross_origin_opener_policy.cc
index 002282f..652fcda 100644
--- a/services/network/public/cpp/cross_origin_opener_policy.cc
+++ b/services/network/public/cpp/cross_origin_opener_policy.cc
@@ -60,7 +60,8 @@
 
 // [spec]: https://html.spec.whatwg.org/C/#obtain-coop
 void AugmentCoopWithCoep(CrossOriginOpenerPolicy* coop,
-                         const CrossOriginEmbedderPolicy& coep) {
+                         const CrossOriginEmbedderPolicy& coep,
+                         bool is_coop_soap_plus_coep_enabled) {
   // COOP:
   //
   // [spec]: 4.1.2. If coep's value is compatible with cross-origin isolation,
@@ -70,6 +71,15 @@
     coop->value = mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep;
   }
 
+  // COOP: SOAPPC case.
+  if (is_coop_soap_plus_coep_enabled &&
+      coop->value ==
+          mojom::CrossOriginOpenerPolicyValue::kSameOriginAllowPopups &&
+      CompatibleWithCrossOriginIsolated(coep.value)) {
+    coop->value =
+        mojom::CrossOriginOpenerPolicyValue::kSameOriginAllowPopupsPlusCoep;
+  }
+
   // COOP: SOAP by default
   if (coop->soap_by_default_value ==
           mojom::CrossOriginOpenerPolicyValue::kSameOrigin &&
@@ -78,6 +88,15 @@
         mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep;
   }
 
+  // COOP: SOAP by default SOAPPC case.
+  if (is_coop_soap_plus_coep_enabled &&
+      coop->soap_by_default_value ==
+          mojom::CrossOriginOpenerPolicyValue::kSameOriginAllowPopups &&
+      CompatibleWithCrossOriginIsolated(coep.value)) {
+    coop->soap_by_default_value =
+        mojom::CrossOriginOpenerPolicyValue::kSameOriginAllowPopupsPlusCoep;
+  }
+
   // COOP-Report-Only:
   //
   // [spec]: 6.1.2. If coep's value is compatible with cross-origin isolation or
@@ -90,6 +109,16 @@
     coop->report_only_value =
         mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep;
   }
+
+  // COOP-Report-Only: SOAPPC case.
+  if (is_coop_soap_plus_coep_enabled &&
+      coop->report_only_value ==
+          mojom::CrossOriginOpenerPolicyValue::kSameOriginAllowPopups &&
+      (CompatibleWithCrossOriginIsolated(coep.value) ||
+       CompatibleWithCrossOriginIsolated(coep.report_only_value))) {
+    coop->report_only_value =
+        mojom::CrossOriginOpenerPolicyValue::kSameOriginAllowPopupsPlusCoep;
+  }
 }
 
 }  // namespace network
diff --git a/services/network/public/cpp/cross_origin_opener_policy.h b/services/network/public/cpp/cross_origin_opener_policy.h
index 97a808b..7dd3b6de 100644
--- a/services/network/public/cpp/cross_origin_opener_policy.h
+++ b/services/network/public/cpp/cross_origin_opener_policy.h
@@ -43,7 +43,8 @@
 
 COMPONENT_EXPORT(NETWORK_CPP_BASE)
 void AugmentCoopWithCoep(CrossOriginOpenerPolicy* coop,
-                         const CrossOriginEmbedderPolicy& coep);
+                         const CrossOriginEmbedderPolicy& coep,
+                         bool is_coop_soap_plus_coep_enabled);
 
 }  // namespace network
 
diff --git a/services/network/public/cpp/cross_origin_opener_policy_parser_unittest.cc b/services/network/public/cpp/cross_origin_opener_policy_parser_unittest.cc
index 32cab2e..f1adce4 100644
--- a/services/network/public/cpp/cross_origin_opener_policy_parser_unittest.cc
+++ b/services/network/public/cpp/cross_origin_opener_policy_parser_unittest.cc
@@ -16,10 +16,20 @@
 
 namespace network {
 
-TEST(CrossOriginOpenerPolicyTest, Parse) {
+class CrossOriginOpenerPolicyTest : public ::testing::Test,
+                                    public ::testing::WithParamInterface<bool> {
+};
+
+TEST_P(CrossOriginOpenerPolicyTest, Parse) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(features::kCrossOriginOpenerPolicy);
 
+  // This allows us to test COOP: Same-Origin-Allow-Popups-Plus-Coep.
+  // The feature is currently off by default, but is passed to
+  // AugmentCoopWithCoep through a boolean, which is simulated here.
+  // See https://crbug.com/1221127 for details on the feature.
+  bool is_coop_soap_plus_coep_enabled = GetParam();
+
   using mojom::CrossOriginOpenerPolicyValue;
   constexpr auto kSameOrigin = CrossOriginOpenerPolicyValue::kSameOrigin;
   constexpr auto kSameOriginAllowPopups =
@@ -27,6 +37,10 @@
   constexpr auto kUnsafeNone = CrossOriginOpenerPolicyValue::kUnsafeNone;
   constexpr auto kSameOriginPlusCoep =
       CrossOriginOpenerPolicyValue::kSameOriginPlusCoep;
+  auto kSameOriginAllowPopupsPlusCoepIfEnabled =
+      is_coop_soap_plus_coep_enabled
+          ? CrossOriginOpenerPolicyValue::kSameOriginAllowPopupsPlusCoep
+          : CrossOriginOpenerPolicyValue::kSameOriginAllowPopups;
   constexpr auto kCoepNone = mojom::CrossOriginEmbedderPolicyValue::kNone;
   constexpr auto kCoepCorp =
       mojom::CrossOriginEmbedderPolicyValue::kRequireCorp;
@@ -42,7 +56,7 @@
     absl::optional<std::string> expected_endpoint;
     CrossOriginOpenerPolicyValue expected_policy;
     CrossOriginOpenerPolicyValue expected_soap_by_default_policy;
-    absl::optional<std::string> expected_endpoit_report_only;
+    absl::optional<std::string> expected_endpoint_report_only;
     CrossOriginOpenerPolicyValue expected_policy_report_only;
   } kTestCases[] = {
       {"same-origin", kCoepNone, kNoHeader, kCoepNone, kNoEndpoint, kSameOrigin,
@@ -174,21 +188,32 @@
       // Same-origin with COEP
       {"same-origin", kCoepCorp, kNoHeader, kCoepNone, kNoEndpoint,
        kSameOriginPlusCoep, kSameOriginPlusCoep, kNoEndpoint, kUnsafeNone},
-      // Same-origin-allow-popups with COEP
-      {"same-origin-allow-popups", kCoepCorp, kNoHeader, kCoepNone, kNoEndpoint,
-       kSameOriginAllowPopups, kSameOriginAllowPopups, kNoEndpoint,
-       kUnsafeNone},
       // Same-origin with report only COEP
       {"same-origin", kCoepNone, kNoHeader, kCoepCorp, kNoEndpoint, kSameOrigin,
-       kSameOrigin,
-
-       kNoEndpoint, kUnsafeNone},
+       kSameOrigin, kNoEndpoint, kUnsafeNone},
       // reporting Same-origin with COEP
       {kNoHeader, kCoepCorp, "same-origin", kCoepNone, kNoEndpoint, kUnsafeNone,
-       kSameOriginAllowPopups, kNoEndpoint, kSameOriginPlusCoep},
+       kSameOriginAllowPopupsPlusCoepIfEnabled, kNoEndpoint,
+       kSameOriginPlusCoep},
       // reporting Same-origin with reporting COEP
       {kNoHeader, kCoepNone, "same-origin", kCoepCorp, kNoEndpoint, kUnsafeNone,
        kSameOriginAllowPopups, kNoEndpoint, kSameOriginPlusCoep},
+      // Same-origin-allow-popups with COEP
+      {"same-origin-allow-popups", kCoepCorp, kNoHeader, kCoepNone, kNoEndpoint,
+       kSameOriginAllowPopupsPlusCoepIfEnabled,
+       kSameOriginAllowPopupsPlusCoepIfEnabled, kNoEndpoint, kUnsafeNone},
+      // Same-origin-allow-popups with report only COEP
+      {"same-origin-allow-popups", kCoepNone, kNoHeader, kCoepCorp, kNoEndpoint,
+       kSameOriginAllowPopups, kSameOriginAllowPopups, kNoEndpoint,
+       kUnsafeNone},
+      // reporting Same-origin-allow-popups with COEP
+      {kNoHeader, kCoepCorp, "same-origin-allow-popups", kCoepNone, kNoEndpoint,
+       kUnsafeNone, kSameOriginAllowPopupsPlusCoepIfEnabled, kNoEndpoint,
+       kSameOriginAllowPopupsPlusCoepIfEnabled},
+      // reporting Same-origin-allow-popups with reporting COEP
+      {kNoHeader, kCoepNone, "same-origin-allow-popups", kCoepCorp, kNoEndpoint,
+       kUnsafeNone, kSameOriginAllowPopups, kNoEndpoint,
+       kSameOriginAllowPopupsPlusCoepIfEnabled},
   };
 
   for (const auto& test_case : kTestCases) {
@@ -219,18 +244,20 @@
     network::CrossOriginEmbedderPolicy coep;
     coep.value = test_case.coep_value;
     coep.report_only_value = test_case.coep_report_only_value;
-    AugmentCoopWithCoep(&coop, coep);
+    AugmentCoopWithCoep(&coop, coep, is_coop_soap_plus_coep_enabled);
 
     EXPECT_EQ(test_case.expected_endpoint, coop.reporting_endpoint);
     EXPECT_EQ(test_case.expected_policy, coop.value);
     EXPECT_EQ(test_case.expected_soap_by_default_policy,
               coop.soap_by_default_value);
-    EXPECT_EQ(test_case.expected_endpoit_report_only,
+    EXPECT_EQ(test_case.expected_endpoint_report_only,
               coop.report_only_reporting_endpoint);
     EXPECT_EQ(test_case.expected_policy_report_only, coop.report_only_value);
   }
 }
 
+INSTANTIATE_TEST_SUITE_P(All, CrossOriginOpenerPolicyTest, testing::Bool());
+
 TEST(CrossOriginOpenerPolicyTest, Default) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(features::kCrossOriginOpenerPolicy);
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index ae5b94d..4153beb 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -99,6 +99,13 @@
 const base::Feature kCrossOriginOpenerPolicyByDefault{
     "CrossOriginOpenerPolicyByDefault", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Introduce a new COOP value, Same-Origin-Opener-Policy-Plus-Coep, which grants
+// cross-origin isolation. This used mainly for testing the process model and
+// should not be enabled in any production code.
+// See https://crbug.com/1221127.
+const base::Feature kCoopSameOriginAllowPopupsPlusCoep{
+    "CoopSameOriginAllowPopupsPlusCoep", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables or defaults splittup up server (not proxy) entries in the
 // HttpAuthCache.
 const base::Feature kSplitAuthCacheByNetworkIsolationKey{
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index 3abf8ae..54e510c 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -37,6 +37,8 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kCrossOriginOpenerPolicyByDefault;
 COMPONENT_EXPORT(NETWORK_CPP)
+extern const base::Feature kCoopSameOriginAllowPopupsPlusCoep;
+COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kSplitAuthCacheByNetworkIsolationKey;
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kDnsOverHttpsUpgrade;
diff --git a/services/network/public/mojom/cross_origin_opener_policy.mojom b/services/network/public/mojom/cross_origin_opener_policy.mojom
index 4a103c4cd..b2a8320 100644
--- a/services/network/public/mojom/cross_origin_opener_policy.mojom
+++ b/services/network/public/mojom/cross_origin_opener_policy.mojom
@@ -66,6 +66,10 @@
 
   // Same origin with Cross-Origin-Embedder-Policy: require-corp.
   kSameOriginPlusCoep,
+
+  // Same origin allow popups with Cross-Origin-Embedder-Policy: require-corp.
+  // Reserved for testing only at this stage. See https://crbug.com/1221127.
+  kSameOriginAllowPopupsPlusCoep,
 };
 
 // Cross-Origin-Opener-Policy enum representing parsed values.
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc
index 4feffe9..ef36928d 100644
--- a/storage/browser/quota/quota_database.cc
+++ b/storage/browser/quota/quota_database.cc
@@ -571,26 +571,6 @@
   return QuotaError::kNone;
 }
 
-QuotaError QuotaDatabase::DeleteStorageKeyInfo(const StorageKey& storage_key,
-                                               StorageType type) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound);
-  if (open_error != QuotaError::kNone)
-    return open_error;
-
-  static constexpr char kSql[] =
-      "DELETE FROM buckets WHERE storage_key = ? AND type = ?";
-  sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
-  statement.BindString(0, storage_key.Serialize());
-  statement.BindInt(1, static_cast<int>(type));
-
-  if (!statement.Run())
-    return QuotaError::kDatabaseError;
-
-  ScheduleCommit();
-  return QuotaError::kNone;
-}
-
 QuotaError QuotaDatabase::DeleteBucketInfo(BucketId bucket_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!bucket_id.is_null());
diff --git a/storage/browser/quota/quota_database.h b/storage/browser/quota/quota_database.h
index d500962..686d896 100644
--- a/storage/browser/quota/quota_database.h
+++ b/storage/browser/quota/quota_database.h
@@ -188,10 +188,6 @@
   // QuotaError if not found or the operation has failed.
   QuotaErrorOr<BucketTableEntry> GetBucketInfo(BucketId bucket_id);
 
-  // Removes all buckets for `storage_key` with `type`.
-  QuotaError DeleteStorageKeyInfo(const blink::StorageKey& storage_key,
-                                  blink::mojom::StorageType type);
-
   // Deletes the specified bucket. This method is virtual for testing.
   virtual QuotaError DeleteBucketInfo(BucketId bucket_id);
 
diff --git a/storage/browser/quota/quota_database_unittest.cc b/storage/browser/quota/quota_database_unittest.cc
index 9a5870a..cd46cd79 100644
--- a/storage/browser/quota/quota_database_unittest.cc
+++ b/storage/browser/quota/quota_database_unittest.cc
@@ -480,40 +480,6 @@
 }
 #endif  // !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN)
 
-TEST_P(QuotaDatabaseTest, DeleteStorageKeyInfo) {
-  QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath());
-  EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound));
-
-  const StorageKey storage_key =
-      StorageKey::CreateFromStringForTesting("http://example-a/");
-  QuotaErrorOr<BucketInfo> temp_bucket1 =
-      db.CreateBucketForTesting(storage_key, "temp1", kTemp);
-  QuotaErrorOr<BucketInfo> temp_bucket2 =
-      db.CreateBucketForTesting(storage_key, "temp2", kTemp);
-  QuotaErrorOr<BucketInfo> perm_bucket =
-      db.CreateBucketForTesting(storage_key, "perm", kPerm);
-
-  db.DeleteStorageKeyInfo(storage_key, kTemp);
-
-  QuotaErrorOr<BucketInfo> result =
-      db.GetBucket(storage_key, temp_bucket1->name, kTemp);
-  ASSERT_FALSE(result.ok());
-  ASSERT_EQ(result.error(), QuotaError::kNotFound);
-
-  result = db.GetBucket(storage_key, temp_bucket2->name, kTemp);
-  ASSERT_FALSE(result.ok());
-  ASSERT_EQ(result.error(), QuotaError::kNotFound);
-
-  result = db.GetBucket(storage_key, perm_bucket->name, kPerm);
-  ASSERT_TRUE(result.ok());
-
-  db.DeleteStorageKeyInfo(storage_key, kPerm);
-
-  result = db.GetBucket(storage_key, perm_bucket->name, kPerm);
-  ASSERT_FALSE(result.ok());
-  ASSERT_EQ(result.error(), QuotaError::kNotFound);
-}
-
 TEST_P(QuotaDatabaseTest, SetStorageKeyLastModifiedTime) {
   QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath());
   EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound));
diff --git a/storage/browser/quota/quota_manager_impl.cc b/storage/browser/quota/quota_manager_impl.cc
index 9db6985..f6c6097 100644
--- a/storage/browser/quota/quota_manager_impl.cc
+++ b/storage/browser/quota/quota_manager_impl.cc
@@ -199,13 +199,6 @@
   return database->GetLRUBucket(type, bucket_exceptions, policy);
 }
 
-QuotaError DeleteStorageKeyInfoOnDBThread(const StorageKey& storage_key,
-                                          StorageType type,
-                                          QuotaDatabase* database) {
-  DCHECK(database);
-  return database->DeleteStorageKeyInfo(storage_key, type);
-}
-
 QuotaError DeleteBucketInfoOnDBThread(BucketId bucket_id,
                                       QuotaDatabase* database) {
   DCHECK(database);
@@ -714,99 +707,6 @@
       GUARDED_BY_CONTEXT(sequence_checker_){this};
 };
 
-// Calls each QuotaClient for `quota_client_types` to delete `storage_key` data.
-// If `storage_key` is delete for all registered client types, and there are no
-// deletion errors, StorageKeyDataDeleter will call to delete `storage_key` from
-// QuotaDatabase. It will return QuotaStatusCode::kOk to the `callback` on
-// success and will finish by making a call to delete itself.
-class QuotaManagerImpl::StorageKeyDataDeleter : public QuotaTask {
- public:
-  StorageKeyDataDeleter(QuotaManagerImpl* manager,
-                        const StorageKey& storage_key,
-                        StorageType type,
-                        QuotaClientTypes quota_client_types,
-                        StatusCallback callback)
-      : QuotaTask(manager),
-        storage_key_(storage_key),
-        type_(type),
-        quota_client_types_(std::move(quota_client_types)),
-        callback_(std::move(callback)) {}
-
- protected:
-  void Run() override {
-    DCHECK(manager()->client_types_.contains(type_));
-    remaining_clients_ = manager()->client_types_[type_].size();
-
-    for (const auto& client_and_type : manager()->client_types_[type_]) {
-      mojom::QuotaClient* client = client_and_type.first;
-      QuotaClientType client_type = client_and_type.second;
-      if (quota_client_types_.contains(client_type)) {
-        static int tracing_id = 0;
-        TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
-            "browsing_data", "QuotaManagerImpl::StorageKeyDataDeleter",
-            ++tracing_id, "client_type", client_type, "storage_key",
-            storage_key_.Serialize());
-        client->DeleteStorageKeyData(
-            storage_key_, type_,
-            base::BindOnce(&StorageKeyDataDeleter::DidDeleteStorageKeyData,
-                           weak_factory_.GetWeakPtr(), tracing_id));
-      } else {
-        ++skipped_clients_;
-        --remaining_clients_;
-      }
-    }
-
-    if (remaining_clients_ == 0)
-      CallCompleted();
-  }
-
-  void Completed() override {
-    if (error_count_ == 0) {
-      // Only remove the entire storage key if we didn't skip any client types.
-      if (skipped_clients_ == 0)
-        manager()->DeleteStorageKeyFromDatabase(storage_key_, type_);
-      std::move(callback_).Run(blink::mojom::QuotaStatusCode::kOk);
-    } else {
-      std::move(callback_).Run(
-          blink::mojom::QuotaStatusCode::kErrorInvalidModification);
-    }
-    DeleteSoon();
-  }
-
-  void Aborted() override {
-    std::move(callback_).Run(blink::mojom::QuotaStatusCode::kErrorAbort);
-    DeleteSoon();
-  }
-
- private:
-  void DidDeleteStorageKeyData(int tracing_id,
-                               blink::mojom::QuotaStatusCode status) {
-    DCHECK_GT(remaining_clients_, 0U);
-    TRACE_EVENT_NESTABLE_ASYNC_END0(
-        "browsing_data", "QuotaManagerImpl::StorageKeyDataDeleter", tracing_id);
-
-    if (status != blink::mojom::QuotaStatusCode::kOk)
-      ++error_count_;
-
-    if (--remaining_clients_ == 0)
-      CallCompleted();
-  }
-
-  QuotaManagerImpl* manager() const {
-    return static_cast<QuotaManagerImpl*>(observer());
-  }
-
-  const StorageKey storage_key_;
-  const StorageType type_;
-  const QuotaClientTypes quota_client_types_;
-  int error_count_ = 0;
-  size_t remaining_clients_ = 0;
-  int skipped_clients_ = 0;
-  StatusCallback callback_;
-
-  base::WeakPtrFactory<StorageKeyDataDeleter> weak_factory_{this};
-};
-
 // Calls QuotaClients in `quota_client_types` for the `bucket` to delete bucket
 // data. Will delete bucket entries from the QuotaDatabase if bucket data has
 // been successfully deleted from all registered QuotaClient.
@@ -817,11 +717,12 @@
 // non-default buckets when QuotaClient is migrated to operate on buckets.
 class QuotaManagerImpl::BucketDataDeleter {
  public:
-  BucketDataDeleter(QuotaManagerImpl* manager,
-                    const BucketLocator& bucket,
-                    QuotaClientTypes quota_client_types,
-                    StatusCallback callback,
-                    base::OnceClosure completion_closure)
+  BucketDataDeleter(
+      QuotaManagerImpl* manager,
+      const BucketLocator& bucket,
+      QuotaClientTypes quota_client_types,
+      StatusCallback callback,
+      base::OnceCallback<void(BucketDataDeleter*)> completion_closure)
       : manager_(manager),
         bucket_(bucket),
         quota_client_types_(std::move(quota_client_types)),
@@ -832,6 +733,14 @@
     DCHECK(completion_closure_);
   }
 
+  ~BucketDataDeleter() {
+    if (callback_)
+      std::move(callback_).Run(blink::mojom::QuotaStatusCode::kErrorAbort);
+
+    if (completion_closure_)
+      std::move(completion_closure_).Run(this);
+  }
+
   void Run() {
     DCHECK(manager_->client_types_.contains(bucket_.type));
 
@@ -912,7 +821,7 @@
                 : blink::mojom::QuotaStatusCode::kErrorInvalidModification);
 
     // Deletes `this`.
-    std::move(completion_closure_).Run();
+    std::move(completion_closure_).Run(this);
   }
 
   QuotaManagerImpl* const manager_;
@@ -922,102 +831,119 @@
   size_t remaining_clients_ = 0;
   int skipped_clients_ = 0;
   StatusCallback callback_;
-  base::OnceClosure completion_closure_;
+  base::OnceCallback<void(BucketDataDeleter*)> completion_closure_;
 
   base::WeakPtrFactory<BucketDataDeleter> weak_factory_{this};
 };
 
-class QuotaManagerImpl::HostDataDeleter : public QuotaTask {
+// Retrieves all buckets for `host` from QuotaDatabase and calls
+// BucketDataDeleter for `quota_client_types` for each bucket.
+// If BucketDataDeleter is called for all registered QuotaClientTypes,
+// BucketDataDeleter will remove the bucket from QuotaDatabase.
+class QuotaManagerImpl::HostDataDeleter {
  public:
   HostDataDeleter(QuotaManagerImpl* manager,
                   const std::string& host,
                   StorageType type,
                   QuotaClientTypes quota_client_types,
-                  StatusCallback callback)
-      : QuotaTask(manager),
+                  StatusCallback callback,
+                  base::OnceCallback<void(HostDataDeleter*)> completion_closure)
+      : manager_(manager),
         host_(host),
         type_(type),
         quota_client_types_(std::move(quota_client_types)),
-        error_count_(0),
-        remaining_clients_(0),
-        remaining_deleters_(0),
-        callback_(std::move(callback)) {}
-
- protected:
-  void Run() override {
-    DCHECK(manager()->client_types_.contains(type_));
-    remaining_clients_ = manager()->client_types_[type_].size();
-
-    for (const auto& client_and_type : manager()->client_types_[type_]) {
-      client_and_type.first->GetStorageKeysForHost(
-          type_, host_,
-          base::BindOnce(&HostDataDeleter::DidGetStorageKeysForHost,
-                         weak_factory_.GetWeakPtr()));
-    }
+        callback_(std::move(callback)),
+        completion_closure_(std::move(completion_closure)) {
+    DCHECK(manager_);
+    DCHECK(callback_);
+    DCHECK(completion_closure_);
   }
 
-  void Completed() override {
-    if (error_count_ == 0) {
-      std::move(callback_).Run(blink::mojom::QuotaStatusCode::kOk);
-    } else {
-      std::move(callback_).Run(
-          blink::mojom::QuotaStatusCode::kErrorInvalidModification);
-    }
-    DeleteSoon();
+  ~HostDataDeleter() {
+    if (callback_)
+      std::move(callback_).Run(blink::mojom::QuotaStatusCode::kErrorAbort);
+
+    if (completion_closure_)
+      std::move(completion_closure_).Run(this);
   }
 
-  void Aborted() override {
-    std::move(callback_).Run(blink::mojom::QuotaStatusCode::kErrorAbort);
-    DeleteSoon();
+  void Run() {
+#if DCHECK_IS_ON()
+    DCHECK(!run_called_) << __func__ << " already called";
+    run_called_ = true;
+#endif  // DCHECK_IS_ON()
+    manager_->GetBucketsForHost(
+        host_, type_,
+        base::BindOnce(&HostDataDeleter::DidGetBucketsForHost,
+                       weak_factory_.GetWeakPtr()));
   }
 
+  bool completed() { return !callback_; }
+
  private:
-  void DidGetStorageKeysForHost(const std::vector<StorageKey>& storage_keys) {
-    DCHECK_GT(remaining_clients_, 0U);
-
-    storage_keys_.insert(storage_keys.begin(), storage_keys.end());
-
-    if (--remaining_clients_ == 0) {
-      if (!storage_keys_.empty())
-        ScheduleStorageKeysDeletion();
-      else
-        CallCompleted();
+  void DidGetBucketsForHost(QuotaErrorOr<std::set<BucketLocator>> result) {
+    if (!result.ok()) {
+      Complete(/*success=*/false);
+      return;
     }
+
+    buckets_ = result.value();
+    if (!buckets_.empty()) {
+      ScheduleBucketsDeletion();
+      return;
+    }
+    Complete(/*success=*/true);
   }
 
-  void ScheduleStorageKeysDeletion() {
-    remaining_deleters_ = storage_keys_.size();
-    for (const auto& storage_key : storage_keys_) {
-      StorageKeyDataDeleter* deleter = new StorageKeyDataDeleter(
-          manager(), storage_key, type_, std::move(quota_client_types_),
-          base::BindOnce(&HostDataDeleter::DidDeleteStorageKeyData,
+  void ScheduleBucketsDeletion() {
+    for (const auto& bucket : buckets_) {
+      auto bucket_deleter = std::make_unique<BucketDataDeleter>(
+          manager_, bucket, quota_client_types_,
+          base::BindOnce(&HostDataDeleter::DidDeleteBucketData,
+                         weak_factory_.GetWeakPtr()),
+          base::BindOnce(&HostDataDeleter::FinishedBucketDeletion,
                          weak_factory_.GetWeakPtr()));
-      deleter->Start();
+      bucket_deleter->Run();
+      bucket_deleters_[bucket_deleter.get()] = std::move(bucket_deleter);
     }
   }
 
-  void DidDeleteStorageKeyData(blink::mojom::QuotaStatusCode status) {
-    DCHECK_GT(remaining_deleters_, 0U);
-
+  void DidDeleteBucketData(blink::mojom::QuotaStatusCode status) {
     if (status != blink::mojom::QuotaStatusCode::kOk)
       ++error_count_;
-
-    if (--remaining_deleters_ == 0)
-      CallCompleted();
   }
 
-  QuotaManagerImpl* manager() const {
-    return static_cast<QuotaManagerImpl*>(observer());
+  void FinishedBucketDeletion(BucketDataDeleter* deleter) {
+    DCHECK(deleter->completed());
+    bucket_deleters_.erase(deleter);
+
+    if (bucket_deleters_.empty())
+      Complete(/*success=*/error_count_ == 0);
   }
 
+  void Complete(bool success) {
+    std::move(callback_).Run(
+        success ? blink::mojom::QuotaStatusCode::kOk
+                : blink::mojom::QuotaStatusCode::kErrorInvalidModification);
+
+    // Deletes `this`.
+    std::move(completion_closure_).Run(this);
+  }
+
+  QuotaManagerImpl* const manager_;
   const std::string host_;
   const StorageType type_;
   const QuotaClientTypes quota_client_types_;
-  std::set<StorageKey> storage_keys_;
-  int error_count_;
-  size_t remaining_clients_;
-  size_t remaining_deleters_;
+  std::map<BucketDataDeleter*, std::unique_ptr<BucketDataDeleter>>
+      bucket_deleters_;
+  std::set<BucketLocator> buckets_;
+  int error_count_ = 0;
   StatusCallback callback_;
+  base::OnceCallback<void(HostDataDeleter*)> completion_closure_;
+
+#if DCHECK_IS_ON()
+  bool run_called_ = false;
+#endif  // DCHECK_IS_ON()
 
   base::WeakPtrFactory<HostDataDeleter> weak_factory_{this};
 };
@@ -1500,10 +1426,17 @@
     std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk);
     return;
   }
+  auto host_deleter = std::make_unique<HostDataDeleter>(
+      this, host, type, std::move(quota_client_types), std::move(callback),
+      base::BindOnce(&QuotaManagerImpl::DidDeleteHostData,
+                     weak_factory_.GetWeakPtr()));
+  host_deleter->Run();
+  host_data_deleters_[host_deleter.get()] = std::move(host_deleter);
+}
 
-  HostDataDeleter* deleter = new HostDataDeleter(
-      this, host, type, std::move(quota_client_types), std::move(callback));
-  deleter->Start();
+void QuotaManagerImpl::DidDeleteHostData(HostDataDeleter* deleter) {
+  DCHECK(deleter->completed());
+  host_data_deleters_.erase(deleter);
 }
 
 void QuotaManagerImpl::BindInternalsHandler(
@@ -1941,20 +1874,6 @@
   temporary_storage_evictor_->Start();
 }
 
-void QuotaManagerImpl::DeleteStorageKeyFromDatabase(
-    const StorageKey& storage_key,
-    StorageType type) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  EnsureDatabaseOpened();
-  if (db_disabled_)
-    return;
-
-  PostTaskAndReplyWithResultForDBThread(
-      base::BindOnce(&DeleteStorageKeyInfoOnDBThread, storage_key, type),
-      base::BindOnce(&QuotaManagerImpl::OnComplete,
-                     weak_factory_.GetWeakPtr()));
-}
-
 void QuotaManagerImpl::DeleteBucketFromDatabase(
     BucketId bucket_id,
     base::OnceCallback<void(QuotaError)> callback) {
@@ -2007,20 +1926,17 @@
     std::move(callback).Run(blink::mojom::QuotaStatusCode::kErrorInvalidAccess);
     return;
   }
-  bucket_data_deleters_.emplace_back(std::make_unique<BucketDataDeleter>(
+  auto bucket_deleter = std::make_unique<BucketDataDeleter>(
       this, bucket, std::move(quota_client_types), std::move(callback),
       base::BindOnce(&QuotaManagerImpl::DidDeleteBucketData,
-                     weak_factory_.GetWeakPtr())));
-  bucket_data_deleters_.back()->Run();
+                     weak_factory_.GetWeakPtr()));
+  bucket_deleter->Run();
+  bucket_data_deleters_[bucket_deleter.get()] = std::move(bucket_deleter);
 }
 
-void QuotaManagerImpl::DidDeleteBucketData() {
-  bucket_data_deleters_.erase(
-      std::remove_if(bucket_data_deleters_.begin(), bucket_data_deleters_.end(),
-                     [](std::unique_ptr<BucketDataDeleter>& deleter) {
-                       return deleter->completed();
-                     }),
-      bucket_data_deleters_.end());
+void QuotaManagerImpl::DidDeleteBucketData(BucketDataDeleter* deleter) {
+  DCHECK(deleter->completed());
+  bucket_data_deleters_.erase(deleter);
 }
 
 void QuotaManagerImpl::MaybeRunStoragePressureCallback(
diff --git a/storage/browser/quota/quota_manager_impl.h b/storage/browser/quota/quota_manager_impl.h
index ecb8b3d8..0dfea02d 100644
--- a/storage/browser/quota/quota_manager_impl.h
+++ b/storage/browser/quota/quota_manager_impl.h
@@ -322,8 +322,8 @@
                             blink::mojom::StorageType type,
                             bool enabled);
 
-  // DeleteHostData (surprisingly enough) deletes data of a particular
-  // blink::mojom::StorageType associated with a set of storage keys.
+  // DeleteHostData deletes buckets of a particular blink::mojom::StorageType
+  // with storage keys that match the specified host.
   // DeleteBucketData will only delete the specified bucket.
   // Each method additionally requires a `quota_client_types` which specifies
   // the types of QuotaClients to delete from the storage key.
@@ -452,7 +452,6 @@
   class GetUsageInfoTask;
   class StorageKeyGathererTask;
   class BucketDataDeleter;
-  class StorageKeyDataDeleter;
   class HostDataDeleter;
   class DumpQuotaTableHelper;
   class DumpBucketTableHelper;
@@ -532,13 +531,12 @@
   void DeleteBucketDataInternal(const BucketLocator& bucket,
                                 QuotaClientTypes quota_client_types,
                                 StatusCallback callback);
-  // Cleans up BucketDataDeleter tasks that have completed.
-  void DidDeleteBucketData();
+  // Cleans up deleter tasks that have completed.
+  void DidDeleteHostData(HostDataDeleter* deleter);
+  void DidDeleteBucketData(BucketDataDeleter* deleter);
 
   // Methods for eviction logic.
   void StartEviction();
-  void DeleteStorageKeyFromDatabase(const blink::StorageKey& storage_key,
-                                    blink::mojom::StorageType type);
   void DeleteBucketFromDatabase(BucketId bucket_id,
                                 base::OnceCallback<void(QuotaError)> callback);
 
@@ -749,7 +747,10 @@
   GetVolumeInfoFn get_volume_info_fn_;
 
   std::unique_ptr<EvictionRoundInfoHelper> eviction_helper_;
-  std::vector<std::unique_ptr<BucketDataDeleter>> bucket_data_deleters_;
+  std::map<HostDataDeleter*, std::unique_ptr<HostDataDeleter>>
+      host_data_deleters_;
+  std::map<BucketDataDeleter*, std::unique_ptr<BucketDataDeleter>>
+      bucket_data_deleters_;
   std::unique_ptr<StorageKeyGathererTask> storage_key_gatherer_;
 
   SEQUENCE_CHECKER(sequence_checker_);
diff --git a/styleguide/c++/c++.md b/styleguide/c++/c++.md
index de3ff1d..93662bb 100644
--- a/styleguide/c++/c++.md
+++ b/styleguide/c++/c++.md
@@ -152,6 +152,12 @@
 
 ## Types
 
+  * Refer to the [Mojo style
+    guide](https://chromium.googlesource.com/chromium/src/+/main/docs/security/mojo.md)
+    when working with types that will be passed across network or process
+    boundaries. For example, explicitly-sized integral types must be used for
+    safety, since the sending and receiving ends may not have been compiled
+    with the same sizes for things like `int` and `size_t`.
   * Use `size_t` for object and allocation sizes, object counts, array and
     pointer offsets, vector indices, and so on. This prevents casts when
     dealing with STL APIs, and if followed consistently across the codebase,
@@ -161,7 +167,11 @@
     these cases, continue to use `size_t` in public-facing function
     declarations, and continue to use unsigned types internally (e.g.
     `uint32_t`).
-  * Follow [Google C++ casting
+  * Follow the [integer semantics
+    guide](https://chromium.googlesource.com/chromium/src/+/main/docs/security/integer-semantics.md)
+    for all arithmetic conversions and calculations used in memory management
+    or passed across network or process boundaries. In other circumstances,
+    follow [Google C++ casting
     conventions](https://google.github.io/styleguide/cppguide.html#Casting)
     to convert arithmetic types when you know the conversion is safe. Use
     `checked_cast<T>` (from `base/numerics/safe_conversions.h`) when you need to
@@ -169,11 +179,6 @@
     `saturated_cast<T>` if you instead wish to clamp out-of-range values.
     `CheckedNumeric` is an ergonomic way to perform safe arithmetic and casting
     in many cases.
-  * When passing values across network or process boundaries, use
-    explicitly-sized types for safety, since the sending and receiving ends may
-    not have been compiled with the same sizes for things like `int` and
-    `size_t`. However, to the greatest degree possible, avoid letting these
-    sized types bleed through the APIs of the layers in question.
   * The Google Style Guide [bans
     UTF-16](https://google.github.io/styleguide/cppguide.html#Non-ASCII_Characters).
     For various reasons, Chromium uses UTF-16 extensively. Use `std::u16string`
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index ff863a1..58d4d6d3 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -5701,7 +5701,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.7"
+              "revision": "version:99.0.4844.9"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5965,7 +5965,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.7"
+              "revision": "version:99.0.4844.9"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 9b0e9748..475219df 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -43299,7 +43299,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.7"
+              "revision": "version:99.0.4844.9"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -43563,7 +43563,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.7"
+              "revision": "version:99.0.4844.9"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -43902,7 +43902,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.7"
+              "revision": "version:99.0.4844.9"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -44166,7 +44166,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.7"
+              "revision": "version:99.0.4844.9"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -44505,7 +44505,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.7"
+              "revision": "version:99.0.4844.9"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -44769,7 +44769,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.7"
+              "revision": "version:99.0.4844.9"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index ce182df..3d3e635 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -21721,6 +21721,25 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "inside_docker": "1",
+              "os": "Ubuntu-20.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "mojo_core_unittests",
+        "test_id_prefix": "ninja://mojo/core:mojo_core_unittests/"
+      },
+      {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter"
         ],
@@ -24319,6 +24338,24 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "mojo_core_unittests",
+        "test_id_prefix": "ninja://mojo/core:mojo_core_unittests/"
+      },
+      {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter"
         ],
@@ -24794,6 +24831,27 @@
       },
       {
         "args": [
+          "--custom-image=workstation.qemu-x64-release"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "mojo_core_unittests",
+        "test_id_prefix": "ninja://mojo/core:mojo_core_unittests/"
+      },
+      {
+        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter",
           "--custom-image=workstation.qemu-x64-release"
         ],
diff --git a/testing/buildbot/chromium.rust.json b/testing/buildbot/chromium.rust.json
index 7ffc002..f52065f 100644
--- a/testing/buildbot/chromium.rust.json
+++ b/testing/buildbot/chromium.rust.json
@@ -3,6 +3,7 @@
   "AAAAA2 See generate_buildbot_json.py to make changes": {},
   "android-rust-arm-rel": {
     "additional_compile_targets": [
+      "mojo_rust",
       "rust_build_tests"
     ],
     "gtest_tests": [
@@ -63,6 +64,9 @@
   },
   "linux-rust-x64-rel": {
     "additional_compile_targets": [
+      "mojo_rust",
+      "mojo_rust_extra_tests",
+      "mojo_rust_unittests",
       "rust_build_tests"
     ],
     "gtest_tests": [
diff --git a/testing/buildbot/client.devtools-frontend.integration.json b/testing/buildbot/client.devtools-frontend.integration.json
index b8340a2..47575631 100644
--- a/testing/buildbot/client.devtools-frontend.integration.json
+++ b/testing/buildbot/client.devtools-frontend.integration.json
@@ -106,5 +106,111 @@
         "test_id_prefix": "ninja://:devtools_web_tests/"
       }
     ]
+  },
+  "DevTools Linux Fastbuild": {
+    "additional_compile_targets": [
+      "blink_tests"
+    ],
+    "gtest_tests": [
+      {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "blink_unit_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "blink_unittests",
+        "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
+      },
+      {
+        "args": [
+          "--gtest_filter=*DevTools*"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "devtools_browser_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "browser_tests",
+        "test_id_prefix": "ninja://chrome/test:browser_tests/"
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "--num-retries=3"
+        ],
+        "isolate_name": "blink_web_tests",
+        "merge": {
+          "args": [
+            "--verbose"
+          ],
+          "script": "//third_party/blink/tools/merge_web_test_results.py"
+        },
+        "name": "blink_web_tests",
+        "resultdb": {
+          "enable": true
+        },
+        "results_handler": "layout tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 12
+        },
+        "test_id_prefix": "ninja://:blink_web_tests/"
+      },
+      {
+        "args": [
+          "--num-retries=3",
+          "--layout-tests-directory=../../third_party/devtools-frontend/src/test/webtests/",
+          "http/tests/devtools"
+        ],
+        "isolate_name": "devtools_web_tests",
+        "merge": {
+          "args": [
+            "--verbose"
+          ],
+          "script": "//third_party/blink/tools/merge_web_test_results.py"
+        },
+        "name": "webkit_layout_from_devtools",
+        "resultdb": {
+          "enable": true
+        },
+        "results_handler": "layout tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 4
+        },
+        "test_id_prefix": "ninja://:devtools_web_tests/"
+      }
+    ]
   }
 }
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 5798c895..a6697896 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1288,6 +1288,24 @@
     "script": "//testing/scripts/run_isolated_script_test.py",
     "type": "script",
   },
+  "mojo_rust": {
+    "label": "//mojo/public/rust:mojo_rust",
+    # Since we can't build rust tests on Android now, add this for build
+    # coverage.
+    "type": "additional_compile_target",
+  },
+  "mojo_rust_unittests": {
+    "label": "//mojo/public/rust:mojo_rust_unittests",
+    # We don't yet support running Rust test binaries. For now, at least build
+    # the target. TODO(https://crbug.com/1260120): make this a test.
+    "type": "additional_compile_target",
+  },
+  "mojo_rust_extra_tests": {
+    "label": "//mojo/public/rust:mojo_rust",
+    # We don't yet support running Rust test binaries. For now, at least build
+    # the target. TODO(https://crbug.com/1260120): make this a test.
+    "type": "additional_compile_target",
+  },
   "mojo_test_apk": {
     "label": "//mojo/public/java/system:mojo_test_apk",
     "type": "console_test_launcher",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 954f7ed..8e96685d 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -415,6 +415,14 @@
           'shards': 4,
         },
       },
+      'devtools_frontend_linux_blink_light_rel_fastbuild': {
+        'args': [
+          'http/tests/devtools',
+        ],
+        'swarming': {
+          'shards': 4,
+        },
+      },
       'fuchsia-fyi-x64-rel': {
         'args': [
           '--platform=fuchsia',
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index dd56ab5b..4b47816a 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -1768,6 +1768,7 @@
           'shards': 6,
         },
       },
+      'mojo_core_unittests': {},
       'unit_tests': {
         'args': [
           '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter',
diff --git a/testing/buildbot/tryserver.devtools-frontend.json b/testing/buildbot/tryserver.devtools-frontend.json
index 956a941..ba728d0 100644
--- a/testing/buildbot/tryserver.devtools-frontend.json
+++ b/testing/buildbot/tryserver.devtools-frontend.json
@@ -87,6 +87,92 @@
       }
     ]
   },
+  "devtools_frontend_linux_blink_light_rel_fastbuild": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--gtest_filter=*DevTools*"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "devtools_browser_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "browser_tests",
+        "test_id_prefix": "ninja://chrome/test:browser_tests/"
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "--num-retries=3",
+          "http/tests/devtools"
+        ],
+        "isolate_name": "blink_web_tests",
+        "merge": {
+          "args": [
+            "--verbose"
+          ],
+          "script": "//third_party/blink/tools/merge_web_test_results.py"
+        },
+        "name": "blink_web_tests",
+        "resultdb": {
+          "enable": true
+        },
+        "results_handler": "layout tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 4
+        },
+        "test_id_prefix": "ninja://:blink_web_tests/"
+      },
+      {
+        "args": [
+          "--num-retries=3",
+          "--layout-tests-directory=../../third_party/devtools-frontend/src/test/webtests/",
+          "http/tests/devtools"
+        ],
+        "isolate_name": "devtools_web_tests",
+        "merge": {
+          "args": [
+            "--verbose"
+          ],
+          "script": "//third_party/blink/tools/merge_web_test_results.py"
+        },
+        "name": "webkit_layout_from_devtools",
+        "resultdb": {
+          "enable": true
+        },
+        "results_handler": "layout tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 4
+        },
+        "test_id_prefix": "ninja://:devtools_web_tests/"
+      }
+    ]
+  },
   "devtools_frontend_linux_blink_rel": {
     "isolated_scripts": [
       {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 4674cac..2f206f5d 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -363,7 +363,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M99',
-          'revision': 'version:99.0.4844.7',
+          'revision': 'version:99.0.4844.9',
         }
       ],
     },
@@ -435,7 +435,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M99',
-          'revision': 'version:99.0.4844.7',
+          'revision': 'version:99.0.4844.9',
         }
       ],
     },
@@ -507,7 +507,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M99',
-          'revision': 'version:99.0.4844.7',
+          'revision': 'version:99.0.4844.9',
         }
       ],
     },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index bc9e06d..509ff5e4 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -5412,6 +5412,7 @@
     'machines': {
       'android-rust-arm-rel': {
         'additional_compile_targets': [
+          'mojo_rust',
           'rust_build_tests',
         ],
         'mixins': [ 'marshmallow' ],
@@ -5424,6 +5425,9 @@
       },
       'linux-rust-x64-rel' : {
         'additional_compile_targets': [
+          'mojo_rust',
+          'mojo_rust_extra_tests',
+          'mojo_rust_unittests',
           'rust_build_tests',
         ],
         'test_suites': {
@@ -6155,6 +6159,16 @@
           'isolated_scripts': 'devtools_webkit_isolated_scripts',
         },
       },
+      'DevTools Linux Fastbuild': {
+        'mixins': [
+          'linux-bionic',
+        ],
+        'additional_compile_targets': ['blink_tests'],
+        'test_suites': {
+          'gtest_tests': 'devtools_gtests',
+          'isolated_scripts': 'devtools_webkit_isolated_scripts',
+        },
+      },
     },
   },
   {
@@ -6579,6 +6593,15 @@
           'isolated_scripts': 'devtools_webkit_isolated_scripts',
         },
       },
+      'devtools_frontend_linux_blink_light_rel_fastbuild': {
+        'mixins': [
+          'linux-bionic',
+        ],
+        'test_suites': {
+          'gtest_tests': 'devtools_browser_tests',
+          'isolated_scripts': 'devtools_webkit_isolated_scripts',
+        },
+      },
       'devtools_frontend_linux_blink_rel': {
         'mixins': [
           'linux-bionic',
diff --git a/testing/scripts/wpt_common.py b/testing/scripts/wpt_common.py
index 91c1b04b..f705925 100644
--- a/testing/scripts/wpt_common.py
+++ b/testing/scripts/wpt_common.py
@@ -112,12 +112,11 @@
             self._process_wpt_report(self.wptreport)
 
     def get_wpt_revision(self):
-        path_to_readme = os.path.join(
-            common.SRC_DIR, "third_party", "wpt_tools", "README.chromium")
-        with open(path_to_readme) as f:
+        path_to_version = os.path.join(WEB_TESTS_DIR, 'external', 'Version')
+        with open(path_to_version) as f:
             for line in f.readlines():
                 if line.startswith("Version:"):
-                    rev = line.rstrip()[len("Version:"):].strip()
+                    rev = line[len("Version:"):].strip()
                     return rev
         return None
 
diff --git a/testing/unexpected_passes_common/queries.py b/testing/unexpected_passes_common/queries.py
index 3c147eb6..02f7a615 100644
--- a/testing/unexpected_passes_common/queries.py
+++ b/testing/unexpected_passes_common/queries.py
@@ -37,20 +37,18 @@
 # Subquery for getting all try builds that were used for CL submission. 30 days
 # is chosen because the ResultDB tables we pull data from only keep data around
 # for 30 days.
-SUBMITTED_BUILDS_SUBQUERY = """\
-  submitted_builds AS (
+SUBMITTED_BUILDS_TEMPLATE = """\
     SELECT
       CONCAT("build-", CAST(unnested_builds.id AS STRING)) as id
     FROM
-      `commit-queue.chromium.attempts`,
+      `commit-queue.{project_view}.attempts`,
       UNNEST(builds) as unnested_builds,
       UNNEST(gerrit_changes) as unnested_changes
     WHERE
       unnested_builds.host = "cr-buildbucket.appspot.com"
       AND unnested_changes.submit_status = "SUCCESS"
       AND start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(),
-                                     INTERVAL 30 DAY)
-  ),"""
+                                     INTERVAL 30 DAY)"""
 
 
 class BigQueryQuerier(object):
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 137fa0b..3cbf405 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1570,24 +1570,6 @@
             ]
         }
     ],
-    "ChimeAndroidSDK": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "ChimeAndroidSDK",
-                    "params": {
-                        "always_register": "true"
-                    },
-                    "enable_features": [
-                        "UseChimeAndroidSdk"
-                    ]
-                }
-            ]
-        }
-    ],
     "ChromeCleanupDistribution": [
         {
             "platforms": [
@@ -2303,21 +2285,6 @@
             ]
         }
     ],
-    "CupsIppPrintingBackend": [
-        {
-            "platforms": [
-                "mac"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "CupsIppPrintingBackend"
-                    ]
-                }
-            ]
-        }
-    ],
     "DWriteFontProxyOnIO": [
         {
             "platforms": [
@@ -2480,32 +2447,6 @@
             ]
         }
     ],
-    "DesktopPwaInstallInProductHelp": [
-        {
-            "platforms": [
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "params": {
-                        "availability": "any",
-                        "event_trigger": "name:desktop_pwa_install_iph_triggered;comparator:any;window:90;storage:365",
-                        "event_used": "name:desktop_pwa_installed;comparator:any;window:90;storage:365",
-                        "session_rate": "==0",
-                        "x_site_engagement_threshold": "10"
-                    },
-                    "enable_features": [
-                        "IPH_DesktopPwaInstall"
-                    ]
-                }
-            ]
-        }
-    ],
     "DesktopReadingListAddFromDialog": [
         {
             "platforms": [
@@ -2698,22 +2639,6 @@
             ]
         }
     ],
-    "DisableGles2ForOopR": [
-        {
-            "platforms": [
-                "android",
-                "android_webview"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "disable_features": [
-                        "UseGles2ForOopR"
-                    ]
-                }
-            ]
-        }
-    ],
     "DisableHttpDiskCache": [
         {
             "platforms": [
@@ -3096,7 +3021,7 @@
                     "params": {
                         "availability": "any",
                         "event_trigger": "name:pulltorefresh_triggered;comparator:==0;window:360;storage:360",
-                        "event_used": "name:pulltorefresh_dummy;comparator:==0;window:360;storage:360",
+                        "event_used": "name:feed_swipe_refresh_shown;comparator:==0;window:7;storage:360",
                         "session_rate": "==0"
                     },
                     "enable_features": [
@@ -3318,31 +3243,6 @@
             ]
         }
     ],
-    "GwpAsanAndroid": [
-        {
-            "platforms": [
-                "android",
-                "android_weblayer",
-                "android_webview"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "params": {
-                        "AllocationSamplingRange": "16",
-                        "MaxAllocations": "70",
-                        "MaxMetadata": "255",
-                        "ProcessSamplingBoost2": "10",
-                        "ProcessSamplingProbability": "0.015"
-                    },
-                    "enable_features": [
-                        "GwpAsanMalloc",
-                        "GwpAsanPartitionAlloc"
-                    ]
-                }
-            ]
-        }
-    ],
     "GwpAsanLinux": [
         {
             "platforms": [
@@ -3636,21 +3536,6 @@
             ]
         }
     ],
-    "IOSScreenTimeIntegration": [
-        {
-            "platforms": [
-                "ios"
-            ],
-            "experiments": [
-                {
-                    "name": "Disabled",
-                    "disable_features": [
-                        "ScreenTimeIntegration"
-                    ]
-                }
-            ]
-        }
-    ],
     "IOSSharedHighlightingColorChange": [
         {
             "platforms": [
@@ -3739,28 +3624,6 @@
             ]
         }
     ],
-    "IdentityDiscIPH": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "IdentityDiscIPH",
-                    "params": {
-                        "availability": "any",
-                        "event_trigger": "name:iph_identity_disc_triggered;comparator:<1;window:360;storage:360",
-                        "event_used": "name:identity_disc_used;comparator:<1;window:90;storage:360",
-                        "session_rate": "<1"
-                    },
-                    "enable_features": [
-                        "IPH_IdentityDisc"
-                    ],
-                    "disable_features": []
-                }
-            ]
-        }
-    ],
     "IgnoreSyncEncryptionKeysLongMissing": [
         {
             "platforms": [
@@ -4510,24 +4373,6 @@
             ]
         }
     ],
-    "OptimizationHintsFieldTrials": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "params": {
-                        "allowed_field_trial_names": "ChromeStart"
-                    },
-                    "enable_features": [
-                        "OptimizationHintsFieldTrials"
-                    ]
-                }
-            ]
-        }
-    ],
     "OptimizeEarlyNavigation": [
         {
             "platforms": [
@@ -6415,26 +6260,6 @@
             ]
         }
     ],
-    "TranslateRankerModelAndroid": [
-        {
-            "platforms": [
-                "android",
-                "android_weblayer"
-            ],
-            "experiments": [
-                {
-                    "name": "Enforcement20170918",
-                    "params": {
-                        "translate-ranker-model-url": "https://www.gstatic.com/chrome/intelligence/assist/ranker/models/translate/android/translate_ranker_model_android_20170918.pb.bin"
-                    },
-                    "enable_features": [
-                        "TranslateRankerEnforcement",
-                        "TranslateRankerQuery"
-                    ]
-                }
-            ]
-        }
-    ],
     "TreatPreconnectAsDefault": [
         {
             "platforms": [
@@ -7073,32 +6898,6 @@
             ]
         }
     ],
-    "VideoTutorialVoiceSearchStudy": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "VideoTutorialNTPVoiceSearch",
-                    "params": {
-                        "availability": ">=0",
-                        "event_1": "name:search_completed;comparator:any;window:30;storage:30",
-                        "event_2": "name:video_tutorial_iph_clicked_voice_search;comparator:==0;window:30;storage:30",
-                        "event_3": "name:video_tutorial_iph_dismissed_voice_search;comparator:==0;window:30;storage:30",
-                        "event_trigger": "name:tutorial_voice_search_iph_trigger;comparator:any;window:30;storage:30",
-                        "event_used": "name:voice_search;comparator:any;window:30;storage:30",
-                        "session_rate": "any",
-                        "session_rate_impact": "none"
-                    },
-                    "enable_features": [
-                        "IPH_VideoTutorial_NTP_VoiceSearch"
-                    ],
-                    "disable_features": []
-                }
-            ]
-        }
-    ],
     "VideoTutorials": [
         {
             "platforms": [
diff --git a/third_party/abseil-cpp/BUILD.gn b/third_party/abseil-cpp/BUILD.gn
index 127ab23..d3234b0 100644
--- a/third_party/abseil-cpp/BUILD.gn
+++ b/third_party/abseil-cpp/BUILD.gn
@@ -188,7 +188,6 @@
         "absl/container:node_slot_policy_test",
         "absl/container:sample_element_size_test",
         "absl/hash:low_level_hash_test",
-        "absl/hash:hash_test",
         "absl/memory:memory_test",
         "absl/meta:type_traits_test",
         "absl/profiling:exponential_biased_test",
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium
index 360212e..f1b540b7 100644
--- a/third_party/abseil-cpp/README.chromium
+++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@
 License: Apache 2.0
 License File: LICENSE
 Version: 0
-Revision: e3fdd9b16a2a90c9e01e00de46605ce59bebc661
+Revision: c59e7e59f5d29619ddc07fcb59be3dcba9585814
 Security Critical: yes
 
 Description:
diff --git a/third_party/abseil-cpp/absl/base/attributes.h b/third_party/abseil-cpp/absl/base/attributes.h
index 4ab6fa2..00aad48 100644
--- a/third_party/abseil-cpp/absl/base/attributes.h
+++ b/third_party/abseil-cpp/absl/base/attributes.h
@@ -136,9 +136,9 @@
 // for further information.
 // The MinGW compiler doesn't complain about the weak attribute until the link
 // step, presumably because Windows doesn't use ELF binaries.
-#if (ABSL_HAVE_ATTRIBUTE(weak) ||                                         \
-     (defined(__GNUC__) && !defined(__clang__))) &&                       \
-    (!defined(_WIN32) || (defined(__clang__) && __clang_major__ >= 9)) && \
+#if (ABSL_HAVE_ATTRIBUTE(weak) ||                                        \
+     (defined(__GNUC__) && !defined(__clang__))) &&                      \
+    (!defined(_WIN32) || (defined(__clang__) && __clang_major__ < 9)) && \
     !defined(__MINGW32__)
 #undef ABSL_ATTRIBUTE_WEAK
 #define ABSL_ATTRIBUTE_WEAK __attribute__((weak))
@@ -312,6 +312,7 @@
   __attribute__((section(#name))) __attribute__((noinline))
 #endif
 
+
 // ABSL_ATTRIBUTE_SECTION_VARIABLE
 //
 // Tells the compiler/linker to put a given variable into a section and define
@@ -338,8 +339,8 @@
 // a no-op on ELF but not on Mach-O.
 //
 #ifndef ABSL_DECLARE_ATTRIBUTE_SECTION_VARS
-#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name)   \
-  extern char __start_##name[] ABSL_ATTRIBUTE_WEAK; \
+#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) \
+  extern char __start_##name[] ABSL_ATTRIBUTE_WEAK;    \
   extern char __stop_##name[] ABSL_ATTRIBUTE_WEAK
 #endif
 #ifndef ABSL_DEFINE_ATTRIBUTE_SECTION_VARS
@@ -502,7 +503,7 @@
 #define ABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]]
 #if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args)
 #define ABSL_XRAY_LOG_ARGS(N) \
-  [[clang::xray_always_instrument, clang::xray_log_args(N)]]
+    [[clang::xray_always_instrument, clang::xray_log_args(N)]]
 #else
 #define ABSL_XRAY_LOG_ARGS(N) [[clang::xray_always_instrument]]
 #endif
diff --git a/third_party/abseil-cpp/absl/base/casts.h b/third_party/abseil-cpp/absl/base/casts.h
index bf100ef..b16af233 100644
--- a/third_party/abseil-cpp/absl/base/casts.h
+++ b/third_party/abseil-cpp/absl/base/casts.h
@@ -44,12 +44,8 @@
           bool,
           sizeof(Dest) == sizeof(Source) &&
               type_traits_internal::is_trivially_copyable<Source>::value &&
-              type_traits_internal::is_trivially_copyable<Dest>::value
-#if !ABSL_HAVE_BUILTIN(__builtin_bit_cast)
-              && std::is_default_constructible<Dest>::value
-#endif
-          > {
-};
+              type_traits_internal::is_trivially_copyable<Dest>::value &&
+              std::is_default_constructible<Dest>::value> {};
 
 }  // namespace internal_casts
 
@@ -151,26 +147,20 @@
 // introducing this undefined behavior (since the original value is never
 // accessed in the wrong way).
 //
-// NOTE: The requirements here are more strict than the bit_cast of standard
-// proposal P0476 when __builtin_bit_cast is not available.
+// NOTE: The requirements here are stricter than the bit_cast of standard
+// proposal P0476 due to the need for workarounds and lack of intrinsics.
 // Specifically, this implementation also requires `Dest` to be
 // default-constructible.
 template <
     typename Dest, typename Source,
     typename std::enable_if<internal_casts::is_bitcastable<Dest, Source>::value,
                             int>::type = 0>
-#if ABSL_HAVE_BUILTIN(__builtin_bit_cast)
-inline constexpr Dest bit_cast(const Source& source) {
-  return __builtin_bit_cast(Dest, source);
-}
-#else
 inline Dest bit_cast(const Source& source) {
   Dest dest;
   memcpy(static_cast<void*>(std::addressof(dest)),
          static_cast<const void*>(std::addressof(source)), sizeof(dest));
   return dest;
 }
-#endif
 
 // NOTE: This overload is only picked if the requirements of bit_cast are
 // not met. It is therefore UB, but is provided temporarily as previous
diff --git a/third_party/abseil-cpp/absl/container/btree_test.cc b/third_party/abseil-cpp/absl/container/btree_test.cc
index b2c3d73..13cb8186 100644
--- a/third_party/abseil-cpp/absl/container/btree_test.cc
+++ b/third_party/abseil-cpp/absl/container/btree_test.cc
@@ -15,7 +15,6 @@
 #include "absl/container/btree_test.h"
 
 #include <cstdint>
-#include <functional>
 #include <limits>
 #include <map>
 #include <memory>
@@ -1345,34 +1344,38 @@
   EXPECT_EQ(++it, range.second);
 }
 
-template <typename Compare, typename Key>
-void AssertKeyCompareStringAdapted() {
-  using Adapted = typename key_compare_adapter<Compare, Key>::type;
+template <typename Compare, typename K>
+void AssertKeyCompareToAdapted() {
+  using Adapted = typename key_compare_to_adapter<Compare>::type;
+  static_assert(!std::is_same<Adapted, Compare>::value,
+                "key_compare_to_adapter should have adapted this comparator.");
   static_assert(
-      std::is_same<Adapted, StringBtreeDefaultLess>::value ||
-          std::is_same<Adapted, StringBtreeDefaultGreater>::value,
-      "key_compare_adapter should have string-adapted this comparator.");
+      std::is_same<absl::weak_ordering,
+                   absl::result_of_t<Adapted(const K &, const K &)>>::value,
+      "Adapted comparator should be a key-compare-to comparator.");
 }
-template <typename Compare, typename Key>
-void AssertKeyCompareNotStringAdapted() {
-  using Adapted = typename key_compare_adapter<Compare, Key>::type;
+template <typename Compare, typename K>
+void AssertKeyCompareToNotAdapted() {
+  using Unadapted = typename key_compare_to_adapter<Compare>::type;
   static_assert(
-      !std::is_same<Adapted, StringBtreeDefaultLess>::value &&
-          !std::is_same<Adapted, StringBtreeDefaultGreater>::value,
-      "key_compare_adapter shouldn't have string-adapted this comparator.");
+      std::is_same<Unadapted, Compare>::value,
+      "key_compare_to_adapter shouldn't have adapted this comparator.");
+  static_assert(
+      std::is_same<bool,
+                   absl::result_of_t<Unadapted(const K &, const K &)>>::value,
+      "Un-adapted comparator should return bool.");
 }
 
-TEST(Btree, KeyCompareAdapter) {
-  AssertKeyCompareStringAdapted<std::less<std::string>, std::string>();
-  AssertKeyCompareStringAdapted<std::greater<std::string>, std::string>();
-  AssertKeyCompareStringAdapted<std::less<absl::string_view>,
-                                absl::string_view>();
-  AssertKeyCompareStringAdapted<std::greater<absl::string_view>,
-                                absl::string_view>();
-  AssertKeyCompareStringAdapted<std::less<absl::Cord>, absl::Cord>();
-  AssertKeyCompareStringAdapted<std::greater<absl::Cord>, absl::Cord>();
-  AssertKeyCompareNotStringAdapted<std::less<int>, int>();
-  AssertKeyCompareNotStringAdapted<std::greater<int>, int>();
+TEST(Btree, KeyCompareToAdapter) {
+  AssertKeyCompareToAdapted<std::less<std::string>, std::string>();
+  AssertKeyCompareToAdapted<std::greater<std::string>, std::string>();
+  AssertKeyCompareToAdapted<std::less<absl::string_view>, absl::string_view>();
+  AssertKeyCompareToAdapted<std::greater<absl::string_view>,
+                            absl::string_view>();
+  AssertKeyCompareToAdapted<std::less<absl::Cord>, absl::Cord>();
+  AssertKeyCompareToAdapted<std::greater<absl::Cord>, absl::Cord>();
+  AssertKeyCompareToNotAdapted<std::less<int>, int>();
+  AssertKeyCompareToNotAdapted<std::greater<int>, int>();
 }
 
 TEST(Btree, RValueInsert) {
@@ -1422,19 +1425,11 @@
   EXPECT_EQ(tracker.swaps(), 0);
 }
 
-template <typename Cmp>
-struct CheckedCompareOptedOutCmp : Cmp, BtreeTestOnlyCheckedCompareOptOutBase {
-  using Cmp::Cmp;
-  CheckedCompareOptedOutCmp() {}
-  CheckedCompareOptedOutCmp(Cmp cmp) : Cmp(std::move(cmp)) {}  // NOLINT
-};
-
-// A btree set with a specific number of values per node. Opt out of
-// checked_compare so that we can expect exact numbers of comparisons.
+// A btree set with a specific number of values per node.
 template <typename Key, int TargetValuesPerNode, typename Cmp = std::less<Key>>
 class SizedBtreeSet
     : public btree_set_container<btree<
-          set_params<Key, CheckedCompareOptedOutCmp<Cmp>, std::allocator<Key>,
+          set_params<Key, Cmp, std::allocator<Key>,
                      BtreeNodePeer::GetTargetNodeSize<Key>(TargetValuesPerNode),
                      /*Multi=*/false>>> {
   using Base = typename SizedBtreeSet::btree_set_container;
@@ -2302,9 +2297,7 @@
   };
   using Cmp = decltype(cmp);
 
-  // Use a map that is opted out of key_compare being adapted so we can expect
-  // strict comparison call limits.
-  absl::btree_map<int, int, CheckedCompareOptedOutCmp<Cmp>> m(cmp);
+  absl::btree_map<int, int, Cmp> m(cmp);
   for (int i = 0; i < 128; ++i) {
     m.emplace(i, i);
   }
@@ -2974,58 +2967,6 @@
   absl::btree_set<MultiKey, MultiKeyComp> set = {{}, MultiKeyComp{}};
 }
 
-#ifndef NDEBUG
-TEST(Btree, InvalidComparatorsCaught) {
-  {
-    struct ZeroAlwaysLessCmp {
-      bool operator()(int lhs, int rhs) const {
-        if (lhs == 0) return true;
-        return lhs < rhs;
-      }
-    };
-    absl::btree_set<int, ZeroAlwaysLessCmp> set;
-    EXPECT_DEATH(set.insert({0, 1, 2}), "is_self_equivalent");
-  }
-  {
-    struct ThreeWayAlwaysLessCmp {
-      absl::weak_ordering operator()(int, int) const {
-        return absl::weak_ordering::less;
-      }
-    };
-    absl::btree_set<int, ThreeWayAlwaysLessCmp> set;
-    EXPECT_DEATH(set.insert({0, 1, 2}), "is_self_equivalent");
-  }
-  {
-    struct SumGreaterZeroCmp {
-      bool operator()(int lhs, int rhs) const {
-        // First, do equivalence correctly - so we can test later condition.
-        if (lhs == rhs) return false;
-        return lhs + rhs > 0;
-      }
-    };
-    absl::btree_set<int, SumGreaterZeroCmp> set;
-    // Note: '!' only needs to be escaped when it's the first character.
-    EXPECT_DEATH(set.insert({0, 1, 2}),
-                 R"regex(\!lhs_comp_rhs \|\| !comp\(\)\(rhs, lhs\))regex");
-  }
-  {
-    struct ThreeWaySumGreaterZeroCmp {
-      absl::weak_ordering operator()(int lhs, int rhs) const {
-        // First, do equivalence correctly - so we can test later condition.
-        if (lhs == rhs) return absl::weak_ordering::equivalent;
-
-        if (lhs + rhs > 0) return absl::weak_ordering::less;
-        if (lhs + rhs == 0) return absl::weak_ordering::equivalent;
-        return absl::weak_ordering::greater;
-      }
-    };
-    absl::btree_set<int, ThreeWaySumGreaterZeroCmp> set;
-    EXPECT_DEATH(set.insert({0, 1, 2}),
-                 R"regex(lhs_comp_rhs < 0 -> rhs_comp_lhs > 0)regex");
-  }
-}
-#endif
-
 }  // namespace
 }  // namespace container_internal
 ABSL_NAMESPACE_END
diff --git a/third_party/abseil-cpp/absl/container/flat_hash_set.h b/third_party/abseil-cpp/absl/container/flat_hash_set.h
index 0fb2ae6f..f1c650c 100644
--- a/third_party/abseil-cpp/absl/container/flat_hash_set.h
+++ b/third_party/abseil-cpp/absl/container/flat_hash_set.h
@@ -67,7 +67,7 @@
 //
 // By default, `flat_hash_set` uses the `absl::Hash` hashing framework. All
 // fundamental and Abseil types that support the `absl::Hash` framework have a
-// compatible equality operator for comparing insertions into `flat_hash_set`.
+// compatible equality operator for comparing insertions into `flat_hash_map`.
 // If your type is not yet supported by the `absl::Hash` framework, see
 // absl/hash/hash.h for information on extending Abseil hashing to user-defined
 // types.
@@ -106,7 +106,7 @@
  public:
   // Constructors and Assignment Operators
   //
-  // A flat_hash_set supports the same overload set as `std::unordered_set`
+  // A flat_hash_set supports the same overload set as `std::unordered_map`
   // for construction and assignment:
   //
   // *  Default constructor
@@ -173,7 +173,7 @@
   // available within the `flat_hash_set`.
   //
   // NOTE: this member function is particular to `absl::flat_hash_set` and is
-  // not provided in the `std::unordered_set` API.
+  // not provided in the `std::unordered_map` API.
   using Base::capacity;
 
   // flat_hash_set::empty()
@@ -332,7 +332,7 @@
   // flat_hash_set::swap(flat_hash_set& other)
   //
   // Exchanges the contents of this `flat_hash_set` with those of the `other`
-  // flat hash set, avoiding invocation of any move, copy, or swap operations on
+  // flat hash map, avoiding invocation of any move, copy, or swap operations on
   // individual elements.
   //
   // All iterators and references on the `flat_hash_set` remain valid, excepting
@@ -340,7 +340,7 @@
   //
   // `swap()` requires that the flat hash set's hashing and key equivalence
   // functions be Swappable, and are exchaged using unqualified calls to
-  // non-member `swap()`. If the set's allocator has
+  // non-member `swap()`. If the map's allocator has
   // `std::allocator_traits<allocator_type>::propagate_on_container_swap::value`
   // set to `true`, the allocators are also exchanged using an unqualified call
   // to non-member `swap()`; otherwise, the allocators are not swapped.
@@ -395,14 +395,14 @@
   // flat_hash_set::bucket_count()
   //
   // Returns the number of "buckets" within the `flat_hash_set`. Note that
-  // because a flat hash set contains all elements within its internal storage,
+  // because a flat hash map contains all elements within its internal storage,
   // this value simply equals the current capacity of the `flat_hash_set`.
   using Base::bucket_count;
 
   // flat_hash_set::load_factor()
   //
   // Returns the current load factor of the `flat_hash_set` (the average number
-  // of slots occupied with a value within the hash set).
+  // of slots occupied with a value within the hash map).
   using Base::load_factor;
 
   // flat_hash_set::max_load_factor()
diff --git a/third_party/abseil-cpp/absl/container/internal/btree.h b/third_party/abseil-cpp/absl/container/internal/btree.h
index bbc319c1..26bd5e1 100644
--- a/third_party/abseil-cpp/absl/container/internal/btree.h
+++ b/third_party/abseil-cpp/absl/container/internal/btree.h
@@ -74,14 +74,12 @@
 ABSL_NAMESPACE_BEGIN
 namespace container_internal {
 
-template <typename Compare, typename T, typename U>
-using compare_result_t = absl::result_of_t<const Compare(const T &, const U &)>;
-
 // A helper class that indicates if the Compare parameter is a key-compare-to
 // comparator.
 template <typename Compare, typename T>
 using btree_is_key_compare_to =
-    std::is_convertible<compare_result_t<Compare, T, T>, absl::weak_ordering>;
+    std::is_convertible<absl::result_of_t<Compare(const T &, const T &)>,
+                        absl::weak_ordering>;
 
 struct StringBtreeDefaultLess {
   using is_transparent = void;
@@ -148,140 +146,49 @@
   }
 };
 
-// See below comments for checked_compare.
-template <typename Compare, bool is_class = std::is_class<Compare>::value>
-struct checked_compare_base : Compare {
-  using Compare::Compare;
-  explicit checked_compare_base(Compare c) : Compare(std::move(c)) {}
-  const Compare &comp() const { return *this; }
-};
+// A helper class to convert a boolean comparison into a three-way "compare-to"
+// comparison that returns an `absl::weak_ordering`. This helper
+// class is specialized for less<std::string>, greater<std::string>,
+// less<string_view>, greater<string_view>, less<absl::Cord>, and
+// greater<absl::Cord>.
+//
+// key_compare_to_adapter is provided so that btree users
+// automatically get the more efficient compare-to code when using common
+// Abseil string types with common comparison functors.
+// These string-like specializations also turn on heterogeneous lookup by
+// default.
 template <typename Compare>
-struct checked_compare_base<Compare, false> {
-  explicit checked_compare_base(Compare c) : compare(std::move(c)) {}
-  const Compare &comp() const { return compare; }
-  Compare compare;
-};
-
-// A mechanism for opting out of checked_compare for use only in btree_test.cc.
-struct BtreeTestOnlyCheckedCompareOptOutBase {};
-
-// A helper class to adapt the specified comparator for two use cases:
-// (1) When using common Abseil string types with common comparison functors,
-// convert a boolean comparison into a three-way comparison that returns an
-// `absl::weak_ordering`. This helper class is specialized for
-// less<std::string>, greater<std::string>, less<string_view>,
-// greater<string_view>, less<absl::Cord>, and greater<absl::Cord>.
-// (2) Adapt the comparator to diagnose cases of non-strict-weak-ordering (see
-// https://en.cppreference.com/w/cpp/named_req/Compare) in debug mode. Whenever
-// a comparison is made, we will make assertions to verify that the comparator
-// is valid.
-template <typename Compare, typename Key>
-struct key_compare_adapter {
-  // Inherit from checked_compare_base to support function pointers and also
-  // keep empty-base-optimization (EBO) support for classes.
-  // Note: we can't use CompressedTuple here because that would interfere
-  // with the EBO for `btree::root_`. `btree::root_` is itself a CompressedTuple
-  // and nested `CompressedTuple`s don't support EBO.
-  // TODO(b/214288561): use CompressedTuple instead once it supports EBO for
-  // nested `CompressedTuple`s.
-  struct checked_compare : checked_compare_base<Compare> {
-   private:
-    using Base = typename checked_compare::checked_compare_base;
-    using Base::comp;
-
-    // If possible, returns whether `t` is equivalent to itself. We can only do
-    // this for `Key`s because we can't be sure that it's safe to call
-    // `comp()(k, k)` otherwise. Even if SFINAE allows it, there could be a
-    // compilation failure inside the implementation of the comparison operator.
-    bool is_self_equivalent(const Key &k) const {
-      // Note: this works for both boolean and three-way comparators.
-      return comp()(k, k) == 0;
-    }
-    // If we can't compare `t` with itself, returns true unconditionally.
-    template <typename T>
-    bool is_self_equivalent(const T &) const {
-      return true;
-    }
-
-   public:
-    using Base::Base;
-    checked_compare(Compare comp) : Base(std::move(comp)) {}  // NOLINT
-
-    // Allow converting to Compare for use in key_comp()/value_comp().
-    explicit operator Compare() const { return comp(); }
-
-    template <typename T, typename U,
-              absl::enable_if_t<
-                  std::is_same<bool, compare_result_t<Compare, T, U>>::value,
-                  int> = 0>
-    bool operator()(const T &lhs, const U &rhs) const {
-      // NOTE: if any of these assertions fail, then the comparator does not
-      // establish a strict-weak-ordering (see
-      // https://en.cppreference.com/w/cpp/named_req/Compare).
-      assert(is_self_equivalent(lhs));
-      assert(is_self_equivalent(rhs));
-      const bool lhs_comp_rhs = comp()(lhs, rhs);
-      assert(!lhs_comp_rhs || !comp()(rhs, lhs));
-      return lhs_comp_rhs;
-    }
-
-    template <
-        typename T, typename U,
-        absl::enable_if_t<std::is_convertible<compare_result_t<Compare, T, U>,
-                                              absl::weak_ordering>::value,
-                          int> = 0>
-    absl::weak_ordering operator()(const T &lhs, const U &rhs) const {
-      // NOTE: if any of these assertions fail, then the comparator does not
-      // establish a strict-weak-ordering (see
-      // https://en.cppreference.com/w/cpp/named_req/Compare).
-      assert(is_self_equivalent(lhs));
-      assert(is_self_equivalent(rhs));
-      const absl::weak_ordering lhs_comp_rhs = comp()(lhs, rhs);
-#ifndef NDEBUG
-      const absl::weak_ordering rhs_comp_lhs = comp()(rhs, lhs);
-      if (lhs_comp_rhs > 0) {
-        assert(rhs_comp_lhs < 0 && "lhs_comp_rhs > 0 -> rhs_comp_lhs < 0");
-      } else if (lhs_comp_rhs == 0) {
-        assert(rhs_comp_lhs == 0 && "lhs_comp_rhs == 0 -> rhs_comp_lhs == 0");
-      } else {
-        assert(rhs_comp_lhs > 0 && "lhs_comp_rhs < 0 -> rhs_comp_lhs > 0");
-      }
-#endif
-      return lhs_comp_rhs;
-    }
-  };
-  using type = absl::conditional_t<
-      std::is_base_of<BtreeTestOnlyCheckedCompareOptOutBase, Compare>::value,
-      Compare, checked_compare>;
+struct key_compare_to_adapter {
+  using type = Compare;
 };
 
 template <>
-struct key_compare_adapter<std::less<std::string>, std::string> {
+struct key_compare_to_adapter<std::less<std::string>> {
   using type = StringBtreeDefaultLess;
 };
 
 template <>
-struct key_compare_adapter<std::greater<std::string>, std::string> {
+struct key_compare_to_adapter<std::greater<std::string>> {
   using type = StringBtreeDefaultGreater;
 };
 
 template <>
-struct key_compare_adapter<std::less<absl::string_view>, absl::string_view> {
+struct key_compare_to_adapter<std::less<absl::string_view>> {
   using type = StringBtreeDefaultLess;
 };
 
 template <>
-struct key_compare_adapter<std::greater<absl::string_view>, absl::string_view> {
+struct key_compare_to_adapter<std::greater<absl::string_view>> {
   using type = StringBtreeDefaultGreater;
 };
 
 template <>
-struct key_compare_adapter<std::less<absl::Cord>, absl::Cord> {
+struct key_compare_to_adapter<std::less<absl::Cord>> {
   using type = StringBtreeDefaultLess;
 };
 
 template <>
-struct key_compare_adapter<std::greater<absl::Cord>, absl::Cord> {
+struct key_compare_to_adapter<std::greater<absl::Cord>> {
   using type = StringBtreeDefaultGreater;
 };
 
@@ -317,13 +224,6 @@
     T, absl::void_t<typename T::absl_btree_prefer_linear_node_search>>
     : T::absl_btree_prefer_linear_node_search {};
 
-template <typename Compare, typename Key>
-constexpr bool compare_has_valid_result_type() {
-  using compare_result_type = compare_result_t<Compare, Key, Key>;
-  return std::is_same<compare_result_type, bool>::value ||
-         std::is_convertible<compare_result_type, absl::weak_ordering>::value;
-}
-
 template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
           bool Multi, typename SlotPolicy>
 struct common_params {
@@ -331,24 +231,7 @@
 
   // If Compare is a common comparator for a string-like type, then we adapt it
   // to use heterogeneous lookup and to be a key-compare-to comparator.
-  // We also adapt the comparator to diagnose invalid comparators in debug mode.
-  // We disable this when `Compare` is invalid in a way that will cause
-  // adaptation to fail (having invalid return type) so that we can give a
-  // better compilation failure in static_assert_validation. If we don't do
-  // this, then there will be cascading compilation failures that are confusing
-  // for users.
-  using key_compare =
-      absl::conditional_t<!compare_has_valid_result_type<Compare, Key>(),
-                          Compare,
-                          typename key_compare_adapter<Compare, Key>::type>;
-
-  static constexpr bool kIsKeyCompareStringAdapted =
-      std::is_same<key_compare, StringBtreeDefaultLess>::value ||
-      std::is_same<key_compare, StringBtreeDefaultGreater>::value;
-  static constexpr bool kIsKeyCompareTransparent =
-      IsTransparent<original_key_compare>::value ||
-      kIsKeyCompareStringAdapted;
-
+  using key_compare = typename key_compare_to_adapter<Compare>::type;
   // A type which indicates if we have a key-compare-to functor or a plain old
   // key-compare functor.
   using is_key_compare_to = btree_is_key_compare_to<key_compare, Key>;
@@ -377,9 +260,11 @@
   //   that we know has the same equivalence classes for all lookup types.
   template <typename LookupKey>
   constexpr static bool can_have_multiple_equivalent_keys() {
-    return Multi || (IsTransparent<key_compare>::value &&
-                     !std::is_same<LookupKey, Key>::value &&
-                     !kIsKeyCompareStringAdapted);
+    return Multi ||
+           (IsTransparent<key_compare>::value &&
+            !std::is_same<LookupKey, Key>::value &&
+            !std::is_same<key_compare, StringBtreeDefaultLess>::value &&
+            !std::is_same<key_compare, StringBtreeDefaultGreater>::value);
   }
 
   enum {
@@ -481,7 +366,6 @@
   using field_type = typename Params::node_count_type;
   using allocator_type = typename Params::allocator_type;
   using slot_type = typename Params::slot_type;
-  using original_key_compare = typename Params::original_key_compare;
 
  public:
   using params_type = Params;
@@ -503,15 +387,15 @@
   //   - Otherwise, choose binary.
   // TODO(ezb): Might make sense to add condition(s) based on node-size.
   using use_linear_search = std::integral_constant<
-      bool, has_linear_node_search_preference<original_key_compare>::value
-                ? prefers_linear_node_search<original_key_compare>::value
-            : has_linear_node_search_preference<key_type>::value
+      bool,
+      has_linear_node_search_preference<key_compare>::value
+          ? prefers_linear_node_search<key_compare>::value
+          : has_linear_node_search_preference<key_type>::value
                 ? prefers_linear_node_search<key_type>::value
                 : std::is_arithmetic<key_type>::value &&
-                      (std::is_same<std::less<key_type>,
-                                    original_key_compare>::value ||
+                      (std::is_same<std::less<key_type>, key_compare>::value ||
                        std::is_same<std::greater<key_type>,
-                                    original_key_compare>::value)>;
+                                    key_compare>::value)>;
 
   // This class is organized by absl::container_internal::Layout as if it had
   // the following structure:
@@ -1937,8 +1821,11 @@
       "target node size too large");
 
   // Verify that key_compare returns an absl::{weak,strong}_ordering or bool.
+  using compare_result_type =
+      absl::result_of_t<key_compare(key_type, key_type)>;
   static_assert(
-      compare_has_valid_result_type<key_compare, key_type>(),
+      std::is_same<compare_result_type, bool>::value ||
+          std::is_convertible<compare_result_type, absl::weak_ordering>::value,
       "key comparison function must return absl::{weak,strong}_ordering or "
       "bool.");
 
diff --git a/third_party/abseil-cpp/absl/container/internal/btree_container.h b/third_party/abseil-cpp/absl/container/internal/btree_container.h
index bae5c6e..d28b244 100644
--- a/third_party/abseil-cpp/absl/container/internal/btree_container.h
+++ b/third_party/abseil-cpp/absl/container/internal/btree_container.h
@@ -44,8 +44,8 @@
   // transparent case.
   template <class K>
   using key_arg =
-      typename KeyArg<params_type::kIsKeyCompareTransparent>::template type<
-          K, typename Tree::key_type>;
+      typename KeyArg<IsTransparent<typename Tree::key_compare>::value>::
+          template type<K, typename Tree::key_type>;
 
  public:
   using key_type = typename Tree::key_type;
diff --git a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc
index 322e054..1d24db5f 100644
--- a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc
+++ b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc
@@ -27,7 +27,6 @@
 #include "absl/profiling/internal/exponential_biased.h"
 #include "absl/profiling/internal/sample_recorder.h"
 #include "absl/synchronization/mutex.h"
-#include "absl/utility/utility.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -54,7 +53,7 @@
 }  // namespace
 
 #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
-ABSL_PER_THREAD_TLS_KEYWORD SamplingState global_next_sample = {0, 0};
+ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0;
 #endif  // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
 
 HashtablezSampler& GlobalHashtablezSampler() {
@@ -65,8 +64,7 @@
 HashtablezInfo::HashtablezInfo() = default;
 HashtablezInfo::~HashtablezInfo() = default;
 
-void HashtablezInfo::PrepareForSampling(int64_t stride,
-                                        size_t inline_element_size_value) {
+void HashtablezInfo::PrepareForSampling(size_t inline_element_size_value) {
   capacity.store(0, std::memory_order_relaxed);
   size.store(0, std::memory_order_relaxed);
   num_erases.store(0, std::memory_order_relaxed);
@@ -79,7 +77,6 @@
   max_reserve.store(0, std::memory_order_relaxed);
 
   create_time = absl::Now();
-  weight = stride;
   // The inliner makes hardcoded skip_count difficult (especially when combined
   // with LTO).  We use the ability to exclude stacks by regex when encoding
   // instead.
@@ -108,32 +105,23 @@
   return state == kForce;
 }
 
-HashtablezInfo* SampleSlow(SamplingState& next_sample,
-                           size_t inline_element_size) {
+HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size) {
   if (ABSL_PREDICT_FALSE(ShouldForceSampling())) {
-    next_sample.next_sample = 1;
-    const int64_t old_stride = exchange(next_sample.sample_stride, 1);
+    *next_sample = 1;
     HashtablezInfo* result =
-        GlobalHashtablezSampler().Register(old_stride, inline_element_size);
+        GlobalHashtablezSampler().Register(inline_element_size);
     return result;
   }
 
 #if !defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
-  next_sample = {
-      std::numeric_limits<int64_t>::max(),
-      std::numeric_limits<int64_t>::max(),
-  };
+  *next_sample = std::numeric_limits<int64_t>::max();
   return nullptr;
 #else
-  bool first = next_sample.next_sample < 0;
-
-  const int64_t next_stride = g_exponential_biased_generator.GetStride(
+  bool first = *next_sample < 0;
+  *next_sample = g_exponential_biased_generator.GetStride(
       g_hashtablez_sample_parameter.load(std::memory_order_relaxed));
-
-  next_sample.next_sample = next_stride;
-  const int64_t old_stride = exchange(next_sample.sample_stride, next_stride);
   // Small values of interval are equivalent to just sampling next time.
-  ABSL_ASSERT(next_stride >= 1);
+  ABSL_ASSERT(*next_sample >= 1);
 
   // g_hashtablez_enabled can be dynamically flipped, we need to set a threshold
   // low enough that we will start sampling in a reasonable time, so we just use
@@ -143,11 +131,11 @@
   // We will only be negative on our first count, so we should just retry in
   // that case.
   if (first) {
-    if (ABSL_PREDICT_TRUE(--next_sample.next_sample > 0)) return nullptr;
+    if (ABSL_PREDICT_TRUE(--*next_sample > 0)) return nullptr;
     return SampleSlow(next_sample, inline_element_size);
   }
 
-  return GlobalHashtablezSampler().Register(old_stride, inline_element_size);
+  return GlobalHashtablezSampler().Register(inline_element_size);
 #endif
 }
 
diff --git a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
index e7c204e..6738786c 100644
--- a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
+++ b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
@@ -67,7 +67,7 @@
 
   // Puts the object into a clean state, fills in the logically `const` members,
   // blocking for any readers that are currently sampling the object.
-  void PrepareForSampling(int64_t stride, size_t inline_element_size_value)
+  void PrepareForSampling(size_t inline_element_size_value)
       ABSL_EXCLUSIVE_LOCKS_REQUIRED(init_mu);
 
   // These fields are mutated by the various Record* APIs and need to be
@@ -145,15 +145,7 @@
       std::memory_order_relaxed);
 }
 
-struct SamplingState {
-  int64_t next_sample;
-  // When we make a sampling decision, we record that distance so we can weight
-  // each sample.
-  int64_t sample_stride;
-};
-
-HashtablezInfo* SampleSlow(SamplingState& next_sample,
-                           size_t inline_element_size);
+HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size);
 void UnsampleSlow(HashtablezInfo* info);
 
 #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
@@ -243,7 +235,7 @@
 #endif  // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
 
 #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
-extern ABSL_PER_THREAD_TLS_KEYWORD SamplingState global_next_sample;
+extern ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample;
 #endif  // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
 
 // Returns an RAII sampling handle that manages registration and unregistation
@@ -251,11 +243,11 @@
 inline HashtablezInfoHandle Sample(
     size_t inline_element_size ABSL_ATTRIBUTE_UNUSED) {
 #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
-  if (ABSL_PREDICT_TRUE(--global_next_sample.next_sample > 0)) {
+  if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) {
     return HashtablezInfoHandle(nullptr);
   }
   return HashtablezInfoHandle(
-      SampleSlow(global_next_sample, inline_element_size));
+      SampleSlow(&global_next_sample, inline_element_size));
 #else
   return HashtablezInfoHandle(nullptr);
 #endif  // !ABSL_PER_THREAD_TLS
diff --git a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
index 77cdf2f..ac6ed9b 100644
--- a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
+++ b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
@@ -70,9 +70,8 @@
 }
 
 HashtablezInfo* Register(HashtablezSampler* s, size_t size) {
-  const int64_t test_stride = 123;
   const size_t test_element_size = 17;
-  auto* info = s->Register(test_stride, test_element_size);
+  auto* info = s->Register(test_element_size);
   assert(info != nullptr);
   info->size.store(size);
   return info;
@@ -80,11 +79,10 @@
 
 TEST(HashtablezInfoTest, PrepareForSampling) {
   absl::Time test_start = absl::Now();
-  const int64_t test_stride = 123;
   const size_t test_element_size = 17;
   HashtablezInfo info;
   absl::MutexLock l(&info.init_mu);
-  info.PrepareForSampling(test_stride, test_element_size);
+  info.PrepareForSampling(test_element_size);
 
   EXPECT_EQ(info.capacity.load(), 0);
   EXPECT_EQ(info.size.load(), 0);
@@ -97,7 +95,6 @@
   EXPECT_EQ(info.hashes_bitwise_xor.load(), 0);
   EXPECT_EQ(info.max_reserve.load(), 0);
   EXPECT_GE(info.create_time, test_start);
-  EXPECT_EQ(info.weight, test_stride);
   EXPECT_EQ(info.inline_element_size, test_element_size);
 
   info.capacity.store(1, std::memory_order_relaxed);
@@ -111,7 +108,7 @@
   info.max_reserve.store(1, std::memory_order_relaxed);
   info.create_time = test_start - absl::Hours(20);
 
-  info.PrepareForSampling(test_stride * 2, test_element_size);
+  info.PrepareForSampling(test_element_size);
   EXPECT_EQ(info.capacity.load(), 0);
   EXPECT_EQ(info.size.load(), 0);
   EXPECT_EQ(info.num_erases.load(), 0);
@@ -122,7 +119,6 @@
   EXPECT_EQ(info.hashes_bitwise_and.load(), ~size_t{});
   EXPECT_EQ(info.hashes_bitwise_xor.load(), 0);
   EXPECT_EQ(info.max_reserve.load(), 0);
-  EXPECT_EQ(info.weight, 2 * test_stride);
   EXPECT_EQ(info.inline_element_size, test_element_size);
   EXPECT_GE(info.create_time, test_start);
 }
@@ -130,9 +126,8 @@
 TEST(HashtablezInfoTest, RecordStorageChanged) {
   HashtablezInfo info;
   absl::MutexLock l(&info.init_mu);
-  const int64_t test_stride = 21;
   const size_t test_element_size = 19;
-  info.PrepareForSampling(test_stride, test_element_size);
+  info.PrepareForSampling(test_element_size);
   RecordStorageChangedSlow(&info, 17, 47);
   EXPECT_EQ(info.size.load(), 17);
   EXPECT_EQ(info.capacity.load(), 47);
@@ -144,9 +139,8 @@
 TEST(HashtablezInfoTest, RecordInsert) {
   HashtablezInfo info;
   absl::MutexLock l(&info.init_mu);
-  const int64_t test_stride = 25;
   const size_t test_element_size = 23;
-  info.PrepareForSampling(test_stride, test_element_size);
+  info.PrepareForSampling(test_element_size);
   EXPECT_EQ(info.max_probe_length.load(), 0);
   RecordInsertSlow(&info, 0x0000FF00, 6 * kProbeLength);
   EXPECT_EQ(info.max_probe_length.load(), 6);
@@ -166,11 +160,10 @@
 }
 
 TEST(HashtablezInfoTest, RecordErase) {
-  const int64_t test_stride = 31;
   const size_t test_element_size = 29;
   HashtablezInfo info;
   absl::MutexLock l(&info.init_mu);
-  info.PrepareForSampling(test_stride, test_element_size);
+  info.PrepareForSampling(test_element_size);
   EXPECT_EQ(info.num_erases.load(), 0);
   EXPECT_EQ(info.size.load(), 0);
   RecordInsertSlow(&info, 0x0000FF00, 6 * kProbeLength);
@@ -182,11 +175,10 @@
 }
 
 TEST(HashtablezInfoTest, RecordRehash) {
-  const int64_t test_stride = 33;
   const size_t test_element_size = 31;
   HashtablezInfo info;
   absl::MutexLock l(&info.init_mu);
-  info.PrepareForSampling(test_stride, test_element_size);
+  info.PrepareForSampling(test_element_size);
   RecordInsertSlow(&info, 0x1, 0);
   RecordInsertSlow(&info, 0x2, kProbeLength);
   RecordInsertSlow(&info, 0x4, kProbeLength);
@@ -211,9 +203,8 @@
 TEST(HashtablezInfoTest, RecordReservation) {
   HashtablezInfo info;
   absl::MutexLock l(&info.init_mu);
-  const int64_t test_stride = 35;
   const size_t test_element_size = 33;
-  info.PrepareForSampling(test_stride, test_element_size);
+  info.PrepareForSampling(test_element_size);
   RecordReservationSlow(&info, 3);
   EXPECT_EQ(info.max_reserve.load(), 3);
 
@@ -233,10 +224,9 @@
   SetHashtablezSampleParameter(100);
 
   for (int i = 0; i < 1000; ++i) {
-    SamplingState next_sample = {0, 0};
-    HashtablezInfo* sample = SampleSlow(next_sample, test_element_size);
-    EXPECT_GT(next_sample.next_sample, 0);
-    EXPECT_EQ(next_sample.next_sample, next_sample.sample_stride);
+    int64_t next_sample = 0;
+    HashtablezInfo* sample = SampleSlow(&next_sample, test_element_size);
+    EXPECT_GT(next_sample, 0);
     EXPECT_NE(sample, nullptr);
     UnsampleSlow(sample);
   }
@@ -248,10 +238,9 @@
   SetHashtablezSampleParameter(std::numeric_limits<int32_t>::max());
 
   for (int i = 0; i < 1000; ++i) {
-    SamplingState next_sample = {0, 0};
-    HashtablezInfo* sample = SampleSlow(next_sample, test_element_size);
-    EXPECT_GT(next_sample.next_sample, 0);
-    EXPECT_EQ(next_sample.next_sample, next_sample.sample_stride);
+    int64_t next_sample = 0;
+    HashtablezInfo* sample = SampleSlow(&next_sample, test_element_size);
+    EXPECT_GT(next_sample, 0);
     EXPECT_NE(sample, nullptr);
     UnsampleSlow(sample);
   }
@@ -278,16 +267,14 @@
 
 TEST(HashtablezSamplerTest, Handle) {
   auto& sampler = GlobalHashtablezSampler();
-  const int64_t test_stride = 41;
   const size_t test_element_size = 39;
-  HashtablezInfoHandle h(sampler.Register(test_stride, test_element_size));
+  HashtablezInfoHandle h(sampler.Register(test_element_size));
   auto* info = HashtablezInfoHandlePeer::GetInfo(&h);
   info->hashes_bitwise_and.store(0x12345678, std::memory_order_relaxed);
 
   bool found = false;
   sampler.Iterate([&](const HashtablezInfo& h) {
     if (&h == info) {
-      EXPECT_EQ(h.weight, test_stride);
       EXPECT_EQ(h.hashes_bitwise_and.load(), 0x12345678);
       found = true;
     }
@@ -353,20 +340,19 @@
   ThreadPool pool(10);
 
   for (int i = 0; i < 10; ++i) {
-    const int64_t sampling_stride = 11 + i % 3;
     const size_t elt_size = 10 + i % 2;
-    pool.Schedule([&sampler, &stop, sampling_stride, elt_size]() {
+    pool.Schedule([&sampler, &stop, elt_size]() {
       std::random_device rd;
       std::mt19937 gen(rd());
 
       std::vector<HashtablezInfo*> infoz;
       while (!stop.HasBeenNotified()) {
         if (infoz.empty()) {
-          infoz.push_back(sampler.Register(sampling_stride, elt_size));
+          infoz.push_back(sampler.Register(elt_size));
         }
         switch (std::uniform_int_distribution<>(0, 2)(gen)) {
           case 0: {
-            infoz.push_back(sampler.Register(sampling_stride, elt_size));
+            infoz.push_back(sampler.Register(elt_size));
             break;
           }
           case 1: {
@@ -375,7 +361,6 @@
             HashtablezInfo* info = infoz[p];
             infoz[p] = infoz.back();
             infoz.pop_back();
-            EXPECT_EQ(info->weight, sampling_stride);
             sampler.Unregister(info);
             break;
           }
diff --git a/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h b/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h
index 93a3fa8..1157d25a 100644
--- a/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h
+++ b/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h
@@ -1539,14 +1539,6 @@
     return !(a == b);
   }
 
-  template <typename H>
-  friend typename std::enable_if<H::template is_hashable<value_type>::value,
-                                 H>::type
-  AbslHashValue(H h, const raw_hash_set& s) {
-    return H::combine(H::combine_unordered(std::move(h), s.begin(), s.end()),
-                      s.size());
-  }
-
   friend void swap(raw_hash_set& a,
                    raw_hash_set& b) noexcept(noexcept(a.swap(b))) {
     a.swap(b);
diff --git a/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc b/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
index 47015bcf..362b3ca 100644
--- a/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
+++ b/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
@@ -1244,7 +1244,7 @@
     case 16:
       if (kRandomizesInserts) {
         return {0.1,
-                2.0,
+                1.0,
                 {{0.95, 0.1}},
                 {{0.95, 0}, {0.99, 1}, {0.999, 8}, {0.9999, 15}}};
       } else {
@@ -1258,7 +1258,7 @@
   return {};
 }
 
-TEST(Table, EnsureNonQuadraticTopNXorSeedByProbeSeqLength) {
+TEST(Table, DISABLED_EnsureNonQuadraticTopNXorSeedByProbeSeqLength) {
   ProbeStatsPerSize stats;
   std::vector<size_t> sizes = {Group::kWidth << 5, Group::kWidth << 10};
   for (size_t size : sizes) {
@@ -1330,17 +1330,17 @@
                 {{0.95, 0.3}},
                 {{0.95, 0}, {0.99, 1}, {0.999, 8}, {0.9999, 15}}};
       } else {
-        return {0.4,
-                0.6,
-                {{0.95, 0.5}},
-                {{0.95, 1}, {0.99, 14}, {0.999, 23}, {0.9999, 26}}};
+        return {0.15,
+                0.5,
+                {{0.95, 0.3}},
+                {{0.95, 0}, {0.99, 3}, {0.999, 15}, {0.9999, 25}}};
       }
     case 16:
       if (kRandomizesInserts) {
         return {0.1,
                 0.4,
                 {{0.95, 0.3}},
-                {{0.95, 1}, {0.99, 2}, {0.999, 9}, {0.9999, 15}}};
+                {{0.95, 0}, {0.99, 1}, {0.999, 8}, {0.9999, 15}}};
       } else {
         return {0.05,
                 0.2,
@@ -1352,7 +1352,7 @@
   return {};
 }
 
-TEST(Table, EnsureNonQuadraticTopNLinearTransformByProbeSeqLength) {
+TEST(Table, DISABLED_EnsureNonQuadraticTopNLinearTransformByProbeSeqLength) {
   ProbeStatsPerSize stats;
   std::vector<size_t> sizes = {Group::kWidth << 5, Group::kWidth << 10};
   for (size_t size : sizes) {
diff --git a/third_party/abseil-cpp/absl/hash/BUILD.bazel b/third_party/abseil-cpp/absl/hash/BUILD.bazel
index bcc316f..f0640d34 100644
--- a/third_party/abseil-cpp/absl/hash/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/hash/BUILD.bazel
@@ -41,7 +41,6 @@
         "//absl/base:core_headers",
         "//absl/base:endian",
         "//absl/container:fixed_array",
-        "//absl/functional:function_ref",
         "//absl/meta:type_traits",
         "//absl/numeric:int128",
         "//absl/strings",
@@ -75,11 +74,7 @@
         ":hash_testing",
         ":spy_hash_state",
         "//absl/base:core_headers",
-        "//absl/container:btree",
-        "//absl/container:flat_hash_map",
         "//absl/container:flat_hash_set",
-        "//absl/container:node_hash_map",
-        "//absl/container:node_hash_set",
         "//absl/meta:type_traits",
         "//absl/numeric:int128",
         "//absl/strings:cord_test_helpers",
@@ -98,7 +93,6 @@
     deps = [
         ":hash",
         "//absl/base:core_headers",
-        "//absl/container:flat_hash_set",
         "//absl/random",
         "//absl/strings",
         "//absl/strings:cord",
diff --git a/third_party/abseil-cpp/absl/hash/BUILD.gn b/third_party/abseil-cpp/absl/hash/BUILD.gn
index d05a270a..bec226c 100644
--- a/third_party/abseil-cpp/absl/hash/BUILD.gn
+++ b/third_party/abseil-cpp/absl/hash/BUILD.gn
@@ -18,7 +18,6 @@
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/base:endian",
     "//third_party/abseil-cpp/absl/container:fixed_array",
-    "//third_party/abseil-cpp/absl/functional:function_ref",
     "//third_party/abseil-cpp/absl/meta:type_traits",
     "//third_party/abseil-cpp/absl/numeric:int128",
     "//third_party/abseil-cpp/absl/strings",
@@ -40,27 +39,6 @@
   ]
 }
 
-absl_source_set("hash_test") {
-  testonly = true
-  sources = [ "hash_test.cc" ]
-  deps = [
-    ":hash",
-    ":hash_testing",
-    ":spy_hash_state",
-    "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/container:btree",
-    "//third_party/abseil-cpp/absl/container:flat_hash_map",
-    "//third_party/abseil-cpp/absl/container:flat_hash_set",
-    "//third_party/abseil-cpp/absl/container:node_hash_map",
-    "//third_party/abseil-cpp/absl/container:node_hash_set",
-    "//third_party/abseil-cpp/absl/meta:type_traits",
-    "//third_party/abseil-cpp/absl/numeric:int128",
-    "//third_party/abseil-cpp/absl/strings:cord_test_helpers",
-    "//third_party/googletest:gtest",
-    "//third_party/googletest:gmock",
-  ]
-}
-
 absl_source_set("spy_hash_state") {
   testonly = true
   public = [ "internal/spy_hash_state.h" ]
diff --git a/third_party/abseil-cpp/absl/hash/CMakeLists.txt b/third_party/abseil-cpp/absl/hash/CMakeLists.txt
index 34434fa..5916ae3c 100644
--- a/third_party/abseil-cpp/absl/hash/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/hash/CMakeLists.txt
@@ -30,7 +30,6 @@
     absl::core_headers
     absl::endian
     absl::fixed_array
-    absl::function_ref
     absl::meta
     absl::int128
     absl::strings
@@ -69,11 +68,7 @@
     absl::hash
     absl::hash_testing
     absl::core_headers
-    absl::btree
-    absl::flat_hash_map
     absl::flat_hash_set
-    absl::node_hash_map
-    absl::node_hash_set
     absl::spy_hash_state
     absl::meta
     absl::int128
diff --git a/third_party/abseil-cpp/absl/hash/hash.h b/third_party/abseil-cpp/absl/hash/hash.h
index f31fde4..8282ea5 100644
--- a/third_party/abseil-cpp/absl/hash/hash.h
+++ b/third_party/abseil-cpp/absl/hash/hash.h
@@ -26,9 +26,9 @@
 //     support Abseil hashing without requiring you to define a hashing
 //     algorithm.
 //   * `HashState`, a type-erased class which implements the manipulation of the
-//     hash state (H) itself; contains member functions `combine()`,
-//     `combine_contiguous()`, and `combine_unordered()`; and which you can use
-//     to contribute to an existing hash state when hashing your types.
+//     hash state (H) itself, contains member functions `combine()` and
+//     `combine_contiguous()`, which you can use to contribute to an existing
+//     hash state when hashing your types.
 //
 // Unlike `std::hash` or other hashing frameworks, the Abseil hashing framework
 // provides most of its utility by abstracting away the hash algorithm (and its
@@ -74,9 +74,7 @@
 #define ABSL_HASH_HASH_H_
 
 #include <tuple>
-#include <utility>
 
-#include "absl/functional/function_ref.h"
 #include "absl/hash/internal/hash.h"
 
 namespace absl {
@@ -109,27 +107,14 @@
 //     * std::string_view (as well as any instance of std::basic_string that
 //       uses char and std::char_traits)
 //  * All the standard sequence containers (provided the elements are hashable)
-//  * All the standard associative containers (provided the elements are
+//  * All the standard ordered associative containers (provided the elements are
 //    hashable)
 //  * absl types such as the following:
 //    * absl::string_view
-//    * absl::uint128
-//    * absl::Time, absl::Duration, and absl::TimeZone
-//  * absl containers (provided the elements are hashable) such as the
-//    following:
-//    * absl::flat_hash_set, absl::node_hash_set, absl::btree_set
-//    * absl::flat_hash_map, absl::node_hash_map, absl::btree_map
-//    * absl::btree_multiset, absl::btree_multimap
 //    * absl::InlinedVector
 //    * absl::FixedArray
-//
-// When absl::Hash is used to hash an unordered container with a custom hash
-// functor, the elements are hashed using default absl::Hash semantics, not
-// the custom hash functor.  This is consistent with the behavior of
-// operator==() on unordered containers, which compares elements pairwise with
-// operator==() rather than the custom equality functor.  It is usually a
-// mistake to use either operator==() or absl::Hash on unordered collections
-// that use functors incompatible with operator==() equality.
+//    * absl::uint128
+//    * absl::Time, absl::Duration, and absl::TimeZone
 //
 // Note: the list above is not meant to be exhaustive. Additional type support
 // may be added, in which case the above list will be updated.
@@ -168,8 +153,7 @@
 //   that are otherwise difficult to extend using `AbslHashValue()`. (See the
 //   `HashState` class below.)
 //
-// The "hash state" concept contains three member functions for mixing hash
-// state:
+// The "hash state" concept contains two member functions for mixing hash state:
 //
 // * `H::combine(state, values...)`
 //
@@ -203,15 +187,6 @@
 //    (it may perform internal optimizations). If you need this guarantee, use a
 //    loop instead.
 //
-// * `H::combine_unordered(state, begin, end)`
-//
-//    Combines a set of elements denoted by an iterator pair into a hash
-//    state, returning the updated state.  Note that the existing hash
-//    state is move-only and must be passed by value.
-//
-//    Unlike the other two methods, the hashing is order-independent.
-//    This can be used to hash unordered collections.
-//
 // -----------------------------------------------------------------------------
 // Adding Type Support to `absl::Hash`
 // -----------------------------------------------------------------------------
@@ -268,9 +243,8 @@
 // classes, virtual functions, etc.). The type erasure adds overhead so it
 // should be avoided unless necessary.
 //
-// Note: This wrapper will only erase calls to
+// Note: This wrapper will only erase calls to:
 //     combine_contiguous(H, const unsigned char*, size_t)
-//     RunCombineUnordered(H, CombinerF)
 //
 // All other calls will be handled internally and will not invoke overloads
 // provided by the wrapped class.
@@ -344,8 +318,6 @@
  private:
   HashState() = default;
 
-  friend class HashState::HashStateBase;
-
   template <typename T>
   static void CombineContiguousImpl(void* p, const unsigned char* first,
                                     size_t size) {
@@ -357,57 +329,16 @@
   void Init(T* state) {
     state_ = state;
     combine_contiguous_ = &CombineContiguousImpl<T>;
-    run_combine_unordered_ = &RunCombineUnorderedImpl<T>;
-  }
-
-  template <typename HS>
-  struct CombineUnorderedInvoker {
-    template <typename T, typename ConsumerT>
-    void operator()(T inner_state, ConsumerT inner_cb) {
-      f(HashState::Create(&inner_state),
-        [&](HashState& inner_erased) { inner_cb(inner_erased.Real<T>()); });
-    }
-
-    absl::FunctionRef<void(HS, absl::FunctionRef<void(HS&)>)> f;
-  };
-
-  template <typename T>
-  static HashState RunCombineUnorderedImpl(
-      HashState state,
-      absl::FunctionRef<void(HashState, absl::FunctionRef<void(HashState&)>)>
-          f) {
-    // Note that this implementation assumes that inner_state and outer_state
-    // are the same type.  This isn't true in the SpyHash case, but SpyHash
-    // types are move-convertible to each other, so this still works.
-    T& real_state = state.Real<T>();
-    real_state = T::RunCombineUnordered(
-        std::move(real_state), CombineUnorderedInvoker<HashState>{f});
-    return state;
-  }
-
-  template <typename CombinerT>
-  static HashState RunCombineUnordered(HashState state, CombinerT combiner) {
-    auto* run = state.run_combine_unordered_;
-    return run(std::move(state), std::ref(combiner));
   }
 
   // Do not erase an already erased state.
   void Init(HashState* state) {
     state_ = state->state_;
     combine_contiguous_ = state->combine_contiguous_;
-    run_combine_unordered_ = state->run_combine_unordered_;
-  }
-
-  template <typename T>
-  T& Real() {
-    return *static_cast<T*>(state_);
   }
 
   void* state_;
   void (*combine_contiguous_)(void*, const unsigned char*, size_t);
-  HashState (*run_combine_unordered_)(
-      HashState state,
-      absl::FunctionRef<void(HashState, absl::FunctionRef<void(HashState&)>)>);
 };
 
 ABSL_NAMESPACE_END
diff --git a/third_party/abseil-cpp/absl/hash/hash_benchmark.cc b/third_party/abseil-cpp/absl/hash/hash_benchmark.cc
index 8712a01..d498ac2 100644
--- a/third_party/abseil-cpp/absl/hash/hash_benchmark.cc
+++ b/third_party/abseil-cpp/absl/hash/hash_benchmark.cc
@@ -19,7 +19,6 @@
 #include <vector>
 
 #include "absl/base/attributes.h"
-#include "absl/container/flat_hash_set.h"
 #include "absl/hash/hash.h"
 #include "absl/random/random.h"
 #include "absl/strings/cord.h"
@@ -108,44 +107,6 @@
   return result;
 }
 
-template <typename T>
-std::vector<T> Vector(size_t count) {
-  std::vector<T> result;
-  for (size_t v = 0; v < count; ++v) {
-    result.push_back(v);
-  }
-  return result;
-}
-
-// Bogus type that replicates an unorderd_set's bit mixing, but with
-// vector-speed iteration. This is intended to measure the overhead of unordered
-// hashing without counting the speed of unordered_set iteration.
-template <typename T>
-struct FastUnorderedSet {
-  explicit FastUnorderedSet(size_t count) {
-    for (size_t v = 0; v < count; ++v) {
-      values.push_back(v);
-    }
-  }
-  std::vector<T> values;
-
-  template <typename H>
-  friend H AbslHashValue(H h, const FastUnorderedSet& fus) {
-    return H::combine(H::combine_unordered(std::move(h), fus.values.begin(),
-                                           fus.values.end()),
-                      fus.values.size());
-  }
-};
-
-template <typename T>
-absl::flat_hash_set<T> FlatHashSet(size_t count) {
-  absl::flat_hash_set<T> result;
-  for (size_t v = 0; v < count; ++v) {
-    result.insert(v);
-  }
-  return result;
-}
-
 // Generates a benchmark and a codegen method for the provided types.  The
 // codegen method provides a well known entrypoint for dumping assembly.
 #define MAKE_BENCHMARK(hash, name, ...)                          \
@@ -184,22 +145,10 @@
 MAKE_BENCHMARK(AbslHash, Cord_Flat_5000, FlatCord(5000));
 MAKE_BENCHMARK(AbslHash, Cord_Fragmented_200, FragmentedCord(200));
 MAKE_BENCHMARK(AbslHash, Cord_Fragmented_5000, FragmentedCord(5000));
-MAKE_BENCHMARK(AbslHash, VectorInt64_10, Vector<int64_t>(10));
-MAKE_BENCHMARK(AbslHash, VectorInt64_100, Vector<int64_t>(100));
-MAKE_BENCHMARK(AbslHash, VectorInt64_1000, Vector<int64_t>(1000));
-MAKE_BENCHMARK(AbslHash, VectorDouble_10, Vector<double>(10));
-MAKE_BENCHMARK(AbslHash, VectorDouble_100, Vector<double>(100));
-MAKE_BENCHMARK(AbslHash, VectorDouble_1000, Vector<double>(1000));
-MAKE_BENCHMARK(AbslHash, FlatHashSetInt64_10, FlatHashSet<int64_t>(10));
-MAKE_BENCHMARK(AbslHash, FlatHashSetInt64_100, FlatHashSet<int64_t>(100));
-MAKE_BENCHMARK(AbslHash, FlatHashSetInt64_1000, FlatHashSet<int64_t>(1000));
-MAKE_BENCHMARK(AbslHash, FlatHashSetDouble_10, FlatHashSet<double>(10));
-MAKE_BENCHMARK(AbslHash, FlatHashSetDouble_100, FlatHashSet<double>(100));
-MAKE_BENCHMARK(AbslHash, FlatHashSetDouble_1000, FlatHashSet<double>(1000));
-MAKE_BENCHMARK(AbslHash, FastUnorderedSetInt64_1000,
-               FastUnorderedSet<int64_t>(1000));
-MAKE_BENCHMARK(AbslHash, FastUnorderedSetDouble_1000,
-               FastUnorderedSet<double>(1000));
+MAKE_BENCHMARK(AbslHash, VectorInt64_10, std::vector<int64_t>(10));
+MAKE_BENCHMARK(AbslHash, VectorInt64_100, std::vector<int64_t>(100));
+MAKE_BENCHMARK(AbslHash, VectorDouble_10, std::vector<double>(10, 1.1));
+MAKE_BENCHMARK(AbslHash, VectorDouble_100, std::vector<double>(100, 1.1));
 MAKE_BENCHMARK(AbslHash, PairStringString_0,
                std::make_pair(std::string(), std::string()));
 MAKE_BENCHMARK(AbslHash, PairStringString_10,
@@ -231,24 +180,6 @@
                std::vector<double>(10, 1.1));
 MAKE_BENCHMARK(TypeErasedAbslHash, VectorDouble_100,
                std::vector<double>(100, 1.1));
-MAKE_BENCHMARK(TypeErasedAbslHash, VectorDouble_1000,
-               std::vector<double>(1000, 1.1));
-MAKE_BENCHMARK(TypeErasedAbslHash, FlatHashSetInt64_10,
-               FlatHashSet<int64_t>(10));
-MAKE_BENCHMARK(TypeErasedAbslHash, FlatHashSetInt64_100,
-               FlatHashSet<int64_t>(100));
-MAKE_BENCHMARK(TypeErasedAbslHash, FlatHashSetInt64_1000,
-               FlatHashSet<int64_t>(1000));
-MAKE_BENCHMARK(TypeErasedAbslHash, FlatHashSetDouble_10,
-               FlatHashSet<double>(10));
-MAKE_BENCHMARK(TypeErasedAbslHash, FlatHashSetDouble_100,
-               FlatHashSet<double>(100));
-MAKE_BENCHMARK(TypeErasedAbslHash, FlatHashSetDouble_1000,
-               FlatHashSet<double>(1000));
-MAKE_BENCHMARK(TypeErasedAbslHash, FastUnorderedSetInt64_1000,
-               FastUnorderedSet<int64_t>(1000));
-MAKE_BENCHMARK(TypeErasedAbslHash, FastUnorderedSetDouble_1000,
-               FastUnorderedSet<double>(1000));
 
 // The latency benchmark attempts to model the speed of the hash function in
 // production. When a hash function is used for hashtable lookups it is rarely
diff --git a/third_party/abseil-cpp/absl/hash/hash_test.cc b/third_party/abseil-cpp/absl/hash/hash_test.cc
index 39ff8f5..dbfacb2 100644
--- a/third_party/abseil-cpp/absl/hash/hash_test.cc
+++ b/third_party/abseil-cpp/absl/hash/hash_test.cc
@@ -34,18 +34,12 @@
 #include <tuple>
 #include <type_traits>
 #include <unordered_map>
-#include <unordered_set>
 #include <utility>
 #include <vector>
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/container/btree_map.h"
-#include "absl/container/btree_set.h"
-#include "absl/container/flat_hash_map.h"
 #include "absl/container/flat_hash_set.h"
-#include "absl/container/node_hash_map.h"
-#include "absl/container/node_hash_set.h"
 #include "absl/hash/hash_testing.h"
 #include "absl/hash/internal/spy_hash_state.h"
 #include "absl/meta/type_traits.h"
@@ -139,10 +133,10 @@
             absl::Hash<std::tuple<TypeParam>>{}(std::tuple<TypeParam>(n)));
 }
 
-REGISTER_TYPED_TEST_SUITE_P(HashValueIntTest, BasicUsage, FastPath);
+REGISTER_TYPED_TEST_CASE_P(HashValueIntTest, BasicUsage, FastPath);
 using IntTypes = testing::Types<unsigned char, char, int, int32_t, int64_t,
                                 uint32_t, uint64_t, size_t>;
-INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueIntTest, IntTypes);
+INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueIntTest, IntTypes);
 
 enum LegacyEnum { kValue1, kValue2, kValue3 };
 
@@ -439,52 +433,6 @@
        std::bitset<kNumBits>(bit_strings[5].c_str())}));
 }  // namespace
 
-// Dummy type with unordered equality and hashing semantics.  This preserves
-// input order internally, and is used below to ensure we get test coverage
-// for equal sequences with different iteraton orders.
-template <typename T>
-class UnorderedSequence {
- public:
-  UnorderedSequence() = default;
-  template <typename TT>
-  UnorderedSequence(std::initializer_list<TT> l)
-      : values_(l.begin(), l.end()) {}
-  template <typename ForwardIterator,
-            typename std::enable_if<!std::is_integral<ForwardIterator>::value,
-                                    bool>::type = true>
-  UnorderedSequence(ForwardIterator begin, ForwardIterator end)
-      : values_(begin, end) {}
-  // one-argument constructor of value type T, to appease older toolchains that
-  // get confused by one-element initializer lists in some contexts
-  explicit UnorderedSequence(const T& v) : values_(&v, &v + 1) {}
-
-  using value_type = T;
-
-  size_t size() const { return values_.size(); }
-  typename std::vector<T>::const_iterator begin() const {
-    return values_.begin();
-  }
-  typename std::vector<T>::const_iterator end() const { return values_.end(); }
-
-  friend bool operator==(const UnorderedSequence& lhs,
-                         const UnorderedSequence& rhs) {
-    return lhs.size() == rhs.size() &&
-           std::is_permutation(lhs.begin(), lhs.end(), rhs.begin());
-  }
-  friend bool operator!=(const UnorderedSequence& lhs,
-                         const UnorderedSequence& rhs) {
-    return !(lhs == rhs);
-  }
-  template <typename H>
-  friend H AbslHashValue(H h, const UnorderedSequence& u) {
-    return H::combine(H::combine_unordered(std::move(h), u.begin(), u.end()),
-                      u.size());
-  }
-
- private:
-  std::vector<T> values_;
-};
-
 template <typename T>
 class HashValueSequenceTest : public testing::Test {
 };
@@ -507,15 +455,12 @@
   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars));
 }
 
-REGISTER_TYPED_TEST_SUITE_P(HashValueSequenceTest, BasicUsage);
-using IntSequenceTypes = testing::Types<
-    std::deque<int>, std::forward_list<int>, std::list<int>, std::vector<int>,
-    std::vector<bool>, TypeErasedContainer<std::vector<int>>, std::set<int>,
-    std::multiset<int>, UnorderedSequence<int>,
-    TypeErasedContainer<UnorderedSequence<int>>, std::unordered_set<int>,
-    std::unordered_multiset<int>, absl::flat_hash_set<int>,
-    absl::node_hash_set<int>, absl::btree_set<int>>;
-INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueSequenceTest, IntSequenceTypes);
+REGISTER_TYPED_TEST_CASE_P(HashValueSequenceTest, BasicUsage);
+using IntSequenceTypes =
+    testing::Types<std::deque<int>, std::forward_list<int>, std::list<int>,
+                   std::vector<int>, std::vector<bool>, TypeErasedVector<int>,
+                   TypeErasedVector<bool>, std::set<int>, std::multiset<int>>;
+INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueSequenceTest, IntSequenceTypes);
 
 template <typename T>
 class HashValueNestedSequenceTest : public testing::Test {};
@@ -541,17 +486,13 @@
   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars));
 }
 
-REGISTER_TYPED_TEST_SUITE_P(HashValueNestedSequenceTest, BasicUsage);
-template <typename T>
-using TypeErasedSet = TypeErasedContainer<UnorderedSequence<T>>;
-
-using NestedIntSequenceTypes = testing::Types<
-    std::vector<std::vector<int>>, std::vector<UnorderedSequence<int>>,
-    std::vector<TypeErasedSet<int>>, UnorderedSequence<std::vector<int>>,
-    UnorderedSequence<UnorderedSequence<int>>,
-    UnorderedSequence<TypeErasedSet<int>>, TypeErasedSet<std::vector<int>>,
-    TypeErasedSet<UnorderedSequence<int>>, TypeErasedSet<TypeErasedSet<int>>>;
-INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueNestedSequenceTest,
+REGISTER_TYPED_TEST_CASE_P(HashValueNestedSequenceTest, BasicUsage);
+using NestedIntSequenceTypes =
+    testing::Types<std::vector<std::vector<int>>,
+                   std::vector<TypeErasedVector<int>>,
+                   TypeErasedVector<std::vector<int>>,
+                   TypeErasedVector<TypeErasedVector<int>>>;
+INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueNestedSequenceTest,
                               NestedIntSequenceTypes);
 
 // Private type that only supports AbslHashValue to make sure our chosen hash
@@ -732,13 +673,9 @@
   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars));
 }
 
-REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMapTest, BasicUsage);
-using AssociativeMapTypes = testing::Types<
-    std::map<int, std::string>, std::unordered_map<int, std::string>,
-    absl::flat_hash_map<int, std::string>,
-    absl::node_hash_map<int, std::string>, absl::btree_map<int, std::string>,
-    UnorderedSequence<std::pair<const int, std::string>>>;
-INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMapTest,
+REGISTER_TYPED_TEST_CASE_P(HashValueAssociativeMapTest, BasicUsage);
+using AssociativeMapTypes = testing::Types<std::map<int, std::string>>;
+INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueAssociativeMapTest,
                               AssociativeMapTypes);
 
 template <typename T>
@@ -763,11 +700,10 @@
   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars));
 }
 
-REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMultimapTest, BasicUsage);
+REGISTER_TYPED_TEST_CASE_P(HashValueAssociativeMultimapTest, BasicUsage);
 using AssociativeMultimapTypes =
-    testing::Types<std::multimap<int, std::string>,
-                   std::unordered_multimap<int, std::string>>;
-INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMultimapTest,
+    testing::Types<std::multimap<int, std::string>>;
+INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueAssociativeMultimapTest,
                               AssociativeMultimapTypes);
 
 TEST(HashValueTest, ReferenceWrapper) {
@@ -1007,10 +943,10 @@
             Hash<CombineVariadic<TypeParam>>()({}));
 }
 
-REGISTER_TYPED_TEST_SUITE_P(HashIntTest, BasicUsage);
+REGISTER_TYPED_TEST_CASE_P(HashIntTest, BasicUsage);
 using IntTypes = testing::Types<unsigned char, char, int, int32_t, int64_t,
                                 uint32_t, uint64_t, size_t>;
-INSTANTIATE_TYPED_TEST_SUITE_P(My, HashIntTest, IntTypes);
+INSTANTIATE_TYPED_TEST_CASE_P(My, HashIntTest, IntTypes);
 
 struct StructWithPadding {
   char c;
@@ -1126,14 +1062,6 @@
 
   EXPECT_EQ(SpyHash(std::make_pair(TypeErasedValue<size_t>(7), 17)),
             SpyHash(std::make_pair(size_t{7}, 17)));
-
-  absl::flat_hash_set<absl::flat_hash_set<int>> ss = {{1, 2}, {3, 4}};
-  TypeErasedContainer<absl::flat_hash_set<absl::flat_hash_set<int>>> es = {
-      absl::flat_hash_set<int>{1, 2}, {3, 4}};
-  absl::flat_hash_set<TypeErasedContainer<absl::flat_hash_set<int>>> se = {
-      {1, 2}, {3, 4}};
-  EXPECT_EQ(SpyHash(ss), SpyHash(es));
-  EXPECT_EQ(SpyHash(ss), SpyHash(se));
 }
 
 struct ValueWithBoolConversion {
diff --git a/third_party/abseil-cpp/absl/hash/internal/hash.h b/third_party/abseil-cpp/absl/hash/internal/hash.h
index a424e014..97b68ba 100644
--- a/third_party/abseil-cpp/absl/hash/internal/hash.h
+++ b/third_party/abseil-cpp/absl/hash/internal/hash.h
@@ -23,7 +23,6 @@
 #include <array>
 #include <bitset>
 #include <cmath>
-#include <cstddef>
 #include <cstring>
 #include <deque>
 #include <forward_list>
@@ -37,8 +36,6 @@
 #include <string>
 #include <tuple>
 #include <type_traits>
-#include <unordered_map>
-#include <unordered_set>
 #include <utility>
 #include <vector>
 
@@ -57,9 +54,6 @@
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
-
-class HashState;
-
 namespace hash_internal {
 
 // Internal detail: Large buffers are hashed in smaller chunks.  This function
@@ -121,66 +115,24 @@
   size_t position_;
 };
 
-// is_hashable()
-//
-// Trait class which returns true if T is hashable by the absl::Hash framework.
-// Used for the AbslHashValue implementations for composite types below.
-template <typename T>
-struct is_hashable;
-
 // HashStateBase
 //
-// An internal implementation detail that contains common implementation details
-// for all of the "hash state objects" objects generated by Abseil.  This is not
-// a public API; users should not create classes that inherit from this.
-//
-// A hash state object is the template argument `H` passed to `AbslHashValue`.
-// It represents an intermediate state in the computation of an unspecified hash
-// algorithm. `HashStateBase` provides a CRTP style base class for hash state
-// implementations. Developers adding type support for `absl::Hash` should not
-// rely on any parts of the state object other than the following member
-// functions:
+// A hash state object represents an intermediate state in the computation
+// of an unspecified hash algorithm. `HashStateBase` provides a CRTP style
+// base class for hash state implementations. Developers adding type support
+// for `absl::Hash` should not rely on any parts of the state object other than
+// the following member functions:
 //
 //   * HashStateBase::combine()
 //   * HashStateBase::combine_contiguous()
-//   * HashStateBase::combine_unordered()
 //
-// A derived hash state class of type `H` must provide a public member function
+// A derived hash state class of type `H` must provide a static member function
 // with a signature similar to the following:
 //
 //    `static H combine_contiguous(H state, const unsigned char*, size_t)`.
 //
-// It must also provide a private template method named RunCombineUnordered.
-//
-// A "consumer" is a 1-arg functor returning void.  Its argument is a reference
-// to an inner hash state object, and it may be called multiple times.  When
-// called, the functor consumes the entropy from the provided state object,
-// and resets that object to its empty state.
-//
-// A "combiner" is a stateless 2-arg functor returning void.  Its arguments are
-// an inner hash state object and an ElementStateConsumer functor.  A combiner
-// uses the provided inner hash state object to hash each element of the
-// container, passing the inner hash state object to the consumer after hashing
-// each element.
-//
-// Given these definitions, a derived hash state class of type H
-// must provide a private template method with a signature similar to the
-// following:
-//
-//    `template <typename CombinerT>`
-//    `static H RunCombineUnordered(H outer_state, CombinerT combiner)`
-//
-// This function is responsible for constructing the inner state object and
-// providing a consumer to the combiner.  It uses side effects of the consumer
-// and combiner to mix the state of each element in an order-independent manner,
-// and uses this to return an updated value of `outer_state`.
-//
-// This inside-out approach generates efficient object code in the normal case,
-// but allows us to use stack storage to implement the absl::HashState type
-// erasure mechanism (avoiding heap allocations while hashing).
-//
 // `HashStateBase` will provide a complete implementation for a hash state
-// object in terms of these two methods.
+// object in terms of this method.
 //
 // Example:
 //
@@ -189,10 +141,6 @@
 //       static H combine_contiguous(H state, const unsigned char*, size_t);
 //       using MyHashState::HashStateBase::combine;
 //       using MyHashState::HashStateBase::combine_contiguous;
-//       using MyHashState::HashStateBase::combine_unordered;
-//     private:
-//       template <typename CombinerT>
-//       static H RunCombineUnordered(H state, CombinerT combiner);
 //   };
 template <typename H>
 class HashStateBase {
@@ -233,30 +181,7 @@
   template <typename T>
   static H combine_contiguous(H state, const T* data, size_t size);
 
-  template <typename I>
-  static H combine_unordered(H state, I begin, I end);
-
   using AbslInternalPiecewiseCombiner = PiecewiseCombiner;
-
-  template <typename T>
-  using is_hashable = absl::hash_internal::is_hashable<T>;
-
- private:
-  // Common implementation of the iteration step of a "combiner", as described
-  // above.
-  template <typename I>
-  struct CombineUnorderedCallback {
-    I begin;
-    I end;
-
-    template <typename InnerH, typename ElementStateConsumer>
-    void operator()(InnerH inner_state, ElementStateConsumer cb) {
-      for (; begin != end; ++begin) {
-        inner_state = H::combine(std::move(inner_state), *begin);
-        cb(inner_state);
-      }
-    }
-  };
 };
 
 // is_uniquely_represented
@@ -425,6 +350,13 @@
 // AbslHashValue for Composite Types
 // -----------------------------------------------------------------------------
 
+// is_hashable()
+//
+// Trait class which returns true if T is hashable by the absl::Hash framework.
+// Used for the AbslHashValue implementations for composite types below.
+template <typename T>
+struct is_hashable;
+
 // AbslHashValue() for hashing pairs
 template <typename H, typename T1, typename T2>
 typename std::enable_if<is_hashable<T1>::value && is_hashable<T2>::value,
@@ -571,10 +503,8 @@
 }
 
 // AbslHashValue special cases for hashing std::vector<bool>
-
 #if defined(ABSL_IS_BIG_ENDIAN) && \
     (defined(__GLIBCXX__) || defined(__GLIBCPP__))
-
 // std::hash in libstdc++ does not work correctly with vector<bool> on Big
 // Endian platforms therefore we need to implement a custom AbslHashValue for
 // it. More details on the bug:
@@ -658,55 +588,6 @@
 }
 
 // -----------------------------------------------------------------------------
-// AbslHashValue for Unordered Associative Containers
-// -----------------------------------------------------------------------------
-
-// AbslHashValue for hashing std::unordered_set
-template <typename H, typename Key, typename Hash, typename KeyEqual,
-          typename Alloc>
-typename std::enable_if<is_hashable<Key>::value, H>::type AbslHashValue(
-    H hash_state, const std::unordered_set<Key, Hash, KeyEqual, Alloc>& s) {
-  return H::combine(
-      H::combine_unordered(std::move(hash_state), s.begin(), s.end()),
-      s.size());
-}
-
-// AbslHashValue for hashing std::unordered_multiset
-template <typename H, typename Key, typename Hash, typename KeyEqual,
-          typename Alloc>
-typename std::enable_if<is_hashable<Key>::value, H>::type AbslHashValue(
-    H hash_state,
-    const std::unordered_multiset<Key, Hash, KeyEqual, Alloc>& s) {
-  return H::combine(
-      H::combine_unordered(std::move(hash_state), s.begin(), s.end()),
-      s.size());
-}
-
-// AbslHashValue for hashing std::unordered_set
-template <typename H, typename Key, typename T, typename Hash,
-          typename KeyEqual, typename Alloc>
-typename std::enable_if<is_hashable<Key>::value && is_hashable<T>::value,
-                        H>::type
-AbslHashValue(H hash_state,
-              const std::unordered_map<Key, T, Hash, KeyEqual, Alloc>& s) {
-  return H::combine(
-      H::combine_unordered(std::move(hash_state), s.begin(), s.end()),
-      s.size());
-}
-
-// AbslHashValue for hashing std::unordered_multiset
-template <typename H, typename Key, typename T, typename Hash,
-          typename KeyEqual, typename Alloc>
-typename std::enable_if<is_hashable<Key>::value && is_hashable<T>::value,
-                        H>::type
-AbslHashValue(H hash_state,
-              const std::unordered_multimap<Key, T, Hash, KeyEqual, Alloc>& s) {
-  return H::combine(
-      H::combine_unordered(std::move(hash_state), s.begin(), s.end()),
-      s.size());
-}
-
-// -----------------------------------------------------------------------------
 // AbslHashValue for Wrapper Types
 // -----------------------------------------------------------------------------
 
@@ -949,31 +830,6 @@
   // move-only ensures that there is only one non-moved-from object.
   MixingHashState() : state_(Seed()) {}
 
-  friend class MixingHashState::HashStateBase;
-
-  template <typename CombinerT>
-  static MixingHashState RunCombineUnordered(MixingHashState state,
-                                             CombinerT combiner) {
-    uint64_t unordered_state = 0;
-    combiner(MixingHashState{}, [&](MixingHashState& inner_state) {
-      // Add the hash state of the element to the running total, but mix the
-      // carry bit back into the low bit.  This in intended to avoid losing
-      // entropy to overflow, especially when unordered_multisets contain
-      // multiple copies of the same value.
-      auto element_state = inner_state.state_;
-      unordered_state += element_state;
-      if (unordered_state < element_state) {
-        ++unordered_state;
-      }
-      inner_state = MixingHashState{};
-    });
-    return MixingHashState::combine(std::move(state), unordered_state);
-  }
-
-  // Allow the HashState type-erasure implementation to invoke
-  // RunCombinedUnordered() directly.
-  friend class absl::HashState;
-
   // Workaround for MSVC bug.
   // We make the type copyable to fix the calling convention, even though we
   // never actually copy it. Keep it private to not affect the public API of the
@@ -1208,14 +1064,6 @@
   return hash_internal::hash_range_or_bytes(std::move(state), data, size);
 }
 
-// HashStateBase::combine_unordered()
-template <typename H>
-template <typename I>
-H HashStateBase<H>::combine_unordered(H state, I begin, I end) {
-  return H::RunCombineUnordered(std::move(state),
-                                CombineUnorderedCallback<I>{begin, end});
-}
-
 // HashStateBase::PiecewiseCombiner::add_buffer()
 template <typename H>
 H PiecewiseCombiner::add_buffer(H state, const unsigned char* data,
diff --git a/third_party/abseil-cpp/absl/hash/internal/spy_hash_state.h b/third_party/abseil-cpp/absl/hash/internal/spy_hash_state.h
index 0972826..c083120 100644
--- a/third_party/abseil-cpp/absl/hash/internal/spy_hash_state.h
+++ b/third_party/abseil-cpp/absl/hash/internal/spy_hash_state.h
@@ -15,7 +15,6 @@
 #ifndef ABSL_HASH_INTERNAL_SPY_HASH_STATE_H_
 #define ABSL_HASH_INTERNAL_SPY_HASH_STATE_H_
 
-#include <algorithm>
 #include <ostream>
 #include <string>
 #include <vector>
@@ -168,24 +167,6 @@
 
   using SpyHashStateImpl::HashStateBase::combine_contiguous;
 
-  template <typename CombinerT>
-  static SpyHashStateImpl RunCombineUnordered(SpyHashStateImpl state,
-                                              CombinerT combiner) {
-    UnorderedCombinerCallback cb;
-
-    combiner(SpyHashStateImpl<void>{}, std::ref(cb));
-
-    std::sort(cb.element_hash_representations.begin(),
-              cb.element_hash_representations.end());
-    state.hash_representation_.insert(state.hash_representation_.end(),
-                                      cb.element_hash_representations.begin(),
-                                      cb.element_hash_representations.end());
-    if (cb.error && cb.error->has_value()) {
-      state.error_ = std::move(cb.error);
-    }
-    return state;
-  }
-
   absl::optional<std::string> error() const {
     if (moved_from_) {
       return "Returned a moved-from instance of the hash state object.";
@@ -197,22 +178,6 @@
   template <typename U>
   friend class SpyHashStateImpl;
 
-  struct UnorderedCombinerCallback {
-    std::vector<std::string> element_hash_representations;
-    std::shared_ptr<absl::optional<std::string>> error;
-
-    // The inner spy can have a different type.
-    template <typename U>
-    void operator()(SpyHashStateImpl<U>& inner) {
-      element_hash_representations.push_back(
-          absl::StrJoin(inner.hash_representation_, ""));
-      if (inner.error_->has_value()) {
-        error = std::move(inner.error_);
-      }
-      inner = SpyHashStateImpl<void>{};
-    }
-  };
-
   // This is true if SpyHashStateImpl<T> has been passed to a call of
   // AbslHashValue with the wrong type. This detects that the user called
   // AbslHashValue directly (because the hash state type does not match).
diff --git a/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h b/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h
index 5f65983bc..fc269bd 100644
--- a/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h
+++ b/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h
@@ -46,7 +46,6 @@
   absl::Mutex init_mu;
   T* next = nullptr;
   T* dead ABSL_GUARDED_BY(init_mu) = nullptr;
-  int64_t weight;  // How many sampling events were required to sample this one.
 };
 
 // Holds samples and their associated stack traces with a soft limit of
diff --git a/third_party/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc b/third_party/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc
index 3373329..ec6e0fa 100644
--- a/third_party/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc
+++ b/third_party/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc
@@ -36,7 +36,7 @@
 
 struct Info : public Sample<Info> {
  public:
-  void PrepareForSampling(int64_t w) { weight = w; }
+  void PrepareForSampling() {}
   std::atomic<size_t> size;
   absl::Time create_time;
 };
@@ -49,14 +49,8 @@
   return res;
 }
 
-std::vector<int64_t> GetWeights(SampleRecorder<Info>* s) {
-  std::vector<int64_t> res;
-  s->Iterate([&](const Info& info) { res.push_back(info.weight); });
-  return res;
-}
-
-Info* Register(SampleRecorder<Info>* s, int64_t weight, size_t size) {
-  auto* info = s->Register(weight);
+Info* Register(SampleRecorder<Info>* s, size_t size) {
+  auto* info = s->Register();
   assert(info != nullptr);
   info->size.store(size);
   return info;
@@ -64,15 +58,13 @@
 
 TEST(SampleRecorderTest, Registration) {
   SampleRecorder<Info> sampler;
-  auto* info1 = Register(&sampler, 31, 1);
+  auto* info1 = Register(&sampler, 1);
   EXPECT_THAT(GetSizes(&sampler), UnorderedElementsAre(1));
-  EXPECT_THAT(GetWeights(&sampler), UnorderedElementsAre(31));
 
-  auto* info2 = Register(&sampler, 32, 2);
+  auto* info2 = Register(&sampler, 2);
   EXPECT_THAT(GetSizes(&sampler), UnorderedElementsAre(1, 2));
   info1->size.store(3);
   EXPECT_THAT(GetSizes(&sampler), UnorderedElementsAre(3, 2));
-  EXPECT_THAT(GetWeights(&sampler), UnorderedElementsAre(31, 32));
 
   sampler.Unregister(info1);
   sampler.Unregister(info2);
@@ -82,22 +74,18 @@
   SampleRecorder<Info> sampler;
   std::vector<Info*> infos;
   for (size_t i = 0; i < 3; ++i) {
-    infos.push_back(Register(&sampler, 33 + i, i));
+    infos.push_back(Register(&sampler, i));
   }
   EXPECT_THAT(GetSizes(&sampler), UnorderedElementsAre(0, 1, 2));
-  EXPECT_THAT(GetWeights(&sampler), UnorderedElementsAre(33, 34, 35));
 
   sampler.Unregister(infos[1]);
   EXPECT_THAT(GetSizes(&sampler), UnorderedElementsAre(0, 2));
-  EXPECT_THAT(GetWeights(&sampler), UnorderedElementsAre(33, 35));
 
-  infos.push_back(Register(&sampler, 36, 3));
-  infos.push_back(Register(&sampler, 37, 4));
+  infos.push_back(Register(&sampler, 3));
+  infos.push_back(Register(&sampler, 4));
   EXPECT_THAT(GetSizes(&sampler), UnorderedElementsAre(0, 2, 3, 4));
-  EXPECT_THAT(GetWeights(&sampler), UnorderedElementsAre(33, 35, 36, 37));
   sampler.Unregister(infos[3]);
   EXPECT_THAT(GetSizes(&sampler), UnorderedElementsAre(0, 2, 4));
-  EXPECT_THAT(GetWeights(&sampler), UnorderedElementsAre(33, 35, 37));
 
   sampler.Unregister(infos[0]);
   sampler.Unregister(infos[2]);
@@ -111,18 +99,18 @@
   ThreadPool pool(10);
 
   for (int i = 0; i < 10; ++i) {
-    pool.Schedule([&sampler, &stop, i]() {
+    pool.Schedule([&sampler, &stop]() {
       std::random_device rd;
       std::mt19937 gen(rd());
 
       std::vector<Info*> infoz;
       while (!stop.HasBeenNotified()) {
         if (infoz.empty()) {
-          infoz.push_back(sampler.Register(i));
+          infoz.push_back(sampler.Register());
         }
         switch (std::uniform_int_distribution<>(0, 2)(gen)) {
           case 0: {
-            infoz.push_back(sampler.Register(i));
+            infoz.push_back(sampler.Register());
             break;
           }
           case 1: {
@@ -131,7 +119,6 @@
             Info* info = infoz[p];
             infoz[p] = infoz.back();
             infoz.pop_back();
-            EXPECT_EQ(info->weight, i);
             sampler.Unregister(info);
             break;
           }
@@ -156,8 +143,8 @@
 TEST(SampleRecorderTest, Callback) {
   SampleRecorder<Info> sampler;
 
-  auto* info1 = Register(&sampler, 39, 1);
-  auto* info2 = Register(&sampler, 40, 2);
+  auto* info1 = Register(&sampler, 1);
+  auto* info2 = Register(&sampler, 2);
 
   static const Info* expected;
 
diff --git a/third_party/abseil-cpp/absl/random/internal/randen.h b/third_party/abseil-cpp/absl/random/internal/randen.h
index 9ff4a7a..9a3840b8 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen.h
+++ b/third_party/abseil-cpp/absl/random/internal/randen.h
@@ -43,8 +43,10 @@
 
   // Generate updates the randen sponge. The outer portion of the sponge
   // (kCapacityBytes .. kStateBytes) may be consumed as PRNG state.
-  // REQUIRES: state points to kStateBytes of state.
-  inline void Generate(void* state) const {
+  template <typename T, size_t N>
+  void Generate(T (&state)[N]) const {
+    static_assert(N * sizeof(T) == kStateBytes,
+                  "Randen::Generate() requires kStateBytes of state");
 #if ABSL_RANDOM_INTERNAL_AES_DISPATCH
     // HW AES Dispatch.
     if (has_crypto_) {
@@ -63,9 +65,13 @@
 
   // Absorb incorporates additional seed material into the randen sponge.  After
   // absorb returns, Generate must be called before the state may be consumed.
-  // REQUIRES: seed points to kSeedBytes of seed.
-  // REQUIRES: state points to kStateBytes of state.
-  inline void Absorb(const void* seed, void* state) const {
+  template <typename S, size_t M, typename T, size_t N>
+  void Absorb(const S (&seed)[M], T (&state)[N]) const {
+    static_assert(M * sizeof(S) == RandenTraits::kSeedBytes,
+                  "Randen::Absorb() requires kSeedBytes of seed");
+
+    static_assert(N * sizeof(T) == RandenTraits::kStateBytes,
+                  "Randen::Absorb() requires kStateBytes of state");
 #if ABSL_RANDOM_INTERNAL_AES_DISPATCH
     // HW AES Dispatch.
     if (has_crypto_) {
diff --git a/third_party/abseil-cpp/absl/random/internal/randen_engine.h b/third_party/abseil-cpp/absl/random/internal/randen_engine.h
index b4708664..372c3ac 100644
--- a/third_party/abseil-cpp/absl/random/internal/randen_engine.h
+++ b/third_party/abseil-cpp/absl/random/internal/randen_engine.h
@@ -42,7 +42,7 @@
 // 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
 // generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
 template <typename T>
-class alignas(8) randen_engine {
+class alignas(16) randen_engine {
  public:
   // C++11 URBG interface:
   using result_type = T;
@@ -58,8 +58,7 @@
     return (std::numeric_limits<result_type>::max)();
   }
 
-  randen_engine() : randen_engine(0) {}
-  explicit randen_engine(result_type seed_value) { seed(seed_value); }
+  explicit randen_engine(result_type seed_value = 0) { seed(seed_value); }
 
   template <class SeedSequence,
             typename = typename absl::enable_if_t<
@@ -68,27 +67,17 @@
     seed(seq);
   }
 
-  // alignment requirements dictate custom copy and move constructors.
-  randen_engine(const randen_engine& other)
-      : next_(other.next_), impl_(other.impl_) {
-    std::memcpy(state(), other.state(), kStateSizeT * sizeof(result_type));
-  }
-  randen_engine& operator=(const randen_engine& other) {
-    next_ = other.next_;
-    impl_ = other.impl_;
-    std::memcpy(state(), other.state(), kStateSizeT * sizeof(result_type));
-    return *this;
-  }
+  randen_engine(const randen_engine&) = default;
 
   // Returns random bits from the buffer in units of result_type.
   result_type operator()() {
     // Refill the buffer if needed (unlikely).
-    auto* begin = state();
     if (next_ >= kStateSizeT) {
       next_ = kCapacityT;
-      impl_.Generate(begin);
+      impl_.Generate(state_);
     }
-    return little_endian::ToHost(begin[next_++]);
+
+    return little_endian::ToHost(state_[next_++]);
   }
 
   template <class SeedSequence>
@@ -103,10 +92,9 @@
   void seed(result_type seed_value = 0) {
     next_ = kStateSizeT;
     // Zeroes the inner state and fills the outer state with seed_value to
-    // mimic the behaviour of reseed
-    auto* begin = state();
-    std::fill(begin, begin + kCapacityT, 0);
-    std::fill(begin + kCapacityT, begin + kStateSizeT, seed_value);
+    // mimics behaviour of reseed
+    std::fill(std::begin(state_), std::begin(state_) + kCapacityT, 0);
+    std::fill(std::begin(state_) + kCapacityT, std::end(state_), seed_value);
   }
 
   // Inserts entropy into (part of) the state. Calling this periodically with
@@ -117,6 +105,7 @@
     using sequence_result_type = typename SeedSequence::result_type;
     static_assert(sizeof(sequence_result_type) == 4,
                   "SeedSequence::result_type must be 32-bit");
+
     constexpr size_t kBufferSize =
         Randen::kSeedBytes / sizeof(sequence_result_type);
     alignas(16) sequence_result_type buffer[kBufferSize];
@@ -130,8 +119,8 @@
     if (entropy_size < kBufferSize) {
       // ... and only request that many values, or 256-bits, when unspecified.
       const size_t requested_entropy = (entropy_size == 0) ? 8u : entropy_size;
-      std::fill(buffer + requested_entropy, buffer + kBufferSize, 0);
-      seq.generate(buffer, buffer + requested_entropy);
+      std::fill(std::begin(buffer) + requested_entropy, std::end(buffer), 0);
+      seq.generate(std::begin(buffer), std::begin(buffer) + requested_entropy);
 #ifdef ABSL_IS_BIG_ENDIAN
       // Randen expects the seed buffer to be in Little Endian; reverse it on
       // Big Endian platforms.
@@ -157,9 +146,9 @@
         std::swap(buffer[--dst], buffer[--src]);
       }
     } else {
-      seq.generate(buffer, buffer + kBufferSize);
+      seq.generate(std::begin(buffer), std::end(buffer));
     }
-    impl_.Absorb(buffer, state());
+    impl_.Absorb(buffer, state_);
 
     // Generate will be called when operator() is called
     next_ = kStateSizeT;
@@ -170,10 +159,9 @@
     count -= step;
 
     constexpr uint64_t kRateT = kStateSizeT - kCapacityT;
-    auto* begin = state();
     while (count > 0) {
       next_ = kCapacityT;
-      impl_.Generate(*reinterpret_cast<result_type(*)[kStateSizeT]>(begin));
+      impl_.Generate(state_);
       step = std::min<uint64_t>(kRateT, count);
       count -= step;
     }
@@ -181,9 +169,9 @@
   }
 
   bool operator==(const randen_engine& other) const {
-    const auto* begin = state();
     return next_ == other.next_ &&
-           std::equal(begin, begin + kStateSizeT, other.state());
+           std::equal(std::begin(state_), std::end(state_),
+                      std::begin(other.state_));
   }
 
   bool operator!=(const randen_engine& other) const {
@@ -197,12 +185,11 @@
     using numeric_type =
         typename random_internal::stream_format_type<result_type>::type;
     auto saver = random_internal::make_ostream_state_saver(os);
-    auto* it = engine.state();
-    for (auto* end = it + kStateSizeT; it < end; ++it) {
+    for (const auto& elem : engine.state_) {
       // In the case that `elem` is `uint8_t`, it must be cast to something
       // larger so that it prints as an integer rather than a character. For
       // simplicity, apply the cast all circumstances.
-      os << static_cast<numeric_type>(little_endian::FromHost(*it))
+      os << static_cast<numeric_type>(little_endian::FromHost(elem))
          << os.fill();
     }
     os << engine.next_;
@@ -228,7 +215,7 @@
     if (is.fail()) {
       return is;
     }
-    std::memcpy(engine.state(), state, sizeof(state));
+    std::memcpy(engine.state_, state, sizeof(engine.state_));
     engine.next_ = next;
     return is;
   }
@@ -239,21 +226,9 @@
   static constexpr size_t kCapacityT =
       Randen::kCapacityBytes / sizeof(result_type);
 
-  // Returns the state array pointer, which is aligned to 16 bytes.
-  // The first kCapacityT are the `inner' sponge; the remainder are available.
-  result_type* state() {
-    return reinterpret_cast<result_type*>(
-        (reinterpret_cast<uintptr_t>(&raw_state_) & 0xf) ? (raw_state_ + 8)
-                                                         : raw_state_);
-  }
-  const result_type* state() const {
-    return const_cast<randen_engine*>(this)->state();
-  }
-
-  // raw state array, manually aligned in state(). This overallocates
-  // by 8 bytes since C++ does not guarantee extended heap alignment.
-  alignas(8) char raw_state_[Randen::kStateBytes + 8];
-  size_t next_;  // index within state()
+  // First kCapacityT are `inner', the others are accessible random bits.
+  alignas(16) result_type state_[kStateSizeT];
+  size_t next_;  // index within state_
   Randen impl_;
 };
 
diff --git a/third_party/abseil-cpp/absl/status/internal/status_internal.h b/third_party/abseil-cpp/absl/status/internal/status_internal.h
index 34914d2..ac12940 100644
--- a/third_party/abseil-cpp/absl/status/internal/status_internal.h
+++ b/third_party/abseil-cpp/absl/status/internal/status_internal.h
@@ -16,7 +16,6 @@
 
 #include <string>
 
-#include "absl/base/attributes.h"
 #include "absl/container/inlined_vector.h"
 #include "absl/strings/cord.h"
 
@@ -26,14 +25,7 @@
 ABSL_NAMESPACE_BEGIN
 // Returned Status objects may not be ignored. Codesearch doesn't handle ifdefs
 // as part of a class definitions (b/6995610), so we use a forward declaration.
-//
-// TODO(b/176172494): ABSL_MUST_USE_RESULT should expand to the more strict
-// [[nodiscard]]. For now, just use [[nodiscard]] directly when it is available.
-#if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
-class [[nodiscard]] Status;
-#else
 class ABSL_MUST_USE_RESULT Status;
-#endif
 ABSL_NAMESPACE_END
 }  // namespace absl
 #endif  // !SWIG
diff --git a/third_party/abseil-cpp/absl/status/statusor.h b/third_party/abseil-cpp/absl/status/statusor.h
index d6ebdc2..c051fbb3 100644
--- a/third_party/abseil-cpp/absl/status/statusor.h
+++ b/third_party/abseil-cpp/absl/status/statusor.h
@@ -106,13 +106,7 @@
 
 // Returned StatusOr objects may not be ignored.
 template <typename T>
-#if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
-// TODO(b/176172494): ABSL_MUST_USE_RESULT should expand to the more strict
-// [[nodiscard]]. For now, just use [[nodiscard]] directly when it is available.
-class [[nodiscard]] StatusOr;
-#else
 class ABSL_MUST_USE_RESULT StatusOr;
-#endif  // ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
 
 // absl::StatusOr<T>
 //
diff --git a/third_party/abseil-cpp/absl/strings/internal/escaping.cc b/third_party/abseil-cpp/absl/strings/internal/escaping.cc
index 7f87e124..c5271286a 100644
--- a/third_party/abseil-cpp/absl/strings/internal/escaping.cc
+++ b/third_party/abseil-cpp/absl/strings/internal/escaping.cc
@@ -102,8 +102,8 @@
     }
   }
   // To save time, we didn't update szdest or szsrc in the loop.  So do it now.
-  szdest = static_cast<size_t>(limit_dest - cur_dest);
-  szsrc = static_cast<size_t>(limit_src - cur_src);
+  szdest = limit_dest - cur_dest;
+  szsrc = limit_src - cur_src;
 
   /* now deal with the tail (<=3 bytes) */
   switch (szsrc) {
@@ -154,8 +154,7 @@
       // the loop because the loop above always reads 4 bytes, and the fourth
       // byte is past the end of the input.
       if (szdest < 4) return 0;
-      uint32_t in =
-          (uint32_t{cur_src[0]} << 16) + absl::big_endian::Load16(cur_src + 1);
+      uint32_t in = (cur_src[0] << 16) + absl::big_endian::Load16(cur_src + 1);
       cur_dest[0] = base64[in >> 18];
       in &= 0x3FFFF;
       cur_dest[1] = base64[in >> 12];
@@ -173,7 +172,7 @@
       ABSL_RAW_LOG(FATAL, "Logic problem? szsrc = %zu", szsrc);
       break;
   }
-  return static_cast<size_t>(cur_dest - dest);
+  return (cur_dest - dest);
 }
 
 }  // namespace strings_internal
diff --git a/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc b/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc
index dc6cfe1..05324c780 100644
--- a/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc
+++ b/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc
@@ -27,7 +27,7 @@
 
 std::streamsize OStringStream::xsputn(const char* s, std::streamsize n) {
   assert(s_);
-  s_->append(s, static_cast<size_t>(n));
+  s_->append(s, n);
   return n;
 }
 
diff --git a/third_party/abseil-cpp/absl/strings/internal/utf8.cc b/third_party/abseil-cpp/absl/strings/internal/utf8.cc
index 7ecb93d..8fd8edc1 100644
--- a/third_party/abseil-cpp/absl/strings/internal/utf8.cc
+++ b/third_party/abseil-cpp/absl/strings/internal/utf8.cc
@@ -25,25 +25,25 @@
     *buffer = static_cast<char>(utf8_char);
     return 1;
   } else if (utf8_char <= 0x7FF) {
-    buffer[1] = static_cast<char>(0x80 | (utf8_char & 0x3F));
+    buffer[1] = 0x80 | (utf8_char & 0x3F);
     utf8_char >>= 6;
-    buffer[0] = static_cast<char>(0xC0 | utf8_char);
+    buffer[0] = 0xC0 | utf8_char;
     return 2;
   } else if (utf8_char <= 0xFFFF) {
-    buffer[2] = static_cast<char>(0x80 | (utf8_char & 0x3F));
+    buffer[2] = 0x80 | (utf8_char & 0x3F);
     utf8_char >>= 6;
-    buffer[1] = static_cast<char>(0x80 | (utf8_char & 0x3F));
+    buffer[1] = 0x80 | (utf8_char & 0x3F);
     utf8_char >>= 6;
-    buffer[0] = static_cast<char>(0xE0 | utf8_char);
+    buffer[0] = 0xE0 | utf8_char;
     return 3;
   } else {
-    buffer[3] = static_cast<char>(0x80 | (utf8_char & 0x3F));
+    buffer[3] = 0x80 | (utf8_char & 0x3F);
     utf8_char >>= 6;
-    buffer[2] = static_cast<char>(0x80 | (utf8_char & 0x3F));
+    buffer[2] = 0x80 | (utf8_char & 0x3F);
     utf8_char >>= 6;
-    buffer[1] = static_cast<char>(0x80 | (utf8_char & 0x3F));
+    buffer[1] = 0x80 | (utf8_char & 0x3F);
     utf8_char >>= 6;
-    buffer[0] = static_cast<char>(0xF0 | utf8_char);
+    buffer[0] = 0xF0 | utf8_char;
     return 4;
   }
 }
diff --git a/third_party/abseil-cpp/symbols_arm64_dbg.def b/third_party/abseil-cpp/symbols_arm64_dbg.def
index cc1e519..ff87ecc 100644
--- a/third_party/abseil-cpp/symbols_arm64_dbg.def
+++ b/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -350,6 +350,7 @@
     ??$FromInt64@$0DLJKMKAA@@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$0DLJKMKAA@@__1@std@@@Z
     ??$FromInt64@$0DOI@@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$0DOI@@__1@std@@@Z
     ??$FromInt64@$0PECEA@@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$0PECEA@@__1@std@@@Z
+    ??$Generate@I$0EA@@Randen@random_internal@absl@@QEBAXAEAY0EA@I@Z
     ??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z
     ??$GenericCompare@HVstring_view@absl@@@absl@@YAHAEBVCord@0@AEBVstring_view@0@_K@Z
     ??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z
@@ -423,9 +424,9 @@
     ??$Pointer@$01D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBAPEAIPEAD@Z
     ??$Pointer@$0A@$$CBD@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBAPEB_KPEBD@Z
     ??$Pointer@$0A@D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBAPEA_KPEAD@Z
-    ??$PopDead@_J_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_J_K@Z
+    ??$PopDead@_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_K@Z
     ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$Register@AEB_JAEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K@Z
+    ??$Register@AEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEA_K@Z
     ??$STLStringResizeUninitialized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
     ??$STLStringResizeUninitializedAmortized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
     ??$Seconds@H$0A@@absl@@YA?AVDuration@0@H@Z
@@ -653,7 +654,6 @@
     ??$emplace_back@PEAUCordRep@cord_internal@absl@@@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@1@$$QEAPEAU231@@Z
     ??$emplace_back@UPayload@status_internal@absl@@@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAAEAUPayload@status_internal@1@$$QEAU231@@Z
     ??$emplace_back@USubRange@absl@@@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAAEAUSubRange@1@$$QEAU21@@Z
-    ??$exchange@_JH@absl@@YA_JAEA_J$$QEAH@Z
     ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??$find_first_non_full@X@container_internal@absl@@YA?AUFindInfo@01@PEBW4ctrl_t@01@_K1@Z
     ??$forward@$$T@absl@@YA$$QEA$$TAEA$$T@Z
@@ -695,7 +695,6 @@
     ??$forward@AEBVCord@absl@@@__1@std@@YAAEBVCord@absl@@AEBV23@@Z
     ??$forward@AEBVCord@absl@@@absl@@YAAEBVCord@0@AEBV10@@Z
     ??$forward@AEBVstring_view@absl@@@__1@std@@YAAEBVstring_view@absl@@AEBV23@@Z
-    ??$forward@H@absl@@YA$$QEAHAEAH@Z
     ??$forward@I@absl@@YA$$QEAIAEAI@Z
     ??$forward@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@YA$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@01@AEAPEAPEAU201@@Z
     ??$forward@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YA$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEBV23456@@Z
@@ -808,7 +807,6 @@
     ??$move@AEAVCord@absl@@@__1@std@@YA$$QEAVCord@absl@@AEAV23@@Z
     ??$move@AEAVInlineRep@Cord@absl@@@__1@std@@YA$$QEAVInlineRep@Cord@absl@@AEAV234@@Z
     ??$move@AEAVStatus@absl@@@__1@std@@YA$$QEAVStatus@absl@@AEAV23@@Z
-    ??$move@AEA_J@absl@@YA$$QEA_JAEA_J@Z
     ??$move@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV12345@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@00@Z
     ??$move@PEAUTransition@cctz@time_internal@absl@@PEAU1234@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@00@Z
     ??$move@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@__1@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@00@Z
@@ -1588,6 +1586,7 @@
     ?Align@adl_barrier@internal_layout@container_internal@absl@@YA_K_K0@Z
     ?AlignBegin@CordRepBtree@cord_internal@absl@@AEAAXXZ
     ?AlignEnd@CordRepBtree@cord_internal@absl@@AEAAXXZ
+    ?Alloc@LowLevelAlloc@base_internal@absl@@SAPEAX_K@Z
     ?AllocSize@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ
     ?AllocSize@CordRepRing@cord_internal@absl@@SA_K_K@Z
     ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPEAX_KPEAUArena@123@@Z
@@ -1940,6 +1939,7 @@
     ?FormatTime@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@VTime@1@VTimeZone@1@@Z
     ?FormatUntyped@str_format_internal@absl@@YA_NVFormatRawSinkImpl@12@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
     ?FprintF@str_format_internal@absl@@YAHPEAU_iobuf@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
+    ?Free@LowLevelAlloc@base_internal@absl@@SAXPEAX@Z
     ?Frequency@CycleClock@base_internal@absl@@SANXZ
     ?Frequency@UnscaledCycleClock@base_internal@absl@@CANXZ
     ?FromChrono@absl@@YA?AVDuration@1@AEBV?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@chrono@__1@std@@@Z
@@ -1958,7 +1958,6 @@
     ?Generate@?$RandenPool@G@random_internal@absl@@KAGXZ
     ?Generate@?$RandenPool@I@random_internal@absl@@KAIXZ
     ?Generate@?$RandenPool@_K@random_internal@absl@@KA_KXZ
-    ?Generate@Randen@random_internal@absl@@QEBAXPEAX@Z
     ?Generate@RandenHwAes@random_internal@absl@@SAXPEBXPEAX@Z
     ?Generate@RandenSlow@random_internal@absl@@SAXPEBXPEAX@Z
     ?Get@RefcountAndFlags@cord_internal@absl@@QEBAHXZ
@@ -2312,7 +2311,7 @@
     ?Poke@Waiter@synchronization_internal@absl@@QEAAXXZ
     ?Post@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z
     ?Post@Waiter@synchronization_internal@absl@@QEAAXXZ
-    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_J_K@Z
+    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_K@Z
     ?PrepareToModify@Status@absl@@AEAAXXZ
     ?Prepend@Cord@absl@@QEAAXAEBV12@@Z
     ?Prepend@Cord@absl@@QEAAXVstring_view@2@@Z
@@ -2406,7 +2405,7 @@
     ?RoundUpForTag@cord_internal@absl@@YA_K_K@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z
-    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@AEAUSamplingState@12@_K@Z
+    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J_K@Z
     ?Seek@CordRepBtreeNavigator@cord_internal@absl@@QEAA?AUPosition@123@_K@Z
     ?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z
     ?SetAllocation@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@H@__1@std@@@23@@Z
diff --git a/third_party/abseil-cpp/symbols_arm64_rel.def b/third_party/abseil-cpp/symbols_arm64_rel.def
index 25ee4ea..d7695d2d 100644
--- a/third_party/abseil-cpp/symbols_arm64_rel.def
+++ b/third_party/abseil-cpp/symbols_arm64_rel.def
@@ -76,9 +76,9 @@
     ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
     ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
     ??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NVstring_view@1@UParsedFormatConsumer@ParsedFormatBase@01@@Z
-    ??$PopDead@_J_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_J_K@Z
+    ??$PopDead@_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_K@Z
     ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$Register@AEB_JAEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K@Z
+    ??$Register@AEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEA_K@Z
     ??$STLStringResizeUninitializedAmortized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
     ??$SetEdge@$00@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
     ??$SetEdge@$0A@@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
@@ -235,6 +235,7 @@
     ?AdvanceBytesBtree@ChunkIterator@Cord@absl@@AEAAX_K@Z
     ?AdvanceBytesSlowPath@ChunkIterator@Cord@absl@@AEAAX_K@Z
     ?AdvanceStack@ChunkIterator@Cord@absl@@AEAAAEAV123@XZ
+    ?Alloc@LowLevelAlloc@base_internal@absl@@SAPEAX_K@Z
     ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPEAX_KPEAUArena@123@@Z
     ?Allocate@?$MallocAdapter@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@$0A@@inlined_vector_internal@absl@@SA?AU?$Allocation@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@23@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@_K@Z
     ?Allocate@?$MallocAdapter@V?$allocator@PEAUCordRepConcat@cord_internal@absl@@@__1@std@@$0A@@inlined_vector_internal@absl@@SA?AU?$Allocation@V?$allocator@PEAUCordRepConcat@cord_internal@absl@@@__1@std@@@23@AEAV?$allocator@PEAUCordRepConcat@cord_internal@absl@@@__1@std@@_K@Z
@@ -465,6 +466,7 @@
     ?FormatTime@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@VTime@1@VTimeZone@1@@Z
     ?FormatUntyped@str_format_internal@absl@@YA_NVFormatRawSinkImpl@12@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
     ?FprintF@str_format_internal@absl@@YAHPEAU_iobuf@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
+    ?Free@LowLevelAlloc@base_internal@absl@@SAXPEAX@Z
     ?Frequency@CycleClock@base_internal@absl@@SANXZ
     ?Frequency@UnscaledCycleClock@base_internal@absl@@CANXZ
     ?FromChrono@absl@@YA?AVTime@1@AEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@234@@chrono@__1@std@@@Z
@@ -641,7 +643,7 @@
     ?PermissionDeniedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Poke@Waiter@synchronization_internal@absl@@QEAAXXZ
     ?Post@Waiter@synchronization_internal@absl@@QEAAXXZ
-    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_J_K@Z
+    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_K@Z
     ?PrepareToModify@Status@absl@@AEAAXXZ
     ?Prepend@Cord@absl@@QEAAXAEBV12@@Z
     ?Prepend@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z
@@ -706,7 +708,7 @@
     ?ReverseConsume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z
-    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@AEAUSamplingState@12@_K@Z
+    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J_K@Z
     ?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z
     ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QEAAX_K@Z
     ?SetCurrentThreadIdentity@base_internal@absl@@YAXPEAUThreadIdentity@12@P6AXPEAX@Z@Z
diff --git a/third_party/abseil-cpp/symbols_x64_dbg.def b/third_party/abseil-cpp/symbols_x64_dbg.def
index a1d37062..4ed9529 100644
--- a/third_party/abseil-cpp/symbols_x64_dbg.def
+++ b/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -350,6 +350,7 @@
     ??$FromInt64@$0DLJKMKAA@@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$0DLJKMKAA@@__1@std@@@Z
     ??$FromInt64@$0DOI@@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$0DOI@@__1@std@@@Z
     ??$FromInt64@$0PECEA@@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$0PECEA@@__1@std@@@Z
+    ??$Generate@I$0EA@@Randen@random_internal@absl@@QEBAXAEAY0EA@I@Z
     ??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z
     ??$GenericCompare@HVstring_view@absl@@@absl@@YAHAEBVCord@0@AEBVstring_view@0@_K@Z
     ??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z
@@ -423,9 +424,9 @@
     ??$Pointer@$01D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBAPEAIPEAD@Z
     ??$Pointer@$0A@$$CBD@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBAPEB_KPEBD@Z
     ??$Pointer@$0A@D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBAPEA_KPEAD@Z
-    ??$PopDead@_J_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_J_K@Z
+    ??$PopDead@_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_K@Z
     ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$Register@AEB_JAEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K@Z
+    ??$Register@AEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEA_K@Z
     ??$STLStringResizeUninitialized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
     ??$STLStringResizeUninitializedAmortized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
     ??$Seconds@H$0A@@absl@@YA?AVDuration@0@H@Z
@@ -657,7 +658,6 @@
     ??$emplace_back@PEAUCordRep@cord_internal@absl@@@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@1@$$QEAPEAU231@@Z
     ??$emplace_back@UPayload@status_internal@absl@@@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAAEAUPayload@status_internal@1@$$QEAU231@@Z
     ??$emplace_back@USubRange@absl@@@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAAEAUSubRange@1@$$QEAU21@@Z
-    ??$exchange@_JH@absl@@YA_JAEA_J$$QEAH@Z
     ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??$find_first_non_full@X@container_internal@absl@@YA?AUFindInfo@01@PEBW4ctrl_t@01@_K1@Z
     ??$forward@$$T@absl@@YA$$QEA$$TAEA$$T@Z
@@ -699,7 +699,6 @@
     ??$forward@AEBVCord@absl@@@__1@std@@YAAEBVCord@absl@@AEBV23@@Z
     ??$forward@AEBVCord@absl@@@absl@@YAAEBVCord@0@AEBV10@@Z
     ??$forward@AEBVstring_view@absl@@@__1@std@@YAAEBVstring_view@absl@@AEBV23@@Z
-    ??$forward@H@absl@@YA$$QEAHAEAH@Z
     ??$forward@I@absl@@YA$$QEAIAEAI@Z
     ??$forward@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@YA$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@01@AEAPEAPEAU201@@Z
     ??$forward@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YA$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEBV23456@@Z
@@ -812,7 +811,6 @@
     ??$move@AEAVCord@absl@@@__1@std@@YA$$QEAVCord@absl@@AEAV23@@Z
     ??$move@AEAVInlineRep@Cord@absl@@@__1@std@@YA$$QEAVInlineRep@Cord@absl@@AEAV234@@Z
     ??$move@AEAVStatus@absl@@@__1@std@@YA$$QEAVStatus@absl@@AEAV23@@Z
-    ??$move@AEA_J@absl@@YA$$QEA_JAEA_J@Z
     ??$move@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV12345@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@00@Z
     ??$move@PEAUTransition@cctz@time_internal@absl@@PEAU1234@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@00@Z
     ??$move@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@__1@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@00@Z
@@ -1591,6 +1589,7 @@
     ?Align@adl_barrier@internal_layout@container_internal@absl@@YA_K_K0@Z
     ?AlignBegin@CordRepBtree@cord_internal@absl@@AEAAXXZ
     ?AlignEnd@CordRepBtree@cord_internal@absl@@AEAAXXZ
+    ?Alloc@LowLevelAlloc@base_internal@absl@@SAPEAX_K@Z
     ?AllocSize@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ
     ?AllocSize@CordRepRing@cord_internal@absl@@SA_K_K@Z
     ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPEAX_KPEAUArena@123@@Z
@@ -1943,6 +1942,7 @@
     ?FormatTime@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@VTime@1@VTimeZone@1@@Z
     ?FormatUntyped@str_format_internal@absl@@YA_NVFormatRawSinkImpl@12@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
     ?FprintF@str_format_internal@absl@@YAHPEAU_iobuf@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
+    ?Free@LowLevelAlloc@base_internal@absl@@SAXPEAX@Z
     ?Frequency@CycleClock@base_internal@absl@@SANXZ
     ?Frequency@UnscaledCycleClock@base_internal@absl@@CANXZ
     ?FromChrono@absl@@YA?AVDuration@1@AEBV?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@chrono@__1@std@@@Z
@@ -1960,7 +1960,6 @@
     ?Generate@?$RandenPool@G@random_internal@absl@@KAGXZ
     ?Generate@?$RandenPool@I@random_internal@absl@@KAIXZ
     ?Generate@?$RandenPool@_K@random_internal@absl@@KA_KXZ
-    ?Generate@Randen@random_internal@absl@@QEBAXPEAX@Z
     ?Generate@RandenHwAes@random_internal@absl@@SAXPEBXPEAX@Z
     ?Generate@RandenSlow@random_internal@absl@@SAXPEBXPEAX@Z
     ?Get@RefcountAndFlags@cord_internal@absl@@QEBAHXZ
@@ -2313,7 +2312,7 @@
     ?Poke@Waiter@synchronization_internal@absl@@QEAAXXZ
     ?Post@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z
     ?Post@Waiter@synchronization_internal@absl@@QEAAXXZ
-    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_J_K@Z
+    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_K@Z
     ?PrepareToModify@Status@absl@@AEAAXXZ
     ?Prepend@Cord@absl@@QEAAXAEBV12@@Z
     ?Prepend@Cord@absl@@QEAAXVstring_view@2@@Z
@@ -2407,7 +2406,7 @@
     ?RoundUpForTag@cord_internal@absl@@YA_K_K@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z
-    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@AEAUSamplingState@12@_K@Z
+    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J_K@Z
     ?Seek@CordRepBtreeNavigator@cord_internal@absl@@QEAA?AUPosition@123@_K@Z
     ?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z
     ?SetAllocation@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@H@__1@std@@@23@@Z
diff --git a/third_party/abseil-cpp/symbols_x64_rel.def b/third_party/abseil-cpp/symbols_x64_rel.def
index bbd2172..4d392c6 100644
--- a/third_party/abseil-cpp/symbols_x64_rel.def
+++ b/third_party/abseil-cpp/symbols_x64_rel.def
@@ -64,6 +64,7 @@
     ??$ForEach@V<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$0A@@012@AEAAXPEBV012@II@Z@@Z
     ??$ForEach@V<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z
     ??$ForEach@V<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z
+    ??$Generate@I$0EA@@Randen@random_internal@absl@@QEBAXAEAY0EA@I@Z
     ??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z
     ??$GenericCompare@HVstring_view@absl@@@absl@@YAHAEBVCord@0@AEBVstring_view@0@_K@Z
     ??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z
@@ -76,9 +77,9 @@
     ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
     ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
     ??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NVstring_view@1@UParsedFormatConsumer@ParsedFormatBase@01@@Z
-    ??$PopDead@_J_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_J_K@Z
+    ??$PopDead@_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_K@Z
     ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$Register@AEB_JAEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K@Z
+    ??$Register@AEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEA_K@Z
     ??$STLStringResizeUninitializedAmortized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
     ??$SetEdge@$00@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
     ??$SetEdge@$0A@@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
@@ -237,6 +238,7 @@
     ?AdvanceBytesBtree@ChunkIterator@Cord@absl@@AEAAX_K@Z
     ?AdvanceBytesSlowPath@ChunkIterator@Cord@absl@@AEAAX_K@Z
     ?AdvanceStack@ChunkIterator@Cord@absl@@AEAAAEAV123@XZ
+    ?Alloc@LowLevelAlloc@base_internal@absl@@SAPEAX_K@Z
     ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPEAX_KPEAUArena@123@@Z
     ?AlreadyExistsError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Append@?$AppendUninitializedTraits@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@SAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
@@ -463,6 +465,7 @@
     ?FormatTime@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@VTime@1@VTimeZone@1@@Z
     ?FormatUntyped@str_format_internal@absl@@YA_NVFormatRawSinkImpl@12@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
     ?FprintF@str_format_internal@absl@@YAHPEAU_iobuf@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
+    ?Free@LowLevelAlloc@base_internal@absl@@SAXPEAX@Z
     ?Frequency@CycleClock@base_internal@absl@@SANXZ
     ?Frequency@UnscaledCycleClock@base_internal@absl@@CANXZ
     ?FromChrono@absl@@YA?AVTime@1@AEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@234@@chrono@__1@std@@@Z
@@ -640,7 +643,7 @@
     ?PermissionDeniedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Poke@Waiter@synchronization_internal@absl@@QEAAXXZ
     ?Post@Waiter@synchronization_internal@absl@@QEAAXXZ
-    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_J_K@Z
+    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_K@Z
     ?PrepareToModify@Status@absl@@AEAAXXZ
     ?Prepend@Cord@absl@@QEAAXAEBV12@@Z
     ?Prepend@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z
@@ -705,7 +708,7 @@
     ?ReverseConsume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z
-    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@AEAUSamplingState@12@_K@Z
+    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J_K@Z
     ?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z
     ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QEAAX_K@Z
     ?SetCurrentThreadIdentity@base_internal@absl@@YAXPEAUThreadIdentity@12@P6AXPEAX@Z@Z
diff --git a/third_party/abseil-cpp/symbols_x64_rel_asan.def b/third_party/abseil-cpp/symbols_x64_rel_asan.def
index 557aba6..01bc1fd 100644
--- a/third_party/abseil-cpp/symbols_x64_rel_asan.def
+++ b/third_party/abseil-cpp/symbols_x64_rel_asan.def
@@ -63,6 +63,7 @@
     ??$ForEach@V<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$0A@@012@AEAAXPEBV012@II@Z@@Z
     ??$ForEach@V<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z
     ??$ForEach@V<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z
+    ??$Generate@I$0EA@@Randen@random_internal@absl@@QEBAXAEAY0EA@I@Z
     ??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z
     ??$GenericCompare@HVstring_view@absl@@@absl@@YAHAEBVCord@0@AEBVstring_view@0@_K@Z
     ??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z
@@ -75,9 +76,9 @@
     ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
     ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
     ??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NVstring_view@1@UParsedFormatConsumer@ParsedFormatBase@01@@Z
-    ??$PopDead@_J_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_J_K@Z
+    ??$PopDead@_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_K@Z
     ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$Register@AEB_JAEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K@Z
+    ??$Register@AEA_K@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEA_K@Z
     ??$STLStringResizeUninitializedAmortized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
     ??$SetEdge@$00@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
     ??$SetEdge@$0A@@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
@@ -246,6 +247,7 @@
     ?AdvanceBytesBtree@ChunkIterator@Cord@absl@@AEAAX_K@Z
     ?AdvanceBytesSlowPath@ChunkIterator@Cord@absl@@AEAAX_K@Z
     ?AdvanceStack@ChunkIterator@Cord@absl@@AEAAAEAV123@XZ
+    ?Alloc@LowLevelAlloc@base_internal@absl@@SAPEAX_K@Z
     ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPEAX_KPEAUArena@123@@Z
     ?AlreadyExistsError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?AnnotateConstruct@NonEmptyInlinedStorage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAX_K@Z
@@ -473,6 +475,7 @@
     ?FormatTime@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@VTime@1@VTimeZone@1@@Z
     ?FormatUntyped@str_format_internal@absl@@YA_NVFormatRawSinkImpl@12@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
     ?FprintF@str_format_internal@absl@@YAHPEAU_iobuf@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
+    ?Free@LowLevelAlloc@base_internal@absl@@SAXPEAX@Z
     ?Frequency@CycleClock@base_internal@absl@@SANXZ
     ?Frequency@UnscaledCycleClock@base_internal@absl@@CANXZ
     ?FromChrono@absl@@YA?AVTime@1@AEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@234@@chrono@__1@std@@@Z
@@ -650,7 +653,7 @@
     ?PermissionDeniedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Poke@Waiter@synchronization_internal@absl@@QEAAXXZ
     ?Post@Waiter@synchronization_internal@absl@@QEAAXXZ
-    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_J_K@Z
+    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QEAAX_K@Z
     ?PrepareToModify@Status@absl@@AEAAXXZ
     ?Prepend@Cord@absl@@QEAAXAEBV12@@Z
     ?Prepend@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z
@@ -715,7 +718,7 @@
     ?ReverseConsume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z
-    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@AEAUSamplingState@12@_K@Z
+    ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J_K@Z
     ?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z
     ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QEAAX_K@Z
     ?SetCurrentThreadIdentity@base_internal@absl@@YAXPEAUThreadIdentity@12@P6AXPEAX@Z@Z
diff --git a/third_party/abseil-cpp/symbols_x86_dbg.def b/third_party/abseil-cpp/symbols_x86_dbg.def
index 61838f97..36d5875 100644
--- a/third_party/abseil-cpp/symbols_x86_dbg.def
+++ b/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -350,6 +350,7 @@
     ??$FromInt64@$0DLJKMKAA@@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$0DLJKMKAA@@__1@std@@@Z
     ??$FromInt64@$0DOI@@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$0DOI@@__1@std@@@Z
     ??$FromInt64@$0PECEA@@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$0PECEA@@__1@std@@@Z
+    ??$Generate@I$0EA@@Randen@random_internal@absl@@QBEXAAY0EA@I@Z
     ??$GenericCompare@HVCord@absl@@@absl@@YAHABVCord@0@0I@Z
     ??$GenericCompare@HVstring_view@absl@@@absl@@YAHABVCord@0@ABVstring_view@0@I@Z
     ??$GenericCompare@_NVCord@absl@@@absl@@YA_NABVCord@0@0I@Z
@@ -421,9 +422,9 @@
     ??$Pointer@$01D@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00@absl@@U?$integer_sequence@I$0A@$00$01@5@@internal_layout@container_internal@absl@@QBEPAIPAD@Z
     ??$Pointer@$0A@$$CBD@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$S@absl@@U?$integer_sequence@I$0A@@5@@internal_layout@container_internal@absl@@QBEPBIPBD@Z
     ??$Pointer@$0A@D@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$S@absl@@U?$integer_sequence@I$0A@@5@@internal_layout@container_internal@absl@@QBEPAIPAD@Z
-    ??$PopDead@_JI@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AAEPAUHashtablezInfo@container_internal@2@_JI@Z
+    ??$PopDead@I@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AAEPAUHashtablezInfo@container_internal@2@I@Z
     ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$Register@AB_JAAI@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEPAUHashtablezInfo@container_internal@2@AB_JAAI@Z
+    ??$Register@AAI@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEPAUHashtablezInfo@container_internal@2@AAI@Z
     ??$STLStringResizeUninitialized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@I@Z
     ??$STLStringResizeUninitializedAmortized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@strings_internal@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@I@Z
     ??$Seconds@H$0A@@absl@@YA?AVDuration@0@H@Z
@@ -653,7 +654,6 @@
     ??$emplace_back@PAUCordRep@cord_internal@absl@@@?$InlinedVector@PAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QAEAAPAUCordRep@cord_internal@1@$$QAPAU231@@Z
     ??$emplace_back@UPayload@status_internal@absl@@@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QAEAAUPayload@status_internal@1@$$QAU231@@Z
     ??$emplace_back@USubRange@absl@@@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QAEAAUSubRange@1@$$QAU21@@Z
-    ??$exchange@_JH@absl@@YA_JAA_J$$QAH@Z
     ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??$find_first_non_full@X@container_internal@absl@@YA?AUFindInfo@01@PBW4ctrl_t@01@II@Z
     ??$forward@$$T@absl@@YA$$QA$$TAA$$T@Z
@@ -694,7 +694,6 @@
     ??$forward@ABVCord@absl@@@__1@std@@YAABVCord@absl@@ABV23@@Z
     ??$forward@ABVCord@absl@@@absl@@YAABVCord@0@ABV10@@Z
     ??$forward@ABVstring_view@absl@@@__1@std@@YAABVstring_view@absl@@ABV23@@Z
-    ??$forward@H@absl@@YA$$QAHAAH@Z
     ??$forward@I@absl@@YA$$QAIAAI@Z
     ??$forward@PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@YA$$QAPAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@01@AAPAPAU201@@Z
     ??$forward@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YA$$QAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAPAPBV23456@@Z
@@ -807,7 +806,6 @@
     ??$move@AAVCord@absl@@@__1@std@@YA$$QAVCord@absl@@AAV23@@Z
     ??$move@AAVInlineRep@Cord@absl@@@__1@std@@YA$$QAVInlineRep@Cord@absl@@AAV234@@Z
     ??$move@AAVStatus@absl@@@__1@std@@YA$$QAVStatus@absl@@AAV23@@Z
-    ??$move@AA_J@absl@@YA$$QA_JAA_J@Z
     ??$move@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV12345@@__1@std@@YAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV23456@00@Z
     ??$move@PAUTransition@cctz@time_internal@absl@@PAU1234@@__1@std@@YAPAUTransition@cctz@time_internal@absl@@PAU2345@00@Z
     ??$move@PAUTransitionType@cctz@time_internal@absl@@PAU1234@@__1@std@@YAPAUTransitionType@cctz@time_internal@absl@@PAU2345@00@Z
@@ -1586,6 +1584,7 @@
     ?Align@adl_barrier@internal_layout@container_internal@absl@@YAIII@Z
     ?AlignBegin@CordRepBtree@cord_internal@absl@@AAEXXZ
     ?AlignEnd@CordRepBtree@cord_internal@absl@@AAEXXZ
+    ?Alloc@LowLevelAlloc@base_internal@absl@@SAPAXI@Z
     ?AllocSize@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QBEIXZ
     ?AllocSize@CordRepRing@cord_internal@absl@@SAII@Z
     ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPAXIPAUArena@123@@Z
@@ -1938,6 +1937,7 @@
     ?FormatTime@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@VTime@1@VTimeZone@1@@Z
     ?FormatUntyped@str_format_internal@absl@@YA_NVFormatRawSinkImpl@12@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
     ?FprintF@str_format_internal@absl@@YAHPAU_iobuf@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
+    ?Free@LowLevelAlloc@base_internal@absl@@SAXPAX@Z
     ?Frequency@CycleClock@base_internal@absl@@SANXZ
     ?Frequency@UnscaledCycleClock@base_internal@absl@@CANXZ
     ?FromChrono@absl@@YA?AVDuration@1@ABV?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@chrono@__1@std@@@Z
@@ -1955,7 +1955,6 @@
     ?Generate@?$RandenPool@G@random_internal@absl@@KAGXZ
     ?Generate@?$RandenPool@I@random_internal@absl@@KAIXZ
     ?Generate@?$RandenPool@_K@random_internal@absl@@KA_KXZ
-    ?Generate@Randen@random_internal@absl@@QBEXPAX@Z
     ?Generate@RandenHwAes@random_internal@absl@@SAXPBXPAX@Z
     ?Generate@RandenSlow@random_internal@absl@@SAXPBXPAX@Z
     ?Get@RefcountAndFlags@cord_internal@absl@@QBEHXZ
@@ -2308,7 +2307,7 @@
     ?Poke@Waiter@synchronization_internal@absl@@QAEXXZ
     ?Post@PerThreadSem@synchronization_internal@absl@@CAXPAUThreadIdentity@base_internal@3@@Z
     ?Post@Waiter@synchronization_internal@absl@@QAEXXZ
-    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QAEX_JI@Z
+    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QAEXI@Z
     ?PrepareToModify@Status@absl@@AAEXXZ
     ?Prepend@Cord@absl@@QAEXABV12@@Z
     ?Prepend@Cord@absl@@QAEXVstring_view@2@@Z
@@ -2402,7 +2401,7 @@
     ?RoundUpForTag@cord_internal@absl@@YAII@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QBE_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPBDI@Z
-    ?SampleSlow@container_internal@absl@@YAPAUHashtablezInfo@12@AAUSamplingState@12@I@Z
+    ?SampleSlow@container_internal@absl@@YAPAUHashtablezInfo@12@PA_JI@Z
     ?Seek@CordRepBtreeNavigator@cord_internal@absl@@QAE?AUPosition@123@I@Z
     ?Seek@CordRepBtreeReader@cord_internal@absl@@QAE?AVstring_view@3@I@Z
     ?SetAllocation@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAEXU?$Allocation@V?$allocator@H@__1@std@@@23@@Z
diff --git a/third_party/abseil-cpp/symbols_x86_rel.def b/third_party/abseil-cpp/symbols_x86_rel.def
index 79d93e6f..e24357d 100644
--- a/third_party/abseil-cpp/symbols_x86_rel.def
+++ b/third_party/abseil-cpp/symbols_x86_rel.def
@@ -76,9 +76,9 @@
     ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PBD0W4chars_format@1@@Z
     ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PBD0W4chars_format@1@@Z
     ??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NVstring_view@1@UParsedFormatConsumer@ParsedFormatBase@01@@Z
-    ??$PopDead@_JI@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AAEPAUHashtablezInfo@container_internal@2@_JI@Z
+    ??$PopDead@I@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AAEPAUHashtablezInfo@container_internal@2@I@Z
     ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$Register@AB_JAAI@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEPAUHashtablezInfo@container_internal@2@AB_JAAI@Z
+    ??$Register@AAI@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEPAUHashtablezInfo@container_internal@2@AAI@Z
     ??$STLStringResizeUninitializedAmortized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@strings_internal@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@I@Z
     ??$SetEdge@$00@CordRepBtree@cord_internal@absl@@QAE?AUOpResult@012@_NPAUCordRep@12@I@Z
     ??$SetEdge@$0A@@CordRepBtree@cord_internal@absl@@QAE?AUOpResult@012@_NPAUCordRep@12@I@Z
@@ -234,6 +234,7 @@
     ?AdvanceBytesBtree@ChunkIterator@Cord@absl@@AAEXI@Z
     ?AdvanceBytesSlowPath@ChunkIterator@Cord@absl@@AAEXI@Z
     ?AdvanceStack@ChunkIterator@Cord@absl@@AAEAAV123@XZ
+    ?Alloc@LowLevelAlloc@base_internal@absl@@SAPAXI@Z
     ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPAXIPAUArena@123@@Z
     ?Allocate@?$MallocAdapter@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@$0A@@inlined_vector_internal@absl@@SA?AU?$Allocation@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@23@AAV?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@I@Z
     ?Allocate@?$MallocAdapter@V?$allocator@PAUCordRepConcat@cord_internal@absl@@@__1@std@@$0A@@inlined_vector_internal@absl@@SA?AU?$Allocation@V?$allocator@PAUCordRepConcat@cord_internal@absl@@@__1@std@@@23@AAV?$allocator@PAUCordRepConcat@cord_internal@absl@@@__1@std@@I@Z
@@ -464,6 +465,7 @@
     ?FormatTime@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@VTime@1@VTimeZone@1@@Z
     ?FormatUntyped@str_format_internal@absl@@YA_NVFormatRawSinkImpl@12@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
     ?FprintF@str_format_internal@absl@@YAHPAU_iobuf@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
+    ?Free@LowLevelAlloc@base_internal@absl@@SAXPAX@Z
     ?Frequency@CycleClock@base_internal@absl@@SANXZ
     ?Frequency@UnscaledCycleClock@base_internal@absl@@CANXZ
     ?FromChrono@absl@@YA?AVTime@1@ABV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@234@@chrono@__1@std@@@Z
@@ -640,7 +642,7 @@
     ?PermissionDeniedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Poke@Waiter@synchronization_internal@absl@@QAEXXZ
     ?Post@Waiter@synchronization_internal@absl@@QAEXXZ
-    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QAEX_JI@Z
+    ?PrepareForSampling@HashtablezInfo@container_internal@absl@@QAEXI@Z
     ?PrepareToModify@Status@absl@@AAEXXZ
     ?Prepend@Cord@absl@@QAEXABV12@@Z
     ?Prepend@CordRepBtree@cord_internal@absl@@SAPAV123@PAV123@Vstring_view@3@I@Z
@@ -705,7 +707,7 @@
     ?ReverseConsume@cord_internal@absl@@YAXPAUCordRep@12@V?$FunctionRef@$$A6AXPAUCordRep@cord_internal@absl@@II@Z@2@@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QBE_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPBDI@Z
-    ?SampleSlow@container_internal@absl@@YAPAUHashtablezInfo@12@AAUSamplingState@12@I@Z
+    ?SampleSlow@container_internal@absl@@YAPAUHashtablezInfo@12@PA_JI@Z
     ?Seek@CordRepBtreeReader@cord_internal@absl@@QAE?AVstring_view@3@I@Z
     ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QAEXI@Z
     ?SetCurrentThreadIdentity@base_internal@absl@@YAXPAUThreadIdentity@12@P6AXPAX@Z@Z
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
index e06d8b6..1b97f73 100644
--- a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
+++ b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
@@ -82,6 +82,7 @@
       'androidx_constraintlayout',
       'androidx_documentfile',
       'androidx_legacy',
+      'androidx_localbroadcastmanager_localbroadcastmanager',
       'androidx_multidex_multidex',
       'androidx_print',
       'androidx_test',
diff --git a/third_party/androidx/build.gradle.template b/third_party/androidx/build.gradle.template
index f93f2406..7d4133a 100644
--- a/third_party/androidx/build.gradle.template
+++ b/third_party/androidx/build.gradle.template
@@ -45,7 +45,6 @@
     compile 'androidx.interpolator:interpolator:{{androidx_dependency_version}}'
     compile 'androidx.leanback:leanback:{{androidx_dependency_version}}'
     compile 'androidx.leanback:leanback-preference:{{androidx_dependency_version}}'
-    compile 'androidx.localbroadcastmanager:localbroadcastmanager:{{androidx_dependency_version}}'
     compile 'androidx.media:media:{{androidx_dependency_version}}'
     compile 'androidx.mediarouter:mediarouter:{{androidx_dependency_version}}'
     compile 'androidx.preference:preference:{{androidx_dependency_version}}'
diff --git a/third_party/androidx/fetch_all_androidx.py b/third_party/androidx/fetch_all_androidx.py
index e3b32ea..2d065aa 100755
--- a/third_party/androidx/fetch_all_androidx.py
+++ b/third_party/androidx/fetch_all_androidx.py
@@ -7,14 +7,16 @@
 
 More specifically, to generate build.gradle:
   - It downloads the BUILD_INFO file for the latest androidx snapshot from
-    https://androidx.dev/snapshots/
+    https://androidx.dev/snapshots/builds
   - It replaces {{androidx_repository_url}} with the URL for the latest snapshot
   - For each dependency, it looks up the version in the BUILD_INFO file and
     substitutes the version into {{androidx_dependency_version}}.
 """
 
+import argparse
 import contextlib
 import json
+import logging
 import os
 import re
 import shutil
@@ -117,6 +119,9 @@
     with _build_dir() as build_dir:
         androidx_build_info_response = request.urlopen(
             _ANDROIDX_LATEST_SNAPSHOT_BUILD_INFO_URL)
+        androidx_build_info_url = androidx_build_info_response.geturl()
+        logging.info('URL for the latest build info: %s',
+                     androidx_build_info_url)
         androidx_build_info_path = os.path.join(build_dir, 'BUILD_INFO')
         with open(androidx_build_info_path, 'w') as f:
             f.write(androidx_build_info_response.read().decode('utf-8'))
@@ -126,7 +131,7 @@
             _build_snapshot_repository_url('([0-9]*)').rsplit('/', 1)[0])
 
         version = re.match(resolved_snapshot_repository_url_pattern,
-                           androidx_build_info_response.geturl()).group(1)
+                           androidx_build_info_url).group(1)
 
         with open(androidx_build_info_path, 'r') as f:
             build_info_dict = json.loads(f.read())
@@ -198,6 +203,19 @@
 
 
 def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument('-v',
+                        '--verbose',
+                        dest='verbose_count',
+                        default=0,
+                        action='count',
+                        help='Verbose level (multiple times for more)')
+    args = parser.parse_args()
+
+    logging.basicConfig(
+        level=logging.WARNING - 10 * args.verbose_count,
+        format='%(levelname).1s %(relativeCreated)6d %(message)s')
+
     libs_dir = os.path.join(_ANDROIDX_PATH, 'libs')
 
     # Let recipe delete contents of lib directory because it has API to retry
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index d45ca0a..2280526 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -1161,6 +1161,10 @@
 const base::Feature kAutoExpandDetailsElement{"AutoExpandDetailsElement",
                                               base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Enables loading the response body earlier in navigation.
+const base::Feature kEarlyBodyLoad{"EarlyBodyLoad",
+                                   base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables fetching the code cache earlier in navigation.
 const base::Feature kEarlyCodeCache{"EarlyCodeCache",
                                     base::FEATURE_DISABLED_BY_DEFAULT};
@@ -1205,5 +1209,8 @@
 
 const base::Feature kSystemColorChooser{"SystemColorChooser",
                                         base::FEATURE_DISABLED_BY_DEFAULT};
+
+const base::Feature kNoForcedFrameUpdates{"NoForcedFrameUpdates",
+                                          base::FEATURE_DISABLED_BY_DEFAULT};
 }  // namespace features
 }  // namespace blink
diff --git a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
index b9a65b0a..386ce09d 100644
--- a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
+++ b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
@@ -97,8 +97,6 @@
   out->accelerated_2d_canvas_enabled = data.accelerated_2d_canvas_enabled();
   out->new_canvas_2d_api_enabled = data.new_canvas_2d_api_enabled();
   out->canvas_2d_layers_enabled = data.canvas_2d_layers_enabled();
-  out->canvas_context_lost_in_background_enabled =
-      data.canvas_context_lost_in_background_enabled();
   out->antialiased_2d_canvas_disabled = data.antialiased_2d_canvas_disabled();
   out->antialiased_clips_2d_canvas_enabled =
       data.antialiased_clips_2d_canvas_enabled();
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index ca0a3b8..c9475eac 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -559,6 +559,8 @@
 // and released to stable with no issues.
 BLINK_COMMON_EXPORT extern const base::Feature kAutoExpandDetailsElement;
 
+BLINK_COMMON_EXPORT extern const base::Feature kEarlyBodyLoad;
+
 BLINK_COMMON_EXPORT extern const base::Feature kEarlyCodeCache;
 
 BLINK_COMMON_EXPORT extern const base::Feature
@@ -597,6 +599,9 @@
 
 BLINK_COMMON_EXPORT extern const base::Feature kSystemColorChooser;
 
+// Disables forced frame updates for web tests. Used by web test runner only.
+BLINK_COMMON_EXPORT extern const base::Feature kNoForcedFrameUpdates;
+
 }  // namespace features
 }  // namespace blink
 
diff --git a/third_party/blink/public/common/web_preferences/web_preferences.h b/third_party/blink/public/common/web_preferences/web_preferences.h
index a8d4f19..8509f72 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences.h
@@ -96,7 +96,6 @@
   bool hide_scrollbars;
   bool accelerated_2d_canvas_enabled;
   bool canvas_2d_layers_enabled = false;
-  bool canvas_context_lost_in_background_enabled = false;
   bool new_canvas_2d_api_enabled;
   bool antialiased_2d_canvas_disabled;
   bool antialiased_clips_2d_canvas_enabled;
diff --git a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
index dc84e6f5..a6291be 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
@@ -218,11 +218,6 @@
     return r.accelerated_2d_canvas_enabled;
   }
 
-  static bool canvas_context_lost_in_background_enabled(
-      const blink::web_pref::WebPreferences& r) {
-    return r.canvas_context_lost_in_background_enabled;
-  }
-
   static bool new_canvas_2d_api_enabled(
       const blink::web_pref::WebPreferences& r) {
     return r.new_canvas_2d_api_enabled;
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index dec4c4c..13a7e61 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -6154,6 +6154,7 @@
       SameOriginAllowPopups
       UnsafeNone
       SameOriginPlusCoep
+      SameOriginAllowPopupsPlusCoep
 
   experimental type CrossOriginOpenerPolicyStatus extends object
     properties
diff --git a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
index 067bb3b..c09e8c49 100644
--- a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
+++ b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
@@ -151,7 +151,6 @@
   bool webgl_errors_to_console_enabled;
   bool hide_scrollbars;
   bool accelerated_2d_canvas_enabled;
-  bool canvas_context_lost_in_background_enabled;
   bool new_canvas_2d_api_enabled;
   bool canvas_2d_layers_enabled;
   bool antialiased_2d_canvas_disabled;
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 166c32b..45f6662 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1226,7 +1226,6 @@
     "css/mock_css_paint_image_generator.h",
     "display_lock/display_lock_context_test.cc",
     "display_lock/display_lock_utilities_test.cc",
-    "document_transition/document_transition_origin_trial_test.cc",
     "document_transition/document_transition_test.cc",
     "editing/caret_display_item_client_test.cc",
     "editing/finder/text_finder_test.cc",
diff --git a/third_party/blink/renderer/core/animation/animation_timeline.cc b/third_party/blink/renderer/core/animation/animation_timeline.cc
index d4725fd2..4b954b95 100644
--- a/third_party/blink/renderer/core/animation/animation_timeline.cc
+++ b/third_party/blink/renderer/core/animation/animation_timeline.cc
@@ -177,8 +177,10 @@
   DCHECK(animation->Outdated());
   outdated_animation_count_++;
   animations_needing_update_.insert(animation);
-  if (IsActive() && !document_->GetPage()->Animator().IsServicingAnimations())
+  if (IsActive() && document_->GetPage() &&
+      !document_->GetPage()->Animator().IsServicingAnimations()) {
     ScheduleServiceOnNextFrame();
+  }
 }
 
 void AnimationTimeline::ScheduleServiceOnNextFrame() {
diff --git a/third_party/blink/renderer/core/app_history/app_history.cc b/third_party/blink/renderer/core/app_history/app_history.cc
index ca6c267..c805f80 100644
--- a/third_party/blink/renderer/core/app_history/app_history.cc
+++ b/third_party/blink/renderer/core/app_history/app_history.cc
@@ -313,12 +313,6 @@
     keys_to_indices_.insert(entries_[current_index_]->key(), current_index_);
   }
 
-  auto* init = AppHistoryCurrentChangeEventInit::Create();
-  init->setNavigationType(DetermineNavigationType(type));
-  init->setFrom(old_current);
-  DispatchEvent(*AppHistoryCurrentChangeEvent::Create(
-      event_type_names::kCurrentchange, init));
-
   // It's important to do this before firing dispose events, since dispose
   // events could start another navigation or otherwise mess with
   // ongoing_navigation_.
@@ -327,6 +321,12 @@
         entries_[current_index_]);
   }
 
+  auto* init = AppHistoryCurrentChangeEventInit::Create();
+  init->setNavigationType(DetermineNavigationType(type));
+  init->setFrom(old_current);
+  DispatchEvent(*AppHistoryCurrentChangeEvent::Create(
+      event_type_names::kCurrentchange, init));
+
   for (const auto& disposed_entry : disposed_entries) {
     disposed_entry->DispatchEvent(*Event::Create(event_type_names::kDispose));
   }
@@ -699,8 +699,23 @@
     NavigateReaction::ReactType react_type =
         promise_list.IsEmpty() ? NavigateReaction::ReactType::kImmediate
                                : NavigateReaction::ReactType::kTransitionWhile;
+
+    // There is a subtle timing difference between the fast-path for zero
+    // promises and the path for 1+ promises, in both spec and implementation.
+    // In most uses of ScriptPromise::All / the Web IDL spec's "wait for all",
+    // this does not matter. However for us there are so many events and promise
+    // handlers firing around the same time (navigatesuccess, committed promise,
+    // finished promise, ...) that the difference is pretty easily observable by
+    // web developers and web platform tests. So, let's make sure we always go
+    // down the 1+ promises path.
+    const HeapVector<ScriptPromise>& tweaked_promise_list =
+        promise_list.IsEmpty()
+            ? HeapVector<ScriptPromise>(
+                  {ScriptPromise::CastUndefined(script_state)})
+            : promise_list;
+
     NavigateReaction::React(
-        script_state, ScriptPromise::All(script_state, promise_list),
+        script_state, ScriptPromise::All(script_state, tweaked_promise_list),
         ongoing_navigation_, transition_, navigate_event->signal(), react_type);
   } else if (ongoing_navigation_) {
     // The spec assumes it's ok to leave a promise permanently unresolved, but
diff --git a/third_party/blink/renderer/core/app_history/app_history_api_navigation.cc b/third_party/blink/renderer/core/app_history/app_history_api_navigation.cc
index 7fdda90..79f9bbd 100644
--- a/third_party/blink/renderer/core/app_history/app_history_api_navigation.cc
+++ b/third_party/blink/renderer/core/app_history/app_history_api_navigation.cc
@@ -34,6 +34,20 @@
       result_(AppHistoryResult::Create()) {
   result_->setCommitted(committed_resolver_->Promise());
   result_->setFinished(finished_resolver_->Promise());
+
+  // The web developer doesn't necessarily care about finished promise
+  // rejections:
+  // * They could be listening to other transition-failure signals, like the
+  // navigateerror event, or appHistory.transition.finished.
+  // * They could be doing synchronous navigations within the same task, in
+  // which case the second will always abort the first (causing a rejected
+  // finished promise), but they might not care
+  // * If the committed promise rejects, finished will also reject in the same
+  // way, so any commit failures will already be signaled and saying that you
+  // also have to handle the finished promise is frustrating.
+  //
+  // As such, we mark it as handled to avoid unhandled rejection events.
+  finished_resolver_->Promise().MarkAsHandled();
 }
 
 void AppHistoryApiNavigation::NotifyAboutTheCommittedToEntry(
@@ -42,21 +56,12 @@
   committed_to_entry_ = entry;
 
   committed_resolver_->Resolve(committed_to_entry_);
-
-  if (did_finish_before_commit_) {
-    ResolveFinishedPromise();
-  }
 }
 
 void AppHistoryApiNavigation::ResolveFinishedPromise() {
   if (!app_history_)
     return;
 
-  if (!committed_to_entry_) {
-    did_finish_before_commit_ = true;
-    return;
-  }
-
   finished_resolver_->Resolve(committed_to_entry_);
 
   app_history_->CleanupApiNavigation(*this);
diff --git a/third_party/blink/renderer/core/app_history/app_history_api_navigation.h b/third_party/blink/renderer/core/app_history/app_history_api_navigation.h
index 6bff9525..e70760a 100644
--- a/third_party/blink/renderer/core/app_history/app_history_api_navigation.h
+++ b/third_party/blink/renderer/core/app_history/app_history_api_navigation.h
@@ -60,11 +60,6 @@
   Member<ScriptPromiseResolver> committed_resolver_;
   Member<ScriptPromiseResolver> finished_resolver_;
   Member<AppHistoryResult> result_;
-
-  // In same-document traversal cases ResolveFinishedPromise() can be called
-  // before NotifyAboutTheCommittedToEntry(). This tracks that, to let us ensure
-  // NotifyAboutTheCommittedToEntry() can also resolve the finished promise.
-  bool did_finish_before_commit_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc b/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc
index 552cf04..9c535794 100644
--- a/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc
+++ b/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc
@@ -89,8 +89,6 @@
     return StylePropertySerializer(*inline_style)
         .SerializeShorthand(property.PropertyID());
   }
-
-  NOTREACHED();
   return "";
 }
 
diff --git a/third_party/blink/renderer/core/document_transition/document_transition.cc b/third_party/blink/renderer/core/document_transition/document_transition.cc
index 3bb65b2..98c4f9f2 100644
--- a/third_party/blink/renderer/core/document_transition/document_transition.cc
+++ b/third_party/blink/renderer/core/document_transition/document_transition.cc
@@ -9,7 +9,6 @@
 #include "base/trace_event/trace_event.h"
 #include "cc/document_transition/document_transition_request.h"
 #include "cc/trees/paint_holding_reason.h"
-#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_document_transition_config.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_document_transition_prepare_options.h"
@@ -116,6 +115,10 @@
     start_promise_resolver_->Detach();
     start_promise_resolver_ = nullptr;
   }
+  if (style_tracker_) {
+    style_tracker_->Abort();
+    style_tracker_ = nullptr;
+  }
   active_shared_elements_.clear();
   signal_ = nullptr;
   StopDeferringCommits();
@@ -226,7 +229,7 @@
           &DocumentTransition::NotifyPrepareFinished,
           WrapCrossThreadWeakPersistent(this), last_prepare_sequence_id_)));
 
-  if (base::FeatureList::IsEnabled(features::kDocumentTransitionRenderer)) {
+  if (RuntimeEnabledFeatures::DocumentTransitionRendererEnabled()) {
     style_tracker_ =
         MakeGarbageCollected<DocumentTransitionStyleTracker>(*document_);
     style_tracker_->Prepare(active_shared_elements_);
@@ -274,7 +277,7 @@
     // TODO(khushalsagar) : Viz keeps copy results cached for 5 seconds at this
     // point. We should send an early release. See crbug.com/1266500.
     SetActiveSharedElements({});
-    if (base::FeatureList::IsEnabled(features::kDocumentTransitionRenderer)) {
+    if (RuntimeEnabledFeatures::DocumentTransitionRendererEnabled()) {
       style_tracker_->Abort();
       style_tracker_ = nullptr;
     }
@@ -285,7 +288,7 @@
   state_ = State::kStarted;
   start_promise_resolver_ =
       MakeGarbageCollected<ScriptPromiseResolver>(script_state);
-  if (base::FeatureList::IsEnabled(features::kDocumentTransitionRenderer)) {
+  if (RuntimeEnabledFeatures::DocumentTransitionRendererEnabled()) {
     pending_request_ =
         DocumentTransitionRequest::CreateAnimateRenderer(document_tag_);
     style_tracker_->Start(active_shared_elements_);
@@ -358,7 +361,7 @@
   state_ = State::kIdle;
   SetActiveSharedElements({});
 
-  if (base::FeatureList::IsEnabled(features::kDocumentTransitionRenderer)) {
+  if (RuntimeEnabledFeatures::DocumentTransitionRendererEnabled()) {
     style_tracker_->StartFinished();
     style_tracker_ = nullptr;
     pending_request_ = DocumentTransitionRequest::CreateRelease(document_tag_);
@@ -390,7 +393,7 @@
     // This tags the shared element's content with the resource id used by the
     // first pseudo element. This is okay since in the eventual API we should
     // have a 1:1 mapping between shared elements and pseudo elements.
-    if (base::FeatureList::IsEnabled(features::kDocumentTransitionRenderer)) {
+    if (RuntimeEnabledFeatures::DocumentTransitionRendererEnabled()) {
       if (!resource_id->IsValid()) {
         *resource_id = style_tracker_->GetLiveSnapshotId(element);
       }
@@ -442,15 +445,21 @@
   if (style_tracker_) {
     style_tracker_->RunPostLayoutSteps();
     // If we don't have active animations, schedule a frame to end the
-    // transition. Note that if `disable_end_transition_` is set, then we don't
-    // need to register for lifecycle notifications since we're not ending this
-    // transition.
+    // transition. Note that if we don't have start_promise_resolver_ we don't
+    // need to finish the animation, since it should already be done. See the
+    // DCHECK below.
     //
     // TODO(vmpstr): Note that RunPostLayoutSteps can happen multiple times
     // during a lifecycle update. These checks don't have to happen here, and
     // could perhaps be moved to DidFinishLifecycleUpdate.
+    //
+    // We can end up here multiple times, but if we are in a started state and
+    // don't have a start promise resolver then the only way we're here is if we
+    // disabled end transition.
+    DCHECK(state_ != State::kStarted || start_promise_resolver_ ||
+           disable_end_transition_);
     if (state_ == State::kStarted && !style_tracker_->HasActiveAnimations() &&
-        !disable_end_transition_) {
+        start_promise_resolver_) {
       DCHECK(document_->View());
       document_->View()->RegisterForLifecycleNotifications(this);
       document_->View()->ScheduleAnimation();
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_origin_trial_test.cc b/third_party/blink/renderer/core/document_transition/document_transition_origin_trial_test.cc
deleted file mode 100644
index db3a070c..0000000
--- a/third_party/blink/renderer/core/document_transition/document_transition_origin_trial_test.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2021 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 <vector>
-#include "base/bind.h"
-#include "base/cxx17_backports.h"
-#include "base/test/scoped_feature_list.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/common/origin_trials/scoped_test_origin_trial_policy.h"
-#include "third_party/blink/renderer/core/document_transition/document_transition_supplement.h"
-#include "third_party/blink/renderer/core/frame/local_dom_window.h"
-#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/core/frame/settings.h"
-#include "third_party/blink/renderer/core/html/html_head_element.h"
-#include "third_party/blink/renderer/core/html/html_meta_element.h"
-#include "third_party/blink/renderer/core/html/html_script_element.h"
-#include "third_party/blink/renderer/core/html_names.h"
-#include "third_party/blink/renderer/core/script/classic_script.h"
-#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-
-namespace blink {
-namespace {
-
-// Generated by:
-//  tools/origin_trials/generate_token.py --version 3 --expire-days 3650 \
-//      https://documenttransition.test DocumentTransition
-// Token details:
-//   Version: 3
-//   Origin: https://documenttransition.test:443
-//   Is Subdomain: None
-//   Is Third Party: None
-//   Usage Restriction: None
-//   Feature: DocumentTransition
-//   Expiry: 1935769331 (2031-05-05 17:42:11 UTC)
-//   Signature (Base64):
-//   E22eLb6pyd0TWZLONxJOIxUa86AFkIFgijoM1ZKA2k9440xSvhBC5rzyhGjDUNWUQuaIE1yE4811ogD7ZNaFDA==
-
-constexpr char kDocumentTransitionToken[] =
-    "AxNtni2+qcndE1mSzjcSTiMVGvOgBZCBYIo6DNWSgNpPeONMUr4QQua88oRow1DVlE"
-    "LmiBNchOPNdaIA+2TWhQwAAABoeyJvcmlnaW4iOiAiaHR0cHM6Ly9kb2N1bWVudHRy"
-    "YW5zaXRpb24udGVzdDo0NDMiLCAiZmVhdHVyZSI6ICJEb2N1bWVudFRyYW5zaXRpb2"
-    "4iLCAiZXhwaXJ5IjogMTkzNTc2OTMzMX0=";
-
-::testing::AssertionResult CheckTokenControlsFeature(const char* trial_token) {
-  blink::ScopedTestOriginTrialPolicy using_test_keys;
-
-  DummyPageHolder page_holder;
-  Document& document = page_holder.GetDocument();
-
-  // Clear the security origin and set a secure one, recomputing the security
-  // state.
-  SecurityContext& security_context =
-      page_holder.GetFrame().DomWindow()->GetSecurityContext();
-  security_context.SetSecurityOriginForTesting(nullptr);
-  security_context.SetSecurityOrigin(
-      SecurityOrigin::CreateFromString("https://documenttransition.test"));
-  EXPECT_EQ(security_context.GetSecureContextMode(),
-            SecureContextMode::kSecureContext);
-
-  // Enable scripts so that <script> is not ignored.
-  page_holder.GetFrame().GetSettings()->SetScriptEnabled(true);
-
-  EXPECT_FALSE(RuntimeEnabledFeatures::DocumentTransitionEnabled(
-      document.GetExecutionContext()));
-
-  HTMLMetaElement* meta =
-      MakeGarbageCollected<HTMLMetaElement>(document, CreateElementFlags());
-  meta->setAttribute(html_names::kHttpEquivAttr, "Origin-Trial");
-  meta->setAttribute(html_names::kContentAttr, trial_token);
-  document.head()->appendChild(meta);
-
-  v8::HandleScope scope(v8::Isolate::GetCurrent());
-  auto value =
-      ClassicScript::CreateUnspecifiedScript("!!document.documentTransition")
-          ->RunScriptAndReturnValue(document.domWindow());
-
-  NonThrowableExceptionState exceptionState;
-  bool enabled = ToBoolean(scope.GetIsolate(), value, exceptionState);
-
-  EXPECT_EQ(RuntimeEnabledFeatures::DocumentTransitionEnabled(
-                document.GetExecutionContext()),
-            enabled);
-
-  return enabled
-             ? ::testing::AssertionSuccess() << "feature enabled by token"
-             : ::testing::AssertionFailure() << "feature not enabled by token";
-}
-
-TEST(DocumentTransitionOriginTrialTest, ValidTokenControlsFeature) {
-  EXPECT_TRUE(CheckTokenControlsFeature(kDocumentTransitionToken));
-}
-
-TEST(DocumentTransitionOriginTrialTest, InvalidTokenIsIgnored) {
-  EXPECT_FALSE(CheckTokenControlsFeature("invalid token"));
-}
-
-}  // namespace
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc b/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc
index 8f1766b..21fd84e 100644
--- a/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc
+++ b/third_party/blink/renderer/core/document_transition/document_transition_style_tracker.cc
@@ -172,7 +172,6 @@
 }
 
 void DocumentTransitionStyleTracker::Abort() {
-  DCHECK_NE(state_, State::kStarted);
   EndTransition();
 }
 
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_test.cc b/third_party/blink/renderer/core/document_transition/document_transition_test.cc
index 1b86a44..2d923a6b 100644
--- a/third_party/blink/renderer/core/document_transition/document_transition_test.cc
+++ b/third_party/blink/renderer/core/document_transition/document_transition_test.cc
@@ -9,7 +9,6 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/test/scoped_feature_list.h"
 #include "cc/document_transition/document_transition_request.h"
-#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/web/web_settings.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
@@ -35,11 +34,12 @@
 
 class DocumentTransitionTest : public testing::Test,
                                public PaintTestConfigurations,
-                               private ScopedDocumentTransitionForTest {
+                               private ScopedDocumentTransitionForTest,
+                               private ScopedDocumentTransitionRendererForTest {
  public:
-  DocumentTransitionTest() : ScopedDocumentTransitionForTest(true) {
-    feature_list_.InitWithFeatures({features::kDocumentTransitionRenderer}, {});
-  }
+  DocumentTransitionTest()
+      : ScopedDocumentTransitionForTest(true),
+        ScopedDocumentTransitionRendererForTest(true) {}
 
   static void ConfigureCompositingWebView(WebSettings* settings) {
     settings->SetPreferCompositingToLCDTextEnabled(true);
@@ -161,7 +161,6 @@
 
  protected:
   std::unique_ptr<frame_test_helpers::WebViewHelper> web_view_helper_;
-  base::test::ScopedFeatureList feature_list_;
 };
 
 INSTANTIATE_PAINT_TEST_SUITE_P(DocumentTransitionTest);
diff --git a/third_party/blink/renderer/core/dom/document_init.cc b/third_party/blink/renderer/core/dom/document_init.cc
index 4155bfc2..9667617 100644
--- a/third_party/blink/renderer/core/dom/document_init.cc
+++ b/third_party/blink/renderer/core/dom/document_init.cc
@@ -110,7 +110,6 @@
 // static
 DocumentInit::Type DocumentInit::ComputeDocumentType(
     LocalFrame* frame,
-    const KURL& url,
     const String& mime_type,
     bool* is_for_external_handler) {
   if (frame && frame->InViewSourceMode())
@@ -134,7 +133,7 @@
     return Type::kMedia;
 
   if (frame && frame->GetPage() && frame->Loader().AllowPlugins()) {
-    PluginData* plugin_data = GetPluginData(frame, url);
+    PluginData* plugin_data = GetPluginData(frame);
 
     // Everything else except text/plain can be overridden by plugins.
     // Disallowing plugins to use text/plain prevents plugins from hijacking a
@@ -172,21 +171,13 @@
 }
 
 // static
-PluginData* DocumentInit::GetPluginData(LocalFrame* frame, const KURL& url) {
-  // If the document is being created for the main frame,
-  // frame()->tree().top()->securityContext() returns nullptr.
-  // For that reason, the origin must be retrieved directly from |url|.
-  if (frame->IsMainFrame())
-    return frame->GetPage()->GetPluginData(SecurityOrigin::Create(url).get());
-
-  const SecurityOrigin* main_frame_origin =
-      frame->Tree().Top().GetSecurityContext()->GetSecurityOrigin();
-  return frame->GetPage()->GetPluginData(main_frame_origin);
+PluginData* DocumentInit::GetPluginData(LocalFrame* frame) {
+  return frame->GetPage()->GetPluginData();
 }
 
 DocumentInit& DocumentInit::WithTypeFrom(const String& mime_type) {
   mime_type_ = mime_type;
-  type_ = ComputeDocumentType(window_ ? window_->GetFrame() : nullptr, Url(),
+  type_ = ComputeDocumentType(window_ ? window_->GetFrame() : nullptr,
                               mime_type_, &is_for_external_handler_);
   return *this;
 }
diff --git a/third_party/blink/renderer/core/dom/document_init.h b/third_party/blink/renderer/core/dom/document_init.h
index 4e1b6f5a..e5d6d79 100644
--- a/third_party/blink/renderer/core/dom/document_init.h
+++ b/third_party/blink/renderer/core/dom/document_init.h
@@ -106,14 +106,13 @@
   DocumentInit& ForPrerendering(bool is_prerendering);
   bool IsPrerendering() const { return is_prerendering_; }
 
-  // Compute the type of document to be loaded inside a |frame|, given its |url|
-  // and its |mime_type|.
+  // Compute the type of document to be loaded inside a `frame`, given its
+  // `mime_type`.
   //
   // In case of plugin handled by MimeHandlerview (which do not create a
-  // PluginDocument), the type is Type::KHTML and |is_for_external_handler| is
+  // PluginDocument), the type is Type::KHTML and `is_for_external_handler` is
   // set to true.
   static Type ComputeDocumentType(LocalFrame* frame,
-                                  const KURL& url,
                                   const String& mime_type,
                                   bool* is_for_external_handler = nullptr);
   DocumentInit& WithTypeFrom(const String& mime_type);
@@ -141,7 +140,7 @@
  private:
   DocumentInit() = default;
 
-  static PluginData* GetPluginData(LocalFrame* frame, const KURL& url);
+  static PluginData* GetPluginData(LocalFrame* frame);
 
   Type type_ = Type::kUnspecified;
   bool is_prerendering_ = false;
diff --git a/third_party/blink/renderer/core/dom/document_parser.h b/third_party/blink/renderer/core/dom/document_parser.h
index 7eafb19..37f97bd3 100644
--- a/third_party/blink/renderer/core/dom/document_parser.h
+++ b/third_party/blink/renderer/core/dom/document_parser.h
@@ -101,6 +101,10 @@
   // HTMLDocumentParser to dispatch preloads.
   virtual void DocumentElementAvailable() {}
 
+  // Notifies the parser that any data which was added when preloading can now
+  // be parsed.
+  virtual void CommitPreloadedData() {}
+
   void SetDocumentWasLoadedAsPartOfNavigation() {
     document_was_loaded_as_part_of_navigation_ = true;
   }
@@ -108,6 +112,9 @@
     return document_was_loaded_as_part_of_navigation_;
   }
 
+  void SetIsPreloading(bool is_preloading) { is_preloading_ = is_preloading; }
+  bool IsPreloading() const { return is_preloading_; }
+
   void AddClient(DocumentParserClient*);
   void RemoveClient(DocumentParserClient*);
 
@@ -123,6 +130,7 @@
   };
   ParserState state_;
   bool document_was_loaded_as_part_of_navigation_;
+  bool is_preloading_ = false;
 
   // Every DocumentParser needs a pointer back to the document.
   // document_ will be 0 after the parser is stopped.
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index a15581a..5a6f7fc 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -669,31 +669,35 @@
   DCHECK(
       !GetDocument().IsActive() || GetDocument().InStyleRecalc() ||
       !GetDocument().NeedsLayoutTreeUpdateForNodeIncludingDisplayLocked(*this));
-  // Elements in canvas fallback content are not rendered, but they are allowed
-  // to be focusable as long as they aren't expressly inert and their canvas is
-  // displayed and visible.
-  if (IsInCanvasSubtree()) {
-    // TODO(obrufau): the element can be inert when GetComputedStyle() is null.
-    // Should maybe use EnsureComputedStyle(), but it's not const.
-    if (const ComputedStyle* style = GetComputedStyle()) {
-      if (style->IsInert())
-        return false;
-    }
-    const HTMLCanvasElement* canvas =
-        Traversal<HTMLCanvasElement>::FirstAncestorOrSelf(*this);
-    DCHECK(canvas);
-    return canvas->GetLayoutObject() &&
-           canvas->GetLayoutObject()->Style()->Visibility() ==
-               EVisibility::kVisible;
-  }
 
   // FIXME: Even if we are not visible, we might have a child that is visible.
   // Hyatt wants to fix that some day with a "has visible content" flag or the
   // like.
+  auto IsFocusable = [](const ComputedStyle* style) {
+    return style && !style->IsEnsuredInDisplayNone() &&
+           style->Display() != EDisplay::kContents && !style->IsInert() &&
+           style->Visibility() == EVisibility::kVisible;
+  };
+
   if (LayoutObject* layout_object = GetLayoutObject()) {
-    const ComputedStyle& style = layout_object->StyleRef();
-    return !style.IsInert() && style.Visibility() == EVisibility::kVisible;
+    if (IsFocusable(layout_object->Style()))
+      return true;
   }
+
+  // If a canvas represents embedded content, its descendants are not rendered.
+  // But they are still allowed to be focusable as long as their style allows
+  // focus, their canvas is rendered, and its style allows focus.
+  if (IsInCanvasSubtree()) {
+    if (!IsFocusable(GetComputedStyle()))
+      return false;
+
+    const HTMLCanvasElement* canvas =
+        Traversal<HTMLCanvasElement>::FirstAncestorOrSelf(*this);
+    DCHECK(canvas);
+    if (LayoutObject* layout_object = canvas->GetLayoutObject())
+      return layout_object->IsCanvas() && IsFocusable(layout_object->Style());
+  }
+
   return false;
 }
 
diff --git a/third_party/blink/renderer/core/dom/pseudo_element.cc b/third_party/blink/renderer/core/dom/pseudo_element.cc
index ed0c444..09cf25c 100644
--- a/third_party/blink/renderer/core/dom/pseudo_element.cc
+++ b/third_party/blink/renderer/core/dom/pseudo_element.cc
@@ -28,7 +28,6 @@
 
 #include <utility>
 
-#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
 #include "third_party/blink/renderer/core/document_transition/document_transition_pseudo_element_base.h"
 #include "third_party/blink/renderer/core/document_transition/document_transition_supplement.h"
@@ -143,10 +142,7 @@
     case kPseudoIdTransitionContainer:
     case kPseudoIdTransitionNewContent:
     case kPseudoIdTransitionOldContent:
-      return RuntimeEnabledFeatures::DocumentTransitionEnabled(
-                 parent->GetExecutionContext()) &&
-             base::FeatureList::IsEnabled(
-                 features::kDocumentTransitionRenderer);
+      return RuntimeEnabledFeatures::DocumentTransitionRendererEnabled();
     default:
       return true;
   }
diff --git a/third_party/blink/renderer/core/dom/shadow_root.cc b/third_party/blink/renderer/core/dom/shadow_root.cc
index f4bce404..03cfb48 100644
--- a/third_party/blink/renderer/core/dom/shadow_root.cc
+++ b/third_party/blink/renderer/core/dom/shadow_root.cc
@@ -202,6 +202,14 @@
   return kInsertionDone;
 }
 
+void ShadowRoot::UpdateType(ShadowRootType type) {
+  DCHECK(GetType() == ShadowRootType::kUserAgent);
+  DCHECK(RuntimeEnabledFeatures::HTMLSelectMenuElementEnabled());
+  DCHECK(IsA<HTMLSelectMenuElement>(host()))
+      << "Updating the type is only supported for <selectmenu> elements";
+  type_ = static_cast<unsigned>(type);
+}
+
 void ShadowRoot::RemovedFrom(ContainerNode& insertion_point) {
   if (insertion_point.isConnected()) {
     if (NeedsSlotAssignmentRecalc())
diff --git a/third_party/blink/renderer/core/dom/shadow_root.h b/third_party/blink/renderer/core/dom/shadow_root.h
index 8ebf908..e474cb5b 100644
--- a/third_party/blink/renderer/core/dom/shadow_root.h
+++ b/third_party/blink/renderer/core/dom/shadow_root.h
@@ -33,7 +33,6 @@
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/tree_scope.h"
-#include "third_party/blink/renderer/core/html/forms/html_select_menu_element.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/wtf/casting.h"
@@ -74,13 +73,7 @@
     return *To<Element>(ParentOrShadowHostNode());
   }
   ShadowRootType GetType() const { return static_cast<ShadowRootType>(type_); }
-  void UpdateType(ShadowRootType type) {
-    DCHECK(GetType() == ShadowRootType::kUserAgent);
-    DCHECK(RuntimeEnabledFeatures::HTMLSelectMenuElementEnabled());
-    DCHECK(IsA<HTMLSelectMenuElement>(host()))
-        << "Updating the type is only supported for <selectmenu> elements";
-    type_ = static_cast<unsigned>(type);
-  }
+  void UpdateType(ShadowRootType type);
   String mode() const {
     switch (GetType()) {
       case ShadowRootType::kUserAgent:
diff --git a/third_party/blink/renderer/core/editing/frame_caret.cc b/third_party/blink/renderer/core/editing/frame_caret.cc
index 935fb61..a9e33499 100644
--- a/third_party/blink/renderer/core/editing/frame_caret.cc
+++ b/third_party/blink/renderer/core/editing/frame_caret.cc
@@ -214,11 +214,13 @@
   auto change_type = effect_->Update(
       *effect_->Parent(),
       CaretEffectNodeState(visible, effect_->LocalTransformSpace()));
-  DCHECK_EQ(PaintPropertyChangeType::kChangedOnlySimpleValues, change_type);
-  if (auto* compositor = frame_->View()->GetPaintArtifactCompositor()) {
-    if (compositor->DirectlyUpdateCompositedOpacityValue(*effect_)) {
-      effect_->CompositorSimpleValuesUpdated();
-      return;
+  if (is_composited_caret_enabled_) {
+    DCHECK_EQ(PaintPropertyChangeType::kChangedOnlySimpleValues, change_type);
+    if (auto* compositor = frame_->View()->GetPaintArtifactCompositor()) {
+      if (compositor->DirectlyUpdateCompositedOpacityValue(*effect_)) {
+        effect_->CompositorSimpleValuesUpdated();
+        return;
+      }
     }
   }
   // Fallback to full update if direct update is not available.
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 297ed65..f4743df 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1481,10 +1481,6 @@
   RuntimeEnabledFeatures::SetAccelerated2dCanvasEnabled(
       prefs.accelerated_2d_canvas_enabled);
 
-  // Enable canvas to clear its context when it is running in background.
-  RuntimeEnabledFeatures::SetCanvasContextLostInBackgroundEnabled(
-      prefs.canvas_context_lost_in_background_enabled);
-
   // Enable new canvas 2d api features
   RuntimeEnabledFeatures::SetNewCanvas2DAPIEnabled(
       prefs.new_canvas_2d_api_enabled);
diff --git a/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc b/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc
index 525d77c7..30864b2 100644
--- a/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc
+++ b/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc
@@ -67,25 +67,6 @@
   has_event_listener_ = false;
 }
 
-bool DeviceSingleWindowEventController::IsSameSecurityOriginAsMainFrame()
-    const {
-  LocalFrame* frame = GetWindow().GetFrame();
-  if (!frame)
-    return false;
-
-  if (frame->IsMainFrame())
-    return true;
-
-  const SecurityOrigin* main_security_origin =
-      frame->GetPage()->MainFrame()->GetSecurityContext()->GetSecurityOrigin();
-
-  if (main_security_origin &&
-      GetWindow().GetSecurityOrigin()->CanAccess(main_security_origin))
-    return true;
-
-  return false;
-}
-
 bool DeviceSingleWindowEventController::CheckPolicyFeatures(
     const Vector<mojom::blink::PermissionsPolicyFeature>& features) const {
   LocalDOMWindow& window = GetWindow();
diff --git a/third_party/blink/renderer/core/frame/device_single_window_event_controller.h b/third_party/blink/renderer/core/frame/device_single_window_event_controller.h
index 8d7ac75..0782868 100644
--- a/third_party/blink/renderer/core/frame/device_single_window_event_controller.h
+++ b/third_party/blink/renderer/core/frame/device_single_window_event_controller.h
@@ -33,7 +33,6 @@
  protected:
   explicit DeviceSingleWindowEventController(LocalDOMWindow&);
 
-  bool IsSameSecurityOriginAsMainFrame() const;
   bool CheckPolicyFeatures(
       const Vector<mojom::blink::PermissionsPolicyFeature>& features) const;
 
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index fa6b705..0997dcc9 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -38,6 +38,7 @@
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "third_party/blink/public/common/action_after_pagehide.h"
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/frame/event_page_show_persisted.h"
 #include "third_party/blink/public/mojom/permissions_policy/policy_disposition.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
@@ -719,7 +720,11 @@
   document_ = init.CreateDocument();
   document_->Initialize();
 
-  GetScriptController().UpdateDocument();
+  // If early body loading is turned on, UpdateDocument() will be called right
+  // after the body starts loading.
+  if (!base::FeatureList::IsEnabled(features::kEarlyBodyLoad))
+    GetScriptController().UpdateDocument();
+
   document_->GetViewportData().UpdateViewportDescription();
 
   auto* frame_scheduler = GetFrame()->GetFrameScheduler();
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index bb3841b..d02022a6 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1851,8 +1851,7 @@
 PluginData* LocalFrame::GetPluginData() const {
   if (!Loader().AllowPlugins())
     return nullptr;
-  return GetPage()->GetPluginData(
-      Tree().Top().GetSecurityContext()->GetSecurityOrigin());
+  return GetPage()->GetPluginData();
 }
 
 void LocalFrame::SetAdTrackerForTesting(AdTracker* ad_tracker) {
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 2741019..50bbe52 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -1841,8 +1841,6 @@
     }
   }
 
-  UpdateDocumentAnnotatedRegions();
-
   GetLayoutView()->EnclosingLayer()->UpdateLayerPositionsAfterLayout();
   frame_->Selection().DidLayout();
 
@@ -3172,6 +3170,7 @@
     PerformPostLayoutTasks(visual_viewport_size_changed);
     GetFrame().GetDocument()->LayoutUpdated();
   }
+  UpdateDocumentAnnotatedRegions();
   UpdateGeometriesIfNeeded();
 }
 
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index 254a9a2a..9a31eca8 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -978,8 +978,11 @@
     image_bitmap = context_->GetImage();
   }
 
-  if (!image_bitmap)
+  if (image_bitmap)
+    DCHECK(image_bitmap->SupportsDisplayCompositing());
+  else
     image_bitmap = CreateTransparentImage(size_);
+
   return image_bitmap;
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc
index 94b171b2..adb1a8f 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h"
 #include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/events/keyboard_event.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/html/forms/form_controller.h"
 #include "third_party/blink/renderer/core/html/forms/form_data.h"
@@ -271,6 +272,18 @@
 void HTMLSelectMenuElement::DidMoveToNewDocument(Document& old_document) {
   HTMLFormControlElementWithState::DidMoveToNewDocument(old_document);
   select_mutation_callback_->SetDocument(&GetDocument());
+
+  // Since we're observing the lifecycle updates, ensure that we listen to the
+  // right document's view.
+  if (queued_check_for_missing_parts_) {
+    if (old_document.View())
+      old_document.View()->UnregisterFromLifecycleNotifications(this);
+
+    if (GetDocument().View())
+      GetDocument().View()->RegisterForLifecycleNotifications(this);
+    else
+      queued_check_for_missing_parts_ = false;
+  }
 }
 
 String HTMLSelectMenuElement::value() const {
@@ -335,12 +348,7 @@
   if (new_listbox_part) {
     new_listbox_part->SetOwnerSelectMenuElement(this);
   } else {
-    GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
-        mojom::blink::ConsoleMessageSource::kRendering,
-        mojom::blink::ConsoleMessageLevel::kWarning,
-        "<selectmenu>'s default listbox was removed by an element labeled "
-        "slot=\"listbox\", and a new one was not provided. This <selectmenu> "
-        "will not be fully functional."));
+    QueueCheckForMissingParts();
   }
 
   listbox_part_ = new_listbox_part;
@@ -456,12 +464,7 @@
                                       button_part_listener_,
                                       /*use_capture=*/false);
   } else {
-    GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
-        mojom::blink::ConsoleMessageSource::kRendering,
-        mojom::blink::ConsoleMessageLevel::kWarning,
-        "<selectmenu>'s default button was removed by an element labeled "
-        "slot=\"button\", and a new one was not provided. This <selectmenu> "
-        "will not be fully functional."));
+    QueueCheckForMissingParts();
   }
 
   button_part_ = new_button_part;
@@ -592,6 +595,13 @@
   }
 }
 
+void HTMLSelectMenuElement::QueueCheckForMissingParts() {
+  if (!queued_check_for_missing_parts_ && GetDocument().View()) {
+    queued_check_for_missing_parts_ = true;
+    GetDocument().View()->RegisterForLifecycleNotifications(this);
+  }
+}
+
 void HTMLSelectMenuElement::ResetOptionParts() {
   // Remove part status from all current option parts
   while (!option_parts_.IsEmpty()) {
@@ -695,6 +705,35 @@
   }
 }
 
+void HTMLSelectMenuElement::DidFinishLifecycleUpdate(
+    const LocalFrameView& local_frame_view) {
+  Document* document = local_frame_view.GetFrame().GetDocument();
+  if (document->Lifecycle().GetState() <
+      DocumentLifecycle::kAfterPerformLayout) {
+    return;
+  }
+
+  DCHECK(queued_check_for_missing_parts_);
+  queued_check_for_missing_parts_ = false;
+  document->View()->UnregisterFromLifecycleNotifications(this);
+
+  if (!button_part_) {
+    GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+        mojom::blink::ConsoleMessageSource::kRendering,
+        mojom::blink::ConsoleMessageLevel::kWarning,
+        "A <selectmenu>'s default button was removed and a new one was not "
+        "provided. This <selectmenu> will not be fully functional."));
+  }
+
+  if (!listbox_part_) {
+    GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+        mojom::blink::ConsoleMessageSource::kRendering,
+        mojom::blink::ConsoleMessageLevel::kWarning,
+        "A <selectmenu>'s default listbox was removed and a new one was not "
+        "provided. This <selectmenu> will not be fully functional."));
+  }
+}
+
 HTMLOptionElement* HTMLSelectMenuElement::selectedOption() const {
   DCHECK(!selected_option_ ||
          IsValidOptionPart(selected_option_, /*show_warning=*/false));
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.h b/third_party/blink/renderer/core/html/forms/html_select_menu_element.h
index 4e74873..cd0e5db6 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_SELECT_MENU_ELEMENT_H_
 
 #include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
+#include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h"
 
 namespace blink {
@@ -21,12 +22,16 @@
 // https://groups.google.com/u/1/a/chromium.org/g/blink-dev/c/9TcfjaOs5zg/m/WAiv6WpUAAAJ
 // for more details.
 class CORE_EXPORT HTMLSelectMenuElement final
-    : public HTMLFormControlElementWithState {
+    : public HTMLFormControlElementWithState,
+      public LocalFrameView::LifecycleNotificationObserver {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
   explicit HTMLSelectMenuElement(Document&);
 
+  // LocalFrameView::LifecycleNotificationObserver
+  void DidFinishLifecycleUpdate(const LocalFrameView&) override;
+
   HTMLOptionElement* selectedOption() const;
   String value() const;
   void setValue(const String&, bool send_events = false);
@@ -87,6 +92,7 @@
   void UpdateListboxPart();
   void OptionPartInserted(HTMLOptionElement*);
   void OptionPartRemoved(HTMLOptionElement*);
+  void QueueCheckForMissingParts();
   void ResetOptionParts();
   void ResetToDefaultSelection();
   void DispatchInputAndChangeEventsIfNeeded();
@@ -161,6 +167,7 @@
   Member<HTMLSlotElement> listbox_slot_;
   Member<HTMLOptionElement> selected_option_;
   Member<HTMLOptionElement> selected_option_when_listbox_opened_;
+  bool queued_check_for_missing_parts_{false};
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_popup_element.cc b/third_party/blink/renderer/core/html/html_popup_element.cc
index 64b155e..cc238b1 100644
--- a/third_party/blink/renderer/core/html/html_popup_element.cc
+++ b/third_party/blink/renderer/core/html/html_popup_element.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
 #include "third_party/blink/renderer/core/events/keyboard_event.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -284,7 +285,11 @@
 }
 
 void HTMLPopupElement::HandleLightDismiss(const Event& event) {
-  auto* target_node = event.target()->ToNode();
+  if (event.GetEventPath().IsEmpty())
+    return;
+  // Ensure that shadow DOM event retargeting is considered when computing
+  // the event target node.
+  auto* target_node = event.GetEventPath()[0].Target()->ToNode();
   if (!target_node)
     return;
   auto& document = target_node->GetDocument();
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
index 080728b..6f00aadf 100644
--- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc
+++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -1343,6 +1343,15 @@
     return;
   }
 
+  // If we are preloading, FinishAppend() will be called later in
+  // CommitPreloadedData().
+  if (IsPreloading())
+    return;
+
+  FinishAppend();
+}
+
+void HTMLDocumentParser::FinishAppend() {
   // Schedule a tokenizer pump to process this new data. We schedule to give
   // paint a chance to happen, and because devtools somehow depends on it
   // for js loads.
@@ -1355,6 +1364,15 @@
   }
 }
 
+void HTMLDocumentParser::CommitPreloadedData() {
+  if (!IsPreloading())
+    return;
+
+  SetIsPreloading(false);
+  if (task_runner_state_->HaveSeenFirstByte() && !IsStopped())
+    FinishAppend();
+}
+
 void HTMLDocumentParser::end() {
   DCHECK(!IsDetached());
   DCHECK(!IsScheduledForUnpause());
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.h b/third_party/blink/renderer/core/html/parser/html_document_parser.h
index 208f9adf..30da9905 100644
--- a/third_party/blink/renderer/core/html/parser/html_document_parser.h
+++ b/third_party/blink/renderer/core/html/parser/html_document_parser.h
@@ -183,6 +183,7 @@
   void DidLoadAllPendingParserBlockingStylesheets() final;
   void CheckIfBlockingStylesheetAdded();
   void DocumentElementAvailable() override;
+  void CommitPreloadedData() override;
 
   // HTMLParserScriptRunnerHost
   void NotifyScriptLoaded() final;
@@ -243,6 +244,7 @@
   void ScanAndPreload(HTMLPreloadScanner*);
   void FetchQueuedPreloads();
   std::string GetPreloadHistogramSuffix();
+  void FinishAppend();
 
   HTMLToken& Token() { return *token_; }
 
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index 12b760b4..7633115 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -49,6 +49,7 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_content_security_policy_struct.h"
 #include "third_party/blink/public/platform/web_url_request.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/core/app_history/app_history.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_init.h"
@@ -394,6 +395,7 @@
       loading_srcdoc_(url_.IsAboutSrcdocURL()),
       loading_url_as_empty_document_(!params_->is_static_data &&
                                      WillLoadUrlAsEmpty(url_)),
+      is_static_data_(params_->is_static_data),
       web_bundle_physical_url_(params_->web_bundle_physical_url),
       web_bundle_claimed_url_(params_->web_bundle_claimed_url),
       ukm_source_id_(params_->document_ukm_source_id),
@@ -903,6 +905,12 @@
   if (cached_metadata_handler_) {
     cached_metadata_handler_->SetSerializedCachedMetadata(std::move(data));
   }
+
+  if (base::FeatureList::IsEnabled(features::kEarlyBodyLoad)) {
+    waiting_for_code_cache_ = false;
+    if (!waiting_for_document_loader_ && parser_)
+      parser_->CommitPreloadedData();
+  }
 }
 
 void DocumentLoader::BodyDataReceived(base::span<const char> data) {
@@ -1705,11 +1713,31 @@
       MakeGarbageCollected<SourceKeyedCachedMetadataHandler>(
           WTF::TextEncoding(), std::move(cached_metadata_sender));
 
+  if (waiting_for_document_loader_) {
+    // If we were just waiting for the document loader, the body has already
+    // started loading and it is safe to continue parsing if the code cache is
+    // already available.
+    waiting_for_document_loader_ = false;
+    if (!waiting_for_code_cache_)
+      parser_->CommitPreloadedData();
+  } else {
+    StartLoadingBodyWithCodeCache();
+  }
+}
+
+void DocumentLoader::StartLoadingBodyWithCodeCache() {
   CodeCacheHost* code_cache_host = nullptr;
   if (UseIsolatedCodeCache()) {
     code_cache_host = GetCodeCacheHost();
     DCHECK(code_cache_host);
   }
+  if (base::FeatureList::IsEnabled(features::kEarlyBodyLoad)) {
+    waiting_for_code_cache_ = true;
+    // If the body can load in parallel with the code cache, we need to enter
+    // preload mode until the code cache is received. The data will be committed
+    // once the code cache is available.
+    parser_->SetIsPreloading(true);
+  }
   body_loader_->StartLoadingBody(this, code_cache_host);
 }
 
@@ -2501,6 +2529,21 @@
     document->SetEncodingData(data);
   }
 
+  if (base::FeatureList::IsEnabled(features::kEarlyBodyLoad)) {
+    if (frame_ && body_loader_ && !loading_main_document_from_mhtml_archive_ &&
+        !loading_url_as_empty_document_ && url_.ProtocolIsInHTTPFamily() &&
+        !is_static_data_ && frame_->IsMainFrame() &&
+        !document->IsPrefetchOnly()) {
+      waiting_for_document_loader_ = true;
+      StartLoadingBodyWithCodeCache();
+
+      if (!frame_ || !body_loader_)
+        return;
+    }
+
+    frame_->DomWindow()->GetScriptController().UpdateDocument();
+  }
+
   // If this is a scriptable parser and there is a resource, register the
   // resource's cache handler with the parser.
   ScriptableDocumentParser* scriptable_parser =
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h
index 16c02bf4..583d566 100644
--- a/third_party/blink/renderer/core/loader/document_loader.h
+++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -433,6 +433,7 @@
 
   void StartLoadingInternal();
   void StartLoadingResponse();
+  void StartLoadingBodyWithCodeCache();
   void FinishedLoading(base::TimeTicks finish_time);
   void CancelLoadAfterCSPDenied(const ResourceResponse&);
 
@@ -602,6 +603,7 @@
   bool loading_main_document_from_mhtml_archive_ = false;
   const bool loading_srcdoc_ = false;
   const bool loading_url_as_empty_document_ = false;
+  const bool is_static_data_ = false;
   CommitReason commit_reason_ = CommitReason::kRegular;
   uint64_t main_resource_identifier_ = 0;
   scoped_refptr<ResourceTimingInfo> navigation_timing_info_;
@@ -653,6 +655,11 @@
 
   // Whether the document should be anonymous or not.
   const bool anonymous_ = false;
+
+  // Both of these bits must be true to commit preloaded data to the parser when
+  // features::kEarlyBodyLoad is enabled.
+  bool waiting_for_document_loader_ = false;
+  bool waiting_for_code_cache_ = false;
 };
 
 DECLARE_WEAK_IDENTIFIER_MAP(DocumentLoader);
diff --git a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc
index 8a68c53..c676c2d 100644
--- a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc
+++ b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc
@@ -15,6 +15,7 @@
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
 #include "third_party/blink/renderer/core/html/html_anchor_element.h"
+#include "third_party/blink/renderer/core/html/html_image_element.h"
 #include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
 #include "third_party/blink/renderer/core/layout/layout_image.h"
 #include "third_party/blink/renderer/core/layout/layout_object.h"
@@ -151,7 +152,11 @@
   }
 };
 
-bool IsTapTargetCandidate(const Node* node) {
+bool IsTapTargetCandidate(Node* node) {
+  if (auto* image = DynamicTo<HTMLImageElement>(node);
+      image && image->WillRespondToMouseClickEvents()) {
+    return true;
+  }
   return IsA<HTMLFormControlElement>(node) ||
          (IsA<HTMLAnchorElement>(node) &&
           !To<HTMLAnchorElement>(node)->Href().IsEmpty());
diff --git a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc
index ecebeabc..486403dbb 100644
--- a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc
+++ b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker_test.cc
@@ -39,6 +39,10 @@
 static constexpr int kDeviceHeight = 800;
 static constexpr float kMinimumZoom = 0.25f;
 static constexpr float kMaximumZoom = 5;
+static constexpr char kInlineRedDot[] =
+    "data:image/"
+    "png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4/"
+    "/8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
 
 class MobileFriendlinessCheckerTest : public testing::Test {
   static void EvalMobileFriendliness(LocalFrameView* view,
@@ -801,6 +805,43 @@
   EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 0);
 }
 
+TEST_F(ClockFixedMobileFriendlinessCheckerTest, TwoImageTapTargetsClose) {
+  MobileFriendliness actual_mf = CalculateMetricsForHTMLString(
+      base::StringPrintf(R"(
+<html>
+  <head>
+    <meta name="viewport" content="width=480, initial-scale=1">
+  </head>
+  <body>
+    <img onclick="alert('clicked');" src="%s">
+    <img onclick="alert('clicked');" src="%s">
+  </body>
+</html>
+)",
+                         kInlineRedDot, kInlineRedDot));
+  // Two onclick images next to each other are both bad tap targets.
+  EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 100);
+}
+
+TEST_F(ClockFixedMobileFriendlinessCheckerTest, TwoImageTapTargetsFar) {
+  MobileFriendliness actual_mf = CalculateMetricsForHTMLString(
+      base::StringPrintf(R"(
+<html>
+  <head>
+    <meta name="viewport" content="width=480, initial-scale=1">
+  </head>
+  <body>
+    <img onclick="alert('clicked');" src="%s">
+    <p style="line-height: 100px">some text</p>
+    <img onclick="alert('clicked');" src="%s">
+  </body>
+</html>
+)",
+                         kInlineRedDot, kInlineRedDot));
+  // Two onclick images aren't a problem if there's some distance between them.
+  EXPECT_EQ(actual_mf.bad_tap_targets_ratio, 0);
+}
+
 TEST_F(ClockFixedMobileFriendlinessCheckerTest, NoBadTapTarget) {
   MobileFriendliness actual_mf = CalculateMetricsForHTMLString(R"(
 <html>
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index 321818f9..546ab36 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -408,14 +408,11 @@
   }
 }
 
-PluginData* Page::GetPluginData(const SecurityOrigin* main_frame_origin) {
+PluginData* Page::GetPluginData() {
   if (!plugin_data_)
     plugin_data_ = MakeGarbageCollected<PluginData>();
 
-  if (!plugin_data_->Origin() ||
-      !main_frame_origin->IsSameOriginWith(plugin_data_->Origin()))
-    plugin_data_->UpdatePluginList(main_frame_origin);
-
+  plugin_data_->UpdatePluginList();
   return plugin_data_.Get();
 }
 
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h
index f3231c1c..5535cda 100644
--- a/third_party/blink/renderer/core/page/page.h
+++ b/third_party/blink/renderer/core/page/page.h
@@ -80,7 +80,6 @@
 class ScopedPagePauser;
 class ScrollingCoordinator;
 class ScrollbarTheme;
-class SecurityOrigin;
 class Settings;
 class SpatialNavigationController;
 class TopDocumentRootScrollerController;
@@ -148,8 +147,8 @@
 
   ViewportDescription GetViewportDescription() const;
 
-  // Returns the plugin data associated with |main_frame_origin|.
-  PluginData* GetPluginData(const SecurityOrigin* main_frame_origin);
+  // Returns the plugin data.
+  PluginData* GetPluginData();
 
   // Resets the plugin data for all pages in the renderer process and notifies
   // PluginsChangedObservers.
diff --git a/third_party/blink/renderer/core/page/plugin_data.cc b/third_party/blink/renderer/core/page/plugin_data.cc
index 2221b02..8a1c903 100644
--- a/third_party/blink/renderer/core/page/plugin_data.cc
+++ b/third_party/blink/renderer/core/page/plugin_data.cc
@@ -97,10 +97,13 @@
   registry->GetPlugins(true, &plugins);
 }
 
-void PluginData::UpdatePluginList(const SecurityOrigin* main_frame_origin) {
+void PluginData::UpdatePluginList() {
+  if (updated_)
+    return;
+
   SCOPED_UMA_HISTOGRAM_TIMER("Blink.Plugin.UpdateTime");
   ResetPluginData();
-  main_frame_origin_ = main_frame_origin;
+  updated_ = true;
 
   mojo::Remote<mojom::blink::PluginRegistry> registry;
   Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
@@ -137,7 +140,7 @@
 void PluginData::ResetPluginData() {
   plugins_.clear();
   mimes_.clear();
-  main_frame_origin_ = nullptr;
+  updated_ = false;
 }
 
 bool PluginData::SupportsMimeType(const String& mime_type) const {
diff --git a/third_party/blink/renderer/core/page/plugin_data.h b/third_party/blink/renderer/core/page/plugin_data.h
index bc4d9d4..165360546 100644
--- a/third_party/blink/renderer/core/page/plugin_data.h
+++ b/third_party/blink/renderer/core/page/plugin_data.h
@@ -25,7 +25,6 @@
 #include "third_party/blink/renderer/platform/graphics/color.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
@@ -101,8 +100,7 @@
 
   const HeapVector<Member<PluginInfo>>& Plugins() const { return plugins_; }
   const HeapVector<Member<MimeClassInfo>>& Mimes() const { return mimes_; }
-  const SecurityOrigin* Origin() const { return main_frame_origin_.get(); }
-  void UpdatePluginList(const SecurityOrigin* main_frame_origin);
+  void UpdatePluginList();
   void ResetPluginData();
 
   bool SupportsMimeType(const String& mime_type) const;
@@ -116,7 +114,7 @@
  private:
   HeapVector<Member<PluginInfo>> plugins_;
   HeapVector<Member<MimeClassInfo>> mimes_;
-  scoped_refptr<const SecurityOrigin> main_frame_origin_;
+  bool updated_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/page/plugin_data_test.cc b/third_party/blink/renderer/core/page/plugin_data_test.cc
index 8ea7a41..2b181192 100644
--- a/third_party/blink/renderer/core/page/plugin_data_test.cc
+++ b/third_party/blink/renderer/core/page/plugin_data_test.cc
@@ -10,10 +10,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/mojom/plugins/plugin_registry.mojom-blink.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
-#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
-#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
-#include "url/url_util.h"
 
 namespace blink {
 namespace {
@@ -28,12 +25,8 @@
   MOCK_METHOD(void, DidGetPlugins, (bool));
 };
 
-// Regression test for https://crbug.com/862282
-TEST(PluginDataTest, NonStandardUrlSchemeRequestsPluginsWithUniqueOrigin) {
+TEST(PluginDataTest, UpdatePluginList) {
   ScopedTestingPlatformSupport<TestingPlatformSupport> support;
-  // Create a scheme that's local but nonstandard, as in bug 862282.
-  url::ScopedSchemeRegistryForTests scoped_registry;
-  url::AddLocalScheme("nonstandard-862282");
 
   MockPluginRegistry mock_plugin_registry;
   mojo::Receiver<mojom::blink::PluginRegistry> registry_receiver(
@@ -53,11 +46,8 @@
 
   EXPECT_CALL(mock_plugin_registry, DidGetPlugins(false));
 
-  scoped_refptr<SecurityOrigin> non_standard_origin =
-      SecurityOrigin::CreateFromString("nonstandard-862282:foo/bar");
-  EXPECT_FALSE(non_standard_origin->IsOpaque());
   auto* plugin_data = MakeGarbageCollected<PluginData>();
-  plugin_data->UpdatePluginList(non_standard_origin.get());
+  plugin_data->UpdatePluginList();
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
index 1fe69e2..1e9139b 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -213,14 +213,4 @@
   weak_ptr_factory_.InvalidateWeakPtrs();
 }
 
-bool ScrollingCoordinator::IsForMainFrame(
-    ScrollableArea* scrollable_area) const {
-  if (!IsA<LocalFrame>(page_->MainFrame()))
-    return false;
-
-  // FIXME(305811): Refactor for OOPI.
-  return scrollable_area ==
-         page_->DeprecatedLocalMainFrame()->View()->LayoutViewport();
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
index 6713ae3d..005fc8c 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
@@ -117,8 +117,6 @@
   void Reset(LocalFrame*);
 
  protected:
-  bool IsForMainFrame(ScrollableArea*) const;
-
   Member<Page> page_;
 
  private:
diff --git a/third_party/blink/renderer/core/web_test/web_test_web_frame_widget_impl.cc b/third_party/blink/renderer/core/web_test/web_test_web_frame_widget_impl.cc
index f774a7d..c6e9435 100644
--- a/third_party/blink/renderer/core/web_test/web_test_web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/web_test/web_test_web_frame_widget_impl.cc
@@ -6,6 +6,7 @@
 
 #include "content/web_test/renderer/event_sender.h"
 #include "content/web_test/renderer/test_runner.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
 #include "third_party/blink/public/web/web_frame_widget.h"
 #include "third_party/blink/public/web/web_local_frame.h"
@@ -224,6 +225,11 @@
   if (!LayerTreeHost()->IsVisible())
     return;
 
+  if (base::FeatureList::IsEnabled(blink::features::kNoForcedFrameUpdates) &&
+      LayerTreeHost()->MainFrameUpdatesAreDeferred()) {
+    return;
+  }
+
   if (in_synchronous_composite_) {
     // Web tests can use a nested message loop to pump frames while inside a
     // frame, but the compositor does not support this. In this case, we only
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_test.cc b/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
index 5a195c50..8c5b1057 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
@@ -1452,45 +1452,51 @@
   NonThrowableExceptionState exception_state;
   SetBodyInnerHTML(R"HTML(
     <canvas>
-      <section style="display: none">
+      <section>
         <div tabindex="-1" id="div"></div>
         <span tabindex="-1" id="span"></div>
         <a tabindex="-1" id="a"></a>
       </section>
-      <section style="display: none" inert>
+      <section hidden>
+        <div tabindex="-1" id="div-hidden"></div>
+        <span tabindex="-1" id="span-hidden"></div>
+        <a tabindex="-1" id="a-hidden"></a>
+      </section>
+      <section inert>
         <div tabindex="-1" id="div-inert"></div>
         <span tabindex="-1" id="span-inert"></div>
         <a tabindex="-1" id="a-inert"></a>
       </section>
+      <section hidden inert>
+        <div tabindex="-1" id="div-hidden-inert"></div>
+        <span tabindex="-1" id="span-hidden-inert"></div>
+        <a tabindex="-1" id="a-hidden-inert"></a>
+      </section>
     </div>
   )HTML");
 
-  // Elements being used as relevant canvas fallback content can be focusable,
-  // even in a display:none subtree.
-  AXObject* div = GetAXObjectByElementId("div");
-  ASSERT_NE(div, nullptr);
-  ASSERT_TRUE(div->CanSetFocusAttribute());
+  // Elements being used as relevant canvas fallback content can be focusable.
+  ASSERT_TRUE(GetAXObjectByElementId("div")->CanSetFocusAttribute());
+  ASSERT_TRUE(GetAXObjectByElementId("span")->CanSetFocusAttribute());
+  ASSERT_TRUE(GetAXObjectByElementId("a")->CanSetFocusAttribute());
 
-  AXObject* span = GetAXObjectByElementId("span");
-  ASSERT_NE(span, nullptr);
-  ASSERT_TRUE(span->CanSetFocusAttribute());
+  // But they are not focusable if in a display:none subtree...
+  ASSERT_FALSE(GetAXObjectByElementId("div-hidden")->CanSetFocusAttribute());
+  ASSERT_FALSE(GetAXObjectByElementId("span-hidden")->CanSetFocusAttribute());
+  ASSERT_FALSE(GetAXObjectByElementId("a-hidden")->CanSetFocusAttribute());
 
-  AXObject* a = GetAXObjectByElementId("a");
-  ASSERT_NE(a, nullptr);
-  ASSERT_TRUE(a->CanSetFocusAttribute());
+  // ...nor if expressly inert...
+  ASSERT_FALSE(GetAXObjectByElementId("div-inert")->CanSetFocusAttribute());
+  ASSERT_FALSE(GetAXObjectByElementId("span-inert")->CanSetFocusAttribute());
+  ASSERT_FALSE(GetAXObjectByElementId("a-inert")->CanSetFocusAttribute());
 
-  // But they are not focusable if expressly inert.
-  AXObject* div_inert = GetAXObjectByElementId("div-inert");
-  ASSERT_NE(div_inert, nullptr);
-  ASSERT_FALSE(div_inert->CanSetFocusAttribute());
-
-  AXObject* span_inert = GetAXObjectByElementId("span-inert");
-  ASSERT_NE(span_inert, nullptr);
-  ASSERT_FALSE(span_inert->CanSetFocusAttribute());
-
-  AXObject* a_inert = GetAXObjectByElementId("a-inert");
-  ASSERT_NE(a_inert, nullptr);
-  ASSERT_FALSE(a_inert->CanSetFocusAttribute());
+  // ...nor a combination of both.
+  ASSERT_FALSE(
+      GetAXObjectByElementId("div-hidden-inert")->CanSetFocusAttribute());
+  ASSERT_FALSE(
+      GetAXObjectByElementId("span-hidden-inert")->CanSetFocusAttribute());
+  ASSERT_FALSE(
+      GetAXObjectByElementId("a-hidden-inert")->CanSetFocusAttribute());
 }
 
 }  // namespace test
diff --git a/third_party/blink/renderer/modules/autofill_assistant/node_signals.cc b/third_party/blink/renderer/modules/autofill_assistant/node_signals.cc
index 2ed6f87..472782d 100644
--- a/third_party/blink/renderer/modules/autofill_assistant/node_signals.cc
+++ b/third_party/blink/renderer/modules/autofill_assistant/node_signals.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/core/dom/qualified_name.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/dom/space_split_string.h"
+#include "third_party/blink/renderer/core/html/html_element.h"
 #include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
 #include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
diff --git a/third_party/blink/renderer/modules/font_access/font_manager.cc b/third_party/blink/renderer/modules/font_access/font_manager.cc
index 5c5b88c5..0c379c4 100644
--- a/third_party/blink/renderer/modules/font_access/font_manager.cc
+++ b/third_party/blink/renderer/modules/font_access/font_manager.cc
@@ -54,24 +54,6 @@
   ExecutionContextLifecycleObserver::Trace(visitor);
 }
 
-void FontManager::DidShowFontChooser(
-    ScriptPromiseResolver* resolver,
-    FontEnumerationStatus status,
-    Vector<mojom::blink::FontMetadataPtr> fonts) {
-  if (RejectPromiseIfNecessary(status, resolver))
-    return;
-
-  auto entries = HeapVector<Member<FontMetadata>>();
-  for (const auto& font : fonts) {
-    auto entry = FontEnumerationEntry{.postscript_name = font->postscript_name,
-                                      .full_name = font->full_name,
-                                      .family = font->family,
-                                      .style = font->style};
-    entries.push_back(FontMetadata::Create(std::move(entry)));
-  }
-  resolver->Resolve(std::move(entries));
-}
-
 void FontManager::DidGetEnumerationResponse(
     ScriptPromiseResolver* resolver,
     const Vector<String>& selection,
diff --git a/third_party/blink/renderer/modules/font_access/font_manager.h b/third_party/blink/renderer/modules/font_access/font_manager.h
index 7813acd..0785e1c 100644
--- a/third_party/blink/renderer/modules/font_access/font_manager.h
+++ b/third_party/blink/renderer/modules/font_access/font_manager.h
@@ -37,9 +37,6 @@
   void Trace(blink::Visitor*) const override;
 
  private:
-  void DidShowFontChooser(ScriptPromiseResolver* resolver,
-                          mojom::blink::FontEnumerationStatus status,
-                          Vector<mojom::blink::FontMetadataPtr> fonts);
   void DidGetEnumerationResponse(ScriptPromiseResolver* resolver,
                                  const Vector<String>& selection,
                                  mojom::blink::FontEnumerationStatus,
diff --git a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
index e9662814..6f3dce44 100644
--- a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
+++ b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
@@ -66,6 +66,8 @@
     "Access to the feature \"gamepad\" requires a secure context";
 const char kFeaturePolicyBlocked[] =
     "Access to the feature \"gamepad\" is disallowed by permissions policy.";
+const char kFencedFrameBlocked[] =
+    "getGamepad is not allowed in a fenced frame tree.";
 
 NavigatorGamepad& NavigatorGamepad::From(Navigator& navigator) {
   NavigatorGamepad* supplement =
@@ -127,6 +129,13 @@
 
   auto* navigator_gamepad = &NavigatorGamepad::From(navigator);
 
+  // TODO(https://crbug.com/1011006): Remove fenced frame specific code when
+  // permission policy implements the Gamepad API support.
+  if (navigator.DomWindow()->GetFrame()->IsInFencedFrameTree()) {
+    exception_state.ThrowSecurityError(kFencedFrameBlocked);
+    return HeapVector<Member<Gamepad>>();
+  }
+
   ExecutionContext* context = navigator_gamepad->GetExecutionContext();
   if (!context || !context->IsSecureContext()) {
     if (base::FeatureList::IsEnabled(::features::kRestrictGamepadAccess)) {
@@ -259,11 +268,18 @@
 
 bool NavigatorGamepad::StartUpdatingIfAttached() {
   // The frame must be attached to start updating.
-  if (DomWindow()) {
-    StartUpdating();
-    return true;
+  if (!DomWindow()) {
+    return false;
   }
-  return false;
+
+  // TODO(https://crbug.com/1011006): Remove fenced frame specific code when
+  // permission policy implements the Gamepad API support.
+  if (DomWindow()->GetFrame()->IsInFencedFrameTree()) {
+    return false;
+  }
+
+  StartUpdating();
+  return true;
 }
 
 void NavigatorGamepad::DidUpdateData() {
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc
index d310d65a..86b41d7 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source.cc
+++ b/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -530,6 +530,17 @@
 bool MediaSource::IsTypeSupportedInternal(ExecutionContext* context,
                                           const String& type,
                                           bool enforce_codec_specificity) {
+  // Even after ExecutionContext teardown notification, bindings may still call
+  // code-behinds for a short while. If |context| is null, this is likely
+  // happening. To prevent possible null deref of |context| in this path, claim
+  // lack of support immediately without proceeding.
+  if (!context) {
+    DVLOG(1) << __func__ << "(" << type << ", "
+             << (enforce_codec_specificity ? "true" : "false")
+             << ") -> false (context is null)";
+    return false;
+  }
+
   // Section 2.2 isTypeSupported() method steps.
   // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#widl-MediaSource-isTypeSupported-boolean-DOMString-type
   // 1. If type is an empty string, then return false.
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.cc b/third_party/blink/renderer/modules/mediastream/media_devices.cc
index 41527c8..da98f777 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -114,6 +114,43 @@
   kMaxValue = kAllowed
 };
 
+#if !BUILDFLAG(IS_ANDROID)
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+//
+// Note: The mismatch between "CropId" and "CropTarget" is due to spec-changes
+// as part of the work in the W3C working group. These will be reflected in
+// code at a later point.
+// TODO(crbug.com/1291140): Remove above explanation once implementation
+// is updated to CropTargets.
+enum class ProduceCropTargetFunctionResult {
+  kPromiseProduced = 0,
+  kGenericError = 1,
+  kInvalidContext = 2,
+  kDuplicateCallBeforePromiseResolution = 3,
+  kDuplicateCallAfterPromiseResolution = 4,
+  kMaxValue = kDuplicateCallAfterPromiseResolution
+};
+
+void RecordUma(ProduceCropTargetFunctionResult result) {
+  base::UmaHistogramEnumeration(
+      "Media.RegionCapture.ProduceCropTarget.Function.Result", result);
+}
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class ProduceCropTargetPromiseResult {
+  kPromiseResolved = 0,
+  kPromiseRejected = 1,
+  kMaxValue = kPromiseRejected
+};
+
+void RecordUma(ProduceCropTargetPromiseResult result) {
+  base::UmaHistogramEnumeration(
+      "Media.RegionCapture.ProduceCropTarget.Promise.Result", result);
+}
+#endif
+
 }  // namespace
 
 const char MediaDevices::kSupplementName[] = "MediaDevices";
@@ -350,11 +387,13 @@
   if (!script_state->ContextIsValid()) {
     exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
                                       "Current frame is detached.");
+    RecordUma(ProduceCropTargetFunctionResult::kInvalidContext);
     return ScriptPromise();
   }
 
   LocalDOMWindow* const window = To<LocalDOMWindow>(GetExecutionContext());
   if (!window) {
+    RecordUma(ProduceCropTargetFunctionResult::kGenericError);
     exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
                                       "Missing execution context.");
     return ScriptPromise();
@@ -374,6 +413,8 @@
     const ScriptPromise promise = resolver->Promise();
     resolver->Resolve(WTF::String(
         blink::TokenToGUID(old_crop_id->value()).AsLowercaseString()));
+    RecordUma(
+        ProduceCropTargetFunctionResult::kDuplicateCallAfterPromiseResolution);
     return promise;
   }
 
@@ -383,6 +424,8 @@
     // has already been kicked off, and a response will soon arrive from
     // the browser process. The Promise we return here will be resolved along
     // with the original one.
+    RecordUma(
+        ProduceCropTargetFunctionResult::kDuplicateCallBeforePromiseResolution);
     return it->value->Promise();
   }
 
@@ -394,6 +437,7 @@
   GetDispatcherHost(window->GetFrame())
       ->ProduceCropId(WTF::Bind(&MediaDevices::ResolveProduceCropIdPromise,
                                 WrapPersistent(this), WrapPersistent(element)));
+  RecordUma(ProduceCropTargetFunctionResult::kPromiseProduced);
   return promise;
 #endif
 }
@@ -696,12 +740,14 @@
 
   if (crop_id.IsEmpty()) {
     resolver->Reject();
+    RecordUma(ProduceCropTargetPromiseResult::kPromiseRejected);
   } else {
     const base::GUID guid = base::GUID::ParseLowercase(crop_id.Ascii());
     DCHECK(guid.is_valid());
     element->SetRegionCaptureCropId(
         std::make_unique<RegionCaptureCropId>(blink::GUIDToToken(guid)));
     resolver->Resolve(crop_id);
+    RecordUma(ProduceCropTargetPromiseResult::kPromiseResolved);
   }
 }
 #endif
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index ec7bc99..cff752a 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -774,6 +774,12 @@
   return features::kInstallingServiceWorkerOutstandingThrottledLimit.Get();
 }
 
+// Note that ServiceWorkers can be for cross-origin iframes, and that it might
+// look like an escape from the Permissions-Policy enforced on documents. It is
+// safe however, even on platforms without OOPIF  because a ServiceWorker
+// controlling a cross-origin iframe would be put in  a different process from
+// the page, due to an origin mismatch in their cross-origin isolation.
+// See https://crbug.com/1290224 for details.
 bool ServiceWorkerGlobalScope::CrossOriginIsolatedCapability() const {
   return Agent::IsCrossOriginIsolated();
 }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc
index 345585e..b92cf11b 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc
@@ -159,9 +159,14 @@
                                       viz::ResourceFormatToClosestSkColorType(
                                           /*gpu_compositing=*/true, Format()),
                                       kPremul_SkAlphaType);
+  // We tag the SharedImage inside the WebGPUImageProvider with display usage
+  // since there are uncommon paths which may use this snapshot for compositing.
+  // These paths are usually related to either printing or either video and
+  // usually related to OffscreenCanvas; in cases where the image created from
+  // this Snapshot will be sent eventually to the Display Compositor.
   auto resource_provider = CanvasResourceProvider::CreateWebGPUImageProvider(
       info,
-      /*is_origin_top_left=*/true);
+      /*is_origin_top_left=*/true, gpu::SHARED_IMAGE_USAGE_DISPLAY);
   if (!resource_provider)
     return nullptr;
 
diff --git a/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc b/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc
index e982c38..ecacc87 100644
--- a/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc
+++ b/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc
@@ -109,7 +109,7 @@
           To<CalculationExpressionPixelsAndPercentNode>(
               *maybe_pixels_and_percent_node);
       PixelsAndPercent value(pixels_and_percent.Pixels() * number.Value(),
-                             pixels_and_percent.Percent());
+                             pixels_and_percent.Percent() * number.Value());
       return base::MakeRefCounted<CalculationExpressionPixelsAndPercentNode>(
           value);
     }
diff --git a/third_party/blink/renderer/platform/geometry/length_test.cc b/third_party/blink/renderer/platform/geometry/length_test.cc
index 75ce870..e78050d 100644
--- a/third_party/blink/renderer/platform/geometry/length_test.cc
+++ b/third_party/blink/renderer/platform/geometry/length_test.cc
@@ -17,6 +17,7 @@
 const PixelsAndPercent thirty_px(30, 0);
 const PixelsAndPercent ten_percent(0, 10);
 const PixelsAndPercent twenty_percent(0, 20);
+const PixelsAndPercent twenty_px_ten_percent(20, 10);
 
 }  // namespace
 
@@ -331,6 +332,30 @@
   }
 }
 
+// Non-simplified and simplified CalculationExpressionOperationNode creation
+// with CalculationOperator::kMultiply should return the same evaluation result.
+TEST_F(LengthTest, MultiplyPixelsAndPercent) {
+  // Multiply (20px + 10%) by 2
+  Length non_simplified =
+      CreateLength(Multiply(PixelsAndPercent(twenty_px_ten_percent), 2));
+  const auto& non_simplified_calc_value = non_simplified.GetCalculationValue();
+  EXPECT_TRUE(non_simplified_calc_value.IsExpression());
+  float result_for_non_simplified =
+      non_simplified_calc_value.GetOrCreateExpression()->Evaluate(100);
+  EXPECT_EQ(60.0f, result_for_non_simplified);
+
+  Length simplified =
+      CreateLength(CalculationExpressionOperationNode::CreateSimplified(
+          CalculationExpressionOperationNode::Children(
+              {PixelsAndPercent(twenty_px_ten_percent),
+               base::MakeRefCounted<CalculationExpressionNumberNode>(2)}),
+          CalculationOperator::kMultiply));
+  const auto& simplified_calc_value = simplified.GetCalculationValue();
+  EXPECT_FALSE(simplified_calc_value.IsExpression());
+  float result_for_simplified = simplified_calc_value.Evaluate(100);
+  EXPECT_EQ(60.0f, result_for_simplified);
+}
+
 TEST_F(LengthTest, ZoomToOperator) {
   // Add 10px + 20px
   {
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
index 359a9bd..4c114d4a 100644
--- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
+++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -56,12 +56,14 @@
     base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
     base::PlatformThreadRef context_thread_ref,
     scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
-    viz::ReleaseCallback release_callback) {
+    viz::ReleaseCallback release_callback,
+    bool supports_display_compositing) {
   return base::AdoptRef(new AcceleratedStaticBitmapImage(
       mailbox, sync_token, shared_image_texture_id, sk_image_info,
-      texture_target, is_origin_top_left, ImageOrientationEnum::kDefault,
-      std::move(context_provider_wrapper), context_thread_ref,
-      std::move(context_task_runner), std::move(release_callback)));
+      texture_target, is_origin_top_left, supports_display_compositing,
+      ImageOrientationEnum::kDefault, std::move(context_provider_wrapper),
+      context_thread_ref, std::move(context_task_runner),
+      std::move(release_callback)));
 }
 
 AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(
@@ -71,6 +73,7 @@
     const SkImageInfo& sk_image_info,
     GLenum texture_target,
     bool is_origin_top_left,
+    bool supports_display_compositing,
     const ImageOrientation& orientation,
     base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
     base::PlatformThreadRef context_thread_ref,
@@ -81,6 +84,7 @@
       sk_image_info_(sk_image_info),
       texture_target_(texture_target),
       is_origin_top_left_(is_origin_top_left),
+      supports_display_compositing_(supports_display_compositing),
       context_provider_wrapper_(std::move(context_provider_wrapper)),
       mailbox_ref_(
           base::MakeRefCounted<MailboxRef>(sync_token,
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
index 7e9d393..7072de2 100644
--- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
+++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
@@ -64,7 +64,11 @@
       base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
       base::PlatformThreadRef context_thread_ref,
       scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
-      viz::ReleaseCallback release_callback);
+      viz::ReleaseCallback release_callback,
+      // TODO(crbug/1289449) Remove ths default value and extend this validation
+      // to all type of AcceleratedStaticBitmapImage created from
+      // CreateFromCanvasMailbox.
+      bool supports_display_compositing_ = true);
 
   bool CurrentFrameKnownToBeOpaque() override;
   bool IsTextureBacked() const override { return true; }
@@ -113,6 +117,9 @@
   // sync token before accessing this mailbox.
   gpu::MailboxHolder GetMailboxHolder() const final;
   bool IsOriginTopLeft() const final { return is_origin_top_left_; }
+  bool SupportsDisplayCompositing() const final {
+    return supports_display_compositing_;
+  }
 
   SkColorType GetSkColorType() const override {
     return sk_image_info_.colorType();
@@ -136,6 +143,7 @@
       const SkImageInfo& sk_image_info,
       GLenum texture_target,
       bool is_origin_top_left,
+      bool supports_display_compositing,
       const ImageOrientation& orientation,
       base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
       base::PlatformThreadRef context_thread_ref,
@@ -151,6 +159,7 @@
   const SkImageInfo sk_image_info_;
   const GLenum texture_target_;
   const bool is_origin_top_left_;
+  const bool supports_display_compositing_;
 
   base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
   scoped_refptr<MailboxRef> mailbox_ref_;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
index 2d42bb3..a7aad00 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -357,6 +357,8 @@
       is_overlay_candidate_(shared_image_usage_flags &
                             gpu::SHARED_IMAGE_USAGE_SCANOUT),
 #endif
+      supports_display_compositing_(shared_image_usage_flags &
+                                    gpu::SHARED_IMAGE_USAGE_DISPLAY),
       texture_target_(is_overlay_candidate_
                           ? gpu::GetBufferTextureTarget(
                                 gfx::BufferUsage::SCANOUT,
@@ -643,9 +645,10 @@
     owning_thread_data().mailbox_sync_mode = kUnverifiedSyncToken;
   }
   image = AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
-      mailbox(), GetSyncToken(), texture_id_for_image, image_info, texture_target_,
-      is_origin_top_left_, context_provider_wrapper_, owning_thread_ref_,
-      owning_thread_task_runner_, std::move(release_callback));
+      mailbox(), GetSyncToken(), texture_id_for_image, image_info,
+      texture_target_, is_origin_top_left_, context_provider_wrapper_,
+      owning_thread_ref_, owning_thread_task_runner_,
+      std::move(release_callback), supports_display_compositing_);
 
   DCHECK(image);
   return image;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.h b/third_party/blink/renderer/platform/graphics/canvas_resource.h
index 6f76fd3..d67cfb0 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource.h
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource.h
@@ -418,6 +418,7 @@
   const bool is_origin_top_left_;
   const bool is_accelerated_;
   const bool is_overlay_candidate_;
+  const bool supports_display_compositing_;
   const GLenum texture_target_;
   const bool use_oop_rasterization_;
 
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
index 00faa120..362f771c 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -1007,14 +1007,16 @@
 }
 
 std::unique_ptr<CanvasResourceProvider>
-CanvasResourceProvider::CreateWebGPUImageProvider(const SkImageInfo& info,
-                                                  bool is_origin_top_left) {
+CanvasResourceProvider::CreateWebGPUImageProvider(
+    const SkImageInfo& info,
+    bool is_origin_top_left,
+    uint32_t shared_image_usage_flags) {
   auto context_provider_wrapper = SharedGpuContext::ContextProviderWrapper();
   return CreateSharedImageProvider(
       info, cc::PaintFlags::FilterQuality::kLow,
       CanvasResourceProvider::ShouldInitialize::kNo,
       std::move(context_provider_wrapper), RasterMode::kGPU, is_origin_top_left,
-      gpu::SHARED_IMAGE_USAGE_WEBGPU);
+      shared_image_usage_flags | gpu::SHARED_IMAGE_USAGE_WEBGPU);
 }
 
 std::unique_ptr<CanvasResourceProvider>
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
index 72c4d63f..06cd1d3 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
@@ -126,7 +126,8 @@
 
   static std::unique_ptr<CanvasResourceProvider> CreateWebGPUImageProvider(
       const SkImageInfo& info,
-      bool is_origin_top_left);
+      bool is_origin_top_left,
+      uint32_t shared_image_usage_flags = 0);
 
   static std::unique_ptr<CanvasResourceProvider> CreatePassThroughProvider(
       const SkImageInfo& info,
diff --git a/third_party/blink/renderer/platform/graphics/static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
index affc4f5..c02381c 100644
--- a/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
+++ b/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
@@ -56,6 +56,7 @@
   virtual bool IsValid() const { return true; }
   virtual void Transfer() {}
   virtual bool IsOriginTopLeft() const { return true; }
+  virtual bool SupportsDisplayCompositing() const { return true; }
 
   // Creates a non-gpu copy of the image, or returns this if image is already
   // non-gpu.
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
index dad194d9..f92cfca8 100644
--- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -389,7 +389,7 @@
 }
 
 NOINLINE void RawResourceClientStateChecker::SetSerializedCachedMetadata() {
-  SECURITY_CHECK(state_ == kResponseReceived ||
+  SECURITY_CHECK(state_ == kStarted || state_ == kResponseReceived ||
                  state_ == kDataReceivedAsBytesConsumer ||
                  state_ == kDataReceived);
 }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_error.cc b/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
index 4ff92c5..0ce1919 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
@@ -88,6 +88,12 @@
   return ResourceError(net::ERR_FAILED, url, absl::nullopt);
 }
 
+ResourceError ResourceError::HttpError(const KURL& url) {
+  ResourceError error = CancelledError(url);
+  error.is_cancelled_from_http_error_ = true;
+  return error;
+}
+
 ResourceError::ResourceError(
     int error_code,
     const KURL& url,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_error.h b/third_party/blink/renderer/platform/loader/fetch/resource_error.h
index ab797ed..f4c3aabf 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_error.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_error.h
@@ -64,6 +64,7 @@
   static ResourceError CacheMissError(const KURL&);
   static ResourceError TimeoutError(const KURL&);
   static ResourceError Failure(const KURL&);
+  static ResourceError HttpError(const KURL&);
 
   ResourceError() = delete;
   // |error_code| must not be 0.
@@ -100,6 +101,9 @@
   bool IsCacheMiss() const;
   bool WasBlockedByResponse() const;
   bool ShouldCollapseInitiator() const { return should_collapse_inititator_; }
+  bool IsCancelledFromHttpError() const {
+    return is_cancelled_from_http_error_;
+  }
 
   absl::optional<ResourceRequestBlockedReason> GetResourceRequestBlockedReason()
       const;
@@ -131,6 +135,7 @@
   bool has_copy_in_cache_ = false;
   absl::optional<network::CorsErrorStatus> cors_error_status_;
   bool should_collapse_inititator_ = false;
+  bool is_cancelled_from_http_error_ = false;
 
   absl::optional<network::mojom::BlockedByResponseReason>
       blocked_by_response_reason_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index e188b438..dccc886 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -1935,7 +1935,9 @@
   }
 
   resource->VirtualTimePauser().UnpauseVirtualTime();
-  if (error.IsCancellation())
+  // If the preload was cancelled due to an HTTP error, we don't want to request
+  // the resource a second time.
+  if (error.IsCancellation() && !error.IsCancelledFromHttpError())
     RemovePreload(resource);
   if (network_utils::IsCertificateTransparencyRequiredError(
           error.ErrorCode())) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
index 7cbc9362..9fe9bef 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -1150,7 +1150,7 @@
 
   if (response.HttpStatusCode() >= 400 &&
       !resource_->ShouldIgnoreHTTPStatusCodeErrors()) {
-    HandleError(ResourceError::CancelledError(response.CurrentRequestUrl()));
+    HandleError(ResourceError::HttpError(response.CurrentRequestUrl()));
     return;
   }
 }
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc
index c3643d9..4ad87c90 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.cc
@@ -14,6 +14,7 @@
 #include "services/network/public/cpp/url_loader_completion_status.h"
 #include "services/network/public/mojom/early_hints.mojom.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/loader/referrer_utils.h"
 #include "third_party/blink/public/mojom/loader/code_cache.mojom.h"
 #include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
@@ -152,10 +153,18 @@
     // started, so start it now.
     if (!code_cache_loader_)
       StartLoadingCodeCache(code_cache_host);
+
+    // TODO(crbug.com/1274867): See if this can be enabled for subframes too.
+    if (base::FeatureList::IsEnabled(features::kEarlyBodyLoad) &&
+        is_main_frame_) {
+      // Start loading the body in parallel with the code cache.
+      BindURLLoaderAndStartLoadingResponseBodyIfPossible();
+    }
     return;
   }
 
-  BindURLLoaderAndStartLoadingResponseBodyIfPossible();
+  code_cache_data_ = mojo_base::BigBuffer();
+  ContinueWithCodeCache(base::TimeTicks::Now(), response_head_response_time);
 }
 
 void NavigationBodyLoader::StartLoadingCodeCache(
@@ -180,20 +189,28 @@
 void NavigationBodyLoader::ContinueWithCodeCache(
     base::TimeTicks start_time,
     base::Time response_head_response_time) {
-  base::UmaHistogramTimes(
-      base::StrCat({"Navigation.CodeCacheTime.",
-                    is_main_frame_ ? "MainFrame" : "Subframe"}),
-      base::TimeTicks::Now() - start_time);
+  if (code_cache_loader_) {
+    base::UmaHistogramTimes(
+        base::StrCat({"Navigation.CodeCacheTime.",
+                      is_main_frame_ ? "MainFrame" : "Subframe"}),
+        base::TimeTicks::Now() - start_time);
+  }
 
   // Check that the times match to ensure that the code cache data is for this
   // response. See https://crbug.com/1099587.
-  if (response_head_response_time == code_cache_response_time_ && client_) {
-    base::WeakPtr<NavigationBodyLoader> weak_self = weak_factory_.GetWeakPtr();
+  if (response_head_response_time != code_cache_response_time_)
+    code_cache_data_ = mojo_base::BigBuffer();
+
+  auto weak_self = weak_factory_.GetWeakPtr();
+  if (client_) {
     client_->BodyCodeCacheReceived(std::move(*code_cache_data_));
     if (!weak_self)
       return;
   }
   code_cache_loader_.reset();
+  NotifyCompletionIfAppropriate();
+  if (!weak_self)
+    return;
 
   // TODO(dgozman): we should explore retrieveing code cache in parallel with
   // receiving response or reading the first data chunk.
@@ -282,7 +299,7 @@
 }
 
 void NavigationBodyLoader::NotifyCompletionIfAppropriate() {
-  if (!has_received_completion_ || !has_seen_end_of_data_)
+  if (!has_received_completion_ || !has_seen_end_of_data_ || code_cache_loader_)
     return;
 
   handle_watcher_.Cancel();
@@ -308,6 +325,10 @@
 
 void NavigationBodyLoader::
     BindURLLoaderAndStartLoadingResponseBodyIfPossible() {
+  if (!response_body_) {
+    DCHECK(base::FeatureList::IsEnabled(features::kEarlyBodyLoad));
+    return;
+  }
   // Bind the mojo::URLLoaderClient interface in advance, because we will start
   // to read from the data pipe immediately which may potentially postpone the
   // method calls from the remote. That causes the flakiness of some layout
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.h
index c6045a8e..30f1394 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.h
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader.h
@@ -62,6 +62,9 @@
   //
   // StartLoadingBody
   //   request code cache
+  //   Note: If the kEarlyBodyLoad feature is enabled, BindURLLoaderAndContinue
+  //   can run in parallel with requesting the code cache. The client will get a
+  //   completion signal for both these events.
   // ContinueWithCodeCache
   //   notify client about cache
   // BindURLLoaderAndContinue
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader_unittest.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader_unittest.cc
index 5d80914..10560897 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader_unittest.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/navigation_body_loader_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/run_loop.h"
 #include "base/task/single_thread_task_runner.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "net/cert/x509_util.h"
@@ -15,18 +16,62 @@
 #include "services/network/public/cpp/url_loader_completion_status.h"
 #include "services/network/public/mojom/fetch_api.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/navigation/navigation_params.h"
 #include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
 #include "third_party/blink/public/platform/resource_load_info_notifier_wrapper.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/web_navigation_body_loader.h"
 #include "third_party/blink/public/web/web_navigation_params.h"
+#include "third_party/blink/renderer/platform/loader/fetch/code_cache_host.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
 
 namespace blink {
 
 namespace {
 
+class FakeCodeCacheHost : public mojom::CodeCacheHost {
+ public:
+  FakeCodeCacheHost()
+      : code_cache_host_(mojo::Remote<mojom::CodeCacheHost>(
+            receiver_.BindNewPipeAndPassRemote())) {}
+
+  // blink::mojom::CodeCacheHost implementation.
+  void DidGenerateCacheableMetadata(blink::mojom::CodeCacheType cache_type,
+                                    const GURL& url,
+                                    base::Time expected_response_time,
+                                    mojo_base::BigBuffer data) override {}
+  void FetchCachedCode(blink::mojom::CodeCacheType cache_type,
+                       const GURL& url,
+                       FetchCachedCodeCallback callback) override {
+    if (run_loop_.running())
+      run_loop_.Quit();
+    callback_ = std::move(callback);
+  }
+  void ClearCodeCacheEntry(blink::mojom::CodeCacheType cache_type,
+                           const GURL& url) override {}
+  void DidGenerateCacheableMetadataInCacheStorage(
+      const GURL& url,
+      base::Time expected_response_time,
+      mojo_base::BigBuffer data,
+      const url::Origin& cache_storage_origin,
+      const std::string& cache_storage_cache_name) override {}
+
+  blink::CodeCacheHost* GetCodeCacheHost() { return &code_cache_host_; }
+
+  void FinishFetch() {
+    if (!callback_)
+      run_loop_.Run();
+    std::move(callback_).Run(base::Time(), std::vector<uint8_t>());
+  }
+
+ private:
+  FetchCachedCodeCallback callback_;
+  mojo::Receiver<mojom::CodeCacheHost> receiver_{this};
+  blink::CodeCacheHost code_cache_host_;
+  base::RunLoop run_loop_;
+};
+
 class NavigationBodyLoaderTest : public ::testing::Test,
                                  public WebNavigationBodyLoader::Client {
  protected:
@@ -69,8 +114,8 @@
     loader_ = std::move(navigation_params.body_loader);
   }
 
-  void StartLoading() {
-    loader_->StartLoadingBody(this, nullptr /*code_cache_host*/);
+  void StartLoading(CodeCacheHost* code_cache_host = nullptr) {
+    loader_->StartLoadingBody(this, code_cache_host);
     base::RunLoop().RunUntilIdle();
   }
 
@@ -86,15 +131,20 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  void BodyCodeCacheReceived(mojo_base::BigBuffer data) override {}
+  void BodyCodeCacheReceived(mojo_base::BigBuffer data) override {
+    ASSERT_TRUE(expecting_code_cache_received_);
+    did_receive_code_cache_ = true;
+    if (run_loop_)
+      run_loop_->Quit();
+  }
 
   void BodyDataReceived(base::span<const char> data) override {
     ASSERT_TRUE(expecting_data_received_);
     did_receive_data_ = true;
     data_received_ += std::string(data.data(), data.size());
     TakeActions();
-    if (run_loop_.running())
-      run_loop_.Quit();
+    if (run_loop_)
+      run_loop_->Quit();
   }
 
   void BodyLoadingFinished(base::TimeTicks completion_time,
@@ -107,8 +157,8 @@
     did_finish_ = true;
     error_ = error;
     TakeActions();
-    if (run_loop_.running())
-      run_loop_.Quit();
+    if (run_loop_)
+      run_loop_->Quit();
   }
 
   void TakeActions() {
@@ -129,6 +179,11 @@
     }
   }
 
+  void ExpectCodeCacheReceived() {
+    expecting_code_cache_received_ = true;
+    did_receive_code_cache_ = false;
+  }
+
   void ExpectDataReceived() {
     expecting_data_received_ = true;
     did_receive_data_ = false;
@@ -146,31 +201,46 @@
   }
 
   void Wait() {
+    if (expecting_code_cache_received_) {
+      if (!did_receive_code_cache_)
+        WaitForRunLoop();
+      ASSERT_TRUE(did_receive_code_cache_);
+      expecting_code_cache_received_ = false;
+    }
     if (expecting_data_received_) {
       if (!did_receive_data_)
-        run_loop_.Run();
+        WaitForRunLoop();
       ASSERT_TRUE(did_receive_data_);
       expecting_data_received_ = false;
     }
     if (expecting_finished_) {
       if (!did_finish_)
-        run_loop_.Run();
+        WaitForRunLoop();
       ASSERT_TRUE(did_finish_);
       expecting_finished_ = false;
     }
   }
 
+  void WaitForRunLoop() {
+    run_loop_ = std::make_unique<base::RunLoop>();
+    run_loop_->Run();
+    run_loop_.reset();
+  }
+
   base::test::TaskEnvironment task_environment_;
   static const MojoWriteDataFlags kNone = MOJO_WRITE_DATA_FLAG_NONE;
   mojo::Remote<network::mojom::URLLoaderClient> client_remote_;
   std::unique_ptr<WebNavigationBodyLoader> loader_;
   mojo::ScopedDataPipeProducerHandle writer_;
 
-  base::RunLoop run_loop_;
+  std::unique_ptr<base::RunLoop> run_loop_;
   bool expecting_data_received_ = false;
   bool did_receive_data_ = false;
   bool expecting_finished_ = false;
   bool did_finish_ = false;
+  // Code cache is always called by default.
+  bool expecting_code_cache_received_ = true;
+  bool did_receive_code_cache_ = false;
   std::string buffer_to_write_;
   bool toggle_defers_loading_ = false;
   bool destroy_loader_ = false;
@@ -355,6 +425,39 @@
       navigation_params.response.ToResourceResponse().GetSSLInfo().has_value());
 }
 
+TEST_F(NavigationBodyLoaderTest, CodeCache) {
+  FakeCodeCacheHost code_cache_host;
+  CreateBodyLoader();
+  StartLoading(code_cache_host.GetCodeCacheHost());
+  code_cache_host.FinishFetch();
+  ExpectDataReceived();
+  Write("hello");
+  Wait();
+  EXPECT_EQ("hello", TakeDataReceived());
+}
+
+TEST_F(NavigationBodyLoaderTest, CodeCacheInParallelWithEarlyBodyLoad) {
+  base::test::ScopedFeatureList feature_list(features::kEarlyBodyLoad);
+  FakeCodeCacheHost code_cache_host;
+  CreateBodyLoader();
+  StartLoading(code_cache_host.GetCodeCacheHost());
+
+  // We should be able to receive data without receiving the code cache.
+  expecting_code_cache_received_ = false;
+  ExpectDataReceived();
+  Write("hello");
+  Complete(net::OK);
+  writer_.reset();
+  Wait();
+  EXPECT_EQ("hello", TakeDataReceived());
+
+  // Now wait for the code cache, and loading should finish.
+  ExpectCodeCacheReceived();
+  ExpectFinished();
+  code_cache_host.FinishFetch();
+  Wait();
+}
+
 }  // namespace
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.cc b/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.cc
index 81dabf8..ab1c5ce5 100644
--- a/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.cc
+++ b/third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.cc
@@ -44,6 +44,14 @@
     CodeCacheHost* code_cache_host) {
   DCHECK(!is_in_continue_);
   client_ = client;
+
+  if (client_) {
+    auto weak_self = weak_factory_.GetWeakPtr();
+    client_->BodyCodeCacheReceived(mojo_base::BigBuffer());
+    if (!weak_self)
+      return;
+  }
+
   Continue();
 }
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index a4dad92..afa4b1c 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -365,9 +365,6 @@
       status: "experimental",
     },
     {
-      name: "CanvasContextLostInBackground",
-    },
-    {
       name: "CanvasFormattedText",
       status: "experimental",
     },
@@ -951,7 +948,12 @@
       // Document transitions, including shared element transitions.
       // See https://github.com/WICG/shared-element-transitions
       name: "DocumentTransition",
-      origin_trial_feature_name: "DocumentTransition",
+      implied_by: ["DocumentTransitionRenderer"],
+    },
+    {
+      // Document transitions, including shared element transitions.
+      // See https://github.com/WICG/shared-element-transitions
+      name: "DocumentTransitionRenderer",
     },
     {
       name: "DocumentWrite",
@@ -2614,7 +2616,7 @@
     {
       name: "WebNFCMakeReadOnly",
       depends_on: ["WebNFC"],
-      status: "experimental",
+      status: {"Android": "stable", "default": "test"},
     },
     {
       name: "WebOTP",
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer.py b/third_party/blink/tools/blinkpy/w3c/test_importer.py
index c21702cd..85f12b4 100644
--- a/third_party/blink/tools/blinkpy/w3c/test_importer.py
+++ b/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -202,6 +202,9 @@
         if not options.auto_update:
             return 0
 
+        if not self.record_version():
+            return 1
+
         if not self.run_commit_queue_for_cl():
             return 1
 
@@ -211,6 +214,17 @@
 
         return 0
 
+    def record_version(self):
+        _log.info('Update external/Version to record upstream ToT.')
+        path_to_version = self.finder.path_from_web_tests('external', 'Version')
+        with open(path_to_version, "w") as f:
+            f.write("Version: %s\n" % self.wpt_revision)
+
+        message = 'Update revision'
+        self._commit_changes(message)
+        self._upload_patchset(message)
+        return True
+
     def update_expectations_for_cl(self):
         """Performs the expectation-updating part of an auto-import job.
 
diff --git a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/builders.py b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/builders.py
index 31453680..e467fdb 100644
--- a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/builders.py
+++ b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/builders.py
@@ -99,8 +99,10 @@
         if self._non_chromium_builders is None:
             str_builders = {
                 'devtools_frontend_linux_blink_light_rel',
+                'devtools_frontend_linux_blink_light_rel_fastbuild',
                 'devtools_frontend_linux_blink_rel',
                 'DevTools Linux',
+                'DevTools Linux Fastbuild',
                 'DevTools Linux (chromium)',
                 # Could be used in the future, but has never run any builds.
                 'linux-exp-code-coverage',
diff --git a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries.py b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries.py
index 79c76ed..7661679 100644
--- a/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries.py
+++ b/third_party/blink/tools/blinkpy/web_tests/stale_expectation_removal/queries.py
@@ -78,6 +78,12 @@
     builder_type=common_constants.BuilderTypes.CI),
            final_selector_query=FINAL_SELECTOR_QUERY)
 
+SUBMITTED_BUILDS_SUBQUERY = """\
+  submitted_builds AS (
+{chromium_builds}
+  ),""".format(chromium_builds=queries_module.SUBMITTED_BUILDS_TEMPLATE.format(
+    project_view='chromium'))
+
 # Same as CI_BQ_QUERY_TEMPLATE, but for tryjobs. Only data from builds that
 # were used for CL submission is considered.
 TRY_BQ_QUERY_TEMPLATE = """\
@@ -99,7 +105,7 @@
   ),
 {results_subquery}
 {final_selector_query}
-""".format(submitted_builds_subquery=queries_module.SUBMITTED_BUILDS_SUBQUERY,
+""".format(submitted_builds_subquery=SUBMITTED_BUILDS_SUBQUERY,
            results_subquery=RESULTS_SUBQUERY.format(
                builder_type=common_constants.BuilderTypes.TRY),
            final_selector_query=FINAL_SELECTOR_QUERY)
diff --git a/third_party/blink/tools/blinkpy/web_tests/views/metered_stream_unittest.py b/third_party/blink/tools/blinkpy/web_tests/views/metered_stream_unittest.py
index e096943..ab392af8 100644
--- a/third_party/blink/tools/blinkpy/web_tests/views/metered_stream_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/views/metered_stream_unittest.py
@@ -28,6 +28,7 @@
 
 import logging
 import re
+import six
 import unittest
 
 from blinkpy.web_tests.views.metered_stream import MeteredStream
@@ -41,7 +42,6 @@
 
     def setUp(self):
         self.stream = StringIO()
-        self.buflist = self.stream.buflist
         self.stream.isatty = lambda: self.isatty
 
         # configure a logger to test that log calls do normally get included.
@@ -50,7 +50,7 @@
         self.logger.propagate = False
 
         # add a dummy time counter for a default behavior.
-        self.times = range(10)
+        self.times = list(range(10))
 
         self.meter = MeteredStream(self.stream, self.verbose, self.logger,
                                    self.time_fn, 8675)
@@ -78,7 +78,7 @@
             self.meter.write_throttled_update('foo')
             self.meter.write_update('bar')
             self.meter.write('baz')
-            self.assertEqual(logging_stream.buflist, [])
+            self.assertEqual(logging_stream.getvalue().splitlines(), [])
         finally:
             root_logger.removeHandler(handler)
             root_logger.setLevel(orig_level)
@@ -91,24 +91,24 @@
         self.meter.write_throttled_update('baz 2')
         self.meter.writeln('done')
         self.assertEqual(self.times, [])
-        return self.buflist
+        return self.stream.getvalue().splitlines()
 
     def test_basic(self):
         buflist = self._basic([0, 1, 2, 13, 14])
-        self.assertEqual(buflist, ['foo\n', 'bar\n', 'baz 2\n', 'done\n'])
+        self.assertEqual(buflist, ['foo', 'bar', 'baz 2', 'done'])
 
     def _log_after_update(self):
         self.meter.write_update('foo')
         self.logger.info('bar')
-        return self.buflist
+        return self.stream.getvalue().splitlines()
 
     def test_log_after_update(self):
         buflist = self._log_after_update()
-        self.assertEqual(buflist, ['foo\n', 'bar\n'])
+        self.assertEqual(self.stream.getvalue().splitlines(), ['foo', 'bar'])
 
     def test_log_args(self):
         self.logger.info('foo %s %d', 'bar', 2)
-        self.assertEqual(self.buflist, ['foo bar 2\n'])
+        self.assertEqual(self.stream.getvalue().splitlines(), ['foo bar 2'])
 
 
 class TtyTest(RegularTest):
@@ -118,23 +118,30 @@
     def test_basic(self):
         buflist = self._basic([0, 1, 1.05, 1.1, 2])
         self.assertEqual(buflist, [
-            'foo',
-            MeteredStream._erasure('foo'), 'bar',
-            MeteredStream._erasure('bar'), 'baz 2',
-            MeteredStream._erasure('baz 2'), 'done\n'
+            'foo' + MeteredStream._erasure('foo') + 'bar' +
+            MeteredStream._erasure('bar') + 'baz 2' +
+            MeteredStream._erasure('baz 2') + 'done'
         ])
 
     def test_log_after_update(self):
         buflist = self._log_after_update()
         self.assertEqual(buflist,
-                         ['foo', MeteredStream._erasure('foo'), 'bar\n'])
+                         ['foo' + MeteredStream._erasure('foo') + 'bar'])
 
     def test_bytestream(self):
         self.meter.write('German umlauts: \xe4\xf6\xfc')
         self.meter.write(u'German umlauts: \xe4\xf6\xfc')
-        self.assertEqual(
-            self.buflist,
-            ['German umlauts: \xe4\xf6\xfc', u'German umlauts: \xe4\xf6\xfc'])
+        if six.PY2:
+            # TODO(preethim) : self.stream.getvalue() was giving unicode error.
+            # continued with buflist for now.
+            self.assertEqual(self.stream.buflist, [
+                'German umlauts: \xe4\xf6\xfc', u'German umlauts: \xe4\xf6\xfc'
+            ])
+
+        else:
+            self.assertEqual(self.stream.getvalue().splitlines(), [
+                'German umlauts: \xe4\xf6\xfc' + 'German umlauts: \xe4\xf6\xfc'
+            ])
 
 
 class VerboseTest(RegularTest):
@@ -145,23 +152,22 @@
         buflist = self._basic([0, 1, 2.1, 13, 14.1234])
         # We don't bother to match the hours and minutes of the timestamp since
         # the local timezone can vary and we can't set that portably and easily.
-        self.assertTrue(re.match(r'\d\d:\d\d:00.000 8675 foo\n', buflist[0]))
-        self.assertTrue(re.match(r'\d\d:\d\d:01.000 8675 bar\n', buflist[1]))
-        self.assertTrue(re.match(r'\d\d:\d\d:13.000 8675 baz 2\n', buflist[2]))
-        self.assertTrue(re.match(r'\d\d:\d\d:14.123 8675 done\n', buflist[3]))
+        self.assertTrue(re.match(r'\d\d:\d\d:00.000 8675 foo', buflist[0]))
+        self.assertTrue(re.match(r'\d\d:\d\d:01.000 8675 bar', buflist[1]))
+        self.assertTrue(re.match(r'\d\d:\d\d:13.000 8675 baz 2', buflist[2]))
+        self.assertTrue(re.match(r'\d\d:\d\d:14.123 8675 done', buflist[3]))
         self.assertEqual(len(buflist), 4)
 
     def test_log_after_update(self):
         buflist = self._log_after_update()
-        self.assertTrue(re.match(r'\d\d:\d\d:00.000 8675 foo\n', buflist[0]))
+        self.assertTrue(re.match(r'\d\d:\d\d:00.000 8675 foo', buflist[0]))
 
         # The second argument should have a real timestamp and pid, so we just check the format.
-        self.assertTrue(
-            re.match(r'\d\d:\d\d:\d\d.\d\d\d \d+ bar\n', buflist[1]))
+        self.assertTrue(re.match(r'\d\d:\d\d:\d\d.\d\d\d \d+ bar', buflist[1]))
 
         self.assertEqual(len(buflist), 2)
 
     def test_log_args(self):
         self.logger.info('foo %s %d', 'bar', 2)
-        self.assertEqual(len(self.buflist), 1)
-        self.assertTrue(self.buflist[0].endswith('foo bar 2\n'))
+        self.assertEqual(len(self.stream.getvalue().splitlines()), 1)
+        self.assertTrue(self.stream.getvalue().endswith('foo bar 2\n'))
diff --git a/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py b/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py
index 698fe9f..18234b4e 100644
--- a/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/views/printing_unittest.py
@@ -83,11 +83,11 @@
         self.assertTrue(stream.getvalue())
 
     def assertWritten(self, stream, contents):
-        self.assertEqual(stream.buflist, contents)
+        self.assertEqual(stream.getvalue().splitlines(), contents)
 
     def reset(self, stream):
-        stream.buflist = []
-        stream.buf = ''
+        stream.truncate(0)
+        stream.seek(0)
 
     def get_printer(self, args=None):
         args = args or []
@@ -155,31 +155,30 @@
             self.assertWritten(err, result)
 
         # Without times:
-        run_test(1, 1, 0, [], ['The test ran as expected.\n'])
+        run_test(1, 1, 0, [], ['The test ran as expected.'])
         run_test(2, 1, 1, [],
-                 ['\n', "1 test ran as expected, 1 didn't:\n", '    test0\n'])
+                 ['', "1 test ran as expected, 1 didn't:", '    test0'])
         run_test(3, 2, 1, [],
-                 ['\n', "2 tests ran as expected, 1 didn't:\n", '    test0\n'])
-        run_test(3, 2, 0, [],
-                 ['\n', "2 tests ran as expected (1 didn't run).\n"])
+                 ['', "2 tests ran as expected, 1 didn't:", '    test0'])
+        run_test(3, 2, 0, [], ['', "2 tests ran as expected (1 didn't run)."])
 
         # With times:
         fake_shards = [FakeShard('foo', 1), FakeShard('bar', 2)]
         run_test(1, 1, 0, fake_shards,
-                 ['The test ran as expected in 5.00s (2.00s in rwt, 1x).\n'])
+                 ['The test ran as expected in 5.00s (2.00s in rwt, 1x).'])
         run_test(2, 1, 1, fake_shards, [
-            '\n',
-            "1 test ran as expected, 1 didn't in 5.00s (2.00s in rwt, 1x):\n",
-            '    test0\n'
+            '',
+            "1 test ran as expected, 1 didn't in 5.00s (2.00s in rwt, 1x):",
+            '    test0'
         ])
         run_test(3, 2, 1, fake_shards, [
-            '\n',
-            "2 tests ran as expected, 1 didn't in 5.00s (2.00s in rwt, 1x):\n",
-            '    test0\n'
+            '',
+            "2 tests ran as expected, 1 didn't in 5.00s (2.00s in rwt, 1x):",
+            '    test0'
         ])
         run_test(3, 2, 0, fake_shards, [
-            '\n',
-            "2 tests ran as expected (1 didn't run) in 5.00s (2.00s in rwt, 1x).\n"
+            '',
+            "2 tests ran as expected (1 didn't run) in 5.00s (2.00s in rwt, 1x)."
         ])
 
     def test_test_status_line(self):
@@ -243,18 +242,17 @@
 
         self.reset(err)
         printer.print_found(100, 100, 10, 1, 1)
-        self.assertWritten(err,
-                           ['Found 100 tests; running 10, skipping 90.\n'])
+        self.assertWritten(err, ['Found 100 tests; running 10, skipping 90.'])
 
         self.reset(err)
         printer.print_found(100, 20, 10, 1, 1)
         self.assertWritten(
-            err, ['Found 20 tests (total 100); running 10, skipping 10.\n'])
+            err, ['Found 20 tests (total 100); running 10, skipping 10.'])
 
         self.reset(err)
         printer.print_found(100, 100, 10, 2, 3)
         self.assertWritten(err, [
-            'Found 100 tests; running 10 (6 times each: --repeat-each=2 --iterations=3), skipping 90.\n'
+            'Found 100 tests; running 10 (6 times each: --repeat-each=2 --iterations=3), skipping 90.'
         ])
 
     def test_debug_rwt_logging_is_throttled(self):
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index 9e8144f5d..28901be 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -13,6 +13,9 @@
 # Tests that fail in legacy but pass in NG
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/domxpath/xpath-evaluate-crash.html [ Crash ]
+crbug.com/626703 virtual/prerender/external/wpt/speculation-rules/prerender/media-autoplay.html [ Failure Timeout ]
+crbug.com/626703 virtual/prerender/external/wpt/speculation-rules/prerender/restrictions.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-flexbox/abspos/flex-abspos-staticpos-margin-003.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-overflow/scrollbar-gutter-vertical-lr-002.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-writing-modes/inline-box-orthogonal-child-with-margins.html [ Failure ]
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials b/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials
index 1eb709b..280f932 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials
+++ b/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials
@@ -44,6 +44,9 @@
 crbug.com/1209223 external/wpt/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-security-check-same-origin-domain.sub.html [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/domxpath/xpath-evaluate-crash.html [ Crash ]
+crbug.com/626703 virtual/prerender/external/wpt/speculation-rules/prerender/media-autoplay.html [ Failure Timeout ]
+crbug.com/626703 virtual/prerender/external/wpt/speculation-rules/prerender/restrictions.html [ Timeout ]
 crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/oklch-008.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-masking/mask-image/mask-composite-1c.html [ Crash Failure ]
 crbug.com/626703 external/wpt/selection/textcontrols/onselectionchange-content-attribute.html [ Timeout ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index fc6d0d197..f953fc01 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -2009,3 +2009,9 @@
 crbug.com/626703 [ Mac10.15 ] external/wpt/appmanifest/icons-member/icons-member-cors-fail-manual.sub.html [ Skip ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/appmanifest/start_url-member/start_url-member-pass-manual.html [ Skip ]
 crbug.com/626703 [ Mac11 ] virtual/fsa-incognito/external/wpt/file-system-access/local_FileSystemBaseHandle-postMessage-windows-manual.https.html [ Skip ]
+
+# The following tests never pass in the default Blink test runner due to forced
+# frame updates, but still pass in the full browser. They are only run in the
+# no-forced-frame-updates virtual test suite.
+external/wpt/html/dom/render-blocking-mechanism/* [ Skip ]
+virtual/no-forced-frame-updates/external/wpt/html/dom/render-blocking-mechanism/* [ Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 3d2ef1f97..51cf64a 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3177,6 +3177,25 @@
 crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-flexbox/flexbox_flow-column-wrap.html [ Crash Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/css/compositing/background-blending/background-blend-mode-plus-lighter.html [ Failure ]
+crbug.com/626703 external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg-basic.html [ Failure ]
+crbug.com/626703 external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg.html [ Failure ]
+crbug.com/626703 external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter.html [ Failure ]
+crbug.com/626703 external/wpt/domxpath/xpath-evaluate-crash.html [ Crash ]
+crbug.com/626703 [ Mac11-arm64 ] external/wpt/fetch/data-urls/processing.any.html [ Failure Timeout ]
+crbug.com/626703 [ Mac11 ] external/wpt/mediacapture-record/MediaRecorder-mimetype.html [ Failure Timeout ]
+crbug.com/626703 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-background-image-tiled-003.https.html [ Failure ]
+crbug.com/626703 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-function-this-value.https.html [ Failure ]
+crbug.com/626703 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-008.https.html [ Failure ]
+crbug.com/626703 [ Mac10.15 ] virtual/prerender/external/wpt/speculation-rules/prerender/cache-storage.https.html [ Skip Timeout ]
+crbug.com/626703 [ Mac10.15 ] virtual/prerender/external/wpt/speculation-rules/prerender/indexeddb.html [ Skip Timeout ]
+crbug.com/626703 [ Win ] virtual/prerender/external/wpt/speculation-rules/prerender/indexeddb.html [ Skip Timeout ]
+crbug.com/626703 [ Linux ] virtual/prerender/external/wpt/speculation-rules/prerender/local-storage.html [ Skip Timeout ]
+crbug.com/626703 [ Linux ] virtual/prerender/external/wpt/speculation-rules/prerender/media-autoplay.html [ Failure Skip Timeout ]
+crbug.com/626703 [ Mac10.14 ] virtual/prerender/external/wpt/speculation-rules/prerender/restriction-focus.html [ Skip Timeout ]
+crbug.com/626703 [ Mac10.15 ] virtual/prerender/external/wpt/speculation-rules/prerender/restriction-focus.html [ Skip Timeout ]
+crbug.com/626703 [ Win7 ] virtual/prerender/external/wpt/speculation-rules/prerender/restriction-focus.html [ Skip Timeout ]
+crbug.com/626703 virtual/prerender/external/wpt/speculation-rules/prerender/restrictions.html [ Skip Timeout ]
 crbug.com/626703 [ Mac10.13 ] external/wpt/wasm/jsapi/constructor/instantiate-bad-imports.any.html [ Timeout ]
 crbug.com/626703 [ Mac10.13 ] external/wpt/wasm/jsapi/constructor/instantiate-bad-imports.any.worker.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-createImageBitmap-e_srgb.html [ Timeout ]
@@ -6841,7 +6860,7 @@
 crbug.com/1229708 fast/events/pointerevents/pointer-event-in-slop-region.html [ Skip ]
 crbug.com/1229711 [ Linux ] http/tests/devtools/console-resource-errors.js [ Failure Pass ]
 # pause-on-elements-panel.js is marked as Slow, so it's required to also be Skipped due to it Timing out.
-crbug.com/1229725 http/tests/devtools/sources/debugger-pause/pause-on-elements-panel.js [ Crash Timeout Skip Failure Pass ]
+crbug.com/1229725 http/tests/devtools/sources/debugger-pause/pause-on-elements-panel.js [ Crash Failure Pass Skip Timeout ]
 crbug.com/1085647 external/wpt/pointerevents/compat/pointerevent_mouse-pointer-preventdefault.html [ Pass Timeout ]
 crbug.com/1087232 http/tests/devtools/network/network-worker-fetch-blocked.js [ Failure Pass ]
 crbug.com/1229801 http/tests/devtools/elements/css-rule-hover-highlights-selectors.js [ Failure Pass ]
@@ -7274,7 +7293,7 @@
 crbug.com/1249043 [ Linux ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Pass ]
 crbug.com/1249043 [ Mac10.12 ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Pass ]
 crbug.com/1249043 [ Mac10.13 ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Pass ]
-crbug.com/1249043 [ Mac10.14 ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Pass Timeout Skip ]
+crbug.com/1249043 [ Mac10.14 ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Pass Skip Timeout ]
 crbug.com/1249043 [ Mac11 ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Pass ]
 crbug.com/1249043 [ Mac11-arm64 ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Pass ]
 crbug.com/1249043 [ Win ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Pass ]
@@ -7312,7 +7331,9 @@
 crbug.com/1267734 [ Win7 ] fast/forms/suggestion-picker/week-suggestion-picker-appearance.html [ Failure Pass ]
 
 # This test is flaky on all platforms
-crbug.com/1191846 virtual/prerender/external/wpt/speculation-rules/prerender/local-storage.html [ Failure Pass ]
+crbug.com/1191846 [ Fuchsia ] virtual/prerender/external/wpt/speculation-rules/prerender/local-storage.html [ Failure Pass ]
+crbug.com/1191846 [ Mac ] virtual/prerender/external/wpt/speculation-rules/prerender/local-storage.html [ Failure Pass ]
+crbug.com/1191846 [ Win ] virtual/prerender/external/wpt/speculation-rules/prerender/local-storage.html [ Failure Pass ]
 
 # Sheriff 2021-11-10
 crbug.com/1268963 [ Linux ] external/wpt/resource-timing/object-not-found-after-TAO-cross-origin-redirect.html [ Failure Pass ]
@@ -7355,10 +7376,6 @@
 crbug.com/1272801 http/tests/permissions/chromium/test-request-sharedworker.html [ Pass Timeout ]
 
 # Flaky with setTimeout without clamp
-crbug.com/1272954 external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-same-doc.html [ Failure Pass ]
-crbug.com/1272954 external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-same-doc.html [ Failure Pass ]
-crbug.com/1272954 external/wpt/app-history/currentchange-event/currentchange-history-back-same-doc.html [ Failure Pass ]
-crbug.com/1272954 external/wpt/app-history/navigate-event/navigate-history-back-after-fragment.html [ Failure Pass ]
 crbug.com/1272955 http/tests/devtools/extensions/extensions-timeline-api.js [ Failure Pass ]
 
 # Flaky as depends upon order of execution.
@@ -7512,9 +7529,6 @@
 # Sanitizer API: Namespace-based tests will partially fail until namespace support is complete.
 crbug.com/1225606 external/wpt/sanitizer-api/sanitizer-names.https.tentative.html [ Failure ]
 
-# Changes to fork() on Mac causing test to crash
-crbug.com/1284401 [ Mac ] virtual/fenced-frame-mparch/wpt_internal/fenced_frame/create-credential.https.html [ Crash Failure ]
-
 # Flaky failures in finding the reference file on Mac
 crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-012.https.html [ Failure Pass ]
 crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-constructor-error.https.html [ Failure Pass ]
@@ -7536,9 +7550,9 @@
 
 # Sheriff 2022-01-18
 crbug.com/1287067 virtual/fenced-frame-mparch/wpt_internal/fenced_frame/embedder-require-corp.https.html [ Failure Pass ]
-crbug.com/1288264 [ Win ] http/tests/fetch/serviceworker-proxied/thorough/redirect-loop-base-https-other-https.html [ Skip Pass Timeout ]
-crbug.com/1288264 [ Win ] http/tests/fetch/window/thorough/cors-preflight2-base-https-other-https.html [ Skip Pass Timeout ]
-crbug.com/1288264 [ Win ] http/tests/fetch/serviceworker/thorough/nocors-base-https-other-https.html [ Skip Pass Timeout ]
+crbug.com/1288264 [ Win ] http/tests/fetch/serviceworker-proxied/thorough/redirect-loop-base-https-other-https.html [ Pass Skip Timeout ]
+crbug.com/1288264 [ Win ] http/tests/fetch/window/thorough/cors-preflight2-base-https-other-https.html [ Pass Skip Timeout ]
+crbug.com/1288264 [ Win ] http/tests/fetch/serviceworker/thorough/nocors-base-https-other-https.html [ Pass Skip Timeout ]
 crbug.com/1288264 [ Win ] http/tests/security/aboutBlank/xss-DENIED-navigate-opener-document-write.html [ Pass Timeout ]
 crbug.com/1227911 [ Linux Release ] virtual/no-auto-wpt-origin-isolation/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/2-iframes/parent-no-child1-no-subdomain-child2-yes-subdomainport.sub.https.html [ Failure Pass ]
 crbug.com/1227911 [ Mac10.14 ] virtual/no-auto-wpt-origin-isolation/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/2-iframes/parent-no-child1-no-subdomain-child2-yes-subdomainport.sub.https.html [ Failure Pass ]
@@ -7548,10 +7562,10 @@
 crbug.com/1227911 [ Mac10.14 ] virtual/no-auto-wpt-origin-isolation/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/2-iframes/parent-yes-child1-no-subdomain-child2-no-subdomain2.sub.https.html [ Failure Pass ]
 crbug.com/1227911 [ Linux Release ] virtual/no-auto-wpt-origin-isolation/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/iframe-navigation/parent-no-1-subdomain-yes-2-subdomain2-no.sub.https.html [ Failure Pass ]
 crbug.com/1227911 [ Mac10.14 ] virtual/no-auto-wpt-origin-isolation/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/iframe-navigation/parent-no-1-subdomain-yes-2-subdomain2-no.sub.https.html [ Failure Pass ]
-crbug.com/1227911 [ Win Release ] virtual/not-site-per-process/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/2-iframes/parent-no-child1-no-subdomain-child2-yes-subdomain.sub.https.html [ Failure Pass ]
+crbug.com/1227911 [ Release Win ] virtual/not-site-per-process/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/2-iframes/parent-no-child1-no-subdomain-child2-yes-subdomain.sub.https.html [ Failure Pass ]
 crbug.com/1227911 [ Linux Release ] virtual/not-site-per-process/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/2-iframes/parent-no-child1-no-subdomain-child2-yes-subdomain.sub.https.html [ Failure Pass ]
 crbug.com/1227911 [ Mac10.14 ] virtual/not-site-per-process/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/2-iframes/parent-no-child1-no-subdomain-child2-yes-subdomain.sub.https.html [ Failure Pass ]
-crbug.com/1227911 [ Win Release ] virtual/not-site-per-process/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/iframe-navigation/parent-no-1-no-subdomain-2-yes-subdomain.sub.https.html [ Failure Pass ]
+crbug.com/1227911 [ Release Win ] virtual/not-site-per-process/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/iframe-navigation/parent-no-1-no-subdomain-2-yes-subdomain.sub.https.html [ Failure Pass ]
 crbug.com/1227911 [ Linux Release ] virtual/not-site-per-process/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/iframe-navigation/parent-no-1-no-subdomain-2-yes-subdomain.sub.https.html [ Failure Pass ]
 crbug.com/1227911 [ Mac10.14 ] virtual/not-site-per-process/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/iframe-navigation/parent-no-1-no-subdomain-2-yes-subdomain.sub.https.html [ Failure Pass ]
 
@@ -7563,8 +7577,6 @@
 crbug.com/1290767 external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-in-worker.https.html [ Crash Pass ]
 crbug.com/1290767 external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-pipes-data-in-worker.https.html [ Crash Pass ]
 
-# Sheriff 2022-01-25
-crbug.com/1289992 virtual/document-transition/document-transition/paint-order.html [ Skip ]
 # Temporarily disable tests to land branded types related changes.
 crbug.com/1253323 [ Win ] http/tests/devtools/sources/debugger-breakpoints/nodejs-set-breakpoint.js [ Skip ]
 crbug.com/1253323 http/tests/devtools/persistence/automapping-urlencoded-paths.js [ Skip ]
@@ -7576,3 +7588,9 @@
 crbug.com/1290978 [ Win ] external/wpt/css/CSS2/normal-flow/crashtests/block-in-inline-ax-crash.html [ Crash Failure Pass Timeout ]
 crbug.com/1290978 [ Mac ] external/wpt/css/CSS2/normal-flow/crashtests/block-in-inline-ax-crash.html [ Crash Failure Pass Timeout ]
 crbug.com/1290978 [ Win7 ] http/tests/devtools/elements/accessibility/edit-aria-attributes.js [ Crash Failure Pass Timeout Skip ]
+crbug.com/1291246 [ Mac ] virtual/dark-system-color-picker-appearance/fast/forms/color-scheme/color/color-picker-appearance.html [ Failure Pass ]
+crbug.com/1291246 [ Mac ] virtual/system-color-picker-appearance/fast/forms/color-scheme/color/color-picker-appearance.html [ Failure Pass ]
+crbug.com/1291274 [ Mac ] virtual/document-transition/wpt_internal/document-transition/transition-waits-for-animations.html [ Crash ]
+crbug.com/1291383 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-perfect-negotiation-stress-glare-linear.https.html [ Skip ]
+crbug.com/1291383 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-perfect-negotiation-stress-glare.https.html [ Skip ]
+crbug.com/1291383 virtual/shared_array_buffer_on_desktop/fast/peerconnection/RTCPeerConnection-addMultipleTransceivers.html [ Skip ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 691f350..4e19f863 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -614,6 +614,11 @@
     "args": ["--disable-blink-features=PaymentRequestTotalOptional"]
   },
   {
+    "prefix": "basic-card-disabled",
+    "bases": ["payments/payment-request-interface.html", "http/tests/payments/payment-instruments.html"],
+    "args": ["--disable-blink-features=PaymentRequestBasicCard"]
+  },
+  {
     "prefix": "json-modules",
     "bases": ["external/wpt/html/semantics/scripting-1/the-script-element/json-module"],
     "args": ["--enable-features=JSONModules", "--js-flags=--harmony-import-assertions"]
@@ -1070,5 +1075,10 @@
     "prefix": "dark-system-color-picker-appearance",
     "bases": ["fast/forms/color-scheme/color/color-picker-appearance.html"],
     "args": ["--blink-settings=preferredColorScheme=0", "--enable-features=SystemColorChooser"]
+  },
+  {
+    "prefix": "no-forced-frame-updates",
+    "bases": ["external/wpt/html/dom/render-blocking-mechanism"],
+    "args": ["--enable-features=NoForcedFrameUpdates"]
   }
 ]
diff --git a/third_party/blink/web_tests/WebDriverExpectations b/third_party/blink/web_tests/WebDriverExpectations
index 7f686d4..731057b 100644
--- a/third_party/blink/web_tests/WebDriverExpectations
+++ b/third_party/blink/web_tests/WebDriverExpectations
@@ -295,3 +295,4 @@
 crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/stress.py>>test_stress[4] [ Failure Pass ]
 crbug.com/1123907 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/stress.py>>test_stress [ Failure Pass ]
 crbug.com/1128104 [ Linux ] external/wpt/webdriver/tests/release_actions/sequence.py>>test_no_release_mouse_sequence_keeps_dblclick_state [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_origin.py>>test_element_larger_than_viewport [ Failure ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version
new file mode 100644
index 0000000..758cd28
--- /dev/null
+++ b/third_party/blink/web_tests/external/Version
@@ -0,0 +1 @@
+Version: 165e350edf37719726d3240af2935cdec43d1447
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index e8918f3..a94e1fa3 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -225,6 +225,17 @@
        ]
       ]
      },
+     "normal-flow": {
+      "crashtests": {
+       "block-in-inline-ax-crash.html": [
+        "dee9ed8a1b8ed368d854e2d4c7f8cd3dfcd2e222",
+        [
+         null,
+         {}
+        ]
+       ]
+      }
+     },
      "text": {
       "crashtests": {
        "bidi-inline-fragment-oof-crash.html": [
@@ -342,6 +353,20 @@
        {}
       ]
      ],
+     "chrome-bug-1288769-000-crash.html": [
+      "884c92f0852adaeec74103fd9271fb9ea464f8d8",
+      [
+       null,
+       {}
+      ]
+     ],
+     "chrome-bug-1288769-001-crash.html": [
+      "bf7ab3b7e61ace333bcbab6cb8860a16b657b0e5",
+      [
+       null,
+       {}
+      ]
+     ],
      "flexbox": {
       "fixed-flex-item-inside-abs-flex-in-multicol-crash.html": [
        "29ba56748f9a81615977ded26f4299fa744475f0",
@@ -459,6 +484,27 @@
       ]
      ],
      "container-queries": {
+      "chrome-bug-1289718-000-crash.html": [
+       "5dab634a2a2586722ddbd0a9cf9eea8e31001dc6",
+       [
+        null,
+        {}
+       ]
+      ],
+      "chrome-bug-1289718-001-crash.html": [
+       "7236714183fd2130c9d12ffaf5226376d3ee7e58",
+       [
+        null,
+        {}
+       ]
+      ],
+      "container-type-change-chrome-legacy-crash.html": [
+       "609142a2c5f7fa16f241b6ac06842a62ed68be8c",
+       [
+        null,
+        {}
+       ]
+      ],
       "flex-in-columns-000-crash.html": [
        "65d5aafe4fde7bafcffdb44aa645baa45c6352c8",
        [
@@ -550,6 +596,13 @@
         {}
        ]
       ],
+      "input-placeholder-inline-size-crash.html": [
+       "4b1284e5cb3d90a76a756a8d89a439c43d7e65e1",
+       [
+        null,
+        {}
+       ]
+      ],
       "pseudo-container-crash.html": [
        "f998c3a4464ca3eb3ce07687cf24d9dcdc9a16af",
        [
@@ -1021,6 +1074,20 @@
      ]
     },
     "css-layout-api": {
+     "chrome-bug-1287843-000-crash.https.html": [
+      "6137eba6dcf1d5fa61abb0b4bd2c437be8b72d36",
+      [
+       null,
+       {}
+      ]
+     ],
+     "chrome-bug-1287843-001-crash.https.html": [
+      "ac8c6ecf1ad77fe2432ba66f69a30b71e46118c5",
+      [
+       null,
+       {}
+      ]
+     ],
      "input-text-crash.https.html": [
       "2d32609040a970fa0b20ec6f0530b91c53a360d4",
       [
@@ -1133,6 +1200,13 @@
       ]
      ],
      "crashtests": {
+      "multicol-block-in-inline-crash.html": [
+       "037b558ac0be08da6dfa6868b06e7a03e44031de",
+       [
+        null,
+        {}
+       ]
+      ],
       "multicol-cached-consumed-bsize-crash.html": [
        "f82bddfef1c1f7f9f32abeb0dad4a215db807f9a",
        [
@@ -1225,6 +1299,13 @@
        {}
       ]
      ],
+     "remove-block-sibling-of-inline-with-block-crash.html": [
+      "e752abc9f51aa7a42f22fd5944b37424b561fb2e",
+      [
+       null,
+       {}
+      ]
+     ],
      "remove-inline-with-block-beside-spanners-crash.html": [
       "d48ff19b99afd6e96e070749798ccc8b37fdeefe",
       [
@@ -2146,7 +2227,7 @@
    },
    "domxpath": {
     "xpath-evaluate-crash.html": [
-     "d32254936f6c629d856e25052e007c8de1d6f2c5",
+     "5303d85ad31ca0ee230ac36231898342b07ad2c3",
      [
       null,
       {}
@@ -2462,6 +2543,19 @@
      ]
     }
    },
+   "fetch": {
+    "api": {
+     "crashtests": {
+      "request.html": [
+       "2d21930c3bbc8743ebfe5ad679e62f41a776ebde",
+       [
+        null,
+        {}
+       ]
+      ]
+     }
+    }
+   },
    "html": {
     "browsers": {
      "origin": {
@@ -2952,6 +3046,13 @@
    },
    "mathml": {
     "crashtests": {
+     "chrome-bug-1287843.html": [
+      "6fc95fc12e11d28ae69ec05bcd8d935103b5bcb1",
+      [
+       null,
+       {}
+      ]
+     ],
      "display-and-column-properties.html": [
       "c40a2a05497642d076962315b6b90cc3f5987360",
       [
@@ -3314,6 +3415,17 @@
     }
    },
    "web-animations": {
+    "animation-model": {
+     "keyframe-effects": {
+      "effect-in-removed-iframe-crash.html": [
+       "209ede786ff425050b3a1749568afb6a9029a2cf",
+       [
+        null,
+        {}
+       ]
+      ]
+     }
+    },
     "interfaces": {
      "Animation": {
       "commitStyles-crash.html": [
@@ -13392,6 +13504,13 @@
       {}
      ]
     ],
+    "serialPort_loopback_flowControl-manual.https.html": [
+     "930dab74d64fce9585394157593bbc3538a5b19c",
+     [
+      null,
+      {}
+     ]
+    ],
     "serialPort_readable-manual.https.html": [
      "4e49ef4061774bf6d48f9fec7d7f09f45414fb11",
      [
@@ -13904,6 +14023,15 @@
      ]
     ]
    },
+   "window-placement": {
+    "multi-screen-window-open-manual.tentative.https.html": [
+     "5214a48702eb196b7673110ef1aa8569ffe5ce80",
+     [
+      null,
+      {}
+     ]
+    ]
+   },
    "xhr": {
     "send-authentication-existing-session-manual.htm": [
      "a80efd6e8436408db15d8019beef3abc0dfd0ab9",
@@ -51534,6 +51662,35 @@
         {}
        ]
       ],
+      "resizable-iframe-paint-order.html": [
+       "574df950ce6449093b317e648d0566e23a6d6716",
+       [
+        null,
+        [
+         [
+          "/css/CSS2/normal-flow/resizable-iframe-paint-order-ref.html",
+          "=="
+         ]
+        ],
+        {
+         "fuzzy": [
+          [
+           null,
+           [
+            [
+             0,
+             255
+            ],
+            [
+             0,
+             200
+            ]
+           ]
+          ]
+         ]
+        }
+       ]
+      ],
       "root-box-001.xht": [
        "2863619a50bd29a9edec38094314884b07f47bd3",
        [
@@ -69400,6 +69557,19 @@
         ],
         {}
        ]
+      ],
+      "background-blend-mode-plus-lighter.html": [
+       "0816dc691b7f812da4962755b8c765a0e5074e99",
+       [
+        null,
+        [
+         [
+          "/css/compositing/background-blending/reference/background-blend-mode-plus-lighter-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
       ]
      },
      "compositing_simple_div.html": [
@@ -69780,7 +69950,20 @@
         {}
        ]
       ],
-      "mix-blend-mode-plus-lighter-svg.html": [
+      "mix-blend-mode-plus-lighter-basic.html": [
+       "fcf2d172afd6b1ebc99f64021a66a548d5b1f1fd",
+       [
+        null,
+        [
+         [
+          "/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-basic-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "mix-blend-mode-plus-lighter-svg-basic.html": [
        "4762389ca9257440a1297a3e246af0eddd78bf22",
        [
         null,
@@ -69793,8 +69976,21 @@
         {}
        ]
       ],
+      "mix-blend-mode-plus-lighter-svg.html": [
+       "fc5e94e74e90b083b5bf609f19fefbe570190bc0",
+       [
+        null,
+        [
+         [
+          "/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-svg-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "mix-blend-mode-plus-lighter.html": [
-       "ae3dff155dce88166be3bb28ac40e2531720e2f3",
+       "e6fc4d73a0421e4e1978c3d4875b0f2e85c5917e",
        [
         null,
         [
@@ -70619,6 +70815,19 @@
         {}
        ]
       ],
+      "background-color-animation-with-mask.html": [
+       "9001121edc5b2663ca195592d098c012ff3824bc",
+       [
+        null,
+        [
+         [
+          "/css/css-backgrounds/animations/background-color-animation-with-mask-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "background-color-animation-with-table1.html": [
        "de5f482e886b54ec67573097c7d8c509a26496cc",
        [
@@ -77596,6 +77805,19 @@
        {}
       ]
      ],
+     "fieldset-inset-shadow.html": [
+      "cb13cd805d0dafcdd1c288c71809a6531eb76fae",
+      [
+       null,
+       [
+        [
+         "/css/css-backgrounds/fieldset-inset-shadow-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "first-letter-space-not-selected.html": [
       "842832c01bac0c0643395ed3387d7263ec4dbf0f",
       [
@@ -78774,7 +78996,7 @@
        ]
       ],
       "multi-line-row-flex-fragmentation-010.html": [
-       "5723fbfb77a27d45fede7be6a0d325acc2ac8cf5",
+       "18cd9d7ee7575fd2791c65580ac2a613aa7951da",
        [
         null,
         [
@@ -78839,7 +79061,7 @@
        ]
       ],
       "multi-line-row-flex-fragmentation-015.html": [
-       "0620a419d56983f4d39d18a8239fb1a19283fa28",
+       "64c32c0692ef5fd2d4bc7166884cb46292d69024",
        [
         null,
         [
@@ -78877,6 +79099,58 @@
         {}
        ]
       ],
+      "multi-line-row-flex-fragmentation-018.html": [
+       "f12e6519a756c57f421724bc66f1e8d073553bc5",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multi-line-row-flex-fragmentation-019.html": [
+       "3c85a703f99f6ea3f4113d6550cd4ac56a3401d7",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multi-line-row-flex-fragmentation-020.html": [
+       "334e53468e08aa0e87478774c6a9f5f6166ea2b2",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multi-line-row-flex-fragmentation-021.html": [
+       "74890bea9138834d67add4b4782839b2791be25c",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "single-line-column-flex-fragmentation-001.html": [
        "d1411f9a16a14585b945408b162182ed343419d2",
        [
@@ -79448,6 +79722,19 @@
         ],
         {}
        ]
+      ],
+      "single-line-row-flex-fragmentation-014.html": [
+       "00f9afa701be64b04e2265a91d0479ac7e9af505",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
       ]
      },
      "float-000.html": [
@@ -90699,6 +90986,19 @@
         {}
        ]
       ],
+      "chrome-legacy-skip-recalc.html": [
+       "d4a27c3d77d49540f11ee777b18ea7cf809b70a9",
+       [
+        null,
+        [
+         [
+          "/css/reference/pass_if_pass_below.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "counters-in-container-dynamic.html": [
        "d817fe64bace3c414dc13ef76d5b242f071c87e3",
        [
@@ -131890,6 +132190,58 @@
        {}
       ]
      ],
+     "change-fragmentainer-size-000.html": [
+      "823506d1c55e23addc2838ee3c92bf19995d8ec5",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "change-fragmentainer-size-001.html": [
+      "d9ae7b1b6628c51e239977e23bf3ec97dc347737",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "change-fragmentainer-size-002.html": [
+      "4b3804361e1cb432962275726fc355fcc5e415f6",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "change-fragmentainer-size-003.html": [
+      "b8fae275022202f4ec3491167a0080eb8484ed16",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "change-intrinsic-width.html": [
       "3df3e1ebc8f9b5780dc858a878bca13dbedcdb35",
       [
@@ -133204,7 +133556,7 @@
       ]
      ],
      "multicol-fill-balance-018.html": [
-      "692071c4834bfa64326823ea365db57200dd6605",
+      "fd4f47c591d743ab4cbb6e52c22ee8b7323396db",
       [
        null,
        [
@@ -135374,58 +135726,6 @@
        {}
       ]
      ],
-     "multicol-table-cell-001.xht": [
-      "d6f052905a4f4a0e57bbe44c339da74ceab5571a",
-      [
-       null,
-       [
-        [
-         "/css/css-multicol/multicol-table-cell-001-ref.xht",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
-     "multicol-table-cell-height-001.xht": [
-      "2efd64b869cf969ab3b990ed0c4510eed775665f",
-      [
-       null,
-       [
-        [
-         "/css/css-multicol/multicol-table-cell-height-001-ref.xht",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
-     "multicol-table-cell-height-002.xht": [
-      "c7ece15d2d01f1367ced620a7909205bad4a30b3",
-      [
-       null,
-       [
-        [
-         "/css/css-multicol/multicol-table-cell-height-001-ref.xht",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
-     "multicol-table-cell-vertical-align-001.xht": [
-      "b2fc3f833115dcd5cd74341a7916ea1310255c58",
-      [
-       null,
-       [
-        [
-         "/css/css-multicol/multicol-table-cell-vertical-align-ref.xht",
-         "=="
-        ]
-       ],
-       {}
-      ]
-     ],
      "multicol-under-vertical-rl-scroll.html": [
       "61754e7d29d2d5399e6b41ceb27fe25af3b8019c",
       [
@@ -136050,6 +136350,60 @@
        {}
       ]
      ],
+     "table": {
+      "multicol-table-cell-001.xht": [
+       "405ace9234022d68bdf1d5153465324bc0f898cf",
+       [
+        null,
+        [
+         [
+          "/css/css-multicol/table/multicol-table-cell-001-ref.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multicol-table-cell-height-001.xht": [
+       "1d3e44ea5f3288aa47896225950bf9e103f6a724",
+       [
+        null,
+        [
+         [
+          "/css/css-multicol/table/multicol-table-cell-height-001-ref.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multicol-table-cell-height-002.xht": [
+       "c66c475f12a1431ed098c9d7b1f001c36732af14",
+       [
+        null,
+        [
+         [
+          "/css/css-multicol/table/multicol-table-cell-height-001-ref.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multicol-table-cell-vertical-align-001.xht": [
+       "b2fc3f833115dcd5cd74341a7916ea1310255c58",
+       [
+        null,
+        [
+         [
+          "/css/css-multicol/table/multicol-table-cell-vertical-align-ref.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ]
+     },
      "with-custom-layout-on-same-element.https.html": [
       "5388b08cde3936088978f09ccb0fd438347421e1",
       [
@@ -137796,6 +138150,19 @@
        {}
       ]
      ],
+     "webkit-line-clamp-block-in-inline-001.html": [
+      "75d1de3bf5bcf5d00d6980de4a70845e9f7ae8e4",
+      [
+       null,
+       [
+        [
+         "/css/css-overflow/reference/webkit-line-clamp-block-in-inline-001-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "webkit-line-clamp-dynamic-001.html": [
       "fc4f2f9e4db6b55d124dd774e0563e2625ca3288",
       [
@@ -139303,6 +139670,19 @@
      ]
     },
     "css-position": {
+     "change-insets-inside-strict-containment-nested.html": [
+      "b70ef0e667be3adb46f261da9e407ae8ecdc1299",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "containing-block-change-button.html": [
       "a4d20685ce9f25ae1ff655a13b14186b74bc4323",
       [
@@ -143210,7 +143590,7 @@
       ]
      ],
      "marker-line-height.html": [
-      "8d226e3feaa359fe8ddacfd75610879abe33d955",
+      "ee32f3bb6d6135b02a25a3bb5d48110053bd4347",
       [
        null,
        [
@@ -167853,6 +168233,136 @@
         {}
        ]
       ],
+      "trailing-space-and-text-alignment-001.html": [
+       "011518bdd84defaba71bd32c87b4db1511644013",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-001-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "trailing-space-and-text-alignment-002.html": [
+       "a015c74766a1dbd767fc9770d3ca3cad6654f251",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-002-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "trailing-space-and-text-alignment-003.html": [
+       "9d0c971830f3a9a17be197a0fdabc5ea0d63a2bc",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-001-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "trailing-space-and-text-alignment-004.html": [
+       "2328afa74922c64a63e8320e5dff8438a89d3756",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-002-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "trailing-space-and-text-alignment-005.html": [
+       "059a2af436d64db772d59d7118273654ba6153a2",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-001-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "trailing-space-and-text-alignment-rtl-001.html": [
+       "5351fdc5f74aaa54371c0ad371966943a9d69782",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-rtl-001-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "trailing-space-and-text-alignment-rtl-002.html": [
+       "8fdf694390dc137520090f2d33ff98ba3816155a",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-rtl-002-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "trailing-space-and-text-alignment-rtl-003.html": [
+       "00186110d7df1e4e7540422e7395bbe71c6a2fba",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-rtl-001-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "trailing-space-and-text-alignment-rtl-004.html": [
+       "628c7fa70f70cc87cdef7836237d05e1b30ce999",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-rtl-005-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "trailing-space-and-text-alignment-rtl-005.html": [
+       "bb69506714610acce46ab15fad50d8d31ca501c2",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/trailing-space-and-text-alignment-rtl-001-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "trailing-space-rtl-001.html": [
        "8bc6cc75cbeaf8b6a091b2aadd5eead52d3b1bfd",
        [
@@ -168431,6 +168941,32 @@
         {}
        ]
       ],
+      "white-space-pre-wrap-trailing-spaces-022.html": [
+       "95f4361e8395e28e21d03dce4d9e0d454651bf5c",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "white-space-pre-wrap-trailing-spaces-023.html": [
+       "3986079e62b95a2c64098a62c6cfe8ad44a58e64",
+       [
+        null,
+        [
+         [
+          "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "white-space-wrap-after-nowrap-001.html": [
        "5947c289e8752c26a17631f37309de7874d68986",
        [
@@ -206340,7 +206876,7 @@
       ]
      ],
      "mq-invalid-media-type-001.html": [
-      "24ebd9fd4fcf302a9d695b549098ed7663d18277",
+      "a88f18173e0c4f95a92943c0e6ff388827142932",
       [
        null,
        [
@@ -206353,7 +206889,7 @@
       ]
      ],
      "mq-invalid-media-type-002.html": [
-      "71f597e447b346d5115307cb8e174b2b6ebd52c0",
+      "763a7f29205757b57395465741b9a2ae65e9dd42",
       [
        null,
        [
@@ -206366,7 +206902,7 @@
       ]
      ],
      "mq-invalid-media-type-003.html": [
-      "b12bd75814a52a7232467bcd724db1b94dc08ee9",
+      "acc524ca98a305fe8fad3a871c18e02bbe5c4933",
       [
        null,
        [
@@ -206379,7 +206915,7 @@
       ]
      ],
      "mq-invalid-media-type-004.html": [
-      "d039281c0254e2bb794e229baecbe4d39c547baa",
+      "689c8d1a78d193225eac5a6b84c19f32b0e94913",
       [
        null,
        [
@@ -214632,6 +215168,19 @@
          {}
         ]
        ],
+       "select-intrinsic-option-font-size.html": [
+        "7f36708973d4c01f9af0e3c613ccaddd738ea6e9",
+        [
+         null,
+         [
+          [
+           "/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size-ref.html",
+           "=="
+          ]
+         ],
+         {}
+        ]
+       ],
        "select-intrinsic-text-transform.html": [
         "1026e29977bfbc1ccc24bd2597743c40fb7eb4c3",
         [
@@ -227401,6 +227950,10 @@
       "61aebdf326679cdd7e4d9318e2fa1cf90283eb82",
       []
      ],
+     "empty-document.html": [
+      "b9cd130a07f77ee1a54f4bf54df54dc126fec1ee",
+      []
+     ],
      "historical-serviceworker.js": [
       "8bd89a23adb70fd0075131d29b6c4d36cb079d18",
       []
@@ -227503,6 +228056,10 @@
      []
     ],
     "resources": {
+     "cross-origin-helper-frame.html": [
+      "997c5a2b72bafcad3421ccb48e48e323de6ef6f0",
+      []
+     ],
      "idbfactory-origin-isolation-iframe.html": [
       "d405ea48e15e298241a2c400a6d04adbd054e1e5",
       []
@@ -228224,6 +228781,18 @@
        "f61f9a829820411a8323fe5b3f49cab4cd1d4e32",
        []
       ],
+      "no-referrer-meta.html": [
+       "bd5ec391cce892199b0d448b516f6dd087c99665",
+       []
+      ],
+      "no-referrer.html": [
+       "c8b7661f42212985888d1dfdf1d8729f89c4fc35",
+       []
+      ],
+      "no-referrer.html.headers": [
+       "7ffbf17d6be5a59e5b3636adc0eb14f3e2e528c2",
+       []
+      ],
       "opaque-origin-page.html": [
        "5e8a71981c5f6ce101e8c3f131373d77cf17717a",
        []
@@ -229832,7 +230401,7 @@
       []
      ],
      "dispatcher.js": [
-      "b789c6e50c2ccb2d691eb26cc44c51c7f0ed3cb9",
+      "1bac9386e6f729c3a2135475e7b5cbfaab2f6e71",
       []
      ],
      "dispatcher.py": [
@@ -232880,6 +233449,10 @@
      "b58767080c33af12e82638869ef395346ca509e5",
      []
     ],
+    "idlharness.https.window-expected.txt": [
+     "6e82efe03661492bd611a401f2af2e0a63a0f86d",
+     []
+    ],
     "passwordcredential-framed-get.sub.https-expected.txt": [
      "b58767080c33af12e82638869ef395346ca509e5",
      []
@@ -237258,6 +237831,10 @@
        "e0efaf7c7e8d472ba31ca31a8b743f4a208b6464",
        []
       ],
+      "resizable-iframe-paint-order-ref.html": [
+       "ef067c82b704db66e1305dbbda81c1b41690d032",
+       []
+      ],
       "root-box-001-ref.xht": [
        "fc396c4419693b5c8a34ce6b4dbab6582b716f27",
        []
@@ -239908,6 +240485,10 @@
        "background-blend-mode-gradient-image-ref.html": [
         "4389960d783c91c414b33e1aaf0466ca91ee5942",
         []
+       ],
+       "background-blend-mode-plus-lighter-ref.html": [
+        "550981986b04746bda8f20ced60c0f9bd7ff3053",
+        []
        ]
       },
       "support": {
@@ -240035,14 +240616,22 @@
         "275105c5dbb03cf1b82eb058e856d53b129ecbe9",
         []
        ],
-       "mix-blend-mode-plus-lighter-ref.html": [
+       "mix-blend-mode-plus-lighter-basic-ref.html": [
         "e5acd26b6fd498d12f2591d4b04aa3c8f748e153",
         []
        ],
-       "mix-blend-mode-plus-lighter-svg-ref.html": [
+       "mix-blend-mode-plus-lighter-ref.html": [
+        "4709ab8b6882eb5cf33d1d3180ca5a7585f1ddb2",
+        []
+       ],
+       "mix-blend-mode-plus-lighter-svg-basic-ref.html": [
         "9193bb574b3f9537a26f5ce0c5430f1685058c63",
         []
        ],
+       "mix-blend-mode-plus-lighter-svg-ref.html": [
+        "8e1cb707599c4f5d2a9b42343076d61253ad22a2",
+        []
+       ],
        "mix-blend-mode-rotated-clip-ref.html": [
         "377ed7c879fd8ec15ff660da617294bc119206e0",
         []
@@ -240153,6 +240742,16 @@
       "be2348ab967f2ff4c161f8bbb9999a0bd8523e82",
       []
      ],
+     "support": {
+      "plus-lighter.js": [
+       "cadefa57282360af0910e9616671f1103c5f4c5d",
+       []
+      ],
+      "utils.js": [
+       "eb369ce2e58f0a25e1ff543b2ed53e2e2ac99b06",
+       []
+      ]
+     },
      "svg": {
       "reference": {
        "mix-blend-mode-in-svg-image-ref.html": [
@@ -240439,12 +241038,16 @@
       "757a1e70d8b76c5a2fc8757f683a1b5633ef383b",
       []
      ],
+     "CSSAnimation-effect.tentative-expected.txt": [
+      "aa98c773694103c8dc59882bf72c6474ab3a75f0",
+      []
+     ],
      "Document-getAnimations.tentative-expected.txt": [
       "e32e17fc830a811972cb94a46597e8db005fa55f",
       []
      ],
      "KeyframeEffect-getKeyframes.tentative-expected.txt": [
-      "3b7549d25f5792ea52546fcd2e24916c6b0a7e59",
+      "ce7f4a742384b2dfb22b8f422b7c8f2fb0e063c4",
       []
      ],
      "META.yml": [
@@ -240496,6 +241099,14 @@
       []
      ],
      "parsing": {
+      "animation-composition-computed.tentative-expected.txt": [
+       "44d81d1bb976a15e39e2e7db734efc3c6ebeeac8",
+       []
+      ],
+      "animation-composition-valid.tentative-expected.txt": [
+       "0f58883c97448d970d76b822f26f36efe3f14489",
+       []
+      ],
       "animation-name-invalid-expected.txt": [
        "a6d072671edbf2b2528754cf15f469eb7ce08d41",
        []
@@ -240590,6 +241201,10 @@
        "ba414f7b349d6a3de8b10eb539de48b408365f2a",
        []
       ],
+      "background-color-animation-with-mask-ref.html": [
+       "6cb20f12d13c853871a5f6fdc389a6192f9b4502",
+       []
+      ],
       "background-color-animation-with-table1-ref.html": [
        "7522c388f064caf63a589618d842894c709c0445",
        []
@@ -241435,6 +242050,10 @@
       "8612aaafa99b6805690766d4ac5f910a695a7991",
       []
      ],
+     "fieldset-inset-shadow-ref.html": [
+      "6b4b9e5755fea014152af3802415146277fd36d7",
+      []
+     ],
      "hidpi": {
       "simple-bg-color-ref.html": [
        "d768c02b25a82e45cd8cb9e7120d2655d55f33d5",
@@ -243546,10 +244165,6 @@
        "262fe39522e0e251756616705d700a7ba77b0ca7",
        []
       ],
-      "container-for-shadow-dom.tentative-expected.txt": [
-       "c68cca2e9841c1417971e347182def49812084cb",
-       []
-      ],
       "container-name-parsing-expected.txt": [
        "cda9550e7fa97b050f5aa2d435ad54a015e41fc1",
        []
@@ -259757,18 +260372,6 @@
       "4fcc57a658894e9ea8b75d80ee96f32353a27637",
       []
      ],
-     "multicol-table-cell-001-ref.xht": [
-      "fcc736a029b7d4a8a393cf209edf5981f14b2d12",
-      []
-     ],
-     "multicol-table-cell-height-001-ref.xht": [
-      "a2e4a840661e62cf5ebaa308e518465bd892796d",
-      []
-     ],
-     "multicol-table-cell-vertical-align-ref.xht": [
-      "6d20530b73bb6276fba3d2ac5c740aca1100e0b2",
-      []
-     ],
      "multicol-under-vertical-rl-scroll-ref.html": [
       "1a7cfb6e2303ce8778fed9587e208a7df950ff6f",
       []
@@ -260002,6 +260605,20 @@
        "59843ae54b64f6ce4f7e616d4be491c911ea84cf",
        []
       ]
+     },
+     "table": {
+      "multicol-table-cell-001-ref.xht": [
+       "37f172d5e18e53c2eff5853b1ee459aec5ff614a",
+       []
+      ],
+      "multicol-table-cell-height-001-ref.xht": [
+       "e028d1f797d4f0083bb6a8d13c76d16707259255",
+       []
+      ],
+      "multicol-table-cell-vertical-align-ref.xht": [
+       "6d20530b73bb6276fba3d2ac5c740aca1100e0b2",
+       []
+      ]
      }
     },
     "css-namespaces": {
@@ -260418,6 +261035,10 @@
        "fd8a76b2f8e67a901500dd0ae26074f2404518a0",
        []
       ],
+      "webkit-line-clamp-block-in-inline-001-ref.html": [
+       "79f2e409109d72a76e12374220bd423aba16f4eb",
+       []
+      ],
       "webkit-line-clamp-dynamic-001-ref.html": [
        "21458953df99e0be27d2143c182a5829438ede5d",
        []
@@ -260475,6 +261096,14 @@
       "0f0aa2cf146ceccfed0d0fa426813e4ab0ad2c5e",
       []
      ],
+     "page-rule-declarations-003-expected.txt": [
+      "47dc2b253ab7d606a2899440755f5ca7e330e5eb",
+      []
+     ],
+     "page-rule-declarations-004-expected.txt": [
+      "e65d05ca7bd4fad54d39be845b0fb8150b6b750f",
+      []
+     ],
      "parsing": {
       "page-orientation-invalid.tentative-expected.txt": [
        "d5bc3cab32c7efa9b487bf5f8e78b5e89159d49b",
@@ -261484,7 +262113,7 @@
       []
      ],
      "idlharness-expected.txt": [
-      "46168b29be8578ef30c6b2b2cc71e88883ab6d75",
+      "f76169b892e8b8f5dc8d8c2ce5a1ee1992fe6432",
       []
      ],
      "marker-and-other-pseudo-elements-ref.html": [
@@ -261636,7 +262265,7 @@
       []
      ],
      "marker-line-height-ref.html": [
-      "64b0d41a38988730b15522a4be57f0f6621f6d18",
+      "a32fb812f107682996dec567eda22be23100b3d2",
       []
      ],
      "marker-list-style-position-ref-001.html": [
@@ -261693,7 +262322,7 @@
      ],
      "parsing": {
       "marker-supported-properties-expected.txt": [
-       "3b1189ccdf31f07452875606ebf38a736363409b",
+       "6f5035319016f71d05a0c053eeb737b08726f33b",
        []
       ],
       "marker-supported-properties-in-animation-expected.txt": [
@@ -267307,6 +267936,26 @@
         "b65a8fe75479c0119a8ecc156b9a5d5f318d66d0",
         []
        ],
+       "trailing-space-and-text-alignment-001-ref.html": [
+        "3dbb85a711f2d6af13d5e21b0028922921f40592",
+        []
+       ],
+       "trailing-space-and-text-alignment-002-ref.html": [
+        "a0811e61a11c77a3582053033fd6d93210a0e79b",
+        []
+       ],
+       "trailing-space-and-text-alignment-rtl-001-ref.html": [
+        "3de3f475b03e97b884c857c576cc4b1fbdd2acb1",
+        []
+       ],
+       "trailing-space-and-text-alignment-rtl-002-ref.html": [
+        "8b29f31dbf8cdc31bc90c2231af8b67f02ccf0b7",
+        []
+       ],
+       "trailing-space-and-text-alignment-rtl-005-ref.html": [
+        "e93ee65281fb0867f2d114b4d29de51dc1b9b0b8",
+        []
+       ],
        "trailing-space-rtl-001-ref.html": [
         "f3f25235911e7a317377a57d66d68318aaf2eaf6",
         []
@@ -272398,6 +273047,10 @@
      "viewport-units-001-print-ref.html": [
       "bc914522c7fcf556c69ba56d2d0ba792d7e92b89",
       []
+     ],
+     "viewport-units-parsing-expected.txt": [
+      "3984c7c987664bb5f2c5a06ced4618d72f89c24d",
+      []
      ]
     },
     "css-variables": {
@@ -277592,7 +278245,7 @@
       []
      ],
      "chrome.md": [
-      "808639e927ab52d66c4e3c68c56457558e2d0694",
+      "0c07b6fef9e68d3f905fe710d39be06c3960a064",
       []
      ],
      "chrome_android.md": [
@@ -278030,16 +278683,6 @@
      "6fd5b12664da091fd9ee773b821ad72ee704ee8f",
      []
     ],
-    "abort": {
-     "event.any-expected.txt": [
-      "e5730d03ed1eff8458351b1d9c1b5440d25fd134",
-      []
-     ],
-     "event.any.worker-expected.txt": [
-      "e5730d03ed1eff8458351b1d9c1b5440d25fd134",
-      []
-     ]
-    },
     "collections": {
      "HTMLCollection-as-prototype-expected.txt": [
       "f36f3bf1426c59572dc577805db9d9a3503ffd29",
@@ -278067,6 +278710,10 @@
       "dfa29a887db747cc5f1d34aa120b8860fa39a552",
       []
      ],
+     "EventListener-handleEvent-cross-realm-expected.txt": [
+      "bbda97de800889e3add4560d075bc140db95a8ed",
+      []
+     ],
      "EventListener-handleEvent-expected.txt": [
       "bb076e74f458f8aa89855d42ef845b55b2ccb354",
       []
@@ -278096,6 +278743,10 @@
       []
      ],
      "resources": {
+      "empty-document.html": [
+       "b9cd130a07f77ee1a54f4bf54df54dc126fec1ee",
+       []
+      ],
       "event-global-extra-frame.html": [
        "241dda8b66f8c8fe128e736bcb073479aee634a9",
        []
@@ -278128,8 +278779,12 @@
      "e31ca4f3c12693d4faa4a336b46edb3df545a09f",
      []
     ],
+    "idlharness-shadowrealm.window-expected.txt": [
+     "2db45e1a047c174b9c072cddd88d6f749c59eb7c",
+     []
+    ],
     "idlharness.window_exclude=Node-expected.txt": [
-     "12920ef81a8107ddc637b89bf590c64e5a154d74",
+     "d224b4cba61ecf3402b62cfb3b0cb0d054a781fd",
      []
     ],
     "lists": {
@@ -278523,26 +279178,18 @@
      []
     ],
     "traversal": {
-     "TreeWalker-acceptNode-filter-cross-realm-expected.txt": [
-      "7948b1bf20723649a696ddc36b6a885c1f3a62a7",
-      []
-     ],
-     "TreeWalker-acceptNode-filter-cross-realm-null-browsing-context-expected.txt": [
-      "e9ed6f07909cb4a9ba25de88d5426744236e701f",
-      []
-     ],
      "support": {
       "TreeWalker-acceptNode-filter-cross-realm-null-browsing-context-subframe.html": [
        "f5e393d0f081728aba806a7155fb8139796b089d",
        []
       ],
-      "TreeWalker-acceptNode-filter-cross-realm-subframe.html": [
-       "0c8bda14c0faf2b81fbb7556f9c12a0631bba7ec",
-       []
-      ],
       "assert-node.js": [
        "0d5d8ad74fce7dcd4d60a1a11525c5134407f8ba",
        []
+      ],
+      "empty-document.html": [
+       "b9cd130a07f77ee1a54f4bf54df54dc126fec1ee",
+       []
       ]
      },
      "unfinished": {
@@ -278688,6 +279335,10 @@
      "0805bd682b48461588250a22018a6bd90990d002",
      []
     ],
+    "resolver-callback-interface-cross-realm-expected.txt": [
+     "1e681034783394d9c33b46355bec25169e0dd234",
+     []
+    ],
     "resolver-callback-interface-expected.txt": [
      "a3e74bd621d3cbd370e1c657bc545e0b32474a60",
      []
@@ -278697,8 +279348,12 @@
      []
     ],
     "resources": {
+     "empty-document.html": [
+      "b9cd130a07f77ee1a54f4bf54df54dc126fec1ee",
+      []
+     ],
      "invalid_namespace_test.js": [
-      "b985261551e0b7526c205ec85667c4948ed8b681",
+      "8b934eff4e8d14d41ec30caecfcd4a7dcad305bc",
       []
      ]
     },
@@ -278754,7 +279409,7 @@
       []
      ],
      "delete.js": [
-      "3c3d1ef703b08bf79c44e3726b75d6a50ebb703c",
+      "edfdcdb393515a9d2849955fc63884443030f7cb",
       []
      ],
      "fontname.js": [
@@ -278774,7 +279429,7 @@
       []
      ],
      "forwarddelete.js": [
-      "52152327f2154f69763ce434c52ba18f95aceefc",
+      "2f96ef642346490133f19b635e3ad82a06224015",
       []
      ],
      "hilitecolor.js": [
@@ -279056,7 +279711,7 @@
       []
      ],
      "delete_7001-last-expected.txt": [
-      "a05da9c7ef446ee33011f53df9df721804308fbd",
+      "881a294fdd3107dab0dfffa3640a0bcf69e5e896",
       []
      ],
      "fontname-expected.txt": [
@@ -280950,6 +281605,10 @@
      "9e3a2546556a896943d73233cb647edca73d9dd4",
      []
     ],
+    "idlharness.any-expected.txt": [
+     "c4137e86e3b4245e560d978087e3dfae56422500",
+     []
+    ],
     "resources": {
      "crossiframe-childframe.html": [
       "6a8bc6b64240636dbc576aaa15b9c86b799dae8e",
@@ -281515,6 +282174,22 @@
       "general.any.worker-expected.txt": [
        "7a1b5a41a93f460ec4b77ac7cab653906ce133be",
        []
+      ],
+      "request.any-expected.txt": [
+       "b5c62553e1c85e15a48365a5aef586cbc34cb9f3",
+       []
+      ],
+      "request.any.serviceworker-expected.txt": [
+       "b5c62553e1c85e15a48365a5aef586cbc34cb9f3",
+       []
+      ],
+      "request.any.sharedworker-expected.txt": [
+       "b5c62553e1c85e15a48365a5aef586cbc34cb9f3",
+       []
+      ],
+      "request.any.worker-expected.txt": [
+       "b5c62553e1c85e15a48365a5aef586cbc34cb9f3",
+       []
       ]
      },
      "basic": {
@@ -282250,7 +282925,7 @@
       []
      ],
      "README.md": [
-      "f131b5a1da986a2041aa526ab2dd449733e3dc4c",
+      "f29562b0606143f0be21765715dab06d44269407",
       []
      ],
      "img-html-correctly-labeled.sub-ref.html": [
@@ -282414,19 +283089,19 @@
       []
      ],
      "processing.any-expected.txt": [
-      "cfab79c6b3c7ecfefeba9e4541a3a5d81a8e2723",
+      "3ac9e12bcce1bc06631eee1bee1e271648a439eb",
       []
      ],
      "processing.any.serviceworker-expected.txt": [
-      "cfab79c6b3c7ecfefeba9e4541a3a5d81a8e2723",
+      "3ac9e12bcce1bc06631eee1bee1e271648a439eb",
       []
      ],
      "processing.any.sharedworker-expected.txt": [
-      "cfab79c6b3c7ecfefeba9e4541a3a5d81a8e2723",
+      "3ac9e12bcce1bc06631eee1bee1e271648a439eb",
       []
      ],
      "processing.any.worker-expected.txt": [
-      "cfab79c6b3c7ecfefeba9e4541a3a5d81a8e2723",
+      "3ac9e12bcce1bc06631eee1bee1e271648a439eb",
       []
      ],
      "resources": {
@@ -282435,7 +283110,7 @@
        []
       ],
       "data-urls.json": [
-       "be1d1e74cf5f5105619a574c3caa7f2c0a39e7f6",
+       "f318d1f3e547d3d5b98ec737c231178f796166db",
        []
       ]
      }
@@ -282875,41 +283550,17 @@
       "6c834a89c8d481231d211249ff5451aaa9164f5b",
       []
      ],
-     "shared-worker-fetch.https.window-expected.txt": [
-      "31ae173f70264676caf5d4173fd308f9f20acb1b",
-      []
-     ],
-     "shared-worker-fetch.window-expected.txt": [
-      "cd62872e656ae0b85bc3257d8e1b789e087b9935",
-      []
-     ],
-     "shared-worker.https.window-expected.txt": [
-      "c7cd66da3743edf09e60f658824fea067e4da015",
-      []
-     ],
-     "shared-worker.window-expected.txt": [
-      "8718ffde7bc70a2802ec04ecd5c1e3b42e0dca32",
-      []
-     ],
      "websocket.window-expected.txt": [
       "11e2dcac903cb8fb7f68563036c4b8a4a9c1a9e7",
       []
      ],
      "worker-fetch.https.window-expected.txt": [
-      "0b54e1fb1a79866ca2e731de446b21f1d79e3a5d",
+      "4ea413e243878208fb41d891d71645b433c64018",
       []
      ],
      "worker-fetch.window-expected.txt": [
       "cd62872e656ae0b85bc3257d8e1b789e087b9935",
       []
-     ],
-     "worker.https.window-expected.txt": [
-      "c7cd66da3743edf09e60f658824fea067e4da015",
-      []
-     ],
-     "worker.window-expected.txt": [
-      "8718ffde7bc70a2802ec04ecd5c1e3b42e0dca32",
-      []
      ]
     },
     "range": {
@@ -283506,11 +284157,11 @@
       []
      ],
      "window-tests-blob.js": [
-      "e21733ce7f1afc8410899d1b5e58d56ec642c43c",
+      "3279849c5e285fc756f2f0620f09e64121d1a24c",
       []
      ],
      "window-tests-enumeration.js": [
-      "838e5c34346286545fe7aa5cd7faf8bcb2310fe8",
+      "be906f6ed3355784d3848891685fb2bc27089920",
       []
      ]
     }
@@ -284549,7 +285200,7 @@
      []
     ],
     "generic-sensor-iframe-tests.sub.js": [
-     "11c9f50f4ab6f9ef8cb6570f9e24c85f655fdb8b",
+     "1d1a012380f6384fecfd5377b838bb71744a52ae",
      []
     ],
     "generic-sensor-tests.js": [
@@ -284637,7 +285288,7 @@
      []
     ],
     "GeolocationSensor-iframe-access.https-expected.txt": [
-     "821f00d1a8ce2590fd33aa40c25e56e8cbae9df3",
+     "9adf77affdd3d01c0af9278c1362aaccf3810210",
      []
     ],
     "GeolocationSensor.https-expected.txt": [
@@ -284785,6 +285436,14 @@
         "broadcast-channel-expected.txt": [
          "307bd14234d626c558b4070b1f9225ae6b722981",
          []
+        ],
+        "inflight-fetch-expected.txt": [
+         "187f0a83c26d1787dd1bbbf854f1a0159e5c4d38",
+         []
+        ],
+        "inflight-fetch-redirects-expected.txt": [
+         "7a97c17c52f2b642f8a48cded54e5e386705beb0",
+         []
         ]
        },
        "events-expected.txt": [
@@ -284801,10 +285460,22 @@
          []
         ],
         "helper.sub.js": [
-         "b2087d9de507ede95c59a3862696603ef1e20e41",
+         "731487b71820c239fea3c39da2673cae02996fc9",
+         []
+        ],
+        "inflight-fetch-helper.js": [
+         "7832003b76b9518d5f3588bb5e9f6e0dbd8cea07",
+         []
+        ],
+        "slow.py": [
+         "01bb3309b103d5bba772bdbf1d0d0b8bc28c8e99",
          []
         ]
-       }
+       },
+       "timers-expected.txt": [
+        "e9f695c2140906f4ba4c7d16fe3fe03a23eb462d",
+        []
+       ]
       },
       "history-traversal": {
        "001-1.html": [
@@ -288522,10 +289193,6 @@
          "133807fb285da0e897d84b688da39281d5b67bfc",
          []
         ],
-        "drawing-rectangles-to-the-canvas.yaml": [
-         "7b042d854fefdedd4691609c0c322b6b0730062b",
-         []
-        ],
         "drawing-text-to-the-canvas.yaml": [
          "686bd0763f214cff22be0fa5bd7a59a5a057fcb3",
          []
@@ -288592,10 +289259,6 @@
          "f2be7b8e07bd648c8fb690750fb894a17cbcc81e",
          []
         ],
-        "drawing-rectangles-to-the-canvas.yaml": [
-         "4903aa2f42818beb0c8f938bb91cd85e4e999df2",
-         []
-        ],
         "fill-and-stroke-styles.yaml": [
          "7a57a4730e096c728010b754c503c753a6972326",
          []
@@ -288654,6 +289317,10 @@
        "conformance_requirements.yaml": [
         "89091d6e7c760c192650dbd8994304ceb4586287",
         []
+       ],
+       "drawing-rectangles-to-the-canvas.yaml": [
+        "129fe95530a81b5b9fc5da74d19ba273e5dc28ca",
+        []
        ]
       }
      }
@@ -288680,13 +289347,17 @@
        "377c7296a781adb8ce5792cda50a4ded28472339",
        []
       ],
+      "fenced-frame.tentative.https.window-expected.txt": [
+       "dc538e12907885d23b2fa5b3a6f9c6364b88fdc4",
+       []
+      ],
       "require-corp-embed-anonymous-iframe.tentative.https.window.js.headers": [
        "6604450991a122e3e241e40b1b9e0516c525389d",
        []
       ],
       "resources": {
        "common.js": [
-        "e11e2307defd6e4bba7006e2add47e7aad965a6f",
+        "1378f3e9a75ff7b0587887792e626cc92772f4e6",
         []
        ],
        "serviceworker-partitioning-helper.js": [
@@ -288720,6 +289391,14 @@
        "86654525dda61a31ed7a9617ad449309b8a55366",
        []
       ],
+      "cache-storage.tentative.https.window_dedicated_worker-expected.txt": [
+       "cfb3376feff4285356d70408c109d44938f656c1",
+       []
+      ],
+      "dedicated-worker.tentative.https.window-expected.txt": [
+       "7ecbf9ce7d5e1358c846788eb555627ca00c4833",
+       []
+      ],
       "resources": {
        "common.js": [
         "ce21c766f6c30fcb87147611ae1a6af9aa54ce0e",
@@ -288736,7 +289415,7 @@
       ]
      },
      "cross-origin-isolated-permission.https-expected.txt": [
-      "166ed23b4c3be77a825df7f24afa2d53b9b3a8ed",
+      "9ba1e94eead1a6e1e5aa8fc45751951a2a98afca",
       []
      ],
      "cross-origin-isolated-permission.https.html.headers": [
@@ -288747,6 +289426,14 @@
       "6604450991a122e3e241e40b1b9e0516c525389d",
       []
      ],
+     "dedicated-worker-cache-storage.https-expected.txt": [
+      "88a4a82baccbde282990faed56ab17e438fa51cf",
+      []
+     ],
+     "dedicated-worker.https-expected.txt": [
+      "883c29a04dfcd6030c7bf83b60deb63e970cd110",
+      []
+     ],
      "javascript.https.html.headers": [
       "6604450991a122e3e241e40b1b9e0516c525389d",
       []
@@ -289700,11 +290387,11 @@
       []
      ],
      "elements-metadata.js": [
-      "8af6a6a67c088c16a46c2a70b3f6b255d66281be",
+      "49d7bb25adea968126ea94bb51486c698e702209",
       []
      ],
      "elements-misc.js": [
-      "b747ac6e5966cd7d8bc75a08463b83e3064b48c8",
+      "1a74c54797f7b73120bb08ce5913e26b1b99a82e",
       []
      ],
      "elements-obsolete.js": [
@@ -289736,7 +290423,7 @@
       []
      ],
      "idlharness.worker-expected.txt": [
-      "9609f524ee724b2aaf8c2847fbf9c59ca981948d",
+      "0e04c9174c346bb33240b482245fab61e1eab32c",
       []
      ],
      "new-harness.js": [
@@ -289752,11 +290439,7 @@
       []
      ],
      "reflection-metadata-expected.txt": [
-      "bfd647b43547c65a956c1dcb85ab8b4a8f77ae51",
-      []
-     ],
-     "reflection-misc-expected.txt": [
-      "13c04358aac2ed10ea424f3be12dcb0a06c25b30",
+      "a8e83c42d156ae78c42eec32ca5a2c66ee7f8038",
       []
      ],
      "reflection-original.html": [
@@ -293246,6 +293929,10 @@
          "163d1356ed2ff327dea9d646c352a70d57bfb425",
          []
         ],
+        "lone-surrogates.sub_encoding=windows-1252-expected.txt": [
+         "a581aae810a039486dfca73921405c2d63d35025",
+         []
+        ],
         "resources": {
          "blank.py": [
           "bbd269d17036bdb8cf9a1501c44168618a145f5d",
@@ -294241,6 +294928,10 @@
         "31ba23a5cf86f161b1204ea3f4c9fef4585af909",
         []
        ],
+       "select-intrinsic-option-font-size-ref.html": [
+        "8b1b422176f8f7dbb080910b71b0b3ae89f876cd",
+        []
+       ],
        "select-intrinsic-text-transform-ref.html": [
         "18e272ba10d3c319c06cdb669e5f7a535946d024",
         []
@@ -296042,6 +296733,10 @@
         []
        ]
       },
+      "beforeinput.tentative-expected.txt": [
+       "faf65093abc756295cc374b2e3d27c1423ea12ff",
+       []
+      ],
       "constraints": {
        "form-validation-validity-patternMismatch-expected.txt": [
         "df1338f90958d2f67e2301bc52fabb634221e689",
@@ -296057,7 +296752,7 @@
        ],
        "support": {
         "validator.js": [
-         "48e56488e283960e7aa890c50a280842fbb6850b",
+         "aa43b3a2f6afd63b745bdb78fefc1b086628e5ef",
          []
         ]
        }
@@ -296569,6 +297264,10 @@
         "38b628c3092ab223010db32373e786787e4355b0",
         []
        ],
+       "modal-dialog-in-visibility-hidden-expected.txt": [
+        "52d249ce7baa8cfb7ef71544459a70aad9c1af9d",
+        []
+       ],
        "modal-dialog-sibling-ref.html": [
         "38b628c3092ab223010db32373e786787e4355b0",
         []
@@ -301493,7 +302192,7 @@
      []
     ],
     "OES_draw_buffers_indexed.idl": [
-     "25696f12fca77799ddd803483de22c251c75eb82",
+     "bf1932c665353800f8a93ec43769b86aa05fc26a",
      []
     ],
     "OES_element_index_uint.idl": [
@@ -301621,13 +302320,17 @@
      []
     ],
     "app-history.idl": [
-     "b87bb582e67e9fbd521a36db433d114944164aa2",
+     "f5f1b7e4937dd53838f64a0681db652fa4300bf3",
      []
     ],
     "audio-output.idl": [
      "80ceb225308a057d99ce39f575ebcf8eb40ab5fb",
      []
     ],
+    "autoplay.idl": [
+     "f2be5bb3789b123b33a07a8e237a3c48a7ae1cc4",
+     []
+    ],
     "background-fetch.idl": [
      "993bd8bc2fd8db2a52fcc4b703e6b0801ab76ff8",
      []
@@ -301665,7 +302368,7 @@
      []
     ],
     "compute-pressure.idl": [
-     "8ea37bfbb9c47511d6aa8d34484f97527ec9ea29",
+     "0cf880b4503fede8f40b1c656834d806cd906d5e",
      []
     ],
     "console.idl": [
@@ -301673,7 +302376,7 @@
      []
     ],
     "contact-api.idl": [
-     "7f67a5d19a84087182469b6f06887a2dafc37073",
+     "d7f2ba5d959ee316f8045697177c0b052302107a",
      []
     ],
     "content-index.idl": [
@@ -301693,7 +302396,7 @@
      []
     ],
     "credential-management.idl": [
-     "a07aa0b4447cd3119dc5bd22c5c3d16679e3afe5",
+     "bf1adbaffcbe7e6221f8629724e29ac2cf75aa19",
      []
     ],
     "csp-embedded-enforcement.idl": [
@@ -301716,8 +302419,8 @@
      "8185170943281bd1ceb8bb8fd3cd701a60fa290c",
      []
     ],
-    "css-cascade-5.idl": [
-     "4166ae6b9ba780c8cb4108eb98da0647fbef0d1d",
+    "css-cascade.idl": [
+     "9011dc7fd9e2a3f835e6d6ff565d9854db82e96f",
      []
     ],
     "css-conditional.idl": [
@@ -301741,7 +302444,7 @@
      []
     ],
     "css-highlight-api.idl": [
-     "56db8c35ac099bbfc79fb40b88a3ba14ab700f43",
+     "f3c6b2e9d21a525e80461a22e511c672ce05ba87",
      []
     ],
     "css-images-4.idl": [
@@ -301777,7 +302480,7 @@
      []
     ],
     "css-pseudo.idl": [
-     "2c90ff2b3174eea5d1245214b79ac79ac2479ee5",
+     "dbe4c5461f6ae2199968bb77c81d32570f55f1c7",
      []
     ],
     "css-regions.idl": [
@@ -301797,7 +302500,7 @@
      []
     ],
     "css-typed-om.idl": [
-     "b3942e6bcf55556978fc244861936a5c21252036",
+     "3a0a6bd064ddf65930c7170c38f3f9b40e694879",
      []
     ],
     "cssom-view.idl": [
@@ -301829,7 +302532,11 @@
      []
     ],
     "dom.idl": [
-     "d3255b45e01b302347ab5a3d695963871e1eedba",
+     "762e7a5c3ef4c71237272c4451bc65aeb817efde",
+     []
+    ],
+    "edit-context.idl": [
+     "f5e60bd0d02c45ca8f3145c729edcfd0b240b61e",
      []
     ],
     "element-timing.idl": [
@@ -301849,7 +302556,7 @@
      []
     ],
     "event-timing.idl": [
-     "98e8d920fca47b6d0daf87ce88acce442c9da9ab",
+     "329570e44314278526ecf949ebc1a98e4d4dd840",
      []
     ],
     "eyedropper-api.idl": [
@@ -301892,14 +302599,14 @@
      "157072f6341821aba5403be50ddd5355dbb940d8",
      []
     ],
-    "geolocation-API.idl": [
-     "4b971f097babf71b9ef1b5091d1a8777b4d717ea",
-     []
-    ],
     "geolocation-sensor.idl": [
      "e1d676205fff369c5cdc656f8563e4bb1fca9946",
      []
     ],
+    "geolocation.idl": [
+     "4b971f097babf71b9ef1b5091d1a8777b4d717ea",
+     []
+    ],
     "geometry.idl": [
      "a1159c0d77a3f6f9c302d4c70c185a4130e2b383",
      []
@@ -301921,7 +302628,7 @@
      []
     ],
     "html.idl": [
-     "2b5efa90ba2c3af6df84735bee4c45e1be5b66f8",
+     "2eaf5d09e2c882588a3069b51fffa88802e4ed61",
      []
     ],
     "idle-detection.idl": [
@@ -301980,12 +302687,8 @@
      "4fb1b70398e7486a0596574b3ef76d361806e0f3",
      []
     ],
-    "lighting-estimation.idl": [
-     "35aa1d746a7466e80a9de9d366935b831da8cc7f",
-     []
-    ],
     "local-font-access.idl": [
-     "577cd3621ac327c00d55a346942138c18711fa2a",
+     "e37b2c7d56f028c3bf9fe32352382697f2410f05",
      []
     ],
     "longtasks.idl": [
@@ -301996,6 +302699,10 @@
      "45ba9edcfe570c5d1828d089409e8220788c7e94",
      []
     ],
+    "manifest-incubations.idl": [
+     "bab3998dedd1353ba95b824a36500f1ab9a69987",
+     []
+    ],
     "mathml-core.idl": [
      "3989288b3bd14de69f0d9ce9c188825b06836697",
      []
@@ -302025,7 +302732,11 @@
      []
     ],
     "mediacapture-streams.idl": [
-     "7d51a2af8077c4430423701dc5c58fb8dd9847d8",
+     "33511eb24153ab4ac4dd213b932219244ea98d21",
+     []
+    ],
+    "mediacapture-transform.idl": [
+     "5b2c8fa67a6b130d1fe99f962ff85c5cf7a7bc3d",
      []
     ],
     "mediasession.idl": [
@@ -302109,7 +302820,7 @@
      []
     ],
     "permissions.idl": [
-     "3112ef6d20b9ab6f71846a9c8e620f67c80f8684",
+     "3a0f159c2b2e330c6d8af9e74952d10879008240",
      []
     ],
     "picture-in-picture.idl": [
@@ -302136,6 +302847,10 @@
      "4f1e4bee835a23c5b7bcf54b5b05f4ded2b08023",
      []
     ],
+    "priority-hints.idl": [
+     "835b0180d30655ce85298e42442d676bf6bc3f9a",
+     []
+    ],
     "private-click-measurement.idl": [
      "3bed7ccf991f6b8cd4e9a5a237275c4ff5fc6f1f",
      []
@@ -302173,7 +302888,7 @@
      []
     ],
     "sanitizer-api.idl": [
-     "b98da2a2c671e2e86c113d3ebe904470b82e60ad",
+     "8268384affc8c23daadadb79959d4b953c563f1b",
      []
     ],
     "sanitizer-api.tentative.idl": [
@@ -302209,7 +302924,7 @@
      []
     ],
     "secure-payment-confirmation.idl": [
-     "0a4416ef4b20e1577484a875c511f7a41a936ff2",
+     "1522bff76eac485d8046cbad2634fdfd9fda5e06",
      []
     ],
     "selection-api.idl": [
@@ -302249,7 +302964,7 @@
      []
     ],
     "streams.idl": [
-     "2ebe5b7491f3757e5df3e3f543fdef48ea296755",
+     "f7084dd60610420628f6b3468bf071b66e93dc14",
      []
     ],
     "svg-animations.idl": [
@@ -302317,7 +303032,7 @@
      []
     ],
     "wasm-js-api.idl": [
-     "b56c8cf0c7943e746c64b0acab5ea8a2bbbdd75e",
+     "141af90fd2d9d9432747277fc7d38ab6f53ea1f5",
      []
     ],
     "wasm-web-api.idl": [
@@ -302337,11 +303052,11 @@
      []
     ],
     "web-locks.idl": [
-     "a0319a00fd208a8bdeecd9700e00fd0d67549a60",
+     "d79e404b983fb4388028de8b269ee16b652fed0f",
      []
     ],
     "web-nfc.idl": [
-     "3b8be7fd81cf7ca5e8f96c5a36abeb7914614b91",
+     "ff042b044e1da41ee42c07361a1f814684049f4a",
      []
     ],
     "web-otp.idl": [
@@ -302357,7 +303072,7 @@
      []
     ],
     "webauthn.idl": [
-     "92143205d672f08471370498623d71202a6cee84",
+     "2b897608ab4b1118bdaf90ba716b88b2f1b1eaa4",
      []
     ],
     "webcodecs.idl": [
@@ -302377,11 +303092,11 @@
      []
     ],
     "webgpu.idl": [
-     "c23ba7878172556f0db75a45f88bc135489cad1e",
+     "6ded86e1d6389ab9f864272549d7cbf662043035",
      []
     ],
     "webhid.idl": [
-     "d4ce439785d866a9667d2a5e716d139d355a4d12",
+     "997d82c3986e5e4b908e032475723e8b9348d459",
      []
     ],
     "webidl.idl": [
@@ -302421,11 +303136,11 @@
      []
     ],
     "webrtc.idl": [
-     "ff0a4a9ec5ccfc153dbafa2d2c6fdab7582eb66e",
+     "aed8fbbedfe5d236a9d85fbfa75fa6c07b51695b",
      []
     ],
     "webtransport.idl": [
-     "f098e47d179b4e02ed3f6c0bde20832c29183acd",
+     "95ab9e05d498c9e5bf244e173bf8cd106a0d8c7f",
      []
     ],
     "webusb.idl": [
@@ -302464,6 +303179,10 @@
      "fa4fb71c9decd64054669249353a16b3476aae56",
      []
     ],
+    "webxr-lighting-estimation.idl": [
+     "35aa1d746a7466e80a9de9d366935b831da8cc7f",
+     []
+    ],
     "webxr.idl": [
      "004f104c8e23c5200e8ef3d63f6ee85b6ec39365",
      []
@@ -302473,7 +303192,7 @@
      []
     ],
     "window-controls-overlay.idl": [
-     "de5e67419743fef952bc6e1df09ab77f03c18386",
+     "051978d693e3aa5213096e571be66d10cc8d8199",
      []
     ],
     "xhr.idl": [
@@ -302782,7 +303501,7 @@
     ]
    },
    "lint.ignore": [
-    "b9973747dc6ca675b335a0d01350d214c71503ca",
+    "797e2b8c388fa9291547431b1545618dd601a497",
     []
    ],
    "loading": {
@@ -302879,7 +303598,7 @@
      []
     ],
     "Magnetometer-iframe-access.https-expected.txt": [
-     "35f075392c022833c9a0b2d628696b8933ea3d02",
+     "6b161d3577baf1015532ed8f216978a8dbe662a8",
      []
     ],
     "Magnetometer.https-expected.txt": [
@@ -304390,17 +305109,17 @@
      "563fa6720ba3a89d6ad8add86cd903465fe456f2",
      []
     ],
-    "MediaStreamTrackGenerator-in-worker.https-expected.txt": [
-     "11ecc9430dc08d3eceb70b8bacc693b955564dc2",
-     []
-    ],
-    "MediaStreamTrackGenerator-pipes-data-in-worker.https-expected.txt": [
-     "df92162d3842b7f0e814d46fae1921a9195442c6",
-     []
-    ],
     "MediaStreamTrackProcessor-worker.js": [
      "51eaef80a90a6e24fce8cad4fee03e05548e4517",
      []
+    ],
+    "dedicated-worker.js": [
+     "0dbcc32d0b271f9772ee5664ba9f5fee35e95a41",
+     []
+    ],
+    "shared-worker.js": [
+     "61ff67bcff03099cbf93fbb594e9b188d85a9f11",
+     []
     ]
    },
    "mediacapture-record": {
@@ -304471,6 +305190,12 @@
      ]
     }
    },
+   "mediacapture-region": {
+    "MediaDevices-produceCropId.https.html": [
+     "682caad7e7de5e79bae3a5b8d2b0da1bdfbb498f",
+     []
+    ]
+   },
    "mediacapture-streams": {
     "DIR_METADATA": [
      "914b263a9ad0c34d7a2d75c935a1addc64e60045",
@@ -304516,10 +305241,6 @@
      "973e380f7808eec4d031e62130107ec97297c6f5",
      []
     ],
-    "MediaDevices-produceCropId.https.html": [
-     "682caad7e7de5e79bae3a5b8d2b0da1bdfbb498f",
-     []
-    ],
     "MediaStream-MediaElement-firstframe.https-expected.txt": [
      "19c548627bb73155b5c0667321a7d939fcd54163",
      []
@@ -304545,7 +305266,7 @@
      []
     ],
     "idlharness.https.window-expected.txt": [
-     "35a2f4c8c4e26a49ef72cdefc7e9f826f4dbe7fc",
+     "07cd17de93769ec3e2a05e2e0d0f5be3debeaced",
      []
     ],
     "iframe-enumerate-cleared.html": [
@@ -308998,6 +309719,10 @@
      "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
      []
     ],
+    "iframe-sequence-of-events-expected.txt": [
+     "4999c6179224dc8b36a017406fba85efae225e5d",
+     []
+    ],
     "initiator-type": {
      "resources": {
       "initiator-type-test.js": [
@@ -309175,6 +309900,10 @@
       "4a2f609aa469f14d7efe64baaeb739efdb2fdc75",
       []
      ],
+     "iframe-with-delay.sub.html": [
+      "fe50aa7e471debe9c0fa9483dd9ad4353d4456ac",
+      []
+     ],
      "iframe_TAO_match_origin.html": [
       "cf68aade7954e609087d34f21e437c285eb73a58",
       []
@@ -309183,6 +309912,10 @@
       "44d09675d38e26a9c69de4ed9133667d8dc5c5ef",
       []
      ],
+     "invalid.jpg": [
+      "81c545efebe5f57d4cab2ba9ec294c4b0cadf672",
+      []
+     ],
      "manifest.json": [
       "e107c044d5d8a8a484652917b83902d5e19ed987",
       []
@@ -309348,7 +310081,7 @@
     ],
     "chromium": {
      "README.md": [
-      "3813f6de5d7db8a5cbabf89b7642d8ac5fa2eb23",
+      "be090b332fc41b5f5b8fe45b4f5c156a5d26eaf3",
       []
      ],
      "contacts_manager_mock.js": [
@@ -309363,6 +310096,10 @@
       "263f6512f09a90220940975b9474fecabf2837c7",
       []
      ],
+     "fake-hid.js": [
+      "89318b57a990345cd128677f1ee3cd0161463526",
+      []
+     ],
      "fake-serial.js": [
       "1a0f4b521787332a65179af2db675b913f6278e7",
       []
@@ -309651,6 +310388,12 @@
      []
     ]
    },
+   "screen-details": {
+    "META.yml": [
+     "abfee89ffbdd29ccd2741bbd3d4a314387025509",
+     []
+    ]
+   },
    "screen-orientation": {
     "DIR_METADATA": [
      "726cc0038d469c7904537d0d8c92f66229fa34e4",
@@ -309731,12 +310474,6 @@
      []
     ]
    },
-   "screen_enumeration": {
-    "META.yml": [
-     "abfee89ffbdd29ccd2741bbd3d4a314387025509",
-     []
-    ]
-   },
    "scroll-animations": {
     "META.yml": [
      "c7f0e4903b5ad46b411f0f0741112af80661cfc7",
@@ -311205,18 +311942,30 @@
       "9aa4a28996b56e4303a741353f626591b56802af",
       []
      ],
+     "client-url-of-blob-url-worker.https-expected.txt": [
+      "bc07e042a2626d0bf8c80179df67cfd90d4a5463",
+      []
+     ],
+     "clients-get-client-types.https-expected.txt": [
+      "58bae3013f3e9b54f93bad719971ffcaf2a09b26",
+      []
+     ],
+     "clients-matchall-blob-url-worker.https-expected.txt": [
+      "0065aa4ad95bafe37955a86b9ba9397d760dfa4c",
+      []
+     ],
      "clients-matchall-client-types.https-expected.txt": [
       "a5702d0326367c8a1552bbd99d98bb3d0c12cb7c",
       []
      ],
-     "clients-matchall-frozen.https-expected.txt": [
-      "05dc9954cc0bb0e41ffdc71435d083c412669532",
-      []
-     ],
      "clients-matchall-order.https-expected.txt": [
       "78737fe4f60050c6e8cd4762d776fa8518e91225",
       []
      ],
+     "dedicated-worker-service-worker-interception.https-expected.txt": [
+      "e6e6986dc00a2077b683c28c4b9d639ef0f2d949",
+      []
+     ],
      "fetch-canvas-tainting-video-with-range-request.https-expected.txt": [
       "eb2733136fe9f8fbdb385fff6da47c50a73f9148",
       []
@@ -311278,7 +312027,7 @@
       []
      ],
      "local-url-inherit-controller.https-expected.txt": [
-      "b3b46912445464bbcd50a77d995dae0adfb3328e",
+      "5bbd21b5890f94e6eff4c5cd8f4e6300fa79c0e1",
       []
      ],
      "multi-globals": {
@@ -312970,11 +313719,11 @@
       []
      ],
      "worker-interception-redirect.https-expected.txt": [
-      "06706c050fa5c7504d224c44f353b7b19ae3f5ea",
+      "6ebfc05e07493232ef0f3d8a9f06e2605b54c558",
       []
      ],
      "worker-interception.https-expected.txt": [
-      "41d45df239565395ab8ce55043002800aa21c35f",
+      "dba3694a6f928b5d0802aabda02604ae19797663",
       []
      ],
      "xhr-content-length.https.window-expected.txt": [
@@ -313444,18 +314193,10 @@
        "262a1ae4d52973f650e34a2924c48598f657edff",
        []
       ],
-      "cache-storage-access.https.html": [
-       "ac714cc4ed2a1403eae9097751d75e58b96f1faf",
-       []
-      ],
       "cache.txt": [
        "89164cfabed56b5852445eb70470cfd1331bdb48",
        []
       ],
-      "cookies-access.html": [
-       "43b636c0a5a31fb59e4f64305fb6f2cea223e1e2",
-       []
-      ],
       "cross-origin-isolated-iframe.https.html": [
        "acad3c3e64f6cc514456cb6a10e3e246d4b92ff0",
        []
@@ -313480,34 +314221,30 @@
        "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
        []
       ],
+      "eval-channel.html": [
+       "5918a48baa5758ef746ce0da873946b591458df4",
+       []
+      ],
+      "eval-init.html": [
+       "621ab372c74049ffa9a983fd4ca0ec8aadd67425",
+       []
+      ],
       "iframe-added-post-activation.html": [
        "fb7aaa8e95cea564e03e0e9a35b767cd7ac4b24e",
        []
       ],
       "indexedb-utils.js": [
-       "39cb1a802a97358c7364c4dca52445824a351155",
-       []
-      ],
-      "indexeddb-access.html": [
-       "20e2956cd141b87a9ea1c5906d1708525949e3ef",
+       "7c57000d5cf48a3bbf74c0b0d8f812922f0575ef",
        []
       ],
       "key-value-store.py": [
        "1ab609f11bf2be22696f0b132b88d8fc86546b93",
        []
       ],
-      "local-storage-access.html": [
-       "00af1d5d16d832f1b611b6fe0978f059397d9add",
-       []
-      ],
       "notification.html": [
        "f9502dd5f21d6f93fd97f3553f4fc01f0cf57809",
        []
       ],
-      "prerender-focus.html": [
-       "f6a79533e560c80f1acbcbf28217ada86d660903",
-       []
-      ],
       "prerender-state.html": [
        "914db2a9ed900ece42982c12913576086f7db928",
        []
@@ -313521,7 +314258,7 @@
        []
       ],
       "utils.js": [
-       "1c1cdb2fbf08dcadd7502d9299077d1a298a0e0b",
+       "59e1462afc62bc02251a4e545904e2f1667a30eb",
        []
       ],
       "visibility-state-check.html": [
@@ -315946,7 +316683,7 @@
       []
      ],
      "urltestdata.json": [
-      "b39c6e7578c3cdb9a4753fd3f939cb3a91bebbc9",
+      "fa619fb8930fa0296e417bdc6d663b000c5e39fe",
       []
      ]
     },
@@ -315974,7 +316711,7 @@
       []
      ],
      "urlpatterntestdata.json": [
-      "671751fd3105b56ca0584553619c73634a971849",
+      "8992c95b59b9c53f16496591e6c91ec32adc9bd1",
       []
      ],
      "urlpatterntests.js": [
@@ -316259,6 +316996,16 @@
        ]
       }
      },
+     "global": {
+      "type.tentative.any-expected.txt": [
+       "2aec539c575a8bc88c84d5608d0b74081054966b",
+       []
+      ],
+      "type.tentative.any.worker-expected.txt": [
+       "2aec539c575a8bc88c84d5608d0b74081054966b",
+       []
+      ]
+     },
      "idlharness.any-expected.txt": [
       "845370fc1055ff291bf102d65281592f1a3552c1",
       []
@@ -316305,14 +317052,6 @@
       "c5880db327517f6bd5fdf09c4a8f2b291bdecf27",
       []
      ],
-     "prototypes.any-expected.txt": [
-      "4df42608c6b1973327cd517e9e267d1c8acecd8d",
-      []
-     ],
-     "prototypes.any.worker-expected.txt": [
-      "4df42608c6b1973327cd517e9e267d1c8acecd8d",
-      []
-     ],
      "table": {
       "assertions.js": [
        "19cc5c3b92d6fa6748c3831f3629c92b62ed757f",
@@ -316334,22 +317073,6 @@
        "dbd6539ea90e6578e0e76234ea555f414a3aeb4f",
        []
       ],
-      "constructor.any-expected.txt": [
-       "49f77337eed4303808b94d77f97b5856f9f4b7af",
-       []
-      ],
-      "constructor.any.worker-expected.txt": [
-       "49f77337eed4303808b94d77f97b5856f9f4b7af",
-       []
-      ],
-      "get-set.any-expected.txt": [
-       "cad5a835b6d9c95500261243889ea88456e94d1b",
-       []
-      ],
-      "get-set.any.worker-expected.txt": [
-       "cad5a835b6d9c95500261243889ea88456e94d1b",
-       []
-      ],
       "grow-reftypes.tentative.any-expected.txt": [
        "5a04fca68f6843a86f7f5e900a26253a9a08dd5b",
        []
@@ -316358,14 +317081,6 @@
        "7d6bf80291cd295caabfe4c09d1f60144101d655",
        []
       ],
-      "grow.any-expected.txt": [
-       "16927db9100e7aee0392d8a36b5d35df6b338416",
-       []
-      ],
-      "grow.any.worker-expected.txt": [
-       "16927db9100e7aee0392d8a36b5d35df6b338416",
-       []
-      ],
       "set-reftypes.tentative.any-expected.txt": [
        "5eb1b117af669e2c21fe01b2e9c370426d5e72a8",
        []
@@ -316373,6 +317088,14 @@
       "set-reftypes.tentative.any.worker-expected.txt": [
        "5eb1b117af669e2c21fe01b2e9c370426d5e72a8",
        []
+      ],
+      "type.tentative.any-expected.txt": [
+       "f65819c8872ca3a75623c0eb1b58e80070a9aa23",
+       []
+      ],
+      "type.tentative.any.worker-expected.txt": [
+       "f65819c8872ca3a75623c0eb1b58e80070a9aa23",
+       []
       ]
      },
      "tag": {
@@ -317544,10 +318267,6 @@
       }
      },
      "the-audiocontext-interface": {
-      "audiocontext-not-fully-active-expected.txt": [
-       "86d99c233ebb1d7ad83ddbb3571b87a5bb9fdc06",
-       []
-      ],
       "audiocontext-suspend-resume-expected.txt": [
        "4b3708bcb872ac53b8e82e6d780745dcb59cafab",
        []
@@ -318387,11 +319106,11 @@
        []
       ],
       "defaults.py": [
-       "8dd171aa64c71fa031e0e14ef4344f4335e368cc",
+       "64ee18b6c157488766f5c9d24f8f9dff79ff4387",
        []
       ],
       "fixtures.py": [
-       "cb98ccb6a754e9cb90687a84491b5f8c7b2d2237",
+       "30f93d4cea0fb44e0930c98eeb881b4dc19d1c88",
        []
       ],
       "fixtures_bidi.py": [
@@ -318403,7 +319122,7 @@
        []
       ],
       "helpers.py": [
-       "43680d4cd484459924990b8829de2fbc303bf500",
+       "e79a31448a323d06f583d35c6ffc9cbeef6d6f44",
        []
       ],
       "html": {
@@ -318517,9 +319236,19 @@
      []
     ],
     "idlharness.https.window-expected.txt": [
-     "6ed0916d004bd748428d92ecb2296fb2790f3eec",
+     "7b3f1ae73d65e4c10fef92795b0d5a9ad64fefb2",
      []
-    ]
+    ],
+    "resources": {
+     "automation.js": [
+      "f7477d1eccf816e507c401c26d9deaf360f33699",
+      []
+     ],
+     "common.js": [
+      "1d0904af837814ad0bd19a79a08a88faaa616164",
+      []
+     ]
+    }
    },
    "webidl": {
     "META.yml": [
@@ -318861,7 +319590,7 @@
      []
     ],
     "RTCPeerConnection-addIceCandidate-expected.txt": [
-     "eb37b1b3c75b43cae59b029ae4e858235d0958a5",
+     "864ee7ec848a5eb6f84d54c6989bfe3824c3000f",
      []
     ],
     "RTCPeerConnection-createAnswer-expected.txt": [
@@ -319111,7 +319840,7 @@
      []
     ],
     "RTCPeerConnection-insertable-streams.js": [
-     "24acb699ac01f869603fa0dd35946c69a15e942b",
+     "f1b872294bade2f9bf633238afe30265f133e6ff",
      []
     ],
     "RTCPeerConnection-sender-worker-single-frame.js": [
@@ -320104,7 +320833,7 @@
     ],
     "resources": {
      "fake-devices.js": [
-      "975d2242c949740217c050beea72db908ef46fc7",
+      "c5c5cadaa6af48f676565775d1dc8e27efffc3a2",
       []
      ],
      "manual.js": [
@@ -323246,6 +323975,10 @@
      "b798ab749a54304a3d396dd3f33f16538157e886",
      []
     ],
+    "shared-worker-partitioned.tentative-expected.txt": [
+     "a963a6ff35f29941aede44080a38339439325d06",
+     []
+    ],
     "support": {
      "ErrorEvent-error.js": [
       "930b54c0d5881ed4d13de51df1b35aa4ab585735",
@@ -323395,6 +324128,10 @@
       "49ceb2648a93410bdd5ee53ef0e114146210741b",
       []
      ],
+     "iframe-sw-shared-name.html": [
+      "c1c7a536e13ed59f950b953be32c9fdc91538f4d",
+      []
+     ],
      "iframe_sw_dataUrl.html": [
       "0fb0ec228079de8dd15626fb3161b53d48c68112",
       []
@@ -323466,6 +324203,10 @@
      "throw-on-message-Worker.js": [
       "3648f1f478538f0521f8ca15f0c61bf0c3f866e4",
       []
+     ],
+     "window-sw-shared-name.html": [
+      "4a0704f9e4be8cac1133bb1823a27a2ebba2ff86",
+      []
      ]
     }
    },
@@ -324341,6 +325082,13 @@
     ]
    },
    "FileAPI": {
+    "Blob-methods-from-detached-frame.html": [
+     "37efd5ed2016b76f5d4047d6858225330871a20a",
+     [
+      null,
+      {}
+     ]
+    ],
     "FileReader": {
      "progress_event_bubbles_cancelable.html": [
       "6a03243f934081b18cf456d741c3fc2d1660f9c3",
@@ -325565,6 +326313,15 @@
       {}
      ]
     ],
+    "database-names-by-origin.html": [
+     "2224d5b5c371f791a64849f36ace5b830f6e1a65",
+     [
+      null,
+      {
+       "timeout": "long"
+      }
+     ]
+    ],
     "delete-range.any.js": [
      "c11c68a609e444cffc9dd9aa1387cfc01be9a9de",
      [
@@ -337193,7 +337950,7 @@
       ]
      ],
      "entry-after-detach.html": [
-      "9d99918c5b263c3937af59725293a7aa9a50d21b",
+      "dc31f1a695b013fd8e135d12814ce3bc5e8348e3",
       [
        null,
        {}
@@ -337241,6 +337998,27 @@
        {}
       ]
      ],
+     "no-referrer-dynamic-url-censored.html": [
+      "91484daa00eeda75a279fb4aed1b2057ef0d9927",
+      [
+       null,
+       {}
+      ]
+     ],
+     "no-referrer-from-meta-url-censored.html": [
+      "0f23f3b539b064178df159cafd53f6e1584cae35",
+      [
+       null,
+       {}
+      ]
+     ],
+     "no-referrer-url-censored.html": [
+      "2db425368f6a0436b0e713d8bed96f7a98e98967",
+      [
+       null,
+       {}
+      ]
+     ],
      "opaque-origin-data-url.html": [
       "a1e765dd1bb75f2ee20a7efae64f2b7cbd464e40",
       [
@@ -357283,7 +358061,7 @@
       ]
      ],
      "CSSAnimation-effect.tentative.html": [
-      "fadcaa129ab2c4da612add9951bf99b447fe948d",
+      "04812d24e589c22f2266522877a2eb41fa17dcd1",
       [
        null,
        {
@@ -357362,7 +358140,7 @@
       ]
      ],
      "KeyframeEffect-getKeyframes.tentative.html": [
-      "1119d06d4a33298d351d7d702d2a92d24282e1f8",
+      "df319c2526569a2fccbf8b4106c6bde387be5727",
       [
        null,
        {}
@@ -357529,6 +358307,27 @@
       ]
      ],
      "parsing": {
+      "animation-composition-computed.tentative.html": [
+       "535a40c9ca9d5c875b2b9eb7f7a16b22d55071fe",
+       [
+        null,
+        {}
+       ]
+      ],
+      "animation-composition-invalid.tentative.html": [
+       "a08b33c84d815812b22d4a01ece10ec6e809f585",
+       [
+        null,
+        {}
+       ]
+      ],
+      "animation-composition-valid.tentative.html": [
+       "8dca8dbabe70a4fcc75312809a7896a83c1dfe78",
+       [
+        null,
+        {}
+       ]
+      ],
       "animation-computed.html": [
        "467f4357f102fb75ed8df196d221d83cd2efdabc",
        [
@@ -359034,6 +359833,13 @@
        {}
       ]
      ],
+     "transform-010.html": [
+      "8418551cdc8172862d57d8359a732968b3467aba",
+      [
+       null,
+       {}
+      ]
+     ],
      "widows-orphans-005.html": [
       "713849703ce92e062780bd20e0708c8dfcd21f5f",
       [
@@ -359051,7 +359857,7 @@
       ]
      ],
      "idlharness.html": [
-      "80d33185561cc1f6708e7e8de967d57288a6827a",
+      "9bde23b946ccf1537c92c6de2301005144bf12a6",
       [
        null,
        {}
@@ -359680,7 +360486,7 @@
        ]
       ],
       "container-for-shadow-dom.tentative.html": [
-       "24d52da256a8802e47b4e33f3c3c98f6216537b6",
+       "66e9ea088aaa024a3ae3f15da2e69436e7855383",
        [
         null,
         {}
@@ -359799,7 +360605,7 @@
        ]
       ],
       "container-units-selection.html": [
-       "861381345f9e63e01ca5c655b0dc95c6c02881d2",
+       "7471ec4dbf1b84f87bcd3ec899a3b51eec53ca5b",
        [
         null,
         {}
@@ -366750,6 +367556,13 @@
         {}
        ]
       ],
+      "grid-template-shorthand-areas-valid.html": [
+       "59770ed430bc5cab4c6915cbebe10694012a86d1",
+       [
+        null,
+        {}
+       ]
+      ],
       "grid-template-shorthand-invalid.html": [
        "366cdf4d887aa937875cd5e5a49631d1b3e283b1",
        [
@@ -368303,13 +369116,6 @@
        ]
       ]
      },
-     "balance-table-with-fractional-height-row.html": [
-      "434dc52ea3d731bd1393270372294cd007382e59",
-      [
-       null,
-       {}
-      ]
-     ],
      "filter-with-abspos.html": [
       "763bf1fc5a13ba86f440155aa0373357bf7782cb",
       [
@@ -368683,6 +369489,15 @@
        {}
       ]
      ],
+     "table": {
+      "balance-table-with-fractional-height-row.html": [
+       "434dc52ea3d731bd1393270372294cd007382e59",
+       [
+        null,
+        {}
+       ]
+      ]
+     },
      "zero-column-width-computed-style.html": [
       "46d876f1a150c257be9c37d25a4a4c34d2f1d73d",
       [
@@ -369171,6 +369986,20 @@
        {}
       ]
      ],
+     "page-rule-declarations-003.html": [
+      "aaf0bbb1a8c1a2e4298be5be2a6895ddc290ed48",
+      [
+       null,
+       {}
+      ]
+     ],
+     "page-rule-declarations-004.html": [
+      "94d0f8291d71d74572bdaf1c729e2d5155a4557a",
+      [
+       null,
+       {}
+      ]
+     ],
      "parsing": {
       "page-computed.html": [
        "0accba057487570e6a1a1e990c66cd72d0c17155",
@@ -370144,7 +370973,7 @@
        ]
       ],
       "marker-supported-properties.html": [
-       "ab03b9825deee02142bd0a03a21e9ff95feaa82f",
+       "700d04aa83a10c9d38c30d4695f2a14be27297a9",
        [
         null,
         {}
@@ -373951,7 +374780,7 @@
        ]
       ],
       "computing-column-measure-1.html": [
-       "f032fcd198720ec53f1435a768c6c8146d9433ae",
+       "eeae1c7a46f0120600aa8fde35854c6ea9b94b27",
        [
         null,
         {}
@@ -377759,7 +378588,7 @@
        ]
       ],
       "cssTransformValue.tentative.html": [
-       "8d9e2a41593644d7b2710916ffd776ac310a4528",
+       "e313647fa569121c1326217635979f275aab87b7",
        [
         null,
         {}
@@ -381132,6 +381961,13 @@
        null,
        {}
       ]
+     ],
+     "viewport-units-parsing.html": [
+      "4373b2a9f0844456c00904a3d90e159c78362c28",
+      [
+       null,
+       {}
+      ]
      ]
     },
     "css-variables": {
@@ -383517,6 +384353,15 @@
        }
       ]
      ],
+     "scroll-behavior-smooth-navigation.html": [
+      "299fd76976c1e2811766f606b378dc9cff867759",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
      "scroll-behavior-smooth-positions.html": [
       "97905bb708134107e95731a1c9e38108f41bfe47",
       [
@@ -383527,7 +384372,7 @@
       ]
      ],
      "scroll-behavior-smooth.html": [
-      "3e15199043863dae3a72184c03bd8b091c602291",
+      "cb2dd9e48a4b08ae9ce77d4ca05154263218be3a",
       [
        null,
        {
@@ -384297,6 +385142,13 @@
        {}
       ]
      ],
+     "mq-invalid-media-type-005.html": [
+      "3e25a248b3f58ad3d3777953d482a81965e6ff81",
+      [
+       null,
+       {}
+      ]
+     ],
      "navigation-controls.tentative.html": [
       "ac1087bb65b9a8fd85d924ad1ae0de797762dac5",
       [
@@ -385131,6 +385983,20 @@
        {}
       ]
      ],
+     "has-specificity-01.html": [
+      "b33e3a0eb3663266d7806ea9d243428684d673fd",
+      [
+       null,
+       {}
+      ]
+     ],
+     "has-specificity.html": [
+      "186d35fdd97286d5dcd6e5d7fddc3bd2c541349e",
+      [
+       null,
+       {}
+      ]
+     ],
      "hover-002.html": [
       "02cee99bf6cd161eb95806854cb12e39504a359e",
       [
@@ -385480,7 +386346,7 @@
        ]
       ],
       "has-complexity.html": [
-       "df127bcf1e4e830b32abfe069873a928b9f1d191",
+       "0bdcdec13b97d8a2b3973f86773512474988519c",
        [
         null,
         {}
@@ -385521,6 +386387,13 @@
         {}
        ]
       ],
+      "has-with-not.html": [
+       "b67ec5e3b7d05cee54666c079d197d2232609dad",
+       [
+        null,
+        {}
+       ]
+      ],
       "has-with-pseudo-class.html": [
        "4dc4c1a6a26e6bbbaf299a55b28a45e542ce672b",
        [
@@ -387634,6 +388507,13 @@
        {}
       ]
      ],
+     "EventListener-handleEvent-cross-realm.html": [
+      "663d04213f82bbcfabe420d3b738a706e0fd86e0",
+      [
+       null,
+       {}
+      ]
+     ],
      "EventListener-handleEvent.html": [
       "06bc1f6e2ab267e36c3d15da9e278db2aced85c0",
       [
@@ -387829,14 +388709,10 @@
        {}
       ]
      ],
-     "event-global-set-before-handleEvent-lookup.any.js": [
-      "5199cc7d6ddbe858369cf633989036a51ad8d61e",
+     "event-global-set-before-handleEvent-lookup.window.js": [
+      "8f934bcea97fe10a4195d18ab11066bb2c655084",
       [
-       "dom/events/event-global-set-before-handleEvent-lookup.any.html",
-       {}
-      ],
-      [
-       "dom/events/event-global-set-before-handleEvent-lookup.any.worker.html",
+       "dom/events/event-global-set-before-handleEvent-lookup.window.html",
        {}
       ]
      ],
@@ -388059,6 +388935,20 @@
       {}
      ]
     ],
+    "idlharness-shadowrealm.window.js": [
+     "cb03c07c9be1d8f4eb6d3656a17b1bf3d6625ed3",
+     [
+      "dom/idlharness-shadowrealm.window.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "/resources/idlharness-shadowrealm.js"
+        ]
+       ]
+      }
+     ]
+    ],
     "idlharness.any.js": [
      "26da3ab3bf94d59a6e1fd9b7c4131b63c7c3bf30",
      [
@@ -390199,14 +391089,14 @@
       ]
      ],
      "TreeWalker-acceptNode-filter-cross-realm-null-browsing-context.html": [
-      "4d6bb53289f47257a0ae21d451e48ec59529512c",
+      "f8e71bcdf56e155ad704facc8a5a1be981c02e73",
       [
        null,
        {}
       ]
      ],
      "TreeWalker-acceptNode-filter-cross-realm.html": [
-      "60a80d31190de6cf394be338bfeecaf3e9699338",
+      "da91cf6cb2379839367d09e48cadaa970b34e42a",
       [
        null,
        {}
@@ -390645,6 +391535,13 @@
       {}
      ]
     ],
+    "resolver-callback-interface-cross-realm.html": [
+     "55fbb070a3b482b1546a52eef0285f9e7e5483f0",
+     [
+      null,
+      {}
+     ]
+    ],
     "resolver-callback-interface.html": [
      "b43695f4aa56d2e7b8a05d0798657ff1057e3c9b",
      [
@@ -406273,6 +407170,73 @@
         {}
        ]
       ],
+      "request.any.js": [
+       "dcc7803abe5576d048a5a4dd9291768149190fb3",
+       [
+        "fetch/api/abort/request.any.html",
+        {
+         "script_metadata": [
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "global",
+           "window,worker"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "fetch/api/abort/request.any.serviceworker.html",
+        {
+         "script_metadata": [
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "global",
+           "window,worker"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "fetch/api/abort/request.any.sharedworker.html",
+        {
+         "script_metadata": [
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "global",
+           "window,worker"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ],
+       [
+        "fetch/api/abort/request.any.worker.html",
+        {
+         "script_metadata": [
+          [
+           "timeout",
+           "long"
+          ],
+          [
+           "global",
+           "window,worker"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ]
+      ],
       "serviceworker-intercepted.https.html": [
        "603f29eac981c7abcacd72c153685bc181ee80c4",
        [
@@ -413673,7 +414637,7 @@
       ]
      ],
      "script-resource-with-json-parser-breaker.tentative.sub.html": [
-      "1a8095ec658197833cf07f1f08407ac9970f33c4",
+      "1d9af352c863a26cec0e80924a0f1c4a8b62e5f0",
       [
        null,
        {}
@@ -416354,7 +417318,7 @@
       ]
      ],
      "shared-worker-fetch.https.window.js": [
-      "b5789346e391852b633392291b25a2a6a3026a3e",
+      "29e9f32c7e0b8102ba63435913bec49d29e1bce0",
       [
        "fetch/private-network-access/shared-worker-fetch.https.window.html",
        {
@@ -416372,7 +417336,7 @@
       ]
      ],
      "shared-worker-fetch.window.js": [
-      "215cf9b1c70529859dfbddfd033a6b225ea0063e",
+      "a317608ce8e983e9aa5e90108a3c8a1a7e792293",
       [
        "fetch/private-network-access/shared-worker-fetch.window.html",
        {
@@ -416454,7 +417418,7 @@
       ]
      ],
      "worker-fetch.https.window.js": [
-      "78e51b0f8af848b69a2e6f1b12230bde14b66ebd",
+      "528b556a2e5af8a765bd820ebd5aacb6730ec965",
       [
        "fetch/private-network-access/worker-fetch.https.window.html",
        {
@@ -418256,33 +419220,6 @@
       }
      ]
     ],
-    "font_access-chooser-multiple.tentative.manual.https.html": [
-     "bf70a0a7192a6d7b49d40a653110ccf2d75f0b7e",
-     [
-      null,
-      {
-       "testdriver": true
-      }
-     ]
-    ],
-    "font_access-chooser-selection.tentative.manual.https.html": [
-     "e8a1e8d91b21eed5b074f860cedd5f768cec3d8e",
-     [
-      null,
-      {
-       "testdriver": true
-      }
-     ]
-    ],
-    "font_access-chooser.tentative.manual.https.html": [
-     "499d8be4a1fcc15367ba5c07e21dd695d17c51f8",
-     [
-      null,
-      {
-       "testdriver": true
-      }
-     ]
-    ],
     "font_access-enumeration.tentative.https.window.js": [
      "677fe82c70233de2e1cbeab4beb41437319688b3",
      [
@@ -418310,7 +419247,7 @@
      ]
     ],
     "font_metadata.tentative.https.window.js": [
-     "21d3ea1c1125c7e2ea2674c38a421b3130a357f6",
+     "672bc082f2d73117eb415dfe785905319e9fd504",
      [
       "font-access/font_metadata.tentative.https.window.html",
       {
@@ -418752,7 +419689,7 @@
      ]
     ],
     "idlharness.https.window.js": [
-     "7f83eaf52d1d19be3074daf72cf32162d46ea4e6",
+     "176bae86af93745c5b5611a1070f3d9619c4a352",
      [
       "geolocation-API/idlharness.https.window.html",
       {
@@ -419165,6 +420102,33 @@
           null,
           {}
          ]
+        ],
+        "inflight-fetch-cors.html": [
+         "c04089a5e25ebae1d22b287cb1a063b2a44076c0",
+         [
+          null,
+          {
+           "timeout": "long"
+          }
+         ]
+        ],
+        "inflight-fetch-redirects.html": [
+         "b0b49d5f12af2ecae033ab3947765b0e473cc8b0",
+         [
+          null,
+          {
+           "timeout": "long"
+          }
+         ]
+        ],
+        "inflight-fetch.html": [
+         "3ce8e9920406f437156d4f42331186697cb29fed",
+         [
+          null,
+          {
+           "timeout": "long"
+          }
+         ]
         ]
        },
        "events.html": [
@@ -419175,6 +420139,15 @@
           "timeout": "long"
          }
         ]
+       ],
+       "timers.html": [
+        "f488855da20ecd84ebe6080c7f126650995cecb0",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
       },
       "history-traversal": {
@@ -424063,7 +425036,7 @@
         ]
        ],
        "2d.clearRect.clip.html": [
-        "92d6dd51cd5341494c32fccd55ce02af2625be32",
+        "0c6deaaaada1e675882b81cc63e343d3b2f60f2e",
         [
          null,
          {}
@@ -424091,7 +425064,7 @@
         ]
        ],
        "2d.clearRect.nonfinite.html": [
-        "6f1dacc5a2e90b4cefbfb779c913aea95d7997a1",
+        "18ce63081322d29d8365b59c23c8ad0689104c17",
         [
          null,
          {}
@@ -424133,7 +425106,7 @@
         ]
        ],
        "2d.fillRect.clip.html": [
-        "96925f1c2e5f020c1b5a95502c4b35d977bd5e19",
+        "ccbe776889ac1849f6770968248b39d8ab1ec7ab",
         [
          null,
          {}
@@ -424147,7 +425120,7 @@
         ]
        ],
        "2d.fillRect.nonfinite.html": [
-        "22deef6c81697004797fef0c539ca2cc0203bc4d",
+        "98b19cee4fda962aa53555ec847c84d60efef6c2",
         [
          null,
          {}
@@ -424189,7 +425162,7 @@
         ]
        ],
        "2d.strokeRect.clip.html": [
-        "2b1b3f6d60b0fafca0f5f9b6ae87e0f6b6632f08",
+        "1da47f43d959d91fa7cfcb784a168cd4fddf772b",
         [
          null,
          {}
@@ -424217,7 +425190,7 @@
         ]
        ],
        "2d.strokeRect.nonfinite.html": [
-        "8fee577df8d53c434a046af4d7bed2e5bcbe7bab",
+        "27829cb31f0bee9906342689a35f6d25d57bd34b",
         [
          null,
          {}
@@ -426860,7 +427833,7 @@
          ]
         ],
         "createImageBitmap-sizeOverflow.html": [
-         "f58825cc371f04bf186ba23fa869391f3d2d3f6c",
+         "7239c2e7a1c5983583e04d8bce7ebe028401ffec",
          [
           null,
           {}
@@ -442506,36 +443479,6 @@
         }
        ]
       ],
-      "broadcast-channel.tentative.window.js": [
-       "255a71920992328cf3e3b504a2a20aeda8b45f6f",
-       [
-        "html/cross-origin-embedder-policy/anonymous-iframe/broadcast-channel.tentative.window.html",
-        {
-         "script_metadata": [
-          [
-           "script",
-           "/common/get-host-info.sub.js"
-          ],
-          [
-           "script",
-           "/common/utils.js"
-          ],
-          [
-           "script",
-           "/common/dispatcher/dispatcher.js"
-          ],
-          [
-           "script",
-           "../credentialless/resources/common.js"
-          ],
-          [
-           "script",
-           "./resources/common.js"
-          ]
-         ]
-        }
-       ]
-      ],
       "cookie-store.tentative.https.window.js": [
        "60a856c7584681d20d12b72dcd951cd4fd43e2a1",
        [
@@ -442601,6 +443544,41 @@
         }
        ]
       ],
+      "fenced-frame.tentative.https.window.js": [
+       "8f6bfd35d761a69725f88efe484a31555c5d5b8a",
+       [
+        "html/cross-origin-embedder-policy/anonymous-iframe/fenced-frame.tentative.https.window.html",
+        {
+         "script_metadata": [
+          [
+           "script",
+           "/common/get-host-info.sub.js"
+          ],
+          [
+           "script",
+           "/common/utils.js"
+          ],
+          [
+           "script",
+           "/common/dispatcher/dispatcher.js"
+          ],
+          [
+           "script",
+           "../credentialless/resources/common.js"
+          ],
+          [
+           "script",
+           "./resources/common.js"
+          ],
+          [
+           "timeout",
+           "long"
+          ]
+         ],
+         "timeout": "long"
+        }
+       ]
+      ],
       "local-storage.tentative.https.window.js": [
        "9ce8b0f00250e3231cf3013b975426d92cf56d5a",
        [
@@ -445724,7 +446702,7 @@
         ]
        ],
        "outertext-setter.html": [
-        "6500931a8411bad79a44d7ae5ae93d5778f91309",
+        "953bedc9a8f0c07b4225e5fc688efdb9551b9baa",
         [
          null,
          {}
@@ -446535,6 +447513,17 @@
           {}
          ]
         ],
+        "lone-surrogates.sub.html": [
+         "e47ab0f310655eeec9aa151b12efe4e533cf677b",
+         [
+          "html/infrastructure/urls/resolving-urls/query-encoding/lone-surrogates.sub.html?encoding=utf8",
+          {}
+         ],
+         [
+          "html/infrastructure/urls/resolving-urls/query-encoding/lone-surrogates.sub.html?encoding=windows-1252",
+          {}
+         ]
+        ],
         "navigation.sub.html": [
          "7808434f05a49b8ac925dd9f03064f406ac291d8",
          [
@@ -452236,6 +453225,20 @@
          {}
         ]
        ],
+       "srcdoc-anchor.html": [
+        "cf26c28f0859ef80ae024b7462ac3ad946238ee1",
+        [
+         null,
+         {}
+        ]
+       ],
+       "srcdoc-attribute-reset.html": [
+        "452a984afbbd025d75d526ead388bc6b5a8f3489",
+        [
+         null,
+         {}
+        ]
+       ],
        "srcdoc_change_hash.html": [
         "fe72333d1a638966e14e46fdb6b0bdf21beaa75d",
         [
@@ -452988,6 +453991,16 @@
         ]
        ]
       },
+      "beforeinput.tentative.html": [
+       "7aa51a252300a0bff9d5d338892921faff9e57f8",
+       [
+        null,
+        {
+         "testdriver": true,
+         "timeout": "long"
+        }
+       ]
+      ],
       "constraints": {
        "form-validation-checkValidity.html": [
         "2e790c75d82dec2f60f64199ea4e1cba1164bc63",
@@ -454873,7 +455886,7 @@
         ]
        ],
        "selectmenu-parts-structure.tentative.html": [
-        "97a9698744a9c0256feb15f12ab11812dcc262da",
+        "65959a4275de0b4b9a6cebebb8ae85e9be9690dc",
         [
          null,
          {
@@ -455506,6 +456519,13 @@
          }
         ]
        ],
+       "modal-dialog-in-visibility-hidden.html": [
+        "abba08cfde54fd9beecbed25f6bb53519352bc03",
+        [
+         null,
+         {}
+        ]
+       ],
        "modal-dialog-scroll-height.html": [
         "638217f02100de800fd231c4d94d0ac43783c9af",
         [
@@ -467077,6 +468097,27 @@
     }
    },
    "js-self-profiling": {
+    "class-getter-names.https.html": [
+     "46e2ed274890ffff70d31a183e493f0ef2c29ab6",
+     [
+      null,
+      {}
+     ]
+    ],
+    "class-names.https.html": [
+     "9d201b03a18916f638d9f95962c912d764cc2bcd",
+     [
+      null,
+      {}
+     ]
+    ],
+    "class-setter-names.https.html": [
+     "f03a372460ceb8dd6fe42d488dd61f76878923cb",
+     [
+      null,
+      {}
+     ]
+    ],
     "concurrent-profilers.https.html": [
      "26f37ec8bdcd8b67173c3b83b285ed1e291870a4",
      [
@@ -467105,8 +468146,22 @@
       {}
      ]
     ],
-    "function-names.https.html": [
-     "1d61248725fbe930e21cdae8f9b490ab6eda6f6d",
+    "function-anonymous-names.https.html": [
+     "fd7fbecc506d739cbb7144727c1e91215b10b4e6",
+     [
+      null,
+      {}
+     ]
+    ],
+    "function-declaration-names.https.html": [
+     "9cb02cbfc0dd8c6e8c8549b52ec6179e104921dd",
+     [
+      null,
+      {}
+     ]
+    ],
+    "function-expression-names.https.html": [
+     "402797402e6e7a8fa5fb8ceb8fd5e7fbf4509d95",
      [
       null,
       {}
@@ -470917,8 +471972,15 @@
       }
      ]
     ],
+    "MediaStreamTrackGenerator-in-shared-worker.https.html": [
+     "deecfccad16f5df61028b9fc65e0e65e5f825e64",
+     [
+      null,
+      {}
+     ]
+    ],
     "MediaStreamTrackGenerator-in-worker.https.html": [
-     "ff3b9459686d6507f89efb502b4d3436fff81f13",
+     "e0a8f2fc2792e2f0d0ca2b45735ae2d7a207e779",
      [
       null,
       {}
@@ -479535,7 +480597,7 @@
      ]
     ],
     "pointerevent_constructor.html": [
-     "5aab1326cc5bb4f7390658b69f75bc5ce744ea08",
+     "3b278746e1256edcc9066ccd8d7c3ea5ba43376b",
      [
       null,
       {}
@@ -481026,7 +482088,7 @@
      ]
     ],
     "subresource-integrity.html": [
-     "ab4ded327f891802aac26f16d6c4942faf183586",
+     "a1c867e2911cba6d5acea84f6059f73cdc500c74",
      [
       null,
       {}
@@ -494080,6 +495142,20 @@
       {}
      ]
     ],
+    "iframe-sequence-of-events.html": [
+     "9013800721a96f8f2fbeb52e71408257e627f323",
+     [
+      null,
+      {}
+     ]
+    ],
+    "image-sequence-of-events.html": [
+     "630fed78c964bd439ec3151fed7c5b88760fdfb5",
+     [
+      null,
+      {}
+     ]
+    ],
     "initiator-type": {
      "audio.html": [
       "f09fc618478fd63eee8c9015dba121472ef9f672",
@@ -494215,7 +495291,7 @@
      ]
     ],
     "nextHopProtocol-is-tao-protected.https.html": [
-     "e0e96af8e80cf4fb06d7f1b3393f2191265b23ce",
+     "b16ff7af75dc7a61c2e458827b86340a6639b884",
      [
       null,
       {}
@@ -496205,6 +497281,66 @@
      ]
     ]
    },
+   "screen-details": {
+    "getScreenDetails.tentative.https.window.js": [
+     "e36b8938c4d0ce74177ae1aa23eb969597a61b01",
+     [
+      "screen-details/getScreenDetails.tentative.https.window.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window"
+        ],
+        [
+         "script",
+         "/resources/testdriver.js"
+        ],
+        [
+         "script",
+         "/resources/testdriver-vendor.js"
+        ]
+       ]
+      }
+     ]
+    ],
+    "isExtended.tentative.https.window.js": [
+     "3c814ae3d91d519500f7b44ab8fe4faa8a861d88",
+     [
+      "screen-details/isExtended.tentative.https.window.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window"
+        ]
+       ]
+      }
+     ]
+    ],
+    "screen_enumeration_permission.https.window.js": [
+     "00adbfc52acfceedc949093444f24f04f9dc1a27",
+     [
+      "screen-details/screen_enumeration_permission.https.window.html",
+      {
+       "script_metadata": [
+        [
+         "global",
+         "window"
+        ],
+        [
+         "script",
+         "/resources/testdriver.js"
+        ],
+        [
+         "script",
+         "/resources/testdriver-vendor.js"
+        ]
+       ]
+      }
+     ]
+    ]
+   },
    "screen-orientation": {
     "active-lock.html": [
      "84fb603eaeb48420c2abe47bc561516dd24a6e49",
@@ -496275,10 +497411,12 @@
      ]
     ],
     "onchange-event-subframe.html": [
-     "363c9cdf01091bb38587476e2cd9081ef24775ea",
+     "0ba0edc957cf27c99ba072769bf28de9ddf74b57",
      [
       null,
-      {}
+      {
+       "testdriver": true
+      }
      ]
     ],
     "onchange-event.html": [
@@ -496479,66 +497617,6 @@
      ]
     ]
    },
-   "screen_enumeration": {
-    "getScreenDetails.tentative.https.window.js": [
-     "6503a43db75b6156bd35bd32f143dba314ad11f4",
-     [
-      "screen_enumeration/getScreenDetails.tentative.https.window.html",
-      {
-       "script_metadata": [
-        [
-         "global",
-         "window"
-        ],
-        [
-         "script",
-         "/resources/testdriver.js"
-        ],
-        [
-         "script",
-         "/resources/testdriver-vendor.js"
-        ]
-       ]
-      }
-     ]
-    ],
-    "isExtended.tentative.https.window.js": [
-     "3c814ae3d91d519500f7b44ab8fe4faa8a861d88",
-     [
-      "screen_enumeration/isExtended.tentative.https.window.html",
-      {
-       "script_metadata": [
-        [
-         "global",
-         "window"
-        ]
-       ]
-      }
-     ]
-    ],
-    "screen_enumeration_permission.https.window.js": [
-     "00adbfc52acfceedc949093444f24f04f9dc1a27",
-     [
-      "screen_enumeration/screen_enumeration_permission.https.window.html",
-      {
-       "script_metadata": [
-        [
-         "global",
-         "window"
-        ],
-        [
-         "script",
-         "/resources/testdriver.js"
-        ],
-        [
-         "script",
-         "/resources/testdriver-vendor.js"
-        ]
-       ]
-      }
-     ]
-    ]
-   },
    "scroll-animations": {
     "css": {
      "animation-shorthand.html": [
@@ -502165,7 +503243,7 @@
      ]
     ],
     "detection-VideoFrame.https.window.js": [
-     "dd8b67830da277a7ca5f3ba3c9eaa42b1fe984bc",
+     "601c60bcaf87ef370a819b380c5114143781b350",
      [
       "shape-detection/detection-VideoFrame.https.window.html",
       {}
@@ -502756,7 +503834,7 @@
       ]
      ],
      "cache-storage.https.html": [
-      "015094c11517f4b7a9b901f50aa71b208048f534",
+      "39d0de399c03d669b7f554d702ee827c034b51a5",
       [
        null,
        {
@@ -502765,7 +503843,7 @@
       ]
      ],
      "cookies.html": [
-      "6e83532cce6ef16e845738ba229b89cde426c003",
+      "7f5e416188cacba1e52e453a045a701e8380b324",
       [
        null,
        {
@@ -502782,6 +503860,15 @@
        }
       ]
      ],
+     "fetch-blob.html": [
+      "880b05bdb969bc26359eaca1896650e6eb404054",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
      "iframe-added-post-activation.html": [
       "aeec5fc99bbd6519c7c0a8345a0beeafb58a0c2d",
       [
@@ -502792,7 +503879,7 @@
       ]
      ],
      "indexeddb.html": [
-      "65368acbaef86b5af4dac28cc1205e6eca2c1b89",
+      "0ac0d21a3389660bbb11d168a94173b7ce5afa4b",
       [
        null,
        {
@@ -502801,7 +503888,16 @@
       ]
      ],
      "local-storage.html": [
-      "b07d1f054be0efa5800c5eb994327c8f42a72556",
+      "dc4008c7ecc435823063fca5cbfa79b18fbdf7d3",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
+     "media-autoplay.html": [
+      "efbff1458826b329e32e20f16336695e73e32b0c",
       [
        null,
        {
@@ -502810,7 +503906,7 @@
       ]
      ],
      "restriction-focus.html": [
-      "b6576eb15a29e66ce0d0a3e9b046b171835d8837",
+      "0806b0c1943119b4bc9ce6b1f9bb5aee9f50e9a1",
       [
        null,
        {
@@ -502864,6 +503960,15 @@
        }
       ]
      ],
+     "restrictions.html": [
+      "5019d4b280cfe523aea11b7a4bee1fdb9fd7ddb6",
+      [
+       null,
+       {
+        "timeout": "long"
+       }
+      ]
+     ],
      "state-and-event.html": [
       "b8252121b1569dad90098636e86b8ad930cf5c70",
       [
@@ -511658,6 +512763,13 @@
       {}
      ]
     ],
+    "Document-execCommand.tentative.html": [
+     "0fd7e644b9ee019d5efcb86dc50ea14de02aa3cf",
+     [
+      null,
+      {}
+     ]
+    ],
     "Document-write.tentative.html": [
      "87e9e724699efc3f0edde3afade4cf53ec2c9c3e",
      [
@@ -511891,6 +513003,13 @@
       {}
      ]
     ],
+    "block-Document-execCommand.tentative.html": [
+     "e25b7dd28a2f646293d1abe879d525259db7d187",
+     [
+      null,
+      {}
+     ]
+    ],
     "block-Node-multiple-arguments.tentative.html": [
      "c3e7671534e70b959b30c8ed9cc16429ee23c45d",
      [
@@ -515802,6 +516921,13 @@
       {}
      ]
     ],
+    "viewport-resize-event-on-iframe-show.html": [
+     "688148a88fb21f899a16a710f24dd4836631fd13",
+     [
+      null,
+      {}
+     ]
+    ],
     "viewport-resize-event-on-iframe-size-change.html": [
      "802fee7879200a8e9352a54ba0a5f9719ca5f401",
      [
@@ -526830,7 +527956,7 @@
      ]
     ],
     "videoFrame-alpha.any.js": [
-     "93e7cc9d5d71c8b91fe8f8cdfe3f4592193bf78a",
+     "f4c4dfa737bdeb4eacacf47bff5fd4cae4883eb0",
      [
       "webcodecs/videoFrame-alpha.any.html",
       {
@@ -526855,14 +527981,14 @@
      ]
     ],
     "videoFrame-canvasImageSource.html": [
-     "ea470852158d443f93f378ecf578878ac08de674",
+     "397404be4ec99b56efbef730085ddc2b8d73ebcc",
      [
       null,
       {}
      ]
     ],
     "videoFrame-construction.any.js": [
-     "f121d09d24dd18e54e216b1aae04bb6e4f7a8e6f",
+     "be4d24e8941a29948d8929417c9254fb80c883ac",
      [
       "webcodecs/videoFrame-construction.any.html",
       {
@@ -527076,7 +528202,7 @@
      ]
     ],
     "videoFrame-drawImage.any.js": [
-     "f8a246d14a71a5abac0732cba74bf6aad8fc2bd6",
+     "9830181c4f50a83a36c74453f58b403d91f75493",
      [
       "webcodecs/videoFrame-drawImage.any.html",
       {
@@ -543666,7 +544792,7 @@
      ]
     ],
     "usbDevice.https.any.js": [
-     "5bfd841d5248e91a5cabf10d00d78db23d11f0e5",
+     "527d238d69b703b1fcf5d8a001d02e9f87b5689a",
      [
       "webusb/usbDevice.https.any.html",
       {
@@ -548189,6 +549315,13 @@
       {}
      ]
     ],
+    "shared-worker-partitioned.tentative.html": [
+     "0be8479fa9b0d6f8bca1109d3adc27ae76242cef",
+     [
+      null,
+      {}
+     ]
+    ],
     "worker-performance.worker.js": [
      "c913b2e7375067c1a21bdc655f394b5c27bc5aed",
      [
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/Blob-methods-from-detached-frame.html b/third_party/blink/web_tests/external/wpt/FileAPI/Blob-methods-from-detached-frame.html
new file mode 100644
index 0000000..37efd5e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/FileAPI/Blob-methods-from-detached-frame.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Blob methods from detached frame work as expected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<iframe id="emptyDocumentIframe" src="../support/empty-document.html"></iframe>
+
+<script>
+const BlobPrototypeFromDetachedFramePromise = new Promise(resolve => {
+    emptyDocumentIframe.onload = () => {
+        const BlobPrototype = emptyDocumentIframe.contentWindow.Blob.prototype;
+        emptyDocumentIframe.remove();
+        resolve(BlobPrototype);
+    };
+});
+
+const charCodeArrayToString = charCodeArray => Array.from(charCodeArray, c => String.fromCharCode(c)).join("");
+const charCodeBufferToString = charCodeBuffer => charCodeArrayToString(new Uint8Array(charCodeBuffer));
+
+promise_test(async () => {
+    const { slice } = await BlobPrototypeFromDetachedFramePromise;
+    const blob = new Blob(["foobar"]);
+
+    const slicedBlob = slice.call(blob, 1, 3);
+    assert_true(slicedBlob instanceof Blob);
+
+    assert_equals(await slicedBlob.text(), "oo");
+    assert_equals(charCodeBufferToString(await slicedBlob.arrayBuffer()), "oo");
+
+    const reader = slicedBlob.stream().getReader();
+    const { value } = await reader.read();
+    assert_equals(charCodeArrayToString(value), "oo");
+}, "slice()");
+
+promise_test(async () => {
+    const { text } = await BlobPrototypeFromDetachedFramePromise;
+    const blob = new Blob(["foo"]);
+
+    assert_equals(await text.call(blob), "foo");
+}, "text()");
+
+promise_test(async () => {
+    const { arrayBuffer } = await BlobPrototypeFromDetachedFramePromise;
+    const blob = new Blob(["bar"]);
+
+    const charCodeBuffer = await arrayBuffer.call(blob);
+    assert_equals(charCodeBufferToString(charCodeBuffer), "bar");
+}, "arrayBuffer()");
+
+promise_test(async () => {
+    const { stream } = await BlobPrototypeFromDetachedFramePromise;
+    const blob = new Blob(["baz"]);
+
+    const reader = stream.call(blob).getReader();
+    const { value } = await reader.read();
+    assert_equals(charCodeArrayToString(value), "baz");
+}, "stream()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/support/empty-document.html b/third_party/blink/web_tests/external/wpt/FileAPI/support/empty-document.html
new file mode 100644
index 0000000..b9cd130
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/FileAPI/support/empty-document.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<body>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-same-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-same-doc.html
index 85a93a21..9b1b777 100644
--- a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-same-doc.html
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-same-doc.html
@@ -6,7 +6,7 @@
   // Wait for after the load event so that the navigation doesn't get converted
   // into a replace navigation.
   await new Promise(resolve => window.onload = t.step_timeout(resolve, 0));
-  await appHistory.navigate("#foo");
+  await appHistory.navigate("#foo").committed;
   assert_equals(appHistory.entries().length, 2);
 
   let oncurrentchange_back_called = false;
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate-event/transitionWhile-and-navigate.html b/third_party/blink/web_tests/external/wpt/app-history/navigate-event/transitionWhile-and-navigate.html
index 66a43b25..65e9d04 100644
--- a/third_party/blink/web_tests/external/wpt/app-history/navigate-event/transitionWhile-and-navigate.html
+++ b/third_party/blink/web_tests/external/wpt/app-history/navigate-event/transitionWhile-and-navigate.html
@@ -16,12 +16,12 @@
       assert_equals(appHistory.entries().length, 2);
       appHistory.navigate("#2");
     }
-  }
+  };
   let back_result = appHistory.back();
-  await promise_rejects_dom(t, "AbortError", back_result.committed);
-  await promise_rejects_dom(t, "AbortError", back_result.finished);
+  await back_result.committed;
   assert_equals(location.hash, "#2");
+  await promise_rejects_dom(t, "AbortError", back_result.finished);
   assert_equals(appHistory.current.index, 1);
   assert_equals(appHistory.entries().length, 2);
-}, "Using transitionWhile then navigate() in the ensuing currentchange should abort the transitionWhile");
+}, "Using transitionWhile() then navigate() in the ensuing currentchange should abort the finished promise (but not the committed promise)");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate/navigate-same-document-event-order.html b/third_party/blink/web_tests/external/wpt/app-history/navigate/navigate-same-document-event-order.html
deleted file mode 100644
index 4be537f..0000000
--- a/third_party/blink/web_tests/external/wpt/app-history/navigate/navigate-same-document-event-order.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!doctype html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-async_test(t => {
-  let events = [];
-  function finish() {
-    // Until https://github.com/whatwg/html/issues/1792 (see also https://crbug.com/1254926) is
-    // resolved, ignore the ordering of hashchange and popstate (while still testing that they are
-    // the last two, in some order, and come in at most one task after "promisefulfilled").
-    // TODO(domenic): fix the spec, write non-app history tests, then reenable these checks.
-    assert_array_equals(
-      events.slice(0, -2),
-      ["onnavigate", "onnavigatesuccess", "promisefulfilled"/*, "onpopstate", "onhashchange"*/]
-    );
-    t.done();
-  }
-
-  appHistory.onnavigate = () => events.push("onnavigate");
-  appHistory.onnavigatesuccess = () => events.push("onnavigatesuccess");
-  appHistory.onnavigateerror = () => events.push("onnavigateerror");
-  window.onhashchange = t.step_func(() => {
-    events.push("onhashchange");
-    t.step_timeout(finish, 0);
-  });
-  window.onpopstate = () => events.push("onpopstate");
-  appHistory.navigate("#1").committed.then(
-      () => events.push("promisefulfilled"), () => events.push("promiserejected"));
-}, "navigate() event ordering for same-document navigation");
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate/navigate-transitionWhile-reject-event-order.html b/third_party/blink/web_tests/external/wpt/app-history/navigate/navigate-transitionWhile-reject-event-order.html
deleted file mode 100644
index 96e7427..0000000
--- a/third_party/blink/web_tests/external/wpt/app-history/navigate/navigate-transitionWhile-reject-event-order.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!doctype html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-async_test(t => {
-  let events = [];
-  function finish() {
-    // Until https://github.com/whatwg/html/issues/1792 (see also https://crbug.com/1254926) is
-    // resolved, ignore the ordering of hashchange and popstate (while still testing that they are
-    // the last two, in some order, and come in at most one task after "finished promiserejected").
-    // TODO(domenic): fix the spec, write non-app history tests, then reenable these checks.
-    assert_array_equals(
-      events.slice(0, -2),
-      ["onnavigate", "committed promisefulfilled", "onnavigateerror", "finished promiserejected"/*, "onhashchange", "onpopstate"*/]
-    );
-    t.done();
-  }
-
-  appHistory.onnavigate = e => {
-    events.push("onnavigate");
-    e.transitionWhile(Promise.reject());
-  };
-  appHistory.onnavigatesuccess = () => events.push("onnavigatesuccess");
-  appHistory.onnavigateerror = () => events.push("onnavigateerror");
-  window.onhashchange = () => events.push("onhashchange");
-  window.onpopstate = () => events.push("onpopstate");
-  const result = appHistory.navigate("#1");
-
-  result.committed.then(
-      () => events.push("committed promisefulfilled"),
-      () => events.push("committed promiserejected"));
-
-  result.finished.then(
-      () => events.push("finished promisefulfilled"),
-      () => {
-        events.push("finished promiserejected");
-        t.step_timeout(finish, 0);
-      });
-}, "navigate() event ordering for same-document navigation");
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/ordering/README.md b/third_party/blink/web_tests/external/wpt/app-history/ordering/README.md
new file mode 100644
index 0000000..9ae6c7b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/ordering/README.md
@@ -0,0 +1,24 @@
+# App history ordering tests
+
+These are meant to test the ordering between various events and promises; they
+don't fit into any particular sibling directory.
+
+Some of them test simple cases rather-exhaustively, and others test tricky cases
+(e.g. reentrancy or navigations aborting previous navigations) in a more focused
+way.
+
+Note:
+
+* Variants specifically exist for `currentchange` because an event listener
+  existing for `currentchange` causes code to run, and thus microtasks to run,
+  at a very specific point in the navigation-commit lifecycle. We want to test
+  that it doesn't impact the ordering.
+* Similarly we test that `transitionWhile(Promise.resolve())` does not change
+  the ordering compared to no `transitionWhile()` call, for same-document
+  navigations.
+
+TODOs:
+
+* Also test `appHistory.transition.finished` when it is implemented.
+* Also test `popstate` and `hashchange` once
+  <https://github.com/whatwg/html/issues/1792> is fixed.
diff --git a/third_party/blink/web_tests/external/wpt/app-history/ordering/back-same-document.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/back-same-document.html
new file mode 100644
index 0000000..f4a2c382
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/ordering/back-same-document.html
@@ -0,0 +1,63 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="variant" content="?">
+<meta name="variant" content="?transitionWhile">
+<meta name="variant" content="?currentchange">
+<meta name="variant" content="?transitionWhile&currentChange">
+
+<script>
+const variants = new Set((new URLSearchParams(location.search)).keys());
+
+promise_test(async t => {
+  // Wait for after the load event so that the navigation doesn't get converted
+  // into a replace navigation.
+  await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
+
+  await appHistory.navigate("#1").finished;
+
+  const events = [];
+  appHistory.addEventListener("navigatesuccess", () => events.push(`navigatesuccess ${location.hash}`));
+  appHistory.addEventListener("navigateerror", () => events.push(`navigateerror ${location.hash}`));
+  if (variants.has("currentchange")) {
+    appHistory.addEventListener("currentchange", () => events.push(`currentchange ${location.hash}`));
+  }
+
+  if (variants.has("transitionWhile")) {
+    appHistory.addEventListener("navigate", e => {
+      e.transitionWhile(Promise.resolve());
+    });
+  }
+
+  const { committed, finished } = appHistory.back();
+  committed.then(
+    () => events.push(`committed fulfilled ${location.hash}`),
+    () => events.push(`committed rejected ${location.hash}`)
+  );
+  finished.then(
+    () => events.push(`finished fulfilled ${location.hash}`),
+    () => events.push(`finished rejected ${location.hash}`)
+  );
+
+  Promise.resolve().then(() => events.push(`promise microtask ${location.hash}`));
+
+  await finished;
+
+  if (variants.has("currentchange")) {
+    assert_array_equals(events, [
+      "promise microtask #1",
+      "currentchange ",
+      "committed fulfilled ",
+      "navigatesuccess ",
+      "finished fulfilled "
+    ]);
+  } else {
+    assert_array_equals(events, [
+      "promise microtask #1",
+      "committed fulfilled ",
+      "navigatesuccess ",
+      "finished fulfilled "
+    ]);
+  }
+}, "event and promise ordering for same-document appHistory.back()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-dispose-ordering.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/currentchange-dispose-ordering.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-dispose-ordering.html
rename to third_party/blink/web_tests/external/wpt/app-history/ordering/currentchange-dispose-ordering.html
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate/navigate-cross-document-event-order.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigate-cross-document-event-order.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/app-history/navigate/navigate-cross-document-event-order.html
rename to third_party/blink/web_tests/external/wpt/app-history/ordering/navigate-cross-document-event-order.html
diff --git a/third_party/blink/web_tests/external/wpt/app-history/ordering/navigate-same-document-transitionWhile-reject.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigate-same-document-transitionWhile-reject.html
new file mode 100644
index 0000000..84e95eea
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigate-same-document-transitionWhile-reject.html
@@ -0,0 +1,57 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="variant" content="?">
+<meta name="variant" content="?currentchange">
+
+<script>
+const variants = new Set((new URLSearchParams(location.search)).keys());
+
+promise_test(async t => {
+  // Wait for after the load event so that the navigation doesn't get converted
+  // into a replace navigation.
+  await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
+
+  const events = [];
+  appHistory.addEventListener("navigatesuccess", () => events.push(`navigatesuccess ${location.hash}`));
+  appHistory.addEventListener("navigateerror", () => events.push(`navigateerror ${location.hash}`));
+  if (variants.has("currentchange")) {
+    appHistory.addEventListener("currentchange", () => events.push(`currentchange ${location.hash}`));
+  }
+
+  appHistory.addEventListener("navigate", e => {
+    e.transitionWhile(Promise.reject());
+  });
+
+  const { committed, finished } = appHistory.navigate("#1");
+  committed.then(
+    () => events.push(`committed fulfilled ${location.hash}`),
+    () => events.push(`committed rejected ${location.hash}`)
+  );
+  finished.then(
+    () => events.push(`finished fulfilled ${location.hash}`),
+    () => events.push(`finished rejected ${location.hash}`)
+  );
+
+  Promise.resolve().then(() => events.push(`promise microtask ${location.hash}`));
+
+  await finished.catch(() => {});
+
+  if (variants.has("currentchange")) {
+    assert_array_equals(events, [
+      "currentchange #1",
+      "committed fulfilled #1",
+      "promise microtask #1",
+      "navigateerror #1",
+      "finished rejected #1"
+    ]);
+  } else {
+    assert_array_equals(events, [
+      "committed fulfilled #1",
+      "promise microtask #1",
+      "navigateerror #1",
+      "finished rejected #1"
+    ]);
+  }
+}, "event and promise ordering for appHistory.navigate() with a rejected promise passed to transitionWhile()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/ordering/navigate-same-document.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigate-same-document.html
new file mode 100644
index 0000000..0d30eed
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigate-same-document.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="variant" content="?">
+<meta name="variant" content="?transitionWhile">
+<meta name="variant" content="?currentchange">
+<meta name="variant" content="?transitionWhile&currentChange">
+
+<script>
+const variants = new Set((new URLSearchParams(location.search)).keys());
+
+promise_test(async t => {
+  // Wait for after the load event so that the navigation doesn't get converted
+  // into a replace navigation.
+  await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
+
+  const events = [];
+  appHistory.addEventListener("navigatesuccess", () => events.push(`navigatesuccess ${location.hash}`));
+  appHistory.addEventListener("navigateerror", () => events.push(`navigateerror ${location.hash}`));
+  if (variants.has("currentchange")) {
+    appHistory.addEventListener("currentchange", () => events.push(`currentchange ${location.hash}`));
+  }
+
+  if (variants.has("transitionWhile")) {
+    appHistory.addEventListener("navigate", e => {
+      e.transitionWhile(Promise.resolve());
+    });
+  }
+
+  const { committed, finished } = appHistory.navigate("#1");
+  committed.then(
+    () => events.push(`committed fulfilled ${location.hash}`),
+    () => events.push(`committed rejected ${location.hash}`)
+  );
+  finished.then(
+    () => events.push(`finished fulfilled ${location.hash}`),
+    () => events.push(`finished rejected ${location.hash}`)
+  );
+
+  Promise.resolve().then(() => events.push(`promise microtask ${location.hash}`));
+
+  await finished;
+
+  if (variants.has("currentchange")) {
+    assert_array_equals(events, [
+      "currentchange #1",
+      "committed fulfilled #1",
+      "promise microtask #1",
+      "navigatesuccess #1",
+      "finished fulfilled #1"
+    ]);
+  } else {
+    assert_array_equals(events, [
+      "committed fulfilled #1",
+      "promise microtask #1",
+      "navigatesuccess #1",
+      "finished fulfilled #1"
+    ]);
+  }
+}, "event and promise ordering for same-document appHistory.navigate()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-location-api-reentrant.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-location-api-reentrant.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-location-api-reentrant.html
rename to third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-location-api-reentrant.html
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-location-api.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-location-api.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-location-api.html
rename to third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-location-api.html
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-cross-document.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-navigate-cross-document.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-cross-document.html
rename to third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-navigate-cross-document.html
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-transitionWhile-reentrant.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-transitionWhile-reentrant.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-transitionWhile-reentrant.html
rename to third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-transitionWhile-reentrant.html
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-transitionWhile.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-transitionWhile.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/app-history/navigate-event/navigateerror-ordering-transitionWhile.html
rename to third_party/blink/web_tests/external/wpt/app-history/ordering/navigateerror-ordering-transitionWhile.html
diff --git a/third_party/blink/web_tests/external/wpt/app-history/navigate/resources/notify-top-early.html b/third_party/blink/web_tests/external/wpt/app-history/ordering/resources/notify-top-early.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/app-history/navigate/resources/notify-top-early.html
rename to third_party/blink/web_tests/external/wpt/app-history/ordering/resources/notify-top-early.html
diff --git a/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any-expected.txt
deleted file mode 100644
index 084f5119..0000000
--- a/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-FAIL CookieListItem - cookieStore.set defaults with positional name and value assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set defaults with name and value in options assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with expires set to a timestamp 10 years in the future assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-PASS CookieListItem - cookieStore.set with expires set to a Date 10 years in the future
-FAIL CookieListItem - cookieStore.set with domain set to the current hostname assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with path set to the current directory assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set adds / to path if it does not end with / assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with sameSite set to strict assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with sameSite set to lax assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with sameSite set to none assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.js b/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.js
index e46d6b6..88ec4e9 100644
--- a/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.js
@@ -28,7 +28,10 @@
   assert_equals(cookie.expires, null);
   assert_equals(cookie.secure, true);
   assert_equals(cookie.sameSite, 'strict');
-  assert_array_equals(Object.keys(cookie).sort(), kCookieListItemKeys);
+  const itemKeys = Object.keys(cookie);
+  for (const key of kCookieListItemKeys) {
+    assert_in_array(key, itemKeys);
+  }
 }, 'CookieListItem - cookieStore.set defaults with positional name and value');
 
 promise_test(async testCase => {
@@ -46,7 +49,10 @@
   assert_equals(cookie.expires, null);
   assert_equals(cookie.secure, true);
   assert_equals(cookie.sameSite, 'strict');
-  assert_array_equals(Object.keys(cookie).sort(), kCookieListItemKeys);
+  const itemKeys = Object.keys(cookie);
+  for (const key of kCookieListItemKeys) {
+    assert_in_array(key, itemKeys);
+  }
 }, 'CookieListItem - cookieStore.set defaults with name and value in options');
 
 promise_test(async testCase => {
@@ -65,7 +71,10 @@
   assert_approx_equals(cookie.expires, kTenYearsFromNow, kOneDay);
   assert_equals(cookie.secure, true);
   assert_equals(cookie.sameSite, 'strict');
-  assert_array_equals(Object.keys(cookie).sort(), kCookieListItemKeys);
+  const itemKeys = Object.keys(cookie);
+  for (const key of kCookieListItemKeys) {
+    assert_in_array(key, itemKeys);
+  }
 }, 'CookieListItem - cookieStore.set with expires set to a timestamp 10 ' +
    'years in the future');
 
@@ -103,7 +112,10 @@
   assert_equals(cookie.expires, null);
   assert_equals(cookie.secure, true);
   assert_equals(cookie.sameSite, 'strict');
-  assert_array_equals(Object.keys(cookie).sort(), kCookieListItemKeys);
+  const itemKeys = Object.keys(cookie);
+  for (const key of kCookieListItemKeys) {
+    assert_in_array(key, itemKeys);
+  }
 }, 'CookieListItem - cookieStore.set with domain set to the current hostname');
 
 promise_test(async testCase => {
@@ -126,7 +138,10 @@
   assert_equals(cookie.expires, null);
   assert_equals(cookie.secure, true);
   assert_equals(cookie.sameSite, 'strict');
-  assert_array_equals(Object.keys(cookie).sort(), kCookieListItemKeys);
+  const itemKeys = Object.keys(cookie);
+  for (const key of kCookieListItemKeys) {
+    assert_in_array(key, itemKeys);
+  }
 }, 'CookieListItem - cookieStore.set with path set to the current directory');
 
 promise_test(async testCase => {
@@ -148,7 +163,10 @@
   assert_equals(cookie.expires, null);
   assert_equals(cookie.secure, true);
   assert_equals(cookie.sameSite, 'strict');
-  assert_array_equals(Object.keys(cookie).sort(), kCookieListItemKeys);
+  const itemKeys = Object.keys(cookie);
+  for (const key of kCookieListItemKeys) {
+    assert_in_array(key, itemKeys);
+  }
 }, 'CookieListItem - cookieStore.set adds / to path if it does not end with /');
 
 ['strict', 'lax', 'none'].forEach(sameSiteValue => {
@@ -168,7 +186,10 @@
     assert_equals(cookie.expires, null);
     assert_equals(cookie.secure, true);
     assert_equals(cookie.sameSite, sameSiteValue);
-    assert_array_equals(Object.keys(cookie).sort(), kCookieListItemKeys);
+    const itemKeys = Object.keys(cookie);
+    for (const key of kCookieListItemKeys) {
+      assert_in_array(key, itemKeys);
+    }
   }, `CookieListItem - cookieStore.set with sameSite set to ${sameSiteValue}`);
 
 });
diff --git a/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.serviceworker-expected.txt
deleted file mode 100644
index 084f5119..0000000
--- a/third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.serviceworker-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-FAIL CookieListItem - cookieStore.set defaults with positional name and value assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set defaults with name and value in options assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with expires set to a timestamp 10 years in the future assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-PASS CookieListItem - cookieStore.set with expires set to a Date 10 years in the future
-FAIL CookieListItem - cookieStore.set with domain set to the current hostname assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with path set to the current directory assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set adds / to path if it does not end with / assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with sameSite set to strict assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with sameSite set to lax assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-FAIL CookieListItem - cookieStore.set with sameSite set to none assert_array_equals: lengths differ, expected array ["domain", "expires", "name", "path", "sameSite", "secure", "value"] length 7, got ["domain", "expires", "name", "path", "sameParty", "sameSite", "secure", "value"] length 8
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path-redirect-shared.js b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path-redirect-shared.js
index 7144e65..777d0abd 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path-redirect-shared.js
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path-redirect-shared.js
@@ -1,11 +1,7 @@
 // Note: this function has a dependency on testdriver.js. Any test files calling
 // it should include testdriver.js and testdriver-vendor.js
 window.addEventListener("message", (e) => {
-  let test_window = window.top;
-  while (test_window.opener && !test_window.opener.closed) {
-    test_window = test_window.opener.top;
-  }
-  test_driver.set_test_context(test_window);
+  setTestContextUsingRootWindow();
   if (e.data == "getAndExpireCookiesForRedirectTest") {
     const cookies = document.cookie;
     test_driver.delete_all_cookies().then(() => {
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path.html b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path.html
index 1b53e77..5ff90b9 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path.html
@@ -8,6 +8,7 @@
 <body>
   <script src="/resources/testdriver.js"></script>
   <script src="/resources/testdriver-vendor.js"></script>
+  <script src="/cookies/resources/cookie-test.js"></script>
   <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/one.html b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/one.html
index 1b53e77..5ff90b9 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/one.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/one.html
@@ -8,6 +8,7 @@
 <body>
   <script src="/resources/testdriver.js"></script>
   <script src="/resources/testdriver-vendor.js"></script>
+  <script src="/cookies/resources/cookie-test.js"></script>
   <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/three.html b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/three.html
index 1b53e77..5ff90b9 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/three.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/three.html
@@ -8,6 +8,7 @@
 <body>
   <script src="/resources/testdriver.js"></script>
   <script src="/resources/testdriver-vendor.js"></script>
+  <script src="/cookies/resources/cookie-test.js"></script>
   <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/two.html b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/two.html
index 1b53e77..5ff90b9 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/two.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/path/two.html
@@ -8,6 +8,7 @@
 <body>
   <script src="/resources/testdriver.js"></script>
   <script src="/resources/testdriver-vendor.js"></script>
+  <script src="/cookies/resources/cookie-test.js"></script>
   <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/pathfakeout.html b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/pathfakeout.html
index 1b53e77..5ff90b9 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/pathfakeout.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/pathfakeout.html
@@ -8,6 +8,7 @@
 <body>
   <script src="/resources/testdriver.js"></script>
   <script src="/resources/testdriver-vendor.js"></script>
+  <script src="/cookies/resources/cookie-test.js"></script>
   <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/pathfakeout/one.html b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/pathfakeout/one.html
index 1b53e77..5ff90b9 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/pathfakeout/one.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/pathfakeout/one.html
@@ -8,6 +8,7 @@
 <body>
   <script src="/resources/testdriver.js"></script>
   <script src="/resources/testdriver-vendor.js"></script>
+  <script src="/cookies/resources/cookie-test.js"></script>
   <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/secure-non-secure-child.html b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/secure-non-secure-child.html
index 443b0a1..e5d68b8 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/secure-non-secure-child.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/attributes/resources/secure-non-secure-child.html
@@ -12,6 +12,7 @@
   </head>
   <body>
     <script>
+      setTestContextUsingRootWindow();
       // These tests are the non-secure analog to secure.https.html.
       // They're not in the /cookies/attributes folder because they shouldn't
       // be run by themselves. Instead, /cookies/attributes/secure.https.html
diff --git a/third_party/blink/web_tests/external/wpt/cookies/resources/cookie-test.js b/third_party/blink/web_tests/external/wpt/cookies/resources/cookie-test.js
index 2e435dd..7c3b861 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/resources/cookie-test.js
+++ b/third_party/blink/web_tests/external/wpt/cookies/resources/cookie-test.js
@@ -143,3 +143,15 @@
 function cookieStringWithNameAndValueLengths(nameLength, valueLength) {
   return `${"t".repeat(nameLength)}=${"1".repeat(valueLength)}`;
 }
+
+// Finds the root window.top.opener and directs test_driver commands to it.
+//
+// If you see a message like: "Error: Tried to run in a non-testharness window
+// without a call to set_test_context." then you probably need to call this.
+function setTestContextUsingRootWindow() {
+  let test_window = window.top;
+  while (test_window.opener && !test_window.opener.closed) {
+    test_window = test_window.opener.top;
+  }
+  test_driver.set_test_context(test_window);
+}
diff --git a/third_party/blink/web_tests/external/wpt/cookies/resources/echo-cookie.html b/third_party/blink/web_tests/external/wpt/cookies/resources/echo-cookie.html
index 172020c..ab78af8 100644
--- a/third_party/blink/web_tests/external/wpt/cookies/resources/echo-cookie.html
+++ b/third_party/blink/web_tests/external/wpt/cookies/resources/echo-cookie.html
@@ -6,6 +6,7 @@
   <meta name=help href="http://tools.ietf.org/html/rfc6265#section-5.1.4">
   <script src="/resources/testdriver.js"></script>
   <script src="/resources/testdriver-vendor.js"></script>
+  <script src="/cookies/resources/cookie-test.js"></script>
 </head>
 <body>
 <script>
@@ -21,11 +22,7 @@
 // Note: this function has a dependency on testdriver.js. Any test files calling
 // it should include testdriver.js and testdriver-vendor.js
 window.expireCookies = async () => {
-  let test_window = window.top;
-  while (test_window.opener && !test_window.opener.closed) {
-    test_window = test_window.opener.top;
-  }
-  test_driver.set_test_context(test_window);
+  setTestContextUsingRootWindow();
   await test_driver.delete_all_cookies();
 };
 window.getCookies = () => document.cookie;
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/credential-management/idlharness.https.window-expected.txt
new file mode 100644
index 0000000..6e82efe0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/credential-management/idlharness.https.window-expected.txt
@@ -0,0 +1,99 @@
+This is a testharness.js-based test.
+Found 95 tests; 94 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS idl_test setup
+PASS idl_test validation
+PASS Partial interface Navigator: original interface defined
+PASS Partial interface Navigator: member names are unique
+PASS Partial dictionary CredentialRequestOptions: original dictionary defined
+PASS Partial dictionary CredentialRequestOptions: member names are unique
+PASS Partial dictionary CredentialCreationOptions: original dictionary defined
+PASS Partial dictionary CredentialCreationOptions: member names are unique
+PASS Partial dictionary CredentialRequestOptions[2]: original dictionary defined
+PASS Partial dictionary CredentialRequestOptions[2]: member names are unique
+PASS Partial dictionary CredentialCreationOptions[2]: original dictionary defined
+PASS Partial dictionary CredentialCreationOptions[2]: member names are unique
+PASS Partial interface mixin NavigatorID: member names are unique
+PASS PasswordCredential includes CredentialUserData: member names are unique
+PASS FederatedCredential includes CredentialUserData: member names are unique
+PASS HTMLElement includes GlobalEventHandlers: member names are unique
+PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
+PASS HTMLElement includes ElementContentEditable: member names are unique
+PASS HTMLElement includes HTMLOrSVGElement: member names are unique
+PASS Navigator includes NavigatorID: member names are unique
+PASS Navigator includes NavigatorLanguage: member names are unique
+PASS Navigator includes NavigatorOnLine: member names are unique
+PASS Navigator includes NavigatorContentUtils: member names are unique
+PASS Navigator includes NavigatorCookies: member names are unique
+PASS Navigator includes NavigatorPlugins: member names are unique
+PASS Navigator includes NavigatorConcurrentHardware: member names are unique
+PASS Element includes ParentNode: member names are unique
+PASS Element includes NonDocumentTypeChildNode: member names are unique
+PASS Element includes ChildNode: member names are unique
+PASS Element includes Slottable: member names are unique
+PASS Credential interface: existence and properties of interface object
+PASS Credential interface object length
+PASS Credential interface object name
+PASS Credential interface: existence and properties of interface prototype object
+PASS Credential interface: existence and properties of interface prototype object's "constructor" property
+PASS Credential interface: existence and properties of interface prototype object's @@unscopables property
+PASS Credential interface: attribute id
+PASS Credential interface: attribute type
+FAIL Credential interface: operation isConditionalMediationAvailable() assert_own_property: interface object missing static operation expected property "isConditionalMediationAvailable" missing
+PASS CredentialsContainer interface: existence and properties of interface object
+PASS CredentialsContainer interface object length
+PASS CredentialsContainer interface object name
+PASS CredentialsContainer interface: existence and properties of interface prototype object
+PASS CredentialsContainer interface: existence and properties of interface prototype object's "constructor" property
+PASS CredentialsContainer interface: existence and properties of interface prototype object's @@unscopables property
+PASS CredentialsContainer interface: operation get(optional CredentialRequestOptions)
+PASS CredentialsContainer interface: operation store(Credential)
+PASS CredentialsContainer interface: operation create(optional CredentialCreationOptions)
+PASS CredentialsContainer interface: operation preventSilentAccess()
+PASS CredentialsContainer must be primary interface of navigator.credentials
+PASS Stringification of navigator.credentials
+PASS CredentialsContainer interface: navigator.credentials must inherit property "get(optional CredentialRequestOptions)" with the proper type
+PASS CredentialsContainer interface: calling get(optional CredentialRequestOptions) on navigator.credentials with too few arguments must throw TypeError
+PASS CredentialsContainer interface: navigator.credentials must inherit property "store(Credential)" with the proper type
+PASS CredentialsContainer interface: calling store(Credential) on navigator.credentials with too few arguments must throw TypeError
+PASS CredentialsContainer interface: navigator.credentials must inherit property "create(optional CredentialCreationOptions)" with the proper type
+PASS CredentialsContainer interface: calling create(optional CredentialCreationOptions) on navigator.credentials with too few arguments must throw TypeError
+PASS CredentialsContainer interface: navigator.credentials must inherit property "preventSilentAccess()" with the proper type
+PASS PasswordCredential interface: existence and properties of interface object
+PASS PasswordCredential interface object length
+PASS PasswordCredential interface object name
+PASS PasswordCredential interface: existence and properties of interface prototype object
+PASS PasswordCredential interface: existence and properties of interface prototype object's "constructor" property
+PASS PasswordCredential interface: existence and properties of interface prototype object's @@unscopables property
+PASS PasswordCredential interface: attribute password
+PASS PasswordCredential interface: attribute name
+PASS PasswordCredential interface: attribute iconURL
+PASS PasswordCredential must be primary interface of passwordCredential
+PASS Stringification of passwordCredential
+PASS PasswordCredential interface: passwordCredential must inherit property "password" with the proper type
+PASS PasswordCredential interface: passwordCredential must inherit property "name" with the proper type
+PASS PasswordCredential interface: passwordCredential must inherit property "iconURL" with the proper type
+PASS Credential interface: passwordCredential must inherit property "id" with the proper type
+PASS Credential interface: passwordCredential must inherit property "type" with the proper type
+PASS Credential interface: passwordCredential must inherit property "isConditionalMediationAvailable()" with the proper type
+PASS FederatedCredential interface: existence and properties of interface object
+PASS FederatedCredential interface object length
+PASS FederatedCredential interface object name
+PASS FederatedCredential interface: existence and properties of interface prototype object
+PASS FederatedCredential interface: existence and properties of interface prototype object's "constructor" property
+PASS FederatedCredential interface: existence and properties of interface prototype object's @@unscopables property
+PASS FederatedCredential interface: attribute provider
+PASS FederatedCredential interface: attribute protocol
+PASS FederatedCredential interface: attribute name
+PASS FederatedCredential interface: attribute iconURL
+PASS FederatedCredential must be primary interface of federatedCredential
+PASS Stringification of federatedCredential
+PASS FederatedCredential interface: federatedCredential must inherit property "provider" with the proper type
+PASS FederatedCredential interface: federatedCredential must inherit property "protocol" with the proper type
+PASS FederatedCredential interface: federatedCredential must inherit property "name" with the proper type
+PASS FederatedCredential interface: federatedCredential must inherit property "iconURL" with the proper type
+PASS Credential interface: federatedCredential must inherit property "id" with the proper type
+PASS Credential interface: federatedCredential must inherit property "type" with the proper type
+PASS Credential interface: federatedCredential must inherit property "isConditionalMediationAvailable()" with the proper type
+PASS Navigator interface: attribute credentials
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/background-blending/background-blend-mode-plus-lighter.html b/third_party/blink/web_tests/external/wpt/css/compositing/background-blending/background-blend-mode-plus-lighter.html
new file mode 100644
index 0000000..0816dc6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/background-blending/background-blend-mode-plus-lighter.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>background-blend-mode: plus-lighter test</title>
+<link rel="author" title="Jake Archibald" href="mailto:jakearchibald@chromium.org">
+<link rel="help" href="https://drafts.fxtf.org/compositing-2/#background-blend-mode">
+<link rel="match" href="reference/background-blend-mode-plus-lighter-ref.html">
+<style>
+  .test {
+    width: 100px;
+    height: 100px;
+    background-blend-mode: plus-lighter;
+  }
+</style>
+<script type="module">
+  import { tests } from '../support/plus-lighter.js';
+  import { toCSSColor } from '../support/utils.js';
+
+  // Create a solid color CSS image.
+  const colorImage = (pixel) =>
+    `linear-gradient(to right, ${toCSSColor(pixel)}, ${toCSSColor(pixel)})`;
+
+  const createBackgrounds = (colors) => colors
+    // Backgrounds are top first
+    .slice().reverse()
+    .map((color) => colorImage(color))
+    .join(', ');
+
+  for (const colors of tests) {
+    document.body.insertAdjacentHTML('beforeend', `
+      <div class="test" style="background-image: ${createBackgrounds(colors)}"></div>
+    `);
+  }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/background-blending/reference/background-blend-mode-plus-lighter-ref.html b/third_party/blink/web_tests/external/wpt/css/compositing/background-blending/reference/background-blend-mode-plus-lighter-ref.html
new file mode 100644
index 0000000..55098198
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/background-blending/reference/background-blend-mode-plus-lighter-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>background-blend-mode: plus-lighter test</title>
+<link rel="author" title="Jake Archibald" href="mailto:jakearchibald@chromium.org">
+<link rel="help" href="https://drafts.fxtf.org/compositing-2/#background-blend-mode">
+<style>
+  .test {
+    width: 100px;
+    height: 100px;
+  }
+</style>
+<script type="module">
+  import { tests, plusLighter } from '../../support/plus-lighter.js';
+  import { toCSSColor } from '../../support/utils.js';
+
+  for (const colors of tests) {
+    document.body.insertAdjacentHTML('beforeend', `
+      <div class="test" style="background-color: ${toCSSColor(plusLighter(colors))}"></div>
+    `);
+  }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-basic.html b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-basic.html
new file mode 100644
index 0000000..fcf2d17
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-basic.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<title>mix-blend-mode: plus-lighter test</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://drafts.fxtf.org/compositing-2/#mix-blend-mode">
+<link rel="match" href="reference/mix-blend-mode-plus-lighter-basic-ref.html">
+
+<style>
+.container {
+  position: relative;
+  isolation: isolate;
+  width: 500px;
+  height: 500px;
+}
+.blue { background: #000064; }
+.green { background: #006400; }
+.common {
+  position: absolute;
+  width: 100px;
+  height: 100px;
+  opacity: 0.6;
+}
+.one {
+  top: 10px;
+  left: 10px;
+}
+.two {
+  top: 65px;
+  left: 30px;
+  mix-blend-mode: plus-lighter;
+}
+.three {
+  top: 120px;
+  left: 50px;
+  mix-blend-mode: plus-lighter;
+}
+</style>
+
+<div class=container>
+  <div class="one common blue"></div>
+  <div class="two common blue"></div>
+  <div class="three common green"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg-basic.html b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg-basic.html
new file mode 100644
index 0000000..4762389
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg-basic.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<title>mix-blend-mode: plus-lighter SVG test</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://drafts.fxtf.org/compositing-2/#mix-blend-mode">
+<link rel="match" href="reference/mix-blend-mode-plus-lighter-svg-ref.html">
+
+<style>
+.isolate { isolation: isolate; }
+rect {
+  opacity: 0.6;
+  mix-blend-mode: plus-lighter;
+}
+</style>
+
+<svg width=500 height=500>
+  <g class="isolate">
+    <rect x="10" y="10" width="100" height="100" fill="#000064"></rect>
+    <rect x="30" y="65" width="100" height="100" fill="#000064"></rect>
+    <rect x="50" y="120" width="100" height="100" fill="#006400"></rect>
+  </g>
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg.html b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg.html
index 4762389..fc5e94e 100644
--- a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg.html
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter-svg.html
@@ -1,21 +1,37 @@
 <!DOCTYPE html>
 <title>mix-blend-mode: plus-lighter SVG test</title>
-<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="author" title="Jake Archibald" href="mailto:jakearchibald@chromium.org">
 <link rel="help" href="https://drafts.fxtf.org/compositing-2/#mix-blend-mode">
 <link rel="match" href="reference/mix-blend-mode-plus-lighter-svg-ref.html">
-
 <style>
-.isolate { isolation: isolate; }
-rect {
-  opacity: 0.6;
-  mix-blend-mode: plus-lighter;
-}
+  .blend-group {
+    isolation: isolate;
+  }
+  .layer {
+    mix-blend-mode: plus-lighter;
+  }
 </style>
+<script type="module">
+  import { tests } from '../support/plus-lighter.js';
+  import { toCSSColor } from '../support/utils.js';
 
-<svg width=500 height=500>
-  <g class="isolate">
-    <rect x="10" y="10" width="100" height="100" fill="#000064"></rect>
-    <rect x="30" y="65" width="100" height="100" fill="#000064"></rect>
-    <rect x="50" y="120" width="100" height="100" fill="#006400"></rect>
-  </g>
-</svg>
+  function createRects(colors) {
+    let html = '';
+
+    for (const color of colors) {
+      html += `<rect class="layer" x="0" y="0" width="100%" height="100%" fill="${toCSSColor(color)}" />`;
+    }
+
+    return html;
+  }
+
+  for (const colors of tests) {
+    document.body.insertAdjacentHTML('beforeend', `
+      <svg width="100" height="100">
+        <g class="blend-group">
+          ${createRects(colors)}
+        </g>
+      </svg>
+    `);
+  }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter.html b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter.html
index ae3dff1..e6fc4d7 100644
--- a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter.html
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/mix-blend-mode-plus-lighter.html
@@ -1,42 +1,38 @@
 <!DOCTYPE html>
 <title>mix-blend-mode: plus-lighter test</title>
-<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="author" title="Jake Archibald" href="mailto:jakearchibald@chromium.org">
 <link rel="help" href="https://drafts.fxtf.org/compositing-2/#mix-blend-mode">
 <link rel="match" href="reference/mix-blend-mode-plus-lighter-ref.html">
-
 <style>
-.container {
-  position: relative;
-  isolation: isolate;
-  width: 500px;
-  height: 500px;
-}
-.blue { background: #000064; }
-.green { background: #006400; }
-.common {
-  position: absolute;
-  width: 100px;
-  height: 100px;
-  opacity: 0.6;
-}
-.one {
-  top: 10px;
-  left: 10px;
-}
-.two {
-  top: 65px;
-  left: 30px;
-  mix-blend-mode: plus-lighter;
-}
-.three {
-  top: 120px;
-  left: 50px;
-  mix-blend-mode: plus-lighter;
-}
+  .test {
+    width: 100px;
+    height: 100px;
+    position: relative;
+    isolation: isolate;
+  }
+  .layer {
+    position: absolute;
+    inset: 0;
+    mix-blend-mode: plus-lighter;
+  }
 </style>
+<script type="module">
+  import { tests } from '../support/plus-lighter.js';
+  import { toCSSColor } from '../support/utils.js';
 
-<div class=container>
-  <div class="one common blue"></div>
-  <div class="two common blue"></div>
-  <div class="three common green"></div>
-</div>
+  function createLayers(colors) {
+    let html = '';
+
+    for (const color of colors) {
+      html += `<div class="layer" style="background-color: ${toCSSColor(color)}"></div>`;
+    }
+
+    return html;
+  }
+
+  for (const colors of tests) {
+    document.body.insertAdjacentHTML('beforeend', `
+      <div class="test">${createLayers(colors)}</div>
+    `);
+  }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-basic-ref.html b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-basic-ref.html
new file mode 100644
index 0000000..e5acd26
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-basic-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<title>mix-blend-mode: plus-lighter test</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://drafts.fxtf.org/compositing-2/#mix-blend-mode">
+
+<style>
+.container {
+  isolation: isolate;
+  position: relative;
+  width: 500px;
+  height: 500px;
+}
+.blue { background: #000064; }
+.green { background: #006400; }
+.common {
+  position: absolute;
+  width: 100px;
+  height: 100px;
+  opacity: 0.6;
+}
+.one {
+  top: 10px;
+  left: 10px;
+}
+.two {
+  top: 65px;
+  left: 30px;
+}
+.three {
+  top: 120px;
+  left: 50px;
+}
+.one_and_two {
+  position: absolute;
+  width: 80px;
+  height: 45px;
+  top: 65px;
+  left: 30px;
+  background: #000078;
+}
+.two_and_three {
+  position: absolute;
+  width: 80px;
+  height: 45px;
+  top: 120px;
+  left: 50px;
+  background: #003C3C;
+}
+</style>
+
+<div class=container>
+  <div class="one common blue"></div>
+  <div class="two common blue"></div>
+  <div class="three common green"></div>
+  <div class="one_and_two"></div>
+  <div class="two_and_three"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-ref.html b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-ref.html
index e5acd26..4709ab8 100644
--- a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-ref.html
@@ -1,57 +1,20 @@
 <!DOCTYPE html>
 <title>mix-blend-mode: plus-lighter test</title>
-<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="author" title="Jake Archibald" href="mailto:jakearchibald@chromium.org">
 <link rel="help" href="https://drafts.fxtf.org/compositing-2/#mix-blend-mode">
-
 <style>
-.container {
-  isolation: isolate;
-  position: relative;
-  width: 500px;
-  height: 500px;
-}
-.blue { background: #000064; }
-.green { background: #006400; }
-.common {
-  position: absolute;
-  width: 100px;
-  height: 100px;
-  opacity: 0.6;
-}
-.one {
-  top: 10px;
-  left: 10px;
-}
-.two {
-  top: 65px;
-  left: 30px;
-}
-.three {
-  top: 120px;
-  left: 50px;
-}
-.one_and_two {
-  position: absolute;
-  width: 80px;
-  height: 45px;
-  top: 65px;
-  left: 30px;
-  background: #000078;
-}
-.two_and_three {
-  position: absolute;
-  width: 80px;
-  height: 45px;
-  top: 120px;
-  left: 50px;
-  background: #003C3C;
-}
+  .test {
+    width: 100px;
+    height: 100px;
+  }
 </style>
+<script type="module">
+  import { tests, plusLighter } from '../../support/plus-lighter.js';
+  import { toCSSColor } from '../../support/utils.js';
 
-<div class=container>
-  <div class="one common blue"></div>
-  <div class="two common blue"></div>
-  <div class="three common green"></div>
-  <div class="one_and_two"></div>
-  <div class="two_and_three"></div>
-</div>
+  for (const colors of tests) {
+    document.body.insertAdjacentHTML('beforeend', `
+      <div class="test" style="background-color: ${toCSSColor(plusLighter(colors))}"></div>
+    `);
+  }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-svg-basic-ref.html b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-svg-basic-ref.html
new file mode 100644
index 0000000..9193bb5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-svg-basic-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>mix-blend-mode: plus-lighter SVG test</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://drafts.fxtf.org/compositing-2/#mix-blend-mode">
+
+<style>
+.isolate { isolation: isolate; }
+.original { opacity: 0.6; }
+</style>
+
+<svg width=500 height=500>
+  <g class="isolate">
+    <rect class="original" x="10" y="10" width="100" height="100" fill="#000064"></rect>
+    <rect class="original" x="30" y="65" width="100" height="100" fill="#000064"></rect>
+    <rect class="original" x="50" y="120" width="100" height="100" fill="#006400"></rect>
+    <rect x="30" y="65" width="80" height="45" fill="#000078"></rect>
+    <rect x="50" y="120" width="80" height="45" fill="#003C3C"></rect>
+  </g>
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-svg-ref.html b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-svg-ref.html
index 9193bb5..8e1cb70 100644
--- a/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-svg-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/mix-blend-mode/reference/mix-blend-mode-plus-lighter-svg-ref.html
@@ -1,19 +1,14 @@
 <!DOCTYPE html>
 <title>mix-blend-mode: plus-lighter SVG test</title>
-<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="author" title="Jake Archibald" href="mailto:jakearchibald@chromium.org">
 <link rel="help" href="https://drafts.fxtf.org/compositing-2/#mix-blend-mode">
+<script type="module">
+  import { tests, plusLighter } from '../../support/plus-lighter.js';
+  import { toCSSColor } from '../../support/utils.js';
 
-<style>
-.isolate { isolation: isolate; }
-.original { opacity: 0.6; }
-</style>
-
-<svg width=500 height=500>
-  <g class="isolate">
-    <rect class="original" x="10" y="10" width="100" height="100" fill="#000064"></rect>
-    <rect class="original" x="30" y="65" width="100" height="100" fill="#000064"></rect>
-    <rect class="original" x="50" y="120" width="100" height="100" fill="#006400"></rect>
-    <rect x="30" y="65" width="80" height="45" fill="#000078"></rect>
-    <rect x="50" y="120" width="80" height="45" fill="#003C3C"></rect>
-  </g>
-</svg>
+  for (const colors of tests) {
+    document.body.insertAdjacentHTML('beforeend', `
+      <svg width="100" height="100" style="background-color: ${toCSSColor(plusLighter(colors))}"></svg>
+    `);
+  }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/support/plus-lighter.js b/third_party/blink/web_tests/external/wpt/css/compositing/support/plus-lighter.js
new file mode 100644
index 0000000..cadefa5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/support/plus-lighter.js
@@ -0,0 +1,47 @@
+import { clamp01, multiplyAlpha, unmultiplyAlpha } from "./utils.js";
+
+export function plusLighter(pixels) {
+  if (pixels.length === 1) return pixels[0];
+
+  return pixels.reduce((destination, source) => {
+    const premultipliedSource = multiplyAlpha(source);
+    const premultipliedDestination = multiplyAlpha(destination);
+    const premultipliedResult = premultipliedDestination.map((channel, i) =>
+      clamp01(channel + premultipliedSource[i])
+    );
+    return unmultiplyAlpha(premultipliedResult);
+  });
+}
+
+export const tests = [
+  // Each test is a list of colors to composite.
+  // Each color is [r, g, b, a], unmultiplied, in the range 0-1.
+  [
+    [1, 0, 0, 0.5],
+    [0, 0, 1, 0.5],
+  ],
+  [
+    [1, 0, 0, 0.25],
+    [0, 0, 1, 0.25],
+  ],
+  [
+    [0.5, 0, 0, 0.5],
+    [0, 0, 1, 0.5],
+  ],
+  // Test clamping
+  [
+    [1, 0, 0, 1],
+    [0, 0, 1, 1],
+  ],
+  // Test more than two elements
+  [
+    [0.5, 0, 0, 0.25],
+    [0.25, 0.25, 0, 0.25],
+    [0.25, 0, 0.1, 0.25],
+    [0, 0, 0.1, 0.25],
+  ],
+  // Test a single element
+  [
+    [0.5, 0, 0, 0.25],
+  ],
+];
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/support/utils.js b/third_party/blink/web_tests/external/wpt/css/compositing/support/utils.js
new file mode 100644
index 0000000..eb369ce
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/compositing/support/utils.js
@@ -0,0 +1,31 @@
+export function multiplyAlpha(pixel) {
+  return pixel.map((channel, i) => {
+    // Pass the alpha channel through unchanged
+    if (i === 3) return channel;
+    // Otherwise, multiply by alpha
+    return channel * pixel[3];
+  });
+}
+
+export function unmultiplyAlpha(pixel) {
+  return pixel.map((channel, i) => {
+    // Pass the alpha channel through unchanged
+    if (i === 3) return channel;
+    // Avoid divide-by-zero
+    if (pixel[3] === 0) return channel;
+    // Divide by alpha
+    return channel / pixel[3];
+  });
+}
+
+export function clamp01(value) {
+  if (value < 0) return 0;
+  if (value > 1) return 1;
+  return value;
+}
+
+const toPercent = (num) => `${num * 100}%`;
+export const toCSSColor = (pixel) =>
+  `rgb(${toPercent(pixel[0])} ${toPercent(pixel[1])} ${toPercent(pixel[2])} / ${
+    pixel[3]
+  })`;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/CSSAnimation-effect.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/CSSAnimation-effect.tentative-expected.txt
new file mode 100644
index 0000000..aa98c77
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/CSSAnimation-effect.tentative-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+PASS Setting a null effect on a running animation fires an animationend event
+PASS Replacing an animation's effect with an effect that targets a different property should update both properties
+PASS Replacing an animation's effect with a shorter one that should have already finished, the animation finishes immediately
+PASS A play-pending animation's effect whose effect is replaced still exits the pending state
+PASS CSS animation events are dispatched at the original element even after setting an effect with a different target element
+PASS After replacing a finished animation's effect with a longer one it fires an animationstart event
+FAIL Setting animation-composition sets the composite property on the effect assert_equals: expected "add" but got "replace"
+PASS Replacing the effect of a CSSAnimation causes subsequent changes to corresponding animation-* properties to be ignored
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/CSSAnimation-effect.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/CSSAnimation-effect.tentative.html
index fadcaa1..04812d2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-animations/CSSAnimation-effect.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/CSSAnimation-effect.tentative.html
@@ -133,6 +133,14 @@
 
 test(t => {
   const div = addDiv(t);
+  div.style.animation = 'anim 100s';
+  div.style.animationComposition = 'add';
+  const animation = div.getAnimations()[0];
+  assert_equals(animation.effect.composite, 'add');
+}, 'Setting animation-composition sets the composite property on the effect');
+
+test(t => {
+  const div = addDiv(t);
 
   // Create custom keyframes so we can tweak them
   const stylesheet = document.styleSheets[0];
@@ -161,6 +169,7 @@
   div.style.animationDelay = '8s';
   div.style.animationFillMode = 'both';
   div.style.animationPlayState = 'paused';
+  div.style.animationComposition = 'add';
 
   // Update the keyframes
   keyframesRule.deleteRule(0);
@@ -197,6 +206,11 @@
     '200px',
     'keyframes should be the value set by the API'
   );
+  assert_equals(
+    animation.effect.composite,
+    'replace',
+    'composite should be the value set by the API'
+  );
 
   // Unlike the other properties animation-play-state maps to the Animation
   // not the KeyframeEffect so it should be overridden.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt
index 3b7549d2..ce7f4a74 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt
@@ -4,6 +4,9 @@
 PASS KeyframeEffect.getKeyframes() returns frames with expected easing values, when the easing comes from animation-timing-function on the element
 PASS KeyframeEffect.getKeyframes() returns frames with expected easing values, when the easing is specified on each keyframe
 PASS KeyframeEffect.getKeyframes() returns frames with expected easing values, when the easing is specified on some keyframes
+PASS KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is set on the effect using animation-composition on the element
+FAIL KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is specified on each keyframe assert_equals: value of 'composite' on ComputedKeyframe #0 expected "replace" but got "auto"
+FAIL KeyframeEffect.getKeyframes() returns frames with expected composite values, when the composite is specified on some keyframes assert_equals: value of 'composite' on ComputedKeyframe #0 expected "add" but got "auto"
 PASS KeyframeEffect.getKeyframes() returns expected frames for a simple animation that specifies a single shorthand property
 PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with a 0% keyframe and no 100% keyframe
 PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with a 100% keyframe and no 0% keyframe
@@ -14,6 +17,8 @@
 PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time, and all with the same easing function
 PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time and with different easing functions
 PASS KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time and with different but equivalent easing functions
+FAIL KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time and with different composite operations assert_equals: Number of keyframes should match expected 3 but got 2
+FAIL KeyframeEffect.getKeyframes() returns expected frames for an animation with multiple keyframes for the same time and with different easing functions and composite operations assert_equals: Number of keyframes should match expected 4 but got 3
 PASS KeyframeEffect.getKeyframes() returns expected frames for overlapping keyframes
 FAIL KeyframeEffect.getKeyframes() returns expected values for animations with filter properties and missing keyframes assert_equals: value for 'filter' on Keyframe #1 should match expected "blur(5px) sepia(60%) saturate(30%)" but got "blur(5px) sepia(0.6) saturate(0.3)"
 PASS KeyframeEffect.getKeyframes() returns expected values for animation with drop-shadow of filter property
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative.html
index 1119d06..df319c25 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative.html
@@ -37,7 +37,7 @@
 
 @keyframes anim-simple-timing {
   from { color: rgb(0, 0, 0); animation-timing-function: linear; }
-  50%  { color: rgb(0, 0, 255);  animation-timing-function: ease-in-out; }
+  50%  { color: rgb(0, 0, 255); animation-timing-function: ease-in-out; }
   to   { color: rgb(255, 255, 255); animation-timing-function: step-end; }
 }
 
@@ -47,6 +47,18 @@
   to   { color: rgb(255, 255, 255); }
 }
 
+@keyframes anim-simple-composite {
+  from { color: rgb(0, 0, 0); animation-composition: replace; }
+  50%  { color: rgb(0, 0, 255); animation-composition: add; }
+  to   { color: rgb(255, 255, 255); animation-composition: accumulate; }
+}
+
+@keyframes anim-simple-composite-some {
+  from { color: rgb(0, 0, 0); animation-composition: add; }
+  50%  { color: rgb(0, 0, 255); }
+  to   { color: rgb(255, 255, 255); }
+}
+
 @keyframes anim-simple-shorthand {
   from { margin: 8px; }
   to   { margin: 16px; }
@@ -113,6 +125,28 @@
   to   { margin-top: 20px; margin-right: 20px; margin-bottom: 20px; }
 }
 
+@keyframes anim-merge-offset-and-composite {
+  from { color: rgb(0, 0, 0); animation-composition: add; }
+  to   { color: rgb(255, 255, 255); }
+  from { margin-top: 8px; animation-composition: accumulate; }
+  to   { margin-top: 16px; }
+  from { font-size: 16px; animation-composition: add; }
+  to   { font-size: 32px; }
+  from { padding-left: 2px; animation-composition: accumulate; }
+  to   { padding-left: 4px; }
+}
+
+@keyframes anim-merge-offset-easing-and-composite {
+  from { color: rgb(0, 0, 0); animation-composition: add; }
+  to   { color: rgb(255, 255, 255); }
+  from { margin-top: 8px; animation-composition: accumulate; }
+  to   { margin-top: 16px; }
+  from { font-size: 16px; animation-composition: add; animation-timing-function: linear; }
+  to   { font-size: 32px; }
+  from { padding-left: 2px; animation-composition: accumulate; }
+  to   { padding-left: 4px; }
+}
+
 @keyframes anim-overriding {
   from          { padding-top: 50px }
   50%, from     { padding-top: 30px } /* wins: 0% */
@@ -182,6 +216,12 @@
   "cubic-bezier(0, 0.25, 0.75, 1)"
 ];
 
+const kCompositeValues = [
+  "replace",
+  "add",
+  "accumulate"
+];
+
 test(t => {
   const div = addDiv(t);
 
@@ -272,6 +312,58 @@
    + ' values, when the easing is specified on some keyframes');
 
 test(t => {
+  for (const composite of kCompositeValues) {
+    const div = addDiv(t);
+
+    div.style.animation = 'anim-simple-three 100s';
+    div.style.animationComposition = composite;
+    const frames = getKeyframes(div);
+
+    assert_equals(frames.length, 3, "number of frames");
+
+    for (let i = 0; i < frames.length; i++) {
+      assert_equals(frames[i].composite, "auto",
+                    "value for 'composite' on ComputedKeyframe #" + i);
+    }
+  }
+}, 'KeyframeEffect.getKeyframes() returns frames with expected composite'
+   + ' values, when the composite is set on the effect using animation-composition on the'
+   + ' element');
+
+test(t => {
+  const div = addDiv(t);
+
+  div.style.animation = 'anim-simple-composite 100s';
+  const frames = getKeyframes(div);
+
+  assert_equals(frames.length, 3, "number of frames");
+  assert_equals(frames[0].composite, "replace",
+                "value of 'composite' on ComputedKeyframe #0");
+  assert_equals(frames[1].composite, "add",
+                "value of 'composite' on ComputedKeyframe #1");
+  assert_equals(frames[2].composite, "accumulate",
+                "value of 'composite' on ComputedKeyframe #2");
+}, 'KeyframeEffect.getKeyframes() returns frames with expected composite'
+   + ' values, when the composite is specified on each keyframe');
+
+test(t => {
+  const div = addDiv(t);
+
+  div.style.animation = 'anim-simple-composite-some 100s';
+  div.style.animationComposition = 'accumulate';
+  const frames = getKeyframes(div);
+
+  assert_equals(frames.length, 3, "number of frames");
+  assert_equals(frames[0].composite, "add",
+                "value of 'composite' on ComputedKeyframe #0");
+  assert_equals(frames[1].composite, "auto",
+                "value of 'composite' on ComputedKeyframe #1");
+  assert_equals(frames[2].composite, "auto",
+                "value of 'composite' on ComputedKeyframe #2");
+}, 'KeyframeEffect.getKeyframes() returns frames with expected composite'
+   + ' values, when the composite is specified on some keyframes');
+
+test(t => {
   const div = addDiv(t);
   div.style.animation = 'anim-simple-shorthand 100s';
 
@@ -460,6 +552,48 @@
 
 test(t => {
   const div = addDiv(t);
+  div.style.animation = 'anim-merge-offset-and-composite 100s';
+
+  const frames = getKeyframes(div);
+
+  const expected = [
+    { offset: 0, computedOffset: 0, easing: "ease", composite: "add",
+      color: "rgb(0, 0, 0)", fontSize: "16px" },
+    { offset: 0, computedOffset: 0, easing: "ease", composite: "accumulate",
+      marginTop: "8px", paddingLeft: "2px" },
+    { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
+      color: "rgb(255, 255, 255)", fontSize: "32px", marginTop: "16px",
+      paddingLeft: "4px" },
+  ];
+  assert_frame_lists_equal(frames, expected);
+}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
+   'animation with multiple keyframes for the same time and with ' +
+   'different composite operations');
+
+test(t => {
+  const div = addDiv(t);
+  div.style.animation = 'anim-merge-offset-easing-and-composite 100s';
+
+  const frames = getKeyframes(div);
+
+  const expected = [
+    { offset: 0, computedOffset: 0, easing: "ease", composite: "add",
+      color: "rgb(0, 0, 0)" },
+    { offset: 0, computedOffset: 0, easing: "ease", composite: "accumulate",
+      marginTop: "8px", paddingLeft: "2px" },
+    { offset: 0, computedOffset: 0, easing: "linear", composite: "add",
+      fontSize: "16px" },
+    { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
+      color: "rgb(255, 255, 255)", fontSize: "32px", marginTop: "16px",
+      paddingLeft: "4px" },
+  ];
+  assert_frame_lists_equal(frames, expected);
+}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
+   'animation with multiple keyframes for the same time and with ' +
+   'different easing functions and composite operations');
+
+test(t => {
+  const div = addDiv(t);
   div.style.animation = 'anim-overriding 100s';
 
   const frames = getKeyframes(div);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-computed.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-computed.tentative-expected.txt
new file mode 100644
index 0000000..44d81d1b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-computed.tentative-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Property animation-composition value 'replace, add, accumulate' assert_true: animation-composition doesn't seem to be supported in the computed style expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-computed.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-computed.tentative.html
new file mode 100644
index 0000000..535a40c9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-computed.tentative.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Animations: getComputedStyle().animationComposition</title>
+<link rel="help" href="https://drafts.csswg.org/css-animations-2/#propdef-animation-composition">
+<meta name="assert" content="animation-composition computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value("animation-composition", "replace, add, accumulate");
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-invalid.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-invalid.tentative.html
new file mode 100644
index 0000000..a08b33c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-invalid.tentative.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Animations: parsing animation-composition with invalid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-animations-2/#propdef-animation-composition">
+<meta name="assert" content="animation-composition supports only the grammar '<single-animation-composition> #'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value("animation-composition", "auto");
+test_invalid_value("animation-composition", "add replace");
+
+test_invalid_value("animation-composition", "add, initial");
+test_invalid_value("animation-composition", "initial, add");
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-valid.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-valid.tentative-expected.txt
new file mode 100644
index 0000000..0f58883c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-valid.tentative-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL e.style['animation-composition'] = "replace" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['animation-composition'] = "add" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['animation-composition'] = "accumulate" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['animation-composition'] = "replace, add, accumulate" should set the property value assert_not_equals: property should be set got disallowed value ""
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-valid.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-valid.tentative.html
new file mode 100644
index 0000000..8dca8dba
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-composition-valid.tentative.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Animations: parsing animation-composition with valid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-animations-2/#propdef-animation-composition">
+<meta name="assert" content="animation-composition supports the full grammar '<single-animation-composition> #'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value("animation-composition", "replace");
+test_valid_value("animation-composition", "add");
+test_valid_value("animation-composition", "accumulate");
+test_valid_value("animation-composition", "replace, add, accumulate");
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/fieldset-inset-shadow-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/fieldset-inset-shadow-ref.html
new file mode 100644
index 0000000..6b4b9e57
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/fieldset-inset-shadow-ref.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<style>
+  div {
+    width: 100px;
+    height: 100px;
+    box-sizing: border-box;
+    box-shadow: 0 0 0 10px inset black;
+  }
+</style>
+<div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/fieldset-inset-shadow.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/fieldset-inset-shadow.html
new file mode 100644
index 0000000..cb13cd8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/fieldset-inset-shadow.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>inset box shadow works on fieldset</title>
+<link rel=help href="https://drafts.csswg.org/css-backgrounds/#box-shadow">
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1750276">
+<link rel=author title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel=author title="Mozilla" href="https://mozilla.org">
+<link rel=match href="fieldset-inset-shadow-ref.html">
+<style>
+  fieldset {
+    width: 100px;
+    height: 100px;
+    border: none;
+    margin: 0;
+    box-sizing: border-box;
+    box-shadow: 0 0 0 10px inset black;
+  }
+</style>
+<fieldset></fieldset>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/idlharness.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/idlharness.html
index 80d3318..9bde23b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-cascade/idlharness.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/idlharness.html
@@ -15,7 +15,7 @@
 <script>
   'use strict';
   idl_test(
-    ['css-cascade-5'],
+    ['css-cascade'],
     ['cssom'],
     idl_array => {
       try {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-003-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-003-expected.txt
new file mode 100644
index 0000000..47dc2b2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-003-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS contents for selector ['auto']
+PASS contents for selector ['_abcd']
+PASS expected empty selector when assigning blank string
+FAIL CSS Paged Media: parsing @page selectors assert_equals: missing @page selectors expected 0 but got 7
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-003.html b/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-003.html
new file mode 100644
index 0000000..aaf0bbb1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-003.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Paged Media: parsing @page selectors</title>
+<link rel="author" title="Mozilla" href="https://mozilla.org"/>
+<link rel="help" href="https://drafts.csswg.org/css-page/#page-selectors"/>
+<meta name="assert" content="Test that @page selectors are parsed correctly.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+    @page a, B {
+        size: 1in;
+    }
+    @page A,b,C {
+        size: 2in;
+    }
+    @page auto {
+        size: 3in;
+    }
+    @page something, auto {
+        size: 4in;
+    }
+    @page auto, other_thing {
+        size: 5in;
+    }
+    @page _a, Z {
+        size: 6in;
+    }
+    @page -b, y {
+        size: 7in;
+    }
+    @page _abcd {
+        size: 8in;
+    }
+    @page n,-XYZ {
+        size: 9in;
+    }
+</style>
+
+<script>
+    let expectedForSelector = {
+        "a, B" : "size: 1in;",
+        "A, b, C" : "size: 2in;",
+        "auto" : "size: 3in;",
+        "something, auto" : "size: 4in;",
+        "auto, other_thing" : "size: 5in;",
+        "_a, Z" : "size: 6in;",
+        "-b, y" : "size: 7in;",
+        "_abcd" : "size: 8in;",
+        "n, -XYZ" : "size: 9in;"
+    };
+    let styleSheets = document.styleSheets;
+    for (let sheet of styleSheets) {
+        let rules = sheet.cssRules;
+        for (let rule of rules) {
+            if (rule.type == CSSRule.PAGE_RULE) {
+                let expected = expectedForSelector[rule.selectorText];
+                test(function(){
+                    assert_equals(rule.style.cssText, expected, "unexpected @page contents");
+                }, "contents for selector ['" + rule.selectorText + "']");
+                delete expectedForSelector[rule.selectorText];
+            }
+        }
+    }
+    // Validate that we can assign an empty selector
+    test(function() {
+        let rule = styleSheets[0].cssRules[0];
+        assert_equals(rule.type, CSSRule.PAGE_RULE, "expected first rule to be @page");
+        rule.selectorText = "";
+        assert_equals(rule.selectorText, "", "unexpected selector when assigning blank string");
+    }, "expected empty selector when assigning blank string");
+    test(function() {
+        assert_equals(Object.keys(expectedForSelector).length, 0, "missing @page selectors");
+    });
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-004-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-004-expected.txt
new file mode 100644
index 0000000..e65d05c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-004-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL rule with invalid selector ['--a'] assert_not_equals: no @page rule should have been parsed got disallowed value 6
+PASS adding a blank @page rule
+PASS assigning invalid selector text ['1']
+PASS assigning invalid selector text ['-3']
+FAIL assigning invalid selector text ['--a'] assert_equals: should not be able to assign an invalid selector expected "" but got "--a"
+PASS assigning invalid selector text ['7cm']
+PASS assigning invalid selector text ['0.17']
+PASS assigning invalid selector text ['a, 123']
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-004.html b/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-004.html
new file mode 100644
index 0000000..94d0f82
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-page/page-rule-declarations-004.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Paged Media: parsing invalid @page selectors</title>
+<link rel="author" title="Mozilla" href="https://mozilla.org"/>
+<link rel="help" href="https://drafts.csswg.org/css-page/#page-selectors"/>
+<meta name="assert" content="Test that @page selectors are parsed correctly.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+    @page 1 {
+        size: 1in;
+    }
+    @page -3 {
+        size: 2in;
+    }
+    @page --a {
+        size: 3in;
+    }
+    @page 7cm {
+        size: 4in;
+    }
+    @page 0.17 {
+        size: 5in;
+    }
+    @page a, 123 {
+        size: 6in;
+    }
+</style>
+
+<script>
+    const invalidSelectorTexts = [
+        "1",
+        "-3",
+        "--a",
+        "7cm",
+        "0.17",
+        "a, 123",
+    ];
+
+    let styleSheets = document.styleSheets;
+    for (let sheet of styleSheets) {
+        for (let rule of sheet.cssRules) {
+            test(function(){
+                assert_not_equals(rule.type, CSSRule.PAGE_RULE,
+                    "no @page rule should have been parsed");
+            }, "rule with invalid selector ['" + rule.selectorText + "']");
+        }
+    }
+
+    let ruleIndex = styleSheets[0].insertRule("@page{}");
+    let rule = styleSheets[0].cssRules[ruleIndex];
+    test(function() {
+        assert_equals(rule.selectorText, "", "Initial selector text should have been empty");
+        assert_equals(rule.type, CSSRule.PAGE_RULE, "unexpected rule type (not @page)");
+    }, "adding a blank @page rule");
+    for (let selectorText of invalidSelectorTexts){
+        test(function() {
+            // Clear the selector first
+            rule.selectorText = "";
+            rule.selectorText = selectorText;
+            assert_equals(rule.selectorText, "",
+                "should not be able to assign an invalid selector");
+        }, "assigning invalid selector text ['" + selectorText + "']");
+    }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/idlharness-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-pseudo/idlharness-expected.txt
index 46168b2..f76169b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/idlharness-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/idlharness-expected.txt
@@ -15,10 +15,15 @@
 FAIL CSSPseudoElement interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
 FAIL CSSPseudoElement interface: attribute type assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
 FAIL CSSPseudoElement interface: attribute element assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: attribute parent assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: operation pseudo(CSSOMString) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
 FAIL CSSPseudoElement must be primary interface of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
 FAIL Stringification of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
 FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "type" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
 FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "element" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "parent" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "pseudo(CSSOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: calling pseudo(CSSOMString) on beforeElements.item(0) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
 FAIL Element interface: operation pseudo(CSSOMString) assert_own_property: interface prototype object missing non-static operation expected property "pseudo" missing
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-line-height-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-line-height-ref.html
index 64b0d41..a32fb812 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-line-height-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-line-height-ref.html
@@ -3,6 +3,7 @@
 <title>CSS Reftest Reference</title>
 <link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
 <style>
+::marker { font-family: inherit; }
 ol {
   float: left;
   width: 50px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-line-height.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-line-height.html
index 8d226e3f..ee32f3b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-line-height.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-line-height.html
@@ -7,6 +7,7 @@
 <link rel="match" href="marker-line-height-ref.html">
 <meta name="assert" content="Checks that ::marker supports 'line-height', both explicitly set or inherited from an ancestor">
 <style>
+::marker { font-family: inherit; }
 ol {
   float: left;
   width: 50px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-expected.txt
index 3b1189ccd..6f50353 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 61 tests; 59 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 62 tests; 59 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Property font value 'italic small-caps 900 expanded 25px / 50px Ahem' in ::marker
 PASS Property font-family value 'Ahem' in ::marker
 PASS Property font-feature-settings value '"smcp"' in ::marker
@@ -35,6 +35,7 @@
 PASS Property animation-name value 'anim' in ::marker
 PASS Property animation-play-state value 'paused' in ::marker
 PASS Property animation-timing-function value 'linear' in ::marker
+FAIL Property animation-composition value 'add' in ::marker assert_true: animation-composition doesn't seem to be supported in the computed style expected true got false
 PASS Property transition value 'display 1s linear 2s' in ::marker
 PASS Property transition-delay value '1s' in ::marker
 PASS Property transition-duration value '2s' in ::marker
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties.html
index ab03b98..700d04aa 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/parsing/marker-supported-properties.html
@@ -61,6 +61,7 @@
 test_pseudo_computed_value("::marker", "animation-name", "anim");
 test_pseudo_computed_value("::marker", "animation-play-state", "paused");
 test_pseudo_computed_value("::marker", "animation-timing-function", "linear");
+test_pseudo_computed_value("::marker", "animation-composition", "add");
 
 // ::marker supports transition properties.
 test_pseudo_computed_value("::marker", "transition", "display 1s linear 2s");
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/resources/testhelper.js b/third_party/blink/web_tests/external/wpt/css/css-typed-om/resources/testhelper.js
index e4b0ddb..2792ee51 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/resources/testhelper.js
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/resources/testhelper.js
@@ -144,6 +144,17 @@
   return element;
 }
 
+// Creates a new div element without inline style.
+// The created element is deleted during test cleanup.
+function createDivWithoutStyle(test) {
+  let element = document.createElement('div');
+  document.body.appendChild(element);
+  test.add_cleanup(() => {
+    element.remove();
+  });
+  return element;
+}
+
 // Creates a new div element with inline style |cssText| and returns
 // its inline style property map.
 function createInlineStyleMap(test, cssText) {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/get-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/get-shorthand.html
index 0355e39..6ce318d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/get-shorthand.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/get-shorthand.html
@@ -27,4 +27,10 @@
 }, 'Getting a shorthand property that is partially set in inline style ' +
    'returns null');
 
+test(t => {
+  const styleMap = createDivWithoutStyle(t).attributeStyleMap;
+  assert_equals(styleMap.get('margin'), null,
+    'Shorthand value must be null for element without style');
+}, 'Getting an attributeStyleMap shorthand property from an element without ' +
+   'a style attribute');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/viewport-units-parsing-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-values/viewport-units-parsing-expected.txt
new file mode 100644
index 0000000..3984c7c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/viewport-units-parsing-expected.txt
@@ -0,0 +1,27 @@
+This is a testharness.js-based test.
+PASS e.style['width'] = "1vw" should set the property value
+PASS e.style['width'] = "1vh" should set the property value
+FAIL e.style['width'] = "1vi" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1vb" should set the property value assert_not_equals: property should be set got disallowed value ""
+PASS e.style['width'] = "1vmin" should set the property value
+PASS e.style['width'] = "1vmax" should set the property value
+FAIL e.style['width'] = "1svw" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1svh" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1svi" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1svb" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1svmin" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1svmax" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1lvw" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1lvh" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1lvi" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1lvb" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1lvmin" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1lvmax" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1dvw" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1dvh" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1dvi" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1dvb" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1dvmin" should set the property value assert_not_equals: property should be set got disallowed value ""
+FAIL e.style['width'] = "1dvmax" should set the property value assert_not_equals: property should be set got disallowed value ""
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/viewport-units-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-values/viewport-units-parsing.html
new file mode 100644
index 0000000..4373b2a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/viewport-units-parsing.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Values: parsing width with valid viewport units</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+const prefixes = ["", "s", "l", "d"];
+const suffixes = ["vw", "vh", "vi", "vb", "vmin", "vmax"];
+const units = [];
+
+for (const prefix of prefixes) {
+  for (const suffix of suffixes) {
+    units.push(prefix + suffix);
+  }
+}
+
+for (const unit of units) {
+  test_valid_value("width", "1" + unit);
+}
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-001.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-001.html
index 24ebd9f..a88f181 100644
--- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-001.html
@@ -18,6 +18,9 @@
 			@media not and {
 				div { background-color: red; }
 			}
+			@media and {
+				div { background-color: red; }
+			}
 	</style>
 	</head>
 	<body>
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-002.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-002.html
index 71f597e..763a7f29 100644
--- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-002.html
+++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-002.html
@@ -18,6 +18,9 @@
 			@media not or {
 				div { background-color: red; }
 			}
+			@media or {
+				div { background-color: red; }
+			}
 	</style>
 	</head>
 	<body>
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-003.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-003.html
index b12bd758..acc524c 100644
--- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-003.html
+++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-003.html
@@ -18,6 +18,9 @@
 			@media not not {
 				div { background-color: red; }
 			}
+			@media not {
+				div { background-color: red; }
+			}
 	</style>
 	</head>
 	<body>
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-004.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-004.html
index d039281c..689c8d1a78 100644
--- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-004.html
+++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-004.html
@@ -18,6 +18,9 @@
 			@media not only {
 				div { background-color: red; }
 			}
+			@media only {
+				div { background-color: red; }
+			}
 	</style>
 	</head>
 	<body>
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-005.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-005.html
new file mode 100644
index 0000000..3e25a248
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/mq-invalid-media-type-005.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<title>Mediaqueries-3 test: parsing hanging-punctuation with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#error-handling">
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<meta name="flags" content="invalid">
+<meta name="assert" content="media types ''not'', ''and'', ''only'' and ''or'' must not be treated as unknown media types, but rather trigger the malformed query clause.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+    @media not and {
+        div { background-color: red; }
+    }
+    @media and {
+        div { background-color: red; }
+    }
+    @media not or {
+        div { background-color: red; }
+    }
+    @media or {
+        div { background-color: red; }
+    }
+    @media not not {
+        div { background-color: red; }
+    }
+    @media not {
+        div { background-color: red; }
+    }
+    @media not only {
+        div { background-color: red; }
+    }
+    @media only {
+        div { background-color: red; }
+    }
+</style>
+<script>
+var queries = document.styleSheets[0].cssRules;
+test(() => {
+        for (const query of queries) {
+                assert_equals(query.conditionText, "not all");
+        }
+        assert_equals(queries.length, 8, "invalid rules must be treated as 'not all', not dropped");
+    }, "syntactical MQ keywords used as media types are a syntax error");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/has-specificity-01.html b/third_party/blink/web_tests/external/wpt/css/selectors/has-specificity-01.html
new file mode 100644
index 0000000..b33e3a0e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/has-specificity-01.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<title>Specificity for complex :has selectors</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/selectors/#specificity-rules">
+<style>
+  main :has(#foo) { --t0:PASS; }
+  main :has(.foo) { --t0:FAIL; }
+
+  main :has(span#foo) { --t1:PASS; }
+  main :has(#foo) { --t1:FAIL; }
+
+  main :has(.bar, #foo) { --t2:FAIL; }
+  main :has(#foo, .bar) { --t2:PASS; }
+
+  main :has(.bar, #foo) { --t3:PASS; }
+  main :has(.foo, .bar) { --t3:FAIL; }
+
+  main :has(span + span) { --t4:PASS; }
+  main :has(span) { --t4:FAIL; }
+
+  main :has(span, li, #foo) { --t5:PASS; }
+  main :has(span, li, p) { --t5:FAIL; }
+</style>
+<main id=main>
+  <div id=div><p><span id=foo class=foo></span><span class=bar></span><li></li></p></div>
+</main>
+<script>
+  function test_value(name, description) {
+    test(function() {
+      let actual = getComputedStyle(div).getPropertyValue(name);
+      assert_equals(actual, 'PASS');
+    }, description);
+  }
+
+  test_value('--t0', ':has(#foo) wins over :has(.foo)');
+  test_value('--t1', ':has(span#foo) wins over :has(#foo)');
+  test_value('--t2', ':has(.bar, #foo) has same specificity as :has(#foo, .bar)');
+  test_value('--t3', ':has(.bar, #foo) wins over :has(.foo, .bar)');
+  test_value('--t4', ':has(span + span) wins over :has(span)');
+  test_value('--t5', ':has(span, li, p) wins over :has(span, lo, p)');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/has-specificity.html b/third_party/blink/web_tests/external/wpt/css/selectors/has-specificity.html
deleted file mode 100644
index 186d35fd..0000000
--- a/third_party/blink/web_tests/external/wpt/css/selectors/has-specificity.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>:has() pseudo class specificity</title>
-<link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.com">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
-
-<style>
-  .subject:has(.a.c) {
-    color: green
-  }
-  .subject:has(.b.c) {
-    color: blue
-  }
-  .subject:has(.c) {
-    color: red
-  }
-  .subject:has(child1 + child2) {
-    color: green
-  }
-  .subject:has(child3) {
-    color: red
-  }
-</style>
-<main>
-  <div id=subject1 class=subject>
-    <div class="a b c"></div>
-  </div>
-  <div id=subject2 class=subject>
-    <div class="a c"></div>
-  </div>
-  <div id=subject3 class=subject>
-    <div class="b c"></div>
-  </div>
-  <div id=subject4 class=subject>
-    <child1></child1><child2></child2><child3></child3>
-  </div>
-</main>
-<script>
-  function test_color(test_name, subject, color) {
-    test(function() {
-      assert_equals(getComputedStyle(subject).color, color);
-    }, test_name);
-  }
-
-  test_color(':has(.c) < :has(.a.c) == :has(.b.c), so :has(.b.c) wins', subject1, "rgb(0, 0, 255)");
-  test_color(':has(.c) < :has(.a.c), so :has(.a.c) wins', subject2, "rgb(0, 128, 0)");
-  test_color(':has(.c) < :has(.b.c), so :has(.b.c) wins', subject3, "rgb(0, 0, 255)");
-  test_color(':has(child3) < :has(child1 + child2), so :has(child1 + child2) wins', subject4, "rgb(0, 128, 0)");
-</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/has-with-not.html b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/has-with-not.html
new file mode 100644
index 0000000..b67ec5e3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/has-with-not.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Selector Invalidation: :has() with :not()</title>
+<link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
+<style>
+div, main { color: grey }
+#subject:has(:not(.test)) { color: green }
+#subject:has(.test :not(.test)) { color: red }
+</style>
+
+<main id=main>
+    <div id=subject>
+        <div id=subject_child class=test>
+            <div id=subject_descendant class=test></div>
+        </div>
+    </div>
+</main>
+
+<script>
+const grey = 'rgb(128, 128, 128)';
+const red = 'rgb(255, 0, 0)';
+const green = 'rgb(0, 128, 0)';
+const blue = 'rgb(0, 0, 255)';
+
+function testColor(test_name, color) {
+    test(function() {
+        assert_equals(getComputedStyle(subject).color, color);
+    }, test_name);
+}
+
+function testClassChange(element, expectedColor)
+{
+    element.classList.remove('test');
+    testColor(`remove .test to ${element.id}`, expectedColor);
+    element.classList.add('test');
+    testColor(`add .test from ${element.id}`, grey);
+}
+
+function testElementInsertionBefore(beforeElement, expectedColor)
+{
+    const newElement = document.createElement('div');
+
+    beforeElement.before(newElement);
+    testColor(`insert element div before ${beforeElement.id}`, expectedColor);
+
+    newElement.remove();
+    testColor(`remove element div before ${beforeElement.id}`, grey);
+}
+
+function testElementInsertionAfter(afterElement, expectedColor)
+{
+    const newElement = document.createElement('div');
+
+    afterElement.after(newElement);
+    testColor(`insert element div after ${afterElement.id}`, expectedColor);
+
+    newElement.remove();
+    testColor(`remove element div after ${afterElement.id}`, grey);
+}
+
+function testTreeInsertionBefore(beforeElement, expectedColor)
+{
+    const newElement = document.createElement('div');
+    const newChild = document.createElement('div');
+    newElement.appendChild(newChild);
+
+    beforeElement.before(newElement);
+    testColor(`insert tree div>div before ${beforeElement.id}`, expectedColor);
+
+    newElement.remove();
+    testColor(`remove tree div>div before ${beforeElement.id}`, grey);
+}
+
+function testTreeInsertionAfter(afterElement, expectedColor)
+{
+    const newElement = document.createElement('div');
+    const newChild = document.createElement('div');
+    newElement.appendChild(newChild);
+
+    afterElement.after(newElement);
+    testColor(`insert tree div.test after ${afterElement.id}`, expectedColor);
+
+    newElement.remove();
+    testColor(`remove tree div.test after ${afterElement.id}`, grey);
+}
+
+testColor('Initial color', grey);
+
+testClassChange(subject_child, green);
+testClassChange(subject_descendant, red);
+
+testElementInsertionBefore(subject_child, green);
+testElementInsertionBefore(subject_descendant, red);
+
+testElementInsertionAfter(subject_child, green);
+testElementInsertionAfter(subject_descendant, red);
+
+testTreeInsertionBefore(subject_child, green);
+testTreeInsertionBefore(subject_descendant, red);
+
+testTreeInsertionAfter(subject_child, green);
+testTreeInsertionAfter(subject_descendant, red);
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/EventListener-handleEvent-cross-realm-expected.txt b/third_party/blink/web_tests/external/wpt/dom/events/EventListener-handleEvent-cross-realm-expected.txt
new file mode 100644
index 0000000..bbda97d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/dom/events/EventListener-handleEvent-cross-realm-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL EventListener is cross-realm plain object without 'handleEvent' property assert_equals: expected "object" but got "undefined"
+FAIL EventListener is cross-realm plain object with non-callable 'handleEvent' property assert_equals: expected "object" but got "undefined"
+PASS EventListener is cross-realm plain object with revoked Proxy as 'handleEvent' property
+FAIL EventListener is cross-realm non-callable revoked Proxy assert_equals: expected "object" but got "undefined"
+PASS EventListener is cross-realm callable revoked Proxy
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/EventListener-handleEvent-cross-realm.html b/third_party/blink/web_tests/external/wpt/dom/events/EventListener-handleEvent-cross-realm.html
new file mode 100644
index 0000000..663d042
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/dom/events/EventListener-handleEvent-cross-realm.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Cross-realm EventListener throws TypeError of its associated Realm</title>
+<link rel="help" href="https://webidl.spec.whatwg.org/#ref-for-prepare-to-run-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<iframe name="eventListenerGlobalObject" src="resources/empty-document.html"></iframe>
+
+<script>
+setup({ allow_uncaught_exception: true });
+
+test_onload(() => {
+    const eventTarget = new EventTarget;
+    const eventListener = new eventListenerGlobalObject.Object;
+
+    eventTarget.addEventListener("foo", eventListener);
+    assert_reports_exception(eventListenerGlobalObject.TypeError, () => { eventTarget.dispatchEvent(new Event("foo")); });
+}, "EventListener is cross-realm plain object without 'handleEvent' property");
+
+test_onload(() => {
+    const eventTarget = new EventTarget;
+    const eventListener = new eventListenerGlobalObject.Object;
+    eventListener.handleEvent = {};
+
+    eventTarget.addEventListener("foo", eventListener);
+    assert_reports_exception(eventListenerGlobalObject.TypeError, () => { eventTarget.dispatchEvent(new Event("foo")); });
+}, "EventListener is cross-realm plain object with non-callable 'handleEvent' property");
+
+test_onload(() => {
+    const eventTarget = new EventTarget;
+    const { proxy, revoke } = Proxy.revocable(() => {}, {});
+    revoke();
+
+    const eventListener = new eventListenerGlobalObject.Object;
+    eventListener.handleEvent = proxy;
+
+    eventTarget.addEventListener("foo", eventListener);
+    assert_reports_exception(eventListenerGlobalObject.TypeError, () => { eventTarget.dispatchEvent(new Event("foo")); });
+}, "EventListener is cross-realm plain object with revoked Proxy as 'handleEvent' property");
+
+test_onload(() => {
+    const eventTarget = new EventTarget;
+    const { proxy, revoke } = eventListenerGlobalObject.Proxy.revocable({}, {});
+    revoke();
+
+    eventTarget.addEventListener("foo", proxy);
+    assert_reports_exception(eventListenerGlobalObject.TypeError, () => { eventTarget.dispatchEvent(new Event("foo")); });
+}, "EventListener is cross-realm non-callable revoked Proxy");
+
+test_onload(() => {
+    const eventTarget = new EventTarget;
+    const { proxy, revoke } = eventListenerGlobalObject.Proxy.revocable(() => {}, {});
+    revoke();
+
+    eventTarget.addEventListener("foo", proxy);
+    assert_reports_exception(eventListenerGlobalObject.TypeError, () => { eventTarget.dispatchEvent(new Event("foo")); });
+}, "EventListener is cross-realm callable revoked Proxy");
+
+function test_onload(fn, desc) {
+    async_test(t => { window.addEventListener("load", t.step_func_done(fn)); }, desc);
+}
+
+function assert_reports_exception(expectedConstructor, fn) {
+    let error;
+    const onErrorHandler = event => { error = event.error; };
+
+    eventListenerGlobalObject.addEventListener("error", onErrorHandler);
+    fn();
+    eventListenerGlobalObject.removeEventListener("error", onErrorHandler);
+
+    assert_equals(typeof error, "object");
+    assert_equals(error.constructor, expectedConstructor);
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/event-global-set-before-handleEvent-lookup.any.js b/third_party/blink/web_tests/external/wpt/dom/events/event-global-set-before-handleEvent-lookup.any.js
deleted file mode 100644
index 5199cc7d6..0000000
--- a/third_party/blink/web_tests/external/wpt/dom/events/event-global-set-before-handleEvent-lookup.any.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke (steps 8.2 - 12)
-// https://webidl.spec.whatwg.org/#call-a-user-objects-operation (step 10.1)
-
-test(() => {
-  const eventTarget = new EventTarget;
-
-  let currentEvent;
-  eventTarget.addEventListener("foo", {
-    get handleEvent() {
-      currentEvent = self.event;
-      return () => {};
-    }
-  });
-
-  const event = new Event("foo");
-  eventTarget.dispatchEvent(event);
-
-  assert_equals(currentEvent, event);
-}, "self.event is set before 'handleEvent' lookup");
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/event-global-set-before-handleEvent-lookup.window.js b/third_party/blink/web_tests/external/wpt/dom/events/event-global-set-before-handleEvent-lookup.window.js
new file mode 100644
index 0000000..8f934bce
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/dom/events/event-global-set-before-handleEvent-lookup.window.js
@@ -0,0 +1,19 @@
+// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke (steps 8.2 - 12)
+// https://webidl.spec.whatwg.org/#call-a-user-objects-operation (step 10.1)
+
+test(() => {
+  const eventTarget = new EventTarget;
+
+  let currentEvent;
+  eventTarget.addEventListener("foo", {
+    get handleEvent() {
+      currentEvent = window.event;
+      return () => {};
+    }
+  });
+
+  const event = new Event("foo");
+  eventTarget.dispatchEvent(event);
+
+  assert_equals(currentEvent, event);
+}, "window.event is set before 'handleEvent' lookup");
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/resources/empty-document.html b/third_party/blink/web_tests/external/wpt/dom/events/resources/empty-document.html
new file mode 100644
index 0000000..b9cd130
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/dom/events/resources/empty-document.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<body>
diff --git a/third_party/blink/web_tests/external/wpt/dom/idlharness-shadowrealm.window-expected.txt b/third_party/blink/web_tests/external/wpt/dom/idlharness-shadowrealm.window-expected.txt
new file mode 100644
index 0000000..2db45e1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/dom/idlharness-shadowrealm.window-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = ReferenceError: ShadowRealm is not defined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/dom/idlharness-shadowrealm.window.js b/third_party/blink/web_tests/external/wpt/dom/idlharness-shadowrealm.window.js
new file mode 100644
index 0000000..cb03c07c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/dom/idlharness-shadowrealm.window.js
@@ -0,0 +1,2 @@
+// META: script=/resources/idlharness-shadowrealm.js
+idl_test_shadowrealm(["dom"], ["html"]);
diff --git a/third_party/blink/web_tests/external/wpt/dom/idlharness.window_exclude=Node-expected.txt b/third_party/blink/web_tests/external/wpt/dom/idlharness.window_exclude=Node-expected.txt
index 12920ef..d224b4c 100644
--- a/third_party/blink/web_tests/external/wpt/dom/idlharness.window_exclude=Node-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/dom/idlharness.window_exclude=Node-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 1290 tests; 1287 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 1292 tests; 1289 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Partial interface Window: original interface defined
@@ -194,6 +194,7 @@
 PASS AbortSignal interface: operation abort(optional any)
 PASS AbortSignal interface: attribute aborted
 PASS AbortSignal interface: attribute reason
+PASS AbortSignal interface: operation throwIfAborted()
 PASS AbortSignal interface: attribute onabort
 PASS AbortSignal must be primary interface of new AbortController().signal
 PASS Stringification of new AbortController().signal
@@ -201,6 +202,7 @@
 PASS AbortSignal interface: calling abort(optional any) on new AbortController().signal with too few arguments must throw TypeError
 PASS AbortSignal interface: new AbortController().signal must inherit property "aborted" with the proper type
 PASS AbortSignal interface: new AbortController().signal must inherit property "reason" with the proper type
+PASS AbortSignal interface: new AbortController().signal must inherit property "throwIfAborted()" with the proper type
 PASS AbortSignal interface: new AbortController().signal must inherit property "onabort" with the proper type
 PASS EventTarget interface: new AbortController().signal must inherit property "addEventListener(DOMString, EventListener?, optional (AddEventListenerOptions or boolean))" with the proper type
 PASS EventTarget interface: calling addEventListener(DOMString, EventListener?, optional (AddEventListenerOptions or boolean)) on new AbortController().signal with too few arguments must throw TypeError
diff --git a/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-expected.txt b/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-expected.txt
deleted file mode 100644
index 7948b1b..0000000
--- a/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-PASS parent's |this|, parent's method, parent's filter, parent's root
-PASS parent's |this|, parent's method, parent's filter, iframe's root
-FAIL parent's |this|, parent's method, iframe's filter, iframe's root assert_equals: expected function "function TypeError() { [native code] }" but got function "function TypeError() { [native code] }"
-PASS parent's |this|, iframes's method, iframe's filter, iframe's root
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context-expected.txt b/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context-expected.txt
deleted file mode 100644
index e9ed6f0..0000000
--- a/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL TreeWalker: NodeFilter from detached iframe works as expected Failed to execute 'acceptNode' on 'NodeFilter': The provided callback is no longer runnable.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context.html b/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context.html
index 4d6bb532..f8e71bc 100644
--- a/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context.html
+++ b/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context.html
@@ -1,11 +1,12 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
-<title>TreeWalker: NodeFilter from detached iframe works as expected</title>
-<link rel="help" href="https://dom.spec.whatwg.org/#ref-for-call-a-user-objects-operation%E2%91%A0">
+<title>TreeWalker: NodeFilter from detached iframe doesn't get called</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <body>
+<div></div>
+
 <script>
 const t = async_test();
 
@@ -16,8 +17,13 @@
     iframe.remove();
 
     assert_equals(iframe.contentWindow, null);
-    assert_equals(nodeIterator.nextNode(), document.body);
-    assert_true(nodeIterator.dummyFilterCalled);
+
+    let errorWasThrown = false;
+    try { nodeIterator.nextNode(); }
+    catch { errorWasThrown = true; }
+
+    assert_true(errorWasThrown);
+    assert_false(nodeIterator.dummyFilterCalled);
 });
 
 document.body.append(iframe);
diff --git a/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm.html b/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm.html
index 60a80d31..da91cf6c 100644
--- a/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm.html
+++ b/third_party/blink/web_tests/external/wpt/dom/traversal/TreeWalker-acceptNode-filter-cross-realm.html
@@ -1,21 +1,60 @@
 <!DOCTYPE html>
-<title>TreeWalker: cross-realm NodeFilter throws TypeError of current realm</title>
+<meta charset="utf-8">
+<title>TreeWalker: cross-realm NodeFilter throws TypeError of its associated Realm</title>
+<link rel="help" href="https://webidl.spec.whatwg.org/#ref-for-prepare-to-run-script">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<link rel="help" href="https://webidl.spec.whatwg.org/#call-a-user-objects-operation">
 
-<body id="treeWalkerRoot">
-<div></div>
+<iframe name="nodeFilterGlobalObject" src="support/empty-document.html"></iframe>
+
+<div id="treeWalkerRoot">
+    <div class="firstChild"></div>
+</div>
 
 <script>
-const iframe = document.createElement("iframe");
-iframe.src = "support/TreeWalker-acceptNode-filter-cross-realm-subframe.html";
-iframe.onload = () => {
-    for (const testCase of iframe.contentWindow.testCases) {
-        test(t => {
-            assert_equals(testCase.actual.constructor, testCase.expected);
-        }, testCase.description);
-    }
-};
-document.body.append(iframe);
+test_onload(() => {
+    const nodeFilter = new nodeFilterGlobalObject.Object;
+
+    const walker = document.createTreeWalker(treeWalkerRoot, NodeFilter.SHOW_ELEMENT, nodeFilter);
+    assert_throws_js(nodeFilterGlobalObject.TypeError, () => { walker.firstChild(); });
+}, "NodeFilter is cross-realm plain object without 'acceptNode' property");
+
+test_onload(() => {
+    const nodeFilter = new nodeFilterGlobalObject.Object;
+    nodeFilter.acceptNode = {};
+
+    const walker = document.createTreeWalker(treeWalkerRoot, NodeFilter.SHOW_ELEMENT, nodeFilter);
+    assert_throws_js(nodeFilterGlobalObject.TypeError, () => { walker.firstChild(); });
+}, "NodeFilter is cross-realm plain object with non-callable 'acceptNode' property");
+
+test_onload(() => {
+    const { proxy, revoke } = Proxy.revocable(() => {}, {});
+    revoke();
+
+    const nodeFilter = new nodeFilterGlobalObject.Object;
+    nodeFilter.acceptNode = proxy;
+
+    const walker = document.createTreeWalker(treeWalkerRoot, NodeFilter.SHOW_ELEMENT, nodeFilter);
+    assert_throws_js(nodeFilterGlobalObject.TypeError, () => { walker.firstChild(); });
+}, "NodeFilter is cross-realm plain object with revoked Proxy as 'acceptNode' property");
+
+test_onload(() => {
+    const { proxy, revoke } = nodeFilterGlobalObject.Proxy.revocable({}, {});
+    revoke();
+
+    const walker = document.createTreeWalker(treeWalkerRoot, NodeFilter.SHOW_ELEMENT, proxy);
+    assert_throws_js(nodeFilterGlobalObject.TypeError, () => { walker.firstChild(); });
+}, "NodeFilter is cross-realm non-callable revoked Proxy");
+
+test_onload(() => {
+    const { proxy, revoke } = nodeFilterGlobalObject.Proxy.revocable(() => {}, {});
+    revoke();
+
+    const walker = document.createTreeWalker(treeWalkerRoot, NodeFilter.SHOW_ELEMENT, proxy);
+    assert_throws_js(nodeFilterGlobalObject.TypeError, () => { walker.firstChild(); });
+}, "NodeFilter is cross-realm callable revoked Proxy");
+
+function test_onload(fn, desc) {
+    async_test(t => { window.addEventListener("load", t.step_func_done(fn)); }, desc);
+}
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/dom/traversal/support/TreeWalker-acceptNode-filter-cross-realm-subframe.html b/third_party/blink/web_tests/external/wpt/dom/traversal/support/TreeWalker-acceptNode-filter-cross-realm-subframe.html
deleted file mode 100644
index 0c8bda14..0000000
--- a/third_party/blink/web_tests/external/wpt/dom/traversal/support/TreeWalker-acceptNode-filter-cross-realm-subframe.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!DOCTYPE html>
-
-<body id="treeWalkerRoot">
-<div></div>
-
-<script>
-window.testCases = [];
-
-(function() {
-    let walker = parent.document.createTreeWalker(parent.treeWalkerRoot, NodeFilter.SHOW_ELEMENT, new parent.Object);
-    try { walker.firstChild(); } catch (err) { testCases.push({ actual: err, expected: parent.TypeError, description: "parent's |this|, parent's method, parent's filter, parent's root" }); }
-
-    walker = parent.document.createTreeWalker(treeWalkerRoot, NodeFilter.SHOW_ELEMENT, new parent.Object);
-    try { walker.firstChild(); } catch (err) { testCases.push({ actual: err, expected: parent.TypeError, description: "parent's |this|, parent's method, parent's filter, iframe's root" }); }
-
-    walker = parent.document.createTreeWalker(treeWalkerRoot, NodeFilter.SHOW_ELEMENT, {});
-    try { walker.firstChild(); } catch (err) { testCases.push({ actual: err, expected: parent.TypeError, description: "parent's |this|, parent's method, iframe's filter, iframe's root" }); }
-
-    walker = document.createTreeWalker.call(parent.document, treeWalkerRoot, NodeFilter.SHOW_ELEMENT, {});
-    try { walker.firstChild(); } catch (err) { testCases.push({ actual: err, expected: TypeError, description: "parent's |this|, iframes's method, iframe's filter, iframe's root" }); }
-})();
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/dom/traversal/support/empty-document.html b/third_party/blink/web_tests/external/wpt/dom/traversal/support/empty-document.html
new file mode 100644
index 0000000..b9cd130
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/dom/traversal/support/empty-document.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<body>
diff --git a/third_party/blink/web_tests/external/wpt/domxpath/resolver-callback-interface-cross-realm-expected.txt b/third_party/blink/web_tests/external/wpt/domxpath/resolver-callback-interface-cross-realm-expected.txt
new file mode 100644
index 0000000..1e681034
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/domxpath/resolver-callback-interface-cross-realm-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL XPathNSResolver is cross-realm plain object without 'lookupNamespaceURI' property assert_unreached: Should have rejected: undefined Reached unreachable code
+FAIL XPathNSResolver is cross-realm plain object with non-callable 'lookupNamespaceURI' property assert_unreached: Should have rejected: undefined Reached unreachable code
+FAIL XPathNSResolver is cross-realm plain object with revoked Proxy as 'lookupNamespaceURI' property assert_unreached: Should have rejected: undefined Reached unreachable code
+FAIL XPathNSResolver is cross-realm non-callable revoked Proxy assert_unreached: Should have rejected: undefined Reached unreachable code
+FAIL XPathNSResolver is cross-realm callable revoked Proxy assert_unreached: Should have rejected: undefined Reached unreachable code
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/domxpath/resolver-callback-interface-cross-realm.html b/third_party/blink/web_tests/external/wpt/domxpath/resolver-callback-interface-cross-realm.html
new file mode 100644
index 0000000..55fbb07
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/domxpath/resolver-callback-interface-cross-realm.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Cross-realm XPathNSResolver throws TypeError of its associated Realm</title>
+<link rel="help" href="https://webidl.spec.whatwg.org/#ref-for-prepare-to-run-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/invalid_namespace_test.js"></script>
+
+<iframe name="resolverGlobalObject" src="resources/empty-document.html"></iframe>
+
+<script>
+setup({ allow_uncaught_exception: true });
+
+const iframeLoaded = new Promise(resolve => { window.addEventListener("load", resolve); });
+
+promise_test(async t => {
+  await iframeLoaded;
+  const resolver = new resolverGlobalObject.Object;
+
+  return promise_rejects_js(t, resolverGlobalObject.TypeError,
+    invalid_namespace_test(t, resolver, resolverGlobalObject)
+  );
+}, "XPathNSResolver is cross-realm plain object without 'lookupNamespaceURI' property");
+
+promise_test(async t => {
+  await iframeLoaded;
+  const resolver = new resolverGlobalObject.Object;
+  resolver.lookupNamespaceURI = {};
+
+  return promise_rejects_js(t, resolverGlobalObject.TypeError,
+    invalid_namespace_test(t, resolver, resolverGlobalObject)
+  );
+}, "XPathNSResolver is cross-realm plain object with non-callable 'lookupNamespaceURI' property");
+
+promise_test(async t => {
+  await iframeLoaded;
+  const { proxy, revoke } = Proxy.revocable(() => {}, {});
+  revoke();
+
+  const resolver = new resolverGlobalObject.Object;
+  resolver.lookupNamespaceURI = proxy;
+
+  return promise_rejects_js(t, resolverGlobalObject.TypeError,
+    invalid_namespace_test(t, resolver, resolverGlobalObject)
+  );
+}, "XPathNSResolver is cross-realm plain object with revoked Proxy as 'lookupNamespaceURI' property");
+
+promise_test(async t => {
+  await iframeLoaded;
+  const { proxy, revoke } = resolverGlobalObject.Proxy.revocable({}, {});
+  revoke();
+
+  return promise_rejects_js(t, resolverGlobalObject.TypeError,
+    invalid_namespace_test(t, proxy, resolverGlobalObject)
+  );
+}, "XPathNSResolver is cross-realm non-callable revoked Proxy");
+
+promise_test(async t => {
+  await iframeLoaded;
+  const { proxy, revoke } = resolverGlobalObject.Proxy.revocable(() => {}, {});
+  revoke();
+
+  return promise_rejects_js(t, resolverGlobalObject.TypeError,
+    invalid_namespace_test(t, proxy, resolverGlobalObject)
+  );
+}, "XPathNSResolver is cross-realm callable revoked Proxy");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/domxpath/resources/empty-document.html b/third_party/blink/web_tests/external/wpt/domxpath/resources/empty-document.html
new file mode 100644
index 0000000..b9cd130
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/domxpath/resources/empty-document.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<body>
diff --git a/third_party/blink/web_tests/external/wpt/domxpath/resources/invalid_namespace_test.js b/third_party/blink/web_tests/external/wpt/domxpath/resources/invalid_namespace_test.js
index b985261..8b934ef 100644
--- a/third_party/blink/web_tests/external/wpt/domxpath/resources/invalid_namespace_test.js
+++ b/third_party/blink/web_tests/external/wpt/domxpath/resources/invalid_namespace_test.js
@@ -1,15 +1,15 @@
 "use strict";
 setup({ allow_uncaught_exception: true });
 
-const invalid_namespace_test = (t, resolver) => {
+const invalid_namespace_test = (t, resolver, resolverWindow = window) => {
   const result = new Promise((resolve, reject) => {
     const handler = event => {
       reject(event.error);
     };
 
-    window.addEventListener("error", handler);
+    resolverWindow.addEventListener("error", handler);
     t.add_cleanup(() => {
-      window.removeEventListener("error", handler);
+      resolverWindow.removeEventListener("error", handler);
     });
 
     t.step_timeout(resolve, 0);
diff --git a/third_party/blink/web_tests/external/wpt/domxpath/xpath-evaluate-crash.html b/third_party/blink/web_tests/external/wpt/domxpath/xpath-evaluate-crash.html
index d322549..5303d85 100644
--- a/third_party/blink/web_tests/external/wpt/domxpath/xpath-evaluate-crash.html
+++ b/third_party/blink/web_tests/external/wpt/domxpath/xpath-evaluate-crash.html
@@ -1,11 +1,20 @@
 <!DOCTYPE html>
+<meta charset="utf-8">
+<title>Evaluating XPath expressions with orhpaned Attr as context node doesn't crash</title>
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1236967">
-
+<script src="/resources/testharnessreport.js"></script>
 <body>
 <script>
-const domParser = new DOMParser();
-const doc = domParser.parseFromString(undefined, 'text/html', {includeShadowRoots: false});
-const attribute = doc.createAttribute("test");
-new XPathEvaluator().evaluate("..", attribute, null, 2, null);
+for (const expression of [
+    "..",
+    "parent",
+    "ancestor::*",
+    "ancestor-or-self::*",
+    "following::*",
+    "preceding::*",
+]) {
+    const orphanedAttr = document.createAttribute("foo");
+    new XPathEvaluator().evaluate(expression, orphanedAttr, null, 2);
+}
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/editing/data/delete.js b/third_party/blink/web_tests/external/wpt/editing/data/delete.js
index 3c3d1ef..edfdcdb 100644
--- a/third_party/blink/web_tests/external/wpt/editing/data/delete.js
+++ b/third_party/blink/web_tests/external/wpt/editing/data/delete.js
@@ -1,3 +1,5 @@
+class MyCustomElement extends HTMLElement {};
+customElements.define("custom-element", MyCustomElement);
 // For documentation of the format, see README in this directory.
 var browserTests = [
 ["foo[]bar",
@@ -2746,4 +2748,28 @@
     "<p contenteditable=\"false\"><unknown-element contenteditable=\"\"></unknown-element></p>",
     [true],
     {"delete":[false,false,"",false,false,""]}],
+["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>",
+    [["delete",""]],
+    ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>d</p></custom-element></div>",
+     "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>d<br></p></custom-element></div>"],
+    [true],
+    {"delete":[false,false,"",false,false,""]}],
+["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>",
+    [["delete",""]],
+    ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a</p></custom-element></div>",
+     "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a<br></p></custom-element></div>"],
+    [true],
+    {"delete":[false,false,"",false,false,""]}],
+["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>",
+    [["delete",""]],
+    ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><i>d</i></p></custom-element></div>",
+     "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><i>d</i><br></p></custom-element></div>"],
+    [true],
+    {"delete":[false,false,"",false,false,""]}],
+["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>",
+    [["delete",""]],
+    ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a</b></p></custom-element></div>",
+     "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a</b><br></p></custom-element></div>"],
+    [true],
+    {"delete":[false,false,"",false,false,""]}],
 ]
diff --git a/third_party/blink/web_tests/external/wpt/editing/data/forwarddelete.js b/third_party/blink/web_tests/external/wpt/editing/data/forwarddelete.js
index 5215232..2f96ef6 100644
--- a/third_party/blink/web_tests/external/wpt/editing/data/forwarddelete.js
+++ b/third_party/blink/web_tests/external/wpt/editing/data/forwarddelete.js
@@ -1,3 +1,5 @@
+class MyCustomElement extends HTMLElement {};
+customElements.define("custom-element", MyCustomElement);
 // For documentation of the format, see README in this directory.
 var browserTests = [
 ["foo[]",
@@ -2627,4 +2629,28 @@
     "<p contenteditable=\"false\"><unknown-element contenteditable=\"\"></unknown-element></p>",
     [true],
     {"forwarddelete":[false,false,"",false,false,""]}],
+["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>",
+    [["forwarddelete",""]],
+    ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>d</p></custom-element></div>",
+     "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>d<br></p></custom-element></div>"],
+    [true],
+    {"forwarddelete":[false,false,"",false,false,""]}],
+["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>",
+    [["forwarddelete",""]],
+    ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a</p></custom-element></div>",
+     "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a<br></p></custom-element></div>"],
+    [true],
+    {"forwarddelete":[false,false,"",false,false,""]}],
+["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>",
+    [["forwarddelete",""]],
+    ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><i>d</i></p></custom-element></div>",
+     "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><i>d</i><br></p></custom-element></div>"],
+    [true],
+    {"forwarddelete":[false,false,"",false,false,""]}],
+["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>",
+    [["forwarddelete",""]],
+    ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a</b></p></custom-element></div>",
+     "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a</b><br></p></custom-element></div>"],
+    [true],
+    {"forwarddelete":[false,false,"",false,false,""]}],
 ]
diff --git a/third_party/blink/web_tests/external/wpt/editing/run/delete_7001-last-expected.txt b/third_party/blink/web_tests/external/wpt/editing/run/delete_7001-last-expected.txt
index a05da9c..881a294 100644
--- a/third_party/blink/web_tests/external/wpt/editing/run/delete_7001-last-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/run/delete_7001-last-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 219 tests; 216 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 255 tests; 252 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS [["delete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" queryCommandIndeterm("delete") after
 PASS [["delete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" queryCommandState("delete") after
 PASS [["delete",""]] "<p contenteditable=false><span contenteditable=true>[abc]</span></p>" queryCommandValue("delete") after
@@ -219,5 +219,41 @@
 PASS [["delete",""]] "<p contenteditable=\"false\"><unknown-element contenteditable>[abc]</unknown-element></p>" queryCommandIndeterm("delete") after
 PASS [["delete",""]] "<p contenteditable=\"false\"><unknown-element contenteditable>[abc]</unknown-element></p>" queryCommandState("delete") after
 PASS [["delete",""]] "<p contenteditable=\"false\"><unknown-element contenteditable>[abc]</unknown-element></p>" queryCommandValue("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>": execCommand("delete", false, "") return value
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>" checks for modifications to non-editable content
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>" compare innerHTML
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>" queryCommandIndeterm("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>" queryCommandState("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>" queryCommandValue("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>" queryCommandIndeterm("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>" queryCommandState("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>" queryCommandValue("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>": execCommand("delete", false, "") return value
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>" checks for modifications to non-editable content
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>" compare innerHTML
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>" queryCommandIndeterm("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>" queryCommandState("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>" queryCommandValue("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>" queryCommandIndeterm("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>" queryCommandState("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>" queryCommandValue("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>": execCommand("delete", false, "") return value
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>" checks for modifications to non-editable content
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>" compare innerHTML
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>" queryCommandIndeterm("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>" queryCommandState("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>" queryCommandValue("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>" queryCommandIndeterm("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>" queryCommandState("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>" queryCommandValue("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>": execCommand("delete", false, "") return value
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>" checks for modifications to non-editable content
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>" compare innerHTML
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>" queryCommandIndeterm("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>" queryCommandState("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>" queryCommandValue("delete") before
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>" queryCommandIndeterm("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>" queryCommandState("delete") after
+PASS [["delete",""]] "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>" queryCommandValue("delete") after
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/idlharness.any-expected.txt b/third_party/blink/web_tests/external/wpt/event-timing/idlharness.any-expected.txt
new file mode 100644
index 0000000..c4137e86
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/event-timing/idlharness.any-expected.txt
@@ -0,0 +1,39 @@
+This is a testharness.js-based test.
+PASS idl_test setup
+PASS idl_test validation
+PASS Partial interface Performance: original interface defined
+PASS Partial interface Performance: valid exposure set
+PASS Partial interface Performance: member names are unique
+PASS Partial dictionary PerformanceObserverInit: original dictionary defined
+PASS Partial dictionary PerformanceObserverInit: member names are unique
+PASS Partial interface Performance[2]: member names are unique
+PASS PerformanceEventTiming interface: existence and properties of interface object
+PASS PerformanceEventTiming interface object length
+PASS PerformanceEventTiming interface object name
+PASS PerformanceEventTiming interface: existence and properties of interface prototype object
+PASS PerformanceEventTiming interface: existence and properties of interface prototype object's "constructor" property
+PASS PerformanceEventTiming interface: existence and properties of interface prototype object's @@unscopables property
+PASS PerformanceEventTiming interface: attribute processingStart
+PASS PerformanceEventTiming interface: attribute processingEnd
+PASS PerformanceEventTiming interface: attribute cancelable
+PASS PerformanceEventTiming interface: attribute target
+PASS PerformanceEventTiming interface: attribute interactionId
+PASS PerformanceEventTiming interface: operation toJSON()
+PASS EventCounts interface: existence and properties of interface object
+PASS EventCounts interface object length
+PASS EventCounts interface object name
+PASS EventCounts interface: existence and properties of interface prototype object
+PASS EventCounts interface: existence and properties of interface prototype object's "constructor" property
+PASS EventCounts interface: existence and properties of interface prototype object's @@unscopables property
+FAIL InteractionCounts interface: existence and properties of interface object assert_own_property: self does not have own property "InteractionCounts" expected property "InteractionCounts" missing
+FAIL InteractionCounts interface object length assert_own_property: self does not have own property "InteractionCounts" expected property "InteractionCounts" missing
+FAIL InteractionCounts interface object name assert_own_property: self does not have own property "InteractionCounts" expected property "InteractionCounts" missing
+FAIL InteractionCounts interface: existence and properties of interface prototype object assert_own_property: self does not have own property "InteractionCounts" expected property "InteractionCounts" missing
+FAIL InteractionCounts interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "InteractionCounts" expected property "InteractionCounts" missing
+FAIL InteractionCounts interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "InteractionCounts" expected property "InteractionCounts" missing
+PASS Performance interface: attribute eventCounts
+FAIL Performance interface: attribute interactionCounts assert_true: The prototype object must have a property "interactionCounts" expected true got false
+PASS Performance interface: performance must inherit property "eventCounts" with the proper type
+FAIL Performance interface: performance must inherit property "interactionCounts" with the proper type assert_inherits: property "interactionCounts" not found in prototype chain
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any-expected.txt
new file mode 100644
index 0000000..b5c6255
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+PASS Calling arrayBuffer() on an aborted request
+PASS Aborting a request after calling arrayBuffer()
+PASS Calling arrayBuffer() on an aborted consumed empty request
+PASS Calling arrayBuffer() on an aborted consumed nonempty request
+PASS Calling blob() on an aborted request
+PASS Aborting a request after calling blob()
+PASS Calling blob() on an aborted consumed empty request
+PASS Calling blob() on an aborted consumed nonempty request
+FAIL Calling formData() on an aborted request promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+FAIL Aborting a request after calling formData() promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS Calling formData() on an aborted consumed nonempty request
+PASS Calling json() on an aborted request
+PASS Aborting a request after calling json()
+PASS Calling json() on an aborted consumed nonempty request
+PASS Calling text() on an aborted request
+PASS Aborting a request after calling text()
+PASS Calling text() on an aborted consumed empty request
+PASS Calling text() on an aborted consumed nonempty request
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.js b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.js
new file mode 100644
index 0000000..dcc7803
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.js
@@ -0,0 +1,85 @@
+// META: timeout=long
+// META: global=window,worker
+
+const BODY_FUNCTION_AND_DATA = {
+  arrayBuffer: null,
+  blob: null,
+  formData: new FormData(),
+  json: new Blob(["{}"]),
+  text: null,
+};
+
+for (const [bodyFunction, body] of Object.entries(BODY_FUNCTION_AND_DATA)) {
+  promise_test(async () => {
+    const controller = new AbortController();
+    const signal = controller.signal;
+    const request = new Request("../resources/data.json", {
+      method: "post",
+      signal,
+      body,
+    });
+
+    controller.abort();
+    await request[bodyFunction]();
+    assert_true(
+      true,
+      `An aborted request should still be able to run ${bodyFunction}()`
+    );
+  }, `Calling ${bodyFunction}() on an aborted request`);
+
+  promise_test(async () => {
+    const controller = new AbortController();
+    const signal = controller.signal;
+    const request = new Request("../resources/data.json", {
+      method: "post",
+      signal,
+      body,
+    });
+
+    const p = request[bodyFunction]();
+    controller.abort();
+    await p;
+    assert_true(
+      true,
+      `An aborted request should still be able to run ${bodyFunction}()`
+    );
+  }, `Aborting a request after calling ${bodyFunction}()`);
+
+  if (!body) {
+    promise_test(async () => {
+      const controller = new AbortController();
+      const signal = controller.signal;
+      const request = new Request("../resources/data.json", {
+        method: "post",
+        signal,
+        body,
+      });
+
+      // consuming happens synchronously, so don't wait
+      fetch(request).catch(() => {});
+
+      controller.abort();
+      await request[bodyFunction]();
+      assert_true(
+        true,
+        `An aborted consumed request should still be able to run ${bodyFunction}() when empty`
+      );
+    }, `Calling ${bodyFunction}() on an aborted consumed empty request`);
+  }
+
+  promise_test(async t => {
+    const controller = new AbortController();
+    const signal = controller.signal;
+    const request = new Request("../resources/data.json", {
+      method: "post",
+      signal,
+      body: body || new Blob(["foo"]),
+    });
+
+    // consuming happens synchronously, so don't wait
+    fetch(request).catch(() => {});
+
+    controller.abort();
+    await promise_rejects_js(t, TypeError, request[bodyFunction]());
+  }, `Calling ${bodyFunction}() on an aborted consumed nonempty request`);
+}
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.serviceworker-expected.txt
new file mode 100644
index 0000000..b5c6255
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.serviceworker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+PASS Calling arrayBuffer() on an aborted request
+PASS Aborting a request after calling arrayBuffer()
+PASS Calling arrayBuffer() on an aborted consumed empty request
+PASS Calling arrayBuffer() on an aborted consumed nonempty request
+PASS Calling blob() on an aborted request
+PASS Aborting a request after calling blob()
+PASS Calling blob() on an aborted consumed empty request
+PASS Calling blob() on an aborted consumed nonempty request
+FAIL Calling formData() on an aborted request promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+FAIL Aborting a request after calling formData() promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS Calling formData() on an aborted consumed nonempty request
+PASS Calling json() on an aborted request
+PASS Aborting a request after calling json()
+PASS Calling json() on an aborted consumed nonempty request
+PASS Calling text() on an aborted request
+PASS Aborting a request after calling text()
+PASS Calling text() on an aborted consumed empty request
+PASS Calling text() on an aborted consumed nonempty request
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.sharedworker-expected.txt
new file mode 100644
index 0000000..b5c6255
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.sharedworker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+PASS Calling arrayBuffer() on an aborted request
+PASS Aborting a request after calling arrayBuffer()
+PASS Calling arrayBuffer() on an aborted consumed empty request
+PASS Calling arrayBuffer() on an aborted consumed nonempty request
+PASS Calling blob() on an aborted request
+PASS Aborting a request after calling blob()
+PASS Calling blob() on an aborted consumed empty request
+PASS Calling blob() on an aborted consumed nonempty request
+FAIL Calling formData() on an aborted request promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+FAIL Aborting a request after calling formData() promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS Calling formData() on an aborted consumed nonempty request
+PASS Calling json() on an aborted request
+PASS Aborting a request after calling json()
+PASS Calling json() on an aborted consumed nonempty request
+PASS Calling text() on an aborted request
+PASS Aborting a request after calling text()
+PASS Calling text() on an aborted consumed empty request
+PASS Calling text() on an aborted consumed nonempty request
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.worker-expected.txt
new file mode 100644
index 0000000..b5c6255
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/abort/request.any.worker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+PASS Calling arrayBuffer() on an aborted request
+PASS Aborting a request after calling arrayBuffer()
+PASS Calling arrayBuffer() on an aborted consumed empty request
+PASS Calling arrayBuffer() on an aborted consumed nonempty request
+PASS Calling blob() on an aborted request
+PASS Aborting a request after calling blob()
+PASS Calling blob() on an aborted consumed empty request
+PASS Calling blob() on an aborted consumed nonempty request
+FAIL Calling formData() on an aborted request promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+FAIL Aborting a request after calling formData() promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS Calling formData() on an aborted consumed nonempty request
+PASS Calling json() on an aborted request
+PASS Aborting a request after calling json()
+PASS Calling json() on an aborted consumed nonempty request
+PASS Calling text() on an aborted request
+PASS Aborting a request after calling text()
+PASS Calling text() on an aborted consumed empty request
+PASS Calling text() on an aborted consumed nonempty request
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/crashtests/request.html b/third_party/blink/web_tests/external/wpt/fetch/api/crashtests/request.html
new file mode 100644
index 0000000..2d21930
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/crashtests/request.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/common/utils.js"></script>
+<script>
+  // Cycle collection test for a case where the Request object is alive and accessible globally.
+  var req = new Request(`/`);
+  fetch(req)
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any-expected.txt
index cfab79c..3ac9e12 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 71 tests; 49 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 73 tests; 51 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup.
 PASS "data://test/,X"
 FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -20,6 +20,8 @@
 FAIL "data:;x=x,X" assert_equals: expected "text/plain;x=x" but got "text/plain;charset=US-ASCII"
 PASS "data:text/plain;charset=windows-1252,%C2%B1"
 PASS "data:text/plain;Charset=UTF-8,%C2%B1"
+PASS "data:text/plain;charset=windows-1252,áñçə💩"
+PASS "data:text/plain;charset=UTF-8,áñçə💩"
 PASS "data:image/gif,%C2%B1"
 PASS "data:IMAGE/gif,%C2%B1"
 FAIL "data:IMAGE/gif;hi=x,%C2%B1" assert_equals: expected "image/gif;hi=x" but got "image/gif"
diff --git a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.serviceworker-expected.txt
index cfab79c..3ac9e12 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.serviceworker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 71 tests; 49 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 73 tests; 51 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup.
 PASS "data://test/,X"
 FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -20,6 +20,8 @@
 FAIL "data:;x=x,X" assert_equals: expected "text/plain;x=x" but got "text/plain;charset=US-ASCII"
 PASS "data:text/plain;charset=windows-1252,%C2%B1"
 PASS "data:text/plain;Charset=UTF-8,%C2%B1"
+PASS "data:text/plain;charset=windows-1252,áñçə💩"
+PASS "data:text/plain;charset=UTF-8,áñçə💩"
 PASS "data:image/gif,%C2%B1"
 PASS "data:IMAGE/gif,%C2%B1"
 FAIL "data:IMAGE/gif;hi=x,%C2%B1" assert_equals: expected "image/gif;hi=x" but got "image/gif"
diff --git a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.sharedworker-expected.txt
index cfab79c..3ac9e12 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.sharedworker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 71 tests; 49 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 73 tests; 51 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup.
 PASS "data://test/,X"
 FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -20,6 +20,8 @@
 FAIL "data:;x=x,X" assert_equals: expected "text/plain;x=x" but got "text/plain;charset=US-ASCII"
 PASS "data:text/plain;charset=windows-1252,%C2%B1"
 PASS "data:text/plain;Charset=UTF-8,%C2%B1"
+PASS "data:text/plain;charset=windows-1252,áñçə💩"
+PASS "data:text/plain;charset=UTF-8,áñçə💩"
 PASS "data:image/gif,%C2%B1"
 PASS "data:IMAGE/gif,%C2%B1"
 FAIL "data:IMAGE/gif;hi=x,%C2%B1" assert_equals: expected "image/gif;hi=x" but got "image/gif"
diff --git a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt
index cfab79c..3ac9e12 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 71 tests; 49 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 73 tests; 51 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup.
 PASS "data://test/,X"
 FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -20,6 +20,8 @@
 FAIL "data:;x=x,X" assert_equals: expected "text/plain;x=x" but got "text/plain;charset=US-ASCII"
 PASS "data:text/plain;charset=windows-1252,%C2%B1"
 PASS "data:text/plain;Charset=UTF-8,%C2%B1"
+PASS "data:text/plain;charset=windows-1252,áñçə💩"
+PASS "data:text/plain;charset=UTF-8,áñçə💩"
 PASS "data:image/gif,%C2%B1"
 PASS "data:IMAGE/gif,%C2%B1"
 FAIL "data:IMAGE/gif;hi=x,%C2%B1" assert_equals: expected "image/gif;hi=x" but got "image/gif"
diff --git a/third_party/blink/web_tests/external/wpt/fetch/data-urls/resources/data-urls.json b/third_party/blink/web_tests/external/wpt/fetch/data-urls/resources/data-urls.json
index be1d1e7..f318d1f 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/data-urls/resources/data-urls.json
+++ b/third_party/blink/web_tests/external/wpt/fetch/data-urls/resources/data-urls.json
@@ -52,6 +52,12 @@
   ["data:text/plain;Charset=UTF-8,%C2%B1",
    "text/plain;charset=UTF-8",
    [194, 177]],
+  ["data:text/plain;charset=windows-1252,áñçə💩",
+   "text/plain;charset=windows-1252",
+   [195, 161, 195, 177, 195, 167, 201, 153, 240, 159, 146, 169]],
+  ["data:text/plain;charset=UTF-8,áñçə💩",
+   "text/plain;charset=UTF-8",
+   [195, 161, 195, 177, 195, 167, 201, 153, 240, 159, 146, 169]],
   ["data:image/gif,%C2%B1",
    "image/gif",
    [194, 177]],
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.https.window-expected.txt
new file mode 100644
index 0000000..8718ffde
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.https.window-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+FAIL treat-as-public to local: failure. assert_equals: worker error expected (string) "unknown error" but got (undefined) undefined
+FAIL treat-as-public to private: failure. assert_equals: worker error expected (string) "unknown error" but got (undefined) undefined
+PASS public to public: success.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.https.window.js b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.https.window.js
new file mode 100644
index 0000000..3eeb435b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.https.window.js
@@ -0,0 +1,36 @@
+// META: script=/common/utils.js
+// META: script=resources/support.sub.js
+//
+// Spec: https://wicg.github.io/private-network-access/#integration-fetch
+//
+// These tests check that initial `Worker` script fetches from within worker
+// scopes are subject to Private Network Access checks, just like a worker
+// script fetches from within document scopes (for non-nested workers). The
+// latter are tested in: worker.https.window.js
+//
+// This file covers only those tests that must execute in a secure context.
+// Other tests are defined in: nested-worker.window.js
+
+promise_test(t => nestedWorkerScriptTest(t, {
+  source: {
+    server: Server.HTTPS_LOCAL,
+    treatAsPublic: true,
+  },
+  target: { server: Server.HTTPS_LOCAL },
+  expected: WorkerScriptTestResult.FAILURE,
+}), "treat-as-public to local: failure.");
+
+promise_test(t => nestedWorkerScriptTest(t, {
+  source: {
+    server: Server.HTTPS_PRIVATE,
+    treatAsPublic: true,
+  },
+  target: { server: Server.HTTPS_PRIVATE },
+  expected: WorkerScriptTestResult.FAILURE,
+}), "treat-as-public to private: failure.");
+
+promise_test(t => nestedWorkerScriptTest(t, {
+  source: { server: Server.HTTPS_PUBLIC },
+  target: { server: Server.HTTPS_PUBLIC },
+  expected: WorkerScriptTestResult.SUCCESS,
+}), "public to public: success.");
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.window-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.window-expected.txt
new file mode 100644
index 0000000..8718ffde
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.window-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+FAIL treat-as-public to local: failure. assert_equals: worker error expected (string) "unknown error" but got (undefined) undefined
+FAIL treat-as-public to private: failure. assert_equals: worker error expected (string) "unknown error" but got (undefined) undefined
+PASS public to public: success.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.window.js b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.window.js
new file mode 100644
index 0000000..6d246e1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/nested-worker.window.js
@@ -0,0 +1,36 @@
+// META: script=/common/utils.js
+// META: script=resources/support.sub.js
+//
+// Spec: https://wicg.github.io/private-network-access/#integration-fetch
+//
+// These tests check that initial `Worker` script fetches from within worker
+// scopes are subject to Private Network Access checks, just like a worker
+// script fetches from within document scopes (for non-nested workers). The
+// latter are tested in: worker.window.js
+//
+// This file covers only those tests that must execute in a non secure context.
+// Other tests are defined in: nested-worker.https.window.js
+
+promise_test(t => nestedWorkerScriptTest(t, {
+  source: {
+    server: Server.HTTP_LOCAL,
+    treatAsPublic: true,
+  },
+  target: { server: Server.HTTP_LOCAL },
+  expected: WorkerScriptTestResult.FAILURE,
+}), "treat-as-public to local: failure.");
+
+promise_test(t => nestedWorkerScriptTest(t, {
+  source: {
+    server: Server.HTTP_PRIVATE,
+    treatAsPublic: true,
+  },
+  target: { server: Server.HTTP_PRIVATE },
+  expected: WorkerScriptTestResult.FAILURE,
+}), "treat-as-public to private: failure.");
+
+promise_test(t => nestedWorkerScriptTest(t, {
+  source: { server: Server.HTTP_PUBLIC },
+  target: { server: Server.HTTP_PUBLIC },
+  expected: WorkerScriptTestResult.SUCCESS,
+}), "public to public: success.");
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/support.sub.js b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/support.sub.js
index 9fcba9d..98ae1f3 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/support.sub.js
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/support.sub.js
@@ -343,14 +343,21 @@
   FAILURE: { error: "unknown error" },
 };
 
+function workerScriptUrl(target) {
+  const url =
+    resolveUrl("resources/preflight.py", targetResolveOptions(target));
+
+  url.searchParams.append("body", "postMessage({ loaded: true })")
+  url.searchParams.append("mime-type", "application/javascript")
+
+  return url;
+}
+
 async function workerScriptTest(t, { source, target, expected }) {
   const sourceUrl =
       resolveUrl("resources/worker-fetcher.html", sourceResolveOptions(source));
 
-  const targetUrl =
-      resolveUrl("resources/preflight.py", targetResolveOptions(target));
-  targetUrl.searchParams.append("body", "postMessage({ loaded: true })")
-  targetUrl.searchParams.append("mime-type", "application/javascript")
+  const targetUrl = workerScriptUrl(target);
 
   const iframe = await appendIframe(t, document, sourceUrl);
   const reply = futureMessage();
@@ -363,6 +370,27 @@
   assert_equals(loaded, expected.loaded, "response loaded");
 }
 
+async function nestedWorkerScriptTest(t, { source, target, expected }) {
+  const targetUrl = workerScriptUrl(target);
+
+  const sourceUrl = resolveUrl(
+      "resources/worker-fetcher.js", sourceResolveOptions(source));
+  sourceUrl.searchParams.append("url", targetUrl);
+
+  // Iframe must be same-origin with the parent worker.
+  const iframeUrl = new URL("worker-fetcher.html", sourceUrl);
+
+  const iframe = await appendIframe(t, document, iframeUrl);
+  const reply = futureMessage();
+
+  iframe.contentWindow.postMessage({ url: sourceUrl.href }, "*");
+
+  const { error, loaded } = await reply;
+
+  assert_equals(error, expected.error, "worker error");
+  assert_equals(loaded, expected.loaded, "response loaded");
+}
+
 async function sharedWorkerScriptTest(t, { source, target, expected }) {
   const sourceUrl = resolveUrl("resources/shared-worker-fetcher.html",
                                sourceResolveOptions(source));
diff --git a/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/worker-fetcher.js b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/worker-fetcher.js
new file mode 100644
index 0000000..aab49afe
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/private-network-access/resources/worker-fetcher.js
@@ -0,0 +1,11 @@
+const url = new URL(self.location).searchParams.get("url");
+const worker = new Worker(url);
+
+// Relay messages from the worker to the parent frame.
+worker.addEventListener("message", (evt) => {
+  self.postMessage(evt.data);
+});
+
+worker.addEventListener("error", (evt) => {
+  self.postMessage({ error: evt.message || "unknown error" });
+});
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window.js
index 7f83eaf..176bae8 100644
--- a/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window.js
+++ b/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window.js
@@ -4,7 +4,7 @@
 // https://www.w3.org/TR/geolocation-API/
 
 idl_test(
-  ['geolocation-API'],
+  ['geolocation'],
   ['hr-time', 'html'],
   idl_array => {
     self.audio = document.createElement('audio');
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/elements-metadata.js b/third_party/blink/web_tests/external/wpt/html/dom/elements-metadata.js
index 8af6a6a6..49d7bb25 100644
--- a/third_party/blink/web_tests/external/wpt/html/dom/elements-metadata.js
+++ b/third_party/blink/web_tests/external/wpt/html/dom/elements-metadata.js
@@ -35,6 +35,7 @@
     name: "string",
     httpEquiv: {type: "string", domAttrName: "http-equiv"},
     content: "string",
+    media: "string",
 
     // Obsolete
     scheme: "string",
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/elements-misc.js b/third_party/blink/web_tests/external/wpt/html/dom/elements-misc.js
index b747ac6..1a74c547 100644
--- a/third_party/blink/web_tests/external/wpt/html/dom/elements-misc.js
+++ b/third_party/blink/web_tests/external/wpt/html/dom/elements-misc.js
@@ -14,7 +14,6 @@
     // TODO: async attribute (complicated).
     defer: "boolean",
     crossOrigin: {type: "enum", keywords: ["anonymous", "use-credentials"], nonCanon:{"": "anonymous"}, isNullable: true, defaultVal: null, invalidVal: "anonymous"},
-    nonce: "string",
     integrity: "string",
 
     // Obsolete
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.html b/third_party/blink/web_tests/external/wpt/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.html
index 6500931a..953bedc 100644
--- a/third_party/blink/web_tests/external/wpt/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.html
+++ b/third_party/blink/web_tests/external/wpt/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.html
@@ -8,6 +8,7 @@
   <li><span id="testReplaceFollowing">A</span> B</li>
   <li>A <span id="testReplaceBoth">B</span> C</li>
   <li><span id="testRemove">Testing</span> removing node using outerText.</li>
+  <li><span id="testNewlines">Replace this child with lots of newlines</span></li>
 </ul>
 
 <div id="container"></div>
@@ -62,6 +63,45 @@
   assert_equals(container.childNodes[2].data, "E");
 }, "Only merges with the previous and following text nodes, does not completely normalize");
 
+test(t => {
+  const container = document.getElementById("container");
+  t.add_cleanup(() => { container.textContent = ""; });
+
+  container.append(document.createElement("span"));
+  const node = container.childNodes[0];
+  node.outerText = "";
+
+  assert_equals(container.childNodes.length, 1, "Creates text node for the empty string");
+  assert_equals(container.childNodes[0].data, "");
+}, "Empty string");
+
+test(t => {
+  const container = document.getElementById("container");
+  t.add_cleanup(() => { container.textContent = ""; });
+
+  container.append("1", "2", document.createElement("span"), "3", "4");
+  const node = container.childNodes[2];
+  node.outerText = "";
+
+  assert_equals(container.childNodes.length, 3, "It got merged with the previous and following text node");
+  assert_equals(container.childNodes[0].data, "1");
+  assert_equals(container.childNodes[1].data, "23");
+  assert_equals(container.childNodes[2].data, "4");
+}, "Empty string with surrounding text nodes");
+
+test(t => {
+  const node = document.getElementById("testNewlines");
+  const parent = node.parentNode;
+
+  node.outerText = "\n\r\n\r";
+
+  assert_equals(parent.innerHTML, "<br><br><br>");
+  assert_equals(parent.childNodes.length, 3);
+  assert_equals(parent.childNodes[0].localName, "br", "node 1");
+  assert_equals(parent.childNodes[1].localName, "br", "node 2");
+  assert_equals(parent.childNodes[2].localName, "br", "node 3");
+}, "Setting outerText to a bunch of newlines creates a bunch of <br>s with no text nodes");
+
 test(() => {
   const node = document.getElementById("testRemove");
   const parent = node.parentNode;
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt
index 9609f52..0e04c917 100644
--- a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 816 tests; 808 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 822 tests; 813 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Partial interface Document: original interface defined
@@ -254,6 +254,12 @@
 PASS HTMLSlotElement interface: existence and properties of interface object
 PASS HTMLCanvasElement interface: existence and properties of interface object
 PASS CanvasRenderingContext2D interface: existence and properties of interface object
+PASS CanvasFilter interface: existence and properties of interface object
+FAIL CanvasFilter interface object length assert_equals: wrong value for CanvasFilter.length expected 0 but got 1
+PASS CanvasFilter interface object name
+PASS CanvasFilter interface: existence and properties of interface prototype object
+PASS CanvasFilter interface: existence and properties of interface prototype object's "constructor" property
+PASS CanvasFilter interface: existence and properties of interface prototype object's @@unscopables property
 PASS CanvasGradient interface: existence and properties of interface object
 PASS CanvasGradient interface object length
 PASS CanvasGradient interface object name
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/reflection-metadata-expected.txt b/third_party/blink/web_tests/external/wpt/html/dom/reflection-metadata-expected.txt
index bfd647b4..a8e83c4 100644
--- a/third_party/blink/web_tests/external/wpt/html/dom/reflection-metadata-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/dom/reflection-metadata-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 3060 tests; 2974 PASS, 86 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 3098 tests; 3012 PASS, 86 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS head.title: 38 tests
 PASS head.lang: 38 tests
 PASS head.dir: 68 tests
@@ -172,6 +172,7 @@
 PASS meta.name: 38 tests
 PASS meta.httpEquiv (<meta http-equiv>): 38 tests
 PASS meta.content: 38 tests
+PASS meta.media: 38 tests
 PASS meta.scheme: 38 tests
 PASS style.title: 38 tests
 PASS style.lang: 38 tests
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/reflection-misc-expected.txt b/third_party/blink/web_tests/external/wpt/html/dom/reflection-misc-expected.txt
deleted file mode 100644
index 13c04358a..0000000
--- a/third_party/blink/web_tests/external/wpt/html/dom/reflection-misc-expected.txt
+++ /dev/null
@@ -1,139 +0,0 @@
-This is a testharness.js-based test.
-Found 4891 tests; 4874 PASS, 17 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS html.title: 38 tests
-PASS html.lang: 38 tests
-PASS html.dir: 68 tests
-PASS html.className (<html class>): 38 tests
-PASS html.autofocus: 39 tests
-PASS html.hidden: 39 tests
-PASS html.accessKey: 38 tests
-PASS html.tabIndex: 26 tests
-PASS html.version: 38 tests
-PASS script.title: 38 tests
-PASS script.lang: 38 tests
-PASS script.dir: 68 tests
-PASS script.className (<script class>): 38 tests
-PASS script.autofocus: 39 tests
-PASS script.hidden: 39 tests
-PASS script.accessKey: 38 tests
-PASS script.tabIndex: 26 tests
-PASS script.src: 44 tests
-PASS script.type: 38 tests
-PASS script.noModule: 39 tests
-PASS script.charset: 38 tests
-PASS script.defer: 39 tests
-PASS script.crossOrigin: 62 tests
-PASS script.nonce: 20 tests
-FAIL script.nonce: IDL set to "" assert_equals: getAttribute() expected "" but got "test-valueOf"
-FAIL script.nonce: IDL set to " \0\x01\x02\x03\x04\x05\x06\x07 \b\t\n\v\f\r\x0e\x0f \x10\x11\x12\x13\x14\x15\x16\x17 \x18\x19\x1a\x1b\x1c\x1d\x1e\x1f  foo " assert_equals: getAttribute() expected " \0\x01\x02\x03\x04\x05\x06\x07 \b\t\n\v\f\r\x0e\x0f \x10\x11\x12\x13\x14\x15\x16\x17 \x18\x19\x1a\x1b\x1c\x1d\x1e\x1f  foo " but got "test-valueOf"
-FAIL script.nonce: IDL set to undefined assert_equals: getAttribute() expected "undefined" but got "test-valueOf"
-FAIL script.nonce: IDL set to 7 assert_equals: getAttribute() expected "7" but got "test-valueOf"
-FAIL script.nonce: IDL set to 1.5 assert_equals: getAttribute() expected "1.5" but got "test-valueOf"
-FAIL script.nonce: IDL set to "5%" assert_equals: getAttribute() expected "5%" but got "test-valueOf"
-FAIL script.nonce: IDL set to "+100" assert_equals: getAttribute() expected "+100" but got "test-valueOf"
-FAIL script.nonce: IDL set to ".5" assert_equals: getAttribute() expected ".5" but got "test-valueOf"
-FAIL script.nonce: IDL set to true assert_equals: getAttribute() expected "true" but got "test-valueOf"
-FAIL script.nonce: IDL set to false assert_equals: getAttribute() expected "false" but got "test-valueOf"
-FAIL script.nonce: IDL set to object "[object Object]" assert_equals: getAttribute() expected "[object Object]" but got "test-valueOf"
-FAIL script.nonce: IDL set to NaN assert_equals: getAttribute() expected "NaN" but got "test-valueOf"
-FAIL script.nonce: IDL set to Infinity assert_equals: getAttribute() expected "Infinity" but got "test-valueOf"
-FAIL script.nonce: IDL set to -Infinity assert_equals: getAttribute() expected "-Infinity" but got "test-valueOf"
-FAIL script.nonce: IDL set to "\0" assert_equals: getAttribute() expected "\0" but got "test-valueOf"
-FAIL script.nonce: IDL set to null assert_equals: getAttribute() expected "null" but got "test-valueOf"
-FAIL script.nonce: IDL set to object "test-toString" assert_equals: getAttribute() expected "test-toString" but got "test-valueOf"
-PASS script.nonce: IDL set to object "test-valueOf"
-PASS script.integrity: 38 tests
-PASS script.event: 38 tests
-PASS script.htmlFor (<script for>): 38 tests
-PASS noscript.title: 38 tests
-PASS noscript.lang: 38 tests
-PASS noscript.dir: 68 tests
-PASS noscript.className (<noscript class>): 38 tests
-PASS noscript.autofocus: 39 tests
-PASS noscript.hidden: 39 tests
-PASS noscript.accessKey: 38 tests
-PASS noscript.tabIndex: 26 tests
-PASS template.title: 38 tests
-PASS template.lang: 38 tests
-PASS template.dir: 68 tests
-PASS template.className (<template class>): 38 tests
-PASS template.autofocus: 39 tests
-PASS template.hidden: 39 tests
-PASS template.accessKey: 38 tests
-PASS template.tabIndex: 26 tests
-PASS slot.title: 38 tests
-PASS slot.lang: 38 tests
-PASS slot.dir: 68 tests
-PASS slot.className (<slot class>): 38 tests
-PASS slot.autofocus: 39 tests
-PASS slot.hidden: 39 tests
-PASS slot.accessKey: 38 tests
-PASS slot.tabIndex: 26 tests
-PASS slot.name: 38 tests
-PASS ins.title: 38 tests
-PASS ins.lang: 38 tests
-PASS ins.dir: 68 tests
-PASS ins.className (<ins class>): 38 tests
-PASS ins.autofocus: 39 tests
-PASS ins.hidden: 39 tests
-PASS ins.accessKey: 38 tests
-PASS ins.tabIndex: 26 tests
-PASS ins.cite: 44 tests
-PASS ins.dateTime: 38 tests
-PASS del.title: 38 tests
-PASS del.lang: 38 tests
-PASS del.dir: 68 tests
-PASS del.className (<del class>): 38 tests
-PASS del.autofocus: 39 tests
-PASS del.hidden: 39 tests
-PASS del.accessKey: 38 tests
-PASS del.tabIndex: 26 tests
-PASS del.cite: 44 tests
-PASS del.dateTime: 38 tests
-PASS details.title: 38 tests
-PASS details.lang: 38 tests
-PASS details.dir: 68 tests
-PASS details.className (<details class>): 38 tests
-PASS details.autofocus: 39 tests
-PASS details.hidden: 39 tests
-PASS details.accessKey: 38 tests
-PASS details.tabIndex: 26 tests
-PASS details.open: 39 tests
-PASS summary.title: 38 tests
-PASS summary.lang: 38 tests
-PASS summary.dir: 68 tests
-PASS summary.className (<summary class>): 38 tests
-PASS summary.autofocus: 39 tests
-PASS summary.hidden: 39 tests
-PASS summary.accessKey: 38 tests
-PASS summary.tabIndex: 26 tests
-PASS menu.title: 38 tests
-PASS menu.lang: 38 tests
-PASS menu.dir: 68 tests
-PASS menu.className (<menu class>): 38 tests
-PASS menu.autofocus: 39 tests
-PASS menu.hidden: 39 tests
-PASS menu.accessKey: 38 tests
-PASS menu.tabIndex: 26 tests
-PASS menu.compact: 39 tests
-PASS dialog.title: 38 tests
-PASS dialog.lang: 38 tests
-PASS dialog.dir: 68 tests
-PASS dialog.className (<dialog class>): 38 tests
-PASS dialog.autofocus: 39 tests
-PASS dialog.hidden: 39 tests
-PASS dialog.accessKey: 38 tests
-PASS dialog.tabIndex: 26 tests
-PASS dialog.open: 39 tests
-PASS undefinedelement.title: 38 tests
-PASS undefinedelement.lang: 38 tests
-PASS undefinedelement.dir: 68 tests
-PASS undefinedelement.className (<undefinedelement class>): 38 tests
-PASS undefinedelement.autofocus: 39 tests
-PASS undefinedelement.hidden: 39 tests
-PASS undefinedelement.accessKey: 38 tests
-PASS undefinedelement.tabIndex: 26 tests
-PASS undefinedelement.enterKeyHint: 114 tests
-PASS undefinedelement.inputMode: 120 tests
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/parser-inserted-style-element.tentative.html b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/parser-inserted-style-element.tentative.html
new file mode 100644
index 0000000..9a358aa4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/parser-inserted-style-element.tentative.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>Parser-inserted style elements are implicitly render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+<script>
+// Test case must be set up before the stylesheet, because the stylesheet is
+// script-blocking, which means we can't set it up while the stylesheet is
+// loading.
+test_render_blocking(() => {
+  let color = getComputedStyle(document.querySelector('.target')).color;
+  assert_equals(color, 'rgb(255, 0, 0)');
+}, 'Render-blocking stylesheet is applied');
+</script>
+<style>
+@import url('support/target-red.css?pipe=trickle(d1)');
+</style>
+<div class="target">
+  This should be red
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/parser-inserted-stylesheet-link.tentative.html b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/parser-inserted-stylesheet-link.tentative.html
new file mode 100644
index 0000000..0a77144
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/parser-inserted-stylesheet-link.tentative.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>Parser-inserted stylesheet links are implicitly render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+<script>
+// Test case must be set up before the stylesheet, because the stylesheet is
+// script-blocking, which means we can't set it up while the stylesheet is
+// loading.
+test_render_blocking(() => {
+  let color = getComputedStyle(document.querySelector('.target')).color;
+  assert_equals(color, 'rgb(255, 0, 0)');
+}, 'Render-blocking stylesheet is applied');
+</script>
+<link rel="stylesheet" href="support/target-red.css?pipe=trickle(d1)">
+<div class="target">
+  This should be red
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/support/target-red.css b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/support/target-red.css
new file mode 100644
index 0000000..a387acd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/support/target-red.css
@@ -0,0 +1,3 @@
+.target {
+  color: red;
+}
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/support/test-render-blocking.js b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/support/test-render-blocking.js
new file mode 100644
index 0000000..3cd3b7d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/dom/render-blocking-mechanism/support/test-render-blocking.js
@@ -0,0 +1,46 @@
+class LoadObserver {
+  constructor(object) {
+    this.finishTime = null;
+    this.load = new Promise((resolve, reject) => {
+      object.onload = ev => {
+        this.finishTime = ev.timeStamp;
+        resolve(ev);
+      };
+      object.onerror = reject;
+    });
+  }
+
+  get finished() {
+    return this.finishTime !== null;
+  }
+}
+
+// Error margin for comparing timestamps of paint and load events, in case they
+// are reported by different threads.
+const epsilon = 50;
+
+function test_render_blocking(finalTest, finalTestTitle) {
+  // Ideally, we should observe the 'load' event on the specific render-blocking
+  // elements. However, this is not possible for script-blocking stylesheets, so
+  // we have to observe the 'load' event on 'window' instead.
+  // TODO(xiaochengh): Add tests for other types of render-blocking elements and
+  // observe the specific 'load' events on them.
+  const loadObserver = new LoadObserver(window);
+
+  promise_test(async test => {
+    assert_implements(window.PerformancePaintTiming);
+
+    await test.step_wait(() => performance.getEntriesByType('paint').length);
+
+    assert_true(loadObserver.finished);
+    for (let entry of performance.getEntriesByType('paint')) {
+      assert_greater_than(entry.startTime, loadObserver.finishTime - epsilon,
+                          `${entry.name} should occur after loading render-blocking resources`);
+    }
+  }, 'Rendering is blocked before render-blocking resources are loaded');
+
+  promise_test(test => {
+    return loadObserver.load.then(() => finalTest(test));
+  }, finalTestTitle);
+}
+
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/lone-surrogates.sub.html b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/lone-surrogates.sub.html
new file mode 100644
index 0000000..e47ab0f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/lone-surrogates.sub.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset={{GET[encoding]}}> <!-- ends up as <meta charset> by default which is windows-1252 -->
+<meta name=variant content="?encoding=windows-1252">
+<meta name=variant content="?encoding=utf8">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+function expected(encoding) {
+  return "?" + {
+    // Replacement character (not bogus UTF-8)
+    "UTF-8": "%EF%BF%BD",
+    // Charref for the replacement character (not the lone surrogate)
+    "windows-1252": "%26%2365533%3B",
+  }[encoding];
+}
+
+test(t => {
+  const elm = document.createElement("a");
+  document.body.appendChild(elm);
+  t.add_cleanup(() => elm.remove());
+  elm.setAttribute("href", "?\uD800");
+
+  const shouldEndWith = expected(document.characterSet);
+  assert_true(
+    elm.href.endsWith(shouldEndWith),
+    `${elm.href} did not end with ${shouldEndWith}`
+  );
+}, `Query parsing with lone surrogates in ${document.characterSet}`);
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/lone-surrogates.sub_encoding=windows-1252-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/lone-surrogates.sub_encoding=windows-1252-expected.txt
new file mode 100644
index 0000000..a581aae8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/lone-surrogates.sub_encoding=windows-1252-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Query parsing with lone surrogates in windows-1252 assert_true: http://web-platform.test:8001/html/infrastructure/urls/resolving-urls/query-encoding/lone-surrogates.sub.html?%26%2355296%3B did not end with ?%26%2365533%3B expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size-ref.html b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size-ref.html
new file mode 100644
index 0000000..8b1b422
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size-ref.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<select>
+  <option>ABC</option>
+</select>
+<select>
+  <option>ABC</option>
+</select>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size.html b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size.html
new file mode 100644
index 0000000..7f36708
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>Select should be as wide as needed to fit its options regardless of option styles</title>
+<link rel=match href=select-intrinsic-option-font-size-ref.html>
+<select>
+  <option style="font-size: 5px">ABC</option>
+</select>
+<select>
+  <option style="font-size: 50px">ABC</option>
+</select>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-001.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-001.html
new file mode 100644
index 0000000..327c9f4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-001.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Canvas descendants focusability</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#being-used-as-relevant-canvas-fallback-content">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#focusable-area">
+<meta name="assert" content="Checks that elements being used as relevant canvas
+    fallback content can be focusable even if not rendered.">
+<div id="log"></div>
+<canvas>
+  <button data-focusable="true"></button>
+  <section data-focusable="false">
+    <div data-focusable="false"></div>
+    <span data-focusable="false"></span>
+    <a data-focusable="false"></a>
+  </section>
+  <section tabindex="-1" data-focusable="true">
+    <div tabindex="-1" data-focusable="true"></div>
+    <span tabindex="-1" data-focusable="true"></span>
+    <a href="#" data-focusable="true"></a>
+  </section>
+</canvas>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+for (let element of document.querySelectorAll("[data-focusable]")) {
+  let title = element.cloneNode(false).outerHTML.toLowerCase();
+  title = title.slice(0, title.lastIndexOf("<"));
+  test(function() {
+    assert_true(document.activeElement !== element, "Not initially focused");
+    element.focus();
+    if (JSON.parse(element.dataset.focusable)) {
+      assert_true(document.activeElement === element, "Should be focused");
+    } else {
+      assert_true(document.activeElement !== element, "Shouldn't be focused");
+    }
+  }, title);
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-002.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-002.html
new file mode 100644
index 0000000..aa60736
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-002.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Canvas descendants focusability</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#being-used-as-relevant-canvas-fallback-content">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#focusable-area">
+<meta name="assert" content="Checks that descendants of a non-rendered canvas
+    aren't relevant canvas fallback content, so they aren't focusable.">
+<div id="log"></div>
+<canvas hidden>
+  <button data-focusable="false"></button>
+  <section tabindex="-1" data-focusable="false">
+    <div tabindex="-1" data-focusable="false"></div>
+    <span tabindex="-1" data-focusable="false"></span>
+    <a href="#" data-focusable="false"></a>
+  </section>
+</canvas>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup(() => {
+  const canvas = document.querySelector("canvas");
+  assert_equals(canvas.getClientRects().length, 0, "Canvas not rendered");
+});
+for (let element of document.querySelectorAll("[data-focusable]")) {
+  let title = element.cloneNode(false).outerHTML.toLowerCase();
+  title = title.slice(0, title.lastIndexOf("<"));
+  test(function() {
+    assert_equals(element.getClientRects().length, 0, "Not rendered");
+    assert_true(document.activeElement !== element, "Not initially focused");
+    element.focus();
+    if (JSON.parse(element.dataset.focusable)) {
+      assert_true(document.activeElement === element, "Should be focused");
+    } else {
+      assert_true(document.activeElement !== element, "Shouldn't be focused");
+    }
+  }, title);
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-003.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-003.tentative.html
new file mode 100644
index 0000000..98d60cf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-003.tentative.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Canvas descendants focusability</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#being-used-as-relevant-canvas-fallback-content">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#focusable-area">
+<link rel="help" href="https://github.com/whatwg/html/issues/7534">
+<meta name="assert" content="Checks that elements being used as relevant canvas
+    fallback content can't be focusable if they are not rendered because of an
+    explicit 'display: none' or 'display: contents' style.">
+<div id="log"></div>
+<canvas>
+  <button hidden data-focusable="false"></button>
+  <section hidden tabindex="-1" data-focusable="false">
+    <div tabindex="-1" data-focusable="false"></div>
+    <span tabindex="-1" data-focusable="false"></span>
+    <a href="#" data-focusable="false"></a>
+  </section>
+  <button style="display: contents" data-focusable="false"></button>
+  <section style="display: contents" tabindex="-1" data-focusable="false">
+    <div style="display: contents" tabindex="-1" data-focusable="false"></div>
+    <span style="display: contents" tabindex="-1" data-focusable="false"></span>
+    <a style="display: contents" href="#" data-focusable="false"></a>
+  </section>
+</canvas>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup(() => {
+  const canvas = document.querySelector("canvas");
+  assert_greater_than(canvas.getClientRects().length, 0, "Canvas is rendered");
+});
+for (let element of document.querySelectorAll("[data-focusable]")) {
+  let title = element.cloneNode(false).outerHTML.toLowerCase();
+  title = title.slice(0, title.lastIndexOf("<"));
+  test(function() {
+    assert_equals(element.getClientRects().length, 0, "Not rendered");
+    assert_true(document.activeElement !== element, "Not initially focused");
+    element.focus();
+    if (JSON.parse(element.dataset.focusable)) {
+      assert_true(document.activeElement === element, "Should be focused");
+    } else {
+      assert_true(document.activeElement !== element, "Shouldn't be focused");
+    }
+  }, title);
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-004.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-004.tentative.html
new file mode 100644
index 0000000..5d8dfcd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-004.tentative.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Canvas descendants focusability</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#being-used-as-relevant-canvas-fallback-content">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#focusable-area">
+<link rel="help" href="https://github.com/whatwg/html/issues/7534">
+<meta name="assert" content="Checks that elements being used as relevant canvas
+    fallback content can't be focusable if they are not in the flat tree.">
+<div id="log"></div>
+<canvas>
+  <section id="shadow-host">
+    <button data-focusable="false"></button>
+    <section tabindex="-1" data-focusable="false">
+      <div tabindex="-1" data-focusable="false"></div>
+      <span tabindex="-1" data-focusable="false"></span>
+      <a href="#" data-focusable="false"></a>
+    </section>
+  </section>
+</canvas>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup(() => {
+  const canvas = document.querySelector("canvas");
+  assert_greater_than(canvas.getClientRects().length, 0, "Canvas is rendered");
+  const shadowHost = document.getElementById("shadow-host");
+  const shadowRoot = shadowHost.attachShadow({ mode: "open" });
+  const slot = document.createElement("slot");
+  slot.name = "slot";
+  shadowRoot.appendChild(slot);
+});
+for (let element of document.querySelectorAll("[data-focusable]")) {
+  let title = element.cloneNode(false).outerHTML.toLowerCase();
+  title = title.slice(0, title.lastIndexOf("<"));
+  test(function() {
+    assert_equals(element.getClientRects().length, 0, "Not rendered");
+    assert_true(document.activeElement !== element, "Not initially focused");
+    element.focus();
+    if (JSON.parse(element.dataset.focusable)) {
+      assert_true(document.activeElement === element, "Should be focused");
+    } else {
+      assert_true(document.activeElement !== element, "Shouldn't be focused");
+    }
+  }, title);
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-005.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-005.html
new file mode 100644
index 0000000..f3bee6b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/canvas-descendants-focusability-005.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Canvas descendants focusability</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#being-used-as-relevant-canvas-fallback-content">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#focusable-area">
+<meta name="assert" content="Checks that descendants of a canvas that represents
+    fallback content are not focusable if not rendered, as usual.">
+<div id="log"></div>
+<!-- Use a sandboxed iframe to disable scripting and make the canvas
+     represent its fallback content instead of embedded content. -->
+<iframe sandbox="allow-same-origin" allow="focus-without-user-activation *"
+    srcdoc='
+    <button data-focusable="true" a></button>
+    <canvas>
+      <button data-focusable="true"></button>
+      <section tabindex="-1" data-focusable="true">
+        <div tabindex="-1" data-focusable="true"></div>
+        <span tabindex="-1" data-focusable="true"></span>
+        <a href="#" data-focusable="true"></a>
+      </section>
+      <button hidden data-focusable="false"></button>
+      <section tabindex="-1" hidden data-focusable="false">
+        <div tabindex="-1" data-focusable="false"></div>
+        <span tabindex="-1" data-focusable="false"></span>
+        <a href="#" data-focusable="false"></a>
+      </section>
+    </canvas>
+    '></iframe>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup({ explicit_done: true });
+setup(async () => {
+  const iframe = document.querySelector("iframe");
+  await new Promise(resolve => {
+    const win = iframe.contentWindow;
+    if (win.location.href === "about:blank" ||
+        win.document.readyState !== "complete") {
+      iframe.addEventListener("load", resolve, {once: true});
+    } else {
+      resolve();
+    }
+  });
+  const doc = iframe.contentDocument;
+  for (let element of doc.querySelectorAll("[data-focusable]")) {
+    let title = element.cloneNode(false).outerHTML.toLowerCase();
+    title = title.slice(0, title.lastIndexOf("<"));
+    test(function() {
+      assert_true(doc.activeElement !== element, "Not initially focused");
+      element.focus();
+      if (JSON.parse(element.dataset.focusable)) {
+        assert_true(doc.activeElement === element, "Should be focused");
+      } else {
+        assert_true(doc.activeElement !== element, "Shouldn't be focused");
+      }
+    }, title);
+  }
+  done();
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/beforeinput.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/forms/beforeinput.tentative-expected.txt
new file mode 100644
index 0000000..faf6509
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/beforeinput.tentative-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+FAIL <input type="text" onbeforeinput="onBeforeInput(event)" oninput="onInput(event)"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="text"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="search" onbeforeinput="onBeforeInput(event)" oninput="onInput(event)"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="search"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="tel" onbeforeinput="onBeforeInput(event)" oninput="onInput(event)"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="tel"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="url" onbeforeinput="onBeforeInput(event)" oninput="onInput(event)"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="url"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="email" onbeforeinput="onBeforeInput(event)" oninput="onInput(event)"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="email"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="password" onbeforeinput="onBeforeInput(event)" oninput="onInput(event)"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="password"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="number" onbeforeinput="onBeforeInput(event)" oninput="onInput(event)"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <input type="number"> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <textarea onbeforeinput="onBeforeInput(event)" oninput="onInput(event)"></textarea> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+FAIL <textarea></textarea> assert_array_equals: Got expected events lengths differ, expected array ["beforeinput", "input"] length 2, got ["input"] length 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/beforeinput.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/beforeinput.tentative.html
new file mode 100644
index 0000000..7aa51a2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/beforeinput.tentative.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test the onbeforeinput attribute</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<div id="container"></div>
+<script>
+  const container = document.getElementById("container");
+  const events = new Map();
+
+  function handleEvent(event) {
+    if (!events.has(event.target)) {
+      events.set(event.target, []);
+    }
+    events.get(event.target).push(event);
+  }
+
+  let onInputFired = null;
+
+  const onBeforeInput = handleEvent;
+  const onInput = (event) => {
+    handleEvent(event);
+    onInputFired()
+  }
+
+  let elems = [];
+  for (let type of ["text", "search", "tel", "url", "email", "password", "number"]) {
+    elems.push(`<input type=${type} onbeforeinput="onBeforeInput(event)" oninput="onInput(event)">
+<input type=${type}>
+`);
+  }
+  elems.push(`<textarea onbeforeinput="onBeforeInput(event)" oninput="onInput(event)"></textarea>
+<textarea></textarea>`)
+  container.innerHTML = elems.join("");
+
+for (const element of container.children) {
+  promise_test(async t => {
+    if (!element.hasAttribute("onbeforeinput")) {
+      element.onbeforeinput = e => onBeforeInput(e);
+      element.oninput = e => onInput(e);
+    };
+
+    let afterOnInput = new Promise(resolve => {onInputFired = resolve});
+    await test_driver.send_keys(element, "1"); // has to be a number so <input type=number> works
+    // Ensure we're in the post-update state
+    await afterOnInput;
+
+    assert_true(events.has(element), "Got events for element");
+    let elementEvents = events.get(element);
+
+    assert_array_equals(elementEvents.map(event => event.type), ["beforeinput", "input"], "Got expected events");
+  }, `${element.outerHTML}`);
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/support/validator.js b/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/support/validator.js
index 48e5648..aa43b3a2f 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/support/validator.js
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/support/validator.js
@@ -319,12 +319,6 @@
     }, data.name + " (in a form)");
   },
 
-  test_support_type: function(ctl, typ, testName) {
-    test(function () {
-      assert_equals(ctl.type, typ, "The " + typ + " type should be supported.");
-    }, testName);
-  },
-
   set_conditions: function(ctl, obj) {
     [
       "checked",
@@ -461,14 +455,6 @@
           }
 
           prefix = "[" + testee[i].tag.toUpperCase() + " in " + testee[i].types[typ].toUpperCase() + " status] ";
-          if (ele.type != testee[i].types[typ]) {
-            this.test_support_type(
-              ele,
-              testee[i].types[typ],
-              prefix + "The " + testee[i].types[typ] + " type must be supported."
-            );
-            continue;
-          }
 
           for (var j = 0; j < testee[i].testData.length; j++) {
             testee[i].testData[j].name = testee[i].testData[j].name.replace(/\[.*\]\s/g, prefix);
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-visibility-hidden-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-visibility-hidden-expected.txt
new file mode 100644
index 0000000..52d249ce
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-visibility-hidden-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+PASS Non-modal dialog should let parent visibility inherit
+FAIL Modal dialog should have visibility: visible by default in UA sheet assert_equals: expected "visible" but got "hidden"
+PASS Modal dialog visibility should be overridable
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-visibility-hidden.html b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-visibility-hidden.html
new file mode 100644
index 0000000..abba08c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-visibility-hidden.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<title>Test that modal dialogs have visibility: visible set from the UA sheet</title>
+<meta charset="utf-8">
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3:is-modal">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div style="visibility: hidden">
+    <dialog>This is a dialog</dialog>
+</div>
+
+<script>
+let dialog = document.querySelector("dialog");
+
+test(t => {
+    dialog.show();
+    t.add_cleanup(() => dialog.close());
+    assert_equals(getComputedStyle(dialog).visibility, "hidden");
+}, "Non-modal dialog should let parent visibility inherit");
+
+test(t => {
+    dialog.showModal();
+    t.add_cleanup(() => dialog.close());
+    assert_equals(getComputedStyle(dialog).visibility, "visible");
+}, "Modal dialog should have visibility: visible by default in UA sheet");
+
+test(t => {
+    dialog.style.visibility = "hidden";
+    dialog.showModal();
+    t.add_cleanup(() => {
+        dialog.style.removeProperty("visibility");
+        dialog.close();
+    });
+    assert_equals(getComputedStyle(dialog).visibility, "hidden");
+}, "Modal dialog visibility should be overridable");
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative.html
index e001258..2b37c2d6 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative.html
@@ -33,6 +33,16 @@
 </popup>
 <button popup=p6>Popup 6</button>
 
+<my-element id="myElement">
+  <template shadowroot="open">
+    <button id=b7 onclick='showPopup7()'>Popup7</button>
+    <popup id=p7 anchor=b7 style="top: 100px;">
+      <p>Popup content.</p>
+      <input id="inside7" type="text" placeholder="some text">
+    </popup>
+  </template>
+</my-element>
+
 <style>
   #p1 { top:50px; }
   #p2 { top:50px; left:250px; }
@@ -71,6 +81,13 @@
   const popup4 = document.querySelector('#p4');
   const popup5 = document.querySelector('#p5');
   const popup6 = document.querySelector('#p6');
+  const button7 = document.querySelector('#myElement').shadowRoot.querySelector('#b7');
+  const popup7 = document.querySelector('#myElement').shadowRoot.querySelector('#p7');
+  const inside7 = document.querySelector('#myElement').shadowRoot.querySelector('#inside7');
+
+  function showPopup7() {
+    popup7.show();
+  }
 
   (async function() {
     setup({ explicit_done: true });
@@ -184,6 +201,17 @@
       popup6.hide();
     },'Scrolling within a popup should not close the popup');
 
+    button7.click();
+    assert_true(popup7.open,'invoking element should open popup');
+    inside7.click();
+    test(t => {
+      assert_true(popup7.open);
+    },'Clicking inside a shadow DOM popup does not close that popup');
+    await clickOn(outside);
+    test(t => {
+      assert_false(popup7.open);
+    },'Clicking outside a shadow DOM popup should close that popup');
+
     done();
   })();
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/inert/inert-canvas-fallback-content.tentative.html b/third_party/blink/web_tests/external/wpt/inert/inert-canvas-fallback-content.tentative.html
new file mode 100644
index 0000000..f22549b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/inert/inert-canvas-fallback-content.tentative.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Focusability of inert inside canvas</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#focusable-area">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#inert">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#being-used-as-relevant-canvas-fallback-content">
+<link rel="help" href="https://github.com/whatwg/html/issues/7534">
+<meta name="assert" content="
+  Checks that inert elements are not focusable
+  even when being used as relevant canvas fallback content,
+  even in a display:none subtree">
+<div id="log"></div>
+<canvas>
+  <section>
+    <div tabindex="-1" data-focusable="true">
+      normal `div`
+    </div>
+    <span tabindex="-1" data-focusable="true">
+      normal `span`
+    </span>
+    <a href="#" data-focusable="true">
+      normal `a`
+    </a>
+  </section>
+  <section style="display: none">
+    <div tabindex="-1" data-focusable="false">
+      `div` in `display: none`
+    </div>
+    <span tabindex="-1" data-focusable="false">
+      `span` in `display: none`
+    </span>
+    <a href="#" data-focusable="false">
+      `a` in `display: none`
+    </a>
+  </section>
+  <section inert>
+    <div tabindex="-1" data-focusable="false">
+      inert `div`
+    </div>
+    <span tabindex="-1" data-focusable="false">
+      inert `span`
+    </span>
+    <a href="#" data-focusable="false">
+      inert `a`
+    </a>
+  </section>
+  <section inert style="display: none">
+    <div tabindex="-1" data-focusable="false">
+      inert `div` in `display: none`
+    </div>
+    <span tabindex="-1" data-focusable="false">
+      inert `span` in `display: none`
+    </span>
+    <a href="#" data-focusable="false">
+      inert `a` in `display: none`
+    </a>
+  </section>
+</canvas>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+for (let element of document.querySelectorAll("[data-focusable]")) {
+  test(function() {
+    assert_not_equals(document.activeElement, element);
+    element.focus();
+    if (JSON.parse(element.dataset.focusable)) {
+      assert_equals(document.activeElement, element);
+    } else {
+      assert_not_equals(document.activeElement, element);
+    }
+  }, element.textContent);
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/OES_draw_buffers_indexed.idl b/third_party/blink/web_tests/external/wpt/interfaces/OES_draw_buffers_indexed.idl
index 25696f12..bf1932c 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/OES_draw_buffers_indexed.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/OES_draw_buffers_indexed.idl
@@ -1,7 +1,7 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into webref
 // (https://github.com/w3c/webref)
-// Source: WebGL OES_draw_buffers_indexed Extension Draft Specification (https://www.khronos.org/registry/webgl/extensions/OES_draw_buffers_indexed/)
+// Source: WebGL OES_draw_buffers_indexed Extension Specification (https://www.khronos.org/registry/webgl/extensions/OES_draw_buffers_indexed/)
 
 [Exposed=(Window,Worker), LegacyNoInterfaceObject]
 interface OES_draw_buffers_indexed {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/app-history.idl b/third_party/blink/web_tests/external/wpt/interfaces/app-history.idl
index b87bb582..f5f1b7e 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/app-history.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/app-history.idl
@@ -121,7 +121,7 @@
 
 [Exposed=Window]
 interface AppHistoryEntry : EventTarget {
-  readonly attribute USVString url;
+  readonly attribute USVString? url;
   readonly attribute DOMString key;
   readonly attribute DOMString id;
   readonly attribute long long index;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/autoplay.idl b/third_party/blink/web_tests/external/wpt/interfaces/autoplay.idl
new file mode 100644
index 0000000..f2be5bb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/interfaces/autoplay.idl
@@ -0,0 +1,18 @@
+// GENERATED CONTENT - DO NOT EDIT
+// Content was automatically extracted by Reffy into webref
+// (https://github.com/w3c/webref)
+// Source: Autoplay Policy Detection (https://w3c.github.io/autoplay/)
+
+enum AutoplayPolicy {
+  "allowed",
+  "allowed-muted",
+  "disallowed"
+};
+
+partial interface Document {
+  readonly attribute AutoplayPolicy autoplayPolicy;
+};
+
+partial interface HTMLMediaElement {
+  readonly attribute AutoplayPolicy autoplayPolicy;
+};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/compute-pressure.idl b/third_party/blink/web_tests/external/wpt/interfaces/compute-pressure.idl
index 8ea37bf..0cf880b 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/compute-pressure.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/compute-pressure.idl
@@ -4,7 +4,7 @@
 // Source: Compute Pressure API (https://wicg.github.io/compute-pressure/)
 
 callback ComputePressureUpdateCallback = undefined (
-  ComputePressureObserverUpdate update,
+  ComputePressureEntry update,
   ComputePressureObserver observer
 );
 
@@ -18,7 +18,7 @@
   undefined unobserve();
 };
 
-dictionary ComputePressureObserverUpdate {
+dictionary ComputePressureEntry {
   double cpuSpeed;
   double cpuUtilization;
   ComputePressureObserverOptions options;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/contact-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/contact-api.idl
index 7f67a5d..d7f2ba5d 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/contact-api.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/contact-api.idl
@@ -1,7 +1,7 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into webref
 // (https://github.com/w3c/webref)
-// Source: Contact Picker API (https://wicg.github.io/contact-api/spec/)
+// Source: Contact Picker API (https://w3c.github.io/contact-api/spec/)
 
 [Exposed=Window]
 partial interface Navigator {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/credential-management.idl b/third_party/blink/web_tests/external/wpt/interfaces/credential-management.idl
index a07aa0b..bf1adba 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/credential-management.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/credential-management.idl
@@ -7,6 +7,7 @@
 interface Credential {
   readonly attribute USVString id;
   readonly attribute DOMString type;
+  static boolean isConditionalMediationAvailable();
 };
 
 [SecureContext]
@@ -39,6 +40,7 @@
 enum CredentialMediationRequirement {
   "silent",
   "optional",
+  "conditional",
   "required"
 };
 
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-cascade-5.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-cascade-5.idl
deleted file mode 100644
index 4166ae6..0000000
--- a/third_party/blink/web_tests/external/wpt/interfaces/css-cascade-5.idl
+++ /dev/null
@@ -1,16 +0,0 @@
-// Source: CSS Cascading and Inheritance Level 5 (https://drafts.csswg.org/css-cascade-5/)
-
-[Exposed=Window]
-partial interface CSSImportRule {
-  readonly attribute CSSOMString? layerName;
-};
-
-[Exposed=Window]
-interface CSSLayerBlockRule : CSSGroupingRule {
-  readonly attribute CSSOMString name;
-};
-
-[Exposed=Window]
-interface CSSLayerStatementRule : CSSRule {
-  readonly attribute FrozenArray<CSSOMString> nameList;
-};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-cascade.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-cascade.idl
new file mode 100644
index 0000000..9011dc7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/interfaces/css-cascade.idl
@@ -0,0 +1,18 @@
+// GENERATED CONTENT - DO NOT EDIT
+// Content was automatically extracted by Reffy into webref
+// (https://github.com/w3c/webref)
+// Source: CSS Cascading and Inheritance Level 5 (https://drafts.csswg.org/css-cascade-5/)
+
+partial interface CSSImportRule {
+  readonly attribute CSSOMString? layerName;
+};
+
+[Exposed=Window]
+interface CSSLayerBlockRule : CSSGroupingRule {
+  readonly attribute CSSOMString name;
+};
+
+[Exposed=Window]
+interface CSSLayerStatementRule : CSSRule {
+  readonly attribute FrozenArray<CSSOMString> nameList;
+};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-highlight-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-highlight-api.idl
index 56db8c35..f3c6b2e9 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/css-highlight-api.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/css-highlight-api.idl
@@ -3,11 +3,18 @@
 // (https://github.com/w3c/webref)
 // Source: CSS Custom Highlight API Module Level 1 (https://drafts.csswg.org/css-highlight-api-1/)
 
+enum HighlightType {
+  "highlight",
+  "spelling-error",
+  "grammar-error"
+};
+
 [Exposed=Window]
 interface Highlight {
   constructor(AbstractRange... initialRanges);
   setlike<AbstractRange>;
   attribute long priority;
+  attribute HighlightType type;
 };
 
 partial namespace CSS {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-pseudo.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-pseudo.idl
index 2c90ff2b..dbe4c54 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/css-pseudo.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/css-pseudo.idl
@@ -7,6 +7,8 @@
 interface CSSPseudoElement : EventTarget {
     readonly attribute CSSOMString type;
     readonly attribute Element element;
+    readonly attribute (Element or CSSPseudoElement) parent;
+    CSSPseudoElement? pseudo(CSSOMString type);
 };
 
 partial interface Element {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-typed-om.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-typed-om.idl
index b3942e6b..3a0a6bd 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/css-typed-om.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/css-typed-om.idl
@@ -323,7 +323,7 @@
 interface CSSColorValue : CSSStyleValue {
     readonly attribute CSSKeywordValue colorSpace;
     CSSColorValue to(CSSKeywordish colorSpace);
-    [Exposed=Window] static CSSColorValue parse(USVString cssText);
+    [Exposed=Window] static (CSSColorValue or CSSStyleValue) parse(USVString cssText);
 };
 
 [Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/dom.idl b/third_party/blink/web_tests/external/wpt/interfaces/dom.idl
index d3255b4..762e7a5 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/dom.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/dom.idl
@@ -3,7 +3,7 @@
 // (https://github.com/w3c/webref)
 // Source: DOM Standard (https://dom.spec.whatwg.org/)
 
-[Exposed=(Window,Worker,AudioWorklet)]
+[Exposed=*]
 interface Event {
   constructor(DOMString type, optional EventInit eventInitDict = {});
 
@@ -46,7 +46,7 @@
   [Replaceable] readonly attribute (Event or undefined) event; // legacy
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=*]
 interface CustomEvent : Event {
   constructor(DOMString type, optional CustomEventInit eventInitDict = {});
 
@@ -59,7 +59,7 @@
   any detail = null;
 };
 
-[Exposed=(Window,Worker,AudioWorklet)]
+[Exposed=*]
 interface EventTarget {
   constructor();
 
@@ -82,7 +82,7 @@
   AbortSignal signal;
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=*]
 interface AbortController {
   constructor();
 
@@ -91,12 +91,13 @@
   undefined abort(optional any reason);
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=*]
 interface AbortSignal : EventTarget {
   [NewObject] static AbortSignal abort(optional any reason);
 
   readonly attribute boolean aborted;
   readonly attribute any reason;
+  undefined throwIfAborted();
 
   attribute EventHandler onabort;
 };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/edit-context.idl b/third_party/blink/web_tests/external/wpt/interfaces/edit-context.idl
new file mode 100644
index 0000000..f5e60bd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/interfaces/edit-context.idl
@@ -0,0 +1,113 @@
+// GENERATED CONTENT - DO NOT EDIT
+// Content was automatically extracted by Reffy into webref
+// (https://github.com/w3c/webref)
+// Source: EditContext API (https://w3c.github.io/edit-context/)
+
+partial interface Element {
+     attribute EditContext? editContext;
+};
+
+dictionary EditContextInit {
+    DOMString text;
+    unsigned long selectionStart;
+    unsigned long selectionEnd;
+};
+
+[Exposed=Window]
+interface EditContext : EventTarget {
+    constructor(optional EditContextInit options = {});
+
+    undefined updateText(unsigned long rangeStart, unsigned long rangeEnd,
+        DOMString text);
+    undefined updateSelection(unsigned long start, unsigned long end);
+    undefined updateControlBound(DOMRect controlBound);
+    undefined updateSelectionBound(DOMRect selectionBound);
+    undefined updateCharacterBounds(unsigned long rangeStart, sequence<DOMRect> characterBounds);
+
+    sequence<Element> attachedElements();
+
+    readonly attribute DOMString text;
+    readonly attribute unsigned long selectionStart;
+    readonly attribute unsigned long selectionEnd;
+    readonly attribute unsigned long compositionRangeStart;
+    readonly attribute unsigned long compositionRangeEnd;
+    readonly attribute boolean isInComposition;
+    readonly attribute DOMRect controlBound;
+    readonly attribute DOMRect selectionBound;
+    readonly attribute unsigned long characterBoundsRangeStart;
+    sequence<DOMRect> characterBounds();
+
+    attribute EventHandler ontextupdate;
+    attribute EventHandler ontextformatupdate;
+    attribute EventHandler oncharacterboundsupdate;
+    attribute EventHandler oncompositionstart;
+    attribute EventHandler oncompositionend;
+};
+
+dictionary TextUpdateEventInit {
+    unsigned long updateRangeStart;
+    unsigned long updateRangeEnd;
+    DOMString text;
+    unsigned long selectionStart;
+    unsigned long selectionEnd;
+    unsigned long compositionStart;
+    unsigned long compositionEnd;
+};
+
+[Exposed=Window]
+interface TextUpdateEvent : Event {
+    constructor(optional TextUpdateEventInit options = {});
+    readonly attribute unsigned long updateRangeStart;
+    readonly attribute unsigned long updateRangeEnd;
+    readonly attribute DOMString text;
+    readonly attribute unsigned long selectionStart;
+    readonly attribute unsigned long selectionEnd;
+    readonly attribute unsigned long compositionStart;
+    readonly attribute unsigned long compositionEnd;
+};
+
+dictionary TextFormatInit {
+    unsigned long rangeStart;
+    unsigned long rangeEnd;
+    DOMString textColor;
+    DOMString backgroundColor;
+    DOMString underlineStyle;
+    DOMString underlineThickness;
+    DOMString underlineColor;
+};
+
+[Exposed=Window]
+interface TextFormat {
+    constructor(optional TextFormatInit options = {});
+    attribute unsigned long rangeStart;
+    attribute unsigned long rangeEnd;
+    attribute DOMString textColor;
+    attribute DOMString backgroundColor;
+    attribute DOMString underlineStyle;
+    attribute DOMString underlineThickness;
+    attribute DOMString underlineColor;
+};
+
+dictionary TextFormatUpdateEventInit {
+    sequence<TextFormat> textFormats;
+};
+
+[Exposed=Window]
+interface TextFormatUpdateEvent : Event {
+    constructor(optional TextFormatUpdateEventInit options = {});
+
+    sequence<TextFormat> getTextFormats();
+};
+
+dictionary CharacterBoundsUpdateEventInit {
+    unsigned long rangeStart;
+    unsigned long rangeEnd;
+};
+
+[Exposed=Window]
+interface CharacterBoundsUpdateEvent : Event {
+    constructor(optional CharacterBoundsUpdateEventInit options = {});
+
+    readonly attribute unsigned long rangeStart;
+    readonly attribute unsigned long rangeEnd;
+};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/event-timing.idl b/third_party/blink/web_tests/external/wpt/interfaces/event-timing.idl
index 98e8d920f..329570e 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/event-timing.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/event-timing.idl
@@ -19,8 +19,14 @@
 };
 
 [Exposed=Window]
+interface InteractionCounts {
+    readonly maplike<DOMString, unsigned long long>;
+};
+
+[Exposed=Window]
 partial interface Performance {
     [SameObject] readonly attribute EventCounts eventCounts;
+    [SameObject] readonly attribute InteractionCounts interactionCounts;
 };
 
 partial dictionary PerformanceObserverInit {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/geolocation-API.idl b/third_party/blink/web_tests/external/wpt/interfaces/geolocation.idl
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/interfaces/geolocation-API.idl
rename to third_party/blink/web_tests/external/wpt/interfaces/geolocation.idl
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/html.idl b/third_party/blink/web_tests/external/wpt/interfaces/html.idl
index 2b5efa90..2eaf5d0 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/html.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/html.idl
@@ -933,6 +933,8 @@
   undefined setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve");
   undefined setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction);
 
+  undefined showPicker();
+
   // also has obsolete members
 };
 
@@ -1367,7 +1369,14 @@
 
 interface mixin CanvasFilters {
   // filters
-  attribute DOMString filter; // (default "none")
+  attribute (DOMString or CanvasFilter) filter; // (default "none")
+};
+
+typedef record<DOMString, any> CanvasFilterInput;
+
+[Exposed=(Window,Worker,PaintWorklet)]
+interface CanvasFilter {
+  constructor(optional (CanvasFilterInput or sequence<CanvasFilterInput>) filters);
 };
 
 interface mixin CanvasRect {
@@ -1993,9 +2002,9 @@
 
   // timers
   long setTimeout(TimerHandler handler, optional long timeout = 0, any... arguments);
-  undefined clearTimeout(optional long handle = 0);
+  undefined clearTimeout(optional long id = 0);
   long setInterval(TimerHandler handler, optional long timeout = 0, any... arguments);
-  undefined clearInterval(optional long handle = 0);
+  undefined clearInterval(optional long id = 0);
 
   // microtask queuing
   undefined queueMicrotask(VoidFunction callback);
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/local-font-access.idl b/third_party/blink/web_tests/external/wpt/interfaces/local-font-access.idl
index 577cd36..e37b2c7d 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/local-font-access.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/local-font-access.idl
@@ -8,20 +8,18 @@
   [SameObject] readonly attribute FontManager fonts;
 };
 Navigator includes NavigatorFonts;
-WorkerNavigator includes NavigatorFonts;
 
 [SecureContext,
- Exposed=(Window,Worker)]
+ Exposed=Window]
 interface FontManager {
   Promise<sequence<FontMetadata>> query(optional QueryOptions options = {});
 };
 
 dictionary QueryOptions {
-  boolean persistentAccess = false;
   sequence<DOMString> select = [];
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=Window]
 interface FontMetadata {
   Promise<Blob> blob();
 
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/manifest-incubations.idl b/third_party/blink/web_tests/external/wpt/interfaces/manifest-incubations.idl
new file mode 100644
index 0000000..bab3998
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/interfaces/manifest-incubations.idl
@@ -0,0 +1,24 @@
+// GENERATED CONTENT - DO NOT EDIT
+// Content was automatically extracted by Reffy into webref
+// (https://github.com/w3c/webref)
+// Source: Manifest Incubations (https://wicg.github.io/manifest-incubations/)
+
+[Exposed=Window]
+interface BeforeInstallPromptEvent : Event {
+  constructor(DOMString type, optional EventInit eventInitDict = {});
+  Promise<PromptResponseObject> prompt();
+};
+
+dictionary PromptResponseObject {
+  AppBannerPromptOutcome userChoice;
+};
+
+enum AppBannerPromptOutcome {
+  "accepted",
+  "dismissed"
+};
+
+partial interface Window {
+  attribute EventHandler onappinstalled;
+  attribute EventHandler onbeforeinstallprompt;
+};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-streams.idl b/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-streams.idl
index 7d51a2a..33511eb 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-streams.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-streams.idl
@@ -238,3 +238,11 @@
 typedef (DOMString or
 sequence<DOMString> or
 ConstrainDOMStringParameters) ConstrainDOMString;
+
+dictionary DevicePermissionDescriptor : PermissionDescriptor {
+  DOMString deviceId;
+};
+
+dictionary CameraDevicePermissionDescriptor : DevicePermissionDescriptor {
+  boolean panTiltZoom = false;
+};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-transform.idl b/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-transform.idl
new file mode 100644
index 0000000..5b2c8fa6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/interfaces/mediacapture-transform.idl
@@ -0,0 +1,23 @@
+// GENERATED CONTENT - DO NOT EDIT
+// Content was automatically extracted by Reffy into webref
+// (https://github.com/w3c/webref)
+// Source: MediaStreamTrack Insertable Media Processing using Streams (https://w3c.github.io/mediacapture-transform/)
+
+[Exposed=DedicatedWorker]
+interface MediaStreamTrackProcessor {
+    constructor(MediaStreamTrackProcessorInit init);
+    attribute ReadableStream readable;
+};
+
+dictionary MediaStreamTrackProcessorInit {
+  required MediaStreamTrack track;
+  [EnforceRange] unsigned short maxBufferSize;
+};
+
+[Exposed=DedicatedWorker]
+interface VideoTrackGenerator {
+  constructor();
+  readonly attribute WritableStream writable;
+  attribute boolean muted;
+  readonly attribute MediaStreamTrack track;
+};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/permissions.idl b/third_party/blink/web_tests/external/wpt/interfaces/permissions.idl
index 3112ef6..3a0f159 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/permissions.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/permissions.idl
@@ -56,11 +56,3 @@
   "speaker-selection",
   "xr-spatial-tracking",
 };
-
-dictionary DevicePermissionDescriptor : PermissionDescriptor {
-  DOMString deviceId;
-};
-
-dictionary CameraDevicePermissionDescriptor : DevicePermissionDescriptor {
-  boolean panTiltZoom = false;
-};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/priority-hints.idl b/third_party/blink/web_tests/external/wpt/interfaces/priority-hints.idl
new file mode 100644
index 0000000..835b0180
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/interfaces/priority-hints.idl
@@ -0,0 +1,30 @@
+// GENERATED CONTENT - DO NOT EDIT
+// Content was automatically extracted by Reffy into webref
+// (https://github.com/w3c/webref)
+// Source: Priority Hints (https://wicg.github.io/priority-hints/)
+
+enum Importance { "high", "low", "auto" };
+
+partial interface Request {
+  readonly attribute Importance importance;
+};
+
+partial dictionary RequestInit {
+  Importance importance;
+};
+
+partial interface HTMLImageElement {
+    [CEReactions] attribute DOMString importance;
+};
+
+partial interface HTMLLinkElement {
+    [CEReactions] attribute DOMString importance;
+};
+
+partial interface HTMLScriptElement {
+    [CEReactions] attribute DOMString importance;
+};
+
+partial interface HTMLIFrameElement {
+    [CEReactions] attribute DOMString importance;
+};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/sanitizer-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/sanitizer-api.idl
index b98da2a..8268384 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/sanitizer-api.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/sanitizer-api.idl
@@ -16,8 +16,11 @@
   static SanitizerConfig getDefaultConfiguration();
 };
 
+dictionary SetHTMLOptions {
+  Sanitizer sanitizer;
+};
 partial interface Element {
-  undefined setHTML(DOMString input, Sanitizer sanitizer);
+  undefined setHTML(DOMString input, optional SetHTMLOptions options = {});
 };
 
 dictionary SanitizerConfig {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/secure-payment-confirmation.idl b/third_party/blink/web_tests/external/wpt/interfaces/secure-payment-confirmation.idl
index 0a4416e..1522bff 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/secure-payment-confirmation.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/secure-payment-confirmation.idl
@@ -1,7 +1,7 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into webref
 // (https://github.com/w3c/webref)
-// Source: Secure Payment Confirmation (https://w3c.github.io/secure-payment-confirmation)
+// Source: Secure Payment Confirmation (https://w3c.github.io/secure-payment-confirmation/)
 
 dictionary SecurePaymentConfirmationRequest {
     required BufferSource challenge;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/streams.idl b/third_party/blink/web_tests/external/wpt/interfaces/streams.idl
index 2ebe5b74..f7084dd 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/streams.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/streams.idl
@@ -74,8 +74,8 @@
 ReadableStreamDefaultReader includes ReadableStreamGenericReader;
 
 dictionary ReadableStreamDefaultReadResult {
- any value;
- boolean done;
+  any value;
+  boolean done;
 };
 
 [Exposed=(Window,Worker,Worklet)]
@@ -88,8 +88,8 @@
 ReadableStreamBYOBReader includes ReadableStreamGenericReader;
 
 dictionary ReadableStreamBYOBReadResult {
- ArrayBufferView value;
- boolean done;
+  ArrayBufferView value;
+  boolean done;
 };
 
 [Exposed=(Window,Worker,Worklet)]
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/wasm-js-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/wasm-js-api.idl
index b56c8cf..141af90 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/wasm-js-api.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/wasm-js-api.idl
@@ -92,6 +92,7 @@
   "i64",
   "f32",
   "f64",
+  "v128",
   "externref",
   "anyfunc",
 };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-locks.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-locks.idl
index a0319a0..d79e404 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/web-locks.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/web-locks.idl
@@ -1,7 +1,7 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into webref
 // (https://github.com/w3c/webref)
-// Source: Web Locks API (https://wicg.github.io/web-locks/)
+// Source: Web Locks API (https://w3c.github.io/web-locks/)
 
 [SecureContext]
 interface mixin NavigatorLocks {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl
index 3b8be7fd..ff042b0 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl
@@ -51,6 +51,7 @@
   Promise<undefined> scan(optional NDEFScanOptions options={});
   Promise<undefined> write(NDEFMessageSource message,
                                  optional NDEFWriteOptions options={});
+  Promise<undefined> makeReadOnly(optional NDEFMakeReadOnlyOptions options={});
 };
 
 [SecureContext, Exposed=Window]
@@ -71,6 +72,10 @@
   AbortSignal? signal;
 };
 
+dictionary NDEFMakeReadOnlyOptions {
+  AbortSignal? signal;
+};
+
 dictionary NDEFScanOptions {
   AbortSignal signal;
 };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl b/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl
index 9214320..2b89760 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webauthn.idl
@@ -1,7 +1,7 @@
 // GENERATED CONTENT - DO NOT EDIT
 // Content was automatically extracted by Reffy into webref
 // (https://github.com/w3c/webref)
-// Source: Web Authentication: An API for accessing Public Key Credentials - Level 3 (https://w3c.github.io/webauthn/)
+// Source: Web Authentication: An API for accessing Public Key Credentials - Level (https://w3c.github.io/webauthn/)
 
 [SecureContext, Exposed=Window]
 interface PublicKeyCredential : Credential {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webgpu.idl b/third_party/blink/web_tests/external/wpt/interfaces/webgpu.idl
index c23ba78..6ded86e 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webgpu.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webgpu.idl
@@ -277,13 +277,19 @@
     "rgba32sint",
     "rgba32float",
 
-    // Depth and stencil formats
+    // Depth/stencil formats
     "stencil8",
     "depth16unorm",
     "depth24plus",
     "depth24plus-stencil8",
     "depth32float",
 
+    // "depth24unorm-stencil8" feature
+    "depth24unorm-stencil8",
+
+    // "depth32float-stencil8" feature
+    "depth32float-stencil8",
+
     // BC compressed formats usable if "texture-compression-bc" is both
     // supported by the device/user agent and enabled in requestDevice.
     "bc1-rgba-unorm",
@@ -344,12 +350,6 @@
     "astc-12x10-unorm-srgb",
     "astc-12x12-unorm",
     "astc-12x12-unorm-srgb",
-
-    // "depth24unorm-stencil8" feature
-    "depth24unorm-stencil8",
-
-    // "depth32float-stencil8" feature
-    "depth32float-stencil8",
 };
 
 [Exposed=(Window, DedicatedWorker), SecureContext]
@@ -517,9 +517,14 @@
 };
 GPUShaderModule includes GPUObjectBase;
 
+dictionary GPUShaderModuleCompilationHint {
+    required GPUPipelineLayout layout;
+};
+
 dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase {
     required USVString code;
     object sourceMap;
+    record<USVString, GPUShaderModuleCompilationHint> hints;
 };
 
 enum GPUCompilationMessageType {
@@ -777,6 +782,9 @@
 dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase {
 };
 
+interface mixin GPUCommandsMixin {
+};
+
 [Exposed=(Window, DedicatedWorker), SecureContext]
 interface GPUCommandEncoder {
     GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
@@ -804,14 +812,10 @@
         GPUImageCopyTexture destination,
         GPUExtent3D copySize);
 
-    undefined fillBuffer(
-        GPUBuffer destination,
-        GPUSize64 destinationOffset,
-        GPUSize64 size);
-
-    undefined pushDebugGroup(USVString groupLabel);
-    undefined popDebugGroup();
-    undefined insertDebugMarker(USVString markerLabel);
+    undefined clearBuffer(
+        GPUBuffer buffer,
+        optional GPUSize64 offset = 0,
+        optional GPUSize64 size);
 
     undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex);
 
@@ -825,6 +829,8 @@
     GPUCommandBuffer finish(optional GPUCommandBufferDescriptor descriptor = {});
 };
 GPUCommandEncoder includes GPUObjectBase;
+GPUCommandEncoder includes GPUCommandsMixin;
+GPUCommandEncoder includes GPUDebugCommandsMixin;
 
 dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase {
 };
@@ -854,6 +860,7 @@
 dictionary GPUImageCopyExternalImage {
     required (ImageBitmap or HTMLCanvasElement or OffscreenCanvas) source;
     GPUOrigin2D origin = {};
+    boolean flipY = false;
 };
 
 interface mixin GPUProgrammablePassEncoder {
@@ -864,7 +871,9 @@
                       Uint32Array dynamicOffsetsData,
                       GPUSize64 dynamicOffsetsDataStart,
                       GPUSize32 dynamicOffsetsDataLength);
+};
 
+interface mixin GPUDebugCommandsMixin {
     undefined pushDebugGroup(USVString groupLabel);
     undefined popDebugGroup();
     undefined insertDebugMarker(USVString markerLabel);
@@ -879,6 +888,8 @@
     undefined endPass();
 };
 GPUComputePassEncoder includes GPUObjectBase;
+GPUComputePassEncoder includes GPUCommandsMixin;
+GPUComputePassEncoder includes GPUDebugCommandsMixin;
 GPUComputePassEncoder includes GPUProgrammablePassEncoder;
 
 enum GPUComputePassTimestampLocation {
@@ -934,6 +945,8 @@
     undefined endPass();
 };
 GPURenderPassEncoder includes GPUObjectBase;
+GPURenderPassEncoder includes GPUCommandsMixin;
+GPURenderPassEncoder includes GPUDebugCommandsMixin;
 GPURenderPassEncoder includes GPUProgrammablePassEncoder;
 GPURenderPassEncoder includes GPURenderEncoderBase;
 
@@ -1005,6 +1018,8 @@
     GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {});
 };
 GPURenderBundleEncoder includes GPUObjectBase;
+GPURenderBundleEncoder includes GPUCommandsMixin;
+GPURenderBundleEncoder includes GPUDebugCommandsMixin;
 GPURenderBundleEncoder includes GPUProgrammablePassEncoder;
 GPURenderBundleEncoder includes GPURenderEncoderBase;
 
@@ -1123,7 +1138,7 @@
         DOMString type,
         GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict
     );
-    [SameObject] readonly attribute GPUError error;
+    readonly attribute GPUError error;
 };
 
 dictionary GPUUncapturedErrorEventInit : EventInit {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webhid.idl b/third_party/blink/web_tests/external/wpt/interfaces/webhid.idl
index d4ce439..997d82c3 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webhid.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webhid.idl
@@ -37,6 +37,7 @@
     readonly attribute FrozenArray<HIDCollectionInfo> collections;
     Promise<undefined> open();
     Promise<undefined> close();
+    Promise<undefined> forget();
     Promise<undefined> sendReport([EnforceRange] octet reportId, BufferSource data);
     Promise<undefined> sendFeatureReport(
         [EnforceRange] octet reportId,
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
index ff0a4a9..aed8fbb 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
@@ -4,11 +4,11 @@
 // Source: WebRTC 1.0: Real-Time Communication Between Browsers (https://w3c.github.io/webrtc-pc/)
 
 dictionary RTCConfiguration {
-  sequence<RTCIceServer> iceServers;
-  RTCIceTransportPolicy iceTransportPolicy;
-  RTCBundlePolicy bundlePolicy;
-  RTCRtcpMuxPolicy rtcpMuxPolicy;
-  sequence<RTCCertificate> certificates;
+  sequence<RTCIceServer> iceServers = [];
+  RTCIceTransportPolicy iceTransportPolicy = "all";
+  RTCBundlePolicy bundlePolicy = "balanced";
+  RTCRtcpMuxPolicy rtcpMuxPolicy = "require";
+  sequence<RTCCertificate> certificates = [];
   [EnforceRange] octet iceCandidatePoolSize = 0;
 };
 
@@ -247,7 +247,7 @@
 };
 
 dictionary RTCCertificateExpiration {
-  [EnforceRange] EpochTimeStamp expires;
+  [EnforceRange] unsigned long long expires;
 };
 
 [Exposed=Window, Serializable]
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webtransport.idl b/third_party/blink/web_tests/external/wpt/interfaces/webtransport.idl
index f098e47..95ab9e0 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webtransport.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webtransport.idl
@@ -46,8 +46,8 @@
 };
 
 dictionary WebTransportCloseInfo {
-  unsigned long closeCode;
-  DOMString reason;
+  unsigned long closeCode = 0;
+  DOMString reason = "";
 };
 
 dictionary WebTransportStats {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/lighting-estimation.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr-lighting-estimation.idl
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/interfaces/lighting-estimation.idl
rename to third_party/blink/web_tests/external/wpt/interfaces/webxr-lighting-estimation.idl
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/window-controls-overlay.idl b/third_party/blink/web_tests/external/wpt/interfaces/window-controls-overlay.idl
index de5e674..051978d6 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/window-controls-overlay.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/window-controls-overlay.idl
@@ -11,18 +11,18 @@
 [Exposed=Window]
 interface WindowControlsOverlay : EventTarget {
   readonly attribute boolean visible;
-  DOMRect getBoundingClientRect();
+  DOMRect getTitlebarAreaRect();
   attribute EventHandler ongeometrychange;
 };
 
 [Exposed=Window]
 interface WindowControlsOverlayGeometryChangeEvent : Event {
   constructor(DOMString type, WindowControlsOverlayGeometryChangeEventInit eventInitDict);
-  [SameObject] readonly attribute DOMRect boundingRect;
+  [SameObject] readonly attribute DOMRect titlebarAreaRect;
   readonly attribute boolean visible;
 };
 
 dictionary WindowControlsOverlayGeometryChangeEventInit : EventInit {
-  required DOMRect boundingRect;
+  required DOMRect titlebarAreaRect;
   boolean visible = false;
 };
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window-expected.txt
index 35a2f4c..07cd17d 100644
--- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window-expected.txt
@@ -1,6 +1,5 @@
 This is a testharness.js-based test.
-Found 190 tests; 184 PASS, 6 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
+FAIL idl_test setup promise_test: Unhandled rejection with value: object "DevicePermissionDescriptor inherits PermissionDescriptor, but PermissionDescriptor is undefined."
 PASS idl_test validation
 PASS Partial interface Navigator: original interface defined
 PASS Partial interface Navigator: member names are unique
@@ -16,179 +15,5 @@
 PASS Navigator includes NavigatorCookies: member names are unique
 PASS Navigator includes NavigatorPlugins: member names are unique
 PASS Navigator includes NavigatorConcurrentHardware: member names are unique
-PASS MediaStream interface: existence and properties of interface object
-PASS MediaStream interface object length
-PASS MediaStream interface object name
-PASS MediaStream interface: existence and properties of interface prototype object
-PASS MediaStream interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStream interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStream interface: attribute id
-PASS MediaStream interface: operation getAudioTracks()
-PASS MediaStream interface: operation getVideoTracks()
-PASS MediaStream interface: operation getTracks()
-PASS MediaStream interface: operation getTrackById(DOMString)
-PASS MediaStream interface: operation addTrack(MediaStreamTrack)
-PASS MediaStream interface: operation removeTrack(MediaStreamTrack)
-PASS MediaStream interface: operation clone()
-PASS MediaStream interface: attribute active
-PASS MediaStream interface: attribute onaddtrack
-PASS MediaStream interface: attribute onremovetrack
-PASS MediaStream must be primary interface of stream
-PASS Stringification of stream
-PASS MediaStream interface: stream must inherit property "id" with the proper type
-PASS MediaStream interface: stream must inherit property "getAudioTracks()" with the proper type
-PASS MediaStream interface: stream must inherit property "getVideoTracks()" with the proper type
-PASS MediaStream interface: stream must inherit property "getTracks()" with the proper type
-PASS MediaStream interface: stream must inherit property "getTrackById(DOMString)" with the proper type
-PASS MediaStream interface: calling getTrackById(DOMString) on stream with too few arguments must throw TypeError
-PASS MediaStream interface: stream must inherit property "addTrack(MediaStreamTrack)" with the proper type
-PASS MediaStream interface: calling addTrack(MediaStreamTrack) on stream with too few arguments must throw TypeError
-PASS MediaStream interface: stream must inherit property "removeTrack(MediaStreamTrack)" with the proper type
-PASS MediaStream interface: calling removeTrack(MediaStreamTrack) on stream with too few arguments must throw TypeError
-PASS MediaStream interface: stream must inherit property "clone()" with the proper type
-PASS MediaStream interface: stream must inherit property "active" with the proper type
-PASS MediaStream interface: stream must inherit property "onaddtrack" with the proper type
-PASS MediaStream interface: stream must inherit property "onremovetrack" with the proper type
-PASS MediaStream must be primary interface of new MediaStream()
-PASS Stringification of new MediaStream()
-PASS MediaStream interface: new MediaStream() must inherit property "id" with the proper type
-PASS MediaStream interface: new MediaStream() must inherit property "getAudioTracks()" with the proper type
-PASS MediaStream interface: new MediaStream() must inherit property "getVideoTracks()" with the proper type
-PASS MediaStream interface: new MediaStream() must inherit property "getTracks()" with the proper type
-PASS MediaStream interface: new MediaStream() must inherit property "getTrackById(DOMString)" with the proper type
-PASS MediaStream interface: calling getTrackById(DOMString) on new MediaStream() with too few arguments must throw TypeError
-PASS MediaStream interface: new MediaStream() must inherit property "addTrack(MediaStreamTrack)" with the proper type
-PASS MediaStream interface: calling addTrack(MediaStreamTrack) on new MediaStream() with too few arguments must throw TypeError
-PASS MediaStream interface: new MediaStream() must inherit property "removeTrack(MediaStreamTrack)" with the proper type
-PASS MediaStream interface: calling removeTrack(MediaStreamTrack) on new MediaStream() with too few arguments must throw TypeError
-PASS MediaStream interface: new MediaStream() must inherit property "clone()" with the proper type
-PASS MediaStream interface: new MediaStream() must inherit property "active" with the proper type
-PASS MediaStream interface: new MediaStream() must inherit property "onaddtrack" with the proper type
-PASS MediaStream interface: new MediaStream() must inherit property "onremovetrack" with the proper type
-PASS MediaStreamTrack interface: existence and properties of interface object
-PASS MediaStreamTrack interface object length
-PASS MediaStreamTrack interface object name
-PASS MediaStreamTrack interface: existence and properties of interface prototype object
-PASS MediaStreamTrack interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStreamTrack interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStreamTrack interface: attribute kind
-PASS MediaStreamTrack interface: attribute id
-PASS MediaStreamTrack interface: attribute label
-PASS MediaStreamTrack interface: attribute enabled
-PASS MediaStreamTrack interface: attribute muted
-PASS MediaStreamTrack interface: attribute onmute
-PASS MediaStreamTrack interface: attribute onunmute
-PASS MediaStreamTrack interface: attribute readyState
-PASS MediaStreamTrack interface: attribute onended
-PASS MediaStreamTrack interface: operation clone()
-PASS MediaStreamTrack interface: operation stop()
-PASS MediaStreamTrack interface: operation getCapabilities()
-PASS MediaStreamTrack interface: operation getConstraints()
-PASS MediaStreamTrack interface: operation getSettings()
-PASS MediaStreamTrack interface: operation applyConstraints(optional MediaTrackConstraints)
-PASS MediaStreamTrack must be primary interface of track
-PASS Stringification of track
-PASS MediaStreamTrack interface: track must inherit property "kind" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "id" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "label" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "enabled" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "muted" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "onmute" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "onunmute" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "readyState" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "onended" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "clone()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "stop()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "getCapabilities()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "getConstraints()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "getSettings()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "applyConstraints(optional MediaTrackConstraints)" with the proper type
-PASS MediaStreamTrack interface: calling applyConstraints(optional MediaTrackConstraints) on track with too few arguments must throw TypeError
-PASS MediaStreamTrackEvent interface: existence and properties of interface object
-PASS MediaStreamTrackEvent interface object length
-PASS MediaStreamTrackEvent interface object name
-PASS MediaStreamTrackEvent interface: existence and properties of interface prototype object
-PASS MediaStreamTrackEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStreamTrackEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStreamTrackEvent interface: attribute track
-PASS MediaStreamTrackEvent must be primary interface of trackEvent
-PASS Stringification of trackEvent
-PASS MediaStreamTrackEvent interface: trackEvent must inherit property "track" with the proper type
-FAIL OverconstrainedError interface: existence and properties of interface object assert_equals: prototype of OverconstrainedError is not DOMException expected function "function DOMException() { [native code] }" but got function "function () { [native code] }"
-FAIL OverconstrainedError interface object length assert_equals: wrong value for OverconstrainedError.length expected 1 but got 2
-PASS OverconstrainedError interface object name
-FAIL OverconstrainedError interface: existence and properties of interface prototype object assert_equals: prototype of OverconstrainedError.prototype is not DOMException.prototype expected [stringifying object threw TypeError: Illegal invocation with type object] but got object "[object Object]"
-PASS OverconstrainedError interface: existence and properties of interface prototype object's "constructor" property
-PASS OverconstrainedError interface: existence and properties of interface prototype object's @@unscopables property
-PASS OverconstrainedError interface: attribute constraint
-FAIL OverconstrainedError must be primary interface of new OverconstrainedError("constraint") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'OverconstrainedError': 2 arguments required, but only 1 present."
-FAIL Stringification of new OverconstrainedError("constraint") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'OverconstrainedError': 2 arguments required, but only 1 present."
-FAIL OverconstrainedError interface: new OverconstrainedError("constraint") must inherit property "constraint" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'OverconstrainedError': 2 arguments required, but only 1 present."
-PASS MediaDevices interface: existence and properties of interface object
-PASS MediaDevices interface object length
-PASS MediaDevices interface object name
-PASS MediaDevices interface: existence and properties of interface prototype object
-PASS MediaDevices interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaDevices interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaDevices interface: attribute ondevicechange
-PASS MediaDevices interface: operation enumerateDevices()
-PASS MediaDevices interface: operation getSupportedConstraints()
-PASS MediaDevices interface: operation getUserMedia(optional MediaStreamConstraints)
-PASS MediaDevices must be primary interface of navigator.mediaDevices
-PASS Stringification of navigator.mediaDevices
-PASS MediaDevices interface: navigator.mediaDevices must inherit property "ondevicechange" with the proper type
-PASS MediaDevices interface: navigator.mediaDevices must inherit property "enumerateDevices()" with the proper type
-PASS MediaDevices interface: navigator.mediaDevices must inherit property "getSupportedConstraints()" with the proper type
-PASS MediaDevices interface: navigator.mediaDevices must inherit property "getUserMedia(optional MediaStreamConstraints)" with the proper type
-PASS MediaDevices interface: calling getUserMedia(optional MediaStreamConstraints) on navigator.mediaDevices with too few arguments must throw TypeError
-PASS MediaDeviceInfo interface: existence and properties of interface object
-PASS MediaDeviceInfo interface object length
-PASS MediaDeviceInfo interface object name
-PASS MediaDeviceInfo interface: existence and properties of interface prototype object
-PASS MediaDeviceInfo interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaDeviceInfo interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaDeviceInfo interface: attribute deviceId
-PASS MediaDeviceInfo interface: attribute kind
-PASS MediaDeviceInfo interface: attribute label
-PASS MediaDeviceInfo interface: attribute groupId
-PASS MediaDeviceInfo interface: operation toJSON()
-PASS MediaDeviceInfo must be primary interface of audiooutput
-PASS Stringification of audiooutput
-PASS MediaDeviceInfo interface: audiooutput must inherit property "deviceId" with the proper type
-PASS MediaDeviceInfo interface: audiooutput must inherit property "kind" with the proper type
-PASS MediaDeviceInfo interface: audiooutput must inherit property "label" with the proper type
-PASS MediaDeviceInfo interface: audiooutput must inherit property "groupId" with the proper type
-PASS MediaDeviceInfo interface: audiooutput must inherit property "toJSON()" with the proper type
-PASS MediaDeviceInfo interface: default toJSON operation on audiooutput
-PASS InputDeviceInfo interface: existence and properties of interface object
-PASS InputDeviceInfo interface object length
-PASS InputDeviceInfo interface object name
-PASS InputDeviceInfo interface: existence and properties of interface prototype object
-PASS InputDeviceInfo interface: existence and properties of interface prototype object's "constructor" property
-PASS InputDeviceInfo interface: existence and properties of interface prototype object's @@unscopables property
-PASS InputDeviceInfo interface: operation getCapabilities()
-PASS InputDeviceInfo must be primary interface of audioinput
-PASS Stringification of audioinput
-PASS InputDeviceInfo interface: audioinput must inherit property "getCapabilities()" with the proper type
-PASS MediaDeviceInfo interface: audioinput must inherit property "deviceId" with the proper type
-PASS MediaDeviceInfo interface: audioinput must inherit property "kind" with the proper type
-PASS MediaDeviceInfo interface: audioinput must inherit property "label" with the proper type
-PASS MediaDeviceInfo interface: audioinput must inherit property "groupId" with the proper type
-PASS MediaDeviceInfo interface: audioinput must inherit property "toJSON()" with the proper type
-PASS MediaDeviceInfo interface: default toJSON operation on audioinput
-PASS InputDeviceInfo must be primary interface of videoinput
-PASS Stringification of videoinput
-PASS InputDeviceInfo interface: videoinput must inherit property "getCapabilities()" with the proper type
-PASS MediaDeviceInfo interface: videoinput must inherit property "deviceId" with the proper type
-PASS MediaDeviceInfo interface: videoinput must inherit property "kind" with the proper type
-PASS MediaDeviceInfo interface: videoinput must inherit property "label" with the proper type
-PASS MediaDeviceInfo interface: videoinput must inherit property "groupId" with the proper type
-PASS MediaDeviceInfo interface: videoinput must inherit property "toJSON()" with the proper type
-PASS MediaDeviceInfo interface: default toJSON operation on videoinput
-PASS Navigator interface: attribute mediaDevices
-PASS Navigator interface: operation getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback)
-PASS Navigator interface: navigator must inherit property "mediaDevices" with the proper type
-PASS Navigator interface: navigator must inherit property "getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback)" with the proper type
-PASS Navigator interface: calling getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) on navigator with too few arguments must throw TypeError
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_constructor.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_constructor.html
index 5aab1326..3b278746 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_constructor.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_constructor.html
@@ -38,13 +38,13 @@
                         ["getCoalescedEvents()[" + i + "].isPrimary", coalescedEvent.isPrimary, event.isPrimary],
                         ["getCoalescedEvents()[" + i + "].getCoalescedEvents().length", coalescedEvent.getCoalescedEvents().length, 0],
                         ["getCoalescedEvents()[" + i + "].getPredictedEvents().length", coalescedEvent.getPredictedEvents().length, 0],
-                        ["getCoalescedEvents()[" + i + "].target", coalescedEvent.target, target0],
+                        ["getCoalescedEvents()[" + i + "].target", coalescedEvent.target, null],
                         ["getCoalescedEvents()[" + i + "].currentTarget", coalescedEvent.currentTarget, null],
                         ["getCoalescedEvents()[" + i + "].eventPhase", coalescedEvent.eventPhase, Event.NONE],
                         ["getCoalescedEvents()[" + i + "].cancelable", coalescedEvent.cancelable, false],
                         ["getCoalescedEvents()[" + i + "].bubbles", coalescedEvent.bubbles, false],
-                        ["getCoalescedEvents()[" + i + "].offsetX", coalescedEvent.offsetX, event.offsetX + (i==0?-10:0)],
-                        ["getCoalescedEvents()[" + i + "].offsetY", coalescedEvent.offsetY, event.offsetY],
+                        ["getCoalescedEvents()[" + i + "].offsetX", coalescedEvent.offsetX, 310 + (i==0?-10:0)],
+                        ["getCoalescedEvents()[" + i + "].offsetY", coalescedEvent.offsetY, 0],
                     ]);
                 }
                 for (var i=0; i<event.getPredictedEvents().length; i++) {
@@ -55,13 +55,13 @@
                         ["getPredictedEvents()[" + i + "].isPrimary", predictedEvent.isPrimary, event.isPrimary],
                         ["getPredictedEvents()[" + i + "].getCoalescedEvents().length", predictedEvent.getCoalescedEvents().length, 0],
                         ["getPredictedEvents()[" + i + "].getPredictedEvents().length", predictedEvent.getPredictedEvents().length, 0],
-                        ["getPredictedEvents()[" + i + "].target", predictedEvent.target, target0],
+                        ["getPredictedEvents()[" + i + "].target", predictedEvent.target, null],
                         ["getPredictedEvents()[" + i + "].currentTarget", predictedEvent.currentTarget, null],
                         ["getPredictedEvents()[" + i + "].eventPhase", predictedEvent.eventPhase, Event.NONE],
                         ["getPredictedEvents()[" + i + "].cancelable", predictedEvent.cancelable, false],
                         ["getPredictedEvents()[" + i + "].bubbles", predictedEvent.bubbles, false],
-                        ["getPredictedEvents()[" + i + "].offsetX", predictedEvent.offsetX, event.offsetX + (i==0?10:20)],
-                        ["getPredictedEvents()[" + i + "].offsetY", predictedEvent.offsetY, event.offsetY],
+                        ["getPredictedEvents()[" + i + "].offsetX", predictedEvent.offsetX, 310 + (i==0?10:20)],
+                        ["getPredictedEvents()[" + i + "].offsetY", predictedEvent.offsetY, 0],
                     ]);
                 }
             }));
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/iframe-sequence-of-events-expected.txt b/third_party/blink/web_tests/external/wpt/resource-timing/iframe-sequence-of-events-expected.txt
new file mode 100644
index 0000000..4999c61
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/iframe-sequence-of-events-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+PASS An iframe should report its RT entry when the response is done and before it is completely loaded
+FAIL An iframe should report separate RT entries if src changed assert_equals: expected 2 but got 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/iframe-sequence-of-events.html b/third_party/blink/web_tests/external/wpt/resource-timing/iframe-sequence-of-events.html
new file mode 100644
index 0000000..9013800
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/iframe-sequence-of-events.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test the sequence of events when reporting image timing.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+  promise_test(async t => {
+    const delay = 500;
+    const iframe = document.createElement('iframe');
+    t.add_cleanup(() => iframe.remove());
+    await new Promise(resolve => {
+      iframe.addEventListener('load', resolve);
+      iframe.src = `resources/iframe-with-delay.sub.html?delay=${delay}`;
+      document.body.appendChild(iframe);
+    });
+
+    const entries = performance.getEntriesByName(iframe.src);
+    const navigationEntry = iframe.contentWindow.performance.getEntriesByType('navigation')[0];
+    assert_equals(entries.length, 1);
+    assert_greater_than(performance.now(), entries[0].responseEnd + delay);
+    const domContentLoadedEventAbsoluteTime = navigationEntry.domContentLoadedEventStart + iframe.contentWindow.performance.timeOrigin;
+    const iframeResponseEndAbsoluteTime = entries[0].responseEnd + performance.timeOrigin;
+    assert_greater_than(domContentLoadedEventAbsoluteTime, iframeResponseEndAbsoluteTime);
+  }, "An iframe should report its RT entry when the response is done and before it is completely loaded");
+
+  promise_test(async t => {
+    const iframe = document.createElement('iframe');
+    t.add_cleanup(() => iframe.remove());
+    await new Promise(resolve => {
+      const done = () => {
+        resolve();
+        iframe.removeEventListener('load', done);
+      }
+      iframe.addEventListener('load', done);
+      iframe.src = 'resources/green.html?1';
+      document.body.appendChild(iframe);
+    });
+
+    await new Promise(resolve => {
+      iframe.addEventListener('load', resolve);
+      iframe.src = 'resources/green.html?2';
+    });
+
+    const entries = performance.getEntries().filter(e => e.name.includes('green.html'));
+    assert_equals(entries.length, 2);
+  }, "An iframe should report separate RT entries if src changed");
+
+  </script>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/image-sequence-of-events.html b/third_party/blink/web_tests/external/wpt/resource-timing/image-sequence-of-events.html
new file mode 100644
index 0000000..630fed78
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/image-sequence-of-events.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test the sequence of events when reporting image timing.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+  function test_image_sequence(src, event, t) {
+    const image = document.createElement('img');
+    const absoluteURL = new URL(src, location.href).toString();
+    document.body.appendChild(image);
+    t.add_cleanup(() => image.remove());
+    return new Promise(resolve => {
+      image.addEventListener(event, t.step_func(() => {
+        assert_equals(performance.getEntriesByName(absoluteURL).length, 1);
+        resolve();
+      }));
+      image.src = src;
+    });
+  }
+  promise_test(t => test_image_sequence('resources/blue.png', 'load', t),
+  "An image should receive its load event after the ResourceTiming entry is available");
+
+  promise_test(t => test_image_sequence('resources/nothing-at-all.png', 'error', t),
+  "A non-existent (404) image should receive its error event after the ResourceTiming entry is available");
+
+  promise_test(t => test_image_sequence('resources/invalid.png', 'error', t),
+  "An invalid image should receive its error event after the ResourceTiming entry is available");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/iframe-with-delay.sub.html b/third_party/blink/web_tests/external/wpt/resource-timing/resources/iframe-with-delay.sub.html
new file mode 100644
index 0000000..fe50aa7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/iframe-with-delay.sub.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<img src="/xhr/resources/delay.py?ms={{GET[delay]}}" />
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/invalid.jpg b/third_party/blink/web_tests/external/wpt/resource-timing/resources/invalid.jpg
new file mode 100644
index 0000000..81c545e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/invalid.jpg
@@ -0,0 +1 @@
+1234
diff --git a/third_party/blink/web_tests/external/wpt/screen-orientation/onchange-event-subframe.html b/third_party/blink/web_tests/external/wpt/screen-orientation/onchange-event-subframe.html
index 363c9cd..0ba0edc 100644
--- a/third_party/blink/web_tests/external/wpt/screen-orientation/onchange-event-subframe.html
+++ b/third_party/blink/web_tests/external/wpt/screen-orientation/onchange-event-subframe.html
@@ -1,6 +1,8 @@
 <!DOCTYPE html>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
 
 <iframe
   id="testIframe"
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-timeline-in-removed-iframe-crash.html b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-timeline-in-removed-iframe-crash.html
new file mode 100644
index 0000000..07edbd8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/scroll-timeline-in-removed-iframe-crash.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Starting an animation with a scroll timeline in a removed iframe
+         should not crash</title>
+</head>
+<body>
+  <div id="target"></div>
+  <iframe id="frame"></iframe>
+</body>
+<script type="text/javascript">
+  const target = document.getElementById('target');
+  const frame = document.getElementById('frame');
+  const timeline = new frame.contentWindow.ScrollTimeline();
+  frame.remove();
+  target.animate(null, {timeline: timeline});
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/cache-storage.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/cache-storage.https.html
index 015094c1..39d0de3 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/cache-storage.https.html
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/cache-storage.https.html
@@ -3,6 +3,7 @@
 <meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
 <script src="resources/utils.js"></script>
 <body>
 <script>
@@ -10,32 +11,23 @@
 setup(() => assertSpeculationRulesIsSupported());
 
 promise_test(async t => {
-  const bc = new BroadcastChannel('prerender-channel');
-
-  const gotMessage = new Promise(resolve => {
-    bc.addEventListener('message', e => {
-      resolve(e.data);
-    }, {
-      once: true
-    });
-  });
-
-  const cacheName = 'checkallowed';
+  const cacheName = token();
   const cache = await caches.open(cacheName);
   await cache.add('resources/cache.txt');
+  t.add_cleanup(() => caches.delete(cacheName));
   const response = await cache.match('resources/cache.txt');
   const cacheText = await (response ? response.text() : 'primary cache match failed');
 
-  // Start prerendering a page that attempts to access cache storage.
-  startPrerendering(`resources/cache-storage-access.https.html`);
-  const result = await gotMessage;
+  const {exec} = await create_prerendered_page(t);
+  const result = await exec(async cacheName => {
+    const cache = await caches.open(cacheName);
+    const match = await cache.match('cache.txt');
+    return await match.text();
+  }, [cacheName]);
 
   assert_equals(
     result, cacheText,
     'prerendering page should be able to read from cache storage.');
-  await caches.delete(cacheName);
-
-  bc.close();
 }, 'prerendering page should be able to access cache storage')
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/cookies.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/cookies.html
index 6e83532..7f5e416 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/cookies.html
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/cookies.html
@@ -3,34 +3,31 @@
 <meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
 <script src="resources/utils.js"></script>
+<script src="/cookie-store/resources/cookie-test-helpers.js"></script>
 <body>
 <script>
 
 setup(() => assertSpeculationRulesIsSupported());
 
-promise_test(async t => {
-  const bc = new BroadcastChannel('prerender-channel');
-
-  const gotMessage = new Promise(resolve => {
-    bc.addEventListener('message', e => {
-      resolve(e.data);
-    }, {
-      once: true
-    });
-  });
-
+cookie_test(async t => {
+  const {exec} = await create_prerendered_page(t);
   const initiator_cookie = 'initiator_cookie=exist';
   const prerender_cookie = 'prerender_cookie=exist';
 
   document.cookie = initiator_cookie;
+  const result = await exec(() => {
+    const result = document.cookie;
+    prerender_log(result);
+    document.cookie = "prerender_cookie=exist;path=/;";
+    return result;
+  });
 
-  // Start prerendering a page that attempts to access cookies.
-  startPrerendering(`resources/cookies-access.html`);
-  const result = await gotMessage;
   assert_equals(
     result, initiator_cookie,
     'prerendering page should be able to read from document cookies.');
+
   assert_equals(
     document.cookie, initiator_cookie + '; ' + prerender_cookie,
     'prerendering page should be able to write to document cookies');
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/fetch-blob.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/fetch-blob.html
new file mode 100644
index 0000000..880b05bd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/fetch-blob.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<title>Same-origin prerendering can access localStorage</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="resources/utils.js"></script>
+<body>
+<script>
+
+setup(() => assertSpeculationRulesIsSupported());
+
+promise_test(async t => {
+  const {exec} = await create_prerendered_page(t);
+  const result = await exec(async () => {
+    const blob = await (await fetch('cache.txt')).blob();
+    const reader = new FileReader();
+    reader.readAsText(blob);
+    return new Promise(function(resolve, reject) {
+      reader.onload = () => resolve(reader.result);
+      reader.onerror = () => reject(reader.error);
+    });
+  });
+  const expected = "Hello, Prerender API!";
+
+  // Start prerendering a page that attempts to access the blob.
+  assert_equals(
+    result, expected,
+    'prerendering page should be able to read from blobs.');
+}, 'prerendering page should be able to access blobs');
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/indexeddb.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/indexeddb.html
index 65368acb..0ac0d21a 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/indexeddb.html
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/indexeddb.html
@@ -3,6 +3,7 @@
 <meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
 <script src="resources/utils.js"></script>
 <script src="resources/indexedb-utils.js"></script>
 <body>
@@ -11,33 +12,30 @@
 setup(() => assertSpeculationRulesIsSupported());
 
 promise_test(async t => {
-  const bc = new BroadcastChannel('prerender-channel');
-
-  const gotMessage = new Promise(resolve => {
-    bc.addEventListener('message', e => {
-      resolve(e.data);
-    }, {
-      once: true
-    });
-  });
-
-  const db = await openIndexedDatabase();
+  const db = await openIndexedDatabase(t);
   assert_not_equals(db, null, 'Failed to open database.');
   await addData(db, INITIATOR_KEY, INITIATOR_VALUE);
 
-  // Start prerendering a page that attempts to access the IndexedDB API.
-  startPrerendering(`resources/indexeddb-access.html`);
+  const {exec} = await create_prerendered_page(t);
 
-  const prerenderReadResult = await gotMessage;
+  const result = await exec(async () => {
+    await import_script_to_prerendered_page("indexedb-utils.js");
+    const db = await openIndexedDatabase();
+
+    await addData(db, PRERENDER_KEY, PRERENDER_VALUE);
+    const result = await readData(db, INITIATOR_KEY);
+    db.close();
+    return result;
+  });
+
   assert_equals(
-    prerenderReadResult, INITIATOR_VALUE,
+    result, INITIATOR_VALUE,
     'prerendering page should be able to read from Indexed DataBase');
   const initiatorReadResult = await readData(db, PRERENDER_KEY);
   assert_equals(
     initiatorReadResult, PRERENDER_VALUE,
     'prerendering page should be able to write to Indexed DataBase');
   db.close();
-  bc.close();
 }, 'prerendering page should be able to access Indexed DataBase')
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/local-storage.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/local-storage.html
index b07d1f0..dc4008c 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/local-storage.html
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/local-storage.html
@@ -3,6 +3,7 @@
 <meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
 <script src="resources/utils.js"></script>
 <body>
 <script>
@@ -10,25 +11,21 @@
 setup(() => assertSpeculationRulesIsSupported());
 
 promise_test(async t => {
-  const bc = new BroadcastChannel('prerender-channel');
-
-  const gotMessage = new Promise(resolve => {
-    bc.addEventListener('message', e => {
-      resolve(e.data);
-    }, {once:true});
-  });
-
-  const initialValue = "initial_set";
-  window.localStorage.setItem('initial', initialValue);
+  const uid1 = token();
+  const uid2 = token();
+  window.localStorage.setItem('initial', uid1);
+  const {exec} = await create_prerendered_page(t);
+  const result = await exec(uid2 => {
+    window.localStorage.setItem('prerender', uid2);
+    return window.localStorage.getItem('initial');
+  }, [uid2])
 
   // Start prerendering a page that attempts to access localStorage API.
-  startPrerendering(`resources/local-storage-access.html`);
-  const result = await gotMessage;
   assert_equals(
-    result, initialValue,
+    result, uid1,
       'prerendering page should be able to read from local storage');
   assert_equals(
-      window.localStorage.getItem('prerender'), 'prerender_set',
+      window.localStorage.getItem('prerender'), uid2,
       'prerendering page should be able to write to local storage');
 }, 'prerendering page should be able to access local storage');
 
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/media-autoplay.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/media-autoplay.html
new file mode 100644
index 0000000..efbff145
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/media-autoplay.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<title>Same-origin prerendering can trigger autoplay</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="resources/utils.js"></script>
+<body>
+<script>
+  setup(() => assertSpeculationRulesIsSupported());
+
+  promise_test(async t => {
+    const {exec, activate} = await create_prerendered_page(t);
+    await exec(() => {
+      const video = document.createElement('video');
+      video.src = '/media/A4.mp4';
+      video.autoplay = true;
+      video.muted = true;
+      window.video = video;
+      prerender_log('hello2');
+      document.body.appendChild(video);
+    });
+
+    await new Promise(resolve => t.step_timeout(resolve, 500));
+
+    const before_activation = await exec(() => ({
+      readyState: video.readyState,
+      paused: video.paused,
+      currentTime: video.currentTime
+    }));
+
+    await activate();
+    await new Promise(resolve => t.step_timeout(resolve, 500));
+    const after_activation = await exec(() => ({
+      readyState: video.readyState,
+      paused: video.paused,
+      currentTime: video.currentTime
+    }));
+
+    assert_equals(before_activation.paused, false);
+    assert_equals(before_activation.currentTime, 0);
+    assert_equals(after_activation.paused, false);
+    assert_greater_than(before_activation.currentTime, 0);
+ }, "media autoplay should defer playaback");
+</script>
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/cache-storage-access.https.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/cache-storage-access.https.html
deleted file mode 100644
index ac714cc..0000000
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/cache-storage-access.https.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-
-const bc = new BroadcastChannel('prerender-channel');
-assert_true(document.prerendering);
-
-const cacheName = 'checkallowed';
-caches.open(cacheName).then(cache => cache.match('cache.txt'))
-.then(response => response.text())
-.then(result => {
-  bc.postMessage(result);
-  bc.close();
-});
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/cookies-access.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/cookies-access.html
deleted file mode 100644
index 43b636c0..0000000
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/cookies-access.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-
-const bc = new BroadcastChannel('prerender-channel');
-assert_true(document.prerendering);
-
-const result = document.cookie;
-document.cookie = "prerender_cookie=exist;path=/;";
-
-bc.postMessage(result);
-bc.close();
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/eval-channel.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/eval-channel.html
new file mode 100644
index 0000000..5918a48
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/eval-channel.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<head>
+  <script src="/common/utils.js"></script>
+  <script src="utils.js"></script>
+  <script>
+      const params = new URLSearchParams(window.location.search);
+      const uuid = params.get('uuid');
+      const logChannel = new PrerenderChannel(uuid, 'log');
+      window.prerender_log = (...args) => logChannel.postMessage(args);
+      new PrerenderChannel(uuid, 'exec').addEventListener('message',
+        async ({detail: {fn, args, receiver}}) => {
+          const receiverChannel = new PrerenderChannel(uuid, receiver);
+          try {
+            const result = await (eval(`(${fn})`)(args)) || null;
+            receiverChannel.postMessage({result});
+          } catch (error) {
+            receiverChannel.postMessage({error});
+          }
+        });
+
+      window.import_script_to_prerendered_page = src => {
+        const script = document.createElement('script');
+        script.src = src;
+        document.head.appendChild(script);
+        return new Promise(resolve => script.addEventListener('load', resolve));
+      }
+
+      window.addEventListener('error', error =>
+        logChannel.postMessage('[Prerendered Page Error]', {message: error.message, stack: error.stack}));
+
+      window.prerender_log('Channel Created');
+      new PrerenderChannel(uuid, 'ready').postMessage({});
+    </script>
+</head>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/eval-init.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/eval-init.html
new file mode 100644
index 0000000..621ab37
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/eval-init.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="utils.js"></script>
+</head>
+<body>
+    <a id="open" href="#">Activate Prerendered Page</a>
+    <script>
+        const params = new URLSearchParams(window.location.search);
+        const uuid = params.get('uuid');
+        const url = `eval-channel.html${location.search}`;
+        new PrerenderChannel(uuid, 'initiator').addEventListener('message',
+            ({detail}) => {
+                if (detail === 'close')
+                    window.close();
+                else if (detail === 'activate')
+                    location.href = url;
+            });
+        const rules = document.createElement('script');
+        document.querySelector('a#open').href = url;
+        rules.type = "speculationrules";
+        rules.text = JSON.stringify({prerender: [{source: 'list', urls: [url]}]});
+        document.head.appendChild(rules);
+    </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/indexedb-utils.js b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/indexedb-utils.js
index 39cb1a80..7c57000 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/indexedb-utils.js
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/indexedb-utils.js
@@ -4,9 +4,14 @@
 const PRERENDER_KEY = 'prerender';
 const PRERENDER_VALUE = PRERENDER_KEY + '_set';
 
-async function openIndexedDatabase() {
+async function openIndexedDatabase(t) {
   return new Promise(resolve => {
     const request = window.indexedDB.open(STORAGE_NAME);
+    if (t)
+      t.add_cleanup(() => new Promise(resolve => {
+        window.indexedDB.deleteDatabase(STORAGE_NAME);
+        resolve();
+      }));
     request.onupgradeneeded = e => {
       const db = e.target.result;
       const objectStore =
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/indexeddb-access.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/indexeddb-access.html
deleted file mode 100644
index 20e2956c..0000000
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/indexeddb-access.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="indexedb-utils.js"></script>
-<script>
-
-assert_true(document.prerendering);
-
-async function operateDatabase(){
-  const bc = new BroadcastChannel('prerender-channel');
-
-  const db = await openIndexedDatabase();
-  assert_not_equals(db, null, 'Failed to open database.');
-
-  await addData(db, PRERENDER_KEY, PRERENDER_VALUE);
-  const result = await readData(db, INITIATOR_KEY);
-  bc.postMessage(result);
-  bc.close();
-  db.close();
-}
-
-operateDatabase();
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/local-storage-access.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/local-storage-access.html
deleted file mode 100644
index 00af1d5..0000000
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/local-storage-access.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-
-const bc = new BroadcastChannel('prerender-channel');
-assert_true(document.prerendering);
-
-window.localStorage.setItem('prerender', 'prerender_set');
-const result = window.localStorage.getItem('initial');
-
-bc.postMessage(result);
-bc.close();
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/prerender-focus.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/prerender-focus.html
deleted file mode 100644
index f6a79533..0000000
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/prerender-focus.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<title>Check the focus state of prerendering pages</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<body>
-<input type="text" id = "prerenderTextField">
-<script>
-
-// Check this page is being prerendered.
-assert_true(document.prerendering);
-
-const bc = new BroadcastChannel('prerender-channel');
-
-// Try to set focus.
-const element = document.getElementById('prerenderTextField');
-element.focus();
-
-// Post the focus and active states to the initiator page.
-bc.postMessage({
-  activeElementUpdated: document.activeElement === element,
-  documentHasFocus: document.hasFocus()});
-bc.close();
-
-</script>
-</body>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js
index 1c1cdb2..59e1462a 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js
@@ -143,3 +143,112 @@
       document.body.appendChild(frame);
     });
 }
+
+class PrerenderChannel extends EventTarget {
+  broadcastChannel = null;
+
+  constructor(uid, name) {
+    super();
+    this.broadcastChannel = new BroadcastChannel(`${uid}-${name}`);
+    this.broadcastChannel.addEventListener('message', e => {
+      this.dispatchEvent(new CustomEvent('message', {detail: e.data}));
+    });
+  }
+
+  postMessage(message) {
+    this.broadcastChannel.postMessage(message);
+  }
+
+  close() {
+    this.broadcastChannel.close();
+  }
+};
+
+async function create_prerendered_page(t) {
+  const uuid = token();
+  new PrerenderChannel(uuid, 'log').addEventListener('message', message => {
+    // Calling it with ['log'] to avoid lint issue. This log should be used for debugging
+    // the prerendered context, not testing.
+    if(window.console)
+      console['log']('[From Prerendered]', ...message.detail);
+  });
+
+  const execChannel = new PrerenderChannel(uuid, 'exec');
+  const initChannel = new PrerenderChannel(uuid, 'initiator');
+  const exec = (func, args = []) => {
+      const receiver = token();
+      execChannel.postMessage({receiver, fn: func.toString(), args});
+      return new Promise((resolve, reject) => {
+        const channel = new PrerenderChannel(uuid, receiver);
+        channel.addEventListener('message', ({detail}) => {
+          channel.close();
+          if (detail.error)
+            reject(detail.error)
+          else
+            resolve(detail.result);
+        });
+      })
+    };
+
+  window.open(`/speculation-rules/prerender/resources/eval-init.html?uuid=${uuid}`, '_blank', 'noopener');
+  t.add_cleanup(() => initChannel.postMessage('close'));
+  t.add_cleanup(() => exec(() => window.close()));
+  await new Promise(resolve => {
+    const channel = new PrerenderChannel(uuid, 'ready');
+    channel.addEventListener('message', () => {
+      channel.close();
+      resolve();
+    });
+  });
+
+  async function activate() {
+    const prerendering = exec(() => new Promise(resolve =>
+      document.addEventListener('prerenderingchange', () => {
+        resolve(document.prerendering);
+      })));
+
+    initChannel.postMessage('activate');
+    if (await prerendering)
+      throw new Error('Should not be prerendering at this point')
+  }
+
+  return {
+    exec,
+    activate
+  };
+}
+
+
+function test_prerender_restricted(fn, expected, label) {
+  promise_test(async t => {
+    const {exec} = await create_prerendered_page(t);
+    let result = null;
+    try {
+      await exec(fn);
+      result = "OK";
+    } catch (e) {
+      result = e.name;
+    }
+
+    assert_equals(result, expected);
+  }, label);
+}
+
+function test_prerender_defer(fn, label) {
+  promise_test(async t => {
+    const {exec, activate} = await create_prerendered_page(t);
+    let activated = false;
+    const deferred = exec(fn);
+
+    const post = new Promise(resolve =>
+      deferred.then(result => {
+        assert_true(activated, "Deferred operation should occur only after activation");
+        resolve(result);
+      }));
+
+    await new Promise(resolve => t.step_timeout(resolve, 100));
+    await activate();
+    activated = true;
+    await post;
+  }, label);
+}
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-focus.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-focus.html
index b6576eb1..0806b0c 100644
--- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-focus.html
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restriction-focus.html
@@ -3,6 +3,7 @@
 <meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
 <script src="resources/utils.js"></script>
 <body>
 <input type="text" id = "prerenderTextField">
@@ -18,19 +19,22 @@
       document.hasFocus(),
       'Initial document should have focus.');
 
-  const gotMessage = new Promise(resolve => {
-    bc.addEventListener('message', e => {
-      resolve(e.data);
-    }, {once:true});
-  });
+  const {exec} = await create_prerendered_page(t);
+  const result = await exec(() => {
+    const element = document.createElement('input');
+    element.setAttribute('type', 'text');
+    document.body.appendChild(element);
+    element.focus();
 
-  // Start prerendering a page that accesses the focus state of the page.
-  startPrerendering(`resources/prerender-focus.html`);
+    // Post the focus and active states to the initiator page.
+    return {
+      activeElementUpdated: document.activeElement === element,
+      documentHasFocus: document.hasFocus()
+    };
+  })
 
-  const result = await gotMessage;
-  assert_true(result.activeElementUpdated);
-  assert_false(result.documentHasFocus);
-  bc.close();
+  assert_true(result.activeElementUpdated, 'Active element has been updated');
+  assert_false(result.documentHasFocus, 'Document should not have focus');
 }, 'Prerendering document should update the active element but not have focus');
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restrictions.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restrictions.html
new file mode 100644
index 0000000..5019d4b2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restrictions.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Same-origin prerendering can access localStorage</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="resources/utils.js"></script>
+<body>
+<script>
+
+setup(() => assertSpeculationRulesIsSupported());
+
+test_prerender_restricted(
+  () => navigator.clipboard.writeText(location.href),
+  "NotAllowedError", "prerendering pages should not be able to access the clipboard via the Async Clipboard API");
+
+test_prerender_restricted(async () => {
+  const canvas = document.createElement('canvas');
+  document.body.appendChild(canvas);
+  await canvas.requestPointerLock();
+}, "WrongDocumentError", "prerendering pages should not be able to access the pointer-lock API");
+
+test_prerender_restricted(async () => {
+  const div = document.createElement('div');
+  document.body.appendChild(div);
+  await div.requestFullscreen();
+}, "TypeError", "prerendering pages should not be able to access the FullScreen API");
+
+test_prerender_defer(() => new Promise(
+  resolve => navigator.geolocation.getCurrentPosition(p => resolve(p.toString()))),
+  "Geolocation API should be deferred");
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/url/resources/urltestdata.json b/third_party/blink/web_tests/external/wpt/url/resources/urltestdata.json
index b39c6e7..fa619fb8 100644
--- a/third_party/blink/web_tests/external/wpt/url/resources/urltestdata.json
+++ b/third_party/blink/web_tests/external/wpt/url/resources/urltestdata.json
@@ -4538,16 +4538,6 @@
     "hash": ""
   },
   {
-    "input": "sc://\u0000/",
-    "base": "about:blank",
-    "failure": true
-  },
-  {
-    "input": "sc:// /",
-    "base": "about:blank",
-    "failure": true
-  },
-  {
     "input": "sc://%/",
     "base": "about:blank",
     "href": "sc://%/",
@@ -4582,21 +4572,6 @@
     "failure": true
   },
   {
-    "input": "sc://[/",
-    "base": "about:blank",
-    "failure": true
-  },
-  {
-    "input": "sc://\\/",
-    "base": "about:blank",
-    "failure": true
-  },
-  {
-    "input": "sc://]/",
-    "base": "about:blank",
-    "failure": true
-  },
-  {
     "input": "x",
     "base": "sc://ñ",
     "href": "sc://%C3%B1/x",
@@ -4707,42 +4682,47 @@
   },
   "Forbidden host code points",
   {
-    "input": "http://a<b",
+    "input": "sc://a\u0000b/",
     "base": "about:blank",
     "failure": true
   },
   {
-    "input": "http://a>b",
+    "input": "sc://a b/",
     "base": "about:blank",
     "failure": true
   },
   {
-    "input": "http://a^b",
+    "input": "sc://a<b",
     "base": "about:blank",
     "failure": true
   },
   {
-    "input": "non-special://a<b",
+    "input": "sc://a>b",
     "base": "about:blank",
     "failure": true
   },
   {
-    "input": "non-special://a>b",
+    "input": "sc://a[b/",
     "base": "about:blank",
     "failure": true
   },
   {
-    "input": "non-special://a^b",
+    "input": "sc://a\\b/",
     "base": "about:blank",
     "failure": true
   },
   {
-    "input": "foo://ho\u0000st/",
+    "input": "sc://a]b/",
     "base": "about:blank",
     "failure": true
   },
   {
-    "input": "foo://ho|st/",
+    "input": "sc://a^b",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "sc://a|b/",
     "base": "about:blank",
     "failure": true
   },
@@ -4789,13 +4769,620 @@
     "search": "",
     "username": ""
   },
-  "Encoded forbidden host codepoints in special URLs",
+  "Forbidden domain code-points",
+  {
+    "input": "http://a\u0000b/",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "http://a\u0001b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0001b",
+    "hostname": "a\u0001b",
+    "href":"http://a\u0001b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0002b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0002b",
+    "hostname": "a\u0002b",
+    "href":"http://a\u0002b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0003b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0003b",
+    "hostname": "a\u0003b",
+    "href":"http://a\u0003b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0004b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0004b",
+    "hostname": "a\u0004b",
+    "href":"http://a\u0004b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0005b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0005b",
+    "hostname": "a\u0005b",
+    "href":"http://a\u0005b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0006b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0006b",
+    "hostname": "a\u0006b",
+    "href":"http://a\u0006b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0007b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0007b",
+    "hostname": "a\u0007b",
+    "href":"http://a\u0007b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0008b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0008b",
+    "hostname": "a\u0008b",
+    "href":"http://a\u0008b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u000Bb/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u000Bb",
+    "hostname": "a\u000Bb",
+    "href":"http://a\u000Bb/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u000Cb/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u000Cb",
+    "hostname": "a\u000Cb",
+    "href":"http://a\u000Cb/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u000Eb/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u000Eb",
+    "hostname": "a\u000Eb",
+    "href":"http://a\u000Eb/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u000Fb/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u000Fb",
+    "hostname": "a\u000Fb",
+    "href":"http://a\u000Fb/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0010b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0010b",
+    "hostname": "a\u0010b",
+    "href":"http://a\u0010b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0011b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0011b",
+    "hostname": "a\u0011b",
+    "href":"http://a\u0011b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0012b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0012b",
+    "hostname": "a\u0012b",
+    "href":"http://a\u0012b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0013b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0013b",
+    "hostname": "a\u0013b",
+    "href":"http://a\u0013b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0014b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0014b",
+    "hostname": "a\u0014b",
+    "href":"http://a\u0014b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0015b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0015b",
+    "hostname": "a\u0015b",
+    "href":"http://a\u0015b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0016b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0016b",
+    "hostname": "a\u0016b",
+    "href":"http://a\u0016b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0017b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0017b",
+    "hostname": "a\u0017b",
+    "href":"http://a\u0017b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0018b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0018b",
+    "hostname": "a\u0018b",
+    "href":"http://a\u0018b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u0019b/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u0019b",
+    "hostname": "a\u0019b",
+    "href":"http://a\u0019b/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u001Ab/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u001Ab",
+    "hostname": "a\u001Ab",
+    "href":"http://a\u001Ab/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u001Bb/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u001Bb",
+    "hostname": "a\u001Bb",
+    "href":"http://a\u001Bb/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u001Cb/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u001Cb",
+    "hostname": "a\u001Cb",
+    "href":"http://a\u001Cb/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u001Db/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u001Db",
+    "hostname": "a\u001Db",
+    "href":"http://a\u001Db/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u001Eb/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u001Eb",
+    "hostname": "a\u001Eb",
+    "href":"http://a\u001Eb/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a\u001Fb/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u001Fb",
+    "hostname": "a\u001Fb",
+    "href":"http://a\u001Fb/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://a b/",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "http://a%b/",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "http://a<b",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "http://a>b",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "http://a[b/",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "http://a]b/",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "http://a^b",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "http://a|b/",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
+    "input": "http://a\u007Fb/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "a\u007Fb",
+    "hostname": "a\u007Fb",
+    "href":"http://a\u007Fb/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  "Forbidden domain codepoints: tabs and newlines are removed during preprocessing",
+  {
+    "input": "http://ho\u0009st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "host",
+    "hostname": "host",
+    "href":"http://host/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho\u000Ast/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "host",
+    "hostname": "host",
+    "href":"http://host/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho\u000Dst/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "host",
+    "hostname": "host",
+    "href":"http://host/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  "Encoded forbidden domain codepoints in special URLs",
   {
     "input": "http://ho%00st/",
     "base": "about:blank",
     "failure": true
   },
   {
+    "input": "http://ho%01st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0001st",
+    "hostname": "ho\u0001st",
+    "href":"http://ho\u0001st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%02st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0002st",
+    "hostname": "ho\u0002st",
+    "href":"http://ho\u0002st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%03st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0003st",
+    "hostname": "ho\u0003st",
+    "href":"http://ho\u0003st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%04st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0004st",
+    "hostname": "ho\u0004st",
+    "href":"http://ho\u0004st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%05st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0005st",
+    "hostname": "ho\u0005st",
+    "href":"http://ho\u0005st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%06st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0006st",
+    "hostname": "ho\u0006st",
+    "href":"http://ho\u0006st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%07st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0007st",
+    "hostname": "ho\u0007st",
+    "href":"http://ho\u0007st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%08st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0008st",
+    "hostname": "ho\u0008st",
+    "href":"http://ho\u0008st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
     "input": "http://ho%09st/",
     "base": "about:blank",
     "failure": true
@@ -4806,11 +5393,291 @@
     "failure": true
   },
   {
+    "input": "http://ho%0Bst/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u000Bst",
+    "hostname": "ho\u000Bst",
+    "href":"http://ho\u000Bst/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%0Cst/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u000Cst",
+    "hostname": "ho\u000Cst",
+    "href":"http://ho\u000Cst/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
     "input": "http://ho%0Dst/",
     "base": "about:blank",
     "failure": true
   },
   {
+    "input": "http://ho%0Est/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u000Est",
+    "hostname": "ho\u000Est",
+    "href":"http://ho\u000Est/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%0Fst/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u000Fst",
+    "hostname": "ho\u000Fst",
+    "href":"http://ho\u000Fst/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%10st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0010st",
+    "hostname": "ho\u0010st",
+    "href":"http://ho\u0010st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%11st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0011st",
+    "hostname": "ho\u0011st",
+    "href":"http://ho\u0011st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%12st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0012st",
+    "hostname": "ho\u0012st",
+    "href":"http://ho\u0012st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%13st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0013st",
+    "hostname": "ho\u0013st",
+    "href":"http://ho\u0013st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%14st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0014st",
+    "hostname": "ho\u0014st",
+    "href":"http://ho\u0014st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%15st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0015st",
+    "hostname": "ho\u0015st",
+    "href":"http://ho\u0015st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%16st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0016st",
+    "hostname": "ho\u0016st",
+    "href":"http://ho\u0016st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%17st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0017st",
+    "hostname": "ho\u0017st",
+    "href":"http://ho\u0017st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%18st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0018st",
+    "hostname": "ho\u0018st",
+    "href":"http://ho\u0018st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%19st/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u0019st",
+    "hostname": "ho\u0019st",
+    "href":"http://ho\u0019st/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%1Ast/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u001Ast",
+    "hostname": "ho\u001Ast",
+    "href":"http://ho\u001Ast/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%1Bst/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u001Bst",
+    "hostname": "ho\u001Bst",
+    "href":"http://ho\u001Bst/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%1Cst/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u001Cst",
+    "hostname": "ho\u001Cst",
+    "href":"http://ho\u001Cst/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%1Dst/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u001Dst",
+    "hostname": "ho\u001Dst",
+    "href":"http://ho\u001Dst/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%1Est/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u001Est",
+    "hostname": "ho\u001Est",
+    "href":"http://ho\u001Est/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
+    "input": "http://ho%1Fst/",
+    "base": "about:blank",
+    "hash": "",
+    "host": "ho\u001Fst",
+    "hostname": "ho\u001Fst",
+    "href":"http://ho\u001Fst/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  {
     "input": "http://ho%20st/",
     "base": "about:blank",
     "failure": true
@@ -4821,6 +5688,11 @@
     "failure": true
   },
   {
+    "input": "http://ho%25st/",
+    "base": "about:blank",
+    "failure": true
+  },
+  {
     "input": "http://ho%2Fst/",
     "base": "about:blank",
     "failure": true
@@ -4870,32 +5742,46 @@
     "base": "about:blank",
     "failure": true
   },
-  "Allowed host code points",
   {
-    "input": "http://\u001F!\"$&'()*+,-.;=_`{}~/",
+    "input": "http://ho%7Fst/",
     "base": "about:blank",
-    "href": "http://\u001F!\"$&'()*+,-.;=_`{}~/",
-    "origin": "http://\u001F!\"$&'()*+,-.;=_`{}~",
+    "hash": "",
+    "host": "ho\u007Fst",
+    "hostname": "ho\u007Fst",
+    "href":"http://ho\u007Fst/",
+    "password": "",
+    "pathname": "/",
+    "port":"",
+    "protocol": "http:",
+    "search": "",
+    "username": ""
+  },
+  "Allowed host/domain code points",
+  {
+    "input": "http://\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F!\"$&'()*+,-.;=_`{}~/",
+    "base": "about:blank",
+    "href": "http://\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F!\"$&'()*+,-.;=_`{}~/",
+    "origin": "http://\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F!\"$&'()*+,-.;=_`{}~",
     "protocol": "http:",
     "username": "",
     "password": "",
-    "host": "\u001F!\"$&'()*+,-.;=_`{}~",
-    "hostname": "\u001F!\"$&'()*+,-.;=_`{}~",
+    "host": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F!\"$&'()*+,-.;=_`{}~",
+    "hostname": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F!\"$&'()*+,-.;=_`{}~",
     "port": "",
     "pathname": "/",
     "search": "",
     "hash": ""
   },
   {
-    "input": "sc://\u001F!\"$&'()*+,-.;=_`{}~/",
+    "input": "sc://\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F!\"$%&'()*+,-.;=_`{}~/",
     "base": "about:blank",
-    "href": "sc://%1F!\"$&'()*+,-.;=_`{}~/",
+    "href": "sc://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~/",
     "origin": "null",
     "protocol": "sc:",
     "username": "",
     "password": "",
-    "host": "%1F!\"$&'()*+,-.;=_`{}~",
-    "hostname": "%1F!\"$&'()*+,-.;=_`{}~",
+    "host": "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~",
+    "hostname": "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~",
     "port": "",
     "pathname": "/",
     "search": "",
diff --git a/third_party/blink/web_tests/external/wpt/visual-viewport/viewport-resize-event-on-iframe-show.html b/third_party/blink/web_tests/external/wpt/visual-viewport/viewport-resize-event-on-iframe-show.html
new file mode 100644
index 0000000..688148a8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/visual-viewport/viewport-resize-event-on-iframe-show.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<html>
+    <head>
+        <title>Viewport: Resize Event On Showing Iframe</title>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, minimum-scale=1">
+        <script src="/resources/testharness.js"></script>
+        <script src="/resources/testharnessreport.js"></script>
+        <script>
+          async_test(t => {
+            document.addEventListener("DOMContentLoaded", () => {
+              let iframe = document.querySelector("iframe");
+              onload = () => {
+                requestAnimationFrame(() => { requestAnimationFrame(() => {
+                  // First full rendering update is complete.
+                  let resize_event_count = 0;
+                  iframe.contentWindow.visualViewport.addEventListener("resize", () => {
+                    resize_event_count++;
+                  });
+                  iframe.style.display = "";
+                  iframe.clientWidth;
+                  requestAnimationFrame(() => {
+                    t.step(() => {
+                      assert_equals(resize_event_count, 1);
+                      t.done();
+                    });
+                  }) }); // 2x requestAnimationFrame
+                })
+              };
+            });
+          }, "Resize event fired when an iframe is shown.");
+        </script>
+    </head>
+    <body>
+        <h1>Viewport: Resize Event On Iframe Size Change</h1>
+        <h4>
+          Test Description: This test ensures that we fire a resize event when
+          an iframe is shown.
+        </h4>
+        <iframe style="display: none;" srcdoc="<p>Hello, world!</p>"></iframe>
+        <div id="log"></div>
+    </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py
index 9c4c7b1..30f93d4 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py
@@ -31,6 +31,15 @@
     )
 
 
+def pytest_sessionfinish(session, exitstatus):
+    # Cleanup at the end of a test run
+    global _current_session
+
+    if _current_session is not None:
+        _current_session.end()
+        _current_session = None
+
+
 @pytest.fixture
 def capabilities():
     """Default capabilities to use for a new WebDriver session."""
diff --git a/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt
index 6ed0916d..7b3f1ae7 100644
--- a/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 64 tests; 63 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 65 tests; 64 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Partial interface Navigator: original interface defined
@@ -43,6 +43,7 @@
 PASS HIDDevice interface: attribute collections
 PASS HIDDevice interface: operation open()
 PASS HIDDevice interface: operation close()
+PASS HIDDevice interface: operation forget()
 PASS HIDDevice interface: operation sendReport(octet, BufferSource)
 PASS HIDDevice interface: operation sendFeatureReport(octet, BufferSource)
 PASS HIDDevice interface: operation receiveFeatureReport(octet)
diff --git a/third_party/blink/web_tests/fast/forms/color/input-color-under-shadow-popup-crash.html b/third_party/blink/web_tests/fast/forms/color/input-color-under-shadow-popup-crash.html
index 9fa854f..43046b8 100644
--- a/third_party/blink/web_tests/fast/forms/color/input-color-under-shadow-popup-crash.html
+++ b/third_party/blink/web_tests/fast/forms/color/input-color-under-shadow-popup-crash.html
@@ -3,6 +3,9 @@
 <!-- crbug.com/1160433 -->
 <title>Test that popup, its owner element unassigned under a shadow root, is cleanup when the page is shutdown. </title>
 <script src="../resources/picker-common.js"></script>
+<script src="../../../resources/testdriver.js"></script>
+<script src="../../../resources/testdriver-vendor.js"></script>
+
 <canvas>
 <video>
 <select>
@@ -26,9 +29,16 @@
     testRunner.notifyDone();
 }
 
-window.onload = function () {
-    openPicker(color, openCallback, errorCallback);
-}
+window.onload = async function () {
+    await test_driver.bless("show color picker");
+    color.showPicker();
+
+    popupWindow = internals.pagePopupWindow;
+    if (popupWindow)
+        setPopupOpenCallback(openCallback);
+    else
+        errorCallback();
+};
 </script>
 </body>
 </html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-button-expected.txt b/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-button-expected.txt
new file mode 100644
index 0000000..b90d635
--- /dev/null
+++ b/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-button-expected.txt
@@ -0,0 +1,5 @@
+CONSOLE WARNING: A <selectmenu>'s default button was removed and a new one was not provided. This <selectmenu> will not be fully functional.
+This is a testharness.js-based test.
+PASS selectmenu-slot-warning-button
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-button.html b/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-button.html
new file mode 100644
index 0000000..fa8835a
--- /dev/null
+++ b/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-button.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en">
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src="../../resources/testdriver.js"></script>
+<script src="../../resources/testdriver-actions.js"></script>
+<script src="../../resources/testdriver-vendor.js"></script>
+
+<!-- No console warnings: button was replaced. -->
+<selectmenu>
+  <div slot="button">
+    <div behavior="button">
+      My custom button
+    </div>
+  </div>
+</selectmenu>
+
+<!-- One console warning: button was not replaced. -->
+<selectmenu>
+  <div slot="button">
+    <div>
+      Not a button
+    </div>
+  </div>
+</selectmenu>
+
+<script>
+  setup({ single_test: true });
+  // The purpose of this test to to ensure that the correct
+  // console warnings are logged, via comparison with the expectations
+  // file. So, nothing to test here.
+  done();
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-listbox-expected.txt b/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-listbox-expected.txt
new file mode 100644
index 0000000..85ebfb4
--- /dev/null
+++ b/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-listbox-expected.txt
@@ -0,0 +1,5 @@
+CONSOLE WARNING: A <selectmenu>'s default listbox was removed and a new one was not provided. This <selectmenu> will not be fully functional.
+This is a testharness.js-based test.
+PASS selectmenu-slot-warning-listbox
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-listbox.html b/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-listbox.html
new file mode 100644
index 0000000..054edc8
--- /dev/null
+++ b/third_party/blink/web_tests/html/selectmenu/selectmenu-slot-warning-listbox.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src="../../resources/testdriver.js"></script>
+<script src="../../resources/testdriver-actions.js"></script>
+<script src="../../resources/testdriver-vendor.js"></script>
+
+<!-- No console warnings: listbox was replaced. -->
+<selectmenu>
+  <div slot="listbox">
+    <popup behavior="listbox"></popup>
+  </div>
+</selectmenu>
+
+<!-- One console warning: listbox was not replaced. -->
+<selectmenu>
+  <div slot="listbox">
+    <popup></popup>
+  </div>
+</selectmenu>
+
+<script>
+  setup({ single_test: true });
+  // The purpose of this test to to ensure that the correct
+  // console warnings are logged, via comparison with the expectations
+  // file. So, nothing to test here.
+  done();
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/payments/payment-instruments.html b/third_party/blink/web_tests/http/tests/payments/payment-instruments.html
index bc51519..b0cff63 100644
--- a/third_party/blink/web_tests/http/tests/payments/payment-instruments.html
+++ b/third_party/blink/web_tests/http/tests/payments/payment-instruments.html
@@ -71,7 +71,64 @@
             });
         })
       .catch(unreached_rejection(test));
-  }, 'PaymentInstruments set/get methods test');
+  }, 'PaymentInstruments set/get methods test with basic-card');
+
+promise_test(test => {
+    var registration;
+    var script_url = 'resources/empty-worker.js';
+    var scope = 'resources/';
+
+    return service_worker_unregister_and_register(test, script_url, scope)
+      .then(r => {
+          registration = r;
+          return wait_for_state(test, registration.installing, 'activated');
+        })
+      .then(state => {
+          assert_equals(state, 'activated');
+          return PermissionsHelper.setPermission('payment-handler', 'granted');
+        })
+      .then(() => {
+          return registration.paymentManager.instruments.set(
+              'test_key',
+              {
+                name: 'ChromePay',
+                icons: [
+                  {
+                    'src': './resources/icon-1x.png',
+                    'sizes': '32x32 48x48',
+                    'type': 'image/png'
+                  },
+                  {
+                    'src': './resources/icon-2x.png',
+                    'sizes': '96x96',
+                    'type': 'image/png',
+                    'purpose': 'any monochrome'
+                  }
+                ],
+                method: 'https://www.chromium.org/pay'
+              });
+        })
+      .then(result => {
+          assert_equals(result, undefined);
+          return registration.paymentManager.instruments.get('test_key');
+        })
+      .then(stored_instrument => {
+          assert_equals(stored_instrument.name, 'ChromePay');
+          assert_equals(stored_instrument.method, 'https://www.chromium.org/pay');
+          assert_equals(stored_instrument.icons.length, 2);
+          assert_object_equals(stored_instrument.icons[0], {
+              src: location.origin + '/payments/resources/icon-1x.png',
+              sizes: '32x32 48x48',
+              type: 'image/png'
+            });
+          assert_object_equals(stored_instrument.icons[1], {
+              src: location.origin + '/payments/resources/icon-2x.png',
+              sizes: '96x96',
+              type: 'image/png'
+            });
+        })
+      .catch(unreached_rejection(test));
+  }, 'PaymentInstruments set/get methods test with url method');
 
 promise_test(test => {
     var registration;
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-expected.txt
index 9af8e6a..314db574 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 665 tests; 383 PASS, 282 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 736 tests; 389 PASS, 347 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -277,6 +277,10 @@
 PASS Parsing: <https://x/�?�#�> against <about:blank>
 FAIL Parsing: <http://a.b.c.xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://10.0.0.xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a.b.c.XN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a.b.c.Xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.XN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.xN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 PASS Parsing: <http://Go.com> against <http://other.com/>
 FAIL Parsing: <http://%41.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://%ef%bc%85%ef%bc%94%ef%bc%91.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
@@ -347,16 +351,11 @@
 FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
 FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
 FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
-FAIL Parsing: <sc://\0/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc:// /> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
 FAIL Parsing: <sc://@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://te@s:t@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:12/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://[/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://\/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://]/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1/x" but got "sc://%C3%B1"
 PASS Parsing: <sc:\../> against <about:blank>
 PASS Parsing: <sc::a@example.net> against <about:blank>
@@ -364,24 +363,96 @@
 PASS Parsing: <wow:%1G> against <about:blank>
 FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
 FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: href expected "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF" but got "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD"
-FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
-FAIL Parsing: <non-special://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho|st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho
 st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <http://a\0b/> against <about:blank> assert_equals: failure should set href to input expected "http://a\0b/" but got "http://a%00b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x01b/" but got "http://a%01b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x02b/" but got "http://a%02b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x03b/" but got "http://a%03b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x04b/" but got "http://a%04b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x05b/" but got "http://a%05b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x06b/" but got "http://a%06b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x07b/" but got "http://a%07b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\bb/" but got "http://a%08b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\vb/" but got "http://a%0Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\fb/" but got "http://a%0Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0eb/" but got "http://a%0Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0fb/" but got "http://a%0Fb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x10b/" but got "http://a%10b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x11b/" but got "http://a%11b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x12b/" but got "http://a%12b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x13b/" but got "http://a%13b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x14b/" but got "http://a%14b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x15b/" but got "http://a%15b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x16b/" but got "http://a%16b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x17b/" but got "http://a%17b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x18b/" but got "http://a%18b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x19b/" but got "http://a%19b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1ab/" but got "http://a%1Ab/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1bb/" but got "http://a%1Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1cb/" but got "http://a%1Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1db/" but got "http://a%1Db/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1eb/" but got "http://a%1Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1fb/" but got "http://a%1Fb/"
+FAIL Parsing: <http://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a%b/> against <about:blank> assert_equals: failure should set href to input expected "http://a%b/" but got "http://a%25b/"
+FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
+FAIL Parsing: <http://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://ab/" but got "http://a%7Fb/"
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
 PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> assert_equals: href expected "http://ho\x01st/" but got "http://ho%01st/"
+FAIL Parsing: <http://ho%02st/> against <about:blank> assert_equals: href expected "http://ho\x02st/" but got "http://ho%02st/"
+FAIL Parsing: <http://ho%03st/> against <about:blank> assert_equals: href expected "http://ho\x03st/" but got "http://ho%03st/"
+FAIL Parsing: <http://ho%04st/> against <about:blank> assert_equals: href expected "http://ho\x04st/" but got "http://ho%04st/"
+FAIL Parsing: <http://ho%05st/> against <about:blank> assert_equals: href expected "http://ho\x05st/" but got "http://ho%05st/"
+FAIL Parsing: <http://ho%06st/> against <about:blank> assert_equals: href expected "http://ho\x06st/" but got "http://ho%06st/"
+FAIL Parsing: <http://ho%07st/> against <about:blank> assert_equals: href expected "http://ho\x07st/" but got "http://ho%07st/"
+FAIL Parsing: <http://ho%08st/> against <about:blank> assert_equals: href expected "http://ho\bst/" but got "http://ho%08st/"
 PASS Parsing: <http://ho%09st/> against <about:blank>
 PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> assert_equals: href expected "http://ho\vst/" but got "http://ho%0Bst/"
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> assert_equals: href expected "http://ho\fst/" but got "http://ho%0Cst/"
 PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> assert_equals: href expected "http://ho\x0est/" but got "http://ho%0Est/"
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> assert_equals: href expected "http://ho\x0fst/" but got "http://ho%0Fst/"
+FAIL Parsing: <http://ho%10st/> against <about:blank> assert_equals: href expected "http://ho\x10st/" but got "http://ho%10st/"
+FAIL Parsing: <http://ho%11st/> against <about:blank> assert_equals: href expected "http://ho\x11st/" but got "http://ho%11st/"
+FAIL Parsing: <http://ho%12st/> against <about:blank> assert_equals: href expected "http://ho\x12st/" but got "http://ho%12st/"
+FAIL Parsing: <http://ho%13st/> against <about:blank> assert_equals: href expected "http://ho\x13st/" but got "http://ho%13st/"
+FAIL Parsing: <http://ho%14st/> against <about:blank> assert_equals: href expected "http://ho\x14st/" but got "http://ho%14st/"
+FAIL Parsing: <http://ho%15st/> against <about:blank> assert_equals: href expected "http://ho\x15st/" but got "http://ho%15st/"
+FAIL Parsing: <http://ho%16st/> against <about:blank> assert_equals: href expected "http://ho\x16st/" but got "http://ho%16st/"
+FAIL Parsing: <http://ho%17st/> against <about:blank> assert_equals: href expected "http://ho\x17st/" but got "http://ho%17st/"
+FAIL Parsing: <http://ho%18st/> against <about:blank> assert_equals: href expected "http://ho\x18st/" but got "http://ho%18st/"
+FAIL Parsing: <http://ho%19st/> against <about:blank> assert_equals: href expected "http://ho\x19st/" but got "http://ho%19st/"
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> assert_equals: href expected "http://ho\x1ast/" but got "http://ho%1Ast/"
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> assert_equals: href expected "http://ho\x1bst/" but got "http://ho%1Bst/"
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> assert_equals: href expected "http://ho\x1cst/" but got "http://ho%1Cst/"
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> assert_equals: href expected "http://ho\x1dst/" but got "http://ho%1Dst/"
+FAIL Parsing: <http://ho%1Est/> against <about:blank> assert_equals: href expected "http://ho\x1est/" but got "http://ho%1Est/"
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> assert_equals: href expected "http://ho\x1fst/" but got "http://ho%1Fst/"
 FAIL Parsing: <http://ho%20st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://ho%23st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%25st/> against <about:blank>
 PASS Parsing: <http://ho%2Fst/> against <about:blank>
 FAIL Parsing: <http://ho%3Ast/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%3Ast/" but got "http://ho:st/"
 FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
@@ -392,8 +463,9 @@
 PASS Parsing: <http://ho%5Cst/> against <about:blank>
 FAIL Parsing: <http://ho%5Dst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Dst/" but got "http://ho]st/"
 FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%1F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
-FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> assert_equals: href expected "http://host/" but got "http://ho%7Fst/"
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
 FAIL Parsing: <ftp://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%80/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <ftp://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%A0/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <https://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%80/" but got "https://example.com%EF%BF%BD/"
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-expected.txt
index 0353e737..89bc28a 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-expected.txt
@@ -264,8 +264,8 @@
 PASS Parsing origin: <wow:%1G> against <about:blank>
 PASS Parsing origin: <wow:￿> against <about:blank>
 FAIL Parsing origin: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
-FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
-PASS Parsing origin: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Parsing origin: <ftp://%e2%98%83> against <about:blank>
 PASS Parsing origin: <https://%e2%98%83> against <about:blank>
 PASS Parsing origin: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-xhtml-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-xhtml-expected.txt
index 0353e737..89bc28a 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-origin-xhtml-expected.txt
@@ -264,8 +264,8 @@
 PASS Parsing origin: <wow:%1G> against <about:blank>
 PASS Parsing origin: <wow:￿> against <about:blank>
 FAIL Parsing origin: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
-FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
-PASS Parsing origin: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Parsing origin: <ftp://%e2%98%83> against <about:blank>
 PASS Parsing origin: <https://%e2%98%83> against <about:blank>
 PASS Parsing origin: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt
index 9af8e6a..314db574 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 665 tests; 383 PASS, 282 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 736 tests; 389 PASS, 347 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -277,6 +277,10 @@
 PASS Parsing: <https://x/�?�#�> against <about:blank>
 FAIL Parsing: <http://a.b.c.xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://10.0.0.xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a.b.c.XN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a.b.c.Xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.XN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.xN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 PASS Parsing: <http://Go.com> against <http://other.com/>
 FAIL Parsing: <http://%41.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://%ef%bc%85%ef%bc%94%ef%bc%91.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
@@ -347,16 +351,11 @@
 FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
 FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
 FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
-FAIL Parsing: <sc://\0/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc:// /> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
 FAIL Parsing: <sc://@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://te@s:t@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:12/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://[/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://\/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://]/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1/x" but got "sc://%C3%B1"
 PASS Parsing: <sc:\../> against <about:blank>
 PASS Parsing: <sc::a@example.net> against <about:blank>
@@ -364,24 +363,96 @@
 PASS Parsing: <wow:%1G> against <about:blank>
 FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
 FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: href expected "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF" but got "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD"
-FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
-FAIL Parsing: <non-special://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho|st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho
 st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <http://a\0b/> against <about:blank> assert_equals: failure should set href to input expected "http://a\0b/" but got "http://a%00b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x01b/" but got "http://a%01b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x02b/" but got "http://a%02b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x03b/" but got "http://a%03b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x04b/" but got "http://a%04b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x05b/" but got "http://a%05b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x06b/" but got "http://a%06b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x07b/" but got "http://a%07b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\bb/" but got "http://a%08b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\vb/" but got "http://a%0Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\fb/" but got "http://a%0Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0eb/" but got "http://a%0Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0fb/" but got "http://a%0Fb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x10b/" but got "http://a%10b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x11b/" but got "http://a%11b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x12b/" but got "http://a%12b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x13b/" but got "http://a%13b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x14b/" but got "http://a%14b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x15b/" but got "http://a%15b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x16b/" but got "http://a%16b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x17b/" but got "http://a%17b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x18b/" but got "http://a%18b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x19b/" but got "http://a%19b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1ab/" but got "http://a%1Ab/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1bb/" but got "http://a%1Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1cb/" but got "http://a%1Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1db/" but got "http://a%1Db/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1eb/" but got "http://a%1Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1fb/" but got "http://a%1Fb/"
+FAIL Parsing: <http://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a%b/> against <about:blank> assert_equals: failure should set href to input expected "http://a%b/" but got "http://a%25b/"
+FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
+FAIL Parsing: <http://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://ab/" but got "http://a%7Fb/"
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
 PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> assert_equals: href expected "http://ho\x01st/" but got "http://ho%01st/"
+FAIL Parsing: <http://ho%02st/> against <about:blank> assert_equals: href expected "http://ho\x02st/" but got "http://ho%02st/"
+FAIL Parsing: <http://ho%03st/> against <about:blank> assert_equals: href expected "http://ho\x03st/" but got "http://ho%03st/"
+FAIL Parsing: <http://ho%04st/> against <about:blank> assert_equals: href expected "http://ho\x04st/" but got "http://ho%04st/"
+FAIL Parsing: <http://ho%05st/> against <about:blank> assert_equals: href expected "http://ho\x05st/" but got "http://ho%05st/"
+FAIL Parsing: <http://ho%06st/> against <about:blank> assert_equals: href expected "http://ho\x06st/" but got "http://ho%06st/"
+FAIL Parsing: <http://ho%07st/> against <about:blank> assert_equals: href expected "http://ho\x07st/" but got "http://ho%07st/"
+FAIL Parsing: <http://ho%08st/> against <about:blank> assert_equals: href expected "http://ho\bst/" but got "http://ho%08st/"
 PASS Parsing: <http://ho%09st/> against <about:blank>
 PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> assert_equals: href expected "http://ho\vst/" but got "http://ho%0Bst/"
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> assert_equals: href expected "http://ho\fst/" but got "http://ho%0Cst/"
 PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> assert_equals: href expected "http://ho\x0est/" but got "http://ho%0Est/"
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> assert_equals: href expected "http://ho\x0fst/" but got "http://ho%0Fst/"
+FAIL Parsing: <http://ho%10st/> against <about:blank> assert_equals: href expected "http://ho\x10st/" but got "http://ho%10st/"
+FAIL Parsing: <http://ho%11st/> against <about:blank> assert_equals: href expected "http://ho\x11st/" but got "http://ho%11st/"
+FAIL Parsing: <http://ho%12st/> against <about:blank> assert_equals: href expected "http://ho\x12st/" but got "http://ho%12st/"
+FAIL Parsing: <http://ho%13st/> against <about:blank> assert_equals: href expected "http://ho\x13st/" but got "http://ho%13st/"
+FAIL Parsing: <http://ho%14st/> against <about:blank> assert_equals: href expected "http://ho\x14st/" but got "http://ho%14st/"
+FAIL Parsing: <http://ho%15st/> against <about:blank> assert_equals: href expected "http://ho\x15st/" but got "http://ho%15st/"
+FAIL Parsing: <http://ho%16st/> against <about:blank> assert_equals: href expected "http://ho\x16st/" but got "http://ho%16st/"
+FAIL Parsing: <http://ho%17st/> against <about:blank> assert_equals: href expected "http://ho\x17st/" but got "http://ho%17st/"
+FAIL Parsing: <http://ho%18st/> against <about:blank> assert_equals: href expected "http://ho\x18st/" but got "http://ho%18st/"
+FAIL Parsing: <http://ho%19st/> against <about:blank> assert_equals: href expected "http://ho\x19st/" but got "http://ho%19st/"
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> assert_equals: href expected "http://ho\x1ast/" but got "http://ho%1Ast/"
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> assert_equals: href expected "http://ho\x1bst/" but got "http://ho%1Bst/"
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> assert_equals: href expected "http://ho\x1cst/" but got "http://ho%1Cst/"
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> assert_equals: href expected "http://ho\x1dst/" but got "http://ho%1Dst/"
+FAIL Parsing: <http://ho%1Est/> against <about:blank> assert_equals: href expected "http://ho\x1est/" but got "http://ho%1Est/"
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> assert_equals: href expected "http://ho\x1fst/" but got "http://ho%1Fst/"
 FAIL Parsing: <http://ho%20st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://ho%23st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%25st/> against <about:blank>
 PASS Parsing: <http://ho%2Fst/> against <about:blank>
 FAIL Parsing: <http://ho%3Ast/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%3Ast/" but got "http://ho:st/"
 FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
@@ -392,8 +463,9 @@
 PASS Parsing: <http://ho%5Cst/> against <about:blank>
 FAIL Parsing: <http://ho%5Dst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Dst/" but got "http://ho]st/"
 FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%1F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
-FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> assert_equals: href expected "http://host/" but got "http://ho%7Fst/"
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
 FAIL Parsing: <ftp://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%80/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <ftp://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%A0/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <https://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%80/" but got "https://example.com%EF%BF%BD/"
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/failure-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/failure-expected.txt
index 03b5393bc..13edad9 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/failure-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/failure-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 635 tests; 390 PASS, 245 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 695 tests; 414 PASS, 281 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS URL's constructor's base argument: file://example:1/ should throw
 PASS URL's href: file://example:1/ should throw
@@ -103,6 +103,30 @@
 FAIL sendBeacon(): http://10.0.0.xn--pokxncvks should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
 FAIL Location's href: http://10.0.0.xn--pokxncvks should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): http://10.0.0.xn--pokxncvks should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: http://a.b.c.XN--pokxncvks should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://a.b.c.XN--pokxncvks should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://a.b.c.XN--pokxncvks should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://a.b.c.XN--pokxncvks should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://a.b.c.XN--pokxncvks should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://a.b.c.XN--pokxncvks should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: http://a.b.c.Xn--pokxncvks should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://a.b.c.Xn--pokxncvks should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://a.b.c.Xn--pokxncvks should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://a.b.c.Xn--pokxncvks should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://a.b.c.Xn--pokxncvks should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://a.b.c.Xn--pokxncvks should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: http://10.0.0.XN--pokxncvks should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://10.0.0.XN--pokxncvks should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://10.0.0.XN--pokxncvks should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://10.0.0.XN--pokxncvks should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://10.0.0.XN--pokxncvks should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://10.0.0.XN--pokxncvks should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: http://10.0.0.xN--pokxncvks should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://10.0.0.xN--pokxncvks should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://10.0.0.xN--pokxncvks should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://10.0.0.xN--pokxncvks should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://10.0.0.xN--pokxncvks should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://10.0.0.xN--pokxncvks should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
 FAIL URL's constructor's base argument: https://x x:12 should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
 FAIL URL's href: https://x x:12 should throw assert_throws_js: function "() => url.href = test.input" did not throw
 FAIL XHR: https://x x:12 should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
@@ -115,18 +139,6 @@
 PASS sendBeacon(): http://[www.google.com]/ should throw
 FAIL Location's href: http://[www.google.com]/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://[www.google.com]/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
 PASS window.open(): http://[www.google.com]/ should throw
-FAIL URL's constructor's base argument: sc://\0/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://\0/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://\0/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://\0/ should throw
-FAIL Location's href: sc://\0/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://\0/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc:// / should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc:// / should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc:// / should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc:// / should throw
-FAIL Location's href: sc:// / should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc:// / should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
 FAIL URL's constructor's base argument: sc://@/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
 FAIL URL's href: sc://@/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
 FAIL XHR: sc://@/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
@@ -151,24 +163,78 @@
 PASS sendBeacon(): sc://:12/ should throw
 FAIL Location's href: sc://:12/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): sc://:12/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc://[/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://[/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://[/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://[/ should throw
-FAIL Location's href: sc://[/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://[/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc://\/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://\/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://\/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://\/ should throw
-FAIL Location's href: sc://\/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://\/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc://]/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://]/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://]/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://]/ should throw
-FAIL Location's href: sc://]/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://]/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a\0b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a\0b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a\0b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a\0b/ should throw
+FAIL Location's href: sc://a\0b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a\0b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a b/ should throw
+FAIL Location's href: sc://a b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a<b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a<b should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a<b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a<b should throw
+FAIL Location's href: sc://a<b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a<b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a>b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a>b should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a>b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a>b should throw
+FAIL Location's href: sc://a>b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a>b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a[b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a[b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a[b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a[b/ should throw
+FAIL Location's href: sc://a[b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a[b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a\b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a\b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a\b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a\b/ should throw
+FAIL Location's href: sc://a\b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a\b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a]b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a]b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a]b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a]b/ should throw
+FAIL Location's href: sc://a]b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a]b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a^b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a^b should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a^b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a^b should throw
+FAIL Location's href: sc://a^b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a^b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a|b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a|b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a|b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a|b/ should throw
+FAIL Location's href: sc://a|b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a|b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://a\0b/ should throw
+PASS URL's href: http://a\0b/ should throw
+PASS XHR: http://a\0b/ should throw
+PASS sendBeacon(): http://a\0b/ should throw
+FAIL Location's href: http://a\0b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a\0b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a\0b/ should throw
+FAIL URL's constructor's base argument: http://a b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://a b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://a b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://a b/ should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://a b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://a b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://a%b/ should throw
+PASS URL's href: http://a%b/ should throw
+PASS XHR: http://a%b/ should throw
+PASS sendBeacon(): http://a%b/ should throw
+FAIL Location's href: http://a%b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a%b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a%b/ should throw
 FAIL URL's constructor's base argument: http://a<b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
 FAIL URL's href: http://a<b should throw assert_throws_js: function "() => url.href = test.input" did not throw
 FAIL XHR: http://a<b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
@@ -181,42 +247,30 @@
 FAIL sendBeacon(): http://a>b should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
 FAIL Location's href: http://a>b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): http://a>b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://a[b/ should throw
+PASS URL's href: http://a[b/ should throw
+PASS XHR: http://a[b/ should throw
+PASS sendBeacon(): http://a[b/ should throw
+FAIL Location's href: http://a[b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a[b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a[b/ should throw
+PASS URL's constructor's base argument: http://a]b/ should throw
+PASS URL's href: http://a]b/ should throw
+PASS XHR: http://a]b/ should throw
+PASS sendBeacon(): http://a]b/ should throw
+FAIL Location's href: http://a]b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a]b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a]b/ should throw
 PASS URL's constructor's base argument: http://a^b should throw
 PASS URL's href: http://a^b should throw
 PASS XHR: http://a^b should throw
 PASS sendBeacon(): http://a^b should throw
 FAIL Location's href: http://a^b should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a^b' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
 PASS window.open(): http://a^b should throw
-FAIL URL's constructor's base argument: non-special://a<b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: non-special://a<b should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: non-special://a<b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): non-special://a<b should throw
-FAIL Location's href: non-special://a<b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): non-special://a<b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: non-special://a>b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: non-special://a>b should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: non-special://a>b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): non-special://a>b should throw
-FAIL Location's href: non-special://a>b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): non-special://a>b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: non-special://a^b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: non-special://a^b should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: non-special://a^b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): non-special://a^b should throw
-FAIL Location's href: non-special://a^b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): non-special://a^b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: foo://ho\0st/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: foo://ho\0st/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: foo://ho\0st/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): foo://ho\0st/ should throw
-FAIL Location's href: foo://ho\0st/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): foo://ho\0st/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: foo://ho|st/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: foo://ho|st/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: foo://ho|st/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): foo://ho|st/ should throw
-FAIL Location's href: foo://ho|st/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): foo://ho|st/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: http://a|b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://a|b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://a|b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://a|b/ should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://a|b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://a|b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
 PASS URL's constructor's base argument: http://ho%00st/ should throw
 PASS URL's href: http://ho%00st/ should throw
 PASS XHR: http://ho%00st/ should throw
@@ -253,6 +307,12 @@
 FAIL sendBeacon(): http://ho%23st/ should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
 FAIL Location's href: http://ho%23st/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): http://ho%23st/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://ho%25st/ should throw
+PASS URL's href: http://ho%25st/ should throw
+PASS XHR: http://ho%25st/ should throw
+PASS sendBeacon(): http://ho%25st/ should throw
+FAIL Location's href: http://ho%25st/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://ho%25st/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://ho%25st/ should throw
 PASS URL's constructor's base argument: http://ho%2Fst/ should throw
 PASS URL's href: http://ho%2Fst/ should throw
 PASS XHR: http://ho%2Fst/ should throw
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any-expected.txt
index 04e543b1..080ccd89 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-constructor.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 667 tests; 485 PASS, 182 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 738 tests; 493 PASS, 245 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -289,6 +289,18 @@
 FAIL Parsing: <http://10.0.0.xn--pokxncvks> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
+FAIL Parsing: <http://a.b.c.XN--pokxncvks> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <http://a.b.c.Xn--pokxncvks> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <http://10.0.0.XN--pokxncvks> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <http://10.0.0.xN--pokxncvks> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
 PASS Parsing: <http://Go.com> against <http://other.com/>
 FAIL Parsing: <http://%41.com> against <http://other.com/> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
@@ -373,12 +385,6 @@
 FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
 FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
 FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
-FAIL Parsing: <sc://\0/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
-FAIL Parsing: <sc:// /> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
 FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
 FAIL Parsing: <sc://@/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
@@ -392,15 +398,6 @@
 FAIL Parsing: <sc://:12/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <sc://[/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
-FAIL Parsing: <sc://\/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
-FAIL Parsing: <sc://]/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
 FAIL Parsing: <x> against <sc://ñ> Failed to construct 'URL': Invalid URL
 PASS Parsing: <sc:\../> against <about:blank>
 PASS Parsing: <sc::a@example.net> against <about:blank>
@@ -408,42 +405,126 @@
 PASS Parsing: <wow:%1G> against <about:blank>
 FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
 FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Parsing: <http://a<b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <http://a>b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-PASS Parsing: <http://a^b> against <about:blank>
-FAIL Parsing: <non-special://a<b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a<b> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <non-special://a>b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a>b> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <non-special://a^b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <foo://ho|st/> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <sc://a^b> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
 FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho
 st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+PASS Parsing: <http://a\0b/> against <about:blank>
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://a b/> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+PASS Parsing: <http://a%b/> against <about:blank>
+FAIL Parsing: <http://a<b> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <http://a>b> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+PASS Parsing: <http://a^b> against <about:blank>
+FAIL Parsing: <http://a|b/> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
 PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%02st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%03st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%04st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%05st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%06st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%07st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%08st/> against <about:blank> Failed to construct 'URL': Invalid URL
 PASS Parsing: <http://ho%09st/> against <about:blank>
 PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> Failed to construct 'URL': Invalid URL
 PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%10st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%11st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%12st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%13st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%14st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%15st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%16st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%17st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%18st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%19st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Est/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> Failed to construct 'URL': Invalid URL
 FAIL Parsing: <http://ho%20st/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
 FAIL Parsing: <http://ho%23st/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
+PASS Parsing: <http://ho%25st/> against <about:blank>
 PASS Parsing: <http://ho%2Fst/> against <about:blank>
 PASS Parsing: <http://ho%3Ast/> against <about:blank>
 FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_throws_js: function "function() {
@@ -462,8 +543,9 @@
 FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
 PASS Parsing: <ftp://example.com%80/> against <about:blank>
 PASS Parsing: <ftp://example.com%A0/> against <about:blank>
 PASS Parsing: <https://example.com%80/> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any-expected.txt
index b5223c0..943cea0 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any-expected.txt
@@ -264,8 +264,8 @@
 PASS Origin parsing: <wow:%1G> against <about:blank>
 PASS Origin parsing: <wow:￿> against <about:blank>
 FAIL Origin parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
-PASS Origin parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
+PASS Origin parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Origin parsing: <ftp://%e2%98%83> against <about:blank>
 PASS Origin parsing: <https://%e2%98%83> against <about:blank>
 PASS Origin parsing: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any.worker-expected.txt
index b5223c0..943cea0 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/url/url-origin.any.worker-expected.txt
@@ -264,8 +264,8 @@
 PASS Origin parsing: <wow:%1G> against <about:blank>
 PASS Origin parsing: <wow:￿> against <about:blank>
 FAIL Origin parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
-PASS Origin parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
+PASS Origin parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Origin parsing: <ftp://%e2%98%83> against <about:blank>
 PASS Origin parsing: <https://%e2%98%83> against <about:blank>
 PASS Origin parsing: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/webhid/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/webhid/idlharness.https.window-expected.txt
deleted file mode 100644
index 0c5ed838..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/webhid/idlharness.https.window-expected.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-This is a testharness.js-based test.
-Found 64 tests; 63 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Navigator: original interface defined
-PASS Partial interface Navigator: member names are unique
-PASS Partial interface mixin NavigatorID: member names are unique
-PASS Navigator includes NavigatorID: member names are unique
-PASS Navigator includes NavigatorLanguage: member names are unique
-PASS Navigator includes NavigatorOnLine: member names are unique
-PASS Navigator includes NavigatorContentUtils: member names are unique
-PASS Navigator includes NavigatorCookies: member names are unique
-PASS Navigator includes NavigatorPlugins: member names are unique
-PASS Navigator includes NavigatorConcurrentHardware: member names are unique
-PASS HID interface: existence and properties of interface object
-PASS HID interface object length
-PASS HID interface object name
-PASS HID interface: existence and properties of interface prototype object
-PASS HID interface: existence and properties of interface prototype object's "constructor" property
-PASS HID interface: existence and properties of interface prototype object's @@unscopables property
-PASS HID interface: attribute onconnect
-PASS HID interface: attribute ondisconnect
-PASS HID interface: operation getDevices()
-PASS HID interface: operation requestDevice(HIDDeviceRequestOptions)
-PASS HID must be primary interface of navigator.hid
-PASS Stringification of navigator.hid
-PASS HID interface: navigator.hid must inherit property "onconnect" with the proper type
-PASS HID interface: navigator.hid must inherit property "ondisconnect" with the proper type
-PASS HID interface: navigator.hid must inherit property "getDevices()" with the proper type
-PASS HID interface: navigator.hid must inherit property "requestDevice(HIDDeviceRequestOptions)" with the proper type
-PASS HID interface: calling requestDevice(HIDDeviceRequestOptions) on navigator.hid with too few arguments must throw TypeError
-PASS HIDConnectionEvent interface: existence and properties of interface object
-PASS HIDConnectionEvent interface object length
-PASS HIDConnectionEvent interface object name
-PASS HIDConnectionEvent interface: existence and properties of interface prototype object
-PASS HIDConnectionEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS HIDConnectionEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS HIDConnectionEvent interface: attribute device
-PASS HIDInputReportEvent interface: existence and properties of interface object
-FAIL HIDInputReportEvent interface object length assert_equals: wrong value for HIDInputReportEvent.length expected 2 but got 0
-PASS HIDInputReportEvent interface object name
-PASS HIDInputReportEvent interface: existence and properties of interface prototype object
-PASS HIDInputReportEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS HIDInputReportEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS HIDInputReportEvent interface: attribute device
-PASS HIDInputReportEvent interface: attribute reportId
-PASS HIDInputReportEvent interface: attribute data
-PASS HIDDevice interface: existence and properties of interface object
-PASS HIDDevice interface object length
-PASS HIDDevice interface object name
-PASS HIDDevice interface: existence and properties of interface prototype object
-PASS HIDDevice interface: existence and properties of interface prototype object's "constructor" property
-PASS HIDDevice interface: existence and properties of interface prototype object's @@unscopables property
-PASS HIDDevice interface: attribute oninputreport
-PASS HIDDevice interface: attribute opened
-PASS HIDDevice interface: attribute vendorId
-PASS HIDDevice interface: attribute productId
-PASS HIDDevice interface: attribute productName
-PASS HIDDevice interface: attribute collections
-PASS HIDDevice interface: operation open()
-PASS HIDDevice interface: operation close()
-PASS HIDDevice interface: operation sendReport(octet, BufferSource)
-PASS HIDDevice interface: operation sendFeatureReport(octet, BufferSource)
-PASS HIDDevice interface: operation receiveFeatureReport(octet)
-PASS Navigator interface: attribute hid
-PASS Navigator interface: navigator must inherit property "hid" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/css/css-pseudo/idlharness-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/css/css-pseudo/idlharness-expected.txt
new file mode 100644
index 0000000..f76169b
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/css/css-pseudo/idlharness-expected.txt
@@ -0,0 +1,29 @@
+This is a testharness.js-based test.
+FAIL idl_test setup promise_test: Unhandled rejection with value: object "TypeError: window.getPseudoElements is not a function"
+PASS idl_test validation
+PASS Partial interface Element: original interface defined
+PASS Partial interface Element: member names are unique
+PASS Element includes ParentNode: member names are unique
+PASS Element includes NonDocumentTypeChildNode: member names are unique
+PASS Element includes ChildNode: member names are unique
+PASS Element includes Slottable: member names are unique
+FAIL CSSPseudoElement interface: existence and properties of interface object assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface object length assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface object name assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: attribute type assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: attribute element assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: attribute parent assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: operation pseudo(CSSOMString) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement must be primary interface of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL Stringification of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "type" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "element" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "parent" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "pseudo(CSSOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: calling pseudo(CSSOMString) on beforeElements.item(0) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL Element interface: operation pseudo(CSSOMString) assert_own_property: interface prototype object missing non-static operation expected property "pseudo" missing
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element-expected.txt
new file mode 100644
index 0000000..314db574
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element-expected.txt
@@ -0,0 +1,752 @@
+This is a testharness.js-based test.
+Found 736 tests; 389 PASS, 347 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Loading data…
+PASS Parsing: <http://example	.
+org> against <http://example.org/foo/bar>
+PASS Parsing: <http://user:pass@foo:21/bar;par?b#c> against <http://example.org/foo/bar>
+PASS Parsing: <https://test:@test> against <about:blank>
+PASS Parsing: <https://:@test> against <about:blank>
+FAIL Parsing: <non-special://test:@test/x> against <about:blank> assert_equals: href expected "non-special://test@test/x" but got "non-special://test:@test/x"
+FAIL Parsing: <non-special://:@test/x> against <about:blank> assert_equals: href expected "non-special://test/x" but got "non-special://:@test/x"
+PASS Parsing: <http:foo.com> against <http://example.org/foo/bar>
+PASS Parsing: <	   :foo.com   
+> against <http://example.org/foo/bar>
+PASS Parsing: < foo.com  > against <http://example.org/foo/bar>
+PASS Parsing: <a:	 foo.com> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:21/ b ? d # e > against <http://example.org/foo/bar>
+PASS Parsing: <lolscheme:x x#x x> against <about:blank>
+PASS Parsing: <http://f:/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:0/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:00000000000000/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:00000000000000000000080/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:b/c> against <http://example.org/foo/bar>
+FAIL Parsing: <http://f: /c> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://f: /c" but got "http://f:%20/c"
+PASS Parsing: <http://f:
+/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:fifty-two/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:999999/c> against <http://example.org/foo/bar>
+FAIL Parsing: <non-special://f:999999/c> against <http://example.org/foo/bar> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://f: 21 / b ? d # e > against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://f: 21 / b ? d # e " but got "http://f:%2021%20/%20b%20?%20d%20#%20e"
+PASS Parsing: <> against <http://example.org/foo/bar>
+PASS Parsing: <  	> against <http://example.org/foo/bar>
+PASS Parsing: <:foo.com/> against <http://example.org/foo/bar>
+PASS Parsing: <:foo.com\> against <http://example.org/foo/bar>
+PASS Parsing: <:> against <http://example.org/foo/bar>
+PASS Parsing: <:a> against <http://example.org/foo/bar>
+PASS Parsing: <:/> against <http://example.org/foo/bar>
+PASS Parsing: <:\> against <http://example.org/foo/bar>
+PASS Parsing: <:#> against <http://example.org/foo/bar>
+PASS Parsing: <#> against <http://example.org/foo/bar>
+PASS Parsing: <#/> against <http://example.org/foo/bar>
+PASS Parsing: <#\> against <http://example.org/foo/bar>
+PASS Parsing: <#;?> against <http://example.org/foo/bar>
+PASS Parsing: <?> against <http://example.org/foo/bar>
+PASS Parsing: </> against <http://example.org/foo/bar>
+PASS Parsing: <:23> against <http://example.org/foo/bar>
+PASS Parsing: </:23> against <http://example.org/foo/bar>
+PASS Parsing: <\x> against <http://example.org/foo/bar>
+PASS Parsing: <\\x\hello> against <http://example.org/foo/bar>
+PASS Parsing: <::> against <http://example.org/foo/bar>
+PASS Parsing: <::23> against <http://example.org/foo/bar>
+FAIL Parsing: <foo://> against <http://example.org/foo/bar> assert_equals: pathname expected "" but got "//"
+PASS Parsing: <http://a:b@c:29/d> against <http://example.org/foo/bar>
+PASS Parsing: <http::@c:29> against <http://example.org/foo/bar>
+PASS Parsing: <http://&a:foo(b]c@d:2/> against <http://example.org/foo/bar>
+PASS Parsing: <http://::@c@d:2> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo.com:b@d/> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo.com/\@> against <http://example.org/foo/bar>
+PASS Parsing: <http:\\foo.com\> against <http://example.org/foo/bar>
+PASS Parsing: <http:\\a\b:c\d@foo.com\> against <http://example.org/foo/bar>
+PASS Parsing: <foo:/> against <http://example.org/foo/bar>
+PASS Parsing: <foo:/bar.com/> against <http://example.org/foo/bar>
+FAIL Parsing: <foo://///////> against <http://example.org/foo/bar> assert_equals: pathname expected "///////" but got "/////////"
+FAIL Parsing: <foo://///////bar.com/> against <http://example.org/foo/bar> assert_equals: pathname expected "///////bar.com/" but got "/////////bar.com/"
+FAIL Parsing: <foo:////://///> against <http://example.org/foo/bar> assert_equals: pathname expected "//://///" but got "////://///"
+PASS Parsing: <c:/foo> against <http://example.org/foo/bar>
+PASS Parsing: <//foo/bar> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo/path;a??e#f#g> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo/abcd?efgh?ijkl> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo/abcd#foo?bar> against <http://example.org/foo/bar>
+PASS Parsing: <[61:24:74]:98> against <http://example.org/foo/bar>
+PASS Parsing: <http:[61:27]/:foo> against <http://example.org/foo/bar>
+FAIL Parsing: <http://[1::2]:3:4> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://[1::2]:3:4" but got "http://[1::2]:3:4/"
+FAIL Parsing: <http://2001::1> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://2001::1" but got "http://2001::1/"
+FAIL Parsing: <http://2001::1]> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://2001::1]" but got "http://2001::1]/"
+FAIL Parsing: <http://2001::1]:80> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://2001::1]:80" but got "http://2001::1]/"
+PASS Parsing: <http://[2001::1]> against <http://example.org/foo/bar>
+PASS Parsing: <http://[::127.0.0.1]> against <http://example.org/foo/bar>
+PASS Parsing: <http://[0:0:0:0:0:0:13.1.68.3]> against <http://example.org/foo/bar>
+PASS Parsing: <http://[2001::1]:80> against <http://example.org/foo/bar>
+PASS Parsing: <http:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ftp:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <https:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <madeupscheme:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <file:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <file://example:1/> against <about:blank>
+PASS Parsing: <file://example:test/> against <about:blank>
+FAIL Parsing: <file://example%/> against <about:blank> assert_equals: failure should set href to input expected "file://example%/" but got "file://example%25/"
+PASS Parsing: <file://[example]/> against <about:blank>
+PASS Parsing: <ftps:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <gopher:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ws:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <wss:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <data:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <javascript:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <mailto:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <http:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ftp:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <https:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <madeupscheme:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ftps:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <gopher:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ws:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <wss:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <data:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <javascript:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <mailto:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: </a/b/c> against <http://example.org/foo/bar>
+PASS Parsing: </a/ /c> against <http://example.org/foo/bar>
+PASS Parsing: </a%2fc> against <http://example.org/foo/bar>
+PASS Parsing: </a/%2f/c> against <http://example.org/foo/bar>
+PASS Parsing: <#β> against <http://example.org/foo/bar>
+PASS Parsing: <data:text/html,test#test> against <http://example.org/foo/bar>
+PASS Parsing: <tel:1234567890> against <http://example.org/foo/bar>
+FAIL Parsing: <ssh://example.com/foo/bar.git> against <http://example.org/> assert_equals: host expected "example.com" but got ""
+FAIL Parsing: <file:c:\foo\bar.html> against <file:///tmp/mock/path> assert_equals: href expected "file:///c:/foo/bar.html" but got "file:///tmp/mock/c:/foo/bar.html"
+FAIL Parsing: <  File:c|////foo\bar.html> against <file:///tmp/mock/path> assert_equals: href expected "file:///c:////foo/bar.html" but got "file:///tmp/mock/c%7C////foo/bar.html"
+FAIL Parsing: <C|/foo/bar> against <file:///tmp/mock/path> assert_equals: href expected "file:///C:/foo/bar" but got "file:///tmp/mock/C%7C/foo/bar"
+FAIL Parsing: </C|\foo\bar> against <file:///tmp/mock/path> assert_equals: href expected "file:///C:/foo/bar" but got "file:///C%7C/foo/bar"
+FAIL Parsing: <//C|/foo/bar> against <file:///tmp/mock/path> assert_equals: href expected "file:///C:/foo/bar" but got "file://c%7C/foo/bar"
+PASS Parsing: <//server/file> against <file:///tmp/mock/path>
+PASS Parsing: <\\server\file> against <file:///tmp/mock/path>
+PASS Parsing: </\server/file> against <file:///tmp/mock/path>
+PASS Parsing: <file:///foo/bar.txt> against <file:///tmp/mock/path>
+PASS Parsing: <file:///home/me> against <file:///tmp/mock/path>
+PASS Parsing: <//> against <file:///tmp/mock/path>
+PASS Parsing: <///> against <file:///tmp/mock/path>
+PASS Parsing: <///test> against <file:///tmp/mock/path>
+PASS Parsing: <file://test> against <file:///tmp/mock/path>
+FAIL Parsing: <file://localhost> against <file:///tmp/mock/path> assert_equals: href expected "file:///" but got "file://localhost/"
+FAIL Parsing: <file://localhost/> against <file:///tmp/mock/path> assert_equals: href expected "file:///" but got "file://localhost/"
+FAIL Parsing: <file://localhost/test> against <file:///tmp/mock/path> assert_equals: href expected "file:///test" but got "file://localhost/test"
+PASS Parsing: <test> against <file:///tmp/mock/path>
+PASS Parsing: <file:test> against <file:///tmp/mock/path>
+PASS Parsing: <http://example.com/././foo> against <about:blank>
+PASS Parsing: <http://example.com/./.foo> against <about:blank>
+PASS Parsing: <http://example.com/foo/.> against <about:blank>
+PASS Parsing: <http://example.com/foo/./> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar/..> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar/../> against <about:blank>
+PASS Parsing: <http://example.com/foo/..bar> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar/../ton> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar/../ton/../../a> against <about:blank>
+PASS Parsing: <http://example.com/foo/../../..> against <about:blank>
+PASS Parsing: <http://example.com/foo/../../../ton> against <about:blank>
+PASS Parsing: <http://example.com/foo/%2e> against <about:blank>
+FAIL Parsing: <http://example.com/foo/%2e%2> against <about:blank> assert_equals: href expected "http://example.com/foo/%2e%2" but got "http://example.com/foo/.%2"
+FAIL Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank> assert_equals: href expected "http://example.com/%2e.bar" but got "http://example.com/..bar"
+PASS Parsing: <http://example.com////../..> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar//../..> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar//..> against <about:blank>
+PASS Parsing: <http://example.com/foo> against <about:blank>
+PASS Parsing: <http://example.com/%20foo> against <about:blank>
+PASS Parsing: <http://example.com/foo%> against <about:blank>
+PASS Parsing: <http://example.com/foo%2> against <about:blank>
+PASS Parsing: <http://example.com/foo%2zbar> against <about:blank>
+PASS Parsing: <http://example.com/foo%2©zbar> against <about:blank>
+FAIL Parsing: <http://example.com/foo%41%7a> against <about:blank> assert_equals: href expected "http://example.com/foo%41%7a" but got "http://example.com/fooAz"
+PASS Parsing: <http://example.com/foo	‘%91> against <about:blank>
+FAIL Parsing: <http://example.com/foo%00%51> against <about:blank> assert_equals: href expected "http://example.com/foo%00%51" but got "http://example.com/foo%00Q"
+PASS Parsing: <http://example.com/(%28:%3A%29)> against <about:blank>
+PASS Parsing: <http://example.com/%3A%3a%3C%3c> against <about:blank>
+PASS Parsing: <http://example.com/foo	bar> against <about:blank>
+PASS Parsing: <http://example.com\\foo\\bar> against <about:blank>
+PASS Parsing: <http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd> against <about:blank>
+PASS Parsing: <http://example.com/@asdf%40> against <about:blank>
+PASS Parsing: <http://example.com/你好你好> against <about:blank>
+PASS Parsing: <http://example.com/‥/foo> against <about:blank>
+PASS Parsing: <http://example.com//foo> against <about:blank>
+PASS Parsing: <http://example.com/‮/foo/‭/bar> against <about:blank>
+PASS Parsing: <http://www.google.com/foo?bar=baz#> against <about:blank>
+PASS Parsing: <http://www.google.com/foo?bar=baz# »> against <about:blank>
+PASS Parsing: <data:test# »> against <about:blank>
+PASS Parsing: <http://www.google.com> against <about:blank>
+PASS Parsing: <http://192.0x00A80001> against <about:blank>
+FAIL Parsing: <http://www/foo%2Ehtml> against <about:blank> assert_equals: href expected "http://www/foo%2Ehtml" but got "http://www/foo.html"
+PASS Parsing: <http://www/foo/%2E/html> against <about:blank>
+PASS Parsing: <http://user:pass@/> against <about:blank>
+PASS Parsing: <http://%25DOMAIN:foobar@foodomain.com/> against <about:blank>
+PASS Parsing: <http:\\www.google.com\foo> against <about:blank>
+PASS Parsing: <http://foo:80/> against <about:blank>
+PASS Parsing: <http://foo:81/> against <about:blank>
+FAIL Parsing: <httpa://foo:80/> against <about:blank> assert_equals: host expected "foo:80" but got ""
+PASS Parsing: <http://foo:-80/> against <about:blank>
+PASS Parsing: <https://foo:443/> against <about:blank>
+PASS Parsing: <https://foo:80/> against <about:blank>
+PASS Parsing: <ftp://foo:21/> against <about:blank>
+PASS Parsing: <ftp://foo:80/> against <about:blank>
+FAIL Parsing: <gopher://foo:70/> against <about:blank> assert_equals: host expected "foo:70" but got ""
+FAIL Parsing: <gopher://foo:443/> against <about:blank> assert_equals: host expected "foo:443" but got ""
+PASS Parsing: <ws://foo:80/> against <about:blank>
+PASS Parsing: <ws://foo:81/> against <about:blank>
+PASS Parsing: <ws://foo:443/> against <about:blank>
+PASS Parsing: <ws://foo:815/> against <about:blank>
+PASS Parsing: <wss://foo:80/> against <about:blank>
+PASS Parsing: <wss://foo:81/> against <about:blank>
+PASS Parsing: <wss://foo:443/> against <about:blank>
+PASS Parsing: <wss://foo:815/> against <about:blank>
+PASS Parsing: <http:/example.com/> against <about:blank>
+PASS Parsing: <ftp:/example.com/> against <about:blank>
+PASS Parsing: <https:/example.com/> against <about:blank>
+PASS Parsing: <madeupscheme:/example.com/> against <about:blank>
+PASS Parsing: <file:/example.com/> against <about:blank>
+PASS Parsing: <ftps:/example.com/> against <about:blank>
+PASS Parsing: <gopher:/example.com/> against <about:blank>
+PASS Parsing: <ws:/example.com/> against <about:blank>
+PASS Parsing: <wss:/example.com/> against <about:blank>
+PASS Parsing: <data:/example.com/> against <about:blank>
+PASS Parsing: <javascript:/example.com/> against <about:blank>
+PASS Parsing: <mailto:/example.com/> against <about:blank>
+PASS Parsing: <http:example.com/> against <about:blank>
+PASS Parsing: <ftp:example.com/> against <about:blank>
+PASS Parsing: <https:example.com/> against <about:blank>
+PASS Parsing: <madeupscheme:example.com/> against <about:blank>
+PASS Parsing: <ftps:example.com/> against <about:blank>
+PASS Parsing: <gopher:example.com/> against <about:blank>
+PASS Parsing: <ws:example.com/> against <about:blank>
+PASS Parsing: <wss:example.com/> against <about:blank>
+PASS Parsing: <data:example.com/> against <about:blank>
+PASS Parsing: <javascript:example.com/> against <about:blank>
+PASS Parsing: <mailto:example.com/> against <about:blank>
+PASS Parsing: <http:@www.example.com> against <about:blank>
+PASS Parsing: <http:/@www.example.com> against <about:blank>
+PASS Parsing: <http://@www.example.com> against <about:blank>
+PASS Parsing: <http:a:b@www.example.com> against <about:blank>
+PASS Parsing: <http:/a:b@www.example.com> against <about:blank>
+PASS Parsing: <http://a:b@www.example.com> against <about:blank>
+PASS Parsing: <http://@pple.com> against <about:blank>
+PASS Parsing: <http::b@www.example.com> against <about:blank>
+PASS Parsing: <http:/:b@www.example.com> against <about:blank>
+PASS Parsing: <http://:b@www.example.com> against <about:blank>
+FAIL Parsing: <http:/:@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:/:@/www.example.com" but got "http:///www.example.com"
+PASS Parsing: <http://user@/www.example.com> against <about:blank>
+FAIL Parsing: <http:@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:@/www.example.com" but got "http:///www.example.com"
+FAIL Parsing: <http:/@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:/@/www.example.com" but got "http:///www.example.com"
+FAIL Parsing: <http://@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http://@/www.example.com" but got "http:///www.example.com"
+FAIL Parsing: <https:@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "https:@/www.example.com" but got "https:///www.example.com"
+FAIL Parsing: <http:a:b@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:a:b@/www.example.com" but got "http://a:b@/www.example.com"
+FAIL Parsing: <http:/a:b@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:/a:b@/www.example.com" but got "http://a:b@/www.example.com"
+PASS Parsing: <http://a:b@/www.example.com> against <about:blank>
+FAIL Parsing: <http::@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http::@/www.example.com" but got "http:///www.example.com"
+PASS Parsing: <http:a:@www.example.com> against <about:blank>
+PASS Parsing: <http:/a:@www.example.com> against <about:blank>
+PASS Parsing: <http://a:@www.example.com> against <about:blank>
+PASS Parsing: <http://www.@pple.com> against <about:blank>
+FAIL Parsing: <http:@:www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:@:www.example.com" but got "http://:www.example.com/"
+FAIL Parsing: <http:/@:www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:/@:www.example.com" but got "http://:www.example.com/"
+FAIL Parsing: <http://@:www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http://@:www.example.com" but got "http://:www.example.com/"
+PASS Parsing: <http://:@www.example.com> against <about:blank>
+PASS Parsing: </> against <http://www.example.com/test>
+PASS Parsing: </test.txt> against <http://www.example.com/test>
+PASS Parsing: <.> against <http://www.example.com/test>
+PASS Parsing: <..> against <http://www.example.com/test>
+PASS Parsing: <test.txt> against <http://www.example.com/test>
+PASS Parsing: <./test.txt> against <http://www.example.com/test>
+PASS Parsing: <../test.txt> against <http://www.example.com/test>
+PASS Parsing: <../aaa/test.txt> against <http://www.example.com/test>
+PASS Parsing: <../../test.txt> against <http://www.example.com/test>
+PASS Parsing: <中/test.txt> against <http://www.example.com/test>
+PASS Parsing: <http://www.example2.com> against <http://www.example.com/test>
+PASS Parsing: <//www.example2.com> against <http://www.example.com/test>
+PASS Parsing: <file:...> against <http://www.example.com/test>
+PASS Parsing: <file:..> against <http://www.example.com/test>
+PASS Parsing: <file:a> against <http://www.example.com/test>
+PASS Parsing: <http://ExAmPlE.CoM> against <http://other.com/>
+FAIL Parsing: <http://example example.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://Goo%20 goo%7C|.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://[]> against <http://other.com/> assert_equals: failure should set href to input expected "http://[]" but got "http://[]/"
+FAIL Parsing: <http://[:]> against <http://other.com/> assert_equals: failure should set href to input expected "http://[:]" but got "http://[:]/"
+FAIL Parsing: <http://GOO  goo.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://GOO​⁠goo.com> against <http://other.com/>
+PASS Parsing: <\0 http://example.com/ \r > against <about:blank>
+PASS Parsing: <http://www.foo。bar.com> against <http://other.com/>
+FAIL Parsing: <http://﷐zyx.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://﷐zyx.com" but got "http://%EF%BF%BDzyx.com/"
+FAIL Parsing: <http://%ef%b7%90zyx.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://%ef%b7%90zyx.com" but got "http://%EF%BF%BDzyx.com/"
+FAIL Parsing: <https://�> against <about:blank> assert_equals: failure should set href to input expected "https://\ufffd" but got "https://%EF%BF%BD/"
+FAIL Parsing: <https://%EF%BF%BD> against <about:blank> assert_equals: failure should set href to input expected "https://%EF%BF%BD" but got "https://%EF%BF%BD/"
+PASS Parsing: <https://x/�?�#�> against <about:blank>
+FAIL Parsing: <http://a.b.c.xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a.b.c.XN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a.b.c.Xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.XN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.xN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://Go.com> against <http://other.com/>
+FAIL Parsing: <http://%41.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://%ef%bc%85%ef%bc%94%ef%bc%91.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://%00.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://%00.com" but got "http://%00.com/"
+FAIL Parsing: <http://%ef%bc%85%ef%bc%90%ef%bc%90.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://%ef%bc%85%ef%bc%90%ef%bc%90.com" but got "http://%00.com/"
+PASS Parsing: <http://你好你好> against <http://other.com/>
+FAIL Parsing: <https://faß.ExAmPlE/> against <about:blank> assert_equals: href expected "https://xn--fa-hia.example/" but got "https://fass.example/"
+FAIL Parsing: <sc://faß.ExAmPlE/> against <about:blank> assert_equals: host expected "fa%C3%9F.ExAmPlE" but got ""
+FAIL Parsing: <http://%zz%66%a.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://%zz%66%a.com" but got "http://%25zzf%25a.com/"
+FAIL Parsing: <http://%25> against <http://other.com/> assert_equals: failure should set href to input expected "http://%25" but got "http://%25/"
+FAIL Parsing: <http://hello%00> against <http://other.com/> assert_equals: failure should set href to input expected "http://hello%00" but got "http://hello%00/"
+PASS Parsing: <http://%30%78%63%30%2e%30%32%35%30.01> against <http://other.com/>
+PASS Parsing: <http://%30%78%63%30%2e%30%32%35%30.01%2e> against <http://other.com/>
+FAIL Parsing: <http://192.168.0.257> against <http://other.com/> assert_equals: failure should set href to input expected "http://192.168.0.257" but got "http://192.168.0.257/"
+FAIL Parsing: <http://%3g%78%63%30%2e%30%32%35%30%2E.01> against <http://other.com/> assert_equals: failure should set href to input expected "http://%3g%78%63%30%2e%30%32%35%30%2E.01" but got "http://%253gxc0.0250..01/"
+FAIL Parsing: <http://192.168.0.1 hello> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <https://x x:12> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://0Xc0.0250.01> against <http://other.com/>
+PASS Parsing: <http://./> against <about:blank>
+PASS Parsing: <http://../> against <about:blank>
+PASS Parsing: <http://[www.google.com]/> against <about:blank>
+FAIL Parsing: <http://[google.com]> against <http://other.com/> assert_equals: failure should set href to input expected "http://[google.com]" but got "http://[google.com]/"
+FAIL Parsing: <http://[::1.2.3.4x]> against <http://other.com/> assert_equals: failure should set href to input expected "http://[::1.2.3.4x]" but got "http://[::1.2.3.4x]/"
+FAIL Parsing: <http://[::1.2.3.]> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://[::1.2.]> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://[::1.]> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://foo:💩@example.com/bar> against <http://other.com/>
+PASS Parsing: <#> against <test:test>
+PASS Parsing: <#x> against <mailto:x@x.com>
+FAIL Parsing: <#x> against <data:,> assert_equals: href expected "data:,#x" but got "mailto:x@x.com#x"
+PASS Parsing: <#x> against <about:blank>
+PASS Parsing: <#> against <test:test?test>
+PASS Parsing: <https://@test@test@example:800/> against <http://doesnotmatter/>
+PASS Parsing: <https://@@@example> against <http://doesnotmatter/>
+PASS Parsing: <http://`{}:`{}@h/`{}?`{}> against <http://doesnotmatter/>
+PASS Parsing: <http://host/?'> against <about:blank>
+FAIL Parsing: <notspecial://host/?'> against <about:blank> assert_equals: href expected "notspecial://host/?'" but got "notspecial://host/?%27"
+PASS Parsing: </some/path> against <http://user@example.org/smth>
+PASS Parsing: <> against <http://user:pass@example.org:21/smth>
+PASS Parsing: </some/path> against <http://user:pass@example.org:21/smth>
+FAIL Parsing: <i> against <sc:sd> assert_equals: failure should set href to input expected "i" but got ""
+FAIL Parsing: <i> against <sc:sd/sd> assert_equals: failure should set href to input expected "i" but got ""
+PASS Parsing: <i> against <sc:/pa/pa>
+FAIL Parsing: <i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: <i> against <sc:///pa/pa> assert_equals: pathname expected "/pa/i" but got "///pa/i"
+FAIL Parsing: <../i> against <sc:sd> assert_equals: failure should set href to input expected "../i" but got ""
+FAIL Parsing: <../i> against <sc:sd/sd> assert_equals: failure should set href to input expected "../i" but got ""
+PASS Parsing: <../i> against <sc:/pa/pa>
+FAIL Parsing: <../i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: <../i> against <sc:///pa/pa> assert_equals: href expected "sc:///i" but got "sc:///pa/i"
+FAIL Parsing: </i> against <sc:sd> assert_equals: failure should set href to input expected "/i" but got ""
+FAIL Parsing: </i> against <sc:sd/sd> assert_equals: failure should set href to input expected "/i" but got ""
+PASS Parsing: </i> against <sc:/pa/pa>
+FAIL Parsing: </i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: </i> against <sc:///pa/pa> assert_equals: href expected "sc:///i" but got "sc:///pa/i"
+FAIL Parsing: <?i> against <sc:sd> assert_equals: failure should set href to input expected "?i" but got ""
+FAIL Parsing: <?i> against <sc:sd/sd> assert_equals: failure should set href to input expected "?i" but got ""
+PASS Parsing: <?i> against <sc:/pa/pa>
+FAIL Parsing: <?i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: <?i> against <sc:///pa/pa> assert_equals: pathname expected "/pa/pa" but got "///pa/pa"
+PASS Parsing: <#i> against <sc:sd>
+PASS Parsing: <#i> against <sc:sd/sd>
+PASS Parsing: <#i> against <sc:/pa/pa>
+FAIL Parsing: <#i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: <#i> against <sc:///pa/pa> assert_equals: pathname expected "/pa/pa" but got "///pa/pa"
+FAIL Parsing: <about:/../> against <about:blank> assert_equals: href expected "about:/" but got "about:/../"
+FAIL Parsing: <data:/../> against <about:blank> assert_equals: href expected "data:/" but got "data:/../"
+FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
+FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
+FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
+FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
+FAIL Parsing: <sc://@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://te@s:t@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://:/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://:12/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1/x" but got "sc://%C3%B1"
+PASS Parsing: <sc:\../> against <about:blank>
+PASS Parsing: <sc::a@example.net> against <about:blank>
+PASS Parsing: <wow:%NBD> against <about:blank>
+PASS Parsing: <wow:%1G> against <about:blank>
+FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
+FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: href expected "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF" but got "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD"
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <foo://ho
+st/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <http://a\0b/> against <about:blank> assert_equals: failure should set href to input expected "http://a\0b/" but got "http://a%00b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x01b/" but got "http://a%01b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x02b/" but got "http://a%02b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x03b/" but got "http://a%03b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x04b/" but got "http://a%04b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x05b/" but got "http://a%05b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x06b/" but got "http://a%06b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x07b/" but got "http://a%07b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\bb/" but got "http://a%08b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\vb/" but got "http://a%0Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\fb/" but got "http://a%0Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0eb/" but got "http://a%0Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0fb/" but got "http://a%0Fb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x10b/" but got "http://a%10b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x11b/" but got "http://a%11b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x12b/" but got "http://a%12b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x13b/" but got "http://a%13b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x14b/" but got "http://a%14b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x15b/" but got "http://a%15b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x16b/" but got "http://a%16b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x17b/" but got "http://a%17b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x18b/" but got "http://a%18b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x19b/" but got "http://a%19b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1ab/" but got "http://a%1Ab/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1bb/" but got "http://a%1Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1cb/" but got "http://a%1Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1db/" but got "http://a%1Db/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1eb/" but got "http://a%1Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1fb/" but got "http://a%1Fb/"
+FAIL Parsing: <http://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a%b/> against <about:blank> assert_equals: failure should set href to input expected "http://a%b/" but got "http://a%25b/"
+FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
+FAIL Parsing: <http://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://ab/" but got "http://a%7Fb/"
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
+PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> assert_equals: href expected "http://ho\x01st/" but got "http://ho%01st/"
+FAIL Parsing: <http://ho%02st/> against <about:blank> assert_equals: href expected "http://ho\x02st/" but got "http://ho%02st/"
+FAIL Parsing: <http://ho%03st/> against <about:blank> assert_equals: href expected "http://ho\x03st/" but got "http://ho%03st/"
+FAIL Parsing: <http://ho%04st/> against <about:blank> assert_equals: href expected "http://ho\x04st/" but got "http://ho%04st/"
+FAIL Parsing: <http://ho%05st/> against <about:blank> assert_equals: href expected "http://ho\x05st/" but got "http://ho%05st/"
+FAIL Parsing: <http://ho%06st/> against <about:blank> assert_equals: href expected "http://ho\x06st/" but got "http://ho%06st/"
+FAIL Parsing: <http://ho%07st/> against <about:blank> assert_equals: href expected "http://ho\x07st/" but got "http://ho%07st/"
+FAIL Parsing: <http://ho%08st/> against <about:blank> assert_equals: href expected "http://ho\bst/" but got "http://ho%08st/"
+PASS Parsing: <http://ho%09st/> against <about:blank>
+PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> assert_equals: href expected "http://ho\vst/" but got "http://ho%0Bst/"
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> assert_equals: href expected "http://ho\fst/" but got "http://ho%0Cst/"
+PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> assert_equals: href expected "http://ho\x0est/" but got "http://ho%0Est/"
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> assert_equals: href expected "http://ho\x0fst/" but got "http://ho%0Fst/"
+FAIL Parsing: <http://ho%10st/> against <about:blank> assert_equals: href expected "http://ho\x10st/" but got "http://ho%10st/"
+FAIL Parsing: <http://ho%11st/> against <about:blank> assert_equals: href expected "http://ho\x11st/" but got "http://ho%11st/"
+FAIL Parsing: <http://ho%12st/> against <about:blank> assert_equals: href expected "http://ho\x12st/" but got "http://ho%12st/"
+FAIL Parsing: <http://ho%13st/> against <about:blank> assert_equals: href expected "http://ho\x13st/" but got "http://ho%13st/"
+FAIL Parsing: <http://ho%14st/> against <about:blank> assert_equals: href expected "http://ho\x14st/" but got "http://ho%14st/"
+FAIL Parsing: <http://ho%15st/> against <about:blank> assert_equals: href expected "http://ho\x15st/" but got "http://ho%15st/"
+FAIL Parsing: <http://ho%16st/> against <about:blank> assert_equals: href expected "http://ho\x16st/" but got "http://ho%16st/"
+FAIL Parsing: <http://ho%17st/> against <about:blank> assert_equals: href expected "http://ho\x17st/" but got "http://ho%17st/"
+FAIL Parsing: <http://ho%18st/> against <about:blank> assert_equals: href expected "http://ho\x18st/" but got "http://ho%18st/"
+FAIL Parsing: <http://ho%19st/> against <about:blank> assert_equals: href expected "http://ho\x19st/" but got "http://ho%19st/"
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> assert_equals: href expected "http://ho\x1ast/" but got "http://ho%1Ast/"
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> assert_equals: href expected "http://ho\x1bst/" but got "http://ho%1Bst/"
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> assert_equals: href expected "http://ho\x1cst/" but got "http://ho%1Cst/"
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> assert_equals: href expected "http://ho\x1dst/" but got "http://ho%1Dst/"
+FAIL Parsing: <http://ho%1Est/> against <about:blank> assert_equals: href expected "http://ho\x1est/" but got "http://ho%1Est/"
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> assert_equals: href expected "http://ho\x1fst/" but got "http://ho%1Fst/"
+FAIL Parsing: <http://ho%20st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ho%23st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%25st/> against <about:blank>
+PASS Parsing: <http://ho%2Fst/> against <about:blank>
+FAIL Parsing: <http://ho%3Ast/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%3Ast/" but got "http://ho:st/"
+FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ho%3Est/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%3Fst/> against <about:blank>
+FAIL Parsing: <http://ho%40st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ho%5Bst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Bst/" but got "http://ho[st/"
+PASS Parsing: <http://ho%5Cst/> against <about:blank>
+FAIL Parsing: <http://ho%5Dst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Dst/" but got "http://ho]st/"
+FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> assert_equals: href expected "http://host/" but got "http://ho%7Fst/"
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <ftp://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%80/" but got "ftp://example.com%EF%BF%BD/"
+FAIL Parsing: <ftp://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%A0/" but got "ftp://example.com%EF%BF%BD/"
+FAIL Parsing: <https://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%80/" but got "https://example.com%EF%BF%BD/"
+FAIL Parsing: <https://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%A0/" but got "https://example.com%EF%BF%BD/"
+PASS Parsing: <ftp://%e2%98%83> against <about:blank>
+PASS Parsing: <https://%e2%98%83> against <about:blank>
+PASS Parsing: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
+PASS Parsing: <http://facebook.com/?foo=%7B%22abc%22> against <about:blank>
+PASS Parsing: <https://localhost:3000/jqueryui@1.2.3> against <about:blank>
+PASS Parsing: <h	t
+t\rp://h	o
+s\rt:9	0
+0\r0/p	a
+t\rh?q	u
+e\rry#f	r
+a\rg> against <about:blank>
+PASS Parsing: <?a=b&c=d> against <http://example.org/foo/bar>
+PASS Parsing: <??a=b&c=d> against <http://example.org/foo/bar>
+PASS Parsing: <http:> against <http://example.org/foo/bar>
+PASS Parsing: <http:> against <https://example.org/foo/bar>
+PASS Parsing: <sc:> against <https://example.org/foo/bar>
+PASS Parsing: <http://foo.bar/baz?qux#foobar> against <about:blank>
+PASS Parsing: <http://foo.bar/baz?qux#foo"bar> against <about:blank>
+PASS Parsing: <http://foo.bar/baz?qux#foo<bar> against <about:blank>
+PASS Parsing: <http://foo.bar/baz?qux#foo>bar> against <about:blank>
+PASS Parsing: <http://foo.bar/baz?qux#foo`bar> against <about:blank>
+PASS Parsing: <http://1.2.3.4/> against <http://other.com/>
+PASS Parsing: <http://1.2.3.4./> against <http://other.com/>
+PASS Parsing: <http://192.168.257> against <http://other.com/>
+PASS Parsing: <http://192.168.257.> against <http://other.com/>
+PASS Parsing: <http://192.168.257.com> against <http://other.com/>
+PASS Parsing: <http://256> against <http://other.com/>
+PASS Parsing: <http://256.com> against <http://other.com/>
+PASS Parsing: <http://999999999> against <http://other.com/>
+PASS Parsing: <http://999999999.> against <http://other.com/>
+PASS Parsing: <http://999999999.com> against <http://other.com/>
+FAIL Parsing: <http://10000000000> against <http://other.com/> assert_equals: failure should set href to input expected "http://10000000000" but got "http://10000000000/"
+PASS Parsing: <http://10000000000.com> against <http://other.com/>
+PASS Parsing: <http://4294967295> against <http://other.com/>
+FAIL Parsing: <http://4294967296> against <http://other.com/> assert_equals: failure should set href to input expected "http://4294967296" but got "http://4294967296/"
+PASS Parsing: <http://0xffffffff> against <http://other.com/>
+FAIL Parsing: <http://0xffffffff1> against <http://other.com/> assert_equals: failure should set href to input expected "http://0xffffffff1" but got "http://0xffffffff1/"
+FAIL Parsing: <http://256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256" but got "http://256.256.256.256/"
+PASS Parsing: <https://0x.0x.0> against <about:blank>
+PASS Parsing: <https://0x100000000/test> against <about:blank>
+PASS Parsing: <https://256.0.0.1/test> against <about:blank>
+PASS Parsing: <file:///C%3A/> against <about:blank>
+PASS Parsing: <file:///C%7C/> against <about:blank>
+FAIL Parsing: <file://%43%3A> against <about:blank> assert_equals: failure should set href to input expected "file://%43%3A" but got "file://c:/"
+FAIL Parsing: <file://%43%7C> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <file://%43|> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <file://C%7C> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <file://%43%7C/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <https://%43%7C/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <asdf://%43|/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <asdf://%43%7C/> against <about:blank> assert_equals: host expected "%43%7C" but got ""
+PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
+FAIL Parsing: <..> against <file:///C:/> assert_equals: href expected "file:///C:/" but got "file:///"
+PASS Parsing: <..> against <file:///>
+FAIL Parsing: </> against <file:///C:/a/b> assert_equals: href expected "file:///C:/" but got "file:///"
+FAIL Parsing: </> against <file://h/C:/a/b> assert_equals: href expected "file://h/C:/" but got "file://h/"
+PASS Parsing: </> against <file://h/a/b>
+FAIL Parsing: <//d:> against <file:///C:/a/b> assert_equals: href expected "file:///d:" but got "file://d:/"
+FAIL Parsing: <//d:/..> against <file:///C:/a/b> assert_equals: href expected "file:///d:/" but got "file://d:/"
+PASS Parsing: <..> against <file:///ab:/>
+PASS Parsing: <..> against <file:///1:/>
+PASS Parsing: <> against <file:///test?test#test>
+PASS Parsing: <file:> against <file:///test?test#test>
+PASS Parsing: <?x> against <file:///test?test#test>
+PASS Parsing: <file:?x> against <file:///test?test#test>
+PASS Parsing: <#x> against <file:///test?test#test>
+PASS Parsing: <file:#x> against <file:///test?test#test>
+FAIL Parsing: <file:\\//> against <about:blank> assert_equals: href expected "file:////" but got "file:///"
+FAIL Parsing: <file:\\\\> against <about:blank> assert_equals: href expected "file:////" but got "file:///"
+FAIL Parsing: <file:\\\\?fox> against <about:blank> assert_equals: href expected "file:////?fox" but got "file:///?fox"
+FAIL Parsing: <file:\\\\#guppy> against <about:blank> assert_equals: href expected "file:////#guppy" but got "file:///#guppy"
+PASS Parsing: <file://spider///> against <about:blank>
+FAIL Parsing: <file:\\localhost//> against <about:blank> assert_equals: href expected "file:////" but got "file://localhost//"
+PASS Parsing: <file:///localhost//cat> against <about:blank>
+FAIL Parsing: <file://\/localhost//cat> against <about:blank> assert_equals: href expected "file:////localhost//cat" but got "file:///localhost//cat"
+FAIL Parsing: <file://localhost//a//../..//> against <about:blank> assert_equals: href expected "file://///" but got "file://localhost///"
+FAIL Parsing: </////mouse> against <file:///elephant> assert_equals: href expected "file://///mouse" but got "file:///mouse"
+PASS Parsing: <\//pig> against <file://lion/>
+FAIL Parsing: <\/localhost//pig> against <file://lion/> assert_equals: href expected "file:////pig" but got "file://localhost//pig"
+FAIL Parsing: <//localhost//pig> against <file://lion/> assert_equals: href expected "file:////pig" but got "file://localhost//pig"
+PASS Parsing: </..//localhost//pig> against <file://lion/>
+PASS Parsing: <file://> against <file://ape/>
+PASS Parsing: </rooibos> against <file://tea/>
+PASS Parsing: </?chai> against <file://tea/>
+FAIL Parsing: <C|> against <file://host/dir/file> assert_equals: href expected "file://host/C:" but got "file://host/dir/C%7C"
+FAIL Parsing: <C|> against <file://host/D:/dir1/dir2/file> assert_equals: href expected "file://host/C:" but got "file://host/D:/dir1/dir2/C%7C"
+FAIL Parsing: <C|#> against <file://host/dir/file> assert_equals: href expected "file://host/C:#" but got "file://host/dir/C%7C#"
+FAIL Parsing: <C|?> against <file://host/dir/file> assert_equals: href expected "file://host/C:?" but got "file://host/dir/C%7C?"
+FAIL Parsing: <C|/> against <file://host/dir/file> assert_equals: href expected "file://host/C:/" but got "file://host/dir/C%7C/"
+FAIL Parsing: <C|
+/> against <file://host/dir/file> assert_equals: href expected "file://host/C:/" but got "file://host/dir/C%7C/"
+FAIL Parsing: <C|\> against <file://host/dir/file> assert_equals: href expected "file://host/C:/" but got "file://host/dir/C%7C/"
+PASS Parsing: <C> against <file://host/dir/file>
+FAIL Parsing: <C|a> against <file://host/dir/file> assert_equals: href expected "file://host/dir/C|a" but got "file://host/dir/C%7Ca"
+PASS Parsing: </c:/foo/bar> against <file:///c:/baz/qux>
+FAIL Parsing: </c|/foo/bar> against <file:///c:/baz/qux> assert_equals: href expected "file:///c:/foo/bar" but got "file:///c%7C/foo/bar"
+PASS Parsing: <file:\c:\foo\bar> against <file:///c:/baz/qux>
+PASS Parsing: </c:/foo/bar> against <file://host/path>
+PASS Parsing: <file://example.net/C:/> against <about:blank>
+PASS Parsing: <file://1.2.3.4/C:/> against <about:blank>
+PASS Parsing: <file://[1::8]/C:/> against <about:blank>
+FAIL Parsing: <C|/> against <file://host/> assert_equals: href expected "file://host/C:/" but got "file://host/C%7C/"
+PASS Parsing: </C:/> against <file://host/>
+PASS Parsing: <file:C:/> against <file://host/>
+PASS Parsing: <file:/C:/> against <file://host/>
+FAIL Parsing: <//C:/> against <file://host/> assert_equals: href expected "file:///C:/" but got "file://c:/"
+FAIL Parsing: <file://C:/> against <file://host/> assert_equals: href expected "file:///C:/" but got "file://c:/"
+PASS Parsing: <///C:/> against <file://host/>
+PASS Parsing: <file:///C:/> against <file://host/>
+FAIL Parsing: <file:/C|/> against <about:blank> assert_equals: href expected "file:///C:/" but got "file:///C%7C/"
+FAIL Parsing: <file://C|/> against <about:blank> assert_equals: href expected "file:///C:/" but got "file://c%7C/"
+PASS Parsing: <file:> against <about:blank>
+PASS Parsing: <file:?q=v> against <about:blank>
+PASS Parsing: <file:#frag> against <about:blank>
+PASS Parsing: <file:///Y:> against <about:blank>
+PASS Parsing: <file:///Y:/> against <about:blank>
+PASS Parsing: <file:///./Y> against <about:blank>
+PASS Parsing: <file:///./Y:> against <about:blank>
+FAIL Parsing: <\\\.\Y:> against <about:blank> assert_equals: failure should set href to input expected "\\\\\\.\\Y:" but got ""
+PASS Parsing: <file:///y:> against <about:blank>
+PASS Parsing: <file:///y:/> against <about:blank>
+PASS Parsing: <file:///./y> against <about:blank>
+PASS Parsing: <file:///./y:> against <about:blank>
+FAIL Parsing: <\\\.\y:> against <about:blank> assert_equals: failure should set href to input expected "\\\\\\.\\y:" but got ""
+FAIL Parsing: <file://localhost//a//../..//foo> against <about:blank> assert_equals: href expected "file://///foo" but got "file://localhost///foo"
+FAIL Parsing: <file://localhost////foo> against <about:blank> assert_equals: href expected "file://////foo" but got "file://localhost////foo"
+FAIL Parsing: <file:////foo> against <about:blank> assert_equals: href expected "file:////foo" but got "file:///foo"
+PASS Parsing: <file:///one/two> against <file:///>
+FAIL Parsing: <file:////one/two> against <file:///> assert_equals: href expected "file:////one/two" but got "file:///one/two"
+PASS Parsing: <//one/two> against <file:///>
+PASS Parsing: <///one/two> against <file:///>
+FAIL Parsing: <////one/two> against <file:///> assert_equals: href expected "file:////one/two" but got "file:///one/two"
+PASS Parsing: <file:///.//> against <file:////>
+PASS Parsing: <file:.//p> against <about:blank>
+PASS Parsing: <file:/.//p> against <about:blank>
+PASS Parsing: <http://[1:0::]> against <http://example.net/>
+FAIL Parsing: <http://[0:1:2:3:4:5:6:7:8]> against <http://example.net/> assert_equals: failure should set href to input expected "http://[0:1:2:3:4:5:6:7:8]" but got "http://[0:1:2:3:4:5:6:7:8]/"
+FAIL Parsing: <https://[0::0::0]> against <about:blank> assert_equals: failure should set href to input expected "https://[0::0::0]" but got "https://[0::0::0]/"
+FAIL Parsing: <https://[0:.0]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:.0]" but got "https://[0:.0]/"
+FAIL Parsing: <https://[0:0:]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:0:]" but got "https://[0:0:]/"
+FAIL Parsing: <https://[0:1:2:3:4:5:6:7.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:1:2:3:4:5:6:7.0.0.0.1]" but got "https://[0:1:2:3:4:5:6:7.0.0.0.1]/"
+FAIL Parsing: <https://[0:1.00.0.0.0]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:1.00.0.0.0]" but got "https://[0:1.00.0.0.0]/"
+FAIL Parsing: <https://[0:1.290.0.0.0]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:1.290.0.0.0]" but got "https://[0:1.290.0.0.0]/"
+FAIL Parsing: <https://[0:1.23.23]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:1.23.23]" but got "https://[0:1.23.23]/"
+FAIL Parsing: <http://?> against <about:blank> assert_equals: failure should set href to input expected "http://?" but got "http:/?"
+FAIL Parsing: <http://#> against <about:blank> assert_equals: failure should set href to input expected "http://#" but got "http:/#"
+PASS Parsing: <http://f:4294967377/c> against <http://example.org/>
+PASS Parsing: <http://f:18446744073709551697/c> against <http://example.org/>
+PASS Parsing: <http://f:340282366920938463463374607431768211537/c> against <http://example.org/>
+FAIL Parsing: <sc://ñ> against <about:blank> assert_equals: host expected "%C3%B1" but got ""
+FAIL Parsing: <sc://ñ?x> against <about:blank> assert_equals: host expected "%C3%B1" but got ""
+FAIL Parsing: <sc://ñ#x> against <about:blank> assert_equals: host expected "%C3%B1" but got ""
+FAIL Parsing: <#x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1#x" but got "sc://%C3%B1"
+FAIL Parsing: <?x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1?x" but got "sc://%C3%B1"
+FAIL Parsing: <sc://?> against <about:blank> assert_equals: pathname expected "" but got "//"
+FAIL Parsing: <sc://#> against <about:blank> assert_equals: pathname expected "" but got "//"
+FAIL Parsing: <///> against <sc://x/> assert_equals: href expected "sc:///" but got "sc:"
+FAIL Parsing: <////> against <sc://x/> assert_equals: href expected "sc:////" but got "sc:"
+FAIL Parsing: <////x/> against <sc://x/> assert_equals: href expected "sc:////x/" but got "sc://x/"
+FAIL Parsing: <tftp://foobar.com/someconfig;mode=netascii> against <about:blank> assert_equals: host expected "foobar.com" but got ""
+FAIL Parsing: <telnet://user:pass@foobar.com:23/> against <about:blank> assert_equals: username expected "user" but got ""
+FAIL Parsing: <ut2004://10.10.10.10:7777/Index.ut2> against <about:blank> assert_equals: host expected "10.10.10.10:7777" but got ""
+FAIL Parsing: <redis://foo:bar@somehost:6379/0?baz=bam&qux=baz> against <about:blank> assert_equals: username expected "foo" but got ""
+FAIL Parsing: <rsync://foo@host:911/sup> against <about:blank> assert_equals: username expected "foo" but got ""
+FAIL Parsing: <git://github.com/foo/bar.git> against <about:blank> assert_equals: host expected "github.com" but got ""
+FAIL Parsing: <irc://myserver.com:6999/channel?passwd> against <about:blank> assert_equals: host expected "myserver.com:6999" but got ""
+FAIL Parsing: <dns://fw.example.org:9999/foo.bar.org?type=TXT> against <about:blank> assert_equals: host expected "fw.example.org:9999" but got ""
+FAIL Parsing: <ldap://localhost:389/ou=People,o=JNDITutorial> against <about:blank> assert_equals: host expected "localhost:389" but got ""
+FAIL Parsing: <git+https://github.com/foo/bar> against <about:blank> assert_equals: host expected "github.com" but got ""
+PASS Parsing: <urn:ietf:rfc:2648> against <about:blank>
+PASS Parsing: <tag:joe@example.org,2001:foo/bar> against <about:blank>
+FAIL Parsing: <non-spec:/.//> against <about:blank> assert_equals: pathname expected "//" but got "/.//"
+FAIL Parsing: <non-spec:/..//> against <about:blank> assert_equals: href expected "non-spec:/.//" but got "non-spec:/..//"
+FAIL Parsing: <non-spec:/a/..//> against <about:blank> assert_equals: href expected "non-spec:/.//" but got "non-spec:/a/..//"
+FAIL Parsing: <non-spec:/.//path> against <about:blank> assert_equals: pathname expected "//path" but got "/.//path"
+FAIL Parsing: <non-spec:/..//path> against <about:blank> assert_equals: href expected "non-spec:/.//path" but got "non-spec:/..//path"
+FAIL Parsing: <non-spec:/a/..//path> against <about:blank> assert_equals: href expected "non-spec:/.//path" but got "non-spec:/a/..//path"
+FAIL Parsing: </.//path> against <non-spec:/p> assert_equals: href expected "non-spec:/.//path" but got "non-spec://path"
+FAIL Parsing: </..//path> against <non-spec:/p> assert_equals: href expected "non-spec:/.//path" but got "non-spec://path"
+FAIL Parsing: <..//path> against <non-spec:/p> assert_equals: href expected "non-spec:/.//path" but got "non-spec://path"
+FAIL Parsing: <a/..//path> against <non-spec:/p> assert_equals: href expected "non-spec:/.//path" but got "non-spec://path"
+FAIL Parsing: <> against <non-spec:/..//p> assert_equals: href expected "non-spec:/.//p" but got "non-spec:/..//p"
+FAIL Parsing: <path> against <non-spec:/..//p> assert_equals: href expected "non-spec:/.//path" but got "non-spec:/..//path"
+FAIL Parsing: <../path> against <non-spec:/.//p> assert_equals: href expected "non-spec:/path" but got "non-spec:/./path"
+FAIL Parsing: <non-special://%E2%80%A0/> against <about:blank> assert_equals: host expected "%E2%80%A0" but got ""
+FAIL Parsing: <non-special://H%4fSt/path> against <about:blank> assert_equals: host expected "H%4fSt" but got ""
+FAIL Parsing: <non-special://[1:2:0:0:5:0:0:0]/> against <about:blank> assert_equals: href expected "non-special://[1:2:0:0:5::]/" but got "non-special://[1:2:0:0:5:0:0:0]/"
+FAIL Parsing: <non-special://[1:2:0:0:0:0:0:3]/> against <about:blank> assert_equals: href expected "non-special://[1:2::3]/" but got "non-special://[1:2:0:0:0:0:0:3]/"
+FAIL Parsing: <non-special://[1:2::3]:80/> against <about:blank> assert_equals: host expected "[1:2::3]:80" but got ""
+FAIL Parsing: <non-special://[:80/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <blob:https://example.com:443/> against <about:blank>
+PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
+PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
+PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
+FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
+PASS Parsing: <http://[0:1:0:1:0:1:0:1]> against <about:blank>
+PASS Parsing: <http://[1:0:1:0:1:0:1:0]> against <about:blank>
+PASS Parsing: <http://example.org/test?"> against <about:blank>
+PASS Parsing: <http://example.org/test?#> against <about:blank>
+PASS Parsing: <http://example.org/test?<> against <about:blank>
+PASS Parsing: <http://example.org/test?>> against <about:blank>
+PASS Parsing: <http://example.org/test?⌣> against <about:blank>
+PASS Parsing: <http://example.org/test?%23%23> against <about:blank>
+PASS Parsing: <http://example.org/test?%GH> against <about:blank>
+PASS Parsing: <http://example.org/test?a#%EF> against <about:blank>
+PASS Parsing: <http://example.org/test?a#%GH> against <about:blank>
+FAIL Parsing: <a> against <about:blank> assert_equals: failure should set href to input expected "a" but got ""
+FAIL Parsing: <a/> against <about:blank> assert_equals: failure should set href to input expected "a/" but got ""
+FAIL Parsing: <a//> against <about:blank> assert_equals: failure should set href to input expected "a//" but got ""
+FAIL Parsing: <test-a-colon.html> against <a:> assert_equals: failure should set href to input expected "test-a-colon.html" but got ""
+FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got ""
+PASS Parsing: <test-a-colon-slash.html> against <a:/>
+FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got ""
+PASS Parsing: <test-a-colon-slash-b.html> against <a:/b>
+FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> assert_equals: href expected "a://b/test-a-colon-slash-slash-b.html" but got "a://b"
+PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
+FAIL Parsing: <non-spec://example.org/test?a#b\0c> against <about:blank> assert_equals: host expected "example.org" but got ""
+PASS Parsing: <non-spec:/test?a#b\0c> against <about:blank>
+PASS Parsing: <10.0.0.7:8080/foo.html> against <file:///some/dir/bar.html>
+PASS Parsing: <a!@$*=/foo.html> against <file:///some/dir/bar.html>
+PASS Parsing: <a1234567890-+.:foo/bar> against <http://example.com/dir/file>
+PASS Parsing: <file://a­b/p> against <about:blank>
+PASS Parsing: <file://a%C2%ADb/p> against <about:blank>
+FAIL Parsing: <file://­/p> against <about:blank> assert_equals: failure should set href to input expected "file://­/p" but got "file://%C2%AD/p"
+PASS Parsing: <file://%C2%AD/p> against <about:blank>
+FAIL Parsing: <file://xn--/p> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <#link> against <https://example.org/##link>
+PASS Parsing: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
+PASS Parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
+PASS Parsing: <https://user:pass[@foo/bar> against <http://example.org>
+FAIL Parsing: <foo:// !"$%&'()*+,-.;<=>@[\]^_`{|}~@host/> against <about:blank> assert_equals: href expected "foo://%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~@host/" but got "foo:// !\"$%&'()*+,-.;<=>@[\\]^_`{|}~@host/"
+FAIL Parsing: <wss:// !"$%&'()*+,-.;<=>@[]^_`{|}~@host/> against <about:blank> assert_equals: href expected "wss://%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/" but got "wss://%20!%22$%&%27()*+,-.%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/"
+FAIL Parsing: <foo://joe: !"$%&'()*+,-.:;<=>@[\]^_`{|}~@host/> against <about:blank> assert_equals: href expected "foo://joe:%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~@host/" but got "foo://joe: !\"$%&'()*+,-.:;<=>@[\\]^_`{|}~@host/"
+FAIL Parsing: <wss://joe: !"$%&'()*+,-.:;<=>@[]^_`{|}~@host/> against <about:blank> assert_equals: href expected "wss://joe:%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/" but got "wss://joe:%20!%22$%&%27()*+,-.%3A%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/"
+FAIL Parsing: <foo://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "!\"$%&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <wss://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "wss://!\"$&'()*+,-.;=_`{}~/" but got "wss://%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <foo://host/ !"$%&'()*+,-./:;<=>@[\]^_`{|}~> against <about:blank> assert_equals: href expected "foo://host/%20!%22$%&'()*+,-./:;%3C=%3E@[\\]^_%60%7B|%7D~" but got "foo://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~"
+FAIL Parsing: <wss://host/ !"$%&'()*+,-./:;<=>@[\]^_`{|}~> against <about:blank> assert_equals: href expected "wss://host/%20!%22$%&'()*+,-./:;%3C=%3E@[/]^_%60%7B|%7D~" but got "wss://host/%20!%22$%&'()*+,-./:;%3C=%3E@[/]%5E_%60%7B%7C%7D~"
+FAIL Parsing: <foo://host/dir/? !"$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank> assert_equals: href expected "foo://host/dir/?%20!%22$%&'()*+,-./:;%3C=%3E?@[\\]^_`{|}~" but got "foo://host/dir/?%20!%22$%&%27()*+,-./:;%3C=%3E?@[\\]^_`{|}~"
+PASS Parsing: <wss://host/dir/? !"$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+FAIL Parsing: <foo://host/dir/# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank> assert_equals: host expected "host" but got ""
+PASS Parsing: <wss://host/dir/# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+FAIL Parsing: <abc:rootless> against <abc://host/path> assert_equals: href expected "abc:rootless" but got "abc://host/rootless"
+FAIL Parsing: <abc:rootless> against <abc:/path> assert_equals: href expected "abc:rootless" but got "abc:/rootless"
+PASS Parsing: <abc:rootless> against <abc:path>
+FAIL Parsing: <abc:/rooted> against <abc://host/path> assert_equals: href expected "abc:/rooted" but got "abc://host/rooted"
+FAIL Parsing: <http://1.2.3.4.5> against <http://other.com/> assert_equals: failure should set href to input expected "http://1.2.3.4.5" but got "http://1.2.3.4.5/"
+FAIL Parsing: <http://1.2.3.4.5.> against <http://other.com/> assert_equals: failure should set href to input expected "http://1.2.3.4.5." but got "http://1.2.3.4.5./"
+PASS Parsing: <http://0..0x300/> against <about:blank>
+PASS Parsing: <http://0..0x300./> against <about:blank>
+FAIL Parsing: <http://256.256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256.256" but got "http://256.256.256.256.256/"
+FAIL Parsing: <http://256.256.256.256.256.> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256.256." but got "http://256.256.256.256.256./"
+FAIL Parsing: <http://1.2.3.08> against <about:blank> assert_equals: failure should set href to input expected "http://1.2.3.08" but got "http://1.2.3.08/"
+FAIL Parsing: <http://1.2.3.08.> against <about:blank> assert_equals: failure should set href to input expected "http://1.2.3.08." but got "http://1.2.3.08./"
+FAIL Parsing: <http://1.2.3.09> against <about:blank> assert_equals: failure should set href to input expected "http://1.2.3.09" but got "http://1.2.3.09/"
+FAIL Parsing: <http://09.2.3.4> against <about:blank> assert_equals: failure should set href to input expected "http://09.2.3.4" but got "http://09.2.3.4/"
+FAIL Parsing: <http://09.2.3.4.> against <about:blank> assert_equals: failure should set href to input expected "http://09.2.3.4." but got "http://09.2.3.4./"
+FAIL Parsing: <http://01.2.3.4.5> against <about:blank> assert_equals: failure should set href to input expected "http://01.2.3.4.5" but got "http://01.2.3.4.5/"
+FAIL Parsing: <http://01.2.3.4.5.> against <about:blank> assert_equals: failure should set href to input expected "http://01.2.3.4.5." but got "http://01.2.3.4.5./"
+FAIL Parsing: <http://0x100.2.3.4> against <about:blank> assert_equals: failure should set href to input expected "http://0x100.2.3.4" but got "http://0x100.2.3.4/"
+FAIL Parsing: <http://0x100.2.3.4.> against <about:blank> assert_equals: failure should set href to input expected "http://0x100.2.3.4." but got "http://0x100.2.3.4./"
+FAIL Parsing: <http://0x1.2.3.4.5> against <about:blank> assert_equals: failure should set href to input expected "http://0x1.2.3.4.5" but got "http://0x1.2.3.4.5/"
+FAIL Parsing: <http://0x1.2.3.4.5.> against <about:blank> assert_equals: failure should set href to input expected "http://0x1.2.3.4.5." but got "http://0x1.2.3.4.5./"
+FAIL Parsing: <http://foo.1.2.3.4> against <about:blank> assert_equals: failure should set href to input expected "http://foo.1.2.3.4" but got "http://foo.1.2.3.4/"
+FAIL Parsing: <http://foo.1.2.3.4.> against <about:blank> assert_equals: failure should set href to input expected "http://foo.1.2.3.4." but got "http://foo.1.2.3.4./"
+FAIL Parsing: <http://foo.2.3.4> against <about:blank> assert_equals: failure should set href to input expected "http://foo.2.3.4" but got "http://foo.2.3.4/"
+FAIL Parsing: <http://foo.2.3.4.> against <about:blank> assert_equals: failure should set href to input expected "http://foo.2.3.4." but got "http://foo.2.3.4./"
+FAIL Parsing: <http://foo.09> against <about:blank> assert_equals: failure should set href to input expected "http://foo.09" but got "http://foo.09/"
+FAIL Parsing: <http://foo.09.> against <about:blank> assert_equals: failure should set href to input expected "http://foo.09." but got "http://foo.09./"
+FAIL Parsing: <http://foo.0x4> against <about:blank> assert_equals: failure should set href to input expected "http://foo.0x4" but got "http://foo.0x4/"
+FAIL Parsing: <http://foo.0x4.> against <about:blank> assert_equals: failure should set href to input expected "http://foo.0x4." but got "http://foo.0x4./"
+PASS Parsing: <http://foo.09..> against <about:blank>
+PASS Parsing: <http://0999999999999999999/> against <about:blank>
+FAIL Parsing: <http://foo.0x> against <about:blank> assert_equals: failure should set href to input expected "http://foo.0x" but got "http://foo.0x/"
+FAIL Parsing: <http://foo.0XFfFfFfFfFfFfFfFfFfAcE123> against <about:blank> assert_equals: failure should set href to input expected "http://foo.0XFfFfFfFfFfFfFfFfFfAcE123" but got "http://foo.0xfffffffffffffffffface123/"
+FAIL Parsing: <http://💩.123/> against <about:blank> assert_equals: failure should set href to input expected "http://💩.123/" but got "http://xn--ls8h.123/"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element-origin-expected.txt
new file mode 100644
index 0000000..89bc28a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/url/a-element-origin-expected.txt
@@ -0,0 +1,342 @@
+This is a testharness.js-based test.
+Found 329 tests; 324 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Loading data…
+PASS Parsing origin: <http://example	.
+org> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://user:pass@foo:21/bar;par?b#c> against <http://example.org/foo/bar>
+PASS Parsing origin: <https://test:@test> against <about:blank>
+PASS Parsing origin: <https://:@test> against <about:blank>
+PASS Parsing origin: <non-special://test:@test/x> against <about:blank>
+PASS Parsing origin: <non-special://:@test/x> against <about:blank>
+PASS Parsing origin: <http:foo.com> against <http://example.org/foo/bar>
+PASS Parsing origin: <	   :foo.com   
+> against <http://example.org/foo/bar>
+PASS Parsing origin: < foo.com  > against <http://example.org/foo/bar>
+PASS Parsing origin: <a:	 foo.com> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:21/ b ? d # e > against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:0/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:00000000000000/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:00000000000000000000080/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:
+/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <> against <http://example.org/foo/bar>
+PASS Parsing origin: <  	> against <http://example.org/foo/bar>
+PASS Parsing origin: <:foo.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <:foo.com\> against <http://example.org/foo/bar>
+PASS Parsing origin: <:> against <http://example.org/foo/bar>
+PASS Parsing origin: <:a> against <http://example.org/foo/bar>
+PASS Parsing origin: <:/> against <http://example.org/foo/bar>
+PASS Parsing origin: <:\> against <http://example.org/foo/bar>
+PASS Parsing origin: <:#> against <http://example.org/foo/bar>
+PASS Parsing origin: <#> against <http://example.org/foo/bar>
+PASS Parsing origin: <#/> against <http://example.org/foo/bar>
+PASS Parsing origin: <#\> against <http://example.org/foo/bar>
+PASS Parsing origin: <#;?> against <http://example.org/foo/bar>
+PASS Parsing origin: <?> against <http://example.org/foo/bar>
+PASS Parsing origin: </> against <http://example.org/foo/bar>
+PASS Parsing origin: <:23> against <http://example.org/foo/bar>
+PASS Parsing origin: </:23> against <http://example.org/foo/bar>
+PASS Parsing origin: <\x> against <http://example.org/foo/bar>
+PASS Parsing origin: <\\x\hello> against <http://example.org/foo/bar>
+PASS Parsing origin: <::> against <http://example.org/foo/bar>
+PASS Parsing origin: <::23> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo://> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://a:b@c:29/d> against <http://example.org/foo/bar>
+PASS Parsing origin: <http::@c:29> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://&a:foo(b]c@d:2/> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://::@c@d:2> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo.com:b@d/> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo.com/\@> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:\\foo.com\> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:\\a\b:c\d@foo.com\> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo:/> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo:/bar.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo://///////> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo://///////bar.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo:////://///> against <http://example.org/foo/bar>
+PASS Parsing origin: <c:/foo> against <http://example.org/foo/bar>
+PASS Parsing origin: <//foo/bar> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo/path;a??e#f#g> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo/abcd?efgh?ijkl> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo/abcd#foo?bar> against <http://example.org/foo/bar>
+PASS Parsing origin: <[61:24:74]:98> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:[61:27]/:foo> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://[2001::1]> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://[::127.0.0.1]> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://[0:0:0:0:0:0:13.1.68.3]> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://[2001::1]:80> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ftp:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <https:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <madeupscheme:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ftps:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <gopher:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ws:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <wss:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <data:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <javascript:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <mailto:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ftp:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <https:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <madeupscheme:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ftps:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <gopher:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ws:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <wss:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <data:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <javascript:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <mailto:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: </a/b/c> against <http://example.org/foo/bar>
+PASS Parsing origin: </a/ /c> against <http://example.org/foo/bar>
+PASS Parsing origin: </a%2fc> against <http://example.org/foo/bar>
+PASS Parsing origin: </a/%2f/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <#β> against <http://example.org/foo/bar>
+PASS Parsing origin: <data:text/html,test#test> against <http://example.org/foo/bar>
+PASS Parsing origin: <tel:1234567890> against <http://example.org/foo/bar>
+PASS Parsing origin: <ssh://example.com/foo/bar.git> against <http://example.org/>
+PASS Parsing origin: <http://example.com/././foo> against <about:blank>
+PASS Parsing origin: <http://example.com/./.foo> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/.> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/./> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar/..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar/../> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/..bar> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar/../ton> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar/../ton/../../a> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/../../..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/../../../ton> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/%2e> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/%2e%2> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank>
+PASS Parsing origin: <http://example.com////../..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar//../..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar//..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo> against <about:blank>
+PASS Parsing origin: <http://example.com/%20foo> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%2> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%2zbar> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%2©zbar> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%41%7a> against <about:blank>
+PASS Parsing origin: <http://example.com/foo	‘%91> against <about:blank>
+FAIL Parsing origin: <http://example.com/foo%00%51> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
+PASS Parsing origin: <http://example.com/(%28:%3A%29)> against <about:blank>
+PASS Parsing origin: <http://example.com/%3A%3a%3C%3c> against <about:blank>
+PASS Parsing origin: <http://example.com/foo	bar> against <about:blank>
+PASS Parsing origin: <http://example.com\\foo\\bar> against <about:blank>
+PASS Parsing origin: <http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd> against <about:blank>
+PASS Parsing origin: <http://example.com/@asdf%40> against <about:blank>
+PASS Parsing origin: <http://example.com/你好你好> against <about:blank>
+PASS Parsing origin: <http://example.com/‥/foo> against <about:blank>
+PASS Parsing origin: <http://example.com//foo> against <about:blank>
+PASS Parsing origin: <http://example.com/‮/foo/‭/bar> against <about:blank>
+PASS Parsing origin: <http://www.google.com/foo?bar=baz#> against <about:blank>
+PASS Parsing origin: <http://www.google.com/foo?bar=baz# »> against <about:blank>
+PASS Parsing origin: <data:test# »> against <about:blank>
+PASS Parsing origin: <http://www.google.com> against <about:blank>
+PASS Parsing origin: <http://192.0x00A80001> against <about:blank>
+PASS Parsing origin: <http://www/foo%2Ehtml> against <about:blank>
+PASS Parsing origin: <http://www/foo/%2E/html> against <about:blank>
+PASS Parsing origin: <http://%25DOMAIN:foobar@foodomain.com/> against <about:blank>
+PASS Parsing origin: <http:\\www.google.com\foo> against <about:blank>
+PASS Parsing origin: <http://foo:80/> against <about:blank>
+PASS Parsing origin: <http://foo:81/> against <about:blank>
+PASS Parsing origin: <httpa://foo:80/> against <about:blank>
+PASS Parsing origin: <https://foo:443/> against <about:blank>
+PASS Parsing origin: <https://foo:80/> against <about:blank>
+PASS Parsing origin: <ftp://foo:21/> against <about:blank>
+PASS Parsing origin: <ftp://foo:80/> against <about:blank>
+PASS Parsing origin: <gopher://foo:70/> against <about:blank>
+PASS Parsing origin: <gopher://foo:443/> against <about:blank>
+PASS Parsing origin: <ws://foo:80/> against <about:blank>
+PASS Parsing origin: <ws://foo:81/> against <about:blank>
+PASS Parsing origin: <ws://foo:443/> against <about:blank>
+PASS Parsing origin: <ws://foo:815/> against <about:blank>
+PASS Parsing origin: <wss://foo:80/> against <about:blank>
+PASS Parsing origin: <wss://foo:81/> against <about:blank>
+PASS Parsing origin: <wss://foo:443/> against <about:blank>
+PASS Parsing origin: <wss://foo:815/> against <about:blank>
+PASS Parsing origin: <http:/example.com/> against <about:blank>
+PASS Parsing origin: <ftp:/example.com/> against <about:blank>
+PASS Parsing origin: <https:/example.com/> against <about:blank>
+PASS Parsing origin: <madeupscheme:/example.com/> against <about:blank>
+PASS Parsing origin: <ftps:/example.com/> against <about:blank>
+PASS Parsing origin: <gopher:/example.com/> against <about:blank>
+PASS Parsing origin: <ws:/example.com/> against <about:blank>
+PASS Parsing origin: <wss:/example.com/> against <about:blank>
+PASS Parsing origin: <data:/example.com/> against <about:blank>
+PASS Parsing origin: <javascript:/example.com/> against <about:blank>
+PASS Parsing origin: <mailto:/example.com/> against <about:blank>
+PASS Parsing origin: <http:example.com/> against <about:blank>
+PASS Parsing origin: <ftp:example.com/> against <about:blank>
+PASS Parsing origin: <https:example.com/> against <about:blank>
+PASS Parsing origin: <madeupscheme:example.com/> against <about:blank>
+PASS Parsing origin: <ftps:example.com/> against <about:blank>
+PASS Parsing origin: <gopher:example.com/> against <about:blank>
+PASS Parsing origin: <ws:example.com/> against <about:blank>
+PASS Parsing origin: <wss:example.com/> against <about:blank>
+PASS Parsing origin: <data:example.com/> against <about:blank>
+PASS Parsing origin: <javascript:example.com/> against <about:blank>
+PASS Parsing origin: <mailto:example.com/> against <about:blank>
+PASS Parsing origin: <http:@www.example.com> against <about:blank>
+PASS Parsing origin: <http:/@www.example.com> against <about:blank>
+PASS Parsing origin: <http://@www.example.com> against <about:blank>
+PASS Parsing origin: <http:a:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http:/a:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http://a:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http://@pple.com> against <about:blank>
+PASS Parsing origin: <http::b@www.example.com> against <about:blank>
+PASS Parsing origin: <http:/:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http://:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http:a:@www.example.com> against <about:blank>
+PASS Parsing origin: <http:/a:@www.example.com> against <about:blank>
+PASS Parsing origin: <http://a:@www.example.com> against <about:blank>
+PASS Parsing origin: <http://www.@pple.com> against <about:blank>
+PASS Parsing origin: <http://:@www.example.com> against <about:blank>
+PASS Parsing origin: </> against <http://www.example.com/test>
+PASS Parsing origin: </test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <.> against <http://www.example.com/test>
+PASS Parsing origin: <..> against <http://www.example.com/test>
+PASS Parsing origin: <test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <./test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <../test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <../aaa/test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <../../test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <中/test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <http://www.example2.com> against <http://www.example.com/test>
+PASS Parsing origin: <//www.example2.com> against <http://www.example.com/test>
+PASS Parsing origin: <http://ExAmPlE.CoM> against <http://other.com/>
+PASS Parsing origin: <http://GOO​⁠goo.com> against <http://other.com/>
+PASS Parsing origin: <\0 http://example.com/ \r > against <about:blank>
+PASS Parsing origin: <http://www.foo。bar.com> against <http://other.com/>
+PASS Parsing origin: <https://x/�?�#�> against <about:blank>
+PASS Parsing origin: <http://Go.com> against <http://other.com/>
+PASS Parsing origin: <http://你好你好> against <http://other.com/>
+FAIL Parsing origin: <https://faß.ExAmPlE/> against <about:blank> assert_equals: origin expected "https://xn--fa-hia.example" but got "https://fass.example"
+PASS Parsing origin: <sc://faß.ExAmPlE/> against <about:blank>
+PASS Parsing origin: <http://%30%78%63%30%2e%30%32%35%30.01> against <http://other.com/>
+PASS Parsing origin: <http://%30%78%63%30%2e%30%32%35%30.01%2e> against <http://other.com/>
+PASS Parsing origin: <http://0Xc0.0250.01> against <http://other.com/>
+PASS Parsing origin: <http://./> against <about:blank>
+PASS Parsing origin: <http://../> against <about:blank>
+PASS Parsing origin: <http://foo:💩@example.com/bar> against <http://other.com/>
+PASS Parsing origin: <#> against <test:test>
+PASS Parsing origin: <#x> against <mailto:x@x.com>
+PASS Parsing origin: <#x> against <data:,>
+PASS Parsing origin: <#x> against <about:blank>
+PASS Parsing origin: <#> against <test:test?test>
+PASS Parsing origin: <https://@test@test@example:800/> against <http://doesnotmatter/>
+PASS Parsing origin: <https://@@@example> against <http://doesnotmatter/>
+PASS Parsing origin: <http://`{}:`{}@h/`{}?`{}> against <http://doesnotmatter/>
+PASS Parsing origin: <http://host/?'> against <about:blank>
+PASS Parsing origin: <notspecial://host/?'> against <about:blank>
+PASS Parsing origin: </some/path> against <http://user@example.org/smth>
+PASS Parsing origin: <> against <http://user:pass@example.org:21/smth>
+PASS Parsing origin: </some/path> against <http://user:pass@example.org:21/smth>
+PASS Parsing origin: <i> against <sc:/pa/pa>
+PASS Parsing origin: <i> against <sc://ho/pa>
+PASS Parsing origin: <i> against <sc:///pa/pa>
+PASS Parsing origin: <../i> against <sc:/pa/pa>
+PASS Parsing origin: <../i> against <sc://ho/pa>
+PASS Parsing origin: <../i> against <sc:///pa/pa>
+PASS Parsing origin: </i> against <sc:/pa/pa>
+PASS Parsing origin: </i> against <sc://ho/pa>
+PASS Parsing origin: </i> against <sc:///pa/pa>
+PASS Parsing origin: <?i> against <sc:/pa/pa>
+PASS Parsing origin: <?i> against <sc://ho/pa>
+PASS Parsing origin: <?i> against <sc:///pa/pa>
+PASS Parsing origin: <#i> against <sc:sd>
+PASS Parsing origin: <#i> against <sc:sd/sd>
+PASS Parsing origin: <#i> against <sc:/pa/pa>
+PASS Parsing origin: <#i> against <sc://ho/pa>
+PASS Parsing origin: <#i> against <sc:///pa/pa>
+PASS Parsing origin: <about:/../> against <about:blank>
+PASS Parsing origin: <data:/../> against <about:blank>
+PASS Parsing origin: <javascript:/../> against <about:blank>
+PASS Parsing origin: <mailto:/../> against <about:blank>
+PASS Parsing origin: <sc://ñ.test/> against <about:blank>
+PASS Parsing origin: <x> against <sc://ñ>
+PASS Parsing origin: <sc:\../> against <about:blank>
+PASS Parsing origin: <sc::a@example.net> against <about:blank>
+PASS Parsing origin: <wow:%NBD> against <about:blank>
+PASS Parsing origin: <wow:%1G> against <about:blank>
+PASS Parsing origin: <wow:￿> against <about:blank>
+FAIL Parsing origin: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
+FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
+PASS Parsing origin: <ftp://%e2%98%83> against <about:blank>
+PASS Parsing origin: <https://%e2%98%83> against <about:blank>
+PASS Parsing origin: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
+PASS Parsing origin: <http://facebook.com/?foo=%7B%22abc%22> against <about:blank>
+PASS Parsing origin: <https://localhost:3000/jqueryui@1.2.3> against <about:blank>
+PASS Parsing origin: <h	t
+t\rp://h	o
+s\rt:9	0
+0\r0/p	a
+t\rh?q	u
+e\rry#f	r
+a\rg> against <about:blank>
+PASS Parsing origin: <?a=b&c=d> against <http://example.org/foo/bar>
+PASS Parsing origin: <??a=b&c=d> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:> against <http://example.org/foo/bar>
+PASS Parsing origin: <sc:> against <https://example.org/foo/bar>
+PASS Parsing origin: <http://foo.bar/baz?qux#foobar> against <about:blank>
+PASS Parsing origin: <http://foo.bar/baz?qux#foo"bar> against <about:blank>
+PASS Parsing origin: <http://foo.bar/baz?qux#foo<bar> against <about:blank>
+PASS Parsing origin: <http://foo.bar/baz?qux#foo>bar> against <about:blank>
+PASS Parsing origin: <http://foo.bar/baz?qux#foo`bar> against <about:blank>
+PASS Parsing origin: <http://1.2.3.4/> against <http://other.com/>
+PASS Parsing origin: <http://1.2.3.4./> against <http://other.com/>
+PASS Parsing origin: <http://192.168.257> against <http://other.com/>
+PASS Parsing origin: <http://192.168.257.> against <http://other.com/>
+PASS Parsing origin: <http://192.168.257.com> against <http://other.com/>
+PASS Parsing origin: <http://256> against <http://other.com/>
+PASS Parsing origin: <http://256.com> against <http://other.com/>
+PASS Parsing origin: <http://999999999> against <http://other.com/>
+PASS Parsing origin: <http://999999999.> against <http://other.com/>
+PASS Parsing origin: <http://999999999.com> against <http://other.com/>
+PASS Parsing origin: <http://10000000000.com> against <http://other.com/>
+PASS Parsing origin: <http://4294967295> against <http://other.com/>
+PASS Parsing origin: <http://0xffffffff> against <http://other.com/>
+PASS Parsing origin: <https://0x.0x.0> against <about:blank>
+PASS Parsing origin: <asdf://%43%7C/> against <about:blank>
+PASS Parsing origin: <http://[1:0::]> against <http://example.net/>
+PASS Parsing origin: <sc://ñ> against <about:blank>
+PASS Parsing origin: <sc://ñ?x> against <about:blank>
+PASS Parsing origin: <sc://ñ#x> against <about:blank>
+PASS Parsing origin: <#x> against <sc://ñ>
+PASS Parsing origin: <?x> against <sc://ñ>
+PASS Parsing origin: <tftp://foobar.com/someconfig;mode=netascii> against <about:blank>
+PASS Parsing origin: <telnet://user:pass@foobar.com:23/> against <about:blank>
+PASS Parsing origin: <ut2004://10.10.10.10:7777/Index.ut2> against <about:blank>
+PASS Parsing origin: <redis://foo:bar@somehost:6379/0?baz=bam&qux=baz> against <about:blank>
+PASS Parsing origin: <rsync://foo@host:911/sup> against <about:blank>
+PASS Parsing origin: <git://github.com/foo/bar.git> against <about:blank>
+PASS Parsing origin: <irc://myserver.com:6999/channel?passwd> against <about:blank>
+PASS Parsing origin: <dns://fw.example.org:9999/foo.bar.org?type=TXT> against <about:blank>
+PASS Parsing origin: <ldap://localhost:389/ou=People,o=JNDITutorial> against <about:blank>
+PASS Parsing origin: <git+https://github.com/foo/bar> against <about:blank>
+PASS Parsing origin: <urn:ietf:rfc:2648> against <about:blank>
+PASS Parsing origin: <tag:joe@example.org,2001:foo/bar> against <about:blank>
+PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
+PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
+PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
+PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
+PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
+PASS Parsing origin: <foo:// !"$%&'()*+,-.;<=>@[\]^_`{|}~@host/> against <about:blank>
+PASS Parsing origin: <wss:// !"$%&'()*+,-.;<=>@[]^_`{|}~@host/> against <about:blank>
+PASS Parsing origin: <foo://joe: !"$%&'()*+,-.:;<=>@[\]^_`{|}~@host/> against <about:blank>
+PASS Parsing origin: <wss://joe: !"$%&'()*+,-.:;<=>@[]^_`{|}~@host/> against <about:blank>
+PASS Parsing origin: <foo://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Parsing origin: <wss://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "wss://!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <foo://host/ !"$%&'()*+,-./:;<=>@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <wss://host/ !"$%&'()*+,-./:;<=>@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <foo://host/dir/? !"$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <wss://host/dir/? !"$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <foo://host/dir/# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <wss://host/dir/# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/css/css-pseudo/idlharness-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/css/css-pseudo/idlharness-expected.txt
new file mode 100644
index 0000000..46168b2
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/css/css-pseudo/idlharness-expected.txt
@@ -0,0 +1,24 @@
+This is a testharness.js-based test.
+FAIL idl_test setup promise_test: Unhandled rejection with value: object "TypeError: window.getPseudoElements is not a function"
+PASS idl_test validation
+PASS Partial interface Element: original interface defined
+PASS Partial interface Element: member names are unique
+PASS Element includes ParentNode: member names are unique
+PASS Element includes NonDocumentTypeChildNode: member names are unique
+PASS Element includes ChildNode: member names are unique
+PASS Element includes Slottable: member names are unique
+FAIL CSSPseudoElement interface: existence and properties of interface object assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface object length assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface object name assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: attribute type assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: attribute element assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement must be primary interface of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL Stringification of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "type" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "element" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL Element interface: operation pseudo(CSSOMString) assert_own_property: interface prototype object missing non-static operation expected property "pseudo" missing
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/url/a-element-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/url/a-element-expected.txt
new file mode 100644
index 0000000..f4e57be3
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/url/a-element-expected.txt
@@ -0,0 +1,684 @@
+This is a testharness.js-based test.
+Found 669 tests; 383 PASS, 286 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Loading data…
+PASS Parsing: <http://example	.
+org> against <http://example.org/foo/bar>
+PASS Parsing: <http://user:pass@foo:21/bar;par?b#c> against <http://example.org/foo/bar>
+PASS Parsing: <https://test:@test> against <about:blank>
+PASS Parsing: <https://:@test> against <about:blank>
+FAIL Parsing: <non-special://test:@test/x> against <about:blank> assert_equals: href expected "non-special://test@test/x" but got "non-special://test:@test/x"
+FAIL Parsing: <non-special://:@test/x> against <about:blank> assert_equals: href expected "non-special://test/x" but got "non-special://:@test/x"
+PASS Parsing: <http:foo.com> against <http://example.org/foo/bar>
+PASS Parsing: <	   :foo.com   
+> against <http://example.org/foo/bar>
+PASS Parsing: < foo.com  > against <http://example.org/foo/bar>
+PASS Parsing: <a:	 foo.com> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:21/ b ? d # e > against <http://example.org/foo/bar>
+PASS Parsing: <lolscheme:x x#x x> against <about:blank>
+PASS Parsing: <http://f:/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:0/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:00000000000000/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:00000000000000000000080/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:b/c> against <http://example.org/foo/bar>
+FAIL Parsing: <http://f: /c> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://f: /c" but got "http://f:%20/c"
+PASS Parsing: <http://f:
+/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:fifty-two/c> against <http://example.org/foo/bar>
+PASS Parsing: <http://f:999999/c> against <http://example.org/foo/bar>
+FAIL Parsing: <non-special://f:999999/c> against <http://example.org/foo/bar> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://f: 21 / b ? d # e > against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://f: 21 / b ? d # e " but got "http://f:%2021%20/%20b%20?%20d%20#%20e"
+PASS Parsing: <> against <http://example.org/foo/bar>
+PASS Parsing: <  	> against <http://example.org/foo/bar>
+PASS Parsing: <:foo.com/> against <http://example.org/foo/bar>
+PASS Parsing: <:foo.com\> against <http://example.org/foo/bar>
+PASS Parsing: <:> against <http://example.org/foo/bar>
+PASS Parsing: <:a> against <http://example.org/foo/bar>
+PASS Parsing: <:/> against <http://example.org/foo/bar>
+PASS Parsing: <:\> against <http://example.org/foo/bar>
+PASS Parsing: <:#> against <http://example.org/foo/bar>
+PASS Parsing: <#> against <http://example.org/foo/bar>
+PASS Parsing: <#/> against <http://example.org/foo/bar>
+PASS Parsing: <#\> against <http://example.org/foo/bar>
+PASS Parsing: <#;?> against <http://example.org/foo/bar>
+PASS Parsing: <?> against <http://example.org/foo/bar>
+PASS Parsing: </> against <http://example.org/foo/bar>
+PASS Parsing: <:23> against <http://example.org/foo/bar>
+PASS Parsing: </:23> against <http://example.org/foo/bar>
+PASS Parsing: <\x> against <http://example.org/foo/bar>
+PASS Parsing: <\\x\hello> against <http://example.org/foo/bar>
+PASS Parsing: <::> against <http://example.org/foo/bar>
+PASS Parsing: <::23> against <http://example.org/foo/bar>
+FAIL Parsing: <foo://> against <http://example.org/foo/bar> assert_equals: pathname expected "" but got "//"
+PASS Parsing: <http://a:b@c:29/d> against <http://example.org/foo/bar>
+PASS Parsing: <http::@c:29> against <http://example.org/foo/bar>
+PASS Parsing: <http://&a:foo(b]c@d:2/> against <http://example.org/foo/bar>
+PASS Parsing: <http://::@c@d:2> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo.com:b@d/> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo.com/\@> against <http://example.org/foo/bar>
+PASS Parsing: <http:\\foo.com\> against <http://example.org/foo/bar>
+PASS Parsing: <http:\\a\b:c\d@foo.com\> against <http://example.org/foo/bar>
+PASS Parsing: <foo:/> against <http://example.org/foo/bar>
+PASS Parsing: <foo:/bar.com/> against <http://example.org/foo/bar>
+FAIL Parsing: <foo://///////> against <http://example.org/foo/bar> assert_equals: pathname expected "///////" but got "/////////"
+FAIL Parsing: <foo://///////bar.com/> against <http://example.org/foo/bar> assert_equals: pathname expected "///////bar.com/" but got "/////////bar.com/"
+FAIL Parsing: <foo:////://///> against <http://example.org/foo/bar> assert_equals: pathname expected "//://///" but got "////://///"
+PASS Parsing: <c:/foo> against <http://example.org/foo/bar>
+PASS Parsing: <//foo/bar> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo/path;a??e#f#g> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo/abcd?efgh?ijkl> against <http://example.org/foo/bar>
+PASS Parsing: <http://foo/abcd#foo?bar> against <http://example.org/foo/bar>
+PASS Parsing: <[61:24:74]:98> against <http://example.org/foo/bar>
+PASS Parsing: <http:[61:27]/:foo> against <http://example.org/foo/bar>
+FAIL Parsing: <http://[1::2]:3:4> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://[1::2]:3:4" but got "http://[1::2]:3:4/"
+FAIL Parsing: <http://2001::1> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://2001::1" but got "http://2001::1/"
+FAIL Parsing: <http://2001::1]> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://2001::1]" but got "http://2001::1]/"
+FAIL Parsing: <http://2001::1]:80> against <http://example.org/foo/bar> assert_equals: failure should set href to input expected "http://2001::1]:80" but got "http://2001::1]/"
+PASS Parsing: <http://[2001::1]> against <http://example.org/foo/bar>
+PASS Parsing: <http://[::127.0.0.1]> against <http://example.org/foo/bar>
+PASS Parsing: <http://[0:0:0:0:0:0:13.1.68.3]> against <http://example.org/foo/bar>
+PASS Parsing: <http://[2001::1]:80> against <http://example.org/foo/bar>
+PASS Parsing: <http:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ftp:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <https:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <madeupscheme:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <file:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <file://example:1/> against <about:blank>
+PASS Parsing: <file://example:test/> against <about:blank>
+FAIL Parsing: <file://example%/> against <about:blank> assert_equals: failure should set href to input expected "file://example%/" but got "file://example%25/"
+PASS Parsing: <file://[example]/> against <about:blank>
+PASS Parsing: <ftps:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <gopher:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ws:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <wss:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <data:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <javascript:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <mailto:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <http:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ftp:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <https:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <madeupscheme:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ftps:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <gopher:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <ws:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <wss:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <data:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <javascript:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: <mailto:example.com/> against <http://example.org/foo/bar>
+PASS Parsing: </a/b/c> against <http://example.org/foo/bar>
+PASS Parsing: </a/ /c> against <http://example.org/foo/bar>
+PASS Parsing: </a%2fc> against <http://example.org/foo/bar>
+PASS Parsing: </a/%2f/c> against <http://example.org/foo/bar>
+PASS Parsing: <#β> against <http://example.org/foo/bar>
+PASS Parsing: <data:text/html,test#test> against <http://example.org/foo/bar>
+PASS Parsing: <tel:1234567890> against <http://example.org/foo/bar>
+FAIL Parsing: <ssh://example.com/foo/bar.git> against <http://example.org/> assert_equals: host expected "example.com" but got ""
+FAIL Parsing: <file:c:\foo\bar.html> against <file:///tmp/mock/path> assert_equals: href expected "file:///c:/foo/bar.html" but got "file:///tmp/mock/c:/foo/bar.html"
+FAIL Parsing: <  File:c|////foo\bar.html> against <file:///tmp/mock/path> assert_equals: href expected "file:///c:////foo/bar.html" but got "file:///tmp/mock/c%7C////foo/bar.html"
+FAIL Parsing: <C|/foo/bar> against <file:///tmp/mock/path> assert_equals: href expected "file:///C:/foo/bar" but got "file:///tmp/mock/C%7C/foo/bar"
+FAIL Parsing: </C|\foo\bar> against <file:///tmp/mock/path> assert_equals: href expected "file:///C:/foo/bar" but got "file:///C%7C/foo/bar"
+FAIL Parsing: <//C|/foo/bar> against <file:///tmp/mock/path> assert_equals: href expected "file:///C:/foo/bar" but got "file://c%7C/foo/bar"
+PASS Parsing: <//server/file> against <file:///tmp/mock/path>
+PASS Parsing: <\\server\file> against <file:///tmp/mock/path>
+PASS Parsing: </\server/file> against <file:///tmp/mock/path>
+PASS Parsing: <file:///foo/bar.txt> against <file:///tmp/mock/path>
+PASS Parsing: <file:///home/me> against <file:///tmp/mock/path>
+PASS Parsing: <//> against <file:///tmp/mock/path>
+PASS Parsing: <///> against <file:///tmp/mock/path>
+PASS Parsing: <///test> against <file:///tmp/mock/path>
+PASS Parsing: <file://test> against <file:///tmp/mock/path>
+FAIL Parsing: <file://localhost> against <file:///tmp/mock/path> assert_equals: href expected "file:///" but got "file://localhost/"
+FAIL Parsing: <file://localhost/> against <file:///tmp/mock/path> assert_equals: href expected "file:///" but got "file://localhost/"
+FAIL Parsing: <file://localhost/test> against <file:///tmp/mock/path> assert_equals: href expected "file:///test" but got "file://localhost/test"
+PASS Parsing: <test> against <file:///tmp/mock/path>
+PASS Parsing: <file:test> against <file:///tmp/mock/path>
+PASS Parsing: <http://example.com/././foo> against <about:blank>
+PASS Parsing: <http://example.com/./.foo> against <about:blank>
+PASS Parsing: <http://example.com/foo/.> against <about:blank>
+PASS Parsing: <http://example.com/foo/./> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar/..> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar/../> against <about:blank>
+PASS Parsing: <http://example.com/foo/..bar> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar/../ton> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar/../ton/../../a> against <about:blank>
+PASS Parsing: <http://example.com/foo/../../..> against <about:blank>
+PASS Parsing: <http://example.com/foo/../../../ton> against <about:blank>
+PASS Parsing: <http://example.com/foo/%2e> against <about:blank>
+FAIL Parsing: <http://example.com/foo/%2e%2> against <about:blank> assert_equals: href expected "http://example.com/foo/%2e%2" but got "http://example.com/foo/.%2"
+FAIL Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank> assert_equals: href expected "http://example.com/%2e.bar" but got "http://example.com/..bar"
+PASS Parsing: <http://example.com////../..> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar//../..> against <about:blank>
+PASS Parsing: <http://example.com/foo/bar//..> against <about:blank>
+PASS Parsing: <http://example.com/foo> against <about:blank>
+PASS Parsing: <http://example.com/%20foo> against <about:blank>
+PASS Parsing: <http://example.com/foo%> against <about:blank>
+PASS Parsing: <http://example.com/foo%2> against <about:blank>
+PASS Parsing: <http://example.com/foo%2zbar> against <about:blank>
+PASS Parsing: <http://example.com/foo%2©zbar> against <about:blank>
+FAIL Parsing: <http://example.com/foo%41%7a> against <about:blank> assert_equals: href expected "http://example.com/foo%41%7a" but got "http://example.com/fooAz"
+PASS Parsing: <http://example.com/foo	‘%91> against <about:blank>
+FAIL Parsing: <http://example.com/foo%00%51> against <about:blank> assert_equals: href expected "http://example.com/foo%00%51" but got "http://example.com/foo%00Q"
+PASS Parsing: <http://example.com/(%28:%3A%29)> against <about:blank>
+PASS Parsing: <http://example.com/%3A%3a%3C%3c> against <about:blank>
+PASS Parsing: <http://example.com/foo	bar> against <about:blank>
+PASS Parsing: <http://example.com\\foo\\bar> against <about:blank>
+PASS Parsing: <http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd> against <about:blank>
+PASS Parsing: <http://example.com/@asdf%40> against <about:blank>
+PASS Parsing: <http://example.com/你好你好> against <about:blank>
+PASS Parsing: <http://example.com/‥/foo> against <about:blank>
+PASS Parsing: <http://example.com//foo> against <about:blank>
+PASS Parsing: <http://example.com/‮/foo/‭/bar> against <about:blank>
+PASS Parsing: <http://www.google.com/foo?bar=baz#> against <about:blank>
+PASS Parsing: <http://www.google.com/foo?bar=baz# »> against <about:blank>
+PASS Parsing: <data:test# »> against <about:blank>
+PASS Parsing: <http://www.google.com> against <about:blank>
+PASS Parsing: <http://192.0x00A80001> against <about:blank>
+FAIL Parsing: <http://www/foo%2Ehtml> against <about:blank> assert_equals: href expected "http://www/foo%2Ehtml" but got "http://www/foo.html"
+PASS Parsing: <http://www/foo/%2E/html> against <about:blank>
+PASS Parsing: <http://user:pass@/> against <about:blank>
+PASS Parsing: <http://%25DOMAIN:foobar@foodomain.com/> against <about:blank>
+PASS Parsing: <http:\\www.google.com\foo> against <about:blank>
+PASS Parsing: <http://foo:80/> against <about:blank>
+PASS Parsing: <http://foo:81/> against <about:blank>
+FAIL Parsing: <httpa://foo:80/> against <about:blank> assert_equals: host expected "foo:80" but got ""
+PASS Parsing: <http://foo:-80/> against <about:blank>
+PASS Parsing: <https://foo:443/> against <about:blank>
+PASS Parsing: <https://foo:80/> against <about:blank>
+PASS Parsing: <ftp://foo:21/> against <about:blank>
+PASS Parsing: <ftp://foo:80/> against <about:blank>
+FAIL Parsing: <gopher://foo:70/> against <about:blank> assert_equals: host expected "foo:70" but got ""
+FAIL Parsing: <gopher://foo:443/> against <about:blank> assert_equals: host expected "foo:443" but got ""
+PASS Parsing: <ws://foo:80/> against <about:blank>
+PASS Parsing: <ws://foo:81/> against <about:blank>
+PASS Parsing: <ws://foo:443/> against <about:blank>
+PASS Parsing: <ws://foo:815/> against <about:blank>
+PASS Parsing: <wss://foo:80/> against <about:blank>
+PASS Parsing: <wss://foo:81/> against <about:blank>
+PASS Parsing: <wss://foo:443/> against <about:blank>
+PASS Parsing: <wss://foo:815/> against <about:blank>
+PASS Parsing: <http:/example.com/> against <about:blank>
+PASS Parsing: <ftp:/example.com/> against <about:blank>
+PASS Parsing: <https:/example.com/> against <about:blank>
+PASS Parsing: <madeupscheme:/example.com/> against <about:blank>
+PASS Parsing: <file:/example.com/> against <about:blank>
+PASS Parsing: <ftps:/example.com/> against <about:blank>
+PASS Parsing: <gopher:/example.com/> against <about:blank>
+PASS Parsing: <ws:/example.com/> against <about:blank>
+PASS Parsing: <wss:/example.com/> against <about:blank>
+PASS Parsing: <data:/example.com/> against <about:blank>
+PASS Parsing: <javascript:/example.com/> against <about:blank>
+PASS Parsing: <mailto:/example.com/> against <about:blank>
+PASS Parsing: <http:example.com/> against <about:blank>
+PASS Parsing: <ftp:example.com/> against <about:blank>
+PASS Parsing: <https:example.com/> against <about:blank>
+PASS Parsing: <madeupscheme:example.com/> against <about:blank>
+PASS Parsing: <ftps:example.com/> against <about:blank>
+PASS Parsing: <gopher:example.com/> against <about:blank>
+PASS Parsing: <ws:example.com/> against <about:blank>
+PASS Parsing: <wss:example.com/> against <about:blank>
+PASS Parsing: <data:example.com/> against <about:blank>
+PASS Parsing: <javascript:example.com/> against <about:blank>
+PASS Parsing: <mailto:example.com/> against <about:blank>
+PASS Parsing: <http:@www.example.com> against <about:blank>
+PASS Parsing: <http:/@www.example.com> against <about:blank>
+PASS Parsing: <http://@www.example.com> against <about:blank>
+PASS Parsing: <http:a:b@www.example.com> against <about:blank>
+PASS Parsing: <http:/a:b@www.example.com> against <about:blank>
+PASS Parsing: <http://a:b@www.example.com> against <about:blank>
+PASS Parsing: <http://@pple.com> against <about:blank>
+PASS Parsing: <http::b@www.example.com> against <about:blank>
+PASS Parsing: <http:/:b@www.example.com> against <about:blank>
+PASS Parsing: <http://:b@www.example.com> against <about:blank>
+FAIL Parsing: <http:/:@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:/:@/www.example.com" but got "http:///www.example.com"
+PASS Parsing: <http://user@/www.example.com> against <about:blank>
+FAIL Parsing: <http:@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:@/www.example.com" but got "http:///www.example.com"
+FAIL Parsing: <http:/@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:/@/www.example.com" but got "http:///www.example.com"
+FAIL Parsing: <http://@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http://@/www.example.com" but got "http:///www.example.com"
+FAIL Parsing: <https:@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "https:@/www.example.com" but got "https:///www.example.com"
+FAIL Parsing: <http:a:b@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:a:b@/www.example.com" but got "http://a:b@/www.example.com"
+FAIL Parsing: <http:/a:b@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:/a:b@/www.example.com" but got "http://a:b@/www.example.com"
+PASS Parsing: <http://a:b@/www.example.com> against <about:blank>
+FAIL Parsing: <http::@/www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http::@/www.example.com" but got "http:///www.example.com"
+PASS Parsing: <http:a:@www.example.com> against <about:blank>
+PASS Parsing: <http:/a:@www.example.com> against <about:blank>
+PASS Parsing: <http://a:@www.example.com> against <about:blank>
+PASS Parsing: <http://www.@pple.com> against <about:blank>
+FAIL Parsing: <http:@:www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:@:www.example.com" but got "http://:www.example.com/"
+FAIL Parsing: <http:/@:www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http:/@:www.example.com" but got "http://:www.example.com/"
+FAIL Parsing: <http://@:www.example.com> against <about:blank> assert_equals: failure should set href to input expected "http://@:www.example.com" but got "http://:www.example.com/"
+PASS Parsing: <http://:@www.example.com> against <about:blank>
+PASS Parsing: </> against <http://www.example.com/test>
+PASS Parsing: </test.txt> against <http://www.example.com/test>
+PASS Parsing: <.> against <http://www.example.com/test>
+PASS Parsing: <..> against <http://www.example.com/test>
+PASS Parsing: <test.txt> against <http://www.example.com/test>
+PASS Parsing: <./test.txt> against <http://www.example.com/test>
+PASS Parsing: <../test.txt> against <http://www.example.com/test>
+PASS Parsing: <../aaa/test.txt> against <http://www.example.com/test>
+PASS Parsing: <../../test.txt> against <http://www.example.com/test>
+PASS Parsing: <中/test.txt> against <http://www.example.com/test>
+PASS Parsing: <http://www.example2.com> against <http://www.example.com/test>
+PASS Parsing: <//www.example2.com> against <http://www.example.com/test>
+PASS Parsing: <file:...> against <http://www.example.com/test>
+PASS Parsing: <file:..> against <http://www.example.com/test>
+PASS Parsing: <file:a> against <http://www.example.com/test>
+PASS Parsing: <http://ExAmPlE.CoM> against <http://other.com/>
+FAIL Parsing: <http://example example.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://Goo%20 goo%7C|.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://[]> against <http://other.com/> assert_equals: failure should set href to input expected "http://[]" but got "http://[]/"
+FAIL Parsing: <http://[:]> against <http://other.com/> assert_equals: failure should set href to input expected "http://[:]" but got "http://[:]/"
+FAIL Parsing: <http://GOO  goo.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://GOO​⁠goo.com> against <http://other.com/>
+PASS Parsing: <\0 http://example.com/ \r > against <about:blank>
+PASS Parsing: <http://www.foo。bar.com> against <http://other.com/>
+FAIL Parsing: <http://﷐zyx.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://﷐zyx.com" but got "http://%EF%BF%BDzyx.com/"
+FAIL Parsing: <http://%ef%b7%90zyx.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://%ef%b7%90zyx.com" but got "http://%EF%BF%BDzyx.com/"
+FAIL Parsing: <https://�> against <about:blank> assert_equals: failure should set href to input expected "https://\ufffd" but got "https://%EF%BF%BD/"
+FAIL Parsing: <https://%EF%BF%BD> against <about:blank> assert_equals: failure should set href to input expected "https://%EF%BF%BD" but got "https://%EF%BF%BD/"
+PASS Parsing: <https://x/�?�#�> against <about:blank>
+FAIL Parsing: <http://a.b.c.xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a.b.c.XN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a.b.c.Xn--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.XN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://10.0.0.xN--pokxncvks> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://Go.com> against <http://other.com/>
+FAIL Parsing: <http://%41.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://%ef%bc%85%ef%bc%94%ef%bc%91.com> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://%00.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://%00.com" but got "http://%00.com/"
+FAIL Parsing: <http://%ef%bc%85%ef%bc%90%ef%bc%90.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://%ef%bc%85%ef%bc%90%ef%bc%90.com" but got "http://%00.com/"
+PASS Parsing: <http://你好你好> against <http://other.com/>
+FAIL Parsing: <https://faß.ExAmPlE/> against <about:blank> assert_equals: href expected "https://xn--fa-hia.example/" but got "https://fass.example/"
+FAIL Parsing: <sc://faß.ExAmPlE/> against <about:blank> assert_equals: host expected "fa%C3%9F.ExAmPlE" but got ""
+FAIL Parsing: <http://%zz%66%a.com> against <http://other.com/> assert_equals: failure should set href to input expected "http://%zz%66%a.com" but got "http://%25zzf%25a.com/"
+FAIL Parsing: <http://%25> against <http://other.com/> assert_equals: failure should set href to input expected "http://%25" but got "http://%25/"
+FAIL Parsing: <http://hello%00> against <http://other.com/> assert_equals: failure should set href to input expected "http://hello%00" but got "http://hello%00/"
+PASS Parsing: <http://%30%78%63%30%2e%30%32%35%30.01> against <http://other.com/>
+PASS Parsing: <http://%30%78%63%30%2e%30%32%35%30.01%2e> against <http://other.com/>
+FAIL Parsing: <http://192.168.0.257> against <http://other.com/> assert_equals: failure should set href to input expected "http://192.168.0.257" but got "http://192.168.0.257/"
+FAIL Parsing: <http://%3g%78%63%30%2e%30%32%35%30%2E.01> against <http://other.com/> assert_equals: failure should set href to input expected "http://%3g%78%63%30%2e%30%32%35%30%2E.01" but got "http://%253gxc0.0250..01/"
+FAIL Parsing: <http://192.168.0.1 hello> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <https://x x:12> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://0Xc0.0250.01> against <http://other.com/>
+PASS Parsing: <http://./> against <about:blank>
+PASS Parsing: <http://../> against <about:blank>
+PASS Parsing: <http://[www.google.com]/> against <about:blank>
+FAIL Parsing: <http://[google.com]> against <http://other.com/> assert_equals: failure should set href to input expected "http://[google.com]" but got "http://[google.com]/"
+FAIL Parsing: <http://[::1.2.3.4x]> against <http://other.com/> assert_equals: failure should set href to input expected "http://[::1.2.3.4x]" but got "http://[::1.2.3.4x]/"
+FAIL Parsing: <http://[::1.2.3.]> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://[::1.2.]> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://[::1.]> against <http://other.com/> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://foo:💩@example.com/bar> against <http://other.com/>
+PASS Parsing: <#> against <test:test>
+PASS Parsing: <#x> against <mailto:x@x.com>
+FAIL Parsing: <#x> against <data:,> assert_equals: href expected "data:,#x" but got "mailto:x@x.com#x"
+PASS Parsing: <#x> against <about:blank>
+PASS Parsing: <#> against <test:test?test>
+PASS Parsing: <https://@test@test@example:800/> against <http://doesnotmatter/>
+PASS Parsing: <https://@@@example> against <http://doesnotmatter/>
+PASS Parsing: <http://`{}:`{}@h/`{}?`{}> against <http://doesnotmatter/>
+PASS Parsing: <http://host/?'> against <about:blank>
+FAIL Parsing: <notspecial://host/?'> against <about:blank> assert_equals: href expected "notspecial://host/?'" but got "notspecial://host/?%27"
+PASS Parsing: </some/path> against <http://user@example.org/smth>
+PASS Parsing: <> against <http://user:pass@example.org:21/smth>
+PASS Parsing: </some/path> against <http://user:pass@example.org:21/smth>
+FAIL Parsing: <i> against <sc:sd> assert_equals: failure should set href to input expected "i" but got ""
+FAIL Parsing: <i> against <sc:sd/sd> assert_equals: failure should set href to input expected "i" but got ""
+PASS Parsing: <i> against <sc:/pa/pa>
+FAIL Parsing: <i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: <i> against <sc:///pa/pa> assert_equals: pathname expected "/pa/i" but got "///pa/i"
+FAIL Parsing: <../i> against <sc:sd> assert_equals: failure should set href to input expected "../i" but got ""
+FAIL Parsing: <../i> against <sc:sd/sd> assert_equals: failure should set href to input expected "../i" but got ""
+PASS Parsing: <../i> against <sc:/pa/pa>
+FAIL Parsing: <../i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: <../i> against <sc:///pa/pa> assert_equals: href expected "sc:///i" but got "sc:///pa/i"
+FAIL Parsing: </i> against <sc:sd> assert_equals: failure should set href to input expected "/i" but got ""
+FAIL Parsing: </i> against <sc:sd/sd> assert_equals: failure should set href to input expected "/i" but got ""
+PASS Parsing: </i> against <sc:/pa/pa>
+FAIL Parsing: </i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: </i> against <sc:///pa/pa> assert_equals: href expected "sc:///i" but got "sc:///pa/i"
+FAIL Parsing: <?i> against <sc:sd> assert_equals: failure should set href to input expected "?i" but got ""
+FAIL Parsing: <?i> against <sc:sd/sd> assert_equals: failure should set href to input expected "?i" but got ""
+PASS Parsing: <?i> against <sc:/pa/pa>
+FAIL Parsing: <?i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: <?i> against <sc:///pa/pa> assert_equals: pathname expected "/pa/pa" but got "///pa/pa"
+PASS Parsing: <#i> against <sc:sd>
+PASS Parsing: <#i> against <sc:sd/sd>
+PASS Parsing: <#i> against <sc:/pa/pa>
+FAIL Parsing: <#i> against <sc://ho/pa> assert_equals: host expected "ho" but got ""
+FAIL Parsing: <#i> against <sc:///pa/pa> assert_equals: pathname expected "/pa/pa" but got "///pa/pa"
+FAIL Parsing: <about:/../> against <about:blank> assert_equals: href expected "about:/" but got "about:/../"
+FAIL Parsing: <data:/../> against <about:blank> assert_equals: href expected "data:/" but got "data:/../"
+FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
+FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
+FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
+FAIL Parsing: <sc://\0/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc:// /> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
+FAIL Parsing: <sc://@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://te@s:t@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://:/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://:12/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://[/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://\/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://]/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1/x" but got "sc://%C3%B1"
+PASS Parsing: <sc:\../> against <about:blank>
+PASS Parsing: <sc::a@example.net> against <about:blank>
+PASS Parsing: <wow:%NBD> against <about:blank>
+PASS Parsing: <wow:%1G> against <about:blank>
+FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
+FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: href expected "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF" but got "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD"
+FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
+FAIL Parsing: <non-special://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <non-special://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <non-special://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <foo://ho|st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <foo://ho
+st/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+PASS Parsing: <http://ho%00st/> against <about:blank>
+PASS Parsing: <http://ho%09st/> against <about:blank>
+PASS Parsing: <http://ho%0Ast/> against <about:blank>
+PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%20st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ho%23st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%2Fst/> against <about:blank>
+FAIL Parsing: <http://ho%3Ast/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%3Ast/" but got "http://ho:st/"
+FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ho%3Est/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%3Fst/> against <about:blank>
+FAIL Parsing: <http://ho%40st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ho%5Bst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Bst/" but got "http://ho[st/"
+PASS Parsing: <http://ho%5Cst/> against <about:blank>
+FAIL Parsing: <http://ho%5Dst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Dst/" but got "http://ho]st/"
+FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%1F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <ftp://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%80/" but got "ftp://example.com%EF%BF%BD/"
+FAIL Parsing: <ftp://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%A0/" but got "ftp://example.com%EF%BF%BD/"
+FAIL Parsing: <https://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%80/" but got "https://example.com%EF%BF%BD/"
+FAIL Parsing: <https://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%A0/" but got "https://example.com%EF%BF%BD/"
+PASS Parsing: <ftp://%e2%98%83> against <about:blank>
+PASS Parsing: <https://%e2%98%83> against <about:blank>
+PASS Parsing: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
+PASS Parsing: <http://facebook.com/?foo=%7B%22abc%22> against <about:blank>
+PASS Parsing: <https://localhost:3000/jqueryui@1.2.3> against <about:blank>
+PASS Parsing: <h	t
+t\rp://h	o
+s\rt:9	0
+0\r0/p	a
+t\rh?q	u
+e\rry#f	r
+a\rg> against <about:blank>
+PASS Parsing: <?a=b&c=d> against <http://example.org/foo/bar>
+PASS Parsing: <??a=b&c=d> against <http://example.org/foo/bar>
+PASS Parsing: <http:> against <http://example.org/foo/bar>
+PASS Parsing: <http:> against <https://example.org/foo/bar>
+PASS Parsing: <sc:> against <https://example.org/foo/bar>
+PASS Parsing: <http://foo.bar/baz?qux#foobar> against <about:blank>
+PASS Parsing: <http://foo.bar/baz?qux#foo"bar> against <about:blank>
+PASS Parsing: <http://foo.bar/baz?qux#foo<bar> against <about:blank>
+PASS Parsing: <http://foo.bar/baz?qux#foo>bar> against <about:blank>
+PASS Parsing: <http://foo.bar/baz?qux#foo`bar> against <about:blank>
+PASS Parsing: <http://1.2.3.4/> against <http://other.com/>
+PASS Parsing: <http://1.2.3.4./> against <http://other.com/>
+PASS Parsing: <http://192.168.257> against <http://other.com/>
+PASS Parsing: <http://192.168.257.> against <http://other.com/>
+PASS Parsing: <http://192.168.257.com> against <http://other.com/>
+PASS Parsing: <http://256> against <http://other.com/>
+PASS Parsing: <http://256.com> against <http://other.com/>
+PASS Parsing: <http://999999999> against <http://other.com/>
+PASS Parsing: <http://999999999.> against <http://other.com/>
+PASS Parsing: <http://999999999.com> against <http://other.com/>
+FAIL Parsing: <http://10000000000> against <http://other.com/> assert_equals: failure should set href to input expected "http://10000000000" but got "http://10000000000/"
+PASS Parsing: <http://10000000000.com> against <http://other.com/>
+PASS Parsing: <http://4294967295> against <http://other.com/>
+FAIL Parsing: <http://4294967296> against <http://other.com/> assert_equals: failure should set href to input expected "http://4294967296" but got "http://4294967296/"
+PASS Parsing: <http://0xffffffff> against <http://other.com/>
+FAIL Parsing: <http://0xffffffff1> against <http://other.com/> assert_equals: failure should set href to input expected "http://0xffffffff1" but got "http://0xffffffff1/"
+FAIL Parsing: <http://256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256" but got "http://256.256.256.256/"
+PASS Parsing: <https://0x.0x.0> against <about:blank>
+PASS Parsing: <https://0x100000000/test> against <about:blank>
+PASS Parsing: <https://256.0.0.1/test> against <about:blank>
+PASS Parsing: <file:///C%3A/> against <about:blank>
+PASS Parsing: <file:///C%7C/> against <about:blank>
+FAIL Parsing: <file://%43%3A> against <about:blank> assert_equals: failure should set href to input expected "file://%43%3A" but got "file://c:/"
+FAIL Parsing: <file://%43%7C> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <file://%43|> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <file://C%7C> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <file://%43%7C/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <https://%43%7C/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <asdf://%43|/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <asdf://%43%7C/> against <about:blank> assert_equals: host expected "%43%7C" but got ""
+PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
+FAIL Parsing: <..> against <file:///C:/> assert_equals: href expected "file:///C:/" but got "file:///"
+PASS Parsing: <..> against <file:///>
+FAIL Parsing: </> against <file:///C:/a/b> assert_equals: href expected "file:///C:/" but got "file:///"
+FAIL Parsing: </> against <file://h/C:/a/b> assert_equals: href expected "file://h/C:/" but got "file://h/"
+PASS Parsing: </> against <file://h/a/b>
+FAIL Parsing: <//d:> against <file:///C:/a/b> assert_equals: href expected "file:///d:" but got "file://d:/"
+FAIL Parsing: <//d:/..> against <file:///C:/a/b> assert_equals: href expected "file:///d:/" but got "file://d:/"
+PASS Parsing: <..> against <file:///ab:/>
+PASS Parsing: <..> against <file:///1:/>
+PASS Parsing: <> against <file:///test?test#test>
+PASS Parsing: <file:> against <file:///test?test#test>
+PASS Parsing: <?x> against <file:///test?test#test>
+PASS Parsing: <file:?x> against <file:///test?test#test>
+PASS Parsing: <#x> against <file:///test?test#test>
+PASS Parsing: <file:#x> against <file:///test?test#test>
+FAIL Parsing: <file:\\//> against <about:blank> assert_equals: href expected "file:////" but got "file:///"
+FAIL Parsing: <file:\\\\> against <about:blank> assert_equals: href expected "file:////" but got "file:///"
+FAIL Parsing: <file:\\\\?fox> against <about:blank> assert_equals: href expected "file:////?fox" but got "file:///?fox"
+FAIL Parsing: <file:\\\\#guppy> against <about:blank> assert_equals: href expected "file:////#guppy" but got "file:///#guppy"
+PASS Parsing: <file://spider///> against <about:blank>
+FAIL Parsing: <file:\\localhost//> against <about:blank> assert_equals: href expected "file:////" but got "file://localhost//"
+PASS Parsing: <file:///localhost//cat> against <about:blank>
+FAIL Parsing: <file://\/localhost//cat> against <about:blank> assert_equals: href expected "file:////localhost//cat" but got "file:///localhost//cat"
+FAIL Parsing: <file://localhost//a//../..//> against <about:blank> assert_equals: href expected "file://///" but got "file://localhost///"
+FAIL Parsing: </////mouse> against <file:///elephant> assert_equals: href expected "file://///mouse" but got "file:///mouse"
+PASS Parsing: <\//pig> against <file://lion/>
+FAIL Parsing: <\/localhost//pig> against <file://lion/> assert_equals: href expected "file:////pig" but got "file://localhost//pig"
+FAIL Parsing: <//localhost//pig> against <file://lion/> assert_equals: href expected "file:////pig" but got "file://localhost//pig"
+PASS Parsing: </..//localhost//pig> against <file://lion/>
+PASS Parsing: <file://> against <file://ape/>
+PASS Parsing: </rooibos> against <file://tea/>
+PASS Parsing: </?chai> against <file://tea/>
+FAIL Parsing: <C|> against <file://host/dir/file> assert_equals: href expected "file://host/C:" but got "file://host/dir/C%7C"
+FAIL Parsing: <C|> against <file://host/D:/dir1/dir2/file> assert_equals: href expected "file://host/C:" but got "file://host/D:/dir1/dir2/C%7C"
+FAIL Parsing: <C|#> against <file://host/dir/file> assert_equals: href expected "file://host/C:#" but got "file://host/dir/C%7C#"
+FAIL Parsing: <C|?> against <file://host/dir/file> assert_equals: href expected "file://host/C:?" but got "file://host/dir/C%7C?"
+FAIL Parsing: <C|/> against <file://host/dir/file> assert_equals: href expected "file://host/C:/" but got "file://host/dir/C%7C/"
+FAIL Parsing: <C|
+/> against <file://host/dir/file> assert_equals: href expected "file://host/C:/" but got "file://host/dir/C%7C/"
+FAIL Parsing: <C|\> against <file://host/dir/file> assert_equals: href expected "file://host/C:/" but got "file://host/dir/C%7C/"
+PASS Parsing: <C> against <file://host/dir/file>
+FAIL Parsing: <C|a> against <file://host/dir/file> assert_equals: href expected "file://host/dir/C|a" but got "file://host/dir/C%7Ca"
+PASS Parsing: </c:/foo/bar> against <file:///c:/baz/qux>
+FAIL Parsing: </c|/foo/bar> against <file:///c:/baz/qux> assert_equals: href expected "file:///c:/foo/bar" but got "file:///c%7C/foo/bar"
+PASS Parsing: <file:\c:\foo\bar> against <file:///c:/baz/qux>
+PASS Parsing: </c:/foo/bar> against <file://host/path>
+PASS Parsing: <file://example.net/C:/> against <about:blank>
+PASS Parsing: <file://1.2.3.4/C:/> against <about:blank>
+PASS Parsing: <file://[1::8]/C:/> against <about:blank>
+FAIL Parsing: <C|/> against <file://host/> assert_equals: href expected "file://host/C:/" but got "file://host/C%7C/"
+PASS Parsing: </C:/> against <file://host/>
+PASS Parsing: <file:C:/> against <file://host/>
+PASS Parsing: <file:/C:/> against <file://host/>
+FAIL Parsing: <//C:/> against <file://host/> assert_equals: href expected "file:///C:/" but got "file://c:/"
+FAIL Parsing: <file://C:/> against <file://host/> assert_equals: href expected "file:///C:/" but got "file://c:/"
+PASS Parsing: <///C:/> against <file://host/>
+PASS Parsing: <file:///C:/> against <file://host/>
+FAIL Parsing: <file:/C|/> against <about:blank> assert_equals: href expected "file:///C:/" but got "file:///C%7C/"
+FAIL Parsing: <file://C|/> against <about:blank> assert_equals: href expected "file:///C:/" but got "file://c%7C/"
+PASS Parsing: <file:> against <about:blank>
+PASS Parsing: <file:?q=v> against <about:blank>
+PASS Parsing: <file:#frag> against <about:blank>
+PASS Parsing: <file:///Y:> against <about:blank>
+PASS Parsing: <file:///Y:/> against <about:blank>
+PASS Parsing: <file:///./Y> against <about:blank>
+PASS Parsing: <file:///./Y:> against <about:blank>
+FAIL Parsing: <\\\.\Y:> against <about:blank> assert_equals: failure should set href to input expected "\\\\\\.\\Y:" but got ""
+PASS Parsing: <file:///y:> against <about:blank>
+PASS Parsing: <file:///y:/> against <about:blank>
+PASS Parsing: <file:///./y> against <about:blank>
+PASS Parsing: <file:///./y:> against <about:blank>
+FAIL Parsing: <\\\.\y:> against <about:blank> assert_equals: failure should set href to input expected "\\\\\\.\\y:" but got ""
+FAIL Parsing: <file://localhost//a//../..//foo> against <about:blank> assert_equals: href expected "file://///foo" but got "file://localhost///foo"
+FAIL Parsing: <file://localhost////foo> against <about:blank> assert_equals: href expected "file://////foo" but got "file://localhost////foo"
+FAIL Parsing: <file:////foo> against <about:blank> assert_equals: href expected "file:////foo" but got "file:///foo"
+PASS Parsing: <file:///one/two> against <file:///>
+FAIL Parsing: <file:////one/two> against <file:///> assert_equals: href expected "file:////one/two" but got "file:///one/two"
+PASS Parsing: <//one/two> against <file:///>
+PASS Parsing: <///one/two> against <file:///>
+FAIL Parsing: <////one/two> against <file:///> assert_equals: href expected "file:////one/two" but got "file:///one/two"
+PASS Parsing: <file:///.//> against <file:////>
+PASS Parsing: <file:.//p> against <about:blank>
+PASS Parsing: <file:/.//p> against <about:blank>
+PASS Parsing: <http://[1:0::]> against <http://example.net/>
+FAIL Parsing: <http://[0:1:2:3:4:5:6:7:8]> against <http://example.net/> assert_equals: failure should set href to input expected "http://[0:1:2:3:4:5:6:7:8]" but got "http://[0:1:2:3:4:5:6:7:8]/"
+FAIL Parsing: <https://[0::0::0]> against <about:blank> assert_equals: failure should set href to input expected "https://[0::0::0]" but got "https://[0::0::0]/"
+FAIL Parsing: <https://[0:.0]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:.0]" but got "https://[0:.0]/"
+FAIL Parsing: <https://[0:0:]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:0:]" but got "https://[0:0:]/"
+FAIL Parsing: <https://[0:1:2:3:4:5:6:7.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:1:2:3:4:5:6:7.0.0.0.1]" but got "https://[0:1:2:3:4:5:6:7.0.0.0.1]/"
+FAIL Parsing: <https://[0:1.00.0.0.0]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:1.00.0.0.0]" but got "https://[0:1.00.0.0.0]/"
+FAIL Parsing: <https://[0:1.290.0.0.0]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:1.290.0.0.0]" but got "https://[0:1.290.0.0.0]/"
+FAIL Parsing: <https://[0:1.23.23]> against <about:blank> assert_equals: failure should set href to input expected "https://[0:1.23.23]" but got "https://[0:1.23.23]/"
+FAIL Parsing: <http://?> against <about:blank> assert_equals: failure should set href to input expected "http://?" but got "http:/?"
+FAIL Parsing: <http://#> against <about:blank> assert_equals: failure should set href to input expected "http://#" but got "http:/#"
+PASS Parsing: <http://f:4294967377/c> against <http://example.org/>
+PASS Parsing: <http://f:18446744073709551697/c> against <http://example.org/>
+PASS Parsing: <http://f:340282366920938463463374607431768211537/c> against <http://example.org/>
+FAIL Parsing: <sc://ñ> against <about:blank> assert_equals: host expected "%C3%B1" but got ""
+FAIL Parsing: <sc://ñ?x> against <about:blank> assert_equals: host expected "%C3%B1" but got ""
+FAIL Parsing: <sc://ñ#x> against <about:blank> assert_equals: host expected "%C3%B1" but got ""
+FAIL Parsing: <#x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1#x" but got "sc://%C3%B1"
+FAIL Parsing: <?x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1?x" but got "sc://%C3%B1"
+FAIL Parsing: <sc://?> against <about:blank> assert_equals: pathname expected "" but got "//"
+FAIL Parsing: <sc://#> against <about:blank> assert_equals: pathname expected "" but got "//"
+FAIL Parsing: <///> against <sc://x/> assert_equals: href expected "sc:///" but got "sc:"
+FAIL Parsing: <////> against <sc://x/> assert_equals: href expected "sc:////" but got "sc:"
+FAIL Parsing: <////x/> against <sc://x/> assert_equals: href expected "sc:////x/" but got "sc://x/"
+FAIL Parsing: <tftp://foobar.com/someconfig;mode=netascii> against <about:blank> assert_equals: host expected "foobar.com" but got ""
+FAIL Parsing: <telnet://user:pass@foobar.com:23/> against <about:blank> assert_equals: username expected "user" but got ""
+FAIL Parsing: <ut2004://10.10.10.10:7777/Index.ut2> against <about:blank> assert_equals: host expected "10.10.10.10:7777" but got ""
+FAIL Parsing: <redis://foo:bar@somehost:6379/0?baz=bam&qux=baz> against <about:blank> assert_equals: username expected "foo" but got ""
+FAIL Parsing: <rsync://foo@host:911/sup> against <about:blank> assert_equals: username expected "foo" but got ""
+FAIL Parsing: <git://github.com/foo/bar.git> against <about:blank> assert_equals: host expected "github.com" but got ""
+FAIL Parsing: <irc://myserver.com:6999/channel?passwd> against <about:blank> assert_equals: host expected "myserver.com:6999" but got ""
+FAIL Parsing: <dns://fw.example.org:9999/foo.bar.org?type=TXT> against <about:blank> assert_equals: host expected "fw.example.org:9999" but got ""
+FAIL Parsing: <ldap://localhost:389/ou=People,o=JNDITutorial> against <about:blank> assert_equals: host expected "localhost:389" but got ""
+FAIL Parsing: <git+https://github.com/foo/bar> against <about:blank> assert_equals: host expected "github.com" but got ""
+PASS Parsing: <urn:ietf:rfc:2648> against <about:blank>
+PASS Parsing: <tag:joe@example.org,2001:foo/bar> against <about:blank>
+FAIL Parsing: <non-spec:/.//> against <about:blank> assert_equals: pathname expected "//" but got "/.//"
+FAIL Parsing: <non-spec:/..//> against <about:blank> assert_equals: href expected "non-spec:/.//" but got "non-spec:/..//"
+FAIL Parsing: <non-spec:/a/..//> against <about:blank> assert_equals: href expected "non-spec:/.//" but got "non-spec:/a/..//"
+FAIL Parsing: <non-spec:/.//path> against <about:blank> assert_equals: pathname expected "//path" but got "/.//path"
+FAIL Parsing: <non-spec:/..//path> against <about:blank> assert_equals: href expected "non-spec:/.//path" but got "non-spec:/..//path"
+FAIL Parsing: <non-spec:/a/..//path> against <about:blank> assert_equals: href expected "non-spec:/.//path" but got "non-spec:/a/..//path"
+FAIL Parsing: </.//path> against <non-spec:/p> assert_equals: href expected "non-spec:/.//path" but got "non-spec://path"
+FAIL Parsing: </..//path> against <non-spec:/p> assert_equals: href expected "non-spec:/.//path" but got "non-spec://path"
+FAIL Parsing: <..//path> against <non-spec:/p> assert_equals: href expected "non-spec:/.//path" but got "non-spec://path"
+FAIL Parsing: <a/..//path> against <non-spec:/p> assert_equals: href expected "non-spec:/.//path" but got "non-spec://path"
+FAIL Parsing: <> against <non-spec:/..//p> assert_equals: href expected "non-spec:/.//p" but got "non-spec:/..//p"
+FAIL Parsing: <path> against <non-spec:/..//p> assert_equals: href expected "non-spec:/.//path" but got "non-spec:/..//path"
+FAIL Parsing: <../path> against <non-spec:/.//p> assert_equals: href expected "non-spec:/path" but got "non-spec:/./path"
+FAIL Parsing: <non-special://%E2%80%A0/> against <about:blank> assert_equals: host expected "%E2%80%A0" but got ""
+FAIL Parsing: <non-special://H%4fSt/path> against <about:blank> assert_equals: host expected "H%4fSt" but got ""
+FAIL Parsing: <non-special://[1:2:0:0:5:0:0:0]/> against <about:blank> assert_equals: href expected "non-special://[1:2:0:0:5::]/" but got "non-special://[1:2:0:0:5:0:0:0]/"
+FAIL Parsing: <non-special://[1:2:0:0:0:0:0:3]/> against <about:blank> assert_equals: href expected "non-special://[1:2::3]/" but got "non-special://[1:2:0:0:0:0:0:3]/"
+FAIL Parsing: <non-special://[1:2::3]:80/> against <about:blank> assert_equals: host expected "[1:2::3]:80" but got ""
+FAIL Parsing: <non-special://[:80/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <blob:https://example.com:443/> against <about:blank>
+PASS Parsing: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
+PASS Parsing: <blob:> against <about:blank>
+PASS Parsing: <http://0x7f.0.0.0x7g> against <about:blank>
+PASS Parsing: <http://0X7F.0.0.0X7G> against <about:blank>
+FAIL Parsing: <http://[::127.0.0.0.1]> against <about:blank> assert_equals: failure should set href to input expected "http://[::127.0.0.0.1]" but got "http://[::127.0.0.0.1]/"
+PASS Parsing: <http://[0:1:0:1:0:1:0:1]> against <about:blank>
+PASS Parsing: <http://[1:0:1:0:1:0:1:0]> against <about:blank>
+PASS Parsing: <http://example.org/test?"> against <about:blank>
+PASS Parsing: <http://example.org/test?#> against <about:blank>
+PASS Parsing: <http://example.org/test?<> against <about:blank>
+PASS Parsing: <http://example.org/test?>> against <about:blank>
+PASS Parsing: <http://example.org/test?⌣> against <about:blank>
+PASS Parsing: <http://example.org/test?%23%23> against <about:blank>
+PASS Parsing: <http://example.org/test?%GH> against <about:blank>
+PASS Parsing: <http://example.org/test?a#%EF> against <about:blank>
+PASS Parsing: <http://example.org/test?a#%GH> against <about:blank>
+FAIL Parsing: <a> against <about:blank> assert_equals: failure should set href to input expected "a" but got ""
+FAIL Parsing: <a/> against <about:blank> assert_equals: failure should set href to input expected "a/" but got ""
+FAIL Parsing: <a//> against <about:blank> assert_equals: failure should set href to input expected "a//" but got ""
+FAIL Parsing: <test-a-colon.html> against <a:> assert_equals: failure should set href to input expected "test-a-colon.html" but got ""
+FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got ""
+PASS Parsing: <test-a-colon-slash.html> against <a:/>
+FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got ""
+PASS Parsing: <test-a-colon-slash-b.html> against <a:/b>
+FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> assert_equals: href expected "a://b/test-a-colon-slash-slash-b.html" but got "a://b"
+PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
+FAIL Parsing: <non-spec://example.org/test?a#b\0c> against <about:blank> assert_equals: host expected "example.org" but got ""
+PASS Parsing: <non-spec:/test?a#b\0c> against <about:blank>
+PASS Parsing: <10.0.0.7:8080/foo.html> against <file:///some/dir/bar.html>
+PASS Parsing: <a!@$*=/foo.html> against <file:///some/dir/bar.html>
+PASS Parsing: <a1234567890-+.:foo/bar> against <http://example.com/dir/file>
+PASS Parsing: <file://a­b/p> against <about:blank>
+PASS Parsing: <file://a%C2%ADb/p> against <about:blank>
+FAIL Parsing: <file://­/p> against <about:blank> assert_equals: failure should set href to input expected "file://­/p" but got "file://%C2%AD/p"
+PASS Parsing: <file://%C2%AD/p> against <about:blank>
+FAIL Parsing: <file://xn--/p> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <#link> against <https://example.org/##link>
+PASS Parsing: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
+PASS Parsing: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
+PASS Parsing: <https://user:pass[@foo/bar> against <http://example.org>
+FAIL Parsing: <foo:// !"$%&'()*+,-.;<=>@[\]^_`{|}~@host/> against <about:blank> assert_equals: href expected "foo://%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~@host/" but got "foo:// !\"$%&'()*+,-.;<=>@[\\]^_`{|}~@host/"
+FAIL Parsing: <wss:// !"$%&'()*+,-.;<=>@[]^_`{|}~@host/> against <about:blank> assert_equals: href expected "wss://%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/" but got "wss://%20!%22$%&%27()*+,-.%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/"
+FAIL Parsing: <foo://joe: !"$%&'()*+,-.:;<=>@[\]^_`{|}~@host/> against <about:blank> assert_equals: href expected "foo://joe:%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~@host/" but got "foo://joe: !\"$%&'()*+,-.:;<=>@[\\]^_`{|}~@host/"
+FAIL Parsing: <wss://joe: !"$%&'()*+,-.:;<=>@[]^_`{|}~@host/> against <about:blank> assert_equals: href expected "wss://joe:%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/" but got "wss://joe:%20!%22$%&%27()*+,-.%3A%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/"
+FAIL Parsing: <foo://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "!\"$%&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <wss://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "wss://!\"$&'()*+,-.;=_`{}~/" but got "wss://%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <foo://host/ !"$%&'()*+,-./:;<=>@[\]^_`{|}~> against <about:blank> assert_equals: href expected "foo://host/%20!%22$%&'()*+,-./:;%3C=%3E@[\\]^_%60%7B|%7D~" but got "foo://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~"
+FAIL Parsing: <wss://host/ !"$%&'()*+,-./:;<=>@[\]^_`{|}~> against <about:blank> assert_equals: href expected "wss://host/%20!%22$%&'()*+,-./:;%3C=%3E@[/]^_%60%7B|%7D~" but got "wss://host/%20!%22$%&'()*+,-./:;%3C=%3E@[/]%5E_%60%7B%7C%7D~"
+FAIL Parsing: <foo://host/dir/? !"$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank> assert_equals: href expected "foo://host/dir/?%20!%22$%&'()*+,-./:;%3C=%3E?@[\\]^_`{|}~" but got "foo://host/dir/?%20!%22$%&%27()*+,-./:;%3C=%3E?@[\\]^_`{|}~"
+PASS Parsing: <wss://host/dir/? !"$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+FAIL Parsing: <foo://host/dir/# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank> assert_equals: host expected "host" but got ""
+PASS Parsing: <wss://host/dir/# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+FAIL Parsing: <abc:rootless> against <abc://host/path> assert_equals: href expected "abc:rootless" but got "abc://host/rootless"
+FAIL Parsing: <abc:rootless> against <abc:/path> assert_equals: href expected "abc:rootless" but got "abc:/rootless"
+PASS Parsing: <abc:rootless> against <abc:path>
+FAIL Parsing: <abc:/rooted> against <abc://host/path> assert_equals: href expected "abc:/rooted" but got "abc://host/rooted"
+FAIL Parsing: <http://1.2.3.4.5> against <http://other.com/> assert_equals: failure should set href to input expected "http://1.2.3.4.5" but got "http://1.2.3.4.5/"
+FAIL Parsing: <http://1.2.3.4.5.> against <http://other.com/> assert_equals: failure should set href to input expected "http://1.2.3.4.5." but got "http://1.2.3.4.5./"
+PASS Parsing: <http://0..0x300/> against <about:blank>
+PASS Parsing: <http://0..0x300./> against <about:blank>
+FAIL Parsing: <http://256.256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256.256" but got "http://256.256.256.256.256/"
+FAIL Parsing: <http://256.256.256.256.256.> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256.256." but got "http://256.256.256.256.256./"
+FAIL Parsing: <http://1.2.3.08> against <about:blank> assert_equals: failure should set href to input expected "http://1.2.3.08" but got "http://1.2.3.08/"
+FAIL Parsing: <http://1.2.3.08.> against <about:blank> assert_equals: failure should set href to input expected "http://1.2.3.08." but got "http://1.2.3.08./"
+FAIL Parsing: <http://1.2.3.09> against <about:blank> assert_equals: failure should set href to input expected "http://1.2.3.09" but got "http://1.2.3.09/"
+FAIL Parsing: <http://09.2.3.4> against <about:blank> assert_equals: failure should set href to input expected "http://09.2.3.4" but got "http://09.2.3.4/"
+FAIL Parsing: <http://09.2.3.4.> against <about:blank> assert_equals: failure should set href to input expected "http://09.2.3.4." but got "http://09.2.3.4./"
+FAIL Parsing: <http://01.2.3.4.5> against <about:blank> assert_equals: failure should set href to input expected "http://01.2.3.4.5" but got "http://01.2.3.4.5/"
+FAIL Parsing: <http://01.2.3.4.5.> against <about:blank> assert_equals: failure should set href to input expected "http://01.2.3.4.5." but got "http://01.2.3.4.5./"
+FAIL Parsing: <http://0x100.2.3.4> against <about:blank> assert_equals: failure should set href to input expected "http://0x100.2.3.4" but got "http://0x100.2.3.4/"
+FAIL Parsing: <http://0x100.2.3.4.> against <about:blank> assert_equals: failure should set href to input expected "http://0x100.2.3.4." but got "http://0x100.2.3.4./"
+FAIL Parsing: <http://0x1.2.3.4.5> against <about:blank> assert_equals: failure should set href to input expected "http://0x1.2.3.4.5" but got "http://0x1.2.3.4.5/"
+FAIL Parsing: <http://0x1.2.3.4.5.> against <about:blank> assert_equals: failure should set href to input expected "http://0x1.2.3.4.5." but got "http://0x1.2.3.4.5./"
+FAIL Parsing: <http://foo.1.2.3.4> against <about:blank> assert_equals: failure should set href to input expected "http://foo.1.2.3.4" but got "http://foo.1.2.3.4/"
+FAIL Parsing: <http://foo.1.2.3.4.> against <about:blank> assert_equals: failure should set href to input expected "http://foo.1.2.3.4." but got "http://foo.1.2.3.4./"
+FAIL Parsing: <http://foo.2.3.4> against <about:blank> assert_equals: failure should set href to input expected "http://foo.2.3.4" but got "http://foo.2.3.4/"
+FAIL Parsing: <http://foo.2.3.4.> against <about:blank> assert_equals: failure should set href to input expected "http://foo.2.3.4." but got "http://foo.2.3.4./"
+FAIL Parsing: <http://foo.09> against <about:blank> assert_equals: failure should set href to input expected "http://foo.09" but got "http://foo.09/"
+FAIL Parsing: <http://foo.09.> against <about:blank> assert_equals: failure should set href to input expected "http://foo.09." but got "http://foo.09./"
+FAIL Parsing: <http://foo.0x4> against <about:blank> assert_equals: failure should set href to input expected "http://foo.0x4" but got "http://foo.0x4/"
+FAIL Parsing: <http://foo.0x4.> against <about:blank> assert_equals: failure should set href to input expected "http://foo.0x4." but got "http://foo.0x4./"
+PASS Parsing: <http://foo.09..> against <about:blank>
+PASS Parsing: <http://0999999999999999999/> against <about:blank>
+FAIL Parsing: <http://foo.0x> against <about:blank> assert_equals: failure should set href to input expected "http://foo.0x" but got "http://foo.0x/"
+FAIL Parsing: <http://foo.0XFfFfFfFfFfFfFfFfFfAcE123> against <about:blank> assert_equals: failure should set href to input expected "http://foo.0XFfFfFfFfFfFfFfFfFfAcE123" but got "http://foo.0xfffffffffffffffffface123/"
+FAIL Parsing: <http://💩.123/> against <about:blank> assert_equals: failure should set href to input expected "http://💩.123/" but got "http://xn--ls8h.123/"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/url/a-element-origin-expected.txt
new file mode 100644
index 0000000..0353e737
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/url/a-element-origin-expected.txt
@@ -0,0 +1,342 @@
+This is a testharness.js-based test.
+Found 329 tests; 324 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Loading data…
+PASS Parsing origin: <http://example	.
+org> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://user:pass@foo:21/bar;par?b#c> against <http://example.org/foo/bar>
+PASS Parsing origin: <https://test:@test> against <about:blank>
+PASS Parsing origin: <https://:@test> against <about:blank>
+PASS Parsing origin: <non-special://test:@test/x> against <about:blank>
+PASS Parsing origin: <non-special://:@test/x> against <about:blank>
+PASS Parsing origin: <http:foo.com> against <http://example.org/foo/bar>
+PASS Parsing origin: <	   :foo.com   
+> against <http://example.org/foo/bar>
+PASS Parsing origin: < foo.com  > against <http://example.org/foo/bar>
+PASS Parsing origin: <a:	 foo.com> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:21/ b ? d # e > against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:0/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:00000000000000/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:00000000000000000000080/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://f:
+/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <> against <http://example.org/foo/bar>
+PASS Parsing origin: <  	> against <http://example.org/foo/bar>
+PASS Parsing origin: <:foo.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <:foo.com\> against <http://example.org/foo/bar>
+PASS Parsing origin: <:> against <http://example.org/foo/bar>
+PASS Parsing origin: <:a> against <http://example.org/foo/bar>
+PASS Parsing origin: <:/> against <http://example.org/foo/bar>
+PASS Parsing origin: <:\> against <http://example.org/foo/bar>
+PASS Parsing origin: <:#> against <http://example.org/foo/bar>
+PASS Parsing origin: <#> against <http://example.org/foo/bar>
+PASS Parsing origin: <#/> against <http://example.org/foo/bar>
+PASS Parsing origin: <#\> against <http://example.org/foo/bar>
+PASS Parsing origin: <#;?> against <http://example.org/foo/bar>
+PASS Parsing origin: <?> against <http://example.org/foo/bar>
+PASS Parsing origin: </> against <http://example.org/foo/bar>
+PASS Parsing origin: <:23> against <http://example.org/foo/bar>
+PASS Parsing origin: </:23> against <http://example.org/foo/bar>
+PASS Parsing origin: <\x> against <http://example.org/foo/bar>
+PASS Parsing origin: <\\x\hello> against <http://example.org/foo/bar>
+PASS Parsing origin: <::> against <http://example.org/foo/bar>
+PASS Parsing origin: <::23> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo://> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://a:b@c:29/d> against <http://example.org/foo/bar>
+PASS Parsing origin: <http::@c:29> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://&a:foo(b]c@d:2/> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://::@c@d:2> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo.com:b@d/> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo.com/\@> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:\\foo.com\> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:\\a\b:c\d@foo.com\> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo:/> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo:/bar.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo://///////> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo://///////bar.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <foo:////://///> against <http://example.org/foo/bar>
+PASS Parsing origin: <c:/foo> against <http://example.org/foo/bar>
+PASS Parsing origin: <//foo/bar> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo/path;a??e#f#g> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo/abcd?efgh?ijkl> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://foo/abcd#foo?bar> against <http://example.org/foo/bar>
+PASS Parsing origin: <[61:24:74]:98> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:[61:27]/:foo> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://[2001::1]> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://[::127.0.0.1]> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://[0:0:0:0:0:0:13.1.68.3]> against <http://example.org/foo/bar>
+PASS Parsing origin: <http://[2001::1]:80> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ftp:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <https:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <madeupscheme:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ftps:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <gopher:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ws:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <wss:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <data:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <javascript:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <mailto:/example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ftp:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <https:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <madeupscheme:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ftps:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <gopher:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <ws:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <wss:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <data:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <javascript:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: <mailto:example.com/> against <http://example.org/foo/bar>
+PASS Parsing origin: </a/b/c> against <http://example.org/foo/bar>
+PASS Parsing origin: </a/ /c> against <http://example.org/foo/bar>
+PASS Parsing origin: </a%2fc> against <http://example.org/foo/bar>
+PASS Parsing origin: </a/%2f/c> against <http://example.org/foo/bar>
+PASS Parsing origin: <#β> against <http://example.org/foo/bar>
+PASS Parsing origin: <data:text/html,test#test> against <http://example.org/foo/bar>
+PASS Parsing origin: <tel:1234567890> against <http://example.org/foo/bar>
+PASS Parsing origin: <ssh://example.com/foo/bar.git> against <http://example.org/>
+PASS Parsing origin: <http://example.com/././foo> against <about:blank>
+PASS Parsing origin: <http://example.com/./.foo> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/.> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/./> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar/..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar/../> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/..bar> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar/../ton> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar/../ton/../../a> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/../../..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/../../../ton> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/%2e> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/%2e%2> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank>
+PASS Parsing origin: <http://example.com////../..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar//../..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo/bar//..> against <about:blank>
+PASS Parsing origin: <http://example.com/foo> against <about:blank>
+PASS Parsing origin: <http://example.com/%20foo> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%2> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%2zbar> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%2©zbar> against <about:blank>
+PASS Parsing origin: <http://example.com/foo%41%7a> against <about:blank>
+PASS Parsing origin: <http://example.com/foo	‘%91> against <about:blank>
+FAIL Parsing origin: <http://example.com/foo%00%51> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
+PASS Parsing origin: <http://example.com/(%28:%3A%29)> against <about:blank>
+PASS Parsing origin: <http://example.com/%3A%3a%3C%3c> against <about:blank>
+PASS Parsing origin: <http://example.com/foo	bar> against <about:blank>
+PASS Parsing origin: <http://example.com\\foo\\bar> against <about:blank>
+PASS Parsing origin: <http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd> against <about:blank>
+PASS Parsing origin: <http://example.com/@asdf%40> against <about:blank>
+PASS Parsing origin: <http://example.com/你好你好> against <about:blank>
+PASS Parsing origin: <http://example.com/‥/foo> against <about:blank>
+PASS Parsing origin: <http://example.com//foo> against <about:blank>
+PASS Parsing origin: <http://example.com/‮/foo/‭/bar> against <about:blank>
+PASS Parsing origin: <http://www.google.com/foo?bar=baz#> against <about:blank>
+PASS Parsing origin: <http://www.google.com/foo?bar=baz# »> against <about:blank>
+PASS Parsing origin: <data:test# »> against <about:blank>
+PASS Parsing origin: <http://www.google.com> against <about:blank>
+PASS Parsing origin: <http://192.0x00A80001> against <about:blank>
+PASS Parsing origin: <http://www/foo%2Ehtml> against <about:blank>
+PASS Parsing origin: <http://www/foo/%2E/html> against <about:blank>
+PASS Parsing origin: <http://%25DOMAIN:foobar@foodomain.com/> against <about:blank>
+PASS Parsing origin: <http:\\www.google.com\foo> against <about:blank>
+PASS Parsing origin: <http://foo:80/> against <about:blank>
+PASS Parsing origin: <http://foo:81/> against <about:blank>
+PASS Parsing origin: <httpa://foo:80/> against <about:blank>
+PASS Parsing origin: <https://foo:443/> against <about:blank>
+PASS Parsing origin: <https://foo:80/> against <about:blank>
+PASS Parsing origin: <ftp://foo:21/> against <about:blank>
+PASS Parsing origin: <ftp://foo:80/> against <about:blank>
+PASS Parsing origin: <gopher://foo:70/> against <about:blank>
+PASS Parsing origin: <gopher://foo:443/> against <about:blank>
+PASS Parsing origin: <ws://foo:80/> against <about:blank>
+PASS Parsing origin: <ws://foo:81/> against <about:blank>
+PASS Parsing origin: <ws://foo:443/> against <about:blank>
+PASS Parsing origin: <ws://foo:815/> against <about:blank>
+PASS Parsing origin: <wss://foo:80/> against <about:blank>
+PASS Parsing origin: <wss://foo:81/> against <about:blank>
+PASS Parsing origin: <wss://foo:443/> against <about:blank>
+PASS Parsing origin: <wss://foo:815/> against <about:blank>
+PASS Parsing origin: <http:/example.com/> against <about:blank>
+PASS Parsing origin: <ftp:/example.com/> against <about:blank>
+PASS Parsing origin: <https:/example.com/> against <about:blank>
+PASS Parsing origin: <madeupscheme:/example.com/> against <about:blank>
+PASS Parsing origin: <ftps:/example.com/> against <about:blank>
+PASS Parsing origin: <gopher:/example.com/> against <about:blank>
+PASS Parsing origin: <ws:/example.com/> against <about:blank>
+PASS Parsing origin: <wss:/example.com/> against <about:blank>
+PASS Parsing origin: <data:/example.com/> against <about:blank>
+PASS Parsing origin: <javascript:/example.com/> against <about:blank>
+PASS Parsing origin: <mailto:/example.com/> against <about:blank>
+PASS Parsing origin: <http:example.com/> against <about:blank>
+PASS Parsing origin: <ftp:example.com/> against <about:blank>
+PASS Parsing origin: <https:example.com/> against <about:blank>
+PASS Parsing origin: <madeupscheme:example.com/> against <about:blank>
+PASS Parsing origin: <ftps:example.com/> against <about:blank>
+PASS Parsing origin: <gopher:example.com/> against <about:blank>
+PASS Parsing origin: <ws:example.com/> against <about:blank>
+PASS Parsing origin: <wss:example.com/> against <about:blank>
+PASS Parsing origin: <data:example.com/> against <about:blank>
+PASS Parsing origin: <javascript:example.com/> against <about:blank>
+PASS Parsing origin: <mailto:example.com/> against <about:blank>
+PASS Parsing origin: <http:@www.example.com> against <about:blank>
+PASS Parsing origin: <http:/@www.example.com> against <about:blank>
+PASS Parsing origin: <http://@www.example.com> against <about:blank>
+PASS Parsing origin: <http:a:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http:/a:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http://a:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http://@pple.com> against <about:blank>
+PASS Parsing origin: <http::b@www.example.com> against <about:blank>
+PASS Parsing origin: <http:/:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http://:b@www.example.com> against <about:blank>
+PASS Parsing origin: <http:a:@www.example.com> against <about:blank>
+PASS Parsing origin: <http:/a:@www.example.com> against <about:blank>
+PASS Parsing origin: <http://a:@www.example.com> against <about:blank>
+PASS Parsing origin: <http://www.@pple.com> against <about:blank>
+PASS Parsing origin: <http://:@www.example.com> against <about:blank>
+PASS Parsing origin: </> against <http://www.example.com/test>
+PASS Parsing origin: </test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <.> against <http://www.example.com/test>
+PASS Parsing origin: <..> against <http://www.example.com/test>
+PASS Parsing origin: <test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <./test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <../test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <../aaa/test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <../../test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <中/test.txt> against <http://www.example.com/test>
+PASS Parsing origin: <http://www.example2.com> against <http://www.example.com/test>
+PASS Parsing origin: <//www.example2.com> against <http://www.example.com/test>
+PASS Parsing origin: <http://ExAmPlE.CoM> against <http://other.com/>
+PASS Parsing origin: <http://GOO​⁠goo.com> against <http://other.com/>
+PASS Parsing origin: <\0 http://example.com/ \r > against <about:blank>
+PASS Parsing origin: <http://www.foo。bar.com> against <http://other.com/>
+PASS Parsing origin: <https://x/�?�#�> against <about:blank>
+PASS Parsing origin: <http://Go.com> against <http://other.com/>
+PASS Parsing origin: <http://你好你好> against <http://other.com/>
+FAIL Parsing origin: <https://faß.ExAmPlE/> against <about:blank> assert_equals: origin expected "https://xn--fa-hia.example" but got "https://fass.example"
+PASS Parsing origin: <sc://faß.ExAmPlE/> against <about:blank>
+PASS Parsing origin: <http://%30%78%63%30%2e%30%32%35%30.01> against <http://other.com/>
+PASS Parsing origin: <http://%30%78%63%30%2e%30%32%35%30.01%2e> against <http://other.com/>
+PASS Parsing origin: <http://0Xc0.0250.01> against <http://other.com/>
+PASS Parsing origin: <http://./> against <about:blank>
+PASS Parsing origin: <http://../> against <about:blank>
+PASS Parsing origin: <http://foo:💩@example.com/bar> against <http://other.com/>
+PASS Parsing origin: <#> against <test:test>
+PASS Parsing origin: <#x> against <mailto:x@x.com>
+PASS Parsing origin: <#x> against <data:,>
+PASS Parsing origin: <#x> against <about:blank>
+PASS Parsing origin: <#> against <test:test?test>
+PASS Parsing origin: <https://@test@test@example:800/> against <http://doesnotmatter/>
+PASS Parsing origin: <https://@@@example> against <http://doesnotmatter/>
+PASS Parsing origin: <http://`{}:`{}@h/`{}?`{}> against <http://doesnotmatter/>
+PASS Parsing origin: <http://host/?'> against <about:blank>
+PASS Parsing origin: <notspecial://host/?'> against <about:blank>
+PASS Parsing origin: </some/path> against <http://user@example.org/smth>
+PASS Parsing origin: <> against <http://user:pass@example.org:21/smth>
+PASS Parsing origin: </some/path> against <http://user:pass@example.org:21/smth>
+PASS Parsing origin: <i> against <sc:/pa/pa>
+PASS Parsing origin: <i> against <sc://ho/pa>
+PASS Parsing origin: <i> against <sc:///pa/pa>
+PASS Parsing origin: <../i> against <sc:/pa/pa>
+PASS Parsing origin: <../i> against <sc://ho/pa>
+PASS Parsing origin: <../i> against <sc:///pa/pa>
+PASS Parsing origin: </i> against <sc:/pa/pa>
+PASS Parsing origin: </i> against <sc://ho/pa>
+PASS Parsing origin: </i> against <sc:///pa/pa>
+PASS Parsing origin: <?i> against <sc:/pa/pa>
+PASS Parsing origin: <?i> against <sc://ho/pa>
+PASS Parsing origin: <?i> against <sc:///pa/pa>
+PASS Parsing origin: <#i> against <sc:sd>
+PASS Parsing origin: <#i> against <sc:sd/sd>
+PASS Parsing origin: <#i> against <sc:/pa/pa>
+PASS Parsing origin: <#i> against <sc://ho/pa>
+PASS Parsing origin: <#i> against <sc:///pa/pa>
+PASS Parsing origin: <about:/../> against <about:blank>
+PASS Parsing origin: <data:/../> against <about:blank>
+PASS Parsing origin: <javascript:/../> against <about:blank>
+PASS Parsing origin: <mailto:/../> against <about:blank>
+PASS Parsing origin: <sc://ñ.test/> against <about:blank>
+PASS Parsing origin: <x> against <sc://ñ>
+PASS Parsing origin: <sc:\../> against <about:blank>
+PASS Parsing origin: <sc::a@example.net> against <about:blank>
+PASS Parsing origin: <wow:%NBD> against <about:blank>
+PASS Parsing origin: <wow:%1G> against <about:blank>
+PASS Parsing origin: <wow:￿> against <about:blank>
+FAIL Parsing origin: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
+FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+PASS Parsing origin: <ftp://%e2%98%83> against <about:blank>
+PASS Parsing origin: <https://%e2%98%83> against <about:blank>
+PASS Parsing origin: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
+PASS Parsing origin: <http://facebook.com/?foo=%7B%22abc%22> against <about:blank>
+PASS Parsing origin: <https://localhost:3000/jqueryui@1.2.3> against <about:blank>
+PASS Parsing origin: <h	t
+t\rp://h	o
+s\rt:9	0
+0\r0/p	a
+t\rh?q	u
+e\rry#f	r
+a\rg> against <about:blank>
+PASS Parsing origin: <?a=b&c=d> against <http://example.org/foo/bar>
+PASS Parsing origin: <??a=b&c=d> against <http://example.org/foo/bar>
+PASS Parsing origin: <http:> against <http://example.org/foo/bar>
+PASS Parsing origin: <sc:> against <https://example.org/foo/bar>
+PASS Parsing origin: <http://foo.bar/baz?qux#foobar> against <about:blank>
+PASS Parsing origin: <http://foo.bar/baz?qux#foo"bar> against <about:blank>
+PASS Parsing origin: <http://foo.bar/baz?qux#foo<bar> against <about:blank>
+PASS Parsing origin: <http://foo.bar/baz?qux#foo>bar> against <about:blank>
+PASS Parsing origin: <http://foo.bar/baz?qux#foo`bar> against <about:blank>
+PASS Parsing origin: <http://1.2.3.4/> against <http://other.com/>
+PASS Parsing origin: <http://1.2.3.4./> against <http://other.com/>
+PASS Parsing origin: <http://192.168.257> against <http://other.com/>
+PASS Parsing origin: <http://192.168.257.> against <http://other.com/>
+PASS Parsing origin: <http://192.168.257.com> against <http://other.com/>
+PASS Parsing origin: <http://256> against <http://other.com/>
+PASS Parsing origin: <http://256.com> against <http://other.com/>
+PASS Parsing origin: <http://999999999> against <http://other.com/>
+PASS Parsing origin: <http://999999999.> against <http://other.com/>
+PASS Parsing origin: <http://999999999.com> against <http://other.com/>
+PASS Parsing origin: <http://10000000000.com> against <http://other.com/>
+PASS Parsing origin: <http://4294967295> against <http://other.com/>
+PASS Parsing origin: <http://0xffffffff> against <http://other.com/>
+PASS Parsing origin: <https://0x.0x.0> against <about:blank>
+PASS Parsing origin: <asdf://%43%7C/> against <about:blank>
+PASS Parsing origin: <http://[1:0::]> against <http://example.net/>
+PASS Parsing origin: <sc://ñ> against <about:blank>
+PASS Parsing origin: <sc://ñ?x> against <about:blank>
+PASS Parsing origin: <sc://ñ#x> against <about:blank>
+PASS Parsing origin: <#x> against <sc://ñ>
+PASS Parsing origin: <?x> against <sc://ñ>
+PASS Parsing origin: <tftp://foobar.com/someconfig;mode=netascii> against <about:blank>
+PASS Parsing origin: <telnet://user:pass@foobar.com:23/> against <about:blank>
+PASS Parsing origin: <ut2004://10.10.10.10:7777/Index.ut2> against <about:blank>
+PASS Parsing origin: <redis://foo:bar@somehost:6379/0?baz=bam&qux=baz> against <about:blank>
+PASS Parsing origin: <rsync://foo@host:911/sup> against <about:blank>
+PASS Parsing origin: <git://github.com/foo/bar.git> against <about:blank>
+PASS Parsing origin: <irc://myserver.com:6999/channel?passwd> against <about:blank>
+PASS Parsing origin: <dns://fw.example.org:9999/foo.bar.org?type=TXT> against <about:blank>
+PASS Parsing origin: <ldap://localhost:389/ou=People,o=JNDITutorial> against <about:blank>
+PASS Parsing origin: <git+https://github.com/foo/bar> against <about:blank>
+PASS Parsing origin: <urn:ietf:rfc:2648> against <about:blank>
+PASS Parsing origin: <tag:joe@example.org,2001:foo/bar> against <about:blank>
+PASS Parsing origin: <blob:https://example.com:443/> against <about:blank>
+PASS Parsing origin: <blob:d3958f5c-0777-0845-9dcf-2cb28783acaf> against <about:blank>
+PASS Parsing origin: <blob:> against <about:blank>
+PASS Parsing origin: <non-special:cannot-be-a-base-url-\0~€> against <about:blank>
+PASS Parsing origin: <https://www.example.com/path{path.html?query'=query#fragment<fragment> against <about:blank>
+PASS Parsing origin: <https://user:pass[@foo/bar> against <http://example.org>
+PASS Parsing origin: <foo:// !"$%&'()*+,-.;<=>@[\]^_`{|}~@host/> against <about:blank>
+PASS Parsing origin: <wss:// !"$%&'()*+,-.;<=>@[]^_`{|}~@host/> against <about:blank>
+PASS Parsing origin: <foo://joe: !"$%&'()*+,-.:;<=>@[\]^_`{|}~@host/> against <about:blank>
+PASS Parsing origin: <wss://joe: !"$%&'()*+,-.:;<=>@[]^_`{|}~@host/> against <about:blank>
+PASS Parsing origin: <foo://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Parsing origin: <wss://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "wss://!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <foo://host/ !"$%&'()*+,-./:;<=>@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <wss://host/ !"$%&'()*+,-./:;<=>@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <foo://host/dir/? !"$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <wss://host/dir/? !"$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <foo://host/dir/# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+PASS Parsing origin: <wss://host/dir/# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~> against <about:blank>
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/pointerevents/pointerevent_constructor-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/pointerevents/pointerevent_constructor-expected.txt
new file mode 100644
index 0000000..af36434
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/pointerevents/pointerevent_constructor-expected.txt
@@ -0,0 +1,68 @@
+This is a testharness.js-based test.
+Found 64 tests; 52 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS PointerEvent: Constructor test
+PASS getCoalescedEvents().length
+PASS getPredictedEvents().length
+PASS event.target
+PASS event.currentTarget
+PASS event.eventPhase
+PASS event.clientX
+PASS event.pointerType
+PASS getCoalescedEvents()[0].clientX
+PASS getCoalescedEvents()[1].clientX
+PASS getPredictedEvents()[0].clientX
+PASS getPredictedEvents()[1].clientX
+PASS getCoalescedEvents()[0].pointerId
+PASS getCoalescedEvents()[0].pointerType
+PASS getCoalescedEvents()[0].isPrimary
+PASS getCoalescedEvents()[0].getCoalescedEvents().length
+PASS getCoalescedEvents()[0].getPredictedEvents().length
+FAIL getCoalescedEvents()[0].target assert_equals: expected null but got Element node <div id="target0"></div>
+PASS getCoalescedEvents()[0].currentTarget
+PASS getCoalescedEvents()[0].eventPhase
+PASS getCoalescedEvents()[0].cancelable
+PASS getCoalescedEvents()[0].bubbles
+FAIL getCoalescedEvents()[0].offsetX assert_equals: expected 300 but got 292
+FAIL getCoalescedEvents()[0].offsetY assert_equals: expected 0 but got -119.140625
+PASS getCoalescedEvents()[1].pointerId
+PASS getCoalescedEvents()[1].pointerType
+PASS getCoalescedEvents()[1].isPrimary
+PASS getCoalescedEvents()[1].getCoalescedEvents().length
+PASS getCoalescedEvents()[1].getPredictedEvents().length
+FAIL getCoalescedEvents()[1].target assert_equals: expected null but got Element node <div id="target0"></div>
+PASS getCoalescedEvents()[1].currentTarget
+PASS getCoalescedEvents()[1].eventPhase
+PASS getCoalescedEvents()[1].cancelable
+PASS getCoalescedEvents()[1].bubbles
+FAIL getCoalescedEvents()[1].offsetX assert_equals: expected 310 but got 302
+FAIL getCoalescedEvents()[1].offsetY assert_equals: expected 0 but got -119.140625
+PASS getPredictedEvents()[0].pointerId
+PASS getPredictedEvents()[0].pointerType
+PASS getPredictedEvents()[0].isPrimary
+PASS getPredictedEvents()[0].getCoalescedEvents().length
+PASS getPredictedEvents()[0].getPredictedEvents().length
+FAIL getPredictedEvents()[0].target assert_equals: expected null but got Element node <div id="target0"></div>
+PASS getPredictedEvents()[0].currentTarget
+PASS getPredictedEvents()[0].eventPhase
+PASS getPredictedEvents()[0].cancelable
+PASS getPredictedEvents()[0].bubbles
+FAIL getPredictedEvents()[0].offsetX assert_equals: expected 320 but got 312
+FAIL getPredictedEvents()[0].offsetY assert_equals: expected 0 but got -119.140625
+PASS getPredictedEvents()[1].pointerId
+PASS getPredictedEvents()[1].pointerType
+PASS getPredictedEvents()[1].isPrimary
+PASS getPredictedEvents()[1].getCoalescedEvents().length
+PASS getPredictedEvents()[1].getPredictedEvents().length
+FAIL getPredictedEvents()[1].target assert_equals: expected null but got Element node <div id="target0"></div>
+PASS getPredictedEvents()[1].currentTarget
+PASS getPredictedEvents()[1].eventPhase
+PASS getPredictedEvents()[1].cancelable
+PASS getPredictedEvents()[1].bubbles
+FAIL getPredictedEvents()[1].offsetX assert_equals: expected 330 but got 322
+FAIL getPredictedEvents()[1].offsetY assert_equals: expected 0 but got -119.140625
+PASS default event.pointerType
+PASS default getCoalescedEvents().length
+PASS default getPredictedEvents().length
+PASS type event.pointerType
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-expected.txt
index f4e57be3..314db574 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 669 tests; 383 PASS, 286 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 736 tests; 389 PASS, 347 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -351,16 +351,11 @@
 FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
 FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
 FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
-FAIL Parsing: <sc://\0/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc:// /> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
 FAIL Parsing: <sc://@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://te@s:t@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:12/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://[/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://\/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://]/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1/x" but got "sc://%C3%B1"
 PASS Parsing: <sc:\../> against <about:blank>
 PASS Parsing: <sc::a@example.net> against <about:blank>
@@ -368,24 +363,96 @@
 PASS Parsing: <wow:%1G> against <about:blank>
 FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
 FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: href expected "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF" but got "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD"
-FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
-FAIL Parsing: <non-special://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho|st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho
 st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <http://a\0b/> against <about:blank> assert_equals: failure should set href to input expected "http://a\0b/" but got "http://a%00b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x01b/" but got "http://a%01b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x02b/" but got "http://a%02b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x03b/" but got "http://a%03b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x04b/" but got "http://a%04b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x05b/" but got "http://a%05b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x06b/" but got "http://a%06b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x07b/" but got "http://a%07b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\bb/" but got "http://a%08b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\vb/" but got "http://a%0Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\fb/" but got "http://a%0Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0eb/" but got "http://a%0Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0fb/" but got "http://a%0Fb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x10b/" but got "http://a%10b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x11b/" but got "http://a%11b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x12b/" but got "http://a%12b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x13b/" but got "http://a%13b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x14b/" but got "http://a%14b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x15b/" but got "http://a%15b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x16b/" but got "http://a%16b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x17b/" but got "http://a%17b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x18b/" but got "http://a%18b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x19b/" but got "http://a%19b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1ab/" but got "http://a%1Ab/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1bb/" but got "http://a%1Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1cb/" but got "http://a%1Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1db/" but got "http://a%1Db/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1eb/" but got "http://a%1Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1fb/" but got "http://a%1Fb/"
+FAIL Parsing: <http://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a%b/> against <about:blank> assert_equals: failure should set href to input expected "http://a%b/" but got "http://a%25b/"
+FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
+FAIL Parsing: <http://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://ab/" but got "http://a%7Fb/"
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
 PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> assert_equals: href expected "http://ho\x01st/" but got "http://ho%01st/"
+FAIL Parsing: <http://ho%02st/> against <about:blank> assert_equals: href expected "http://ho\x02st/" but got "http://ho%02st/"
+FAIL Parsing: <http://ho%03st/> against <about:blank> assert_equals: href expected "http://ho\x03st/" but got "http://ho%03st/"
+FAIL Parsing: <http://ho%04st/> against <about:blank> assert_equals: href expected "http://ho\x04st/" but got "http://ho%04st/"
+FAIL Parsing: <http://ho%05st/> against <about:blank> assert_equals: href expected "http://ho\x05st/" but got "http://ho%05st/"
+FAIL Parsing: <http://ho%06st/> against <about:blank> assert_equals: href expected "http://ho\x06st/" but got "http://ho%06st/"
+FAIL Parsing: <http://ho%07st/> against <about:blank> assert_equals: href expected "http://ho\x07st/" but got "http://ho%07st/"
+FAIL Parsing: <http://ho%08st/> against <about:blank> assert_equals: href expected "http://ho\bst/" but got "http://ho%08st/"
 PASS Parsing: <http://ho%09st/> against <about:blank>
 PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> assert_equals: href expected "http://ho\vst/" but got "http://ho%0Bst/"
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> assert_equals: href expected "http://ho\fst/" but got "http://ho%0Cst/"
 PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> assert_equals: href expected "http://ho\x0est/" but got "http://ho%0Est/"
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> assert_equals: href expected "http://ho\x0fst/" but got "http://ho%0Fst/"
+FAIL Parsing: <http://ho%10st/> against <about:blank> assert_equals: href expected "http://ho\x10st/" but got "http://ho%10st/"
+FAIL Parsing: <http://ho%11st/> against <about:blank> assert_equals: href expected "http://ho\x11st/" but got "http://ho%11st/"
+FAIL Parsing: <http://ho%12st/> against <about:blank> assert_equals: href expected "http://ho\x12st/" but got "http://ho%12st/"
+FAIL Parsing: <http://ho%13st/> against <about:blank> assert_equals: href expected "http://ho\x13st/" but got "http://ho%13st/"
+FAIL Parsing: <http://ho%14st/> against <about:blank> assert_equals: href expected "http://ho\x14st/" but got "http://ho%14st/"
+FAIL Parsing: <http://ho%15st/> against <about:blank> assert_equals: href expected "http://ho\x15st/" but got "http://ho%15st/"
+FAIL Parsing: <http://ho%16st/> against <about:blank> assert_equals: href expected "http://ho\x16st/" but got "http://ho%16st/"
+FAIL Parsing: <http://ho%17st/> against <about:blank> assert_equals: href expected "http://ho\x17st/" but got "http://ho%17st/"
+FAIL Parsing: <http://ho%18st/> against <about:blank> assert_equals: href expected "http://ho\x18st/" but got "http://ho%18st/"
+FAIL Parsing: <http://ho%19st/> against <about:blank> assert_equals: href expected "http://ho\x19st/" but got "http://ho%19st/"
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> assert_equals: href expected "http://ho\x1ast/" but got "http://ho%1Ast/"
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> assert_equals: href expected "http://ho\x1bst/" but got "http://ho%1Bst/"
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> assert_equals: href expected "http://ho\x1cst/" but got "http://ho%1Cst/"
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> assert_equals: href expected "http://ho\x1dst/" but got "http://ho%1Dst/"
+FAIL Parsing: <http://ho%1Est/> against <about:blank> assert_equals: href expected "http://ho\x1est/" but got "http://ho%1Est/"
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> assert_equals: href expected "http://ho\x1fst/" but got "http://ho%1Fst/"
 FAIL Parsing: <http://ho%20st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://ho%23st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%25st/> against <about:blank>
 PASS Parsing: <http://ho%2Fst/> against <about:blank>
 FAIL Parsing: <http://ho%3Ast/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%3Ast/" but got "http://ho:st/"
 FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
@@ -396,8 +463,9 @@
 PASS Parsing: <http://ho%5Cst/> against <about:blank>
 FAIL Parsing: <http://ho%5Dst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Dst/" but got "http://ho]st/"
 FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%1F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
-FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> assert_equals: href expected "http://host/" but got "http://ho%7Fst/"
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
 FAIL Parsing: <ftp://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%80/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <ftp://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%A0/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <https://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%80/" but got "https://example.com%EF%BF%BD/"
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-expected.txt
index 0353e737..89bc28a 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-expected.txt
@@ -264,8 +264,8 @@
 PASS Parsing origin: <wow:%1G> against <about:blank>
 PASS Parsing origin: <wow:￿> against <about:blank>
 FAIL Parsing origin: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
-FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
-PASS Parsing origin: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Parsing origin: <ftp://%e2%98%83> against <about:blank>
 PASS Parsing origin: <https://%e2%98%83> against <about:blank>
 PASS Parsing origin: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-xhtml-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-xhtml-expected.txt
index 0353e737..89bc28a 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-origin-xhtml-expected.txt
@@ -264,8 +264,8 @@
 PASS Parsing origin: <wow:%1G> against <about:blank>
 PASS Parsing origin: <wow:￿> against <about:blank>
 FAIL Parsing origin: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
-FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
-PASS Parsing origin: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Parsing origin: <ftp://%e2%98%83> against <about:blank>
 PASS Parsing origin: <https://%e2%98%83> against <about:blank>
 PASS Parsing origin: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt
index f4e57be3..314db574 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 669 tests; 383 PASS, 286 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 736 tests; 389 PASS, 347 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -351,16 +351,11 @@
 FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
 FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
 FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
-FAIL Parsing: <sc://\0/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc:// /> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
 FAIL Parsing: <sc://@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://te@s:t@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:12/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://[/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://\/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://]/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1/x" but got "sc://%C3%B1"
 PASS Parsing: <sc:\../> against <about:blank>
 PASS Parsing: <sc::a@example.net> against <about:blank>
@@ -368,24 +363,96 @@
 PASS Parsing: <wow:%1G> against <about:blank>
 FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
 FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: href expected "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF" but got "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD"
-FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
-FAIL Parsing: <non-special://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho|st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho
 st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <http://a\0b/> against <about:blank> assert_equals: failure should set href to input expected "http://a\0b/" but got "http://a%00b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x01b/" but got "http://a%01b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x02b/" but got "http://a%02b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x03b/" but got "http://a%03b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x04b/" but got "http://a%04b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x05b/" but got "http://a%05b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x06b/" but got "http://a%06b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x07b/" but got "http://a%07b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\bb/" but got "http://a%08b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\vb/" but got "http://a%0Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\fb/" but got "http://a%0Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0eb/" but got "http://a%0Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0fb/" but got "http://a%0Fb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x10b/" but got "http://a%10b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x11b/" but got "http://a%11b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x12b/" but got "http://a%12b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x13b/" but got "http://a%13b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x14b/" but got "http://a%14b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x15b/" but got "http://a%15b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x16b/" but got "http://a%16b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x17b/" but got "http://a%17b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x18b/" but got "http://a%18b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x19b/" but got "http://a%19b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1ab/" but got "http://a%1Ab/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1bb/" but got "http://a%1Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1cb/" but got "http://a%1Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1db/" but got "http://a%1Db/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1eb/" but got "http://a%1Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1fb/" but got "http://a%1Fb/"
+FAIL Parsing: <http://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a%b/> against <about:blank> assert_equals: failure should set href to input expected "http://a%b/" but got "http://a%25b/"
+FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
+FAIL Parsing: <http://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://ab/" but got "http://a%7Fb/"
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
 PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> assert_equals: href expected "http://ho\x01st/" but got "http://ho%01st/"
+FAIL Parsing: <http://ho%02st/> against <about:blank> assert_equals: href expected "http://ho\x02st/" but got "http://ho%02st/"
+FAIL Parsing: <http://ho%03st/> against <about:blank> assert_equals: href expected "http://ho\x03st/" but got "http://ho%03st/"
+FAIL Parsing: <http://ho%04st/> against <about:blank> assert_equals: href expected "http://ho\x04st/" but got "http://ho%04st/"
+FAIL Parsing: <http://ho%05st/> against <about:blank> assert_equals: href expected "http://ho\x05st/" but got "http://ho%05st/"
+FAIL Parsing: <http://ho%06st/> against <about:blank> assert_equals: href expected "http://ho\x06st/" but got "http://ho%06st/"
+FAIL Parsing: <http://ho%07st/> against <about:blank> assert_equals: href expected "http://ho\x07st/" but got "http://ho%07st/"
+FAIL Parsing: <http://ho%08st/> against <about:blank> assert_equals: href expected "http://ho\bst/" but got "http://ho%08st/"
 PASS Parsing: <http://ho%09st/> against <about:blank>
 PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> assert_equals: href expected "http://ho\vst/" but got "http://ho%0Bst/"
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> assert_equals: href expected "http://ho\fst/" but got "http://ho%0Cst/"
 PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> assert_equals: href expected "http://ho\x0est/" but got "http://ho%0Est/"
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> assert_equals: href expected "http://ho\x0fst/" but got "http://ho%0Fst/"
+FAIL Parsing: <http://ho%10st/> against <about:blank> assert_equals: href expected "http://ho\x10st/" but got "http://ho%10st/"
+FAIL Parsing: <http://ho%11st/> against <about:blank> assert_equals: href expected "http://ho\x11st/" but got "http://ho%11st/"
+FAIL Parsing: <http://ho%12st/> against <about:blank> assert_equals: href expected "http://ho\x12st/" but got "http://ho%12st/"
+FAIL Parsing: <http://ho%13st/> against <about:blank> assert_equals: href expected "http://ho\x13st/" but got "http://ho%13st/"
+FAIL Parsing: <http://ho%14st/> against <about:blank> assert_equals: href expected "http://ho\x14st/" but got "http://ho%14st/"
+FAIL Parsing: <http://ho%15st/> against <about:blank> assert_equals: href expected "http://ho\x15st/" but got "http://ho%15st/"
+FAIL Parsing: <http://ho%16st/> against <about:blank> assert_equals: href expected "http://ho\x16st/" but got "http://ho%16st/"
+FAIL Parsing: <http://ho%17st/> against <about:blank> assert_equals: href expected "http://ho\x17st/" but got "http://ho%17st/"
+FAIL Parsing: <http://ho%18st/> against <about:blank> assert_equals: href expected "http://ho\x18st/" but got "http://ho%18st/"
+FAIL Parsing: <http://ho%19st/> against <about:blank> assert_equals: href expected "http://ho\x19st/" but got "http://ho%19st/"
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> assert_equals: href expected "http://ho\x1ast/" but got "http://ho%1Ast/"
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> assert_equals: href expected "http://ho\x1bst/" but got "http://ho%1Bst/"
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> assert_equals: href expected "http://ho\x1cst/" but got "http://ho%1Cst/"
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> assert_equals: href expected "http://ho\x1dst/" but got "http://ho%1Dst/"
+FAIL Parsing: <http://ho%1Est/> against <about:blank> assert_equals: href expected "http://ho\x1est/" but got "http://ho%1Est/"
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> assert_equals: href expected "http://ho\x1fst/" but got "http://ho%1Fst/"
 FAIL Parsing: <http://ho%20st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://ho%23st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%25st/> against <about:blank>
 PASS Parsing: <http://ho%2Fst/> against <about:blank>
 FAIL Parsing: <http://ho%3Ast/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%3Ast/" but got "http://ho:st/"
 FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
@@ -396,8 +463,9 @@
 PASS Parsing: <http://ho%5Cst/> against <about:blank>
 FAIL Parsing: <http://ho%5Dst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Dst/" but got "http://ho]st/"
 FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%1F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
-FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> assert_equals: href expected "http://host/" but got "http://ho%7Fst/"
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
 FAIL Parsing: <ftp://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%80/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <ftp://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%A0/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <https://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%80/" but got "https://example.com%EF%BF%BD/"
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/failure-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/failure-expected.txt
index 834654f..13edad9 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/failure-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/failure-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 659 tests; 390 PASS, 269 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 695 tests; 414 PASS, 281 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS URL's constructor's base argument: file://example:1/ should throw
 PASS URL's href: file://example:1/ should throw
@@ -139,18 +139,6 @@
 PASS sendBeacon(): http://[www.google.com]/ should throw
 FAIL Location's href: http://[www.google.com]/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://[www.google.com]/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
 PASS window.open(): http://[www.google.com]/ should throw
-FAIL URL's constructor's base argument: sc://\0/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://\0/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://\0/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://\0/ should throw
-FAIL Location's href: sc://\0/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://\0/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc:// / should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc:// / should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc:// / should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc:// / should throw
-FAIL Location's href: sc:// / should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc:// / should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
 FAIL URL's constructor's base argument: sc://@/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
 FAIL URL's href: sc://@/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
 FAIL XHR: sc://@/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
@@ -175,24 +163,78 @@
 PASS sendBeacon(): sc://:12/ should throw
 FAIL Location's href: sc://:12/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): sc://:12/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc://[/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://[/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://[/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://[/ should throw
-FAIL Location's href: sc://[/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://[/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc://\/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://\/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://\/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://\/ should throw
-FAIL Location's href: sc://\/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://\/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc://]/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://]/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://]/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://]/ should throw
-FAIL Location's href: sc://]/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://]/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a\0b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a\0b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a\0b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a\0b/ should throw
+FAIL Location's href: sc://a\0b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a\0b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a b/ should throw
+FAIL Location's href: sc://a b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a<b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a<b should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a<b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a<b should throw
+FAIL Location's href: sc://a<b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a<b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a>b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a>b should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a>b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a>b should throw
+FAIL Location's href: sc://a>b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a>b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a[b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a[b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a[b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a[b/ should throw
+FAIL Location's href: sc://a[b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a[b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a\b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a\b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a\b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a\b/ should throw
+FAIL Location's href: sc://a\b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a\b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a]b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a]b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a]b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a]b/ should throw
+FAIL Location's href: sc://a]b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a]b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a^b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a^b should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a^b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a^b should throw
+FAIL Location's href: sc://a^b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a^b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a|b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a|b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a|b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a|b/ should throw
+FAIL Location's href: sc://a|b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a|b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://a\0b/ should throw
+PASS URL's href: http://a\0b/ should throw
+PASS XHR: http://a\0b/ should throw
+PASS sendBeacon(): http://a\0b/ should throw
+FAIL Location's href: http://a\0b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a\0b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a\0b/ should throw
+FAIL URL's constructor's base argument: http://a b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://a b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://a b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://a b/ should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://a b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://a b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://a%b/ should throw
+PASS URL's href: http://a%b/ should throw
+PASS XHR: http://a%b/ should throw
+PASS sendBeacon(): http://a%b/ should throw
+FAIL Location's href: http://a%b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a%b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a%b/ should throw
 FAIL URL's constructor's base argument: http://a<b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
 FAIL URL's href: http://a<b should throw assert_throws_js: function "() => url.href = test.input" did not throw
 FAIL XHR: http://a<b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
@@ -205,42 +247,30 @@
 FAIL sendBeacon(): http://a>b should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
 FAIL Location's href: http://a>b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): http://a>b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://a[b/ should throw
+PASS URL's href: http://a[b/ should throw
+PASS XHR: http://a[b/ should throw
+PASS sendBeacon(): http://a[b/ should throw
+FAIL Location's href: http://a[b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a[b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a[b/ should throw
+PASS URL's constructor's base argument: http://a]b/ should throw
+PASS URL's href: http://a]b/ should throw
+PASS XHR: http://a]b/ should throw
+PASS sendBeacon(): http://a]b/ should throw
+FAIL Location's href: http://a]b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a]b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a]b/ should throw
 PASS URL's constructor's base argument: http://a^b should throw
 PASS URL's href: http://a^b should throw
 PASS XHR: http://a^b should throw
 PASS sendBeacon(): http://a^b should throw
 FAIL Location's href: http://a^b should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a^b' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
 PASS window.open(): http://a^b should throw
-FAIL URL's constructor's base argument: non-special://a<b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: non-special://a<b should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: non-special://a<b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): non-special://a<b should throw
-FAIL Location's href: non-special://a<b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): non-special://a<b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: non-special://a>b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: non-special://a>b should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: non-special://a>b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): non-special://a>b should throw
-FAIL Location's href: non-special://a>b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): non-special://a>b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: non-special://a^b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: non-special://a^b should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: non-special://a^b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): non-special://a^b should throw
-FAIL Location's href: non-special://a^b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): non-special://a^b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: foo://ho\0st/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: foo://ho\0st/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: foo://ho\0st/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): foo://ho\0st/ should throw
-FAIL Location's href: foo://ho\0st/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): foo://ho\0st/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: foo://ho|st/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: foo://ho|st/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: foo://ho|st/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): foo://ho|st/ should throw
-FAIL Location's href: foo://ho|st/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): foo://ho|st/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: http://a|b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://a|b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://a|b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://a|b/ should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://a|b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://a|b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
 PASS URL's constructor's base argument: http://ho%00st/ should throw
 PASS URL's href: http://ho%00st/ should throw
 PASS XHR: http://ho%00st/ should throw
@@ -277,6 +307,12 @@
 FAIL sendBeacon(): http://ho%23st/ should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
 FAIL Location's href: http://ho%23st/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): http://ho%23st/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://ho%25st/ should throw
+PASS URL's href: http://ho%25st/ should throw
+PASS XHR: http://ho%25st/ should throw
+PASS sendBeacon(): http://ho%25st/ should throw
+FAIL Location's href: http://ho%25st/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://ho%25st/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://ho%25st/ should throw
 PASS URL's constructor's base argument: http://ho%2Fst/ should throw
 PASS URL's href: http://ho%2Fst/ should throw
 PASS XHR: http://ho%2Fst/ should throw
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any-expected.txt
index 46a0c816..080ccd89 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-constructor.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 671 tests; 485 PASS, 186 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 738 tests; 493 PASS, 245 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -385,12 +385,6 @@
 FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
 FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
 FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
-FAIL Parsing: <sc://\0/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
-FAIL Parsing: <sc:// /> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
 FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
 FAIL Parsing: <sc://@/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
@@ -404,15 +398,6 @@
 FAIL Parsing: <sc://:12/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <sc://[/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
-FAIL Parsing: <sc://\/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
-FAIL Parsing: <sc://]/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
 FAIL Parsing: <x> against <sc://ñ> Failed to construct 'URL': Invalid URL
 PASS Parsing: <sc:\../> against <about:blank>
 PASS Parsing: <sc::a@example.net> against <about:blank>
@@ -420,42 +405,126 @@
 PASS Parsing: <wow:%1G> against <about:blank>
 FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
 FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Parsing: <http://a<b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <http://a>b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-PASS Parsing: <http://a^b> against <about:blank>
-FAIL Parsing: <non-special://a<b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a<b> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <non-special://a>b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a>b> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <non-special://a^b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <foo://ho|st/> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <sc://a^b> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
 FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho
 st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+PASS Parsing: <http://a\0b/> against <about:blank>
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://a b/> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+PASS Parsing: <http://a%b/> against <about:blank>
+FAIL Parsing: <http://a<b> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <http://a>b> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+PASS Parsing: <http://a^b> against <about:blank>
+FAIL Parsing: <http://a|b/> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
 PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%02st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%03st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%04st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%05st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%06st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%07st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%08st/> against <about:blank> Failed to construct 'URL': Invalid URL
 PASS Parsing: <http://ho%09st/> against <about:blank>
 PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> Failed to construct 'URL': Invalid URL
 PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%10st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%11st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%12st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%13st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%14st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%15st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%16st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%17st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%18st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%19st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Est/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> Failed to construct 'URL': Invalid URL
 FAIL Parsing: <http://ho%20st/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
 FAIL Parsing: <http://ho%23st/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
+PASS Parsing: <http://ho%25st/> against <about:blank>
 PASS Parsing: <http://ho%2Fst/> against <about:blank>
 PASS Parsing: <http://ho%3Ast/> against <about:blank>
 FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_throws_js: function "function() {
@@ -474,8 +543,9 @@
 FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
 PASS Parsing: <ftp://example.com%80/> against <about:blank>
 PASS Parsing: <ftp://example.com%A0/> against <about:blank>
 PASS Parsing: <https://example.com%80/> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any-expected.txt
index b5223c0..943cea0 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any-expected.txt
@@ -264,8 +264,8 @@
 PASS Origin parsing: <wow:%1G> against <about:blank>
 PASS Origin parsing: <wow:￿> against <about:blank>
 FAIL Origin parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
-PASS Origin parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
+PASS Origin parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Origin parsing: <ftp://%e2%98%83> against <about:blank>
 PASS Origin parsing: <https://%e2%98%83> against <about:blank>
 PASS Origin parsing: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any.worker-expected.txt
index b5223c0..943cea0 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/url/url-origin.any.worker-expected.txt
@@ -264,8 +264,8 @@
 PASS Origin parsing: <wow:%1G> against <about:blank>
 PASS Origin parsing: <wow:￿> against <about:blank>
 FAIL Origin parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
-PASS Origin parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
+PASS Origin parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Origin parsing: <ftp://%e2%98%83> against <about:blank>
 PASS Origin parsing: <https://%e2%98%83> against <about:blank>
 PASS Origin parsing: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/pointerevents/pointerevent_constructor-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/pointerevents/pointerevent_constructor-expected.txt
new file mode 100644
index 0000000..035bb68e
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/pointerevents/pointerevent_constructor-expected.txt
@@ -0,0 +1,68 @@
+This is a testharness.js-based test.
+Found 64 tests; 52 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS PointerEvent: Constructor test
+PASS getCoalescedEvents().length
+PASS getPredictedEvents().length
+PASS event.target
+PASS event.currentTarget
+PASS event.eventPhase
+PASS event.clientX
+PASS event.pointerType
+PASS getCoalescedEvents()[0].clientX
+PASS getCoalescedEvents()[1].clientX
+PASS getPredictedEvents()[0].clientX
+PASS getPredictedEvents()[1].clientX
+PASS getCoalescedEvents()[0].pointerId
+PASS getCoalescedEvents()[0].pointerType
+PASS getCoalescedEvents()[0].isPrimary
+PASS getCoalescedEvents()[0].getCoalescedEvents().length
+PASS getCoalescedEvents()[0].getPredictedEvents().length
+FAIL getCoalescedEvents()[0].target assert_equals: expected null but got Element node <div id="target0"></div>
+PASS getCoalescedEvents()[0].currentTarget
+PASS getCoalescedEvents()[0].eventPhase
+PASS getCoalescedEvents()[0].cancelable
+PASS getCoalescedEvents()[0].bubbles
+FAIL getCoalescedEvents()[0].offsetX assert_equals: expected 300 but got 292
+FAIL getCoalescedEvents()[0].offsetY assert_equals: expected 0 but got -121.140625
+PASS getCoalescedEvents()[1].pointerId
+PASS getCoalescedEvents()[1].pointerType
+PASS getCoalescedEvents()[1].isPrimary
+PASS getCoalescedEvents()[1].getCoalescedEvents().length
+PASS getCoalescedEvents()[1].getPredictedEvents().length
+FAIL getCoalescedEvents()[1].target assert_equals: expected null but got Element node <div id="target0"></div>
+PASS getCoalescedEvents()[1].currentTarget
+PASS getCoalescedEvents()[1].eventPhase
+PASS getCoalescedEvents()[1].cancelable
+PASS getCoalescedEvents()[1].bubbles
+FAIL getCoalescedEvents()[1].offsetX assert_equals: expected 310 but got 302
+FAIL getCoalescedEvents()[1].offsetY assert_equals: expected 0 but got -121.140625
+PASS getPredictedEvents()[0].pointerId
+PASS getPredictedEvents()[0].pointerType
+PASS getPredictedEvents()[0].isPrimary
+PASS getPredictedEvents()[0].getCoalescedEvents().length
+PASS getPredictedEvents()[0].getPredictedEvents().length
+FAIL getPredictedEvents()[0].target assert_equals: expected null but got Element node <div id="target0"></div>
+PASS getPredictedEvents()[0].currentTarget
+PASS getPredictedEvents()[0].eventPhase
+PASS getPredictedEvents()[0].cancelable
+PASS getPredictedEvents()[0].bubbles
+FAIL getPredictedEvents()[0].offsetX assert_equals: expected 320 but got 312
+FAIL getPredictedEvents()[0].offsetY assert_equals: expected 0 but got -121.140625
+PASS getPredictedEvents()[1].pointerId
+PASS getPredictedEvents()[1].pointerType
+PASS getPredictedEvents()[1].isPrimary
+PASS getPredictedEvents()[1].getCoalescedEvents().length
+PASS getPredictedEvents()[1].getPredictedEvents().length
+FAIL getPredictedEvents()[1].target assert_equals: expected null but got Element node <div id="target0"></div>
+PASS getPredictedEvents()[1].currentTarget
+PASS getPredictedEvents()[1].eventPhase
+PASS getPredictedEvents()[1].cancelable
+PASS getPredictedEvents()[1].bubbles
+FAIL getPredictedEvents()[1].offsetX assert_equals: expected 330 but got 322
+FAIL getPredictedEvents()[1].offsetY assert_equals: expected 0 but got -121.140625
+PASS default event.pointerType
+PASS default getCoalescedEvents().length
+PASS default getPredictedEvents().length
+PASS type event.pointerType
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-expected.txt
index f483c8f..415c9e1 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 669 tests; 370 PASS, 299 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 736 tests; 376 PASS, 360 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -351,16 +351,11 @@
 FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
 FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
 FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
-FAIL Parsing: <sc://\0/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc:// /> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
 FAIL Parsing: <sc://@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://te@s:t@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:12/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://[/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://\/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://]/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1/x" but got "sc://%C3%B1"
 PASS Parsing: <sc:\../> against <about:blank>
 PASS Parsing: <sc::a@example.net> against <about:blank>
@@ -368,24 +363,96 @@
 PASS Parsing: <wow:%1G> against <about:blank>
 FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
 FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: href expected "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF" but got "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD"
-FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
-FAIL Parsing: <non-special://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho|st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho
 st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <http://a\0b/> against <about:blank> assert_equals: failure should set href to input expected "http://a\0b/" but got "http://a%00b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x01b/" but got "http://a%01b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x02b/" but got "http://a%02b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x03b/" but got "http://a%03b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x04b/" but got "http://a%04b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x05b/" but got "http://a%05b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x06b/" but got "http://a%06b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x07b/" but got "http://a%07b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\bb/" but got "http://a%08b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\vb/" but got "http://a%0Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\fb/" but got "http://a%0Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0eb/" but got "http://a%0Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0fb/" but got "http://a%0Fb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x10b/" but got "http://a%10b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x11b/" but got "http://a%11b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x12b/" but got "http://a%12b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x13b/" but got "http://a%13b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x14b/" but got "http://a%14b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x15b/" but got "http://a%15b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x16b/" but got "http://a%16b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x17b/" but got "http://a%17b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x18b/" but got "http://a%18b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x19b/" but got "http://a%19b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1ab/" but got "http://a%1Ab/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1bb/" but got "http://a%1Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1cb/" but got "http://a%1Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1db/" but got "http://a%1Db/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1eb/" but got "http://a%1Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1fb/" but got "http://a%1Fb/"
+FAIL Parsing: <http://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a%b/> against <about:blank> assert_equals: failure should set href to input expected "http://a%b/" but got "http://a%25b/"
+FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
+FAIL Parsing: <http://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://ab/" but got "http://a%7Fb/"
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
 PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> assert_equals: href expected "http://ho\x01st/" but got "http://ho%01st/"
+FAIL Parsing: <http://ho%02st/> against <about:blank> assert_equals: href expected "http://ho\x02st/" but got "http://ho%02st/"
+FAIL Parsing: <http://ho%03st/> against <about:blank> assert_equals: href expected "http://ho\x03st/" but got "http://ho%03st/"
+FAIL Parsing: <http://ho%04st/> against <about:blank> assert_equals: href expected "http://ho\x04st/" but got "http://ho%04st/"
+FAIL Parsing: <http://ho%05st/> against <about:blank> assert_equals: href expected "http://ho\x05st/" but got "http://ho%05st/"
+FAIL Parsing: <http://ho%06st/> against <about:blank> assert_equals: href expected "http://ho\x06st/" but got "http://ho%06st/"
+FAIL Parsing: <http://ho%07st/> against <about:blank> assert_equals: href expected "http://ho\x07st/" but got "http://ho%07st/"
+FAIL Parsing: <http://ho%08st/> against <about:blank> assert_equals: href expected "http://ho\bst/" but got "http://ho%08st/"
 PASS Parsing: <http://ho%09st/> against <about:blank>
 PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> assert_equals: href expected "http://ho\vst/" but got "http://ho%0Bst/"
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> assert_equals: href expected "http://ho\fst/" but got "http://ho%0Cst/"
 PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> assert_equals: href expected "http://ho\x0est/" but got "http://ho%0Est/"
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> assert_equals: href expected "http://ho\x0fst/" but got "http://ho%0Fst/"
+FAIL Parsing: <http://ho%10st/> against <about:blank> assert_equals: href expected "http://ho\x10st/" but got "http://ho%10st/"
+FAIL Parsing: <http://ho%11st/> against <about:blank> assert_equals: href expected "http://ho\x11st/" but got "http://ho%11st/"
+FAIL Parsing: <http://ho%12st/> against <about:blank> assert_equals: href expected "http://ho\x12st/" but got "http://ho%12st/"
+FAIL Parsing: <http://ho%13st/> against <about:blank> assert_equals: href expected "http://ho\x13st/" but got "http://ho%13st/"
+FAIL Parsing: <http://ho%14st/> against <about:blank> assert_equals: href expected "http://ho\x14st/" but got "http://ho%14st/"
+FAIL Parsing: <http://ho%15st/> against <about:blank> assert_equals: href expected "http://ho\x15st/" but got "http://ho%15st/"
+FAIL Parsing: <http://ho%16st/> against <about:blank> assert_equals: href expected "http://ho\x16st/" but got "http://ho%16st/"
+FAIL Parsing: <http://ho%17st/> against <about:blank> assert_equals: href expected "http://ho\x17st/" but got "http://ho%17st/"
+FAIL Parsing: <http://ho%18st/> against <about:blank> assert_equals: href expected "http://ho\x18st/" but got "http://ho%18st/"
+FAIL Parsing: <http://ho%19st/> against <about:blank> assert_equals: href expected "http://ho\x19st/" but got "http://ho%19st/"
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> assert_equals: href expected "http://ho\x1ast/" but got "http://ho%1Ast/"
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> assert_equals: href expected "http://ho\x1bst/" but got "http://ho%1Bst/"
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> assert_equals: href expected "http://ho\x1cst/" but got "http://ho%1Cst/"
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> assert_equals: href expected "http://ho\x1dst/" but got "http://ho%1Dst/"
+FAIL Parsing: <http://ho%1Est/> against <about:blank> assert_equals: href expected "http://ho\x1est/" but got "http://ho%1Est/"
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> assert_equals: href expected "http://ho\x1fst/" but got "http://ho%1Fst/"
 FAIL Parsing: <http://ho%20st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://ho%23st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%25st/> against <about:blank>
 PASS Parsing: <http://ho%2Fst/> against <about:blank>
 FAIL Parsing: <http://ho%3Ast/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%3Ast/" but got "http://ho:st/"
 FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
@@ -396,8 +463,9 @@
 PASS Parsing: <http://ho%5Cst/> against <about:blank>
 FAIL Parsing: <http://ho%5Dst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Dst/" but got "http://ho]st/"
 FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%1F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
-FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> assert_equals: href expected "http://host/" but got "http://ho%7Fst/"
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
 FAIL Parsing: <ftp://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%80/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <ftp://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%A0/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <https://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%80/" but got "https://example.com%EF%BF%BD/"
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-expected.txt
index ab8352b..2147fb96 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-expected.txt
@@ -264,8 +264,8 @@
 PASS Parsing origin: <wow:%1G> against <about:blank>
 PASS Parsing origin: <wow:￿> against <about:blank>
 FAIL Parsing origin: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
-FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
-PASS Parsing origin: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Parsing origin: <ftp://%e2%98%83> against <about:blank>
 PASS Parsing origin: <https://%e2%98%83> against <about:blank>
 PASS Parsing origin: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-xhtml-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-xhtml-expected.txt
index ab8352b..2147fb96 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-origin-xhtml-expected.txt
@@ -264,8 +264,8 @@
 PASS Parsing origin: <wow:%1G> against <about:blank>
 PASS Parsing origin: <wow:￿> against <about:blank>
 FAIL Parsing origin: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: origin expected "http://example.com" but got "null"
-FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
-PASS Parsing origin: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Parsing origin: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: origin expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~" but got "null"
+PASS Parsing origin: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Parsing origin: <ftp://%e2%98%83> against <about:blank>
 PASS Parsing origin: <https://%e2%98%83> against <about:blank>
 PASS Parsing origin: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-xhtml-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-xhtml-expected.txt
index f483c8f..415c9e1 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-xhtml-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/a-element-xhtml-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 669 tests; 370 PASS, 299 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 736 tests; 376 PASS, 360 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -351,16 +351,11 @@
 FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
 FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
 FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
-FAIL Parsing: <sc://\0/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc:// /> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
 FAIL Parsing: <sc://@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://te@s:t@/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <sc://:12/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://[/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://\/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <sc://]/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <x> against <sc://ñ> assert_equals: href expected "sc://%C3%B1/x" but got "sc://%C3%B1"
 PASS Parsing: <sc:\../> against <about:blank>
 PASS Parsing: <sc::a@example.net> against <about:blank>
@@ -368,24 +363,96 @@
 PASS Parsing: <wow:%1G> against <about:blank>
 FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
 FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> assert_equals: href expected "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF" but got "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%BF%BD%EF%B7%8F%EF%BF%BD%EF%B7%B0%EF%BF%BD%EF%BF%BD"
-FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
-FAIL Parsing: <non-special://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <non-special://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <foo://ho|st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a^b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho
 st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+FAIL Parsing: <http://a\0b/> against <about:blank> assert_equals: failure should set href to input expected "http://a\0b/" but got "http://a%00b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x01b/" but got "http://a%01b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x02b/" but got "http://a%02b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x03b/" but got "http://a%03b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x04b/" but got "http://a%04b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x05b/" but got "http://a%05b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x06b/" but got "http://a%06b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x07b/" but got "http://a%07b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\bb/" but got "http://a%08b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\vb/" but got "http://a%0Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\fb/" but got "http://a%0Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0eb/" but got "http://a%0Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x0fb/" but got "http://a%0Fb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x10b/" but got "http://a%10b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x11b/" but got "http://a%11b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x12b/" but got "http://a%12b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x13b/" but got "http://a%13b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x14b/" but got "http://a%14b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x15b/" but got "http://a%15b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x16b/" but got "http://a%16b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x17b/" but got "http://a%17b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x18b/" but got "http://a%18b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x19b/" but got "http://a%19b/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1ab/" but got "http://a%1Ab/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1bb/" but got "http://a%1Bb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1cb/" but got "http://a%1Cb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1db/" but got "http://a%1Db/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1eb/" but got "http://a%1Eb/"
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://a\x1fb/" but got "http://a%1Fb/"
+FAIL Parsing: <http://a b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a%b/> against <about:blank> assert_equals: failure should set href to input expected "http://a%b/" but got "http://a%25b/"
+FAIL Parsing: <http://a<b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://a>b> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+FAIL Parsing: <http://a^b> against <about:blank> assert_equals: failure should set href to input expected "http://a^b" but got "http://a%5Eb/"
+FAIL Parsing: <http://a|b/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+FAIL Parsing: <http://ab/> against <about:blank> assert_equals: href expected "http://ab/" but got "http://a%7Fb/"
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
 PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> assert_equals: href expected "http://ho\x01st/" but got "http://ho%01st/"
+FAIL Parsing: <http://ho%02st/> against <about:blank> assert_equals: href expected "http://ho\x02st/" but got "http://ho%02st/"
+FAIL Parsing: <http://ho%03st/> against <about:blank> assert_equals: href expected "http://ho\x03st/" but got "http://ho%03st/"
+FAIL Parsing: <http://ho%04st/> against <about:blank> assert_equals: href expected "http://ho\x04st/" but got "http://ho%04st/"
+FAIL Parsing: <http://ho%05st/> against <about:blank> assert_equals: href expected "http://ho\x05st/" but got "http://ho%05st/"
+FAIL Parsing: <http://ho%06st/> against <about:blank> assert_equals: href expected "http://ho\x06st/" but got "http://ho%06st/"
+FAIL Parsing: <http://ho%07st/> against <about:blank> assert_equals: href expected "http://ho\x07st/" but got "http://ho%07st/"
+FAIL Parsing: <http://ho%08st/> against <about:blank> assert_equals: href expected "http://ho\bst/" but got "http://ho%08st/"
 PASS Parsing: <http://ho%09st/> against <about:blank>
 PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> assert_equals: href expected "http://ho\vst/" but got "http://ho%0Bst/"
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> assert_equals: href expected "http://ho\fst/" but got "http://ho%0Cst/"
 PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> assert_equals: href expected "http://ho\x0est/" but got "http://ho%0Est/"
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> assert_equals: href expected "http://ho\x0fst/" but got "http://ho%0Fst/"
+FAIL Parsing: <http://ho%10st/> against <about:blank> assert_equals: href expected "http://ho\x10st/" but got "http://ho%10st/"
+FAIL Parsing: <http://ho%11st/> against <about:blank> assert_equals: href expected "http://ho\x11st/" but got "http://ho%11st/"
+FAIL Parsing: <http://ho%12st/> against <about:blank> assert_equals: href expected "http://ho\x12st/" but got "http://ho%12st/"
+FAIL Parsing: <http://ho%13st/> against <about:blank> assert_equals: href expected "http://ho\x13st/" but got "http://ho%13st/"
+FAIL Parsing: <http://ho%14st/> against <about:blank> assert_equals: href expected "http://ho\x14st/" but got "http://ho%14st/"
+FAIL Parsing: <http://ho%15st/> against <about:blank> assert_equals: href expected "http://ho\x15st/" but got "http://ho%15st/"
+FAIL Parsing: <http://ho%16st/> against <about:blank> assert_equals: href expected "http://ho\x16st/" but got "http://ho%16st/"
+FAIL Parsing: <http://ho%17st/> against <about:blank> assert_equals: href expected "http://ho\x17st/" but got "http://ho%17st/"
+FAIL Parsing: <http://ho%18st/> against <about:blank> assert_equals: href expected "http://ho\x18st/" but got "http://ho%18st/"
+FAIL Parsing: <http://ho%19st/> against <about:blank> assert_equals: href expected "http://ho\x19st/" but got "http://ho%19st/"
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> assert_equals: href expected "http://ho\x1ast/" but got "http://ho%1Ast/"
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> assert_equals: href expected "http://ho\x1bst/" but got "http://ho%1Bst/"
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> assert_equals: href expected "http://ho\x1cst/" but got "http://ho%1Cst/"
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> assert_equals: href expected "http://ho\x1dst/" but got "http://ho%1Dst/"
+FAIL Parsing: <http://ho%1Est/> against <about:blank> assert_equals: href expected "http://ho\x1est/" but got "http://ho%1Est/"
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> assert_equals: href expected "http://ho\x1fst/" but got "http://ho%1Fst/"
 FAIL Parsing: <http://ho%20st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
 FAIL Parsing: <http://ho%23st/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
+PASS Parsing: <http://ho%25st/> against <about:blank>
 PASS Parsing: <http://ho%2Fst/> against <about:blank>
 FAIL Parsing: <http://ho%3Ast/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%3Ast/" but got "http://ho:st/"
 FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
@@ -396,8 +463,9 @@
 PASS Parsing: <http://ho%5Cst/> against <about:blank>
 FAIL Parsing: <http://ho%5Dst/> against <about:blank> assert_equals: failure should set href to input expected "http://ho%5Dst/" but got "http://ho]st/"
 FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_unreached: Expected URL to fail parsing Reached unreachable code
-FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%1F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
-FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> assert_equals: href expected "http://host/" but got "http://ho%7Fst/"
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: href expected "http://\x01\x02\x03\x04\x05\x06\x07\b\v\f\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!\"$&'()*+,-.;=_`{}~/" but got "http://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F%21%22%24%26%27%28%29%2A+%2C-.%3B%3D_%60%7B%7D%7E/"
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
 FAIL Parsing: <ftp://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%80/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <ftp://example.com%A0/> against <about:blank> assert_equals: failure should set href to input expected "ftp://example.com%A0/" but got "ftp://example.com%EF%BF%BD/"
 FAIL Parsing: <https://example.com%80/> against <about:blank> assert_equals: failure should set href to input expected "https://example.com%80/" but got "https://example.com%EF%BF%BD/"
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/failure-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/failure-expected.txt
index b9949a1..4d55511 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/failure-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/failure-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 659 tests; 386 PASS, 273 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 695 tests; 410 PASS, 285 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS URL's constructor's base argument: file://example:1/ should throw
 PASS URL's href: file://example:1/ should throw
@@ -139,18 +139,6 @@
 PASS sendBeacon(): http://[www.google.com]/ should throw
 FAIL Location's href: http://[www.google.com]/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://[www.google.com]/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
 PASS window.open(): http://[www.google.com]/ should throw
-FAIL URL's constructor's base argument: sc://\0/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://\0/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://\0/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://\0/ should throw
-FAIL Location's href: sc://\0/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://\0/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc:// / should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc:// / should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc:// / should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc:// / should throw
-FAIL Location's href: sc:// / should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc:// / should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
 FAIL URL's constructor's base argument: sc://@/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
 FAIL URL's href: sc://@/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
 FAIL XHR: sc://@/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
@@ -175,24 +163,78 @@
 PASS sendBeacon(): sc://:12/ should throw
 FAIL Location's href: sc://:12/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): sc://:12/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc://[/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://[/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://[/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://[/ should throw
-FAIL Location's href: sc://[/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://[/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc://\/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://\/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://\/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://\/ should throw
-FAIL Location's href: sc://\/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://\/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: sc://]/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: sc://]/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: sc://]/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): sc://]/ should throw
-FAIL Location's href: sc://]/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): sc://]/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a\0b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a\0b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a\0b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a\0b/ should throw
+FAIL Location's href: sc://a\0b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a\0b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a b/ should throw
+FAIL Location's href: sc://a b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a<b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a<b should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a<b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a<b should throw
+FAIL Location's href: sc://a<b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a<b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a>b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a>b should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a>b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a>b should throw
+FAIL Location's href: sc://a>b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a>b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a[b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a[b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a[b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a[b/ should throw
+FAIL Location's href: sc://a[b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a[b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a\b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a\b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a\b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a\b/ should throw
+FAIL Location's href: sc://a\b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a\b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a]b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a]b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a]b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a]b/ should throw
+FAIL Location's href: sc://a]b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a]b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a^b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a^b should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a^b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a^b should throw
+FAIL Location's href: sc://a^b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a^b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: sc://a|b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: sc://a|b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: sc://a|b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+PASS sendBeacon(): sc://a|b/ should throw
+FAIL Location's href: sc://a|b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): sc://a|b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://a\0b/ should throw
+PASS URL's href: http://a\0b/ should throw
+PASS XHR: http://a\0b/ should throw
+PASS sendBeacon(): http://a\0b/ should throw
+FAIL Location's href: http://a\0b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a\0b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a\0b/ should throw
+FAIL URL's constructor's base argument: http://a b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://a b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://a b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://a b/ should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://a b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://a b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://a%b/ should throw
+PASS URL's href: http://a%b/ should throw
+PASS XHR: http://a%b/ should throw
+PASS sendBeacon(): http://a%b/ should throw
+FAIL Location's href: http://a%b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a%b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a%b/ should throw
 FAIL URL's constructor's base argument: http://a<b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
 FAIL URL's href: http://a<b should throw assert_throws_js: function "() => url.href = test.input" did not throw
 FAIL XHR: http://a<b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
@@ -205,42 +247,30 @@
 FAIL sendBeacon(): http://a>b should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
 FAIL Location's href: http://a>b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): http://a>b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://a[b/ should throw
+PASS URL's href: http://a[b/ should throw
+PASS XHR: http://a[b/ should throw
+PASS sendBeacon(): http://a[b/ should throw
+FAIL Location's href: http://a[b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a[b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a[b/ should throw
+PASS URL's constructor's base argument: http://a]b/ should throw
+PASS URL's href: http://a]b/ should throw
+PASS XHR: http://a]b/ should throw
+PASS sendBeacon(): http://a]b/ should throw
+FAIL Location's href: http://a]b/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a]b/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://a]b/ should throw
 PASS URL's constructor's base argument: http://a^b should throw
 PASS URL's href: http://a^b should throw
 PASS XHR: http://a^b should throw
 PASS sendBeacon(): http://a^b should throw
 FAIL Location's href: http://a^b should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a^b' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
 PASS window.open(): http://a^b should throw
-FAIL URL's constructor's base argument: non-special://a<b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: non-special://a<b should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: non-special://a<b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): non-special://a<b should throw
-FAIL Location's href: non-special://a<b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): non-special://a<b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: non-special://a>b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: non-special://a>b should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: non-special://a>b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): non-special://a>b should throw
-FAIL Location's href: non-special://a>b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): non-special://a>b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: non-special://a^b should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: non-special://a^b should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: non-special://a^b should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): non-special://a^b should throw
-FAIL Location's href: non-special://a^b should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): non-special://a^b should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: foo://ho\0st/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: foo://ho\0st/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: foo://ho\0st/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): foo://ho\0st/ should throw
-FAIL Location's href: foo://ho\0st/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): foo://ho\0st/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
-FAIL URL's constructor's base argument: foo://ho|st/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
-FAIL URL's href: foo://ho|st/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
-FAIL XHR: foo://ho|st/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
-PASS sendBeacon(): foo://ho|st/ should throw
-FAIL Location's href: foo://ho|st/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
-FAIL window.open(): foo://ho|st/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+FAIL URL's constructor's base argument: http://a|b/ should throw assert_throws_js: function "() => new URL("about:blank", test.input)" did not throw
+FAIL URL's href: http://a|b/ should throw assert_throws_js: function "() => url.href = test.input" did not throw
+FAIL XHR: http://a|b/ should throw assert_throws_dom: function "() => client.open("GET", test.input)" did not throw
+FAIL sendBeacon(): http://a|b/ should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
+FAIL Location's href: http://a|b/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
+FAIL window.open(): http://a|b/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
 PASS URL's constructor's base argument: http://ho%00st/ should throw
 PASS URL's href: http://ho%00st/ should throw
 PASS XHR: http://ho%00st/ should throw
@@ -277,6 +307,12 @@
 FAIL sendBeacon(): http://ho%23st/ should throw assert_throws_js: function "() => self.navigator.sendBeacon(test.input)" did not throw
 FAIL Location's href: http://ho%23st/ should throw assert_throws_js: function "() => self[0].location = test.input" did not throw
 FAIL window.open(): http://ho%23st/ should throw assert_throws_dom: function "() => self.open(test.input).close()" did not throw
+PASS URL's constructor's base argument: http://ho%25st/ should throw
+PASS URL's href: http://ho%25st/ should throw
+PASS XHR: http://ho%25st/ should throw
+PASS sendBeacon(): http://ho%25st/ should throw
+FAIL Location's href: http://ho%25st/ should throw assert_throws_js: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://ho%25st/' is not a valid URL." ("SyntaxError") expected instance of function "function TypeError() { [native code] }" ("TypeError")
+PASS window.open(): http://ho%25st/ should throw
 PASS URL's constructor's base argument: http://ho%2Fst/ should throw
 PASS URL's href: http://ho%2Fst/ should throw
 PASS XHR: http://ho%2Fst/ should throw
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any-expected.txt
index a09acb9..45bb947 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/url-constructor.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 671 tests; 468 PASS, 203 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 738 tests; 476 PASS, 262 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS Parsing: <http://example	.
 org> against <http://example.org/foo/bar>
@@ -385,12 +385,6 @@
 FAIL Parsing: <javascript:/../> against <about:blank> assert_equals: href expected "javascript:/" but got "javascript:/../"
 FAIL Parsing: <mailto:/../> against <about:blank> assert_equals: href expected "mailto:/" but got "mailto:/../"
 FAIL Parsing: <sc://ñ.test/> against <about:blank> assert_equals: host expected "%C3%B1.test" but got ""
-FAIL Parsing: <sc://\0/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
-FAIL Parsing: <sc:// /> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
 FAIL Parsing: <sc://%/> against <about:blank> assert_equals: host expected "%" but got ""
 FAIL Parsing: <sc://@/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
@@ -404,15 +398,6 @@
 FAIL Parsing: <sc://:12/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <sc://[/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
-FAIL Parsing: <sc://\/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
-FAIL Parsing: <sc://]/> against <about:blank> assert_throws_js: function "function() {
-          bURL(expected.input, expected.base)
-        }" did not throw
 FAIL Parsing: <x> against <sc://ñ> Failed to construct 'URL': Invalid URL
 PASS Parsing: <sc:\../> against <about:blank>
 PASS Parsing: <sc::a@example.net> against <about:blank>
@@ -420,42 +405,126 @@
 PASS Parsing: <wow:%1G> against <about:blank>
 FAIL Parsing: <wow:￿> against <about:blank> assert_equals: href expected "wow:%EF%BF%BF" but got "wow:%EF%BF%BD"
 FAIL Parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Parsing: <http://a<b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a\0b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <http://a>b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-PASS Parsing: <http://a^b> against <about:blank>
-FAIL Parsing: <non-special://a<b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a<b> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <non-special://a>b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a>b> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <non-special://a^b> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a[b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <foo://ho\0st/> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a\b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <foo://ho|st/> against <about:blank> assert_throws_js: function "function() {
+FAIL Parsing: <sc://a]b/> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <sc://a^b> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <sc://a|b/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
 FAIL Parsing: <foo://ho	st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho
 st/> against <about:blank> assert_equals: host expected "host" but got ""
 FAIL Parsing: <foo://ho\rst/> against <about:blank> assert_equals: host expected "host" but got ""
+PASS Parsing: <http://a\0b/> against <about:blank>
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://a b/> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+PASS Parsing: <http://a%b/> against <about:blank>
+FAIL Parsing: <http://a<b> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <http://a>b> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+PASS Parsing: <http://a[b/> against <about:blank>
+PASS Parsing: <http://a]b/> against <about:blank>
+PASS Parsing: <http://a^b> against <about:blank>
+FAIL Parsing: <http://a|b/> against <about:blank> assert_throws_js: function "function() {
+          bURL(expected.input, expected.base)
+        }" did not throw
+FAIL Parsing: <http://ab/> against <about:blank> Failed to construct 'URL': Invalid URL
+PASS Parsing: <http://ho	st/> against <about:blank>
+PASS Parsing: <http://ho
+st/> against <about:blank>
+PASS Parsing: <http://ho\rst/> against <about:blank>
 PASS Parsing: <http://ho%00st/> against <about:blank>
+FAIL Parsing: <http://ho%01st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%02st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%03st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%04st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%05st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%06st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%07st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%08st/> against <about:blank> Failed to construct 'URL': Invalid URL
 PASS Parsing: <http://ho%09st/> against <about:blank>
 PASS Parsing: <http://ho%0Ast/> against <about:blank>
+FAIL Parsing: <http://ho%0Bst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%0Cst/> against <about:blank> Failed to construct 'URL': Invalid URL
 PASS Parsing: <http://ho%0Dst/> against <about:blank>
+FAIL Parsing: <http://ho%0Est/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%0Fst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%10st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%11st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%12st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%13st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%14st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%15st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%16st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%17st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%18st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%19st/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Ast/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Bst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Cst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Dst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Est/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://ho%1Fst/> against <about:blank> Failed to construct 'URL': Invalid URL
 FAIL Parsing: <http://ho%20st/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
 FAIL Parsing: <http://ho%23st/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
+PASS Parsing: <http://ho%25st/> against <about:blank>
 PASS Parsing: <http://ho%2Fst/> against <about:blank>
 PASS Parsing: <http://ho%3Ast/> against <about:blank>
 FAIL Parsing: <http://ho%3Cst/> against <about:blank> assert_throws_js: function "function() {
@@ -474,8 +543,9 @@
 FAIL Parsing: <http://ho%7Cst/> against <about:blank> assert_throws_js: function "function() {
           bURL(expected.input, expected.base)
         }" did not throw
-FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%1F!\"$&'()*+,-.;=_`{}~" but got ""
+FAIL Parsing: <http://ho%7Fst/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
+FAIL Parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank> assert_equals: host expected "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~" but got ""
 PASS Parsing: <ftp://example.com%80/> against <about:blank>
 PASS Parsing: <ftp://example.com%A0/> against <about:blank>
 PASS Parsing: <https://example.com%80/> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any-expected.txt
index 40b0cfe..815ef087 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any-expected.txt
@@ -264,8 +264,8 @@
 PASS Origin parsing: <wow:%1G> against <about:blank>
 PASS Origin parsing: <wow:￿> against <about:blank>
 FAIL Origin parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
-PASS Origin parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
+PASS Origin parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Origin parsing: <ftp://%e2%98%83> against <about:blank>
 PASS Origin parsing: <https://%e2%98%83> against <about:blank>
 PASS Origin parsing: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any.worker-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any.worker-expected.txt
index 40b0cfe..815ef087 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/url/url-origin.any.worker-expected.txt
@@ -264,8 +264,8 @@
 PASS Origin parsing: <wow:%1G> against <about:blank>
 PASS Origin parsing: <wow:￿> against <about:blank>
 FAIL Origin parsing: <http://example.com/U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿?U+d800𐟾U+dfff﷐﷏﷯ﷰ￾￿> against <about:blank> Failed to construct 'URL': Invalid URL
-FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
-PASS Origin parsing: <sc://!"$&'()*+,-.;=_`{}~/> against <about:blank>
+FAIL Origin parsing: <http://!"$&'()*+,-.;=_`{}~/> against <about:blank> Failed to construct 'URL': Invalid URL
+PASS Origin parsing: <sc://!"$%&'()*+,-.;=_`{}~/> against <about:blank>
 PASS Origin parsing: <ftp://%e2%98%83> against <about:blank>
 PASS Origin parsing: <https://%e2%98%83> against <about:blank>
 PASS Origin parsing: <http://127.0.0.1:10100/relative_import.html> against <about:blank>
diff --git a/third_party/blink/web_tests/virtual/basic-card-disabled/README.md b/third_party/blink/web_tests/virtual/basic-card-disabled/README.md
new file mode 100644
index 0000000..f6507ba
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/basic-card-disabled/README.md
@@ -0,0 +1 @@
+The tests that depend on basic-card fail as expected when the basic-card feature is disabled.
diff --git a/third_party/blink/web_tests/virtual/basic-card-disabled/http/tests/payments/payment-instruments-expected.txt b/third_party/blink/web_tests/virtual/basic-card-disabled/http/tests/payments/payment-instruments-expected.txt
new file mode 100644
index 0000000..700c5303
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/basic-card-disabled/http/tests/payments/payment-instruments-expected.txt
@@ -0,0 +1,17 @@
+CONSOLE WARNING: The page that installed the payment handler does not contain a web app manifest link: <link rel="manifest" href="some-file-name-here">. This manifest defines the payment handler's name and icon. User may not recognize this payment handler in UI, because it will be labeled only by its origin.
+CONSOLE WARNING: The page that installed the payment handler does not contain a web app manifest link: <link rel="manifest" href="some-file-name-here">. This manifest defines the payment handler's name and icon. User may not recognize this payment handler in UI, because it will be labeled only by its origin.
+CONSOLE WARNING: The page that installed the payment handler does not contain a web app manifest link: <link rel="manifest" href="some-file-name-here">. This manifest defines the payment handler's name and icon. User may not recognize this payment handler in UI, because it will be labeled only by its origin.
+CONSOLE WARNING: The page that installed the payment handler does not contain a web app manifest link: <link rel="manifest" href="some-file-name-here">. This manifest defines the payment handler's name and icon. User may not recognize this payment handler in UI, because it will be labeled only by its origin.
+CONSOLE WARNING: The page that installed the payment handler does not contain a web app manifest link: <link rel="manifest" href="some-file-name-here">. This manifest defines the payment handler's name and icon. User may not recognize this payment handler in UI, because it will be labeled only by its origin.
+CONSOLE WARNING: The page that installed the payment handler does not contain a web app manifest link: <link rel="manifest" href="some-file-name-here">. This manifest defines the payment handler's name and icon. User may not recognize this payment handler in UI, because it will be labeled only by its origin.
+This is a testharness.js-based test.
+FAIL PaymentInstruments set/get methods test with basic-card assert_unreached: unexpected rejection: assert_object_equals: value is undefined, expected object Reached unreachable code
+PASS PaymentInstruments set/get methods test with url method
+PASS PaymentInstruments.get() should throw NotFoundError if no stored key
+PASS PaymentInstruments delete method test
+PASS PaymentInstruments |has| method test
+PASS PaymentInstruments |keys| method test
+PASS PaymentInstruments |clear| method test
+PASS Throw NotAllowedError if permission is not granted
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/basic-card-disabled/payments/payment-request-interface-expected.txt b/third_party/blink/web_tests/virtual/basic-card-disabled/payments/payment-request-interface-expected.txt
new file mode 100644
index 0000000..0c526f6
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/basic-card-disabled/payments/payment-request-interface-expected.txt
@@ -0,0 +1,152 @@
+CONSOLE ERROR: Uncaught (in promise) UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process.
+CONSOLE ERROR: Uncaught (in promise) UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process.
+CONSOLE ERROR: Uncaught (in promise) UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process.
+CONSOLE ERROR: Uncaught (in promise) UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process.
+This is a testharness.js-based test.
+PASS Creating a PaymentRequest with empty parameters should not throw or crash.
+PASS Creating a PaymentRequest with extra parameters should not throw or crash.
+PASS Creating a PaymentRequest with omitted optional parameters should not throw or crash.
+PASS Creating a PaymentRequest with undefined optional parameters should not throw or crash.
+PASS Creating a PaymentRequest with null optional parameters should not throw or crash.
+PASS PaymentRequest should have readonly shippingAddress and shippingOption properties.
+PASS PaymentRequest should have onShippingAddressChange and onShippingOptionChange events.
+PASS PaymentRequest should have methods abort() and show().
+PASS PaymentRequest.abort() and PaymentRequest.show() should take no parameters.
+PASS Valid data causes no errors.
+PASS Shipping option identifier should be null if shipping request is omitted.
+PASS Shipping option identifier should be null if shipping is explicitly not requested.
+PASS Shipping option identifier should be null if no shipping options are provided.
+PASS Shipping option identifier should be null if the single provided option is not selected.
+PASS Shipping option identifier should default to the single provided option if it is selected.
+PASS Shipping option identifier should be null if multiple unselected shipping options are provided.
+PASS Shipping option identifier should default to the selected shipping option.
+PASS Shipping option identifier should default to the last selected shipping option, if multiple are selected.
+PASS A TypeError should be thrown for duplicate shipping option identifiers.
+PASS Shipping type should be null if shipping is explicitly not requested.
+PASS Shipping type should be 'shipping' by default if shipping type isn't specified.
+PASS Shipping type should be null if shipping type is specified but requestShipping is false.
+PASS Shipping type should be 'shipping' if shipping type is specified as 'shipping'.
+PASS Shipping type should be 'delivery' if shipping type is specified as 'delivery'.
+PASS Shipping type should be 'pickup' if shipping type is specified as 'pickup'.
+PASS Shipping type should be 'shipping' if shipping type is specified as undefined.
+PASS Undefined display items should not throw.
+PASS Empty display items should not throw.
+PASS Non-negative total value should not throw.
+PASS Negative line item value should not throw.
+PASS Undefined modifiers should not throw.
+PASS Non-negative total value in PaymentDetailsModifier should not throw.
+PASS Duplicate supported payment method identifiers in separate methoData objects of modifiers should not throw.
+PASS Android Pay parameters for test environment with gateway token should not throw.
+PASS Android Pay parameters for produciton environment with network token should not throw.
+PASS Basic card parameters should not throw.
+PASS Empty basic card parameters should not throw.
+PASS Invalid basic card parameters should not throw when method name is not "basic-card".
+PASS Android Pay parameters for network token without environment key should not throw.
+PASS Invalid Android Pay parameters should not throw when method name is not "https://android.com/pay".
+PASS Invalid Android Pay parameters should not throw even when method name is "https://android.com/pay".
+PASS Array value for payment method specific data parameter should not throw
+PASS abort() without show() should reject with error
+PASS PaymentRequest constructor should throw for incorrect parameter types.
+PASS PaymentRequest constructor should throw for undefined required parameters.
+PASS PaymentRequest constructor should throw for null required parameter.
+PASS Empty list of supported payment method identifiers should throw TypeError.
+PASS Empty supported payment method identifier should throw RangeError.
+PASS Absence of total should throw TypeError.
+PASS Negative total value should throw a TypeError.
+PASS Negative total value in PaymentDetailsModifier should throw a TypeError.
+PASS Undefined supportedMethods in modifiers should throw TypeError.
+PASS Empty supportedMethods in modifiers should throw RangeError.
+PASS Absence of supportedMethods in modifiers should throw TypeError.
+PASS Empty details should throw
+PASS Null items should throw
+PASS Null shipping options should throw
+PASS Undefined PaymentShippingType value for shppingType should throw a TypeError
+PASS Null for shppingType should throw a TypeError
+PASS Array value for shppingType should throw a TypeError
+PASS Object value for shppingType should throw a TypeError
+PASS Numeric value for shppingType should throw a TypeError
+PASS String value for payment method specific data parameter should throw
+PASS Numeric value for payment method specific data parameter should throw
+PASS Infinite JSON value for one of the payment method specific data pieces should throw
+PASS Null for payment method specific data parameter should throw
+PASS Empty string for payment method specific data parameter should throw
+FAIL PaymentRequest constructor should throw for invalid "basic-card" parameters. assert_throws_js: function "function() {
+        new PaymentRequest([{'supportedMethods': 'basic-card', 'data': {'supportedTypes': 0, 'supportedNetworks': 'foo'}}], buildDetails())
+    }" did not throw
+PASS Undefined currency code in total should throw
+PASS Invalid amount "-" in total should throw
+PASS Invalid amount "notdigits" in total should throw
+PASS Invalid amount "ALSONOTDIGITS" in total should throw
+PASS Invalid amount "10." in total should throw
+PASS Invalid amount ".99" in total should throw
+PASS Invalid amount "-10." in total should throw
+PASS Invalid amount "-.99" in total should throw
+PASS Invalid amount "10-" in total should throw
+PASS Invalid amount "1-0" in total should throw
+PASS Invalid amount "1.0.0" in total should throw
+PASS Invalid amount "1/3" in total should throw
+PASS Empty amount in total should throw
+PASS Null amount in total should throw
+PASS Undefined amount in total should throw
+PASS Undefined currency code in displayItems.0 should throw
+PASS Invalid amount "-" in displayItems.0 should throw
+PASS Invalid amount "notdigits" in displayItems.0 should throw
+PASS Invalid amount "ALSONOTDIGITS" in displayItems.0 should throw
+PASS Invalid amount "10." in displayItems.0 should throw
+PASS Invalid amount ".99" in displayItems.0 should throw
+PASS Invalid amount "-10." in displayItems.0 should throw
+PASS Invalid amount "-.99" in displayItems.0 should throw
+PASS Invalid amount "10-" in displayItems.0 should throw
+PASS Invalid amount "1-0" in displayItems.0 should throw
+PASS Invalid amount "1.0.0" in displayItems.0 should throw
+PASS Invalid amount "1/3" in displayItems.0 should throw
+PASS Empty amount in displayItems.0 should throw
+PASS Null amount in displayItems.0 should throw
+PASS Undefined amount in displayItems.0 should throw
+PASS Undefined currency code in shippingOptions.0 should throw
+PASS Invalid amount "-" in shippingOptions.0 should throw
+PASS Invalid amount "notdigits" in shippingOptions.0 should throw
+PASS Invalid amount "ALSONOTDIGITS" in shippingOptions.0 should throw
+PASS Invalid amount "10." in shippingOptions.0 should throw
+PASS Invalid amount ".99" in shippingOptions.0 should throw
+PASS Invalid amount "-10." in shippingOptions.0 should throw
+PASS Invalid amount "-.99" in shippingOptions.0 should throw
+PASS Invalid amount "10-" in shippingOptions.0 should throw
+PASS Invalid amount "1-0" in shippingOptions.0 should throw
+PASS Invalid amount "1.0.0" in shippingOptions.0 should throw
+PASS Invalid amount "1/3" in shippingOptions.0 should throw
+PASS Empty amount in shippingOptions.0 should throw
+PASS Null amount in shippingOptions.0 should throw
+PASS Undefined amount in shippingOptions.0 should throw
+PASS Undefined currency code in modifiers.0.total should throw
+PASS Invalid amount "-" in modifiers.0.total should throw
+PASS Invalid amount "notdigits" in modifiers.0.total should throw
+PASS Invalid amount "ALSONOTDIGITS" in modifiers.0.total should throw
+PASS Invalid amount "10." in modifiers.0.total should throw
+PASS Invalid amount ".99" in modifiers.0.total should throw
+PASS Invalid amount "-10." in modifiers.0.total should throw
+PASS Invalid amount "-.99" in modifiers.0.total should throw
+PASS Invalid amount "10-" in modifiers.0.total should throw
+PASS Invalid amount "1-0" in modifiers.0.total should throw
+PASS Invalid amount "1.0.0" in modifiers.0.total should throw
+PASS Invalid amount "1/3" in modifiers.0.total should throw
+PASS Empty amount in modifiers.0.total should throw
+PASS Null amount in modifiers.0.total should throw
+PASS Undefined amount in modifiers.0.total should throw
+PASS Undefined currency code in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "-" in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "notdigits" in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "ALSONOTDIGITS" in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "10." in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount ".99" in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "-10." in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "-.99" in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "10-" in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "1-0" in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "1.0.0" in modifiers.0.additionalDisplayItems.0 should throw
+PASS Invalid amount "1/3" in modifiers.0.additionalDisplayItems.0 should throw
+PASS Empty amount in modifiers.0.additionalDisplayItems.0 should throw
+PASS Null amount in modifiers.0.additionalDisplayItems.0 should throw
+PASS Undefined amount in modifiers.0.additionalDisplayItems.0 should throw
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/css-highlight-inheritance/external/wpt/css/css-pseudo/idlharness-expected.txt b/third_party/blink/web_tests/virtual/css-highlight-inheritance/external/wpt/css/css-pseudo/idlharness-expected.txt
new file mode 100644
index 0000000..f76169b
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/css-highlight-inheritance/external/wpt/css/css-pseudo/idlharness-expected.txt
@@ -0,0 +1,29 @@
+This is a testharness.js-based test.
+FAIL idl_test setup promise_test: Unhandled rejection with value: object "TypeError: window.getPseudoElements is not a function"
+PASS idl_test validation
+PASS Partial interface Element: original interface defined
+PASS Partial interface Element: member names are unique
+PASS Element includes ParentNode: member names are unique
+PASS Element includes NonDocumentTypeChildNode: member names are unique
+PASS Element includes ChildNode: member names are unique
+PASS Element includes Slottable: member names are unique
+FAIL CSSPseudoElement interface: existence and properties of interface object assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface object length assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface object name assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: attribute type assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: attribute element assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: attribute parent assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement interface: operation pseudo(CSSOMString) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
+FAIL CSSPseudoElement must be primary interface of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL Stringification of beforeElements.item(0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "type" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "element" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "parent" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: beforeElements.item(0) must inherit property "pseudo(CSSOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL CSSPseudoElement interface: calling pseudo(CSSOMString) on beforeElements.item(0) with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: beforeElements is not defined"
+FAIL Element interface: operation pseudo(CSSOMString) assert_own_property: interface prototype object missing non-static operation expected property "pseudo" missing
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/no-forced-frame-updates/README.md b/third_party/blink/web_tests/virtual/no-forced-frame-updates/README.md
new file mode 100644
index 0000000..c286d2a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/no-forced-frame-updates/README.md
@@ -0,0 +1,5 @@
+This suite runs WPT tests under `html/dom/render-blocking/mechanism` with
+`--enable-features=NoForcedFrameUpdates`.
+
+TODO(crbug.com/1271296): Remove this virtual test suite when WPT runner is
+enabled on CQ.
diff --git a/third_party/blink/web_tests/virtual/prerender/external/wpt/speculation-rules/prerender/cookies-expected.txt b/third_party/blink/web_tests/virtual/prerender/external/wpt/speculation-rules/prerender/cookies-expected.txt
new file mode 100644
index 0000000..56e7b27
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/prerender/external/wpt/speculation-rules/prerender/cookies-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL prerendering page should be able to access cookies promise_test: Unhandled rejection with value: object "ReferenceError: cookieStore is not defined"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/prerender/external/wpt/speculation-rules/prerender/media-autoplay-expected.txt b/third_party/blink/web_tests/virtual/prerender/external/wpt/speculation-rules/prerender/media-autoplay-expected.txt
new file mode 100644
index 0000000..4a68d62
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/prerender/external/wpt/speculation-rules/prerender/media-autoplay-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL media autoplay should defer playaback assert_equals: expected false but got true
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-no-coep.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-no-coep.https.html
index 21089e5..75980a1 100644
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-no-coep.https.html
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-no-coep.https.html
@@ -2,38 +2,23 @@
 <title>Test COEP properties set for a Fenced Frame Tree</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
 <script src="resources/utils.js"></script>
+<script src="resources/embedder-policy.js"></script>
 
 <body>
 <script>
-// This key is used by `resources/embeddee-coep-require-corp.https.html` to
-// let us know if a script inside has been executed.
-const corp_key = KEYS["embed_coep_require_corp"];
-
-// This key is used by `resources/embeddee-no-coep.https.html` to let us know
-// if a script inside has been executed.
-const no_coep_key = KEYS["embed_no_coep"];
-
-async function setupTest(test_type) {
-  switch (test_type) {
-    case "coep:require-corp":
-      return attachFencedFrame(`resources/embeddee-coep-require-corp.https.html`);
-      break;
-    case "no coep":
-      return attachFencedFrame(`resources/embeddee-no-coep.https.html`);
-      break;
-  }
-}
-
 promise_test(async () => {
-  const frame = setupTest("coep:require-corp");
-  const result = await nextValueFromServer(corp_key);
+  const uuid = token();
+  const frame = setupTest("coep:require-corp", uuid);
+  const result = await nextValueFromServer(uuid);
   assert_equals(result, "PASS", "embedded page has been loaded.");
 }, "Create fencedframe with COEP:require-corp");
 
 promise_test(async () => {
-  const frame = setupTest("no coep");
-  const result = await nextValueFromServer(no_coep_key);
+  const uuid = token();
+  const frame = setupTest("no coep", uuid);
+  const result = await nextValueFromServer(uuid);
   assert_equals(result, "PASS",
                 "page without COEP should be able to load page with COEP");
 }, "Create fencedframe without COEP header");
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-require-corp.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-require-corp.https.html
index 600b69f..029fcc82 100644
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-require-corp.https.html
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/embedder-require-corp.https.html
@@ -2,41 +2,25 @@
 <title>Test COEP properties set for a Fenced Frame Tree</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
 <script src="resources/utils.js"></script>
+<script src="resources/embedder-policy.js"></script>
 
 <body>
 <script>
-// This key is used by `resources/embeddee-coep-require-corp.https.html` to
-// let us know if a script inside has been executed.
-const corp_key = KEYS["embed_coep_require_corp"];
-
-// This key is used by `resources/embeddee-no-coep.https.html` to let us know
-// if a script inside has been executed.
-const no_coep_key = KEYS["embed_no_coep"];
-
-async function setupTest(test_type) {
-  switch (test_type) {
-    case "coep:require-corp":
-      return attachFencedFrame(`resources/embeddee-coep-require-corp.https.html`);
-      break;
-    case "no coep":
-      return attachFencedFrame(`resources/embeddee-no-coep.https.html`);
-      break;
-  }
-}
-
 promise_test(async () => {
-  const frame = setupTest("coep:require-corp");
-  const result = await nextValueFromServer(corp_key);
+  const uuid = token();
+  const frame = setupTest("coep:require-corp", uuid);
+  const result = await nextValueFromServer(uuid);
   assert_equals(result, "PASS", "embedded page has been loaded.");
 }, "Create fencedframe with COEP:require-corp");
 
 promise_test(async (t) => {
+  const uuid = token();
   t.step_timeout(() => t.done(), 3000);
-  const frame = setupTest("no coep");
-  const result = await nextValueFromServer(no_coep_key);
+  const frame = setupTest("no coep", uuid);
+  const result = await nextValueFromServer(uuid);
   assert_unreached("embedded page should not be loaded.");
 }, "Create fencedframe without COEP header");
-
 </script>
 </body>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/gamepad.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/gamepad.https.html
new file mode 100644
index 0000000..ef6b91e9
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/gamepad.https.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Gamepad API test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<script>
+promise_test(async () => {
+  const key = token();
+  attachFencedFrame(generateURL('resources/gamepad-inner.html', [key]));
+  const result = await nextValueFromServer(key);
+  assert_equals(
+      result,
+      'SecurityError',
+      'getGamepads should throw an error in a fenced frame');
+}, 'Gamepads information should not be read in the fenced frame.');
+</script>
+</body>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/maxframes.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/maxframes.html
index d174560..206dd35d 100644
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/maxframes.html
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/maxframes.html
@@ -2,12 +2,13 @@
 <title>Test Maximum Subframes</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
 <script src="resources/utils.js"></script>
 
 <body>
 <script>
 promise_test(async (t) => {
-  const maxframes_key = KEYS['maxframes_response'];
+  const maxframes_key = token();
 
   internals.setMaxNumberOfFramesToTen(true);
 
@@ -25,11 +26,13 @@
 
   // Now that the last frame is removed, a new fenced frame can be
   // created since the page is now under the subframe limit.
-  attachFencedFrame('resources/maxframes-inner.html');
+  const frame_url = generateURL("resources/maxframes-inner.html",
+                                [maxframes_key]);
+  attachFencedFrame(frame_url);
   const response = await nextValueFromServer(maxframes_key);
   assert_equals(response, "page loaded", "The inner frame should be loaded.");
 }, 'Max Subframes Test');
 
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-coep-require-corp.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-coep-require-corp.https.html
deleted file mode 100644
index c116c38..0000000
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-coep-require-corp.https.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<script src="utils.js"></script>
-<title>Embedded page embedded as a Fenced Frame</title>
-<script>
-const key = KEYS["embed_coep_require_corp"];
-writeValueToServer(key, "PASS");
-</script>
-</script>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-coep-require-corp.https.html.headers b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-coep-require-corp.https.html.headers
deleted file mode 100644
index 6a268d77..0000000
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-coep-require-corp.https.html.headers
+++ /dev/null
@@ -1,2 +0,0 @@
-Supports-Loading-Mode: fenced-frame
-cross-origin-embedder-policy: require-corp
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-no-coep.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-no-coep.https.html
deleted file mode 100644
index 91070a3..0000000
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-no-coep.https.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<script src="utils.js"></script>
-<title>Embedded page embedded as a Fenced Frame</title>
-<script>
-// This file is expected to be unreachable from
-// wpt_internal/fenced_frame/embedder-require-corp.https.html
-// because this file does not have COEP:require-corp and this file should not be
-// loaded.
-const key = KEYS["embed_no_coep"];
-writeValueToServer(key, "PASS");
-</script>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-no-coep.https.html.headers b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-no-coep.https.html.headers
deleted file mode 100644
index 1b63235..0000000
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee-no-coep.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Supports-Loading-Mode: fenced-frame
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee.html
new file mode 100644
index 0000000..3423be9a
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embeddee.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<script src="utils.js"></script>
+<title>A page embedded as a Fenced Frame for COEP tests</title>
+<script>
+const [uuid] = parseKeylist();
+writeValueToServer(uuid, "PASS");
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embedder-policy.js b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embedder-policy.js
new file mode 100644
index 0000000..9929b522
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/embedder-policy.js
@@ -0,0 +1,33 @@
+// This file should be loaded alongside with utils.js.
+// This file is loaded by:
+// - embedder-no-coep.https.html
+// - embedder-require-corp.https.html
+
+// Make input list to be used as a wptserve pipe
+// (https://web-platform-tests.org/writing-tests/server-pipes.html).
+// e.g.
+// args: ['content-type,text/plain','Age,0']
+// return: 'header(content-type,text/plain)|header(Age,0)'
+function generateHeader(headers) {
+  return headers.map((h) => {
+    return 'header(' + h + ')';
+  }).join('|');
+}
+
+// Setup a fenced frame for embedder-* WPTs.
+async function setupTest(test_type, uuid) {
+  let headers = ["Supports-Loading-Mode,fenced-frame"];
+  switch (test_type) {
+    case "coep:require-corp":
+      headers.push("cross-origin-embedder-policy,require-corp");
+      break;
+    case "no coep":
+      break;
+    default:
+      assert_unreachable("unknown test_type:" + test_type);
+      break;
+  }
+  const header_pipe = generateHeader(headers);
+  const url = generateURL('resources/embeddee.html?pipe=' + header_pipe, [uuid]);
+  return attachFencedFrame(url);
+}
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/gamepad-inner.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/gamepad-inner.html
new file mode 100644
index 0000000..3e253e4
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/gamepad-inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<script src="utils.js"></script>
+<title>getGamepads should throw an error in a fenced frame</title>
+<script>
+const [key] = parseKeylist();
+try {
+  navigator.getGamepads();
+  writeValueToServer(key, 'Expected exception but successed');
+} catch (e) {
+  writeValueToServer(key, e.name);
+}
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/gamepad-inner.html.headers b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/gamepad-inner.html.headers
new file mode 100644
index 0000000..6247f6d
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/gamepad-inner.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
\ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/maxframes-inner.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/maxframes-inner.html
index 1c14cfd..177b4d6 100644
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/maxframes-inner.html
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/maxframes-inner.html
@@ -8,11 +8,11 @@
   // This file is meant to be navigated to from a <fencedframe> element.
   // It reports back to the page hosting the <fencedframe> letting it
   // know that the frame loaded successfully.
-  const window_data_key = KEYS["maxframes_response"];
+  const [window_data_key] = parseKeylist();
   writeValueToServer(window_data_key, "page loaded");
 }
 
 init();
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
index 5880093..536ee12c 100644
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
@@ -80,9 +80,6 @@
   "fenced_history_length"                       : "00000000-0000-0000-0000-00000000002F",
   "outer_page_ready_for_next_navigation"        : "00000000-0000-0000-0000-000000000030",
 
-  "embed_coep_require_corp"                     : "00000000-0000-0000-0000-000000000031",
-  "embed_no_coep"                               : "00000000-0000-0000-0000-000000000032",
-
   "hid.getDevice"                               : "00000000-0000-0000-0000-000000000033",
 
   "ndef.write"                                  : "00000000-0000-0000-0000-000000000034",
@@ -106,8 +103,6 @@
 
   "frame_navigation"                            : "00000000-0000-0000-0000-000000000051",
   "frame_navigation ACK"                        : "00000000-0000-0000-0000-000000000052",
-
-  "maxframes_response"                          : "00000000-0000-0000-0000-000000000053",
   // Add keys above this list, incrementing the key UUID in hexadecimal
 }
 
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index e53a98f..2bf143a5 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-11-1-75-g267c6918d
-Revision: 267c6918d1575c83fc4412e3ffff91ae0b07b823
+Version: VER-2-11-1-78-g837f0345a
+Revision: 837f0345a9a6f3f64c94a41d944b097ffa359e5a
 CPEPrefix: cpe:/a:freetype:freetype:2.11.1
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/libjingle_xmpp/BUILD.gn b/third_party/libjingle_xmpp/BUILD.gn
index 5dc29ec..0600475 100644
--- a/third_party/libjingle_xmpp/BUILD.gn
+++ b/third_party/libjingle_xmpp/BUILD.gn
@@ -5,36 +5,10 @@
 import("//testing/libfuzzer/fuzzer_test.gni")
 import("//testing/test.gni")
 
-group("libjingle_xmpp") {
-  public_deps = [
-    ":rtc_xmllite",
-    ":rtc_xmpp",
-  ]
-}
-
 config("libjingle_xmpp_common_config") {
   defines = [ "EXPAT_RELATIVE_PATH" ]
 }
 
-static_library("rtc_task_runner") {
-  visibility = [
-    ":*",
-    "//jingle:*",
-  ]
-  sources = [
-    "task_runner/task.cc",
-    "task_runner/task.h",
-    "task_runner/taskparent.cc",
-    "task_runner/taskparent.h",
-    "task_runner/taskrunner.cc",
-    "task_runner/taskrunner.h",
-  ]
-  deps = [
-    "//base",
-    "//third_party/webrtc_overrides:webrtc_component",
-  ]
-}
-
 static_library("rtc_xmllite") {
   visibility = [
     ":*",
@@ -62,68 +36,14 @@
   all_dependent_configs = [ ":libjingle_xmpp_common_config" ]
 }
 
-static_library("rtc_xmpp") {
-  visibility = [
-    ":*",
-    "//remoting/*",
-  ]
-  cflags = []
-  sources = [
-    "xmpp/asyncsocket.h",
-    "xmpp/constants.cc",
-    "xmpp/constants.h",
-    "xmpp/jid.cc",
-    "xmpp/jid.h",
-    "xmpp/plainsaslhandler.h",
-    "xmpp/prexmppauth.h",
-    "xmpp/saslcookiemechanism.h",
-    "xmpp/saslhandler.h",
-    "xmpp/saslmechanism.cc",
-    "xmpp/saslmechanism.h",
-    "xmpp/saslplainmechanism.h",
-    "xmpp/xmppclient.cc",
-    "xmpp/xmppclient.h",
-    "xmpp/xmppclientsettings.h",
-    "xmpp/xmppengine.h",
-    "xmpp/xmppengineimpl.cc",
-    "xmpp/xmppengineimpl.h",
-    "xmpp/xmppengineimpl_iq.cc",
-    "xmpp/xmpplogintask.cc",
-    "xmpp/xmpplogintask.h",
-    "xmpp/xmppstanzaparser.cc",
-    "xmpp/xmppstanzaparser.h",
-    "xmpp/xmpptask.cc",
-    "xmpp/xmpptask.h",
-  ]
-
-  defines = []
-
-  deps = [
-    ":rtc_xmllite",
-    "//base",
-    "//net",
-    "//third_party/webrtc_overrides:webrtc_component",
-  ]
-  public_deps = [
-    ":rtc_task_runner",
-    "//third_party/expat",
-  ]
-  all_dependent_configs = [ ":libjingle_xmpp_common_config" ]
-
-  if (is_nacl) {
-    deps += [ "//native_client_sdk/src/libraries/nacl_io" ]
-  }
-}
-
 fuzzer_test("libjingle_xmpp_xmlparser_fuzzer") {
   sources = [ "xmllite/xmlparser_fuzzer.cc" ]
-  deps = [ ":libjingle_xmpp" ]
+  deps = [ ":rtc_xmllite" ]
 }
 
 test("libjingle_xmpp_unittests") {
   deps = [
-    ":libjingle_xmpp",
-    ":rtc_task_runner",
+    ":rtc_xmllite",
     "//base/test:run_all_unittests",
     "//base/test:test_support",
     "//testing/gtest",
@@ -131,19 +51,11 @@
   ]
 
   sources = [
-    "task_runner/task_unittest.cc",
     "xmllite/qname_unittest.cc",
     "xmllite/xmlbuilder_unittest.cc",
     "xmllite/xmlelement_unittest.cc",
     "xmllite/xmlnsstack_unittest.cc",
     "xmllite/xmlparser_unittest.cc",
     "xmllite/xmlprinter_unittest.cc",
-    "xmpp/fakexmppclient.h",
-    "xmpp/jid_unittest.cc",
-    "xmpp/util_unittest.cc",
-    "xmpp/util_unittest.h",
-    "xmpp/xmppengine_unittest.cc",
-    "xmpp/xmpplogintask_unittest.cc",
-    "xmpp/xmppstanzaparser_unittest.cc",
   ]
 }
diff --git a/third_party/libjingle_xmpp/OWNERS b/third_party/libjingle_xmpp/OWNERS
index 57740b5..4192e7b 100644
--- a/third_party/libjingle_xmpp/OWNERS
+++ b/third_party/libjingle_xmpp/OWNERS
@@ -1,3 +1 @@
-hta@chromium.org
-sergeyu@chromium.org
-tommi@chromium.org
+file://remoting/OWNERS
diff --git a/third_party/libjingle_xmpp/README.chromium b/third_party/libjingle_xmpp/README.chromium
index b401fa8..755f1ce 100644
--- a/third_party/libjingle_xmpp/README.chromium
+++ b/third_party/libjingle_xmpp/README.chromium
@@ -7,18 +7,13 @@
 License Android Compatible: Yes
 
 Description:
-XMPP (Extensible Messaging and Presence Protocol) is a communications protocol
-for messaging based on XML. xmllite is a minimalistic library for parsing and
-generating XML. The source for these libraries originates from the libjingle
-project, which was merged into the WebRTC codebase where it received minor
-updates. The code in the task_runner subdirectory used to live in
-third_party/webrtc/base, and it is a dependency for these libraries and
-Chromium's jingle component. As time passed, the code was no longer used in
-WebRTC but is still used in Chromium. Only the parts that are used in Chromium
-are added here.
+xmllite is a minimalistic library for parsing and generating XML. Initially it
+was a part of libjingle, which was used in chromium in the past. xmllite is the
+only part of libjingle still being used in chromium, particularly in
+//remoting.
 
-Nothing but Chromium uses this copy. If code in this directory is found to be
-unused in Chromium, it's OK to delete it.
+Nothing outside Chromium uses this copy. If code in this directory is found to
+be unused in Chromium, it's OK to delete it.
 
 The targets are restricted to current consumers. People considering whether
 to add new consumers should consider if they want to take over maintenance
diff --git a/third_party/libjingle_xmpp/task_runner/DEPS b/third_party/libjingle_xmpp/task_runner/DEPS
deleted file mode 100644
index 4b6d255..0000000
--- a/third_party/libjingle_xmpp/task_runner/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+third_party/webrtc/rtc_base/third_party",
-]
diff --git a/third_party/libjingle_xmpp/task_runner/DIR_METADATA b/third_party/libjingle_xmpp/task_runner/DIR_METADATA
deleted file mode 100644
index c7764d0..0000000
--- a/third_party/libjingle_xmpp/task_runner/DIR_METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-monorail {
-  component: "Internals>Headless"
-}
diff --git a/third_party/libjingle_xmpp/task_runner/task.cc b/third_party/libjingle_xmpp/task_runner/task.cc
deleted file mode 100644
index 573a10d..0000000
--- a/third_party/libjingle_xmpp/task_runner/task.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/task_runner/task.h"
-
-#include "base/check_op.h"
-#include "third_party/libjingle_xmpp/task_runner/taskrunner.h"
-
-namespace jingle_xmpp {
-
-int32_t Task::unique_id_seed_ = 0;
-
-Task::Task(TaskParent *parent)
-    : TaskParent(this, parent),
-      state_(STATE_INIT),
-      blocked_(false),
-      done_(false),
-      aborted_(false),
-      busy_(false),
-      error_(false),
-      start_time_(0),
-      timeout_time_(0),
-      timeout_seconds_(0),
-      timeout_suspended_(false)  {
-  unique_id_ = unique_id_seed_++;
-
-  // sanity check that we didn't roll-over our id seed
-  DCHECK(unique_id_ < unique_id_seed_);
-}
-
-Task::~Task() {
-  // Is this task being deleted in the correct manner?
-#if DCHECK_IS_ON
-  DCHECK(!done_ || GetRunner()->is_ok_to_delete(this));
-#endif
-  DCHECK(state_ == STATE_INIT || done_);
-  DCHECK(state_ == STATE_INIT || blocked_);
-
-  // If the task is being deleted without being done, it
-  // means that it hasn't been removed from its parent.
-  // This happens if a task is deleted outside of TaskRunner.
-  if (!done_) {
-    Stop();
-  }
-}
-
-void Task::Start() {
-  if (state_ != STATE_INIT)
-    return;
-  GetRunner()->StartTask(this);
-}
-
-void Task::Step() {
-  if (done_) {
-#if DCHECK_IS_ON
-    // we do not know how !blocked_ happens when done_ - should be impossible.
-    // But it causes problems, so in retail build, we force blocked_, and
-    // under debug we assert.
-    DCHECK(blocked_);
-#else
-    blocked_ = true;
-#endif
-    return;
-  }
-
-  // Async Error() was called
-  if (error_) {
-    done_ = true;
-    state_ = STATE_ERROR;
-    blocked_ = true;
-//   obsolete - an errored task is not considered done now
-//   SignalDone();
-
-    Stop();
-#if DCHECK_IS_ON
-    // verify that stop removed this from its parent
-    DCHECK(!parent()->IsChildTask(this));
-#endif
-    return;
-  }
-
-  busy_ = true;
-  int new_state = Process(state_);
-  busy_ = false;
-
-  if (aborted_) {
-    Abort(true);  // no need to wake because we're awake
-    return;
-  }
-
-  if (new_state == STATE_BLOCKED) {
-    blocked_ = true;
-    // Let the timeout continue
-  } else {
-    state_ = new_state;
-    blocked_ = false;
-  }
-
-  if (new_state == STATE_DONE) {
-    done_ = true;
-  } else if (new_state == STATE_ERROR) {
-    done_ = true;
-    error_ = true;
-  }
-
-  if (done_) {
-//  obsolete - call this yourself
-//    SignalDone();
-
-    Stop();
-#if DCHECK_IS_ON
-    // verify that stop removed this from its parent
-    DCHECK(!parent()->IsChildTask(this));
-#endif
-    blocked_ = true;
-  }
-}
-
-void Task::Abort(bool nowake) {
-  // Why only check for done_ (instead of "aborted_ || done_")?
-  //
-  // If aborted_ && !done_, it means the logic for aborting still
-  // needs to be executed (because busy_ must have been true when
-  // Abort() was previously called).
-  if (done_)
-    return;
-  aborted_ = true;
-  if (!busy_) {
-    done_ = true;
-    blocked_ = true;
-    error_ = true;
-
-    // "done_" is set before calling "Stop()" to ensure that this code
-    // doesn't execute more than once (recursively) for the same task.
-    Stop();
-#if DCHECK_IS_ON
-    // verify that stop removed this from its parent
-    DCHECK(!parent()->IsChildTask(this));
-#endif
-    if (!nowake) {
-      // WakeTasks to self-delete.
-      // Don't call Wake() because it is a no-op after "done_" is set.
-      // Even if Wake() did run, it clears "blocked_" which isn't desireable.
-      GetRunner()->WakeTasks();
-    }
-  }
-}
-
-void Task::Wake() {
-  if (done_)
-    return;
-  if (blocked_) {
-    blocked_ = false;
-    GetRunner()->WakeTasks();
-  }
-}
-
-void Task::Error() {
-  if (error_ || done_)
-    return;
-  error_ = true;
-  Wake();
-}
-
-std::string Task::GetStateName(int state) const {
-  switch (state) {
-    case STATE_BLOCKED: return "BLOCKED";
-    case STATE_INIT: return "INIT";
-    case STATE_START: return "START";
-    case STATE_DONE: return "DONE";
-    case STATE_ERROR: return "ERROR";
-    case STATE_RESPONSE: return "RESPONSE";
-  }
-  return "??";
-}
-
-int Task::Process(int state) {
-  int newstate = STATE_ERROR;
-
-  switch (state) {
-    case STATE_INIT:
-      newstate = STATE_START;
-      break;
-    case STATE_START:
-      newstate = ProcessStart();
-      break;
-    case STATE_RESPONSE:
-      newstate = ProcessResponse();
-      break;
-    case STATE_DONE:
-    case STATE_ERROR:
-      newstate = STATE_BLOCKED;
-      break;
-  }
-
-  return newstate;
-}
-
-void Task::Stop() {
-  // No need to wake because we're either awake or in abort
-  TaskParent::OnStopped(this);
-}
-
-int Task::ProcessResponse() {
-  return STATE_DONE;
-}
-
-} // namespace jingle_xmpp
diff --git a/third_party/libjingle_xmpp/task_runner/task.h b/third_party/libjingle_xmpp/task_runner/task.h
deleted file mode 100644
index dd9711a..0000000
--- a/third_party/libjingle_xmpp/task_runner/task.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_TASK_RUNNER_TASK_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_TASK_RUNNER_TASK_H_
-
-#include <stdint.h>
-
-#include <string>
-
-#include "third_party/libjingle_xmpp/task_runner/taskparent.h"
-
-/////////////////////////////////////////////////////////////////////
-//
-// TASK
-//
-/////////////////////////////////////////////////////////////////////
-//
-// Task is a state machine infrastructure.  States are pushed forward by
-// pushing forwards a TaskRunner that holds on to all Tasks.  The purpose
-// of Task is threefold:
-//
-// (1) It manages ongoing work on the UI thread.  Multitasking without
-// threads, keeping it easy, keeping it real. :-)  It does this by
-// organizing a set of states for each task.  When you return from your
-// Process*() function, you return an integer for the next state.  You do
-// not go onto the next state yourself.  Every time you enter a state,
-// you check to see if you can do anything yet.  If not, you return
-// STATE_BLOCKED.  If you _could_ do anything, do not return
-// STATE_BLOCKED - even if you end up in the same state, return
-// STATE_mysamestate.  When you are done, return STATE_DONE and then the
-// task will self-delete sometime afterwards.
-//
-// (2) It helps you avoid all those reentrancy problems when you chain
-// too many triggers on one thread.  Basically if you want to tell a task
-// to process something for you, you feed your task some information and
-// then you Wake() it.  Don't tell it to process it right away.  If it
-// might be working on something as you send it information, you may want
-// to have a queue in the task.
-//
-// (3) Finally it helps manage parent tasks and children.  If a parent
-// task gets aborted, all the children tasks are too.  The nice thing
-// about this, for example, is if you have one parent task that
-// represents, say, and Xmpp connection, then you can spawn a whole bunch
-// of infinite lifetime child tasks and now worry about cleaning them up.
-//  When the parent task goes to STATE_DONE, the task engine will make
-// sure all those children are aborted and get deleted.
-//
-// Notice that Task has a few built-in states, e.g.,
-//
-// STATE_INIT - the task isn't running yet
-// STATE_START - the task is in its first state
-// STATE_RESPONSE - the task is in its second state
-// STATE_DONE - the task is done
-//
-// STATE_ERROR - indicates an error - we should audit the error code in
-// light of any usage of it to see if it should be improved.  When I
-// first put down the task stuff I didn't have a good sense of what was
-// needed for Abort and Error, and now the subclasses of Task will ground
-// the design in a stronger way.
-//
-// STATE_NEXT - the first undefined state number.  (like WM_USER) - you
-// can start defining more task states there.
-//
-// When you define more task states, just override Process(int state) and
-// add your own switch statement.  If you want to delegate to
-// Task::Process, you can effectively delegate to its switch statement.
-// No fancy method pointers or such - this is all just pretty low tech,
-// easy to debug, and fast.
-//
-// Also notice that Task has some primitive built-in timeout functionality.
-//
-// A timeout is defined as "the task stays in STATE_BLOCKED longer than
-// timeout_seconds_."
-//
-// Descendant classes can override this behavior by calling the
-// various protected methods to change the timeout behavior.  For
-// instance, a descendand might call SuspendTimeout() when it knows
-// that it isn't waiting for anything that might timeout, but isn't
-// yet in the STATE_DONE state.
-//
-
-namespace jingle_xmpp {
-
-// Executes a sequence of steps
-class Task : public TaskParent {
- public:
-  Task(TaskParent *parent);
-  ~Task() override;
-
-  int32_t unique_id() { return unique_id_; }
-
-  void Start();
-  void Step();
-  int GetState() const { return state_; }
-  bool HasError() const { return (GetState() == STATE_ERROR); }
-  bool Blocked() const { return blocked_; }
-  bool IsDone() const { return done_; }
-  int64_t ElapsedTime();
-
-  // Called from outside to stop task without any more callbacks
-  void Abort(bool nowake = false);
-
-  // Called inside the task to signal that the task may be unblocked
-  void Wake();
-
- protected:
-
-  enum {
-    STATE_BLOCKED = -1,
-    STATE_INIT = 0,
-    STATE_START = 1,
-    STATE_DONE = 2,
-    STATE_ERROR = 3,
-    STATE_RESPONSE = 4,
-    STATE_NEXT = 5,  // Subclasses which need more states start here and higher
-  };
-
-  // Called inside to advise that the task should wake and signal an error
-  void Error();
-
-  virtual std::string GetStateName(int state) const;
-  virtual int Process(int state);
-  virtual void Stop();
-  virtual int ProcessStart() = 0;
-  virtual int ProcessResponse();
-
- protected:
-
- private:
-  void Done();
-
-  int state_;
-  bool blocked_;
-  bool done_;
-  bool aborted_;
-  bool busy_;
-  bool error_;
-  int64_t start_time_;
-  int64_t timeout_time_;
-  int timeout_seconds_;
-  bool timeout_suspended_;
-  int32_t unique_id_;
-
-  static int32_t unique_id_seed_;
-};
-
-}  // namespace jingle_xmpp
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_TASK_RUNNER_TASK_H_
diff --git a/third_party/libjingle_xmpp/task_runner/task_unittest.cc b/third_party/libjingle_xmpp/task_runner/task_unittest.cc
deleted file mode 100644
index 6b98054..0000000
--- a/third_party/libjingle_xmpp/task_runner/task_unittest.cc
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/task_runner/task.h"
-
-#include "base/stl_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libjingle_xmpp/task_runner/taskrunner.h"
-
-namespace jingle_xmpp {
-
-class FakeTask : public Task {
- public:
-  explicit FakeTask(TaskParent *parent) : Task(parent) {}
-  int ProcessStart() override {
-    return STATE_RESPONSE;
-  }
-};
-
-// simple implementation of a task runner which uses Windows'
-// GetSystemTimeAsFileTime() to get the current clock ticks
-class MyTaskRunner : public TaskRunner {
- public:
-  virtual void WakeTasks() { RunTasks(); }
-
-  bool timeout_change() const {
-    return timeout_change_;
-  }
-
-  void clear_timeout_change() {
-    timeout_change_ = false;
-  }
- protected:
-  virtual void OnTimeoutChange() {
-    timeout_change_ = true;
-  }
-  bool timeout_change_;
-};
-
-// Test for aborting the task while it is running
-
-class AbortTask : public Task {
- public:
-  explicit AbortTask(TaskParent *parent) : Task(parent) {
-  }
-
-  AbortTask(const AbortTask&) = delete;
-  AbortTask& operator=(const AbortTask&) = delete;
-
-  virtual int ProcessStart() {
-    Abort();
-    return STATE_NEXT;
-  }
-};
-
-class TaskAbortTest : public sigslot::has_slots<> {
- public:
-  TaskAbortTest() {}
-
-  TaskAbortTest(const TaskAbortTest&) = delete;
-  TaskAbortTest& operator=(const TaskAbortTest&) = delete;
-
-  // no need to delete any tasks; the task runner owns them
-  ~TaskAbortTest() {}
-
-  void Start() {
-    Task *abort_task = new AbortTask(&task_runner_);
-    abort_task->Start();
-
-    // run the task
-    task_runner_.RunTasks();
-  }
-
- private:
-  void OnTimeout() {
-    FAIL() << "Task timed out instead of aborting.";
-  }
-
-  MyTaskRunner task_runner_;
-};
-
-TEST(start_task_test, Abort) {
-  TaskAbortTest abort_test;
-  abort_test.Start();
-}
-
-// Test for aborting a task to verify that it does the Wake operation
-// which gets it deleted.
-
-class SetBoolOnDeleteTask : public Task {
- public:
-  SetBoolOnDeleteTask(TaskParent *parent, bool *set_when_deleted)
-    : Task(parent),
-      set_when_deleted_(set_when_deleted) {
-    EXPECT_TRUE(NULL != set_when_deleted);
-    EXPECT_FALSE(*set_when_deleted);
-  }
-
-  SetBoolOnDeleteTask(const SetBoolOnDeleteTask&) = delete;
-  SetBoolOnDeleteTask& operator=(const SetBoolOnDeleteTask&) = delete;
-
-  virtual ~SetBoolOnDeleteTask() {
-    *set_when_deleted_ = true;
-  }
-
-  virtual int ProcessStart() {
-    return STATE_BLOCKED;
-  }
-
- private:
-  bool* set_when_deleted_;
-};
-
-class AbortShouldWakeTest : public sigslot::has_slots<> {
- public:
-  AbortShouldWakeTest() {}
-
-  AbortShouldWakeTest(const AbortShouldWakeTest&) = delete;
-  AbortShouldWakeTest& operator=(const AbortShouldWakeTest&) = delete;
-
-  // no need to delete any tasks; the task runner owns them
-  ~AbortShouldWakeTest() {}
-
-  void Start() {
-    bool task_deleted = false;
-    Task *task_to_abort = new SetBoolOnDeleteTask(&task_runner_, &task_deleted);
-    task_to_abort->Start();
-
-    // Task::Abort() should call TaskRunner::WakeTasks(). WakeTasks calls
-    // TaskRunner::RunTasks() immediately which should delete the task.
-    task_to_abort->Abort();
-    EXPECT_TRUE(task_deleted);
-
-    if (!task_deleted) {
-      // avoid a crash (due to referencing a local variable)
-      // if the test fails.
-      task_runner_.RunTasks();
-    }
-  }
-
- private:
-  void OnTimeout() {
-    FAIL() << "Task timed out instead of aborting.";
-  }
-
-  MyTaskRunner task_runner_;
-};
-
-TEST(start_task_test, AbortShouldWake) {
-  AbortShouldWakeTest abort_should_wake_test;
-  abort_should_wake_test.Start();
-}
-
-class DeleteTestTaskRunner : public TaskRunner {
- public:
-  DeleteTestTaskRunner() {
-  }
-
-  DeleteTestTaskRunner(const DeleteTestTaskRunner&) = delete;
-  DeleteTestTaskRunner& operator=(const DeleteTestTaskRunner&) = delete;
-
-  virtual void WakeTasks() { }
-};
-
-TEST(unstarted_task_test, DeleteTask) {
-  // This test ensures that we don't
-  // crash if a task is deleted without running it.
-  DeleteTestTaskRunner task_runner;
-  FakeTask* task = new FakeTask(&task_runner);
-  task->Start();
-
-  // try deleting the task directly
-  FakeTask* child_task = new FakeTask(task);
-  delete child_task;
-
-  // run the unblocked tasks
-  task_runner.RunTasks();
-}
-
-TEST(unstarted_task_test, DoNotDeleteTask1) {
-  // This test ensures that we don't
-  // crash if a task runner is deleted without
-  // running a certain task.
-  DeleteTestTaskRunner task_runner;
-  FakeTask* task = new FakeTask(&task_runner);
-  task->Start();
-
-  FakeTask* child_task = new FakeTask(task);
-  child_task->Start();
-
-  // Never run the tasks
-}
-
-}  // namespace jingle_xmpp
diff --git a/third_party/libjingle_xmpp/task_runner/taskparent.cc b/third_party/libjingle_xmpp/task_runner/taskparent.cc
deleted file mode 100644
index 25270d37..0000000
--- a/third_party/libjingle_xmpp/task_runner/taskparent.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <algorithm>
-
-#include "third_party/libjingle_xmpp/task_runner/taskparent.h"
-
-#include "base/check_op.h"
-#include "third_party/libjingle_xmpp/task_runner/task.h"
-#include "third_party/libjingle_xmpp/task_runner/taskrunner.h"
-
-namespace jingle_xmpp {
-
-TaskParent::TaskParent(Task* derived_instance, TaskParent *parent)
-    : parent_(parent) {
-  DCHECK(derived_instance != NULL);
-  DCHECK(parent != NULL);
-  runner_ = parent->GetRunner();
-  parent_->AddChild(derived_instance);
-  Initialize();
-}
-
-TaskParent::TaskParent(TaskRunner *derived_instance)
-    : parent_(NULL),
-      runner_(derived_instance) {
-  DCHECK(derived_instance != NULL);
-  Initialize();
-}
-
-TaskParent::~TaskParent() = default;
-
-// Does common initialization of member variables
-void TaskParent::Initialize() {
-  children_.reset(new ChildSet());
-  child_error_ = false;
-}
-
-void TaskParent::AddChild(Task *child) {
-  children_->insert(child);
-}
-
-#if DCHECK_IS_ON
-bool TaskParent::IsChildTask(Task *task) {
-  DCHECK(task != NULL);
-  return task->parent_ == this && children_->find(task) != children_->end();
-}
-#endif
-
-bool TaskParent::AllChildrenDone() {
-  for (ChildSet::iterator it = children_->begin();
-       it != children_->end();
-       ++it) {
-    if (!(*it)->IsDone())
-      return false;
-  }
-  return true;
-}
-
-bool TaskParent::AnyChildError() {
-  return child_error_;
-}
-
-void TaskParent::AbortAllChildren() {
-  if (children_->size() > 0) {
-#if DCHECK_IS_ON
-    runner_->IncrementAbortCount();
-#endif
-
-    ChildSet copy = *children_;
-    for (ChildSet::iterator it = copy.begin(); it != copy.end(); ++it) {
-      (*it)->Abort(true);  // Note we do not wake
-    }
-
-#if DCHECK_IS_ON
-    runner_->DecrementAbortCount();
-#endif
-  }
-}
-
-void TaskParent::OnStopped(Task *task) {
-  AbortAllChildren();
-  parent_->OnChildStopped(task);
-}
-
-void TaskParent::OnChildStopped(Task *child) {
-  if (child->HasError())
-    child_error_ = true;
-  children_->erase(child);
-}
-
-} // namespace jingle_xmpp
diff --git a/third_party/libjingle_xmpp/task_runner/taskparent.h b/third_party/libjingle_xmpp/task_runner/taskparent.h
deleted file mode 100644
index 615e29b..0000000
--- a/third_party/libjingle_xmpp/task_runner/taskparent.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_TASK_RUNNER_TASKPARENT_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_TASK_RUNNER_TASKPARENT_H_
-
-#include <memory>
-#include <set>
-
-#include "base/check_op.h"
-
-namespace jingle_xmpp {
-
-class Task;
-class TaskRunner;
-
-class TaskParent {
- public:
-  TaskParent(Task *derived_instance, TaskParent *parent);
-  explicit TaskParent(TaskRunner *derived_instance);
-
-  TaskParent(const TaskParent&) = delete;
-  TaskParent& operator=(const TaskParent&) = delete;
-
-  virtual ~TaskParent();
-
-  TaskParent *GetParent() { return parent_; }
-  TaskRunner *GetRunner() { return runner_; }
-
-  bool AllChildrenDone();
-  bool AnyChildError();
-#if DCHECK_IS_ON
-  bool IsChildTask(Task *task);
-#endif
-
- protected:
-  void OnStopped(Task *task);
-  void AbortAllChildren();
-  TaskParent *parent() {
-    return parent_;
-  }
-
- private:
-  void Initialize();
-  void OnChildStopped(Task *child);
-  void AddChild(Task *child);
-
-  TaskParent *parent_;
-  TaskRunner *runner_;
-  bool child_error_;
-  typedef std::set<Task *> ChildSet;
-  std::unique_ptr<ChildSet> children_;
-};
-
-
-} // namespace jingle_xmpp
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_TASK_RUNNER_TASKPARENT_H_
diff --git a/third_party/libjingle_xmpp/task_runner/taskrunner.cc b/third_party/libjingle_xmpp/task_runner/taskrunner.cc
deleted file mode 100644
index f8386351..0000000
--- a/third_party/libjingle_xmpp/task_runner/taskrunner.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <algorithm>
-
-#include "third_party/libjingle_xmpp/task_runner/taskrunner.h"
-
-#include "base/check_op.h"
-#include "third_party/libjingle_xmpp/task_runner/task.h"
-
-namespace jingle_xmpp {
-
-TaskRunner::TaskRunner()
-    : TaskParent(this) {}
-
-TaskRunner::~TaskRunner() {
-  // this kills and deletes children silently!
-  AbortAllChildren();
-  InternalRunTasks(true);
-}
-
-void TaskRunner::StartTask(Task * task) {
-  tasks_.push_back(task);
-  WakeTasks();
-}
-
-void TaskRunner::RunTasks() {
-  InternalRunTasks(false);
-}
-
-void TaskRunner::InternalRunTasks(bool in_destructor) {
-  // This shouldn't run while an abort is happening.
-  // If that occurs, then tasks may be deleted in this method,
-  // but pointers to them will still be in the
-  // "ChildSet copy" in TaskParent::AbortAllChildren.
-  // Subsequent use of those task may cause data corruption or crashes.
-#if DCHECK_IS_ON
-  DCHECK(!abort_count_);
-#endif
-  // Running continues until all tasks are Blocked (ok for a small # of tasks)
-  if (tasks_running_) {
-    return;  // don't reenter
-  }
-
-  tasks_running_ = true;
-
-  int did_run = true;
-  while (did_run) {
-    did_run = false;
-    // use indexing instead of iterators because tasks_ may grow
-    for (size_t i = 0; i < tasks_.size(); ++i) {
-      while (!tasks_[i]->Blocked()) {
-        tasks_[i]->Step();
-        did_run = true;
-      }
-    }
-  }
-  // Tasks are deleted when running has paused
-  for (size_t i = 0; i < tasks_.size(); ++i) {
-    if (tasks_[i]->IsDone()) {
-      Task* task = tasks_[i];
-#if DCHECK_IS_ON
-      deleting_task_ = task;
-#endif
-      delete task;
-#if DCHECK_IS_ON
-      deleting_task_ = NULL;
-#endif
-      tasks_[i] = NULL;
-    }
-  }
-  // Finally, remove nulls
-  std::vector<Task *>::iterator it;
-  it = std::remove(tasks_.begin(), tasks_.end(), static_cast<Task*>(NULL));
-
-  tasks_.erase(it, tasks_.end());
-  tasks_running_ = false;
-}
-
-} // namespace jingle_xmpp
diff --git a/third_party/libjingle_xmpp/task_runner/taskrunner.h b/third_party/libjingle_xmpp/task_runner/taskrunner.h
deleted file mode 100644
index 40b09386..0000000
--- a/third_party/libjingle_xmpp/task_runner/taskrunner.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_TASK_RUNNER_TASKRUNNER_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_TASK_RUNNER_TASKRUNNER_H_
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/check_op.h"
-#include "third_party/libjingle_xmpp/task_runner/taskparent.h"
-#include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
-
-namespace jingle_xmpp {
-class Task;
-
-const int64_t kSecToMsec = 1000;
-const int64_t kMsecTo100ns = 10000;
-const int64_t kSecTo100ns = kSecToMsec * kMsecTo100ns;
-
-class TaskRunner : public TaskParent, public sigslot::has_slots<> {
- public:
-  TaskRunner();
-  ~TaskRunner() override;
-
-  virtual void WakeTasks() = 0;
-
-  void StartTask(Task *task);
-  void RunTasks();
-
-#if DCHECK_IS_ON
-  bool is_ok_to_delete(Task* task) {
-    return task == deleting_task_;
-  }
-
-  void IncrementAbortCount() {
-    ++abort_count_;
-  }
-
-  void DecrementAbortCount() {
-    --abort_count_;
-  }
-#endif
-
-  // Returns the next absolute time when a task times out
-  // OR "0" if there is no next timeout.
-  int64_t next_task_timeout() const;
-
- protected:
-  // The primary usage of this method is to know if
-  // a callback timer needs to be set-up or adjusted.
-  // This method will be called
-  //  * when the next_task_timeout() becomes a smaller value OR
-  //  * when next_task_timeout() has changed values and the previous
-  //    value is in the past.
-  //
-  // If the next_task_timeout moves to the future, this method will *not*
-  // get called (because it subclass should check next_task_timeout()
-  // when its timer goes off up to see if it needs to set-up a new timer).
-  //
-  // Note that this maybe called conservatively.  In that it may be
-  // called when no time change has happened.
-  virtual void OnTimeoutChange() {
-    // by default, do nothing.
-  }
-
- private:
-  void InternalRunTasks(bool in_destructor);
-
-  std::vector<Task *> tasks_;
-  bool tasks_running_ = false;
-#if DCHECK_IS_ON
-  int abort_count_ = 0;
-  Task* deleting_task_ = nullptr;
-#endif
-};
-
-} // namespace jingle_xmpp
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_TASK_RUNNER_TASKRUNNER_H_
diff --git a/third_party/libjingle_xmpp/xmpp/DEPS b/third_party/libjingle_xmpp/xmpp/DEPS
deleted file mode 100644
index 820e76c..0000000
--- a/third_party/libjingle_xmpp/xmpp/DEPS
+++ /dev/null
@@ -1,5 +0,0 @@
-include_rules = [
-  "+third_party/expat",
-  "+third_party/webrtc/rtc_base/third_party/base64",
-  "+third_party/webrtc/rtc_base/third_party/sigslot",
-]
diff --git a/third_party/libjingle_xmpp/xmpp/DIR_METADATA b/third_party/libjingle_xmpp/xmpp/DIR_METADATA
deleted file mode 100644
index 66cc019..0000000
--- a/third_party/libjingle_xmpp/xmpp/DIR_METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-monorail {
-  component: "Blink>WebRTC"
-}
diff --git a/third_party/libjingle_xmpp/xmpp/asyncsocket.h b/third_party/libjingle_xmpp/xmpp/asyncsocket.h
deleted file mode 100644
index 5a334e35..0000000
--- a/third_party/libjingle_xmpp/xmpp/asyncsocket.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_ASYNCSOCKET_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_ASYNCSOCKET_H_
-
-#include <string>
-
-#include "net/base/host_port_pair.h"
-#include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
-
-namespace jingle_xmpp {
-
-class AsyncSocket {
-public:
-  enum State {
-    STATE_CLOSED = 0,      //!< Socket is not open.
-    STATE_CLOSING,         //!< Socket is closing but can have buffered data
-    STATE_CONNECTING,      //!< In the process of
-    STATE_OPEN,            //!< Socket is connected
-    STATE_TLS_CONNECTING,  //!< Establishing TLS connection
-    STATE_TLS_OPEN,        //!< TLS connected
-  };
-
-  enum Error {
-    ERROR_NONE = 0,         //!< No error
-    ERROR_WINSOCK,          //!< Winsock error
-    ERROR_DNS,              //!< Couldn't resolve host name
-    ERROR_WRONGSTATE,       //!< Call made while socket is in the wrong state
-    ERROR_SSL,              //!< Something went wrong with OpenSSL
-  };
-
-  virtual ~AsyncSocket() {}
-  virtual State state() = 0;
-  virtual Error error() = 0;
-  virtual int GetError() = 0;    // winsock error code
-
-  virtual bool Connect(const net::HostPortPair& addr) = 0;
-  virtual bool Read(char * data, size_t len, size_t* len_read) = 0;
-  virtual bool Write(const char * data, size_t len) = 0;
-  virtual bool Close() = 0;
-  // We allow matching any passed domain.  This allows us to avoid
-  // handling the valuable certificates for logins into proxies.  If
-  // both names are passed as empty, we do not require a match.
-  virtual bool StartTls(const std::string & domainname) = 0;
-
-  sigslot::signal0<> SignalConnected;
-  sigslot::signal0<> SignalSSLConnected;
-  sigslot::signal0<> SignalClosed;
-  sigslot::signal0<> SignalRead;
-  sigslot::signal0<> SignalError;
-};
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_ASYNCSOCKET_H_
diff --git a/third_party/libjingle_xmpp/xmpp/constants.cc b/third_party/libjingle_xmpp/xmpp/constants.cc
deleted file mode 100644
index 1102746..0000000
--- a/third_party/libjingle_xmpp/xmpp/constants.cc
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-
-#include <string>
-
-#include "third_party/libjingle_xmpp/xmllite/qname.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/jid.h"
-
-namespace jingle_xmpp {
-
-// TODO: Remove static objects of complex types, particularly
-// Jid and QName.
-
-const char NS_CLIENT[] = "jabber:client";
-const char NS_SERVER[] = "jabber:server";
-const char NS_STREAM[] = "http://etherx.jabber.org/streams";
-const char NS_XSTREAM[] = "urn:ietf:params:xml:ns:xmpp-streams";
-const char NS_TLS[] = "urn:ietf:params:xml:ns:xmpp-tls";
-const char NS_SASL[] = "urn:ietf:params:xml:ns:xmpp-sasl";
-const char NS_BIND[] = "urn:ietf:params:xml:ns:xmpp-bind";
-const char NS_DIALBACK[] = "jabber:server:dialback";
-const char NS_SESSION[] = "urn:ietf:params:xml:ns:xmpp-session";
-const char NS_STANZA[] = "urn:ietf:params:xml:ns:xmpp-stanzas";
-const char NS_PRIVACY[] = "jabber:iq:privacy";
-const char NS_ROSTER[] = "jabber:iq:roster";
-const char NS_VCARD[] = "vcard-temp";
-const char NS_AVATAR_HASH[] = "google:avatar";
-const char NS_VCARD_UPDATE[] = "vcard-temp:x:update";
-const char STR_CLIENT[] = "client";
-const char STR_SERVER[] = "server";
-const char STR_STREAM[] = "stream";
-
-const char STR_GET[] = "get";
-const char STR_SET[] = "set";
-const char STR_RESULT[] = "result";
-const char STR_ERROR[] = "error";
-
-const char STR_FORM[] = "form";
-const char STR_SUBMIT[] = "submit";
-const char STR_TEXT_SINGLE[] = "text-single";
-const char STR_LIST_SINGLE[] = "list-single";
-const char STR_LIST_MULTI[] = "list-multi";
-const char STR_HIDDEN[] = "hidden";
-const char STR_FORM_TYPE[] = "FORM_TYPE";
-
-const char STR_FROM[] = "from";
-const char STR_TO[] = "to";
-const char STR_BOTH[] = "both";
-const char STR_REMOVE[] = "remove";
-const char STR_TRUE[] = "true";
-
-const char STR_TYPE[] = "type";
-const char STR_NAME[] = "name";
-const char STR_ID[] = "id";
-const char STR_JID[] = "jid";
-const char STR_SUBSCRIPTION[] = "subscription";
-const char STR_ASK[] = "ask";
-const char STR_X[] = "x";
-const char STR_GOOGLE_COM[] = "google.com";
-const char STR_GMAIL_COM[] = "gmail.com";
-const char STR_GOOGLEMAIL_COM[] = "googlemail.com";
-const char STR_DEFAULT_DOMAIN[] = "default.talk.google.com";
-const char STR_TALK_GOOGLE_COM[] = "talk.google.com";
-const char STR_TALKX_L_GOOGLE_COM[] = "talkx.l.google.com";
-const char STR_XMPP_GOOGLE_COM[] = "xmpp.google.com";
-const char STR_XMPPX_L_GOOGLE_COM[] = "xmppx.l.google.com";
-
-const char STR_VOICEMAIL[] = "voicemail";
-const char STR_OUTGOINGVOICEMAIL[] = "outgoingvoicemail";
-
-const char STR_UNAVAILABLE[] = "unavailable";
-
-const char NS_PING[] = "urn:xmpp:ping";
-const StaticQName QN_PING = { NS_PING, "ping" };
-
-const char NS_MUC_UNIQUE[] = "http://jabber.org/protocol/muc#unique";
-const StaticQName QN_MUC_UNIQUE_QUERY = { NS_MUC_UNIQUE, "unique" };
-const StaticQName QN_HANGOUT_ID = { STR_EMPTY, "hangout-id" };
-
-const char STR_GOOGLE_MUC_LOOKUP_JID[] = "lookup.groupchat.google.com";
-
-const char STR_MUC_ROOMCONFIG_ROOMNAME[] = "muc#roomconfig_roomname";
-const char STR_MUC_ROOMCONFIG_FEATURES[] = "muc#roomconfig_features";
-const char STR_MUC_ROOM_FEATURE_ENTERPRISE[] = "muc_enterprise";
-const char STR_MUC_ROOMCONFIG[] = "http://jabber.org/protocol/muc#roomconfig";
-const char STR_MUC_ROOM_FEATURE_HANGOUT[] = "muc_es";
-const char STR_MUC_ROOM_FEATURE_HANGOUT_LITE[] = "muc_lite";
-const char STR_MUC_ROOM_FEATURE_BROADCAST[] = "broadcast";
-const char STR_MUC_ROOM_FEATURE_MULTI_USER_VC[] = "muc_muvc";
-const char STR_MUC_ROOM_FEATURE_RECORDABLE[] = "recordable";
-const char STR_MUC_ROOM_FEATURE_CUSTOM_RECORDING[] = "custom_recording";
-const char STR_MUC_ROOM_OWNER_PROFILE_ID[] = "muc#roominfo_owner_profile_id";
-const char STR_MUC_ROOM_FEATURE_ABUSE_RECORDABLE[] = "abuse_recordable";
-
-const char STR_ID_TYPE_CONVERSATION[] = "conversation";
-const char NS_GOOGLE_MUC_HANGOUT[] = "google:muc#hangout";
-const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE =
-    { NS_GOOGLE_MUC_HANGOUT, "invite" };
-const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE_TYPE =
-    { NS_GOOGLE_MUC_HANGOUT, "invite-type" };
-const StaticQName QN_ATTR_CREATE_ACTIVITY =
-    { STR_EMPTY, "create-activity" };
-const StaticQName QN_GOOGLE_MUC_HANGOUT_PUBLIC =
-    { NS_GOOGLE_MUC_HANGOUT, "public" };
-const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITEE =
-    { NS_GOOGLE_MUC_HANGOUT, "invitee" };
-const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_STATUS =
-    { NS_GOOGLE_MUC_HANGOUT, "notification-status" };
-const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_TYPE = {
-    NS_GOOGLE_MUC_HANGOUT, "notification-type" };
-const StaticQName QN_GOOGLE_MUC_HANGOUT_HANGOUT_START_CONTEXT = {
-    NS_GOOGLE_MUC_HANGOUT, "hangout-start-context" };
-const StaticQName QN_GOOGLE_MUC_HANGOUT_CONVERSATION_ID = {
-    NS_GOOGLE_MUC_HANGOUT, "conversation-id" };
-
-const StaticQName QN_STREAM_STREAM = { NS_STREAM, STR_STREAM };
-const StaticQName QN_STREAM_FEATURES = { NS_STREAM, "features" };
-const StaticQName QN_STREAM_ERROR = { NS_STREAM, "error" };
-
-const StaticQName QN_XSTREAM_BAD_FORMAT = { NS_XSTREAM, "bad-format" };
-const StaticQName QN_XSTREAM_BAD_NAMESPACE_PREFIX =
-    { NS_XSTREAM, "bad-namespace-prefix" };
-const StaticQName QN_XSTREAM_CONFLICT = { NS_XSTREAM, "conflict" };
-const StaticQName QN_XSTREAM_CONNECTION_TIMEOUT =
-    { NS_XSTREAM, "connection-timeout" };
-const StaticQName QN_XSTREAM_HOST_GONE = { NS_XSTREAM, "host-gone" };
-const StaticQName QN_XSTREAM_HOST_UNKNOWN = { NS_XSTREAM, "host-unknown" };
-const StaticQName QN_XSTREAM_IMPROPER_ADDRESSIING =
-     { NS_XSTREAM, "improper-addressing" };
-const StaticQName QN_XSTREAM_INTERNAL_SERVER_ERROR =
-    { NS_XSTREAM, "internal-server-error" };
-const StaticQName QN_XSTREAM_INVALID_FROM = { NS_XSTREAM, "invalid-from" };
-const StaticQName QN_XSTREAM_INVALID_ID = { NS_XSTREAM, "invalid-id" };
-const StaticQName QN_XSTREAM_INVALID_NAMESPACE =
-    { NS_XSTREAM, "invalid-namespace" };
-const StaticQName QN_XSTREAM_INVALID_XML = { NS_XSTREAM, "invalid-xml" };
-const StaticQName QN_XSTREAM_NOT_AUTHORIZED = { NS_XSTREAM, "not-authorized" };
-const StaticQName QN_XSTREAM_POLICY_VIOLATION =
-    { NS_XSTREAM, "policy-violation" };
-const StaticQName QN_XSTREAM_REMOTE_CONNECTION_FAILED =
-    { NS_XSTREAM, "remote-connection-failed" };
-const StaticQName QN_XSTREAM_RESOURCE_CONSTRAINT =
-    { NS_XSTREAM, "resource-constraint" };
-const StaticQName QN_XSTREAM_RESTRICTED_XML = { NS_XSTREAM, "restricted-xml" };
-const StaticQName QN_XSTREAM_SEE_OTHER_HOST = { NS_XSTREAM, "see-other-host" };
-const StaticQName QN_XSTREAM_SYSTEM_SHUTDOWN =
-    { NS_XSTREAM, "system-shutdown" };
-const StaticQName QN_XSTREAM_UNDEFINED_CONDITION =
-    { NS_XSTREAM, "undefined-condition" };
-const StaticQName QN_XSTREAM_UNSUPPORTED_ENCODING =
-    { NS_XSTREAM, "unsupported-encoding" };
-const StaticQName QN_XSTREAM_UNSUPPORTED_STANZA_TYPE =
-    { NS_XSTREAM, "unsupported-stanza-type" };
-const StaticQName QN_XSTREAM_UNSUPPORTED_VERSION =
-    { NS_XSTREAM, "unsupported-version" };
-const StaticQName QN_XSTREAM_XML_NOT_WELL_FORMED =
-    { NS_XSTREAM, "xml-not-well-formed" };
-const StaticQName QN_XSTREAM_TEXT = { NS_XSTREAM, "text" };
-
-const StaticQName QN_TLS_STARTTLS = { NS_TLS, "starttls" };
-const StaticQName QN_TLS_REQUIRED = { NS_TLS, "required" };
-const StaticQName QN_TLS_PROCEED = { NS_TLS, "proceed" };
-const StaticQName QN_TLS_FAILURE = { NS_TLS, "failure" };
-
-const StaticQName QN_SASL_MECHANISMS = { NS_SASL, "mechanisms" };
-const StaticQName QN_SASL_MECHANISM = { NS_SASL, "mechanism" };
-const StaticQName QN_SASL_AUTH = { NS_SASL, "auth" };
-const StaticQName QN_SASL_CHALLENGE = { NS_SASL, "challenge" };
-const StaticQName QN_SASL_RESPONSE = { NS_SASL, "response" };
-const StaticQName QN_SASL_ABORT = { NS_SASL, "abort" };
-const StaticQName QN_SASL_SUCCESS = { NS_SASL, "success" };
-const StaticQName QN_SASL_FAILURE = { NS_SASL, "failure" };
-const StaticQName QN_SASL_ABORTED = { NS_SASL, "aborted" };
-const StaticQName QN_SASL_INCORRECT_ENCODING =
-    { NS_SASL, "incorrect-encoding" };
-const StaticQName QN_SASL_INVALID_AUTHZID = { NS_SASL, "invalid-authzid" };
-const StaticQName QN_SASL_INVALID_MECHANISM = { NS_SASL, "invalid-mechanism" };
-const StaticQName QN_SASL_MECHANISM_TOO_WEAK =
-    { NS_SASL, "mechanism-too-weak" };
-const StaticQName QN_SASL_NOT_AUTHORIZED = { NS_SASL, "not-authorized" };
-const StaticQName QN_SASL_TEMPORARY_AUTH_FAILURE =
-    { NS_SASL, "temporary-auth-failure" };
-
-// These are non-standard.
-const char NS_GOOGLE_AUTH_PROTOCOL[] =
-    "http://www.google.com/talk/protocol/auth";
-const StaticQName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT =
-    { NS_GOOGLE_AUTH_PROTOCOL, "client-uses-full-bind-result" };
-const StaticQName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN =
-    { NS_GOOGLE_AUTH_PROTOCOL, "allow-non-google-login" };
-const StaticQName QN_GOOGLE_AUTH_SERVICE =
-    { NS_GOOGLE_AUTH_PROTOCOL, "service" };
-
-const StaticQName QN_DIALBACK_RESULT = { NS_DIALBACK, "result" };
-const StaticQName QN_DIALBACK_VERIFY = { NS_DIALBACK, "verify" };
-
-const StaticQName QN_STANZA_BAD_REQUEST = { NS_STANZA, "bad-request" };
-const StaticQName QN_STANZA_CONFLICT = { NS_STANZA, "conflict" };
-const StaticQName QN_STANZA_FEATURE_NOT_IMPLEMENTED =
-    { NS_STANZA, "feature-not-implemented" };
-const StaticQName QN_STANZA_FORBIDDEN = { NS_STANZA, "forbidden" };
-const StaticQName QN_STANZA_GONE = { NS_STANZA, "gone" };
-const StaticQName QN_STANZA_INTERNAL_SERVER_ERROR =
-    { NS_STANZA, "internal-server-error" };
-const StaticQName QN_STANZA_ITEM_NOT_FOUND = { NS_STANZA, "item-not-found" };
-const StaticQName QN_STANZA_JID_MALFORMED = { NS_STANZA, "jid-malformed" };
-const StaticQName QN_STANZA_NOT_ACCEPTABLE = { NS_STANZA, "not-acceptable" };
-const StaticQName QN_STANZA_NOT_ALLOWED = { NS_STANZA, "not-allowed" };
-const StaticQName QN_STANZA_PAYMENT_REQUIRED =
-    { NS_STANZA, "payment-required" };
-const StaticQName QN_STANZA_RECIPIENT_UNAVAILABLE =
-    { NS_STANZA, "recipient-unavailable" };
-const StaticQName QN_STANZA_REDIRECT = { NS_STANZA, "redirect" };
-const StaticQName QN_STANZA_REGISTRATION_REQUIRED =
-    { NS_STANZA, "registration-required" };
-const StaticQName QN_STANZA_REMOTE_SERVER_NOT_FOUND =
-    { NS_STANZA, "remote-server-not-found" };
-const StaticQName QN_STANZA_REMOTE_SERVER_TIMEOUT =
-    { NS_STANZA, "remote-server-timeout" };
-const StaticQName QN_STANZA_RESOURCE_CONSTRAINT =
-    { NS_STANZA, "resource-constraint" };
-const StaticQName QN_STANZA_SERVICE_UNAVAILABLE =
-    { NS_STANZA, "service-unavailable" };
-const StaticQName QN_STANZA_SUBSCRIPTION_REQUIRED =
-    { NS_STANZA, "subscription-required" };
-const StaticQName QN_STANZA_UNDEFINED_CONDITION =
-    { NS_STANZA, "undefined-condition" };
-const StaticQName QN_STANZA_UNEXPECTED_REQUEST =
-    { NS_STANZA, "unexpected-request" };
-const StaticQName QN_STANZA_TEXT = { NS_STANZA, "text" };
-
-const StaticQName QN_BIND_BIND = { NS_BIND, "bind" };
-const StaticQName QN_BIND_RESOURCE = { NS_BIND, "resource" };
-const StaticQName QN_BIND_JID = { NS_BIND, "jid" };
-
-const StaticQName QN_MESSAGE = { NS_CLIENT, "message" };
-const StaticQName QN_BODY = { NS_CLIENT, "body" };
-const StaticQName QN_SUBJECT = { NS_CLIENT, "subject" };
-const StaticQName QN_THREAD = { NS_CLIENT, "thread" };
-const StaticQName QN_PRESENCE = { NS_CLIENT, "presence" };
-const StaticQName QN_SHOW = { NS_CLIENT, "show" };
-const StaticQName QN_STATUS = { NS_CLIENT, "status" };
-const StaticQName QN_LANG = { NS_CLIENT, "lang" };
-const StaticQName QN_PRIORITY = { NS_CLIENT, "priority" };
-const StaticQName QN_IQ = { NS_CLIENT, "iq" };
-const StaticQName QN_ERROR = { NS_CLIENT, "error" };
-
-const StaticQName QN_SERVER_MESSAGE = { NS_SERVER, "message" };
-const StaticQName QN_SERVER_BODY = { NS_SERVER, "body" };
-const StaticQName QN_SERVER_SUBJECT = { NS_SERVER, "subject" };
-const StaticQName QN_SERVER_THREAD = { NS_SERVER, "thread" };
-const StaticQName QN_SERVER_PRESENCE = { NS_SERVER, "presence" };
-const StaticQName QN_SERVER_SHOW = { NS_SERVER, "show" };
-const StaticQName QN_SERVER_STATUS = { NS_SERVER, "status" };
-const StaticQName QN_SERVER_LANG = { NS_SERVER, "lang" };
-const StaticQName QN_SERVER_PRIORITY = { NS_SERVER, "priority" };
-const StaticQName QN_SERVER_IQ = { NS_SERVER, "iq" };
-const StaticQName QN_SERVER_ERROR = { NS_SERVER, "error" };
-
-const StaticQName QN_SESSION_SESSION = { NS_SESSION, "session" };
-
-const StaticQName QN_PRIVACY_QUERY = { NS_PRIVACY, "query" };
-const StaticQName QN_PRIVACY_ACTIVE = { NS_PRIVACY, "active" };
-const StaticQName QN_PRIVACY_DEFAULT = { NS_PRIVACY, "default" };
-const StaticQName QN_PRIVACY_LIST = { NS_PRIVACY, "list" };
-const StaticQName QN_PRIVACY_ITEM = { NS_PRIVACY, "item" };
-const StaticQName QN_PRIVACY_IQ = { NS_PRIVACY, "iq" };
-const StaticQName QN_PRIVACY_MESSAGE = { NS_PRIVACY, "message" };
-const StaticQName QN_PRIVACY_PRESENCE_IN = { NS_PRIVACY, "presence-in" };
-const StaticQName QN_PRIVACY_PRESENCE_OUT = { NS_PRIVACY, "presence-out" };
-
-const StaticQName QN_ROSTER_QUERY = { NS_ROSTER, "query" };
-const StaticQName QN_ROSTER_ITEM = { NS_ROSTER, "item" };
-const StaticQName QN_ROSTER_GROUP = { NS_ROSTER, "group" };
-
-const StaticQName QN_VCARD = { NS_VCARD, "vCard" };
-const StaticQName QN_VCARD_FN = { NS_VCARD, "FN" };
-const StaticQName QN_VCARD_PHOTO = { NS_VCARD, "PHOTO" };
-const StaticQName QN_VCARD_PHOTO_BINVAL = { NS_VCARD, "BINVAL" };
-const StaticQName QN_VCARD_AVATAR_HASH = { NS_AVATAR_HASH, "hash" };
-const StaticQName QN_VCARD_AVATAR_HASH_MODIFIED =
-    { NS_AVATAR_HASH, "modified" };
-
-const StaticQName QN_NAME = { STR_EMPTY, "name" };
-const StaticQName QN_AFFILIATION = { STR_EMPTY, "affiliation" };
-const StaticQName QN_ROLE = { STR_EMPTY, "role" };
-
-#if defined(FEATURE_ENABLE_PSTN)
-const StaticQName QN_VCARD_TEL = { NS_VCARD, "TEL" };
-const StaticQName QN_VCARD_VOICE = { NS_VCARD, "VOICE" };
-const StaticQName QN_VCARD_HOME = { NS_VCARD, "HOME" };
-const StaticQName QN_VCARD_WORK = { NS_VCARD, "WORK" };
-const StaticQName QN_VCARD_CELL = { NS_VCARD, "CELL" };
-const StaticQName QN_VCARD_NUMBER = { NS_VCARD, "NUMBER" };
-#endif
-
-const StaticQName QN_XML_LANG = { NS_XML, "lang" };
-
-const StaticQName QN_ENCODING = { STR_EMPTY, STR_ENCODING };
-const StaticQName QN_VERSION = { STR_EMPTY, STR_VERSION };
-const StaticQName QN_TO = { STR_EMPTY, "to" };
-const StaticQName QN_FROM = { STR_EMPTY, "from" };
-const StaticQName QN_TYPE = { STR_EMPTY, "type" };
-const StaticQName QN_ID = { STR_EMPTY, "id" };
-const StaticQName QN_CODE = { STR_EMPTY, "code" };
-
-const StaticQName QN_VALUE = { STR_EMPTY, "value" };
-const StaticQName QN_ACTION = { STR_EMPTY, "action" };
-const StaticQName QN_ORDER = { STR_EMPTY, "order" };
-const StaticQName QN_MECHANISM = { STR_EMPTY, "mechanism" };
-const StaticQName QN_ASK = { STR_EMPTY, "ask" };
-const StaticQName QN_JID = { STR_EMPTY, "jid" };
-const StaticQName QN_NICK = { STR_EMPTY, "nick" };
-const StaticQName QN_SUBSCRIPTION = { STR_EMPTY, "subscription" };
-const StaticQName QN_TITLE1 = { STR_EMPTY, "title1" };
-const StaticQName QN_TITLE2 = { STR_EMPTY, "title2" };
-
-const StaticQName QN_XMLNS_CLIENT = { NS_XMLNS, STR_CLIENT };
-const StaticQName QN_XMLNS_SERVER = { NS_XMLNS, STR_SERVER };
-const StaticQName QN_XMLNS_STREAM = { NS_XMLNS, STR_STREAM };
-
-
-// Presence
-const char STR_SHOW_AWAY[] = "away";
-const char STR_SHOW_CHAT[] = "chat";
-const char STR_SHOW_DND[] = "dnd";
-const char STR_SHOW_XA[] = "xa";
-const char STR_SHOW_OFFLINE[] = "offline";
-
-const char NS_GOOGLE_PSTN_CONFERENCE[] = "http://www.google.com/pstn-conference";
-const StaticQName QN_GOOGLE_PSTN_CONFERENCE_STATUS = { NS_GOOGLE_PSTN_CONFERENCE, "status" };
-const StaticQName QN_ATTR_STATUS = { STR_EMPTY, "status" };
-
-// Presence connection status
-const char STR_PSTN_CONFERENCE_STATUS_CONNECTING[] = "connecting";
-const char STR_PSTN_CONFERENCE_STATUS_JOINING[] = "joining";
-const char STR_PSTN_CONFERENCE_STATUS_CONNECTED[] = "connected";
-const char STR_PSTN_CONFERENCE_STATUS_HANGUP[] = "hangup";
-
-// Subscription
-const char STR_SUBSCRIBE[] = "subscribe";
-const char STR_SUBSCRIBED[] = "subscribed";
-const char STR_UNSUBSCRIBE[] = "unsubscribe";
-const char STR_UNSUBSCRIBED[] = "unsubscribed";
-
-// Google Invite
-const char NS_GOOGLE_SUBSCRIBE[] = "google:subscribe";
-const StaticQName QN_INVITATION = { NS_GOOGLE_SUBSCRIBE, "invitation" };
-const StaticQName QN_INVITE_NAME = { NS_GOOGLE_SUBSCRIBE, "name" };
-const StaticQName QN_INVITE_SUBJECT = { NS_GOOGLE_SUBSCRIBE, "subject" };
-const StaticQName QN_INVITE_MESSAGE = { NS_GOOGLE_SUBSCRIBE, "body" };
-
-// Kick
-const char NS_GOOGLE_MUC_ADMIN[] = "google:muc#admin";
-const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY = { NS_GOOGLE_MUC_ADMIN, "query" };
-const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM =
-    { NS_GOOGLE_MUC_ADMIN, "item" };
-const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM_REASON =
-    { NS_GOOGLE_MUC_ADMIN, "reason" };
-
-// PubSub: http://xmpp.org/extensions/xep-0060.html
-const char NS_PUBSUB[] = "http://jabber.org/protocol/pubsub";
-const StaticQName QN_PUBSUB = { NS_PUBSUB, "pubsub" };
-const StaticQName QN_PUBSUB_ITEMS = { NS_PUBSUB, "items" };
-const StaticQName QN_PUBSUB_ITEM = { NS_PUBSUB, "item" };
-const StaticQName QN_PUBSUB_PUBLISH = { NS_PUBSUB, "publish" };
-const StaticQName QN_PUBSUB_RETRACT = { NS_PUBSUB, "retract" };
-const StaticQName QN_ATTR_PUBLISHER = { STR_EMPTY, "publisher" };
-
-const char NS_PUBSUB_EVENT[] = "http://jabber.org/protocol/pubsub#event";
-const StaticQName QN_NODE = { STR_EMPTY, "node" };
-const StaticQName QN_PUBSUB_EVENT = { NS_PUBSUB_EVENT, "event" };
-const StaticQName QN_PUBSUB_EVENT_ITEMS = { NS_PUBSUB_EVENT, "items" };
-const StaticQName QN_PUBSUB_EVENT_ITEM = { NS_PUBSUB_EVENT, "item" };
-const StaticQName QN_PUBSUB_EVENT_RETRACT = { NS_PUBSUB_EVENT, "retract" };
-const StaticQName QN_NOTIFY = { STR_EMPTY, "notify" };
-
-const char NS_PRESENTER[] = "google:presenter";
-const StaticQName QN_PRESENTER_PRESENTER = { NS_PRESENTER, "presenter" };
-const StaticQName QN_PRESENTER_PRESENTATION_ITEM =
-    { NS_PRESENTER, "presentation-item" };
-const StaticQName QN_PRESENTER_PRESENTATION_TYPE =
-    { NS_PRESENTER, "presentation-type" };
-const StaticQName QN_PRESENTER_PRESENTATION_ID =
-    { NS_PRESENTER, "presentation-id" };
-
-// JEP 0030
-const StaticQName QN_CATEGORY = { STR_EMPTY, "category" };
-const StaticQName QN_VAR = { STR_EMPTY, "var" };
-const char NS_DISCO_INFO[] = "http://jabber.org/protocol/disco#info";
-const char NS_DISCO_ITEMS[] = "http://jabber.org/protocol/disco#items";
-const StaticQName QN_DISCO_INFO_QUERY = { NS_DISCO_INFO, "query" };
-const StaticQName QN_DISCO_IDENTITY = { NS_DISCO_INFO, "identity" };
-const StaticQName QN_DISCO_FEATURE = { NS_DISCO_INFO, "feature" };
-
-const StaticQName QN_DISCO_ITEMS_QUERY = { NS_DISCO_ITEMS, "query" };
-const StaticQName QN_DISCO_ITEM = { NS_DISCO_ITEMS, "item" };
-
-// JEP 0020
-const char NS_FEATURE[] = "http://jabber.org/protocol/feature-neg";
-const StaticQName QN_FEATURE_FEATURE = { NS_FEATURE, "feature" };
-
-// JEP 0004
-const char NS_XDATA[] = "jabber:x:data";
-const StaticQName QN_XDATA_X = { NS_XDATA, "x" };
-const StaticQName QN_XDATA_INSTRUCTIONS = { NS_XDATA, "instructions" };
-const StaticQName QN_XDATA_TITLE = { NS_XDATA, "title" };
-const StaticQName QN_XDATA_FIELD = { NS_XDATA, "field" };
-const StaticQName QN_XDATA_REPORTED = { NS_XDATA, "reported" };
-const StaticQName QN_XDATA_ITEM = { NS_XDATA, "item" };
-const StaticQName QN_XDATA_DESC = { NS_XDATA, "desc" };
-const StaticQName QN_XDATA_REQUIRED = { NS_XDATA, "required" };
-const StaticQName QN_XDATA_VALUE = { NS_XDATA, "value" };
-const StaticQName QN_XDATA_OPTION = { NS_XDATA, "option" };
-
-// JEP 0045
-const char NS_MUC[] = "http://jabber.org/protocol/muc";
-const StaticQName QN_MUC_X = { NS_MUC, "x" };
-const StaticQName QN_MUC_ITEM = { NS_MUC, "item" };
-const StaticQName QN_MUC_AFFILIATION = { NS_MUC, "affiliation" };
-const StaticQName QN_MUC_ROLE = { NS_MUC, "role" };
-const char STR_AFFILIATION_NONE[] = "none";
-const char STR_ROLE_PARTICIPANT[] = "participant";
-
-const char NS_GOOGLE_SESSION[] = "http://www.google.com/session";
-const StaticQName QN_GOOGLE_CIRCLE_ID = { STR_EMPTY, "google-circle-id" };
-const StaticQName QN_GOOGLE_USER_ID = { STR_EMPTY, "google-user-id" };
-const StaticQName QN_GOOGLE_SESSION_BLOCKED = { NS_GOOGLE_SESSION, "blocked" };
-const StaticQName QN_GOOGLE_SESSION_BLOCKING =
-    { NS_GOOGLE_SESSION, "blocking" };
-
-const char NS_MUC_OWNER[] = "http://jabber.org/protocol/muc#owner";
-const StaticQName QN_MUC_OWNER_QUERY = { NS_MUC_OWNER, "query" };
-
-const char NS_MUC_USER[] = "http://jabber.org/protocol/muc#user";
-const StaticQName QN_MUC_USER_CONTINUE = { NS_MUC_USER, "continue" };
-const StaticQName QN_MUC_USER_X = { NS_MUC_USER, "x" };
-const StaticQName QN_MUC_USER_ITEM = { NS_MUC_USER, "item" };
-const StaticQName QN_MUC_USER_STATUS = { NS_MUC_USER, "status" };
-const StaticQName QN_MUC_USER_REASON = { NS_MUC_USER, "reason" };
-const StaticQName QN_MUC_USER_ABUSE_VIOLATION = { NS_MUC_USER, "abuse-violation" };
-
-// JEP 0055 - Jabber Search
-const char NS_SEARCH[] = "jabber:iq:search";
-const StaticQName QN_SEARCH_QUERY = { NS_SEARCH, "query" };
-const StaticQName QN_SEARCH_ITEM = { NS_SEARCH, "item" };
-const StaticQName QN_SEARCH_ROOM_NAME = { NS_SEARCH, "room-name" };
-const StaticQName QN_SEARCH_ROOM_DOMAIN = { NS_SEARCH, "room-domain" };
-const StaticQName QN_SEARCH_ROOM_JID = { NS_SEARCH, "room-jid" };
-const StaticQName QN_SEARCH_HANGOUT_ID = { NS_SEARCH, "hangout-id" };
-const StaticQName QN_SEARCH_EXTERNAL_ID = { NS_SEARCH, "external-id" };
-
-// JEP 0115
-const char NS_CAPS[] = "http://jabber.org/protocol/caps";
-const StaticQName QN_CAPS_C = { NS_CAPS, "c" };
-const StaticQName QN_VER = { STR_EMPTY, "ver" };
-const StaticQName QN_EXT = { STR_EMPTY, "ext" };
-
-// JEP 0153
-const char kNSVCard[] = "vcard-temp:x:update";
-const StaticQName kQnVCardX = { kNSVCard, "x" };
-const StaticQName kQnVCardPhoto = { kNSVCard, "photo" };
-
-// JEP 0172 User Nickname
-const char NS_NICKNAME[] = "http://jabber.org/protocol/nick";
-const StaticQName QN_NICKNAME = { NS_NICKNAME, "nick" };
-
-// JEP 0085 chat state
-const char NS_CHATSTATE[] = "http://jabber.org/protocol/chatstates";
-const StaticQName QN_CS_ACTIVE = { NS_CHATSTATE, "active" };
-const StaticQName QN_CS_COMPOSING = { NS_CHATSTATE, "composing" };
-const StaticQName QN_CS_PAUSED = { NS_CHATSTATE, "paused" };
-const StaticQName QN_CS_INACTIVE = { NS_CHATSTATE, "inactive" };
-const StaticQName QN_CS_GONE = { NS_CHATSTATE, "gone" };
-
-// JEP 0091 Delayed Delivery
-const char kNSDelay[] = "jabber:x:delay";
-const StaticQName kQnDelayX = { kNSDelay, "x" };
-const StaticQName kQnStamp = { STR_EMPTY, "stamp" };
-
-// Google time stamping (higher resolution)
-const char kNSTimestamp[] = "google:timestamp";
-const StaticQName kQnTime = { kNSTimestamp, "time" };
-const StaticQName kQnMilliseconds = { STR_EMPTY, "ms" };
-
-// Jingle Info
-const char NS_JINGLE_INFO[] = "google:jingleinfo";
-const StaticQName QN_JINGLE_INFO_QUERY = { NS_JINGLE_INFO, "query" };
-const StaticQName QN_JINGLE_INFO_STUN = { NS_JINGLE_INFO, "stun" };
-const StaticQName QN_JINGLE_INFO_RELAY = { NS_JINGLE_INFO, "relay" };
-const StaticQName QN_JINGLE_INFO_SERVER = { NS_JINGLE_INFO, "server" };
-const StaticQName QN_JINGLE_INFO_TOKEN = { NS_JINGLE_INFO, "token" };
-const StaticQName QN_JINGLE_INFO_HOST = { STR_EMPTY, "host" };
-const StaticQName QN_JINGLE_INFO_TCP = { STR_EMPTY, "tcp" };
-const StaticQName QN_JINGLE_INFO_UDP = { STR_EMPTY, "udp" };
-const StaticQName QN_JINGLE_INFO_TCPSSL = { STR_EMPTY, "tcpssl" };
-
-// Call Performance Logging
-const char NS_GOOGLE_CALLPERF_STATS[] = "google:call-perf-stats";
-const StaticQName QN_CALLPERF_STATS =
-    { NS_GOOGLE_CALLPERF_STATS, "callPerfStats" };
-const StaticQName QN_CALLPERF_SESSIONID = { STR_EMPTY, "sessionId" };
-const StaticQName QN_CALLPERF_LOCALUSER = { STR_EMPTY, "localUser" };
-const StaticQName QN_CALLPERF_REMOTEUSER = { STR_EMPTY, "remoteUser" };
-const StaticQName QN_CALLPERF_STARTTIME = { STR_EMPTY, "startTime" };
-const StaticQName QN_CALLPERF_CALL_LENGTH = { STR_EMPTY, "callLength" };
-const StaticQName QN_CALLPERF_CALL_ACCEPTED = { STR_EMPTY, "callAccepted" };
-const StaticQName QN_CALLPERF_CALL_ERROR_CODE = { STR_EMPTY, "callErrorCode" };
-const StaticQName QN_CALLPERF_TERMINATE_CODE = { STR_EMPTY, "terminateCode" };
-const StaticQName QN_CALLPERF_DATAPOINT =
-    { NS_GOOGLE_CALLPERF_STATS, "dataPoint" };
-const StaticQName QN_CALLPERF_DATAPOINT_TIME = { STR_EMPTY, "timeStamp" };
-const StaticQName QN_CALLPERF_DATAPOINT_FRACTION_LOST =
-    { STR_EMPTY, "fraction_lost" };
-const StaticQName QN_CALLPERF_DATAPOINT_CUM_LOST = { STR_EMPTY, "cum_lost" };
-const StaticQName QN_CALLPERF_DATAPOINT_EXT_MAX = { STR_EMPTY, "ext_max" };
-const StaticQName QN_CALLPERF_DATAPOINT_JITTER = { STR_EMPTY, "jitter" };
-const StaticQName QN_CALLPERF_DATAPOINT_RTT = { STR_EMPTY, "RTT" };
-const StaticQName QN_CALLPERF_DATAPOINT_BYTES_R =
-    { STR_EMPTY, "bytesReceived" };
-const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_R =
-    { STR_EMPTY, "packetsReceived" };
-const StaticQName QN_CALLPERF_DATAPOINT_BYTES_S = { STR_EMPTY, "bytesSent" };
-const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_S =
-    { STR_EMPTY, "packetsSent" };
-const StaticQName QN_CALLPERF_DATAPOINT_PROCESS_CPU =
-    { STR_EMPTY, "processCpu" };
-const StaticQName QN_CALLPERF_DATAPOINT_SYSTEM_CPU = { STR_EMPTY, "systemCpu" };
-const StaticQName QN_CALLPERF_DATAPOINT_CPUS = { STR_EMPTY, "cpus" };
-const StaticQName QN_CALLPERF_CONNECTION =
-    { NS_GOOGLE_CALLPERF_STATS, "connection" };
-const StaticQName QN_CALLPERF_CONNECTION_LOCAL_ADDRESS =
-    { STR_EMPTY, "localAddress" };
-const StaticQName QN_CALLPERF_CONNECTION_REMOTE_ADDRESS =
-    { STR_EMPTY, "remoteAddress" };
-const StaticQName QN_CALLPERF_CONNECTION_FLAGS = { STR_EMPTY, "flags" };
-const StaticQName QN_CALLPERF_CONNECTION_RTT = { STR_EMPTY, "rtt" };
-const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_S =
-    { STR_EMPTY, "totalBytesSent" };
-const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_S =
-    { STR_EMPTY, "bytesSecondSent" };
-const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_R =
-    { STR_EMPTY, "totalBytesRecv" };
-const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_R =
-    { STR_EMPTY, "bytesSecondRecv" };
-const StaticQName QN_CALLPERF_CANDIDATE =
-    { NS_GOOGLE_CALLPERF_STATS, "candidate" };
-const StaticQName QN_CALLPERF_CANDIDATE_ENDPOINT = { STR_EMPTY, "endpoint" };
-const StaticQName QN_CALLPERF_CANDIDATE_PROTOCOL = { STR_EMPTY, "protocol" };
-const StaticQName QN_CALLPERF_CANDIDATE_ADDRESS = { STR_EMPTY, "address" };
-const StaticQName QN_CALLPERF_MEDIA = { NS_GOOGLE_CALLPERF_STATS, "media" };
-const StaticQName QN_CALLPERF_MEDIA_DIRECTION = { STR_EMPTY, "direction" };
-const StaticQName QN_CALLPERF_MEDIA_SSRC = { STR_EMPTY, "SSRC" };
-const StaticQName QN_CALLPERF_MEDIA_ENERGY = { STR_EMPTY, "energy" };
-const StaticQName QN_CALLPERF_MEDIA_FIR = { STR_EMPTY, "fir" };
-const StaticQName QN_CALLPERF_MEDIA_NACK = { STR_EMPTY, "nack" };
-const StaticQName QN_CALLPERF_MEDIA_FPS = { STR_EMPTY, "fps" };
-const StaticQName QN_CALLPERF_MEDIA_FPS_NETWORK = { STR_EMPTY, "fpsNetwork" };
-const StaticQName QN_CALLPERF_MEDIA_FPS_DECODED = { STR_EMPTY, "fpsDecoded" };
-const StaticQName QN_CALLPERF_MEDIA_JITTER_BUFFER_SIZE =
-    { STR_EMPTY, "jitterBufferSize" };
-const StaticQName QN_CALLPERF_MEDIA_PREFERRED_JITTER_BUFFER_SIZE =
-    { STR_EMPTY, "preferredJitterBufferSize" };
-const StaticQName QN_CALLPERF_MEDIA_TOTAL_PLAYOUT_DELAY =
-    { STR_EMPTY, "totalPlayoutDelay" };
-
-// Muc invites.
-const StaticQName QN_MUC_USER_INVITE = { NS_MUC_USER, "invite" };
-
-// Multiway audio/video.
-const char NS_GOOGLE_MUC_USER[] = "google:muc#user";
-const StaticQName QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA =
-    { NS_GOOGLE_MUC_USER, "available-media" };
-const StaticQName QN_GOOGLE_MUC_USER_ENTRY = { NS_GOOGLE_MUC_USER, "entry" };
-const StaticQName QN_GOOGLE_MUC_USER_MEDIA = { NS_GOOGLE_MUC_USER, "media" };
-const StaticQName QN_GOOGLE_MUC_USER_TYPE = { NS_GOOGLE_MUC_USER, "type" };
-const StaticQName QN_GOOGLE_MUC_USER_SRC_ID = { NS_GOOGLE_MUC_USER, "src-id" };
-const StaticQName QN_GOOGLE_MUC_USER_STATUS = { NS_GOOGLE_MUC_USER, "status" };
-const StaticQName QN_CLIENT_VERSION = { NS_GOOGLE_MUC_USER, "client-version" };
-const StaticQName QN_LOCALE = { NS_GOOGLE_MUC_USER, "locale" };
-const StaticQName QN_LABEL = { STR_EMPTY, "label" };
-
-const char NS_GOOGLE_MUC_MEDIA[] = "google:muc#media";
-const StaticQName QN_GOOGLE_MUC_AUDIO_MUTE =
-    { NS_GOOGLE_MUC_MEDIA, "audio-mute" };
-const StaticQName QN_GOOGLE_MUC_VIDEO_MUTE =
-    { NS_GOOGLE_MUC_MEDIA, "video-mute" };
-const StaticQName QN_GOOGLE_MUC_VIDEO_PAUSE =
-    { NS_GOOGLE_MUC_MEDIA, "video-pause" };
-const StaticQName QN_GOOGLE_MUC_RECORDING =
-    { NS_GOOGLE_MUC_MEDIA, "recording" };
-const StaticQName QN_GOOGLE_MUC_MEDIA_BLOCK = { NS_GOOGLE_MUC_MEDIA, "block" };
-const StaticQName QN_STATE_ATTR = { STR_EMPTY, "state" };
-
-const char AUTH_MECHANISM_GOOGLE_COOKIE[] = "X-GOOGLE-COOKIE";
-const char AUTH_MECHANISM_GOOGLE_TOKEN[] = "X-GOOGLE-TOKEN";
-const char AUTH_MECHANISM_OAUTH2[] = "X-OAUTH2";
-const char AUTH_MECHANISM_PLAIN[] = "PLAIN";
-
-}  // namespace jingle_xmpp
diff --git a/third_party/libjingle_xmpp/xmpp/constants.h b/third_party/libjingle_xmpp/xmpp/constants.h
deleted file mode 100644
index 8f65a4b..0000000
--- a/third_party/libjingle_xmpp/xmpp/constants.h
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_CONSTANTS_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_CONSTANTS_H_
-
-#include <string>
-#include "third_party/libjingle_xmpp/xmllite/qname.h"
-#include "third_party/libjingle_xmpp/xmpp/jid.h"
-
-namespace jingle_xmpp {
-
-extern const char NS_CLIENT[];
-extern const char NS_SERVER[];
-extern const char NS_STREAM[];
-extern const char NS_XSTREAM[];
-extern const char NS_TLS[];
-extern const char NS_SASL[];
-extern const char NS_BIND[];
-extern const char NS_DIALBACK[];
-extern const char NS_SESSION[];
-extern const char NS_STANZA[];
-extern const char NS_PRIVACY[];
-extern const char NS_ROSTER[];
-extern const char NS_VCARD[];
-extern const char NS_AVATAR_HASH[];
-extern const char NS_VCARD_UPDATE[];
-extern const char STR_CLIENT[];
-extern const char STR_SERVER[];
-extern const char STR_STREAM[];
-
-extern const char STR_GET[];
-extern const char STR_SET[];
-extern const char STR_RESULT[];
-extern const char STR_ERROR[];
-
-extern const char STR_FORM[];
-extern const char STR_SUBMIT[];
-extern const char STR_TEXT_SINGLE[];
-extern const char STR_LIST_SINGLE[];
-extern const char STR_LIST_MULTI[];
-extern const char STR_HIDDEN[];
-extern const char STR_FORM_TYPE[];
-
-extern const char STR_FROM[];
-extern const char STR_TO[];
-extern const char STR_BOTH[];
-extern const char STR_REMOVE[];
-extern const char STR_TRUE[];
-
-extern const char STR_TYPE[];
-extern const char STR_NAME[];
-extern const char STR_ID[];
-extern const char STR_JID[];
-extern const char STR_SUBSCRIPTION[];
-extern const char STR_ASK[];
-extern const char STR_X[];
-extern const char STR_GOOGLE_COM[];
-extern const char STR_GMAIL_COM[];
-extern const char STR_GOOGLEMAIL_COM[];
-extern const char STR_DEFAULT_DOMAIN[];
-extern const char STR_TALK_GOOGLE_COM[];
-extern const char STR_TALKX_L_GOOGLE_COM[];
-extern const char STR_XMPP_GOOGLE_COM[];
-extern const char STR_XMPPX_L_GOOGLE_COM[];
-
-extern const char STR_VOICEMAIL[];
-extern const char STR_OUTGOINGVOICEMAIL[];
-
-extern const char STR_UNAVAILABLE[];
-
-extern const char NS_PING[];
-extern const StaticQName QN_PING;
-
-extern const char NS_MUC_UNIQUE[];
-extern const StaticQName QN_MUC_UNIQUE_QUERY;
-extern const StaticQName QN_HANGOUT_ID;
-
-extern const char STR_GOOGLE_MUC_LOOKUP_JID[];
-extern const char STR_MUC_ROOMCONFIG_ROOMNAME[];
-extern const char STR_MUC_ROOMCONFIG_FEATURES[];
-extern const char STR_MUC_ROOM_FEATURE_ENTERPRISE[];
-extern const char STR_MUC_ROOMCONFIG[];
-extern const char STR_MUC_ROOM_FEATURE_HANGOUT[];
-extern const char STR_MUC_ROOM_FEATURE_HANGOUT_LITE[];
-extern const char STR_MUC_ROOM_FEATURE_BROADCAST[];
-extern const char STR_MUC_ROOM_FEATURE_MULTI_USER_VC[];
-extern const char STR_MUC_ROOM_FEATURE_RECORDABLE[];
-extern const char STR_MUC_ROOM_FEATURE_CUSTOM_RECORDING[];
-extern const char STR_MUC_ROOM_OWNER_PROFILE_ID[];
-extern const char STR_MUC_ROOM_FEATURE_ABUSE_RECORDABLE[];
-
-extern const char STR_ID_TYPE_CONVERSATION[];
-extern const char NS_GOOGLE_MUC_HANGOUT[];
-extern const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE;
-extern const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE_TYPE;
-extern const StaticQName QN_ATTR_CREATE_ACTIVITY;
-extern const StaticQName QN_GOOGLE_MUC_HANGOUT_PUBLIC;
-extern const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITEE;
-extern const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_STATUS;
-extern const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_TYPE;
-extern const StaticQName QN_GOOGLE_MUC_HANGOUT_HANGOUT_START_CONTEXT;
-extern const StaticQName QN_GOOGLE_MUC_HANGOUT_CONVERSATION_ID;
-
-extern const StaticQName QN_STREAM_STREAM;
-extern const StaticQName QN_STREAM_FEATURES;
-extern const StaticQName QN_STREAM_ERROR;
-
-extern const StaticQName QN_XSTREAM_BAD_FORMAT;
-extern const StaticQName QN_XSTREAM_BAD_NAMESPACE_PREFIX;
-extern const StaticQName QN_XSTREAM_CONFLICT;
-extern const StaticQName QN_XSTREAM_CONNECTION_TIMEOUT;
-extern const StaticQName QN_XSTREAM_HOST_GONE;
-extern const StaticQName QN_XSTREAM_HOST_UNKNOWN;
-extern const StaticQName QN_XSTREAM_IMPROPER_ADDRESSIING;
-extern const StaticQName QN_XSTREAM_INTERNAL_SERVER_ERROR;
-extern const StaticQName QN_XSTREAM_INVALID_FROM;
-extern const StaticQName QN_XSTREAM_INVALID_ID;
-extern const StaticQName QN_XSTREAM_INVALID_NAMESPACE;
-extern const StaticQName QN_XSTREAM_INVALID_XML;
-extern const StaticQName QN_XSTREAM_NOT_AUTHORIZED;
-extern const StaticQName QN_XSTREAM_POLICY_VIOLATION;
-extern const StaticQName QN_XSTREAM_REMOTE_CONNECTION_FAILED;
-extern const StaticQName QN_XSTREAM_RESOURCE_CONSTRAINT;
-extern const StaticQName QN_XSTREAM_RESTRICTED_XML;
-extern const StaticQName QN_XSTREAM_SEE_OTHER_HOST;
-extern const StaticQName QN_XSTREAM_SYSTEM_SHUTDOWN;
-extern const StaticQName QN_XSTREAM_UNDEFINED_CONDITION;
-extern const StaticQName QN_XSTREAM_UNSUPPORTED_ENCODING;
-extern const StaticQName QN_XSTREAM_UNSUPPORTED_STANZA_TYPE;
-extern const StaticQName QN_XSTREAM_UNSUPPORTED_VERSION;
-extern const StaticQName QN_XSTREAM_XML_NOT_WELL_FORMED;
-extern const StaticQName QN_XSTREAM_TEXT;
-
-extern const StaticQName QN_TLS_STARTTLS;
-extern const StaticQName QN_TLS_REQUIRED;
-extern const StaticQName QN_TLS_PROCEED;
-extern const StaticQName QN_TLS_FAILURE;
-
-extern const StaticQName QN_SASL_MECHANISMS;
-extern const StaticQName QN_SASL_MECHANISM;
-extern const StaticQName QN_SASL_AUTH;
-extern const StaticQName QN_SASL_CHALLENGE;
-extern const StaticQName QN_SASL_RESPONSE;
-extern const StaticQName QN_SASL_ABORT;
-extern const StaticQName QN_SASL_SUCCESS;
-extern const StaticQName QN_SASL_FAILURE;
-extern const StaticQName QN_SASL_ABORTED;
-extern const StaticQName QN_SASL_INCORRECT_ENCODING;
-extern const StaticQName QN_SASL_INVALID_AUTHZID;
-extern const StaticQName QN_SASL_INVALID_MECHANISM;
-extern const StaticQName QN_SASL_MECHANISM_TOO_WEAK;
-extern const StaticQName QN_SASL_NOT_AUTHORIZED;
-extern const StaticQName QN_SASL_TEMPORARY_AUTH_FAILURE;
-
-// These are non-standard.
-extern const char NS_GOOGLE_AUTH[];
-extern const char NS_GOOGLE_AUTH_PROTOCOL[];
-extern const StaticQName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT;
-extern const StaticQName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN;
-extern const StaticQName QN_GOOGLE_AUTH_SERVICE;
-
-extern const StaticQName QN_DIALBACK_RESULT;
-extern const StaticQName QN_DIALBACK_VERIFY;
-
-extern const StaticQName QN_STANZA_BAD_REQUEST;
-extern const StaticQName QN_STANZA_CONFLICT;
-extern const StaticQName QN_STANZA_FEATURE_NOT_IMPLEMENTED;
-extern const StaticQName QN_STANZA_FORBIDDEN;
-extern const StaticQName QN_STANZA_GONE;
-extern const StaticQName QN_STANZA_INTERNAL_SERVER_ERROR;
-extern const StaticQName QN_STANZA_ITEM_NOT_FOUND;
-extern const StaticQName QN_STANZA_JID_MALFORMED;
-extern const StaticQName QN_STANZA_NOT_ACCEPTABLE;
-extern const StaticQName QN_STANZA_NOT_ALLOWED;
-extern const StaticQName QN_STANZA_PAYMENT_REQUIRED;
-extern const StaticQName QN_STANZA_RECIPIENT_UNAVAILABLE;
-extern const StaticQName QN_STANZA_REDIRECT;
-extern const StaticQName QN_STANZA_REGISTRATION_REQUIRED;
-extern const StaticQName QN_STANZA_REMOTE_SERVER_NOT_FOUND;
-extern const StaticQName QN_STANZA_REMOTE_SERVER_TIMEOUT;
-extern const StaticQName QN_STANZA_RESOURCE_CONSTRAINT;
-extern const StaticQName QN_STANZA_SERVICE_UNAVAILABLE;
-extern const StaticQName QN_STANZA_SUBSCRIPTION_REQUIRED;
-extern const StaticQName QN_STANZA_UNDEFINED_CONDITION;
-extern const StaticQName QN_STANZA_UNEXPECTED_REQUEST;
-extern const StaticQName QN_STANZA_TEXT;
-
-extern const StaticQName QN_BIND_BIND;
-extern const StaticQName QN_BIND_RESOURCE;
-extern const StaticQName QN_BIND_JID;
-
-extern const StaticQName QN_MESSAGE;
-extern const StaticQName QN_BODY;
-extern const StaticQName QN_SUBJECT;
-extern const StaticQName QN_THREAD;
-extern const StaticQName QN_PRESENCE;
-extern const StaticQName QN_SHOW;
-extern const StaticQName QN_STATUS;
-extern const StaticQName QN_LANG;
-extern const StaticQName QN_PRIORITY;
-extern const StaticQName QN_IQ;
-extern const StaticQName QN_ERROR;
-
-extern const StaticQName QN_SERVER_MESSAGE;
-extern const StaticQName QN_SERVER_BODY;
-extern const StaticQName QN_SERVER_SUBJECT;
-extern const StaticQName QN_SERVER_THREAD;
-extern const StaticQName QN_SERVER_PRESENCE;
-extern const StaticQName QN_SERVER_SHOW;
-extern const StaticQName QN_SERVER_STATUS;
-extern const StaticQName QN_SERVER_LANG;
-extern const StaticQName QN_SERVER_PRIORITY;
-extern const StaticQName QN_SERVER_IQ;
-extern const StaticQName QN_SERVER_ERROR;
-
-extern const StaticQName QN_SESSION_SESSION;
-
-extern const StaticQName QN_PRIVACY_QUERY;
-extern const StaticQName QN_PRIVACY_ACTIVE;
-extern const StaticQName QN_PRIVACY_DEFAULT;
-extern const StaticQName QN_PRIVACY_LIST;
-extern const StaticQName QN_PRIVACY_ITEM;
-extern const StaticQName QN_PRIVACY_IQ;
-extern const StaticQName QN_PRIVACY_MESSAGE;
-extern const StaticQName QN_PRIVACY_PRESENCE_IN;
-extern const StaticQName QN_PRIVACY_PRESENCE_OUT;
-
-extern const StaticQName QN_ROSTER_QUERY;
-extern const StaticQName QN_ROSTER_ITEM;
-extern const StaticQName QN_ROSTER_GROUP;
-
-extern const StaticQName QN_VCARD;
-extern const StaticQName QN_VCARD_FN;
-extern const StaticQName QN_VCARD_PHOTO;
-extern const StaticQName QN_VCARD_PHOTO_BINVAL;
-extern const StaticQName QN_VCARD_AVATAR_HASH;
-extern const StaticQName QN_VCARD_AVATAR_HASH_MODIFIED;
-
-#if defined(FEATURE_ENABLE_PSTN)
-extern const StaticQName QN_VCARD_TEL;
-extern const StaticQName QN_VCARD_VOICE;
-extern const StaticQName QN_VCARD_HOME;
-extern const StaticQName QN_VCARD_WORK;
-extern const StaticQName QN_VCARD_CELL;
-extern const StaticQName QN_VCARD_NUMBER;
-#endif
-
-#if defined(FEATURE_ENABLE_RICHPROFILES)
-extern const StaticQName QN_USER_PROFILE_QUERY;
-extern const StaticQName QN_USER_PROFILE_URL;
-
-extern const StaticQName QN_ATOM_FEED;
-extern const StaticQName QN_ATOM_ENTRY;
-extern const StaticQName QN_ATOM_TITLE;
-extern const StaticQName QN_ATOM_ID;
-extern const StaticQName QN_ATOM_MODIFIED;
-extern const StaticQName QN_ATOM_IMAGE;
-extern const StaticQName QN_ATOM_LINK;
-extern const StaticQName QN_ATOM_HREF;
-#endif
-
-extern const StaticQName QN_XML_LANG;
-
-extern const StaticQName QN_ENCODING;
-extern const StaticQName QN_VERSION;
-extern const StaticQName QN_TO;
-extern const StaticQName QN_FROM;
-extern const StaticQName QN_TYPE;
-extern const StaticQName QN_ID;
-extern const StaticQName QN_CODE;
-extern const StaticQName QN_NAME;
-extern const StaticQName QN_VALUE;
-extern const StaticQName QN_ACTION;
-extern const StaticQName QN_ORDER;
-extern const StaticQName QN_MECHANISM;
-extern const StaticQName QN_ASK;
-extern const StaticQName QN_JID;
-extern const StaticQName QN_NICK;
-extern const StaticQName QN_SUBSCRIPTION;
-extern const StaticQName QN_TITLE1;
-extern const StaticQName QN_TITLE2;
-extern const StaticQName QN_AFFILIATION;
-extern const StaticQName QN_ROLE;
-extern const StaticQName QN_TIME;
-
-extern const StaticQName QN_XMLNS_CLIENT;
-extern const StaticQName QN_XMLNS_SERVER;
-extern const StaticQName QN_XMLNS_STREAM;
-
-// Presence
-extern const char STR_SHOW_AWAY[];
-extern const char STR_SHOW_CHAT[];
-extern const char STR_SHOW_DND[];
-extern const char STR_SHOW_XA[];
-extern const char STR_SHOW_OFFLINE[];
-
-extern const char NS_GOOGLE_PSTN_CONFERENCE[];
-extern const StaticQName QN_GOOGLE_PSTN_CONFERENCE_STATUS;
-extern const StaticQName QN_ATTR_STATUS;
-
-// Presence connection status
-extern const char STR_PSTN_CONFERENCE_STATUS_CONNECTING[];
-extern const char STR_PSTN_CONFERENCE_STATUS_JOINING[];
-extern const char STR_PSTN_CONFERENCE_STATUS_CONNECTED[];
-extern const char STR_PSTN_CONFERENCE_STATUS_HANGUP[];
-
-// Subscription
-extern const char STR_SUBSCRIBE[];
-extern const char STR_SUBSCRIBED[];
-extern const char STR_UNSUBSCRIBE[];
-extern const char STR_UNSUBSCRIBED[];
-
-// Google Invite
-extern const char NS_GOOGLE_SUBSCRIBE[];
-extern const StaticQName QN_INVITATION;
-extern const StaticQName QN_INVITE_NAME;
-extern const StaticQName QN_INVITE_SUBJECT;
-extern const StaticQName QN_INVITE_MESSAGE;
-
-// Kick
-extern const char NS_GOOGLE_MUC_ADMIN[];
-extern const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY;
-extern const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM;
-extern const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM_REASON;
-
-// PubSub: http://xmpp.org/extensions/xep-0060.html
-extern const char NS_PUBSUB[];
-extern const StaticQName QN_PUBSUB;
-extern const StaticQName QN_PUBSUB_ITEMS;
-extern const StaticQName QN_PUBSUB_ITEM;
-extern const StaticQName QN_PUBSUB_PUBLISH;
-extern const StaticQName QN_PUBSUB_RETRACT;
-extern const StaticQName QN_ATTR_PUBLISHER;
-
-extern const char NS_PUBSUB_EVENT[];
-extern const StaticQName QN_NODE;
-extern const StaticQName QN_PUBSUB_EVENT;
-extern const StaticQName QN_PUBSUB_EVENT_ITEMS;
-extern const StaticQName QN_PUBSUB_EVENT_ITEM;
-extern const StaticQName QN_PUBSUB_EVENT_RETRACT;
-extern const StaticQName QN_NOTIFY;
-
-extern const char NS_PRESENTER[];
-extern const StaticQName QN_PRESENTER_PRESENTER;
-extern const StaticQName QN_PRESENTER_PRESENTATION_ITEM;
-extern const StaticQName QN_PRESENTER_PRESENTATION_TYPE;
-extern const StaticQName QN_PRESENTER_PRESENTATION_ID;
-
-// JEP 0030
-extern const StaticQName QN_CATEGORY;
-extern const StaticQName QN_VAR;
-extern const char NS_DISCO_INFO[];
-extern const char NS_DISCO_ITEMS[];
-
-extern const StaticQName QN_DISCO_INFO_QUERY;
-extern const StaticQName QN_DISCO_IDENTITY;
-extern const StaticQName QN_DISCO_FEATURE;
-
-extern const StaticQName QN_DISCO_ITEMS_QUERY;
-extern const StaticQName QN_DISCO_ITEM;
-
-// JEP 0020
-extern const char NS_FEATURE[];
-extern const StaticQName QN_FEATURE_FEATURE;
-
-// JEP 0004
-extern const char NS_XDATA[];
-extern const StaticQName QN_XDATA_X;
-extern const StaticQName QN_XDATA_INSTRUCTIONS;
-extern const StaticQName QN_XDATA_TITLE;
-extern const StaticQName QN_XDATA_FIELD;
-extern const StaticQName QN_XDATA_REPORTED;
-extern const StaticQName QN_XDATA_ITEM;
-extern const StaticQName QN_XDATA_DESC;
-extern const StaticQName QN_XDATA_REQUIRED;
-extern const StaticQName QN_XDATA_VALUE;
-extern const StaticQName QN_XDATA_OPTION;
-
-// JEP 0045
-extern const char NS_MUC[];
-extern const StaticQName QN_MUC_X;
-extern const StaticQName QN_MUC_ITEM;
-extern const StaticQName QN_MUC_AFFILIATION;
-extern const StaticQName QN_MUC_ROLE;
-extern const StaticQName QN_CLIENT_VERSION;
-extern const StaticQName QN_LOCALE;
-extern const char STR_AFFILIATION_NONE[];
-extern const char STR_ROLE_PARTICIPANT[];
-
-extern const char NS_GOOGLE_SESSION[];
-extern const StaticQName QN_GOOGLE_USER_ID;
-extern const StaticQName QN_GOOGLE_CIRCLE_ID;
-extern const StaticQName QN_GOOGLE_SESSION_BLOCKED;
-extern const StaticQName QN_GOOGLE_SESSION_BLOCKING;
-
-extern const char NS_MUC_OWNER[];
-extern const StaticQName QN_MUC_OWNER_QUERY;
-
-extern const char NS_MUC_USER[];
-extern const StaticQName QN_MUC_USER_CONTINUE;
-extern const StaticQName QN_MUC_USER_X;
-extern const StaticQName QN_MUC_USER_ITEM;
-extern const StaticQName QN_MUC_USER_STATUS;
-extern const StaticQName QN_MUC_USER_REASON;
-extern const StaticQName QN_MUC_USER_ABUSE_VIOLATION;
-
-// JEP 0055 - Jabber Search
-extern const char NS_SEARCH[];
-extern const StaticQName QN_SEARCH_QUERY;
-extern const StaticQName QN_SEARCH_ITEM;
-extern const StaticQName QN_SEARCH_ROOM_NAME;
-extern const StaticQName QN_SEARCH_ROOM_JID;
-extern const StaticQName QN_SEARCH_ROOM_DOMAIN;
-extern const StaticQName QN_SEARCH_HANGOUT_ID;
-extern const StaticQName QN_SEARCH_EXTERNAL_ID;
-
-// JEP 0115
-extern const char NS_CAPS[];
-extern const StaticQName QN_CAPS_C;
-extern const StaticQName QN_VER;
-extern const StaticQName QN_EXT;
-
-
-// Avatar - JEP 0153
-extern const char kNSVCard[];
-extern const StaticQName kQnVCardX;
-extern const StaticQName kQnVCardPhoto;
-
-// JEP 0172 User Nickname
-extern const char NS_NICKNAME[];
-extern const StaticQName QN_NICKNAME;
-
-// JEP 0085 chat state
-extern const char NS_CHATSTATE[];
-extern const StaticQName QN_CS_ACTIVE;
-extern const StaticQName QN_CS_COMPOSING;
-extern const StaticQName QN_CS_PAUSED;
-extern const StaticQName QN_CS_INACTIVE;
-extern const StaticQName QN_CS_GONE;
-
-// JEP 0091 Delayed Delivery
-extern const char kNSDelay[];
-extern const StaticQName kQnDelayX;
-extern const StaticQName kQnStamp;
-
-// Google time stamping (higher resolution)
-extern const char kNSTimestamp[];
-extern const StaticQName kQnTime;
-extern const StaticQName kQnMilliseconds;
-
-extern const char NS_JINGLE_INFO[];
-extern const StaticQName QN_JINGLE_INFO_QUERY;
-extern const StaticQName QN_JINGLE_INFO_STUN;
-extern const StaticQName QN_JINGLE_INFO_RELAY;
-extern const StaticQName QN_JINGLE_INFO_SERVER;
-extern const StaticQName QN_JINGLE_INFO_TOKEN;
-extern const StaticQName QN_JINGLE_INFO_HOST;
-extern const StaticQName QN_JINGLE_INFO_TCP;
-extern const StaticQName QN_JINGLE_INFO_UDP;
-extern const StaticQName QN_JINGLE_INFO_TCPSSL;
-
-extern const char NS_GOOGLE_CALLPERF_STATS[];
-extern const StaticQName QN_CALLPERF_STATS;
-extern const StaticQName QN_CALLPERF_SESSIONID;
-extern const StaticQName QN_CALLPERF_LOCALUSER;
-extern const StaticQName QN_CALLPERF_REMOTEUSER;
-extern const StaticQName QN_CALLPERF_STARTTIME;
-extern const StaticQName QN_CALLPERF_CALL_LENGTH;
-extern const StaticQName QN_CALLPERF_CALL_ACCEPTED;
-extern const StaticQName QN_CALLPERF_CALL_ERROR_CODE;
-extern const StaticQName QN_CALLPERF_TERMINATE_CODE;
-extern const StaticQName QN_CALLPERF_DATAPOINT;
-extern const StaticQName QN_CALLPERF_DATAPOINT_TIME;
-extern const StaticQName QN_CALLPERF_DATAPOINT_FRACTION_LOST;
-extern const StaticQName QN_CALLPERF_DATAPOINT_CUM_LOST;
-extern const StaticQName QN_CALLPERF_DATAPOINT_EXT_MAX;
-extern const StaticQName QN_CALLPERF_DATAPOINT_JITTER;
-extern const StaticQName QN_CALLPERF_DATAPOINT_RTT;
-extern const StaticQName QN_CALLPERF_DATAPOINT_BYTES_R;
-extern const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_R;
-extern const StaticQName QN_CALLPERF_DATAPOINT_BYTES_S;
-extern const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_S;
-extern const StaticQName QN_CALLPERF_DATAPOINT_PROCESS_CPU;
-extern const StaticQName QN_CALLPERF_DATAPOINT_SYSTEM_CPU;
-extern const StaticQName QN_CALLPERF_DATAPOINT_CPUS;
-extern const StaticQName QN_CALLPERF_CONNECTION;
-extern const StaticQName QN_CALLPERF_CONNECTION_LOCAL_ADDRESS;
-extern const StaticQName QN_CALLPERF_CONNECTION_REMOTE_ADDRESS;
-extern const StaticQName QN_CALLPERF_CONNECTION_FLAGS;
-extern const StaticQName QN_CALLPERF_CONNECTION_RTT;
-extern const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_S;
-extern const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_S;
-extern const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_R;
-extern const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_R;
-extern const StaticQName QN_CALLPERF_CANDIDATE;
-extern const StaticQName QN_CALLPERF_CANDIDATE_ENDPOINT;
-extern const StaticQName QN_CALLPERF_CANDIDATE_PROTOCOL;
-extern const StaticQName QN_CALLPERF_CANDIDATE_ADDRESS;
-extern const StaticQName QN_CALLPERF_MEDIA;
-extern const StaticQName QN_CALLPERF_MEDIA_DIRECTION;
-extern const StaticQName QN_CALLPERF_MEDIA_SSRC;
-extern const StaticQName QN_CALLPERF_MEDIA_ENERGY;
-extern const StaticQName QN_CALLPERF_MEDIA_FIR;
-extern const StaticQName QN_CALLPERF_MEDIA_NACK;
-extern const StaticQName QN_CALLPERF_MEDIA_FPS;
-extern const StaticQName QN_CALLPERF_MEDIA_FPS_NETWORK;
-extern const StaticQName QN_CALLPERF_MEDIA_FPS_DECODED;
-extern const StaticQName QN_CALLPERF_MEDIA_JITTER_BUFFER_SIZE;
-extern const StaticQName QN_CALLPERF_MEDIA_PREFERRED_JITTER_BUFFER_SIZE;
-extern const StaticQName QN_CALLPERF_MEDIA_TOTAL_PLAYOUT_DELAY;
-
-// Muc invites.
-extern const StaticQName QN_MUC_USER_INVITE;
-
-// Multiway audio/video.
-extern const char NS_GOOGLE_MUC_USER[];
-extern const StaticQName QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA;
-extern const StaticQName QN_GOOGLE_MUC_USER_ENTRY;
-extern const StaticQName QN_GOOGLE_MUC_USER_MEDIA;
-extern const StaticQName QN_GOOGLE_MUC_USER_TYPE;
-extern const StaticQName QN_GOOGLE_MUC_USER_SRC_ID;
-extern const StaticQName QN_GOOGLE_MUC_USER_STATUS;
-extern const StaticQName QN_LABEL;
-
-extern const char NS_GOOGLE_MUC_MEDIA[];
-extern const StaticQName QN_GOOGLE_MUC_AUDIO_MUTE;
-extern const StaticQName QN_GOOGLE_MUC_VIDEO_MUTE;
-extern const StaticQName QN_GOOGLE_MUC_VIDEO_PAUSE;
-extern const StaticQName QN_GOOGLE_MUC_RECORDING;
-extern const StaticQName QN_GOOGLE_MUC_MEDIA_BLOCK;
-extern const StaticQName QN_STATE_ATTR;
-
-
-extern const char AUTH_MECHANISM_GOOGLE_COOKIE[];
-extern const char AUTH_MECHANISM_GOOGLE_TOKEN[];
-extern const char AUTH_MECHANISM_OAUTH2[];
-extern const char AUTH_MECHANISM_PLAIN[];
-
-}  // namespace jingle_xmpp
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_CONSTANTS_H_
diff --git a/third_party/libjingle_xmpp/xmpp/fakexmppclient.h b/third_party/libjingle_xmpp/xmpp/fakexmppclient.h
deleted file mode 100644
index 2aa3c2c..0000000
--- a/third_party/libjingle_xmpp/xmpp/fakexmppclient.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *  Copyright 2011 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-// A fake XmppClient for use in unit tests.
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_FAKEXMPPCLIENT_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_FAKEXMPPCLIENT_H_
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "third_party/libjingle_xmpp/xmpp/xmpptask.h"
-
-namespace jingle_xmpp {
-
-class XmlElement;
-
-class FakeXmppClient : public XmppTaskParentInterface,
-                       public XmppClientInterface {
- public:
-  explicit FakeXmppClient(jingle_xmpp::TaskParent* parent)
-      : XmppTaskParentInterface(parent) {
-  }
-
-  // As XmppTaskParentInterface
-  virtual XmppClientInterface* GetClient() {
-    return this;
-  }
-
-  virtual int ProcessStart() {
-    return STATE_RESPONSE;
-  }
-
-  // As XmppClientInterface
-  virtual XmppEngine::State GetState() const {
-    return XmppEngine::STATE_OPEN;
-  }
-
-  virtual const Jid& jid() const {
-    return jid_;
-  }
-
-  virtual std::string NextId() {
-    // Implement if needed for tests.
-    return "0";
-  }
-
-  virtual XmppReturnStatus SendStanza(const XmlElement* stanza) {
-    sent_stanzas_.push_back(stanza);
-    return XMPP_RETURN_OK;
-  }
-
-  const std::vector<const XmlElement*>& sent_stanzas() {
-    return sent_stanzas_;
-  }
-
-  virtual XmppReturnStatus SendStanzaError(
-      const XmlElement * pelOriginal,
-      XmppStanzaError code,
-      const std::string & text) {
-    // Implement if needed for tests.
-    return XMPP_RETURN_OK;
-  }
-
-  virtual void AddXmppTask(XmppTask* task,
-                           XmppEngine::HandlerLevel level) {
-    tasks_.push_back(task);
-  }
-
-  virtual void RemoveXmppTask(XmppTask* task) {
-    std::remove(tasks_.begin(), tasks_.end(), task);
-  }
-
-  // As FakeXmppClient
-  void set_jid(const Jid& jid) {
-    jid_ = jid;
-  }
-
-  // Takes ownership of stanza.
-  void HandleStanza(XmlElement* stanza) {
-    for (std::vector<XmppTask*>::iterator task = tasks_.begin();
-         task != tasks_.end(); ++task) {
-      if ((*task)->HandleStanza(stanza)) {
-        delete stanza;
-        return;
-      }
-    }
-    delete stanza;
-  }
-
- private:
-  Jid jid_;
-  std::vector<XmppTask*> tasks_;
-  std::vector<const XmlElement*> sent_stanzas_;
-};
-
-}  // namespace jingle_xmpp
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_FAKEXMPPCLIENT_H_
diff --git a/third_party/libjingle_xmpp/xmpp/jid.cc b/third_party/libjingle_xmpp/xmpp/jid.cc
deleted file mode 100644
index fbc8b08..0000000
--- a/third_party/libjingle_xmpp/xmpp/jid.cc
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/xmpp/jid.h"
-
-#include <ctype.h>
-
-#include <algorithm>
-#include <string>
-
-#include "base/check.h"
-#include "base/logging.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-
-namespace jingle_xmpp {
-
-Jid::Jid() {
-}
-
-Jid::Jid(const std::string& jid_string) {
-  if (jid_string.empty())
-    return;
-
-  // First find the slash and slice off that part
-  size_t slash = jid_string.find('/');
-  resource_name_ = (slash == std::string::npos ? STR_EMPTY :
-                    jid_string.substr(slash + 1));
-
-  // Now look for the node
-  size_t at = jid_string.find('@');
-  size_t domain_begin;
-  if (at < slash && at != std::string::npos) {
-    node_name_ = jid_string.substr(0, at);
-    domain_begin = at + 1;
-  } else {
-    domain_begin = 0;
-  }
-
-  // Now take what is left as the domain
-  size_t domain_length = (slash == std::string::npos) ?
-      (jid_string.length() - domain_begin) : (slash - domain_begin);
-  domain_name_ = jid_string.substr(domain_begin, domain_length);
-
-  ValidateOrReset();
-}
-
-Jid::Jid(const std::string& node_name,
-         const std::string& domain_name,
-         const std::string& resource_name)
-    :  node_name_(node_name),
-       domain_name_(domain_name),
-       resource_name_(resource_name) {
-  ValidateOrReset();
-}
-
-void Jid::ValidateOrReset() {
-  bool valid_node;
-  bool valid_domain;
-  bool valid_resource;
-
-  node_name_ = PrepNode(node_name_, &valid_node);
-  domain_name_ = PrepDomain(domain_name_, &valid_domain);
-  resource_name_ = PrepResource(resource_name_, &valid_resource);
-
-  if (!valid_node || !valid_domain || !valid_resource) {
-    node_name_.clear();
-    domain_name_.clear();
-    resource_name_.clear();
-  }
-}
-
-std::string Jid::Str() const {
-  if (!IsValid())
-    return STR_EMPTY;
-
-  std::string ret;
-
-  if (!node_name_.empty())
-    ret = node_name_ + "@";
-
-  DCHECK(domain_name_ != STR_EMPTY);
-  ret += domain_name_;
-
-  if (!resource_name_.empty())
-    ret += "/" + resource_name_;
-
-  return ret;
-}
-
-Jid::~Jid() {
-}
-
-bool Jid::IsEmpty() const {
-  return (node_name_.empty() && domain_name_.empty() &&
-          resource_name_.empty());
-}
-
-bool Jid::IsValid() const {
-  return !domain_name_.empty();
-}
-
-bool Jid::IsBare() const {
-  if (IsEmpty()) {
-    DVLOG(1) << "Warning: Calling IsBare() on the empty jid.";
-    return true;
-  }
-  return IsValid() && resource_name_.empty();
-}
-
-bool Jid::IsFull() const {
-  return IsValid() && !resource_name_.empty();
-}
-
-Jid Jid::BareJid() const {
-  if (!IsValid())
-    return Jid();
-  if (!IsFull())
-    return *this;
-  return Jid(node_name_, domain_name_, STR_EMPTY);
-}
-
-bool Jid::BareEquals(const Jid& other) const {
-  return other.node_name_ == node_name_ &&
-      other.domain_name_ == domain_name_;
-}
-
-void Jid::CopyFrom(const Jid& jid) {
-  this->node_name_ = jid.node_name_;
-  this->domain_name_ = jid.domain_name_;
-  this->resource_name_ = jid.resource_name_;
-}
-
-bool Jid::operator==(const Jid& other) const {
-  return other.node_name_ == node_name_ &&
-      other.domain_name_ == domain_name_ &&
-      other.resource_name_ == resource_name_;
-}
-
-int Jid::Compare(const Jid& other) const {
-  int compare_result;
-  compare_result = node_name_.compare(other.node_name_);
-  if (0 != compare_result)
-    return compare_result;
-  compare_result = domain_name_.compare(other.domain_name_);
-  if (0 != compare_result)
-    return compare_result;
-  compare_result = resource_name_.compare(other.resource_name_);
-  return compare_result;
-}
-
-// --- JID parsing code: ---
-
-// Checks and normalizes the node part of a JID.
-std::string Jid::PrepNode(const std::string& node, bool* valid) {
-  *valid = false;
-  std::string result;
-
-  for (std::string::const_iterator i = node.begin(); i < node.end(); ++i) {
-    bool char_valid = true;
-    unsigned char ch = *i;
-    if (ch <= 0x7F) {
-      result += PrepNodeAscii(ch, &char_valid);
-    }
-    else {
-      // TODO: implement the correct stringprep protocol for these
-      result += tolower(ch);
-    }
-    if (!char_valid) {
-      return STR_EMPTY;
-    }
-  }
-
-  if (result.length() > 1023) {
-    return STR_EMPTY;
-  }
-  *valid = true;
-  return result;
-}
-
-
-// Returns the appropriate mapping for an ASCII character in a node.
-char Jid::PrepNodeAscii(char ch, bool* valid) {
-  *valid = true;
-  switch (ch) {
-    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
-    case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
-    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
-    case 'V': case 'W': case 'X': case 'Y': case 'Z':
-      return (char)(ch + ('a' - 'A'));
-
-    case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
-    case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
-    case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
-    case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
-    case ' ': case '&': case '/': case ':': case '<': case '>': case '@':
-    case '\"': case '\'':
-    case 0x7F:
-      *valid = false;
-      return 0;
-
-    default:
-      return ch;
-  }
-}
-
-
-// Checks and normalizes the resource part of a JID.
-std::string Jid::PrepResource(const std::string& resource, bool* valid) {
-  *valid = false;
-  std::string result;
-
-  for (std::string::const_iterator i = resource.begin();
-       i < resource.end(); ++i) {
-    bool char_valid = true;
-    unsigned char ch = *i;
-    if (ch <= 0x7F) {
-      result += PrepResourceAscii(ch, &char_valid);
-    }
-    else {
-      // TODO: implement the correct stringprep protocol for these
-      result += ch;
-    }
-  }
-
-  if (result.length() > 1023) {
-    return STR_EMPTY;
-  }
-  *valid = true;
-  return result;
-}
-
-// Returns the appropriate mapping for an ASCII character in a resource.
-char Jid::PrepResourceAscii(char ch, bool* valid) {
-  *valid = true;
-  switch (ch) {
-    case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
-    case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
-    case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
-    case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
-    case 0x7F:
-      *valid = false;
-      return 0;
-
-    default:
-      return ch;
-  }
-}
-
-// Checks and normalizes the domain part of a JID.
-std::string Jid::PrepDomain(const std::string& domain, bool* valid) {
-  *valid = false;
-  std::string result;
-
-  // TODO: if the domain contains a ':', then we should parse it
-  // as an IPv6 address rather than giving an error about illegal domain.
-  PrepDomain(domain, &result, valid);
-  if (!*valid) {
-    return STR_EMPTY;
-  }
-
-  if (result.length() > 1023) {
-    return STR_EMPTY;
-  }
-  *valid = true;
-  return result;
-}
-
-
-// Checks and normalizes an IDNA domain.
-void Jid::PrepDomain(const std::string& domain, std::string* buf, bool* valid) {
-  *valid = false;
-  std::string::const_iterator last = domain.begin();
-  for (std::string::const_iterator i = domain.begin(); i < domain.end(); ++i) {
-    bool label_valid = true;
-    char ch = *i;
-    switch (ch) {
-      case 0x002E:
-#if 0 // FIX: This isn't UTF-8-aware.
-      case 0x3002:
-      case 0xFF0E:
-      case 0xFF61:
-#endif
-        PrepDomainLabel(last, i, buf, &label_valid);
-        *buf += '.';
-        last = i + 1;
-        break;
-    }
-    if (!label_valid) {
-      return;
-    }
-  }
-  PrepDomainLabel(last, domain.end(), buf, valid);
-}
-
-// Checks and normalizes a domain label.
-void Jid::PrepDomainLabel(
-    std::string::const_iterator start, std::string::const_iterator end,
-    std::string* buf, bool* valid) {
-  *valid = false;
-
-  int start_len = static_cast<int>(buf->length());
-  for (std::string::const_iterator i = start; i < end; ++i) {
-    bool char_valid = true;
-    unsigned char ch = *i;
-    if (ch <= 0x7F) {
-      *buf += PrepDomainLabelAscii(ch, &char_valid);
-    }
-    else {
-      // TODO: implement ToASCII for these
-      *buf += ch;
-    }
-    if (!char_valid) {
-      return;
-    }
-  }
-
-  int count = static_cast<int>(buf->length() - start_len);
-  if (count == 0) {
-    return;
-  }
-  else if (count > 63) {
-    return;
-  }
-
-  // Is this check needed? See comment in PrepDomainLabelAscii.
-  if ((*buf)[start_len] == '-') {
-    return;
-  }
-  if ((*buf)[buf->length() - 1] == '-') {
-    return;
-  }
-  *valid = true;
-}
-
-
-// Returns the appropriate mapping for an ASCII character in a domain label.
-char Jid::PrepDomainLabelAscii(char ch, bool* valid) {
-  *valid = true;
-  // TODO: A literal reading of the spec seems to say that we do
-  // not need to check for these illegal characters (an "internationalized
-  // domain label" runs ToASCII with UseSTD3... set to false).  But that
-  // can't be right.  We should at least be checking that there are no '/'
-  // or '@' characters in the domain.  Perhaps we should see what others
-  // do in this case.
-
-  switch (ch) {
-    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
-    case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
-    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
-    case 'V': case 'W': case 'X': case 'Y': case 'Z':
-      return (char)(ch + ('a' - 'A'));
-
-    case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
-    case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
-    case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
-    case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
-    case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D:
-    case 0x1E: case 0x1F: case 0x20: case 0x21: case 0x22: case 0x23:
-    case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29:
-    case 0x2A: case 0x2B: case 0x2C: case 0x2E: case 0x2F: case 0x3A:
-    case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: case 0x40:
-    case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: case 0x60:
-    case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F:
-      *valid = false;
-      return 0;
-
-    default:
-      return ch;
-  }
-}
-
-}  // namespace jingle_xmpp
diff --git a/third_party/libjingle_xmpp/xmpp/jid.h b/third_party/libjingle_xmpp/xmpp/jid.h
deleted file mode 100644
index bb77a6c..0000000
--- a/third_party/libjingle_xmpp/xmpp/jid.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_JID_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_JID_H_
-
-#include <string>
-#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h"
-
-namespace jingle_xmpp {
-
-// The Jid class encapsulates and provides parsing help for Jids. A Jid
-// consists of three parts: the node, the domain and the resource, e.g.:
-//
-// node@domain/resource
-//
-// The node and resource are both optional. A valid jid is defined to have
-// a domain. A bare jid is defined to not have a resource and a full jid
-// *does* have a resource.
-class Jid {
-public:
-  explicit Jid();
-  explicit Jid(const std::string& jid_string);
-  explicit Jid(const std::string& node_name,
-               const std::string& domain_name,
-               const std::string& resource_name);
-  ~Jid();
-
-  const std::string & node() const { return node_name_; }
-  const std::string & domain() const { return domain_name_;  }
-  const std::string & resource() const { return resource_name_; }
-
-  std::string Str() const;
-  Jid BareJid() const;
-
-  bool IsEmpty() const;
-  bool IsValid() const;
-  bool IsBare() const;
-  bool IsFull() const;
-
-  bool BareEquals(const Jid& other) const;
-  void CopyFrom(const Jid& jid);
-  bool operator==(const Jid& other) const;
-  bool operator!=(const Jid& other) const { return !operator==(other); }
-
-  bool operator<(const Jid& other) const { return Compare(other) < 0; }
-  bool operator>(const Jid& other) const { return Compare(other) > 0; }
-
-  int Compare(const Jid & other) const;
-
-private:
-  void ValidateOrReset();
-
-  static std::string PrepNode(const std::string& node, bool* valid);
-  static char PrepNodeAscii(char ch, bool* valid);
-  static std::string PrepResource(const std::string& start, bool* valid);
-  static char PrepResourceAscii(char ch, bool* valid);
-  static std::string PrepDomain(const std::string& domain, bool* valid);
-  static void PrepDomain(const std::string& domain,
-                         std::string* buf, bool* valid);
-  static void PrepDomainLabel(
-      std::string::const_iterator start, std::string::const_iterator end,
-      std::string* buf, bool* valid);
-  static char PrepDomainLabelAscii(char ch, bool *valid);
-
-  std::string node_name_;
-  std::string domain_name_;
-  std::string resource_name_;
-};
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_JID_H_
diff --git a/third_party/libjingle_xmpp/xmpp/jid_unittest.cc b/third_party/libjingle_xmpp/xmpp/jid_unittest.cc
deleted file mode 100644
index 8057b705..0000000
--- a/third_party/libjingle_xmpp/xmpp/jid_unittest.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/xmpp/jid.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using jingle_xmpp::Jid;
-
-TEST(JidTest, TestDomain) {
-  Jid jid("dude");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("dude", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("dude", jid.Str());
-  EXPECT_EQ("dude", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestNodeDomain) {
-  Jid jid("walter@dude");
-  EXPECT_EQ("walter", jid.node());
-  EXPECT_EQ("dude", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("walter@dude", jid.Str());
-  EXPECT_EQ("walter@dude", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestDomainResource) {
-  Jid jid("dude/bowlingalley");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("dude", jid.domain());
-  EXPECT_EQ("bowlingalley", jid.resource());
-  EXPECT_EQ("dude/bowlingalley", jid.Str());
-  EXPECT_EQ("dude", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_FALSE(jid.IsBare());
-  EXPECT_TRUE(jid.IsFull());
-}
-
-TEST(JidTest, TestNodeDomainResource) {
-  Jid jid("walter@dude/bowlingalley");
-  EXPECT_EQ("walter", jid.node());
-  EXPECT_EQ("dude", jid.domain());
-  EXPECT_EQ("bowlingalley", jid.resource());
-  EXPECT_EQ("walter@dude/bowlingalley", jid.Str());
-  EXPECT_EQ("walter@dude", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_FALSE(jid.IsBare());
-  EXPECT_TRUE(jid.IsFull());
-}
-
-TEST(JidTest, TestNode) {
-  Jid jid("walter@");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("", jid.Str());
-  EXPECT_EQ("", jid.BareJid().Str());
-  EXPECT_FALSE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestResource) {
-  Jid jid("/bowlingalley");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("", jid.Str());
-  EXPECT_EQ("", jid.BareJid().Str());
-  EXPECT_FALSE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestNodeResource) {
-  Jid jid("walter@/bowlingalley");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("", jid.Str());
-  EXPECT_EQ("", jid.BareJid().Str());
-  EXPECT_FALSE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestFunky) {
-  Jid jid("bowling@muchat/walter@dude");
-  EXPECT_EQ("bowling", jid.node());
-  EXPECT_EQ("muchat", jid.domain());
-  EXPECT_EQ("walter@dude", jid.resource());
-  EXPECT_EQ("bowling@muchat/walter@dude", jid.Str());
-  EXPECT_EQ("bowling@muchat", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_FALSE(jid.IsBare());
-  EXPECT_TRUE(jid.IsFull());
-}
-
-TEST(JidTest, TestFunky2) {
-  Jid jid("muchat/walter@dude");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("muchat", jid.domain());
-  EXPECT_EQ("walter@dude", jid.resource());
-  EXPECT_EQ("muchat/walter@dude", jid.Str());
-  EXPECT_EQ("muchat", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_FALSE(jid.IsBare());
-  EXPECT_TRUE(jid.IsFull());
-}
diff --git a/third_party/libjingle_xmpp/xmpp/plainsaslhandler.h b/third_party/libjingle_xmpp/xmpp/plainsaslhandler.h
deleted file mode 100644
index f2d1da85..0000000
--- a/third_party/libjingle_xmpp/xmpp/plainsaslhandler.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_PLAINSASLHANDLER_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_PLAINSASLHANDLER_H_
-
-#include <algorithm>
-#include "third_party/libjingle_xmpp/xmpp/saslhandler.h"
-#include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h"
-
-namespace jingle_xmpp {
-
-class PlainSaslHandler : public SaslHandler {
-public:
-  PlainSaslHandler(const Jid & jid, const std::string & password,
-      bool allow_plain) : jid_(jid), password_(password),
-                          allow_plain_(allow_plain) {}
-
-  virtual ~PlainSaslHandler() {}
-
-  // Should pick the best method according to this handler
-  // returns the empty string if none are suitable
-  virtual std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) {
-
-    if (!encrypted && !allow_plain_) {
-      return "";
-    }
-
-    std::vector<std::string>::const_iterator it = std::find(mechanisms.begin(), mechanisms.end(), "PLAIN");
-    if (it == mechanisms.end()) {
-      return "";
-    }
-    else {
-      return "PLAIN";
-    }
-  }
-
-  // Creates a SaslMechanism for the given mechanism name (you own it
-  // once you get it).  If not handled, return NULL.
-  virtual SaslMechanism * CreateSaslMechanism(const std::string & mechanism) {
-    if (mechanism == "PLAIN") {
-      return new SaslPlainMechanism(jid_, password_);
-    }
-    return NULL;
-  }
-
-private:
-  Jid jid_;
-  std::string password_;
-  bool allow_plain_;
-};
-
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_PLAINSASLHANDLER_H_
diff --git a/third_party/libjingle_xmpp/xmpp/prexmppauth.h b/third_party/libjingle_xmpp/xmpp/prexmppauth.h
deleted file mode 100644
index 48ba81c8..0000000
--- a/third_party/libjingle_xmpp/xmpp/prexmppauth.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_PREXMPPAUTH_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_PREXMPPAUTH_H_
-
-#include "third_party/libjingle_xmpp/xmpp/saslhandler.h"
-#include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
-
-namespace jingle_xmpp {
-
-class Jid;
-class SaslMechanism;
-
-class CaptchaChallenge {
- public:
-  CaptchaChallenge() : captcha_needed_(false) {}
-  CaptchaChallenge(const std::string& token, const std::string& url)
-    : captcha_needed_(true), captcha_token_(token), captcha_image_url_(url) {
-  }
-
-  bool captcha_needed() const { return captcha_needed_; }
-  const std::string& captcha_token() const { return captcha_token_; }
-
-  // This url is relative to the gaia server.  Once we have better tools
-  // for cracking URLs, we should probably make this a full URL
-  const std::string& captcha_image_url() const { return captcha_image_url_; }
-
- private:
-  bool captcha_needed_;
-  std::string captcha_token_;
-  std::string captcha_image_url_;
-};
-
-class PreXmppAuth : public SaslHandler {
-public:
-  virtual ~PreXmppAuth() {}
-
-  virtual void StartPreXmppAuth(
-    const Jid& jid,
-    const std::string& pass,
-    const std::string& auth_mechanism,
-    const std::string& auth_token) = 0;
-
-  sigslot::signal0<> SignalAuthDone;
-
-  virtual bool IsAuthDone() const = 0;
-  virtual bool IsAuthorized() const = 0;
-  virtual bool HadError() const = 0;
-  virtual int GetError() const = 0;
-  virtual CaptchaChallenge GetCaptchaChallenge() const = 0;
-  virtual std::string GetAuthMechanism() const = 0;
-  virtual std::string GetAuthToken() const = 0;
-};
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_PREXMPPAUTH_H_
diff --git a/third_party/libjingle_xmpp/xmpp/saslcookiemechanism.h b/third_party/libjingle_xmpp/xmpp/saslcookiemechanism.h
deleted file mode 100644
index ceea47b..0000000
--- a/third_party/libjingle_xmpp/xmpp/saslcookiemechanism.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLCOOKIEMECHANISM_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLCOOKIEMECHANISM_H_
-
-#include "third_party/libjingle_xmpp/xmllite/qname.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#include "third_party/libjingle_xmpp/xmpp/saslmechanism.h"
-
-namespace jingle_xmpp {
-
-class SaslCookieMechanism : public SaslMechanism {
-
-public:
-  SaslCookieMechanism(const std::string & mechanism,
-                      const std::string & username,
-                      const std::string & cookie,
-                      const std::string & token_service)
-    : mechanism_(mechanism),
-      username_(username),
-      cookie_(cookie),
-      token_service_(token_service) {}
-
-  SaslCookieMechanism(const std::string & mechanism,
-                      const std::string & username,
-                      const std::string & cookie)
-    : mechanism_(mechanism),
-      username_(username),
-      cookie_(cookie),
-      token_service_("") {}
-
-  virtual std::string GetMechanismName() { return mechanism_; }
-
-  virtual XmlElement * StartSaslAuth() {
-    // send initial request
-    XmlElement * el = new XmlElement(QN_SASL_AUTH, true);
-    el->AddAttr(QN_MECHANISM, mechanism_);
-    if (!token_service_.empty()) {
-      el->AddAttr(QN_GOOGLE_AUTH_SERVICE, token_service_);
-    }
-
-    std::string credential;
-    credential.append("\0", 1);
-    credential.append(username_);
-    credential.append("\0", 1);
-    credential.append(cookie_);
-    el->AddText(Base64Encode(credential));
-    return el;
-  }
-
-private:
-  std::string mechanism_;
-  std::string username_;
-  std::string cookie_;
-  std::string token_service_;
-};
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLCOOKIEMECHANISM_H_
diff --git a/third_party/libjingle_xmpp/xmpp/saslhandler.h b/third_party/libjingle_xmpp/xmpp/saslhandler.h
deleted file mode 100644
index 7bb26c62..0000000
--- a/third_party/libjingle_xmpp/xmpp/saslhandler.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLHANDLER_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLHANDLER_H_
-
-#include <string>
-#include <vector>
-
-namespace jingle_xmpp {
-
-class XmlElement;
-class SaslMechanism;
-
-// Creates mechanisms to deal with a given mechanism
-class SaslHandler {
-
-public:
-
-  // Intended to be subclassed
-  virtual ~SaslHandler() {}
-
-  // Should pick the best method according to this handler
-  // returns the empty string if none are suitable
-  virtual std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) = 0;
-
-  // Creates a SaslMechanism for the given mechanism name (you own it
-  // once you get it).
-  // If not handled, return NULL.
-  virtual SaslMechanism * CreateSaslMechanism(const std::string & mechanism) = 0;
-};
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLHANDLER_H_
diff --git a/third_party/libjingle_xmpp/xmpp/saslmechanism.cc b/third_party/libjingle_xmpp/xmpp/saslmechanism.cc
deleted file mode 100644
index c848894..0000000
--- a/third_party/libjingle_xmpp/xmpp/saslmechanism.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#include "third_party/libjingle_xmpp/xmpp/saslmechanism.h"
-#include "third_party/webrtc/rtc_base/third_party/base64/base64.h"
-
-using rtc::Base64;
-
-namespace jingle_xmpp {
-
-XmlElement *
-SaslMechanism::StartSaslAuth() {
-  return new XmlElement(QN_SASL_AUTH, true);
-}
-
-XmlElement *
-SaslMechanism::HandleSaslChallenge(const XmlElement * challenge) {
-  return new XmlElement(QN_SASL_ABORT, true);
-}
-
-void
-SaslMechanism::HandleSaslSuccess(const XmlElement * success) {
-}
-
-void
-SaslMechanism::HandleSaslFailure(const XmlElement * failure) {
-}
-
-std::string
-SaslMechanism::Base64Encode(const std::string & plain) {
-  return Base64::Encode(plain);
-}
-
-std::string
-SaslMechanism::Base64Decode(const std::string & encoded) {
-  return Base64::Decode(encoded, Base64::DO_LAX);
-}
-
-std::string
-SaslMechanism::Base64EncodeFromArray(const char * plain, size_t length) {
-  std::string result;
-  Base64::EncodeFromArray(plain, length, &result);
-  return result;
-}
-
-}
diff --git a/third_party/libjingle_xmpp/xmpp/saslmechanism.h b/third_party/libjingle_xmpp/xmpp/saslmechanism.h
deleted file mode 100644
index 484c953f..0000000
--- a/third_party/libjingle_xmpp/xmpp/saslmechanism.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLMECHANISM_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLMECHANISM_H_
-
-#include <string>
-
-namespace jingle_xmpp {
-
-class XmlElement;
-
-
-// Defines a mechnanism to do SASL authentication.
-// Subclass instances should have a self-contained way to present
-// credentials.
-class SaslMechanism {
-
-public:
-
-  // Intended to be subclassed
-  virtual ~SaslMechanism() {}
-
-  // Should return the name of the SASL mechanism, e.g., "PLAIN"
-  virtual std::string GetMechanismName() = 0;
-
-  // Should generate the initial "auth" request.  Default is just <auth/>.
-  virtual XmlElement * StartSaslAuth();
-
-  // Should respond to a SASL "<challenge>" request.  Default is
-  // to abort (for mechanisms that do not do challenge-response)
-  virtual XmlElement * HandleSaslChallenge(const XmlElement * challenge);
-
-  // Notification of a SASL "<success>".  Sometimes information
-  // is passed on success.
-  virtual void HandleSaslSuccess(const XmlElement * success);
-
-  // Notification of a SASL "<failure>".  Sometimes information
-  // for the user is passed on failure.
-  virtual void HandleSaslFailure(const XmlElement * failure);
-
-protected:
-  static std::string Base64Encode(const std::string & plain);
-  static std::string Base64Decode(const std::string & encoded);
-  static std::string Base64EncodeFromArray(const char * plain, size_t length);
-};
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLMECHANISM_H_
diff --git a/third_party/libjingle_xmpp/xmpp/saslplainmechanism.h b/third_party/libjingle_xmpp/xmpp/saslplainmechanism.h
deleted file mode 100644
index 06faa72..0000000
--- a/third_party/libjingle_xmpp/xmpp/saslplainmechanism.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLPLAINMECHANISM_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLPLAINMECHANISM_H_
-
-#include "third_party/libjingle_xmpp/xmpp/saslmechanism.h"
-
-namespace jingle_xmpp {
-
-class SaslPlainMechanism : public SaslMechanism {
-
-public:
-  SaslPlainMechanism(const jingle_xmpp::Jid user_jid, const std::string & password) :
-    user_jid_(user_jid), password_(password) {}
-
-  virtual std::string GetMechanismName() { return "PLAIN"; }
-
-  virtual XmlElement * StartSaslAuth() {
-    // send initial request
-    XmlElement * el = new XmlElement(QN_SASL_AUTH, true);
-    el->AddAttr(QN_MECHANISM, "PLAIN");
-
-    std::stringstream ss;
-    ss.write("\0", 1);
-    ss << user_jid_.node();
-    ss.write("\0", 1);
-    ss << password_;
-    el->AddText(Base64EncodeFromArray(ss.str().data(), ss.str().length()));
-    return el;
-  }
-
-private:
-  Jid user_jid_;
-  std::string password_;
-};
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_SASLPLAINMECHANISM_H_
diff --git a/third_party/libjingle_xmpp/xmpp/util_unittest.cc b/third_party/libjingle_xmpp/xmpp/util_unittest.cc
deleted file mode 100644
index 3e5e504c2..0000000
--- a/third_party/libjingle_xmpp/xmpp/util_unittest.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/util_unittest.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-
-namespace jingle_xmpp {
-
-void XmppTestHandler::WriteOutput(const char * bytes, size_t len) {
-  output_ << std::string(bytes, len);
-}
-
-void XmppTestHandler::StartTls(const std::string & cname) {
-  output_ << "[START-TLS " << cname << "]";
-}
-
-void XmppTestHandler::CloseConnection() {
-  output_ << "[CLOSED]";
-}
-
-void XmppTestHandler::OnStateChange(int state) {
-  switch (static_cast<XmppEngine::State>(state)) {
-  case XmppEngine::STATE_START:
-    session_ << "[START]";
-    break;
-  case XmppEngine::STATE_OPENING:
-    session_ << "[OPENING]";
-    break;
-  case XmppEngine::STATE_OPEN:
-    session_ << "[OPEN]";
-    break;
-  case XmppEngine::STATE_CLOSED:
-    session_ << "[CLOSED]";
-    switch (engine_->GetError(NULL)) {
-    case XmppEngine::ERROR_NONE:
-      // do nothing
-      break;
-    case XmppEngine::ERROR_XML:
-      session_ << "[ERROR-XML]";
-      break;
-    case XmppEngine::ERROR_STREAM:
-      session_ << "[ERROR-STREAM]";
-      break;
-    case XmppEngine::ERROR_VERSION:
-      session_ << "[ERROR-VERSION]";
-      break;
-    case XmppEngine::ERROR_UNAUTHORIZED:
-      session_ << "[ERROR-UNAUTHORIZED]";
-      break;
-    case XmppEngine::ERROR_TLS:
-      session_ << "[ERROR-TLS]";
-      break;
-    case XmppEngine::ERROR_AUTH:
-      session_ << "[ERROR-AUTH]";
-      break;
-    case XmppEngine::ERROR_BIND:
-      session_ << "[ERROR-BIND]";
-      break;
-    case XmppEngine::ERROR_CONNECTION_CLOSED:
-      session_ << "[ERROR-CONNECTION-CLOSED]";
-      break;
-    case XmppEngine::ERROR_DOCUMENT_CLOSED:
-      session_ << "[ERROR-DOCUMENT-CLOSED]";
-      break;
-    default:
-      break;
-    }
-    break;
-  default:
-    break;
-  }
-}
-
-bool XmppTestHandler::HandleStanza(const XmlElement * stanza) {
-  stanza_ << stanza->Str();
-  return true;
-}
-
-std::string XmppTestHandler::OutputActivity() {
-  std::string result = output_.str();
-  output_.str("");
-  return result;
-}
-
-std::string XmppTestHandler::SessionActivity() {
-  std::string result = session_.str();
-  session_.str("");
-  return result;
-}
-
-std::string XmppTestHandler::StanzaActivity() {
-  std::string result = stanza_.str();
-  stanza_.str("");
-  return result;
-}
-
-}  // namespace jingle_xmpp
diff --git a/third_party/libjingle_xmpp/xmpp/util_unittest.h b/third_party/libjingle_xmpp/xmpp/util_unittest.h
deleted file mode 100644
index 8087e85..0000000
--- a/third_party/libjingle_xmpp/xmpp/util_unittest.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_UTIL_UNITTEST_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_UTIL_UNITTEST_H_
-
-#include <sstream>
-#include <string>
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-
-namespace jingle_xmpp {
-
-// This class captures callbacks from engine.
-class XmppTestHandler : public XmppOutputHandler,  public XmppSessionHandler,
-                        public XmppStanzaHandler {
- public:
-  explicit XmppTestHandler(XmppEngine* engine) : engine_(engine) {}
-  virtual ~XmppTestHandler() {}
-
-  void SetEngine(XmppEngine* engine);
-
-  // Output handler
-  virtual void WriteOutput(const char * bytes, size_t len);
-  virtual void StartTls(const std::string & cname);
-  virtual void CloseConnection();
-
-  // Session handler
-  virtual void OnStateChange(int state);
-
-  // Stanza handler
-  virtual bool HandleStanza(const XmlElement* stanza);
-
-  std::string OutputActivity();
-  std::string SessionActivity();
-  std::string StanzaActivity();
-
- private:
-  XmppEngine* engine_;
-  std::stringstream output_;
-  std::stringstream session_;
-  std::stringstream stanza_;
-};
-
-}  // namespace jingle_xmpp
-
-inline std::ostream& operator<<(std::ostream& os, const jingle_xmpp::Jid& jid) {
-  os << jid.Str();
-  return os;
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_UTIL_UNITTEST_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppclient.cc b/third_party/libjingle_xmpp/xmpp/xmppclient.cc
deleted file mode 100644
index de92055..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppclient.cc
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/xmpp/xmppclient.h"
-
-#include "base/logging.h"
-#include "net/base/host_port_pair.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#include "third_party/libjingle_xmpp/xmpp/plainsaslhandler.h"
-#include "third_party/libjingle_xmpp/xmpp/prexmppauth.h"
-#include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h"
-#include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
-#include "xmpptask.h"
-
-namespace jingle_xmpp {
-
-class XmppClient::Private :
-    public sigslot::has_slots<>,
-    public XmppSessionHandler,
-    public XmppOutputHandler {
-public:
-
-  explicit Private(XmppClient* client) :
-    client_(client),
-    socket_(),
-    engine_(),
-    pre_engine_error_(XmppEngine::ERROR_NONE),
-    pre_engine_subcode_(0),
-    signal_closed_(false),
-    allow_plain_(false) {}
-
-  virtual ~Private() {
-    // We need to disconnect from socket_ before engine_ is destructed (by
-    // the auto-generated destructor code).
-    ResetSocket();
-  }
-
-  // the owner
-  XmppClient* const client_;
-
-  // the two main objects
-  std::unique_ptr<AsyncSocket> socket_;
-  std::unique_ptr<XmppEngine> engine_;
-  std::unique_ptr<PreXmppAuth> pre_auth_;
-  std::string pass_;
-  std::string auth_mechanism_;
-  std::string auth_token_;
-  net::HostPortPair server_;
-  XmppEngine::Error pre_engine_error_;
-  int pre_engine_subcode_;
-  CaptchaChallenge captcha_challenge_;
-  bool signal_closed_;
-  bool allow_plain_;
-
-  void ResetSocket() {
-    if (socket_) {
-      socket_->SignalConnected.disconnect(this);
-      socket_->SignalRead.disconnect(this);
-      socket_->SignalClosed.disconnect(this);
-      socket_.reset(NULL);
-    }
-  }
-
-  // implementations of interfaces
-  void OnStateChange(int state);
-  void WriteOutput(const char* bytes, size_t len);
-  void StartTls(const std::string& domainname);
-  void CloseConnection();
-
-  // slots for socket signals
-  void OnSocketConnected();
-  void OnSocketRead();
-  void OnSocketClosed();
-};
-
-XmppReturnStatus XmppClient::Connect(
-    const XmppClientSettings& settings,
-    const std::string& lang, AsyncSocket* socket, PreXmppAuth* pre_auth) {
-  if (socket == NULL)
-    return XMPP_RETURN_BADARGUMENT;
-  if (d_->socket_)
-    return XMPP_RETURN_BADSTATE;
-
-  d_->socket_.reset(socket);
-
-  d_->socket_->SignalConnected.connect(d_.get(), &Private::OnSocketConnected);
-  d_->socket_->SignalRead.connect(d_.get(), &Private::OnSocketRead);
-  d_->socket_->SignalClosed.connect(d_.get(), &Private::OnSocketClosed);
-
-  d_->engine_.reset(XmppEngine::Create());
-  d_->engine_->SetSessionHandler(d_.get());
-  d_->engine_->SetOutputHandler(d_.get());
-  if (!settings.resource().empty()) {
-    d_->engine_->SetRequestedResource(settings.resource());
-  }
-  d_->engine_->SetTls(settings.use_tls());
-
-  // The talk.google.com server returns a certificate with common-name:
-  //   CN="gmail.com" for @gmail.com accounts,
-  //   CN="googlemail.com" for @googlemail.com accounts,
-  //   CN="talk.google.com" for other accounts (such as @example.com),
-  // so we tweak the tls server setting for those other accounts to match the
-  // returned certificate CN of "talk.google.com".
-  // For other servers, we leave the strings empty, which causes the jid's
-  // domain to be used.  We do the same for gmail.com and googlemail.com as the
-  // returned CN matches the account domain in those cases.
-  std::string server_name = settings.server().host();
-  if (server_name == jingle_xmpp::STR_TALK_GOOGLE_COM ||
-      server_name == jingle_xmpp::STR_TALKX_L_GOOGLE_COM ||
-      server_name == jingle_xmpp::STR_XMPP_GOOGLE_COM ||
-      server_name == jingle_xmpp::STR_XMPPX_L_GOOGLE_COM) {
-    if (settings.host() != STR_GMAIL_COM &&
-        settings.host() != STR_GOOGLEMAIL_COM) {
-      d_->engine_->SetTlsServer("", STR_TALK_GOOGLE_COM);
-    }
-  }
-
-  // Set language
-  d_->engine_->SetLanguage(lang);
-
-  d_->engine_->SetUser(jingle_xmpp::Jid(settings.user(), settings.host(), STR_EMPTY));
-
-  d_->pass_ = settings.pass();
-  d_->auth_mechanism_ = settings.auth_mechanism();
-  d_->auth_token_ = settings.auth_token();
-  d_->server_ = settings.server();
-  d_->allow_plain_ = settings.allow_plain();
-  d_->pre_auth_.reset(pre_auth);
-
-  return XMPP_RETURN_OK;
-}
-
-XmppEngine::State XmppClient::GetState() const {
-  if (!d_->engine_)
-    return XmppEngine::STATE_NONE;
-  return d_->engine_->GetState();
-}
-
-XmppEngine::Error XmppClient::GetError(int* subcode) {
-  if (subcode) {
-    *subcode = 0;
-  }
-  if (!d_->engine_)
-    return XmppEngine::ERROR_NONE;
-  if (d_->pre_engine_error_ != XmppEngine::ERROR_NONE) {
-    if (subcode) {
-      *subcode = d_->pre_engine_subcode_;
-    }
-    return d_->pre_engine_error_;
-  }
-  return d_->engine_->GetError(subcode);
-}
-
-const XmlElement* XmppClient::GetStreamError() {
-  if (!d_->engine_) {
-    return NULL;
-  }
-  return d_->engine_->GetStreamError();
-}
-
-CaptchaChallenge XmppClient::GetCaptchaChallenge() {
-  if (!d_->engine_)
-    return CaptchaChallenge();
-  return d_->captcha_challenge_;
-}
-
-std::string XmppClient::GetAuthMechanism() {
-  if (!d_->engine_)
-    return "";
-  return d_->auth_mechanism_;
-}
-
-std::string XmppClient::GetAuthToken() {
-  if (!d_->engine_)
-    return "";
-  return d_->auth_token_;
-}
-
-int XmppClient::ProcessStart() {
-  // Should not happen, but was observed in crash reports
-  if (!d_->socket_) {
-    DVLOG(1) << "socket_ already reset";
-    return STATE_DONE;
-  }
-
-  if (d_->pre_auth_) {
-    d_->pre_auth_->SignalAuthDone.connect(this, &XmppClient::OnAuthDone);
-    d_->pre_auth_->StartPreXmppAuth(
-        d_->engine_->GetUser(), d_->pass_,
-        d_->auth_mechanism_, d_->auth_token_);
-    d_->pass_.clear(); // done with this;
-    return STATE_PRE_XMPP_LOGIN;
-  }
-  else {
-    d_->engine_->SetSaslHandler(new PlainSaslHandler(
-              d_->engine_->GetUser(), d_->pass_, d_->allow_plain_));
-    d_->pass_.clear(); // done with this;
-    return STATE_START_XMPP_LOGIN;
-  }
-}
-
-void XmppClient::OnAuthDone() {
-  Wake();
-}
-
-int XmppClient::ProcessTokenLogin() {
-  // Should not happen, but was observed in crash reports
-  if (!d_->socket_) {
-    DVLOG(1) << "socket_ already reset";
-    return STATE_DONE;
-  }
-
-  // Don't know how this could happen, but crash reports show it as NULL
-  if (!d_->pre_auth_) {
-    d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
-    EnsureClosed();
-    return STATE_ERROR;
-  }
-
-  // Wait until pre authentication is done is done
-  if (!d_->pre_auth_->IsAuthDone())
-    return STATE_BLOCKED;
-
-  if (!d_->pre_auth_->IsAuthorized()) {
-    // maybe split out a case when gaia is down?
-    if (d_->pre_auth_->HadError()) {
-      d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
-      d_->pre_engine_subcode_ = d_->pre_auth_->GetError();
-    }
-    else {
-      d_->pre_engine_error_ = XmppEngine::ERROR_UNAUTHORIZED;
-      d_->pre_engine_subcode_ = 0;
-      d_->captcha_challenge_ = d_->pre_auth_->GetCaptchaChallenge();
-    }
-    d_->pre_auth_.reset(NULL); // done with this
-    EnsureClosed();
-    return STATE_ERROR;
-  }
-
-  // Save auth token as a result
-
-  d_->auth_mechanism_ = d_->pre_auth_->GetAuthMechanism();
-  d_->auth_token_ = d_->pre_auth_->GetAuthToken();
-
-  // transfer ownership of pre_auth_ to engine
-  d_->engine_->SetSaslHandler(d_->pre_auth_.release());
-  return STATE_START_XMPP_LOGIN;
-}
-
-int XmppClient::ProcessStartXmppLogin() {
-  // Should not happen, but was observed in crash reports
-  if (!d_->socket_) {
-    DVLOG(1) << "socket_ already reset";
-    return STATE_DONE;
-  }
-
-  // Done with pre-connect tasks - connect!
-  if (!d_->socket_->Connect(d_->server_)) {
-    EnsureClosed();
-    return STATE_ERROR;
-  }
-
-  return STATE_RESPONSE;
-}
-
-int XmppClient::ProcessResponse() {
-  // Hang around while we are connected.
-  if (!delivering_signal_ &&
-      (!d_->engine_ || d_->engine_->GetState() == XmppEngine::STATE_CLOSED))
-    return STATE_DONE;
-  return STATE_BLOCKED;
-}
-
-XmppReturnStatus XmppClient::Disconnect() {
-  if (!d_->socket_)
-    return XMPP_RETURN_BADSTATE;
-  Abort();
-  d_->engine_->Disconnect();
-  d_->ResetSocket();
-  return XMPP_RETURN_OK;
-}
-
-XmppClient::XmppClient(TaskParent* parent)
-    : XmppTaskParentInterface(parent),
-      delivering_signal_(false),
-      valid_(false) {
-  d_.reset(new Private(this));
-  valid_ = true;
-}
-
-XmppClient::~XmppClient() {
-  valid_ = false;
-}
-
-const Jid& XmppClient::jid() const {
-  return d_->engine_->FullJid();
-}
-
-
-std::string XmppClient::NextId() {
-  return d_->engine_->NextId();
-}
-
-XmppReturnStatus XmppClient::SendStanza(const XmlElement* stanza) {
-  return d_->engine_->SendStanza(stanza);
-}
-
-XmppReturnStatus XmppClient::SendStanzaError(
-    const XmlElement* old_stanza, XmppStanzaError xse,
-    const std::string& message) {
-  return d_->engine_->SendStanzaError(old_stanza, xse, message);
-}
-
-XmppReturnStatus XmppClient::SendRaw(const std::string& text) {
-  return d_->engine_->SendRaw(text);
-}
-
-XmppEngine* XmppClient::engine() {
-  return d_->engine_.get();
-}
-
-void XmppClient::Private::OnSocketConnected() {
-  engine_->Connect();
-}
-
-void XmppClient::Private::OnSocketRead() {
-  char bytes[4096];
-  size_t bytes_read;
-  for (;;) {
-    // Should not happen, but was observed in crash reports
-    if (!socket_) {
-      DVLOG(1) << "socket_ already reset";
-      return;
-    }
-
-    if (!socket_->Read(bytes, sizeof(bytes), &bytes_read)) {
-      // TODO: deal with error information
-      return;
-    }
-
-    if (bytes_read == 0)
-      return;
-
-//#if !defined(NDEBUG)
-    client_->SignalLogInput(bytes, static_cast<int>(bytes_read));
-//#endif
-
-    engine_->HandleInput(bytes, bytes_read);
-  }
-}
-
-void XmppClient::Private::OnSocketClosed() {
-  int code = socket_->GetError();
-  engine_->ConnectionClosed(code);
-}
-
-void XmppClient::Private::OnStateChange(int state) {
-  if (state == XmppEngine::STATE_CLOSED) {
-    client_->EnsureClosed();
-  }
-  else {
-    client_->SignalStateChange((XmppEngine::State)state);
-  }
-  client_->Wake();
-}
-
-void XmppClient::Private::WriteOutput(const char* bytes, size_t len) {
-//#if !defined(NDEBUG)
-  client_->SignalLogOutput(bytes, static_cast<int>(len));
-//#endif
-
-  socket_->Write(bytes, len);
-  // TODO: deal with error information
-}
-
-void XmppClient::Private::StartTls(const std::string& domain) {
-  socket_->StartTls(domain);
-}
-
-void XmppClient::Private::CloseConnection() {
-  socket_->Close();
-}
-
-void XmppClient::AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) {
-  d_->engine_->AddStanzaHandler(task, level);
-}
-
-void XmppClient::RemoveXmppTask(XmppTask* task) {
-  d_->engine_->RemoveStanzaHandler(task);
-}
-
-void XmppClient::EnsureClosed() {
-  if (!d_->signal_closed_) {
-    d_->signal_closed_ = true;
-    delivering_signal_ = true;
-    SignalStateChange(XmppEngine::STATE_CLOSED);
-    delivering_signal_ = false;
-  }
-}
-
-}  // namespace jingle_xmpp
diff --git a/third_party/libjingle_xmpp/xmpp/xmppclient.h b/third_party/libjingle_xmpp/xmpp/xmppclient.h
deleted file mode 100644
index da3e89d..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppclient.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPCLIENT_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPCLIENT_H_
-
-#include <memory>
-#include <string>
-
-#include "third_party/libjingle_xmpp/task_runner/task.h"
-#include "third_party/libjingle_xmpp/xmpp/asyncsocket.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-#include "third_party/libjingle_xmpp/xmpp/xmpptask.h"
-#include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
-
-namespace jingle_xmpp {
-
-class PreXmppAuth;
-class CaptchaChallenge;
-
-// Just some non-colliding number.  Could have picked "1".
-#define XMPP_CLIENT_TASK_CODE 0x366c1e47
-
-/////////////////////////////////////////////////////////////////////
-//
-// XMPPCLIENT
-//
-/////////////////////////////////////////////////////////////////////
-//
-// See Task first.  XmppClient is a parent task for XmppTasks.
-//
-// XmppClient is a task which is designed to be the parent task for
-// all tasks that depend on a single Xmpp connection.  If you want to,
-// for example, listen for subscription requests forever, then your
-// listener should be a task that is a child of the XmppClient that owns
-// the connection you are using.  XmppClient has all the utility methods
-// that basically drill through to XmppEngine.
-//
-// XmppClient is just a wrapper for XmppEngine, and if I were writing it
-// all over again, I would make XmppClient == XmppEngine.  Why?
-// XmppEngine needs tasks too, for example it has an XmppLoginTask which
-// should just be the same kind of Task instead of an XmppEngine specific
-// thing.  It would help do certain things like GAIA auth cleaner.
-//
-/////////////////////////////////////////////////////////////////////
-
-class XmppClient : public XmppTaskParentInterface,
-                   public XmppClientInterface,
-                   public sigslot::has_slots<>
-{
-public:
-  explicit XmppClient(jingle_xmpp::TaskParent * parent);
-  virtual ~XmppClient();
-
-  XmppReturnStatus Connect(const XmppClientSettings & settings,
-                           const std::string & lang,
-                           AsyncSocket * socket,
-                           PreXmppAuth * preauth);
-
-  virtual int ProcessStart();
-  virtual int ProcessResponse();
-  XmppReturnStatus Disconnect();
-
-  sigslot::signal1<XmppEngine::State> SignalStateChange;
-  XmppEngine::Error GetError(int *subcode);
-
-  // When there is a <stream:error> stanza, return the stanza
-  // so that they can be handled.
-  const XmlElement *GetStreamError();
-
-  // When there is an authentication error, we may have captcha info
-  // that the user can use to unlock their account
-  CaptchaChallenge GetCaptchaChallenge();
-
-  // When authentication is successful, this returns the service token
-  // (if we used GAIA authentication)
-  std::string GetAuthMechanism();
-  std::string GetAuthToken();
-
-  XmppReturnStatus SendRaw(const std::string & text);
-
-  XmppEngine* engine();
-
-  sigslot::signal2<const char *, int> SignalLogInput;
-  sigslot::signal2<const char *, int> SignalLogOutput;
-
-  // As XmppTaskParentIntreface
-  virtual XmppClientInterface* GetClient() { return this; }
-
-  // As XmppClientInterface
-  virtual XmppEngine::State GetState() const;
-  virtual const Jid& jid() const;
-  virtual std::string NextId();
-  virtual XmppReturnStatus SendStanza(const XmlElement *stanza);
-  virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
-                                           XmppStanzaError code,
-                                           const std::string & text);
-  virtual void AddXmppTask(XmppTask *, XmppEngine::HandlerLevel);
-  virtual void RemoveXmppTask(XmppTask *);
-
- private:
-  friend class XmppTask;
-
-  void OnAuthDone();
-
-  // Internal state management
-  enum {
-    STATE_PRE_XMPP_LOGIN = STATE_NEXT,
-    STATE_START_XMPP_LOGIN = STATE_NEXT + 1,
-  };
-  int Process(int state) {
-    switch (state) {
-      case STATE_PRE_XMPP_LOGIN: return ProcessTokenLogin();
-      case STATE_START_XMPP_LOGIN: return ProcessStartXmppLogin();
-      default: return Task::Process(state);
-    }
-  }
-
-  std::string GetStateName(int state) const {
-    switch (state) {
-      case STATE_PRE_XMPP_LOGIN:      return "PRE_XMPP_LOGIN";
-      case STATE_START_XMPP_LOGIN:  return "START_XMPP_LOGIN";
-      default: return Task::GetStateName(state);
-    }
-  }
-
-  int ProcessTokenLogin();
-  int ProcessStartXmppLogin();
-  void EnsureClosed();
-
-  class Private;
-  friend class Private;
-  std::unique_ptr<Private> d_;
-
-  bool delivering_signal_;
-  bool valid_;
-};
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPCLIENT_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppclientsettings.h b/third_party/libjingle_xmpp/xmpp/xmppclientsettings.h
deleted file mode 100644
index 05000c3..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppclientsettings.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPCLIENTSETTINGS_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPCLIENTSETTINGS_H_
-
-#include "net/base/host_port_pair.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-
-namespace jingle_xmpp {
-
-enum ProtocolType {
-  PROTO_TCP = 1,
-  PROTO_SSLTCP = 2,  // Pseudo-TLS.
-};
-
-class XmppUserSettings {
- public:
-  XmppUserSettings()
-    : use_tls_(jingle_xmpp::TLS_DISABLED),
-      allow_plain_(false) {
-  }
-
-  void set_user(const std::string& user) { user_ = user; }
-  void set_host(const std::string& host) { host_ = host; }
-  void set_pass(const std::string& pass) { pass_ = pass; }
-  void set_auth_token(const std::string& mechanism,
-                      const std::string& token) {
-    auth_mechanism_ = mechanism;
-    auth_token_ = token;
-  }
-  void set_resource(const std::string& resource) { resource_ = resource; }
-  void set_use_tls(const TlsOptions use_tls) { use_tls_ = use_tls; }
-  void set_allow_plain(bool f) { allow_plain_ = f; }
-  void set_token_service(const std::string& token_service) {
-    token_service_ = token_service;
-  }
-
-  const std::string& user() const { return user_; }
-  const std::string& host() const { return host_; }
-  const std::string& pass() const { return pass_; }
-  const std::string& auth_mechanism() const { return auth_mechanism_; }
-  const std::string& auth_token() const { return auth_token_; }
-  const std::string& resource() const { return resource_; }
-  TlsOptions use_tls() const { return use_tls_; }
-  bool allow_plain() const { return allow_plain_; }
-  const std::string& token_service() const { return token_service_; }
-
- private:
-  std::string user_;
-  std::string host_;
-  std::string pass_;
-  std::string auth_mechanism_;
-  std::string auth_token_;
-  std::string resource_;
-  TlsOptions use_tls_;
-  bool allow_plain_;
-  std::string token_service_;
-};
-
-class XmppClientSettings : public XmppUserSettings {
- public:
-  XmppClientSettings() : protocol_(PROTO_TCP) {}
-
-  void set_server(const net::HostPortPair& server) { server_ = server; }
-  void set_protocol(ProtocolType protocol) { protocol_ = protocol; }
-
-  const net::HostPortPair& server() const { return server_; }
-  ProtocolType protocol() const { return protocol_; }
-
- private:
-  net::HostPortPair server_;
-  ProtocolType protocol_;
-};
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPCLIENT_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengine.h b/third_party/libjingle_xmpp/xmpp/xmppengine.h
deleted file mode 100644
index 7a1b21bc..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppengine.h
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPENGINE_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPENGINE_H_
-
-// also part of the API
-#include "third_party/libjingle_xmpp/xmllite/qname.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/jid.h"
-
-
-namespace jingle_xmpp {
-
-class XmppEngine;
-class SaslHandler;
-typedef void * XmppIqCookie;
-
-//! XMPP stanza error codes.
-//! Used in XmppEngine.SendStanzaError().
-enum XmppStanzaError {
-  XSE_BAD_REQUEST,
-  XSE_CONFLICT,
-  XSE_FEATURE_NOT_IMPLEMENTED,
-  XSE_FORBIDDEN,
-  XSE_GONE,
-  XSE_INTERNAL_SERVER_ERROR,
-  XSE_ITEM_NOT_FOUND,
-  XSE_JID_MALFORMED,
-  XSE_NOT_ACCEPTABLE,
-  XSE_NOT_ALLOWED,
-  XSE_PAYMENT_REQUIRED,
-  XSE_RECIPIENT_UNAVAILABLE,
-  XSE_REDIRECT,
-  XSE_REGISTRATION_REQUIRED,
-  XSE_SERVER_NOT_FOUND,
-  XSE_SERVER_TIMEOUT,
-  XSE_RESOURCE_CONSTRAINT,
-  XSE_SERVICE_UNAVAILABLE,
-  XSE_SUBSCRIPTION_REQUIRED,
-  XSE_UNDEFINED_CONDITION,
-  XSE_UNEXPECTED_REQUEST,
-};
-
-// XmppReturnStatus
-//    This is used by API functions to synchronously return status.
-enum XmppReturnStatus {
-  XMPP_RETURN_OK,
-  XMPP_RETURN_BADARGUMENT,
-  XMPP_RETURN_BADSTATE,
-  XMPP_RETURN_PENDING,
-  XMPP_RETURN_UNEXPECTED,
-  XMPP_RETURN_NOTYETIMPLEMENTED,
-};
-
-// TlsOptions
-//    This is used by API to identify TLS setting.
-enum TlsOptions {
-  TLS_DISABLED,
-  TLS_ENABLED,
-  TLS_REQUIRED
-};
-
-//! Callback for socket output for an XmppEngine connection.
-//! Register via XmppEngine.SetOutputHandler.  An XmppEngine
-//! can call back to this handler while it is processing
-//! Connect, SendStanza, SendIq, Disconnect, or HandleInput.
-class XmppOutputHandler {
-public:
-  virtual ~XmppOutputHandler() {}
-
-  //! Deliver the specified bytes to the XMPP socket.
-  virtual void WriteOutput(const char * bytes, size_t len) = 0;
-
-  //! Initiate TLS encryption on the socket.
-  //! The implementation must verify that the SSL
-  //! certificate matches the given domainname.
-  virtual void StartTls(const std::string & domainname) = 0;
-
-  //! Called when engine wants the connecton closed.
-  virtual void CloseConnection() = 0;
-};
-
-//! Callback to deliver engine state change notifications
-//! to the object managing the engine.
-class XmppSessionHandler {
-public:
-  virtual ~XmppSessionHandler() {}
-  //! Called when engine changes state. Argument is new state.
-  virtual void OnStateChange(int state) = 0;
-};
-
-//! Callback to deliver stanzas to an Xmpp application module.
-//! Register via XmppEngine.SetDefaultSessionHandler or via
-//! XmppEngine.AddSessionHAndler.
-class XmppStanzaHandler {
-public:
-  virtual ~XmppStanzaHandler() {}
-  //! Process the given stanza.
-  //! The handler must return true if it has handled the stanza.
-  //! A false return value causes the stanza to be passed on to
-  //! the next registered handler.
-  virtual bool HandleStanza(const XmlElement * stanza) = 0;
-};
-
-//! Callback to deliver iq responses (results and errors).
-//! Register while sending an iq via XmppEngine.SendIq.
-//! Iq responses are routed to matching XmppIqHandlers in preference
-//! to sending to any registered SessionHandlers.
-class XmppIqHandler {
-public:
-  virtual ~XmppIqHandler() {}
-  //! Called to handle the iq response.
-  //! The response may be either a result or an error, and will have
-  //! an 'id' that matches the request and a 'from' that matches the
-  //! 'to' of the request.  Called no more than once; once this is
-  //! called, the handler is automatically unregistered.
-  virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) = 0;
-};
-
-//! The XMPP connection engine.
-//! This engine implements the client side of the 'core' XMPP protocol.
-//! To use it, register an XmppOutputHandler to handle socket output
-//! and pass socket input to HandleInput.  Then application code can
-//! set up the connection with a user, password, and other settings,
-//! and then call Connect() to initiate the connection.
-//! An application can listen for events and receive stanzas by
-//! registering an XmppStanzaHandler via AddStanzaHandler().
-class XmppEngine {
-public:
-  static XmppEngine * Create();
-  virtual ~XmppEngine() {}
-
-  //! Error codes. See GetError().
-  enum Error {
-    ERROR_NONE = 0,         //!< No error
-    ERROR_XML,              //!< Malformed XML or encoding error
-    ERROR_STREAM,           //!< XMPP stream error - see GetStreamError()
-    ERROR_VERSION,          //!< XMPP version error
-    ERROR_UNAUTHORIZED,     //!< User is not authorized (rejected credentials)
-    ERROR_TLS,              //!< TLS could not be negotiated
-    ERROR_AUTH,             //!< Authentication could not be negotiated
-    ERROR_BIND,             //!< Resource or session binding could not be negotiated
-    ERROR_CONNECTION_CLOSED,//!< Connection closed by output handler.
-    ERROR_DOCUMENT_CLOSED,  //!< Closed by </stream:stream>
-    ERROR_SOCKET,           //!< Socket error
-    ERROR_NETWORK_TIMEOUT,  //!< Some sort of timeout (eg., we never got the roster)
-    ERROR_MISSING_USERNAME  //!< User has a Google Account but no nickname
-  };
-
-  //! States.  See GetState().
-  enum State {
-    STATE_NONE = 0,        //!< Nonexistent state
-    STATE_START,           //!< Initial state.
-    STATE_OPENING,         //!< Exchanging stream headers, authenticating and so on.
-    STATE_OPEN,            //!< Authenticated and bound.
-    STATE_CLOSED,          //!< Session closed, possibly due to error.
-  };
-
-  // SOCKET INPUT AND OUTPUT ------------------------------------------------
-
-  //! Registers the handler for socket output
-  virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh) = 0;
-
-  //! Provides socket input to the engine
-  virtual XmppReturnStatus HandleInput(const char * bytes, size_t len) = 0;
-
-  //! Advises the engine that the socket has closed
-  virtual XmppReturnStatus ConnectionClosed(int subcode) = 0;
-
-  // SESSION SETUP ---------------------------------------------------------
-
-  //! Indicates the (bare) JID for the user to use.
-  virtual XmppReturnStatus SetUser(const Jid & jid)= 0;
-
-  //! Get the login (bare) JID.
-  virtual const Jid & GetUser() = 0;
-
-  //! Provides different methods for credentials for login.
-  //! Takes ownership of this object; deletes when login is done
-  virtual XmppReturnStatus SetSaslHandler(SaslHandler * h) = 0;
-
-  //! Sets whether TLS will be used within the connection (default true).
-  virtual XmppReturnStatus SetTls(TlsOptions useTls) = 0;
-
-  //! Sets an alternate domain from which we allows TLS certificates.
-  //! This is for use in the case where a we want to allow a proxy to
-  //! serve up its own certificate rather than one owned by the underlying
-  //! domain.
-  virtual XmppReturnStatus SetTlsServer(const std::string & proxy_hostname,
-                                        const std::string & proxy_domain) = 0;
-
-  //! Gets whether TLS will be used within the connection.
-  virtual TlsOptions GetTls() = 0;
-
-  //! Sets the request resource name, if any (optional).
-  //! Note that the resource name may be overridden by the server; after
-  //! binding, the actual resource name is available as part of FullJid().
-  virtual XmppReturnStatus SetRequestedResource(const std::string& resource) = 0;
-
-  //! Gets the request resource name.
-  virtual const std::string & GetRequestedResource() = 0;
-
-  //! Sets language
-  virtual void SetLanguage(const std::string & lang) = 0;
-
-  // SESSION MANAGEMENT ---------------------------------------------------
-
-  //! Set callback for state changes.
-  virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler) = 0;
-
-  //! Initiates the XMPP connection.
-  //! After supplying connection settings, call this once to initiate,
-  //! (optionally) encrypt, authenticate, and bind the connection.
-  virtual XmppReturnStatus Connect() = 0;
-
-  //! The current engine state.
-  virtual State GetState() = 0;
-
-  //! Returns true if the connection is encrypted (under TLS)
-  virtual bool IsEncrypted() = 0;
-
-  //! The error code.
-  //! Consult this after XmppOutputHandler.OnClose().
-  virtual Error GetError(int *subcode) = 0;
-
-  //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
-  //! Notice the stanza returned is owned by the XmppEngine and
-  //! is deleted when the engine is destroyed.
-  virtual const XmlElement * GetStreamError() = 0;
-
-  //! Closes down the connection.
-  //! Sends CloseConnection to output, and disconnects and registered
-  //! session handlers.  After Disconnect completes, it is guaranteed
-  //! that no further callbacks will be made.
-  virtual XmppReturnStatus Disconnect() = 0;
-
-  // APPLICATION USE -------------------------------------------------------
-
-  enum HandlerLevel {
-    HL_NONE = 0,
-    HL_PEEK,   //!< Sees messages before all other processing; cannot abort
-    HL_SINGLE, //!< Watches for a single message, e.g., by id and sender
-    HL_SENDER, //!< Watches for a type of message from a specific sender
-    HL_TYPE,   //!< Watches a type of message, e.g., all groupchat msgs
-    HL_ALL,    //!< Watches all messages - gets last shot
-    HL_COUNT,  //!< Count of handler levels
-  };
-
-  //! Adds a listener for session events.
-  //! Stanza delivery is chained to session handlers; the first to
-  //! return 'true' is the last to get each stanza.
-  virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler, HandlerLevel level = HL_PEEK) = 0;
-
-  //! Removes a listener for session events.
-  virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler) = 0;
-
-  //! Sends a stanza to the server.
-  virtual XmppReturnStatus SendStanza(const XmlElement * pelStanza) = 0;
-
-  //! Sends raw text to the server
-  virtual XmppReturnStatus SendRaw(const std::string & text) = 0;
-
-  //! Sends an iq to the server, and registers a callback for the result.
-  //! Returns the cookie passed to the result handler.
-  virtual XmppReturnStatus SendIq(const XmlElement* pelStanza,
-                                  XmppIqHandler* iq_handler,
-                                  XmppIqCookie* cookie) = 0;
-
-  //! Unregisters an iq callback handler given its cookie.
-  //! No callback will come to this handler after it's unregistered.
-  virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie,
-                                      XmppIqHandler** iq_handler) = 0;
-
-
-  //! Forms and sends an error in response to the given stanza.
-  //! Swaps to and from, sets type to "error", and adds error information
-  //! based on the passed code.  Text is optional and may be STR_EMPTY.
-  virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
-                                           XmppStanzaError code,
-                                           const std::string & text) = 0;
-
-  //! The fullly bound JID.
-  //! This JID is only valid after binding has succeeded.  If the value
-  //! is JID_NULL, the binding has not succeeded.
-  virtual const Jid & FullJid() = 0;
-
-  //! The next unused iq id for this connection.
-  //! Call this when building iq stanzas, to ensure that each iq
-  //! gets its own unique id.
-  virtual std::string NextId() = 0;
-
-};
-
-}
-
-
-// Move these to a better location
-
-#define XMPP_FAILED(x)                      \
-  ( (x) == jingle_xmpp::XMPP_RETURN_OK ? false : true)   \
-
-
-#define XMPP_SUCCEEDED(x)                   \
-  ( (x) == jingle_xmpp::XMPP_RETURN_OK ? true : false)   \
-
-#define IFR(x)                        \
-  do {                                \
-    xmpp_status = (x);                \
-    if (XMPP_FAILED(xmpp_status)) {   \
-      return xmpp_status;             \
-    }                                 \
-  } while (false)                     \
-
-
-#define IFC(x)                        \
-  do {                                \
-    xmpp_status = (x);                \
-    if (XMPP_FAILED(xmpp_status)) {   \
-      goto Cleanup;                   \
-    }                                 \
-  } while (false)                     \
-
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPENGINE_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc b/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc
deleted file mode 100644
index 7c51854..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <iostream>
-#include <memory>
-#include <sstream>
-#include <string>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#include "third_party/libjingle_xmpp/xmpp/plainsaslhandler.h"
-#include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h"
-#include "third_party/libjingle_xmpp/xmpp/util_unittest.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-
-using jingle_xmpp::Jid;
-using jingle_xmpp::QName;
-using jingle_xmpp::XmlElement;
-using jingle_xmpp::XmppEngine;
-using jingle_xmpp::XmppIqCookie;
-using jingle_xmpp::XmppIqHandler;
-using jingle_xmpp::XmppTestHandler;
-using jingle_xmpp::QN_ID;
-using jingle_xmpp::QN_IQ;
-using jingle_xmpp::QN_TYPE;
-using jingle_xmpp::QN_ROSTER_QUERY;
-using jingle_xmpp::XMPP_RETURN_OK;
-using jingle_xmpp::XMPP_RETURN_BADARGUMENT;
-
-// XmppEngineTestIqHandler
-//    This class grabs the response to an IQ stanza and stores it in a string.
-class XmppEngineTestIqHandler : public XmppIqHandler {
- public:
-  virtual void IqResponse(XmppIqCookie, const XmlElement * stanza) {
-    ss_ << stanza->Str();
-  }
-
-  std::string IqResponseActivity() {
-    std::string result = ss_.str();
-    ss_.str("");
-    return result;
-  }
-
- private:
-  std::stringstream ss_;
-};
-
-class XmppEngineTest : public testing::Test {
- public:
-  XmppEngine* engine() { return engine_.get(); }
-  XmppTestHandler* handler() { return handler_.get(); }
-  virtual void SetUp() {
-    engine_.reset(XmppEngine::Create());
-    handler_.reset(new XmppTestHandler(engine_.get()));
-
-    Jid jid("david@my-server");
-    std::string pass("david");
-    engine_->SetSessionHandler(handler_.get());
-    engine_->SetOutputHandler(handler_.get());
-    engine_->AddStanzaHandler(handler_.get());
-    engine_->SetUser(jid);
-    engine_->SetSaslHandler(
-        new jingle_xmpp::PlainSaslHandler(jid, pass, true));
-  }
-  virtual void TearDown() {
-    handler_.reset();
-    engine_.reset();
-  }
-  void RunLogin();
-
- private:
-  std::unique_ptr<XmppEngine> engine_;
-  std::unique_ptr<XmppTestHandler> handler_;
-};
-
-void XmppEngineTest::RunLogin() {
-  // Connect
-  EXPECT_EQ(XmppEngine::STATE_START, engine()->GetState());
-  engine()->Connect();
-  EXPECT_EQ(XmppEngine::STATE_OPENING, engine()->GetState());
-
-  EXPECT_EQ("[OPENING]", handler_->SessionActivity());
-
-  EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
-           "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-           "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-
-  std::string input =
-    "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
-    "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-    "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  input =
-    "<stream:features>"
-      "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>"
-        "<required/>"
-      "</starttls>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-    "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
-      handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("[START-TLS my-server]"
-           "<stream:stream to=\"my-server\" xml:lang=\"*\" "
-           "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
-           "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<stream:stream id=\"01234567\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  input =
-    "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-    "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" "
-      "auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>",
-      handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
-      "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-      "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<stream:stream id=\"01234567\" version=\"1.0\" "
-      "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-      "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  input = "<stream:features>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
-          "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
-          "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<iq type=\"set\" id=\"0\">"
-           "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>",
-           handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<iq type='result' id='0'>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>"
-          "david@my-server/test</jid></bind></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<iq type=\"set\" id=\"1\">"
-           "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>",
-           handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<iq type='result' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[OPEN]", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-  EXPECT_EQ(Jid("david@my-server/test"), engine()->FullJid());
-}
-
-// TestSuccessfulLogin()
-//    This function simply tests to see if a login works.  This includes
-//    encryption and authentication
-TEST_F(XmppEngineTest, TestSuccessfulLoginAndDisconnect) {
-  RunLogin();
-  engine()->Disconnect();
-  EXPECT_EQ("</stream:stream>[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppEngineTest, TestSuccessfulLoginAndConnectionClosed) {
-  RunLogin();
-  engine()->ConnectionClosed(0);
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-CONNECTION-CLOSED]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-
-// TestNotXmpp()
-//    This tests the error case when connecting to a non XMPP service
-TEST_F(XmppEngineTest, TestNotXmpp) {
-  // Connect
-  engine()->Connect();
-  EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">\r\n", handler()->OutputActivity());
-
-  // Send garbage response (courtesy of apache)
-  std::string input = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[OPENING][CLOSED][ERROR-XML]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-// TestPassthrough()
-//    This tests that arbitrary stanzas can be passed to the server through
-//    the engine.
-TEST_F(XmppEngineTest, TestPassthrough) {
-  // Queue up an app stanza
-  XmlElement application_stanza(QName("test", "app-stanza"));
-  application_stanza.AddText("this-is-a-test");
-  engine()->SendStanza(&application_stanza);
-
-  // Do the whole login handshake
-  RunLogin();
-
-  EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test"
-          "</test:app-stanza>", handler()->OutputActivity());
-
-  // do another stanza
-  XmlElement roster_get(QN_IQ);
-  roster_get.AddAttr(QN_TYPE, "get");
-  roster_get.AddAttr(QN_ID, engine()->NextId());
-  roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
-  engine()->SendStanza(&roster_get);
-  EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>"
-          "</iq>", handler()->OutputActivity());
-
-  // now say the server ends the stream
-  engine()->HandleInput("</stream:stream>", 16);
-  EXPECT_EQ("[CLOSED][ERROR-DOCUMENT-CLOSED]", handler()->SessionActivity());
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-// TestIqCallback()
-//    This tests the routing of Iq stanzas and responses.
-TEST_F(XmppEngineTest, TestIqCallback) {
-  XmppEngineTestIqHandler iq_response;
-  XmppIqCookie cookie;
-
-  // Do the whole login handshake
-  RunLogin();
-
-  // Build an iq request
-  XmlElement roster_get(QN_IQ);
-  roster_get.AddAttr(QN_TYPE, "get");
-  roster_get.AddAttr(QN_ID, engine()->NextId());
-  roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
-  engine()->SendIq(&roster_get, &iq_response, &cookie);
-  EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>"
-          "</iq>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-  EXPECT_EQ("", iq_response.IqResponseActivity());
-
-  // now say the server responds to the iq
-  std::string input = "<iq type='result' id='2'>"
-                      "<query xmlns='jabber:iq:roster'><item>foo</item>"
-                      "</query></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-  EXPECT_EQ("<cli:iq type=\"result\" id=\"2\" xmlns:cli=\"jabber:client\">"
-          "<query xmlns=\"jabber:iq:roster\"><item>foo</item></query>"
-          "</cli:iq>", iq_response.IqResponseActivity());
-
-  EXPECT_EQ(XMPP_RETURN_BADARGUMENT, engine()->RemoveIqHandler(cookie, NULL));
-
-  // Do it again with another id to test cancel
-  roster_get.SetAttr(QN_ID, engine()->NextId());
-  engine()->SendIq(&roster_get, &iq_response, &cookie);
-  EXPECT_EQ("<iq type=\"get\" id=\"3\"><query xmlns=\"jabber:iq:roster\"/>"
-          "</iq>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-  EXPECT_EQ("", iq_response.IqResponseActivity());
-
-  // cancel the handler this time
-  EXPECT_EQ(XMPP_RETURN_OK, engine()->RemoveIqHandler(cookie, NULL));
-
-  // now say the server responds to the iq: the iq handler should not get it.
-  input = "<iq type='result' id='3'><query xmlns='jabber:iq:roster'><item>bar"
-          "</item></query></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<cli:iq type=\"result\" id=\"3\" xmlns:cli=\"jabber:client\">"
-          "<query xmlns=\"jabber:iq:roster\"><item>bar</item></query>"
-          "</cli:iq>", handler()->StanzaActivity());
-  EXPECT_EQ("", iq_response.IqResponseActivity());
-  EXPECT_EQ("", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-}
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc b/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc
deleted file mode 100644
index acd99ef2..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/xmpp/xmppengineimpl.h"
-
-#include <algorithm>
-#include <sstream>
-#include <vector>
-
-#include "base/check.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlprinter.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#include "third_party/libjingle_xmpp/xmpp/saslhandler.h"
-#include "third_party/libjingle_xmpp/xmpp/xmpplogintask.h"
-
-namespace jingle_xmpp {
-
-XmppEngine* XmppEngine::Create() {
-  return new XmppEngineImpl();
-}
-
-
-XmppEngineImpl::XmppEngineImpl()
-    : stanza_parse_handler_(this),
-      stanza_parser_(&stanza_parse_handler_),
-      engine_entered_(0),
-      password_(),
-      requested_resource_(STR_EMPTY),
-      tls_option_(jingle_xmpp::TLS_REQUIRED),
-      login_task_(new XmppLoginTask(this)),
-      next_id_(0),
-      state_(STATE_START),
-      encrypted_(false),
-      error_code_(ERROR_NONE),
-      subcode_(0),
-      stream_error_(),
-      raised_reset_(false),
-      output_handler_(NULL),
-      session_handler_(NULL),
-      iq_entries_(new IqEntryVector()),
-      sasl_handler_(),
-      output_(new std::stringstream()) {
-  for (int i = 0; i < HL_COUNT; i+= 1) {
-    stanza_handlers_[i].reset(new StanzaHandlerVector());
-  }
-
-  // Add XMPP namespaces to XML namespaces stack.
-  xmlns_stack_.AddXmlns("stream", "http://etherx.jabber.org/streams");
-  xmlns_stack_.AddXmlns("", "jabber:client");
-}
-
-XmppEngineImpl::~XmppEngineImpl() {
-  DeleteIqCookies();
-}
-
-XmppReturnStatus XmppEngineImpl::SetOutputHandler(
-    XmppOutputHandler* output_handler) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  output_handler_ = output_handler;
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SetSessionHandler(
-    XmppSessionHandler* session_handler) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  session_handler_ = session_handler;
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::HandleInput(
-    const char* bytes, size_t len) {
-  if (state_ < STATE_OPENING || state_ > STATE_OPEN)
-    return XMPP_RETURN_BADSTATE;
-
-  EnterExit ee(this);
-
-  // TODO: The return value of the xml parser is not checked.
-  stanza_parser_.Parse(bytes, len, false);
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::ConnectionClosed(int subcode) {
-  if (state_ != STATE_CLOSED) {
-    EnterExit ee(this);
-    // If told that connection closed and not already closed,
-    // then connection was unpexectedly dropped.
-    if (subcode) {
-      SignalError(ERROR_SOCKET, subcode);
-    } else {
-      SignalError(ERROR_CONNECTION_CLOSED, 0);  // no subcode
-    }
-  }
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SetTls(TlsOptions use_tls) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-  tls_option_ = use_tls;
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SetTlsServer(
-    const std::string& tls_server_hostname,
-    const std::string& tls_server_domain) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  tls_server_hostname_ = tls_server_hostname;
-  tls_server_domain_= tls_server_domain;
-
-  return XMPP_RETURN_OK;
-}
-
-TlsOptions XmppEngineImpl::GetTls() {
-  return tls_option_;
-}
-
-XmppReturnStatus XmppEngineImpl::SetUser(const Jid& jid) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  user_jid_ = jid;
-
-  return XMPP_RETURN_OK;
-}
-
-const Jid& XmppEngineImpl::GetUser() {
-  return user_jid_;
-}
-
-XmppReturnStatus XmppEngineImpl::SetSaslHandler(SaslHandler* sasl_handler) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  sasl_handler_.reset(sasl_handler);
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SetRequestedResource(
-    const std::string& resource) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  requested_resource_ = resource;
-
-  return XMPP_RETURN_OK;
-}
-
-const std::string& XmppEngineImpl::GetRequestedResource() {
-  return requested_resource_;
-}
-
-XmppReturnStatus XmppEngineImpl::AddStanzaHandler(
-    XmppStanzaHandler* stanza_handler,
-    XmppEngine::HandlerLevel level) {
-  if (state_ == STATE_CLOSED)
-    return XMPP_RETURN_BADSTATE;
-
-  stanza_handlers_[level]->push_back(stanza_handler);
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::RemoveStanzaHandler(
-    XmppStanzaHandler* stanza_handler) {
-  bool found = false;
-
-  for (int level = 0; level < HL_COUNT; level += 1) {
-    StanzaHandlerVector::iterator new_end =
-      std::remove(stanza_handlers_[level]->begin(),
-      stanza_handlers_[level]->end(),
-      stanza_handler);
-
-    if (new_end != stanza_handlers_[level]->end()) {
-      stanza_handlers_[level]->erase(new_end, stanza_handlers_[level]->end());
-      found = true;
-    }
-  }
-
-  if (!found)
-    return XMPP_RETURN_BADARGUMENT;
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::Connect() {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  EnterExit ee(this);
-
-  // get the login task started
-  state_ = STATE_OPENING;
-  if (login_task_) {
-    login_task_->IncomingStanza(NULL, false);
-    if (login_task_->IsDone())
-      login_task_.reset();
-  }
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SendStanza(const XmlElement* element) {
-  if (state_ == STATE_CLOSED)
-    return XMPP_RETURN_BADSTATE;
-
-  EnterExit ee(this);
-
-  if (login_task_) {
-    // still handshaking - then outbound stanzas are queued
-    login_task_->OutgoingStanza(element);
-  } else {
-    // handshake done - send straight through
-    InternalSendStanza(element);
-  }
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SendRaw(const std::string& text) {
-  if (state_ == STATE_CLOSED || login_task_)
-    return XMPP_RETURN_BADSTATE;
-
-  EnterExit ee(this);
-
-  (*output_) << text;
-
-  return XMPP_RETURN_OK;
-}
-
-std::string XmppEngineImpl::NextId() {
-  std::stringstream ss;
-  ss << next_id_++;
-  return ss.str();
-}
-
-XmppReturnStatus XmppEngineImpl::Disconnect() {
-  if (state_ != STATE_CLOSED) {
-    EnterExit ee(this);
-    if (state_ == STATE_OPEN)
-      *output_ << "</stream:stream>";
-    state_ = STATE_CLOSED;
-  }
-
-  return XMPP_RETURN_OK;
-}
-
-void XmppEngineImpl::IncomingStart(const XmlElement* start) {
-  if (HasError() || raised_reset_)
-    return;
-
-  if (login_task_) {
-    // start-stream should go to login task
-    login_task_->IncomingStanza(start, true);
-    if (login_task_->IsDone())
-      login_task_.reset();
-  }
-  else {
-    // if not logging in, it's an error to see a start
-    SignalError(ERROR_XML, 0);
-  }
-}
-
-void XmppEngineImpl::IncomingStanza(const XmlElement* stanza) {
-  if (HasError() || raised_reset_)
-    return;
-
-  if (stanza->Name() == QN_STREAM_ERROR) {
-    // Explicit XMPP stream error
-    SignalStreamError(stanza);
-  } else if (login_task_) {
-    // Handle login handshake
-    login_task_->IncomingStanza(stanza, false);
-    if (login_task_->IsDone())
-      login_task_.reset();
-  } else if (HandleIqResponse(stanza)) {
-    // iq is handled by above call
-  } else {
-    // give every "peek" handler a shot at all stanzas
-    for (size_t i = 0; i < stanza_handlers_[HL_PEEK]->size(); i += 1) {
-      (*stanza_handlers_[HL_PEEK])[i]->HandleStanza(stanza);
-    }
-
-    // give other handlers a shot in precedence order, stopping after handled
-    for (int level = HL_SINGLE; level <= HL_ALL; level += 1) {
-      for (size_t i = 0; i < stanza_handlers_[level]->size(); i += 1) {
-        if ((*stanza_handlers_[level])[i]->HandleStanza(stanza))
-          return;
-      }
-    }
-
-    // If nobody wants to handle a stanza then send back an error.
-    // Only do this for IQ stanzas as messages should probably just be dropped
-    // and presence stanzas should certainly be dropped.
-    std::string type = stanza->Attr(QN_TYPE);
-    if (stanza->Name() == QN_IQ &&
-        !(type == "error" || type == "result")) {
-      SendStanzaError(stanza, XSE_FEATURE_NOT_IMPLEMENTED, STR_EMPTY);
-    }
-  }
-}
-
-void XmppEngineImpl::IncomingEnd(bool isError) {
-  if (HasError() || raised_reset_)
-    return;
-
-  SignalError(isError ? ERROR_XML : ERROR_DOCUMENT_CLOSED, 0);
-}
-
-void XmppEngineImpl::InternalSendStart(const std::string& to) {
-  std::string hostname = tls_server_hostname_;
-  if (hostname.empty())
-    hostname = to;
-
-  // If not language is specified, the spec says use *
-  std::string lang = lang_;
-  if (lang.length() == 0)
-    lang = "*";
-
-  // send stream-beginning
-  // note, we put a \r\n at tne end fo the first line to cause non-XMPP
-  // line-oriented servers (e.g., Apache) to reveal themselves more quickly.
-  *output_ << "<stream:stream to=\"" << hostname << "\" "
-           << "xml:lang=\"" << lang << "\" "
-           << "version=\"1.0\" "
-           << "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-           << "xmlns=\"jabber:client\">\r\n";
-}
-
-void XmppEngineImpl::InternalSendStanza(const XmlElement* element) {
-  // It should really never be necessary to set a FROM attribute on a stanza.
-  // It is implied by the bind on the stream and if you get it wrong
-  // (by flipping from/to on a message?) the server will close the stream.
-  DCHECK(!element->HasAttr(QN_FROM));
-
-  XmlPrinter::PrintXml(output_.get(), element, &xmlns_stack_);
-}
-
-std::string XmppEngineImpl::ChooseBestSaslMechanism(
-    const std::vector<std::string>& mechanisms, bool encrypted) {
-  return sasl_handler_->ChooseBestSaslMechanism(mechanisms, encrypted);
-}
-
-SaslMechanism* XmppEngineImpl::GetSaslMechanism(const std::string& name) {
-  return sasl_handler_->CreateSaslMechanism(name);
-}
-
-void XmppEngineImpl::SignalBound(const Jid& fullJid) {
-  if (state_ == STATE_OPENING) {
-    bound_jid_ = fullJid;
-    state_ = STATE_OPEN;
-  }
-}
-
-void XmppEngineImpl::SignalStreamError(const XmlElement* stream_error) {
-  if (state_ != STATE_CLOSED) {
-    stream_error_.reset(new XmlElement(*stream_error));
-    SignalError(ERROR_STREAM, 0);
-  }
-}
-
-void XmppEngineImpl::SignalError(Error error_code, int sub_code) {
-  if (state_ != STATE_CLOSED) {
-    error_code_ = error_code;
-    subcode_ = sub_code;
-    state_ = STATE_CLOSED;
-  }
-}
-
-bool XmppEngineImpl::HasError() {
-  return error_code_ != ERROR_NONE;
-}
-
-void XmppEngineImpl::StartTls(const std::string& domain) {
-  if (output_handler_) {
-    // As substitute for the real (login jid's) domain, we permit
-    // verifying a tls_server_domain_ instead, if one was passed.
-    // This allows us to avoid running a proxy that needs to handle
-    // valuable certificates.
-    output_handler_->StartTls(
-      tls_server_domain_.empty() ? domain : tls_server_domain_);
-    encrypted_ = true;
-  }
-}
-
-XmppEngineImpl::EnterExit::EnterExit(XmppEngineImpl* engine)
-    : engine_(engine),
-      state_(engine->state_) {
-  engine->engine_entered_ += 1;
-}
-
-XmppEngineImpl::EnterExit::~EnterExit()  {
- XmppEngineImpl* engine = engine_;
-
- engine->engine_entered_ -= 1;
-
- bool closing = (engine->state_ != state_ &&
-       engine->state_ == STATE_CLOSED);
- bool flushing = closing || (engine->engine_entered_ == 0);
-
- if (engine->output_handler_ && flushing) {
-   std::string output = engine->output_->str();
-   if (output.length() > 0)
-     engine->output_handler_->WriteOutput(output.c_str(), output.length());
-   engine->output_->str("");
-
-   if (closing) {
-     engine->output_handler_->CloseConnection();
-     engine->output_handler_ = 0;
-   }
- }
-
- if (engine->engine_entered_)
-   return;
-
- if (engine->raised_reset_) {
-   engine->stanza_parser_.Reset();
-   engine->raised_reset_ = false;
- }
-
- if (engine->session_handler_) {
-   if (engine->state_ != state_)
-     engine->session_handler_->OnStateChange(engine->state_);
-   // Note: Handling of OnStateChange(CLOSED) should allow for the
-   // deletion of the engine, so no members should be accessed
-   // after this line.
- }
-}
-
-}  // namespace jingle_xmpp
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengineimpl.h b/third_party/libjingle_xmpp/xmpp/xmppengineimpl.h
deleted file mode 100644
index c947dd2..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppengineimpl.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPENGINEIMPL_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPENGINEIMPL_H_
-
-#include <memory>
-#include <sstream>
-#include <vector>
-
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h"
-
-namespace jingle_xmpp {
-
-class XmppLoginTask;
-class XmppEngine;
-class XmppIqEntry;
-class SaslHandler;
-class SaslMechanism;
-
-//! The XMPP connection engine.
-//! This engine implements the client side of the 'core' XMPP protocol.
-//! To use it, register an XmppOutputHandler to handle socket output
-//! and pass socket input to HandleInput.  Then application code can
-//! set up the connection with a user, password, and other settings,
-//! and then call Connect() to initiate the connection.
-//! An application can listen for events and receive stanzas by
-//! registering an XmppStanzaHandler via AddStanzaHandler().
-class XmppEngineImpl : public XmppEngine {
- public:
-  XmppEngineImpl();
-  virtual ~XmppEngineImpl();
-
-  // SOCKET INPUT AND OUTPUT ------------------------------------------------
-
-  //! Registers the handler for socket output
-  virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh);
-
-  //! Provides socket input to the engine
-  virtual XmppReturnStatus HandleInput(const char* bytes, size_t len);
-
-  //! Advises the engine that the socket has closed
-  virtual XmppReturnStatus ConnectionClosed(int subcode);
-
-  // SESSION SETUP ---------------------------------------------------------
-
-  //! Indicates the (bare) JID for the user to use.
-  virtual XmppReturnStatus SetUser(const Jid& jid);
-
-  //! Get the login (bare) JID.
-  virtual const Jid& GetUser();
-
-  //! Indicates the autentication to use.  Takes ownership of the object.
-  virtual XmppReturnStatus SetSaslHandler(SaslHandler* sasl_handler);
-
-  //! Sets whether TLS will be used within the connection (default true).
-  virtual XmppReturnStatus SetTls(TlsOptions use_tls);
-
-  //! Sets an alternate domain from which we allows TLS certificates.
-  //! This is for use in the case where a we want to allow a proxy to
-  //! serve up its own certificate rather than one owned by the underlying
-  //! domain.
-  virtual XmppReturnStatus SetTlsServer(const std::string& proxy_hostname,
-                                        const std::string& proxy_domain);
-
-  //! Gets whether TLS will be used within the connection.
-  virtual TlsOptions GetTls();
-
-  //! Sets the request resource name, if any (optional).
-  //! Note that the resource name may be overridden by the server; after
-  //! binding, the actual resource name is available as part of FullJid().
-  virtual XmppReturnStatus SetRequestedResource(const std::string& resource);
-
-  //! Gets the request resource name.
-  virtual const std::string& GetRequestedResource();
-
-  //! Sets language
-  virtual void SetLanguage(const std::string& lang) {
-    lang_ = lang;
-  }
-
-  // SESSION MANAGEMENT ---------------------------------------------------
-
-  //! Set callback for state changes.
-  virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler);
-
-  //! Initiates the XMPP connection.
-  //! After supplying connection settings, call this once to initiate,
-  //! (optionally) encrypt, authenticate, and bind the connection.
-  virtual XmppReturnStatus Connect();
-
-  //! The current engine state.
-  virtual State GetState() { return state_; }
-
-  //! Returns true if the connection is encrypted (under TLS)
-  virtual bool IsEncrypted() { return encrypted_; }
-
-  //! The error code.
-  //! Consult this after XmppOutputHandler.OnClose().
-  virtual Error GetError(int *subcode) {
-     if (subcode) {
-       *subcode = subcode_;
-     }
-     return error_code_;
-  }
-
-  //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
-  //! Notice the stanza returned is owned by the XmppEngine and
-  //! is deleted when the engine is destroyed.
-  virtual const XmlElement* GetStreamError() { return stream_error_.get(); }
-
-  //! Closes down the connection.
-  //! Sends CloseConnection to output, and disconnects and registered
-  //! session handlers.  After Disconnect completes, it is guaranteed
-  //! that no further callbacks will be made.
-  virtual XmppReturnStatus Disconnect();
-
-  // APPLICATION USE -------------------------------------------------------
-
-  //! Adds a listener for session events.
-  //! Stanza delivery is chained to session handlers; the first to
-  //! return 'true' is the last to get each stanza.
-  virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler,
-                                            XmppEngine::HandlerLevel level);
-
-  //! Removes a listener for session events.
-  virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler);
-
-  //! Sends a stanza to the server.
-  virtual XmppReturnStatus SendStanza(const XmlElement* stanza);
-
-  //! Sends raw text to the server
-  virtual XmppReturnStatus SendRaw(const std::string& text);
-
-  //! Sends an iq to the server, and registers a callback for the result.
-  //! Returns the cookie passed to the result handler.
-  virtual XmppReturnStatus SendIq(const XmlElement* stanza,
-                                  XmppIqHandler* iq_handler,
-                                  XmppIqCookie* cookie);
-
-  //! Unregisters an iq callback handler given its cookie.
-  //! No callback will come to this handler after it's unregistered.
-  virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie,
-                                      XmppIqHandler** iq_handler);
-
-  //! Forms and sends an error in response to the given stanza.
-  //! Swaps to and from, sets type to "error", and adds error information
-  //! based on the passed code.  Text is optional and may be STR_EMPTY.
-  virtual XmppReturnStatus SendStanzaError(const XmlElement* pelOriginal,
-                                           XmppStanzaError code,
-                                           const std::string& text);
-
-  //! The fullly bound JID.
-  //! This JID is only valid after binding has succeeded.  If the value
-  //! is JID_NULL, the binding has not succeeded.
-  virtual const Jid& FullJid() { return bound_jid_; }
-
-  //! The next unused iq id for this connection.
-  //! Call this when building iq stanzas, to ensure that each iq
-  //! gets its own unique id.
-  virtual std::string NextId();
-
- private:
-  friend class XmppLoginTask;
-  friend class XmppIqEntry;
-
-  void IncomingStanza(const XmlElement *stanza);
-  void IncomingStart(const XmlElement *stanza);
-  void IncomingEnd(bool isError);
-
-  void InternalSendStart(const std::string& domainName);
-  void InternalSendStanza(const XmlElement* stanza);
-  std::string ChooseBestSaslMechanism(
-      const std::vector<std::string>& mechanisms, bool encrypted);
-  SaslMechanism* GetSaslMechanism(const std::string& name);
-  void SignalBound(const Jid& fullJid);
-  void SignalStreamError(const XmlElement* streamError);
-  void SignalError(Error errorCode, int subCode);
-  bool HasError();
-  void DeleteIqCookies();
-  bool HandleIqResponse(const XmlElement* element);
-  void StartTls(const std::string& domain);
-  void RaiseReset() { raised_reset_ = true; }
-
-  class StanzaParseHandler : public XmppStanzaParseHandler {
-   public:
-    StanzaParseHandler(XmppEngineImpl* outer) : outer_(outer) {}
-    virtual ~StanzaParseHandler() {}
-
-    virtual void StartStream(const XmlElement* stream) {
-      outer_->IncomingStart(stream);
-    }
-    virtual void Stanza(const XmlElement* stanza) {
-      outer_->IncomingStanza(stanza);
-    }
-    virtual void EndStream() {
-      outer_->IncomingEnd(false);
-    }
-    virtual void XmlError() {
-      outer_->IncomingEnd(true);
-    }
-
-   private:
-    XmppEngineImpl* const outer_;
-  };
-
-  class EnterExit {
-   public:
-    EnterExit(XmppEngineImpl* engine);
-    ~EnterExit();
-   private:
-    XmppEngineImpl* engine_;
-    State state_;
-  };
-
-  friend class StanzaParseHandler;
-  friend class EnterExit;
-
-  StanzaParseHandler stanza_parse_handler_;
-  XmppStanzaParser stanza_parser_;
-
-  // state
-  int engine_entered_;
-  Jid user_jid_;
-  std::string password_;
-  std::string requested_resource_;
-  TlsOptions tls_option_;
-  std::string tls_server_hostname_;
-  std::string tls_server_domain_;
-  std::unique_ptr<XmppLoginTask> login_task_;
-  std::string lang_;
-
-  int next_id_;
-  Jid bound_jid_;
-  State state_;
-  bool encrypted_;
-  Error error_code_;
-  int subcode_;
-  std::unique_ptr<XmlElement> stream_error_;
-  bool raised_reset_;
-  XmppOutputHandler* output_handler_;
-  XmppSessionHandler* session_handler_;
-
-  XmlnsStack xmlns_stack_;
-
-  typedef std::vector<XmppStanzaHandler*> StanzaHandlerVector;
-  std::unique_ptr<StanzaHandlerVector> stanza_handlers_[HL_COUNT];
-
-  typedef std::vector<XmppIqEntry*> IqEntryVector;
-  std::unique_ptr<IqEntryVector> iq_entries_;
-
-  std::unique_ptr<SaslHandler> sasl_handler_;
-
-  std::unique_ptr<std::stringstream> output_;
-};
-
-}  // namespace jingle_xmpp
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPENGINEIMPL_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc b/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc
deleted file mode 100644
index b015daa..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <algorithm>
-#include <vector>
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengineimpl.h"
-
-namespace jingle_xmpp {
-
-class XmppIqEntry {
-  XmppIqEntry(const std::string& id,
-              const std::string& to,
-              XmppIqHandler* iq_handler)
-      : id_(id), to_(to), iq_handler_(iq_handler) {}
-
- private:
-  friend class XmppEngineImpl;
-
-  const std::string id_;
-  const std::string to_;
-  XmppIqHandler * const iq_handler_;
-};
-
-
-XmppReturnStatus
-XmppEngineImpl::SendIq(const XmlElement * element, XmppIqHandler * iq_handler,
-  XmppIqCookie* cookie) {
-  if (state_ == STATE_CLOSED)
-    return XMPP_RETURN_BADSTATE;
-  if (NULL == iq_handler)
-    return XMPP_RETURN_BADARGUMENT;
-  if (!element || element->Name() != QN_IQ)
-    return XMPP_RETURN_BADARGUMENT;
-
-  const std::string& type = element->Attr(QN_TYPE);
-  if (type != "get" && type != "set")
-    return XMPP_RETURN_BADARGUMENT;
-
-  if (!element->HasAttr(QN_ID))
-    return XMPP_RETURN_BADARGUMENT;
-  const std::string& id = element->Attr(QN_ID);
-
-  XmppIqEntry* iq_entry = new XmppIqEntry(id, element->Attr(QN_TO), iq_handler);
-  iq_entries_->push_back(iq_entry);
-  SendStanza(element);
-
-  if (cookie)
-    *cookie = iq_entry;
-
-  return XMPP_RETURN_OK;
-}
-
-
-XmppReturnStatus
-XmppEngineImpl::RemoveIqHandler(XmppIqCookie cookie,
-    XmppIqHandler ** iq_handler) {
-
-  std::vector<XmppIqEntry*, std::allocator<XmppIqEntry*> >::iterator pos;
-
-  pos = std::find(iq_entries_->begin(),
-                  iq_entries_->end(),
-                  reinterpret_cast<XmppIqEntry*>(cookie));
-
-  if (pos == iq_entries_->end())
-    return XMPP_RETURN_BADARGUMENT;
-
-  XmppIqEntry* entry = *pos;
-  iq_entries_->erase(pos);
-  if (iq_handler)
-    *iq_handler = entry->iq_handler_;
-  delete entry;
-
-  return XMPP_RETURN_OK;
-}
-
-void
-XmppEngineImpl::DeleteIqCookies() {
-  for (size_t i = 0; i < iq_entries_->size(); i += 1) {
-    XmppIqEntry * iq_entry_ = (*iq_entries_)[i];
-    (*iq_entries_)[i] = NULL;
-    delete iq_entry_;
-  }
-  iq_entries_->clear();
-}
-
-static void
-AecImpl(XmlElement * error_element, const QName & name,
-        const char * type, const char * code) {
-  error_element->AddElement(new XmlElement(QN_ERROR));
-  error_element->AddAttr(QN_CODE, code, 1);
-  error_element->AddAttr(QN_TYPE, type, 1);
-  error_element->AddElement(new XmlElement(name, true), 1);
-}
-
-
-static void
-AddErrorCode(XmlElement * error_element, XmppStanzaError code) {
-  switch (code) {
-    case XSE_BAD_REQUEST:
-      AecImpl(error_element, QN_STANZA_BAD_REQUEST, "modify", "400");
-      break;
-    case XSE_CONFLICT:
-      AecImpl(error_element, QN_STANZA_CONFLICT, "cancel", "409");
-      break;
-    case XSE_FEATURE_NOT_IMPLEMENTED:
-      AecImpl(error_element, QN_STANZA_FEATURE_NOT_IMPLEMENTED,
-              "cancel", "501");
-      break;
-    case XSE_FORBIDDEN:
-      AecImpl(error_element, QN_STANZA_FORBIDDEN, "auth", "403");
-      break;
-    case XSE_GONE:
-      AecImpl(error_element, QN_STANZA_GONE, "modify", "302");
-      break;
-    case XSE_INTERNAL_SERVER_ERROR:
-      AecImpl(error_element, QN_STANZA_INTERNAL_SERVER_ERROR, "wait", "500");
-      break;
-    case XSE_ITEM_NOT_FOUND:
-      AecImpl(error_element, QN_STANZA_ITEM_NOT_FOUND, "cancel", "404");
-      break;
-    case XSE_JID_MALFORMED:
-      AecImpl(error_element, QN_STANZA_JID_MALFORMED, "modify", "400");
-      break;
-    case XSE_NOT_ACCEPTABLE:
-      AecImpl(error_element, QN_STANZA_NOT_ACCEPTABLE, "cancel", "406");
-      break;
-    case XSE_NOT_ALLOWED:
-      AecImpl(error_element, QN_STANZA_NOT_ALLOWED, "cancel", "405");
-      break;
-    case XSE_PAYMENT_REQUIRED:
-      AecImpl(error_element, QN_STANZA_PAYMENT_REQUIRED, "auth", "402");
-      break;
-    case XSE_RECIPIENT_UNAVAILABLE:
-      AecImpl(error_element, QN_STANZA_RECIPIENT_UNAVAILABLE, "wait", "404");
-      break;
-    case XSE_REDIRECT:
-      AecImpl(error_element, QN_STANZA_REDIRECT, "modify", "302");
-      break;
-    case XSE_REGISTRATION_REQUIRED:
-      AecImpl(error_element, QN_STANZA_REGISTRATION_REQUIRED, "auth", "407");
-      break;
-    case XSE_SERVER_NOT_FOUND:
-      AecImpl(error_element, QN_STANZA_REMOTE_SERVER_NOT_FOUND,
-              "cancel", "404");
-      break;
-    case XSE_SERVER_TIMEOUT:
-      AecImpl(error_element, QN_STANZA_REMOTE_SERVER_TIMEOUT, "wait", "502");
-      break;
-    case XSE_RESOURCE_CONSTRAINT:
-      AecImpl(error_element, QN_STANZA_RESOURCE_CONSTRAINT, "wait", "500");
-      break;
-    case XSE_SERVICE_UNAVAILABLE:
-      AecImpl(error_element, QN_STANZA_SERVICE_UNAVAILABLE, "cancel", "503");
-      break;
-    case XSE_SUBSCRIPTION_REQUIRED:
-      AecImpl(error_element, QN_STANZA_SUBSCRIPTION_REQUIRED, "auth", "407");
-      break;
-    case XSE_UNDEFINED_CONDITION:
-      AecImpl(error_element, QN_STANZA_UNDEFINED_CONDITION, "wait", "500");
-      break;
-    case XSE_UNEXPECTED_REQUEST:
-      AecImpl(error_element, QN_STANZA_UNEXPECTED_REQUEST, "wait", "400");
-      break;
-  }
-}
-
-
-XmppReturnStatus
-XmppEngineImpl::SendStanzaError(const XmlElement * element_original,
-                                XmppStanzaError code,
-                                const std::string & text) {
-
-  if (state_ == STATE_CLOSED)
-    return XMPP_RETURN_BADSTATE;
-
-  XmlElement error_element(element_original->Name());
-  error_element.AddAttr(QN_TYPE, "error");
-
-  // copy attrs, copy 'from' to 'to' and strip 'from'
-  for (const XmlAttr * attribute = element_original->FirstAttr();
-       attribute; attribute = attribute->NextAttr()) {
-    QName name = attribute->Name();
-    if (name == QN_TO)
-      continue; // no need to put a from attr.  Server will stamp stanza
-    else if (name == QN_FROM)
-      name = QN_TO;
-    else if (name == QN_TYPE)
-      continue;
-    error_element.AddAttr(name, attribute->Value());
-  }
-
-  // copy children
-  for (const XmlChild * child = element_original->FirstChild();
-       child;
-       child = child->NextChild()) {
-    if (child->IsText()) {
-      error_element.AddText(child->AsText()->Text());
-    } else {
-      error_element.AddElement(new XmlElement(*(child->AsElement())));
-    }
-  }
-
-  // add error information
-  AddErrorCode(&error_element, code);
-  if (text != STR_EMPTY) {
-    XmlElement * text_element = new XmlElement(QN_STANZA_TEXT, true);
-    text_element->AddText(text);
-    error_element.AddElement(text_element);
-  }
-
-  SendStanza(&error_element);
-
-  return XMPP_RETURN_OK;
-}
-
-
-bool
-XmppEngineImpl::HandleIqResponse(const XmlElement * element) {
-  if (iq_entries_->empty())
-    return false;
-  if (element->Name() != QN_IQ)
-    return false;
-  std::string type = element->Attr(QN_TYPE);
-  if (type != "result" && type != "error")
-    return false;
-  if (!element->HasAttr(QN_ID))
-    return false;
-  std::string id = element->Attr(QN_ID);
-  std::string from = element->Attr(QN_FROM);
-
-  for (std::vector<XmppIqEntry *>::iterator it = iq_entries_->begin();
-       it != iq_entries_->end(); it += 1) {
-    XmppIqEntry * iq_entry = *it;
-    if (iq_entry->id_ == id && iq_entry->to_ == from) {
-      iq_entries_->erase(it);
-      iq_entry->iq_handler_->IqResponse(iq_entry, element);
-      delete iq_entry;
-      return true;
-    }
-  }
-
-  return false;
-}
-
-}
diff --git a/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc b/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc
deleted file mode 100644
index 2f34c99..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/xmpp/xmpplogintask.h"
-
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#include "third_party/libjingle_xmpp/xmpp/jid.h"
-#include "third_party/libjingle_xmpp/xmpp/saslmechanism.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengineimpl.h"
-
-namespace jingle_xmpp {
-
-XmppLoginTask::XmppLoginTask(XmppEngineImpl * pctx) :
-  pctx_(pctx),
-  authNeeded_(true),
-  allowNonGoogleLogin_(true),
-  state_(LOGINSTATE_INIT),
-  pelStanza_(NULL),
-  isStart_(false),
-  iqId_(STR_EMPTY),
-  pelFeatures_(),
-  fullJid_(STR_EMPTY),
-  streamId_(STR_EMPTY),
-  pvecQueuedStanzas_(new std::vector<XmlElement *>()),
-  sasl_mech_() {
-}
-
-XmppLoginTask::~XmppLoginTask() {
-  for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1)
-    delete (*pvecQueuedStanzas_)[i];
-}
-
-void
-XmppLoginTask::IncomingStanza(const XmlElement *element, bool isStart) {
-  pelStanza_ = element;
-  isStart_ = isStart;
-  Advance();
-  pelStanza_ = NULL;
-  isStart_ = false;
-}
-
-const XmlElement *
-XmppLoginTask::NextStanza() {
-  const XmlElement * result = pelStanza_;
-  pelStanza_ = NULL;
-  return result;
-}
-
-bool
-XmppLoginTask::Advance() {
-
-  for (;;) {
-
-    const XmlElement * element = NULL;
-
-#if !defined(NDEBUG)
-    DVLOG(1) << "XmppLoginTask::Advance - " << ErrorName(state_);
-#endif
-
-    switch (state_) {
-
-      case LOGINSTATE_INIT: {
-        pctx_->RaiseReset();
-        pelFeatures_.reset(NULL);
-
-        // The proper domain to verify against is the real underlying
-        // domain - i.e., the domain that owns the JID.  Our XmppEngineImpl
-        // also allows matching against a proxy domain instead, if it is told
-        // to do so - see the implementation of XmppEngineImpl::StartTls and
-        // XmppEngine::SetTlsServerDomain to see how you can use that feature
-        pctx_->InternalSendStart(pctx_->user_jid_.domain());
-        state_ = LOGINSTATE_STREAMSTART_SENT;
-        break;
-      }
-
-      case LOGINSTATE_STREAMSTART_SENT: {
-        if (NULL == (element = NextStanza()))
-          return true;
-
-        if (!isStart_ || !HandleStartStream(element))
-          return Failure(XmppEngine::ERROR_VERSION);
-
-        state_ = LOGINSTATE_STARTED_XMPP;
-        return true;
-      }
-
-      case LOGINSTATE_STARTED_XMPP: {
-        if (NULL == (element = NextStanza()))
-          return true;
-
-        if (!HandleFeatures(element))
-          return Failure(XmppEngine::ERROR_VERSION);
-
-        bool tls_present = (GetFeature(QN_TLS_STARTTLS) != NULL);
-        // Error if TLS required but not present.
-        if (pctx_->tls_option_ == jingle_xmpp::TLS_REQUIRED && !tls_present) {
-          return Failure(XmppEngine::ERROR_TLS);
-        }
-        // Use TLS if required or enabled, and also available
-        if ((pctx_->tls_option_ == jingle_xmpp::TLS_REQUIRED ||
-            pctx_->tls_option_ == jingle_xmpp::TLS_ENABLED) && tls_present) {
-          state_ = LOGINSTATE_TLS_INIT;
-          continue;
-        }
-
-        if (authNeeded_) {
-          state_ = LOGINSTATE_AUTH_INIT;
-          continue;
-        }
-
-        state_ = LOGINSTATE_BIND_INIT;
-        continue;
-      }
-
-      case LOGINSTATE_TLS_INIT: {
-        const XmlElement * pelTls = GetFeature(QN_TLS_STARTTLS);
-        if (!pelTls)
-          return Failure(XmppEngine::ERROR_TLS);
-
-        XmlElement el(QN_TLS_STARTTLS, true);
-        pctx_->InternalSendStanza(&el);
-        state_ = LOGINSTATE_TLS_REQUESTED;
-        continue;
-      }
-
-      case LOGINSTATE_TLS_REQUESTED: {
-        if (NULL == (element = NextStanza()))
-          return true;
-        if (element->Name() != QN_TLS_PROCEED)
-          return Failure(XmppEngine::ERROR_TLS);
-
-        // The proper domain to verify against is the real underlying
-        // domain - i.e., the domain that owns the JID.  Our XmppEngineImpl
-        // also allows matching against a proxy domain instead, if it is told
-        // to do so - see the implementation of XmppEngineImpl::StartTls and
-        // XmppEngine::SetTlsServerDomain to see how you can use that feature
-        pctx_->StartTls(pctx_->user_jid_.domain());
-        pctx_->tls_option_ = jingle_xmpp::TLS_ENABLED;
-        state_ = LOGINSTATE_INIT;
-        continue;
-      }
-
-      case LOGINSTATE_AUTH_INIT: {
-        const XmlElement * pelSaslAuth = GetFeature(QN_SASL_MECHANISMS);
-        if (!pelSaslAuth) {
-          return Failure(XmppEngine::ERROR_AUTH);
-        }
-
-        // Collect together the SASL auth mechanisms presented by the server
-        std::vector<std::string> mechanisms;
-        for (const XmlElement * pelMech =
-             pelSaslAuth->FirstNamed(QN_SASL_MECHANISM);
-             pelMech;
-             pelMech = pelMech->NextNamed(QN_SASL_MECHANISM)) {
-
-          mechanisms.push_back(pelMech->BodyText());
-        }
-
-        // Given all the mechanisms, choose the best
-        std::string choice(pctx_->ChooseBestSaslMechanism(mechanisms, pctx_->IsEncrypted()));
-        if (choice.empty()) {
-          return Failure(XmppEngine::ERROR_AUTH);
-        }
-
-        // No recognized auth mechanism - that's an error
-        sasl_mech_.reset(pctx_->GetSaslMechanism(choice));
-        if (!sasl_mech_) {
-          return Failure(XmppEngine::ERROR_AUTH);
-        }
-
-        // OK, let's start it.
-        XmlElement * auth = sasl_mech_->StartSaslAuth();
-        if (auth == NULL) {
-          return Failure(XmppEngine::ERROR_AUTH);
-        }
-        if (allowNonGoogleLogin_) {
-          // Setting the following two attributes is required to support
-          // non-google ids.
-
-          // Allow login with non-google id accounts.
-          auth->SetAttr(QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN, "true");
-
-          // Allow login with either the non-google id or the friendly email.
-          auth->SetAttr(QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT, "true");
-        }
-
-        pctx_->InternalSendStanza(auth);
-        delete auth;
-        state_ = LOGINSTATE_SASL_RUNNING;
-        continue;
-      }
-
-      case LOGINSTATE_SASL_RUNNING: {
-        if (NULL == (element = NextStanza()))
-          return true;
-        if (element->Name().Namespace() != NS_SASL)
-          return Failure(XmppEngine::ERROR_AUTH);
-        if (element->Name() == QN_SASL_CHALLENGE) {
-          XmlElement * response = sasl_mech_->HandleSaslChallenge(element);
-          if (response == NULL) {
-            return Failure(XmppEngine::ERROR_AUTH);
-          }
-          pctx_->InternalSendStanza(response);
-          delete response;
-          state_ = LOGINSTATE_SASL_RUNNING;
-          continue;
-        }
-        if (element->Name() != QN_SASL_SUCCESS) {
-          return Failure(XmppEngine::ERROR_UNAUTHORIZED);
-        }
-
-        // Authenticated!
-        authNeeded_ = false;
-        state_ = LOGINSTATE_INIT;
-        continue;
-      }
-
-      case LOGINSTATE_BIND_INIT: {
-        const XmlElement * pelBindFeature = GetFeature(QN_BIND_BIND);
-        const XmlElement * pelSessionFeature = GetFeature(QN_SESSION_SESSION);
-        if (!pelBindFeature || !pelSessionFeature)
-          return Failure(XmppEngine::ERROR_BIND);
-
-        XmlElement iq(QN_IQ);
-        iq.AddAttr(QN_TYPE, "set");
-
-        iqId_ = pctx_->NextId();
-        iq.AddAttr(QN_ID, iqId_);
-        iq.AddElement(new XmlElement(QN_BIND_BIND, true));
-
-        if (pctx_->requested_resource_ != STR_EMPTY) {
-          iq.AddElement(new XmlElement(QN_BIND_RESOURCE), 1);
-          iq.AddText(pctx_->requested_resource_, 2);
-        }
-        pctx_->InternalSendStanza(&iq);
-        state_ = LOGINSTATE_BIND_REQUESTED;
-        continue;
-      }
-
-      case LOGINSTATE_BIND_REQUESTED: {
-        if (NULL == (element = NextStanza()))
-          return true;
-
-        if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ ||
-            element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set")
-          return true;
-
-        if (element->Attr(QN_TYPE) != "result" || element->FirstElement() == NULL ||
-            element->FirstElement()->Name() != QN_BIND_BIND)
-          return Failure(XmppEngine::ERROR_BIND);
-
-        fullJid_ = Jid(element->FirstElement()->TextNamed(QN_BIND_JID));
-        if (!fullJid_.IsFull()) {
-          return Failure(XmppEngine::ERROR_BIND);
-        }
-
-        // now request session
-        XmlElement iq(QN_IQ);
-        iq.AddAttr(QN_TYPE, "set");
-
-        iqId_ = pctx_->NextId();
-        iq.AddAttr(QN_ID, iqId_);
-        iq.AddElement(new XmlElement(QN_SESSION_SESSION, true));
-        pctx_->InternalSendStanza(&iq);
-
-        state_ = LOGINSTATE_SESSION_REQUESTED;
-        continue;
-      }
-
-      case LOGINSTATE_SESSION_REQUESTED: {
-        if (NULL == (element = NextStanza()))
-          return true;
-        if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ ||
-            element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set")
-          return false;
-
-        if (element->Attr(QN_TYPE) != "result")
-          return Failure(XmppEngine::ERROR_BIND);
-
-        pctx_->SignalBound(fullJid_);
-        FlushQueuedStanzas();
-        state_ = LOGINSTATE_DONE;
-        return true;
-      }
-
-      case LOGINSTATE_DONE:
-        return false;
-    }
-  }
-}
-
-bool
-XmppLoginTask::HandleStartStream(const XmlElement *element) {
-
-  if (element->Name() != QN_STREAM_STREAM)
-    return false;
-
-  if (element->Attr(QN_XMLNS) != "jabber:client")
-    return false;
-
-  if (element->Attr(QN_VERSION) != "1.0")
-    return false;
-
-  if (!element->HasAttr(QN_ID))
-    return false;
-
-  streamId_ = element->Attr(QN_ID);
-
-  return true;
-}
-
-bool
-XmppLoginTask::HandleFeatures(const XmlElement *element) {
-  if (element->Name() != QN_STREAM_FEATURES)
-    return false;
-
-  pelFeatures_.reset(new XmlElement(*element));
-  return true;
-}
-
-const XmlElement *
-XmppLoginTask::GetFeature(const QName & name) {
-  return pelFeatures_->FirstNamed(name);
-}
-
-bool
-XmppLoginTask::Failure(XmppEngine::Error reason) {
-  state_ = LOGINSTATE_DONE;
-  pctx_->SignalError(reason, 0);
-  return false;
-}
-
-void
-XmppLoginTask::OutgoingStanza(const XmlElement * element) {
-  XmlElement * pelCopy = new XmlElement(*element);
-  pvecQueuedStanzas_->push_back(pelCopy);
-}
-
-void
-XmppLoginTask::FlushQueuedStanzas() {
-  for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) {
-    pctx_->InternalSendStanza((*pvecQueuedStanzas_)[i]);
-    delete (*pvecQueuedStanzas_)[i];
-  }
-  pvecQueuedStanzas_->clear();
-}
-
-#if !defined(NDEBUG)
-#define KLABEL(x) \
-  case x:         \
-    return #x
-
-const char* XmppLoginTask::ErrorName(int err) {
-  switch (err) {
-    KLABEL(LOGINSTATE_INIT);
-    KLABEL(LOGINSTATE_STREAMSTART_SENT);
-    KLABEL(LOGINSTATE_STARTED_XMPP);
-    KLABEL(LOGINSTATE_TLS_INIT);
-    KLABEL(LOGINSTATE_AUTH_INIT);
-    KLABEL(LOGINSTATE_BIND_INIT);
-    KLABEL(LOGINSTATE_TLS_REQUESTED);
-    KLABEL(LOGINSTATE_SASL_RUNNING);
-    KLABEL(LOGINSTATE_BIND_REQUESTED);
-    KLABEL(LOGINSTATE_SESSION_REQUESTED);
-    KLABEL(LOGINSTATE_DONE);
-    default:
-      return nullptr;
-  }
-}
-#endif
-}
diff --git a/third_party/libjingle_xmpp/xmpp/xmpplogintask.h b/third_party/libjingle_xmpp/xmpp/xmpplogintask.h
deleted file mode 100644
index 18fdab5c..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmpplogintask.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_LOGINTASK_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_LOGINTASK_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "third_party/libjingle_xmpp/xmpp/jid.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-
-namespace jingle_xmpp {
-
-class XmlElement;
-class XmppEngineImpl;
-class SaslMechanism;
-
-
-// TODO: Rename to LoginTask.
-class XmppLoginTask {
-
-public:
-  XmppLoginTask(XmppEngineImpl *pctx);
-  ~XmppLoginTask();
-
-  bool IsDone()
-    { return state_ == LOGINSTATE_DONE; }
-  void IncomingStanza(const XmlElement * element, bool isStart);
-  void OutgoingStanza(const XmlElement *element);
-  void set_allow_non_google_login(bool b)
-    { allowNonGoogleLogin_ = b; }
-
-private:
-  enum LoginTaskState {
-    LOGINSTATE_INIT = 0,
-    LOGINSTATE_STREAMSTART_SENT,
-    LOGINSTATE_STARTED_XMPP,
-    LOGINSTATE_TLS_INIT,
-    LOGINSTATE_AUTH_INIT,
-    LOGINSTATE_BIND_INIT,
-    LOGINSTATE_TLS_REQUESTED,
-    LOGINSTATE_SASL_RUNNING,
-    LOGINSTATE_BIND_REQUESTED,
-    LOGINSTATE_SESSION_REQUESTED,
-    LOGINSTATE_DONE,
-  };
-
-  const XmlElement * NextStanza();
-  bool Advance();
-  bool HandleStartStream(const XmlElement * element);
-  bool HandleFeatures(const XmlElement * element);
-  const XmlElement * GetFeature(const QName & name);
-  bool Failure(XmppEngine::Error reason);
-  void FlushQueuedStanzas();
-
-#if !defined(NDEBUG)
-  const char* ErrorName(int err);
-#endif
-
-  XmppEngineImpl * pctx_;
-  bool authNeeded_;
-  bool allowNonGoogleLogin_;
-  LoginTaskState state_;
-  const XmlElement * pelStanza_;
-  bool isStart_;
-  std::string iqId_;
-  std::unique_ptr<XmlElement> pelFeatures_;
-  Jid fullJid_;
-  std::string streamId_;
-  std::unique_ptr<std::vector<XmlElement *> > pvecQueuedStanzas_;
-
-  std::unique_ptr<SaslMechanism> sasl_mech_;
-};
-
-}
-
-#endif  //  THIRD_PARTY_LIBJINGLE_XMPP_XMPP_LOGINTASK_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc b/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc
deleted file mode 100644
index 1e42efa..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <iostream>
-#include <memory>
-#include <sstream>
-#include <string>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#include "third_party/libjingle_xmpp/xmpp/plainsaslhandler.h"
-#include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h"
-#include "third_party/libjingle_xmpp/xmpp/util_unittest.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-
-// Macro to be used for switch-case fallthrough (required for enabling
-// -Wimplicit-fallthrough warning on Clang).
-#ifdef __clang__
-#define XLTT_FALLTHROUGH() [[clang::fallthrough]]
-#else
-#define XLTT_FALLTHROUGH() \
-  do {                     \
-  } while (0)
-#endif
-
-using jingle_xmpp::Jid;
-using jingle_xmpp::QName;
-using jingle_xmpp::XmlElement;
-using jingle_xmpp::XmppEngine;
-using jingle_xmpp::XmppTestHandler;
-
-enum XlttStage {
-  XLTT_STAGE_CONNECT = 0,
-  XLTT_STAGE_STREAMSTART,
-  XLTT_STAGE_TLS_FEATURES,
-  XLTT_STAGE_TLS_PROCEED,
-  XLTT_STAGE_ENCRYPTED_START,
-  XLTT_STAGE_AUTH_FEATURES,
-  XLTT_STAGE_AUTH_SUCCESS,
-  XLTT_STAGE_AUTHENTICATED_START,
-  XLTT_STAGE_BIND_FEATURES,
-  XLTT_STAGE_BIND_SUCCESS,
-  XLTT_STAGE_SESSION_SUCCESS,
-};
-
-class XmppLoginTaskTest : public testing::Test {
- public:
-  XmppEngine* engine() { return engine_.get(); }
-  XmppTestHandler* handler() { return handler_.get(); }
-  virtual void SetUp() {
-    engine_.reset(XmppEngine::Create());
-    handler_.reset(new XmppTestHandler(engine_.get()));
-
-    Jid jid("david@my-server");
-    std::string pass("david");
-    engine_->SetSessionHandler(handler_.get());
-    engine_->SetOutputHandler(handler_.get());
-    engine_->AddStanzaHandler(handler_.get());
-    engine_->SetUser(jid);
-    engine_->SetSaslHandler(
-        new jingle_xmpp::PlainSaslHandler(jid, pass, true));
-  }
-  virtual void TearDown() {
-    handler_.reset();
-    engine_.reset();
-  }
-  void RunPartialLogin(XlttStage startstage, XlttStage endstage);
-  void SetTlsOptions(jingle_xmpp::TlsOptions option);
-
- private:
-  std::unique_ptr<XmppEngine> engine_;
-  std::unique_ptr<XmppTestHandler> handler_;
-};
-
-void XmppLoginTaskTest::SetTlsOptions(jingle_xmpp::TlsOptions option) {
-  engine_->SetTls(option);
-}
-void XmppLoginTaskTest::RunPartialLogin(XlttStage startstage,
-                                        XlttStage endstage) {
-  std::string input;
-
-  switch (startstage) {
-    case XLTT_STAGE_CONNECT: {
-      engine_->Connect();
-      XmlElement appStanza(QName("test", "app-stanza"));
-      appStanza.AddText("this-is-a-test");
-      engine_->SendStanza(&appStanza);
-
-      EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
-          "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-      EXPECT_EQ("[OPENING]", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      if (endstage == XLTT_STAGE_CONNECT)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_STREAMSTART: {
-      input = "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->OutputActivity());
-      if (endstage == XLTT_STAGE_STREAMSTART)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_TLS_FEATURES: {
-      input = "<stream:features>"
-        "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"
-       "</stream:features>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
-          handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      if (endstage == XLTT_STAGE_TLS_FEATURES)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_TLS_PROCEED: {
-      input = std::string("<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("[START-TLS my-server]"
-          "<stream:stream to=\"my-server\" xml:lang=\"*\" "
-          "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      if (endstage == XLTT_STAGE_TLS_PROCEED)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_ENCRYPTED_START: {
-      input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">");
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->OutputActivity());
-      if (endstage == XLTT_STAGE_ENCRYPTED_START)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_AUTH_FEATURES: {
-      input = "<stream:features>"
-        "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-          "<mechanism>DIGEST-MD5</mechanism>"
-          "<mechanism>PLAIN</mechanism>"
-        "</mechanisms>"
-       "</stream:features>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-          "mechanism=\"PLAIN\" "
-          "auth:allow-non-google-login=\"true\" "
-          "auth:client-uses-full-bind-result=\"true\" "
-          "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-          ">AGRhdmlkAGRhdmlk</auth>",
-          handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      if (endstage == XLTT_STAGE_AUTH_FEATURES)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_AUTH_SUCCESS: {
-      input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
-          "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      if (endstage == XLTT_STAGE_AUTH_SUCCESS)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_AUTHENTICATED_START: {
-      input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">");
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->OutputActivity());
-      if (endstage == XLTT_STAGE_AUTHENTICATED_START)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_BIND_FEATURES: {
-      input = "<stream:features>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
-          "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
-        "</stream:features>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<iq type=\"set\" id=\"0\">"
-          "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>",
-          handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      if (endstage == XLTT_STAGE_BIND_FEATURES)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_BIND_SUCCESS: {
-      input = "<iq type='result' id='0'>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
-          "<jid>david@my-server/test</jid></bind></iq>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<iq type=\"set\" id=\"1\">"
-          "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>",
-          handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      if (endstage == XLTT_STAGE_BIND_SUCCESS)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-
-    case XLTT_STAGE_SESSION_SUCCESS: {
-      input = "<iq type='result' id='1'/>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test"
-          "</test:app-stanza>", handler_->OutputActivity());
-      EXPECT_EQ("[OPEN]", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      if (endstage == XLTT_STAGE_SESSION_SUCCESS)
-        return;
-      XLTT_FALLTHROUGH();
-    }
-    default:
-      break;
-  }
-}
-
-TEST_F(XmppLoginTaskTest, TestUtf8Good) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
-
-  std::string input = "<?xml version='1.0' encoding='UTF-8'?>"
-      "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
-      "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-      "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestNonUtf8Bad) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
-
-  std::string input = "<?xml version='1.0' encoding='ISO-8859-1'?>"
-      "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
-      "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-      "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestNoFeatures) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<iq type='get' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsRequiredNotPresent) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-     "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsRequeiredAndPresent) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>"
-        "<required/>"
-      "</starttls>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>X-GOOGLE-TOKEN</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-        "<mechanism>X-OAUTH2</mechanism>"
-      "</mechanisms>"
-     "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
-      handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsEnabledNotPresent) {
-  SetTlsOptions(jingle_xmpp::TLS_ENABLED);
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-     "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsEnabledAndPresent) {
-  SetTlsOptions(jingle_xmpp::TLS_ENABLED);
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>X-GOOGLE-TOKEN</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-        "<mechanism>X-OAUTH2</mechanism>"
-      "</mechanisms>"
-      "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsDisabledNotPresent) {
-  SetTlsOptions(jingle_xmpp::TLS_DISABLED);
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-    std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-     "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsDisabledAndPresent) {
-  SetTlsOptions(jingle_xmpp::TLS_DISABLED);
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>X-GOOGLE-TOKEN</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-        "<mechanism>X-OAUTH2</mechanism>"
-      "</mechanisms>"
-      "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsFailure) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_FEATURES);
-
-  std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsBadStream) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_PROCEED);
-
-  std::string input = "<wrongtag>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestMissingSaslPlain) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_ENCRYPTED_START);
-
-  std::string input = "<stream:features>"
-        "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-          "<mechanism>DIGEST-MD5</mechanism>"
-        "</mechanisms>"
-       "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-AUTH]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestWrongPassword) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_FEATURES);
-
-  std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-UNAUTHORIZED]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestAuthBadStream) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_SUCCESS);
-
-  std::string input = "<wrongtag>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestMissingBindFeature) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
-
-  std::string input = "<stream:features>"
-          "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
-        "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestMissingSessionFeature) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
-
-  std::string input = "<stream:features>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
-        "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-/* TODO: Handle this case properly inside XmppLoginTask.
-TEST_F(XmppLoginTaskTest, TestBindFailure1) {
-  // check wrong JID
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
-
-  std::string input = "<iq type='result' id='0'>"
-      "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
-      "<jid>davey@my-server/test</jid></bind></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-*/
-
-TEST_F(XmppLoginTaskTest, TestBindFailure2) {
-  // check missing JID
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
-
-  std::string input = "<iq type='result' id='0'>"
-      "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestBindFailure3) {
-  // check plain failure
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
-
-  std::string input = "<iq type='error' id='0'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestBindFailure4) {
-  // check wrong id to ignore
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
-
-  std::string input = "<iq type='error' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  // continue after an ignored iq
-  RunPartialLogin(XLTT_STAGE_BIND_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
-}
-
-TEST_F(XmppLoginTaskTest, TestSessionFailurePlain1) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
-
-  std::string input = "<iq type='error' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestSessionFailurePlain2) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
-
-  // check reverse iq to ignore
-  // TODO: consider queueing or passing through?
-  std::string input = "<iq type='get' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-
-  // continue after an ignored iq
-  RunPartialLogin(XLTT_STAGE_SESSION_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
-}
-
-TEST_F(XmppLoginTaskTest, TestBadXml) {
-  int errorKind = 0;
-  for (XlttStage stage = XLTT_STAGE_CONNECT;
-      stage <= XLTT_STAGE_SESSION_SUCCESS;
-      stage = static_cast<XlttStage>(stage + 1)) {
-    RunPartialLogin(XLTT_STAGE_CONNECT, stage);
-
-    std::string input;
-    switch (errorKind++ % 5) {
-      case 0: input = "&syntax;"; break;
-      case 1: input = "<nons:iq/>"; break;
-      case 2: input = "<iq a='b' a='dupe'/>"; break;
-      case 3: input = "<>"; break;
-      case 4: input = "<iq a='<wrong>'>"; break;
-    }
-
-    engine()->HandleInput(input.c_str(), input.length());
-
-    EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-    EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
-
-    TearDown();
-    SetUp();
-  }
-}
-
-TEST_F(XmppLoginTaskTest, TestStreamError) {
-  for (XlttStage stage = XLTT_STAGE_CONNECT;
-      stage <= XLTT_STAGE_SESSION_SUCCESS;
-      stage = static_cast<XlttStage>(stage + 1)) {
-    switch (stage) {
-      case XLTT_STAGE_CONNECT:
-      case XLTT_STAGE_TLS_PROCEED:
-      case XLTT_STAGE_AUTH_SUCCESS:
-        continue;
-      default:
-        break;
-    }
-
-    RunPartialLogin(XLTT_STAGE_CONNECT, stage);
-
-    std::string input = "<stream:error>"
-        "<xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>"
-        "<text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>"
-        "Some special application diagnostic information!"
-        "</text>"
-        "<escape-your-data xmlns='application-ns'/>"
-        "</stream:error>";
-
-    engine()->HandleInput(input.c_str(), input.length());
-
-    EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-    EXPECT_EQ("[CLOSED][ERROR-STREAM]", handler()->SessionActivity());
-
-    EXPECT_EQ("<str:error xmlns:str=\"http://etherx.jabber.org/streams\">"
-        "<xml-not-well-formed xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\"/>"
-        "<text xml:lang=\"en\" xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\">"
-        "Some special application diagnostic information!"
-        "</text>"
-        "<escape-your-data xmlns=\"application-ns\"/>"
-        "</str:error>", engine()->GetStreamError()->Str());
-
-    TearDown();
-    SetUp();
-  }
-}
diff --git a/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc b/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc
deleted file mode 100644
index e2c60ff..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h"
-
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#ifdef EXPAT_RELATIVE_PATH
-#include "expat.h"
-#else
-#include "third_party/expat/v2_0_1/Source/lib/expat.h"
-#endif
-
-namespace jingle_xmpp {
-
-XmppStanzaParser::XmppStanzaParser(XmppStanzaParseHandler *psph) :
-  psph_(psph),
-  innerHandler_(this),
-  parser_(&innerHandler_),
-  depth_(0),
-  builder_() {
-}
-
-void
-XmppStanzaParser::Reset() {
-  parser_.Reset();
-  depth_ = 0;
-  builder_.Reset();
-}
-
-void
-XmppStanzaParser::IncomingStartElement(
-    XmlParseContext * pctx, const char * name, const char ** atts) {
-  if (depth_++ == 0) {
-    XmlElement * pelStream = XmlBuilder::BuildElement(pctx, name, atts);
-    if (pelStream == NULL) {
-      pctx->RaiseError(XML_ERROR_SYNTAX);
-      return;
-    }
-    psph_->StartStream(pelStream);
-    delete pelStream;
-    return;
-  }
-
-  builder_.StartElement(pctx, name, atts);
-}
-
-void
-XmppStanzaParser::IncomingCharacterData(
-    XmlParseContext * pctx, const char * text, int len) {
-  if (depth_ > 1) {
-    builder_.CharacterData(pctx, text, len);
-  }
-}
-
-void
-XmppStanzaParser::IncomingEndElement(
-    XmlParseContext * pctx, const char * name) {
-  if (--depth_ == 0) {
-    psph_->EndStream();
-    return;
-  }
-
-  builder_.EndElement(pctx, name);
-
-  if (depth_ == 1) {
-    XmlElement *element = builder_.CreateElement();
-    psph_->Stanza(element);
-    delete element;
-  }
-}
-
-void
-XmppStanzaParser::IncomingError(
-    XmlParseContext * pctx, XML_Error errCode) {
-  psph_->XmlError();
-}
-
-}
diff --git a/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h b/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h
deleted file mode 100644
index b889bb1..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPSTANZAPARSER_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPSTANZAPARSER_H_
-
-#include "third_party/libjingle_xmpp/xmllite/xmlbuilder.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlparser.h"
-
-
-namespace jingle_xmpp {
-
-class XmlElement;
-
-class XmppStanzaParseHandler {
-public:
-  virtual ~XmppStanzaParseHandler() {}
-  virtual void StartStream(const XmlElement * pelStream) = 0;
-  virtual void Stanza(const XmlElement * pelStanza) = 0;
-  virtual void EndStream() = 0;
-  virtual void XmlError() = 0;
-};
-
-class XmppStanzaParser {
-public:
-  XmppStanzaParser(XmppStanzaParseHandler *psph);
-  bool Parse(const char * data, size_t len, bool isFinal)
-    { return parser_.Parse(data, len, isFinal); }
-  void Reset();
-
-private:
-  class ParseHandler : public XmlParseHandler {
-  public:
-    ParseHandler(XmppStanzaParser * outer) : outer_(outer) {}
-    virtual void StartElement(XmlParseContext * pctx,
-               const char * name, const char ** atts)
-      { outer_->IncomingStartElement(pctx, name, atts); }
-    virtual void EndElement(XmlParseContext * pctx,
-               const char * name)
-      { outer_->IncomingEndElement(pctx, name); }
-    virtual void CharacterData(XmlParseContext * pctx,
-               const char * text, int len)
-      { outer_->IncomingCharacterData(pctx, text, len); }
-    virtual void Error(XmlParseContext * pctx,
-               XML_Error errCode)
-      { outer_->IncomingError(pctx, errCode); }
-  private:
-    XmppStanzaParser * const outer_;
-  };
-
-  friend class ParseHandler;
-
-  void IncomingStartElement(XmlParseContext * pctx,
-               const char * name, const char ** atts);
-  void IncomingEndElement(XmlParseContext * pctx,
-               const char * name);
-  void IncomingCharacterData(XmlParseContext * pctx,
-               const char * text, int len);
-  void IncomingError(XmlParseContext * pctx,
-               XML_Error errCode);
-
-  XmppStanzaParseHandler * psph_;
-  ParseHandler innerHandler_;
-  XmlParser parser_;
-  int depth_;
-  XmlBuilder builder_;
-
- };
-
-
-}
-
-#endif  // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPSTANZAPARSER_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc b/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc
deleted file mode 100644
index 34a9503..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h"
-
-using jingle_xmpp::QName;
-using jingle_xmpp::XmlElement;
-using jingle_xmpp::XmppStanzaParser;
-using jingle_xmpp::XmppStanzaParseHandler;
-
-class XmppStanzaParserTestHandler : public XmppStanzaParseHandler {
- public:
-  virtual void StartStream(const XmlElement * element) {
-    ss_ << "START" << element->Str();
-  }
-  virtual void Stanza(const XmlElement * element) {
-    ss_ << "STANZA" << element->Str();
-  }
-  virtual void EndStream() {
-    ss_ << "END";
-  }
-  virtual void XmlError() {
-    ss_ << "ERROR";
-  }
-
-  std::string Str() {
-    return ss_.str();
-  }
-
-  std::string StrClear() {
-    std::string result = ss_.str();
-    ss_.str("");
-    return result;
-  }
-
- private:
-  std::stringstream ss_;
-};
-
-
-TEST(XmppStanzaParserTest, TestTrivial) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<trivial/>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<trivial/>END", handler.StrClear());
-}
-
-TEST(XmppStanzaParserTest, TestStanzaAtATime) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
-      "xmlns:stream=\"str\"/>", handler.StrClear());
-
-  fragment = "<message type='foo'><body>hello</body></message>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">"
-      "<c:body>hello</c:body></c:message>", handler.StrClear());
-
-  fragment = " SOME TEXT TO IGNORE ";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  fragment = "<iq type='set' id='123'><abc xmlns='def'/></iq>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("STANZA<c:iq type=\"set\" id=\"123\" xmlns:c=\"j:c\">"
-      "<abc xmlns=\"def\"/></c:iq>", handler.StrClear());
-
-  fragment = "</stream:stream>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("END", handler.StrClear());
-}
-
-TEST(XmppStanzaParserTest, TestFragmentedStanzas) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<stream:stream id='abc' xmlns='j:c' xml";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  fragment = "ns:stream='str'><message type='foo'><body>hel";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
-      "xmlns:stream=\"str\"/>", handler.StrClear());
-
-  fragment = "lo</body></message> IGNORE ME <iq type='set' id='123'>"
-      "<abc xmlns='def'/></iq></st";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">"
-      "<c:body>hello</c:body></c:message>STANZA<c:iq type=\"set\" id=\"123\" "
-      "xmlns:c=\"j:c\"><abc xmlns=\"def\"/></c:iq>", handler.StrClear());
-
-  fragment = "ream:stream>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("END", handler.StrClear());
-}
-
-TEST(XmppStanzaParserTest, TestReset) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<stream:stream id='abc' xmlns='j:c' xml";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  parser.Reset();
-  fragment = "<stream:stream id='abc' xmlns='j:c' xml";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  fragment = "ns:stream='str'><message type='foo'><body>hel";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
-      "xmlns:stream=\"str\"/>", handler.StrClear());
-  parser.Reset();
-
-  fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
-      "xmlns:stream=\"str\"/>", handler.StrClear());
-
-  fragment = "<message type='foo'><body>hello</body></message>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">"
-      "<c:body>hello</c:body></c:message>", handler.StrClear());
-}
-
-TEST(XmppStanzaParserTest, TestError) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<-foobar/>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("ERROR", handler.StrClear());
-
-  parser.Reset();
-  fragment = "<stream:stream/>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("ERROR", handler.StrClear());
-  parser.Reset();
-
-  fragment = "ns:stream='str'><message type='foo'><body>hel";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("ERROR", handler.StrClear());
-  parser.Reset();
-
-  fragment = "<stream:stream xmlns:stream='st' xmlns='jc'>"
-      "<foo/><bar><st:foobar/></bar>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream xmlns:stream=\"st\" xmlns=\"jc\"/>STANZA"
-      "<jc:foo xmlns:jc=\"jc\"/>ERROR", handler.StrClear());
-}
diff --git a/third_party/libjingle_xmpp/xmpp/xmpptask.cc b/third_party/libjingle_xmpp/xmpp/xmpptask.cc
deleted file mode 100644
index c96e3d7..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmpptask.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "third_party/libjingle_xmpp/xmpp/constants.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppclient.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-#include "third_party/libjingle_xmpp/xmpp/xmpptask.h"
-
-namespace jingle_xmpp {
-
-XmppClientInterface::XmppClientInterface() {
-}
-
-XmppClientInterface::~XmppClientInterface() {
-}
-
-XmppTask::XmppTask(XmppTaskParentInterface* parent,
-                   XmppEngine::HandlerLevel level)
-    : XmppTaskBase(parent), stopped_(false) {
-#if !defined(NDEBUG)
-  debug_force_timeout_ = false;
-#endif
-
-  id_ = GetClient()->NextId();
-  GetClient()->AddXmppTask(this, level);
-  GetClient()->SignalDisconnected.connect(this, &XmppTask::OnDisconnect);
-}
-
-XmppTask::~XmppTask() {
-  StopImpl();
-}
-
-void XmppTask::StopImpl() {
-  while (NextStanza() != NULL) {}
-  if (!stopped_) {
-    GetClient()->RemoveXmppTask(this);
-    GetClient()->SignalDisconnected.disconnect(this);
-    stopped_ = true;
-  }
-}
-
-XmppReturnStatus XmppTask::SendStanza(const XmlElement* stanza) {
-  if (stopped_)
-    return XMPP_RETURN_BADSTATE;
-  return GetClient()->SendStanza(stanza);
-}
-
-XmppReturnStatus XmppTask::SendStanzaError(const XmlElement* element_original,
-                                           XmppStanzaError code,
-                                           const std::string& text) {
-  if (stopped_)
-    return XMPP_RETURN_BADSTATE;
-  return GetClient()->SendStanzaError(element_original, code, text);
-}
-
-void XmppTask::Stop() {
-  StopImpl();
-  Task::Stop();
-}
-
-void XmppTask::OnDisconnect() {
-  Error();
-}
-
-void XmppTask::QueueStanza(const XmlElement* stanza) {
-#if !defined(NDEBUG)
-  if (debug_force_timeout_)
-    return;
-#endif
-
-  stanza_queue_.push_back(new XmlElement(*stanza));
-  Wake();
-}
-
-const XmlElement* XmppTask::NextStanza() {
-  XmlElement* result = NULL;
-  if (!stanza_queue_.empty()) {
-    result = stanza_queue_.front();
-    stanza_queue_.pop_front();
-  }
-  next_stanza_.reset(result);
-  return result;
-}
-
-XmlElement* XmppTask::MakeIq(const std::string& type,
-                             const jingle_xmpp::Jid& to,
-                             const std::string& id) {
-  XmlElement* result = new XmlElement(QN_IQ);
-  if (!type.empty())
-    result->AddAttr(QN_TYPE, type);
-  if (!to.IsEmpty())
-    result->AddAttr(QN_TO, to.Str());
-  if (!id.empty())
-    result->AddAttr(QN_ID, id);
-  return result;
-}
-
-XmlElement* XmppTask::MakeIqResult(const XmlElement * query) {
-  XmlElement* result = new XmlElement(QN_IQ);
-  result->AddAttr(QN_TYPE, STR_RESULT);
-  if (query->HasAttr(QN_FROM)) {
-    result->AddAttr(QN_TO, query->Attr(QN_FROM));
-  }
-  result->AddAttr(QN_ID, query->Attr(QN_ID));
-  return result;
-}
-
-bool XmppTask::MatchResponseIq(const XmlElement* stanza,
-                               const Jid& to,
-                               const std::string& id) {
-  if (stanza->Name() != QN_IQ)
-    return false;
-
-  if (stanza->Attr(QN_ID) != id)
-    return false;
-
-  return MatchStanzaFrom(stanza, to);
-}
-
-bool XmppTask::MatchStanzaFrom(const XmlElement* stanza,
-                               const Jid& to) {
-  Jid from(stanza->Attr(QN_FROM));
-  if (from == to)
-    return true;
-
-  // We address the server as "", check if we are doing so here.
-  if (!to.IsEmpty())
-    return false;
-
-  // It is legal for the server to identify itself with "domain" or
-  // "myself@domain"
-  Jid me = GetClient()->jid();
-  return (from == Jid(me.domain())) || (from == me.BareJid());
-}
-
-bool XmppTask::MatchRequestIq(const XmlElement* stanza,
-                              const std::string& type,
-                              const QName& qn) {
-  if (stanza->Name() != QN_IQ)
-    return false;
-
-  if (stanza->Attr(QN_TYPE) != type)
-    return false;
-
-  if (stanza->FirstNamed(qn) == NULL)
-    return false;
-
-  return true;
-}
-
-}
diff --git a/third_party/libjingle_xmpp/xmpp/xmpptask.h b/third_party/libjingle_xmpp/xmpp/xmpptask.h
deleted file mode 100644
index 0fa967b..0000000
--- a/third_party/libjingle_xmpp/xmpp/xmpptask.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPTASK_H_
-#define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPTASK_H_
-
-#include <deque>
-#include <memory>
-#include <string>
-
-#include "third_party/libjingle_xmpp/task_runner/task.h"
-#include "third_party/libjingle_xmpp/task_runner/taskparent.h"
-#include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
-#include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
-
-namespace jingle_xmpp {
-
-/////////////////////////////////////////////////////////////////////
-//
-// XMPPTASK
-//
-/////////////////////////////////////////////////////////////////////
-//
-// See Task and XmppClient first.
-//
-// XmppTask is a task that is designed to go underneath XmppClient and be
-// useful there.  It has a way of finding its XmppClient parent so you
-// can have it nested arbitrarily deep under an XmppClient and it can
-// still find the XMPP services.
-//
-// Tasks register themselves to listen to particular kinds of stanzas
-// that are sent out by the client.  Rather than processing stanzas
-// right away, they should decide if they own the sent stanza,
-// and if so, queue it and Wake() the task, or if a stanza does not belong
-// to you, return false right away so the next XmppTask can take a crack.
-// This technique (synchronous recognize, but asynchronous processing)
-// allows you to have arbitrary logic for recognizing stanzas yet still,
-// for example, disconnect a client while processing a stanza -
-// without reentrancy problems.
-//
-/////////////////////////////////////////////////////////////////////
-
-class XmppTask;
-
-// XmppClientInterface is an abstract interface for sending and
-// handling stanzas.  It can be implemented for unit tests or
-// different network environments.  It will usually be implemented by
-// XmppClient.
-class XmppClientInterface {
- public:
-  XmppClientInterface();
-
-  XmppClientInterface(const XmppClientInterface&) = delete;
-  XmppClientInterface& operator=(const XmppClientInterface&) = delete;
-
-  virtual ~XmppClientInterface();
-
-  virtual XmppEngine::State GetState() const = 0;
-  virtual const Jid& jid() const = 0;
-  virtual std::string NextId() = 0;
-  virtual XmppReturnStatus SendStanza(const XmlElement* stanza) = 0;
-  virtual XmppReturnStatus SendStanzaError(const XmlElement* original_stanza,
-                                           XmppStanzaError error_code,
-                                           const std::string& message) = 0;
-  virtual void AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) = 0;
-  virtual void RemoveXmppTask(XmppTask* task) = 0;
-  sigslot::signal0<> SignalDisconnected;
-};
-
-// XmppTaskParentInterface is the interface require for any parent of
-// an XmppTask.  It needs, for example, a way to get an
-// XmppClientInterface.
-
-// We really ought to inherit from a TaskParentInterface, but we tried
-// that and it's way too complicated to change
-// Task/TaskParent/TaskRunner.  For now, this works.
-class XmppTaskParentInterface : public jingle_xmpp::Task {
- public:
-  explicit XmppTaskParentInterface(jingle_xmpp::TaskParent* parent)
-      : Task(parent) {
-  }
-
-  XmppTaskParentInterface(const XmppTaskParentInterface&) = delete;
-  XmppTaskParentInterface& operator=(const XmppTaskParentInterface&) = delete;
-
-  virtual ~XmppTaskParentInterface() {}
-
-  virtual XmppClientInterface* GetClient() = 0;
-};
-
-class XmppTaskBase : public XmppTaskParentInterface {
- public:
-  explicit XmppTaskBase(XmppTaskParentInterface* parent)
-      : XmppTaskParentInterface(parent),
-        parent_(parent) {
-  }
-
-  XmppTaskBase(const XmppTaskBase&) = delete;
-  XmppTaskBase& operator=(const XmppTaskBase&) = delete;
-
-  virtual ~XmppTaskBase() {}
-
-  virtual XmppClientInterface* GetClient() {
-    return parent_->GetClient();
-  }
-
- protected:
-  XmppTaskParentInterface* parent_;
-};
-
-class XmppTask : public XmppTaskBase,
-                 public XmppStanzaHandler,
-                 public sigslot::has_slots<>
-{
- public:
-  XmppTask(XmppTaskParentInterface* parent,
-           XmppEngine::HandlerLevel level = XmppEngine::HL_NONE);
-  virtual ~XmppTask();
-
-  std::string task_id() const { return id_; }
-  void set_task_id(std::string id) { id_ = id; }
-
-#if !defined(NDEBUG)
-  void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; }
-#endif
-
-  virtual bool HandleStanza(const XmlElement* stanza) { return false; }
-
- protected:
-  XmppReturnStatus SendStanza(const XmlElement* stanza);
-  XmppReturnStatus SetResult(const std::string& code);
-  XmppReturnStatus SendStanzaError(const XmlElement* element_original,
-                                   XmppStanzaError code,
-                                   const std::string& text);
-
-  virtual void Stop();
-  virtual void OnDisconnect();
-
-  virtual void QueueStanza(const XmlElement* stanza);
-  const XmlElement* NextStanza();
-
-  bool MatchStanzaFrom(const XmlElement* stanza, const Jid& match_jid);
-
-  bool MatchResponseIq(const XmlElement* stanza, const Jid& to,
-                       const std::string& task_id);
-
-  static bool MatchRequestIq(const XmlElement* stanza, const std::string& type,
-                             const QName& qn);
-  static XmlElement *MakeIqResult(const XmlElement* query);
-  static XmlElement *MakeIq(const std::string& type,
-                            const Jid& to, const std::string& task_id);
-
-  // Returns true if the task is under the specified rate limit and updates the
-  // rate limit accordingly
-  bool VerifyTaskRateLimit(const std::string task_name, int max_count,
-                           int per_x_seconds);
-
-private:
-  void StopImpl();
-
-  bool stopped_;
-  std::deque<XmlElement*> stanza_queue_;
-  std::unique_ptr<XmlElement> next_stanza_;
-  std::string id_;
-
-#if !defined(NDEBUG)
-  bool debug_force_timeout_;
-#endif
-};
-
-}  // namespace jingle_xmpp
-
-#endif // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPTASK_H_
diff --git a/third_party/tcmalloc/BUILD.gn b/third_party/tcmalloc/BUILD.gn
deleted file mode 100644
index 970b7a0..0000000
--- a/third_party/tcmalloc/BUILD.gn
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 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.
-
-import("//build/config/compiler/compiler.gni")
-
-executable("addr2line-pdb") {
-  sources = [ "chromium/src/windows/addr2line-pdb.c" ]
-
-  configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [ "//build/config/compiler:no_chromium_code" ]
-}
diff --git a/third_party/tcmalloc/DEPS b/third_party/tcmalloc/DEPS
deleted file mode 100644
index 950de69..0000000
--- a/third_party/tcmalloc/DEPS
+++ /dev/null
@@ -1,12 +0,0 @@
-include_rules = [
-  '+base',
-  '+build',
-  '+gperftools',
-  '+tests',
-  '+../config.h',
-  # The auto-generated gperftools config.h file uses relative paths to
-  # include headers from the windows/ subfolder. Adding the relative paths
-  # to DEPS to minimize manual edits on future uprevs.
-  '+windows/mingw.h',
-  '+windows/port.h',
-]
diff --git a/third_party/tcmalloc/DIR_METADATA b/third_party/tcmalloc/DIR_METADATA
deleted file mode 100644
index 643d2bac..0000000
--- a/third_party/tcmalloc/DIR_METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-monorail: {
-  component: "Internals>Core"
-}
diff --git a/third_party/tcmalloc/LICENSE b/third_party/tcmalloc/LICENSE
deleted file mode 100644
index 13e84762..0000000
--- a/third_party/tcmalloc/LICENSE
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/tcmalloc/OWNERS b/third_party/tcmalloc/OWNERS
deleted file mode 100644
index aeb9549..0000000
--- a/third_party/tcmalloc/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-primiano@chromium.org
-wfh@chromium.org
diff --git a/third_party/tcmalloc/README.chromium b/third_party/tcmalloc/README.chromium
deleted file mode 100644
index fe7ef63..0000000
--- a/third_party/tcmalloc/README.chromium
+++ /dev/null
@@ -1,84 +0,0 @@
-Name: tcmalloc
-Short Name: gperftools
-URL: http://github.com/gperftools/gperftools
-Version: 2.7
-Revision: Unknown
-Security Critical: yes
-License: BSD
-
-Description:
-This contains Chromium's locally patched copy of tcmalloc.
-
-Contents:
-
-  chromium/
-
-    The chromium patched sources, copied from the vendor/
-    subdirectory and containing our local modifications.
-
-    We only copy over the vendor/src/ subdirectory (the only piece
-    we need) but still leave it in a chromium/src/ subdirectory to
-    keep the directory structures in parallel.
-
-  vendor/
-
-    Vanilla sources from upstream:
-
-      http://github.com/gperftools/gperftools
-
-    The current revision is 2.7, pulled in July 2018.
-
-HOWTOs:
-
-  1. Pull from upstream
-    $ git clone https://gitbub.com/gperftools/gperftools vendor
-  2. Checkout and remove git metadata
-     $ cd vendor && git checkout gperftools-2.7 && rm .rf .git
-  3. Mirror the src folder
-     $ cd  .. && rsync -av --delete vendor/src chromium/src
-
-
-Modifications:
-- Converted to utf-8 with: vim +"argdo write ++enc=utf-8" *.h *.c
-- Added support for android.
-- Use NULL instead of static_cast<uintptr_t>(0) in stack_trace_table.cc,
-  for -std=c++11 compatibility.
-- Added support for pseudo-stack heap profiling via a callback to retrieve a
-  simulated stack from the embedding application.
-- Inserted spaces around PRIx64, SCNx64 and friends, for c++11 compatibility.
-- Fix sprintf formatting warning in MaybeDumpProfileLocked
-- Fix logging issues in android
-- Changed DEFINE_foo macros to ignore envname unless ENABLE_PROFILING is defined
-- Changed DEFINE_string to define const char*s instead of strings
-- Disabled HEAPPROFILE envvar unless ENABLE_PROFILING is defined
-- Add "ARMv8-a" to the supporting list of ARM architecture
-- Add generic.total_physical_bytes property to MallocExtension
-- Conditionally define HAVE_VDSO_SUPPORT only on linux_x86 to avoid static initializers
-- Add TC_MALLOPT_IS_OVERRIDDEN_BY_TCMALLOC mallopt() arg
-- Added tc_malloc_skip_new_handler.
-- Added TCMALLOC_DONT_REPLACE_SYSTEM_ALLOC which bypasses the libc_override logic.
-- Backported 7df7f14 "issue-693: enable futex usage on arm" from upstream.
-- Don't use the tls model 'initial-exec' on arm with gcc.
-- Update addr2line-pdb.c to fix format string errors and use relative addresses
-  matching linux's behavior more closely.
-- Changed kint64min to not depend on undefined behavior.
-- Fix potential missing nul character in symbol names produced by addr2line-pdb.
-- Remove superfluous size_t value >= 0 check.
-- Make kFooType in tcmalloc.cc truly const.
-- Added support for mips64el.
-- Pulled SuggestedDelayNS() implementation for 32bit architectures which do not support 64bit atomicity
-- Pulled several mipsel related changes from lss project to fix compile errors
-- Fixed line endings in vendor/README_windows.txt to Unix (LF)
-- Removed have_futex from spinlock_linux-inl.h; assume it's always there
-- Add thread-safe support to query and update the heap sampling period
-- Remove use of LINKER_INITIALIZED in page_heap_allocator.h, to enable the
-  compiler to optimize away a static constructor
-- Include <atomic> in malloc_extension.h due to std::atomic usage
-- Precompute the pointer mask for doubly linked free lists instead of computing it on each access.
-- Move spinlock to function static variable to fix static initializer check error.
-- Enable ASLR support on both Linux and ChromeOS
-- Remove unused base::subtle::Acquire_Store/Release_Load (https://github.com/gperftools/gperftools/pull/1249)
-- Fix thread-safety annotations (https://github.com/gperftools/gperftools/pull/1251)
-- Fixed -Wimplicit-int-float-conversion.
-- Fixed %rsp register clobber in linux_syscall_support.h (https://github.com/gperftools/gperftools/issues/1076)
-- Inlining of DISALLOW_COPY_AND_ASSIGN() macros
diff --git a/third_party/tcmalloc/chromium/src/addressmap-inl.h b/third_party/tcmalloc/chromium/src/addressmap-inl.h
deleted file mode 100644
index fd1dc5b..0000000
--- a/third_party/tcmalloc/chromium/src/addressmap-inl.h
+++ /dev/null
@@ -1,422 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// A fast map from addresses to values.  Assumes that addresses are
-// clustered.  The main use is intended to be for heap-profiling.
-// May be too memory-hungry for other uses.
-//
-// We use a user-defined allocator/de-allocator so that we can use
-// this data structure during heap-profiling.
-//
-// IMPLEMENTATION DETAIL:
-//
-// Some default definitions/parameters:
-//  * Block      -- aligned 128-byte region of the address space
-//  * Cluster    -- aligned 1-MB region of the address space
-//  * Block-ID   -- block-number within a cluster
-//  * Cluster-ID -- Starting address of cluster divided by cluster size
-//
-// We use a three-level map to represent the state:
-//  1. A hash-table maps from a cluster-ID to the data for that cluster.
-//  2. For each non-empty cluster we keep an array indexed by
-//     block-ID tht points to the first entry in the linked-list
-//     for the block.
-//  3. At the bottom, we keep a singly-linked list of all
-//     entries in a block (for non-empty blocks).
-//
-//    hash table
-//  +-------------+
-//  | id->cluster |---> ...
-//  |     ...     |
-//  | id->cluster |--->  Cluster
-//  +-------------+     +-------+    Data for one block
-//                      |  nil  |   +------------------------------------+
-//                      |   ----+---|->[addr/value]-->[addr/value]-->... |
-//                      |  nil  |   +------------------------------------+
-//                      |   ----+--> ...
-//                      |  nil  |
-//                      |  ...  |
-//                      +-------+
-//
-// Note that we require zero-bytes of overhead for completely empty
-// clusters.  The minimum space requirement for a cluster is the size
-// of the hash-table entry plus a pointer value for each block in
-// the cluster.  Empty blocks impose no extra space requirement.
-//
-// The cost of a lookup is:
-//      a. A hash-table lookup to find the cluster
-//      b. An array access in the cluster structure
-//      c. A traversal over the linked-list for a block
-
-#ifndef BASE_ADDRESSMAP_INL_H_
-#define BASE_ADDRESSMAP_INL_H_
-
-#include "config.h"
-#include <stddef.h>
-#include <string.h>
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uint16_t (ISO naming madness)
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uint16_t might be defined
-#else
-#include <sys/types.h>          // our last best hope
-#endif
-
-// This class is thread-unsafe -- that is, instances of this class can
-// not be accessed concurrently by multiple threads -- because the
-// callback function for Iterate() may mutate contained values. If the
-// callback functions you pass do not mutate their Value* argument,
-// AddressMap can be treated as thread-compatible -- that is, it's
-// safe for multiple threads to call "const" methods on this class,
-// but not safe for one thread to call const methods on this class
-// while another thread is calling non-const methods on the class.
-template <class Value>
-class AddressMap {
- public:
-  typedef void* (*Allocator)(size_t size);
-  typedef void  (*DeAllocator)(void* ptr);
-  typedef const void* Key;
-
-  // Create an AddressMap that uses the specified allocator/deallocator.
-  // The allocator/deallocator should behave like malloc/free.
-  // For instance, the allocator does not need to return initialized memory.
-  AddressMap(Allocator alloc, DeAllocator dealloc);
-  ~AddressMap();
-
-  // If the map contains an entry for "key", return it. Else return NULL.
-  inline const Value* Find(Key key) const;
-  inline Value* FindMutable(Key key);
-
-  // Insert <key,value> into the map.  Any old value associated
-  // with key is forgotten.
-  void Insert(Key key, Value value);
-
-  // Remove any entry for key in the map.  If an entry was found
-  // and removed, stores the associated value in "*removed_value"
-  // and returns true.  Else returns false.
-  bool FindAndRemove(Key key, Value* removed_value);
-
-  // Similar to Find but we assume that keys are addresses of non-overlapping
-  // memory ranges whose sizes are given by size_func.
-  // If the map contains a range into which "key" points
-  // (at its start or inside of it, but not at the end),
-  // return the address of the associated value
-  // and store its key in "*res_key".
-  // Else return NULL.
-  // max_size specifies largest range size possibly in existence now.
-  typedef size_t (*ValueSizeFunc)(const Value& v);
-  const Value* FindInside(ValueSizeFunc size_func, size_t max_size,
-                          Key key, Key* res_key);
-
-  // Iterate over the address map calling 'callback'
-  // for all stored key-value pairs and passing 'arg' to it.
-  // We don't use full Closure/Callback machinery not to add
-  // unnecessary dependencies to this class with low-level uses.
-  template<class Type>
-  inline void Iterate(void (*callback)(Key, Value*, Type), Type arg) const;
-
- private:
-  typedef uintptr_t Number;
-
-  // The implementation assumes that addresses inserted into the map
-  // will be clustered.  We take advantage of this fact by splitting
-  // up the address-space into blocks and using a linked-list entry
-  // for each block.
-
-  // Size of each block.  There is one linked-list for each block, so
-  // do not make the block-size too big.  Oterwise, a lot of time
-  // will be spent traversing linked lists.
-  static const int kBlockBits = 7;
-  static const int kBlockSize = 1 << kBlockBits;
-
-  // Entry kept in per-block linked-list
-  struct Entry {
-    Entry* next;
-    Key    key;
-    Value  value;
-  };
-
-  // We further group a sequence of consecutive blocks into a cluster.
-  // The data for a cluster is represented as a dense array of
-  // linked-lists, one list per contained block.
-  static const int kClusterBits = 13;
-  static const Number kClusterSize = 1 << (kBlockBits + kClusterBits);
-  static const int kClusterBlocks = 1 << kClusterBits;
-
-  // We use a simple chaining hash-table to represent the clusters.
-  struct Cluster {
-    Cluster* next;                      // Next cluster in hash table chain
-    Number   id;                        // Cluster ID
-    Entry*   blocks[kClusterBlocks];    // Per-block linked-lists
-  };
-
-  // Number of hash-table entries.  With the block-size/cluster-size
-  // defined above, each cluster covers 1 MB, so an 4K entry
-  // hash-table will give an average hash-chain length of 1 for 4GB of
-  // in-use memory.
-  static const int kHashBits = 12;
-  static const int kHashSize = 1 << 12;
-
-  // Number of entry objects allocated at a time
-  static const int ALLOC_COUNT = 64;
-
-  Cluster**     hashtable_;              // The hash-table
-  Entry*        free_;                   // Free list of unused Entry objects
-
-  // Multiplicative hash function:
-  // The value "kHashMultiplier" is the bottom 32 bits of
-  //    int((sqrt(5)-1)/2 * 2^32)
-  // This is a good multiplier as suggested in CLR, Knuth.  The hash
-  // value is taken to be the top "k" bits of the bottom 32 bits
-  // of the muliplied value.
-  static const uint32_t kHashMultiplier = 2654435769u;
-  static int HashInt(Number x) {
-    // Multiply by a constant and take the top bits of the result.
-    const uint32_t m = static_cast<uint32_t>(x) * kHashMultiplier;
-    return static_cast<int>(m >> (32 - kHashBits));
-  }
-
-  // Find cluster object for specified address.  If not found
-  // and "create" is true, create the object.  If not found
-  // and "create" is false, return NULL.
-  //
-  // This method is bitwise-const if create is false.
-  Cluster* FindCluster(Number address, bool create) {
-    // Look in hashtable
-    const Number cluster_id = address >> (kBlockBits + kClusterBits);
-    const int h = HashInt(cluster_id);
-    for (Cluster* c = hashtable_[h]; c != NULL; c = c->next) {
-      if (c->id == cluster_id) {
-        return c;
-      }
-    }
-
-    // Create cluster if necessary
-    if (create) {
-      Cluster* c = New<Cluster>(1);
-      c->id = cluster_id;
-      c->next = hashtable_[h];
-      hashtable_[h] = c;
-      return c;
-    }
-    return NULL;
-  }
-
-  // Return the block ID for an address within its cluster
-  static int BlockID(Number address) {
-    return (address >> kBlockBits) & (kClusterBlocks - 1);
-  }
-
-  //--------------------------------------------------------------
-  // Memory management -- we keep all objects we allocate linked
-  // together in a singly linked list so we can get rid of them
-  // when we are all done.  Furthermore, we allow the client to
-  // pass in custom memory allocator/deallocator routines.
-  //--------------------------------------------------------------
-  struct Object {
-    Object* next;
-    // The real data starts here
-  };
-
-  Allocator     alloc_;                 // The allocator
-  DeAllocator   dealloc_;               // The deallocator
-  Object*       allocated_;             // List of allocated objects
-
-  // Allocates a zeroed array of T with length "num".  Also inserts
-  // the allocated block into a linked list so it can be deallocated
-  // when we are all done.
-  template <class T> T* New(int num) {
-    void* ptr = (*alloc_)(sizeof(Object) + num*sizeof(T));
-    memset(ptr, 0, sizeof(Object) + num*sizeof(T));
-    Object* obj = reinterpret_cast<Object*>(ptr);
-    obj->next = allocated_;
-    allocated_ = obj;
-    return reinterpret_cast<T*>(reinterpret_cast<Object*>(ptr) + 1);
-  }
-};
-
-// More implementation details follow:
-
-template <class Value>
-AddressMap<Value>::AddressMap(Allocator alloc, DeAllocator dealloc)
-  : free_(NULL),
-    alloc_(alloc),
-    dealloc_(dealloc),
-    allocated_(NULL) {
-  hashtable_ = New<Cluster*>(kHashSize);
-}
-
-template <class Value>
-AddressMap<Value>::~AddressMap() {
-  // De-allocate all of the objects we allocated
-  for (Object* obj = allocated_; obj != NULL; /**/) {
-    Object* next = obj->next;
-    (*dealloc_)(obj);
-    obj = next;
-  }
-}
-
-template <class Value>
-inline const Value* AddressMap<Value>::Find(Key key) const {
-  return const_cast<AddressMap*>(this)->FindMutable(key);
-}
-
-template <class Value>
-inline Value* AddressMap<Value>::FindMutable(Key key) {
-  const Number num = reinterpret_cast<Number>(key);
-  const Cluster* const c = FindCluster(num, false/*do not create*/);
-  if (c != NULL) {
-    for (Entry* e = c->blocks[BlockID(num)]; e != NULL; e = e->next) {
-      if (e->key == key) {
-        return &e->value;
-      }
-    }
-  }
-  return NULL;
-}
-
-template <class Value>
-void AddressMap<Value>::Insert(Key key, Value value) {
-  const Number num = reinterpret_cast<Number>(key);
-  Cluster* const c = FindCluster(num, true/*create*/);
-
-  // Look in linked-list for this block
-  const int block = BlockID(num);
-  for (Entry* e = c->blocks[block]; e != NULL; e = e->next) {
-    if (e->key == key) {
-      e->value = value;
-      return;
-    }
-  }
-
-  // Create entry
-  if (free_ == NULL) {
-    // Allocate a new batch of entries and add to free-list
-    Entry* array = New<Entry>(ALLOC_COUNT);
-    for (int i = 0; i < ALLOC_COUNT-1; i++) {
-      array[i].next = &array[i+1];
-    }
-    array[ALLOC_COUNT-1].next = free_;
-    free_ = &array[0];
-  }
-  Entry* e = free_;
-  free_ = e->next;
-  e->key = key;
-  e->value = value;
-  e->next = c->blocks[block];
-  c->blocks[block] = e;
-}
-
-template <class Value>
-bool AddressMap<Value>::FindAndRemove(Key key, Value* removed_value) {
-  const Number num = reinterpret_cast<Number>(key);
-  Cluster* const c = FindCluster(num, false/*do not create*/);
-  if (c != NULL) {
-    for (Entry** p = &c->blocks[BlockID(num)]; *p != NULL; p = &(*p)->next) {
-      Entry* e = *p;
-      if (e->key == key) {
-        *removed_value = e->value;
-        *p = e->next;         // Remove e from linked-list
-        e->next = free_;      // Add e to free-list
-        free_ = e;
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-template <class Value>
-const Value* AddressMap<Value>::FindInside(ValueSizeFunc size_func,
-                                           size_t max_size,
-                                           Key key,
-                                           Key* res_key) {
-  const Number key_num = reinterpret_cast<Number>(key);
-  Number num = key_num;  // we'll move this to move back through the clusters
-  while (1) {
-    const Cluster* c = FindCluster(num, false/*do not create*/);
-    if (c != NULL) {
-      while (1) {
-        const int block = BlockID(num);
-        bool had_smaller_key = false;
-        for (const Entry* e = c->blocks[block]; e != NULL; e = e->next) {
-          const Number e_num = reinterpret_cast<Number>(e->key);
-          if (e_num <= key_num) {
-            if (e_num == key_num  ||  // to handle 0-sized ranges
-                key_num < e_num + (*size_func)(e->value)) {
-              *res_key = e->key;
-              return &e->value;
-            }
-            had_smaller_key = true;
-          }
-        }
-        if (had_smaller_key) return NULL;  // got a range before 'key'
-                                           // and it did not contain 'key'
-        if (block == 0) break;
-        // try address-wise previous block
-        num |= kBlockSize - 1;  // start at the last addr of prev block
-        num -= kBlockSize;
-        if (key_num - num > max_size) return NULL;
-      }
-    }
-    if (num < kClusterSize) return NULL;  // first cluster
-    // go to address-wise previous cluster to try
-    num |= kClusterSize - 1;  // start at the last block of previous cluster
-    num -= kClusterSize;
-    if (key_num - num > max_size) return NULL;
-      // Having max_size to limit the search is crucial: else
-      // we have to traverse a lot of empty clusters (or blocks).
-      // We can avoid needing max_size if we put clusters into
-      // a search tree, but performance suffers considerably
-      // if we use this approach by using stl::set.
-  }
-}
-
-template <class Value>
-template <class Type>
-inline void AddressMap<Value>::Iterate(void (*callback)(Key, Value*, Type),
-                                       Type arg) const {
-  // We could optimize this by traversing only non-empty clusters and/or blocks
-  // but it does not speed up heap-checker noticeably.
-  for (int h = 0; h < kHashSize; ++h) {
-    for (const Cluster* c = hashtable_[h]; c != NULL; c = c->next) {
-      for (int b = 0; b < kClusterBlocks; ++b) {
-        for (Entry* e = c->blocks[b]; e != NULL; e = e->next) {
-          callback(e->key, &e->value, arg);
-        }
-      }
-    }
-  }
-}
-
-#endif  // BASE_ADDRESSMAP_INL_H_
diff --git a/third_party/tcmalloc/chromium/src/base/abort.cc b/third_party/tcmalloc/chromium/src/base/abort.cc
deleted file mode 100755
index 89c9ab44..0000000
--- a/third_party/tcmalloc/chromium/src/base/abort.cc
+++ /dev/null
@@ -1,18 +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/abort.h"
-
-#include "base/basictypes.h"
-
-namespace tcmalloc {
-
-// Try not to inline so we can find Abort() call from stack trace.
-ATTRIBUTE_NOINLINE void Abort() {
-  // Make a segmentation fault to force abort. Writing to a specific address
-  // so it's easier to find on crash stacks.
-  *(reinterpret_cast<volatile char*>(NULL) + 57) = 0x21;
-}
-
-} // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/base/abort.h b/third_party/tcmalloc/chromium/src/base/abort.h
deleted file mode 100644
index 18ec319..0000000
--- a/third_party/tcmalloc/chromium/src/base/abort.h
+++ /dev/null
@@ -1,19 +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.
-//
-// ---
-// On some platforms abort() is implemented in a way that Chrome's crash
-// reporter treats it as a normal exit. See issue:
-// http://code.google.com/p/chromium/issues/detail?id=118665
-// So we replace abort with a segmentation fault, then crash reporter can
-// always detect.
-
-#ifndef BASE_ABORT_H_
-#define BASE_ABORT_H_
-
-namespace tcmalloc {
-void Abort();
-} // namespace tcmalloc
-
-#endif  // BASE_ABORT_H_
diff --git a/third_party/tcmalloc/chromium/src/base/arm_instruction_set_select.h b/third_party/tcmalloc/chromium/src/base/arm_instruction_set_select.h
deleted file mode 100644
index 6fde685..0000000
--- a/third_party/tcmalloc/chromium/src/base/arm_instruction_set_select.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Alexander Levitskiy
-//
-// Generalizes the plethora of ARM flavors available to an easier to manage set
-// Defs reference is at https://wiki.edubuntu.org/ARM/Thumb2PortingHowto
-
-#ifndef ARM_INSTRUCTION_SET_SELECT_H_
-#define ARM_INSTRUCTION_SET_SELECT_H_
-
-#if defined(__ARM_ARCH_8A__)
-# define ARMV8 1
-#endif
-
-#if defined(ARMV8) || \
-    defined(__ARM_ARCH_7__) || \
-    defined(__ARM_ARCH_7R__) || \
-    defined(__ARM_ARCH_7A__)
-# define ARMV7 1
-#endif
-
-#if defined(ARMV7) || \
-    defined(__ARM_ARCH_6__) || \
-    defined(__ARM_ARCH_6J__) || \
-    defined(__ARM_ARCH_6K__) || \
-    defined(__ARM_ARCH_6Z__) || \
-    defined(__ARM_ARCH_6T2__) || \
-    defined(__ARM_ARCH_6ZK__)
-# define ARMV6 1
-#endif
-
-#if defined(ARMV6) || \
-    defined(__ARM_ARCH_5T__) || \
-    defined(__ARM_ARCH_5E__) || \
-    defined(__ARM_ARCH_5TE__) || \
-    defined(__ARM_ARCH_5TEJ__)
-# define ARMV5 1
-#endif
-
-#if defined(ARMV5) || \
-    defined(__ARM_ARCH_4__) || \
-    defined(__ARM_ARCH_4T__)
-# define ARMV4 1
-#endif
-
-#if defined(ARMV4) || \
-    defined(__ARM_ARCH_3__) || \
-    defined(__ARM_ARCH_3M__)
-# define ARMV3 1
-#endif
-
-#if defined(ARMV3) || \
-    defined(__ARM_ARCH_2__)
-# define ARMV2 1
-#endif
-
-#endif  // ARM_INSTRUCTION_SET_SELECT_H_
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops-internals-arm-generic.h b/third_party/tcmalloc/chromium/src/base/atomicops-internals-arm-generic.h
deleted file mode 100644
index c12a84d3..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops-internals-arm-generic.h
+++ /dev/null
@@ -1,209 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2003, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// ---
-//
-// Author: Lei Zhang, Sasha Levitskiy
-//
-// This file is an internal atomic implementation, use base/atomicops.h instead.
-//
-// LinuxKernelCmpxchg is from Google Gears.
-
-#ifndef BASE_ATOMICOPS_INTERNALS_ARM_GENERIC_H_
-#define BASE_ATOMICOPS_INTERNALS_ARM_GENERIC_H_
-
-#include <stdio.h>
-#include "base/abort.h"
-#include "base/basictypes.h"
-
-typedef int32_t Atomic32;
-
-namespace base {
-namespace subtle {
-
-typedef int64_t Atomic64;
-
-// 0xffff0fc0 is the hard coded address of a function provided by
-// the kernel which implements an atomic compare-exchange. On older
-// ARM architecture revisions (pre-v6) this may be implemented using
-// a syscall. This address is stable, and in active use (hard coded)
-// by at least glibc-2.7 and the Android C library.
-// pLinuxKernelCmpxchg has both acquire and release barrier sematincs.
-typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,
-                                           Atomic32 new_value,
-                                           volatile Atomic32* ptr);
-LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg ATTRIBUTE_WEAK =
-    (LinuxKernelCmpxchgFunc) 0xffff0fc0;
-
-typedef void (*LinuxKernelMemoryBarrierFunc)(void);
-LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier ATTRIBUTE_WEAK =
-    (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
-
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev_value = *ptr;
-  do {
-    if (!pLinuxKernelCmpxchg(old_value, new_value,
-                             const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (pLinuxKernelCmpxchg(old_value, new_value,
-                               const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // pLinuxKernelCmpxchg already has acquire and release barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // pLinuxKernelCmpxchg already has acquire and release barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void MemoryBarrier() {
-  pLinuxKernelMemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-
-// 64-bit versions are not implemented yet.
-
-inline void NotImplementedFatalError(const char *function_name) {
-  fprintf(stderr, "64-bit %s() not implemented on this platform\n",
-          function_name);
-  tcmalloc::Abort();
-}
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  NotImplementedFatalError("NoBarrier_CompareAndSwap");
-  return 0;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  NotImplementedFatalError("NoBarrier_AtomicExchange");
-  return 0;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // pLinuxKernelCmpxchg already has acquire and release barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // pLinuxKernelCmpxchg already has acquire and release barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NotImplementedFatalError("NoBarrier_Store");
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NotImplementedFatalError("Release_Store");
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  NotImplementedFatalError("NoBarrier_Load");
-  return 0;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  NotImplementedFatalError("Atomic64 Acquire_Load");
-  return 0;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  NotImplementedFatalError("Atomic64 Acquire_CompareAndSwap");
-  return 0;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  NotImplementedFatalError("Atomic64 Release_CompareAndSwap");
-  return 0;
-}
-
-}  // namespace base::subtle
-}  // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_ARM_GENERIC_H_
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops-internals-arm-v6plus.h b/third_party/tcmalloc/chromium/src/base/atomicops-internals-arm-v6plus.h
deleted file mode 100644
index afcd79c..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops-internals-arm-v6plus.h
+++ /dev/null
@@ -1,311 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// ---
-//
-// Author: Sasha Levitskiy
-// based on atomicops-internals by Sanjay Ghemawat
-//
-// This file is an internal atomic implementation, use base/atomicops.h instead.
-//
-// This code implements ARM atomics for architectures V6 and  newer.
-
-#ifndef BASE_ATOMICOPS_INTERNALS_ARM_V6PLUS_H_
-#define BASE_ATOMICOPS_INTERNALS_ARM_V6PLUS_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "base/abort.h"
-#include "base/basictypes.h"  // For COMPILE_ASSERT
-
-// The LDREXD and STREXD instructions in ARM all v7 variants or above.  In v6,
-// only some variants support it.  For simplicity, we only use exclusive
-// 64-bit load/store in V7 or above.
-#if defined(ARMV7)
-# define BASE_ATOMICOPS_HAS_LDREXD_AND_STREXD
-#endif
-
-typedef int32_t Atomic32;
-
-namespace base {
-namespace subtle {
-
-typedef int64_t Atomic64;
-
-// 32-bit low-level ops
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 oldval, res;
-  do {
-    __asm__ __volatile__(
-    "ldrex   %1, [%3]\n"
-    "mov     %0, #0\n"
-    "teq     %1, %4\n"
-    // The following IT (if-then) instruction is needed for the subsequent
-    // conditional instruction STREXEQ when compiling in THUMB mode.
-    // In ARM mode, the compiler/assembler will not generate any code for it.
-    "it      eq\n"
-    "strexeq %0, %5, [%3]\n"
-        : "=&r" (res), "=&r" (oldval), "+Qo" (*ptr)
-        : "r" (ptr), "Ir" (old_value), "r" (new_value)
-        : "cc");
-  } while (res);
-  return oldval;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  Atomic32 tmp, old;
-  __asm__ __volatile__(
-      "1:\n"
-      "ldrex  %1, [%2]\n"
-      "strex  %0, %3, [%2]\n"
-      "teq    %0, #0\n"
-      "bne    1b"
-      : "=&r" (tmp), "=&r" (old)
-      : "r" (ptr), "r" (new_value)
-      : "cc", "memory");
-  return old;
-}
-
-inline void MemoryBarrier() {
-#if !defined(ARMV7)
-  uint32_t dest = 0;
-  __asm__ __volatile__("mcr p15,0,%0,c7,c10,5" :"=&r"(dest) : : "memory");
-#else
-  __asm__ __volatile__("dmb" : : : "memory");
-#endif
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_value = NoBarrier_AtomicExchange(ptr, new_value);
-  MemoryBarrier();
-  return old_value;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  MemoryBarrier();
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 value = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  MemoryBarrier();
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-// 64-bit versions are only available if LDREXD and STREXD instructions
-// are available.
-#ifdef BASE_ATOMICOPS_HAS_LDREXD_AND_STREXD
-
-#define BASE_HAS_ATOMIC64 1
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 oldval, res;
-  do {
-    __asm__ __volatile__(
-    "ldrexd   %1, [%3]\n"
-    "mov      %0, #0\n"
-    "teq      %Q1, %Q4\n"
-    // The following IT (if-then) instructions are needed for the subsequent
-    // conditional instructions when compiling in THUMB mode.
-    // In ARM mode, the compiler/assembler will not generate any code for it.
-    "it       eq\n"
-    "teqeq    %R1, %R4\n"
-    "it       eq\n"
-    "strexdeq %0, %5, [%3]\n"
-        : "=&r" (res), "=&r" (oldval), "+Q" (*ptr)
-        : "r" (ptr), "Ir" (old_value), "r" (new_value)
-        : "cc");
-  } while (res);
-  return oldval;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  int store_failed;
-  Atomic64 old;
-  __asm__ __volatile__(
-      "1:\n"
-      "ldrexd  %1, [%2]\n"
-      "strexd  %0, %3, [%2]\n"
-      "teq     %0, #0\n"
-      "bne     1b"
-      : "=&r" (store_failed), "=&r" (old)
-      : "r" (ptr), "r" (new_value)
-      : "cc", "memory");
-  return old;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_value = NoBarrier_AtomicExchange(ptr, new_value);
-  MemoryBarrier();
-  return old_value;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  MemoryBarrier();
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  int store_failed;
-  Atomic64 dummy;
-  __asm__ __volatile__(
-      "1:\n"
-      // Dummy load to lock cache line.
-      "ldrexd  %1, [%3]\n"
-      "strexd  %0, %2, [%3]\n"
-      "teq     %0, #0\n"
-      "bne     1b"
-      : "=&r" (store_failed), "=&r"(dummy)
-      : "r"(value), "r" (ptr)
-      : "cc", "memory");
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  Atomic64 res;
-  __asm__ __volatile__(
-  "ldrexd   %0, [%1]\n"
-  "clrex\n"
-      : "=r" (res)
-      : "r"(ptr), "Q"(*ptr));
-  return res;
-}
-
-#else // BASE_ATOMICOPS_HAS_LDREXD_AND_STREXD
-
-inline void NotImplementedFatalError(const char *function_name) {
-  fprintf(stderr, "64-bit %s() not implemented on this platform\n",
-          function_name);
-  tcmalloc::Abort();
-}
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  NotImplementedFatalError("NoBarrier_CompareAndSwap");
-  return 0;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  NotImplementedFatalError("NoBarrier_AtomicExchange");
-  return 0;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  NotImplementedFatalError("Acquire_AtomicExchange");
-  return 0;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  NotImplementedFatalError("Release_AtomicExchange");
-  return 0;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NotImplementedFatalError("NoBarrier_Store");
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  NotImplementedFatalError("NoBarrier_Load");
-  return 0;
-}
-
-#endif // BASE_ATOMICOPS_HAS_LDREXD_AND_STREXD
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  MemoryBarrier();
-  NoBarrier_Store(ptr, value);
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = NoBarrier_Load(ptr);
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 value = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  MemoryBarrier();
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-}  // namespace subtle ends
-}  // namespace base ends
-
-#endif  // BASE_ATOMICOPS_INTERNALS_ARM_V6PLUS_H_
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops-internals-gcc.h b/third_party/tcmalloc/chromium/src/base/atomicops-internals-gcc.h
deleted file mode 100644
index 0dcf03e..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops-internals-gcc.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, Linaro
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// ---
-//
-// Author: Riku Voipio, riku.voipio@linaro.org
-//
-// atomic primitives implemented with gcc atomic intrinsics:
-// http://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
-//
-
-#ifndef BASE_ATOMICOPS_INTERNALS_GCC_GENERIC_H_
-#define BASE_ATOMICOPS_INTERNALS_GCC_GENERIC_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "base/basictypes.h"
-
-typedef int32_t Atomic32;
-
-namespace base {
-namespace subtle {
-
-typedef int64_t Atomic64;
-
-inline void MemoryBarrier() {
-    __sync_synchronize();
-}
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic32*>(ptr), new_value, __ATOMIC_RELAXED);
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic32*>(ptr), new_value,  __ATOMIC_ACQUIRE);
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic32*>(ptr), new_value, __ATOMIC_RELEASE);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-// 64-bit versions
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic64*>(ptr), new_value, __ATOMIC_RELAXED);
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic64*>(ptr), new_value,  __ATOMIC_ACQUIRE);
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic64*>(ptr), new_value, __ATOMIC_RELEASE);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-}  // namespace base::subtle
-}  // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_GCC_GENERIC_H_
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops-internals-linuxppc.h b/third_party/tcmalloc/chromium/src/base/atomicops-internals-linuxppc.h
deleted file mode 100644
index 73aa1562..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops-internals-linuxppc.h
+++ /dev/null
@@ -1,405 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- */
-
-// Implementation of atomic operations for ppc-linux.  This file should not
-// be included directly.  Clients should instead include
-// "base/atomicops.h".
-
-#ifndef BASE_ATOMICOPS_INTERNALS_LINUXPPC_H_
-#define BASE_ATOMICOPS_INTERNALS_LINUXPPC_H_
-
-typedef int32_t Atomic32;
-
-#ifdef __PPC64__
-#define BASE_HAS_ATOMIC64 1
-#endif
-
-namespace base {
-namespace subtle {
-
-static inline void _sync(void) {
-  __asm__ __volatile__("sync": : : "memory");
-}
-
-static inline void _lwsync(void) {
-  // gcc defines __NO_LWSYNC__ when appropriate; see
-  //    http://gcc.gnu.org/ml/gcc-patches/2006-11/msg01238.html
-#ifdef __NO_LWSYNC__
-  __asm__ __volatile__("msync": : : "memory");
-#else
-  __asm__ __volatile__("lwsync": : : "memory");
-#endif
-}
-
-static inline void _isync(void) {
-  __asm__ __volatile__("isync": : : "memory");
-}
-
-static inline Atomic32 OSAtomicAdd32(Atomic32 amount, Atomic32 *value) {
-  Atomic32 t;
-  __asm__ __volatile__(
-"1:		lwarx   %0,0,%3\n\
-		add     %0,%2,%0\n\
-		stwcx.  %0,0,%3 \n\
-		bne-    1b"
-		: "=&r" (t), "+m" (*value)
-		: "r" (amount), "r" (value)
-                : "cc");
-  return t;
-}
-
-static inline Atomic32 OSAtomicAdd32Barrier(Atomic32 amount, Atomic32 *value) {
-  Atomic32 t;
-  _lwsync();
-  t = OSAtomicAdd32(amount, value);
-  // This is based on the code snippet in the architecture manual (Vol
-  // 2, Appendix B).  It's a little tricky: correctness depends on the
-  // fact that the code right before this (in OSAtomicAdd32) has a
-  // conditional branch with a data dependency on the update.
-  // Otherwise, we'd have to use sync.
-  _isync();
-  return t;
-}
-
-static inline bool OSAtomicCompareAndSwap32(Atomic32 old_value,
-                                            Atomic32 new_value,
-                                            Atomic32 *value) {
-  Atomic32 prev;
-  __asm__ __volatile__(
-"1:		lwarx   %0,0,%2\n\
-		cmpw    0,%0,%3\n\
-		bne-    2f\n\
-		stwcx.  %4,0,%2\n\
-		bne-    1b\n\
-2:"
-                : "=&r" (prev), "+m" (*value)
-                : "r" (value), "r" (old_value), "r" (new_value)
-                : "cc");
-  return prev == old_value;
-}
-
-static inline Atomic32 OSAtomicCompareAndSwap32Acquire(Atomic32 old_value,
-                                                       Atomic32 new_value,
-                                                       Atomic32 *value) {
-  Atomic32 t;
-  t = OSAtomicCompareAndSwap32(old_value, new_value, value);
-  // This is based on the code snippet in the architecture manual (Vol
-  // 2, Appendix B).  It's a little tricky: correctness depends on the
-  // fact that the code right before this (in
-  // OSAtomicCompareAndSwap32) has a conditional branch with a data
-  // dependency on the update.  Otherwise, we'd have to use sync.
-  _isync();
-  return t;
-}
-
-static inline Atomic32 OSAtomicCompareAndSwap32Release(Atomic32 old_value,
-                                                       Atomic32 new_value,
-                                                       Atomic32 *value) {
-  _lwsync();
-  return OSAtomicCompareAndSwap32(old_value, new_value, value);
-}
-
-typedef int64_t Atomic64;
-
-inline void MemoryBarrier() {
-  // This can't be _lwsync(); we need to order the immediately
-  // preceding stores against any load that may follow, but lwsync
-  // doesn't guarantee that.
-  _sync();
-}
-
-// 32-bit Versions.
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32(old_value, new_value,
-                                 const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
-                                         Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32(old_value, new_value,
-                                     const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32Acquire(old_value, new_value,
-                                            const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32Release(old_value, new_value,
-                                            const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32Acquire(old_value, new_value,
-                                        const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32Release(old_value, new_value,
-                                        const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-#ifdef __PPC64__
-
-// 64-bit Versions.
-
-static inline Atomic64 OSAtomicAdd64(Atomic64 amount, Atomic64 *value) {
-  Atomic64 t;
-  __asm__ __volatile__(
-"1:		ldarx   %0,0,%3\n\
-		add     %0,%2,%0\n\
-		stdcx.  %0,0,%3 \n\
-		bne-    1b"
-		: "=&r" (t), "+m" (*value)
-		: "r" (amount), "r" (value)
-                : "cc");
-  return t;
-}
-
-static inline Atomic64 OSAtomicAdd64Barrier(Atomic64 amount, Atomic64 *value) {
-  Atomic64 t;
-  _lwsync();
-  t = OSAtomicAdd64(amount, value);
-  // This is based on the code snippet in the architecture manual (Vol
-  // 2, Appendix B).  It's a little tricky: correctness depends on the
-  // fact that the code right before this (in OSAtomicAdd64) has a
-  // conditional branch with a data dependency on the update.
-  // Otherwise, we'd have to use sync.
-  _isync();
-  return t;
-}
-
-static inline bool OSAtomicCompareAndSwap64(Atomic64 old_value,
-                                            Atomic64 new_value,
-                                            Atomic64 *value) {
-  Atomic64 prev;
-  __asm__ __volatile__(
-"1:		ldarx   %0,0,%2\n\
-		cmpd    0,%0,%3\n\
-		bne-    2f\n\
-		stdcx.  %4,0,%2\n\
-		bne-    1b\n\
-2:"
-                : "=&r" (prev), "+m" (*value)
-                : "r" (value), "r" (old_value), "r" (new_value)
-                : "cc");
-  return prev == old_value;
-}
-
-static inline Atomic64 OSAtomicCompareAndSwap64Acquire(Atomic64 old_value,
-                                                       Atomic64 new_value,
-                                                       Atomic64 *value) {
-  Atomic64 t;
-  t = OSAtomicCompareAndSwap64(old_value, new_value, value);
-  // This is based on the code snippet in the architecture manual (Vol
-  // 2, Appendix B).  It's a little tricky: correctness depends on the
-  // fact that the code right before this (in
-  // OSAtomicCompareAndSwap64) has a conditional branch with a data
-  // dependency on the update.  Otherwise, we'd have to use sync.
-  _isync();
-  return t;
-}
-
-static inline Atomic64 OSAtomicCompareAndSwap64Release(Atomic64 old_value,
-                                                       Atomic64 new_value,
-                                                       Atomic64 *value) {
-  _lwsync();
-  return OSAtomicCompareAndSwap64(old_value, new_value, value);
-}
-
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64(old_value, new_value,
-                                 const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
-                                         Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64(old_value, new_value,
-                                     const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64Acquire(old_value, new_value,
-                                            const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64Release(old_value, new_value,
-                                            const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64Acquire(old_value, new_value,
-                                        const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64Release(old_value, new_value,
-                                        const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-#endif
-
-inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
-  _lwsync();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
-  Atomic32 value = *ptr;
-  _lwsync();
-  return value;
-}
-
-#ifdef __PPC64__
-
-// 64-bit Versions.
-
-inline void NoBarrier_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  _lwsync();
-  *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64 *ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
-  Atomic64 value = *ptr;
-  _lwsync();
-  return value;
-}
-
-#endif
-
-}   // namespace base::subtle
-}   // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_LINUXPPC_H_
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops-internals-macosx.h b/third_party/tcmalloc/chromium/src/base/atomicops-internals-macosx.h
deleted file mode 100644
index c21f606..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops-internals-macosx.h
+++ /dev/null
@@ -1,341 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Implementation of atomic operations for Mac OS X.  This file should not
-// be included directly.  Clients should instead include
-// "base/atomicops.h".
-
-#ifndef BASE_ATOMICOPS_INTERNALS_MACOSX_H_
-#define BASE_ATOMICOPS_INTERNALS_MACOSX_H_
-
-typedef int32_t Atomic32;
-
-// MacOS uses long for intptr_t, AtomicWord and Atomic32 are always different
-// on the Mac, even when they are the same size.  Similarly, on __ppc64__,
-// AtomicWord and Atomic64 are always different.  Thus, we need explicit
-// casting.
-#ifdef __LP64__
-#define AtomicWordCastType base::subtle::Atomic64
-#else
-#define AtomicWordCastType Atomic32
-#endif
-
-#if defined(__LP64__) || defined(__i386__)
-#define BASE_HAS_ATOMIC64 1  // Use only in tests and base/atomic*
-#endif
-
-#include <libkern/OSAtomic.h>
-
-namespace base {
-namespace subtle {
-
-#if !defined(__LP64__) && defined(__ppc__)
-
-// The Mac 64-bit OSAtomic implementations are not available for 32-bit PowerPC,
-// while the underlying assembly instructions are available only some
-// implementations of PowerPC.
-
-// The following inline functions will fail with the error message at compile
-// time ONLY IF they are called.  So it is safe to use this header if user
-// code only calls AtomicWord and Atomic32 operations.
-//
-// NOTE(vchen): Implementation notes to implement the atomic ops below may
-// be found in "PowerPC Virtual Environment Architecture, Book II,
-// Version 2.02", January 28, 2005, Appendix B, page 46.  Unfortunately,
-// extra care must be taken to ensure data are properly 8-byte aligned, and
-// that data are returned correctly according to Mac OS X ABI specs.
-
-inline int64_t OSAtomicCompareAndSwap64(
-    int64_t oldValue, int64_t newValue, int64_t *theValue) {
-  __asm__ __volatile__(
-      "_OSAtomicCompareAndSwap64_not_supported_for_32_bit_ppc\n\t");
-  return 0;
-}
-
-inline int64_t OSAtomicAdd64(int64_t theAmount, int64_t *theValue) {
-  __asm__ __volatile__(
-      "_OSAtomicAdd64_not_supported_for_32_bit_ppc\n\t");
-  return 0;
-}
-
-inline int64_t OSAtomicCompareAndSwap64Barrier(
-    int64_t oldValue, int64_t newValue, int64_t *theValue) {
-  int64_t prev = OSAtomicCompareAndSwap64(oldValue, newValue, theValue);
-  OSMemoryBarrier();
-  return prev;
-}
-
-inline int64_t OSAtomicAdd64Barrier(
-    int64_t theAmount, int64_t *theValue) {
-  int64_t new_val = OSAtomicAdd64(theAmount, theValue);
-  OSMemoryBarrier();
-  return new_val;
-}
-#endif
-
-typedef int64_t Atomic64;
-
-inline void MemoryBarrier() {
-  OSMemoryBarrier();
-}
-
-// 32-bit Versions.
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32(old_value, new_value,
-                                 const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
-                                         Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32(old_value, new_value,
-                                     const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32Barrier(old_value, new_value,
-                                            const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr,
-                                       Atomic32 new_value) {
-  return Acquire_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
-                                        const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
-  Atomic32 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-// 64-bit version
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64(old_value, new_value,
-                                 const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
-                                         Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64(old_value, new_value,
-                                     const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64Barrier(old_value, new_value,
-                                            const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr,
-                                       Atomic64 new_value) {
-  return Acquire_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64Barrier(old_value, new_value,
-                                        const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  // The lib kern interface does not distinguish between
-  // Acquire and Release memory barriers; they are equivalent.
-  return Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-
-#ifdef __LP64__
-
-// 64-bit implementation on 64-bit platform
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
-  Atomic64 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-#else
-
-// 64-bit implementation on 32-bit platform
-
-#if defined(__ppc__)
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-   __asm__ __volatile__(
-       "_NoBarrier_Store_not_supported_for_32_bit_ppc\n\t");
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-   __asm__ __volatile__(
-       "_NoBarrier_Load_not_supported_for_32_bit_ppc\n\t");
-   return 0;
-}
-
-#elif defined(__i386__)
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  __asm__ __volatile__("movq %1, %%mm0\n\t"    // Use mmx reg for 64-bit atomic
-                       "movq %%mm0, %0\n\t"  // moves (ptr could be read-only)
-                       "emms\n\t"              // Reset FP registers
-                       : "=m" (*ptr)
-                       : "m" (value)
-                       : // mark the FP stack and mmx registers as clobbered
-                         "st", "st(1)", "st(2)", "st(3)", "st(4)",
-                         "st(5)", "st(6)", "st(7)", "mm0", "mm1",
-                         "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
-
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  Atomic64 value;
-  __asm__ __volatile__("movq %1, %%mm0\n\t"  // Use mmx reg for 64-bit atomic
-                       "movq %%mm0, %0\n\t"  // moves (ptr could be read-only)
-                       "emms\n\t"            // Reset FP registers
-                       : "=m" (value)
-                       : "m" (*ptr)
-                       : // mark the FP stack and mmx registers as clobbered
-                         "st", "st(1)", "st(2)", "st(3)", "st(4)",
-                         "st(5)", "st(6)", "st(7)", "mm0", "mm1",
-                         "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
-
-  return value;
-}
-#endif
-
-
-inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  MemoryBarrier();
-  NoBarrier_Store(ptr, value);
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
-  Atomic64 value = NoBarrier_Load(ptr);
-  MemoryBarrier();
-  return value;
-}
-
-#endif  // __LP64__
-
-}   // namespace base::subtle
-}   // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_MACOSX_H_
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops-internals-mips.h b/third_party/tcmalloc/chromium/src/base/atomicops-internals-mips.h
deleted file mode 100644
index 58e0f14..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops-internals-mips.h
+++ /dev/null
@@ -1,299 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2013, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Author: Jovan Zelincevic <jovan.zelincevic@imgtec.com>
-// based on atomicops-internals by Sanjay Ghemawat
-
-// This file is an internal atomic implementation, use base/atomicops.h instead.
-//
-// This code implements MIPS atomics.
-
-#ifndef BASE_ATOMICOPS_INTERNALS_MIPS_H_
-#define BASE_ATOMICOPS_INTERNALS_MIPS_H_
-
-#if (_MIPS_ISA == _MIPS_ISA_MIPS64)
-#define BASE_HAS_ATOMIC64 1
-#endif
-
-typedef int32_t Atomic32;
-
-namespace base {
-namespace subtle {
-
-// Atomically execute:
-// result = *ptr;
-// if (*ptr == old_value)
-// *ptr = new_value;
-// return result;
-//
-// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
-// Always return the old value of "*ptr"
-//
-// This routine implies no memory barriers.
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value)
-{
-    Atomic32 prev, tmp;
-    __asm__ volatile(
-        ".set   push                \n"
-        ".set   noreorder           \n"
-
-    "1:                             \n"
-        "ll     %0,     %5          \n" // prev = *ptr
-        "bne    %0,     %3,     2f  \n" // if (prev != old_value) goto 2
-        " move  %2,     %4          \n" // tmp = new_value
-        "sc     %2,     %1          \n" // *ptr = tmp (with atomic check)
-        "beqz   %2,     1b          \n" // start again on atomic error
-        " nop                       \n" // delay slot nop
-    "2:                             \n"
-
-        ".set   pop                 \n"
-        : "=&r" (prev), "=m" (*ptr),
-          "=&r" (tmp)
-        : "Ir" (old_value), "r" (new_value),
-          "m" (*ptr)
-        : "memory"
-    );
-    return prev;
-}
-
-// Atomically store new_value into *ptr, returning the previous value held in
-// *ptr. This routine implies no memory barriers.
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value)
-{
-    Atomic32 temp, old;
-    __asm__ volatile(
-        ".set   push                \n"
-        ".set   noreorder           \n"
-
-    "1:                             \n"
-        "ll     %1,     %2          \n" // old = *ptr
-        "move   %0,     %3          \n" // temp = new_value
-        "sc     %0,     %2          \n" // *ptr = temp (with atomic check)
-        "beqz   %0,     1b          \n" // start again on atomic error
-        " nop                       \n" // delay slot nop
-
-        ".set   pop                 \n"
-        : "=&r" (temp), "=&r" (old),
-          "=m" (*ptr)
-        : "r" (new_value), "m" (*ptr)
-        : "memory"
-    );
-    return old;
-}
-
-inline void MemoryBarrier()
-{
-    __asm__ volatile("sync" : : : "memory");
-}
-
-// "Acquire" operations
-// ensure that no later memory access can be reordered ahead of the operation.
-// "Release" operations ensure that no previous memory access can be reordered
-// after the operation. "Barrier" operations have both "Acquire" and "Release"
-// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory
-// access.
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value)
-{
-    Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-    MemoryBarrier();
-    return res;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value)
-{
-    MemoryBarrier();
-    Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-    return res;
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value)
-{
-    *ptr = value;
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value)
-{
-    Atomic32 old_value = NoBarrier_AtomicExchange(ptr, new_value);
-    MemoryBarrier();
-    return old_value;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value)
-{
-    MemoryBarrier();
-    return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value)
-{
-    MemoryBarrier();
-    *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr)
-{
-    return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr)
-{
-    Atomic32 value = *ptr;
-    MemoryBarrier();
-    return value;
-}
-
-#if (_MIPS_ISA == _MIPS_ISA_MIPS64) || (_MIPS_SIM == _MIPS_SIM_ABI64)
-
-typedef int64_t Atomic64;
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value)
-{
-    Atomic64 prev, tmp;
-    __asm__ volatile(
-        ".set   push                \n"
-        ".set   noreorder           \n"
-
-    "1:                             \n"
-        "lld    %0,     %5          \n" // prev = *ptr
-        "bne    %0,     %3,     2f  \n" // if (prev != old_value) goto 2
-        " move  %2,     %4          \n" // tmp = new_value
-        "scd    %2,     %1          \n" // *ptr = tmp (with atomic check)
-        "beqz   %2,     1b          \n" // start again on atomic error
-        " nop                       \n" // delay slot nop
-    "2:                             \n"
-
-        ".set   pop                 \n"
-        : "=&r" (prev), "=m" (*ptr),
-          "=&r" (tmp)
-        : "Ir" (old_value), "r" (new_value),
-          "m" (*ptr)
-        : "memory"
-    );
-    return prev;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value)
-{
-    Atomic64 temp, old;
-    __asm__ volatile(
-        ".set   push                \n"
-        ".set   noreorder           \n"
-
-    "1:                             \n"
-        "lld    %1,     %2          \n" // old = *ptr
-        "move   %0,     %3          \n" // temp = new_value
-        "scd    %0,     %2          \n" // *ptr = temp (with atomic check)
-        "beqz   %0,     1b          \n" // start again on atomic error
-        " nop                       \n" // delay slot nop
-
-        ".set   pop                 \n"
-        : "=&r" (temp), "=&r" (old),
-          "=m" (*ptr)
-        : "r" (new_value), "m" (*ptr)
-        : "memory"
-    );
-    return old;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value)
-{
-    Atomic64 old_value = NoBarrier_AtomicExchange(ptr, new_value);
-    MemoryBarrier();
-    return old_value;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value)
-{
-    Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-    MemoryBarrier();
-    return res;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value)
-{
-    MemoryBarrier();
-    Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-    return res;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value)
-{
-    *ptr = value;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value)
-{
-    MemoryBarrier();
-    return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value)
-{
-    MemoryBarrier();
-    *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr)
-{
-    return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr)
-{
-    Atomic64 value = *ptr;
-    MemoryBarrier();
-    return value;
-}
-
-#endif
-
-}   // namespace base::subtle
-}   // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_MIPS_H_
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops-internals-windows.h b/third_party/tcmalloc/chromium/src/base/atomicops-internals-windows.h
deleted file mode 100644
index ebd57424..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops-internals-windows.h
+++ /dev/null
@@ -1,429 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-// Implementation of atomic operations using Windows API
-// functions.  This file should not be included directly.  Clients
-// should instead include "base/atomicops.h".
-
-#ifndef BASE_ATOMICOPS_INTERNALS_WINDOWS_H_
-#define BASE_ATOMICOPS_INTERNALS_WINDOWS_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "base/abort.h"
-#include "base/basictypes.h"  // For COMPILE_ASSERT
-
-typedef int32 Atomic32;
-
-#if defined(_WIN64)
-#define BASE_HAS_ATOMIC64 1  // Use only in tests and base/atomic*
-#endif
-
-namespace base {
-namespace subtle {
-
-typedef int64 Atomic64;
-
-// 32-bit low-level operations on any platform
-
-extern "C" {
-// We use windows intrinsics when we can (they seem to be supported
-// well on MSVC 8.0 and above).  Unfortunately, in some
-// environments, <windows.h> and <intrin.h> have conflicting
-// declarations of some other intrinsics, breaking compilation:
-//   http://connect.microsoft.com/VisualStudio/feedback/details/262047
-// Therefore, we simply declare the relevant intrinsics ourself.
-
-// MinGW has a bug in the header files where it doesn't indicate the
-// first argument is volatile -- they're not up to date.  See
-//   http://readlist.com/lists/lists.sourceforge.net/mingw-users/0/3861.html
-// We have to const_cast away the volatile to avoid compiler warnings.
-// TODO(csilvers): remove this once MinGW has updated MinGW/include/winbase.h
-#if defined(__MINGW32__)
-inline LONG FastInterlockedCompareExchange(volatile LONG* ptr,
-                                           LONG newval, LONG oldval) {
-  return ::InterlockedCompareExchange(const_cast<LONG*>(ptr), newval, oldval);
-}
-inline LONG FastInterlockedExchange(volatile LONG* ptr, LONG newval) {
-  return ::InterlockedExchange(const_cast<LONG*>(ptr), newval);
-}
-inline LONG FastInterlockedExchangeAdd(volatile LONG* ptr, LONG increment) {
-  return ::InterlockedExchangeAdd(const_cast<LONG*>(ptr), increment);
-}
-
-#elif _MSC_VER >= 1400   // intrinsics didn't work so well before MSVC 8.0
-// Unfortunately, in some environments, <windows.h> and <intrin.h>
-// have conflicting declarations of some intrinsics, breaking
-// compilation.  So we declare the intrinsics we need ourselves.  See
-//   http://connect.microsoft.com/VisualStudio/feedback/details/262047
-LONG _InterlockedCompareExchange(volatile LONG* ptr, LONG newval, LONG oldval);
-#pragma intrinsic(_InterlockedCompareExchange)
-inline LONG FastInterlockedCompareExchange(volatile LONG* ptr,
-                                           LONG newval, LONG oldval) {
-  return _InterlockedCompareExchange(ptr, newval, oldval);
-}
-
-LONG _InterlockedExchange(volatile LONG* ptr, LONG newval);
-#pragma intrinsic(_InterlockedExchange)
-inline LONG FastInterlockedExchange(volatile LONG* ptr, LONG newval) {
-  return _InterlockedExchange(ptr, newval);
-}
-
-LONG _InterlockedExchangeAdd(volatile LONG* ptr, LONG increment);
-#pragma intrinsic(_InterlockedExchangeAdd)
-inline LONG FastInterlockedExchangeAdd(volatile LONG* ptr, LONG increment) {
-  return _InterlockedExchangeAdd(ptr, increment);
-}
-
-#else
-inline LONG FastInterlockedCompareExchange(volatile LONG* ptr,
-                                           LONG newval, LONG oldval) {
-  return ::InterlockedCompareExchange(ptr, newval, oldval);
-}
-inline LONG FastInterlockedExchange(volatile LONG* ptr, LONG newval) {
-  return ::InterlockedExchange(ptr, newval);
-}
-inline LONG FastInterlockedExchangeAdd(volatile LONG* ptr, LONG increment) {
-  return ::InterlockedExchangeAdd(ptr, increment);
-}
-
-#endif  // ifdef __MINGW32__
-}  // extern "C"
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  LONG result = FastInterlockedCompareExchange(
-      reinterpret_cast<volatile LONG*>(ptr),
-      static_cast<LONG>(new_value),
-      static_cast<LONG>(old_value));
-  return static_cast<Atomic32>(result);
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  LONG result = FastInterlockedExchange(
-      reinterpret_cast<volatile LONG*>(ptr),
-      static_cast<LONG>(new_value));
-  return static_cast<Atomic32>(result);
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // FastInterlockedExchange has both acquire and release memory barriers.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // FastInterlockedExchange has both acquire and release memory barriers.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-}  // namespace base::subtle
-}  // namespace base
-
-
-// In msvc8/vs2005, winnt.h already contains a definition for
-// MemoryBarrier in the global namespace.  Add it there for earlier
-// versions and forward to it from within the namespace.
-#if !(defined(_MSC_VER) && _MSC_VER >= 1400)
-inline void MemoryBarrier() {
-  Atomic32 value = 0;
-  base::subtle::NoBarrier_AtomicExchange(&value, 0);
-                        // actually acts as a barrier in thisd implementation
-}
-#endif
-
-namespace base {
-namespace subtle {
-
-inline void MemoryBarrier() {
-  ::MemoryBarrier();
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value; // works w/o barrier for current Intel chips as of June 2005
-  // See comments in Atomic64 version of Release_Store() below.
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr;
-  return value;
-}
-
-// 64-bit operations
-
-#if defined(_WIN64) || defined(__MINGW64__)
-
-// 64-bit low-level operations on 64-bit platform.
-
-COMPILE_ASSERT(sizeof(Atomic64) == sizeof(PVOID), atomic_word_is_atomic);
-
-// These are the intrinsics needed for 64-bit operations.  Similar to the
-// 32-bit case above.
-
-extern "C" {
-#if defined(__MINGW64__)
-inline PVOID FastInterlockedCompareExchangePointer(volatile PVOID* ptr,
-                                                   PVOID newval, PVOID oldval) {
-  return ::InterlockedCompareExchangePointer(const_cast<PVOID*>(ptr),
-                                             newval, oldval);
-}
-inline PVOID FastInterlockedExchangePointer(volatile PVOID* ptr, PVOID newval) {
-  return ::InterlockedExchangePointer(const_cast<PVOID*>(ptr), newval);
-}
-inline LONGLONG FastInterlockedExchangeAdd64(volatile LONGLONG* ptr,
-                                             LONGLONG increment) {
-  return ::InterlockedExchangeAdd64(const_cast<LONGLONG*>(ptr), increment);
-}
-
-#elif _MSC_VER >= 1400   // intrinsics didn't work so well before MSVC 8.0
-// Like above, we need to declare the intrinsics ourselves.
-PVOID _InterlockedCompareExchangePointer(volatile PVOID* ptr,
-                                         PVOID newval, PVOID oldval);
-#pragma intrinsic(_InterlockedCompareExchangePointer)
-inline PVOID FastInterlockedCompareExchangePointer(volatile PVOID* ptr,
-                                                   PVOID newval, PVOID oldval) {
-  return _InterlockedCompareExchangePointer(const_cast<PVOID*>(ptr),
-                                            newval, oldval);
-}
-
-PVOID _InterlockedExchangePointer(volatile PVOID* ptr, PVOID newval);
-#pragma intrinsic(_InterlockedExchangePointer)
-inline PVOID FastInterlockedExchangePointer(volatile PVOID* ptr, PVOID newval) {
-  return _InterlockedExchangePointer(const_cast<PVOID*>(ptr), newval);
-}
-
-LONGLONG _InterlockedExchangeAdd64(volatile LONGLONG* ptr, LONGLONG increment);
-#pragma intrinsic(_InterlockedExchangeAdd64)
-inline LONGLONG FastInterlockedExchangeAdd64(volatile LONGLONG* ptr,
-                                             LONGLONG increment) {
-  return _InterlockedExchangeAdd64(const_cast<LONGLONG*>(ptr), increment);
-}
-
-#else
-inline PVOID FastInterlockedCompareExchangePointer(volatile PVOID* ptr,
-                                                   PVOID newval, PVOID oldval) {
-  return ::InterlockedCompareExchangePointer(ptr, newval, oldval);
-}
-inline PVOID FastInterlockedExchangePointer(volatile PVOID* ptr, PVOID newval) {
-  return ::InterlockedExchangePointer(ptr, newval);
-}
-inline LONGLONG FastInterlockedExchangeAdd64(volatile LONGLONG* ptr,
-                                         LONGLONG increment) {
-  return ::InterlockedExchangeAdd64(ptr, increment);
-}
-
-#endif  // ifdef __MINGW64__
-}  // extern "C"
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  PVOID result = FastInterlockedCompareExchangePointer(
-    reinterpret_cast<volatile PVOID*>(ptr),
-    reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
-  return reinterpret_cast<Atomic64>(result);
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  PVOID result = FastInterlockedExchangePointer(
-    reinterpret_cast<volatile PVOID*>(ptr),
-    reinterpret_cast<PVOID>(new_value));
-  return reinterpret_cast<Atomic64>(result);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value; // works w/o barrier for current Intel chips as of June 2005
-
-  // When new chips come out, check:
-  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:
-  //  System Programming Guide, Chatper 7: Multiple-processor management,
-  //  Section 7.2, Memory Ordering.
-  // Last seen at:
-  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = *ptr;
-  return value;
-}
-
-#else  // defined(_WIN64) || defined(__MINGW64__)
-
-// 64-bit low-level operations on 32-bit platform
-
-// TODO(vchen): The GNU assembly below must be converted to MSVC inline
-// assembly.  Then the file should be renamed to ...-x86-msvc.h, probably.
-
-inline void NotImplementedFatalError(const char *function_name) {
-  fprintf(stderr, "64-bit %s() not implemented on this platform\n",
-          function_name);
-  tcmalloc::Abort();
-}
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-#if 0 // Not implemented
-  Atomic64 prev;
-  __asm__ __volatile__("movl (%3), %%ebx\n\t"    // Move 64-bit new_value into
-                       "movl 4(%3), %%ecx\n\t"   // ecx:ebx
-                       "lock; cmpxchg8b %1\n\t"  // If edx:eax (old_value) same
-                       : "=A" (prev)             // as contents of ptr:
-                       : "m" (*ptr),             //   ecx:ebx => ptr
-                         "0" (old_value),        // else:
-                         "r" (&new_value)        //   old *ptr => edx:eax
-                       : "memory", "%ebx", "%ecx");
-  return prev;
-#else
-  NotImplementedFatalError("NoBarrier_CompareAndSwap");
-  return 0;
-#endif
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-#if 0 // Not implemented
-  __asm__ __volatile__(
-                       "movl (%2), %%ebx\n\t"    // Move 64-bit new_value into
-                       "movl 4(%2), %%ecx\n\t"   // ecx:ebx
-                       "0:\n\t"
-                       "movl %1, %%eax\n\t"      // Read contents of ptr into
-                       "movl 4%1, %%edx\n\t"     // edx:eax
-                       "lock; cmpxchg8b %1\n\t"  // Attempt cmpxchg; if *ptr
-                       "jnz 0b\n\t"              // is no longer edx:eax, loop
-                       : "=A" (new_value)
-                       : "m" (*ptr),
-                         "r" (&new_value)
-                       : "memory", "%ebx", "%ecx");
-  return new_value;  // Now it's the previous value.
-#else
-  NotImplementedFatalError("NoBarrier_AtomicExchange");
-  return 0;
-#endif
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptrValue, Atomic64 value)
-{
- 	__asm {
-    	movq mm0, value;  // Use mmx reg for 64-bit atomic moves
-    	mov eax, ptrValue;
-    	movq [eax], mm0;
-    	emms;            // Empty mmx state to enable FP registers
-  	}
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NoBarrier_Store(ptr, value);
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptrValue)
-{
-  	Atomic64 value;
-  	__asm {
-    	mov eax, ptrValue;
-    	movq mm0, [eax]; // Use mmx reg for 64-bit atomic moves
-    	movq value, mm0;
-    	emms; // Empty mmx state to enable FP registers
-  }
-  return value;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = NoBarrier_Load(ptr);
-  return value;
-}
-
-#endif  // defined(_WIN64) || defined(__MINGW64__)
-
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // FastInterlockedExchange has both acquire and release memory barriers.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // FastInterlockedExchange has both acquire and release memory barriers.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-}  // namespace base::subtle
-}  // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_WINDOWS_H_
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops-internals-x86.cc b/third_party/tcmalloc/chromium/src/base/atomicops-internals-x86.cc
deleted file mode 100644
index c3391e7..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops-internals-x86.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This module gets enough CPU information to optimize the
- * atomicops module on x86.
- */
-
-#include "base/atomicops.h"
-#include "base/basictypes.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include <string.h>
-
-// This file only makes sense with atomicops-internals-x86.h -- it
-// depends on structs that are defined in that file.  If atomicops.h
-// doesn't sub-include that file, then we aren't needed, and shouldn't
-// try to do anything.
-#ifdef BASE_ATOMICOPS_INTERNALS_X86_H_
-
-// Inline cpuid instruction.  In PIC compilations, %ebx contains the address
-// of the global offset table.  To avoid breaking such executables, this code
-// must preserve that register's value across cpuid instructions.
-#if defined(__i386__)
-#define cpuid(a, b, c, d, inp) \
-  asm ("mov %%ebx, %%edi\n"    \
-       "cpuid\n"               \
-       "xchg %%edi, %%ebx\n"   \
-       : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
-#elif defined (__x86_64__)
-#define cpuid(a, b, c, d, inp) \
-  asm ("mov %%rbx, %%rdi\n"    \
-       "cpuid\n"               \
-       "xchg %%rdi, %%rbx\n"   \
-       : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
-#endif
-
-#if defined(cpuid)        // initialize the struct only on x86
-
-// Set the flags so that code will run correctly and conservatively
-// until InitGoogle() is called.
-struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
-  false,          // no SSE2
-  false           // no cmpxchg16b
-};
-
-// Initialize the AtomicOps_Internalx86CPUFeatures struct.
-static void AtomicOps_Internalx86CPUFeaturesInit() {
-  uint32 eax;
-  uint32 ebx;
-  uint32 ecx;
-  uint32 edx;
-
-  // Get vendor string (issue CPUID with eax = 0)
-  cpuid(eax, ebx, ecx, edx, 0);
-  char vendor[13];
-  memcpy(vendor, &ebx, 4);
-  memcpy(vendor + 4, &edx, 4);
-  memcpy(vendor + 8, &ecx, 4);
-  vendor[12] = 0;
-
-  // get feature flags in ecx/edx, and family/model in eax
-  cpuid(eax, ebx, ecx, edx, 1);
-
-  int family = (eax >> 8) & 0xf;        // family and model fields
-  int model = (eax >> 4) & 0xf;
-  if (family == 0xf) {                  // use extended family and model fields
-    family += (eax >> 20) & 0xff;
-    model += ((eax >> 16) & 0xf) << 4;
-  }
-
-  // edx bit 26 is SSE2 which we use to tell use whether we can use mfence
-  AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);
-
-  // ecx bit 13 indicates whether the cmpxchg16b instruction is supported
-  AtomicOps_Internalx86CPUFeatures.has_cmpxchg16b = ((ecx >> 13) & 1);
-}
-
-REGISTER_MODULE_INITIALIZER(atomicops_x86, {
-  AtomicOps_Internalx86CPUFeaturesInit();
-});
-
-#endif
-
-#endif  /* ifdef BASE_ATOMICOPS_INTERNALS_X86_H_ */
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops-internals-x86.h b/third_party/tcmalloc/chromium/src/base/atomicops-internals-x86.h
deleted file mode 100644
index 4eadacbb..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops-internals-x86.h
+++ /dev/null
@@ -1,353 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-// Implementation of atomic operations for x86.  This file should not
-// be included directly.  Clients should instead include
-// "base/atomicops.h".
-
-#ifndef BASE_ATOMICOPS_INTERNALS_X86_H_
-#define BASE_ATOMICOPS_INTERNALS_X86_H_
-#include "base/basictypes.h"
-
-typedef int32_t Atomic32;
-#define BASE_HAS_ATOMIC64 1  // Use only in tests and base/atomic*
-
-
-// NOTE(vchen): x86 does not need to define AtomicWordCastType, because it
-// already matches Atomic32 or Atomic64, depending on the platform.
-
-
-// This struct is not part of the public API of this module; clients may not
-// use it.
-// Features of this x86.  Values may not be correct before main() is run,
-// but are set conservatively.
-struct AtomicOps_x86CPUFeatureStruct {
-  bool has_sse2;            // Processor has SSE2.
-  bool has_cmpxchg16b;      // Processor supports cmpxchg16b instruction.
-};
-
-ATTRIBUTE_VISIBILITY_HIDDEN
-extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;
-
-
-#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
-
-
-namespace base {
-namespace subtle {
-
-typedef int64_t Atomic64;
-
-// 32-bit low-level operations on any platform.
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev;
-  __asm__ __volatile__("lock; cmpxchgl %1,%2"
-                       : "=a" (prev)
-                       : "q" (new_value), "m" (*ptr), "0" (old_value)
-                       : "memory");
-  return prev;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  __asm__ __volatile__("xchgl %1,%0"  // The lock prefix is implicit for xchg.
-                       : "=r" (new_value)
-                       : "m" (*ptr), "0" (new_value)
-                       : "memory");
-  return new_value;  // Now it's the previous value.
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_val = NoBarrier_AtomicExchange(ptr, new_value);
-  return old_val;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // xchgl already has release memory barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-  return x;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-#if defined(__x86_64__)
-
-// 64-bit implementations of memory barrier can be simpler, because it
-// "mfence" is guaranteed to exist.
-inline void MemoryBarrier() {
-  __asm__ __volatile__("mfence" : : : "memory");
-}
-
-#else
-
-inline void MemoryBarrier() {
-  if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
-    __asm__ __volatile__("mfence" : : : "memory");
-  } else { // mfence is faster but not present on PIII
-    Atomic32 x = 0;
-    Acquire_AtomicExchange(&x, 0);
-  }
-}
-
-#endif
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  ATOMICOPS_COMPILER_BARRIER();
-  *ptr = value; // An x86 store acts as a release barrier.
-  // See comments in Atomic64 version of Release_Store(), below.
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr; // An x86 load acts as a acquire barrier.
-  // See comments in Atomic64 version of Release_Store(), below.
-  ATOMICOPS_COMPILER_BARRIER();
-  return value;
-}
-
-#if defined(__x86_64__)
-
-// 64-bit low-level operations on 64-bit platform.
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 prev;
-  __asm__ __volatile__("lock; cmpxchgq %1,%2"
-                       : "=a" (prev)
-                       : "q" (new_value), "m" (*ptr), "0" (old_value)
-                       : "memory");
-  return prev;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  __asm__ __volatile__("xchgq %1,%0"  // The lock prefix is implicit for xchg.
-                       : "=r" (new_value)
-                       : "m" (*ptr), "0" (new_value)
-                       : "memory");
-  return new_value;  // Now it's the previous value.
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_val = NoBarrier_AtomicExchange(ptr, new_value);
-  return old_val;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // xchgq already has release memory barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  ATOMICOPS_COMPILER_BARRIER();
-
-  *ptr = value; // An x86 store acts as a release barrier
-                // for current AMD/Intel chips as of Jan 2008.
-                // See also Acquire_Load(), below.
-
-  // When new chips come out, check:
-  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:
-  //  System Programming Guide, Chatper 7: Multiple-processor management,
-  //  Section 7.2, Memory Ordering.
-  // Last seen at:
-  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm
-  //
-  // x86 stores/loads fail to act as barriers for a few instructions (clflush
-  // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
-  // not generated by the compiler, and are rare.  Users of these instructions
-  // need to know about cache behaviour in any case since all of these involve
-  // either flushing cache lines or non-temporal cache hints.
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = *ptr; // An x86 load acts as a acquire barrier,
-                         // for current AMD/Intel chips as of Jan 2008.
-                         // See also Release_Store(), above.
-  ATOMICOPS_COMPILER_BARRIER();
-  return value;
-}
-
-#else // defined(__x86_64__)
-
-// 64-bit low-level operations on 32-bit platform.
-
-#if !((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
-// For compilers older than gcc 4.1, we use inline asm.
-//
-// Potential pitfalls:
-//
-// 1. %ebx points to Global offset table (GOT) with -fPIC.
-//    We need to preserve this register.
-// 2. When explicit registers are used in inline asm, the
-//    compiler may not be aware of it and might try to reuse
-//    the same register for another argument which has constraints
-//    that allow it ("r" for example).
-
-inline Atomic64 __sync_val_compare_and_swap(volatile Atomic64* ptr,
-                                            Atomic64 old_value,
-                                            Atomic64 new_value) {
-  Atomic64 prev;
-  __asm__ __volatile__("push %%ebx\n\t"
-                       "movl (%3), %%ebx\n\t"    // Move 64-bit new_value into
-                       "movl 4(%3), %%ecx\n\t"   // ecx:ebx
-                       "lock; cmpxchg8b (%1)\n\t"// If edx:eax (old_value) same
-                       "pop %%ebx\n\t"
-                       : "=A" (prev)             // as contents of ptr:
-                       : "D" (ptr),              //   ecx:ebx => ptr
-                         "0" (old_value),        // else:
-                         "S" (&new_value)        //   old *ptr => edx:eax
-                       : "memory", "%ecx");
-  return prev;
-}
-#endif  // Compiler < gcc-4.1
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_val,
-                                         Atomic64 new_val) {
-  return __sync_val_compare_and_swap(ptr, old_val, new_val);
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_val) {
-  Atomic64 old_val;
-
-  do {
-    old_val = *ptr;
-  } while (__sync_val_compare_and_swap(ptr, old_val, new_val) != old_val);
-
-  return old_val;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_val) {
-  Atomic64 old_val = NoBarrier_AtomicExchange(ptr, new_val);
-  return old_val;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_val) {
- return NoBarrier_AtomicExchange(ptr, new_val);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  __asm__ __volatile__("movq %1, %%mm0\n\t"  // Use mmx reg for 64-bit atomic
-                       "movq %%mm0, %0\n\t"  // moves (ptr could be read-only)
-                       "emms\n\t"            // Empty mmx state/Reset FP regs
-                       : "=m" (*ptr)
-                       : "m" (value)
-                       : // mark the FP stack and mmx registers as clobbered
-			 "st", "st(1)", "st(2)", "st(3)", "st(4)",
-                         "st(5)", "st(6)", "st(7)", "mm0", "mm1",
-                         "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  ATOMICOPS_COMPILER_BARRIER();
-  NoBarrier_Store(ptr, value);
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  Atomic64 value;
-  __asm__ __volatile__("movq %1, %%mm0\n\t"  // Use mmx reg for 64-bit atomic
-                       "movq %%mm0, %0\n\t"  // moves (ptr could be read-only)
-                       "emms\n\t"            // Empty mmx state/Reset FP regs
-                       : "=m" (value)
-                       : "m" (*ptr)
-                       : // mark the FP stack and mmx registers as clobbered
-                         "st", "st(1)", "st(2)", "st(3)", "st(4)",
-                         "st(5)", "st(6)", "st(7)", "mm0", "mm1",
-                         "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
-  return value;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = NoBarrier_Load(ptr);
-  ATOMICOPS_COMPILER_BARRIER();
-  return value;
-}
-
-#endif // defined(__x86_64__)
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-  return x;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-} // namespace base::subtle
-} // namespace base
-
-#undef ATOMICOPS_COMPILER_BARRIER
-
-#endif  // BASE_ATOMICOPS_INTERNALS_X86_H_
diff --git a/third_party/tcmalloc/chromium/src/base/atomicops.h b/third_party/tcmalloc/chromium/src/base/atomicops.h
deleted file mode 100644
index 2f0bc5b..0000000
--- a/third_party/tcmalloc/chromium/src/base/atomicops.h
+++ /dev/null
@@ -1,363 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-// For atomic operations on statistics counters, see atomic_stats_counter.h.
-// For atomic operations on sequence numbers, see atomic_sequence_num.h.
-// For atomic operations on reference counts, see atomic_refcount.h.
-
-// Some fast atomic operations -- typically with machine-dependent
-// implementations.  This file may need editing as Google code is
-// ported to different architectures.
-
-// The routines exported by this module are subtle.  If you use them, even if
-// you get the code right, it will depend on careful reasoning about atomicity
-// and memory ordering; it will be less readable, and harder to maintain.  If
-// you plan to use these routines, you should have a good reason, such as solid
-// evidence that performance would otherwise suffer, or there being no
-// alternative.  You should assume only properties explicitly guaranteed by the
-// specifications in this file.  You are almost certainly _not_ writing code
-// just for the x86; if you assume x86 semantics, x86 hardware bugs and
-// implementations on other archtectures will cause your code to break.  If you
-// do not know what you are doing, avoid these routines, and use a Mutex.
-//
-// These following lower-level operations are typically useful only to people
-// implementing higher-level synchronization operations like spinlocks,
-// mutexes, and condition-variables.  They combine CompareAndSwap(), a load, or
-// a store with appropriate memory-ordering instructions.  "Acquire" operations
-// ensure that no later memory access can be reordered ahead of the operation.
-// "Release" operations ensure that no previous memory access can be reordered
-// after the operation.  "Barrier" operations have both "Acquire" and "Release"
-// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
-// access.
-//
-// It is incorrect to make direct assignments to/from an atomic variable.
-// You should use one of the Load or Store routines.  The NoBarrier
-// versions are provided when no barriers are needed:
-//   NoBarrier_Store()
-//   NoBarrier_Load()
-// Although there are currently no compiler enforcement, you are encouraged
-// to use these.  Moreover, if you choose to use base::subtle::Atomic64 type,
-// you MUST use one of the Load or Store routines to get correct behavior
-// on 32-bit platforms.
-//
-// The intent is eventually to put all of these routines in namespace
-// base::subtle
-
-#ifndef THREAD_ATOMICOPS_H_
-#define THREAD_ATOMICOPS_H_
-
-#include <config.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-// ------------------------------------------------------------------------
-// Include the platform specific implementations of the types
-// and operations listed below.  Implementations are to provide Atomic32
-// and Atomic64 operations. If there is a mismatch between intptr_t and
-// the Atomic32 or Atomic64 types for a platform, the platform-specific header
-// should define the macro, AtomicWordCastType in a clause similar to the
-// following:
-// #if ...pointers are 64 bits...
-// # define AtomicWordCastType base::subtle::Atomic64
-// #else
-// # define AtomicWordCastType Atomic32
-// #endif
-// TODO(csilvers): figure out ARCH_PIII/ARCH_K8 (perhaps via ./configure?)
-// ------------------------------------------------------------------------
-
-#include "base/arm_instruction_set_select.h"
-#define GCC_VERSION (__GNUC__ * 10000                 \
-                     + __GNUC_MINOR__ * 100           \
-                     + __GNUC_PATCHLEVEL__)
-
-#define CLANG_VERSION (__clang_major__ * 10000         \
-                       + __clang_minor__ * 100         \
-                       + __clang_patchlevel__)
-
-#if defined(TCMALLOC_PREFER_GCC_ATOMICS) && defined(__GNUC__) && GCC_VERSION >= 40700
-#include "base/atomicops-internals-gcc.h"
-#elif defined(TCMALLOC_PREFER_GCC_ATOMICS) && defined(__clang__) && CLANG_VERSION >= 30400
-#include "base/atomicops-internals-gcc.h"
-#elif defined(__MACH__) && defined(__APPLE__)
-#include "base/atomicops-internals-macosx.h"
-#elif defined(__GNUC__) && defined(ARMV6)
-#include "base/atomicops-internals-arm-v6plus.h"
-#elif defined(ARMV3)
-#include "base/atomicops-internals-arm-generic.h"
-#elif defined(__GNUC__) && (defined(__i386) || defined(__x86_64__))
-#include "base/atomicops-internals-x86.h"
-#elif defined(_WIN32)
-#include "base/atomicops-internals-windows.h"
-#elif defined(__linux__) && defined(__PPC__)
-#include "base/atomicops-internals-linuxppc.h"
-#elif defined(__GNUC__) && defined(__mips__)
-#include "base/atomicops-internals-mips.h"
-#elif defined(__GNUC__) && GCC_VERSION >= 40700
-#include "base/atomicops-internals-gcc.h"
-#elif defined(__clang__) && CLANG_VERSION >= 30400
-#include "base/atomicops-internals-gcc.h"
-#else
-#error You need to implement atomic operations for this architecture
-#endif
-
-// Signed type that can hold a pointer and supports the atomic ops below, as
-// well as atomic loads and stores.  Instances must be naturally-aligned.
-typedef intptr_t AtomicWord;
-
-#ifdef AtomicWordCastType
-// ------------------------------------------------------------------------
-// This section is needed only when explicit type casting is required to
-// cast AtomicWord to one of the basic atomic types (Atomic64 or Atomic32).
-// It also serves to document the AtomicWord interface.
-// ------------------------------------------------------------------------
-
-namespace base {
-namespace subtle {
-
-// Atomically execute:
-//      result = *ptr;
-//      if (*ptr == old_value)
-//        *ptr = new_value;
-//      return result;
-//
-// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
-// Always return the old value of "*ptr"
-//
-// This routine implies no memory barriers.
-inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
-                                           AtomicWord old_value,
-                                           AtomicWord new_value) {
-  return NoBarrier_CompareAndSwap(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr),
-      old_value, new_value);
-}
-
-// Atomically store new_value into *ptr, returning the previous value held in
-// *ptr.  This routine implies no memory barriers.
-inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
-                                           AtomicWord new_value) {
-  return NoBarrier_AtomicExchange(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), new_value);
-}
-
-inline AtomicWord Acquire_AtomicExchange(volatile AtomicWord* ptr,
-                                         AtomicWord new_value) {
-  return Acquire_AtomicExchange(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), new_value);
-}
-
-inline AtomicWord Release_AtomicExchange(volatile AtomicWord* ptr,
-                                         AtomicWord new_value) {
-  return Release_AtomicExchange(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), new_value);
-}
-
-inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
-                                         AtomicWord old_value,
-                                         AtomicWord new_value) {
-  return base::subtle::Acquire_CompareAndSwap(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr),
-      old_value, new_value);
-}
-
-inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
-                                         AtomicWord old_value,
-                                         AtomicWord new_value) {
-  return base::subtle::Release_CompareAndSwap(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr),
-      old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
-  NoBarrier_Store(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
-}
-
-inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
-  return base::subtle::Release_Store(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
-}
-
-inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
-  return NoBarrier_Load(
-      reinterpret_cast<volatile const AtomicWordCastType*>(ptr));
-}
-
-inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
-  return base::subtle::Acquire_Load(
-      reinterpret_cast<volatile const AtomicWordCastType*>(ptr));
-}
-
-}  // namespace base::subtle
-}  // namespace base
-#endif  // AtomicWordCastType
-
-// ------------------------------------------------------------------------
-// Commented out type definitions and method declarations for documentation
-// of the interface provided by this module.
-// ------------------------------------------------------------------------
-
-#if 0
-
-// Signed 32-bit type that supports the atomic ops below, as well as atomic
-// loads and stores.  Instances must be naturally aligned.  This type differs
-// from AtomicWord in 64-bit binaries where AtomicWord is 64-bits.
-typedef int32_t Atomic32;
-
-// Corresponding operations on Atomic32
-namespace base {
-namespace subtle {
-
-// Signed 64-bit type that supports the atomic ops below, as well as atomic
-// loads and stores.  Instances must be naturally aligned.  This type differs
-// from AtomicWord in 32-bit binaries where AtomicWord is 32-bits.
-typedef int64_t Atomic64;
-
-Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                  Atomic32 old_value,
-                                  Atomic32 new_value);
-Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
-Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
-Atomic32 Release_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
-Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                Atomic32 old_value,
-                                Atomic32 new_value);
-Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                Atomic32 old_value,
-                                Atomic32 new_value);
-void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
-void Release_Store(volatile Atomic32* ptr, Atomic32 value);
-Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
-Atomic32 Acquire_Load(volatile const Atomic32* ptr);
-
-// Corresponding operations on Atomic64
-Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                  Atomic64 old_value,
-                                  Atomic64 new_value);
-Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
-Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
-Atomic64 Release_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
-
-Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                Atomic64 old_value,
-                                Atomic64 new_value);
-Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                Atomic64 old_value,
-                                Atomic64 new_value);
-void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);
-void Release_Store(volatile Atomic64* ptr, Atomic64 value);
-Atomic64 NoBarrier_Load(volatile const Atomic64* ptr);
-Atomic64 Acquire_Load(volatile const Atomic64* ptr);
-}  // namespace base::subtle
-}  // namespace base
-
-void MemoryBarrier();
-
-#endif  // 0
-
-
-// ------------------------------------------------------------------------
-// The following are to be deprecated when all uses have been changed to
-// use the base::subtle namespace.
-// ------------------------------------------------------------------------
-
-#ifdef AtomicWordCastType
-// AtomicWord versions to be deprecated
-inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
-                                         AtomicWord old_value,
-                                         AtomicWord new_value) {
-  return base::subtle::Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
-                                         AtomicWord old_value,
-                                         AtomicWord new_value) {
-  return base::subtle::Release_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
-  return base::subtle::Release_Store(ptr, value);
-}
-
-inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
-  return base::subtle::Acquire_Load(ptr);
-}
-#endif  // AtomicWordCastType
-
-// 32-bit Acquire/Release operations to be deprecated.
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return base::subtle::Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return base::subtle::Release_CompareAndSwap(ptr, old_value, new_value);
-}
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  return base::subtle::Release_Store(ptr, value);
-}
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  return base::subtle::Acquire_Load(ptr);
-}
-
-#ifdef BASE_HAS_ATOMIC64
-
-// 64-bit Acquire/Release operations to be deprecated.
-
-inline base::subtle::Atomic64 Acquire_CompareAndSwap(
-    volatile base::subtle::Atomic64* ptr,
-    base::subtle::Atomic64 old_value, base::subtle::Atomic64 new_value) {
-  return base::subtle::Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-inline base::subtle::Atomic64 Release_CompareAndSwap(
-    volatile base::subtle::Atomic64* ptr,
-    base::subtle::Atomic64 old_value, base::subtle::Atomic64 new_value) {
-  return base::subtle::Release_CompareAndSwap(ptr, old_value, new_value);
-}
-inline void Release_Store(
-    volatile base::subtle::Atomic64* ptr, base::subtle::Atomic64 value) {
-  return base::subtle::Release_Store(ptr, value);
-}
-inline base::subtle::Atomic64 Acquire_Load(
-    volatile const base::subtle::Atomic64* ptr) {
-  return base::subtle::Acquire_Load(ptr);
-}
-
-#endif  // BASE_HAS_ATOMIC64
-
-#endif  // THREAD_ATOMICOPS_H_
diff --git a/third_party/tcmalloc/chromium/src/base/basictypes.h b/third_party/tcmalloc/chromium/src/base/basictypes.h
deleted file mode 100644
index 3bf59f4e..0000000
--- a/third_party/tcmalloc/chromium/src/base/basictypes.h
+++ /dev/null
@@ -1,437 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef _BASICTYPES_H_
-#define _BASICTYPES_H_
-
-#include <config.h>
-#include <string.h>       // for memcpy()
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>     // gets us PRId64, etc
-#endif
-
-// To use this in an autoconf setting, make sure you run the following
-// autoconf macros:
-//    AC_HEADER_STDC              /* for stdint_h and inttypes_h */
-//    AC_CHECK_TYPES([__int64])   /* defined in some windows platforms */
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>           // uint16_t might be here; PRId64 too.
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>             // to get uint16_t (ISO naming madness)
-#endif
-#include <sys/types.h>          // our last best hope for uint16_t
-
-// Standard typedefs
-// All Google code is compiled with -funsigned-char to make "char"
-// unsigned.  Google code therefore doesn't need a "uchar" type.
-// TODO(csilvers): how do we make sure unsigned-char works on non-gcc systems?
-typedef signed char         schar;
-typedef int8_t              int8;
-typedef int16_t             int16;
-typedef int32_t             int32;
-typedef int64_t             int64;
-
-// NOTE: unsigned types are DANGEROUS in loops and other arithmetical
-// places.  Use the signed types unless your variable represents a bit
-// pattern (eg a hash value) or you really need the extra bit.  Do NOT
-// use 'unsigned' to express "this value should always be positive";
-// use assertions for this.
-
-typedef uint8_t            uint8;
-typedef uint16_t           uint16;
-typedef uint32_t           uint32;
-typedef uint64_t           uint64;
-
-const uint16 kuint16max = (   (uint16) 0xFFFF);
-const uint32 kuint32max = (   (uint32) 0xFFFFFFFF);
-const uint64 kuint64max = ( (((uint64) kuint32max) << 32) | kuint32max );
-
-const  int8  kint8max   = (   (  int8) 0x7F);
-const  int16 kint16max  = (   ( int16) 0x7FFF);
-const  int32 kint32max  = (   ( int32) 0x7FFFFFFF);
-const  int64 kint64max =  ( ((( int64) kint32max) << 32) | kuint32max );
-
-const  int8  kint8min   = (   (  int8) 0x80);
-const  int16 kint16min  = (   ( int16) 0x8000);
-const  int32 kint32min  = (   ( int32) 0x80000000);
-const  int64 kint64min =  (-kint64max - 1LL);
-
-// Define the "portable" printf and scanf macros, if they're not
-// already there (via the inttypes.h we #included above, hopefully).
-// Mostly it's old systems that don't support inttypes.h, so we assume
-// they're 32 bit.
-#ifndef PRIx64
-#define PRIx64 "llx"
-#endif
-#ifndef SCNx64
-#define SCNx64 "llx"
-#endif
-#ifndef PRId64
-#define PRId64 "lld"
-#endif
-#ifndef SCNd64
-#define SCNd64 "lld"
-#endif
-#ifndef PRIu64
-#define PRIu64 "llu"
-#endif
-#ifndef PRIxPTR
-#define PRIxPTR "lx"
-#endif
-
-// Also allow for printing of a pthread_t.
-#define GPRIuPTHREAD "lu"
-#define GPRIxPTHREAD "lx"
-#if defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__APPLE__) || defined(__FreeBSD__)
-#define PRINTABLE_PTHREAD(pthreadt) reinterpret_cast<uintptr_t>(pthreadt)
-#else
-#define PRINTABLE_PTHREAD(pthreadt) pthreadt
-#endif
-
-#ifdef HAVE_BUILTIN_EXPECT
-#define PREDICT_TRUE(x) __builtin_expect(!!(x), 1)
-#define PREDICT_FALSE(x) __builtin_expect(!!(x), 0)
-#else
-#define PREDICT_TRUE(x) (x)
-#define PREDICT_FALSE(x) (x)
-#endif
-
-// A macro to disallow the evil copy constructor and operator= functions
-// This should be used in the private: declarations for a class
-#define DISALLOW_EVIL_CONSTRUCTORS(TypeName)    \
-  TypeName(const TypeName&);                    \
-  void operator=(const TypeName&)
-
-// An alternate name that leaves out the moral judgment... :-)
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) DISALLOW_EVIL_CONSTRUCTORS(TypeName)
-
-// The COMPILE_ASSERT macro can be used to verify that a compile time
-// expression is true. For example, you could use it to verify the
-// size of a static array:
-//
-//   COMPILE_ASSERT(sizeof(num_content_type_names) == sizeof(int),
-//                  content_type_names_incorrect_size);
-//
-// or to make sure a struct is smaller than a certain size:
-//
-//   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
-//
-// The second argument to the macro is the name of the variable. If
-// the expression is false, most compilers will issue a warning/error
-// containing the name of the variable.
-//
-// Implementation details of COMPILE_ASSERT:
-//
-// - COMPILE_ASSERT works by defining an array type that has -1
-//   elements (and thus is invalid) when the expression is false.
-//
-// - The simpler definition
-//
-//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
-//
-//   does not work, as gcc supports variable-length arrays whose sizes
-//   are determined at run-time (this is gcc's extension and not part
-//   of the C++ standard).  As a result, gcc fails to reject the
-//   following code with the simple definition:
-//
-//     int foo;
-//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
-//                               // not a compile-time constant.
-//
-// - By using the type CompileAssert<(bool(expr))>, we ensures that
-//   expr is a compile-time constant.  (Template arguments must be
-//   determined at compile-time.)
-//
-// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
-//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
-//
-//     CompileAssert<bool(expr)>
-//
-//   instead, these compilers will refuse to compile
-//
-//     COMPILE_ASSERT(5 > 0, some_message);
-//
-//   (They seem to think the ">" in "5 > 0" marks the end of the
-//   template argument list.)
-//
-// - The array size is (bool(expr) ? 1 : -1), instead of simply
-//
-//     ((expr) ? 1 : -1).
-//
-//   This is to avoid running into a bug in MS VC 7.1, which
-//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
-
-template <bool>
-struct CompileAssert {
-};
-
-#ifdef HAVE___ATTRIBUTE__
-# define ATTRIBUTE_UNUSED __attribute__((unused))
-#else
-# define ATTRIBUTE_UNUSED
-#endif
-
-#if defined(HAVE___ATTRIBUTE__) && defined(HAVE_TLS) && \
-    !(defined(__GNUC__) && !defined(__clang__) && defined(__arm__))
-#define ATTR_INITIAL_EXEC __attribute__ ((tls_model ("initial-exec")))
-#else
-#define ATTR_INITIAL_EXEC
-#endif
-
-#define COMPILE_ASSERT(expr, msg)                               \
-  typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] ATTRIBUTE_UNUSED
-
-#define arraysize(a)  (sizeof(a) / sizeof(*(a)))
-
-#define OFFSETOF_MEMBER(strct, field)                                   \
-   (reinterpret_cast<char*>(&reinterpret_cast<strct*>(16)->field) -     \
-    reinterpret_cast<char*>(16))
-
-// bit_cast<Dest,Source> implements the equivalent of
-// "*reinterpret_cast<Dest*>(&source)".
-//
-// The reinterpret_cast method would produce undefined behavior
-// according to ISO C++ specification section 3.10 -15 -.
-// bit_cast<> calls memcpy() which is blessed by the standard,
-// especially by the example in section 3.9.
-//
-// Fortunately memcpy() is very fast.  In optimized mode, with a
-// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
-// code with the minimal amount of data movement.  On a 32-bit system,
-// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
-// compiles to two loads and two stores.
-
-template <class Dest, class Source>
-inline Dest bit_cast(const Source& source) {
-  COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), bitcasting_unequal_sizes);
-  Dest dest;
-  memcpy(&dest, &source, sizeof(dest));
-  return dest;
-}
-
-// bit_store<Dest,Source> implements the equivalent of
-// "dest = *reinterpret_cast<Dest*>(&source)".
-//
-// This prevents undefined behavior when the dest pointer is unaligned.
-template <class Dest, class Source>
-inline void bit_store(Dest *dest, const Source *source) {
-  COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), bitcasting_unequal_sizes);
-  memcpy(dest, source, sizeof(Dest));
-}
-
-#ifdef HAVE___ATTRIBUTE__
-# define ATTRIBUTE_WEAK      __attribute__((weak))
-# define ATTRIBUTE_NOINLINE  __attribute__((noinline))
-#else
-# define ATTRIBUTE_WEAK
-# define ATTRIBUTE_NOINLINE
-#endif
-
-#if defined(HAVE___ATTRIBUTE__) && defined(__ELF__)
-# define ATTRIBUTE_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
-#else
-# define ATTRIBUTE_VISIBILITY_HIDDEN
-#endif
-
-// Section attributes are supported for both ELF and Mach-O, but in
-// very different ways.  Here's the API we provide:
-// 1) ATTRIBUTE_SECTION: put this with the declaration of all functions
-//    you want to be in the same linker section
-// 2) DEFINE_ATTRIBUTE_SECTION_VARS: must be called once per unique
-//    name.  You want to make sure this is executed before any
-//    DECLARE_ATTRIBUTE_SECTION_VARS; the easiest way is to put them
-//    in the same .cc file.  Put this call at the global level.
-// 3) INIT_ATTRIBUTE_SECTION_VARS: you can scatter calls to this in
-//    multiple places to help ensure execution before any
-//    DECLARE_ATTRIBUTE_SECTION_VARS.  You must have at least one
-//    DEFINE, but you can have many INITs.  Put each in its own scope.
-// 4) DECLARE_ATTRIBUTE_SECTION_VARS: must be called before using
-//    ATTRIBUTE_SECTION_START or ATTRIBUTE_SECTION_STOP on a name.
-//    Put this call at the global level.
-// 5) ATTRIBUTE_SECTION_START/ATTRIBUTE_SECTION_STOP: call this to say
-//    where in memory a given section is.  All functions declared with
-//    ATTRIBUTE_SECTION are guaranteed to be between START and STOP.
-
-#if defined(HAVE___ATTRIBUTE__) && defined(__ELF__)
-# define ATTRIBUTE_SECTION(name) __attribute__ ((section (#name))) __attribute__((noinline))
-
-  // Weak section declaration to be used as a global declaration
-  // for ATTRIBUTE_SECTION_START|STOP(name) to compile and link
-  // even without functions with ATTRIBUTE_SECTION(name).
-# define DECLARE_ATTRIBUTE_SECTION_VARS(name) \
-    extern char __start_##name[] ATTRIBUTE_WEAK; \
-    extern char __stop_##name[] ATTRIBUTE_WEAK
-# define INIT_ATTRIBUTE_SECTION_VARS(name)     // no-op for ELF
-# define DEFINE_ATTRIBUTE_SECTION_VARS(name)   // no-op for ELF
-
-  // Return void* pointers to start/end of a section of code with functions
-  // having ATTRIBUTE_SECTION(name), or 0 if no such function exists.
-  // One must DECLARE_ATTRIBUTE_SECTION(name) for this to compile and link.
-# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))
-# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))
-# define HAVE_ATTRIBUTE_SECTION_START 1
-
-#elif defined(HAVE___ATTRIBUTE__) && defined(__MACH__)
-# define ATTRIBUTE_SECTION(name) __attribute__ ((section ("__TEXT, " #name)))
-
-#include <mach-o/getsect.h>
-#include <mach-o/dyld.h>
-class AssignAttributeStartEnd {
- public:
-  AssignAttributeStartEnd(const char* name, char** pstart, char** pend) {
-    // Find out what dynamic library name is defined in
-    if (_dyld_present()) {
-      for (int i = _dyld_image_count() - 1; i >= 0; --i) {
-        const mach_header* hdr = _dyld_get_image_header(i);
-#ifdef MH_MAGIC_64
-        if (hdr->magic == MH_MAGIC_64) {
-          uint64_t len;
-          *pstart = getsectdatafromheader_64((mach_header_64*)hdr,
-                                             "__TEXT", name, &len);
-          if (*pstart) {   // NULL if not defined in this dynamic library
-            *pstart += _dyld_get_image_vmaddr_slide(i);   // correct for reloc
-            *pend = *pstart + len;
-            return;
-          }
-        }
-#endif
-        if (hdr->magic == MH_MAGIC) {
-          uint32_t len;
-          *pstart = getsectdatafromheader(hdr, "__TEXT", name, &len);
-          if (*pstart) {   // NULL if not defined in this dynamic library
-            *pstart += _dyld_get_image_vmaddr_slide(i);   // correct for reloc
-            *pend = *pstart + len;
-            return;
-          }
-        }
-      }
-    }
-    // If we get here, not defined in a dll at all.  See if defined statically.
-    unsigned long len;    // don't ask me why this type isn't uint32_t too...
-    *pstart = getsectdata("__TEXT", name, &len);
-    *pend = *pstart + len;
-  }
-};
-
-#define DECLARE_ATTRIBUTE_SECTION_VARS(name)    \
-  extern char* __start_##name;                  \
-  extern char* __stop_##name
-
-#define INIT_ATTRIBUTE_SECTION_VARS(name)               \
-  DECLARE_ATTRIBUTE_SECTION_VARS(name);                 \
-  static const AssignAttributeStartEnd __assign_##name( \
-    #name, &__start_##name, &__stop_##name)
-
-#define DEFINE_ATTRIBUTE_SECTION_VARS(name)     \
-  char* __start_##name, *__stop_##name;         \
-  INIT_ATTRIBUTE_SECTION_VARS(name)
-
-# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))
-# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))
-# define HAVE_ATTRIBUTE_SECTION_START 1
-
-#else  // not HAVE___ATTRIBUTE__ && __ELF__, nor HAVE___ATTRIBUTE__ && __MACH__
-# define ATTRIBUTE_SECTION(name)
-# define DECLARE_ATTRIBUTE_SECTION_VARS(name)
-# define INIT_ATTRIBUTE_SECTION_VARS(name)
-# define DEFINE_ATTRIBUTE_SECTION_VARS(name)
-# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(0))
-# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(0))
-
-#endif  // HAVE___ATTRIBUTE__ and __ELF__ or __MACH__
-
-#if defined(HAVE___ATTRIBUTE__)
-# if (defined(__i386__) || defined(__x86_64__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(64)))
-# elif (defined(__PPC__) || defined(__PPC64__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(16)))
-# elif (defined(__arm__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(64)))
-    // some ARMs have shorter cache lines (ARM1176JZF-S is 32 bytes for example) but obviously 64-byte aligned implies 32-byte aligned
-# elif (defined(__mips__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(128)))
-# elif (defined(__aarch64__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(64)))
-    // implementation specific, Cortex-A53 and 57 should have 64 bytes
-# elif (defined(__s390__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(256)))
-# else
-#   error Could not determine cache line length - unknown architecture
-# endif
-#else
-# define CACHELINE_ALIGNED
-#endif  // defined(HAVE___ATTRIBUTE__)
-
-#if defined(HAVE___ATTRIBUTE__ALIGNED_FN)
-#  define CACHELINE_ALIGNED_FN CACHELINE_ALIGNED
-#else
-#  define CACHELINE_ALIGNED_FN
-#endif
-
-// Structure for discovering alignment
-union MemoryAligner {
-  void*  p;
-  double d;
-  size_t s;
-} CACHELINE_ALIGNED;
-
-#if defined(HAVE___ATTRIBUTE__) && defined(__ELF__)
-#define ATTRIBUTE_HIDDEN __attribute__((visibility("hidden")))
-#else
-#define ATTRIBUTE_HIDDEN
-#endif
-
-#if defined(__GNUC__)
-#define ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
-#elif defined(_MSC_VER)
-#define ATTRIBUTE_ALWAYS_INLINE __forceinline
-#else
-#define ATTRIBUTE_ALWAYS_INLINE
-#endif
-
-// The following enum should be used only as a constructor argument to indicate
-// that the variable has static storage class, and that the constructor should
-// do nothing to its state.  It indicates to the reader that it is legal to
-// declare a static nistance of the class, provided the constructor is given
-// the base::LINKER_INITIALIZED argument.  Normally, it is unsafe to declare a
-// static variable that has a constructor or a destructor because invocation
-// order is undefined.  However, IF the type can be initialized by filling with
-// zeroes (which the loader does for static variables), AND the destructor also
-// does nothing to the storage, then a constructor declared as
-//       explicit MyClass(base::LinkerInitialized x) {}
-// and invoked as
-//       static MyClass my_variable_name(base::LINKER_INITIALIZED);
-namespace base {
-enum LinkerInitialized { LINKER_INITIALIZED };
-}
-
-#endif  // _BASICTYPES_H_
diff --git a/third_party/tcmalloc/chromium/src/base/commandlineflags.h b/third_party/tcmalloc/chromium/src/base/commandlineflags.h
deleted file mode 100644
index b2b58e9b..0000000
--- a/third_party/tcmalloc/chromium/src/base/commandlineflags.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// This file is a compatibility layer that defines Google's version of
-// command line flags that are used for configuration.
-//
-// We put flags into their own namespace.  It is purposefully
-// named in an opaque way that people should have trouble typing
-// directly.  The idea is that DEFINE puts the flag in the weird
-// namespace, and DECLARE imports the flag from there into the
-// current namespace.  The net result is to force people to use
-// DECLARE to get access to a flag, rather than saying
-//   extern bool FLAGS_logtostderr;
-// or some such instead.  We want this so we can put extra
-// functionality (like sanity-checking) in DECLARE if we want,
-// and make sure it is picked up everywhere.
-//
-// We also put the type of the variable in the namespace, so that
-// people can't DECLARE_int32 something that they DEFINE_bool'd
-// elsewhere.
-#ifndef BASE_COMMANDLINEFLAGS_H_
-#define BASE_COMMANDLINEFLAGS_H_
-
-#include <config.h>
-#include <string>
-#include <string.h>               // for memchr
-#include <stdlib.h>               // for getenv
-#include "base/basictypes.h"
-
-#define DECLARE_VARIABLE(type, name)                                          \
-  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead {  \
-  extern PERFTOOLS_DLL_DECL type FLAGS_##name;                                \
-  }                                                                           \
-  using FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead::FLAGS_##name
-
-#define DEFINE_VARIABLE(type, name, value, meaning) \
-  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead {  \
-  PERFTOOLS_DLL_DECL type FLAGS_##name(value);                                \
-  char FLAGS_no##name;                                                        \
-  }                                                                           \
-  using FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead::FLAGS_##name
-
-// bool specialization
-#define DECLARE_bool(name) \
-  DECLARE_VARIABLE(bool, name)
-#define DEFINE_bool(name, value, meaning) \
-  DEFINE_VARIABLE(bool, name, value, meaning)
-
-// int32 specialization
-#define DECLARE_int32(name) \
-  DECLARE_VARIABLE(int32, name)
-#define DEFINE_int32(name, value, meaning) \
-  DEFINE_VARIABLE(int32, name, value, meaning)
-
-// int64 specialization
-#define DECLARE_int64(name) \
-  DECLARE_VARIABLE(int64, name)
-#define DEFINE_int64(name, value, meaning) \
-  DEFINE_VARIABLE(int64, name, value, meaning)
-
-#define DECLARE_uint64(name) \
-  DECLARE_VARIABLE(uint64, name)
-#define DEFINE_uint64(name, value, meaning) \
-  DEFINE_VARIABLE(uint64, name, value, meaning)
-
-// double specialization
-#define DECLARE_double(name) \
-  DECLARE_VARIABLE(double, name)
-#define DEFINE_double(name, value, meaning) \
-  DEFINE_VARIABLE(double, name, value, meaning)
-
-// Special case for string, because of the pointer type.
-#define DECLARE_string(name)                                          \
-  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead {  \
-  extern const char* FLAGS_##name;                                            \
-  }                                                                           \
-  using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
-#define DEFINE_string(name, value, meaning) \
-  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead {  \
-  const char* FLAGS_##name = value;                                           \
-  char FLAGS_no##name;                                                        \
-  }                                                                           \
-  using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
-
-// implemented in sysinfo.cc
-namespace tcmalloc {
-  namespace commandlineflags {
-
-    inline bool StringToBool(const char *value, bool def) {
-      if (!value) {
-        return def;
-      }
-      switch (value[0]) {
-      case 't':
-      case 'T':
-      case 'y':
-      case 'Y':
-      case '1':
-      case '\0':
-        return true;
-      }
-      return false;
-    }
-
-    inline int StringToInt(const char *value, int def) {
-      if (!value) {
-        return def;
-      }
-      return strtol(value, NULL, 10);
-    }
-
-    inline long long StringToLongLong(const char *value, long long def) {
-      if (!value) {
-        return def;
-      }
-      return strtoll(value, NULL, 10);
-    }
-
-    inline double StringToDouble(const char *value, double def) {
-      if (!value) {
-        return def;
-      }
-      return strtod(value, NULL);
-    }
-  }
-}
-
-// These macros (could be functions, but I don't want to bother with a .cc
-// file), make it easier to initialize flags from the environment.
-
-#if defined(ENABLE_PROFILING)
-
-#define EnvToString(envname, dflt)   \
-  (!getenv(envname) ? (dflt) : getenv(envname))
-
-#define EnvToBool(envname, dflt)   \
-  tcmalloc::commandlineflags::StringToBool(getenv(envname), dflt)
-
-#define EnvToInt(envname, dflt)  \
-  tcmalloc::commandlineflags::StringToInt(getenv(envname), dflt)
-
-#define EnvToInt64(envname, dflt)  \
-  tcmalloc::commandlineflags::StringToLongLong(getenv(envname), dflt)
-
-#define EnvToDouble(envname, dflt)  \
-  tcmalloc::commandlineflags::StringToDouble(getenv(envname), dflt)
-
-#else  // defined(ENABLE_PROFILING)
-
-#define EnvToString(envname, dflt) (dflt)
-#define EnvToBool(envname, dflt) (dflt)
-#define EnvToInt(envname, dflt) (dflt)
-#define EnvToInt64(envname, dflt) (dflt)
-#define EnvToDouble(envname, dflt) (dflt)
-
-#endif  // defined(ENABLE_PROFILING)
-
-#endif  // BASE_COMMANDLINEFLAGS_H_
diff --git a/third_party/tcmalloc/chromium/src/base/dynamic_annotations.c b/third_party/tcmalloc/chromium/src/base/dynamic_annotations.c
deleted file mode 100644
index 87bd2ec..0000000
--- a/third_party/tcmalloc/chromium/src/base/dynamic_annotations.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* Copyright (c) 2008-2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Kostya Serebryany
- */
-
-#ifdef __cplusplus
-# error "This file should be built as pure C to avoid name mangling"
-#endif
-
-#include "config.h"
-#include <stdlib.h>
-#include <string.h>
-
-#include "base/dynamic_annotations.h"
-#include "getenv_safe.h" // for TCMallocGetenvSafe
-
-#ifdef __GNUC__
-/* valgrind.h uses gcc extensions so it won't build with other compilers */
-# ifdef HAVE_VALGRIND_H    /* prefer the user's copy if they have it */
-#  include <valgrind.h>
-# else                     /* otherwise just use the copy that we have */
-#  include "third_party/valgrind.h"
-# endif
-#endif
-
-/* Compiler-based ThreadSanitizer defines
-   DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL = 1
-   and provides its own definitions of the functions. */
-
-#ifndef DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL
-# define DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL 0
-#endif
-
-/* Each function is empty and called (via a macro) only in debug mode.
-   The arguments are captured by dynamic tools at runtime. */
-
-#if DYNAMIC_ANNOTATIONS_ENABLED == 1 \
-    && DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0
-
-void AnnotateRWLockCreate(const char *file, int line,
-                          const volatile void *lock){}
-void AnnotateRWLockDestroy(const char *file, int line,
-                           const volatile void *lock){}
-void AnnotateRWLockAcquired(const char *file, int line,
-                            const volatile void *lock, long is_w){}
-void AnnotateRWLockReleased(const char *file, int line,
-                            const volatile void *lock, long is_w){}
-void AnnotateBarrierInit(const char *file, int line,
-                         const volatile void *barrier, long count,
-                         long reinitialization_allowed) {}
-void AnnotateBarrierWaitBefore(const char *file, int line,
-                               const volatile void *barrier) {}
-void AnnotateBarrierWaitAfter(const char *file, int line,
-                              const volatile void *barrier) {}
-void AnnotateBarrierDestroy(const char *file, int line,
-                            const volatile void *barrier) {}
-
-void AnnotateCondVarWait(const char *file, int line,
-                         const volatile void *cv,
-                         const volatile void *lock){}
-void AnnotateCondVarSignal(const char *file, int line,
-                           const volatile void *cv){}
-void AnnotateCondVarSignalAll(const char *file, int line,
-                              const volatile void *cv){}
-void AnnotatePublishMemoryRange(const char *file, int line,
-                                const volatile void *address,
-                                long size){}
-void AnnotateUnpublishMemoryRange(const char *file, int line,
-                                  const volatile void *address,
-                                  long size){}
-void AnnotatePCQCreate(const char *file, int line,
-                       const volatile void *pcq){}
-void AnnotatePCQDestroy(const char *file, int line,
-                        const volatile void *pcq){}
-void AnnotatePCQPut(const char *file, int line,
-                    const volatile void *pcq){}
-void AnnotatePCQGet(const char *file, int line,
-                    const volatile void *pcq){}
-void AnnotateNewMemory(const char *file, int line,
-                       const volatile void *mem,
-                       long size){}
-void AnnotateExpectRace(const char *file, int line,
-                        const volatile void *mem,
-                        const char *description){}
-void AnnotateBenignRace(const char *file, int line,
-                        const volatile void *mem,
-                        const char *description){}
-void AnnotateBenignRaceSized(const char *file, int line,
-                             const volatile void *mem,
-                             long size,
-                             const char *description) {}
-void AnnotateMutexIsUsedAsCondVar(const char *file, int line,
-                                  const volatile void *mu){}
-void AnnotateTraceMemory(const char *file, int line,
-                         const volatile void *arg){}
-void AnnotateThreadName(const char *file, int line,
-                        const char *name){}
-void AnnotateIgnoreReadsBegin(const char *file, int line){}
-void AnnotateIgnoreReadsEnd(const char *file, int line){}
-void AnnotateIgnoreWritesBegin(const char *file, int line){}
-void AnnotateIgnoreWritesEnd(const char *file, int line){}
-void AnnotateEnableRaceDetection(const char *file, int line, int enable){}
-void AnnotateNoOp(const char *file, int line,
-                  const volatile void *arg){}
-void AnnotateFlushState(const char *file, int line){}
-
-#endif  /* DYNAMIC_ANNOTATIONS_ENABLED == 1
-    && DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */
-
-#if DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0
-
-static int GetRunningOnValgrind(void) {
-#ifdef RUNNING_ON_VALGRIND
-  if (RUNNING_ON_VALGRIND) return 1;
-#endif
-  const char *running_on_valgrind_str = TCMallocGetenvSafe("RUNNING_ON_VALGRIND");
-  if (running_on_valgrind_str) {
-    return strcmp(running_on_valgrind_str, "0") != 0;
-  }
-  return 0;
-}
-
-/* See the comments in dynamic_annotations.h */
-int RunningOnValgrind(void) {
-  static volatile int running_on_valgrind = -1;
-  int local_running_on_valgrind = running_on_valgrind;
-  /* C doesn't have thread-safe initialization of statics, and we
-     don't want to depend on pthread_once here, so hack it. */
-  ANNOTATE_BENIGN_RACE(&running_on_valgrind, "safe hack");
-  if (local_running_on_valgrind == -1)
-    running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind();
-  return local_running_on_valgrind;
-}
-
-#endif  /* DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */
-
-/* See the comments in dynamic_annotations.h */
-double ValgrindSlowdown(void) {
-  /* Same initialization hack as in RunningOnValgrind(). */
-  static volatile double slowdown = 0.0;
-  double local_slowdown = slowdown;
-  ANNOTATE_BENIGN_RACE(&slowdown, "safe hack");
-  if (RunningOnValgrind() == 0) {
-    return 1.0;
-  }
-  if (local_slowdown == 0.0) {
-    char *env = getenv("VALGRIND_SLOWDOWN");
-    slowdown = local_slowdown = env ? atof(env) : 50.0;
-  }
-  return local_slowdown;
-}
diff --git a/third_party/tcmalloc/chromium/src/base/dynamic_annotations.h b/third_party/tcmalloc/chromium/src/base/dynamic_annotations.h
deleted file mode 100644
index 4669315..0000000
--- a/third_party/tcmalloc/chromium/src/base/dynamic_annotations.h
+++ /dev/null
@@ -1,627 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Kostya Serebryany
- */
-
-/* This file defines dynamic annotations for use with dynamic analysis
-   tool such as valgrind, PIN, etc.
-
-   Dynamic annotation is a source code annotation that affects
-   the generated code (that is, the annotation is not a comment).
-   Each such annotation is attached to a particular
-   instruction and/or to a particular object (address) in the program.
-
-   The annotations that should be used by users are macros in all upper-case
-   (e.g., ANNOTATE_NEW_MEMORY).
-
-   Actual implementation of these macros may differ depending on the
-   dynamic analysis tool being used.
-
-   See http://code.google.com/p/data-race-test/  for more information.
-
-   This file supports the following dynamic analysis tools:
-   - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero).
-      Macros are defined empty.
-   - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1).
-      Macros are defined as calls to non-inlinable empty functions
-      that are intercepted by Valgrind. */
-
-#ifndef BASE_DYNAMIC_ANNOTATIONS_H_
-#define BASE_DYNAMIC_ANNOTATIONS_H_
-
-#ifndef DYNAMIC_ANNOTATIONS_ENABLED
-# define DYNAMIC_ANNOTATIONS_ENABLED 0
-#endif
-
-#if DYNAMIC_ANNOTATIONS_ENABLED != 0
-
-  /* -------------------------------------------------------------
-     Annotations useful when implementing condition variables such as CondVar,
-     using conditional critical sections (Await/LockWhen) and when constructing
-     user-defined synchronization mechanisms.
-
-     The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can
-     be used to define happens-before arcs in user-defined synchronization
-     mechanisms:  the race detector will infer an arc from the former to the
-     latter when they share the same argument pointer.
-
-     Example 1 (reference counting):
-
-     void Unref() {
-       ANNOTATE_HAPPENS_BEFORE(&refcount_);
-       if (AtomicDecrementByOne(&refcount_) == 0) {
-         ANNOTATE_HAPPENS_AFTER(&refcount_);
-         delete this;
-       }
-     }
-
-     Example 2 (message queue):
-
-     void MyQueue::Put(Type *e) {
-       MutexLock lock(&mu_);
-       ANNOTATE_HAPPENS_BEFORE(e);
-       PutElementIntoMyQueue(e);
-     }
-
-     Type *MyQueue::Get() {
-       MutexLock lock(&mu_);
-       Type *e = GetElementFromMyQueue();
-       ANNOTATE_HAPPENS_AFTER(e);
-       return e;
-     }
-
-     Note: when possible, please use the existing reference counting and message
-     queue implementations instead of inventing new ones. */
-
-  /* Report that wait on the condition variable at address "cv" has succeeded
-     and the lock at address "lock" is held. */
-  #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \
-    AnnotateCondVarWait(__FILE__, __LINE__, cv, lock)
-
-  /* Report that wait on the condition variable at "cv" has succeeded.  Variant
-     w/o lock. */
-  #define ANNOTATE_CONDVAR_WAIT(cv) \
-    AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL)
-
-  /* Report that we are about to signal on the condition variable at address
-     "cv". */
-  #define ANNOTATE_CONDVAR_SIGNAL(cv) \
-    AnnotateCondVarSignal(__FILE__, __LINE__, cv)
-
-  /* Report that we are about to signal_all on the condition variable at "cv". */
-  #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \
-    AnnotateCondVarSignalAll(__FILE__, __LINE__, cv)
-
-  /* Annotations for user-defined synchronization mechanisms. */
-  #define ANNOTATE_HAPPENS_BEFORE(obj) ANNOTATE_CONDVAR_SIGNAL(obj)
-  #define ANNOTATE_HAPPENS_AFTER(obj)  ANNOTATE_CONDVAR_WAIT(obj)
-
-  /* Report that the bytes in the range [pointer, pointer+size) are about
-     to be published safely. The race checker will create a happens-before
-     arc from the call ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to
-     subsequent accesses to this memory.
-     Note: this annotation may not work properly if the race detector uses
-     sampling, i.e. does not observe all memory accesses.
-     */
-  #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \
-    AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size)
-
-  /* DEPRECATED. Don't use it. */
-  #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) \
-    AnnotateUnpublishMemoryRange(__FILE__, __LINE__, pointer, size)
-
-  /* DEPRECATED. Don't use it. */
-  #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size)   \
-    do {                                              \
-      ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size); \
-      ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size);   \
-    } while (0)
-
-  /* Instruct the tool to create a happens-before arc between mu->Unlock() and
-     mu->Lock(). This annotation may slow down the race detector and hide real
-     races. Normally it is used only when it would be difficult to annotate each
-     of the mutex's critical sections individually using the annotations above.
-     This annotation makes sense only for hybrid race detectors. For pure
-     happens-before detectors this is a no-op. For more details see
-     http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */
-  #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \
-    AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu)
-
-  /* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */
-  #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \
-    AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu)
-
-  /* -------------------------------------------------------------
-     Annotations useful when defining memory allocators, or when memory that
-     was protected in one way starts to be protected in another. */
-
-  /* Report that a new memory at "address" of size "size" has been allocated.
-     This might be used when the memory has been retrieved from a free list and
-     is about to be reused, or when a the locking discipline for a variable
-     changes. */
-  #define ANNOTATE_NEW_MEMORY(address, size) \
-    AnnotateNewMemory(__FILE__, __LINE__, address, size)
-
-  /* -------------------------------------------------------------
-     Annotations useful when defining FIFO queues that transfer data between
-     threads. */
-
-  /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at
-     address "pcq" has been created.  The ANNOTATE_PCQ_* annotations
-     should be used only for FIFO queues.  For non-FIFO queues use
-     ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). */
-  #define ANNOTATE_PCQ_CREATE(pcq) \
-    AnnotatePCQCreate(__FILE__, __LINE__, pcq)
-
-  /* Report that the queue at address "pcq" is about to be destroyed. */
-  #define ANNOTATE_PCQ_DESTROY(pcq) \
-    AnnotatePCQDestroy(__FILE__, __LINE__, pcq)
-
-  /* Report that we are about to put an element into a FIFO queue at address
-     "pcq". */
-  #define ANNOTATE_PCQ_PUT(pcq) \
-    AnnotatePCQPut(__FILE__, __LINE__, pcq)
-
-  /* Report that we've just got an element from a FIFO queue at address "pcq". */
-  #define ANNOTATE_PCQ_GET(pcq) \
-    AnnotatePCQGet(__FILE__, __LINE__, pcq)
-
-  /* -------------------------------------------------------------
-     Annotations that suppress errors.  It is usually better to express the
-     program's synchronization using the other annotations, but these can
-     be used when all else fails. */
-
-  /* Report that we may have a benign race at "pointer", with size
-     "sizeof(*(pointer))". "pointer" must be a non-void* pointer.  Insert at the
-     point where "pointer" has been allocated, preferably close to the point
-     where the race happens.  See also ANNOTATE_BENIGN_RACE_STATIC. */
-  #define ANNOTATE_BENIGN_RACE(pointer, description) \
-    AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \
-                            sizeof(*(pointer)), description)
-
-  /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to
-     the memory range [address, address+size). */
-  #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
-    AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description)
-
-  /* Request the analysis tool to ignore all reads in the current thread
-     until ANNOTATE_IGNORE_READS_END is called.
-     Useful to ignore intentional racey reads, while still checking
-     other reads and all writes.
-     See also ANNOTATE_UNPROTECTED_READ. */
-  #define ANNOTATE_IGNORE_READS_BEGIN() \
-    AnnotateIgnoreReadsBegin(__FILE__, __LINE__)
-
-  /* Stop ignoring reads. */
-  #define ANNOTATE_IGNORE_READS_END() \
-    AnnotateIgnoreReadsEnd(__FILE__, __LINE__)
-
-  /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */
-  #define ANNOTATE_IGNORE_WRITES_BEGIN() \
-    AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
-
-  /* Stop ignoring writes. */
-  #define ANNOTATE_IGNORE_WRITES_END() \
-    AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
-
-  /* Start ignoring all memory accesses (reads and writes). */
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
-    do {\
-      ANNOTATE_IGNORE_READS_BEGIN();\
-      ANNOTATE_IGNORE_WRITES_BEGIN();\
-    }while(0)\
-
-  /* Stop ignoring all memory accesses. */
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
-    do {\
-      ANNOTATE_IGNORE_WRITES_END();\
-      ANNOTATE_IGNORE_READS_END();\
-    }while(0)\
-
-  /* Enable (enable!=0) or disable (enable==0) race detection for all threads.
-     This annotation could be useful if you want to skip expensive race analysis
-     during some period of program execution, e.g. during initialization. */
-  #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \
-    AnnotateEnableRaceDetection(__FILE__, __LINE__, enable)
-
-  /* -------------------------------------------------------------
-     Annotations useful for debugging. */
-
-  /* Request to trace every access to "address". */
-  #define ANNOTATE_TRACE_MEMORY(address) \
-    AnnotateTraceMemory(__FILE__, __LINE__, address)
-
-  /* Report the current thread name to a race detector. */
-  #define ANNOTATE_THREAD_NAME(name) \
-    AnnotateThreadName(__FILE__, __LINE__, name)
-
-  /* -------------------------------------------------------------
-     Annotations useful when implementing locks.  They are not
-     normally needed by modules that merely use locks.
-     The "lock" argument is a pointer to the lock object. */
-
-  /* Report that a lock has been created at address "lock". */
-  #define ANNOTATE_RWLOCK_CREATE(lock) \
-    AnnotateRWLockCreate(__FILE__, __LINE__, lock)
-
-  /* Report that the lock at address "lock" is about to be destroyed. */
-  #define ANNOTATE_RWLOCK_DESTROY(lock) \
-    AnnotateRWLockDestroy(__FILE__, __LINE__, lock)
-
-  /* Report that the lock at address "lock" has been acquired.
-     is_w=1 for writer lock, is_w=0 for reader lock. */
-  #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \
-    AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w)
-
-  /* Report that the lock at address "lock" is about to be released. */
-  #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \
-    AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w)
-
-  /* -------------------------------------------------------------
-     Annotations useful when implementing barriers.  They are not
-     normally needed by modules that merely use barriers.
-     The "barrier" argument is a pointer to the barrier object. */
-
-  /* Report that the "barrier" has been initialized with initial "count".
-   If 'reinitialization_allowed' is true, initialization is allowed to happen
-   multiple times w/o calling barrier_destroy() */
-  #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
-    AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \
-                        reinitialization_allowed)
-
-  /* Report that we are about to enter barrier_wait("barrier"). */
-  #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \
-    AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier)
-
-  /* Report that we just exited barrier_wait("barrier"). */
-  #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \
-    AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier)
-
-  /* Report that the "barrier" has been destroyed. */
-  #define ANNOTATE_BARRIER_DESTROY(barrier) \
-    AnnotateBarrierDestroy(__FILE__, __LINE__, barrier)
-
-  /* -------------------------------------------------------------
-     Annotations useful for testing race detectors. */
-
-  /* Report that we expect a race on the variable at "address".
-     Use only in unit tests for a race detector. */
-  #define ANNOTATE_EXPECT_RACE(address, description) \
-    AnnotateExpectRace(__FILE__, __LINE__, address, description)
-
-  /* A no-op. Insert where you like to test the interceptors. */
-  #define ANNOTATE_NO_OP(arg) \
-    AnnotateNoOp(__FILE__, __LINE__, arg)
-
-  /* Force the race detector to flush its state. The actual effect depends on
-   * the implementation of the detector. */
-  #define ANNOTATE_FLUSH_STATE() \
-    AnnotateFlushState(__FILE__, __LINE__)
-
-
-#else  /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
-
-  #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */
-  #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */
-  #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */
-  #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */
-  #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */
-  #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */
-  #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */
-  #define ANNOTATE_BARRIER_DESTROY(barrier) /* empty */
-  #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */
-  #define ANNOTATE_CONDVAR_WAIT(cv) /* empty */
-  #define ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */
-  #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */
-  #define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */
-  #define ANNOTATE_HAPPENS_AFTER(obj) /* empty */
-  #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */
-  #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size)  /* empty */
-  #define ANNOTATE_SWAP_MEMORY_RANGE(address, size)  /* empty */
-  #define ANNOTATE_PCQ_CREATE(pcq) /* empty */
-  #define ANNOTATE_PCQ_DESTROY(pcq) /* empty */
-  #define ANNOTATE_PCQ_PUT(pcq) /* empty */
-  #define ANNOTATE_PCQ_GET(pcq) /* empty */
-  #define ANNOTATE_NEW_MEMORY(address, size) /* empty */
-  #define ANNOTATE_EXPECT_RACE(address, description) /* empty */
-  #define ANNOTATE_BENIGN_RACE(address, description) /* empty */
-  #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */
-  #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */
-  #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */
-  #define ANNOTATE_TRACE_MEMORY(arg) /* empty */
-  #define ANNOTATE_THREAD_NAME(name) /* empty */
-  #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */
-  #define ANNOTATE_IGNORE_READS_END() /* empty */
-  #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */
-  #define ANNOTATE_IGNORE_WRITES_END() /* empty */
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */
-  #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */
-  #define ANNOTATE_NO_OP(arg) /* empty */
-  #define ANNOTATE_FLUSH_STATE() /* empty */
-
-#endif  /* DYNAMIC_ANNOTATIONS_ENABLED */
-
-/* Macro definitions for GCC attributes that allow static thread safety
-   analysis to recognize and use some of the dynamic annotations as
-   escape hatches.
-   TODO(lcwu): remove the check for __SUPPORT_DYN_ANNOTATION__ once the
-   default crosstool/GCC supports these GCC attributes.  */
-
-#define ANNOTALYSIS_STATIC_INLINE
-#define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ;
-#define ANNOTALYSIS_IGNORE_READS_BEGIN
-#define ANNOTALYSIS_IGNORE_READS_END
-#define ANNOTALYSIS_IGNORE_WRITES_BEGIN
-#define ANNOTALYSIS_IGNORE_WRITES_END
-#define ANNOTALYSIS_UNPROTECTED_READ
-
-#if defined(__GNUC__) && (!defined(SWIG)) && (!defined(__clang__)) && \
-    defined(__SUPPORT_TS_ANNOTATION__) && defined(__SUPPORT_DYN_ANNOTATION__)
-
-#if DYNAMIC_ANNOTATIONS_ENABLED == 0
-#define ANNOTALYSIS_ONLY 1
-#undef ANNOTALYSIS_STATIC_INLINE
-#define ANNOTALYSIS_STATIC_INLINE static inline
-#undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-#define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY { (void)file; (void)line; }
-#endif
-
-/* Only emit attributes when annotalysis is enabled. */
-#if defined(__SUPPORT_TS_ANNOTATION__) && defined(__SUPPORT_DYN_ANNOTATION__)
-#undef  ANNOTALYSIS_IGNORE_READS_BEGIN
-#define ANNOTALYSIS_IGNORE_READS_BEGIN  __attribute__ ((ignore_reads_begin))
-#undef  ANNOTALYSIS_IGNORE_READS_END
-#define ANNOTALYSIS_IGNORE_READS_END    __attribute__ ((ignore_reads_end))
-#undef  ANNOTALYSIS_IGNORE_WRITES_BEGIN
-#define ANNOTALYSIS_IGNORE_WRITES_BEGIN __attribute__ ((ignore_writes_begin))
-#undef  ANNOTALYSIS_IGNORE_WRITES_END
-#define ANNOTALYSIS_IGNORE_WRITES_END   __attribute__ ((ignore_writes_end))
-#undef  ANNOTALYSIS_UNPROTECTED_READ
-#define ANNOTALYSIS_UNPROTECTED_READ    __attribute__ ((unprotected_read))
-#endif
-
-#endif // defined(__GNUC__) && (!defined(SWIG)) && (!defined(__clang__))
-
-/* Use the macros above rather than using these functions directly. */
-#ifdef __cplusplus
-extern "C" {
-#endif
-void AnnotateRWLockCreate(const char *file, int line,
-                          const volatile void *lock);
-void AnnotateRWLockDestroy(const char *file, int line,
-                           const volatile void *lock);
-void AnnotateRWLockAcquired(const char *file, int line,
-                            const volatile void *lock, long is_w);
-void AnnotateRWLockReleased(const char *file, int line,
-                            const volatile void *lock, long is_w);
-void AnnotateBarrierInit(const char *file, int line,
-                         const volatile void *barrier, long count,
-                         long reinitialization_allowed);
-void AnnotateBarrierWaitBefore(const char *file, int line,
-                               const volatile void *barrier);
-void AnnotateBarrierWaitAfter(const char *file, int line,
-                              const volatile void *barrier);
-void AnnotateBarrierDestroy(const char *file, int line,
-                            const volatile void *barrier);
-void AnnotateCondVarWait(const char *file, int line,
-                         const volatile void *cv,
-                         const volatile void *lock);
-void AnnotateCondVarSignal(const char *file, int line,
-                           const volatile void *cv);
-void AnnotateCondVarSignalAll(const char *file, int line,
-                              const volatile void *cv);
-void AnnotatePublishMemoryRange(const char *file, int line,
-                                const volatile void *address,
-                                long size);
-void AnnotateUnpublishMemoryRange(const char *file, int line,
-                                  const volatile void *address,
-                                  long size);
-void AnnotatePCQCreate(const char *file, int line,
-                       const volatile void *pcq);
-void AnnotatePCQDestroy(const char *file, int line,
-                        const volatile void *pcq);
-void AnnotatePCQPut(const char *file, int line,
-                    const volatile void *pcq);
-void AnnotatePCQGet(const char *file, int line,
-                    const volatile void *pcq);
-void AnnotateNewMemory(const char *file, int line,
-                       const volatile void *address,
-                       long size);
-void AnnotateExpectRace(const char *file, int line,
-                        const volatile void *address,
-                        const char *description);
-void AnnotateBenignRace(const char *file, int line,
-                        const volatile void *address,
-                        const char *description);
-void AnnotateBenignRaceSized(const char *file, int line,
-                        const volatile void *address,
-                        long size,
-                        const char *description);
-void AnnotateMutexIsUsedAsCondVar(const char *file, int line,
-                                  const volatile void *mu);
-void AnnotateTraceMemory(const char *file, int line,
-                         const volatile void *arg);
-void AnnotateThreadName(const char *file, int line,
-                        const char *name);
-ANNOTALYSIS_STATIC_INLINE
-void AnnotateIgnoreReadsBegin(const char *file, int line)
-    ANNOTALYSIS_IGNORE_READS_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-ANNOTALYSIS_STATIC_INLINE
-void AnnotateIgnoreReadsEnd(const char *file, int line)
-    ANNOTALYSIS_IGNORE_READS_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-ANNOTALYSIS_STATIC_INLINE
-void AnnotateIgnoreWritesBegin(const char *file, int line)
-    ANNOTALYSIS_IGNORE_WRITES_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-ANNOTALYSIS_STATIC_INLINE
-void AnnotateIgnoreWritesEnd(const char *file, int line)
-    ANNOTALYSIS_IGNORE_WRITES_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-void AnnotateEnableRaceDetection(const char *file, int line, int enable);
-void AnnotateNoOp(const char *file, int line,
-                  const volatile void *arg);
-void AnnotateFlushState(const char *file, int line);
-
-/* Return non-zero value if running under valgrind.
-
-  If "valgrind.h" is included into dynamic_annotations.c,
-  the regular valgrind mechanism will be used.
-  See http://valgrind.org/docs/manual/manual-core-adv.html about
-  RUNNING_ON_VALGRIND and other valgrind "client requests".
-  The file "valgrind.h" may be obtained by doing
-     svn co svn://svn.valgrind.org/valgrind/trunk/include
-
-  If for some reason you can't use "valgrind.h" or want to fake valgrind,
-  there are two ways to make this function return non-zero:
-    - Use environment variable: export RUNNING_ON_VALGRIND=1
-    - Make your tool intercept the function RunningOnValgrind() and
-      change its return value.
- */
-int RunningOnValgrind(void);
-
-/* ValgrindSlowdown returns:
-    * 1.0, if (RunningOnValgrind() == 0)
-    * 50.0, if (RunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL)
-    * atof(getenv("VALGRIND_SLOWDOWN")) otherwise
-   This function can be used to scale timeout values:
-   EXAMPLE:
-   for (;;) {
-     DoExpensiveBackgroundTask();
-     SleepForSeconds(5 * ValgrindSlowdown());
-   }
- */
-double ValgrindSlowdown(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus)
-
-  /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
-
-     Instead of doing
-        ANNOTATE_IGNORE_READS_BEGIN();
-        ... = x;
-        ANNOTATE_IGNORE_READS_END();
-     one can use
-        ... = ANNOTATE_UNPROTECTED_READ(x); */
-  template <class T>
-  inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x)
-      ANNOTALYSIS_UNPROTECTED_READ {
-    ANNOTATE_IGNORE_READS_BEGIN();
-    T res = x;
-    ANNOTATE_IGNORE_READS_END();
-    return res;
-  }
-  /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
-  #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)        \
-    namespace {                                                       \
-      class static_var ## _annotator {                                \
-       public:                                                        \
-        static_var ## _annotator() {                                  \
-          ANNOTATE_BENIGN_RACE_SIZED(&static_var,                     \
-                                      sizeof(static_var),             \
-            # static_var ": " description);                           \
-        }                                                             \
-      };                                                              \
-      static static_var ## _annotator the ## static_var ## _annotator;\
-    }
-#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
-
-  #define ANNOTATE_UNPROTECTED_READ(x) (x)
-  #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)  /* empty */
-
-#endif /* DYNAMIC_ANNOTATIONS_ENABLED */
-
-/* Annotalysis, a GCC based static analyzer, is able to understand and use
-   some of the dynamic annotations defined in this file. However, dynamic
-   annotations are usually disabled in the opt mode (to avoid additional
-   runtime overheads) while Annotalysis only works in the opt mode.
-   In order for Annotalysis to use these dynamic annotations when they
-   are disabled, we re-define these annotations here. Note that unlike the
-   original macro definitions above, these macros are expanded to calls to
-   static inline functions so that the compiler will be able to remove the
-   calls after the analysis. */
-
-#ifdef ANNOTALYSIS_ONLY
-
-  #undef ANNOTALYSIS_ONLY
-
-  /* Undefine and re-define the macros that the static analyzer understands. */
-  #undef ANNOTATE_IGNORE_READS_BEGIN
-  #define ANNOTATE_IGNORE_READS_BEGIN()           \
-    AnnotateIgnoreReadsBegin(__FILE__, __LINE__)
-
-  #undef ANNOTATE_IGNORE_READS_END
-  #define ANNOTATE_IGNORE_READS_END()             \
-    AnnotateIgnoreReadsEnd(__FILE__, __LINE__)
-
-  #undef ANNOTATE_IGNORE_WRITES_BEGIN
-  #define ANNOTATE_IGNORE_WRITES_BEGIN()          \
-    AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
-
-  #undef ANNOTATE_IGNORE_WRITES_END
-  #define ANNOTATE_IGNORE_WRITES_END()            \
-    AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
-
-  #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN()       \
-    do {                                                 \
-      ANNOTATE_IGNORE_READS_BEGIN();                     \
-      ANNOTATE_IGNORE_WRITES_BEGIN();                    \
-    }while(0)                                            \
-
-  #undef ANNOTATE_IGNORE_READS_AND_WRITES_END
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_END()  \
-    do {                                          \
-      ANNOTATE_IGNORE_WRITES_END();               \
-      ANNOTATE_IGNORE_READS_END();                \
-    }while(0)                                     \
-
-  #if defined(__cplusplus)
-    #undef ANNOTATE_UNPROTECTED_READ
-    template <class T>
-    inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x)
-         ANNOTALYSIS_UNPROTECTED_READ {
-      ANNOTATE_IGNORE_READS_BEGIN();
-      T res = x;
-      ANNOTATE_IGNORE_READS_END();
-      return res;
-    }
-  #endif /* __cplusplus */
-
-#endif /* ANNOTALYSIS_ONLY */
-
-/* Undefine the macros intended only in this file. */
-#undef ANNOTALYSIS_STATIC_INLINE
-#undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-
-#endif  /* BASE_DYNAMIC_ANNOTATIONS_H_ */
diff --git a/third_party/tcmalloc/chromium/src/base/elf_mem_image.cc b/third_party/tcmalloc/chromium/src/base/elf_mem_image.cc
deleted file mode 100644
index d2ca1a5..0000000
--- a/third_party/tcmalloc/chromium/src/base/elf_mem_image.cc
+++ /dev/null
@@ -1,434 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Pluzhnikov
-//
-// Allow dynamic symbol lookup in an in-memory Elf image.
-//
-
-#include "base/elf_mem_image.h"
-
-#ifdef HAVE_ELF_MEM_IMAGE  // defined in elf_mem_image.h
-
-#include <stddef.h>   // for size_t, ptrdiff_t
-#include "base/logging.h"
-
-// From binutils/include/elf/common.h (this doesn't appear to be documented
-// anywhere else).
-//
-//   /* This flag appears in a Versym structure.  It means that the symbol
-//      is hidden, and is only visible with an explicit version number.
-//      This is a GNU extension.  */
-//   #define VERSYM_HIDDEN           0x8000
-//
-//   /* This is the mask for the rest of the Versym information.  */
-//   #define VERSYM_VERSION          0x7fff
-
-#define VERSYM_VERSION 0x7fff
-
-namespace base {
-
-namespace {
-template <int N> class ElfClass {
- public:
-  static const int kElfClass = -1;
-  static int ElfBind(const ElfW(Sym) *) {
-    CHECK(false); // << "Unexpected word size";
-    return 0;
-  }
-  static int ElfType(const ElfW(Sym) *) {
-    CHECK(false); // << "Unexpected word size";
-    return 0;
-  }
-};
-
-template <> class ElfClass<32> {
- public:
-  static const int kElfClass = ELFCLASS32;
-  static int ElfBind(const ElfW(Sym) *symbol) {
-    return ELF32_ST_BIND(symbol->st_info);
-  }
-  static int ElfType(const ElfW(Sym) *symbol) {
-    return ELF32_ST_TYPE(symbol->st_info);
-  }
-};
-
-template <> class ElfClass<64> {
- public:
-  static const int kElfClass = ELFCLASS64;
-  static int ElfBind(const ElfW(Sym) *symbol) {
-    return ELF64_ST_BIND(symbol->st_info);
-  }
-  static int ElfType(const ElfW(Sym) *symbol) {
-    return ELF64_ST_TYPE(symbol->st_info);
-  }
-};
-
-typedef ElfClass<__WORDSIZE> CurrentElfClass;
-
-// Extract an element from one of the ELF tables, cast it to desired type.
-// This is just a simple arithmetic and a glorified cast.
-// Callers are responsible for bounds checking.
-template <class T>
-const T* GetTableElement(const ElfW(Ehdr) *ehdr,
-                         ElfW(Off) table_offset,
-                         ElfW(Word) element_size,
-                         size_t index) {
-  return reinterpret_cast<const T*>(reinterpret_cast<const char *>(ehdr)
-                                    + table_offset
-                                    + index * element_size);
-}
-}  // namespace
-
-const void *const ElfMemImage::kInvalidBase =
-    reinterpret_cast<const void *>(~0L);
-
-ElfMemImage::ElfMemImage(const void *base) {
-  CHECK(base != kInvalidBase);
-  Init(base);
-}
-
-int ElfMemImage::GetNumSymbols() const {
-  if (!hash_) {
-    return 0;
-  }
-  // See http://www.caldera.com/developers/gabi/latest/ch5.dynamic.html#hash
-  return hash_[1];
-}
-
-const ElfW(Sym) *ElfMemImage::GetDynsym(int index) const {
-  CHECK_LT(index, GetNumSymbols());
-  return dynsym_ + index;
-}
-
-const ElfW(Versym) *ElfMemImage::GetVersym(int index) const {
-  CHECK_LT(index, GetNumSymbols());
-  return versym_ + index;
-}
-
-const ElfW(Phdr) *ElfMemImage::GetPhdr(int index) const {
-  CHECK_LT(index, ehdr_->e_phnum);
-  return GetTableElement<ElfW(Phdr)>(ehdr_,
-                                     ehdr_->e_phoff,
-                                     ehdr_->e_phentsize,
-                                     index);
-}
-
-const char *ElfMemImage::GetDynstr(ElfW(Word) offset) const {
-  CHECK_LT(offset, strsize_);
-  return dynstr_ + offset;
-}
-
-const void *ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const {
-  if (sym->st_shndx == SHN_UNDEF || sym->st_shndx >= SHN_LORESERVE) {
-    // Symbol corresponds to "special" (e.g. SHN_ABS) section.
-    return reinterpret_cast<const void *>(sym->st_value);
-  }
-  CHECK_LT(link_base_, sym->st_value);
-  return GetTableElement<char>(ehdr_, 0, 1, sym->st_value) - link_base_;
-}
-
-const ElfW(Verdef) *ElfMemImage::GetVerdef(int index) const {
-  CHECK_LE(index, verdefnum_);
-  const ElfW(Verdef) *version_definition = verdef_;
-  while (version_definition->vd_ndx < index && version_definition->vd_next) {
-    const char *const version_definition_as_char =
-        reinterpret_cast<const char *>(version_definition);
-    version_definition =
-        reinterpret_cast<const ElfW(Verdef) *>(version_definition_as_char +
-                                               version_definition->vd_next);
-  }
-  return version_definition->vd_ndx == index ? version_definition : NULL;
-}
-
-const ElfW(Verdaux) *ElfMemImage::GetVerdefAux(
-    const ElfW(Verdef) *verdef) const {
-  return reinterpret_cast<const ElfW(Verdaux) *>(verdef+1);
-}
-
-const char *ElfMemImage::GetVerstr(ElfW(Word) offset) const {
-  CHECK_LT(offset, strsize_);
-  return dynstr_ + offset;
-}
-
-void ElfMemImage::Init(const void *base) {
-  ehdr_      = NULL;
-  dynsym_    = NULL;
-  dynstr_    = NULL;
-  versym_    = NULL;
-  verdef_    = NULL;
-  hash_      = NULL;
-  strsize_   = 0;
-  verdefnum_ = 0;
-  link_base_ = ~0L;  // Sentinel: PT_LOAD .p_vaddr can't possibly be this.
-  if (!base) {
-    return;
-  }
-  const intptr_t base_as_uintptr_t = reinterpret_cast<uintptr_t>(base);
-  // Fake VDSO has low bit set.
-  const bool fake_vdso = ((base_as_uintptr_t & 1) != 0);
-  base = reinterpret_cast<const void *>(base_as_uintptr_t & ~1);
-  const char *const base_as_char = reinterpret_cast<const char *>(base);
-  if (base_as_char[EI_MAG0] != ELFMAG0 || base_as_char[EI_MAG1] != ELFMAG1 ||
-      base_as_char[EI_MAG2] != ELFMAG2 || base_as_char[EI_MAG3] != ELFMAG3) {
-    RAW_DCHECK(false, "no ELF magic"); // at %p", base);
-    return;
-  }
-  int elf_class = base_as_char[EI_CLASS];
-  if (elf_class != CurrentElfClass::kElfClass) {
-    DCHECK_EQ(elf_class, CurrentElfClass::kElfClass);
-    return;
-  }
-  switch (base_as_char[EI_DATA]) {
-    case ELFDATA2LSB: {
-      if (__LITTLE_ENDIAN != __BYTE_ORDER) {
-        DCHECK_EQ(__LITTLE_ENDIAN, __BYTE_ORDER); // << ": wrong byte order";
-        return;
-      }
-      break;
-    }
-    case ELFDATA2MSB: {
-      if (__BIG_ENDIAN != __BYTE_ORDER) {
-        DCHECK_EQ(__BIG_ENDIAN, __BYTE_ORDER); // << ": wrong byte order";
-        return;
-      }
-      break;
-    }
-    default: {
-      RAW_DCHECK(false, "unexpected data encoding"); // << base_as_char[EI_DATA];
-      return;
-    }
-  }
-
-  ehdr_ = reinterpret_cast<const ElfW(Ehdr) *>(base);
-  const ElfW(Phdr) *dynamic_program_header = NULL;
-  for (int i = 0; i < ehdr_->e_phnum; ++i) {
-    const ElfW(Phdr) *const program_header = GetPhdr(i);
-    switch (program_header->p_type) {
-      case PT_LOAD:
-        if (link_base_ == ~0L) {
-          link_base_ = program_header->p_vaddr;
-        }
-        break;
-      case PT_DYNAMIC:
-        dynamic_program_header = program_header;
-        break;
-    }
-  }
-  if (link_base_ == ~0L || !dynamic_program_header) {
-    RAW_DCHECK(~0L != link_base_, "no PT_LOADs in VDSO");
-    RAW_DCHECK(dynamic_program_header, "no PT_DYNAMIC in VDSO");
-    // Mark this image as not present. Can not recur infinitely.
-    Init(0);
-    return;
-  }
-  ptrdiff_t relocation =
-      base_as_char - reinterpret_cast<const char *>(link_base_);
-  ElfW(Dyn) *dynamic_entry =
-      reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr +
-                                    relocation);
-  for (; dynamic_entry->d_tag != DT_NULL; ++dynamic_entry) {
-    ElfW(Xword) value = dynamic_entry->d_un.d_val;
-    if (fake_vdso) {
-      // A complication: in the real VDSO, dynamic entries are not relocated
-      // (it wasn't loaded by a dynamic loader). But when testing with a
-      // "fake" dlopen()ed vdso library, the loader relocates some (but
-      // not all!) of them before we get here.
-      if (dynamic_entry->d_tag == DT_VERDEF) {
-        // The only dynamic entry (of the ones we care about) libc-2.3.6
-        // loader doesn't relocate.
-        value += relocation;
-      }
-    } else {
-      // Real VDSO. Everything needs to be relocated.
-      value += relocation;
-    }
-    switch (dynamic_entry->d_tag) {
-      case DT_HASH:
-        hash_ = reinterpret_cast<ElfW(Word) *>(value);
-        break;
-      case DT_SYMTAB:
-        dynsym_ = reinterpret_cast<ElfW(Sym) *>(value);
-        break;
-      case DT_STRTAB:
-        dynstr_ = reinterpret_cast<const char *>(value);
-        break;
-      case DT_VERSYM:
-        versym_ = reinterpret_cast<ElfW(Versym) *>(value);
-        break;
-      case DT_VERDEF:
-        verdef_ = reinterpret_cast<ElfW(Verdef) *>(value);
-        break;
-      case DT_VERDEFNUM:
-        verdefnum_ = dynamic_entry->d_un.d_val;
-        break;
-      case DT_STRSZ:
-        strsize_ = dynamic_entry->d_un.d_val;
-        break;
-      default:
-        // Unrecognized entries explicitly ignored.
-        break;
-    }
-  }
-  if (!hash_ || !dynsym_ || !dynstr_ || !versym_ ||
-      !verdef_ || !verdefnum_ || !strsize_) {
-    RAW_DCHECK(hash_, "invalid VDSO (no DT_HASH)");
-    RAW_DCHECK(dynsym_, "invalid VDSO (no DT_SYMTAB)");
-    RAW_DCHECK(dynstr_, "invalid VDSO (no DT_STRTAB)");
-    RAW_DCHECK(versym_, "invalid VDSO (no DT_VERSYM)");
-    RAW_DCHECK(verdef_, "invalid VDSO (no DT_VERDEF)");
-    RAW_DCHECK(verdefnum_, "invalid VDSO (no DT_VERDEFNUM)");
-    RAW_DCHECK(strsize_, "invalid VDSO (no DT_STRSZ)");
-    // Mark this image as not present. Can not recur infinitely.
-    Init(0);
-    return;
-  }
-}
-
-bool ElfMemImage::LookupSymbol(const char *name,
-                               const char *version,
-                               int type,
-                               SymbolInfo *info) const {
-  for (SymbolIterator it = begin(); it != end(); ++it) {
-    if (strcmp(it->name, name) == 0 && strcmp(it->version, version) == 0 &&
-        CurrentElfClass::ElfType(it->symbol) == type) {
-      if (info) {
-        *info = *it;
-      }
-      return true;
-    }
-  }
-  return false;
-}
-
-bool ElfMemImage::LookupSymbolByAddress(const void *address,
-                                        SymbolInfo *info_out) const {
-  for (SymbolIterator it = begin(); it != end(); ++it) {
-    const char *const symbol_start =
-        reinterpret_cast<const char *>(it->address);
-    const char *const symbol_end = symbol_start + it->symbol->st_size;
-    if (symbol_start <= address && address < symbol_end) {
-      if (info_out) {
-        // Client wants to know details for that symbol (the usual case).
-        if (CurrentElfClass::ElfBind(it->symbol) == STB_GLOBAL) {
-          // Strong symbol; just return it.
-          *info_out = *it;
-          return true;
-        } else {
-          // Weak or local. Record it, but keep looking for a strong one.
-          *info_out = *it;
-        }
-      } else {
-        // Client only cares if there is an overlapping symbol.
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-ElfMemImage::SymbolIterator::SymbolIterator(const void *const image, int index)
-    : index_(index), image_(image) {
-}
-
-const ElfMemImage::SymbolInfo *ElfMemImage::SymbolIterator::operator->() const {
-  return &info_;
-}
-
-const ElfMemImage::SymbolInfo& ElfMemImage::SymbolIterator::operator*() const {
-  return info_;
-}
-
-bool ElfMemImage::SymbolIterator::operator==(const SymbolIterator &rhs) const {
-  return this->image_ == rhs.image_ && this->index_ == rhs.index_;
-}
-
-bool ElfMemImage::SymbolIterator::operator!=(const SymbolIterator &rhs) const {
-  return !(*this == rhs);
-}
-
-ElfMemImage::SymbolIterator &ElfMemImage::SymbolIterator::operator++() {
-  this->Update(1);
-  return *this;
-}
-
-ElfMemImage::SymbolIterator ElfMemImage::begin() const {
-  SymbolIterator it(this, 0);
-  it.Update(0);
-  return it;
-}
-
-ElfMemImage::SymbolIterator ElfMemImage::end() const {
-  return SymbolIterator(this, GetNumSymbols());
-}
-
-void ElfMemImage::SymbolIterator::Update(int increment) {
-  const ElfMemImage *image = reinterpret_cast<const ElfMemImage *>(image_);
-  CHECK(image->IsPresent() || increment == 0);
-  if (!image->IsPresent()) {
-    return;
-  }
-  index_ += increment;
-  if (index_ >= image->GetNumSymbols()) {
-    index_ = image->GetNumSymbols();
-    return;
-  }
-  const ElfW(Sym)    *symbol = image->GetDynsym(index_);
-  const ElfW(Versym) *version_symbol = image->GetVersym(index_);
-  CHECK(symbol && version_symbol);
-  const char *const symbol_name = image->GetDynstr(symbol->st_name);
-  const ElfW(Versym) version_index = version_symbol[0] & VERSYM_VERSION;
-  const ElfW(Verdef) *version_definition = NULL;
-  const char *version_name = "";
-  if (symbol->st_shndx == SHN_UNDEF) {
-    // Undefined symbols reference DT_VERNEED, not DT_VERDEF, and
-    // version_index could well be greater than verdefnum_, so calling
-    // GetVerdef(version_index) may trigger assertion.
-  } else {
-    version_definition = image->GetVerdef(version_index);
-  }
-  if (version_definition) {
-    // I am expecting 1 or 2 auxiliary entries: 1 for the version itself,
-    // optional 2nd if the version has a parent.
-    CHECK_LE(1, version_definition->vd_cnt);
-    CHECK_LE(version_definition->vd_cnt, 2);
-    const ElfW(Verdaux) *version_aux = image->GetVerdefAux(version_definition);
-    version_name = image->GetVerstr(version_aux->vda_name);
-  }
-  info_.name    = symbol_name;
-  info_.version = version_name;
-  info_.address = image->GetSymAddr(symbol);
-  info_.symbol  = symbol;
-}
-
-}  // namespace base
-
-#endif  // HAVE_ELF_MEM_IMAGE
diff --git a/third_party/tcmalloc/chromium/src/base/elf_mem_image.h b/third_party/tcmalloc/chromium/src/base/elf_mem_image.h
deleted file mode 100644
index 5fb00ff..0000000
--- a/third_party/tcmalloc/chromium/src/base/elf_mem_image.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Pluzhnikov
-//
-// Allow dynamic symbol lookup for in-memory Elf images.
-
-#ifndef BASE_ELF_MEM_IMAGE_H_
-#define BASE_ELF_MEM_IMAGE_H_
-
-#include <config.h>
-#ifdef HAVE_FEATURES_H
-#include <features.h>   // for __GLIBC__
-#endif
-
-// Maybe one day we can rewrite this file not to require the elf
-// symbol extensions in glibc, but for right now we need them.
-#if defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__)
-
-#define HAVE_ELF_MEM_IMAGE 1
-
-#include <stdlib.h>
-#include <link.h>  // for ElfW
-
-namespace base {
-
-// An in-memory ELF image (may not exist on disk).
-class ElfMemImage {
- public:
-  // Sentinel: there could never be an elf image at this address.
-  static const void *const kInvalidBase;
-
-  // Information about a single vdso symbol.
-  // All pointers are into .dynsym, .dynstr, or .text of the VDSO.
-  // Do not free() them or modify through them.
-  struct SymbolInfo {
-    const char      *name;      // E.g. "__vdso_getcpu"
-    const char      *version;   // E.g. "LINUX_2.6", could be ""
-                                // for unversioned symbol.
-    const void      *address;   // Relocated symbol address.
-    const ElfW(Sym) *symbol;    // Symbol in the dynamic symbol table.
-  };
-
-  // Supports iteration over all dynamic symbols.
-  class SymbolIterator {
-   public:
-    friend class ElfMemImage;
-    const SymbolInfo *operator->() const;
-    const SymbolInfo &operator*() const;
-    SymbolIterator& operator++();
-    bool operator!=(const SymbolIterator &rhs) const;
-    bool operator==(const SymbolIterator &rhs) const;
-   private:
-    SymbolIterator(const void *const image, int index);
-    void Update(int incr);
-    SymbolInfo info_;
-    int index_;
-    const void *const image_;
-  };
-
-
-  explicit ElfMemImage(const void *base);
-  void                 Init(const void *base);
-  bool                 IsPresent() const { return ehdr_ != NULL; }
-  const ElfW(Phdr)*    GetPhdr(int index) const;
-  const ElfW(Sym)*     GetDynsym(int index) const;
-  const ElfW(Versym)*  GetVersym(int index) const;
-  const ElfW(Verdef)*  GetVerdef(int index) const;
-  const ElfW(Verdaux)* GetVerdefAux(const ElfW(Verdef) *verdef) const;
-  const char*          GetDynstr(ElfW(Word) offset) const;
-  const void*          GetSymAddr(const ElfW(Sym) *sym) const;
-  const char*          GetVerstr(ElfW(Word) offset) const;
-  int                  GetNumSymbols() const;
-
-  SymbolIterator begin() const;
-  SymbolIterator end() const;
-
-  // Look up versioned dynamic symbol in the image.
-  // Returns false if image is not present, or doesn't contain given
-  // symbol/version/type combination.
-  // If info_out != NULL, additional details are filled in.
-  bool LookupSymbol(const char *name, const char *version,
-                    int symbol_type, SymbolInfo *info_out) const;
-
-  // Find info about symbol (if any) which overlaps given address.
-  // Returns true if symbol was found; false if image isn't present
-  // or doesn't have a symbol overlapping given address.
-  // If info_out != NULL, additional details are filled in.
-  bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const;
-
- private:
-  const ElfW(Ehdr) *ehdr_;
-  const ElfW(Sym) *dynsym_;
-  const ElfW(Versym) *versym_;
-  const ElfW(Verdef) *verdef_;
-  const ElfW(Word) *hash_;
-  const char *dynstr_;
-  size_t strsize_;
-  size_t verdefnum_;
-  ElfW(Addr) link_base_;     // Link-time base (p_vaddr of first PT_LOAD).
-};
-
-}  // namespace base
-
-#endif  // __ELF__ and __GLIBC__ and !__native_client__
-
-#endif  // BASE_ELF_MEM_IMAGE_H_
diff --git a/third_party/tcmalloc/chromium/src/base/elfcore.h b/third_party/tcmalloc/chromium/src/base/elfcore.h
deleted file mode 100644
index 8193d422..0000000
--- a/third_party/tcmalloc/chromium/src/base/elfcore.h
+++ /dev/null
@@ -1,401 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005-2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke, Carl Crous
- */
-
-#ifndef _ELFCORE_H
-#define _ELFCORE_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* We currently only support x86-32, x86-64, ARM, MIPS, PPC on Linux.
- * Porting to other related platforms should not be difficult.
- */
-#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
-     defined(__mips__) || defined(__PPC__)) && defined(__linux)
-
-#include <stdarg.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <config.h>
-
-
-/* Define the DUMPER symbol to make sure that there is exactly one
- * core dumper built into the library.
- */
-#define DUMPER "ELF"
-
-/* By the time that we get a chance to read CPU registers in the
- * calling thread, they are already in a not particularly useful
- * state. Besides, there will be multiple frames on the stack that are
- * just making the core file confusing. To fix this problem, we take a
- * snapshot of the frame pointer, stack pointer, and instruction
- * pointer at an earlier time, and then insert these values into the
- * core file.
- */
-
-#if defined(__i386__) || defined(__x86_64__)
-  typedef struct i386_regs {    /* Normal (non-FPU) CPU registers            */
-  #ifdef __x86_64__
-    #define BP rbp
-    #define SP rsp
-    #define IP rip
-    uint64_t  r15,r14,r13,r12,rbp,rbx,r11,r10;
-    uint64_t  r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax;
-    uint64_t  rip,cs,eflags;
-    uint64_t  rsp,ss;
-    uint64_t  fs_base, gs_base;
-    uint64_t  ds,es,fs,gs;
-  #else
-    #define BP ebp
-    #define SP esp
-    #define IP eip
-    uint32_t  ebx, ecx, edx, esi, edi, ebp, eax;
-    uint16_t  ds, __ds, es, __es;
-    uint16_t  fs, __fs, gs, __gs;
-    uint32_t  orig_eax, eip;
-    uint16_t  cs, __cs;
-    uint32_t  eflags, esp;
-    uint16_t  ss, __ss;
-  #endif
-  } i386_regs;
-#elif defined(__arm__)
-  typedef struct arm_regs {     /* General purpose registers                 */
-    #define BP uregs[11]        /* Frame pointer                             */
-    #define SP uregs[13]        /* Stack pointer                             */
-    #define IP uregs[15]        /* Program counter                           */
-    #define LR uregs[14]        /* Link register                             */
-    long uregs[18];
-  } arm_regs;
-#elif defined(__mips__)
-  typedef struct mips_regs {
-    unsigned long pad[6];       /* Unused padding to match kernel structures */
-    unsigned long uregs[32];    /* General purpose registers.                */
-    unsigned long hi;           /* Used for multiplication and division.     */
-    unsigned long lo;
-    unsigned long cp0_epc;      /* Program counter.                          */
-    unsigned long cp0_badvaddr;
-    unsigned long cp0_status;
-    unsigned long cp0_cause;
-    unsigned long unused;
-  } mips_regs;
-#elif defined (__PPC__)
-  typedef struct ppc_regs {
-    #define SP uregs[1]         /* Stack pointer                             */
-    #define IP rip              /* Program counter                           */
-    #define LR lr               /* Link register                             */
-    unsigned long uregs[32];	/* General Purpose Registers - r0-r31.       */
-    double        fpr[32];	/* Floating-Point Registers - f0-f31.        */
-    unsigned long rip;		/* Program counter.                          */
-    unsigned long msr;
-    unsigned long ccr;
-    unsigned long lr;
-    unsigned long ctr;
-    unsigned long xeq;
-    unsigned long mq;
-  } ppc_regs;
-#endif
-
-#if defined(__i386__) && defined(__GNUC__)
-  /* On x86 we provide an optimized version of the FRAME() macro, if the
-   * compiler supports a GCC-style asm() directive. This results in somewhat
-   * more accurate values for CPU registers.
-   */
-  typedef struct Frame {
-    struct i386_regs uregs;
-    int              errno_;
-    pid_t            tid;
-  } Frame;
-  #define FRAME(f) Frame f;                                           \
-                   do {                                               \
-                     f.errno_ = errno;                                \
-                     f.tid    = sys_gettid();                         \
-                     __asm__ volatile (                               \
-                       "push %%ebp\n"                                 \
-                       "push %%ebx\n"                                 \
-                       "mov  %%ebx,0(%%eax)\n"                        \
-                       "mov  %%ecx,4(%%eax)\n"                        \
-                       "mov  %%edx,8(%%eax)\n"                        \
-                       "mov  %%esi,12(%%eax)\n"                       \
-                       "mov  %%edi,16(%%eax)\n"                       \
-                       "mov  %%ebp,20(%%eax)\n"                       \
-                       "mov  %%eax,24(%%eax)\n"                       \
-                       "mov  %%ds,%%ebx\n"                            \
-                       "mov  %%ebx,28(%%eax)\n"                       \
-                       "mov  %%es,%%ebx\n"                            \
-                       "mov  %%ebx,32(%%eax)\n"                       \
-                       "mov  %%fs,%%ebx\n"                            \
-                       "mov  %%ebx,36(%%eax)\n"                       \
-                       "mov  %%gs,%%ebx\n"                            \
-                       "mov  %%ebx, 40(%%eax)\n"                      \
-                       "call 0f\n"                                    \
-                     "0:pop %%ebx\n"                                  \
-                       "add  $1f-0b,%%ebx\n"                          \
-                       "mov  %%ebx,48(%%eax)\n"                       \
-                       "mov  %%cs,%%ebx\n"                            \
-                       "mov  %%ebx,52(%%eax)\n"                       \
-                       "pushf\n"                                      \
-                       "pop  %%ebx\n"                                 \
-                       "mov  %%ebx,56(%%eax)\n"                       \
-                       "mov  %%esp,%%ebx\n"                           \
-                       "add  $8,%%ebx\n"                              \
-                       "mov  %%ebx,60(%%eax)\n"                       \
-                       "mov  %%ss,%%ebx\n"                            \
-                       "mov  %%ebx,64(%%eax)\n"                       \
-                       "pop  %%ebx\n"                                 \
-                       "pop  %%ebp\n"                                 \
-                     "1:"                                             \
-                       : : "a" (&f) : "memory");                      \
-                     } while (0)
-  #define SET_FRAME(f,r)                                              \
-                     do {                                             \
-                       errno = (f).errno_;                            \
-                       (r)   = (f).uregs;                             \
-                     } while (0)
-#elif defined(__x86_64__) && defined(__GNUC__)
-  /* The FRAME and SET_FRAME macros for x86_64.  */
-  typedef struct Frame {
-    struct i386_regs uregs;
-    int              errno_;
-    pid_t            tid;
-  } Frame;
-  #define FRAME(f) Frame f;                                           \
-                   do {                                               \
-                     f.errno_ = errno;                                \
-                     f.tid    = sys_gettid();                         \
-                     __asm__ volatile (                               \
-                       "push %%rbp\n"                                 \
-                       "push %%rbx\n"                                 \
-                       "mov  %%r15,0(%%rax)\n"                        \
-                       "mov  %%r14,8(%%rax)\n"                        \
-                       "mov  %%r13,16(%%rax)\n"                       \
-                       "mov  %%r12,24(%%rax)\n"                       \
-                       "mov  %%rbp,32(%%rax)\n"                       \
-                       "mov  %%rbx,40(%%rax)\n"                       \
-                       "mov  %%r11,48(%%rax)\n"                       \
-                       "mov  %%r10,56(%%rax)\n"                       \
-                       "mov  %%r9,64(%%rax)\n"                        \
-                       "mov  %%r8,72(%%rax)\n"                        \
-                       "mov  %%rax,80(%%rax)\n"                       \
-                       "mov  %%rcx,88(%%rax)\n"                       \
-                       "mov  %%rdx,96(%%rax)\n"                       \
-                       "mov  %%rsi,104(%%rax)\n"                      \
-                       "mov  %%rdi,112(%%rax)\n"                      \
-                       "mov  %%ds,%%rbx\n"                            \
-                       "mov  %%rbx,184(%%rax)\n"                      \
-                       "mov  %%es,%%rbx\n"                            \
-                       "mov  %%rbx,192(%%rax)\n"                      \
-                       "mov  %%fs,%%rbx\n"                            \
-                       "mov  %%rbx,200(%%rax)\n"                      \
-                       "mov  %%gs,%%rbx\n"                            \
-                       "mov  %%rbx,208(%%rax)\n"                      \
-                       "call 0f\n"                                    \
-                     "0:pop %%rbx\n"                                  \
-                       "add  $1f-0b,%%rbx\n"                          \
-                       "mov  %%rbx,128(%%rax)\n"                      \
-                       "mov  %%cs,%%rbx\n"                            \
-                       "mov  %%rbx,136(%%rax)\n"                      \
-                       "pushf\n"                                      \
-                       "pop  %%rbx\n"                                 \
-                       "mov  %%rbx,144(%%rax)\n"                      \
-                       "mov  %%rsp,%%rbx\n"                           \
-                       "add  $16,%%ebx\n"                             \
-                       "mov  %%rbx,152(%%rax)\n"                      \
-                       "mov  %%ss,%%rbx\n"                            \
-                       "mov  %%rbx,160(%%rax)\n"                      \
-                       "pop  %%rbx\n"                                 \
-                       "pop  %%rbp\n"                                 \
-                     "1:"                                             \
-                       : : "a" (&f) : "memory");                      \
-                     } while (0)
-  #define SET_FRAME(f,r)                                              \
-                     do {                                             \
-                       errno = (f).errno_;                            \
-                       (f).uregs.fs_base = (r).fs_base;               \
-                       (f).uregs.gs_base = (r).gs_base;               \
-                       (r)   = (f).uregs;                             \
-                     } while (0)
-#elif defined(__arm__) && defined(__GNUC__)
-  /* ARM calling conventions are a little more tricky. A little assembly
-   * helps in obtaining an accurate snapshot of all registers.
-   */
-  typedef struct Frame {
-    struct arm_regs arm;
-    int             errno_;
-    pid_t           tid;
-  } Frame;
-  #define FRAME(f) Frame f;                                           \
-                   do {                                               \
-                     long cpsr;                                       \
-                     f.errno_ = errno;                                \
-                     f.tid    = sys_gettid();                         \
-                     __asm__ volatile(                                \
-                       "stmia %0, {r0-r15}\n" /* All integer regs   */\
-                       : : "r"(&f.arm) : "memory");                   \
-                     f.arm.uregs[16] = 0;                             \
-                     __asm__ volatile(                                \
-                       "mrs %0, cpsr\n"       /* Condition code reg */\
-                       : "=r"(cpsr));                                 \
-                     f.arm.uregs[17] = cpsr;                          \
-                   } while (0)
-  #define SET_FRAME(f,r)                                              \
-                     do {                                             \
-                       /* Don't override the FPU status register.   */\
-                       /* Use the value obtained from ptrace(). This*/\
-                       /* works, because our code does not perform  */\
-                       /* any FPU operations, itself.               */\
-                       long fps      = (f).arm.uregs[16];             \
-                       errno         = (f).errno_;                    \
-                       (r)           = (f).arm;                       \
-                       (r).uregs[16] = fps;                           \
-                     } while (0)
-#elif defined(__mips__) && defined(__GNUC__)
-  typedef struct Frame {
-    struct mips_regs mips_regs;
-    int              errno_;
-    pid_t            tid;
-  } Frame;
-  #define MIPSREG(n) ({ register unsigned long r __asm__("$"#n); r; })
-  #define FRAME(f) Frame f = { 0 };                                   \
-                   do {                                               \
-                     unsigned long hi, lo;                            \
-                     register unsigned long pc __asm__("$31");        \
-                     f.mips_regs.uregs[ 0] = MIPSREG( 0);             \
-                     f.mips_regs.uregs[ 1] = MIPSREG( 1);             \
-                     f.mips_regs.uregs[ 2] = MIPSREG( 2);             \
-                     f.mips_regs.uregs[ 3] = MIPSREG( 3);             \
-                     f.mips_regs.uregs[ 4] = MIPSREG( 4);             \
-                     f.mips_regs.uregs[ 5] = MIPSREG( 5);             \
-                     f.mips_regs.uregs[ 6] = MIPSREG( 6);             \
-                     f.mips_regs.uregs[ 7] = MIPSREG( 7);             \
-                     f.mips_regs.uregs[ 8] = MIPSREG( 8);             \
-                     f.mips_regs.uregs[ 9] = MIPSREG( 9);             \
-                     f.mips_regs.uregs[10] = MIPSREG(10);             \
-                     f.mips_regs.uregs[11] = MIPSREG(11);             \
-                     f.mips_regs.uregs[12] = MIPSREG(12);             \
-                     f.mips_regs.uregs[13] = MIPSREG(13);             \
-                     f.mips_regs.uregs[14] = MIPSREG(14);             \
-                     f.mips_regs.uregs[15] = MIPSREG(15);             \
-                     f.mips_regs.uregs[16] = MIPSREG(16);             \
-                     f.mips_regs.uregs[17] = MIPSREG(17);             \
-                     f.mips_regs.uregs[18] = MIPSREG(18);             \
-                     f.mips_regs.uregs[19] = MIPSREG(19);             \
-                     f.mips_regs.uregs[20] = MIPSREG(20);             \
-                     f.mips_regs.uregs[21] = MIPSREG(21);             \
-                     f.mips_regs.uregs[22] = MIPSREG(22);             \
-                     f.mips_regs.uregs[23] = MIPSREG(23);             \
-                     f.mips_regs.uregs[24] = MIPSREG(24);             \
-                     f.mips_regs.uregs[25] = MIPSREG(25);             \
-                     f.mips_regs.uregs[26] = MIPSREG(26);             \
-                     f.mips_regs.uregs[27] = MIPSREG(27);             \
-                     f.mips_regs.uregs[28] = MIPSREG(28);             \
-                     f.mips_regs.uregs[29] = MIPSREG(29);             \
-                     f.mips_regs.uregs[30] = MIPSREG(30);             \
-                     f.mips_regs.uregs[31] = MIPSREG(31);             \
-                     __asm__ volatile ("mfhi %0" : "=r"(hi));         \
-                     __asm__ volatile ("mflo %0" : "=r"(lo));         \
-                     __asm__ volatile ("jal 1f; 1:nop" : "=r"(pc));   \
-                     f.mips_regs.hi       = hi;                       \
-                     f.mips_regs.lo       = lo;                       \
-                     f.mips_regs.cp0_epc  = pc;                       \
-                     f.errno_             = errno;                    \
-                     f.tid                = sys_gettid();             \
-                   } while (0)
-  #define SET_FRAME(f,r)                                              \
-                   do {                                               \
-                     errno       = (f).errno_;                        \
-                     memcpy((r).uregs, (f).mips_regs.uregs,           \
-                            32*sizeof(unsigned long));                \
-                     (r).hi      = (f).mips_regs.hi;                  \
-                     (r).lo      = (f).mips_regs.lo;                  \
-                     (r).cp0_epc = (f).mips_regs.cp0_epc;             \
-                   } while (0)
-#else
-  /* If we do not have a hand-optimized assembly version of the FRAME()
-   * macro, we cannot reliably unroll the stack. So, we show a few additional
-   * stack frames for the coredumper.
-   */
-  typedef struct Frame {
-    pid_t tid;
-  } Frame;
-  #define FRAME(f) Frame f; do { f.tid = sys_gettid(); } while (0)
-  #define SET_FRAME(f,r) do { } while (0)
-#endif
-
-
-/* Internal function for generating a core file. This API can change without
- * notice and is only supposed to be used internally by the core dumper.
- *
- * This function works for both single- and multi-threaded core
- * dumps. If called as
- *
- *   FRAME(frame);
- *   InternalGetCoreDump(&frame, 0, NULL, ap);
- *
- * it creates a core file that only contains information about the
- * calling thread.
- *
- * Optionally, the caller can provide information about other threads
- * by passing their process ids in "thread_pids". The process id of
- * the caller should not be included in this array. All of the threads
- * must have been attached to with ptrace(), prior to calling this
- * function. They will be detached when "InternalGetCoreDump()" returns.
- *
- * This function either returns a file handle that can be read for obtaining
- * a core dump, or "-1" in case of an error. In the latter case, "errno"
- * will be set appropriately.
- *
- * While "InternalGetCoreDump()" is not technically async signal safe, you
- * might be tempted to invoke it from a signal handler. The code goes to
- * great lengths to make a best effort that this will actually work. But in
- * any case, you must make sure that you preserve the value of "errno"
- * yourself. It is guaranteed to be clobbered otherwise.
- *
- * Also, "InternalGetCoreDump" is not strictly speaking re-entrant. Again,
- * it makes a best effort to behave reasonably when called in a multi-
- * threaded environment, but it is ultimately the caller's responsibility
- * to provide locking.
- */
-int InternalGetCoreDump(void *frame, int num_threads, pid_t *thread_pids,
-                        va_list ap
-                     /* const struct CoreDumpParameters *params,
-                        const char *file_name,
-                        const char *PATH
-                      */);
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _ELFCORE_H */
diff --git a/third_party/tcmalloc/chromium/src/base/googleinit.h b/third_party/tcmalloc/chromium/src/base/googleinit.h
deleted file mode 100644
index 3ea411a3..0000000
--- a/third_party/tcmalloc/chromium/src/base/googleinit.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Jacob Hoffman-Andrews
-
-#ifndef _GOOGLEINIT_H
-#define _GOOGLEINIT_H
-
-#include "base/logging.h"
-
-class GoogleInitializer {
- public:
-  typedef void (*VoidFunction)(void);
-  GoogleInitializer(const char* name, VoidFunction ctor, VoidFunction dtor)
-      : name_(name), destructor_(dtor) {
-    RAW_VLOG(10, "<GoogleModuleObject> constructing: %s\n", name_);
-    if (ctor)
-      ctor();
-  }
-  ~GoogleInitializer() {
-    RAW_VLOG(10, "<GoogleModuleObject> destroying: %s\n", name_);
-    if (destructor_)
-      destructor_();
-  }
-
- private:
-  const char* const name_;
-  const VoidFunction destructor_;
-};
-
-#define REGISTER_MODULE_INITIALIZER(name, body)                 \
-  namespace {                                                   \
-    static void google_init_module_##name () { body; }          \
-    GoogleInitializer google_initializer_module_##name(#name,   \
-            google_init_module_##name, NULL);                   \
-  }
-
-#define REGISTER_MODULE_DESTRUCTOR(name, body)                  \
-  namespace {                                                   \
-    static void google_destruct_module_##name () { body; }      \
-    GoogleInitializer google_destructor_module_##name(#name,    \
-            NULL, google_destruct_module_##name);               \
-  }
-
-
-#endif /* _GOOGLEINIT_H */
diff --git a/third_party/tcmalloc/chromium/src/base/linux_syscall_support.h b/third_party/tcmalloc/chromium/src/base/linux_syscall_support.h
deleted file mode 100644
index 1743bc9..0000000
--- a/third_party/tcmalloc/chromium/src/base/linux_syscall_support.h
+++ /dev/null
@@ -1,2909 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005-2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-/* This file includes Linux-specific support functions common to the
- * coredumper and the thread lister; primarily, this is a collection
- * of direct system calls, and a couple of symbols missing from
- * standard header files.
- * There are a few options that the including file can set to control
- * the behavior of this file:
- *
- * SYS_CPLUSPLUS:
- *   The entire header file will normally be wrapped in 'extern "C" { }",
- *   making it suitable for compilation as both C and C++ source. If you
- *   do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit
- *   the wrapping. N.B. doing so will suppress inclusion of all prerequisite
- *   system header files, too. It is the caller's responsibility to provide
- *   the necessary definitions.
- *
- * SYS_ERRNO:
- *   All system calls will update "errno" unless overriden by setting the
- *   SYS_ERRNO macro prior to including this file. SYS_ERRNO should be
- *   an l-value.
- *
- * SYS_INLINE:
- *   New symbols will be defined "static inline", unless overridden by
- *   the SYS_INLINE macro.
- *
- * SYS_LINUX_SYSCALL_SUPPORT_H
- *   This macro is used to avoid multiple inclusions of this header file.
- *   If you need to include this file more than once, make sure to
- *   unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.
- *
- * SYS_PREFIX:
- *   New system calls will have a prefix of "sys_" unless overridden by
- *   the SYS_PREFIX macro. Valid values for this macro are [0..9] which
- *   results in prefixes "sys[0..9]_". It is also possible to set this
- *   macro to -1, which avoids all prefixes.
- *
- * This file defines a few internal symbols that all start with "LSS_".
- * Do not access these symbols from outside this file. They are not part
- * of the supported API.
- *
- * NOTE: This is a stripped down version of the official opensource
- * version of linux_syscall_support.h, which lives at
- *    http://code.google.com/p/linux-syscall-support/
- * It includes only the syscalls that are used in perftools, plus a
- * few extra.  Here's the breakdown:
- * 1) Perftools uses these: grep -rho 'sys_[a-z0-9_A-Z]* *(' src | sort -u
- *      sys__exit(
- *      sys_clone(
- *      sys_close(
- *      sys_fcntl(
- *      sys_fstat(
- *      sys_futex(
- *      sys_getcpu(
- *      sys_getdents64(
- *      sys_getppid(
- *      sys_gettid(
- *      sys_lseek(
- *      sys_mmap(
- *      sys_mremap(
- *      sys_munmap(
- *      sys_open(
- *      sys_pipe(
- *      sys_prctl(
- *      sys_ptrace(
- *      sys_ptrace_detach(
- *      sys_read(
- *      sys_sched_yield(
- *      sys_sigaction(
- *      sys_sigaltstack(
- *      sys_sigdelset(
- *      sys_sigfillset(
- *      sys_sigprocmask(
- *      sys_socket(
- *      sys_stat(
- *      sys_waitpid(
- * 2) These are used as subroutines of the above:
- *      sys_getpid       -- gettid
- *      sys_kill         -- ptrace_detach
- *      sys_restore      -- sigaction
- *      sys_restore_rt   -- sigaction
- *      sys_socketcall   -- socket
- *      sys_wait4        -- waitpid
- * 3) I left these in even though they're not used.  They either
- * complement the above (write vs read) or are variants (rt_sigaction):
- *      sys_fstat64
- *      sys_llseek
- *      sys_mmap2
- *      sys_openat
- *      sys_getdents
- *      sys_rt_sigaction
- *      sys_rt_sigprocmask
- *      sys_sigaddset
- *      sys_sigemptyset
- *      sys_stat64
- *      sys_write
- */
-#ifndef SYS_LINUX_SYSCALL_SUPPORT_H
-#define SYS_LINUX_SYSCALL_SUPPORT_H
-
-/* We currently only support x86-32, x86-64, ARM, MIPS, PPC/PPC64, Aarch64, s390 and s390x
- * on Linux.
- * Porting to other related platforms should not be difficult.
- */
-#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
-     defined(__mips__) || defined(__PPC__) || \
-     defined(__aarch64__) || defined(__s390__)) \
-  && (defined(__linux))
-
-#ifndef SYS_CPLUSPLUS
-#ifdef __cplusplus
-/* Some system header files in older versions of gcc neglect to properly
- * handle being included from C++. As it appears to be harmless to have
- * multiple nested 'extern "C"' blocks, just add another one here.
- */
-extern "C" {
-#endif
-
-#include <errno.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <syscall.h>
-#include <unistd.h>
-#include <linux/unistd.h>
-#include <endian.h>
-#include <fcntl.h>
-
-#ifdef __mips__
-/* Include definitions of the ABI currently in use.                          */
-#include <sgidefs.h>
-#endif
-
-#endif
-
-/* As glibc often provides subtly incompatible data structures (and implicit
- * wrapper functions that convert them), we provide our own kernel data
- * structures for use by the system calls.
- * These structures have been developed by using Linux 2.6.23 headers for
- * reference. Note though, we do not care about exact API compatibility
- * with the kernel, and in fact the kernel often does not have a single
- * API that works across architectures. Instead, we try to mimic the glibc
- * API where reasonable, and only guarantee ABI compatibility with the
- * kernel headers.
- * Most notably, here are a few changes that were made to the structures
- * defined by kernel headers:
- *
- * - we only define structures, but not symbolic names for kernel data
- *   types. For the latter, we directly use the native C datatype
- *   (i.e. "unsigned" instead of "mode_t").
- * - in a few cases, it is possible to define identical structures for
- *   both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
- *   standardizing on the 64bit version of the data types. In particular,
- *   this means that we use "unsigned" where the 32bit headers say
- *   "unsigned long".
- * - overall, we try to minimize the number of cases where we need to
- *   conditionally define different structures.
- * - the "struct kernel_sigaction" class of structures have been
- *   modified to more closely mimic glibc's API by introducing an
- *   anonymous union for the function pointer.
- * - a small number of field names had to have an underscore appended to
- *   them, because glibc defines a global macro by the same name.
- */
-
-/* include/linux/dirent.h                                                    */
-struct kernel_dirent64 {
-  unsigned long long d_ino;
-  long long          d_off;
-  unsigned short     d_reclen;
-  unsigned char      d_type;
-  char               d_name[256];
-};
-
-/* include/linux/dirent.h                                                    */
-struct kernel_dirent {
-  long               d_ino;
-  long               d_off;
-  unsigned short     d_reclen;
-  char               d_name[256];
-};
-
-/* include/linux/time.h                                                      */
-struct kernel_timespec {
-  long               tv_sec;
-  long               tv_nsec;
-};
-
-/* include/linux/time.h                                                      */
-struct kernel_timeval {
-  long               tv_sec;
-  long               tv_usec;
-};
-
-/* include/linux/resource.h                                                  */
-struct kernel_rusage {
-  struct kernel_timeval ru_utime;
-  struct kernel_timeval ru_stime;
-  long               ru_maxrss;
-  long               ru_ixrss;
-  long               ru_idrss;
-  long               ru_isrss;
-  long               ru_minflt;
-  long               ru_majflt;
-  long               ru_nswap;
-  long               ru_inblock;
-  long               ru_oublock;
-  long               ru_msgsnd;
-  long               ru_msgrcv;
-  long               ru_nsignals;
-  long               ru_nvcsw;
-  long               ru_nivcsw;
-};
-
-#if defined(__i386__) || defined(__arm__) \
-  || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__))
-
-/* include/asm-{arm,i386,mips,ppc}/signal.h                                  */
-struct kernel_old_sigaction {
-  union {
-    void             (*sa_handler_)(int);
-    void             (*sa_sigaction_)(int, siginfo_t *, void *);
-  };
-  unsigned long      sa_mask;
-  unsigned long      sa_flags;
-  void               (*sa_restorer)(void);
-} __attribute__((packed,aligned(4)));
-#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
-  #define kernel_old_sigaction kernel_sigaction
-#elif defined(__aarch64__)
-  // No kernel_old_sigaction defined for arm64.
-#endif
-
-/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
- * exactly match the size of the signal set, even though the API was
- * intended to be extensible. We define our own KERNEL_NSIG to deal with
- * this.
- * Please note that glibc provides signals [1.._NSIG-1], whereas the
- * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
- * actual number of signals is obviously the same, but the constants
- * differ by one.
- */
-#ifdef __mips__
-#define KERNEL_NSIG 128
-#else
-#define KERNEL_NSIG  64
-#endif
-
-/* include/asm-{arm,i386,mips,x86_64}/signal.h                               */
-struct kernel_sigset_t {
-  unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
-                    (8*sizeof(unsigned long))];
-};
-
-/* include/asm-{arm,generic,i386,mips,x86_64,ppc}/signal.h                   */
-struct kernel_sigaction {
-#ifdef __mips__
-  unsigned long      sa_flags;
-  union {
-    void             (*sa_handler_)(int);
-    void             (*sa_sigaction_)(int, siginfo_t *, void *);
-  };
-  struct kernel_sigset_t sa_mask;
-#else
-  union {
-    void             (*sa_handler_)(int);
-    void             (*sa_sigaction_)(int, siginfo_t *, void *);
-  };
-  unsigned long      sa_flags;
-  void               (*sa_restorer)(void);
-  struct kernel_sigset_t sa_mask;
-#endif
-};
-
-/* include/asm-{arm,i386,mips,ppc,s390}/stat.h                               */
-#ifdef __mips__
-#if (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
-struct kernel_stat {
-#else
-struct kernel_stat64 {
-#endif
-  unsigned           st_dev;
-  unsigned           __pad0[3];
-  unsigned long long st_ino;
-  unsigned           st_mode;
-  unsigned           st_nlink;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  unsigned           st_rdev;
-  unsigned           __pad1[3];
-  long long          st_size;
-  unsigned           st_atime_;
-  unsigned           st_atime_nsec_;
-  unsigned           st_mtime_;
-  unsigned           st_mtime_nsec_;
-  unsigned           st_ctime_;
-  unsigned           st_ctime_nsec_;
-  unsigned           st_blksize;
-  unsigned           __pad2;
-  unsigned long long st_blocks;
-};
-#elif defined __PPC__
-struct kernel_stat64 {
-  unsigned long long st_dev;
-  unsigned long long st_ino;
-  unsigned           st_nlink;
-  unsigned           st_mode;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  int                __pad2;
-  unsigned long long st_rdev;
-  long long          st_size;
-  long long          st_blksize;
-  long long          st_blocks;
-  kernel_timespec    st_atim;
-  kernel_timespec    st_mtim;
-  kernel_timespec    st_ctim;
-  unsigned long      __unused4;
-  unsigned long      __unused5;
-  unsigned long      __unused6;
-};
-#else
-struct kernel_stat64 {
-  unsigned long long st_dev;
-  unsigned char      __pad0[4];
-  unsigned           __st_ino;
-  unsigned           st_mode;
-  unsigned           st_nlink;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  unsigned long long st_rdev;
-  unsigned char      __pad3[4];
-  long long          st_size;
-  unsigned           st_blksize;
-  unsigned long long st_blocks;
-  unsigned           st_atime_;
-  unsigned           st_atime_nsec_;
-  unsigned           st_mtime_;
-  unsigned           st_mtime_nsec_;
-  unsigned           st_ctime_;
-  unsigned           st_ctime_nsec_;
-  unsigned long long st_ino;
-};
-#endif
-
-/* include/asm-{arm,generic,i386,mips,x86_64,ppc,s390}/stat.h                     */
-#if defined(__i386__) || defined(__arm__)
-struct kernel_stat {
-  /* The kernel headers suggest that st_dev and st_rdev should be 32bit
-   * quantities encoding 12bit major and 20bit minor numbers in an interleaved
-   * format. In reality, we do not see useful data in the top bits. So,
-   * we'll leave the padding in here, until we find a better solution.
-   */
-  unsigned short     st_dev;
-  short              pad1;
-  unsigned           st_ino;
-  unsigned short     st_mode;
-  unsigned short     st_nlink;
-  unsigned short     st_uid;
-  unsigned short     st_gid;
-  unsigned short     st_rdev;
-  short              pad2;
-  unsigned           st_size;
-  unsigned           st_blksize;
-  unsigned           st_blocks;
-  unsigned           st_atime_;
-  unsigned           st_atime_nsec_;
-  unsigned           st_mtime_;
-  unsigned           st_mtime_nsec_;
-  unsigned           st_ctime_;
-  unsigned           st_ctime_nsec_;
-  unsigned           __unused4;
-  unsigned           __unused5;
-};
-#elif defined(__x86_64__)
-struct kernel_stat {
-  uint64_t           st_dev;
-  uint64_t           st_ino;
-  uint64_t           st_nlink;
-  unsigned           st_mode;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  unsigned           __pad0;
-  uint64_t           st_rdev;
-  int64_t            st_size;
-  int64_t            st_blksize;
-  int64_t            st_blocks;
-  uint64_t           st_atime_;
-  uint64_t           st_atime_nsec_;
-  uint64_t           st_mtime_;
-  uint64_t           st_mtime_nsec_;
-  uint64_t           st_ctime_;
-  uint64_t           st_ctime_nsec_;
-  int64_t            __unused[3];
-};
-#elif defined(__PPC__)
-struct kernel_stat {
-  unsigned long long st_dev;
-  unsigned long      st_ino;
-  unsigned long      st_nlink;
-  unsigned long      st_mode;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  int                __pad2;
-  unsigned long long st_rdev;
-  long               st_size;
-  unsigned long      st_blksize;
-  unsigned long      st_blocks;
-  kernel_timespec    st_atim;
-  kernel_timespec    st_mtim;
-  kernel_timespec    st_ctim;
-  unsigned long      __unused4;
-  unsigned long      __unused5;
-  unsigned long      __unused6;
-};
-#elif defined(__mips__) \
-       && !(_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
-struct kernel_stat {
-  unsigned           st_dev;
-  int                st_pad1[3];
-  unsigned           st_ino;
-  unsigned           st_mode;
-  unsigned           st_nlink;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  unsigned           st_rdev;
-  int                st_pad2[2];
-  long               st_size;
-  int                st_pad3;
-  long               st_atime_;
-  long               st_atime_nsec_;
-  long               st_mtime_;
-  long               st_mtime_nsec_;
-  long               st_ctime_;
-  long               st_ctime_nsec_;
-  int                st_blksize;
-  int                st_blocks;
-  int                st_pad4[14];
-};
-#elif defined(__aarch64__)
-struct kernel_stat {
-  unsigned long      st_dev;
-  unsigned long      st_ino;
-  unsigned int       st_mode;
-  unsigned int       st_nlink;
-  unsigned int       st_uid;
-  unsigned int       st_gid;
-  unsigned long      st_rdev;
-  unsigned long      __pad1;
-  long               st_size;
-  int                st_blksize;
-  int                __pad2;
-  long               st_blocks;
-  long               st_atime_;
-  unsigned long      st_atime_nsec_;
-  long               st_mtime_;
-  unsigned long      st_mtime_nsec_;
-  long               st_ctime_;
-  unsigned long      st_ctime_nsec_;
-  unsigned int       __unused4;
-  unsigned int       __unused5;
-};
-#elif defined(__s390x__)
-struct kernel_stat {
-  unsigned long      st_dev;
-  unsigned long      st_ino;
-  unsigned long      st_nlink;
-  unsigned int       st_mode;
-  unsigned int       st_uid;
-  unsigned int       st_gid;
-  unsigned int       __pad1;
-  unsigned long      st_rdev;
-  unsigned long      st_size;
-  unsigned long      st_atime_;
-  unsigned long      st_atime_nsec_;
-  unsigned long      st_mtime_;
-  unsigned long      st_mtime_nsec_;
-  unsigned long      st_ctime_;
-  unsigned long      st_ctime_nsec_;
-  unsigned long      st_blksize;
-  long               st_blocks;
-  unsigned long      __unused[3];
-};
-#elif defined(__s390__)
-struct kernel_stat {
-  unsigned short     st_dev;
-  unsigned short     __pad1;
-  unsigned long      st_ino;
-  unsigned short     st_mode;
-  unsigned short     st_nlink;
-  unsigned short     st_uid;
-  unsigned short     st_gid;
-  unsigned short     st_rdev;
-  unsigned short     __pad2;
-  unsigned long      st_size;
-  unsigned long      st_blksize;
-  unsigned long      st_blocks;
-  unsigned long      st_atime_;
-  unsigned long      st_atime_nsec_;
-  unsigned long      st_mtime_;
-  unsigned long      st_mtime_nsec_;
-  unsigned long      st_ctime_;
-  unsigned long      st_ctime_nsec_;
-  unsigned long      __unused4;
-  unsigned long      __unused5;
-};
-#endif
-
-
-/* Definitions missing from the standard header files                        */
-#ifndef O_DIRECTORY
-#if defined(__arm__)
-#define O_DIRECTORY             0040000
-#else
-#define O_DIRECTORY             0200000
-#endif
-#endif
-#ifndef PR_GET_DUMPABLE
-#define PR_GET_DUMPABLE         3
-#endif
-#ifndef PR_SET_DUMPABLE
-#define PR_SET_DUMPABLE         4
-#endif
-#ifndef AT_FDCWD
-#define AT_FDCWD                (-100)
-#endif
-#ifndef AT_SYMLINK_NOFOLLOW
-#define AT_SYMLINK_NOFOLLOW     0x100
-#endif
-#ifndef AT_REMOVEDIR
-#define AT_REMOVEDIR            0x200
-#endif
-#ifndef MREMAP_FIXED
-#define MREMAP_FIXED            2
-#endif
-#ifndef SA_RESTORER
-#define SA_RESTORER             0x04000000
-#endif
-
-#if defined(__i386__)
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       174
-#define __NR_rt_sigprocmask     175
-#endif
-#ifndef __NR_stat64
-#define __NR_stat64             195
-#endif
-#ifndef __NR_fstat64
-#define __NR_fstat64            197
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         220
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             224
-#endif
-#ifndef __NR_futex
-#define __NR_futex              240
-#endif
-#ifndef __NR_openat
-#define __NR_openat             295
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             318
-#endif
-/* End of i386 definitions                                                   */
-#elif defined(__arm__)
-#ifndef __syscall
-#if defined(__thumb__) || defined(__ARM_EABI__)
-#define __SYS_REG(name) register long __sysreg __asm__("r6") = __NR_##name;
-#define __SYS_REG_LIST(regs...) [sysreg] "r" (__sysreg) , ##regs
-#define __syscall(name) "swi\t0"
-#define __syscall_safe(name)                     \
-  "push  {r7}\n"                                 \
-  "mov   r7,%[sysreg]\n"                         \
-  __syscall(name)"\n"                            \
-  "pop   {r7}"
-#else
-#define __SYS_REG(name)
-#define __SYS_REG_LIST(regs...) regs
-#define __syscall(name) "swi\t" __sys1(__NR_##name) ""
-#define __syscall_safe(name) __syscall(name)
-#endif
-#endif
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       (__NR_SYSCALL_BASE + 174)
-#define __NR_rt_sigprocmask     (__NR_SYSCALL_BASE + 175)
-#endif
-#ifndef __NR_stat64
-#define __NR_stat64             (__NR_SYSCALL_BASE + 195)
-#endif
-#ifndef __NR_fstat64
-#define __NR_fstat64            (__NR_SYSCALL_BASE + 197)
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         (__NR_SYSCALL_BASE + 217)
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             (__NR_SYSCALL_BASE + 224)
-#endif
-#ifndef __NR_futex
-#define __NR_futex              (__NR_SYSCALL_BASE + 240)
-#endif
-/* End of ARM definitions                                                  */
-#elif defined(__x86_64__)
-#ifndef __NR_gettid
-#define __NR_gettid             186
-#endif
-#ifndef __NR_futex
-#define __NR_futex              202
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         217
-#endif
-#ifndef __NR_openat
-#define __NR_openat             257
-#endif
-/* End of x86-64 definitions                                                 */
-#elif defined(__mips__)
-#if _MIPS_SIM == _MIPS_SIM_ABI32
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       (__NR_Linux + 194)
-#define __NR_rt_sigprocmask     (__NR_Linux + 195)
-#endif
-#ifndef __NR_stat64
-#define __NR_stat64             (__NR_Linux + 213)
-#endif
-#ifndef __NR_fstat64
-#define __NR_fstat64            (__NR_Linux + 215)
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         (__NR_Linux + 219)
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             (__NR_Linux + 222)
-#endif
-#ifndef __NR_futex
-#define __NR_futex              (__NR_Linux + 238)
-#endif
-#ifndef __NR_openat
-#define __NR_openat             (__NR_Linux + 288)
-#endif
-#ifndef __NR_fstatat
-#define __NR_fstatat            (__NR_Linux + 293)
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             (__NR_Linux + 312)
-#endif
-/* End of MIPS (old 32bit API) definitions */
-#elif (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
-#ifndef __NR_gettid
-#define __NR_gettid             (__NR_Linux + 178)
-#endif
-#ifndef __NR_futex
-#define __NR_futex              (__NR_Linux + 194)
-#endif
-#ifndef __NR_openat
-#define __NR_openat             (__NR_Linux + 247)
-#endif
-#ifndef __NR_fstatat
-#define __NR_fstatat            (__NR_Linux + 252)
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             (__NR_Linux + 271)
-#endif
-/* End of MIPS (64bit API) definitions */
-#else
-#ifndef __NR_gettid
-#define __NR_gettid             (__NR_Linux + 178)
-#endif
-#ifndef __NR_futex
-#define __NR_futex              (__NR_Linux + 194)
-#endif
-#ifndef __NR_openat
-#define __NR_openat             (__NR_Linux + 251)
-#endif
-#ifndef __NR_fstatat
-#define __NR_fstatat            (__NR_Linux + 256)
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             (__NR_Linux + 275)
-#endif
-/* End of MIPS (new 32bit API) definitions                                   */
-#endif
-/* End of MIPS definitions                                                   */
-#elif defined(__PPC__)
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       173
-#define __NR_rt_sigprocmask     174
-#endif
-#ifndef __NR_stat64
-#define __NR_stat64             195
-#endif
-#ifndef __NR_fstat64
-#define __NR_fstat64            197
-#endif
-#ifndef __NR_socket
-#define __NR_socket             198
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         202
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             207
-#endif
-#ifndef __NR_futex
-#define __NR_futex              221
-#endif
-#ifndef __NR_openat
-#define __NR_openat             286
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             302
-#endif
-/* End of powerpc defininitions                                              */
-#elif defined(__aarch64__)
-#ifndef __NR_fstatat
-#define __NR_fstatat             79
-#endif
-/* End of aarch64 defininitions                                              */
-#elif defined(__s390__)
-#ifndef __NR_quotactl
-#define __NR_quotactl           131
-#endif
-#ifndef __NR_rt_sigreturn
-#define __NR_rt_sigreturn       173
-#endif
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       174
-#endif
-#ifndef __NR_rt_sigprocmask
-#define __NR_rt_sigprocmask     175
-#endif
-#ifndef __NR_rt_sigpending
-#define __NR_rt_sigpending      176
-#endif
-#ifndef __NR_rt_sigsuspend
-#define __NR_rt_sigsuspend      179
-#endif
-#ifndef __NR_pread64
-#define __NR_pread64            180
-#endif
-#ifndef __NR_pwrite64
-#define __NR_pwrite64           181
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         220
-#endif
-#ifndef __NR_readahead
-#define __NR_readahead          222
-#endif
-#ifndef __NR_setxattr
-#define __NR_setxattr           224
-#endif
-#ifndef __NR_lsetxattr
-#define __NR_lsetxattr          225
-#endif
-#ifndef __NR_getxattr
-#define __NR_getxattr           227
-#endif
-#ifndef __NR_lgetxattr
-#define __NR_lgetxattr          228
-#endif
-#ifndef __NR_listxattr
-#define __NR_listxattr          230
-#endif
-#ifndef __NR_llistxattr
-#define __NR_llistxattr         231
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             236
-#endif
-#ifndef __NR_tkill
-#define __NR_tkill              237
-#endif
-#ifndef __NR_futex
-#define __NR_futex              238
-#endif
-#ifndef __NR_sched_setaffinity
-#define __NR_sched_setaffinity  239
-#endif
-#ifndef __NR_sched_getaffinity
-#define __NR_sched_getaffinity  240
-#endif
-#ifndef __NR_set_tid_address
-#define __NR_set_tid_address    252
-#endif
-#ifndef __NR_clock_gettime
-#define __NR_clock_gettime      260
-#endif
-#ifndef __NR_clock_getres
-#define __NR_clock_getres       261
-#endif
-#ifndef __NR_statfs64
-#define __NR_statfs64           265
-#endif
-#ifndef __NR_fstatfs64
-#define __NR_fstatfs64          266
-#endif
-#ifndef __NR_ioprio_set
-#define __NR_ioprio_set         282
-#endif
-#ifndef __NR_ioprio_get
-#define __NR_ioprio_get         283
-#endif
-#ifndef __NR_openat
-#define __NR_openat             288
-#endif
-#ifndef __NR_unlinkat
-#define __NR_unlinkat           294
-#endif
-#ifndef __NR_move_pages
-#define __NR_move_pages         310
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             311
-#endif
-#ifndef __NR_fallocate
-#define __NR_fallocate          314
-#endif
-/* Some syscalls are named/numbered differently between s390 and s390x. */
-#ifdef __s390x__
-# ifndef __NR_getrlimit
-# define __NR_getrlimit          191
-# endif
-# ifndef __NR_setresuid
-# define __NR_setresuid          208
-# endif
-# ifndef __NR_getresuid
-# define __NR_getresuid          209
-# endif
-# ifndef __NR_setresgid
-# define __NR_setresgid          210
-# endif
-# ifndef __NR_getresgid
-# define __NR_getresgid          211
-# endif
-# ifndef __NR_setfsuid
-# define __NR_setfsuid           215
-# endif
-# ifndef __NR_setfsgid
-# define __NR_setfsgid           216
-# endif
-# ifndef __NR_fadvise64
-# define __NR_fadvise64          253
-# endif
-# ifndef __NR_newfstatat
-# define __NR_newfstatat         293
-# endif
-#else /* __s390x__ */
-# ifndef __NR_getrlimit
-# define __NR_getrlimit          76
-# endif
-# ifndef __NR_setfsuid
-# define __NR_setfsuid           138
-# endif
-# ifndef __NR_setfsgid
-# define __NR_setfsgid           139
-# endif
-# ifndef __NR_setresuid
-# define __NR_setresuid          164
-# endif
-# ifndef __NR_getresuid
-# define __NR_getresuid          165
-# endif
-# ifndef __NR_setresgid
-# define __NR_setresgid          170
-# endif
-# ifndef __NR_getresgid
-# define __NR_getresgid          171
-# endif
-# ifndef __NR_ugetrlimit
-# define __NR_ugetrlimit         191
-# endif
-# ifndef __NR_mmap2
-# define __NR_mmap2              192
-# endif
-# ifndef __NR_setresuid32
-# define __NR_setresuid32        208
-# endif
-# ifndef __NR_getresuid32
-# define __NR_getresuid32        209
-# endif
-# ifndef __NR_setresgid32
-# define __NR_setresgid32        210
-# endif
-# ifndef __NR_getresgid32
-# define __NR_getresgid32        211
-# endif
-# ifndef __NR_setfsuid32
-# define __NR_setfsuid32         215
-# endif
-# ifndef __NR_setfsgid32
-# define __NR_setfsgid32         216
-# endif
-# ifndef __NR_fadvise64_64
-# define __NR_fadvise64_64       264
-# endif
-# ifndef __NR_fstatat64
-# define __NR_fstatat64          293
-# endif
-#endif /* __s390__ */
-/* End of s390/s390x definitions                                             */
-#endif
-
-
-/* After forking, we must make sure to only call system calls.               */
-#if __BOUNDED_POINTERS__
-  #error "Need to port invocations of syscalls for bounded ptrs"
-#else
-  /* The core dumper and the thread lister get executed after threads
-   * have been suspended. As a consequence, we cannot call any functions
-   * that acquire locks. Unfortunately, libc wraps most system calls
-   * (e.g. in order to implement pthread_atfork, and to make calls
-   * cancellable), which means we cannot call these functions. Instead,
-   * we have to call syscall() directly.
-   */
-  #undef LSS_ERRNO
-  #ifdef SYS_ERRNO
-    /* Allow the including file to override the location of errno. This can
-     * be useful when using clone() with the CLONE_VM option.
-     */
-    #define LSS_ERRNO SYS_ERRNO
-  #else
-    #define LSS_ERRNO errno
-  #endif
-
-  #undef LSS_INLINE
-  #ifdef SYS_INLINE
-    #define LSS_INLINE SYS_INLINE
-  #else
-    #define LSS_INLINE static inline
-  #endif
-
-  /* Allow the including file to override the prefix used for all new
-   * system calls. By default, it will be set to "sys_".
-   */
-  #undef LSS_NAME
-  #ifndef SYS_PREFIX
-    #define LSS_NAME(name) sys_##name
-  #elif SYS_PREFIX < 0
-    #define LSS_NAME(name) name
-  #elif SYS_PREFIX == 0
-    #define LSS_NAME(name) sys0_##name
-  #elif SYS_PREFIX == 1
-    #define LSS_NAME(name) sys1_##name
-  #elif SYS_PREFIX == 2
-    #define LSS_NAME(name) sys2_##name
-  #elif SYS_PREFIX == 3
-    #define LSS_NAME(name) sys3_##name
-  #elif SYS_PREFIX == 4
-    #define LSS_NAME(name) sys4_##name
-  #elif SYS_PREFIX == 5
-    #define LSS_NAME(name) sys5_##name
-  #elif SYS_PREFIX == 6
-    #define LSS_NAME(name) sys6_##name
-  #elif SYS_PREFIX == 7
-    #define LSS_NAME(name) sys7_##name
-  #elif SYS_PREFIX == 8
-    #define LSS_NAME(name) sys8_##name
-  #elif SYS_PREFIX == 9
-    #define LSS_NAME(name) sys9_##name
-  #endif
-
-  #undef  LSS_RETURN
-  #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) ||        \
-       defined(__aarch64__) || defined(__s390__))
-  /* Failing system calls return a negative result in the range of
-   * -1..-4095. These are "errno" values with the sign inverted.
-   */
-  #define LSS_RETURN(type, res)                                               \
-    do {                                                                      \
-      if ((unsigned long)(res) >= (unsigned long)(-4095)) {                   \
-        LSS_ERRNO = -(res);                                                   \
-        res = -1;                                                             \
-      }                                                                       \
-      return (type) (res);                                                    \
-    } while (0)
-  #elif defined(__mips__)
-  /* On MIPS, failing system calls return -1, and set errno in a
-   * separate CPU register.
-   */
-  #define LSS_RETURN(type, res, err)                                          \
-    do {                                                                      \
-      if (err) {                                                              \
-        unsigned long __errnovalue = (res);                                   \
-        LSS_ERRNO = __errnovalue;                                             \
-        res = -1;                                                             \
-      }                                                                       \
-      return (type) (res);                                                    \
-    } while (0)
-  #elif defined(__PPC__)
-  /* On PPC, failing system calls return -1, and set errno in a
-   * separate CPU register. See linux/unistd.h.
-   */
-  #define LSS_RETURN(type, res, err)                                          \
-   do {                                                                       \
-     if (err & 0x10000000 ) {                                                 \
-       LSS_ERRNO = (res);                                                     \
-       res = -1;                                                              \
-     }                                                                        \
-     return (type) (res);                                                     \
-   } while (0)
-  #endif
-  #if defined(__i386__)
-    #if defined(NO_FRAME_POINTER) && (100 * __GNUC__ + __GNUC_MINOR__ >= 404)
-      /* This only works for GCC-4.4 and above -- the first version to use
-         .cfi directives for dwarf unwind info.  */
-      #define CFI_ADJUST_CFA_OFFSET(adjust)                                   \
-                  ".cfi_adjust_cfa_offset " #adjust "\n"
-    #else
-      #define CFI_ADJUST_CFA_OFFSET(adjust) /**/
-    #endif
-
-    /* In PIC mode (e.g. when building shared libraries), gcc for i386
-     * reserves ebx. Unfortunately, most distribution ship with implementations
-     * of _syscallX() which clobber ebx.
-     * Also, most definitions of _syscallX() neglect to mark "memory" as being
-     * clobbered. This causes problems with compilers, that do a better job
-     * at optimizing across __asm__ calls.
-     * So, we just have to redefine all of the _syscallX() macros.
-     */
-    #undef  LSS_BODY
-    #define LSS_BODY(type,args...)                                            \
-      long __res;                                                             \
-      __asm__ __volatile__("push %%ebx\n"                                     \
-                           CFI_ADJUST_CFA_OFFSET(4)                           \
-                           "movl %2,%%ebx\n"                                  \
-                           "int $0x80\n"                                      \
-                           "pop %%ebx\n"                                      \
-                           CFI_ADJUST_CFA_OFFSET(-4)                          \
-                           args                                               \
-                           : "esp", "memory");                                \
-      LSS_RETURN(type,__res)
-    #undef  _syscall0
-    #define _syscall0(type,name)                                              \
-      type LSS_NAME(name)(void) {                                             \
-        long __res;                                                           \
-        __asm__ volatile("int $0x80"                                          \
-                         : "=a" (__res)                                       \
-                         : "0" (__NR_##name)                                  \
-                         : "memory");                                         \
-        LSS_RETURN(type,__res);                                               \
-      }
-    #undef  _syscall1
-    #define _syscall1(type,name,type1,arg1)                                   \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        LSS_BODY(type,                                                        \
-             : "=a" (__res)                                                   \
-             : "0" (__NR_##name), "ri" ((long)(arg1)));                       \
-      }
-    #undef  _syscall2
-    #define _syscall2(type,name,type1,arg1,type2,arg2)                        \
-      type LSS_NAME(name)(type1 arg1,type2 arg2) {                            \
-        LSS_BODY(type,                                                        \
-             : "=a" (__res)                                                   \
-             : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2)));    \
-      }
-    #undef  _syscall3
-    #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)             \
-      type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) {                 \
-        LSS_BODY(type,                                                        \
-             : "=a" (__res)                                                   \
-             : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)),    \
-               "d" ((long)(arg3)));                                           \
-      }
-    #undef  _syscall4
-    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_BODY(type,                                                        \
-             : "=a" (__res)                                                   \
-             : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)),    \
-               "d" ((long)(arg3)),"S" ((long)(arg4)));                        \
-      }
-    #undef  _syscall5
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        long __res;                                                           \
-        __asm__ __volatile__("push %%ebx\n"                                   \
-                             "movl %2,%%ebx\n"                                \
-                             "movl %1,%%eax\n"                                \
-                             "int  $0x80\n"                                   \
-                             "pop  %%ebx"                                     \
-                             : "=a" (__res)                                   \
-                             : "i" (__NR_##name), "ri" ((long)(arg1)),        \
-                               "c" ((long)(arg2)), "d" ((long)(arg3)),        \
-                               "S" ((long)(arg4)), "D" ((long)(arg5))         \
-                             : "esp", "memory");                              \
-        LSS_RETURN(type,__res);                                               \
-      }
-    #undef  _syscall6
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        long __res;                                                           \
-        struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 };   \
-        __asm__ __volatile__("push %%ebp\n"                                   \
-                             "push %%ebx\n"                                   \
-                             "movl 4(%2),%%ebp\n"                             \
-                             "movl 0(%2), %%ebx\n"                            \
-                             "movl %1,%%eax\n"                                \
-                             "int  $0x80\n"                                   \
-                             "pop  %%ebx\n"                                   \
-                             "pop  %%ebp"                                     \
-                             : "=a" (__res)                                   \
-                             : "i" (__NR_##name),  "0" ((long)(&__s)),        \
-                               "c" ((long)(arg2)), "d" ((long)(arg3)),        \
-                               "S" ((long)(arg4)), "D" ((long)(arg5))         \
-                             : "esp", "memory");                              \
-        LSS_RETURN(type,__res);                                               \
-      }
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long __res;
-      __asm__ __volatile__(/* if (fn == NULL)
-                            *   return -EINVAL;
-                            */
-                           "movl   %3,%%ecx\n"
-                           "jecxz  1f\n"
-
-                           /* if (child_stack == NULL)
-                            *   return -EINVAL;
-                            */
-                           "movl   %4,%%ecx\n"
-                           "jecxz  1f\n"
-
-                           /* Set up alignment of the child stack:
-                            * child_stack = (child_stack & ~0xF) - 20;
-                            */
-                           "andl   $-16,%%ecx\n"
-                           "subl   $20,%%ecx\n"
-
-                           /* Push "arg" and "fn" onto the stack that will be
-                            * used by the child.
-                            */
-                           "movl   %6,%%eax\n"
-                           "movl   %%eax,4(%%ecx)\n"
-                           "movl   %3,%%eax\n"
-                           "movl   %%eax,(%%ecx)\n"
-
-                           /* %eax = syscall(%eax = __NR_clone,
-                            *                %ebx = flags,
-                            *                %ecx = child_stack,
-                            *                %edx = parent_tidptr,
-                            *                %esi = newtls,
-                            *                %edi = child_tidptr)
-                            * Also, make sure that %ebx gets preserved as it is
-                            * used in PIC mode.
-                            */
-                           "movl   %8,%%esi\n"
-                           "movl   %7,%%edx\n"
-                           "movl   %5,%%eax\n"
-                           "movl   %9,%%edi\n"
-                           "pushl  %%ebx\n"
-                           "movl   %%eax,%%ebx\n"
-                           "movl   %2,%%eax\n"
-                           "int    $0x80\n"
-
-                           /* In the parent: restore %ebx
-                            * In the child:  move "fn" into %ebx
-                            */
-                           "popl   %%ebx\n"
-
-                           /* if (%eax != 0)
-                            *   return %eax;
-                            */
-                           "test   %%eax,%%eax\n"
-                           "jnz    1f\n"
-
-                           /* In the child, now. Terminate frame pointer chain.
-                            */
-                           "movl   $0,%%ebp\n"
-
-                           /* Call "fn". "arg" is already on the stack.
-                            */
-                           "call   *%%ebx\n"
-
-                           /* Call _exit(%ebx). Unfortunately older versions
-                            * of gcc restrict the number of arguments that can
-                            * be passed to asm(). So, we need to hard-code the
-                            * system call number.
-                            */
-                           "movl   %%eax,%%ebx\n"
-                           "movl   $1,%%eax\n"
-                           "int    $0x80\n"
-
-                           /* Return to parent.
-                            */
-                         "1:\n"
-                           : "=a" (__res)
-                           : "0"(-EINVAL), "i"(__NR_clone),
-                             "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
-                             "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
-                           : "esp", "memory", "ecx", "edx", "esi", "edi");
-      LSS_RETURN(int, __res);
-    }
-
-    LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
-      /* On i386, the kernel does not know how to return from a signal
-       * handler. Instead, it relies on user space to provide a
-       * restorer function that calls the {rt_,}sigreturn() system call.
-       * Unfortunately, we cannot just reference the glibc version of this
-       * function, as glibc goes out of its way to make it inaccessible.
-       */
-      void (*res)(void);
-      __asm__ __volatile__("call   2f\n"
-                         "0:.align 16\n"
-                         "1:movl   %1,%%eax\n"
-                           "int    $0x80\n"
-                         "2:popl   %0\n"
-                           "addl   $(1b-0b),%0\n"
-                           : "=a" (res)
-                           : "i"  (__NR_rt_sigreturn));
-      return res;
-    }
-    LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
-      /* On i386, the kernel does not know how to return from a signal
-       * handler. Instead, it relies on user space to provide a
-       * restorer function that calls the {rt_,}sigreturn() system call.
-       * Unfortunately, we cannot just reference the glibc version of this
-       * function, as glibc goes out of its way to make it inaccessible.
-       */
-      void (*res)(void);
-      __asm__ __volatile__("call   2f\n"
-                         "0:.align 16\n"
-                         "1:pop    %%eax\n"
-                           "movl   %1,%%eax\n"
-                           "int    $0x80\n"
-                         "2:popl   %0\n"
-                           "addl   $(1b-0b),%0\n"
-                           : "=a" (res)
-                           : "i"  (__NR_sigreturn));
-      return res;
-    }
-  #elif defined(__x86_64__)
-    /* There are no known problems with any of the _syscallX() macros
-     * currently shipping for x86_64, but we still need to be able to define
-     * our own version so that we can override the location of the errno
-     * location (e.g. when using the clone() system call with the CLONE_VM
-     * option).
-     */
-    #undef  LSS_ENTRYPOINT
-    #define LSS_ENTRYPOINT "syscall\n"
-
-    /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
-     * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
-     * sign extension.  We can't cast pointers directly because those are
-     * 32 bits, and gcc will dump ugly warnings about casting from a pointer
-     * to an integer of a different size.
-     */
-    #undef  LSS_SYSCALL_ARG
-    #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
-    #undef  _LSS_RETURN
-    #define _LSS_RETURN(type, res, cast)                                      \
-      do {                                                                    \
-        if ((uint64_t)(res) >= (uint64_t)(-4095)) {                           \
-          LSS_ERRNO = -(res);                                                 \
-          res = -1;                                                           \
-        }                                                                     \
-        return (type)(cast)(res);                                             \
-      } while (0)
-    #undef  LSS_RETURN
-    #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
-
-    #undef  _LSS_BODY
-    #define _LSS_BODY(nr, type, name, cast, ...)                              \
-          long long __res;                                                    \
-          __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT                \
-            : "=a" (__res)                                                    \
-            : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__)                 \
-            : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory");                   \
-          _LSS_RETURN(type, __res, cast)
-    #undef  LSS_BODY
-    #define LSS_BODY(nr, type, name, args...) \
-      _LSS_BODY(nr, type, name, uintptr_t, ## args)
-
-    #undef  LSS_BODY_ASM0
-    #undef  LSS_BODY_ASM1
-    #undef  LSS_BODY_ASM2
-    #undef  LSS_BODY_ASM3
-    #undef  LSS_BODY_ASM4
-    #undef  LSS_BODY_ASM5
-    #undef  LSS_BODY_ASM6
-    #define LSS_BODY_ASM0
-    #define LSS_BODY_ASM1 LSS_BODY_ASM0
-    #define LSS_BODY_ASM2 LSS_BODY_ASM1
-    #define LSS_BODY_ASM3 LSS_BODY_ASM2
-    #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
-    #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
-    #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
-
-    #undef  LSS_BODY_CLOBBER0
-    #undef  LSS_BODY_CLOBBER1
-    #undef  LSS_BODY_CLOBBER2
-    #undef  LSS_BODY_CLOBBER3
-    #undef  LSS_BODY_CLOBBER4
-    #undef  LSS_BODY_CLOBBER5
-    #undef  LSS_BODY_CLOBBER6
-    #define LSS_BODY_CLOBBER0
-    #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
-    #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
-    #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
-    #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
-    #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
-    #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
-
-    #undef  LSS_BODY_ARG0
-    #undef  LSS_BODY_ARG1
-    #undef  LSS_BODY_ARG2
-    #undef  LSS_BODY_ARG3
-    #undef  LSS_BODY_ARG4
-    #undef  LSS_BODY_ARG5
-    #undef  LSS_BODY_ARG6
-    #define LSS_BODY_ARG0()
-    #define LSS_BODY_ARG1(arg1) \
-      LSS_BODY_ARG0(), "D" (arg1)
-    #define LSS_BODY_ARG2(arg1, arg2) \
-      LSS_BODY_ARG1(arg1), "S" (arg2)
-    #define LSS_BODY_ARG3(arg1, arg2, arg3) \
-      LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
-    #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
-      LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
-    #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
-      LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
-    #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
-      LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
-
-    #undef _syscall0
-    #define _syscall0(type,name)                                              \
-      type LSS_NAME(name)() {                                                 \
-        LSS_BODY(0, type, name);                                              \
-      }
-    #undef _syscall1
-    #define _syscall1(type,name,type1,arg1)                                   \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1));                       \
-      }
-    #undef _syscall2
-    #define _syscall2(type,name,type1,arg1,type2,arg2)                        \
-      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \
-        LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
-      }
-    #undef _syscall3
-    #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \
-        LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
-                                LSS_SYSCALL_ARG(arg3));                       \
-      }
-    #undef _syscall4
-    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
-                                LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
-      }
-    #undef _syscall5
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
-                                LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
-                                LSS_SYSCALL_ARG(arg5));                       \
-      }
-    #undef _syscall6
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
-                                LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
-                                LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
-      }
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long long __res;
-      {
-        __asm__ __volatile__(/* if (fn == NULL)
-                              *   return -EINVAL;
-                              */
-                             "testq  %4,%4\n"
-                             "jz     1f\n"
-
-                             /* if (child_stack == NULL)
-                              *   return -EINVAL;
-                              */
-                             "testq  %5,%5\n"
-                             "jz     1f\n"
-
-                             /* Set up alignment of the child stack:
-                              * child_stack = (child_stack & ~0xF) - 16;
-                              */
-                             "andq   $-16,%5\n"
-                             "subq   $16,%5\n"
-
-                             /* Push "arg" and "fn" onto the stack that will be
-                              * used by the child.
-                              */
-                             "movq   %7,8(%5)\n"
-                             "movq   %4,0(%5)\n"
-
-                             /* %rax = syscall(%rax = __NR_clone,
-                              *                %rdi = flags,
-                              *                %rsi = child_stack,
-                              *                %rdx = parent_tidptr,
-                              *                %r8  = new_tls,
-                              *                %r10 = child_tidptr)
-                              */
-                             "movq   %2,%%rax\n"
-                             "movq   %9,%%r8\n"
-                             "movq   %10,%%r10\n"
-                             "syscall\n"
-
-                             /* if (%rax != 0)
-                              *   return;
-                              */
-                             "testq  %%rax,%%rax\n"
-                             "jnz    1f\n"
-
-                             /* In the child. Terminate frame pointer chain.
-                              */
-                             "xorq   %%rbp,%%rbp\n"
-
-                             /* Call "fn(arg)".
-                              */
-                             "popq   %%rax\n"
-                             "popq   %%rdi\n"
-                             "call   *%%rax\n"
-
-                             /* Call _exit(%ebx).
-                              */
-                             "movq   %%rax,%%rdi\n"
-                             "movq   %3,%%rax\n"
-                             "syscall\n"
-
-                             /* Return to parent.
-                              */
-                           "1:\n"
-                             : "=a" (__res)
-                             : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
-                               "r"(LSS_SYSCALL_ARG(fn)),
-                               "S"(LSS_SYSCALL_ARG(child_stack)),
-                               "D"(LSS_SYSCALL_ARG(flags)),
-                               "r"(LSS_SYSCALL_ARG(arg)),
-                               "d"(LSS_SYSCALL_ARG(parent_tidptr)),
-                               "r"(LSS_SYSCALL_ARG(newtls)),
-                               "r"(LSS_SYSCALL_ARG(child_tidptr))
-                             : "memory", "r8", "r10", "r11", "rcx");
-      }
-      LSS_RETURN(int, __res);
-    }
-
-    LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
-      /* On x86-64, the kernel does not know how to return from
-       * a signal handler. Instead, it relies on user space to provide a
-       * restorer function that calls the rt_sigreturn() system call.
-       * Unfortunately, we cannot just reference the glibc version of this
-       * function, as glibc goes out of its way to make it inaccessible.
-       */
-      long long res;
-      __asm__ __volatile__("call   2f\n"
-                         "0:.align 16\n"
-                         "1:movq   %1,%%rax\n"
-                           "syscall\n"
-                         "2:popq   %0\n"
-                           "addq   $(1b-0b),%0\n"
-                           : "=a" (res)
-                           : "i"  (__NR_rt_sigreturn));
-      return (void (*)(void))(uintptr_t)res;
-    }
-  #elif defined(__arm__)
-    /* Most definitions of _syscallX() neglect to mark "memory" as being
-     * clobbered. This causes problems with compilers, that do a better job
-     * at optimizing across __asm__ calls.
-     * So, we just have to redefine all fo the _syscallX() macros.
-     */
-    #undef LSS_REG
-    #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
-
-    /* r0..r3 are scratch registers and not preserved across function
-     * calls.  We need to first evaluate the first 4 syscall arguments
-     * and store them on stack.  They must be loaded into r0..r3 after
-     * all function calls to avoid r0..r3 being clobbered.
-     */
-    #undef LSS_SAVE_ARG
-    #define LSS_SAVE_ARG(r,a) long __tmp##r = (long)a
-    #undef LSS_LOAD_ARG
-    #define LSS_LOAD_ARG(r) register long __r##r __asm__("r"#r) = __tmp##r
-
-    #undef  LSS_BODY
-    #define LSS_BODY(type, name, args...)                                     \
-          register long __res_r0 __asm__("r0");                               \
-          long __res;                                                         \
-          __SYS_REG(name)                                                     \
-          __asm__ __volatile__ (__syscall_safe(name)                          \
-                                : "=r"(__res_r0)                              \
-                                : __SYS_REG_LIST(args)                        \
-                                : "lr", "memory");                            \
-          __res = __res_r0;                                                   \
-          LSS_RETURN(type, __res)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-      type LSS_NAME(name)() {                                                 \
-        LSS_BODY(type, name);                                                 \
-      }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        /* There is no need for using a volatile temp.  */                    \
-        LSS_REG(0, arg1);                                                     \
-        LSS_BODY(type, name, "r"(__r0));                                      \
-      }
-    #undef _syscall2
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1));                           \
-      }
-    #undef _syscall3
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_SAVE_ARG(2, arg3);                                                \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_LOAD_ARG(2);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2));                \
-      }
-    #undef _syscall4
-    #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                      type4, arg4)                                            \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_SAVE_ARG(2, arg3);                                                \
-        LSS_SAVE_ARG(3, arg4);                                                \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_LOAD_ARG(2);                                                      \
-        LSS_LOAD_ARG(3);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3));     \
-      }
-    #undef _syscall5
-    #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                      type4, arg4, type5, arg5)                               \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_SAVE_ARG(2, arg3);                                                \
-        LSS_SAVE_ARG(3, arg4);                                                \
-        LSS_REG(4, arg5);                                                     \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_LOAD_ARG(2);                                                      \
-        LSS_LOAD_ARG(3);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),      \
-                             "r"(__r4));                                      \
-      }
-    #undef _syscall6
-    #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                      type4, arg4, type5, arg5, type6, arg6)                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_SAVE_ARG(2, arg3);                                                \
-        LSS_SAVE_ARG(3, arg4);                                                \
-        LSS_REG(4, arg5);                                                     \
-        LSS_REG(5, arg6);                                                     \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_LOAD_ARG(2);                                                      \
-        LSS_LOAD_ARG(3);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),      \
-                             "r"(__r4), "r"(__r5));                           \
-      }
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      register long __res __asm__("r5");
-      {
-        if (fn == NULL || child_stack == NULL) {
-            __res = -EINVAL;
-            goto clone_exit;
-        }
-
-        /* stash first 4 arguments on stack first because we can only load
-         * them after all function calls.
-         */
-        int    tmp_flags = flags;
-        int  * tmp_stack = (int*) child_stack;
-        void * tmp_ptid  = parent_tidptr;
-        void * tmp_tls   = newtls;
-
-        register int  *__ctid  __asm__("r4") = child_tidptr;
-
-        /* Push "arg" and "fn" onto the stack that will be
-         * used by the child.
-         */
-        *(--tmp_stack) = (int) arg;
-        *(--tmp_stack) = (int) fn;
-
-        /* We must load r0..r3 last after all possible function calls.  */
-        register int   __flags __asm__("r0") = tmp_flags;
-        register void *__stack __asm__("r1") = tmp_stack;
-        register void *__ptid  __asm__("r2") = tmp_ptid;
-        register void *__tls   __asm__("r3") = tmp_tls;
-
-        /* %r0 = syscall(%r0 = flags,
-         *               %r1 = child_stack,
-         *               %r2 = parent_tidptr,
-         *               %r3 = newtls,
-         *               %r4 = child_tidptr)
-         */
-        __SYS_REG(clone)
-        __asm__ __volatile__(/* %r0 = syscall(%r0 = flags,
-                              *               %r1 = child_stack,
-                              *               %r2 = parent_tidptr,
-                              *               %r3 = newtls,
-                              *               %r4 = child_tidptr)
-                              */
-                             "push  {r7}\n"
-                             "mov   r7,%1\n"
-                             __syscall(clone)"\n"
-
-                             /* if (%r0 != 0)
-                              *   return %r0;
-                              */
-                             "movs  %0,r0\n"
-                             "bne   1f\n"
-
-                             /* In the child, now. Call "fn(arg)".
-                              */
-                             "ldr   r0,[sp, #4]\n"
-                             "mov   lr,pc\n"
-                             "ldr   pc,[sp]\n"
-
-                             /* Call _exit(%r0), which never returns.  We only
-                              * need to set r7 for EABI syscall ABI but we do
-                              * this always to simplify code sharing between
-                              * old and new syscall ABIs.
-                              */
-                             "mov   r7,%2\n"
-                             __syscall(exit)"\n"
-
-                             /* Pop r7 from the stack only in the parent.
-                              */
-                           "1: pop {r7}\n"
-                             : "=r" (__res)
-                             : "r"(__sysreg),
-                               "i"(__NR_exit), "r"(__stack), "r"(__flags),
-                               "r"(__ptid), "r"(__tls), "r"(__ctid)
-                             : "cc", "lr", "memory");
-      }
-      clone_exit:
-      LSS_RETURN(int, __res);
-    }
-  #elif defined(__mips__)
-    #undef LSS_REG
-    #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) =       \
-                                 (unsigned long)(a)
-
-    #if _MIPS_SIM == _MIPS_SIM_ABI32
-    // See http://sources.redhat.com/ml/libc-alpha/2004-10/msg00050.html
-    // or http://www.linux-mips.org/archives/linux-mips/2004-10/msg00142.html
-    #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12",\
-                                "$13", "$14", "$15", "$24", "$25", "memory"
-    #else
-    #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13",     \
-                                "$14", "$15", "$24", "$25", "memory"
-    #endif
-
-    #undef  LSS_BODY
-    #define LSS_BODY(type,name,r7,...)                                        \
-          register unsigned long __v0 __asm__("$2") = __NR_##name;            \
-          __asm__ __volatile__ ("syscall\n"                                   \
-                                : "=r"(__v0), r7 (__r7)                       \
-                                : "0"(__v0), ##__VA_ARGS__                    \
-                                : MIPS_SYSCALL_CLOBBERS);                     \
-          LSS_RETURN(type, __v0, __r7)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-      type LSS_NAME(name)() {                                                 \
-        register unsigned long __r7 __asm__("$7");                            \
-        LSS_BODY(type, name, "=r");                                           \
-      }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        register unsigned long __r7 __asm__("$7");                            \
-        LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4));              \
-      }
-    #undef _syscall2
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \
-        register unsigned long __r7 __asm__("$7");                            \
-        LSS_REG(4, arg1); LSS_REG(5, arg2);                                   \
-        LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5));                     \
-      }
-    #undef _syscall3
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \
-        register unsigned long __r7 __asm__("$7");                            \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6));          \
-      }
-    #undef _syscall4
-    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4);                                                     \
-        LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6));          \
-      }
-    #undef _syscall5
-    #if _MIPS_SIM == _MIPS_SIM_ABI32
-    /* The old 32bit MIPS system call API passes the fifth and sixth argument
-     * on the stack, whereas the new APIs use registers "r8" and "r9".
-     */
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4);                                                     \
-        register unsigned long __v0 __asm__("$2") = __NR_##name;              \
-        __asm__ __volatile__ (".set noreorder\n"                              \
-                              "subu  $29, 32\n"                               \
-                              "sw    %5, 16($29)\n"                           \
-                              "syscall\n"                                     \
-                              "addiu $29, 32\n"                               \
-                              ".set reorder\n"                                \
-                              : "+r"(__v0), "+r" (__r7)                       \
-                              : "r"(__r4), "r"(__r5),                         \
-                                "r"(__r6), "r" ((unsigned long)arg5)          \
-                              : MIPS_SYSCALL_CLOBBERS);                       \
-        LSS_RETURN(type, __v0, __r7);                                         \
-      }
-    #else
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4); LSS_REG(8, arg5);                                   \
-        LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6),           \
-                 "r"(__r8));                                                  \
-      }
-    #endif
-    #undef _syscall6
-    #if _MIPS_SIM == _MIPS_SIM_ABI32
-    /* The old 32bit MIPS system call API passes the fifth and sixth argument
-     * on the stack, whereas the new APIs use registers "r8" and "r9".
-     */
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4);                                                     \
-        register unsigned long __v0 __asm__("$2") = __NR_##name;              \
-        __asm__ __volatile__ (".set noreorder\n"                              \
-                              "subu  $29, 32\n"                               \
-                              "sw    %5, 16($29)\n"                           \
-                              "sw    %6, 20($29)\n"                           \
-                              "syscall\n"                                     \
-                              "addiu $29, 32\n"                               \
-                              ".set reorder\n"                                \
-                              : "+r"(__v0), "+r" (__r7)                       \
-                              : "r"(__r4), "r"(__r5),                         \
-                                "r"(__r6), "r" ((unsigned long)arg5),         \
-                                "r" ((unsigned long)arg6)                     \
-                              : MIPS_SYSCALL_CLOBBERS);                       \
-        LSS_RETURN(type, __v0, __r7);                                         \
-      }
-    #else
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5,type6 arg6) {                            \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6);                 \
-        LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6),           \
-                 "r"(__r8), "r"(__r9));                                       \
-      }
-    #endif
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      register unsigned long __v0 __asm__("$2") = -EINVAL;
-      register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
-      {
-        register int   __flags __asm__("$4") = flags;
-        register void *__stack __asm__("$5") = child_stack;
-        register void *__ptid  __asm__("$6") = parent_tidptr;
-        register int  *__ctid  __asm__("$8") = child_tidptr;
-        __asm__ __volatile__(
-          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
-                             "subu  $29,24\n"
-          #elif _MIPS_SIM == _MIPS_SIM_NABI32
-                             "sub   $29,16\n"
-          #else
-                             "dsubu $29,16\n"
-          #endif
-
-                             /* if (fn == NULL || child_stack == NULL)
-                              *   return -EINVAL;
-                              */
-                             "beqz  %4,1f\n"
-                             "beqz  %5,1f\n"
-
-                             /* Push "arg" and "fn" onto the stack that will be
-                              * used by the child.
-                              */
-          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
-                             "subu  %5,32\n"
-                             "sw    %4,0(%5)\n"
-                             "sw    %7,4(%5)\n"
-          #elif _MIPS_SIM == _MIPS_SIM_NABI32
-                             "sub   %5,32\n"
-                             "sw    %4,0(%5)\n"
-                             "sw    %7,8(%5)\n"
-          #else
-                             "dsubu %5,32\n"
-                             "sd    %4,0(%5)\n"
-                             "sd    %7,8(%5)\n"
-          #endif
-
-                             /* $7 = syscall($4 = flags,
-                              *              $5 = child_stack,
-                              *              $6 = parent_tidptr,
-                              *              $7 = newtls,
-                              *              $8 = child_tidptr)
-                              */
-                             "li    $2,%2\n"
-                             "syscall\n"
-
-                             /* if ($7 != 0)
-                              *   return $2;
-                              */
-                             "bnez  $7,1f\n"
-                             "bnez  $2,1f\n"
-
-                             /* In the child, now. Call "fn(arg)".
-                              */
-          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
-                            "lw    $25,0($29)\n"
-                            "lw    $4,4($29)\n"
-          #elif _MIPS_SIM == _MIPS_SIM_NABI32
-                            "lw    $25,0($29)\n"
-                            "lw    $4,8($29)\n"
-          #else
-                            "ld    $25,0($29)\n"
-                            "ld    $4,8($29)\n"
-          #endif
-                            "jalr  $25\n"
-
-                             /* Call _exit($2)
-                              */
-                            "move  $4,$2\n"
-                            "li    $2,%3\n"
-                            "syscall\n"
-
-                           "1:\n"
-          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
-                             "addu  $29, 24\n"
-          #elif _MIPS_SIM == _MIPS_SIM_NABI32
-                             "add   $29, 16\n"
-          #else
-                             "daddu $29,16\n"
-          #endif
-                             : "+r" (__v0), "+r" (__r7)
-                             : "i"(__NR_clone), "i"(__NR_exit), "r"(fn),
-                               "r"(__stack), "r"(__flags), "r"(arg),
-                               "r"(__ptid), "r"(__ctid)
-                             : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
-                               "$24", "$25", "memory");
-      }
-      LSS_RETURN(int, __v0, __r7);
-    }
-  #elif defined (__PPC__)
-    #undef  LSS_LOADARGS_0
-    #define LSS_LOADARGS_0(name, dummy...)                                    \
-        __sc_0 = __NR_##name
-    #undef  LSS_LOADARGS_1
-    #define LSS_LOADARGS_1(name, arg1)                                        \
-            LSS_LOADARGS_0(name);                                             \
-            __sc_3 = (unsigned long) (arg1)
-    #undef  LSS_LOADARGS_2
-    #define LSS_LOADARGS_2(name, arg1, arg2)                                  \
-            LSS_LOADARGS_1(name, arg1);                                       \
-            __sc_4 = (unsigned long) (arg2)
-    #undef  LSS_LOADARGS_3
-    #define LSS_LOADARGS_3(name, arg1, arg2, arg3)                            \
-            LSS_LOADARGS_2(name, arg1, arg2);                                 \
-            __sc_5 = (unsigned long) (arg3)
-    #undef  LSS_LOADARGS_4
-    #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4)                      \
-            LSS_LOADARGS_3(name, arg1, arg2, arg3);                           \
-            __sc_6 = (unsigned long) (arg4)
-    #undef  LSS_LOADARGS_5
-    #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5)                \
-            LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4);                     \
-            __sc_7 = (unsigned long) (arg5)
-    #undef  LSS_LOADARGS_6
-    #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6)          \
-            LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5);               \
-            __sc_8 = (unsigned long) (arg6)
-    #undef  LSS_ASMINPUT_0
-    #define LSS_ASMINPUT_0 "0" (__sc_0)
-    #undef  LSS_ASMINPUT_1
-    #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
-    #undef  LSS_ASMINPUT_2
-    #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
-    #undef  LSS_ASMINPUT_3
-    #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
-    #undef  LSS_ASMINPUT_4
-    #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
-    #undef  LSS_ASMINPUT_5
-    #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
-    #undef  LSS_ASMINPUT_6
-    #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
-    #undef  LSS_BODY
-    #define LSS_BODY(nr, type, name, args...)                                 \
-        long __sc_ret, __sc_err;                                              \
-        {                                                                     \
-            register unsigned long __sc_0 __asm__ ("r0");                     \
-            register unsigned long __sc_3 __asm__ ("r3");                     \
-            register unsigned long __sc_4 __asm__ ("r4");                     \
-            register unsigned long __sc_5 __asm__ ("r5");                     \
-            register unsigned long __sc_6 __asm__ ("r6");                     \
-            register unsigned long __sc_7 __asm__ ("r7");                     \
-            register unsigned long __sc_8 __asm__ ("r8");                     \
-                                                                              \
-            LSS_LOADARGS_##nr(name, args);                                    \
-            __asm__ __volatile__                                              \
-                ("sc\n\t"                                                     \
-                 "mfcr %0"                                                    \
-                 : "=&r" (__sc_0),                                            \
-                   "=&r" (__sc_3), "=&r" (__sc_4),                            \
-                   "=&r" (__sc_5), "=&r" (__sc_6),                            \
-                   "=&r" (__sc_7), "=&r" (__sc_8)                             \
-                 : LSS_ASMINPUT_##nr                                          \
-                 : "cr0", "ctr", "memory",                                    \
-                   "r9", "r10", "r11", "r12");                                \
-            __sc_ret = __sc_3;                                                \
-            __sc_err = __sc_0;                                                \
-        }                                                                     \
-        LSS_RETURN(type, __sc_ret, __sc_err)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-       type LSS_NAME(name)(void) {                                            \
-          LSS_BODY(0, type, name);                                            \
-       }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-       type LSS_NAME(name)(type1 arg1) {                                      \
-          LSS_BODY(1, type, name, arg1);                                      \
-       }
-    #undef _syscall2
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-       type LSS_NAME(name)(type1 arg1, type2 arg2) {                          \
-          LSS_BODY(2, type, name, arg1, arg2);                                \
-       }
-    #undef _syscall3
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {              \
-          LSS_BODY(3, type, name, arg1, arg2, arg3);                          \
-       }
-    #undef _syscall4
-    #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4)                                \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {  \
-          LSS_BODY(4, type, name, arg1, arg2, arg3, arg4);                    \
-       }
-    #undef _syscall5
-    #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4, type5, arg5)                   \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,    \
-                                               type5 arg5) {                  \
-          LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5);              \
-       }
-    #undef _syscall6
-    #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4, type5, arg5, type6, arg6)      \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,    \
-                                               type5 arg5, type6 arg6) {      \
-          LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6);        \
-       }
-    /* clone function adapted from glibc 2.18 clone.S                       */
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long __ret, __err;
-      {
-#if defined(__PPC64__)
-
-/* Stack frame offsets.  */
-#if _CALL_ELF != 2
-#define FRAME_MIN_SIZE         112
-#define FRAME_TOC_SAVE         40
-#else
-#define FRAME_MIN_SIZE         32
-#define FRAME_TOC_SAVE         24
-#endif
-
-
-        register int (*__fn)(void *) __asm__ ("r3") = fn;
-        register void *__cstack      __asm__ ("r4") = child_stack;
-        register int __flags         __asm__ ("r5") = flags;
-        register void * __arg        __asm__ ("r6") = arg;
-        register int * __ptidptr     __asm__ ("r7") = parent_tidptr;
-        register void * __newtls     __asm__ ("r8") = newtls;
-        register int * __ctidptr     __asm__ ("r9") = child_tidptr;
-        __asm__ __volatile__(
-            /* check for fn == NULL
-             * and child_stack == NULL
-             */
-            "cmpdi cr0, %6, 0\n\t"
-            "cmpdi cr1, %7, 0\n\t"
-            "cror  cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
-            "beq-  cr0, 1f\n\t"
-
-            /* set up stack frame for child                                  */
-            "clrrdi %7, %7, 4\n\t"
-            "li     0, 0\n\t"
-            "stdu   0, -%13(%7)\n\t"
-
-            /* fn, arg, child_stack are saved acrVoss the syscall             */
-            "mr 28, %6\n\t"
-            "mr 29, %7\n\t"
-            "mr 27, %9\n\t"
-
-            /* syscall
-               r3 == flags
-               r4 == child_stack
-               r5 == parent_tidptr
-               r6 == newtls
-               r7 == child_tidptr                                            */
-            "mr 3, %8\n\t"
-            "mr 5, %10\n\t"
-            "mr 6, %11\n\t"
-            "mr 7, %12\n\t"
-	    "li	0, %4\n\t"
-            "sc\n\t"
-
-            /* Test if syscall was successful                                */
-            "cmpdi  cr1, 3, 0\n\t"
-            "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
-            "bne-   cr1, 1f\n\t"
-
-            /* Do the function call                                          */
-            "std   2, %14(1)\n\t"
-#if _CALL_ELF != 2
-	    "ld    0, 0(28)\n\t"
-	    "ld    2, 8(28)\n\t"
-            "mtctr 0\n\t"
-#else
-            "mr    12, 28\n\t"
-            "mtctr 12\n\t"
-#endif
-            "mr    3, 27\n\t"
-            "bctrl\n\t"
-	    "ld    2, %14(1)\n\t"
-
-            /* Call _exit(r3)                                                */
-            "li 0, %5\n\t"
-            "sc\n\t"
-
-            /* Return to parent                                              */
-	    "1:\n\t"
-            "mr %0, 3\n\t"
-              : "=r" (__ret), "=r" (__err)
-              : "0" (-1), "i" (EINVAL),
-                "i" (__NR_clone), "i" (__NR_exit),
-                "r" (__fn), "r" (__cstack), "r" (__flags),
-                "r" (__arg), "r" (__ptidptr), "r" (__newtls),
-                "r" (__ctidptr), "i" (FRAME_MIN_SIZE), "i" (FRAME_TOC_SAVE)
-              : "cr0", "cr1", "memory", "ctr",
-                "r0", "r29", "r27", "r28");
-#else
-        register int (*__fn)(void *)    __asm__ ("r8")  = fn;
-        register void *__cstack                 __asm__ ("r4")  = child_stack;
-        register int __flags                    __asm__ ("r3")  = flags;
-        register void * __arg                   __asm__ ("r9")  = arg;
-        register int * __ptidptr                __asm__ ("r5")  = parent_tidptr;
-        register void * __newtls                __asm__ ("r6")  = newtls;
-        register int * __ctidptr                __asm__ ("r7")  = child_tidptr;
-        __asm__ __volatile__(
-            /* check for fn == NULL
-             * and child_stack == NULL
-             */
-            "cmpwi cr0, %6, 0\n\t"
-            "cmpwi cr1, %7, 0\n\t"
-            "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
-            "beq- cr0, 1f\n\t"
-
-            /* set up stack frame for child                                  */
-            "clrrwi %7, %7, 4\n\t"
-            "li 0, 0\n\t"
-            "stwu 0, -16(%7)\n\t"
-
-            /* fn, arg, child_stack are saved across the syscall: r28-30     */
-            "mr 28, %6\n\t"
-            "mr 29, %7\n\t"
-            "mr 27, %9\n\t"
-
-            /* syscall                                                       */
-            "li 0, %4\n\t"
-            /* flags already in r3
-             * child_stack already in r4
-             * ptidptr already in r5
-             * newtls already in r6
-             * ctidptr already in r7
-             */
-            "sc\n\t"
-
-            /* Test if syscall was successful                                */
-            "cmpwi cr1, 3, 0\n\t"
-            "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
-            "bne- cr1, 1f\n\t"
-
-            /* Do the function call                                          */
-            "mtctr 28\n\t"
-            "mr 3, 27\n\t"
-            "bctrl\n\t"
-
-            /* Call _exit(r3)                                                */
-            "li 0, %5\n\t"
-            "sc\n\t"
-
-            /* Return to parent                                              */
-            "1:\n"
-            "mfcr %1\n\t"
-            "mr %0, 3\n\t"
-              : "=r" (__ret), "=r" (__err)
-              : "0" (-1), "1" (EINVAL),
-                "i" (__NR_clone), "i" (__NR_exit),
-                "r" (__fn), "r" (__cstack), "r" (__flags),
-                "r" (__arg), "r" (__ptidptr), "r" (__newtls),
-                "r" (__ctidptr)
-              : "cr0", "cr1", "memory", "ctr",
-                "r0", "r29", "r27", "r28");
-
-#endif
-      }
-      LSS_RETURN(int, __ret, __err);
-    }
-  #elif defined(__aarch64__)
-    #undef LSS_REG
-    #define LSS_REG(r,a) register long __x##r __asm__("x"#r) = (long)a
-    #undef  LSS_BODY
-    #define LSS_BODY(type,name,args...)                                       \
-          register long __res_x0 __asm__("x0");                               \
-          long __res;                                                         \
-          __asm__ __volatile__ ("mov x8, %1\n"                                \
-                                "svc 0x0\n"                                   \
-                                : "=r"(__res_x0)                              \
-                                : "i"(__NR_##name) , ## args                  \
-                                : "memory");                                  \
-          __res = __res_x0;                                                   \
-          LSS_RETURN(type, __res)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-      type LSS_NAME(name)(void) {                                             \
-        LSS_BODY(type, name);                                                 \
-      }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__x0));                    \
-      }
-    #undef _syscall2
-    #define _syscall2_long(type, name, svc, type1, arg1, type2, arg2)         \
-      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \
-        LSS_REG(0, arg1); LSS_REG(1, arg2);                                   \
-        LSS_BODY(type, svc, "r"(__x0), "r"(__x1));                            \
-      }
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-            _syscall2_long(type, name, name, type1, arg1, type2, arg2)
-    #undef _syscall3
-    #define _syscall3_long(type, name, svc, type1, arg1, type2, arg2,         \
-                           type3, arg3)                                       \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \
-        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \
-        LSS_BODY(type, svc, "r"(__x0), "r"(__x1), "r"(__x2));                 \
-      }
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-            _syscall3_long(type, name, name, type1, arg1, type2, arg2,        \
-                           type3, arg3)
-    #undef _syscall4
-    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \
-        LSS_REG(3, arg4);                                                     \
-        LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2), "r"(__x3));     \
-      }
-    #undef _syscall5
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \
-        LSS_REG(3, arg4); LSS_REG(4, arg5);                                   \
-        LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2), "r"(__x3),      \
-                             "r"(__x4));                                      \
-      }
-    #undef _syscall6
-    #define _syscall6_long(type,name,svc,type1,arg1,type2,arg2,type3,arg3,    \
-                           type4,arg4,type5,arg5,type6,arg6)                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \
-        LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6);                 \
-        LSS_BODY(type, svc, "r"(__x0), "r"(__x1), "x"(__x2), "r"(__x3),       \
-                             "r"(__x4), "r"(__x5));                           \
-      }
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-            _syscall6_long(type,name,name,type1,arg1,type2,arg2,type3,arg3,   \
-                           type4,arg4,type5,arg5,type6,arg6)
-    /* clone function adapted from glibc 2.18 clone.S                       */
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long __res;
-      {
-        register int (*__fn)(void *)  __asm__("x0") = fn;
-        register void *__stack __asm__("x1") = child_stack;
-        register int   __flags __asm__("x2") = flags;
-        register void *__arg   __asm__("x3") = arg;
-        register int  *__ptid  __asm__("x4") = parent_tidptr;
-        register void *__tls   __asm__("x5") = newtls;
-        register int  *__ctid  __asm__("x6") = child_tidptr;
-        __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
-                              *   return -EINVAL;
-                              */
-                             "cbz     x0,1f\n"
-                             "cbz     x1,1f\n"
-
-                             /* Push "arg" and "fn" onto the stack that will be
-                              * used by the child.
-                              */
-                             "stp x0,x3, [x1, #-16]!\n"
-
-                             "mov x0,x2\n" /* flags  */
-                             "mov x2,x4\n" /* ptid  */
-                             "mov x3,x5\n" /* tls */
-                             "mov x4,x6\n" /* ctid */
-                             "mov x8,%9\n" /* clone */
-
-                             "svc 0x0\n"
-
-                             /* if (%r0 != 0)
-                              *   return %r0;
-                              */
-                             "cmp x0, #0\n"
-                             "bne 2f\n"
-
-                             /* In the child, now. Call "fn(arg)".
-                              */
-                             "ldp x1, x0, [sp], #16\n"
-                             "blr x1\n"
-
-                             /* Call _exit(%r0).
-                              */
-                             "mov x8, %10\n"
-                             "svc 0x0\n"
-                           "1:\n"
-                             "mov x8, %1\n"
-                           "2:\n"
-                             : "=r" (__res)
-                             : "i"(-EINVAL),
-                               "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
-                               "r"(__ptid), "r"(__tls), "r"(__ctid),
-                               "i"(__NR_clone), "i"(__NR_exit)
-                             : "x30", "memory");
-      }
-      LSS_RETURN(int, __res);
-    }
-  #elif defined(__s390__)
-    #undef  LSS_REG
-    #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
-    #undef  LSS_BODY
-    #define LSS_BODY(type, name, args...)                                     \
-        register unsigned long __nr __asm__("r1")                             \
-            = (unsigned long)(__NR_##name);                                   \
-        register long __res_r2 __asm__("r2");                                 \
-        long __res;                                                           \
-        __asm__ __volatile__                                                  \
-            ("svc 0\n\t"                                                      \
-             : "=d"(__res_r2)                                                 \
-             : "d"(__nr), ## args                                             \
-             : "memory");                                                     \
-        __res = __res_r2;                                                     \
-        LSS_RETURN(type, __res)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-       type LSS_NAME(name)(void) {                                            \
-          LSS_BODY(type, name);                                               \
-       }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-       type LSS_NAME(name)(type1 arg1) {                                      \
-          LSS_REG(2, arg1);                                                   \
-          LSS_BODY(type, name, "0"(__r2));                                    \
-       }
-    #undef _syscall2
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-       type LSS_NAME(name)(type1 arg1, type2 arg2) {                          \
-          LSS_REG(2, arg1); LSS_REG(3, arg2);                                 \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3));                         \
-       }
-    #undef _syscall3
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {              \
-          LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4));              \
-       }
-    #undef _syscall4
-    #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4)                                \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3,                \
-                           type4 arg4) {                                      \
-          LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
-          LSS_REG(5, arg4);                                                   \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4),               \
-                               "d"(__r5));                                    \
-       }
-    #undef _syscall5
-    #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4, type5, arg5)                   \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3,                \
-                           type4 arg4, type5 arg5) {                          \
-          LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
-          LSS_REG(5, arg4); LSS_REG(6, arg5);                                 \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4),               \
-                               "d"(__r5), "d"(__r6));                         \
-       }
-    #undef _syscall6
-    #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4, type5, arg5, type6, arg6)      \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3,                \
-                           type4 arg4, type5 arg5, type6 arg6) {              \
-          LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
-          LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6);               \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4),               \
-                               "d"(__r5), "d"(__r6), "d"(__r7));              \
-       }
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long __ret;
-      {
-        register int  (*__fn)(void *)    __asm__ ("r1")  = fn;
-        register void  *__cstack         __asm__ ("r2")  = child_stack;
-        register int    __flags          __asm__ ("r3")  = flags;
-        register void  *__arg            __asm__ ("r0")  = arg;
-        register int   *__ptidptr        __asm__ ("r4")  = parent_tidptr;
-        register void  *__newtls         __asm__ ("r6")  = newtls;
-        register int   *__ctidptr        __asm__ ("r5")  = child_tidptr;
-        __asm__ __volatile__ (
-    #ifndef __s390x__
-                                  /* arg already in r0 */
-          "ltr %4, %4\n\t"        /* check fn, which is already in r1 */
-          "jz 1f\n\t"             /* NULL function pointer, return -EINVAL */
-          "ltr %5, %5\n\t"        /* check child_stack, which is already in r2 */
-          "jz 1f\n\t"             /* NULL stack pointer, return -EINVAL */
-                                  /* flags already in r3 */
-                                  /* parent_tidptr already in r4 */
-                                  /* child_tidptr already in r5 */
-                                  /* newtls already in r6 */
-          "svc %2\n\t"            /* invoke clone syscall */
-          "ltr %0,%%r2\n\t"       /* load return code into __ret and test */
-          "jnz 1f\n\t"            /* return to parent if non-zero */
-                                  /* start child thread */
-          "lr %%r2, %7\n\t"       /* set first parameter to void *arg */
-          "ahi %%r15, -96\n\t"    /* make room on the stack for the save area */
-          "xc 0(4,%%r15), 0(%%r15)\n\t"
-          "basr %%r14, %4\n\t"    /* jump to fn */
-          "svc %3\n"              /* invoke exit syscall */
-          "1:\n"
-    #else
-                                  /* arg already in r0 */
-          "ltgr %4, %4\n\t"       /* check fn, which is already in r1 */
-          "jz 1f\n\t"             /* NULL function pointer, return -EINVAL */
-          "ltgr %5, %5\n\t"       /* check child_stack, which is already in r2 */
-          "jz 1f\n\t"             /* NULL stack pointer, return -EINVAL */
-                                  /* flags already in r3 */
-                                  /* parent_tidptr already in r4 */
-                                  /* child_tidptr already in r5 */
-                                  /* newtls already in r6 */
-          "svc %2\n\t"            /* invoke clone syscall */
-          "ltgr %0, %%r2\n\t"     /* load return code into __ret and test */
-          "jnz 1f\n\t"            /* return to parent if non-zero */
-                                  /* start child thread */
-          "lgr %%r2, %7\n\t"      /* set first parameter to void *arg */
-          "aghi %%r15, -160\n\t"  /* make room on the stack for the save area */
-          "xc 0(8,%%r15), 0(%%r15)\n\t"
-          "basr %%r14, %4\n\t"    /* jump to fn */
-          "svc %3\n"              /* invoke exit syscall */
-          "1:\n"
-    #endif
-          : "=r" (__ret)
-          : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
-            "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
-            "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
-          : "cc", "r14", "memory"
-        );
-      }
-      LSS_RETURN(int, __ret);
-    }
-  #endif
-  #define __NR__exit   __NR_exit
-  #define __NR__gettid __NR_gettid
-  #define __NR__mremap __NR_mremap
-  LSS_INLINE _syscall1(int,     close,           int,         f)
-  LSS_INLINE _syscall1(int,     _exit,           int,         e)
-#if defined(__aarch64__) && defined (__ILP32__)
-  /* aarch64_ilp32 uses fcntl64 for sys_fcntl() */
-  LSS_INLINE _syscall3_long(int,     fcntl,      fcntl64,     int,         f,
-                       int,            c, long,   a)
-#else
-  LSS_INLINE _syscall3(int,     fcntl,           int,         f,
-                       int,            c, long,   a)
-#endif
-#if defined(__aarch64__) && defined (__ILP32__)
-  /* aarch64_ilp32 uses fstat64 for sys_fstat() */
-  LSS_INLINE _syscall2_long(int,     fstat,       fstat64,    int,         f,
-                      struct kernel_stat*,   b)
-#else
-  LSS_INLINE _syscall2(int,     fstat,           int,         f,
-                      struct kernel_stat*,   b)
-#endif
-  LSS_INLINE _syscall6(int,     futex,           int*,        a,
-                       int,            o, int,    v,
-                      struct kernel_timespec*, t,
-                       int*, a2,
-                       int, v3)
-#ifdef __NR_getdents64
-    LSS_INLINE _syscall3(int,     getdents64,      int,         f,
-                         struct kernel_dirent64*, d, int,    c)
-#define KERNEL_DIRENT kernel_dirent64
-#define GETDENTS sys_getdents64
-#else
-    LSS_INLINE _syscall3(int,     getdents,        int,         f,
-                         struct kernel_dirent*, d, int,    c)
-#define KERNEL_DIRENT kernel_dirent
-#define GETDENTS sys_getdents
-#endif
-  LSS_INLINE _syscall0(pid_t,   getpid)
-  LSS_INLINE _syscall0(pid_t,   getppid)
-  LSS_INLINE _syscall0(pid_t,   _gettid)
-  LSS_INLINE _syscall2(int,     kill,            pid_t,       p,
-                       int,            s)
-  #if defined(__x86_64__)
-    /* Need to make sure off_t isn't truncated to 32-bits under x32.  */
-    LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
-      _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
-                                        LSS_SYSCALL_ARG(w));
-    }
-  #elif defined(__aarch64__) && defined (__ILP32__)
-    /* aarch64_ilp32 uses llseek for sys_lseek() */
-    LSS_INLINE _syscall3_long(off_t,   lseek,       llseek,    int,         f,
-                         off_t,          o, int,    w)
-  #else
-    LSS_INLINE _syscall3(off_t,   lseek,           int,         f,
-                         off_t,          o, int,    w)
-  #endif
-  LSS_INLINE _syscall2(int,     munmap,          void*,       s,
-                       size_t,         l)
-  LSS_INLINE _syscall5(void*,   _mremap,         void*,       o,
-                       size_t,         os,       size_t,      ns,
-                       unsigned long,  f, void *, a)
-  LSS_INLINE _syscall2(int,     prctl,           int,         o,
-                       long,           a)
-  LSS_INLINE _syscall4(long,    ptrace,          int,         r,
-                       pid_t,          p, void *, a, void *, d)
-  LSS_INLINE _syscall3(ssize_t, read,            int,         f,
-                       void *,         b, size_t, c)
-  LSS_INLINE _syscall4(int,     rt_sigaction,    int,         s,
-                       const struct kernel_sigaction*, a,
-                       struct kernel_sigaction*, o, size_t,   c)
-  LSS_INLINE _syscall4(int, rt_sigprocmask,      int,         h,
-                       const struct kernel_sigset_t*,  s,
-                       struct kernel_sigset_t*,        o, size_t, c);
-  LSS_INLINE _syscall0(int,     sched_yield)
-  LSS_INLINE _syscall2(int,     sigaltstack,     const stack_t*, s,
-                       const stack_t*, o)
-  #if defined(__NR_fstatat)
-    LSS_INLINE _syscall4(int, fstatat, int, d, const char *, p,
-                         struct kernel_stat*,   b, int, flags)
-    LSS_INLINE int LSS_NAME(stat)(const char* p, struct kernel_stat* b) {
-      return LSS_NAME(fstatat)(AT_FDCWD,p,b,0);
-  }
-  #else
-    LSS_INLINE _syscall2(int,     stat,            const char*, f,
-                         struct kernel_stat*,   b)
-  #endif
-  LSS_INLINE _syscall3(ssize_t, write,            int,        f,
-                       const void *,   b, size_t, c)
-  #if defined(__NR_getcpu)
-    LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
-                         unsigned *, node, void *, unused);
-  #endif
-  #if defined(__x86_64__) || defined(__aarch64__) || \
-     (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
-    LSS_INLINE _syscall3(int, socket,             int,   d,
-                         int,                     t, int,       p)
-  #endif
-  #if defined(__x86_64__) || defined(__s390x__)
-    LSS_INLINE int LSS_NAME(sigaction)(int signum,
-                                       const struct kernel_sigaction *act,
-                                       struct kernel_sigaction *oldact) {
-      #if defined(__x86_64__)
-      /* On x86_64, the kernel requires us to always set our own
-       * SA_RESTORER in order to be able to return from a signal handler.
-       * This function must have a "magic" signature that the "gdb"
-       * (and maybe the kernel?) can recognize.
-       */
-      if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
-        struct kernel_sigaction a = *act;
-        a.sa_flags   |= SA_RESTORER;
-        a.sa_restorer = LSS_NAME(restore_rt)();
-        return LSS_NAME(rt_sigaction)(signum, &a, oldact,
-                                      (KERNEL_NSIG+7)/8);
-      } else
-      #endif
-        return LSS_NAME(rt_sigaction)(signum, act, oldact,
-                                      (KERNEL_NSIG+7)/8);
-    }
-
-    LSS_INLINE int LSS_NAME(sigprocmask)(int how,
-                                         const struct kernel_sigset_t *set,
-                                         struct kernel_sigset_t *oldset) {
-      return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
-    }
-  #endif
-  #if (defined(__aarch64__)) || \
-      (defined(__mips__) \
-       && (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32))
-    LSS_INLINE int LSS_NAME(sigaction)(int signum,
-                                       const struct kernel_sigaction *act,
-                                       struct kernel_sigaction *oldact) {
-        return LSS_NAME(rt_sigaction)(signum, act, oldact, (KERNEL_NSIG+7)/8);
-
-    }
-    LSS_INLINE int LSS_NAME(sigprocmask)(int how,
-                                         const struct kernel_sigset_t *set,
-                                         struct kernel_sigset_t *oldset) {
-      return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
-    }
-  #endif
-  #ifdef __NR_wait4
-    LSS_INLINE _syscall4(pid_t, wait4,            pid_t, p,
-                         int*,                    s, int,       o,
-                         struct kernel_rusage*,   r)
-    LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){
-      return LSS_NAME(wait4)(pid, status, options, 0);
-    }
-  #else
-    LSS_INLINE _syscall3(pid_t, waitpid,          pid_t, p,
-                         int*,              s,    int,   o)
-  #endif
-  #ifdef __NR_openat
-    LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
-    LSS_INLINE int LSS_NAME(open)(const char* p, int f, int m) {
-      return LSS_NAME(openat)(AT_FDCWD,p,f,m );
-    }
-  #else
-  LSS_INLINE _syscall3(int,     open,            const char*, p,
-                       int,            f, int,    m)
-  #endif
-  LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
-    memset(&set->sig, 0, sizeof(set->sig));
-    return 0;
-  }
-
-  LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
-    memset(&set->sig, -1, sizeof(set->sig));
-    return 0;
-  }
-
-  LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
-                                     int signum) {
-    if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
-      LSS_ERRNO = EINVAL;
-      return -1;
-    } else {
-      set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
-          |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0])));
-      return 0;
-    }
-  }
-
-  LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
-                                        int signum) {
-    if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
-      LSS_ERRNO = EINVAL;
-      return -1;
-    } else {
-      set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
-          &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0]))));
-      return 0;
-    }
-  }
-
-  #if defined(__i386__) ||                                                    \
-      defined(__arm__) ||                                                     \
-     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) ||                   \
-      defined(__PPC__) ||                                                     \
-     (defined(__s390__) && !defined(__s390x__))
-    #define __NR__sigaction   __NR_sigaction
-    #define __NR__sigprocmask __NR_sigprocmask
-    LSS_INLINE _syscall2(int, fstat64,             int, f,
-                         struct kernel_stat64 *, b)
-    LSS_INLINE _syscall5(int, _llseek,     uint, fd, ulong, hi, ulong, lo,
-                         loff_t *, res, uint, wh)
-#if defined(__s390__) && !defined(__s390x__)
-    /* On s390, mmap2() arguments are passed in memory. */
-    LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
-                                      off_t o) {
-      unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
-                               (unsigned long) p, (unsigned long) f,
-                               (unsigned long) d, (unsigned long) o };
-      LSS_REG(2, buf);
-      LSS_BODY(void*, mmap2, "0"(__r2));
-    }
-#elif !defined(__PPC64__)
-    #define __NR__mmap2 __NR_mmap2
-    LSS_INLINE _syscall6(void*, _mmap2,            void*, s,
-                         size_t,                   l, int,               p,
-                         int,                      f, int,               d,
-                         off_t,                    o)
-#endif
-    LSS_INLINE _syscall3(int,   _sigaction,        int,   s,
-                         const struct kernel_old_sigaction*,  a,
-                         struct kernel_old_sigaction*,        o)
-    LSS_INLINE _syscall3(int,   _sigprocmask,      int,   h,
-                         const unsigned long*,     s,
-                         unsigned long*,           o)
-    LSS_INLINE _syscall2(int, stat64,              const char *, p,
-                         struct kernel_stat64 *, b)
-
-    LSS_INLINE int LSS_NAME(sigaction)(int signum,
-                                       const struct kernel_sigaction *act,
-                                       struct kernel_sigaction *oldact) {
-      int old_errno = LSS_ERRNO;
-      int rc;
-      struct kernel_sigaction a;
-      if (act != NULL) {
-        a             = *act;
-        #ifdef __i386__
-        /* On i386, the kernel requires us to always set our own
-         * SA_RESTORER when using realtime signals. Otherwise, it does not
-         * know how to return from a signal handler. This function must have
-         * a "magic" signature that the "gdb" (and maybe the kernel?) can
-         * recognize.
-         * Apparently, a SA_RESTORER is implicitly set by the kernel, when
-         * using non-realtime signals.
-         *
-         * TODO: Test whether ARM needs a restorer
-         */
-        if (!(a.sa_flags & SA_RESTORER)) {
-          a.sa_flags   |= SA_RESTORER;
-          a.sa_restorer = (a.sa_flags & SA_SIGINFO)
-                          ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
-        }
-        #endif
-      }
-      rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
-                                  (KERNEL_NSIG+7)/8);
-      if (rc < 0 && LSS_ERRNO == ENOSYS) {
-        struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
-        if (!act) {
-          ptr_a            = NULL;
-        } else {
-          oa.sa_handler_   = act->sa_handler_;
-          memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
-          #ifndef __mips__
-          oa.sa_restorer   = act->sa_restorer;
-          #endif
-          oa.sa_flags      = act->sa_flags;
-        }
-        if (!oldact) {
-          ptr_oa           = NULL;
-        }
-        LSS_ERRNO = old_errno;
-        rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
-        if (rc == 0 && oldact) {
-          if (act) {
-            memcpy(oldact, act, sizeof(*act));
-          } else {
-            memset(oldact, 0, sizeof(*oldact));
-          }
-          oldact->sa_handler_    = ptr_oa->sa_handler_;
-          oldact->sa_flags       = ptr_oa->sa_flags;
-          memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
-          #ifndef __mips__
-          oldact->sa_restorer    = ptr_oa->sa_restorer;
-          #endif
-        }
-      }
-      return rc;
-    }
-
-    LSS_INLINE int LSS_NAME(sigprocmask)(int how,
-                                         const struct kernel_sigset_t *set,
-                                         struct kernel_sigset_t *oldset) {
-      int olderrno = LSS_ERRNO;
-      int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
-      if (rc < 0 && LSS_ERRNO == ENOSYS) {
-        LSS_ERRNO = olderrno;
-        if (oldset) {
-          LSS_NAME(sigemptyset)(oldset);
-        }
-        rc = LSS_NAME(_sigprocmask)(how,
-                                    set ? &set->sig[0] : NULL,
-                                    oldset ? &oldset->sig[0] : NULL);
-      }
-      return rc;
-    }
-  #endif
-  #if defined(__i386__) ||                                                    \
-      defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) ||                     \
-     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) ||                   \
-     (defined(__PPC__) && !defined(__PPC64__)) ||                             \
-     (defined(__s390__) && !defined(__s390x__))
-    /* On these architectures, implement mmap() with mmap2(). */
-    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
-                                    int64_t o) {
-      if (o % 4096) {
-        LSS_ERRNO = EINVAL;
-        return (void *) -1;
-      }
-      return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
-    }
-  #elif defined(__s390x__)
-    /* On s390x, mmap() arguments are passed in memory. */
-    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
-                                    int64_t o) {
-      unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
-                               (unsigned long) p, (unsigned long) f,
-                               (unsigned long) d, (unsigned long) o };
-      LSS_REG(2, buf);
-      LSS_BODY(void*, mmap, "0"(__r2));
-    }
-  #elif defined(__x86_64__)
-    /* Need to make sure __off64_t isn't truncated to 32-bits under x32.  */
-    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
-                                    int64_t o) {
-      LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
-                               LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
-                               LSS_SYSCALL_ARG(d), (uint64_t)(o));
-    }
-  #elif defined(__aarch64__) && defined (__ILP32__)
-    /* aarch64_ilp32 uses mmap2 for sys_mmap() */
-    LSS_INLINE _syscall6_long(void*, mmap, mmap2, void*, addr, size_t, length,
-                              int, prot, int, flags, int, fd, int64_t, offset)
-  #else
-    /* Remaining 64-bit architectures. */
-    LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
-                         int, flags, int, fd, int64_t, offset)
-  #endif
-  #if defined(__i386__) || \
-      defined(__PPC__) || \
-      (defined(__arm__) && !defined(__ARM_EABI__)) || \
-      (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
-      defined(__s390__)
-
-    /* See sys_socketcall in net/socket.c in kernel source.
-     * It de-multiplexes on its first arg and unpacks the arglist
-     * array in its second arg.
-     */
-    LSS_INLINE _syscall2(int, socketcall, int, c, unsigned long*, a)
-
-    LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
-      unsigned long args[3] = {
-        (unsigned long) domain,
-        (unsigned long) type,
-        (unsigned long) protocol
-      };
-      return LSS_NAME(socketcall)(1, args);
-    }
-  #elif defined(__ARM_EABI__)
-    LSS_INLINE _syscall3(int, socket,             int,   d,
-                         int,                     t, int,       p)
-  #endif
-  #if defined(__mips__)
-    /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
-     * both file handles through CPU registers.
-     */
-    LSS_INLINE int LSS_NAME(pipe)(int *p) {
-      register unsigned long __v0 __asm__("$2") = __NR_pipe;
-      register unsigned long __v1 __asm__("$3");
-      register unsigned long __r7 __asm__("$7");
-      __asm__ __volatile__ ("syscall\n"
-                            : "=r"(__v0), "=r"(__v1), "=r" (__r7)
-                            : "0"(__v0)
-                            : "$8", "$9", "$10", "$11", "$12",
-                              "$13", "$14", "$15", "$24", "$25", "memory");
-      if (__r7) {
-        unsigned long __errnovalue = __v0;
-        LSS_ERRNO = __errnovalue;
-        return -1;
-      } else {
-        p[0] = __v0;
-        p[1] = __v1;
-        return 0;
-      }
-    }
-  #elif defined(__NR_pipe2)
-    LSS_INLINE _syscall2(int,     pipe2,          int *, p,
-                         int,     f                        )
-    LSS_INLINE int LSS_NAME(pipe)( int * p) {
-        return LSS_NAME(pipe2)(p, 0);
-    }
-  #else
-    LSS_INLINE _syscall1(int,     pipe,           int *, p)
-  #endif
-
-  LSS_INLINE pid_t LSS_NAME(gettid)() {
-    pid_t tid = LSS_NAME(_gettid)();
-    if (tid != -1) {
-      return tid;
-    }
-    return LSS_NAME(getpid)();
-  }
-
-  LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
-                                    size_t new_size, int flags, ...) {
-    va_list ap;
-    void *new_address, *rc;
-    va_start(ap, flags);
-    new_address = va_arg(ap, void *);
-    rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
-                           flags, new_address);
-    va_end(ap);
-    return rc;
-  }
-
-  LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {
-    /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
-     * then sends job control signals to the real parent, rather than to
-     * the tracer. We reduce the risk of this happening by starting a
-     * whole new time slice, and then quickly sending a SIGCONT signal
-     * right after detaching from the tracee.
-     */
-    int rc, err;
-    LSS_NAME(sched_yield)();
-    rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
-    err = LSS_ERRNO;
-    LSS_NAME(kill)(pid, SIGCONT);
-    LSS_ERRNO = err;
-    return rc;
-  }
-#endif
-
-#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
-}
-#endif
-
-#endif
-#endif
diff --git a/third_party/tcmalloc/chromium/src/base/linuxthreads.cc b/third_party/tcmalloc/chromium/src/base/linuxthreads.cc
deleted file mode 100644
index 891e70c8..0000000
--- a/third_party/tcmalloc/chromium/src/base/linuxthreads.cc
+++ /dev/null
@@ -1,707 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005-2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-#include "base/linuxthreads.h"
-
-#ifdef THREADS
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sched.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <sys/prctl.h>
-#include <semaphore.h>
-
-#include "base/linux_syscall_support.h"
-#include "base/thread_lister.h"
-
-#ifndef CLONE_UNTRACED
-#define CLONE_UNTRACED 0x00800000
-#endif
-
-
-/* Synchronous signals that should not be blocked while in the lister thread.
- */
-static const int sync_signals[]  = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, SIGBUS,
-                                     SIGXCPU, SIGXFSZ };
-
-/* itoa() is not a standard function, and we cannot safely call printf()
- * after suspending threads. So, we just implement our own copy. A
- * recursive approach is the easiest here.
- */
-static char *local_itoa(char *buf, int i) {
-  if (i < 0) {
-    *buf++ = '-';
-    return local_itoa(buf, -i);
-  } else {
-    if (i >= 10)
-      buf = local_itoa(buf, i/10);
-    *buf++ = (i%10) + '0';
-    *buf   = '\000';
-    return buf;
-  }
-}
-
-
-/* Wrapper around clone() that runs "fn" on the same stack as the
- * caller! Unlike fork(), the cloned thread shares the same address space.
- * The caller must be careful to use only minimal amounts of stack until
- * the cloned thread has returned.
- * There is a good chance that the cloned thread and the caller will share
- * the same copy of errno!
- */
-#ifdef __GNUC__
-#if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3
-/* Try to force this function into a separate stack frame, and make sure
- * that arguments are passed on the stack.
- */
-static int local_clone (int (*fn)(void *), void *arg, ...)
-  __attribute__ ((noinline));
-#endif
-#endif
-
-/* To avoid the gap cross page boundaries, increase by the large parge
- * size mostly PowerPC system uses.  */
-#ifdef __PPC64__
-#define CLONE_STACK_SIZE 65536
-#else
-#define CLONE_STACK_SIZE 4096
-#endif
-
-static int local_clone (int (*fn)(void *), void *arg, ...) {
-  /* Leave 4kB of gap between the callers stack and the new clone. This
-   * should be more than sufficient for the caller to call waitpid() until
-   * the cloned thread terminates.
-   *
-   * It is important that we set the CLONE_UNTRACED flag, because newer
-   * versions of "gdb" otherwise attempt to attach to our thread, and will
-   * attempt to reap its status codes. This subsequently results in the
-   * caller hanging indefinitely in waitpid(), waiting for a change in
-   * status that will never happen. By setting the CLONE_UNTRACED flag, we
-   * prevent "gdb" from stealing events, but we still expect the thread
-   * lister to fail, because it cannot PTRACE_ATTACH to the process that
-   * is being debugged. This is OK and the error code will be reported
-   * correctly.
-   */
-  return sys_clone(fn, (char *)&arg - CLONE_STACK_SIZE,
-                   CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED, arg, 0, 0, 0);
-}
-
-
-/* Local substitute for the atoi() function, which is not necessarily safe
- * to call once threads are suspended (depending on whether libc looks up
- * locale information,  when executing atoi()).
- */
-static int local_atoi(const char *s) {
-  int n   = 0;
-  int neg = *s == '-';
-  if (neg)
-    s++;
-  while (*s >= '0' && *s <= '9')
-    n = 10*n + (*s++ - '0');
-  return neg ? -n : n;
-}
-
-
-/* Re-runs fn until it doesn't cause EINTR
- */
-#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
-
-
-/* Wrap a class around system calls, in order to give us access to
- * a private copy of errno. This only works in C++, but it has the
- * advantage of not needing nested functions, which are a non-standard
- * language extension.
- */
-#ifdef __cplusplus
-namespace {
-  class SysCalls {
-   public:
-    #define SYS_CPLUSPLUS
-    #define SYS_ERRNO     my_errno
-    #define SYS_INLINE    inline
-    #define SYS_PREFIX    -1
-    #undef  SYS_LINUX_SYSCALL_SUPPORT_H
-    #include "linux_syscall_support.h"
-    SysCalls() : my_errno(0) { }
-    int my_errno;
-  };
-}
-#define ERRNO sys.my_errno
-#else
-#define ERRNO my_errno
-#endif
-
-
-/* Wrapper for open() which is guaranteed to never return EINTR.
- */
-static int c_open(const char *fname, int flags, int mode) {
-  ssize_t rc;
-  NO_INTR(rc = sys_open(fname, flags, mode));
-  return rc;
-}
-
-
-/* abort() is not safely reentrant, and changes it's behavior each time
- * it is called. This means, if the main application ever called abort()
- * we cannot safely call it again. This would happen if we were called
- * from a SIGABRT signal handler in the main application. So, document
- * that calling SIGABRT from the thread lister makes it not signal safe
- * (and vice-versa).
- * Also, since we share address space with the main application, we
- * cannot call abort() from the callback and expect the main application
- * to behave correctly afterwards. In fact, the only thing we can do, is
- * to terminate the main application with extreme prejudice (aka
- * PTRACE_KILL).
- * We set up our own SIGABRT handler to do this.
- * In order to find the main application from the signal handler, we
- * need to store information about it in global variables. This is
- * safe, because the main application should be suspended at this
- * time. If the callback ever called TCMalloc_ResumeAllProcessThreads(), then
- * we are running a higher risk, though. So, try to avoid calling
- * abort() after calling TCMalloc_ResumeAllProcessThreads.
- */
-static volatile int *sig_pids, sig_num_threads, sig_proc, sig_marker;
-
-
-/* Signal handler to help us recover from dying while we are attached to
- * other threads.
- */
-static void SignalHandler(int signum, siginfo_t *si, void *data) {
-  if (sig_pids != NULL) {
-    if (signum == SIGABRT) {
-      while (sig_num_threads-- > 0) {
-        /* Not sure if sched_yield is really necessary here, but it does not */
-        /* hurt, and it might be necessary for the same reasons that we have */
-        /* to do so in sys_ptrace_detach().                                  */
-        sys_sched_yield();
-        sys_ptrace(PTRACE_KILL, sig_pids[sig_num_threads], 0, 0);
-      }
-    } else if (sig_num_threads > 0) {
-      TCMalloc_ResumeAllProcessThreads(sig_num_threads, (int *)sig_pids);
-    }
-  }
-  sig_pids = NULL;
-  if (sig_marker >= 0)
-    NO_INTR(sys_close(sig_marker));
-  sig_marker = -1;
-  if (sig_proc >= 0)
-    NO_INTR(sys_close(sig_proc));
-  sig_proc = -1;
-
-  sys__exit(signum == SIGABRT ? 1 : 2);
-}
-
-
-/* Try to dirty the stack, and hope that the compiler is not smart enough
- * to optimize this function away. Or worse, the compiler could inline the
- * function and permanently allocate the data on the stack.
- */
-static void DirtyStack(size_t amount) {
-  char buf[amount];
-  memset(buf, 0, amount);
-  sys_read(-1, buf, amount);
-}
-
-
-/* Data structure for passing arguments to the lister thread.
- */
-#define ALT_STACKSIZE (MINSIGSTKSZ + 4096)
-
-struct ListerParams {
-  int         result, err;
-  char        *altstack_mem;
-  ListAllProcessThreadsCallBack callback;
-  void        *parameter;
-  va_list     ap;
-  sem_t       *lock;
-};
-
-
-static void ListerThread(struct ListerParams *args) {
-  int                found_parent = 0;
-  pid_t              clone_pid  = sys_gettid(), ppid = sys_getppid();
-  char               proc_self_task[80], marker_name[48], *marker_path;
-  const char         *proc_paths[3];
-  const char *const  *proc_path = proc_paths;
-  int                proc = -1, marker = -1, num_threads = 0;
-  int                max_threads = 0, sig;
-  struct kernel_stat marker_sb, proc_sb;
-  stack_t            altstack;
-
-  /* Wait for parent thread to set appropriate permissions
-   * to allow ptrace activity
-   */
-  if (sem_wait(args->lock) < 0) {
-    goto failure;
-  }
-
-  /* Create "marker" that we can use to detect threads sharing the same
-   * address space and the same file handles. By setting the FD_CLOEXEC flag
-   * we minimize the risk of misidentifying child processes as threads;
-   * and since there is still a race condition,  we will filter those out
-   * later, anyway.
-   */
-  if ((marker = sys_socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0 ||
-      sys_fcntl(marker, F_SETFD, FD_CLOEXEC) < 0) {
-  failure:
-    args->result = -1;
-    args->err    = errno;
-    if (marker >= 0)
-      NO_INTR(sys_close(marker));
-    sig_marker = marker = -1;
-    if (proc >= 0)
-      NO_INTR(sys_close(proc));
-    sig_proc = proc = -1;
-    sys__exit(1);
-  }
-
-  /* Compute search paths for finding thread directories in /proc            */
-  local_itoa(strrchr(strcpy(proc_self_task, "/proc/"), '\000'), ppid);
-  strcpy(marker_name, proc_self_task);
-  marker_path = marker_name + strlen(marker_name);
-  strcat(proc_self_task, "/task/");
-  proc_paths[0] = proc_self_task; /* /proc/$$/task/                          */
-  proc_paths[1] = "/proc/";       /* /proc/                                  */
-  proc_paths[2] = NULL;
-
-  /* Compute path for marker socket in /proc                                 */
-  local_itoa(strcpy(marker_path, "/fd/") + 4, marker);
-  if (sys_stat(marker_name, &marker_sb) < 0) {
-    goto failure;
-  }
-
-  /* Catch signals on an alternate pre-allocated stack. This way, we can
-   * safely execute the signal handler even if we ran out of memory.
-   */
-  memset(&altstack, 0, sizeof(altstack));
-  altstack.ss_sp    = args->altstack_mem;
-  altstack.ss_flags = 0;
-  altstack.ss_size  = ALT_STACKSIZE;
-  sys_sigaltstack(&altstack, (const stack_t *)NULL);
-
-  /* Some kernels forget to wake up traced processes, when the
-   * tracer dies.  So, intercept synchronous signals and make sure
-   * that we wake up our tracees before dying. It is the caller's
-   * responsibility to ensure that asynchronous signals do not
-   * interfere with this function.
-   */
-  sig_marker = marker;
-  sig_proc   = -1;
-  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
-    struct kernel_sigaction sa;
-    memset(&sa, 0, sizeof(sa));
-    sa.sa_sigaction_ = SignalHandler;
-    sys_sigfillset(&sa.sa_mask);
-    sa.sa_flags      = SA_ONSTACK|SA_SIGINFO|SA_RESETHAND;
-    sys_sigaction(sync_signals[sig], &sa, (struct kernel_sigaction *)NULL);
-  }
-  
-  /* Read process directories in /proc/...                                   */
-  for (;;) {
-    /* Some kernels know about threads, and hide them in "/proc"
-     * (although they are still there, if you know the process
-     * id). Threads are moved into a separate "task" directory. We
-     * check there first, and then fall back on the older naming
-     * convention if necessary.
-     */
-    if ((sig_proc = proc = c_open(*proc_path, O_RDONLY|O_DIRECTORY, 0)) < 0) {
-      if (*++proc_path != NULL)
-        continue;
-      goto failure;
-    }
-    if (sys_fstat(proc, &proc_sb) < 0)
-      goto failure;
-    
-    /* Since we are suspending threads, we cannot call any libc
-     * functions that might acquire locks. Most notably, we cannot
-     * call malloc(). So, we have to allocate memory on the stack,
-     * instead. Since we do not know how much memory we need, we
-     * make a best guess. And if we guessed incorrectly we retry on
-     * a second iteration (by jumping to "detach_threads").
-     *
-     * Unless the number of threads is increasing very rapidly, we
-     * should never need to do so, though, as our guestimate is very
-     * conservative.
-     */
-    if (max_threads < proc_sb.st_nlink + 100)
-      max_threads = proc_sb.st_nlink + 100;
-    
-    /* scope */ {
-      pid_t pids[max_threads];
-      int   added_entries = 0;
-      sig_num_threads     = num_threads;
-      sig_pids            = pids;
-      for (;;) {
-        struct KERNEL_DIRENT *entry;
-        char buf[4096];
-        ssize_t nbytes = GETDENTS(proc, (struct KERNEL_DIRENT *)buf,
-                                         sizeof(buf));
-        if (nbytes < 0)
-          goto failure;
-        else if (nbytes == 0) {
-          if (added_entries) {
-            /* Need to keep iterating over "/proc" in multiple
-             * passes until we no longer find any more threads. This
-             * algorithm eventually completes, when all threads have
-             * been suspended.
-             */
-            added_entries = 0;
-            sys_lseek(proc, 0, SEEK_SET);
-            continue;
-          }
-          break;
-        }
-        for (entry = (struct KERNEL_DIRENT *)buf;
-             entry < (struct KERNEL_DIRENT *)&buf[nbytes];
-             entry = (struct KERNEL_DIRENT *)((char *)entry+entry->d_reclen)) {
-          if (entry->d_ino != 0) {
-            const char *ptr = entry->d_name;
-            pid_t pid;
-            
-            /* Some kernels hide threads by preceding the pid with a '.'     */
-            if (*ptr == '.')
-              ptr++;
-            
-            /* If the directory is not numeric, it cannot be a
-             * process/thread
-             */
-            if (*ptr < '0' || *ptr > '9')
-              continue;
-            pid = local_atoi(ptr);
-
-            /* Attach (and suspend) all threads                              */
-            if (pid && pid != clone_pid) {
-              struct kernel_stat tmp_sb;
-              char fname[entry->d_reclen + 48];
-              strcat(strcat(strcpy(fname, "/proc/"),
-                            entry->d_name), marker_path);
-              
-              /* Check if the marker is identical to the one we created      */
-              if (sys_stat(fname, &tmp_sb) >= 0 &&
-                  marker_sb.st_ino == tmp_sb.st_ino) {
-                long i, j;
-
-                /* Found one of our threads, make sure it is no duplicate    */
-                for (i = 0; i < num_threads; i++) {
-                  /* Linear search is slow, but should not matter much for
-                   * the typically small number of threads.
-                   */
-                  if (pids[i] == pid) {
-                    /* Found a duplicate; most likely on second pass         */
-                    goto next_entry;
-                  }
-                }
-                
-                /* Check whether data structure needs growing                */
-                if (num_threads >= max_threads) {
-                  /* Back to square one, this time with more memory          */
-                  NO_INTR(sys_close(proc));
-                  goto detach_threads;
-                }
-
-                /* Attaching to thread suspends it                           */
-                pids[num_threads++] = pid;
-                sig_num_threads     = num_threads;
-                if (sys_ptrace(PTRACE_ATTACH, pid, (void *)0,
-                               (void *)0) < 0) {
-                  /* If operation failed, ignore thread. Maybe it
-                   * just died?  There might also be a race
-                   * condition with a concurrent core dumper or
-                   * with a debugger. In that case, we will just
-                   * make a best effort, rather than failing
-                   * entirely.
-                   */
-                  num_threads--;
-                  sig_num_threads = num_threads;
-                  goto next_entry;
-                }
-                while (sys_waitpid(pid, (int *)0, __WALL) < 0) {
-                  if (errno != EINTR) {
-                    sys_ptrace_detach(pid);
-                    num_threads--;
-                    sig_num_threads = num_threads;
-                    goto next_entry;
-                  }
-                }
-
-                if (sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i++ != j ||
-                    sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i   != j) {
-                  /* Address spaces are distinct, even though both
-                   * processes show the "marker". This is probably
-                   * a forked child process rather than a thread.
-                   */
-                  sys_ptrace_detach(pid);
-                  num_threads--;
-                  sig_num_threads = num_threads;
-                } else {
-                  found_parent |= pid == ppid;
-                  added_entries++;
-                }
-              }
-            }
-          }
-        next_entry:;
-        }
-      }
-      NO_INTR(sys_close(proc));
-      sig_proc = proc = -1;
-
-      /* If we failed to find any threads, try looking somewhere else in
-       * /proc. Maybe, threads are reported differently on this system.
-       */
-      if (num_threads > 1 || !*++proc_path) {
-        NO_INTR(sys_close(marker));
-        sig_marker = marker = -1;
-
-        /* If we never found the parent process, something is very wrong.
-         * Most likely, we are running in debugger. Any attempt to operate
-         * on the threads would be very incomplete. Let's just report an
-         * error to the caller.
-         */
-        if (!found_parent) {
-          TCMalloc_ResumeAllProcessThreads(num_threads, pids);
-          sys__exit(3);
-        }
-
-        /* Now we are ready to call the callback,
-         * which takes care of resuming the threads for us.
-         */
-        args->result = args->callback(args->parameter, num_threads,
-                                      pids, args->ap);
-        args->err = errno;
-
-        /* Callback should have resumed threads, but better safe than sorry  */
-        if (TCMalloc_ResumeAllProcessThreads(num_threads, pids)) {
-          /* Callback forgot to resume at least one thread, report error     */
-          args->err    = EINVAL;
-          args->result = -1;
-        }
-
-        sys__exit(0);
-      }
-    detach_threads:
-      /* Resume all threads prior to retrying the operation                  */
-      TCMalloc_ResumeAllProcessThreads(num_threads, pids);
-      sig_pids = NULL;
-      num_threads = 0;
-      sig_num_threads = num_threads;
-      max_threads += 100;
-    }
-  }
-}
-
-
-/* This function gets the list of all linux threads of the current process
- * passes them to the 'callback' along with the 'parameter' pointer; at the
- * call back call time all the threads are paused via
- * PTRACE_ATTACH.
- * The callback is executed from a separate thread which shares only the
- * address space, the filesystem, and the filehandles with the caller. Most
- * notably, it does not share the same pid and ppid; and if it terminates,
- * the rest of the application is still there. 'callback' is supposed to do
- * or arrange for TCMalloc_ResumeAllProcessThreads. This happens automatically, if
- * the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous
- * signals are blocked. If the 'callback' decides to unblock them, it must
- * ensure that they cannot terminate the application, or that
- * TCMalloc_ResumeAllProcessThreads will get called.
- * It is an error for the 'callback' to make any library calls that could
- * acquire locks. Most notably, this means that most system calls have to
- * avoid going through libc. Also, this means that it is not legal to call
- * exit() or abort().
- * We return -1 on error and the return value of 'callback' on success.
- */
-int TCMalloc_ListAllProcessThreads(void *parameter,
-                                   ListAllProcessThreadsCallBack callback, ...) {
-  char                   altstack_mem[ALT_STACKSIZE];
-  struct ListerParams    args;
-  pid_t                  clone_pid;
-  int                    dumpable = 1, sig;
-  struct kernel_sigset_t sig_blocked, sig_old;
-  sem_t                  lock;
-
-  va_start(args.ap, callback);
-
-  /* If we are short on virtual memory, initializing the alternate stack
-   * might trigger a SIGSEGV. Let's do this early, before it could get us
-   * into more trouble (i.e. before signal handlers try to use the alternate
-   * stack, and before we attach to other threads).
-   */
-  memset(altstack_mem, 0, sizeof(altstack_mem));
-
-  /* Some of our cleanup functions could conceivable use more stack space.
-   * Try to touch the stack right now. This could be defeated by the compiler
-   * being too smart for it's own good, so try really hard.
-   */
-  DirtyStack(32768);
-
-  /* Make this process "dumpable". This is necessary in order to ptrace()
-   * after having called setuid().
-   */
-  dumpable = sys_prctl(PR_GET_DUMPABLE, 0);
-  if (!dumpable)
-    sys_prctl(PR_SET_DUMPABLE, 1);
-
-  /* Fill in argument block for dumper thread                                */
-  args.result       = -1;
-  args.err          = 0;
-  args.altstack_mem = altstack_mem;
-  args.parameter    = parameter;
-  args.callback     = callback;
-  args.lock         = &lock;
-
-  /* Before cloning the thread lister, block all asynchronous signals, as we */
-  /* are not prepared to handle them.                                        */
-  sys_sigfillset(&sig_blocked);
-  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
-    sys_sigdelset(&sig_blocked, sync_signals[sig]);
-  }
-  if (sys_sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old)) {
-    args.err = errno;
-    args.result = -1;
-    goto failed;
-  }
-
-  /* scope */ {
-    /* After cloning, both the parent and the child share the same instance
-     * of errno. We must make sure that at least one of these processes
-     * (in our case, the parent) uses modified syscall macros that update
-     * a local copy of errno, instead.
-     */
-    #ifdef __cplusplus
-      #define sys0_sigprocmask sys.sigprocmask
-      #define sys0_waitpid     sys.waitpid
-      SysCalls sys;
-    #else
-      int my_errno;
-      #define SYS_ERRNO        my_errno
-      #define SYS_INLINE       inline
-      #define SYS_PREFIX       0
-      #undef  SYS_LINUX_SYSCALL_SUPPORT_H
-      #include "linux_syscall_support.h"
-    #endif
-
-    /* Lock before clone so that parent can set
-	 * ptrace permissions (if necessary) prior
-     * to ListerThread actually executing
-     */
-    if (sem_init(&lock, 0, 0) == 0) {
-
-      int clone_errno;
-      clone_pid = local_clone((int (*)(void *))ListerThread, &args);
-      clone_errno = errno;
-
-      sys_sigprocmask(SIG_SETMASK, &sig_old, &sig_old);
-
-      if (clone_pid >= 0) {
-#ifdef PR_SET_PTRACER
-        /* In newer versions of glibc permission must explicitly
-         * be given to allow for ptrace.
-         */
-        prctl(PR_SET_PTRACER, clone_pid, 0, 0, 0);
-#endif
-        /* Releasing the lock here allows the
-         * ListerThread to execute and ptrace us.
-		 */
-        sem_post(&lock);
-        int status, rc;
-        while ((rc = sys0_waitpid(clone_pid, &status, __WALL)) < 0 &&
-               ERRNO == EINTR) {
-                /* Keep waiting                                                 */
-        }
-        if (rc < 0) {
-          args.err = ERRNO;
-          args.result = -1;
-        } else if (WIFEXITED(status)) {
-          switch (WEXITSTATUS(status)) {
-            case 0: break;             /* Normal process termination           */
-            case 2: args.err = EFAULT; /* Some fault (e.g. SIGSEGV) detected   */
-                    args.result = -1;
-                    break;
-            case 3: args.err = EPERM;  /* Process is already being traced      */
-                    args.result = -1;
-                    break;
-            default:args.err = ECHILD; /* Child died unexpectedly              */
-                    args.result = -1;
-                    break;
-          }
-        } else if (!WIFEXITED(status)) {
-          args.err    = EFAULT;        /* Terminated due to an unhandled signal*/
-          args.result = -1;
-        }
-        sem_destroy(&lock);
-      } else {
-        args.result = -1;
-        args.err    = clone_errno;
-      }
-    } else {
-      args.result = -1;
-      args.err    = errno;
-    }
-  }
-
-  /* Restore the "dumpable" state of the process                             */
-failed:
-  if (!dumpable)
-    sys_prctl(PR_SET_DUMPABLE, dumpable);
-
-  va_end(args.ap);
-
-  errno = args.err;
-  return args.result;
-}
-
-/* This function resumes the list of all linux threads that
- * TCMalloc_ListAllProcessThreads pauses before giving to its callback.
- * The function returns non-zero if at least one thread was
- * suspended and has now been resumed.
- */
-int TCMalloc_ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
-  int detached_at_least_one = 0;
-  while (num_threads-- > 0) {
-    detached_at_least_one |= sys_ptrace_detach(thread_pids[num_threads]) >= 0;
-  }
-  return detached_at_least_one;
-}
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/third_party/tcmalloc/chromium/src/base/linuxthreads.h b/third_party/tcmalloc/chromium/src/base/linuxthreads.h
deleted file mode 100644
index 09ce45fc..0000000
--- a/third_party/tcmalloc/chromium/src/base/linuxthreads.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (c) 2005-2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-#ifndef _LINUXTHREADS_H
-#define _LINUXTHREADS_H
-
-/* Include thread_lister.h to get the interface that we implement for linux.
- */
-
-/* We currently only support certain platforms on Linux. Porting to other
- * related platforms should not be difficult.
- */
-#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
-     defined(__mips__) || defined(__PPC__) || defined(__aarch64__) ||       \
-     defined(__s390__)) && defined(__linux)
-
-/* Define the THREADS symbol to make sure that there is exactly one core dumper
- * built into the library.
- */
-#define THREADS "Linux /proc"
-
-#endif
-
-#endif  /* _LINUXTHREADS_H */
diff --git a/third_party/tcmalloc/chromium/src/base/logging.cc b/third_party/tcmalloc/chromium/src/base/logging.cc
deleted file mode 100644
index 761c2fd5..0000000
--- a/third_party/tcmalloc/chromium/src/base/logging.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// This file just provides storage for FLAGS_verbose.
-
-#include <config.h>
-#include "base/logging.h"
-#include "base/commandlineflags.h"
-
-DEFINE_int32(verbose, EnvToInt("PERFTOOLS_VERBOSE", 0),
-             "Set to numbers >0 for more verbose output, or <0 for less.  "
-             "--verbose == -4 means we log fatal errors only.");
-
-
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-
-// While windows does have a POSIX-compatible API
-// (_open/_write/_close), it acquires memory.  Using this lower-level
-// windows API is the closest we can get to being "raw".
-RawFD RawOpenForWriting(const char* filename) {
-  // CreateFile allocates memory if file_name isn't absolute, so if
-  // that ever becomes a problem then we ought to compute the absolute
-  // path on its behalf (perhaps the ntdll/kernel function isn't aware
-  // of the working directory?)
-  RawFD fd = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
-                         CREATE_ALWAYS, 0, NULL);
-  if (fd != kIllegalRawFD && GetLastError() == ERROR_ALREADY_EXISTS)
-    SetEndOfFile(fd);    // truncate the existing file
-  return fd;
-}
-
-void RawWrite(RawFD handle, const char* buf, size_t len) {
-  while (len > 0) {
-    DWORD wrote;
-    BOOL ok = WriteFile(handle, buf, len, &wrote, NULL);
-    // We do not use an asynchronous file handle, so ok==false means an error
-    if (!ok) break;
-    buf += wrote;
-    len -= wrote;
-  }
-}
-
-void RawClose(RawFD handle) {
-  CloseHandle(handle);
-}
-
-#else  // _WIN32 || __CYGWIN__ || __CYGWIN32__
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-// Re-run fn until it doesn't cause EINTR.
-#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)
-
-RawFD RawOpenForWriting(const char* filename) {
-  return open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0664);
-}
-
-void RawWrite(RawFD fd, const char* buf, size_t len) {
-  while (len > 0) {
-    ssize_t r;
-    NO_INTR(r = write(fd, buf, len));
-    if (r <= 0) break;
-    buf += r;
-    len -= r;
-  }
-}
-
-void RawClose(RawFD fd) {
-  NO_INTR(close(fd));
-}
-
-#endif  // _WIN32 || __CYGWIN__ || __CYGWIN32__
diff --git a/third_party/tcmalloc/chromium/src/base/logging.h b/third_party/tcmalloc/chromium/src/base/logging.h
deleted file mode 100644
index b9a0e16..0000000
--- a/third_party/tcmalloc/chromium/src/base/logging.h
+++ /dev/null
@@ -1,262 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// This file contains #include information about logging-related stuff.
-// Pretty much everybody needs to #include this file so that they can
-// log various happenings.
-//
-#ifndef _LOGGING_H_
-#define _LOGGING_H_
-
-#include <config.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for write()
-#endif
-#include <string.h>    // for strlen(), strcmp()
-#include <assert.h>
-#include <errno.h>     // for errno
-#include "base/abort.h"
-#include "base/commandlineflags.h"
-
-// On some systems (like freebsd), we can't call write() at all in a
-// global constructor, perhaps because errno hasn't been set up.
-// (In windows, we can't call it because it might call malloc.)
-// Calling the write syscall is safer (it doesn't set errno), so we
-// prefer that.  Note we don't care about errno for logging: we just
-// do logging on a best-effort basis.
-#if defined(_MSC_VER)
-#define WRITE_TO_STDERR(buf, len) WriteToStderr(buf, len);  // in port.cc
-#elif defined(HAVE_SYS_SYSCALL_H)
-#include <sys/syscall.h>
-#define WRITE_TO_STDERR(buf, len) syscall(SYS_write, STDERR_FILENO, buf, len)
-#else
-#define WRITE_TO_STDERR(buf, len) write(STDERR_FILENO, buf, len)
-#endif
-
-// MSVC and mingw define their own, safe version of vnsprintf (the
-// windows one in broken) in port.cc.  Everyone else can use the
-// version here.  We had to give it a unique name for windows.
-#ifndef _WIN32
-# define perftools_vsnprintf vsnprintf
-#endif
-
-
-// We log all messages at this log-level and below.
-// INFO == -1, WARNING == -2, ERROR == -3, FATAL == -4
-DECLARE_int32(verbose);
-
-// CHECK dies with a fatal error if condition is not true.  It is *not*
-// controlled by NDEBUG, so the check will be executed regardless of
-// compilation mode.  Therefore, it is safe to do things like:
-//    CHECK(fp->Write(x) == 4)
-// Note we use write instead of printf/puts to avoid the risk we'll
-// call malloc().
-#define CHECK(condition)                                                \
-  do {                                                                  \
-    if (!(condition)) {                                                 \
-      WRITE_TO_STDERR("Check failed: " #condition "\n",                 \
-                      sizeof("Check failed: " #condition "\n")-1);      \
-      tcmalloc::Abort();                                                \
-    }                                                                   \
-  } while (0)
-
-// This takes a message to print.  The name is historical.
-#define RAW_CHECK(condition, message)                                          \
-  do {                                                                         \
-    if (!(condition)) {                                                        \
-      WRITE_TO_STDERR("Check failed: " #condition ": " message "\n",           \
-                      sizeof("Check failed: " #condition ": " message "\n")-1);\
-      tcmalloc::Abort();                                                       \
-    }                                                                          \
-  } while (0)
-
-// This is like RAW_CHECK, but only in debug-mode
-#ifdef NDEBUG
-enum { DEBUG_MODE = 0 };
-#define RAW_DCHECK(condition, message)
-#else
-enum { DEBUG_MODE = 1 };
-#define RAW_DCHECK(condition, message)  RAW_CHECK(condition, message)
-#endif
-
-// This prints errno as well.  Note we use write instead of printf/puts to
-// avoid the risk we'll call malloc().
-#define PCHECK(condition)                                               \
-  do {                                                                  \
-    if (!(condition)) {                                                 \
-      const int err_no = errno;                                         \
-      WRITE_TO_STDERR("Check failed: " #condition ": ",                 \
-                      sizeof("Check failed: " #condition ": ")-1);      \
-      WRITE_TO_STDERR(strerror(err_no), strlen(strerror(err_no)));      \
-      WRITE_TO_STDERR("\n", sizeof("\n")-1);                            \
-      tcmalloc::Abort();                                                \
-    }                                                                   \
-  } while (0)
-
-// Helper macro for binary operators; prints the two values on error
-// Don't use this macro directly in your code, use CHECK_EQ et al below
-
-// WARNING: These don't compile correctly if one of the arguments is a pointer
-// and the other is NULL. To work around this, simply static_cast NULL to the
-// type of the desired pointer.
-
-// TODO(jandrews): Also print the values in case of failure.  Requires some
-// sort of type-sensitive ToString() function.
-#define CHECK_OP(op, val1, val2)                                        \
-  do {                                                                  \
-    if (!((val1) op (val2))) {                                          \
-      fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
-      tcmalloc::Abort();                                                \
-    }                                                                   \
-  } while (0)
-
-#define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
-#define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)
-#define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)
-#define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)
-#define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
-#define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
-
-// Synonyms for CHECK_* that are used in some unittests.
-#define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)
-#define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)
-#define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)
-#define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)
-#define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)
-#define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)
-#define ASSERT_EQ(val1, val2) EXPECT_EQ(val1, val2)
-#define ASSERT_NE(val1, val2) EXPECT_NE(val1, val2)
-#define ASSERT_LE(val1, val2) EXPECT_LE(val1, val2)
-#define ASSERT_LT(val1, val2) EXPECT_LT(val1, val2)
-#define ASSERT_GE(val1, val2) EXPECT_GE(val1, val2)
-#define ASSERT_GT(val1, val2) EXPECT_GT(val1, val2)
-// As are these variants.
-#define EXPECT_TRUE(cond)     CHECK(cond)
-#define EXPECT_FALSE(cond)    CHECK(!(cond))
-#define EXPECT_STREQ(a, b)    CHECK(strcmp(a, b) == 0)
-#define ASSERT_TRUE(cond)     EXPECT_TRUE(cond)
-#define ASSERT_FALSE(cond)    EXPECT_FALSE(cond)
-#define ASSERT_STREQ(a, b)    EXPECT_STREQ(a, b)
-
-// Used for (libc) functions that return -1 and set errno
-#define CHECK_ERR(invocation)  PCHECK((invocation) != -1)
-
-// A few more checks that only happen in debug mode
-#ifdef NDEBUG
-#define DCHECK_EQ(val1, val2)
-#define DCHECK_NE(val1, val2)
-#define DCHECK_LE(val1, val2)
-#define DCHECK_LT(val1, val2)
-#define DCHECK_GE(val1, val2)
-#define DCHECK_GT(val1, val2)
-#else
-#define DCHECK_EQ(val1, val2)  CHECK_EQ(val1, val2)
-#define DCHECK_NE(val1, val2)  CHECK_NE(val1, val2)
-#define DCHECK_LE(val1, val2)  CHECK_LE(val1, val2)
-#define DCHECK_LT(val1, val2)  CHECK_LT(val1, val2)
-#define DCHECK_GE(val1, val2)  CHECK_GE(val1, val2)
-#define DCHECK_GT(val1, val2)  CHECK_GT(val1, val2)
-#endif
-
-
-#ifdef ERROR
-#undef ERROR      // may conflict with ERROR macro on windows
-#endif
-enum LogSeverity {INFO = -1, WARNING = -2, ERROR = -3, FATAL = -4};
-
-// NOTE: we add a newline to the end of the output if it's not there already
-inline void LogPrintf(int severity, const char* pat, va_list ap) {
-  // We write directly to the stderr file descriptor and avoid FILE
-  // buffering because that may invoke malloc()
-  char buf[1600];
-  perftools_vsnprintf(buf, sizeof(buf)-1, pat, ap);
-  if (buf[0] != '\0' && buf[strlen(buf)-1] != '\n') {
-    assert(strlen(buf)+1 < sizeof(buf));
-    strcat(buf, "\n");
-  }
-  WRITE_TO_STDERR(buf, strlen(buf));
-  if ((severity) == FATAL) {
-    // LOG(FATAL) indicates a big problem, so don't run atexit() calls
-    tcmalloc::Abort();
-  }
-}
-
-// Note that since the order of global constructors is unspecified,
-// global code that calls RAW_LOG may execute before FLAGS_verbose is set.
-// Such code will run with verbosity == 0 no matter what.
-#define VLOG_IS_ON(severity) (FLAGS_verbose >= severity)
-
-// In a better world, we'd use __VA_ARGS__, but VC++ 7 doesn't support it.
-#define LOG_PRINTF(severity, pat) do {          \
-  if (VLOG_IS_ON(severity)) {                   \
-    va_list ap;                                 \
-    va_start(ap, pat);                          \
-    LogPrintf(severity, pat, ap);               \
-    va_end(ap);                                 \
-  }                                             \
-} while (0)
-
-// RAW_LOG is the main function; some synonyms are used in unittests.
-inline void RAW_LOG(int lvl, const char* pat, ...)  { LOG_PRINTF(lvl, pat); }
-inline void RAW_VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); }
-inline void LOG(int lvl, const char* pat, ...)      { LOG_PRINTF(lvl, pat); }
-inline void VLOG(int lvl, const char* pat, ...)     { LOG_PRINTF(lvl, pat); }
-inline void LOG_IF(int lvl, bool cond, const char* pat, ...) {
-  if (cond)  LOG_PRINTF(lvl, pat);
-}
-
-// This isn't technically logging, but it's also IO and also is an
-// attempt to be "raw" -- that is, to not use any higher-level libc
-// routines that might allocate memory or (ideally) try to allocate
-// locks.  We use an opaque file handle (not necessarily an int)
-// to allow even more low-level stuff in the future.
-// Like other "raw" routines, these functions are best effort, and
-// thus don't return error codes (except RawOpenForWriting()).
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-#ifndef NOMINMAX
-#define NOMINMAX     // @#!$& windows
-#endif
-#include <windows.h>
-typedef HANDLE RawFD;
-const RawFD kIllegalRawFD = INVALID_HANDLE_VALUE;
-#else
-typedef int RawFD;
-const RawFD kIllegalRawFD = -1;   // what open returns if it fails
-#endif  // defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-
-RawFD RawOpenForWriting(const char* filename);   // uses default permissions
-void RawWrite(RawFD fd, const char* buf, size_t len);
-void RawClose(RawFD fd);
-
-#endif // _LOGGING_H_
diff --git a/third_party/tcmalloc/chromium/src/base/low_level_alloc.cc b/third_party/tcmalloc/chromium/src/base/low_level_alloc.cc
deleted file mode 100644
index 346a793..0000000
--- a/third_party/tcmalloc/chromium/src/base/low_level_alloc.cc
+++ /dev/null
@@ -1,585 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// A low-level allocator that can be used by other low-level
-// modules without introducing dependency cycles.
-// This allocator is slow and wasteful of memory;
-// it should not be used when performance is key.
-
-#include "base/low_level_alloc.h"
-#include "base/dynamic_annotations.h"
-#include "base/spinlock.h"
-#include "base/logging.h"
-#include "malloc_hook-inl.h"
-#include <gperftools/malloc_hook.h>
-#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#include <new>                   // for placement-new
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-// A first-fit allocator with amortized logarithmic free() time.
-
-LowLevelAlloc::PagesAllocator::~PagesAllocator() {
-}
-
-// ---------------------------------------------------------------------------
-static const int kMaxLevel = 30;
-
-// We put this class-only struct in a namespace to avoid polluting the
-// global namespace with this struct name (thus risking an ODR violation).
-namespace low_level_alloc_internal {
-  // This struct describes one allocated block, or one free block.
-  struct AllocList {
-    struct Header {
-      intptr_t size;  // size of entire region, including this field. Must be
-                      // first.  Valid in both allocated and unallocated blocks
-      intptr_t magic; // kMagicAllocated or kMagicUnallocated xor this
-      LowLevelAlloc::Arena *arena; // pointer to parent arena
-      void *dummy_for_alignment;   // aligns regions to 0 mod 2*sizeof(void*)
-    } header;
-
-    // Next two fields: in unallocated blocks: freelist skiplist data
-    //                  in allocated blocks: overlaps with client data
-    int levels;           // levels in skiplist used
-    AllocList *next[kMaxLevel];   // actually has levels elements.
-                                  // The AllocList node may not have room for
-                                  // all kMaxLevel entries.  See max_fit in
-                                  // LLA_SkiplistLevels()
-  };
-}
-using low_level_alloc_internal::AllocList;
-
-
-// ---------------------------------------------------------------------------
-// A trivial skiplist implementation.  This is used to keep the freelist
-// in address order while taking only logarithmic time per insert and delete.
-
-// An integer approximation of log2(size/base)
-// Requires size >= base.
-static int IntLog2(size_t size, size_t base) {
-  int result = 0;
-  for (size_t i = size; i > base; i >>= 1) { // i == floor(size/2**result)
-    result++;
-  }
-  //    floor(size / 2**result) <= base < floor(size / 2**(result-1))
-  // =>     log2(size/(base+1)) <= result < 1+log2(size/base)
-  // => result ~= log2(size/base)
-  return result;
-}
-
-// Return a random integer n:  p(n)=1/(2**n) if 1 <= n; p(n)=0 if n < 1.
-static int Random() {
-  static uint32 r = 1;         // no locking---it's not critical
-  ANNOTATE_BENIGN_RACE(&r, "benign race, not critical.");
-  int result = 1;
-  while ((((r = r*1103515245 + 12345) >> 30) & 1) == 0) {
-    result++;
-  }
-  return result;
-}
-
-// Return a number of skiplist levels for a node of size bytes, where
-// base is the minimum node size.  Compute level=log2(size / base)+n
-// where n is 1 if random is false and otherwise a random number generated with
-// the standard distribution for a skiplist:  See Random() above.
-// Bigger nodes tend to have more skiplist levels due to the log2(size / base)
-// term, so first-fit searches touch fewer nodes.  "level" is clipped so
-// level<kMaxLevel and next[level-1] will fit in the node.
-// 0 < LLA_SkiplistLevels(x,y,false) <= LLA_SkiplistLevels(x,y,true) < kMaxLevel
-static int LLA_SkiplistLevels(size_t size, size_t base, bool random) {
-  // max_fit is the maximum number of levels that will fit in a node for the
-  // given size.   We can't return more than max_fit, no matter what the
-  // random number generator says.
-  int max_fit = (size-OFFSETOF_MEMBER(AllocList, next)) / sizeof (AllocList *);
-  int level = IntLog2(size, base) + (random? Random() : 1);
-  if (level > max_fit)     level = max_fit;
-  if (level > kMaxLevel-1) level = kMaxLevel - 1;
-  RAW_CHECK(level >= 1, "block not big enough for even one level");
-  return level;
-}
-
-// Return "atleast", the first element of AllocList *head s.t. *atleast >= *e.
-// For 0 <= i < head->levels, set prev[i] to "no_greater", where no_greater
-// points to the last element at level i in the AllocList less than *e, or is
-// head if no such element exists.
-static AllocList *LLA_SkiplistSearch(AllocList *head,
-                                     AllocList *e, AllocList **prev) {
-  AllocList *p = head;
-  for (int level = head->levels - 1; level >= 0; level--) {
-    for (AllocList *n; (n = p->next[level]) != 0 && n < e; p = n) {
-    }
-    prev[level] = p;
-  }
-  return (head->levels == 0) ?  0 : prev[0]->next[0];
-}
-
-// Insert element *e into AllocList *head.  Set prev[] as LLA_SkiplistSearch.
-// Requires that e->levels be previously set by the caller (using
-// LLA_SkiplistLevels())
-static void LLA_SkiplistInsert(AllocList *head, AllocList *e,
-                               AllocList **prev) {
-  LLA_SkiplistSearch(head, e, prev);
-  for (; head->levels < e->levels; head->levels++) { // extend prev pointers
-    prev[head->levels] = head;                       // to all *e's levels
-  }
-  for (int i = 0; i != e->levels; i++) { // add element to list
-    e->next[i] = prev[i]->next[i];
-    prev[i]->next[i] = e;
-  }
-}
-
-// Remove element *e from AllocList *head.  Set prev[] as LLA_SkiplistSearch().
-// Requires that e->levels be previous set by the caller (using
-// LLA_SkiplistLevels())
-static void LLA_SkiplistDelete(AllocList *head, AllocList *e,
-                               AllocList **prev) {
-  AllocList *found = LLA_SkiplistSearch(head, e, prev);
-  RAW_CHECK(e == found, "element not in freelist");
-  for (int i = 0; i != e->levels && prev[i]->next[i] == e; i++) {
-    prev[i]->next[i] = e->next[i];
-  }
-  while (head->levels > 0 && head->next[head->levels - 1] == 0) {
-    head->levels--;   // reduce head->levels if level unused
-  }
-}
-
-// ---------------------------------------------------------------------------
-// Arena implementation
-
-struct LowLevelAlloc::Arena {
-  Arena() : mu(SpinLock::LINKER_INITIALIZED) {} // does nothing; for static init
-  explicit Arena(int) : pagesize(0) {}  // set pagesize to zero explicitly
-                                        // for non-static init
-
-  SpinLock mu;            // protects freelist, allocation_count,
-                          // pagesize, roundup, min_size
-  AllocList freelist;     // head of free list; sorted by addr (under mu)
-  int32 allocation_count; // count of allocated blocks (under mu)
-  int32 flags;            // flags passed to NewArena (ro after init)
-  size_t pagesize;        // ==getpagesize()  (init under mu, then ro)
-  size_t roundup;         // lowest power of 2 >= max(16,sizeof (AllocList))
-                          // (init under mu, then ro)
-  size_t min_size;        // smallest allocation block size
-                          // (init under mu, then ro)
-  PagesAllocator *allocator;
-};
-
-// The default arena, which is used when 0 is passed instead of an Arena
-// pointer.
-static struct LowLevelAlloc::Arena default_arena;
-
-// Non-malloc-hooked arenas: used only to allocate metadata for arenas that
-// do not want malloc hook reporting, so that for them there's no malloc hook
-// reporting even during arena creation.
-static struct LowLevelAlloc::Arena unhooked_arena;
-static struct LowLevelAlloc::Arena unhooked_async_sig_safe_arena;
-
-namespace {
-
-  class DefaultPagesAllocator : public LowLevelAlloc::PagesAllocator {
-  public:
-    virtual ~DefaultPagesAllocator() {};
-    virtual void *MapPages(int32 flags, size_t size);
-    virtual void UnMapPages(int32 flags, void *addr, size_t size);
-  };
-
-}
-
-// magic numbers to identify allocated and unallocated blocks
-static const intptr_t kMagicAllocated = 0x4c833e95;
-static const intptr_t kMagicUnallocated = ~kMagicAllocated;
-
-namespace {
-  class SCOPED_LOCKABLE ArenaLock {
-   public:
-    explicit ArenaLock(LowLevelAlloc::Arena *arena)
-        EXCLUSIVE_LOCK_FUNCTION(arena->mu)
-        : left_(false), mask_valid_(false), arena_(arena) {
-      if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
-      // We've decided not to support async-signal-safe arena use until
-      // there a demonstrated need.  Here's how one could do it though
-      // (would need to be made more portable).
-#if 0
-        sigset_t all;
-        sigfillset(&all);
-        this->mask_valid_ =
-            (pthread_sigmask(SIG_BLOCK, &all, &this->mask_) == 0);
-#else
-        RAW_CHECK(false, "We do not yet support async-signal-safe arena.");
-#endif
-      }
-      this->arena_->mu.Lock();
-    }
-
-    ArenaLock(const ArenaLock&) = delete;
-    ArenaLock& operator=(const ArenaLock&) = delete;
-
-    ~ArenaLock() { RAW_CHECK(this->left_, "haven't left Arena region"); }
-    void Leave() UNLOCK_FUNCTION() {
-      this->arena_->mu.Unlock();
-#if 0
-      if (this->mask_valid_) {
-        pthread_sigmask(SIG_SETMASK, &this->mask_, 0);
-      }
-#endif
-      this->left_ = true;
-    }
-   private:
-    bool left_;       // whether left region
-    bool mask_valid_;
-#if 0
-    sigset_t mask_;   // old mask of blocked signals
-#endif
-    LowLevelAlloc::Arena *arena_;
-  };
-} // anonymous namespace
-
-// create an appropriate magic number for an object at "ptr"
-// "magic" should be kMagicAllocated or kMagicUnallocated
-inline static intptr_t Magic(intptr_t magic, AllocList::Header *ptr) {
-  return magic ^ reinterpret_cast<intptr_t>(ptr);
-}
-
-// Initialize the fields of an Arena
-static void ArenaInit(LowLevelAlloc::Arena *arena) {
-  if (arena->pagesize == 0) {
-    arena->pagesize = getpagesize();
-    // Round up block sizes to a power of two close to the header size.
-    arena->roundup = 16;
-    while (arena->roundup < sizeof (arena->freelist.header)) {
-      arena->roundup += arena->roundup;
-    }
-    // Don't allocate blocks less than twice the roundup size to avoid tiny
-    // free blocks.
-    arena->min_size = 2 * arena->roundup;
-    arena->freelist.header.size = 0;
-    arena->freelist.header.magic =
-        Magic(kMagicUnallocated, &arena->freelist.header);
-    arena->freelist.header.arena = arena;
-    arena->freelist.levels = 0;
-    memset(arena->freelist.next, 0, sizeof (arena->freelist.next));
-    arena->allocation_count = 0;
-    if (arena == &default_arena) {
-      // Default arena should be hooked, e.g. for heap-checker to trace
-      // pointer chains through objects in the default arena.
-      arena->flags = LowLevelAlloc::kCallMallocHook;
-    } else if (arena == &unhooked_async_sig_safe_arena) {
-      arena->flags = LowLevelAlloc::kAsyncSignalSafe;
-    } else {
-      arena->flags = 0;   // other arenas' flags may be overridden by client,
-                          // but unhooked_arena will have 0 in 'flags'.
-    }
-    arena->allocator = LowLevelAlloc::GetDefaultPagesAllocator();
-  }
-}
-
-// L < meta_data_arena->mu
-LowLevelAlloc::Arena *LowLevelAlloc::NewArena(int32 flags,
-                                              Arena *meta_data_arena) {
-  return NewArenaWithCustomAlloc(flags, meta_data_arena, NULL);
-}
-
-// L < meta_data_arena->mu
-LowLevelAlloc::Arena *LowLevelAlloc::NewArenaWithCustomAlloc(int32 flags,
-                                                             Arena *meta_data_arena,
-                                                             PagesAllocator *allocator) {
-  RAW_CHECK(meta_data_arena != 0, "must pass a valid arena");
-  if (meta_data_arena == &default_arena) {
-    if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
-      meta_data_arena = &unhooked_async_sig_safe_arena;
-    } else if ((flags & LowLevelAlloc::kCallMallocHook) == 0) {
-      meta_data_arena = &unhooked_arena;
-    }
-  }
-  // Arena(0) uses the constructor for non-static contexts
-  Arena *result =
-    new (AllocWithArena(sizeof (*result), meta_data_arena)) Arena(0);
-  ArenaInit(result);
-  result->flags = flags;
-  if (allocator) {
-    result->allocator = allocator;
-  }
-  return result;
-}
-
-// L < arena->mu, L < arena->arena->mu
-bool LowLevelAlloc::DeleteArena(Arena *arena) {
-  RAW_CHECK(arena != 0 && arena != &default_arena && arena != &unhooked_arena,
-            "may not delete default arena");
-  ArenaLock section(arena);
-  bool empty = (arena->allocation_count == 0);
-  section.Leave();
-  if (empty) {
-    while (arena->freelist.next[0] != 0) {
-      AllocList *region = arena->freelist.next[0];
-      size_t size = region->header.size;
-      arena->freelist.next[0] = region->next[0];
-      RAW_CHECK(region->header.magic ==
-                Magic(kMagicUnallocated, &region->header),
-                "bad magic number in DeleteArena()");
-      RAW_CHECK(region->header.arena == arena,
-                "bad arena pointer in DeleteArena()");
-      RAW_CHECK(size % arena->pagesize == 0,
-                "empty arena has non-page-aligned block size");
-      RAW_CHECK(reinterpret_cast<intptr_t>(region) % arena->pagesize == 0,
-                "empty arena has non-page-aligned block");
-      int munmap_result;
-      if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
-        munmap_result = munmap(region, size);
-      } else {
-        munmap_result = MallocHook::UnhookedMUnmap(region, size);
-      }
-      RAW_CHECK(munmap_result == 0,
-                "LowLevelAlloc::DeleteArena:  munmap failed address");
-    }
-    Free(arena);
-  }
-  return empty;
-}
-
-// ---------------------------------------------------------------------------
-
-// Return value rounded up to next multiple of align.
-// align must be a power of two.
-static intptr_t RoundUp(intptr_t addr, intptr_t align) {
-  return (addr + align - 1) & ~(align - 1);
-}
-
-// Equivalent to "return prev->next[i]" but with sanity checking
-// that the freelist is in the correct order, that it
-// consists of regions marked "unallocated", and that no two regions
-// are adjacent in memory (they should have been coalesced).
-// L < arena->mu
-static AllocList *Next(int i, AllocList *prev, LowLevelAlloc::Arena *arena) {
-  RAW_CHECK(i < prev->levels, "too few levels in Next()");
-  AllocList *next = prev->next[i];
-  if (next != 0) {
-    RAW_CHECK(next->header.magic == Magic(kMagicUnallocated, &next->header),
-              "bad magic number in Next()");
-    RAW_CHECK(next->header.arena == arena,
-              "bad arena pointer in Next()");
-    if (prev != &arena->freelist) {
-      RAW_CHECK(prev < next, "unordered freelist");
-      RAW_CHECK(reinterpret_cast<char *>(prev) + prev->header.size <
-                reinterpret_cast<char *>(next), "malformed freelist");
-    }
-  }
-  return next;
-}
-
-// Coalesce list item "a" with its successor if they are adjacent.
-static void Coalesce(AllocList *a) {
-  AllocList *n = a->next[0];
-  if (n != 0 && reinterpret_cast<char *>(a) + a->header.size ==
-                    reinterpret_cast<char *>(n)) {
-    LowLevelAlloc::Arena *arena = a->header.arena;
-    a->header.size += n->header.size;
-    n->header.magic = 0;
-    n->header.arena = 0;
-    AllocList *prev[kMaxLevel];
-    LLA_SkiplistDelete(&arena->freelist, n, prev);
-    LLA_SkiplistDelete(&arena->freelist, a, prev);
-    a->levels = LLA_SkiplistLevels(a->header.size, arena->min_size, true);
-    LLA_SkiplistInsert(&arena->freelist, a, prev);
-  }
-}
-
-// Adds block at location "v" to the free list
-// L >= arena->mu
-static void AddToFreelist(void *v, LowLevelAlloc::Arena *arena) {
-  AllocList *f = reinterpret_cast<AllocList *>(
-                        reinterpret_cast<char *>(v) - sizeof (f->header));
-  RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
-            "bad magic number in AddToFreelist()");
-  RAW_CHECK(f->header.arena == arena,
-            "bad arena pointer in AddToFreelist()");
-  f->levels = LLA_SkiplistLevels(f->header.size, arena->min_size, true);
-  AllocList *prev[kMaxLevel];
-  LLA_SkiplistInsert(&arena->freelist, f, prev);
-  f->header.magic = Magic(kMagicUnallocated, &f->header);
-  Coalesce(f);                  // maybe coalesce with successor
-  Coalesce(prev[0]);            // maybe coalesce with predecessor
-}
-
-// Frees storage allocated by LowLevelAlloc::Alloc().
-// L < arena->mu
-void LowLevelAlloc::Free(void *v) {
-  if (v != 0) {
-    AllocList *f = reinterpret_cast<AllocList *>(
-                        reinterpret_cast<char *>(v) - sizeof (f->header));
-    RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
-              "bad magic number in Free()");
-    LowLevelAlloc::Arena *arena = f->header.arena;
-    if ((arena->flags & kCallMallocHook) != 0) {
-      MallocHook::InvokeDeleteHook(v);
-    }
-    ArenaLock section(arena);
-    AddToFreelist(v, arena);
-    RAW_CHECK(arena->allocation_count > 0, "nothing in arena to free");
-    arena->allocation_count--;
-    section.Leave();
-  }
-}
-
-// allocates and returns a block of size bytes, to be freed with Free()
-// L < arena->mu
-static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
-  void *result = 0;
-  if (request != 0) {
-    AllocList *s;       // will point to region that satisfies request
-    ArenaLock section(arena);
-    ArenaInit(arena);
-    // round up with header
-    size_t req_rnd = RoundUp(request + sizeof (s->header), arena->roundup);
-    for (;;) {      // loop until we find a suitable region
-      // find the minimum levels that a block of this size must have
-      int i = LLA_SkiplistLevels(req_rnd, arena->min_size, false) - 1;
-      if (i < arena->freelist.levels) {   // potential blocks exist
-        AllocList *before = &arena->freelist;  // predecessor of s
-        while ((s = Next(i, before, arena)) != 0 && s->header.size < req_rnd) {
-          before = s;
-        }
-        if (s != 0) {       // we found a region
-          break;
-        }
-      }
-      // we unlock before mmap() both because mmap() may call a callback hook,
-      // and because it may be slow.
-      arena->mu.Unlock();
-      // mmap generous 64K chunks to decrease
-      // the chances/impact of fragmentation:
-      size_t new_pages_size = RoundUp(req_rnd, arena->pagesize * 16);
-      void *new_pages = arena->allocator->MapPages(arena->flags, new_pages_size);
-      arena->mu.Lock();
-      s = reinterpret_cast<AllocList *>(new_pages);
-      s->header.size = new_pages_size;
-      // Pretend the block is allocated; call AddToFreelist() to free it.
-      s->header.magic = Magic(kMagicAllocated, &s->header);
-      s->header.arena = arena;
-      AddToFreelist(&s->levels, arena);  // insert new region into free list
-    }
-    AllocList *prev[kMaxLevel];
-    LLA_SkiplistDelete(&arena->freelist, s, prev);    // remove from free list
-    // s points to the first free region that's big enough
-    if (req_rnd + arena->min_size <= s->header.size) {  // big enough to split
-      AllocList *n = reinterpret_cast<AllocList *>
-                        (req_rnd + reinterpret_cast<char *>(s));
-      n->header.size = s->header.size - req_rnd;
-      n->header.magic = Magic(kMagicAllocated, &n->header);
-      n->header.arena = arena;
-      s->header.size = req_rnd;
-      AddToFreelist(&n->levels, arena);
-    }
-    s->header.magic = Magic(kMagicAllocated, &s->header);
-    RAW_CHECK(s->header.arena == arena, "");
-    arena->allocation_count++;
-    section.Leave();
-    result = &s->levels;
-  }
-  ANNOTATE_NEW_MEMORY(result, request);
-  return result;
-}
-
-void *LowLevelAlloc::Alloc(size_t request) {
-  void *result = DoAllocWithArena(request, &default_arena);
-  if ((default_arena.flags & kCallMallocHook) != 0) {
-    // this call must be directly in the user-called allocator function
-    // for MallocHook::GetCallerStackTrace to work properly
-    MallocHook::InvokeNewHook(result, request);
-  }
-  return result;
-}
-
-void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) {
-  RAW_CHECK(arena != 0, "must pass a valid arena");
-  void *result = DoAllocWithArena(request, arena);
-  if ((arena->flags & kCallMallocHook) != 0) {
-    // this call must be directly in the user-called allocator function
-    // for MallocHook::GetCallerStackTrace to work properly
-    MallocHook::InvokeNewHook(result, request);
-  }
-  return result;
-}
-
-LowLevelAlloc::Arena *LowLevelAlloc::DefaultArena() {
-  return &default_arena;
-}
-
-static DefaultPagesAllocator *default_pages_allocator;
-static union {
-  char chars[sizeof(DefaultPagesAllocator)];
-  void *ptr;
-} debug_pages_allocator_space;
-
-LowLevelAlloc::PagesAllocator *LowLevelAlloc::GetDefaultPagesAllocator(void) {
-  if (default_pages_allocator) {
-    return default_pages_allocator;
-  }
-  default_pages_allocator = new (debug_pages_allocator_space.chars) DefaultPagesAllocator();
-  return default_pages_allocator;
-}
-
-void *DefaultPagesAllocator::MapPages(int32 flags, size_t size) {
-  void *new_pages;
-  if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
-    new_pages = MallocHook::UnhookedMMap(0, size,
-                                         PROT_WRITE|PROT_READ,
-                                         MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
-  } else {
-    new_pages = mmap(0, size,
-                     PROT_WRITE|PROT_READ,
-                     MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
-  }
-  RAW_CHECK(new_pages != MAP_FAILED, "mmap error");
-
-  return new_pages;
-}
-
-void DefaultPagesAllocator::UnMapPages(int32 flags, void *region, size_t size) {
-  int munmap_result;
-  if ((flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
-    munmap_result = munmap(region, size);
-  } else {
-    munmap_result = MallocHook::UnhookedMUnmap(region, size);
-  }
-  RAW_CHECK(munmap_result == 0,
-            "LowLevelAlloc::DeleteArena: munmap failed address");
-}
diff --git a/third_party/tcmalloc/chromium/src/base/low_level_alloc.h b/third_party/tcmalloc/chromium/src/base/low_level_alloc.h
deleted file mode 100644
index d8dfc8f..0000000
--- a/third_party/tcmalloc/chromium/src/base/low_level_alloc.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if !defined(_BASE_LOW_LEVEL_ALLOC_H_)
-#define _BASE_LOW_LEVEL_ALLOC_H_
-
-// A simple thread-safe memory allocator that does not depend on
-// mutexes or thread-specific data.  It is intended to be used
-// sparingly, and only when malloc() would introduce an unwanted
-// dependency, such as inside the heap-checker.
-
-#include <config.h>
-#include <stddef.h>             // for size_t
-#include "base/basictypes.h"
-
-class LowLevelAlloc {
- public:
-  class PagesAllocator {
-  public:
-    virtual ~PagesAllocator();
-    virtual void *MapPages(int32 flags, size_t size) = 0;
-    virtual void UnMapPages(int32 flags, void *addr, size_t size) = 0;
-  };
-
-  static PagesAllocator *GetDefaultPagesAllocator(void);
-
-  struct Arena;       // an arena from which memory may be allocated
-
-  // Returns a pointer to a block of at least "request" bytes
-  // that have been newly allocated from the specific arena.
-  // for Alloc() call the DefaultArena() is used.
-  // Returns 0 if passed request==0.
-  // Does not return 0 under other circumstances; it crashes if memory
-  // is not available.
-  static void *Alloc(size_t request)
-    ATTRIBUTE_SECTION(malloc_hook);
-  static void *AllocWithArena(size_t request, Arena *arena)
-    ATTRIBUTE_SECTION(malloc_hook);
-
-  // Deallocates a region of memory that was previously allocated with
-  // Alloc().   Does nothing if passed 0.   "s" must be either 0,
-  // or must have been returned from a call to Alloc() and not yet passed to
-  // Free() since that call to Alloc().  The space is returned to the arena
-  // from which it was allocated.
-  static void Free(void *s) ATTRIBUTE_SECTION(malloc_hook);
-
-    // ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free
-    // are to put all callers of MallocHook::Invoke* in this module
-    // into special section,
-    // so that MallocHook::GetCallerStackTrace can function accurately.
-
-  // Create a new arena.
-  // The root metadata for the new arena is allocated in the
-  // meta_data_arena; the DefaultArena() can be passed for meta_data_arena.
-  // These values may be ored into flags:
-  enum {
-    // Report calls to Alloc() and Free() via the MallocHook interface.
-    // Set in the DefaultArena.
-    kCallMallocHook = 0x0001,
-
-    // Make calls to Alloc(), Free() be async-signal-safe.  Not set in
-    // DefaultArena().
-    kAsyncSignalSafe = 0x0002,
-
-    // When used with DefaultArena(), the NewArena() and DeleteArena() calls
-    // obey the flags given explicitly in the NewArena() call, even if those
-    // flags differ from the settings in DefaultArena().  So the call
-    // NewArena(kAsyncSignalSafe, DefaultArena()) is itself async-signal-safe,
-    // as well as generatating an arena that provides async-signal-safe
-    // Alloc/Free.
-  };
-  static Arena *NewArena(int32 flags, Arena *meta_data_arena);
-
-  // note: pages allocator will never be destroyed and allocated pages will never be freed
-  // When allocator is NULL, it's same as NewArena
-  static Arena *NewArenaWithCustomAlloc(int32 flags, Arena *meta_data_arena, PagesAllocator *allocator);
-
-  // Destroys an arena allocated by NewArena and returns true,
-  // provided no allocated blocks remain in the arena.
-  // If allocated blocks remain in the arena, does nothing and
-  // returns false.
-  // It is illegal to attempt to destroy the DefaultArena().
-  static bool DeleteArena(Arena *arena);
-
-  // The default arena that always exists.
-  static Arena *DefaultArena();
-
- private:
-  LowLevelAlloc();      // no instances
-};
-
-#endif
diff --git a/third_party/tcmalloc/chromium/src/base/simple_mutex.h b/third_party/tcmalloc/chromium/src/base/simple_mutex.h
deleted file mode 100644
index fe06f7e1..0000000
--- a/third_party/tcmalloc/chromium/src/base/simple_mutex.h
+++ /dev/null
@@ -1,332 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-// ---
-// Author: Craig Silverstein.
-//
-// A simple mutex wrapper, supporting locks and read-write locks.
-// You should assume the locks are *not* re-entrant.
-//
-// To use: you should define the following macros in your configure.ac:
-//   ACX_PTHREAD
-//   AC_RWLOCK
-// The latter is defined in ../autoconf.
-//
-// This class is meant to be internal-only and should be wrapped by an
-// internal namespace.  Before you use this module, please give the
-// name of your internal namespace for this module.  Or, if you want
-// to expose it, you'll want to move it to the Google namespace.  We
-// cannot put this class in global namespace because there can be some
-// problems when we have multiple versions of Mutex in each shared object.
-//
-// NOTE: TryLock() is broken for NO_THREADS mode, at least in NDEBUG
-//       mode.
-//
-// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy:
-//    http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html
-// Because of that, we might as well use windows locks for
-// cygwin.  They seem to be more reliable than the cygwin pthreads layer.
-//
-// TRICKY IMPLEMENTATION NOTE:
-// This class is designed to be safe to use during
-// dynamic-initialization -- that is, by global constructors that are
-// run before main() starts.  The issue in this case is that
-// dynamic-initialization happens in an unpredictable order, and it
-// could be that someone else's dynamic initializer could call a
-// function that tries to acquire this mutex -- but that all happens
-// before this mutex's constructor has run.  (This can happen even if
-// the mutex and the function that uses the mutex are in the same .cc
-// file.)  Basically, because Mutex does non-trivial work in its
-// constructor, it's not, in the naive implementation, safe to use
-// before dynamic initialization has run on it.
-//
-// The solution used here is to pair the actual mutex primitive with a
-// bool that is set to true when the mutex is dynamically initialized.
-// (Before that it's false.)  Then we modify all mutex routines to
-// look at the bool, and not try to lock/unlock until the bool makes
-// it to true (which happens after the Mutex constructor has run.)
-//
-// This works because before main() starts -- particularly, during
-// dynamic initialization -- there are no threads, so a) it's ok that
-// the mutex operations are a no-op, since we don't need locking then
-// anyway; and b) we can be quite confident our bool won't change
-// state between a call to Lock() and a call to Unlock() (that would
-// require a global constructor in one translation unit to call Lock()
-// and another global constructor in another translation unit to call
-// Unlock() later, which is pretty perverse).
-//
-// That said, it's tricky, and can conceivably fail; it's safest to
-// avoid trying to acquire a mutex in a global constructor, if you
-// can.  One way it can fail is that a really smart compiler might
-// initialize the bool to true at static-initialization time (too
-// early) rather than at dynamic-initialization time.  To discourage
-// that, we set is_safe_ to true in code (not the constructor
-// colon-initializer) and set it to true via a function that always
-// evaluates to true, but that the compiler can't know always
-// evaluates to true.  This should be good enough.
-//
-// A related issue is code that could try to access the mutex
-// after it's been destroyed in the global destructors (because
-// the Mutex global destructor runs before some other global
-// destructor, that tries to acquire the mutex).  The way we
-// deal with this is by taking a constructor arg that global
-// mutexes should pass in, that causes the destructor to do no
-// work.  We still depend on the compiler not doing anything
-// weird to a Mutex's memory after it is destroyed, but for a
-// static global variable, that's pretty safe.
-
-#ifndef GOOGLE_MUTEX_H_
-#define GOOGLE_MUTEX_H_
-
-#include <config.h>
-
-#if defined(NO_THREADS)
-  typedef int MutexType;      // to keep a lock-count
-#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-# ifndef WIN32_LEAN_AND_MEAN
-#   define WIN32_LEAN_AND_MEAN  // We only need minimal includes
-# endif
-  // We need Windows NT or later for TryEnterCriticalSection().  If you
-  // don't need that functionality, you can remove these _WIN32_WINNT
-  // lines, and change TryLock() to assert(0) or something.
-# ifndef _WIN32_WINNT
-#   define _WIN32_WINNT 0x0400
-# endif
-# include <windows.h>
-  typedef CRITICAL_SECTION MutexType;
-#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
-  // Needed for pthread_rwlock_*.  If it causes problems, you could take it
-  // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it
-  // *does* cause problems for FreeBSD, or MacOSX, but isn't needed
-  // for locking there.)
-# ifdef __linux__
-#   define _XOPEN_SOURCE 500  // may be needed to get the rwlock calls
-# endif
-# include <pthread.h>
-  typedef pthread_rwlock_t MutexType;
-#elif defined(HAVE_PTHREAD)
-# include <pthread.h>
-  typedef pthread_mutex_t MutexType;
-#else
-# error Need to implement mutex.h for your architecture, or #define NO_THREADS
-#endif
-
-#include <assert.h>
-#include "base/abort.h"
-
-#define MUTEX_NAMESPACE perftools_mutex_namespace
-
-namespace MUTEX_NAMESPACE {
-
-class Mutex {
- public:
-  // This is used for the single-arg constructor
-  enum LinkerInitialized { LINKER_INITIALIZED };
-
-  // Create a Mutex that is not held by anybody.  This constructor is
-  // typically used for Mutexes allocated on the heap or the stack.
-  inline Mutex();
-  // This constructor should be used for global, static Mutex objects.
-  // It inhibits work being done by the destructor, which makes it
-  // safer for code that tries to acqiure this mutex in their global
-  // destructor.
-  inline Mutex(LinkerInitialized);
-
-  // Destructor
-  inline ~Mutex();
-
-  inline void Lock();    // Block if needed until free then acquire exclusively
-  inline void Unlock();  // Release a lock acquired via Lock()
-  inline bool TryLock(); // If free, Lock() and return true, else return false
-  // Note that on systems that don't support read-write locks, these may
-  // be implemented as synonyms to Lock() and Unlock().  So you can use
-  // these for efficiency, but don't use them anyplace where being able
-  // to do shared reads is necessary to avoid deadlock.
-  inline void ReaderLock();   // Block until free or shared then acquire a share
-  inline void ReaderUnlock(); // Release a read share of this Mutex
-  inline void WriterLock() { Lock(); }     // Acquire an exclusive lock
-  inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
-
- private:
-  MutexType mutex_;
-  // We want to make sure that the compiler sets is_safe_ to true only
-  // when we tell it to, and never makes assumptions is_safe_ is
-  // always true.  volatile is the most reliable way to do that.
-  volatile bool is_safe_;
-  // This indicates which constructor was called.
-  bool destroy_;
-
-  inline void SetIsSafe() { is_safe_ = true; }
-
-  // Catch the error of writing Mutex when intending MutexLock.
-  Mutex(Mutex* /*ignored*/) {}
-  // Disallow "evil" constructors
-  Mutex(const Mutex&);
-  void operator=(const Mutex&);
-};
-
-// Now the implementation of Mutex for various systems
-#if defined(NO_THREADS)
-
-// When we don't have threads, we can be either reading or writing,
-// but not both.  We can have lots of readers at once (in no-threads
-// mode, that's most likely to happen in recursive function calls),
-// but only one writer.  We represent this by having mutex_ be -1 when
-// writing and a number > 0 when reading (and 0 when no lock is held).
-//
-// In debug mode, we assert these invariants, while in non-debug mode
-// we do nothing, for efficiency.  That's why everything is in an
-// assert.
-
-Mutex::Mutex() : mutex_(0) { }
-Mutex::Mutex(Mutex::LinkerInitialized) : mutex_(0) { }
-Mutex::~Mutex()            { assert(mutex_ == 0); }
-void Mutex::Lock()         { assert(--mutex_ == -1); }
-void Mutex::Unlock()       { assert(mutex_++ == -1); }
-bool Mutex::TryLock()      { if (mutex_) return false; Lock(); return true; }
-void Mutex::ReaderLock()   { assert(++mutex_ > 0); }
-void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
-
-#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-
-Mutex::Mutex() : destroy_(true) {
-  InitializeCriticalSection(&mutex_);
-  SetIsSafe();
-}
-Mutex::Mutex(LinkerInitialized) : destroy_(false) {
-  InitializeCriticalSection(&mutex_);
-  SetIsSafe();
-}
-Mutex::~Mutex()            { if (destroy_) DeleteCriticalSection(&mutex_); }
-void Mutex::Lock()         { if (is_safe_) EnterCriticalSection(&mutex_); }
-void Mutex::Unlock()       { if (is_safe_) LeaveCriticalSection(&mutex_); }
-bool Mutex::TryLock()      { return is_safe_ ?
-                                 TryEnterCriticalSection(&mutex_) != 0 : true; }
-void Mutex::ReaderLock()   { Lock(); }      // we don't have read-write locks
-void Mutex::ReaderUnlock() { Unlock(); }
-
-#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
-
-#define SAFE_PTHREAD(fncall)  do {   /* run fncall if is_safe_ is true */  \
-  if (is_safe_ && fncall(&mutex_) != 0) tcmalloc::Abort();                 \
-} while (0)
-
-Mutex::Mutex() : destroy_(true) {
-  SetIsSafe();
-  if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) tcmalloc::Abort();
-}
-Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
-  SetIsSafe();
-  if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) tcmalloc::Abort();
-}
-Mutex::~Mutex()       { if (destroy_) SAFE_PTHREAD(pthread_rwlock_destroy); }
-void Mutex::Lock()         { SAFE_PTHREAD(pthread_rwlock_wrlock); }
-void Mutex::Unlock()       { SAFE_PTHREAD(pthread_rwlock_unlock); }
-bool Mutex::TryLock()      { return is_safe_ ?
-                               pthread_rwlock_trywrlock(&mutex_) == 0 : true; }
-void Mutex::ReaderLock()   { SAFE_PTHREAD(pthread_rwlock_rdlock); }
-void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
-#undef SAFE_PTHREAD
-
-#elif defined(HAVE_PTHREAD)
-
-#define SAFE_PTHREAD(fncall)  do {   /* run fncall if is_safe_ is true */  \
-  if (is_safe_ && fncall(&mutex_) != 0) tcmalloc::Abort();                 \
-} while (0)
-
-Mutex::Mutex() : destroy_(true) {
-  SetIsSafe();
-  if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) tcmalloc::Abort();
-}
-Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
-  SetIsSafe();
-  if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) tcmalloc::Abort();
-}
-Mutex::~Mutex()       { if (destroy_) SAFE_PTHREAD(pthread_mutex_destroy); }
-void Mutex::Lock()         { SAFE_PTHREAD(pthread_mutex_lock); }
-void Mutex::Unlock()       { SAFE_PTHREAD(pthread_mutex_unlock); }
-bool Mutex::TryLock()      { return is_safe_ ?
-                                 pthread_mutex_trylock(&mutex_) == 0 : true; }
-void Mutex::ReaderLock()   { Lock(); }
-void Mutex::ReaderUnlock() { Unlock(); }
-#undef SAFE_PTHREAD
-
-#endif
-
-// --------------------------------------------------------------------------
-// Some helper classes
-
-// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
-class MutexLock {
- public:
-  explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
-  ~MutexLock() { mu_->Unlock(); }
- private:
-  Mutex * const mu_;
-  // Disallow "evil" constructors
-  MutexLock(const MutexLock&);
-  void operator=(const MutexLock&);
-};
-
-// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
-class ReaderMutexLock {
- public:
-  explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
-  ~ReaderMutexLock() { mu_->ReaderUnlock(); }
- private:
-  Mutex * const mu_;
-  // Disallow "evil" constructors
-  ReaderMutexLock(const ReaderMutexLock&);
-  void operator=(const ReaderMutexLock&);
-};
-
-class WriterMutexLock {
- public:
-  explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
-  ~WriterMutexLock() { mu_->WriterUnlock(); }
- private:
-  Mutex * const mu_;
-  // Disallow "evil" constructors
-  WriterMutexLock(const WriterMutexLock&);
-  void operator=(const WriterMutexLock&);
-};
-
-// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
-#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
-#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)
-#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)
-
-}  // namespace MUTEX_NAMESPACE
-
-using namespace MUTEX_NAMESPACE;
-
-#undef MUTEX_NAMESPACE
-
-#endif  /* #define GOOGLE_SIMPLE_MUTEX_H_ */
diff --git a/third_party/tcmalloc/chromium/src/base/spinlock.cc b/third_party/tcmalloc/chromium/src/base/spinlock.cc
deleted file mode 100644
index 85ff21ed..0000000
--- a/third_party/tcmalloc/chromium/src/base/spinlock.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-#include <config.h>
-#include "base/spinlock.h"
-#include "base/spinlock_internal.h"
-#include "base/sysinfo.h"   /* for GetSystemCPUsCount() */
-
-// NOTE on the Lock-state values:
-//
-// kSpinLockFree represents the unlocked state
-// kSpinLockHeld represents the locked state with no waiters
-// kSpinLockSleeper represents the locked state with waiters
-
-static int adaptive_spin_count = 0;
-
-const base::LinkerInitialized SpinLock::LINKER_INITIALIZED =
-    base::LINKER_INITIALIZED;
-
-namespace {
-struct SpinLock_InitHelper {
-  SpinLock_InitHelper() {
-    // On multi-cpu machines, spin for longer before yielding
-    // the processor or sleeping.  Reduces idle time significantly.
-    if (GetSystemCPUsCount() > 1) {
-      adaptive_spin_count = 1000;
-    }
-  }
-};
-
-// Hook into global constructor execution:
-// We do not do adaptive spinning before that,
-// but nothing lock-intensive should be going on at that time.
-static SpinLock_InitHelper init_helper;
-
-inline void SpinlockPause(void) {
-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-  __asm__ __volatile__("rep; nop" : : );
-#endif
-}
-
-}  // unnamed namespace
-
-// Monitor the lock to see if its value changes within some time
-// period (adaptive_spin_count loop iterations). The last value read
-// from the lock is returned from the method.
-Atomic32 SpinLock::SpinLoop() {
-  int c = adaptive_spin_count;
-  while (base::subtle::NoBarrier_Load(&lockword_) != kSpinLockFree && --c > 0) {
-    SpinlockPause();
-  }
-  return base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                              kSpinLockSleeper);
-}
-
-void SpinLock::SlowLock() {
-  Atomic32 lock_value = SpinLoop();
-
-  int lock_wait_call_count = 0;
-  while (lock_value != kSpinLockFree) {
-    // If the lock is currently held, but not marked as having a sleeper, mark
-    // it as having a sleeper.
-    if (lock_value == kSpinLockHeld) {
-      // Here, just "mark" that the thread is going to sleep.  Don't store the
-      // lock wait time in the lock as that will cause the current lock
-      // owner to think it experienced contention.
-      lock_value = base::subtle::Acquire_CompareAndSwap(&lockword_,
-                                                        kSpinLockHeld,
-                                                        kSpinLockSleeper);
-      if (lock_value == kSpinLockHeld) {
-        // Successfully transitioned to kSpinLockSleeper.  Pass
-        // kSpinLockSleeper to the SpinLockDelay routine to properly indicate
-        // the last lock_value observed.
-        lock_value = kSpinLockSleeper;
-      } else if (lock_value == kSpinLockFree) {
-        // Lock is free again, so try and acquire it before sleeping.  The
-        // new lock state will be the number of cycles this thread waited if
-        // this thread obtains the lock.
-        lock_value = base::subtle::Acquire_CompareAndSwap(&lockword_,
-                                                          kSpinLockFree,
-                                                          kSpinLockSleeper);
-        continue;  // skip the delay at the end of the loop
-      }
-    }
-
-    // Wait for an OS specific delay.
-    base::internal::SpinLockDelay(&lockword_, lock_value,
-                                  ++lock_wait_call_count);
-    // Spin again after returning from the wait routine to give this thread
-    // some chance of obtaining the lock.
-    lock_value = SpinLoop();
-  }
-}
-
-void SpinLock::SlowUnlock() {
-  // wake waiter if necessary
-  base::internal::SpinLockWake(&lockword_, false);
-}
diff --git a/third_party/tcmalloc/chromium/src/base/spinlock.h b/third_party/tcmalloc/chromium/src/base/spinlock.h
deleted file mode 100644
index 411f262..0000000
--- a/third_party/tcmalloc/chromium/src/base/spinlock.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-// SpinLock is async signal safe.
-// If used within a signal handler, all lock holders
-// should block the signal even outside the signal handler.
-
-#ifndef BASE_SPINLOCK_H_
-#define BASE_SPINLOCK_H_
-
-#include <config.h>
-#include "base/atomicops.h"
-#include "base/basictypes.h"
-#include "base/dynamic_annotations.h"
-#include "base/thread_annotations.h"
-
-class LOCKABLE SpinLock {
- public:
-  SpinLock() : lockword_(kSpinLockFree) { }
-
-  SpinLock(const SpinLock&) = delete;
-  SpinLock& operator=(const SpinLock&) = delete;
-
-  // Special constructor for use with static SpinLock objects.  E.g.,
-  //
-  //    static SpinLock lock(base::LINKER_INITIALIZED);
-  //
-  // When intialized using this constructor, we depend on the fact
-  // that the linker has already initialized the memory appropriately.
-  // A SpinLock constructed like this can be freely used from global
-  // initializers without worrying about the order in which global
-  // initializers run.
-  explicit SpinLock(base::LinkerInitialized /*x*/) {
-    // Does nothing; lockword_ is already initialized
-  }
-
-  // Acquire this SpinLock.
-  inline void Lock() EXCLUSIVE_LOCK_FUNCTION() {
-    if (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                             kSpinLockHeld) != kSpinLockFree) {
-      SlowLock();
-    }
-    ANNOTATE_RWLOCK_ACQUIRED(this, 1);
-  }
-
-  // Try to acquire this SpinLock without blocking and return true if the
-  // acquisition was successful.  If the lock was not acquired, false is
-  // returned.  If this SpinLock is free at the time of the call, TryLock
-  // will return true with high probability.
-  inline bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) {
-    bool res =
-        (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                              kSpinLockHeld) == kSpinLockFree);
-    if (res) {
-      ANNOTATE_RWLOCK_ACQUIRED(this, 1);
-    }
-    return res;
-  }
-
-  // Release this SpinLock, which must be held by the calling thread.
-  inline void Unlock() UNLOCK_FUNCTION() {
-    ANNOTATE_RWLOCK_RELEASED(this, 1);
-    uint64 prev_value = static_cast<uint64>(
-        base::subtle::Release_AtomicExchange(&lockword_, kSpinLockFree));
-    if (prev_value != kSpinLockHeld) {
-      // Speed the wakeup of any waiter.
-      SlowUnlock();
-    }
-  }
-
-  // Determine if the lock is held.  When the lock is held by the invoking
-  // thread, true will always be returned. Intended to be used as
-  // CHECK(lock.IsHeld()).
-  inline bool IsHeld() const {
-    return base::subtle::NoBarrier_Load(&lockword_) != kSpinLockFree;
-  }
-
-  static const base::LinkerInitialized LINKER_INITIALIZED;  // backwards compat
- private:
-  enum { kSpinLockFree = 0 };
-  enum { kSpinLockHeld = 1 };
-  enum { kSpinLockSleeper = 2 };
-
-  volatile Atomic32 lockword_;
-
-  void SlowLock();
-  void SlowUnlock();
-  Atomic32 SpinLoop();
-};
-
-// Corresponding locker object that arranges to acquire a spinlock for
-// the duration of a C++ scope.
-class SCOPED_LOCKABLE SpinLockHolder {
- private:
-  SpinLock* lock_;
- public:
-  inline explicit SpinLockHolder(SpinLock* l) EXCLUSIVE_LOCK_FUNCTION(l)
-      : lock_(l) {
-    l->Lock();
-  }
-  inline ~SpinLockHolder() UNLOCK_FUNCTION() { lock_->Unlock(); }
-};
-// Catch bug where variable name is omitted, e.g. SpinLockHolder (&lock);
-#define SpinLockHolder(x) COMPILE_ASSERT(0, spin_lock_decl_missing_var_name)
-
-
-#endif  // BASE_SPINLOCK_H_
diff --git a/third_party/tcmalloc/chromium/src/base/spinlock_internal.cc b/third_party/tcmalloc/chromium/src/base/spinlock_internal.cc
deleted file mode 100644
index d962971..0000000
--- a/third_party/tcmalloc/chromium/src/base/spinlock_internal.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2010, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// The OS-specific header included below must provide two calls:
-// base::internal::SpinLockDelay() and base::internal::SpinLockWake().
-// See spinlock_internal.h for the spec of SpinLockWake().
-
-// void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop)
-// SpinLockDelay() generates an apprproate spin delay on iteration "loop" of a
-// spin loop on location *w, whose previously observed value was "value".
-// SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick,
-// or may wait for a delay that can be truncated by a call to SpinlockWake(w).
-// In all cases, it must return in bounded time even if SpinlockWake() is not
-// called.
-
-#include "base/spinlock_internal.h"
-
-// forward declaration for use by spinlock_*-inl.h
-namespace base { namespace internal { static int SuggestedDelayNS(int loop); }}
-
-#if defined(_WIN32)
-#include "base/spinlock_win32-inl.h"
-#elif defined(__linux__)
-#include "base/spinlock_linux-inl.h"
-#else
-#include "base/spinlock_posix-inl.h"
-#endif
-
-namespace base {
-namespace internal {
-
-// Return a suggested delay in nanoseconds for iteration number "loop"
-static int SuggestedDelayNS(int loop) {
-  // Weak pseudo-random number generator to get some spread between threads
-  // when many are spinning.
-#ifdef BASE_HAS_ATOMIC64
-  static base::subtle::Atomic64 rand;
-  uint64 r = base::subtle::NoBarrier_Load(&rand);
-  r = 0x5deece66dLL * r + 0xb;   // numbers from nrand48()
-  base::subtle::NoBarrier_Store(&rand, r);
-
-  r <<= 16;   // 48-bit random number now in top 48-bits.
-  if (loop < 0 || loop > 32) {   // limit loop to 0..32
-    loop = 32;
-  }
-  // loop>>3 cannot exceed 4 because loop cannot exceed 32.
-  // Select top 20..24 bits of lower 48 bits,
-  // giving approximately 0ms to 16ms.
-  // Mean is exponential in loop for first 32 iterations, then 8ms.
-  // The futex path multiplies this by 16, since we expect explicit wakeups
-  // almost always on that path.
-  return r >> (44 - (loop >> 3));
-#else
-  static Atomic32 rand;
-  uint32 r = base::subtle::NoBarrier_Load(&rand);
-  r = 0x343fd * r + 0x269ec3;   // numbers from MSVC++
-  base::subtle::NoBarrier_Store(&rand, r);
-
-  r <<= 1;   // 31-bit random number now in top 31-bits.
-  if (loop < 0 || loop > 32) {   // limit loop to 0..32
-    loop = 32;
-  }
-  // loop>>3 cannot exceed 4 because loop cannot exceed 32.
-  // Select top 20..24 bits of lower 31 bits,
-  // giving approximately 0ms to 16ms.
-  // Mean is exponential in loop for first 32 iterations, then 8ms.
-  // The futex path multiplies this by 16, since we expect explicit wakeups
-  // almost always on that path.
-  return r >> (12 - (loop >> 3));
-#endif
-}
-
-} // namespace internal
-} // namespace base
diff --git a/third_party/tcmalloc/chromium/src/base/spinlock_internal.h b/third_party/tcmalloc/chromium/src/base/spinlock_internal.h
deleted file mode 100644
index aa47e67d..0000000
--- a/third_party/tcmalloc/chromium/src/base/spinlock_internal.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2010, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This file is an internal part spinlock.cc and once.cc
- * It may not be used directly by code outside of //base.
- */
-
-#ifndef BASE_SPINLOCK_INTERNAL_H_
-#define BASE_SPINLOCK_INTERNAL_H_
-
-#include <config.h>
-#include "base/basictypes.h"
-#include "base/atomicops.h"
-
-namespace base {
-namespace internal {
-
-void SpinLockWake(volatile Atomic32 *w, bool all);
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop);
-
-} // namespace internal
-} // namespace base
-#endif
diff --git a/third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h b/third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h
deleted file mode 100644
index ece8477b..0000000
--- a/third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This file is a Linux-specific part of spinlock_internal.cc
- */
-
-#include <errno.h>
-#include <sched.h>
-#include <time.h>
-#include <limits.h>
-#include "base/linux_syscall_support.h"
-
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-#define FUTEX_PRIVATE_FLAG 128
-
-// Note: Instead of making direct system calls that are inlined, we rely
-//       on the syscall() function in glibc to do the right thing. This
-//       is necessary to make the code compatible with the seccomp sandbox,
-//       which needs to be able to find and patch all places where system
-//       calls are made. Scanning through and patching glibc is fast, but
-//       doing so on the entire Chrome binary would be prohibitively
-//       expensive.
-//       This is a notable change from the upstream version of tcmalloc,
-//       which prefers direct system calls in order to improve compatibility
-//       with older toolchains and runtime libraries.
-
-namespace base {
-namespace internal {
-
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
-  if (loop != 0) {
-    int save_errno = errno;
-    struct timespec tm;
-    tm.tv_sec = 0;
-    tm.tv_nsec = base::internal::SuggestedDelayNS(loop);
-    tm.tv_nsec *= 16;  // increase the delay; we expect explicit wakeups
-    syscall(__NR_futex, reinterpret_cast<int*>(const_cast<Atomic32*>(w)),
-            FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value,
-            reinterpret_cast<struct kernel_timespec*>(&tm), NULL, 0);
-    errno = save_errno;
-  }
-}
-
-void SpinLockWake(volatile Atomic32 *w, bool all) {
-  syscall(__NR_futex, reinterpret_cast<int*>(const_cast<Atomic32*>(w)),
-          FUTEX_WAKE | FUTEX_PRIVATE_FLAG, all ? INT_MAX : 1, NULL, NULL, 0);
-}
-
-} // namespace internal
-} // namespace base
diff --git a/third_party/tcmalloc/chromium/src/base/spinlock_posix-inl.h b/third_party/tcmalloc/chromium/src/base/spinlock_posix-inl.h
deleted file mode 100644
index e73a30fb..0000000
--- a/third_party/tcmalloc/chromium/src/base/spinlock_posix-inl.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This file is a Posix-specific part of spinlock_internal.cc
- */
-
-#include <config.h>
-#include <errno.h>
-#ifdef HAVE_SCHED_H
-#include <sched.h>      /* For sched_yield() */
-#endif
-#include <time.h>       /* For nanosleep() */
-
-namespace base {
-namespace internal {
-
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
-  int save_errno = errno;
-  if (loop == 0) {
-  } else if (loop == 1) {
-    sched_yield();
-  } else {
-    struct timespec tm;
-    tm.tv_sec = 0;
-    tm.tv_nsec = base::internal::SuggestedDelayNS(loop);
-    nanosleep(&tm, NULL);
-  }
-  errno = save_errno;
-}
-
-void SpinLockWake(volatile Atomic32 *w, bool all) {
-}
-
-} // namespace internal
-} // namespace base
diff --git a/third_party/tcmalloc/chromium/src/base/spinlock_win32-inl.h b/third_party/tcmalloc/chromium/src/base/spinlock_win32-inl.h
deleted file mode 100644
index 956b9653..0000000
--- a/third_party/tcmalloc/chromium/src/base/spinlock_win32-inl.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This file is a Win32-specific part of spinlock_internal.cc
- */
-
-
-#include <windows.h>
-
-namespace base {
-namespace internal {
-
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
-  if (loop == 0) {
-  } else if (loop == 1) {
-    Sleep(0);
-  } else {
-    Sleep(base::internal::SuggestedDelayNS(loop) / 1000000);
-  }
-}
-
-void SpinLockWake(volatile Atomic32 *w, bool all) {
-}
-
-} // namespace internal
-} // namespace base
diff --git a/third_party/tcmalloc/chromium/src/base/stl_allocator.h b/third_party/tcmalloc/chromium/src/base/stl_allocator.h
deleted file mode 100644
index 2345f46..0000000
--- a/third_party/tcmalloc/chromium/src/base/stl_allocator.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Maxim Lifantsev
- */
-
-
-#ifndef BASE_STL_ALLOCATOR_H_
-#define BASE_STL_ALLOCATOR_H_
-
-#include <config.h>
-
-#include <stddef.h>   // for ptrdiff_t
-#include <limits>
-
-#include "base/logging.h"
-
-// Generic allocator class for STL objects
-// that uses a given type-less allocator Alloc, which must provide:
-//   static void* Alloc::Allocate(size_t size);
-//   static void Alloc::Free(void* ptr, size_t size);
-//
-// STL_Allocator<T, MyAlloc> provides the same thread-safety
-// guarantees as MyAlloc.
-//
-// Usage example:
-//   set<T, less<T>, STL_Allocator<T, MyAlloc> > my_set;
-// CAVEAT: Parts of the code below are probably specific
-//         to the STL version(s) we are using.
-//         The code is simply lifted from what std::allocator<> provides.
-template <typename T, class Alloc>
-class STL_Allocator {
- public:
-  typedef size_t     size_type;
-  typedef ptrdiff_t  difference_type;
-  typedef T*         pointer;
-  typedef const T*   const_pointer;
-  typedef T&         reference;
-  typedef const T&   const_reference;
-  typedef T          value_type;
-
-  template <class T1> struct rebind {
-    typedef STL_Allocator<T1, Alloc> other;
-  };
-
-  STL_Allocator() { }
-  STL_Allocator(const STL_Allocator&) { }
-  template <class T1> STL_Allocator(const STL_Allocator<T1, Alloc>&) { }
-  ~STL_Allocator() { }
-
-  pointer address(reference x) const { return &x; }
-  const_pointer address(const_reference x) const { return &x; }
-
-  pointer allocate(size_type n, const void* = 0) {
-    RAW_DCHECK((n * sizeof(T)) / sizeof(T) == n, "n is too big to allocate");
-    return static_cast<T*>(Alloc::Allocate(n * sizeof(T)));
-  }
-  void deallocate(pointer p, size_type n) { Alloc::Free(p, n * sizeof(T)); }
-
-  size_type max_size() const { return size_t(-1) / sizeof(T); }
-
-  void construct(pointer p, const T& val) { ::new(p) T(val); }
-  void construct(pointer p) { ::new(p) T(); }
-  void destroy(pointer p) { p->~T(); }
-
-  // There's no state, so these allocators are always equal
-  bool operator==(const STL_Allocator&) const { return true; }
-};
-
-#endif  // BASE_STL_ALLOCATOR_H_
diff --git a/third_party/tcmalloc/chromium/src/base/sysinfo.cc b/third_party/tcmalloc/chromium/src/base/sysinfo.cc
deleted file mode 100644
index ceb8e43..0000000
--- a/third_party/tcmalloc/chromium/src/base/sysinfo.cc
+++ /dev/null
@@ -1,896 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <config.h>
-#if (defined(_WIN32) || defined(__MINGW32__)) && !defined(__CYGWIN__) && !defined(__CYGWIN32)
-# define PLATFORM_WINDOWS 1
-#endif
-
-#include <ctype.h>    // for isspace()
-#include <stdlib.h>   // for getenv()
-#include <stdio.h>    // for snprintf(), sscanf()
-#include <string.h>   // for memmove(), memchr(), etc.
-#include <fcntl.h>    // for open()
-#include <errno.h>    // for errno
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>   // for read()
-#endif
-#if defined __MACH__          // Mac OS X, almost certainly
-#include <mach-o/dyld.h>      // for iterating over dll's in ProcMapsIter
-#include <mach-o/loader.h>    // for iterating over dll's in ProcMapsIter
-#include <sys/types.h>
-#include <sys/sysctl.h>       // how we figure out numcpu's on OS X
-#elif defined __FreeBSD__
-#include <sys/sysctl.h>
-#elif defined __sun__         // Solaris
-#include <procfs.h>           // for, e.g., prmap_t
-#elif defined(PLATFORM_WINDOWS)
-#include <process.h>          // for getpid() (actually, _getpid())
-#include <shlwapi.h>          // for SHGetValueA()
-#include <tlhelp32.h>         // for Module32First()
-#endif
-#include "base/sysinfo.h"
-#include "base/commandlineflags.h"
-#include "base/dynamic_annotations.h"   // for RunningOnValgrind
-#include "base/logging.h"
-
-#ifdef PLATFORM_WINDOWS
-#ifdef MODULEENTRY32
-// In a change from the usual W-A pattern, there is no A variant of
-// MODULEENTRY32.  Tlhelp32.h #defines the W variant, but not the A.
-// In unicode mode, tlhelp32.h #defines MODULEENTRY32 to be
-// MODULEENTRY32W.  These #undefs are the only way I see to get back
-// access to the original, ascii struct (and related functions).
-#undef MODULEENTRY32
-#undef Module32First
-#undef Module32Next
-#undef PMODULEENTRY32
-#undef LPMODULEENTRY32
-#endif  /* MODULEENTRY32 */
-// MinGW doesn't seem to define this, perhaps some windowsen don't either.
-#ifndef TH32CS_SNAPMODULE32
-#define TH32CS_SNAPMODULE32  0
-#endif  /* TH32CS_SNAPMODULE32 */
-#endif  /* PLATFORM_WINDOWS */
-
-// Re-run fn until it doesn't cause EINTR.
-#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)
-
-// open/read/close can set errno, which may be illegal at this
-// time, so prefer making the syscalls directly if we can.
-#ifdef HAVE_SYS_SYSCALL_H
-# include <sys/syscall.h>
-#endif
-#ifdef SYS_open   // solaris 11, at least sometimes, only defines SYS_openat
-# define safeopen(filename, mode)  syscall(SYS_open, filename, mode)
-#else
-# define safeopen(filename, mode)  open(filename, mode)
-#endif
-#ifdef SYS_read
-# define saferead(fd, buffer, size)  syscall(SYS_read, fd, buffer, size)
-#else
-# define saferead(fd, buffer, size)  read(fd, buffer, size)
-#endif
-#ifdef SYS_close
-# define safeclose(fd)  syscall(SYS_close, fd)
-#else
-# define safeclose(fd)  close(fd)
-#endif
-
-// ----------------------------------------------------------------------
-// GetenvBeforeMain()
-// GetUniquePathFromEnv()
-//    Some non-trivial getenv-related functions.
-// ----------------------------------------------------------------------
-
-// we reimplement memcmp and friends to avoid depending on any glibc
-// calls too early in the process lifetime. This allows us to use
-// GetenvBeforeMain from inside ifunc handler
-static int slow_memcmp(const void *_a, const void *_b, size_t n) {
-  const uint8_t *a = reinterpret_cast<const uint8_t *>(_a);
-  const uint8_t *b = reinterpret_cast<const uint8_t *>(_b);
-  while (n-- != 0) {
-    uint8_t ac = *a++;
-    uint8_t bc = *b++;
-    if (ac != bc) {
-      if (ac < bc) {
-        return -1;
-      }
-      return 1;
-    }
-  }
-  return 0;
-}
-
-static const char *slow_memchr(const char *s, int c, size_t n) {
-  uint8_t ch = static_cast<uint8_t>(c);
-  while (n--) {
-    if (*s++ == ch) {
-      return s - 1;
-    }
-  }
-  return 0;
-}
-
-static size_t slow_strlen(const char *s) {
-  const char *s2 = slow_memchr(s, '\0', static_cast<size_t>(-1));
-  return s2 - s;
-}
-
-// It's not safe to call getenv() in the malloc hooks, because they
-// might be called extremely early, before libc is done setting up
-// correctly.  In particular, the thread library may not be done
-// setting up errno.  So instead, we use the built-in __environ array
-// if it exists, and otherwise read /proc/self/environ directly, using
-// system calls to read the file, and thus avoid setting errno.
-// /proc/self/environ has a limit of how much data it exports (around
-// 8K), so it's not an ideal solution.
-const char* GetenvBeforeMain(const char* name) {
-  const int namelen = slow_strlen(name);
-#if defined(HAVE___ENVIRON)   // if we have it, it's declared in unistd.h
-  if (__environ) {            // can exist but be NULL, if statically linked
-    for (char** p = __environ; *p; p++) {
-      if (!slow_memcmp(*p, name, namelen) && (*p)[namelen] == '=')
-        return *p + namelen+1;
-    }
-    return NULL;
-  }
-#endif
-#if defined(PLATFORM_WINDOWS)
-  // TODO(mbelshe) - repeated calls to this function will overwrite the
-  // contents of the static buffer.
-  static char envvar_buf[1024];  // enough to hold any envvar we care about
-  if (!GetEnvironmentVariableA(name, envvar_buf, sizeof(envvar_buf)-1))
-    return NULL;
-  return envvar_buf;
-#endif
-  // static is ok because this function should only be called before
-  // main(), when we're single-threaded.
-  static char envbuf[16<<10];
-  if (*envbuf == '\0') {    // haven't read the environ yet
-    int fd = safeopen("/proc/self/environ", O_RDONLY);
-    // The -2 below guarantees the last two bytes of the buffer will be \0\0
-    if (fd == -1 ||           // unable to open the file, fall back onto libc
-        saferead(fd, envbuf, sizeof(envbuf) - 2) < 0) { // error reading file
-      RAW_VLOG(1, "Unable to open /proc/self/environ, falling back "
-               "on getenv(\"%s\"), which may not work", name);
-      if (fd != -1) safeclose(fd);
-      return getenv(name);
-    }
-    safeclose(fd);
-  }
-  const char* p = envbuf;
-  while (*p != '\0') {    // will happen at the \0\0 that terminates the buffer
-    // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
-    const char* endp = (char*)slow_memchr(p, '\0',
-                                          sizeof(envbuf) - (p - envbuf));
-    if (endp == NULL)            // this entry isn't NUL terminated
-      return NULL;
-    else if (!slow_memcmp(p, name, namelen) && p[namelen] == '=')    // it's a match
-      return p + namelen+1;      // point after =
-    p = endp + 1;
-  }
-  return NULL;                   // env var never found
-}
-
-extern "C" {
-  const char* TCMallocGetenvSafe(const char* name) {
-    return GetenvBeforeMain(name);
-  }
-}
-
-// This takes as an argument an environment-variable name (like
-// CPUPROFILE) whose value is supposed to be a file-path, and sets
-// path to that path, and returns true.  If the env var doesn't exist,
-// or is the empty string, leave path unchanged and returns false.
-// The reason this is non-trivial is that this function handles munged
-// pathnames.  Here's why:
-//
-// If we're a child process of the 'main' process, we can't just use
-// getenv("CPUPROFILE") -- the parent process will be using that path.
-// Instead we append our pid to the pathname.  How do we tell if we're a
-// child process?  Ideally we'd set an environment variable that all
-// our children would inherit.  But -- and this is seemingly a bug in
-// gcc -- if you do a setenv() in a shared libarary in a global
-// constructor, the environment setting is lost by the time main() is
-// called.  The only safe thing we can do in such a situation is to
-// modify the existing envvar.  So we do a hack: in the parent, we set
-// the high bit of the 1st char of CPUPROFILE.  In the child, we
-// notice the high bit is set and append the pid().  This works
-// assuming cpuprofile filenames don't normally have the high bit set
-// in their first character!  If that assumption is violated, we'll
-// still get a profile, but one with an unexpected name.
-// TODO(csilvers): set an envvar instead when we can do it reliably.
-//
-// In Chromium this hack is intentionally disabled, because the path is not
-// re-initialized upon fork.
-bool GetUniquePathFromEnv(const char* env_name, char* path) {
-  char* envval = getenv(env_name);
-  if (envval == NULL || *envval == '\0')
-    return false;
-  if (envval[0] & 128) {                  // high bit is set
-    snprintf(path, PATH_MAX, "%c%s_%u",   // add pid and clear high bit
-             envval[0] & 127, envval+1, (unsigned int)(getpid()));
-  } else {
-    snprintf(path, PATH_MAX, "%s", envval);
-#if 0
-    envval[0] |= 128;                     // set high bit for kids to see
-#endif
-  }
-  return true;
-}
-
-void SleepForMilliseconds(int milliseconds) {
-#ifdef PLATFORM_WINDOWS
-  _sleep(milliseconds);   // Windows's _sleep takes milliseconds argument
-#else
-  // Sleep for a few milliseconds
-  struct timespec sleep_time;
-  sleep_time.tv_sec = milliseconds / 1000;
-  sleep_time.tv_nsec = (milliseconds % 1000) * 1000000;
-  while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR)
-    ;  // Ignore signals and wait for the full interval to elapse.
-#endif
-}
-
-int GetSystemCPUsCount()
-{
-#if defined(PLATFORM_WINDOWS)
-  // Get the number of processors.
-  SYSTEM_INFO info;
-  GetSystemInfo(&info);
-  return  info.dwNumberOfProcessors;
-#else
-  long rv = sysconf(_SC_NPROCESSORS_ONLN);
-  if (rv < 0) {
-    return 1;
-  }
-  return static_cast<int>(rv);
-#endif
-}
-
-// ----------------------------------------------------------------------
-
-#if defined __linux__ || defined __FreeBSD__ || defined __sun__ || defined __CYGWIN__ || defined __CYGWIN32__
-static void ConstructFilename(const char* spec, pid_t pid,
-                              char* buf, int buf_size) {
-  CHECK_LT(snprintf(buf, buf_size,
-                    spec,
-                    static_cast<int>(pid ? pid : getpid())), buf_size);
-}
-#endif
-
-// A templatized helper function instantiated for Mach (OS X) only.
-// It can handle finding info for both 32 bits and 64 bits.
-// Returns true if it successfully handled the hdr, false else.
-#ifdef __MACH__          // Mac OS X, almost certainly
-template<uint32_t kMagic, uint32_t kLCSegment,
-         typename MachHeader, typename SegmentCommand>
-static bool NextExtMachHelper(const mach_header* hdr,
-                              int current_image, int current_load_cmd,
-                              uint64 *start, uint64 *end, char **flags,
-                              uint64 *offset, int64 *inode, char **filename,
-                              uint64 *file_mapping, uint64 *file_pages,
-                              uint64 *anon_mapping, uint64 *anon_pages,
-                              dev_t *dev) {
-  static char kDefaultPerms[5] = "r-xp";
-  if (hdr->magic != kMagic)
-    return false;
-  const char* lc = (const char *)hdr + sizeof(MachHeader);
-  // TODO(csilvers): make this not-quadradic (increment and hold state)
-  for (int j = 0; j < current_load_cmd; j++)  // advance to *our* load_cmd
-    lc += ((const load_command *)lc)->cmdsize;
-  if (((const load_command *)lc)->cmd == kLCSegment) {
-    const intptr_t dlloff = _dyld_get_image_vmaddr_slide(current_image);
-    const SegmentCommand* sc = (const SegmentCommand *)lc;
-    if (start) *start = sc->vmaddr + dlloff;
-    if (end) *end = sc->vmaddr + sc->vmsize + dlloff;
-    if (flags) *flags = kDefaultPerms;  // can we do better?
-    if (offset) *offset = sc->fileoff;
-    if (inode) *inode = 0;
-    if (filename)
-      *filename = const_cast<char*>(_dyld_get_image_name(current_image));
-    if (file_mapping) *file_mapping = 0;
-    if (file_pages) *file_pages = 0;   // could we use sc->filesize?
-    if (anon_mapping) *anon_mapping = 0;
-    if (anon_pages) *anon_pages = 0;
-    if (dev) *dev = 0;
-    return true;
-  }
-
-  return false;
-}
-#endif
-
-// Finds |c| in |text|, and assign '\0' at the found position.
-// The original character at the modified position should be |c|.
-// A pointer to the modified position is stored in |endptr|.
-// |endptr| should not be NULL.
-static bool ExtractUntilChar(char *text, int c, char **endptr) {
-  CHECK_NE(text, NULL);
-  CHECK_NE(endptr, NULL);
-  char *found;
-  found = strchr(text, c);
-  if (found == NULL) {
-    *endptr = NULL;
-    return false;
-  }
-
-  *endptr = found;
-  *found = '\0';
-  return true;
-}
-
-// Increments |*text_pointer| while it points a whitespace character.
-// It is to follow sscanf's whilespace handling.
-static void SkipWhileWhitespace(char **text_pointer, int c) {
-  if (isspace(c)) {
-    while (isspace(**text_pointer) && isspace(*((*text_pointer) + 1))) {
-      ++(*text_pointer);
-    }
-  }
-}
-
-template<class T>
-static T StringToInteger(char *text, char **endptr, int base) {
-  assert(false);
-  return T();
-}
-
-template<>
-int StringToInteger<int>(char *text, char **endptr, int base) {
-  return strtol(text, endptr, base);
-}
-
-template<>
-int64 StringToInteger<int64>(char *text, char **endptr, int base) {
-  return strtoll(text, endptr, base);
-}
-
-template<>
-uint64 StringToInteger<uint64>(char *text, char **endptr, int base) {
-  return strtoull(text, endptr, base);
-}
-
-template<typename T>
-static T StringToIntegerUntilChar(
-    char *text, int base, int c, char **endptr_result) {
-  CHECK_NE(endptr_result, NULL);
-  *endptr_result = NULL;
-
-  char *endptr_extract;
-  if (!ExtractUntilChar(text, c, &endptr_extract))
-    return 0;
-
-  T result;
-  char *endptr_strto;
-  result = StringToInteger<T>(text, &endptr_strto, base);
-  *endptr_extract = c;
-
-  if (endptr_extract != endptr_strto)
-    return 0;
-
-  *endptr_result = endptr_extract;
-  SkipWhileWhitespace(endptr_result, c);
-
-  return result;
-}
-
-static char *CopyStringUntilChar(
-    char *text, unsigned out_len, int c, char *out) {
-  char *endptr;
-  if (!ExtractUntilChar(text, c, &endptr))
-    return NULL;
-
-  strncpy(out, text, out_len);
-  out[out_len-1] = '\0';
-  *endptr = c;
-
-  SkipWhileWhitespace(&endptr, c);
-  return endptr;
-}
-
-template<typename T>
-static bool StringToIntegerUntilCharWithCheck(
-    T *outptr, char *text, int base, int c, char **endptr) {
-  *outptr = StringToIntegerUntilChar<T>(*endptr, base, c, endptr);
-  if (*endptr == NULL || **endptr == '\0') return false;
-  ++(*endptr);
-  return true;
-}
-
-static bool ParseProcMapsLine(char *text, uint64 *start, uint64 *end,
-                              char *flags, uint64 *offset,
-                              int *major, int *minor, int64 *inode,
-                              unsigned *filename_offset) {
-#if defined(__linux__)
-  /*
-   * It's similar to:
-   * sscanf(text, "%"SCNx64"-%"SCNx64" %4s %"SCNx64" %x:%x %"SCNd64" %n",
-   *        start, end, flags, offset, major, minor, inode, filename_offset)
-   */
-  char *endptr = text;
-  if (endptr == NULL || *endptr == '\0')  return false;
-
-  if (!StringToIntegerUntilCharWithCheck(start, endptr, 16, '-', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(end, endptr, 16, ' ', &endptr))
-    return false;
-
-  endptr = CopyStringUntilChar(endptr, 5, ' ', flags);
-  if (endptr == NULL || *endptr == '\0')  return false;
-  ++endptr;
-
-  if (!StringToIntegerUntilCharWithCheck(offset, endptr, 16, ' ', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(major, endptr, 16, ':', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(minor, endptr, 16, ' ', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(inode, endptr, 10, ' ', &endptr))
-    return false;
-
-  *filename_offset = (endptr - text);
-  return true;
-#else
-  return false;
-#endif
-}
-
-ProcMapsIterator::ProcMapsIterator(pid_t pid) {
-  Init(pid, NULL, false);
-}
-
-ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer) {
-  Init(pid, buffer, false);
-}
-
-ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer,
-                                   bool use_maps_backing) {
-  Init(pid, buffer, use_maps_backing);
-}
-
-void ProcMapsIterator::Init(pid_t pid, Buffer *buffer,
-                            bool use_maps_backing) {
-  pid_ = pid;
-  using_maps_backing_ = use_maps_backing;
-  dynamic_buffer_ = NULL;
-  if (!buffer) {
-    // If the user didn't pass in any buffer storage, allocate it
-    // now. This is the normal case; the signal handler passes in a
-    // static buffer.
-    buffer = dynamic_buffer_ = new Buffer;
-  } else {
-    dynamic_buffer_ = NULL;
-  }
-
-  ibuf_ = buffer->buf_;
-
-  stext_ = etext_ = nextline_ = ibuf_;
-  ebuf_ = ibuf_ + Buffer::kBufSize - 1;
-  nextline_ = ibuf_;
-
-#if defined(__linux__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-  if (use_maps_backing) {  // don't bother with clever "self" stuff in this case
-    ConstructFilename("/proc/%d/maps_backing", pid, ibuf_, Buffer::kBufSize);
-  } else if (pid == 0) {
-    // We have to kludge a bit to deal with the args ConstructFilename
-    // expects.  The 1 is never used -- it's only impt. that it's not 0.
-    ConstructFilename("/proc/self/maps", 1, ibuf_, Buffer::kBufSize);
-  } else {
-    ConstructFilename("/proc/%d/maps", pid, ibuf_, Buffer::kBufSize);
-  }
-  // No error logging since this can be called from the crash dump
-  // handler at awkward moments. Users should call Valid() before
-  // using.
-  NO_INTR(fd_ = open(ibuf_, O_RDONLY));
-#elif defined(__FreeBSD__)
-  // We don't support maps_backing on freebsd
-  if (pid == 0) {
-    ConstructFilename("/proc/curproc/map", 1, ibuf_, Buffer::kBufSize);
-  } else {
-    ConstructFilename("/proc/%d/map", pid, ibuf_, Buffer::kBufSize);
-  }
-  NO_INTR(fd_ = open(ibuf_, O_RDONLY));
-#elif defined(__sun__)
-  if (pid == 0) {
-    ConstructFilename("/proc/self/map", 1, ibuf_, Buffer::kBufSize);
-  } else {
-    ConstructFilename("/proc/%d/map", pid, ibuf_, Buffer::kBufSize);
-  }
-  NO_INTR(fd_ = open(ibuf_, O_RDONLY));
-#elif defined(__MACH__)
-  current_image_ = _dyld_image_count();   // count down from the top
-  current_load_cmd_ = -1;
-#elif defined(PLATFORM_WINDOWS)
-  snapshot_ = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE |
-                                       TH32CS_SNAPMODULE32,
-                                       GetCurrentProcessId());
-  memset(&module_, 0, sizeof(module_));
-#else
-  fd_ = -1;   // so Valid() is always false
-#endif
-
-}
-
-ProcMapsIterator::~ProcMapsIterator() {
-#if defined(PLATFORM_WINDOWS)
-  if (snapshot_ != INVALID_HANDLE_VALUE) CloseHandle(snapshot_);
-#elif defined(__MACH__)
-  // no cleanup necessary!
-#else
-  if (fd_ >= 0) NO_INTR(close(fd_));
-#endif
-  delete dynamic_buffer_;
-}
-
-bool ProcMapsIterator::Valid() const {
-#if defined(PLATFORM_WINDOWS)
-  return snapshot_ != INVALID_HANDLE_VALUE;
-#elif defined(__MACH__)
-  return 1;
-#else
-  return fd_ != -1;
-#endif
-}
-
-bool ProcMapsIterator::Next(uint64 *start, uint64 *end, char **flags,
-                            uint64 *offset, int64 *inode, char **filename) {
-  return NextExt(start, end, flags, offset, inode, filename, NULL, NULL,
-                 NULL, NULL, NULL);
-}
-
-// This has too many arguments.  It should really be building
-// a map object and returning it.  The problem is that this is called
-// when the memory allocator state is undefined, hence the arguments.
-bool ProcMapsIterator::NextExt(uint64 *start, uint64 *end, char **flags,
-                               uint64 *offset, int64 *inode, char **filename,
-                               uint64 *file_mapping, uint64 *file_pages,
-                               uint64 *anon_mapping, uint64 *anon_pages,
-                               dev_t *dev) {
-
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-  do {
-    // Advance to the start of the next line
-    stext_ = nextline_;
-
-    // See if we have a complete line in the buffer already
-    nextline_ = static_cast<char *>(memchr (stext_, '\n', etext_ - stext_));
-    if (!nextline_) {
-      // Shift/fill the buffer so we do have a line
-      int count = etext_ - stext_;
-
-      // Move the current text to the start of the buffer
-      memmove(ibuf_, stext_, count);
-      stext_ = ibuf_;
-      etext_ = ibuf_ + count;
-
-      int nread = 0;            // fill up buffer with text
-      while (etext_ < ebuf_) {
-        NO_INTR(nread = read(fd_, etext_, ebuf_ - etext_));
-        if (nread > 0)
-          etext_ += nread;
-        else
-          break;
-      }
-
-      // Zero out remaining characters in buffer at EOF to avoid returning
-      // garbage from subsequent calls.
-      if (etext_ != ebuf_ && nread == 0) {
-        memset(etext_, 0, ebuf_ - etext_);
-      }
-      *etext_ = '\n';   // sentinel; safe because ibuf extends 1 char beyond ebuf
-      nextline_ = static_cast<char *>(memchr (stext_, '\n', etext_ + 1 - stext_));
-    }
-    *nextline_ = 0;                // turn newline into nul
-    nextline_ += ((nextline_ < etext_)? 1 : 0);  // skip nul if not end of text
-    // stext_ now points at a nul-terminated line
-    uint64 tmpstart, tmpend, tmpoffset;
-    int64 tmpinode;
-    int major, minor;
-    unsigned filename_offset = 0;
-#if defined(__linux__)
-    // for now, assume all linuxes have the same format
-    if (!ParseProcMapsLine(
-        stext_,
-        start ? start : &tmpstart,
-        end ? end : &tmpend,
-        flags_,
-        offset ? offset : &tmpoffset,
-        &major, &minor,
-        inode ? inode : &tmpinode, &filename_offset)) continue;
-#elif defined(__CYGWIN__) || defined(__CYGWIN32__)
-    // cygwin is like linux, except the third field is the "entry point"
-    // rather than the offset (see format_process_maps at
-    // http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/fhandler_process.cc?rev=1.89&content-type=text/x-cvsweb-markup&cvsroot=src
-    // Offset is always be 0 on cygwin: cygwin implements an mmap
-    // by loading the whole file and then calling NtMapViewOfSection.
-    // Cygwin also seems to set its flags kinda randomly; use windows default.
-    char tmpflags[5];
-    if (offset)
-      *offset = 0;
-    strcpy(flags_, "r-xp");
-    if (sscanf(stext_, "%llx-%llx %4s %llx %x:%x %lld %n",
-               start ? start : &tmpstart,
-               end ? end : &tmpend,
-               tmpflags,
-               &tmpoffset,
-               &major, &minor,
-               inode ? inode : &tmpinode, &filename_offset) != 7) continue;
-#elif defined(__FreeBSD__)
-    // For the format, see http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/fs/procfs/procfs_map.c?rev=1.31&content-type=text/x-cvsweb-markup
-    tmpstart = tmpend = tmpoffset = 0;
-    tmpinode = 0;
-    major = minor = 0;   // can't get this info in freebsd
-    if (inode)
-      *inode = 0;        // nor this
-    if (offset)
-      *offset = 0;       // seems like this should be in there, but maybe not
-    // start end resident privateresident obj(?) prot refcnt shadowcnt
-    // flags copy_on_write needs_copy type filename:
-    // 0x8048000 0x804a000 2 0 0xc104ce70 r-x 1 0 0x0 COW NC vnode /bin/cat
-    if (sscanf(stext_, "0x%" SCNx64 " 0x%" SCNx64 " %*d %*d %*p %3s %*d %*d 0x%*x %*s %*s %*s %n",
-               start ? start : &tmpstart,
-               end ? end : &tmpend,
-               flags_,
-               &filename_offset) != 3) continue;
-#endif
-
-    // Depending on the Linux kernel being used, there may or may not be a space
-    // after the inode if there is no filename.  sscanf will in such situations
-    // nondeterministically either fill in filename_offset or not (the results
-    // differ on multiple calls in the same run even with identical arguments).
-    // We don't want to wander off somewhere beyond the end of the string.
-    size_t stext_length = strlen(stext_);
-    if (filename_offset == 0 || filename_offset > stext_length)
-      filename_offset = stext_length;
-
-    // We found an entry
-    if (flags) *flags = flags_;
-    if (filename) *filename = stext_ + filename_offset;
-    if (dev) *dev = minor | (major << 8);
-
-    if (using_maps_backing_) {
-      // Extract and parse physical page backing info.
-      char *backing_ptr = stext_ + filename_offset +
-          strlen(stext_+filename_offset);
-
-      // find the second '('
-      int paren_count = 0;
-      while (--backing_ptr > stext_) {
-        if (*backing_ptr == '(') {
-          ++paren_count;
-          if (paren_count >= 2) {
-            uint64 tmp_file_mapping;
-            uint64 tmp_file_pages;
-            uint64 tmp_anon_mapping;
-            uint64 tmp_anon_pages;
-
-            sscanf(backing_ptr+1, "F %" SCNx64 " %" SCNd64 ") (A %" SCNx64 " %" SCNd64 ")",
-                   file_mapping ? file_mapping : &tmp_file_mapping,
-                   file_pages ? file_pages : &tmp_file_pages,
-                   anon_mapping ? anon_mapping : &tmp_anon_mapping,
-                   anon_pages ? anon_pages : &tmp_anon_pages);
-            // null terminate the file name (there is a space
-            // before the first (.
-            backing_ptr[-1] = 0;
-            break;
-          }
-        }
-      }
-    }
-
-    return true;
-  } while (etext_ > ibuf_);
-#elif defined(__sun__)
-  // This is based on MA_READ == 4, MA_WRITE == 2, MA_EXEC == 1
-  static char kPerms[8][4] = { "---", "--x", "-w-", "-wx",
-                               "r--", "r-x", "rw-", "rwx" };
-  COMPILE_ASSERT(MA_READ == 4, solaris_ma_read_must_equal_4);
-  COMPILE_ASSERT(MA_WRITE == 2, solaris_ma_write_must_equal_2);
-  COMPILE_ASSERT(MA_EXEC == 1, solaris_ma_exec_must_equal_1);
-  Buffer object_path;
-  int nread = 0;            // fill up buffer with text
-  NO_INTR(nread = read(fd_, ibuf_, sizeof(prmap_t)));
-  if (nread == sizeof(prmap_t)) {
-    long inode_from_mapname = 0;
-    prmap_t* mapinfo = reinterpret_cast<prmap_t*>(ibuf_);
-    // Best-effort attempt to get the inode from the filename.  I think the
-    // two middle ints are major and minor device numbers, but I'm not sure.
-    sscanf(mapinfo->pr_mapname, "ufs.%*d.%*d.%ld", &inode_from_mapname);
-
-    if (pid_ == 0) {
-      CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,
-                        "/proc/self/path/%s", mapinfo->pr_mapname),
-               Buffer::kBufSize);
-    } else {
-      CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,
-                        "/proc/%d/path/%s",
-                        static_cast<int>(pid_), mapinfo->pr_mapname),
-               Buffer::kBufSize);
-    }
-    ssize_t len = readlink(object_path.buf_, current_filename_, PATH_MAX);
-    CHECK_LT(len, PATH_MAX);
-    if (len < 0)
-      len = 0;
-    current_filename_[len] = '\0';
-
-    if (start) *start = mapinfo->pr_vaddr;
-    if (end) *end = mapinfo->pr_vaddr + mapinfo->pr_size;
-    if (flags) *flags = kPerms[mapinfo->pr_mflags & 7];
-    if (offset) *offset = mapinfo->pr_offset;
-    if (inode) *inode = inode_from_mapname;
-    if (filename) *filename = current_filename_;
-    if (file_mapping) *file_mapping = 0;
-    if (file_pages) *file_pages = 0;
-    if (anon_mapping) *anon_mapping = 0;
-    if (anon_pages) *anon_pages = 0;
-    if (dev) *dev = 0;
-    return true;
-  }
-#elif defined(__MACH__)
-  // We return a separate entry for each segment in the DLL. (TODO(csilvers):
-  // can we do better?)  A DLL ("image") has load-commands, some of which
-  // talk about segment boundaries.
-  // cf image_for_address from http://svn.digium.com/view/asterisk/team/oej/minivoicemail/dlfcn.c?revision=53912
-  for (; current_image_ >= 0; current_image_--) {
-    const mach_header* hdr = _dyld_get_image_header(current_image_);
-    if (!hdr) continue;
-    if (current_load_cmd_ < 0)   // set up for this image
-      current_load_cmd_ = hdr->ncmds;  // again, go from the top down
-
-    // We start with the next load command (we've already looked at this one).
-    for (current_load_cmd_--; current_load_cmd_ >= 0; current_load_cmd_--) {
-#ifdef MH_MAGIC_64
-      if (NextExtMachHelper<MH_MAGIC_64, LC_SEGMENT_64,
-                            struct mach_header_64, struct segment_command_64>(
-                                hdr, current_image_, current_load_cmd_,
-                                start, end, flags, offset, inode, filename,
-                                file_mapping, file_pages, anon_mapping,
-                                anon_pages, dev)) {
-        return true;
-      }
-#endif
-      if (NextExtMachHelper<MH_MAGIC, LC_SEGMENT,
-                            struct mach_header, struct segment_command>(
-                                hdr, current_image_, current_load_cmd_,
-                                start, end, flags, offset, inode, filename,
-                                file_mapping, file_pages, anon_mapping,
-                                anon_pages, dev)) {
-        return true;
-      }
-    }
-    // If we get here, no more load_cmd's in this image talk about
-    // segments.  Go on to the next image.
-  }
-#elif defined(PLATFORM_WINDOWS)
-  static char kDefaultPerms[5] = "r-xp";
-  BOOL ok;
-  if (module_.dwSize == 0) {  // only possible before first call
-    module_.dwSize = sizeof(module_);
-    ok = Module32First(snapshot_, &module_);
-  } else {
-    ok = Module32Next(snapshot_, &module_);
-  }
-  if (ok) {
-    uint64 base_addr = reinterpret_cast<DWORD_PTR>(module_.modBaseAddr);
-    if (start) *start = base_addr;
-    if (end) *end = base_addr + module_.modBaseSize;
-    if (flags) *flags = kDefaultPerms;
-    if (offset) *offset = 0;
-    if (inode) *inode = 0;
-    if (filename) *filename = module_.szExePath;
-    if (file_mapping) *file_mapping = 0;
-    if (file_pages) *file_pages = 0;
-    if (anon_mapping) *anon_mapping = 0;
-    if (anon_pages) *anon_pages = 0;
-    if (dev) *dev = 0;
-    return true;
-  }
-#endif
-
-  // We didn't find anything
-  return false;
-}
-
-int ProcMapsIterator::FormatLine(char* buffer, int bufsize,
-                                 uint64 start, uint64 end, const char *flags,
-                                 uint64 offset, int64 inode,
-                                 const char *filename, dev_t dev) {
-  // We assume 'flags' looks like 'rwxp' or 'rwx'.
-  char r = (flags && flags[0] == 'r') ? 'r' : '-';
-  char w = (flags && flags[0] && flags[1] == 'w') ? 'w' : '-';
-  char x = (flags && flags[0] && flags[1] && flags[2] == 'x') ? 'x' : '-';
-  // p always seems set on linux, so we set the default to 'p', not '-'
-  char p = (flags && flags[0] && flags[1] && flags[2] && flags[3] != 'p')
-      ? '-' : 'p';
-
-  const int rc = snprintf(buffer, bufsize,
-                          "%08" PRIx64 "-%08" PRIx64 " %c%c%c%c %08" PRIx64 " %02x:%02x %-11" PRId64 " %s\n",
-                          start, end, r,w,x,p, offset,
-                          static_cast<int>(dev/256), static_cast<int>(dev%256),
-                          inode, filename);
-  return (rc < 0 || rc >= bufsize) ? 0 : rc;
-}
-
-namespace tcmalloc {
-
-// Helper to add the list of mapped shared libraries to a profile.
-// Fill formatted "/proc/self/maps" contents into buffer 'buf' of size 'size'
-// and return the actual size occupied in 'buf'.  We fill wrote_all to true
-// if we successfully wrote all proc lines to buf, false else.
-// We do not provision for 0-terminating 'buf'.
-int FillProcSelfMaps(char buf[], int size, bool* wrote_all) {
-  ProcMapsIterator::Buffer iterbuf;
-  ProcMapsIterator it(0, &iterbuf);   // 0 means "current pid"
-
-  uint64 start, end, offset;
-  int64 inode;
-  char *flags, *filename;
-  int bytes_written = 0;
-  *wrote_all = true;
-  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
-    const int line_length = it.FormatLine(buf + bytes_written,
-                                          size - bytes_written,
-                                          start, end, flags, offset,
-                                          inode, filename, 0);
-    if (line_length == 0)
-      *wrote_all = false;     // failed to write this line out
-    else
-      bytes_written += line_length;
-
-  }
-  return bytes_written;
-}
-
-// Dump the same data as FillProcSelfMaps reads to fd.
-// It seems easier to repeat parts of FillProcSelfMaps here than to
-// reuse it via a call.
-void DumpProcSelfMaps(RawFD fd) {
-  ProcMapsIterator::Buffer iterbuf;
-  ProcMapsIterator it(0, &iterbuf);   // 0 means "current pid"
-
-  uint64 start, end, offset;
-  int64 inode;
-  char *flags, *filename;
-  ProcMapsIterator::Buffer linebuf;
-  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
-    int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_),
-                                start, end, flags, offset, inode, filename,
-                                0);
-    RawWrite(fd, linebuf.buf_, written);
-  }
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/base/sysinfo.h b/third_party/tcmalloc/chromium/src/base/sysinfo.h
deleted file mode 100644
index e30b0d4d..0000000
--- a/third_party/tcmalloc/chromium/src/base/sysinfo.h
+++ /dev/null
@@ -1,232 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// All functions here are thread-hostile due to file caching unless
-// commented otherwise.
-
-#ifndef _SYSINFO_H_
-#define _SYSINFO_H_
-
-#include <config.h>
-
-#include <time.h>
-#if (defined(_WIN32) || defined(__MINGW32__)) && (!defined(__CYGWIN__) && !defined(__CYGWIN32__))
-#include <windows.h>   // for DWORD
-#include <tlhelp32.h>  // for CreateToolhelp32Snapshot
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for pid_t
-#endif
-#include <stddef.h>    // for size_t
-#include <limits.h>    // for PATH_MAX
-#include "base/basictypes.h"
-#include "base/logging.h"   // for RawFD
-
-// This getenv function is safe to call before the C runtime is initialized.
-// On Windows, it utilizes GetEnvironmentVariable() and on unix it uses
-// /proc/self/environ instead calling getenv().  It's intended to be used in
-// routines that run before main(), when the state required for getenv() may
-// not be set up yet.  In particular, errno isn't set up until relatively late
-// (after the pthreads library has a chance to make it threadsafe), and
-// getenv() doesn't work until then. 
-// On some platforms, this call will utilize the same, static buffer for
-// repeated GetenvBeforeMain() calls. Callers should not expect pointers from
-// this routine to be long lived.
-// Note that on unix, /proc only has the environment at the time the
-// application was started, so this routine ignores setenv() calls/etc.  Also
-// note it only reads the first 16K of the environment.
-extern const char* GetenvBeforeMain(const char* name);
-
-// This takes as an argument an environment-variable name (like
-// CPUPROFILE) whose value is supposed to be a file-path, and sets
-// path to that path, and returns true.  Non-trivial for surprising
-// reasons, as documented in sysinfo.cc.  path must have space PATH_MAX.
-extern bool GetUniquePathFromEnv(const char* env_name, char* path);
-
-extern int GetSystemCPUsCount();
-
-void SleepForMilliseconds(int milliseconds);
-
-//  Return true if we're running POSIX (e.g., NPTL on Linux) threads,
-//  as opposed to a non-POSIX thread library.  The thing that we care
-//  about is whether a thread's pid is the same as the thread that
-//  spawned it.  If so, this function returns true.
-//  Thread-safe.
-//  Note: We consider false negatives to be OK.
-bool HasPosixThreads();
-
-#ifndef SWIG  // SWIG doesn't like struct Buffer and variable arguments.
-
-// A ProcMapsIterator abstracts access to /proc/maps for a given
-// process. Needs to be stack-allocatable and avoid using stdio/malloc
-// so it can be used in the google stack dumper, heap-profiler, etc.
-//
-// On Windows and Mac OS X, this iterator iterates *only* over DLLs
-// mapped into this process space.  For Linux, FreeBSD, and Solaris,
-// it iterates over *all* mapped memory regions, including anonymous
-// mmaps.  For other O/Ss, it is unlikely to work at all, and Valid()
-// will always return false.  Also note: this routine only works on
-// FreeBSD if procfs is mounted: make sure this is in your /etc/fstab:
-//    proc            /proc   procfs  rw 0 0
-class ProcMapsIterator {
- public:
-  struct Buffer {
-#ifdef __FreeBSD__
-    // FreeBSD requires us to read all of the maps file at once, so
-    // we have to make a buffer that's "always" big enough
-    static const size_t kBufSize = 102400;
-#else   // a one-line buffer is good enough
-    static const size_t kBufSize = PATH_MAX + 1024;
-#endif
-    char buf_[kBufSize];
-  };
-
-
-  // Create a new iterator for the specified pid.  pid can be 0 for "self".
-  explicit ProcMapsIterator(pid_t pid);
-
-  // Create an iterator with specified storage (for use in signal
-  // handler). "buffer" should point to a ProcMapsIterator::Buffer
-  // buffer can be NULL in which case a bufer will be allocated.
-  ProcMapsIterator(pid_t pid, Buffer *buffer);
-
-  // Iterate through maps_backing instead of maps if use_maps_backing
-  // is true.  Otherwise the same as above.  buffer can be NULL and
-  // it will allocate a buffer itself.
-  ProcMapsIterator(pid_t pid, Buffer *buffer,
-                   bool use_maps_backing);
-
-  // Returns true if the iterator successfully initialized;
-  bool Valid() const;
-
-  // Returns a pointer to the most recently parsed line. Only valid
-  // after Next() returns true, and until the iterator is destroyed or
-  // Next() is called again.  This may give strange results on non-Linux
-  // systems.  Prefer FormatLine() if that may be a concern.
-  const char *CurrentLine() const { return stext_; }
-
-  // Writes the "canonical" form of the /proc/xxx/maps info for a single
-  // line to the passed-in buffer. Returns the number of bytes written,
-  // or 0 if it was not able to write the complete line.  (To guarantee
-  // success, buffer should have size at least Buffer::kBufSize.)
-  // Takes as arguments values set via a call to Next().  The
-  // "canonical" form of the line (taken from linux's /proc/xxx/maps):
-  //    <start_addr(hex)>-<end_addr(hex)> <perms(rwxp)> <offset(hex)>   +
-  //    <major_dev(hex)>:<minor_dev(hex)> <inode> <filename> Note: the
-  // eg
-  //    08048000-0804c000 r-xp 00000000 03:01 3793678    /bin/cat
-  // If you don't have the dev_t (dev), feel free to pass in 0.
-  // (Next() doesn't return a dev_t, though NextExt does.)
-  //
-  // Note: if filename and flags were obtained via a call to Next(),
-  // then the output of this function is only valid if Next() returned
-  // true, and only until the iterator is destroyed or Next() is
-  // called again.  (Since filename, at least, points into CurrentLine.)
-  static int FormatLine(char* buffer, int bufsize,
-                        uint64 start, uint64 end, const char *flags,
-                        uint64 offset, int64 inode, const char *filename,
-                        dev_t dev);
-
-  // Find the next entry in /proc/maps; return true if found or false
-  // if at the end of the file.
-  //
-  // Any of the result pointers can be NULL if you're not interested
-  // in those values.
-  //
-  // If "flags" and "filename" are passed, they end up pointing to
-  // storage within the ProcMapsIterator that is valid only until the
-  // iterator is destroyed or Next() is called again. The caller may
-  // modify the contents of these strings (up as far as the first NUL,
-  // and only until the subsequent call to Next()) if desired.
-
-  // The offsets are all uint64 in order to handle the case of a
-  // 32-bit process running on a 64-bit kernel
-  //
-  // IMPORTANT NOTE: see top-of-class notes for details about what
-  // mapped regions Next() iterates over, depending on O/S.
-  // TODO(csilvers): make flags and filename const.
-  bool Next(uint64 *start, uint64 *end, char **flags,
-            uint64 *offset, int64 *inode, char **filename);
-
-  bool NextExt(uint64 *start, uint64 *end, char **flags,
-               uint64 *offset, int64 *inode, char **filename,
-               uint64 *file_mapping, uint64 *file_pages,
-               uint64 *anon_mapping, uint64 *anon_pages,
-               dev_t *dev);
-
-  ~ProcMapsIterator();
-
- private:
-  void Init(pid_t pid, Buffer *buffer, bool use_maps_backing);
-
-  char *ibuf_;        // input buffer
-  char *stext_;       // start of text
-  char *etext_;       // end of text
-  char *nextline_;    // start of next line
-  char *ebuf_;        // end of buffer (1 char for a nul)
-#if (defined(_WIN32) || defined(__MINGW32__)) && (!defined(__CYGWIN__) && !defined(__CYGWIN32__))
-  HANDLE snapshot_;   // filehandle on dll info
-  // In a change from the usual W-A pattern, there is no A variant of
-  // MODULEENTRY32.  Tlhelp32.h #defines the W variant, but not the A.
-  // We want the original A variants, and this #undef is the only
-  // way I see to get them.  Redefining it when we're done prevents us
-  // from affecting other .cc files.
-# ifdef MODULEENTRY32  // Alias of W
-#   undef MODULEENTRY32
-  MODULEENTRY32 module_;   // info about current dll (and dll iterator)
-#   define MODULEENTRY32 MODULEENTRY32W
-# else  // It's the ascii, the one we want.
-  MODULEENTRY32 module_;   // info about current dll (and dll iterator)
-# endif
-#elif defined(__MACH__)
-  int current_image_; // dll's are called "images" in macos parlance
-  int current_load_cmd_;   // the segment of this dll we're examining
-#elif defined(__sun__)     // Solaris
-  int fd_;
-  char current_filename_[PATH_MAX];
-#else
-  int fd_;            // filehandle on /proc/*/maps
-#endif
-  pid_t pid_;
-  char flags_[10];
-  Buffer* dynamic_buffer_;  // dynamically-allocated Buffer
-  bool using_maps_backing_; // true if we are looking at maps_backing instead of maps.
-};
-
-#endif  /* #ifndef SWIG */
-
-// Helper routines
-
-namespace tcmalloc {
-int FillProcSelfMaps(char buf[], int size, bool* wrote_all);
-void DumpProcSelfMaps(RawFD fd);
-}
-
-#endif   /* #ifndef _SYSINFO_H_ */
diff --git a/third_party/tcmalloc/chromium/src/base/thread_annotations.h b/third_party/tcmalloc/chromium/src/base/thread_annotations.h
deleted file mode 100644
index 79962809..0000000
--- a/third_party/tcmalloc/chromium/src/base/thread_annotations.h
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Le-Chun Wu
-//
-// This header file contains the macro definitions for thread safety
-// annotations that allow the developers to document the locking policies
-// of their multi-threaded code. The annotations can also help program
-// analysis tools to identify potential thread safety issues.
-//
-// The annotations are implemented using clang's "attributes" extension.
-// Using the macros defined here instead of the raw clang attributes allows
-// for portability and future compatibility.
-//
-// This functionality is not yet fully implemented in perftools,
-// but may be one day.
-
-#ifndef BASE_THREAD_ANNOTATIONS_H_
-#define BASE_THREAD_ANNOTATIONS_H_
-
-
-#if defined(__clang__)
-#define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
-#else
-#define THREAD_ANNOTATION_ATTRIBUTE__(x)   // no-op
-#endif
-
-
-// Document if a shared variable/field needs to be protected by a lock.
-// GUARDED_BY allows the user to specify a particular lock that should be
-// held when accessing the annotated variable, while GUARDED_VAR only
-// indicates a shared variable should be guarded (by any lock). GUARDED_VAR
-// is primarily used when the client cannot express the name of the lock.
-#define GUARDED_BY(x)          THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
-#define GUARDED_VAR            THREAD_ANNOTATION_ATTRIBUTE__(guarded)
-
-// Document if the memory location pointed to by a pointer should be guarded
-// by a lock when dereferencing the pointer. Similar to GUARDED_VAR,
-// PT_GUARDED_VAR is primarily used when the client cannot express the name
-// of the lock. Note that a pointer variable to a shared memory location
-// could itself be a shared variable. For example, if a shared global pointer
-// q, which is guarded by mu1, points to a shared memory location that is
-// guarded by mu2, q should be annotated as follows:
-//     int *q GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
-#define PT_GUARDED_BY(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x))
-#define PT_GUARDED_VAR \
-  THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded)
-
-// Document the acquisition order between locks that can be held
-// simultaneously by a thread. For any two locks that need to be annotated
-// to establish an acquisition order, only one of them needs the annotation.
-// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER
-// and ACQUIRED_BEFORE.)
-#define ACQUIRED_AFTER(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x))
-#define ACQUIRED_BEFORE(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x))
-
-// The following three annotations document the lock requirements for
-// functions/methods.
-
-// Document if a function expects certain locks to be held before it is called
-#define EXCLUSIVE_LOCKS_REQUIRED(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x))
-
-#define SHARED_LOCKS_REQUIRED(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(x))
-
-// Document the locks acquired in the body of the function. These locks
-// cannot be held when calling this function (as google3's Mutex locks are
-// non-reentrant).
-#define LOCKS_EXCLUDED(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x))
-
-// Document the lock the annotated function returns without acquiring it.
-#define LOCK_RETURNED(x)       THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
-
-// Document if a class/type is a lockable type (such as the Mutex class).
-#define LOCKABLE               THREAD_ANNOTATION_ATTRIBUTE__(lockable)
-
-// Document if a class is a scoped lockable type (such as the MutexLock class).
-#define SCOPED_LOCKABLE        THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
-
-// The following annotations specify lock and unlock primitives.
-#define EXCLUSIVE_LOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(x))
-
-#define SHARED_LOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(x))
-
-#define EXCLUSIVE_TRYLOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(x))
-
-#define SHARED_TRYLOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(x))
-
-#define UNLOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(x))
-
-// An escape hatch for thread safety analysis to ignore the annotated function.
-#define NO_THREAD_SAFETY_ANALYSIS \
-  THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
-
-#endif  // BASE_THREAD_ANNOTATIONS_H_
diff --git a/third_party/tcmalloc/chromium/src/base/thread_lister.c b/third_party/tcmalloc/chromium/src/base/thread_lister.c
deleted file mode 100644
index 9dc8d72..0000000
--- a/third_party/tcmalloc/chromium/src/base/thread_lister.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright (c) 2005-2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-#include "config.h"
-
-#include "base/thread_lister.h"
-
-#include <stdio.h>         /* needed for NULL on some powerpc platforms (?!) */
-#include <sys/types.h>
-#include <unistd.h>        /* for getpid */
-
-#ifdef HAVE_SYS_PRCTL
-# include <sys/prctl.h>
-#endif
-
-#include "base/linuxthreads.h"
-/* Include other thread listers here that define THREADS macro
- * only when they can provide a good implementation.
- */
-
-#ifndef THREADS
-
-/* Default trivial thread lister for single-threaded applications,
- * or if the multi-threading code has not been ported, yet.
- */
-
-int TCMalloc_ListAllProcessThreads(void *parameter,
-				   ListAllProcessThreadsCallBack callback, ...) {
-  int rc;
-  va_list ap;
-  pid_t pid;
-
-#ifdef HAVE_SYS_PRCTL
-  int dumpable = prctl(PR_GET_DUMPABLE, 0);
-  if (!dumpable)
-    prctl(PR_SET_DUMPABLE, 1);
-#endif
-  va_start(ap, callback);
-  pid = getpid();
-  rc = callback(parameter, 1, &pid, ap);
-  va_end(ap);
-#ifdef HAVE_SYS_PRCTL
-  if (!dumpable)
-    prctl(PR_SET_DUMPABLE, 0);
-#endif
-  return rc;
-}
-
-int TCMalloc_ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
-  return 1;
-}
-
-#endif   /* ifndef THREADS */
diff --git a/third_party/tcmalloc/chromium/src/base/thread_lister.h b/third_party/tcmalloc/chromium/src/base/thread_lister.h
deleted file mode 100644
index 6e70b89..0000000
--- a/third_party/tcmalloc/chromium/src/base/thread_lister.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode: c; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* Copyright (c) 2005-2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-#ifndef _THREAD_LISTER_H
-#define _THREAD_LISTER_H
-
-#include <stdarg.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef int (*ListAllProcessThreadsCallBack)(void *parameter,
-                                             int num_threads,
-                                             pid_t *thread_pids,
-                                             va_list ap);
-
-/* This function gets the list of all linux threads of the current process
- * passes them to the 'callback' along with the 'parameter' pointer; at the
- * call back call time all the threads are paused via
- * PTRACE_ATTACH.
- * The callback is executed from a separate thread which shares only the
- * address space, the filesystem, and the filehandles with the caller. Most
- * notably, it does not share the same pid and ppid; and if it terminates,
- * the rest of the application is still there. 'callback' is supposed to do
- * or arrange for TCMalloc_ResumeAllProcessThreads. This happens automatically, if
- * the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous
- * signals are blocked. If the 'callback' decides to unblock them, it must
- * ensure that they cannot terminate the application, or that
- * TCMalloc_ResumeAllProcessThreads will get called.
- * It is an error for the 'callback' to make any library calls that could
- * acquire locks. Most notably, this means that most system calls have to
- * avoid going through libc. Also, this means that it is not legal to call
- * exit() or abort().
- * We return -1 on error and the return value of 'callback' on success.
- */
-int TCMalloc_ListAllProcessThreads(void *parameter,
-                                   ListAllProcessThreadsCallBack callback, ...);
-
-/* This function resumes the list of all linux threads that
- * TCMalloc_ListAllProcessThreads pauses before giving to its
- * callback.  The function returns non-zero if at least one thread was
- * suspended and has now been resumed.
- */
-int TCMalloc_ResumeAllProcessThreads(int num_threads, pid_t *thread_pids);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* _THREAD_LISTER_H */
diff --git a/third_party/tcmalloc/chromium/src/base/vdso_support.cc b/third_party/tcmalloc/chromium/src/base/vdso_support.cc
deleted file mode 100644
index c52fcf9..0000000
--- a/third_party/tcmalloc/chromium/src/base/vdso_support.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Pluzhnikov
-//
-// Allow dynamic symbol lookup in the kernel VDSO page.
-//
-// VDSOSupport -- a class representing kernel VDSO (if present).
-//
-
-#include "base/vdso_support.h"
-
-#ifdef HAVE_VDSO_SUPPORT     // defined in vdso_support.h
-
-#include <fcntl.h>
-#include <stddef.h>   // for ptrdiff_t
-
-#include "base/logging.h"
-#include "base/dynamic_annotations.h"
-#include "base/basictypes.h"  // for COMPILE_ASSERT
-
-#ifndef AT_SYSINFO_EHDR
-#define AT_SYSINFO_EHDR 33
-#endif
-
-namespace base {
-
-const void *VDSOSupport::vdso_base_ = ElfMemImage::kInvalidBase;
-VDSOSupport::VDSOSupport()
-    // If vdso_base_ is still set to kInvalidBase, we got here
-    // before VDSOSupport::Init has been called. Call it now.
-    : image_(vdso_base_ == ElfMemImage::kInvalidBase ? Init() : vdso_base_) {
-}
-
-// NOTE: we can't use GoogleOnceInit() below, because we can be
-// called by tcmalloc, and none of the *once* stuff may be functional yet.
-//
-// In addition, we hope that the VDSOSupportHelper constructor
-// causes this code to run before there are any threads, and before
-// InitGoogle() has executed any chroot or setuid calls.
-//
-// Finally, even if there is a race here, it is harmless, because
-// the operation should be idempotent.
-const void *VDSOSupport::Init() {
-  if (vdso_base_ == ElfMemImage::kInvalidBase) {
-    // Valgrind zaps AT_SYSINFO_EHDR and friends from the auxv[]
-    // on stack, and so glibc works as if VDSO was not present.
-    // But going directly to kernel via /proc/self/auxv below bypasses
-    // Valgrind zapping. So we check for Valgrind separately.
-    if (RunningOnValgrind()) {
-      vdso_base_ = NULL;
-      return NULL;
-    }
-    int fd = open("/proc/self/auxv", O_RDONLY);
-    if (fd == -1) {
-      // Kernel too old to have a VDSO.
-      vdso_base_ = NULL;
-      return NULL;
-    }
-    ElfW(auxv_t) aux;
-    while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) {
-      if (aux.a_type == AT_SYSINFO_EHDR) {
-        COMPILE_ASSERT(sizeof(vdso_base_) == sizeof(aux.a_un.a_val),
-                       unexpected_sizeof_pointer_NE_sizeof_a_val);
-        vdso_base_ = reinterpret_cast<void *>(aux.a_un.a_val);
-        break;
-      }
-    }
-    close(fd);
-    if (vdso_base_ == ElfMemImage::kInvalidBase) {
-      // Didn't find AT_SYSINFO_EHDR in auxv[].
-      vdso_base_ = NULL;
-    }
-  }
-  return vdso_base_;
-}
-
-const void *VDSOSupport::SetBase(const void *base) {
-  CHECK(base != ElfMemImage::kInvalidBase);
-  const void *old_base = vdso_base_;
-  vdso_base_ = base;
-  image_.Init(base);
-  return old_base;
-}
-
-bool VDSOSupport::LookupSymbol(const char *name,
-                               const char *version,
-                               int type,
-                               SymbolInfo *info) const {
-  return image_.LookupSymbol(name, version, type, info);
-}
-
-bool VDSOSupport::LookupSymbolByAddress(const void *address,
-                                        SymbolInfo *info_out) const {
-  return image_.LookupSymbolByAddress(address, info_out);
-}
-
-// We need to make sure VDSOSupport::Init() is called before
-// the main() runs, since it might do something like setuid or
-// chroot.  If VDSOSupport
-// is used in any global constructor, this will happen, since
-// VDSOSupport's constructor calls Init.  But if not, we need to
-// ensure it here, with a global constructor of our own.  This
-// is an allowed exception to the normal rule against non-trivial
-// global constructors.
-static class VDSOInitHelper {
- public:
-  VDSOInitHelper() { VDSOSupport::Init(); }
-} vdso_init_helper;
-}
-
-#endif  // HAVE_VDSO_SUPPORT
diff --git a/third_party/tcmalloc/chromium/src/base/vdso_support.h b/third_party/tcmalloc/chromium/src/base/vdso_support.h
deleted file mode 100644
index cdd8405..0000000
--- a/third_party/tcmalloc/chromium/src/base/vdso_support.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Pluzhnikov
-//
-// Allow dynamic symbol lookup in the kernel VDSO page.
-//
-// VDSO stands for "Virtual Dynamic Shared Object" -- a page of
-// executable code, which looks like a shared library, but doesn't
-// necessarily exist anywhere on disk, and which gets mmap()ed into
-// every process by kernels which support VDSO, such as 2.6.x for 32-bit
-// executables, and 2.6.24 and above for 64-bit executables.
-//
-// More details could be found here:
-// http://www.trilithium.com/johan/2005/08/linux-gate/
-//
-// VDSOSupport -- a class representing kernel VDSO (if present).
-//
-// Example usage:
-//  VDSOSupport vdso;
-//  VDSOSupport::SymbolInfo info;
-//  typedef (*FN)(unsigned *, void *, void *);
-//  FN fn = NULL;
-//  if (vdso.LookupSymbol("__vdso_getcpu", "LINUX_2.6", STT_FUNC, &info)) {
-//     fn = reinterpret_cast<FN>(info.address);
-//  }
-
-#ifndef BASE_VDSO_SUPPORT_H_
-#define BASE_VDSO_SUPPORT_H_
-
-#include <config.h>
-#include "base/basictypes.h"
-#include "base/elf_mem_image.h"
-
-#ifdef HAVE_ELF_MEM_IMAGE
-
-// Enable VDSO support only for the architectures/operating systems that
-// support it.
-#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
-#define HAVE_VDSO_SUPPORT 1
-#endif
-
-#include <stdlib.h>     // for NULL
-
-namespace base {
-
-// NOTE: this class may be used from within tcmalloc, and can not
-// use any memory allocation routines.
-class VDSOSupport {
- public:
-  VDSOSupport();
-
-  VDSOSupport(const VDSOSupport&) = delete;
-  VDSOSupport& operator=(const VDSOSupport&) = delete;
-
-  typedef ElfMemImage::SymbolInfo SymbolInfo;
-  typedef ElfMemImage::SymbolIterator SymbolIterator;
-
-  // Answers whether we have a vdso at all.
-  bool IsPresent() const { return image_.IsPresent(); }
-
-  // Allow to iterate over all VDSO symbols.
-  SymbolIterator begin() const { return image_.begin(); }
-  SymbolIterator end() const { return image_.end(); }
-
-  // Look up versioned dynamic symbol in the kernel VDSO.
-  // Returns false if VDSO is not present, or doesn't contain given
-  // symbol/version/type combination.
-  // If info_out != NULL, additional details are filled in.
-  bool LookupSymbol(const char *name, const char *version,
-                    int symbol_type, SymbolInfo *info_out) const;
-
-  // Find info about symbol (if any) which overlaps given address.
-  // Returns true if symbol was found; false if VDSO isn't present
-  // or doesn't have a symbol overlapping given address.
-  // If info_out != NULL, additional details are filled in.
-  bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const;
-
-  // Used only for testing. Replace real VDSO base with a mock.
-  // Returns previous value of vdso_base_. After you are done testing,
-  // you are expected to call SetBase() with previous value, in order to
-  // reset state to the way it was.
-  const void *SetBase(const void *s);
-
-  // Computes vdso_base_ and returns it. Should be called as early as
-  // possible; before any thread creation, chroot or setuid.
-  static const void *Init();
-
- private:
-  // image_ represents VDSO ELF image in memory.
-  // image_.ehdr_ == NULL implies there is no VDSO.
-  ElfMemImage image_;
-
-  // Cached value of auxv AT_SYSINFO_EHDR, computed once.
-  // This is a tri-state:
-  //   kInvalidBase   => value hasn't been determined yet.
-  //              0   => there is no VDSO.
-  //           else   => vma of VDSO Elf{32,64}_Ehdr.
-  //
-  // When testing with mock VDSO, low bit is set.
-  // The low bit is always available because vdso_base_ is
-  // page-aligned.
-  static const void *vdso_base_;
-};
-
-}  // namespace base
-
-#endif  // HAVE_ELF_MEM_IMAGE
-
-#endif  // BASE_VDSO_SUPPORT_H_
diff --git a/third_party/tcmalloc/chromium/src/central_freelist.cc b/third_party/tcmalloc/chromium/src/central_freelist.cc
deleted file mode 100644
index ac2cbb0..0000000
--- a/third_party/tcmalloc/chromium/src/central_freelist.cc
+++ /dev/null
@@ -1,388 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include "central_freelist.h"
-#include <algorithm>
-#include "config.h"
-#include "free_list.h"         // for FL_Next, FL_Push, etc
-#include "internal_logging.h"  // for ASSERT, MESSAGE
-#include "page_heap.h"         // for PageHeap
-#include "static_vars.h"       // for Static
-
-using std::min;
-using std::max;
-
-namespace tcmalloc {
-
-void CentralFreeList::Init(size_t cl) {
-  size_class_ = cl;
-  tcmalloc::DLL_Init(&empty_);
-  tcmalloc::DLL_Init(&nonempty_);
-  num_spans_ = 0;
-  counter_ = 0;
-
-  max_cache_size_ = kMaxNumTransferEntries;
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-  // Disable the transfer cache for the small footprint case.
-  cache_size_ = 0;
-#else
-  cache_size_ = 16;
-#endif
-  if (cl > 0) {
-    // Limit the maximum size of the cache based on the size class.  If this
-    // is not done, large size class objects will consume a lot of memory if
-    // they just sit in the transfer cache.
-    int32_t bytes = Static::sizemap()->ByteSizeForClass(cl);
-    int32_t objs_to_move = Static::sizemap()->num_objects_to_move(cl);
-
-    ASSERT(objs_to_move > 0 && bytes > 0);
-    // Limit each size class cache to at most 1MB of objects or one entry,
-    // whichever is greater. Total transfer cache memory used across all
-    // size classes then can't be greater than approximately
-    // 1MB * kMaxNumTransferEntries.
-    // min and max are in parens to avoid macro-expansion on windows.
-    max_cache_size_ = (min)(max_cache_size_,
-                          (max)(1, (1024 * 1024) / (bytes * objs_to_move)));
-    cache_size_ = (min)(cache_size_, max_cache_size_);
-  }
-  used_slots_ = 0;
-  ASSERT(cache_size_ <= max_cache_size_);
-}
-
-void CentralFreeList::ReleaseListToSpans(void* start) {
-  while (start) {
-    void* next = FL_Next(start);
-    ReleaseToSpans(start);
-    start = next;
-  }
-}
-
-// MapObjectToSpan should logically be part of ReleaseToSpans.  But
-// this triggers an optimization bug in gcc 4.5.0.  Moving to a
-// separate function, and making sure that function isn't inlined,
-// seems to fix the problem.  It also should be fixed for gcc 4.5.1.
-static
-#if __GNUC__ == 4 && __GNUC_MINOR__ == 5 && __GNUC_PATCHLEVEL__ == 0
-__attribute__ ((noinline))
-#endif
-Span* MapObjectToSpan(void* object) {
-  const PageID p = reinterpret_cast<uintptr_t>(object) >> kPageShift;
-  Span* span = Static::pageheap()->GetDescriptor(p);
-  return span;
-}
-
-void CentralFreeList::ReleaseToSpans(void* object) {
-  Span* span = MapObjectToSpan(object);
-  ASSERT(span != NULL);
-  ASSERT(span->refcount > 0);
-
-  // If span is empty, move it to non-empty list
-  if (span->objects == NULL) {
-    tcmalloc::DLL_Remove(span);
-    tcmalloc::DLL_Prepend(&nonempty_, span);
-    Event(span, 'N', 0);
-  }
-
-  // The following check is expensive, so it is disabled by default
-  if (false) {
-    // Check that object does not occur in list
-    int got = 0;
-    for (void* p = span->objects; p != NULL; p = FL_Next(p)) {
-      ASSERT(p != object);
-      got++;
-    }
-    ASSERT(got + span->refcount ==
-           (span->length<<kPageShift) /
-           Static::sizemap()->ByteSizeForClass(span->sizeclass));
-  }
-
-  counter_++;
-  span->refcount--;
-  if (span->refcount == 0) {
-    Event(span, '#', 0);
-    counter_ -= ((span->length<<kPageShift) /
-                 Static::sizemap()->ByteSizeForClass(span->sizeclass));
-    tcmalloc::DLL_Remove(span);
-    --num_spans_;
-
-    // Release central list lock while operating on pageheap
-    lock_.Unlock();
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      Static::pageheap()->Delete(span);
-    }
-    lock_.Lock();
-  } else {
-    FL_Push(&(span->objects), object);
-  }
-}
-
-bool CentralFreeList::EvictRandomSizeClass(
-    int locked_size_class, bool force) {
-  static int race_counter = 0;
-  int t = race_counter++;  // Updated without a lock, but who cares.
-  if (t >= Static::num_size_classes()) {
-    while (t >= Static::num_size_classes()) {
-      t -= Static::num_size_classes();
-    }
-    race_counter = t;
-  }
-  ASSERT(t >= 0);
-  ASSERT(t < Static::num_size_classes());
-  if (t == locked_size_class) return false;
-  return Static::central_cache()[t].ShrinkCache(locked_size_class, force);
-}
-
-bool CentralFreeList::MakeCacheSpace() {
-  // Is there room in the cache?
-  if (used_slots_ < cache_size_) return true;
-  // Check if we can expand this cache?
-  if (cache_size_ == max_cache_size_) return false;
-  // Ok, we'll try to grab an entry from some other size class.
-  if (EvictRandomSizeClass(size_class_, false) ||
-      EvictRandomSizeClass(size_class_, true)) {
-    // Succeeded in evicting, we're going to make our cache larger.
-    // However, we may have dropped and re-acquired the lock in
-    // EvictRandomSizeClass (via ShrinkCache and the LockInverter), so the
-    // cache_size may have changed.  Therefore, check and verify that it is
-    // still OK to increase the cache_size.
-    if (cache_size_ < max_cache_size_) {
-      cache_size_++;
-      return true;
-    }
-  }
-  return false;
-}
-
-
-namespace {
-class LockInverter {
- private:
-  SpinLock *held_, *temp_;
- public:
-  inline explicit LockInverter(SpinLock* held, SpinLock *temp)
-    : held_(held), temp_(temp) { held_->Unlock(); temp_->Lock(); }
-  inline ~LockInverter() { temp_->Unlock(); held_->Lock();  }
-};
-}
-
-// This function is marked as NO_THREAD_SAFETY_ANALYSIS because it uses
-// LockInverter to release one lock and acquire another in scoped-lock
-// style, which our current annotation/analysis does not support.
-bool CentralFreeList::ShrinkCache(int locked_size_class, bool force)
-    NO_THREAD_SAFETY_ANALYSIS {
-  // Start with a quick check without taking a lock.
-  if (cache_size_ == 0) return false;
-  // We don't evict from a full cache unless we are 'forcing'.
-  if (force == false && used_slots_ == cache_size_) return false;
-
-  // Grab lock, but first release the other lock held by this thread.  We use
-  // the lock inverter to ensure that we never hold two size class locks
-  // concurrently.  That can create a deadlock because there is no well
-  // defined nesting order.
-  LockInverter li(&Static::central_cache()[locked_size_class].lock_, &lock_);
-  ASSERT(used_slots_ <= cache_size_);
-  ASSERT(0 <= cache_size_);
-  if (cache_size_ == 0) return false;
-  if (used_slots_ == cache_size_) {
-    if (force == false) return false;
-    // ReleaseListToSpans releases the lock, so we have to make all the
-    // updates to the central list before calling it.
-    cache_size_--;
-    used_slots_--;
-    ReleaseListToSpans(tc_slots_[used_slots_].head);
-    return true;
-  }
-  cache_size_--;
-  return true;
-}
-
-void CentralFreeList::InsertRange(void *start, void *end, int N) {
-  SpinLockHolder h(&lock_);
-  if (N == Static::sizemap()->num_objects_to_move(size_class_) &&
-    MakeCacheSpace()) {
-    int slot = used_slots_++;
-    ASSERT(slot >=0);
-    ASSERT(slot < max_cache_size_);
-    TCEntry *entry = &tc_slots_[slot];
-    entry->head = start;
-    entry->tail = end;
-    return;
-  }
-  ReleaseListToSpans(start);
-}
-
-int CentralFreeList::RemoveRange(void **start, void **end, int N) {
-  ASSERT(N > 0);
-  lock_.Lock();
-  if (N == Static::sizemap()->num_objects_to_move(size_class_) &&
-      used_slots_ > 0) {
-    int slot = --used_slots_;
-    ASSERT(slot >= 0);
-    TCEntry *entry = &tc_slots_[slot];
-    *start = entry->head;
-    *end = entry->tail;
-    lock_.Unlock();
-    return N;
-  }
-
-  int result = 0;
-  *start = NULL;
-  *end = NULL;
-  // TODO: Prefetch multiple TCEntries?
-  result = FetchFromOneSpansSafe(N, start, end);
-  if (result != 0) {
-    while (result < N) {
-      int n;
-      void* head = NULL;
-      void* tail = NULL;
-      n = FetchFromOneSpans(N - result, &head, &tail);
-      if (!n) break;
-      result += n;
-      FL_PushRange(start, head, tail);
-    }
-  }
-  lock_.Unlock();
-  return result;
-}
-
-
-int CentralFreeList::FetchFromOneSpansSafe(int N, void **start, void **end) {
-  int result = FetchFromOneSpans(N, start, end);
-  if (!result) {
-    Populate();
-    result = FetchFromOneSpans(N, start, end);
-  }
-  return result;
-}
-
-int CentralFreeList::FetchFromOneSpans(int N, void **start, void **end) {
-  if (tcmalloc::DLL_IsEmpty(&nonempty_)) return 0;
-  Span* span = nonempty_.next;
-
-  ASSERT(span->objects != NULL);
-
-  int result = 0;
-  void *prev, *curr;
-  curr = span->objects;
-  do {
-    prev = curr;
-    curr = FL_Next(curr);
-  } while (++result < N && curr != NULL);
-
-  if (curr == NULL) {
-    // Move to empty list
-    tcmalloc::DLL_Remove(span);
-    tcmalloc::DLL_Prepend(&empty_, span);
-    Event(span, 'E', 0);
-  } else {
-    FL_SetPrevious(curr, NULL);
-  }
-
-  *start = span->objects;
-  *end = prev;
-  span->objects = curr;
-  FL_SetNext(*end, NULL);
-  FL_SetPrevious(*start, NULL);
-  span->refcount += result;
-  counter_ -= result;
-  return result;
-}
-
-// Fetch memory from the system and add to the central cache freelist.
-void CentralFreeList::Populate() {
-  // Release central list lock while operating on pageheap
-  lock_.Unlock();
-  const size_t npages = Static::sizemap()->class_to_pages(size_class_);
-
-  Span* span;
-  {
-    SpinLockHolder h(Static::pageheap_lock());
-    span = Static::pageheap()->New(npages);
-    if (span) Static::pageheap()->RegisterSizeClass(span, size_class_);
-  }
-  if (span == NULL) {
-    Log(kLog, __FILE__, __LINE__,
-        "tcmalloc: allocation failed", npages << kPageShift);
-    lock_.Lock();
-    return;
-  }
-  ASSERT(span->length == npages);
-  // Cache sizeclass info eagerly.  Locking is not necessary.
-  // (Instead of being eager, we could just replace any stale info
-  // about this span, but that seems to be no better in practice.)
-  for (int i = 0; i < npages; i++) {
-    Static::pageheap()->SetCachedSizeClass(span->start + i, size_class_);
-  }
-
-  // Split the block into pieces and add to the free-list
-  // TODO: coloring of objects to avoid cache conflicts?
-  void* list = NULL;
-  char* ptr = reinterpret_cast<char*>(span->start << kPageShift);
-  char* limit = ptr + (npages << kPageShift);
-  const size_t size = Static::sizemap()->ByteSizeForClass(size_class_);
-  int num = 0;
-  while (ptr + size <= limit) {
-    FL_Push(&list, ptr);
-    ptr += size;
-    num++;
-  }
-  ASSERT(ptr <= limit);
-  span->objects = list;
-  span->refcount = 0; // No sub-object in use yet
-
-  // Add span to list of non-empty spans
-  lock_.Lock();
-  tcmalloc::DLL_Prepend(&nonempty_, span);
-  ++num_spans_;
-  counter_ += num;
-}
-
-int CentralFreeList::tc_length() {
-  SpinLockHolder h(&lock_);
-  return used_slots_ * Static::sizemap()->num_objects_to_move(size_class_);
-}
-
-size_t CentralFreeList::OverheadBytes() {
-  SpinLockHolder h(&lock_);
-  if (size_class_ == 0) {  // 0 holds the 0-sized allocations
-    return 0;
-  }
-  const size_t pages_per_span = Static::sizemap()->class_to_pages(size_class_);
-  const size_t object_size = Static::sizemap()->class_to_size(size_class_);
-  ASSERT(object_size > 0);
-  const size_t overhead_per_span = (pages_per_span * kPageSize) % object_size;
-  return num_spans_ * overhead_per_span;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/central_freelist.h b/third_party/tcmalloc/chromium/src/central_freelist.h
deleted file mode 100644
index 0f66e0c..0000000
--- a/third_party/tcmalloc/chromium/src/central_freelist.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#ifndef TCMALLOC_CENTRAL_FREELIST_H_
-#define TCMALLOC_CENTRAL_FREELIST_H_
-
-#include "config.h"
-#include <stddef.h>                     // for size_t
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for int32_t
-#endif
-#include "base/spinlock.h"
-#include "base/thread_annotations.h"
-#include "common.h"
-#include "span.h"
-
-namespace tcmalloc {
-
-// Data kept per size-class in central cache.
-class CentralFreeList {
- public:
-  // A CentralFreeList may be used before its constructor runs.
-  // So we prevent lock_'s constructor from doing anything to the
-  // lock_ state.
-  CentralFreeList() : lock_(base::LINKER_INITIALIZED) { }
-
-  void Init(size_t cl);
-
-  // These methods all do internal locking.
-
-  // Insert the specified range into the central freelist.  N is the number of
-  // elements in the range.  RemoveRange() is the opposite operation.
-  void InsertRange(void *start, void *end, int N);
-
-  // Returns the actual number of fetched elements and sets *start and *end.
-  int RemoveRange(void **start, void **end, int N);
-
-  // Returns the number of free objects in cache.
-  int length() {
-    SpinLockHolder h(&lock_);
-    return counter_;
-  }
-
-  // Returns the number of free objects in the transfer cache.
-  int tc_length();
-
-  // Returns the memory overhead (internal fragmentation) attributable
-  // to the freelist.  This is memory lost when the size of elements
-  // in a freelist doesn't exactly divide the page-size (an 8192-byte
-  // page full of 5-byte objects would have 2 bytes memory overhead).
-  size_t OverheadBytes();
-
-  // Lock/Unlock the internal SpinLock. Used on the pthread_atfork call
-  // to set the lock in a consistent state before the fork.
-  void Lock() EXCLUSIVE_LOCK_FUNCTION(lock_) {
-    lock_.Lock();
-  }
-
-  void Unlock() UNLOCK_FUNCTION(lock_) {
-    lock_.Unlock();
-  }
-
- private:
-  // TransferCache is used to cache transfers of
-  // sizemap.num_objects_to_move(size_class) back and forth between
-  // thread caches and the central cache for a given size class.
-  struct TCEntry {
-    void *head;  // Head of chain of objects.
-    void *tail;  // Tail of chain of objects.
-  };
-
-  // A central cache freelist can have anywhere from 0 to kMaxNumTransferEntries
-  // slots to put link list chains into.
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-  // For the small memory model, the transfer cache is not used.
-  static const int kMaxNumTransferEntries = 0;
-#else
-  // Starting point for the the maximum number of entries in the transfer cache.
-  // This actual maximum for a given size class may be lower than this
-  // maximum value.
-  static const int kMaxNumTransferEntries = 64;
-#endif
-
-  // REQUIRES: lock_ is held
-  // Remove object from cache and return.
-  // Return NULL if no free entries in cache.
-  int FetchFromOneSpans(int N, void **start, void **end) EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ is held
-  // Remove object from cache and return.  Fetches
-  // from pageheap if cache is empty.  Only returns
-  // NULL on allocation failure.
-  int FetchFromOneSpansSafe(int N, void **start, void **end) EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ is held
-  // Release a linked list of objects to spans.
-  // May temporarily release lock_.
-  void ReleaseListToSpans(void *start) EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ is held
-  // Release an object to spans.
-  // May temporarily release lock_.
-  void ReleaseToSpans(void* object) EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ is held
-  // Populate cache by fetching from the page heap.
-  // May temporarily release lock_.
-  void Populate() EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock is held.
-  // Tries to make room for a TCEntry.  If the cache is full it will try to
-  // expand it at the cost of some other cache size.  Return false if there is
-  // no space.
-  bool MakeCacheSpace() EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ for locked_size_class is held.
-  // Picks a "random" size class to steal TCEntry slot from.  In reality it
-  // just iterates over the sizeclasses but does so without taking a lock.
-  // Returns true on success.
-  // May temporarily lock a "random" size class.
-  static bool EvictRandomSizeClass(int locked_size_class, bool force);
-
-  // REQUIRES: lock_ is *not* held.
-  // Tries to shrink the Cache.  If force is true it will relase objects to
-  // spans if it allows it to shrink the cache.  Return false if it failed to
-  // shrink the cache.  Decrements cache_size_ on succeess.
-  // May temporarily take lock_.  If it takes lock_, the locked_size_class
-  // lock is released to keep the thread from holding two size class locks
-  // concurrently which could lead to a deadlock.
-  bool ShrinkCache(int locked_size_class, bool force) LOCKS_EXCLUDED(lock_);
-
-  // This lock protects all the data members.  cached_entries and cache_size_
-  // may be looked at without holding the lock.
-  SpinLock lock_;
-
-  // We keep linked lists of empty and non-empty spans.
-  size_t   size_class_;     // My size class
-  Span     empty_;          // Dummy header for list of empty spans
-  Span     nonempty_;       // Dummy header for list of non-empty spans
-  size_t   num_spans_;      // Number of spans in empty_ plus nonempty_
-  size_t   counter_;        // Number of free objects in cache entry
-
-  // Here we reserve space for TCEntry cache slots.  Space is preallocated
-  // for the largest possible number of entries than any one size class may
-  // accumulate.  Not all size classes are allowed to accumulate
-  // kMaxNumTransferEntries, so there is some wasted space for those size
-  // classes.
-  TCEntry tc_slots_[kMaxNumTransferEntries];
-
-  // Number of currently used cached entries in tc_slots_.  This variable is
-  // updated under a lock but can be read without one.
-  int32_t used_slots_;
-  // The current number of slots for this size class.  This is an
-  // adaptive value that is increased if there is lots of traffic
-  // on a given size class.
-  int32_t cache_size_;
-  // Maximum size of the cache for a given size class.
-  int32_t max_cache_size_;
-};
-
-// Pads each CentralCache object to multiple of 64 bytes.  Since some
-// compilers (such as MSVC) don't like it when the padding is 0, I use
-// template specialization to remove the padding entirely when
-// sizeof(CentralFreeList) is a multiple of 64.
-template<int kFreeListSizeMod64>
-class CentralFreeListPaddedTo : public CentralFreeList {
- private:
-  char pad_[64 - kFreeListSizeMod64];
-};
-
-template<>
-class CentralFreeListPaddedTo<0> : public CentralFreeList {
-};
-
-class CentralFreeListPadded : public CentralFreeListPaddedTo<
-  sizeof(CentralFreeList) % 64> {
-};
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_CENTRAL_FREELIST_H_
diff --git a/third_party/tcmalloc/chromium/src/common.cc b/third_party/tcmalloc/chromium/src/common.cc
deleted file mode 100644
index 170ce7d3..0000000
--- a/third_party/tcmalloc/chromium/src/common.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <stdlib.h> // for getenv and strtol
-#include "config.h"
-#include "common.h"
-#include "system-alloc.h"
-#include "base/spinlock.h"
-#include "getenv_safe.h" // TCMallocGetenvSafe
-
-#if defined(HAVE_UNISTD_H) && defined(HAVE_GETPAGESIZE)
-#include <unistd.h>  // for getpagesize
-#endif
-
-namespace tcmalloc {
-
-// Define the maximum number of object per classe type to transfer between
-// thread and central caches.
-static int32 FLAGS_tcmalloc_transfer_num_objects;
-
-static const int32 kDefaultTransferNumObjecs = 32;
-
-// The init function is provided to explicit initialize the variable value
-// from the env. var to avoid C++ global construction that might defer its
-// initialization after a malloc/new call.
-static inline void InitTCMallocTransferNumObjects()
-{
-  if (FLAGS_tcmalloc_transfer_num_objects == 0) {
-    const char *envval = TCMallocGetenvSafe("TCMALLOC_TRANSFER_NUM_OBJ");
-    FLAGS_tcmalloc_transfer_num_objects = !envval ? kDefaultTransferNumObjecs :
-      strtol(envval, NULL, 10);
-  }
-}
-
-// Note: the following only works for "n"s that fit in 32-bits, but
-// that is fine since we only use it for small sizes.
-static inline int LgFloor(size_t n) {
-  int log = 0;
-  for (int i = 4; i >= 0; --i) {
-    int shift = (1 << i);
-    size_t x = n >> shift;
-    if (x != 0) {
-      n = x;
-      log += shift;
-    }
-  }
-  ASSERT(n == 1);
-  return log;
-}
-
-int AlignmentForSize(size_t size) {
-  int alignment = kAlignment;
-  if (size > kMaxSize) {
-    // Cap alignment at kPageSize for large sizes.
-    alignment = kPageSize;
-  } else if (size >= 128) {
-    // Space wasted due to alignment is at most 1/8, i.e., 12.5%.
-    alignment = (1 << LgFloor(size)) / 8;
-  } else if (size >= kMinAlign) {
-    // We need an alignment of at least 16 bytes to satisfy
-    // requirements for some SSE types.
-    alignment = kMinAlign;
-  }
-  // Maximum alignment allowed is page size alignment.
-  if (alignment > kPageSize) {
-    alignment = kPageSize;
-  }
-  CHECK_CONDITION(size < kMinAlign || alignment >= kMinAlign);
-  CHECK_CONDITION((alignment & (alignment - 1)) == 0);
-  return alignment;
-}
-
-int SizeMap::NumMoveSize(size_t size) {
-  if (size == 0) return 0;
-  // Use approx 64k transfers between thread and central caches.
-  int num = static_cast<int>(64.0 * 1024.0 / size);
-  if (num < 2) num = 2;
-
-  // Avoid bringing too many objects into small object free lists.
-  // If this value is too large:
-  // - We waste memory with extra objects sitting in the thread caches.
-  // - The central freelist holds its lock for too long while
-  //   building a linked list of objects, slowing down the allocations
-  //   of other threads.
-  // If this value is too small:
-  // - We go to the central freelist too often and we have to acquire
-  //   its lock each time.
-  // This value strikes a balance between the constraints above.
-  if (num > FLAGS_tcmalloc_transfer_num_objects)
-    num = FLAGS_tcmalloc_transfer_num_objects;
-
-  return num;
-}
-
-// Initialize the mapping arrays
-void SizeMap::Init() {
-  InitTCMallocTransferNumObjects();
-
-  // Do some sanity checking on add_amount[]/shift_amount[]/class_array[]
-  if (ClassIndex(0) != 0) {
-    Log(kCrash, __FILE__, __LINE__,
-        "Invalid class index for size 0", ClassIndex(0));
-  }
-  if (ClassIndex(kMaxSize) >= sizeof(class_array_)) {
-    Log(kCrash, __FILE__, __LINE__,
-        "Invalid class index for kMaxSize", ClassIndex(kMaxSize));
-  }
-
-  // Compute the size classes we want to use
-  int sc = 1;   // Next size class to assign
-  int alignment = kAlignment;
-  CHECK_CONDITION(kAlignment <= kMinAlign);
-  for (size_t size = kMinClassSize; size <= kMaxSize; size += alignment) {
-    alignment = AlignmentForSize(size);
-    CHECK_CONDITION((size % alignment) == 0);
-
-    int blocks_to_move = NumMoveSize(size) / 4;
-    size_t psize = 0;
-    do {
-      psize += kPageSize;
-      // Allocate enough pages so leftover is less than 1/8 of total.
-      // This bounds wasted space to at most 12.5%.
-      while ((psize % size) > (psize >> 3)) {
-        psize += kPageSize;
-      }
-      // Continue to add pages until there are at least as many objects in
-      // the span as are needed when moving objects from the central
-      // freelists and spans to the thread caches.
-    } while ((psize / size) < (blocks_to_move));
-    const size_t my_pages = psize >> kPageShift;
-
-    if (sc > 1 && my_pages == class_to_pages_[sc-1]) {
-      // See if we can merge this into the previous class without
-      // increasing the fragmentation of the previous class.
-      const size_t my_objects = (my_pages << kPageShift) / size;
-      const size_t prev_objects = (class_to_pages_[sc-1] << kPageShift)
-                                  / class_to_size_[sc-1];
-      if (my_objects == prev_objects) {
-        // Adjust last class to include this size
-        class_to_size_[sc-1] = size;
-        continue;
-      }
-    }
-
-    // Add new class
-    class_to_pages_[sc] = my_pages;
-    class_to_size_[sc] = size;
-    sc++;
-  }
-  num_size_classes = sc;
-  if (sc > kClassSizesMax) {
-    Log(kCrash, __FILE__, __LINE__,
-        "too many size classes: (found vs. max)", sc, kClassSizesMax);
-  }
-
-  // Initialize the mapping arrays
-  int next_size = 0;
-  for (int c = 1; c < num_size_classes; c++) {
-    const int max_size_in_class = class_to_size_[c];
-    for (int s = next_size; s <= max_size_in_class; s += kAlignment) {
-      class_array_[ClassIndex(s)] = c;
-    }
-    next_size = max_size_in_class + kAlignment;
-  }
-
-  // Double-check sizes just to be safe
-  for (size_t size = 0; size <= kMaxSize;) {
-    const int sc = SizeClass(size);
-    if (sc <= 0 || sc >= num_size_classes) {
-      Log(kCrash, __FILE__, __LINE__,
-          "Bad size class (class, size)", sc, size);
-    }
-    if (sc > 1 && size <= class_to_size_[sc-1]) {
-      Log(kCrash, __FILE__, __LINE__,
-          "Allocating unnecessarily large class (class, size)", sc, size);
-    }
-    const size_t s = class_to_size_[sc];
-    if (size > s || s == 0) {
-      Log(kCrash, __FILE__, __LINE__,
-          "Bad (class, size, requested)", sc, s, size);
-    }
-    if (size <= kMaxSmallSize) {
-      size += 8;
-    } else {
-      size += 128;
-    }
-  }
-
-  // Our fast-path aligned allocation functions rely on 'naturally
-  // aligned' sizes to produce aligned addresses. Lets check if that
-  // holds for size classes that we produced.
-  //
-  // I.e. we're checking that
-  //
-  // align = (1 << shift), malloc(i * align) % align == 0,
-  //
-  // for all align values up to kPageSize.
-  for (size_t align = kMinAlign; align <= kPageSize; align <<= 1) {
-    for (size_t size = align; size < kPageSize; size += align) {
-      CHECK_CONDITION(class_to_size_[SizeClass(size)] % align == 0);
-    }
-  }
-
-  // Initialize the num_objects_to_move array.
-  for (size_t cl = 1; cl  < num_size_classes; ++cl) {
-    num_objects_to_move_[cl] = NumMoveSize(ByteSizeForClass(cl));
-  }
-}
-
-// Metadata allocator -- keeps stats about how many bytes allocated.
-static uint64_t metadata_system_bytes_ = 0;
-
-// Use a chunk size <2MB to prevent systems with always enabled transparent huge
-// pages from backing the metadata allocation with large pages. Use of large
-// pages for these allocations causes an increase in resident memory.
-static const size_t kMetadataAllocChunkSize = 1 * 1024 * 1024;
-// As ThreadCache objects are allocated with MetaDataAlloc, and also
-// CACHELINE_ALIGNED, we must use the same alignment as TCMalloc_SystemAlloc.
-static const size_t kMetadataAllignment = sizeof(MemoryAligner);
-
-static char *metadata_chunk_alloc_;
-static size_t metadata_chunk_avail_;
-
-static SpinLock metadata_alloc_lock(SpinLock::LINKER_INITIALIZED);
-
-void* MetaDataAlloc(size_t bytes) {
-  static size_t pagesize;
-#ifdef HAVE_GETPAGESIZE
-  if (pagesize == 0)
-    pagesize = getpagesize();
-#endif
-
-  if (bytes + pagesize >= kMetadataAllocChunkSize) {
-    void* rv = TCMalloc_SystemAlloc(bytes + pagesize, NULL, pagesize);
-    if (rv != NULL) {
-      metadata_system_bytes_ += bytes + pagesize;
-
-      // This guard page protects the metadata from being corrupted by a
-      // buffer overrun. We currently have no mechanism for freeing it, since
-      // we never release the metadata buffer. If that changes we'll need to
-      // add something like TCMalloc_SystemRemoveGuard.
-      TCMalloc_SystemAddGuard(rv, bytes + pagesize);
-      rv = static_cast<void*>(static_cast<char*>(rv) + pagesize);
-    }
-    return rv;
-  }
-
-  SpinLockHolder h(&metadata_alloc_lock);
-
-  // the following works by essentially turning address to integer of
-  // log_2 kMetadataAllignment size and negating it. I.e. negated
-  // value + original value gets 0 and that's what we want modulo
-  // kMetadataAllignment. Note, we negate before masking higher bits
-  // off, otherwise we'd have to mask them off after negation anyways.
-  intptr_t alignment = -reinterpret_cast<intptr_t>(metadata_chunk_alloc_) & (kMetadataAllignment-1);
-
-  if (metadata_chunk_avail_ < bytes + alignment) {
-    size_t real_size;
-    void* ptr =
-        TCMalloc_SystemAlloc(kMetadataAllocChunkSize, &real_size, pagesize);
-    if (ptr == NULL) {
-      return NULL;
-    }
-
-    TCMalloc_SystemAddGuard(ptr, kMetadataAllocChunkSize);
-    metadata_chunk_alloc_ = static_cast<char*>(ptr) + pagesize;
-    metadata_chunk_avail_ = real_size - pagesize;
-    metadata_system_bytes_ += pagesize;
-
-    alignment = 0;
-  }
-
-  void *rv = static_cast<void *>(metadata_chunk_alloc_ + alignment);
-  bytes += alignment;
-  metadata_chunk_alloc_ += bytes;
-  metadata_chunk_avail_ -= bytes;
-  metadata_system_bytes_ += bytes;
-  return rv;
-}
-
-uint64_t metadata_system_bytes() { return metadata_system_bytes_; }
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/common.h b/third_party/tcmalloc/chromium/src/common.h
deleted file mode 100644
index 7ad83d3..0000000
--- a/third_party/tcmalloc/chromium/src/common.h
+++ /dev/null
@@ -1,328 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// Common definitions for tcmalloc code.
-
-#ifndef TCMALLOC_COMMON_H_
-#define TCMALLOC_COMMON_H_
-
-#include "config.h"
-#include <stddef.h>                     // for size_t
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uintptr_t, uint64_t
-#endif
-#include "base/basictypes.h"   // for LIKELY, etc
-#include "free_list.h"         // for SIZE_CLASS macros
-#include "internal_logging.h"  // for ASSERT, etc
-
-// Type that can hold a page number
-typedef uintptr_t PageID;
-
-// Type that can hold the length of a run of pages
-typedef uintptr_t Length;
-
-//-------------------------------------------------------------------
-// Configuration
-//-------------------------------------------------------------------
-
-#if defined(TCMALLOC_ALIGN_8BYTES)
-// Unless we force to use 8 bytes alignment we use an alignment of
-// at least 16 bytes to statisfy requirements for some SSE types.
-// Keep in mind when using the 16 bytes alignment you can have a space
-// waste due alignment of 25%. (eg malloc of 24 bytes will get 32 bytes)
-static const size_t kMinAlign   = 8;
-#else
-static const size_t kMinAlign   = 16;
-#endif
-
-// Using large pages speeds up the execution at a cost of larger memory use.
-// Deallocation may speed up by a factor as the page map gets 8x smaller, so
-// lookups in the page map result in fewer L2 cache misses, which translates to
-// speedup for application/platform combinations with high L2 cache pressure.
-// As the number of size classes increases with large pages, we increase
-// the thread cache allowance to avoid passing more free ranges to and from
-// central lists.  Also, larger pages are less likely to get freed.
-// These two factors cause a bounded increase in memory use.
-
-static const size_t kAlignment = 8;
-
-// Constants dependent on tcmalloc configuration and architecture.  Chromium
-// tunes these constants.
-// We need to guarantee the smallest class size is big enough to hold the
-// pointers that form the free list.
-static const size_t kNumFreeListPointers =
-    (tcmalloc::kSupportsDoublyLinkedList ? 2 : 1);
-static const size_t kLinkSize = kNumFreeListPointers * sizeof(void*);
-static const size_t kMinClassSize =
-    (kLinkSize > kAlignment ? kLinkSize : kAlignment);
-
-#if defined(TCMALLOC_32K_PAGES)
-static const size_t kPageShift  = 15;
-#elif defined(TCMALLOC_64K_PAGES)
-static const size_t kPageShift  = 16;
-#else
-// Original TCMalloc code used kPageShift == 13.  In Chromium, we changed
-// this to 12 (as was done in prior versions of TCMalloc).
-static const size_t kPageShift = 12;
-#endif
-
-static const size_t kClassSizesMax = 96;
-
-static const size_t kMaxThreadCacheSize = 4 << 20;
-
-static const size_t kPageSize   = 1 << kPageShift;
-// Original TCMalloc code used kMaxSize == 256 * 1024.  In Chromium, we
-// changed this to 32K.
-static const size_t kMaxSize = 32u * 1024;
-// For all span-lengths <= kMaxPages we keep an exact-size list in PageHeap.
-static const size_t kMaxPages = 1 << (20 - kPageShift);
-
-// Default bound on the total amount of thread caches.
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-// Make the overall thread cache no bigger than that of a single thread
-// for the small memory footprint case.
-static const size_t kDefaultOverallThreadCacheSize = kMaxThreadCacheSize;
-#else
-static const size_t kDefaultOverallThreadCacheSize = 8u * kMaxThreadCacheSize;
-#endif
-
-// Lower bound on the per-thread cache sizes
-static const size_t kMinThreadCacheSize = kMaxSize * 2;
-
-// The number of bytes one ThreadCache will steal from another when
-// the first ThreadCache is forced to Scavenge(), delaying the
-// next call to Scavenge for this thread.
-static const size_t kStealAmount = 1 << 16;
-
-// The number of times that a deallocation can cause a freelist to
-// go over its max_length() before shrinking max_length().
-static const int kMaxOverages = 3;
-
-// Maximum length we allow a per-thread free-list to have before we
-// move objects from it into the corresponding central free-list.  We
-// want this big to avoid locking the central free-list too often.  It
-// should not hurt to make this list somewhat big because the
-// scavenging code will shrink it down when its contents are not in use.
-static const int kMaxDynamicFreeListLength = 8192;
-
-static const Length kMaxValidPages = (~static_cast<Length>(0)) >> kPageShift;
-
-#if __aarch64__ || __x86_64__ || _M_AMD64 || _M_ARM64
-// All current x86_64 processors only look at the lower 48 bits in
-// virtual to physical address translation. The top 16 are all same as
-// bit 47. And bit 47 value 1 reserved for kernel-space addresses in
-// practice. So it is actually 47 usable bits from malloc
-// perspective. This lets us use faster two level page maps on this
-// architecture.
-//
-// There is very similar story on 64-bit arms except it has full 48
-// bits for user-space. Because of that, and because in principle OSes
-// can start giving some of highest-bit-set addresses to user-space,
-// we don't bother to limit x86 to 47 bits.
-//
-// As of now there are published plans to add more bits to x86-64
-// virtual address space, but since 48 bits has been norm for long
-// time and lots of software is relying on it, it will be opt-in from
-// OS perspective. So we can keep doing "48 bits" at least for now.
-static const int kAddressBits = (sizeof(void*) < 8 ? (8 * sizeof(void*)) : 48);
-#else
-// mipsen and ppcs have more general hardware so we have to support
-// full 64-bits of addresses.
-static const int kAddressBits = 8 * sizeof(void*);
-#endif
-
-namespace tcmalloc {
-
-// Convert byte size into pages.  This won't overflow, but may return
-// an unreasonably large value if bytes is huge enough.
-inline Length pages(size_t bytes) {
-  return (bytes >> kPageShift) +
-      ((bytes & (kPageSize - 1)) > 0 ? 1 : 0);
-}
-
-// For larger allocation sizes, we use larger memory alignments to
-// reduce the number of size classes.
-int AlignmentForSize(size_t size);
-
-// Size-class information + mapping
-class SizeMap {
- private:
-  //-------------------------------------------------------------------
-  // Mapping from size to size_class and vice versa
-  //-------------------------------------------------------------------
-
-  // Sizes <= 1024 have an alignment >= 8.  So for such sizes we have an
-  // array indexed by ceil(size/8).  Sizes > 1024 have an alignment >= 128.
-  // So for these larger sizes we have an array indexed by ceil(size/128).
-  //
-  // We flatten both logical arrays into one physical array and use
-  // arithmetic to compute an appropriate index.  The constants used by
-  // ClassIndex() were selected to make the flattening work.
-  //
-  // Examples:
-  //   Size       Expression                      Index
-  //   -------------------------------------------------------
-  //   0          (0 + 7) / 8                     0
-  //   1          (1 + 7) / 8                     1
-  //   ...
-  //   1024       (1024 + 7) / 8                  128
-  //   1025       (1025 + 127 + (120<<7)) / 128   129
-  //   ...
-  //   32768      (32768 + 127 + (120<<7)) / 128  376
-  static const int kMaxSmallSize = 1024;
-  static const size_t kClassArraySize =
-      ((kMaxSize + 127 + (120 << 7)) >> 7) + 1;
-  unsigned char class_array_[kClassArraySize];
-
-  static inline size_t SmallSizeClass(size_t s) {
-    return (static_cast<uint32_t>(s) + 7) >> 3;
-  }
-
-  static inline size_t LargeSizeClass(size_t s) {
-    return (static_cast<uint32_t>(s) + 127 + (120 << 7)) >> 7;
-  }
-
-  // If size is no more than kMaxSize, compute index of the
-  // class_array[] entry for it, putting the class index in output
-  // parameter idx and returning true. Otherwise return false.
-  static inline bool ATTRIBUTE_ALWAYS_INLINE ClassIndexMaybe(size_t s,
-                                                             uint32* idx) {
-    if (PREDICT_TRUE(s <= kMaxSmallSize)) {
-      *idx = (static_cast<uint32>(s) + 7) >> 3;
-      return true;
-    } else if (s <= kMaxSize) {
-      *idx = (static_cast<uint32>(s) + 127 + (120 << 7)) >> 7;
-      return true;
-    }
-    return false;
-  }
-
-  // Compute index of the class_array[] entry for a given size
-  static inline size_t ClassIndex(size_t s) {
-    // Use unsigned arithmetic to avoid unnecessary sign extensions.
-    ASSERT(0 <= s);
-    ASSERT(s <= kMaxSize);
-    if (PREDICT_TRUE(s <= kMaxSmallSize)) {
-      return SmallSizeClass(s);
-    } else {
-      return LargeSizeClass(s);
-    }
-  }
-
-  // Number of objects to move between a per-thread list and a central
-  // list in one shot.  We want this to be not too small so we can
-  // amortize the lock overhead for accessing the central list.  Making
-  // it too big may temporarily cause unnecessary memory wastage in the
-  // per-thread free list until the scavenger cleans up the list.
-  int num_objects_to_move_[kClassSizesMax];
-
-  int NumMoveSize(size_t size);
-
-  // Mapping from size class to max size storable in that class
-  int32 class_to_size_[kClassSizesMax];
-
-  // Mapping from size class to number of pages to allocate at a time
-  size_t class_to_pages_[kClassSizesMax];
-
- public:
-  size_t num_size_classes;
-
-  // Constructor should do nothing since we rely on explicit Init()
-  // call, which may or may not be called before the constructor runs.
-  SizeMap() { }
-
-  // Initialize the mapping arrays
-  void Init();
-
-  inline int SizeClass(size_t size) {
-    return class_array_[ClassIndex(size)];
-  }
-
-  // Check if size is small enough to be representable by a size
-  // class, and if it is, put matching size class into *cl. Returns
-  // true iff matching size class was found.
-  inline bool ATTRIBUTE_ALWAYS_INLINE GetSizeClass(size_t size, uint32* cl) {
-    uint32 idx;
-    if (!ClassIndexMaybe(size, &idx)) {
-      return false;
-    }
-    *cl = class_array_[idx];
-    return true;
-  }
-
-  // Get the byte-size for a specified class
-  inline int32 ATTRIBUTE_ALWAYS_INLINE ByteSizeForClass(uint32 cl) {
-    return class_to_size_[cl];
-  }
-
-  // Mapping from size class to max size storable in that class
-  inline int32 class_to_size(uint32 cl) {
-    return class_to_size_[cl];
-  }
-
-  // Mapping from size class to number of pages to allocate at a time
-  inline size_t class_to_pages(uint32 cl) {
-    return class_to_pages_[cl];
-  }
-
-  // Number of objects to move between a per-thread list and a central
-  // list in one shot.  We want this to be not too small so we can
-  // amortize the lock overhead for accessing the central list.  Making
-  // it too big may temporarily cause unnecessary memory wastage in the
-  // per-thread free list until the scavenger cleans up the list.
-  inline int num_objects_to_move(uint32 cl) {
-    return num_objects_to_move_[cl];
-  }
-};
-
-// Allocates "bytes" worth of memory with a guard page in front and
-// returns it.  Increments metadata_system_bytes appropriately.  May
-// return NULL if allocation fails.  Requires pageheap_lock is held.
-void* MetaDataAlloc(size_t bytes);
-
-// Returns the total number of bytes allocated from the system.
-// Requires pageheap_lock is held.
-uint64_t metadata_system_bytes();
-
-// size/depth are made the same size as a pointer so that some generic
-// code below can conveniently cast them back and forth to void*.
-static const int kMaxStackDepth = 31;
-struct StackTrace {
-  uintptr_t size;          // Size of object
-  uintptr_t depth;         // Number of PC values stored in array below
-  void*     stack[kMaxStackDepth];
-};
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_COMMON_H_
diff --git a/third_party/tcmalloc/chromium/src/config.h b/third_party/tcmalloc/chromium/src/config.h
deleted file mode 100644
index 9c1cec1..0000000
--- a/third_party/tcmalloc/chromium/src/config.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2009 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 CONFIG_H_
-
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include "third_party/tcmalloc/chromium/src/config_win.h"
-#elif defined(OS_ANDROID)
-#include "third_party/tcmalloc/chromium/src/config_android.h"
-#elif defined(OS_LINUX) || defined(OS_CHROMEOS)
-#include "third_party/tcmalloc/chromium/src/config_linux.h"
-#elif defined(OS_FREEBSD)
-#include "third_party/tcmalloc/chromium/src/config_freebsd.h"
-#endif
-
-#endif  // CONFIG_H_
diff --git a/third_party/tcmalloc/chromium/src/config_android.h b/third_party/tcmalloc/chromium/src/config_android.h
deleted file mode 100644
index e33820e..0000000
--- a/third_party/tcmalloc/chromium/src/config_android.h
+++ /dev/null
@@ -1 +0,0 @@
-#error "File must be generated from config.h.in by configure."
diff --git a/third_party/tcmalloc/chromium/src/config_for_unittests.h b/third_party/tcmalloc/chromium/src/config_for_unittests.h
deleted file mode 100644
index 66592a7..0000000
--- a/third_party/tcmalloc/chromium/src/config_for_unittests.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Craig Silverstein
-//
-// This file is needed for windows -- unittests are not part of the
-// perftools dll, but still want to include config.h just like the
-// dll does, so they can use internal tools and APIs for testing.
-//
-// The problem is that config.h declares PERFTOOLS_DLL_DECL to be
-// for exporting symbols, but the unittest needs to *import* symbols
-// (since it's not the dll).
-//
-// The solution is to have this file, which is just like config.h but
-// sets PERFTOOLS_DLL_DECL to do a dllimport instead of a dllexport.
-//
-// The reason we need this extra PERFTOOLS_DLL_DECL_FOR_UNITTESTS
-// variable is in case people want to set PERFTOOLS_DLL_DECL explicitly
-// to something other than __declspec(dllexport).  In that case, they
-// may want to use something other than __declspec(dllimport) for the
-// unittest case.  For that, we allow folks to define both
-// PERFTOOLS_DLL_DECL and PERFTOOLS_DLL_DECL_FOR_UNITTESTS explicitly.
-//
-// NOTE: This file is equivalent to config.h on non-windows systems,
-// which never defined PERFTOOLS_DLL_DECL_FOR_UNITTESTS and always
-// define PERFTOOLS_DLL_DECL to the empty string.
-
-#include "config.h"
-
-#undef PERFTOOLS_DLL_DECL
-#ifdef PERFTOOLS_DLL_DECL_FOR_UNITTESTS
-# define PERFTOOLS_DLL_DECL  PERFTOOLS_DLL_DECL_FOR_UNITTESTS
-#else
-# define PERFTOOLS_DLL_DECL  // if DLL_DECL_FOR_UNITTESTS isn't defined, use ""
-#endif
diff --git a/third_party/tcmalloc/chromium/src/config_freebsd.h b/third_party/tcmalloc/chromium/src/config_freebsd.h
deleted file mode 100644
index e33820e..0000000
--- a/third_party/tcmalloc/chromium/src/config_freebsd.h
+++ /dev/null
@@ -1 +0,0 @@
-#error "File must be generated from config.h.in by configure."
diff --git a/third_party/tcmalloc/chromium/src/config_linux.h b/third_party/tcmalloc/chromium/src/config_linux.h
deleted file mode 100644
index 4e8e398..0000000
--- a/third_party/tcmalloc/chromium/src/config_linux.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/* src/config.h.  Generated from config.h.in by configure.  */
-/* src/config.h.in.  Generated from configure.ac by autoheader.  */
-
-#ifndef GPERFTOOLS_CONFIG_H_
-#define GPERFTOOLS_CONFIG_H_
-
-/* Build new/delete operators for overaligned types */
-/* #undef ENABLE_ALIGNED_NEW_DELETE */
-
-/* Build runtime detection for sized delete */
-/* #undef ENABLE_DYNAMIC_SIZED_DELETE */
-
-/* Build sized deletion operators */
-/* #undef ENABLE_SIZED_DELETE */
-
-/* Define to 1 if compiler supports __builtin_expect */
-#if defined(__GNUC__)
-#define HAVE_BUILTIN_EXPECT 1
-#endif
-
-/* Define to 1 if compiler supports __builtin_stack_pointer */
-/* #undef HAVE_BUILTIN_STACK_POINTER */
-
-/* Define to 1 if you have the <conflict-signal.h> header file. */
-/* #undef HAVE_CONFLICT_SIGNAL_H */
-
-/* Define to 1 if you have the <cygwin/signal.h> header file. */
-/* #undef HAVE_CYGWIN_SIGNAL_H */
-
-/* Define to 1 if you have the declaration of `backtrace', and to 0 if you
-   don't. */
-/* #undef HAVE_DECL_BACKTRACE */
-
-/* Define to 1 if you have the declaration of `cfree', and to 0 if you don't.
- */
-#define HAVE_DECL_CFREE 1
-
-/* Define to 1 if you have the declaration of `memalign', and to 0 if you
-   don't. */
-#define HAVE_DECL_MEMALIGN 1
-
-/* Define to 1 if you have the declaration of `nanosleep', and to 0 if you
-   don't. */
-/* #undef HAVE_DECL_NANOSLEEP */
-
-/* Define to 1 if you have the declaration of `posix_memalign', and to 0 if
-   you don't. */
-#define HAVE_DECL_POSIX_MEMALIGN 1
-
-/* Define to 1 if you have the declaration of `pvalloc', and to 0 if you
-   don't. */
-#define HAVE_DECL_PVALLOC 1
-
-/* Define to 1 if you have the declaration of `sleep', and to 0 if you don't.
- */
-/* #undef HAVE_DECL_SLEEP */
-
-/* Define to 1 if you have the declaration of `uname', and to 0 if you don't.
- */
-#define HAVE_DECL_UNAME 1
-
-/* Define to 1 if you have the declaration of `valloc', and to 0 if you don't.
- */
-#define HAVE_DECL_VALLOC 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if the system has the type `Elf32_Versym'. */
-#define HAVE_ELF32_VERSYM 1
-
-/* Define to 1 if you have the <execinfo.h> header file. */
-#define HAVE_EXECINFO_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the <features.h> header file. */
-#define HAVE_FEATURES_H 1
-
-/* Define to 1 if you have the `fork' function. */
-#define HAVE_FORK 1
-
-/* Define to 1 if you have the `geteuid' function. */
-#define HAVE_GETEUID 1
-
-/* Define to 1 if you have the `getpagesize' function. */
-#define HAVE_GETPAGESIZE 1
-
-/* Define to 1 if you have the <glob.h> header file. */
-#define HAVE_GLOB_H 1
-
-/* Define to 1 if you have the <grp.h> header file. */
-#define HAVE_GRP_H 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <libunwind.h> header file. */
-/* #undef HAVE_LIBUNWIND_H */
-
-/* Define to 1 if you have the <linux/ptrace.h> header file. */
-#define HAVE_LINUX_PTRACE_H 1
-
-/* Define if this is Linux that has SIGEV_THREAD_ID */
-#define HAVE_LINUX_SIGEV_THREAD_ID 1
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#define HAVE_MALLOC_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have a working `mmap' system call. */
-#define HAVE_MMAP 1
-
-/* define if the compiler implements namespaces */
-#define HAVE_NAMESPACES 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#define HAVE_POLL_H 1
-
-/* define if libc has program_invocation_name */
-#define HAVE_PROGRAM_INVOCATION_NAME 1
-
-/* Define if you have POSIX threads libraries and header files. */
-#define HAVE_PTHREAD 1
-
-/* defined to 1 if pthread symbols are exposed even without include pthread.h
- */
-/* #undef HAVE_PTHREAD_DESPITE_ASKING_FOR */
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#define HAVE_PWD_H 1
-
-/* Define to 1 if you have the `sbrk' function. */
-#define HAVE_SBRK 1
-
-/* Define to 1 if you have the <sched.h> header file. */
-#define HAVE_SCHED_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if the system has the type `struct mallinfo'. */
-#define HAVE_STRUCT_MALLINFO 1
-
-/* Define to 1 if you have the <sys/cdefs.h> header file. */
-#define HAVE_SYS_CDEFS_H 1
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the <sys/prctl.h> header file. */
-#define HAVE_SYS_PRCTL_H 1
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#define HAVE_SYS_RESOURCE_H 1
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-#define HAVE_SYS_SYSCALL_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/ucontext.h> header file. */
-#define HAVE_SYS_UCONTEXT_H 1
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define to 1 if compiler supports __thread */
-#define HAVE_TLS 1
-
-/* Define to 1 if you have the <ucontext.h> header file. */
-#define HAVE_UCONTEXT_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Whether <unwind.h> contains _Unwind_Backtrace */
-#define HAVE_UNWIND_BACKTRACE 1
-
-/* Define to 1 if you have the <unwind.h> header file. */
-#define HAVE_UNWIND_H 1
-
-/* Define to 1 if you have the <valgrind.h> header file. */
-/* #undef HAVE_VALGRIND_H */
-
-/* define if your compiler has __attribute__ */
-#define HAVE___ATTRIBUTE__ 1
-
-/* define if your compiler supports alignment of functions */
-#define HAVE___ATTRIBUTE__ALIGNED_FN 1
-
-/* Define to 1 if compiler supports __environ */
-#define HAVE___ENVIRON 1
-
-/* Define to 1 if the system has the type `__int64'. */
-/* #undef HAVE___INT64 */
-
-/* prefix where we look for installed files */
-#define INSTALL_PREFIX "/usr/local"
-
-/* Define to 1 if int32_t is equivalent to intptr_t */
-/* #undef INT32_EQUALS_INTPTR */
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "gperftools"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "gperftools@googlegroups.com"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "gperftools"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gperftools 2.7"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "gperftools"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.7"
-
-/* How to access the PC from a struct ucontext */
-/* TODO(asharif): configure.ac should be changed such that this define gets
- * generated automatically. That change should go to upstream and then pulled
- * back here. */
-#if defined(__arm__)
-#define PC_FROM_UCONTEXT uc_mcontext.arm_pc
-#else
-#define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP]
-#endif
-
-/* Always the empty-string on non-windows systems. On windows, should be
-   "__declspec(dllexport)". This way, when we compile the dll, we export our
-   functions/classes. It's safe to define this here because config.h is only
-   used internally, to compile the DLL, and every DLL source file #includes
-   "config.h" before anything else. */
-#define PERFTOOLS_DLL_DECL /**/
-
-/* printf format code for printing a size_t and ssize_t */
-#define PRIdS "zd"
-
-/* printf format code for printing a size_t and ssize_t */
-#define PRIuS "zu"
-
-/* printf format code for printing a size_t and ssize_t */
-#define PRIxS "zx"
-
-/* Mark the systems where we know it's bad if pthreads runs too
-   early before main (before threads are initialized, presumably).  */
-#ifdef __FreeBSD__
-#define PTHREADS_CRASHES_IF_RUN_TOO_EARLY 1
-#endif
-
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* the namespace where STL code like vector<> is defined */
-#define STL_NAMESPACE std
-
-/* Define 32K of internal pages size for tcmalloc */
-/* #undef TCMALLOC_32K_PAGES */
-
-/* Define 64K of internal pages size for tcmalloc */
-/* #undef TCMALLOC_64K_PAGES */
-
-/* Define 8 bytes of allocation alignment for tcmalloc */
-/* #undef TCMALLOC_ALIGN_8BYTES */
-
-/* Version number of package */
-#define VERSION "2.7"
-
-/* C99 says: define this to get the PRI... macros from stdint.h */
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS 1
-#endif
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-#ifdef __MINGW32__
-#include "windows/mingw.h"
-#endif
-
-#endif /* #ifndef GPERFTOOLS_CONFIG_H_ */
diff --git a/third_party/tcmalloc/chromium/src/config_win.h b/third_party/tcmalloc/chromium/src/config_win.h
deleted file mode 100644
index f22a34b..0000000
--- a/third_party/tcmalloc/chromium/src/config_win.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/* A manual version of config.h fit for windows machines. */
-#error \
-    "File copied from older tcmalloc version. Must be updated for new versions."
-
-/* Sometimes we accidentally #include this config.h instead of the one
-   in .. -- this is particularly true for msys/mingw, which uses the
-   unix config.h but also runs code in the windows directory.
-   */
-#ifdef __MINGW32__
-#include "../config.h"
-#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_
-#endif
-
-#ifndef GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_
-#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_
-
-/* define this if you are linking tcmalloc statically and overriding the
- * default allocators.
- * For instructions on how to use this mode, see
- * http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b
- */
-#define WIN32_OVERRIDE_ALLOCATORS
-
-/* the location of <hash_map> */
-#define HASH_MAP_H <hash_map>
-
-/* the namespace of hash_map/hash_set */
-#define HASH_NAMESPACE stdext
-
-/* the location of <hash_set> */
-#define HASH_SET_H <hash_set>
-
-/* Define to 1 if your libc has a snprintf implementation */
-#undef HAVE_SNPRINTF
-
-/* Define to 1 if compiler supports __builtin_stack_pointer */
-#undef HAVE_BUILTIN_STACK_POINTER
-
-/* Define to 1 if you have the <conflict-signal.h> header file. */
-#undef HAVE_CONFLICT_SIGNAL_H
-
-/* Define to 1 if you have the <cygwin/signal.h> header file. */
-#undef HAVE_CYGWIN_SIGNAL_H
-
-/* Define to 1 if you have the declaration of `cfree', and to 0 if you don't.
- */
-#undef HAVE_DECL_CFREE
-
-/* Define to 1 if you have the declaration of `memalign', and to 0 if you
-   don't. */
-#undef HAVE_DECL_MEMALIGN
-
-/* Define to 1 if you have the declaration of `posix_memalign', and to 0 if
-   you don't. */
-#undef HAVE_DECL_POSIX_MEMALIGN
-
-/* Define to 1 if you have the declaration of `pvalloc', and to 0 if you
-   don't. */
-#undef HAVE_DECL_PVALLOC
-
-/* Define to 1 if you have the declaration of `uname', and to 0 if you don't.
- */
-#undef HAVE_DECL_UNAME
-
-/* Define to 1 if you have the declaration of `valloc', and to 0 if you don't.
- */
-#undef HAVE_DECL_VALLOC
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if the system has the type `Elf32_Versym'. */
-#undef HAVE_ELF32_VERSYM
-
-/* Define to 1 if you have the <execinfo.h> header file. */
-#undef HAVE_EXECINFO_H
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the <features.h> header file. */
-#undef HAVE_FEATURES_H
-
-/* Define to 1 if you have the `geteuid' function. */
-#undef HAVE_GETEUID
-
-/* Define to 1 if you have the `getpagesize' function. */
-#define HAVE_GETPAGESIZE 1 /* we define it in windows/port.cc */
-
-/* Define to 1 if you have the <glob.h> header file. */
-#undef HAVE_GLOB_H
-
-/* Define to 1 if you have the <grp.h> header file. */
-#undef HAVE_GRP_H
-
-/* define if the compiler has hash_map */
-#define HAVE_HASH_MAP 1
-
-/* define if the compiler has hash_set */
-#define HAVE_HASH_SET 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <libunwind.h> header file. */
-#undef HAVE_LIBUNWIND_H
-
-/* Define to 1 if you have the <linux/ptrace.h> header file. */
-#undef HAVE_LINUX_PTRACE_H
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
-
-/* Define to 1 if you have the <malloc/malloc.h> header file. */
-#undef HAVE_MALLOC_MALLOC_H
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have a working `mmap' system call. */
-#undef HAVE_MMAP
-
-/* define if the compiler implements namespaces */
-#define HAVE_NAMESPACES 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#undef HAVE_POLL_H
-
-/* define if libc has program_invocation_name */
-#undef HAVE_PROGRAM_INVOCATION_NAME
-
-/* Define if you have POSIX threads libraries and header files. */
-#undef HAVE_PTHREAD
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#undef HAVE_PWD_H
-
-/* Define to 1 if you have the `sbrk' function. */
-#undef HAVE_SBRK
-/* Define to 1 if you have the <sched.h> header file. */
-#undef HAVE_SCHED_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if the system has the type `struct mallinfo'. */
-#undef HAVE_STRUCT_MALLINFO
-
-/* Define to 1 if you have the <sys/cdefs.h> header file. */
-#undef HAVE_SYS_CDEFS_H
-
-/* Define to 1 if you have the <sys/malloc.h> header file. */
-#undef HAVE_SYS_MALLOC_H
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#undef HAVE_SYS_PARAM_H
-
-/* Define to 1 if you have the <sys/prctl.h> header file. */
-#undef HAVE_SYS_PRCTL_H
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#undef HAVE_SYS_RESOURCE_H
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#undef HAVE_SYS_SOCKET_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-#undef HAVE_SYS_SYSCALL_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* <sys/ucontext.h> is broken on redhat 7 */
-#undef HAVE_SYS_UCONTEXT_H
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define to 1 if compiler supports __thread */
-#undef HAVE_TLS
-
-/* Define to 1 if you have the <ucontext.h> header file. */
-#undef HAVE_UCONTEXT_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the <unwind.h> header file. */
-#undef HAVE_UNWIND_H
-
-/* define if your compiler has __attribute__ */
-#undef HAVE___ATTRIBUTE__
-
-/* Define to 1 if compiler supports __environ */
-#undef HAVE___ENVIRON
-
-/* Define to 1 if the system has the type `__int64'. */
-#define HAVE___INT64 1
-
-/* prefix where we look for installed files */
-#undef INSTALL_PREFIX
-
-/* Define to 1 if int32_t is equivalent to intptr_t */
-#undef INT32_EQUALS_INTPTR
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#undef LT_OBJDIR
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-#undef NO_MINUS_C_MINUS_O
-
-/* Name of package */
-#undef PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* How to access the PC from a struct ucontext */
-#undef PC_FROM_UCONTEXT
-
-/* Always the empty-string on non-windows systems. On windows, should be
-   "__declspec(dllexport)". This way, when we compile the dll, we export our
-   functions/classes. It's safe to define this here because config.h is only
-   used internally, to compile the DLL, and every DLL source file #includes
-   "config.h" before anything else. */
-#ifndef PERFTOOLS_DLL_DECL
-#define PERFTOOLS_IS_A_DLL 1 /* not set if you're statically linking */
-#define PERFTOOLS_DLL_DECL __declspec(dllexport)
-#define PERFTOOLS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
-#endif
-
-/* printf format code for printing a size_t and ssize_t */
-#define PRIdS "Id"
-
-/* printf format code for printing a size_t and ssize_t */
-#define PRIuS "Iu"
-
-/* printf format code for printing a size_t and ssize_t */
-#define PRIxS "Ix"
-
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-#undef PTHREAD_CREATE_JOINABLE
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* the namespace where STL code like vector<> is defined */
-#define STL_NAMESPACE std
-
-/* Version number of package */
-#undef VERSION
-
-/* C99 says: define this to get the PRI... macros from stdint.h */
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS 1
-#endif
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-#undef inline
-#endif
-
-// ---------------------------------------------------------------------
-// Extra stuff not found in config.h.in
-
-// This must be defined before the windows.h is included.  We need at
-// least 0x0400 for mutex.h to have access to TryLock, and at least
-// 0x0501 for patch_functions.cc to have access to GetModuleHandleEx.
-// (This latter is an optimization we could take out if need be.)
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
-// We want to make sure not to ever try to #include heap-checker.h
-#define NO_HEAP_CHECK 1
-
-// TODO(csilvers): include windows/port.h in every relevant source file instead?
-#include "windows/port.h"
-
-#endif /* GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ */
diff --git a/third_party/tcmalloc/chromium/src/debugallocation.cc b/third_party/tcmalloc/chromium/src/debugallocation.cc
deleted file mode 100644
index 6ac0ea4f..0000000
--- a/third_party/tcmalloc/chromium/src/debugallocation.cc
+++ /dev/null
@@ -1,1604 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2000, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Urs Holzle <opensource@google.com>
-
-#include "config.h"
-#include <errno.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-// We only need malloc.h for struct mallinfo.
-#ifdef HAVE_STRUCT_MALLINFO
-// Malloc can be in several places on older versions of OS X.
-# if defined(HAVE_MALLOC_H)
-# include <malloc.h>
-# elif defined(HAVE_MALLOC_MALLOC_H)
-# include <malloc/malloc.h>
-# elif defined(HAVE_SYS_MALLOC_H)
-# include <sys/malloc.h>
-# endif
-#endif
-#ifdef HAVE_PTHREAD
-#include <pthread.h>
-#endif
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <gperftools/malloc_extension.h>
-#include <gperftools/malloc_hook.h>
-#include <gperftools/stacktrace.h>
-#include "addressmap-inl.h"
-#include "base/abort.h"
-#include "base/commandlineflags.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "malloc_hook-inl.h"
-#include "symbolize.h"
-
-// NOTE: due to #define below, tcmalloc.cc will omit tc_XXX
-// definitions. So that debug implementations can be defined
-// instead. We're going to use do_malloc, do_free and other do_XXX
-// functions that are defined in tcmalloc.cc for actual memory
-// management
-#define TCMALLOC_USING_DEBUGALLOCATION
-#include "tcmalloc.cc"
-
-// __THROW is defined in glibc systems.  It means, counter-intuitively,
-// "This function will never throw an exception."  It's an optional
-// optimization tool, but we may need to use it to match glibc prototypes.
-#ifndef __THROW    // I guess we're not on a glibc system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-// ========================================================================= //
-
-DEFINE_bool(malloctrace,
-            EnvToBool("TCMALLOC_TRACE", false),
-            "Enables memory (de)allocation tracing to /tmp/google.alloc.");
-#ifdef HAVE_MMAP
-DEFINE_bool(malloc_page_fence,
-            EnvToBool("TCMALLOC_PAGE_FENCE", false),
-            "Enables putting of memory allocations at page boundaries "
-            "with a guard page following the allocation (to catch buffer "
-            "overruns right when they happen).");
-DEFINE_bool(malloc_page_fence_never_reclaim,
-            EnvToBool("TCMALLOC_PAGE_FENCE_NEVER_RECLAIM", false),
-            "Enables making the virtual address space inaccessible "
-            "upon a deallocation instead of returning it and reusing later.");
-#else
-DEFINE_bool(malloc_page_fence, false, "Not usable (requires mmap)");
-DEFINE_bool(malloc_page_fence_never_reclaim, false, "Not usable (required mmap)");
-#endif
-DEFINE_bool(malloc_reclaim_memory,
-            EnvToBool("TCMALLOC_RECLAIM_MEMORY", true),
-            "If set to false, we never return memory to malloc "
-            "when an object is deallocated. This ensures that all "
-            "heap object addresses are unique.");
-DEFINE_int32(max_free_queue_size,
-             EnvToInt("TCMALLOC_MAX_FREE_QUEUE_SIZE", 10*1024*1024),
-             "If greater than 0, keep freed blocks in a queue instead of "
-             "releasing them to the allocator immediately.  Release them when "
-             "the total size of all blocks in the queue would otherwise exceed "
-             "this limit.");
-
-DEFINE_bool(symbolize_stacktrace,
-            EnvToBool("TCMALLOC_SYMBOLIZE_STACKTRACE", true),
-            "Symbolize the stack trace when provided (on some error exits)");
-
-// If we are LD_PRELOAD-ed against a non-pthreads app, then
-// pthread_once won't be defined.  We declare it here, for that
-// case (with weak linkage) which will cause the non-definition to
-// resolve to NULL.  We can then check for NULL or not in Instance.
-extern "C" int pthread_once(pthread_once_t *, void (*)(void))
-    ATTRIBUTE_WEAK;
-
-// ========================================================================= //
-
-// A safe version of printf() that does not do any allocation and
-// uses very little stack space.
-static void TracePrintf(int fd, const char *fmt, ...)
-  __attribute__ ((__format__ (__printf__, 2, 3)));
-
-// Round "value" up to next "alignment" boundary.
-// Requires that "alignment" be a power of two.
-static intptr_t RoundUp(intptr_t value, intptr_t alignment) {
-  return (value + alignment - 1) & ~(alignment - 1);
-}
-
-// ========================================================================= //
-
-class MallocBlock;
-
-// A circular buffer to hold freed blocks of memory.  MallocBlock::Deallocate
-// (below) pushes blocks into this queue instead of returning them to the
-// underlying allocator immediately.  See MallocBlock::Deallocate for more
-// information.
-//
-// We can't use an STL class for this because we need to be careful not to
-// perform any heap de-allocations in any of the code in this class, since the
-// code in MallocBlock::Deallocate is not re-entrant.
-template <typename QueueEntry>
-class FreeQueue {
- public:
-  FreeQueue() : q_front_(0), q_back_(0) {}
-
-  bool Full() {
-    return (q_front_ + 1) % kFreeQueueSize == q_back_;
-  }
-
-  void Push(const QueueEntry& block) {
-    q_[q_front_] = block;
-    q_front_ = (q_front_ + 1) % kFreeQueueSize;
-  }
-
-  QueueEntry Pop() {
-    RAW_CHECK(q_back_ != q_front_, "Queue is empty");
-    const QueueEntry& ret = q_[q_back_];
-    q_back_ = (q_back_ + 1) % kFreeQueueSize;
-    return ret;
-  }
-
-  size_t size() const {
-    return (q_front_ - q_back_ + kFreeQueueSize) % kFreeQueueSize;
-  }
-
- private:
-  // Maximum number of blocks kept in the free queue before being freed.
-  static const int kFreeQueueSize = 1024;
-
-  QueueEntry q_[kFreeQueueSize];
-  int q_front_;
-  int q_back_;
-};
-
-struct MallocBlockQueueEntry {
-  MallocBlockQueueEntry() : block(NULL), size(0),
-                            num_deleter_pcs(0), deleter_threadid(0) {}
-  MallocBlockQueueEntry(MallocBlock* b, size_t s) : block(b), size(s) {
-    if (FLAGS_max_free_queue_size != 0 && b != NULL) {
-      // Adjust the number of frames to skip (4) if you change the
-      // location of this call.
-      num_deleter_pcs =
-        MallocHook::GetCallerStackTrace(
-          deleter_pcs,
-          sizeof(deleter_pcs) / sizeof(deleter_pcs[0]),
-          4);
-      deleter_threadid = pthread_self();
-    } else {
-      num_deleter_pcs = 0;
-      // Zero is an illegal pthread id by my reading of the pthread
-      // implementation:
-      deleter_threadid = 0;
-    }
-  }
-
-  MallocBlock* block;
-  size_t size;
-
-  // When deleted and put in the free queue, we (flag-controlled)
-  // record the stack so that if corruption is later found, we can
-  // print the deleter's stack.  (These three vars add 144 bytes of
-  // overhead under the LP64 data model.)
-  void* deleter_pcs[16];
-  int num_deleter_pcs;
-  pthread_t deleter_threadid;
-};
-
-class MallocBlock {
- public:  // allocation type constants
-
-  // Different allocation types we distinguish.
-  // Note: The lower 4 bits are not random: we index kAllocName array
-  // by these values masked with kAllocTypeMask;
-  // the rest are "random" magic bits to help catch memory corruption.
-  static const int kMallocType = 0xEFCDAB90;
-  static const int kNewType = 0xFEBADC81;
-  static const int kArrayNewType = 0xBCEADF72;
-
- private:  // constants
-
-  // A mask used on alloc types above to get to 0, 1, 2
-  static const int kAllocTypeMask = 0x3;
-  // An additional bit to set in AllocType constants
-  // to mark now deallocated regions.
-  static const int kDeallocatedTypeBit = 0x4;
-
-  // For better memory debugging, we initialize all storage to known
-  // values, and overwrite the storage when it's deallocated:
-  // Byte that fills uninitialized storage.
-  static const int kMagicUninitializedByte = 0xAB;
-  // Byte that fills deallocated storage.
-  // NOTE: tcmalloc.cc depends on the value of kMagicDeletedByte
-  //       to work around a bug in the pthread library.
-  static const int kMagicDeletedByte = 0xCD;
-  // A size_t (type of alloc_type_ below) in a deallocated storage
-  // filled with kMagicDeletedByte.
-  static const size_t kMagicDeletedSizeT =
-      0xCDCDCDCD | (((size_t)0xCDCDCDCD << 16) << 16);
-    // Initializer works for 32 and 64 bit size_ts;
-    // "<< 16 << 16" is to fool gcc from issuing a warning
-    // when size_ts are 32 bits.
-
-  // NOTE: on Linux, you can enable malloc debugging support in libc by
-  // setting the environment variable MALLOC_CHECK_ to 1 before you
-  // start the program (see man malloc).
-
-  // We use either do_malloc or mmap to make the actual allocation. In
-  // order to remember which one of the two was used for any block, we store an
-  // appropriate magic word next to the block.
-  static const size_t kMagicMalloc = 0xDEADBEEF;
-  static const size_t kMagicMMap = 0xABCDEFAB;
-
-  // This array will be filled with 0xCD, for use with memcmp.
-  static unsigned char kMagicDeletedBuffer[1024];
-  static pthread_once_t deleted_buffer_initialized_;
-  static bool deleted_buffer_initialized_no_pthreads_;
-
- private:  // data layout
-
-                    // The four fields size1_,offset_,magic1_,alloc_type_
-                    // should together occupy a multiple of 16 bytes. (At the
-                    // moment, sizeof(size_t) == 4 or 8 depending on piii vs
-                    // k8, and 4 of those sum to 16 or 32 bytes).
-                    // This, combined with do_malloc's alignment guarantees,
-                    // ensures that SSE types can be stored into the returned
-                    // block, at &size2_.
-  size_t size1_;
-  size_t offset_;   // normally 0 unless memaligned memory
-                    // see comments in memalign() and FromRawPointer().
-  size_t magic1_;
-  size_t alloc_type_;
-  // here comes the actual data (variable length)
-  // ...
-  // then come the size2_ and magic2_, or a full page of mprotect-ed memory
-  // if the malloc_page_fence feature is enabled.
-  size_t size2_;
-  size_t magic2_;
-
- private:  // static data and helpers
-
-  // Allocation map: stores the allocation type for each allocated object,
-  // or the type or'ed with kDeallocatedTypeBit
-  // for each formerly allocated object.
-  typedef AddressMap<int> AllocMap;
-  static AllocMap* alloc_map_;
-  // This protects alloc_map_ and consistent state of metadata
-  // for each still-allocated object in it.
-  // We use spin locks instead of pthread_mutex_t locks
-  // to prevent crashes via calls to pthread_mutex_(un)lock
-  // for the (de)allocations coming from pthreads initialization itself.
-  static SpinLock alloc_map_lock_;
-
-  // A queue of freed blocks.  Instead of releasing blocks to the allocator
-  // immediately, we put them in a queue, freeing them only when necessary
-  // to keep the total size of all the freed blocks below the limit set by
-  // FLAGS_max_free_queue_size.
-  static FreeQueue<MallocBlockQueueEntry>* free_queue_;
-
-  static size_t free_queue_size_;  // total size of blocks in free_queue_
-  // protects free_queue_ and free_queue_size_
-  static SpinLock free_queue_lock_;
-
-  // Names of allocation types (kMallocType, kNewType, kArrayNewType)
-  static const char* const kAllocName[];
-  // Names of corresponding deallocation types
-  static const char* const kDeallocName[];
-
-  static const char* AllocName(int type) {
-    return kAllocName[type & kAllocTypeMask];
-  }
-
-  static const char* DeallocName(int type) {
-    return kDeallocName[type & kAllocTypeMask];
-  }
-
- private:  // helper accessors
-
-  bool IsMMapped() const { return kMagicMMap == magic1_; }
-
-  bool IsValidMagicValue(size_t value) const {
-    return kMagicMMap == value  ||  kMagicMalloc == value;
-  }
-
-  static size_t real_malloced_size(size_t size) {
-    return size + sizeof(MallocBlock);
-  }
-
-  /*
-   * Here we assume size of page is kMinAlign aligned,
-   * so if size is MALLOC_ALIGNMENT aligned too, then we could
-   * guarantee return address is also kMinAlign aligned, because
-   * mmap return address at nearby page boundary on Linux.
-   */
-  static size_t real_mmapped_size(size_t size) {
-    size_t tmp = size + MallocBlock::data_offset();
-    tmp = RoundUp(tmp, kMinAlign);
-    return tmp;
-  }
-
-  size_t real_size() {
-    return IsMMapped() ? real_mmapped_size(size1_) : real_malloced_size(size1_);
-  }
-
-  // NOTE: if the block is mmapped (that is, we're using the
-  // malloc_page_fence option) then there's no size2 or magic2
-  // (instead, the guard page begins where size2 would be).
-
-  size_t* size2_addr() { return (size_t*)((char*)&size2_ + size1_); }
-  const size_t* size2_addr() const {
-    return (const size_t*)((char*)&size2_ + size1_);
-  }
-
-  size_t* magic2_addr() { return (size_t*)(size2_addr() + 1); }
-  const size_t* magic2_addr() const { return (const size_t*)(size2_addr() + 1); }
-
- private:  // other helpers
-
-  void Initialize(size_t size, int type) {
-    RAW_CHECK(IsValidMagicValue(magic1_), "");
-    // record us as allocated in the map
-    alloc_map_lock_.Lock();
-    if (!alloc_map_) {
-      void* p = do_malloc(sizeof(AllocMap));
-      alloc_map_ = new(p) AllocMap(do_malloc, do_free);
-    }
-    alloc_map_->Insert(data_addr(), type);
-    // initialize us
-    size1_ = size;
-    offset_ = 0;
-    alloc_type_ = type;
-    if (!IsMMapped()) {
-      bit_store(magic2_addr(), &magic1_);
-      bit_store(size2_addr(), &size);
-    }
-    alloc_map_lock_.Unlock();
-    memset(data_addr(), kMagicUninitializedByte, size);
-    if (!IsMMapped()) {
-      RAW_CHECK(memcmp(&size1_, size2_addr(), sizeof(size1_)) == 0, "should hold");
-      RAW_CHECK(memcmp(&magic1_, magic2_addr(), sizeof(magic1_)) == 0, "should hold");
-    }
-  }
-
-  size_t CheckAndClear(int type, size_t given_size) {
-    alloc_map_lock_.Lock();
-    CheckLocked(type);
-    if (!IsMMapped()) {
-      RAW_CHECK(memcmp(&size1_, size2_addr(), sizeof(size1_)) == 0, "should hold");
-    }
-    // record us as deallocated in the map
-    alloc_map_->Insert(data_addr(), type | kDeallocatedTypeBit);
-    alloc_map_lock_.Unlock();
-    // clear us
-    const size_t size = real_size();
-    RAW_CHECK(!given_size || given_size == size1_,
-              "right size must be passed to sized delete");
-    memset(this, kMagicDeletedByte, size);
-    return size;
-  }
-
-  void CheckLocked(int type) const {
-    int map_type = 0;
-    const int* found_type =
-      alloc_map_ != NULL ? alloc_map_->Find(data_addr()) : NULL;
-    if (found_type == NULL) {
-      RAW_LOG(FATAL, "memory allocation bug: object at %p "
-                     "has never been allocated", data_addr());
-    } else {
-      map_type = *found_type;
-    }
-    if ((map_type & kDeallocatedTypeBit) != 0) {
-      RAW_LOG(FATAL, "memory allocation bug: object at %p "
-                     "has been already deallocated (it was allocated with %s)",
-                     data_addr(), AllocName(map_type & ~kDeallocatedTypeBit));
-    }
-    if (alloc_type_ == kMagicDeletedSizeT) {
-      RAW_LOG(FATAL, "memory stomping bug: a word before object at %p "
-                     "has been corrupted; or else the object has been already "
-                     "deallocated and our memory map has been corrupted",
-                     data_addr());
-    }
-    if (!IsValidMagicValue(magic1_)) {
-      RAW_LOG(FATAL, "memory stomping bug: a word before object at %p "
-                     "has been corrupted; "
-                     "or else our memory map has been corrupted and this is a "
-                     "deallocation for not (currently) heap-allocated object",
-                     data_addr());
-    }
-    if (!IsMMapped()) {
-      if (memcmp(&size1_, size2_addr(), sizeof(size1_))) {
-        RAW_LOG(FATAL, "memory stomping bug: a word after object at %p "
-                       "has been corrupted", data_addr());
-      }
-      size_t addr;
-      bit_store(&addr, magic2_addr());
-      if (!IsValidMagicValue(addr)) {
-        RAW_LOG(FATAL, "memory stomping bug: a word after object at %p "
-                "has been corrupted", data_addr());
-      }
-    }
-    if (alloc_type_ != type) {
-      if ((alloc_type_ != MallocBlock::kMallocType) &&
-          (alloc_type_ != MallocBlock::kNewType)    &&
-          (alloc_type_ != MallocBlock::kArrayNewType)) {
-        RAW_LOG(FATAL, "memory stomping bug: a word before object at %p "
-                       "has been corrupted", data_addr());
-      }
-      RAW_LOG(FATAL, "memory allocation/deallocation mismatch at %p: "
-                     "allocated with %s being deallocated with %s",
-                     data_addr(), AllocName(alloc_type_), DeallocName(type));
-    }
-    if (alloc_type_ != map_type) {
-      RAW_LOG(FATAL, "memory stomping bug: our memory map has been corrupted : "
-                     "allocation at %p made with %s "
-                     "is recorded in the map to be made with %s",
-                     data_addr(), AllocName(alloc_type_),  AllocName(map_type));
-    }
-  }
-
- public:  // public accessors
-
-  void* data_addr() { return (void*)&size2_; }
-  const void* data_addr() const { return (const void*)&size2_; }
-
-  static size_t data_offset() { return OFFSETOF_MEMBER(MallocBlock, size2_); }
-
-  size_t data_size() const { return size1_; }
-
-  void set_offset(int offset) { this->offset_ = offset; }
-
- public:  // our main interface
-
-  static MallocBlock* Allocate(size_t size, int type) {
-    // Prevent an integer overflow / crash with large allocation sizes.
-    // TODO - Note that for a e.g. 64-bit size_t, max_size_t may not actually
-    // be the maximum value, depending on how the compiler treats ~0. The worst
-    // practical effect is that allocations are limited to 4Gb or so, even if
-    // the address space could take more.
-    static size_t max_size_t = ~0;
-    if (size > max_size_t - sizeof(MallocBlock)) {
-      RAW_LOG(ERROR, "Massive size passed to malloc: %" PRIuS "", size);
-      return NULL;
-    }
-    MallocBlock* b = NULL;
-    const bool use_malloc_page_fence = FLAGS_malloc_page_fence;
-#ifdef HAVE_MMAP
-    if (use_malloc_page_fence) {
-      // Put the block towards the end of the page and make the next page
-      // inaccessible. This will catch buffer overrun right when it happens.
-      size_t sz = real_mmapped_size(size);
-      int pagesize = getpagesize();
-      int num_pages = (sz + pagesize - 1) / pagesize + 1;
-      char* p = (char*) mmap(NULL, num_pages * pagesize, PROT_READ|PROT_WRITE,
-                             MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-      if (p == MAP_FAILED) {
-        // If the allocation fails, abort rather than returning NULL to
-        // malloc. This is because in most cases, the program will run out
-        // of memory in this mode due to tremendous amount of wastage. There
-        // is no point in propagating the error elsewhere.
-        RAW_LOG(FATAL, "Out of memory: possibly due to page fence overhead: %s",
-                strerror(errno));
-      }
-      // Mark the page after the block inaccessible
-      if (mprotect(p + (num_pages - 1) * pagesize, pagesize, PROT_NONE)) {
-        RAW_LOG(FATAL, "Guard page setup failed: %s", strerror(errno));
-      }
-      b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz);
-    } else {
-      b = (MallocBlock*) do_malloc(real_malloced_size(size));
-    }
-#else
-    b = (MallocBlock*) do_malloc(real_malloced_size(size));
-#endif
-
-    // It would be nice to output a diagnostic on allocation failure
-    // here, but logging (other than FATAL) requires allocating
-    // memory, which could trigger a nasty recursion. Instead, preserve
-    // malloc semantics and return NULL on failure.
-    if (b != NULL) {
-      b->magic1_ = use_malloc_page_fence ? kMagicMMap : kMagicMalloc;
-      b->Initialize(size, type);
-    }
-    return b;
-  }
-
-  void Deallocate(int type, size_t given_size) {
-    if (IsMMapped()) {  // have to do this before CheckAndClear
-#ifdef HAVE_MMAP
-      int size = CheckAndClear(type, given_size);
-      int pagesize = getpagesize();
-      int num_pages = (size + pagesize - 1) / pagesize + 1;
-      char* p = (char*) this;
-      if (FLAGS_malloc_page_fence_never_reclaim  ||
-          !FLAGS_malloc_reclaim_memory) {
-        mprotect(p - (num_pages - 1) * pagesize + size,
-                 num_pages * pagesize, PROT_NONE);
-      } else {
-        munmap(p - (num_pages - 1) * pagesize + size, num_pages * pagesize);
-      }
-#endif
-    } else {
-      const size_t size = CheckAndClear(type, given_size);
-      if (FLAGS_malloc_reclaim_memory) {
-        // Instead of freeing the block immediately, push it onto a queue of
-        // recently freed blocks.  Free only enough blocks to keep from
-        // exceeding the capacity of the queue or causing the total amount of
-        // un-released memory in the queue from exceeding
-        // FLAGS_max_free_queue_size.
-        ProcessFreeQueue(this, size, FLAGS_max_free_queue_size);
-      }
-    }
-  }
-
-  static size_t FreeQueueSize() {
-    SpinLockHolder l(&free_queue_lock_);
-    return free_queue_size_;
-  }
-
-  static void ProcessFreeQueue(MallocBlock* b, size_t size,
-                               int max_free_queue_size) {
-    // MallocBlockQueueEntry are about 144 in size, so we can only
-    // use a small array of them on the stack.
-    MallocBlockQueueEntry entries[4];
-    int num_entries = 0;
-    MallocBlockQueueEntry new_entry(b, size);
-    free_queue_lock_.Lock();
-    if (free_queue_ == NULL)
-      free_queue_ = new FreeQueue<MallocBlockQueueEntry>;
-    RAW_CHECK(!free_queue_->Full(), "Free queue mustn't be full!");
-
-    if (b != NULL) {
-      free_queue_size_ += size + sizeof(MallocBlockQueueEntry);
-      free_queue_->Push(new_entry);
-    }
-
-    // Free blocks until the total size of unfreed blocks no longer exceeds
-    // max_free_queue_size, and the free queue has at least one free
-    // space in it.
-    while (free_queue_size_ > max_free_queue_size || free_queue_->Full()) {
-      RAW_CHECK(num_entries < arraysize(entries), "entries array overflow");
-      entries[num_entries] = free_queue_->Pop();
-      free_queue_size_ -=
-          entries[num_entries].size + sizeof(MallocBlockQueueEntry);
-      num_entries++;
-      if (num_entries == arraysize(entries)) {
-        // The queue will not be full at this point, so it is ok to
-        // release the lock.  The queue may still contain more than
-        // max_free_queue_size, but this is not a strict invariant.
-        free_queue_lock_.Unlock();
-        for (int i = 0; i < num_entries; i++) {
-          CheckForDanglingWrites(entries[i]);
-          do_free(entries[i].block);
-        }
-        num_entries = 0;
-        free_queue_lock_.Lock();
-      }
-    }
-    free_queue_lock_.Unlock();
-    for (int i = 0; i < num_entries; i++) {
-      CheckForDanglingWrites(entries[i]);
-      do_free(entries[i].block);
-    }
-  }
-
-  static void InitDeletedBuffer() {
-    memset(kMagicDeletedBuffer, kMagicDeletedByte, sizeof(kMagicDeletedBuffer));
-    deleted_buffer_initialized_no_pthreads_ = true;
-  }
-
-  static void CheckForDanglingWrites(const MallocBlockQueueEntry& queue_entry) {
-    // Initialize the buffer if necessary.
-    if (pthread_once)
-      pthread_once(&deleted_buffer_initialized_, &InitDeletedBuffer);
-    if (!deleted_buffer_initialized_no_pthreads_) {
-      // This will be the case on systems that don't link in pthreads,
-      // including on FreeBSD where pthread_once has a non-zero address
-      // (but doesn't do anything) even when pthreads isn't linked in.
-      InitDeletedBuffer();
-    }
-
-    const unsigned char* p =
-        reinterpret_cast<unsigned char*>(queue_entry.block);
-
-    static const size_t size_of_buffer = sizeof(kMagicDeletedBuffer);
-    const size_t size = queue_entry.size;
-    const size_t buffers = size / size_of_buffer;
-    const size_t remainder = size % size_of_buffer;
-    size_t buffer_idx;
-    for (buffer_idx = 0; buffer_idx < buffers; ++buffer_idx) {
-      CheckForCorruptedBuffer(queue_entry, buffer_idx, p, size_of_buffer);
-      p += size_of_buffer;
-    }
-    CheckForCorruptedBuffer(queue_entry, buffer_idx, p, remainder);
-  }
-
-  static void CheckForCorruptedBuffer(const MallocBlockQueueEntry& queue_entry,
-                                      size_t buffer_idx,
-                                      const unsigned char* buffer,
-                                      size_t size_of_buffer) {
-    if (memcmp(buffer, kMagicDeletedBuffer, size_of_buffer) == 0) {
-      return;
-    }
-
-    RAW_LOG(ERROR,
-            "Found a corrupted memory buffer in MallocBlock (may be offset "
-            "from user ptr): buffer index: %zd, buffer ptr: %p, size of "
-            "buffer: %zd", buffer_idx, buffer, size_of_buffer);
-
-    // The magic deleted buffer should only be 1024 bytes, but in case
-    // this changes, let's put an upper limit on the number of debug
-    // lines we'll output:
-    if (size_of_buffer <= 1024) {
-      for (int i = 0; i < size_of_buffer; ++i) {
-        if (buffer[i] != kMagicDeletedByte) {
-          RAW_LOG(ERROR, "Buffer byte %d is 0x%02x (should be 0x%02x).",
-                  i, buffer[i], kMagicDeletedByte);
-        }
-      }
-    } else {
-      RAW_LOG(ERROR, "Buffer too large to print corruption.");
-    }
-
-    const MallocBlock* b = queue_entry.block;
-    const size_t size = queue_entry.size;
-    if (queue_entry.num_deleter_pcs > 0) {
-      TracePrintf(STDERR_FILENO, "Deleted by thread %p\n",
-                  reinterpret_cast<void*>(
-                      PRINTABLE_PTHREAD(queue_entry.deleter_threadid)));
-
-      // We don't want to allocate or deallocate memory here, so we use
-      // placement-new.  It's ok that we don't destroy this, since we're
-      // just going to error-exit below anyway.  Union is for alignment.
-      union { void* alignment; char buf[sizeof(SymbolTable)]; } tablebuf;
-      SymbolTable* symbolization_table = new (tablebuf.buf) SymbolTable;
-      for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {
-        // Symbolizes the previous address of pc because pc may be in the
-        // next function.  This may happen when the function ends with
-        // a call to a function annotated noreturn (e.g. CHECK).
-        char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);
-        symbolization_table->Add(pc - 1);
-      }
-      if (FLAGS_symbolize_stacktrace)
-        symbolization_table->Symbolize();
-      for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {
-        char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);
-        TracePrintf(STDERR_FILENO, "    @ %p %s\n",
-                    pc, symbolization_table->GetSymbol(pc - 1));
-      }
-    } else {
-      RAW_LOG(ERROR,
-              "Skipping the printing of the deleter's stack!  Its stack was "
-              "not found; either the corruption occurred too early in "
-              "execution to obtain a stack trace or --max_free_queue_size was "
-              "set to 0.");
-    }
-
-    RAW_LOG(FATAL,
-            "Memory was written to after being freed.  MallocBlock: %p, user "
-            "ptr: %p, size: %zd.  If you can't find the source of the error, "
-            "try using ASan (http://code.google.com/p/address-sanitizer/), "
-            "Valgrind, or Purify, or study the "
-            "output of the deleter's stack printed above.",
-            b, b->data_addr(), size);
-  }
-
-  static MallocBlock* FromRawPointer(void* p) {
-    const size_t data_offset = MallocBlock::data_offset();
-    // Find the header just before client's memory.
-    MallocBlock *mb = reinterpret_cast<MallocBlock *>(
-                reinterpret_cast<char *>(p) - data_offset);
-    // If mb->alloc_type_ is kMagicDeletedSizeT, we're not an ok pointer.
-    if (mb->alloc_type_ == kMagicDeletedSizeT) {
-      RAW_LOG(FATAL, "memory allocation bug: object at %p has been already"
-                     " deallocated; or else a word before the object has been"
-                     " corrupted (memory stomping bug)", p);
-    }
-    // If mb->offset_ is zero (common case), mb is the real header.
-    // If mb->offset_ is non-zero, this block was allocated by debug
-    // memallign implementation, and mb->offset_ is the distance
-    // backwards to the real header from mb, which is a fake header.
-    if (mb->offset_ == 0) {
-      return mb;
-    }
-
-    MallocBlock *main_block = reinterpret_cast<MallocBlock *>(
-      reinterpret_cast<char *>(mb) - mb->offset_);
-
-    if (main_block->offset_ != 0) {
-      RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted."
-              " Need 0 but got %x",
-              (unsigned)(main_block->offset_));
-    }
-    if (main_block >= p) {
-      RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted."
-              " Detected main_block address overflow: %x",
-              (unsigned)(mb->offset_));
-    }
-    if (main_block->size2_addr() < p) {
-      RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted."
-              " It points below it's own main_block: %x",
-              (unsigned)(mb->offset_));
-    }
-
-    return main_block;
-  }
-
-  static const MallocBlock* FromRawPointer(const void* p) {
-    // const-safe version: we just cast about
-    return FromRawPointer(const_cast<void*>(p));
-  }
-
-  // Return whether p points to memory returned by memalign.
-  // Requires that p be non-zero and has been checked for sanity with
-  // FromRawPointer().
-  static bool IsMemaligned(const void* p) {
-    const MallocBlock* mb = reinterpret_cast<const MallocBlock*>(
-        reinterpret_cast<const char*>(p) - MallocBlock::data_offset());
-    // If the offset is non-zero, the block was allocated by memalign
-    // (see FromRawPointer above).
-    return mb->offset_ != 0;
-  }
-
-  void Check(int type) const {
-    alloc_map_lock_.Lock();
-    CheckLocked(type);
-    alloc_map_lock_.Unlock();
-  }
-
-  static bool CheckEverything() {
-    alloc_map_lock_.Lock();
-    if (alloc_map_ != NULL)  alloc_map_->Iterate(CheckCallback, 0);
-    alloc_map_lock_.Unlock();
-    return true;  // if we get here, we're okay
-  }
-
-  static bool MemoryStats(int* blocks, size_t* total,
-                          int histogram[kMallocHistogramSize]) {
-    memset(histogram, 0, kMallocHistogramSize * sizeof(int));
-    alloc_map_lock_.Lock();
-    stats_blocks_ = 0;
-    stats_total_ = 0;
-    stats_histogram_ = histogram;
-    if (alloc_map_ != NULL) alloc_map_->Iterate(StatsCallback, 0);
-    *blocks = stats_blocks_;
-    *total = stats_total_;
-    alloc_map_lock_.Unlock();
-    return true;
-  }
-
- private:  // helpers for CheckEverything and MemoryStats
-
-  static void CheckCallback(const void* ptr, int* type, int dummy) {
-    if ((*type & kDeallocatedTypeBit) == 0) {
-      FromRawPointer(ptr)->CheckLocked(*type);
-    }
-  }
-
-  // Accumulation variables for StatsCallback protected by alloc_map_lock_
-  static int stats_blocks_;
-  static size_t stats_total_;
-  static int* stats_histogram_;
-
-  static void StatsCallback(const void* ptr, int* type, int dummy) {
-    if ((*type & kDeallocatedTypeBit) == 0) {
-      const MallocBlock* b = FromRawPointer(ptr);
-      b->CheckLocked(*type);
-      ++stats_blocks_;
-      size_t mysize = b->size1_;
-      int entry = 0;
-      stats_total_ += mysize;
-      while (mysize) {
-        ++entry;
-        mysize >>= 1;
-      }
-      RAW_CHECK(entry < kMallocHistogramSize,
-                "kMallocHistogramSize should be at least as large as log2 "
-                "of the maximum process memory size");
-      stats_histogram_[entry] += 1;
-    }
-  }
-};
-
-void DanglingWriteChecker() {
-  // Clear out the remaining free queue to check for dangling writes.
-  MallocBlock::ProcessFreeQueue(NULL, 0, 0);
-}
-
-// ========================================================================= //
-
-const size_t MallocBlock::kMagicMalloc;
-const size_t MallocBlock::kMagicMMap;
-
-MallocBlock::AllocMap* MallocBlock::alloc_map_ = NULL;
-SpinLock MallocBlock::alloc_map_lock_(SpinLock::LINKER_INITIALIZED);
-
-FreeQueue<MallocBlockQueueEntry>* MallocBlock::free_queue_ = NULL;
-size_t MallocBlock::free_queue_size_ = 0;
-SpinLock MallocBlock::free_queue_lock_(SpinLock::LINKER_INITIALIZED);
-
-unsigned char MallocBlock::kMagicDeletedBuffer[1024];
-pthread_once_t MallocBlock::deleted_buffer_initialized_ = PTHREAD_ONCE_INIT;
-bool MallocBlock::deleted_buffer_initialized_no_pthreads_ = false;
-
-const char* const MallocBlock::kAllocName[] = {
-  "malloc",
-  "new",
-  "new []",
-  NULL,
-};
-
-const char* const MallocBlock::kDeallocName[] = {
-  "free",
-  "delete",
-  "delete []",
-  NULL,
-};
-
-int MallocBlock::stats_blocks_;
-size_t MallocBlock::stats_total_;
-int* MallocBlock::stats_histogram_;
-
-// ========================================================================= //
-
-// The following cut-down version of printf() avoids
-// using stdio or ostreams.
-// This is to guarantee no recursive calls into
-// the allocator and to bound the stack space consumed.  (The pthread
-// manager thread in linuxthreads has a very small stack,
-// so fprintf can't be called.)
-static void TracePrintf(int fd, const char *fmt, ...) {
-  char buf[64];
-  int i = 0;
-  va_list ap;
-  va_start(ap, fmt);
-  const char *p = fmt;
-  char numbuf[25];
-  if (fd < 0) {
-    va_end(ap);
-    return;
-  }
-  numbuf[sizeof(numbuf)-1] = 0;
-  while (*p != '\0') {              // until end of format string
-    char *s = &numbuf[sizeof(numbuf)-1];
-    if (p[0] == '%' && p[1] != 0) {  // handle % formats
-      int64 l = 0;
-      unsigned long base = 0;
-      if (*++p == 's') {                            // %s
-        s = va_arg(ap, char *);
-      } else if (*p == 'l' && p[1] == 'd') {        // %ld
-        l = va_arg(ap, long);
-        base = 10;
-        p++;
-      } else if (*p == 'l' && p[1] == 'u') {        // %lu
-        l = va_arg(ap, unsigned long);
-        base = 10;
-        p++;
-      } else if (*p == 'z' && p[1] == 'u') {        // %zu
-        l = va_arg(ap, size_t);
-        base = 10;
-        p++;
-      } else if (*p == 'u') {                       // %u
-        l = va_arg(ap, unsigned int);
-        base = 10;
-      } else if (*p == 'd') {                       // %d
-        l = va_arg(ap, int);
-        base = 10;
-      } else if (*p == 'p') {                       // %p
-        l = va_arg(ap, intptr_t);
-        base = 16;
-      } else {
-        write(STDERR_FILENO, "Unimplemented TracePrintf format\n", 33);
-        write(STDERR_FILENO, p, 2);
-        write(STDERR_FILENO, "\n", 1);
-        tcmalloc::Abort();
-      }
-      p++;
-      if (base != 0) {
-        bool minus = (l < 0 && base == 10);
-        uint64 ul = minus? -l : l;
-        do {
-          *--s = "0123456789abcdef"[ul % base];
-          ul /= base;
-        } while (ul != 0);
-        if (base == 16) {
-          *--s = 'x';
-          *--s = '0';
-        } else if (minus) {
-          *--s = '-';
-        }
-      }
-    } else {                        // handle normal characters
-      *--s = *p++;
-    }
-    while (*s != 0) {
-      if (i == sizeof(buf)) {
-        write(fd, buf, i);
-        i = 0;
-      }
-      buf[i++] = *s++;
-    }
-  }
-  if (i != 0) {
-    write(fd, buf, i);
-  }
-  va_end(ap);
-}
-
-// Return the file descriptor we're writing a log to
-static int TraceFd() {
-  static int trace_fd = -1;
-  if (trace_fd == -1) {            // Open the trace file on the first call
-    const char *val = getenv("TCMALLOC_TRACE_FILE");
-    bool fallback_to_stderr = false;
-    if (!val) {
-      val = "/tmp/google.alloc";
-      fallback_to_stderr = true;
-    }
-    trace_fd = open(val, O_CREAT|O_TRUNC|O_WRONLY, 0666);
-    if (trace_fd == -1) {
-      if (fallback_to_stderr) {
-        trace_fd = 2;
-        TracePrintf(trace_fd, "Can't open %s.  Logging to stderr.\n", val);
-      } else {
-        TracePrintf(2, "Can't open %s.  Logging disabled.\n", val);
-      }
-    }
-    // Add a header to the log.
-    TracePrintf(trace_fd, "Trace started: %lu\n",
-                static_cast<unsigned long>(time(NULL)));
-    TracePrintf(trace_fd,
-                "func\tsize\tptr\tthread_id\tstack pcs for tools/symbolize\n");
-  }
-  return trace_fd;
-}
-
-// Print the hex stack dump on a single line.   PCs are separated by tabs.
-static void TraceStack(void) {
-  void *pcs[16];
-  int n = GetStackTrace(pcs, sizeof(pcs)/sizeof(pcs[0]), 0);
-  for (int i = 0; i != n; i++) {
-    TracePrintf(TraceFd(), "\t%p", pcs[i]);
-  }
-}
-
-// This protects MALLOC_TRACE, to make sure its info is atomically written.
-static SpinLock malloc_trace_lock(SpinLock::LINKER_INITIALIZED);
-
-#define MALLOC_TRACE(name, size, addr)                                  \
-  do {                                                                  \
-    if (FLAGS_malloctrace) {                                            \
-      SpinLockHolder l(&malloc_trace_lock);                             \
-      TracePrintf(TraceFd(), "%s\t%" PRIuS "\t%p\t%" GPRIuPTHREAD,      \
-                  name, size, addr, PRINTABLE_PTHREAD(pthread_self())); \
-      TraceStack();                                                     \
-      TracePrintf(TraceFd(), "\n");                                     \
-    }                                                                   \
-  } while (0)
-
-// ========================================================================= //
-
-// Write the characters buf[0, ..., size-1] to
-// the malloc trace buffer.
-// This function is intended for debugging,
-// and is not declared in any header file.
-// You must insert a declaration of it by hand when you need
-// to use it.
-void __malloctrace_write(const char *buf, size_t size) {
-  if (FLAGS_malloctrace) {
-    write(TraceFd(), buf, size);
-  }
-}
-
-// ========================================================================= //
-
-// General debug allocation/deallocation
-
-static inline void* DebugAllocate(size_t size, int type) {
-  MallocBlock* ptr = MallocBlock::Allocate(size, type);
-  if (ptr == NULL)  return NULL;
-  MALLOC_TRACE("malloc", size, ptr->data_addr());
-  return ptr->data_addr();
-}
-
-static inline void DebugDeallocate(void* ptr, int type, size_t given_size) {
-  MALLOC_TRACE("free",
-               (ptr != 0 ? MallocBlock::FromRawPointer(ptr)->data_size() : 0),
-               ptr);
-  if (ptr)  MallocBlock::FromRawPointer(ptr)->Deallocate(type, given_size);
-}
-
-// ========================================================================= //
-
-// The following functions may be called via MallocExtension::instance()
-// for memory verification and statistics.
-class DebugMallocImplementation : public TCMallocImplementation {
- public:
-  virtual bool GetNumericProperty(const char* name, size_t* value) {
-    bool result = TCMallocImplementation::GetNumericProperty(name, value);
-    if (result && (strcmp(name, "generic.current_allocated_bytes") == 0)) {
-      // Subtract bytes kept in the free queue
-      size_t qsize = MallocBlock::FreeQueueSize();
-      if (*value >= qsize) {
-        *value -= qsize;
-      }
-    }
-    return result;
-  }
-
-  virtual bool VerifyNewMemory(const void* p) {
-    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kNewType);
-    return true;
-  }
-
-  virtual bool VerifyArrayNewMemory(const void* p) {
-    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kArrayNewType);
-    return true;
-  }
-
-  virtual bool VerifyMallocMemory(const void* p) {
-    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kMallocType);
-    return true;
-  }
-
-  virtual bool VerifyAllMemory() {
-    return MallocBlock::CheckEverything();
-  }
-
-  virtual bool MallocMemoryStats(int* blocks, size_t* total,
-                                 int histogram[kMallocHistogramSize]) {
-    return MallocBlock::MemoryStats(blocks, total, histogram);
-  }
-
-  virtual size_t GetEstimatedAllocatedSize(size_t size) {
-    return size;
-  }
-
-  virtual size_t GetAllocatedSize(const void* p) {
-    if (p) {
-      RAW_CHECK(GetOwnership(p) != MallocExtension::kNotOwned,
-                "ptr not allocated by tcmalloc");
-      return MallocBlock::FromRawPointer(p)->data_size();
-    }
-    return 0;
-  }
-
-  virtual MallocExtension::Ownership GetOwnership(const void* p) {
-    if (!p) {
-      // nobody owns NULL
-      return MallocExtension::kNotOwned;
-    }
-
-    // FIXME: note that correct GetOwnership should not touch memory
-    // that is not owned by tcmalloc. Main implementation is using
-    // pagemap to discover if page in question is owned by us or
-    // not. But pagemap only has marks for first and last page of
-    // spans.  Note that if p was returned out of our memalign with
-    // big alignment, then it will point outside of marked pages. Also
-    // note that FromRawPointer call below requires touching memory
-    // before pointer in order to handle memalign-ed chunks
-    // (offset_). This leaves us with two options:
-    //
-    // * do FromRawPointer first and have possibility of crashing if
-    //   we're given not owned pointer
-    //
-    // * return incorrect ownership for those large memalign chunks
-    //
-    // I've decided to choose later, which appears to happen rarer and
-    // therefore is arguably a lesser evil
-
-    MallocExtension::Ownership rv = TCMallocImplementation::GetOwnership(p);
-    if (rv != MallocExtension::kOwned) {
-      return rv;
-    }
-
-    const MallocBlock* mb = MallocBlock::FromRawPointer(p);
-    return TCMallocImplementation::GetOwnership(mb);
-  }
-
-  virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {
-    static const char* kDebugFreeQueue = "debug.free_queue";
-
-    TCMallocImplementation::GetFreeListSizes(v);
-
-    MallocExtension::FreeListInfo i;
-    i.type = kDebugFreeQueue;
-    i.min_object_size = 0;
-    i.max_object_size = numeric_limits<size_t>::max();
-    i.total_bytes_free = MallocBlock::FreeQueueSize();
-    v->push_back(i);
-  }
-
- };
-
-static union {
-  char chars[sizeof(DebugMallocImplementation)];
-  void *ptr;
-} debug_malloc_implementation_space;
-
-REGISTER_MODULE_INITIALIZER(debugallocation, {
-#if (__cplusplus >= 201103L)
-  static_assert(
-      alignof(decltype(debug_malloc_implementation_space)) >=
-          alignof(DebugMallocImplementation),
-      "DebugMallocImplementation is expected to need just word alignment");
-#endif
-  // Either we or valgrind will control memory management.  We
-  // register our extension if we're the winner. Otherwise let
-  // Valgrind use its own malloc (so don't register our extension).
-  if (!RunningOnValgrind()) {
-    DebugMallocImplementation *impl = new (debug_malloc_implementation_space.chars) DebugMallocImplementation();
-    MallocExtension::Register(impl);
-  }
-});
-
-REGISTER_MODULE_DESTRUCTOR(debugallocation, {
-  if (!RunningOnValgrind()) {
-    // When the program exits, check all blocks still in the free
-    // queue for corruption.
-    DanglingWriteChecker();
-  }
-});
-
-// ========================================================================= //
-
-struct debug_alloc_retry_data {
-  size_t size;
-  int new_type;
-};
-
-static void *retry_debug_allocate(void *arg) {
-  debug_alloc_retry_data *data = static_cast<debug_alloc_retry_data *>(arg);
-  return DebugAllocate(data->size, data->new_type);
-}
-
-// This is mostly the same a cpp_alloc in tcmalloc.cc.
-// TODO(csilvers): change Allocate() above to call cpp_alloc, so we
-// don't have to reproduce the logic here.  To make tc_new_mode work
-// properly, I think we'll need to separate out the logic of throwing
-// from the logic of calling the new-handler.
-inline void* debug_cpp_alloc(size_t size, int new_type, bool nothrow) {
-  void* p = DebugAllocate(size, new_type);
-  if (p != NULL) {
-    return p;
-  }
-  struct debug_alloc_retry_data data;
-  data.size = size;
-  data.new_type = new_type;
-  return handle_oom(retry_debug_allocate, &data,
-                    true, nothrow);
-}
-
-inline void* do_debug_malloc_or_debug_cpp_alloc(size_t size) {
-  void* p = DebugAllocate(size, MallocBlock::kMallocType);
-  if (p != NULL) {
-    return p;
-  }
-  struct debug_alloc_retry_data data;
-  data.size = size;
-  data.new_type = MallocBlock::kMallocType;
-  return handle_oom(retry_debug_allocate, &data,
-                    false, true);
-}
-
-// Exported routines
-
-// frame forcer and force_frame exist only to prevent tail calls to
-// DebugDeallocate to be actually implemented as tail calls. This is
-// important because stack trace capturing in MallocBlockQueueEntry
-// relies on google_malloc section being on stack and tc_XXX functions
-// are in that section. So they must not jump to DebugDeallocate but
-// have to do call. frame_forcer call at the end of such functions
-// prevents tail calls to DebugDeallocate.
-static int frame_forcer;
-static void force_frame() {
-  int dummy = *(int volatile *)&frame_forcer;
-  (void)dummy;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW {
-  if (ThreadCache::IsUseEmergencyMalloc()) {
-    return tcmalloc::EmergencyMalloc(size);
-  }
-  void* ptr = do_debug_malloc_or_debug_cpp_alloc(size);
-  MallocHook::InvokeNewHook(ptr, size);
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW {
-  if (tcmalloc::IsEmergencyPtr(ptr)) {
-    return tcmalloc::EmergencyFree(ptr);
-  }
-  MallocHook::InvokeDeleteHook(ptr);
-  DebugDeallocate(ptr, MallocBlock::kMallocType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(ptr);
-  DebugDeallocate(ptr, MallocBlock::kMallocType, size);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_calloc(size_t count, size_t size) PERFTOOLS_NOTHROW {
-  if (ThreadCache::IsUseEmergencyMalloc()) {
-    return tcmalloc::EmergencyCalloc(count, size);
-  }
-  // Overflow check
-  const size_t total_size = count * size;
-  if (size != 0 && total_size / size != count) return NULL;
-
-  void* block = do_debug_malloc_or_debug_cpp_alloc(total_size);
-  MallocHook::InvokeNewHook(block, total_size);
-  if (block)  memset(block, 0, total_size);
-  return block;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW {
-  if (tcmalloc::IsEmergencyPtr(ptr)) {
-    return tcmalloc::EmergencyFree(ptr);
-  }
-  MallocHook::InvokeDeleteHook(ptr);
-  DebugDeallocate(ptr, MallocBlock::kMallocType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW {
-  if (tcmalloc::IsEmergencyPtr(ptr)) {
-    return tcmalloc::EmergencyRealloc(ptr, size);
-  }
-  if (ptr == NULL) {
-    ptr = do_debug_malloc_or_debug_cpp_alloc(size);
-    MallocHook::InvokeNewHook(ptr, size);
-    return ptr;
-  }
-  MallocBlock* old = MallocBlock::FromRawPointer(ptr);
-  old->Check(MallocBlock::kMallocType);
-  if (MallocBlock::IsMemaligned(ptr)) {
-    RAW_LOG(FATAL,
-            "realloc/memalign mismatch at %p: "
-            "non-NULL pointers passed to realloc must be obtained "
-            "from malloc, calloc, or realloc",
-            ptr);
-  }
-  if (size == 0) {
-    MallocHook::InvokeDeleteHook(ptr);
-    DebugDeallocate(ptr, MallocBlock::kMallocType, 0);
-    return NULL;
-  }
-  MallocBlock* p = MallocBlock::Allocate(size, MallocBlock::kMallocType);
-
-  // If realloc fails we are to leave the old block untouched and
-  // return null
-  if (p == NULL)  return NULL;
-
-  // if ptr was allocated via memalign, then old->data_size() is not
-  // start of user data. So we must be careful to copy only user-data
-  char *old_begin = (char *)old->data_addr();
-  char *old_end = old_begin + old->data_size();
-
-  ssize_t old_ssize = old_end - (char *)ptr;
-  CHECK_CONDITION(old_ssize >= 0);
-
-  size_t old_size = (size_t)old_ssize;
-  CHECK_CONDITION(old_size <= old->data_size());
-
-  memcpy(p->data_addr(), ptr, (old_size < size) ? old_size : size);
-  MallocHook::InvokeDeleteHook(ptr);
-  MallocHook::InvokeNewHook(p->data_addr(), size);
-  DebugDeallocate(ptr, MallocBlock::kMallocType, 0);
-  MALLOC_TRACE("realloc", p->data_size(), p->data_addr());
-  return p->data_addr();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new(size_t size) {
-  void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, false);
-  MallocHook::InvokeNewHook(ptr, size);
-  if (ptr == NULL) {
-    RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new failed.", size);
-  }
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, true);
-  MallocHook::InvokeNewHook(ptr, size);
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kNewType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kNewType, size);
-  force_frame();
-}
-
-// Some STL implementations explicitly invoke this.
-// It is completely equivalent to a normal delete (delete never throws).
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kNewType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size) {
-  void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, false);
-  MallocHook::InvokeNewHook(ptr, size);
-  if (ptr == NULL) {
-    RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new[] failed.", size);
-  }
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::nothrow_t&)
-    PERFTOOLS_NOTHROW {
-  void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, true);
-  MallocHook::InvokeNewHook(ptr, size);
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kArrayNewType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kArrayNewType, size);
-  force_frame();
-}
-
-// Some STL implementations explicitly invoke this.
-// It is completely equivalent to a normal delete (delete never throws).
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kArrayNewType, 0);
-  force_frame();
-}
-
-// This is mostly the same as do_memalign in tcmalloc.cc.
-static void *do_debug_memalign(size_t alignment, size_t size, int type) {
-  // Allocate >= size bytes aligned on "alignment" boundary
-  // "alignment" is a power of two.
-  void *p = 0;
-  RAW_CHECK((alignment & (alignment-1)) == 0, "must be power of two");
-  const size_t data_offset = MallocBlock::data_offset();
-  // Allocate "alignment-1" extra bytes to ensure alignment is possible, and
-  // a further data_offset bytes for an additional fake header.
-  size_t extra_bytes = data_offset + alignment - 1;
-  if (size + extra_bytes < size) return NULL;         // Overflow
-  p = DebugAllocate(size + extra_bytes, type);
-  if (p != 0) {
-    intptr_t orig_p = reinterpret_cast<intptr_t>(p);
-    // Leave data_offset bytes for fake header, and round up to meet
-    // alignment.
-    p = reinterpret_cast<void *>(RoundUp(orig_p + data_offset, alignment));
-    // Create a fake header block with an offset_ that points back to the
-    // real header.  FromRawPointer uses this value.
-    MallocBlock *fake_hdr = reinterpret_cast<MallocBlock *>(
-                reinterpret_cast<char *>(p) - data_offset);
-    // offset_ is distance between real and fake headers.
-    // p is now end of fake header (beginning of client area),
-    // and orig_p is the end of the real header, so offset_
-    // is their difference.
-    //
-    // Note that other fields of fake_hdr are initialized with
-    // kMagicUninitializedByte
-    fake_hdr->set_offset(reinterpret_cast<intptr_t>(p) - orig_p);
-  }
-  return p;
-}
-
-struct memalign_retry_data {
-  size_t align;
-  size_t size;
-  int type;
-};
-
-static void *retry_debug_memalign(void *arg) {
-  memalign_retry_data *data = static_cast<memalign_retry_data *>(arg);
-  return do_debug_memalign(data->align, data->size, data->type);
-}
-
-ATTRIBUTE_ALWAYS_INLINE
-inline void* do_debug_memalign_or_debug_cpp_memalign(size_t align,
-                                                     size_t size,
-                                                     int type,
-                                                     bool from_operator,
-                                                     bool nothrow) {
-  void* p = do_debug_memalign(align, size, type);
-  if (p != NULL) {
-    return p;
-  }
-
-  struct memalign_retry_data data;
-  data.align = align;
-  data.size = size;
-  data.type = type;
-  return handle_oom(retry_debug_memalign, &data,
-                    from_operator, nothrow);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_memalign(size_t align, size_t size) PERFTOOLS_NOTHROW {
-  void *p = do_debug_memalign_or_debug_cpp_memalign(align, size, MallocBlock::kMallocType, false, true);
-  MallocHook::InvokeNewHook(p, size);
-  return p;
-}
-
-// Implementation taken from tcmalloc/tcmalloc.cc
-extern "C" PERFTOOLS_DLL_DECL int tc_posix_memalign(void** result_ptr, size_t align, size_t size)
-    PERFTOOLS_NOTHROW {
-  if (((align % sizeof(void*)) != 0) ||
-      ((align & (align - 1)) != 0) ||
-      (align == 0)) {
-    return EINVAL;
-  }
-
-  void* result = do_debug_memalign_or_debug_cpp_memalign(align, size, MallocBlock::kMallocType, false, true);
-  MallocHook::InvokeNewHook(result, size);
-  if (result == NULL) {
-    return ENOMEM;
-  } else {
-    *result_ptr = result;
-    return 0;
-  }
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_valloc(size_t size) PERFTOOLS_NOTHROW {
-  // Allocate >= size bytes starting on a page boundary
-  void *p = do_debug_memalign_or_debug_cpp_memalign(getpagesize(), size, MallocBlock::kMallocType, false, true);
-  MallocHook::InvokeNewHook(p, size);
-  return p;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t size) PERFTOOLS_NOTHROW {
-  // Round size up to a multiple of pages
-  // then allocate memory on a page boundary
-  int pagesize = getpagesize();
-  size = RoundUp(size, pagesize);
-  if (size == 0) {     // pvalloc(0) should allocate one page, according to
-    size = pagesize;   // http://man.free4web.biz/man3/libmpatrol.3.html
-  }
-  void *p = do_debug_memalign_or_debug_cpp_memalign(pagesize, size, MallocBlock::kMallocType, false, true);
-  MallocHook::InvokeNewHook(p, size);
-  return p;
-}
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t align) {
-  void* result = do_debug_memalign_or_debug_cpp_memalign(static_cast<size_t>(align), size, MallocBlock::kNewType, true, false);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t align, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  void* result = do_debug_memalign_or_debug_cpp_memalign(static_cast<size_t>(align), size, MallocBlock::kNewType, true, true);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t) PERFTOOLS_NOTHROW {
-  tc_delete(p);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t align) PERFTOOLS_NOTHROW {
-  // Reproduce actual size calculation done by do_debug_memalign
-  const size_t alignment = static_cast<size_t>(align);
-  const size_t data_offset = MallocBlock::data_offset();
-  const size_t extra_bytes = data_offset + alignment - 1;
-
-  tc_delete_sized(p, size + extra_bytes);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  tc_delete(p);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t align) {
-  void* result = do_debug_memalign_or_debug_cpp_memalign(static_cast<size_t>(align), size, MallocBlock::kArrayNewType, true, false);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t align, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
-  void* result = do_debug_memalign_or_debug_cpp_memalign(static_cast<size_t>(align), size, MallocBlock::kArrayNewType, true, true);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t) PERFTOOLS_NOTHROW {
-  tc_deletearray(p);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t align) PERFTOOLS_NOTHROW {
-  // Reproduce actual size calculation done by do_debug_memalign
-  const size_t alignment = static_cast<size_t>(align);
-  const size_t data_offset = MallocBlock::data_offset();
-  const size_t extra_bytes = data_offset + alignment - 1;
-
-  tc_deletearray_sized(p, size + extra_bytes);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  tc_deletearray(p);
-}
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-// malloc_stats just falls through to the base implementation.
-extern "C" PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW {
-  do_malloc_stats();
-}
-
-extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW {
-  return do_mallopt(cmd, value);
-}
-
-#ifdef HAVE_STRUCT_MALLINFO
-extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW {
-  return do_mallinfo();
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW {
-  return MallocExtension::instance()->GetAllocatedSize(ptr);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW {
-  void* result = DebugAllocate(size, MallocBlock::kMallocType);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
diff --git a/third_party/tcmalloc/chromium/src/emergency_malloc.cc b/third_party/tcmalloc/chromium/src/emergency_malloc.cc
deleted file mode 100644
index 81c5554..0000000
--- a/third_party/tcmalloc/chromium/src/emergency_malloc.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "config.h"
-
-#include "emergency_malloc.h"
-
-#include <errno.h>                      // for ENOMEM, errno
-#include <string.h>                     // for memset
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/low_level_alloc.h"
-#include "base/spinlock.h"
-#include "internal_logging.h"
-
-
-namespace tcmalloc {
-  __attribute__ ((visibility("internal"))) char *emergency_arena_start;
-  __attribute__ ((visibility("internal"))) uintptr_t emergency_arena_start_shifted;
-
-  static CACHELINE_ALIGNED SpinLock emergency_malloc_lock(base::LINKER_INITIALIZED);
-  static char *emergency_arena_end;
-  static LowLevelAlloc::Arena *emergency_arena;
-
-  class EmergencyArenaPagesAllocator : public LowLevelAlloc::PagesAllocator {
-    ~EmergencyArenaPagesAllocator() {}
-    void *MapPages(int32 flags, size_t size) {
-      char *new_end = emergency_arena_end + size;
-      if (new_end > emergency_arena_start + kEmergencyArenaSize) {
-        RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes in emergency zone.", size);
-      }
-      char *rv = emergency_arena_end;
-      emergency_arena_end = new_end;
-      return static_cast<void *>(rv);
-    }
-    void UnMapPages(int32 flags, void *addr, size_t size) {
-      RAW_LOG(FATAL, "UnMapPages is not implemented for emergency arena");
-    }
-  };
-
-  static union {
-    char bytes[sizeof(EmergencyArenaPagesAllocator)];
-    void *ptr;
-  } pages_allocator_place;
-
-  static void InitEmergencyMalloc(void) {
-    const int32 flags = LowLevelAlloc::kAsyncSignalSafe;
-
-    void *arena = LowLevelAlloc::GetDefaultPagesAllocator()->MapPages(flags, kEmergencyArenaSize * 2);
-
-    uintptr_t arena_ptr = reinterpret_cast<uintptr_t>(arena);
-    uintptr_t ptr = (arena_ptr + kEmergencyArenaSize - 1) & ~(kEmergencyArenaSize-1);
-
-    emergency_arena_end = emergency_arena_start = reinterpret_cast<char *>(ptr);
-    EmergencyArenaPagesAllocator *allocator = new (pages_allocator_place.bytes) EmergencyArenaPagesAllocator();
-    emergency_arena = LowLevelAlloc::NewArenaWithCustomAlloc(0, LowLevelAlloc::DefaultArena(), allocator);
-
-    emergency_arena_start_shifted = reinterpret_cast<uintptr_t>(emergency_arena_start) >> kEmergencyArenaShift;
-
-    uintptr_t head_unmap_size = ptr - arena_ptr;
-    CHECK_CONDITION(head_unmap_size < kEmergencyArenaSize);
-    if (head_unmap_size != 0) {
-      LowLevelAlloc::GetDefaultPagesAllocator()->UnMapPages(flags, arena, ptr - arena_ptr);
-    }
-
-    uintptr_t tail_unmap_size = kEmergencyArenaSize - head_unmap_size;
-    void *tail_start = reinterpret_cast<void *>(arena_ptr + head_unmap_size + kEmergencyArenaSize);
-    LowLevelAlloc::GetDefaultPagesAllocator()->UnMapPages(flags, tail_start, tail_unmap_size);
-  }
-
-  PERFTOOLS_DLL_DECL void *EmergencyMalloc(size_t size) {
-    SpinLockHolder l(&emergency_malloc_lock);
-
-    if (emergency_arena_start == NULL) {
-      InitEmergencyMalloc();
-      CHECK_CONDITION(emergency_arena_start != NULL);
-    }
-
-    void *rv = LowLevelAlloc::AllocWithArena(size, emergency_arena);
-    if (rv == NULL) {
-      errno = ENOMEM;
-    }
-    return rv;
-  }
-
-  PERFTOOLS_DLL_DECL void EmergencyFree(void *p) {
-    SpinLockHolder l(&emergency_malloc_lock);
-    if (emergency_arena_start == NULL) {
-      InitEmergencyMalloc();
-      CHECK_CONDITION(emergency_arena_start != NULL);
-      free(p);
-      return;
-    }
-    CHECK_CONDITION(emergency_arena_start);
-    LowLevelAlloc::Free(p);
-  }
-
-  PERFTOOLS_DLL_DECL void *EmergencyRealloc(void *_old_ptr, size_t new_size) {
-    if (_old_ptr == NULL) {
-      return EmergencyMalloc(new_size);
-    }
-    if (new_size == 0) {
-      EmergencyFree(_old_ptr);
-      return NULL;
-    }
-    SpinLockHolder l(&emergency_malloc_lock);
-    CHECK_CONDITION(emergency_arena_start);
-
-    char *old_ptr = static_cast<char *>(_old_ptr);
-    CHECK_CONDITION(old_ptr <= emergency_arena_end);
-    CHECK_CONDITION(emergency_arena_start <= old_ptr);
-
-    // NOTE: we don't know previous size of old_ptr chunk. So instead
-    // of trying to figure out right size of copied memory, we just
-    // copy largest possible size. We don't care about being slow.
-    size_t old_ptr_size = emergency_arena_end - old_ptr;
-    size_t copy_size = (new_size < old_ptr_size) ? new_size : old_ptr_size;
-
-    void *new_ptr = LowLevelAlloc::AllocWithArena(new_size, emergency_arena);
-    if (new_ptr == NULL) {
-      errno = ENOMEM;
-      return NULL;
-    }
-    memcpy(new_ptr, old_ptr, copy_size);
-
-    LowLevelAlloc::Free(old_ptr);
-    return new_ptr;
-  }
-
-  PERFTOOLS_DLL_DECL void *EmergencyCalloc(size_t n, size_t elem_size) {
-    // Overflow check
-    const size_t size = n * elem_size;
-    if (elem_size != 0 && size / elem_size != n) return NULL;
-    void *rv = EmergencyMalloc(size);
-    if (rv != NULL) {
-      memset(rv, 0, size);
-    }
-    return rv;
-  }
-};
diff --git a/third_party/tcmalloc/chromium/src/emergency_malloc.h b/third_party/tcmalloc/chromium/src/emergency_malloc.h
deleted file mode 100644
index 8a82cfc..0000000
--- a/third_party/tcmalloc/chromium/src/emergency_malloc.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef EMERGENCY_MALLOC_H
-#define EMERGENCY_MALLOC_H
-#include "config.h"
-
-#include <stddef.h>
-
-#include "base/basictypes.h"
-#include "common.h"
-
-namespace tcmalloc {
-  static const uintptr_t kEmergencyArenaShift = 20+4; // 16 megs
-  static const uintptr_t kEmergencyArenaSize = 1 << kEmergencyArenaShift;
-
-  extern __attribute__ ((visibility("internal"))) char *emergency_arena_start;
-  extern __attribute__ ((visibility("internal"))) uintptr_t emergency_arena_start_shifted;;
-
-  PERFTOOLS_DLL_DECL void *EmergencyMalloc(size_t size);
-  PERFTOOLS_DLL_DECL void EmergencyFree(void *p);
-  PERFTOOLS_DLL_DECL void *EmergencyCalloc(size_t n, size_t elem_size);
-  PERFTOOLS_DLL_DECL void *EmergencyRealloc(void *old_ptr, size_t new_size);
-
-  static inline bool IsEmergencyPtr(const void *_ptr) {
-    uintptr_t ptr = reinterpret_cast<uintptr_t>(_ptr);
-    return PREDICT_FALSE((ptr >> kEmergencyArenaShift) == emergency_arena_start_shifted)
-      && emergency_arena_start_shifted;
-  }
-
-} // namespace tcmalloc
-
-#endif
diff --git a/third_party/tcmalloc/chromium/src/emergency_malloc_for_stacktrace.cc b/third_party/tcmalloc/chromium/src/emergency_malloc_for_stacktrace.cc
deleted file mode 100644
index f1dc35e7..0000000
--- a/third_party/tcmalloc/chromium/src/emergency_malloc_for_stacktrace.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "emergency_malloc.h"
-#include "thread_cache.h"
-
-namespace tcmalloc {
-  bool EnterStacktraceScope(void);
-  void LeaveStacktraceScope(void);
-}
-
-bool tcmalloc::EnterStacktraceScope(void) {
-  if (ThreadCache::IsUseEmergencyMalloc()) {
-    return false;
-  }
-  ThreadCache::SetUseEmergencyMalloc();
-  return true;
-}
-
-void tcmalloc::LeaveStacktraceScope(void) {
-  ThreadCache::ResetUseEmergencyMalloc();
-}
diff --git a/third_party/tcmalloc/chromium/src/fake_stacktrace_scope.cc b/third_party/tcmalloc/chromium/src/fake_stacktrace_scope.cc
deleted file mode 100644
index ee35a04..0000000
--- a/third_party/tcmalloc/chromium/src/fake_stacktrace_scope.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "base/basictypes.h"
-
-namespace tcmalloc {
-  ATTRIBUTE_WEAK bool EnterStacktraceScope(void) {
-    return true;
-  }
-  ATTRIBUTE_WEAK void LeaveStacktraceScope(void) {
-  }
-}
diff --git a/third_party/tcmalloc/chromium/src/free_list.cc b/third_party/tcmalloc/chromium/src/free_list.cc
deleted file mode 100644
index 5ba4a8d..0000000
--- a/third_party/tcmalloc/chromium/src/free_list.cc
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Rebecca Shapiro <bxx@google.com>
-//
-// This file contains functions that implement doubly linked and
-// singly linked lists.  The singly linked lists are null terminated,
-// use raw pointers to link neighboring elements, and these pointers
-// are stored at the start of each element, independently of the
-// elements's size.  Because pointers are stored within each element,
-// each element must be large enough to store two raw pointers if
-// doubly linked lists are employed, or one raw pointer if singly
-// linked lists are employed.  On machines with 64 bit pointers, this
-// means elements must be at least 16 bytes in size for doubly linked
-// list support, and 8 bytes for singly linked list support.  No
-// attempts are made to preserve the data in elements stored in the
-// list.
-//
-// Given a machine with pointers of size N (on a 64bit machine N=8, on
-// a 32bit machine, N=4), the list pointers are stored in the
-// following manner:
-// -In doubly linked lists, the |next| pointer is stored in the first N
-// bytes of the node and the |previous| pointer is writtend into the
-// second N bytes.
-// -In singly linked lists, the |next| pointer is stored in the first N
-// bytes of the node.
-//
-// For both types of lists: when a pop operation is performed on a non
-// empty list, the new list head becomes that which is pointed to by
-// the former head's |next| pointer.  If the list is doubly linked, the
-// new head |previous| pointer gets changed from pointing to the former
-// head to nullptr.
-
-#include "free_list.h"
-#include <stddef.h>
-#include <limits>
-
-#if defined(TCMALLOC_USE_DOUBLYLINKED_FREELIST)
-
-namespace tcmalloc {
-
-namespace {
-
-// Precomputed pointer mask.
-uintptr_t ptr_mask = 0;
-
-void* MaskPtr(void* p) {
-  return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) ^ ptr_mask);
-}
-
-void* UnmaskPtr(void* p) {
-  return MaskPtr(p);
-}
-
-void EnsureNonLoop(void* node, void* next) {
-  // We only have time to do minimal checking.  We don't traverse the list, but
-  // only look for an immediate loop (cycle back to ourself).
-  if (node != next)
-    return;
-  Log(kCrash, __FILE__, __LINE__, "Circular loop in list detected: ", next);
-}
-
-template <typename T>
-void FL_EqualityCheck(const T& v0, const T& v1, const char* file, int line) {
-  if (v0 != v1)
-    Log(kCrash, file, line, "Memory corruption detected.");
-}
-
-// Returns value of the |previous| pointer w/out running a sanity
-// check.
-void* FL_Previous_No_Check(void* t) {
-  return UnmaskPtr(reinterpret_cast<void**>(t)[1]);
-}
-
-// Returns value of the |next| pointer w/out running a sanity check.
-void* FL_Next_No_Check(void* t) {
-  return UnmaskPtr(reinterpret_cast<void**>(t)[0]);
-}
-
-void* FL_Previous(void* t) {
-  void* previous = FL_Previous_No_Check(t);
-  if (previous) {
-    FL_EqualityCheck(FL_Next_No_Check(previous), t, __FILE__, __LINE__);
-  }
-  return previous;
-}
-
-}  // namespace
-
-void FL_InitPtrMask(uintptr_t seed) {
-  // Maximize ASLR entropy and guarantee the result is an invalid address.
-  ptr_mask = ~(seed >> 13);
-}
-
-void FL_SetPrevious(void* t, void* n) {
-  EnsureNonLoop(t, n);
-  reinterpret_cast<void**>(t)[1] = MaskPtr(n);
-}
-
-void FL_SetNext(void* t, void* n) {
-  EnsureNonLoop(t, n);
-  reinterpret_cast<void**>(t)[0] = MaskPtr(n);
-}
-
-void* FL_Next(void* t) {
-  void* next = FL_Next_No_Check(t);
-  if (next) {
-    FL_EqualityCheck(FL_Previous_No_Check(next), t, __FILE__, __LINE__);
-  }
-  return next;
-}
-
-// Pops the top element off the linked list whose first element is at
-// |*list|, and updates |*list| to point to the next element in the
-// list.  Returns the address of the element that was removed from the
-// linked list.  |list| must not be nullptr.
-void* FL_Pop(void** list) {
-  void* result = *list;
-  ASSERT(FL_Previous_No_Check(result) == nullptr);
-  *list = FL_Next(result);
-  if (*list != nullptr) {
-    FL_SetPrevious(*list, nullptr);
-  }
-  return result;
-}
-
-// Makes the element at |t| a singleton doubly linked list.
-void FL_Init(void* t) {
-  FL_SetPrevious(t, nullptr);
-  FL_SetNext(t, nullptr);
-}
-
-// Pushes element to a linked list whose first element is at
-// |*list|. When this call returns, |list| will point to the new head
-// of the linked list.
-void FL_Push(void** list, void* element) {
-  void* old = *list;
-  if (old == nullptr) {  // Builds singleton list.
-    FL_Init(element);
-  } else {
-    ASSERT(FL_Previous_No_Check(old) == nullptr);
-    FL_SetNext(element, old);
-    FL_SetPrevious(old, element);
-    FL_SetPrevious(element, nullptr);
-  }
-  *list = element;
-}
-
-// Remove |n| elements from linked list at whose first element is at
-// |*head|.  |head| will be modified to point to the new head.
-// |start| will point to the first node of the range, |end| will point
-// to the last node in the range. |n| must be <= FL_Size(|*head|)
-// If |n| > 0, |head| must not be nullptr.
-void FL_PopRange(void** head, int n, void** start, void** end) {
-  if (n == 0) {
-    *start = nullptr;
-    *end = nullptr;
-    return;
-  }
-
-  *start = *head;  // Remember the first node in the range.
-  void* tmp = *head;
-  for (int i = 1; i < n; ++i) {  // Find end of range.
-    tmp = FL_Next(tmp);
-  }
-  *end = tmp;  // |end| now set to point to last node in range.
-  *head = FL_Next(*end);
-  FL_SetNext(*end, nullptr);  // Unlink range from list.
-
-  if (*head) {  // Fixup popped list.
-    FL_SetPrevious(*head, nullptr);
-  }
-}
-
-// Pushes the nodes in the list beginning at |start| whose last node
-// is |end| into the linked list at |*head|. |*head| is updated to
-// point be the new head of the list.  |head| must not be nullptr.
-void FL_PushRange(void** head, void* start, void* end) {
-  if (!start)
-    return;
-
-  // Sanity checking of ends of list to push is done by calling
-  // FL_Next and FL_Previous.
-  FL_Next(start);
-  FL_Previous(end);
-  ASSERT(FL_Previous_No_Check(start) == nullptr);
-  ASSERT(FL_Next_No_Check(end) == nullptr);
-
-  if (*head) {
-    FL_EqualityCheck(FL_Previous_No_Check(*head), static_cast<void*>(nullptr),
-                     __FILE__, __LINE__);
-    FL_SetNext(end, *head);
-    FL_SetPrevious(*head, end);
-  }
-  *head = start;
-}
-
-// Calculates the size of the list that begins at |head|.
-size_t FL_Size(void* head) {
-  int count = 0;
-  if (head) {
-    FL_EqualityCheck(FL_Previous_No_Check(head), static_cast<void*>(nullptr),
-                     __FILE__, __LINE__);
-  }
-  while (head) {
-    count++;
-    head = FL_Next(head);
-  }
-  return count;
-}
-
-}  // namespace tcmalloc
-
-#else
-#include "linked_list.h"  // for SLL_SetNext
-
-namespace {
-
-inline void FL_SetNext(void* t, void* n) {
-  tcmalloc::SLL_SetNext(t, n);
-}
-
-}  // namespace
-
-#endif  // TCMALLOC_USE_DOUBLYLINKED_FREELIST
diff --git a/third_party/tcmalloc/chromium/src/free_list.h b/third_party/tcmalloc/chromium/src/free_list.h
deleted file mode 100644
index 7065e04..0000000
--- a/third_party/tcmalloc/chromium/src/free_list.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Rebecca Shapiro <bxx@google.com>
-//
-// This file contains declarations of functions that implement doubly
-// linked lists and definitions of functions that implement singly
-// linked lists.  It also contains macros to tell the SizeMap class
-// how much space a node in the freelist needs so that SizeMap can
-// create large enough size classes.
-
-#ifndef TCMALLOC_FREE_LIST_H_
-#define TCMALLOC_FREE_LIST_H_
-
-#include <stddef.h>
-#include "internal_logging.h"
-#include "linked_list.h"
-
-namespace tcmalloc {
-
-#if defined(TCMALLOC_USE_DOUBLYLINKED_FREELIST)
-
-// size class information for common.h.
-static const bool kSupportsDoublyLinkedList = true;
-
-void FL_InitPtrMask(uintptr_t seed);
-void FL_Init(void* t);
-void FL_PopRange(void** head, int n, void** start, void** end);
-void FL_PushRange(void** head, void* start, void* end);
-size_t FL_Size(void* head);
-
-void FL_SetPrevious(void* t, void* n);
-void FL_SetNext(void* t, void* n);
-void* FL_Next(void* t);
-void* FL_Pop(void** list);
-void FL_Push(void** list, void* element);
-
-#else  // TCMALLOC_USE_DOUBLYLINKED_FREELIST not defined
-static const bool kSupportsDoublyLinkedList = false;
-
-inline void* FL_Next(void* t) {
-  return SLL_Next(t);
-}
-
-inline void FL_Init(void* t) {
-  SLL_SetNext(t, NULL);
-}
-
-inline void FL_Push(void** list, void* element) {
-  if (*list != element) {
-    SLL_Push(list, element);
-    return;
-  }
-  Log(kCrash, __FILE__, __LINE__, "Double Free of %p detected", element);
-}
-
-inline void* FL_Pop(void** list) {
-  return SLL_Pop(list);
-}
-
-inline void FL_SetPrevious(void* t, void* n) {
-  // Singly linked list has no previous element.
-}
-
-inline void FL_SetNext(void* t, void* n) {
-  SLL_SetNext(t, n);
-}
-
-// Removes |N| elements from a linked list to which |head| points.
-// |head| will be modified to point to the new |head|.  |start| and
-// |end| will point to the first and last nodes of the range.  Note
-// that |end| will point to NULL after this function is called.
-inline void FL_PopRange(void** head, int n, void** start, void** end) {
-  SLL_PopRange(head, n, start, end);
-}
-
-inline void FL_PushRange(void** head, void* start, void* end) {
-  SLL_PushRange(head, start, end);
-}
-
-inline size_t FL_Size(void* head) {
-  return SLL_Size(head);
-}
-
-#endif  // TCMALLOC_USE_DOUBLYLINKED_FREELIST
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_FREE_LIST_H_
diff --git a/third_party/tcmalloc/chromium/src/getenv_safe.h b/third_party/tcmalloc/chromium/src/getenv_safe.h
deleted file mode 100644
index 3b9f4dbb..0000000
--- a/third_party/tcmalloc/chromium/src/getenv_safe.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
- * Copyright (c) 2014, gperftools Contributors
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef GETENV_SAFE_H
-#define GETENV_SAFE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* 
- * This getenv function is safe to call before the C runtime is initialized.
- * On Windows, it utilizes GetEnvironmentVariable() and on unix it uses
- * /proc/self/environ instead calling getenv().  It's intended to be used in
- * routines that run before main(), when the state required for getenv() may
- * not be set up yet.  In particular, errno isn't set up until relatively late
- * (after the pthreads library has a chance to make it threadsafe), and
- * getenv() doesn't work until then.
- * On some platforms, this call will utilize the same, static buffer for
- * repeated GetenvBeforeMain() calls. Callers should not expect pointers from
- * this routine to be long lived.
- * Note that on unix, /proc only has the environment at the time the
- * application was started, so this routine ignores setenv() calls/etc.  Also
- * note it only reads the first 16K of the environment.
- * 
- * NOTE: this is version of GetenvBeforeMain that's usable from
- * C. Implementation is in sysinfo.cc
- */
-const char* TCMallocGetenvSafe(const char* name);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/third_party/tcmalloc/chromium/src/getpc.h b/third_party/tcmalloc/chromium/src/getpc.h
deleted file mode 100644
index 163873e..0000000
--- a/third_party/tcmalloc/chromium/src/getpc.h
+++ /dev/null
@@ -1,192 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This is an internal header file used by profiler.cc.  It defines
-// the single (inline) function GetPC.  GetPC is used in a signal
-// handler to figure out the instruction that was being executed when
-// the signal-handler was triggered.
-//
-// To get this, we use the ucontext_t argument to the signal-handler
-// callback, which holds the full context of what was going on when
-// the signal triggered.  How to get from a ucontext_t to a Program
-// Counter is OS-dependent.
-
-#ifndef BASE_GETPC_H_
-#define BASE_GETPC_H_
-
-#include "config.h"
-
-// On many linux systems, we may need _GNU_SOURCE to get access to
-// the defined constants that define the register we want to see (eg
-// REG_EIP).  Note this #define must come first!
-#define _GNU_SOURCE 1
-// If #define _GNU_SOURCE causes problems, this might work instead.
-// It will cause problems for FreeBSD though!, because it turns off
-// the needed __BSD_VISIBLE.
-//#define _XOPEN_SOURCE 500
-
-#include <string.h>         // for memcmp
-#if defined(HAVE_SYS_UCONTEXT_H)
-#include <sys/ucontext.h>
-#elif defined(HAVE_UCONTEXT_H)
-#include <ucontext.h>       // for ucontext_t (and also mcontext_t)
-#elif defined(HAVE_CYGWIN_SIGNAL_H)
-#include <cygwin/signal.h>
-typedef ucontext ucontext_t;
-#endif
-
-
-// Take the example where function Foo() calls function Bar().  For
-// many architectures, Bar() is responsible for setting up and tearing
-// down its own stack frame.  In that case, it's possible for the
-// interrupt to happen when execution is in Bar(), but the stack frame
-// is not properly set up (either before it's done being set up, or
-// after it's been torn down but before Bar() returns).  In those
-// cases, the stack trace cannot see the caller function anymore.
-//
-// GetPC can try to identify this situation, on architectures where it
-// might occur, and unwind the current function call in that case to
-// avoid false edges in the profile graph (that is, edges that appear
-// to show a call skipping over a function).  To do this, we hard-code
-// in the asm instructions we might see when setting up or tearing
-// down a stack frame.
-//
-// This is difficult to get right: the instructions depend on the
-// processor, the compiler ABI, and even the optimization level.  This
-// is a best effort patch -- if we fail to detect such a situation, or
-// mess up the PC, nothing happens; the returned PC is not used for
-// any further processing.
-struct CallUnrollInfo {
-  // Offset from (e)ip register where this instruction sequence
-  // should be matched. Interpreted as bytes. Offset 0 is the next
-  // instruction to execute. Be extra careful with negative offsets in
-  // architectures of variable instruction length (like x86) - it is
-  // not that easy as taking an offset to step one instruction back!
-  int pc_offset;
-  // The actual instruction bytes. Feel free to make it larger if you
-  // need a longer sequence.
-  unsigned char ins[16];
-  // How many bytes to match from ins array?
-  int ins_size;
-  // The offset from the stack pointer (e)sp where to look for the
-  // call return address. Interpreted as bytes.
-  int return_sp_offset;
-};
-
-
-// The dereferences needed to get the PC from a struct ucontext were
-// determined at configure time, and stored in the macro
-// PC_FROM_UCONTEXT in config.h.  The only thing we need to do here,
-// then, is to do the magic call-unrolling for systems that support it.
-
-// -- Special case 1: linux x86, for which we have CallUnrollInfo
-#if defined(__linux) && defined(__i386) && defined(__GNUC__)
-static const CallUnrollInfo callunrollinfo[] = {
-  // Entry to a function:  push %ebp;  mov  %esp,%ebp
-  // Top-of-stack contains the caller IP.
-  { 0,
-    {0x55, 0x89, 0xe5}, 3,
-    0
-  },
-  // Entry to a function, second instruction:  push %ebp;  mov  %esp,%ebp
-  // Top-of-stack contains the old frame, caller IP is +4.
-  { -1,
-    {0x55, 0x89, 0xe5}, 3,
-    4
-  },
-  // Return from a function: RET.
-  // Top-of-stack contains the caller IP.
-  { 0,
-    {0xc3}, 1,
-    0
-  }
-};
-
-inline void* GetPC(const ucontext_t& signal_ucontext) {
-  // See comment above struct CallUnrollInfo.  Only try instruction
-  // flow matching if both eip and esp looks reasonable.
-  const int eip = signal_ucontext.uc_mcontext.gregs[REG_EIP];
-  const int esp = signal_ucontext.uc_mcontext.gregs[REG_ESP];
-  if ((eip & 0xffff0000) != 0 && (~eip & 0xffff0000) != 0 &&
-      (esp & 0xffff0000) != 0) {
-    char* eip_char = reinterpret_cast<char*>(eip);
-    for (int i = 0; i < sizeof(callunrollinfo)/sizeof(*callunrollinfo); ++i) {
-      if (!memcmp(eip_char + callunrollinfo[i].pc_offset,
-                  callunrollinfo[i].ins, callunrollinfo[i].ins_size)) {
-        // We have a match.
-        void **retaddr = (void**)(esp + callunrollinfo[i].return_sp_offset);
-        return *retaddr;
-      }
-    }
-  }
-  return (void*)eip;
-}
-
-// Special case #2: Windows, which has to do something totally different.
-#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
-// If this is ever implemented, probably the way to do it is to have
-// profiler.cc use a high-precision timer via timeSetEvent:
-//    http://msdn2.microsoft.com/en-us/library/ms712713.aspx
-// We'd use it in mode TIME_CALLBACK_FUNCTION/TIME_PERIODIC.
-// The callback function would be something like prof_handler, but
-// alas the arguments are different: no ucontext_t!  I don't know
-// how we'd get the PC (using StackWalk64?)
-//    http://msdn2.microsoft.com/en-us/library/ms680650.aspx
-
-#include "base/logging.h"   // for RAW_LOG
-#ifndef HAVE_CYGWIN_SIGNAL_H
-typedef int ucontext_t;
-#endif
-
-inline void* GetPC(const struct ucontext_t& signal_ucontext) {
-  RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n");
-  return NULL;
-}
-
-// Normal cases.  If this doesn't compile, it's probably because
-// PC_FROM_UCONTEXT is the empty string.  You need to figure out
-// the right value for your system, and add it to the list in
-// configure.ac (or set it manually in your config.h).
-#else
-inline void* GetPC(const ucontext_t& signal_ucontext) {
-#if defined(__s390__) && !defined(__s390x__)
-  // Mask out the AMODE31 bit from the PC recorded in the context.
-  return (void*)((unsigned long)signal_ucontext.PC_FROM_UCONTEXT & 0x7fffffffUL);
-#else
-  return (void*)signal_ucontext.PC_FROM_UCONTEXT;   // defined in config.h
-#endif
-}
-
-#endif
-
-#endif  // BASE_GETPC_H_
diff --git a/third_party/tcmalloc/chromium/src/google/heap-checker.h b/third_party/tcmalloc/chromium/src/google/heap-checker.h
deleted file mode 100644
index 6b9ffe5..0000000
--- a/third_party/tcmalloc/chromium/src/google/heap-checker.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/heap-checker.h is deprecated. Use gperftools/heap-checker.h instead"
-#endif
-#include <gperftools/heap-checker.h>
diff --git a/third_party/tcmalloc/chromium/src/google/heap-profiler.h b/third_party/tcmalloc/chromium/src/google/heap-profiler.h
deleted file mode 100644
index 6155484..0000000
--- a/third_party/tcmalloc/chromium/src/google/heap-profiler.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2005, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/heap-profiler.h is deprecated. Use gperftools/heap-profiler.h instead"
-#endif
-#include <gperftools/heap-profiler.h>
diff --git a/third_party/tcmalloc/chromium/src/google/malloc_extension.h b/third_party/tcmalloc/chromium/src/google/malloc_extension.h
deleted file mode 100644
index fdad25a3..0000000
--- a/third_party/tcmalloc/chromium/src/google/malloc_extension.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/malloc_extension.h is deprecated. Use gperftools/malloc_extension.h instead"
-#endif
-#include <gperftools/malloc_extension.h>
diff --git a/third_party/tcmalloc/chromium/src/google/malloc_extension_c.h b/third_party/tcmalloc/chromium/src/google/malloc_extension_c.h
deleted file mode 100644
index 3c5cd38..0000000
--- a/third_party/tcmalloc/chromium/src/google/malloc_extension_c.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/malloc_extension_c.h is deprecated. Use gperftools/malloc_extension_c.h instead"
-#endif
-#include <gperftools/malloc_extension_c.h>
diff --git a/third_party/tcmalloc/chromium/src/google/malloc_hook.h b/third_party/tcmalloc/chromium/src/google/malloc_hook.h
deleted file mode 100644
index 7ec0002..0000000
--- a/third_party/tcmalloc/chromium/src/google/malloc_hook.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/malloc_hook.h is deprecated. Use gperftools/malloc_hook.h instead"
-#endif
-#include <gperftools/malloc_hook.h>
diff --git a/third_party/tcmalloc/chromium/src/google/malloc_hook_c.h b/third_party/tcmalloc/chromium/src/google/malloc_hook_c.h
deleted file mode 100644
index eb21aaf..0000000
--- a/third_party/tcmalloc/chromium/src/google/malloc_hook_c.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/malloc_hook_c.h is deprecated. Use gperftools/malloc_hook_c.h instead"
-#endif
-#include <gperftools/malloc_hook_c.h>
diff --git a/third_party/tcmalloc/chromium/src/google/profiler.h b/third_party/tcmalloc/chromium/src/google/profiler.h
deleted file mode 100644
index 293d605..0000000
--- a/third_party/tcmalloc/chromium/src/google/profiler.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2005, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/profiler.h is deprecated. Use gperftools/profiler.h instead"
-#endif
-#include <gperftools/profiler.h>
diff --git a/third_party/tcmalloc/chromium/src/google/stacktrace.h b/third_party/tcmalloc/chromium/src/google/stacktrace.h
deleted file mode 100644
index 55f12d2..0000000
--- a/third_party/tcmalloc/chromium/src/google/stacktrace.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/stacktrace.h is deprecated. Use gperftools/stacktrace.h instead"
-#endif
-#include <gperftools/stacktrace.h>
diff --git a/third_party/tcmalloc/chromium/src/google/tcmalloc.h b/third_party/tcmalloc/chromium/src/google/tcmalloc.h
deleted file mode 100644
index 1addeb61..0000000
--- a/third_party/tcmalloc/chromium/src/google/tcmalloc.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/tcmalloc.h is deprecated. Use gperftools/tcmalloc.h instead"
-#endif
-#include <gperftools/tcmalloc.h>
diff --git a/third_party/tcmalloc/chromium/src/gperftools/heap-checker.h b/third_party/tcmalloc/chromium/src/gperftools/heap-checker.h
deleted file mode 100644
index edd6cc7..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/heap-checker.h
+++ /dev/null
@@ -1,422 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Maxim Lifantsev (with design ideas by Sanjay Ghemawat)
-//
-//
-// Module for detecing heap (memory) leaks.
-//
-// For full(er) information, see docs/heap_checker.html
-//
-// This module can be linked into programs with
-// no slowdown caused by this unless you activate the leak-checker:
-//
-//    1. Set the environment variable HEAPCHEK to _type_ before
-//       running the program.
-//
-// _type_ is usually "normal" but can also be "minimal", "strict", or
-// "draconian".  (See the html file for other options, like 'local'.)
-//
-// After that, just run your binary.  If the heap-checker detects
-// a memory leak at program-exit, it will print instructions on how
-// to track down the leak.
-
-#ifndef BASE_HEAP_CHECKER_H_
-#define BASE_HEAP_CHECKER_H_
-
-#include <sys/types.h>  // for size_t
-// I can't #include config.h in this public API file, but I should
-// really use configure (and make malloc_extension.h a .in file) to
-// figure out if the system has stdint.h or not.  But I'm lazy, so
-// for now I'm assuming it's a problem only with MSVC.
-#ifndef _MSC_VER
-#include <stdint.h>     // for uintptr_t
-#endif
-#include <stdarg.h>     // for va_list
-#include <vector>
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-
-// The class is thread-safe with respect to all the provided static methods,
-// as well as HeapLeakChecker objects: they can be accessed by multiple threads.
-class PERFTOOLS_DLL_DECL HeapLeakChecker {
- public:
-
-  // ----------------------------------------------------------------------- //
-  // Static functions for working with (whole-program) leak checking.
-
-  // If heap leak checking is currently active in some mode
-  // e.g. if leak checking was started (and is still active now)
-  // due to HEAPCHECK=... defined in the environment.
-  // The return value reflects iff HeapLeakChecker objects manually
-  // constructed right now will be doing leak checking or nothing.
-  // Note that we can go from active to inactive state during InitGoogle()
-  // if FLAGS_heap_check gets set to "" by some code before/during InitGoogle().
-  static bool IsActive();
-
-  // Return pointer to the whole-program checker if it has been created
-  // and NULL otherwise.
-  // Once GlobalChecker() returns non-NULL that object will not disappear and
-  // will be returned by all later GlobalChecker calls.
-  // This is mainly to access BytesLeaked() and ObjectsLeaked() (see below)
-  // for the whole-program checker after one calls NoGlobalLeaks()
-  // or similar and gets false.
-  static HeapLeakChecker* GlobalChecker();
-
-  // Do whole-program leak check now (if it was activated for this binary);
-  // return false only if it was activated and has failed.
-  // The mode of the check is controlled by the command-line flags.
-  // This method can be called repeatedly.
-  // Things like GlobalChecker()->SameHeap() can also be called explicitly
-  // to do the desired flavor of the check.
-  static bool NoGlobalLeaks();
-
-  // If whole-program checker if active,
-  // cancel its automatic execution after main() exits.
-  // This requires that some leak check (e.g. NoGlobalLeaks())
-  // has been called at least once on the whole-program checker.
-  static void CancelGlobalCheck();
-
-  // ----------------------------------------------------------------------- //
-  // Non-static functions for starting and doing leak checking.
-
-  // Start checking and name the leak check performed.
-  // The name is used in naming dumped profiles
-  // and needs to be unique only within your binary.
-  // It must also be a string that can be a part of a file name,
-  // in particular not contain path expressions.
-  explicit HeapLeakChecker(const char *name);
-
-  // Destructor (verifies that some *NoLeaks or *SameHeap method
-  // has been called at least once).
-  ~HeapLeakChecker();
-
-  // These used to be different but are all the same now: they return
-  // true iff all memory allocated since this HeapLeakChecker object
-  // was constructor is still reachable from global state.
-  //
-  // Because we fork to convert addresses to symbol-names, and forking
-  // is not thread-safe, and we may be called in a threaded context,
-  // we do not try to symbolize addresses when called manually.
-  bool NoLeaks() { return DoNoLeaks(DO_NOT_SYMBOLIZE); }
-
-  // These forms are obsolete; use NoLeaks() instead.
-  // TODO(csilvers): mark as DEPRECATED.
-  bool QuickNoLeaks()  { return NoLeaks(); }
-  bool BriefNoLeaks()  { return NoLeaks(); }
-  bool SameHeap()      { return NoLeaks(); }
-  bool QuickSameHeap() { return NoLeaks(); }
-  bool BriefSameHeap() { return NoLeaks(); }
-
-  // Detailed information about the number of leaked bytes and objects
-  // (both of these can be negative as well).
-  // These are available only after a *SameHeap or *NoLeaks
-  // method has been called.
-  // Note that it's possible for both of these to be zero
-  // while SameHeap() or NoLeaks() returned false in case
-  // of a heap state change that is significant
-  // but preserves the byte and object counts.
-  ssize_t BytesLeaked() const;
-  ssize_t ObjectsLeaked() const;
-
-  // ----------------------------------------------------------------------- //
-  // Static helpers to make us ignore certain leaks.
-
-  // Scoped helper class.  Should be allocated on the stack inside a
-  // block of code.  Any heap allocations done in the code block
-  // covered by the scoped object (including in nested function calls
-  // done by the code block) will not be reported as leaks.  This is
-  // the recommended replacement for the GetDisableChecksStart() and
-  // DisableChecksToHereFrom() routines below.
-  //
-  // Example:
-  //   void Foo() {
-  //     HeapLeakChecker::Disabler disabler;
-  //     ... code that allocates objects whose leaks should be ignored ...
-  //   }
-  //
-  // REQUIRES: Destructor runs in same thread as constructor
-  class Disabler {
-   public:
-    Disabler();
-    ~Disabler();
-   private:
-    Disabler(const Disabler&);        // disallow copy
-    void operator=(const Disabler&);  // and assign
-  };
-
-  // Ignore an object located at 'ptr' (can go at the start or into the object)
-  // as well as all heap objects (transitively) referenced from it for the
-  // purposes of heap leak checking. Returns 'ptr' so that one can write
-  //   static T* obj = IgnoreObject(new T(...));
-  //
-  // If 'ptr' does not point to an active allocated object at the time of this
-  // call, it is ignored; but if it does, the object must not get deleted from
-  // the heap later on.
-  //
-  // See also HiddenPointer, below, if you need to prevent a pointer from
-  // being traversed by the heap checker but do not wish to transitively
-  // whitelist objects referenced through it.
-  template <typename T>
-  static T* IgnoreObject(T* ptr) {
-    DoIgnoreObject(static_cast<const void*>(const_cast<const T*>(ptr)));
-    return ptr;
-  }
-
-  // Undo what an earlier IgnoreObject() call promised and asked to do.
-  // At the time of this call 'ptr' must point at or inside of an active
-  // allocated object which was previously registered with IgnoreObject().
-  static void UnIgnoreObject(const void* ptr);
-
-  // ----------------------------------------------------------------------- //
-  // Internal types defined in .cc
-
-  class Allocator;
-  struct RangeValue;
-
- private:
-
-  // ----------------------------------------------------------------------- //
-  // Various helpers
-
-  // Create the name of the heap profile file.
-  // Should be deleted via Allocator::Free().
-  char* MakeProfileNameLocked();
-
-  // Helper for constructors
-  void Create(const char *name, bool make_start_snapshot);
-
-  enum ShouldSymbolize { SYMBOLIZE, DO_NOT_SYMBOLIZE };
-
-  // Helper for *NoLeaks and *SameHeap
-  bool DoNoLeaks(ShouldSymbolize should_symbolize);
-
-  // Helper for NoGlobalLeaks, also called by the global destructor.
-  static bool NoGlobalLeaksMaybeSymbolize(ShouldSymbolize should_symbolize);
-
-  // These used to be public, but they are now deprecated.
-  // Will remove entirely when all internal uses are fixed.
-  // In the meantime, use friendship so the unittest can still test them.
-  static void* GetDisableChecksStart();
-  static void DisableChecksToHereFrom(const void* start_address);
-  static void DisableChecksIn(const char* pattern);
-  friend void RangeDisabledLeaks();
-  friend void NamedTwoDisabledLeaks();
-  friend void* RunNamedDisabledLeaks(void*);
-  friend void TestHeapLeakCheckerNamedDisabling();
-
-  // Actually implements IgnoreObject().
-  static void DoIgnoreObject(const void* ptr);
-
-  // Disable checks based on stack trace entry at a depth <=
-  // max_depth.  Used to hide allocations done inside some special
-  // libraries.
-  static void DisableChecksFromToLocked(const void* start_address,
-                                        const void* end_address,
-                                        int max_depth);
-
-  // Helper for DoNoLeaks to ignore all objects reachable from all live data
-  static void IgnoreAllLiveObjectsLocked(const void* self_stack_top);
-
-  // Callback we pass to TCMalloc_ListAllProcessThreads (see thread_lister.h)
-  // that is invoked when all threads of our process are found and stopped.
-  // The call back does the things needed to ignore live data reachable from
-  // thread stacks and registers for all our threads
-  // as well as do other global-live-data ignoring
-  // (via IgnoreNonThreadLiveObjectsLocked)
-  // during the quiet state of all threads being stopped.
-  // For the argument meaning see the comment by TCMalloc_ListAllProcessThreads.
-  // Here we only use num_threads and thread_pids, that TCMalloc_ListAllProcessThreads
-  // fills for us with the number and pids of all the threads of our process
-  // it found and attached to.
-  static int IgnoreLiveThreadsLocked(void* parameter,
-                                     int num_threads,
-                                     pid_t* thread_pids,
-                                     va_list ap);
-
-  // Helper for IgnoreAllLiveObjectsLocked and IgnoreLiveThreadsLocked
-  // that we prefer to execute from IgnoreLiveThreadsLocked
-  // while all threads are stopped.
-  // This helper does live object discovery and ignoring
-  // for all objects that are reachable from everything
-  // not related to thread stacks and registers.
-  static void IgnoreNonThreadLiveObjectsLocked();
-
-  // Helper for IgnoreNonThreadLiveObjectsLocked and IgnoreLiveThreadsLocked
-  // to discover and ignore all heap objects
-  // reachable from currently considered live objects
-  // (live_objects static global variable in out .cc file).
-  // "name", "name2" are two strings that we print one after another
-  // in a debug message to describe what kind of live object sources
-  // are being used.
-  static void IgnoreLiveObjectsLocked(const char* name, const char* name2);
-
-  // Do the overall whole-program heap leak check if needed;
-  // returns true when did the leak check.
-  static bool DoMainHeapCheck();
-
-  // Type of task for UseProcMapsLocked
-  enum ProcMapsTask {
-    RECORD_GLOBAL_DATA,
-    DISABLE_LIBRARY_ALLOCS
-  };
-
-  // Success/Error Return codes for UseProcMapsLocked.
-  enum ProcMapsResult {
-    PROC_MAPS_USED,
-    CANT_OPEN_PROC_MAPS,
-    NO_SHARED_LIBS_IN_PROC_MAPS
-  };
-
-  // Read /proc/self/maps, parse it, and do the 'proc_maps_task' for each line.
-  static ProcMapsResult UseProcMapsLocked(ProcMapsTask proc_maps_task);
-
-  // A ProcMapsTask to disable allocations from 'library'
-  // that is mapped to [start_address..end_address)
-  // (only if library is a certain system library).
-  static void DisableLibraryAllocsLocked(const char* library,
-                                         uintptr_t start_address,
-                                         uintptr_t end_address);
-
-  // Return true iff "*ptr" points to a heap object
-  // ("*ptr" can point at the start or inside of a heap object
-  //  so that this works e.g. for pointers to C++ arrays, C++ strings,
-  //  multiple-inherited objects, or pointers to members).
-  // We also fill *object_size for this object then
-  // and we move "*ptr" to point to the very start of the heap object.
-  static inline bool HaveOnHeapLocked(const void** ptr, size_t* object_size);
-
-  // Helper to shutdown heap leak checker when it's not needed
-  // or can't function properly.
-  static void TurnItselfOffLocked();
-
-  // Internally-used c-tor to start whole-executable checking.
-  HeapLeakChecker();
-
-  // ----------------------------------------------------------------------- //
-  // Friends and externally accessed helpers.
-
-  // Helper for VerifyHeapProfileTableStackGet in the unittest
-  // to get the recorded allocation caller for ptr,
-  // which must be a heap object.
-  static const void* GetAllocCaller(void* ptr);
-  friend void VerifyHeapProfileTableStackGet();
-
-  // This gets to execute before constructors for all global objects
-  static void BeforeConstructorsLocked();
-  friend void HeapLeakChecker_BeforeConstructors();
-
-  // This gets to execute after destructors for all global objects
-  friend void HeapLeakChecker_AfterDestructors();
-
-  // Full starting of recommended whole-program checking.
-  friend void HeapLeakChecker_InternalInitStart();
-
-  // Runs REGISTER_HEAPCHECK_CLEANUP cleanups and potentially
-  // calls DoMainHeapCheck
-  friend void HeapLeakChecker_RunHeapCleanups();
-
-  // ----------------------------------------------------------------------- //
-  // Member data.
-
-  class SpinLock* lock_;  // to make HeapLeakChecker objects thread-safe
-  const char* name_;  // our remembered name (we own it)
-                      // NULL means this leak checker is a noop
-
-  // Snapshot taken when the checker was created.  May be NULL
-  // for the global heap checker object.  We use void* instead of
-  // HeapProfileTable::Snapshot* to avoid including heap-profile-table.h.
-  void* start_snapshot_;
-
-  bool has_checked_;  // if we have done the leak check, so these are ready:
-  ssize_t inuse_bytes_increase_;  // bytes-in-use increase for this checker
-  ssize_t inuse_allocs_increase_;  // allocations-in-use increase
-                                   // for this checker
-  bool keep_profiles_;  // iff we should keep the heap profiles we've made
-
-  // ----------------------------------------------------------------------- //
-
-  // Disallow "evil" constructors.
-  HeapLeakChecker(const HeapLeakChecker&);
-  void operator=(const HeapLeakChecker&);
-};
-
-
-// Holds a pointer that will not be traversed by the heap checker.
-// Contrast with HeapLeakChecker::IgnoreObject(o), in which o and
-// all objects reachable from o are ignored by the heap checker.
-template <class T>
-class HiddenPointer {
- public:
-  explicit HiddenPointer(T* t)
-      : masked_t_(reinterpret_cast<uintptr_t>(t) ^ kHideMask) {
-  }
-  // Returns unhidden pointer.  Be careful where you save the result.
-  T* get() const { return reinterpret_cast<T*>(masked_t_ ^ kHideMask); }
-
- private:
-  // Arbitrary value, but not such that xor'ing with it is likely
-  // to map one valid pointer to another valid pointer:
-  static const uintptr_t kHideMask =
-      static_cast<uintptr_t>(0xF03A5F7BF03A5F7Bll);
-  uintptr_t masked_t_;
-};
-
-// A class that exists solely to run its destructor.  This class should not be
-// used directly, but instead by the REGISTER_HEAPCHECK_CLEANUP macro below.
-class PERFTOOLS_DLL_DECL HeapCleaner {
- public:
-  typedef void (*void_function)(void);
-  HeapCleaner(void_function f);
-  static void RunHeapCleanups();
- private:
-  static std::vector<void_function>* heap_cleanups_;
-};
-
-// A macro to declare module heap check cleanup tasks
-// (they run only if we are doing heap leak checking.)
-// 'body' should be the cleanup code to run.  'name' doesn't matter,
-// but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls.
-#define REGISTER_HEAPCHECK_CLEANUP(name, body)  \
-  namespace { \
-  void heapcheck_cleanup_##name() { body; } \
-  static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \
-  }
-
-#endif  // BASE_HEAP_CHECKER_H_
diff --git a/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h b/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h
deleted file mode 100644
index 38c6afe..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- *
- * Module for heap-profiling.
- *
- * For full(er) information, see docs/heapprofile.html
- *
- * This module can be linked into your program with
- * no slowdown caused by this unless you activate the profiler
- * using one of the following methods:
- *
- *    1. Before starting the program, set the environment variable
- *       "HEAPPROFILE" to be the name of the file to which the profile
- *       data should be written.
- *
- *    2. Programmatically, start and stop the profiler using the
- *       routines "HeapProfilerStart(filename)" and "HeapProfilerStop()".
- *
- */
-
-#ifndef BASE_HEAP_PROFILER_H_
-#define BASE_HEAP_PROFILER_H_
-
-#include <stddef.h>
-
-/* Annoying stuff for windows; makes sure clients can import these functions */
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-/* All this code should be usable from within C apps. */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Start profiling and arrange to write profile data to file names
- * of the form: "prefix.0000", "prefix.0001", ...
- */
-PERFTOOLS_DLL_DECL void HeapProfilerStart(const char* prefix);
-
-/* Returns non-zero if we are currently profiling the heap.  (Returns
- * an int rather than a bool so it's usable from C.)  This is true
- * between calls to HeapProfilerStart() and HeapProfilerStop(), and
- * also if the program has been run with HEAPPROFILER, or some other
- * way to turn on whole-program profiling.
- */
-int IsHeapProfilerRunning();
-
-/* Stop heap profiling.  Can be restarted again with HeapProfilerStart(),
- * but the currently accumulated profiling information will be cleared.
- */
-PERFTOOLS_DLL_DECL void HeapProfilerStop();
-
-/* Dump a profile now - can be used for dumping at a hopefully
- * quiescent state in your program, in order to more easily track down
- * memory leaks. Will include the reason in the logged message
- */
-PERFTOOLS_DLL_DECL void HeapProfilerDump(const char *reason);
-
-/* Generate current heap profiling information.
- * Returns an empty string when heap profiling is not active.
- * The returned pointer is a '\0'-terminated string allocated using malloc()
- * and should be free()-ed as soon as the caller does not need it anymore.
- */
-PERFTOOLS_DLL_DECL char* GetHeapProfile();
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  /* BASE_HEAP_PROFILER_H_ */
diff --git a/third_party/tcmalloc/chromium/src/gperftools/malloc_extension.h b/third_party/tcmalloc/chromium/src/gperftools/malloc_extension.h
deleted file mode 100644
index 21a6eca5..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/malloc_extension.h
+++ /dev/null
@@ -1,471 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// Extra extensions exported by some malloc implementations.  These
-// extensions are accessed through a virtual base class so an
-// application can link against a malloc that does not implement these
-// extensions, and it will get default versions that do nothing.
-//
-// NOTE FOR C USERS: If you wish to use this functionality from within
-// a C program, see malloc_extension_c.h.
-
-#ifndef BASE_MALLOC_EXTENSION_H_
-#define BASE_MALLOC_EXTENSION_H_
-
-#include <stddef.h>
-// I can't #include config.h in this public API file, but I should
-// really use configure (and make malloc_extension.h a .in file) to
-// figure out if the system has stdint.h or not.  But I'm lazy, so
-// for now I'm assuming it's a problem only with MSVC.
-#ifndef _MSC_VER
-#include <stdint.h>
-#endif
-#include <atomic>
-#include <string>
-#include <vector>
-
-#ifdef __has_attribute
-#define MALLOC_HAVE_ATTRIBUTE(x) __has_attribute(x)
-#else
-#define MALLOC_HAVE_ATTRIBUTE(x) 0
-#endif
-
-#if MALLOC_HAVE_ATTRIBUTE(unused)
-#undef ATTRIBUTE_UNUSED
-#define ATTRIBUTE_UNUSED __attribute__((unused))
-#else
-#define ATTRIBUTE_UNUSED
-#endif
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-static const int kMallocHistogramSize = 64;
-
-// One day, we could support other types of writers (perhaps for C?)
-typedef std::string MallocExtensionWriter;
-
-namespace base {
-struct MallocRange;
-}
-
-// Interface to a pluggable system allocator.
-class PERFTOOLS_DLL_DECL SysAllocator {
- public:
-  SysAllocator() {
-  }
-  virtual ~SysAllocator();
-
-  // Allocates "size"-byte of memory from system aligned with "alignment".
-  // Returns NULL if failed. Otherwise, the returned pointer p up to and
-  // including (p + actual_size -1) have been allocated.
-  virtual void* Alloc(size_t size, size_t *actual_size, size_t alignment) = 0;
-};
-
-// The default implementations of the following routines do nothing.
-// All implementations should be thread-safe; the current one
-// (TCMallocImplementation) is.
-class PERFTOOLS_DLL_DECL MallocExtension {
- public:
-  virtual ~MallocExtension();
-
-  // Call this very early in the program execution -- say, in a global
-  // constructor -- to set up parameters and state needed by all
-  // instrumented malloc implemenatations.  One example: this routine
-  // sets environemnt variables to tell STL to use libc's malloc()
-  // instead of doing its own memory management.  This is safe to call
-  // multiple times, as long as each time is before threads start up.
-  static void Initialize();
-
-  // See "verify_memory.h" to see what these routines do
-  virtual bool VerifyAllMemory();
-  virtual bool VerifyNewMemory(const void* p);
-  virtual bool VerifyArrayNewMemory(const void* p);
-  virtual bool VerifyMallocMemory(const void* p);
-  virtual bool MallocMemoryStats(int* blocks, size_t* total,
-                                 int histogram[kMallocHistogramSize]);
-
-  // Get a human readable description of the following malloc data structures.
-  // - Total inuse memory by application.
-  // - Free memory(thread, central and page heap),
-  // - Freelist of central cache, each class.
-  // - Page heap freelist.
-  // The state is stored as a null-terminated string
-  // in a prefix of "buffer[0,buffer_length-1]".
-  // REQUIRES: buffer_length > 0.
-  virtual void GetStats(char* buffer, int buffer_length);
-
-  // Outputs to "writer" a sample of live objects and the stack traces
-  // that allocated these objects.  The format of the returned output
-  // is equivalent to the output of the heap profiler and can
-  // therefore be passed to "pprof". This function is equivalent to
-  // ReadStackTraces. The main difference is that this function returns
-  // serialized data appropriately formatted for use by the pprof tool.
-  // NOTE: by default, tcmalloc does not do any heap sampling, and this
-  //       function will always return an empty sample.  To get useful
-  //       data from GetHeapSample, you must also set the environment
-  //       variable TCMALLOC_SAMPLE_PARAMETER to a value such as 524288.
-  virtual void GetHeapSample(MallocExtensionWriter* writer);
-
-  // Outputs to "writer" the stack traces that caused growth in the
-  // address space size.  The format of the returned output is
-  // equivalent to the output of the heap profiler and can therefore
-  // be passed to "pprof". This function is equivalent to
-  // ReadHeapGrowthStackTraces. The main difference is that this function
-  // returns serialized data appropriately formatted for use by the
-  // pprof tool.  (This does not depend on, or require,
-  // TCMALLOC_SAMPLE_PARAMETER.)
-  virtual void GetHeapGrowthStacks(MallocExtensionWriter* writer);
-
-  // Invokes func(arg, range) for every controlled memory
-  // range.  *range is filled in with information about the range.
-  //
-  // This is a best-effort interface useful only for performance
-  // analysis.  The implementation may not call func at all.
-  typedef void (RangeFunction)(void*, const base::MallocRange*);
-  virtual void Ranges(void* arg, RangeFunction func);
-
-  // -------------------------------------------------------------------
-  // Control operations for getting and setting malloc implementation
-  // specific parameters.  Some currently useful properties:
-  //
-  // generic
-  // -------
-  // "generic.current_allocated_bytes"
-  //      Number of bytes currently allocated by application
-  //      This property is not writable.
-  //
-  // "generic.heap_size"
-  //      Number of bytes in the heap ==
-  //            current_allocated_bytes +
-  //            fragmentation +
-  //            freed memory regions
-  //      This property is not writable.
-  //
-  //  "generic.total_physical_bytes"
-  //      Estimate of total bytes of the physical memory usage by the
-  //      allocator ==
-  //            current_allocated_bytes +
-  //            fragmentation +
-  //            metadata
-  //      This property is not writable.
-  //
-  // tcmalloc
-  // --------
-  // "tcmalloc.max_total_thread_cache_bytes"
-  //      Upper limit on total number of bytes stored across all
-  //      per-thread caches.  Default: 16MB.
-  //
-  // "tcmalloc.current_total_thread_cache_bytes"
-  //      Number of bytes used across all thread caches.
-  //      This property is not writable.
-  //
-  // "tcmalloc.central_cache_free_bytes"
-  //      Number of free bytes in the central cache that have been
-  //      assigned to size classes. They always count towards virtual
-  //      memory usage, and unless the underlying memory is swapped out
-  //      by the OS, they also count towards physical memory usage.
-  //      This property is not writable.
-  //
-  // "tcmalloc.transfer_cache_free_bytes"
-  //      Number of free bytes that are waiting to be transfered between
-  //      the central cache and a thread cache. They always count
-  //      towards virtual memory usage, and unless the underlying memory
-  //      is swapped out by the OS, they also count towards physical
-  //      memory usage. This property is not writable.
-  //
-  // "tcmalloc.thread_cache_free_bytes"
-  //      Number of free bytes in thread caches. They always count
-  //      towards virtual memory usage, and unless the underlying memory
-  //      is swapped out by the OS, they also count towards physical
-  //      memory usage. This property is not writable.
-  //
-  // "tcmalloc.pageheap_free_bytes"
-  //      Number of bytes in free, mapped pages in page heap.  These
-  //      bytes can be used to fulfill allocation requests.  They
-  //      always count towards virtual memory usage, and unless the
-  //      underlying memory is swapped out by the OS, they also count
-  //      towards physical memory usage.  This property is not writable.
-  //
-  // "tcmalloc.pageheap_unmapped_bytes"
-  //        Number of bytes in free, unmapped pages in page heap.
-  //        These are bytes that have been released back to the OS,
-  //        possibly by one of the MallocExtension "Release" calls.
-  //        They can be used to fulfill allocation requests, but
-  //        typically incur a page fault.  They always count towards
-  //        virtual memory usage, and depending on the OS, typically
-  //        do not count towards physical memory usage.  This property
-  //        is not writable.
-  // -------------------------------------------------------------------
-
-  // Get the named "property"'s value.  Returns true if the property
-  // is known.  Returns false if the property is not a valid property
-  // name for the current malloc implementation.
-  // REQUIRES: property != NULL; value != NULL
-  virtual bool GetNumericProperty(const char* property, size_t* value);
-
-  // Set the named "property"'s value.  Returns true if the property
-  // is known and writable.  Returns false if the property is not a
-  // valid property name for the current malloc implementation, or
-  // is not writable.
-  // REQUIRES: property != NULL
-  virtual bool SetNumericProperty(const char* property, size_t value);
-
-  // Mark the current thread as "idle".  This routine may optionally
-  // be called by threads as a hint to the malloc implementation that
-  // any thread-specific resources should be released.  Note: this may
-  // be an expensive routine, so it should not be called too often.
-  //
-  // Also, if the code that calls this routine will go to sleep for
-  // a while, it should take care to not allocate anything between
-  // the call to this routine and the beginning of the sleep.
-  //
-  // Most malloc implementations ignore this routine.
-  virtual void MarkThreadIdle();
-
-  // Mark the current thread as "busy".  This routine should be
-  // called after MarkThreadIdle() if the thread will now do more
-  // work.  If this method is not called, performance may suffer.
-  //
-  // Most malloc implementations ignore this routine.
-  virtual void MarkThreadBusy();
-
-  // Gets the system allocator used by the malloc extension instance. Returns
-  // NULL for malloc implementations that do not support pluggable system
-  // allocators.
-  virtual SysAllocator* GetSystemAllocator();
-
-  // Sets the system allocator to the specified.
-  //
-  // Users could register their own system allocators for malloc implementation
-  // that supports pluggable system allocators, such as TCMalloc, by doing:
-  //   alloc = new MyOwnSysAllocator();
-  //   MallocExtension::instance()->SetSystemAllocator(alloc);
-  // It's up to users whether to fall back (recommended) to the default
-  // system allocator (use GetSystemAllocator() above) or not. The caller is
-  // responsible to any necessary locking.
-  // See tcmalloc/system-alloc.h for the interface and
-  //     tcmalloc/memfs_malloc.cc for the examples.
-  //
-  // It's a no-op for malloc implementations that do not support pluggable
-  // system allocators.
-  virtual void SetSystemAllocator(SysAllocator *a);
-
-  // Try to release num_bytes of free memory back to the operating
-  // system for reuse.  Use this extension with caution -- to get this
-  // memory back may require faulting pages back in by the OS, and
-  // that may be slow.  (Currently only implemented in tcmalloc.)
-  virtual void ReleaseToSystem(size_t num_bytes);
-
-  // Same as ReleaseToSystem() but release as much memory as possible.
-  virtual void ReleaseFreeMemory();
-
-  // Sets the rate at which we release unused memory to the system.
-  // Zero means we never release memory back to the system.  Increase
-  // this flag to return memory faster; decrease it to return memory
-  // slower.  Reasonable rates are in the range [0,10].  (Currently
-  // only implemented in tcmalloc).
-  virtual void SetMemoryReleaseRate(double rate);
-
-  // Gets the release rate.  Returns a value < 0 if unknown.
-  virtual double GetMemoryReleaseRate();
-
-  // Returns the estimated number of bytes that will be allocated for
-  // a request of "size" bytes.  This is an estimate: an allocation of
-  // SIZE bytes may reserve more bytes, but will never reserve less.
-  // (Currently only implemented in tcmalloc, other implementations
-  // always return SIZE.)
-  // This is equivalent to malloc_good_size() in OS X.
-  virtual size_t GetEstimatedAllocatedSize(size_t size);
-
-  // Returns the actual number N of bytes reserved by tcmalloc for the
-  // pointer p.  The client is allowed to use the range of bytes
-  // [p, p+N) in any way it wishes (i.e. N is the "usable size" of this
-  // allocation).  This number may be equal to or greater than the number
-  // of bytes requested when p was allocated.
-  // p must have been allocated by this malloc implementation,
-  // must not be an interior pointer -- that is, must be exactly
-  // the pointer returned to by malloc() et al., not some offset
-  // from that -- and should not have been freed yet.  p may be NULL.
-  // (Currently only implemented in tcmalloc; other implementations
-  // will return 0.)
-  // This is equivalent to malloc_size() in OS X, malloc_usable_size()
-  // in glibc, and _msize() for windows.
-  virtual size_t GetAllocatedSize(const void* p);
-
-  // Returns kOwned if this malloc implementation allocated the memory
-  // pointed to by p, or kNotOwned if some other malloc implementation
-  // allocated it or p is NULL.  May also return kUnknownOwnership if
-  // the malloc implementation does not keep track of ownership.
-  // REQUIRES: p must be a value returned from a previous call to
-  // malloc(), calloc(), realloc(), memalign(), posix_memalign(),
-  // valloc(), pvalloc(), new, or new[], and must refer to memory that
-  // is currently allocated (so, for instance, you should not pass in
-  // a pointer after having called free() on it).
-  enum Ownership {
-    // NOTE: Enum values MUST be kept in sync with the version in
-    // malloc_extension_c.h
-    kUnknownOwnership = 0,
-    kOwned,
-    kNotOwned
-  };
-  virtual Ownership GetOwnership(const void* p);
-
-  // The current malloc implementation.  Always non-NULL.
-  static MallocExtension* instance() {
-    InitModuleOnce();
-    return current_instance_.load(std::memory_order_acquire);
-  }
-
-  // Change the malloc implementation.  Typically called by the
-  // malloc implementation during initialization.
-  static void Register(MallocExtension* implementation);
-
-  // Returns detailed information about malloc's freelists. For each list,
-  // return a FreeListInfo:
-  struct FreeListInfo {
-    size_t min_object_size;
-    size_t max_object_size;
-    size_t total_bytes_free;
-    const char* type;
-  };
-  // Each item in the vector refers to a different freelist. The lists
-  // are identified by the range of allocations that objects in the
-  // list can satisfy ([min_object_size, max_object_size]) and the
-  // type of freelist (see below). The current size of the list is
-  // returned in total_bytes_free (which count against a processes
-  // resident and virtual size).
-  //
-  // Currently supported types are:
-  //
-  // "tcmalloc.page{_unmapped}" - tcmalloc's page heap. An entry for each size
-  //          class in the page heap is returned. Bytes in "page_unmapped"
-  //          are no longer backed by physical memory and do not count against
-  //          the resident size of a process.
-  //
-  // "tcmalloc.large{_unmapped}" - tcmalloc's list of objects larger
-  //          than the largest page heap size class. Only one "large"
-  //          entry is returned. There is no upper-bound on the size
-  //          of objects in the large free list; this call returns
-  //          kint64max for max_object_size.  Bytes in
-  //          "large_unmapped" are no longer backed by physical memory
-  //          and do not count against the resident size of a process.
-  //
-  // "tcmalloc.central" - tcmalloc's central free-list. One entry per
-  //          size-class is returned. Never unmapped.
-  //
-  // "debug.free_queue" - free objects queued by the debug allocator
-  //                      and not returned to tcmalloc.
-  //
-  // "tcmalloc.thread" - tcmalloc's per-thread caches. Never unmapped.
-  virtual void GetFreeListSizes(std::vector<FreeListInfo>* v);
-
-  // Get a list of stack traces of sampled allocation points.  Returns
-  // a pointer to a "new[]-ed" result array, and stores the sample
-  // period in "sample_period".
-  //
-  // The state is stored as a sequence of adjacent entries
-  // in the returned array.  Each entry has the following form:
-  //    uintptr_t count;        // Number of objects with following trace
-  //    uintptr_t size;         // Total size of objects with following trace
-  //    uintptr_t depth;        // Number of PC values in stack trace
-  //    void*     stack[depth]; // PC values that form the stack trace
-  //
-  // The list of entries is terminated by a "count" of 0.
-  //
-  // It is the responsibility of the caller to "delete[]" the returned array.
-  //
-  // May return NULL to indicate no results.
-  //
-  // This is an internal extension.  Callers should use the more
-  // convenient "GetHeapSample(string*)" method defined above.
-  virtual void** ReadStackTraces(int* sample_period);
-
-  // Like ReadStackTraces(), but returns stack traces that caused growth
-  // in the address space size.
-  virtual void** ReadHeapGrowthStackTraces();
-
-  // Returns the size in bytes of the calling threads cache.
-  virtual size_t GetThreadCacheSize();
-
-  // Like MarkThreadIdle, but does not destroy the internal data
-  // structures of the thread cache. When the thread resumes, it wil
-  // have an empty cache but will not need to pay to reconstruct the
-  // cache data structures.
-  virtual void MarkThreadTemporarilyIdle();
-
- private:
-  static MallocExtension* InitModule();
-
-  static void InitModuleOnce() {
-    // Pointer stored here so heap leak checker will consider the default
-    // instance reachable, even if current_instance_ is later overridden by
-    // MallocExtension::Register().
-    ATTRIBUTE_UNUSED static MallocExtension* default_instance = InitModule();
-  }
-
-  static std::atomic<MallocExtension*> current_instance_;
-};
-
-namespace base {
-
-// Information passed per range.  More fields may be added later.
-struct MallocRange {
-  enum Type {
-    INUSE,                // Application is using this range
-    FREE,                 // Range is currently free
-    UNMAPPED,             // Backing physical memory has been returned to the OS
-    UNKNOWN
-    // More enum values may be added in the future
-  };
-
-  uintptr_t address;    // Address of range
-  size_t length;        // Byte length of range
-  Type type;            // Type of this range
-  double fraction;      // Fraction of range that is being used (0 if !INUSE)
-
-  // Perhaps add the following:
-  // - stack trace if this range was sampled
-  // - heap growth stack trace if applicable to this range
-  // - age when allocated (for inuse) or freed (if not in use)
-};
-
-} // namespace base
-
-#endif  // BASE_MALLOC_EXTENSION_H_
diff --git a/third_party/tcmalloc/chromium/src/gperftools/malloc_extension_c.h b/third_party/tcmalloc/chromium/src/gperftools/malloc_extension_c.h
deleted file mode 100644
index 70ff686..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/malloc_extension_c.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * --
- * Author: Craig Silverstein
- *
- * C shims for the C++ malloc_extension.h.  See malloc_extension.h for
- * details.  Note these C shims always work on
- * MallocExtension::instance(); it is not possible to have more than
- * one MallocExtension object in C applications.
- */
-
-#ifndef _MALLOC_EXTENSION_C_H_
-#define _MALLOC_EXTENSION_C_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-
-/* Annoying stuff for windows -- makes sure clients can import these fns */
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define kMallocExtensionHistogramSize 64
-
-PERFTOOLS_DLL_DECL int MallocExtension_VerifyAllMemory(void);
-PERFTOOLS_DLL_DECL int MallocExtension_VerifyNewMemory(const void* p);
-PERFTOOLS_DLL_DECL int MallocExtension_VerifyArrayNewMemory(const void* p);
-PERFTOOLS_DLL_DECL int MallocExtension_VerifyMallocMemory(const void* p);
-PERFTOOLS_DLL_DECL int MallocExtension_MallocMemoryStats(int* blocks, size_t* total,
-                                      int histogram[kMallocExtensionHistogramSize]);
-PERFTOOLS_DLL_DECL void MallocExtension_GetStats(char* buffer, int buffer_length);
-
-/* TODO(csilvers): write a C version of these routines, that perhaps
- * takes a function ptr and a void *.
- */
-/* void MallocExtension_GetHeapSample(string* result); */
-/* void MallocExtension_GetHeapGrowthStacks(string* result); */
-
-PERFTOOLS_DLL_DECL int MallocExtension_GetNumericProperty(const char* property, size_t* value);
-PERFTOOLS_DLL_DECL int MallocExtension_SetNumericProperty(const char* property, size_t value);
-PERFTOOLS_DLL_DECL void MallocExtension_MarkThreadIdle(void);
-PERFTOOLS_DLL_DECL void MallocExtension_MarkThreadBusy(void);
-PERFTOOLS_DLL_DECL void MallocExtension_ReleaseToSystem(size_t num_bytes);
-PERFTOOLS_DLL_DECL void MallocExtension_ReleaseFreeMemory(void);
-PERFTOOLS_DLL_DECL size_t MallocExtension_GetEstimatedAllocatedSize(size_t size);
-PERFTOOLS_DLL_DECL size_t MallocExtension_GetAllocatedSize(const void* p);
-PERFTOOLS_DLL_DECL size_t MallocExtension_GetThreadCacheSize(void);
-PERFTOOLS_DLL_DECL void MallocExtension_MarkThreadTemporarilyIdle(void);
-
-/*
- * NOTE: These enum values MUST be kept in sync with the version in
- *       malloc_extension.h
- */
-typedef enum {
-  MallocExtension_kUnknownOwnership = 0,
-  MallocExtension_kOwned,
-  MallocExtension_kNotOwned
-} MallocExtension_Ownership;
-
-PERFTOOLS_DLL_DECL MallocExtension_Ownership MallocExtension_GetOwnership(const void* p);
-
-#ifdef __cplusplus
-}   /* extern "C" */
-#endif
-
-#endif /* _MALLOC_EXTENSION_C_H_ */
diff --git a/third_party/tcmalloc/chromium/src/gperftools/malloc_hook.h b/third_party/tcmalloc/chromium/src/gperftools/malloc_hook.h
deleted file mode 100644
index b76411f..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/malloc_hook.h
+++ /dev/null
@@ -1,359 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Some of our malloc implementations can invoke the following hooks whenever
-// memory is allocated or deallocated.  MallocHook is thread-safe, and things
-// you do before calling AddFooHook(MyHook) are visible to any resulting calls
-// to MyHook.  Hooks must be thread-safe.  If you write:
-//
-//   CHECK(MallocHook::AddNewHook(&MyNewHook));
-//
-// MyNewHook will be invoked in subsequent calls in the current thread, but
-// there are no guarantees on when it might be invoked in other threads.
-//
-// There are a limited number of slots available for each hook type.  Add*Hook
-// will return false if there are no slots available.  Remove*Hook will return
-// false if the given hook was not already installed.
-//
-// The order in which individual hooks are called in Invoke*Hook is undefined.
-//
-// It is safe for a hook to remove itself within Invoke*Hook and add other
-// hooks.  Any hooks added inside a hook invocation (for the same hook type)
-// will not be invoked for the current invocation.
-//
-// One important user of these hooks is the heap profiler.
-//
-// CAVEAT: If you add new MallocHook::Invoke* calls then those calls must be
-// directly in the code of the (de)allocation function that is provided to the
-// user and that function must have an ATTRIBUTE_SECTION(malloc_hook) attribute.
-//
-// Note: the Invoke*Hook() functions are defined in malloc_hook-inl.h.  If you
-// need to invoke a hook (which you shouldn't unless you're part of tcmalloc),
-// be sure to #include malloc_hook-inl.h in addition to malloc_hook.h.
-//
-// NOTE FOR C USERS: If you want to use malloc_hook functionality from
-// a C program, #include malloc_hook_c.h instead of this file.
-
-#ifndef _MALLOC_HOOK_H_
-#define _MALLOC_HOOK_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-extern "C" {
-#include "malloc_hook_c.h"  // a C version of the malloc_hook interface
-}
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-// The C++ methods below call the C version (MallocHook_*), and thus
-// convert between an int and a bool.  Windows complains about this
-// (a "performance warning") which we don't care about, so we suppress.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4800)
-#endif
-
-// Note: malloc_hook_c.h defines MallocHook_*Hook and
-// MallocHook_{Add,Remove}*Hook.  The version of these inside the MallocHook
-// class are defined in terms of the malloc_hook_c version.  See malloc_hook_c.h
-// for details of these types/functions.
-
-class PERFTOOLS_DLL_DECL MallocHook {
- public:
-  // The NewHook is invoked whenever an object is allocated.
-  // It may be passed NULL if the allocator returned NULL.
-  typedef MallocHook_NewHook NewHook;
-  inline static bool AddNewHook(NewHook hook) {
-    return MallocHook_AddNewHook(hook);
-  }
-  inline static bool RemoveNewHook(NewHook hook) {
-    return MallocHook_RemoveNewHook(hook);
-  }
-  inline static void InvokeNewHook(const void* p, size_t s);
-
-  // The DeleteHook is invoked whenever an object is deallocated.
-  // It may be passed NULL if the caller is trying to delete NULL.
-  typedef MallocHook_DeleteHook DeleteHook;
-  inline static bool AddDeleteHook(DeleteHook hook) {
-    return MallocHook_AddDeleteHook(hook);
-  }
-  inline static bool RemoveDeleteHook(DeleteHook hook) {
-    return MallocHook_RemoveDeleteHook(hook);
-  }
-  inline static void InvokeDeleteHook(const void* p);
-
-  // The PreMmapHook is invoked with mmap or mmap64 arguments just
-  // before the call is actually made.  Such a hook may be useful
-  // in memory limited contexts, to catch allocations that will exceed
-  // a memory limit, and take outside actions to increase that limit.
-  typedef MallocHook_PreMmapHook PreMmapHook;
-  inline static bool AddPreMmapHook(PreMmapHook hook) {
-    return MallocHook_AddPreMmapHook(hook);
-  }
-  inline static bool RemovePreMmapHook(PreMmapHook hook) {
-    return MallocHook_RemovePreMmapHook(hook);
-  }
-  inline static void InvokePreMmapHook(const void* start,
-                                       size_t size,
-                                       int protection,
-                                       int flags,
-                                       int fd,
-                                       off_t offset);
-
-  // The MmapReplacement is invoked after the PreMmapHook but before
-  // the call is actually made. The MmapReplacement should return true
-  // if it handled the call, or false if it is still necessary to
-  // call mmap/mmap64.
-  // This should be used only by experts, and users must be be
-  // extremely careful to avoid recursive calls to mmap. The replacement
-  // should be async signal safe.
-  // Only one MmapReplacement is supported. After setting an MmapReplacement
-  // you must call RemoveMmapReplacement before calling SetMmapReplacement
-  // again.
-  typedef MallocHook_MmapReplacement MmapReplacement;
-  inline static bool SetMmapReplacement(MmapReplacement hook) {
-    return MallocHook_SetMmapReplacement(hook);
-  }
-  inline static bool RemoveMmapReplacement(MmapReplacement hook) {
-    return MallocHook_RemoveMmapReplacement(hook);
-  }
-  inline static bool InvokeMmapReplacement(const void* start,
-                                           size_t size,
-                                           int protection,
-                                           int flags,
-                                           int fd,
-                                           off_t offset,
-                                           void** result);
-
-
-  // The MmapHook is invoked whenever a region of memory is mapped.
-  // It may be passed MAP_FAILED if the mmap failed.
-  typedef MallocHook_MmapHook MmapHook;
-  inline static bool AddMmapHook(MmapHook hook) {
-    return MallocHook_AddMmapHook(hook);
-  }
-  inline static bool RemoveMmapHook(MmapHook hook) {
-    return MallocHook_RemoveMmapHook(hook);
-  }
-  inline static void InvokeMmapHook(const void* result,
-                                    const void* start,
-                                    size_t size,
-                                    int protection,
-                                    int flags,
-                                    int fd,
-                                    off_t offset);
-
-  // The MunmapReplacement is invoked with munmap arguments just before
-  // the call is actually made. The MunmapReplacement should return true
-  // if it handled the call, or false if it is still necessary to
-  // call munmap.
-  // This should be used only by experts. The replacement should be
-  // async signal safe.
-  // Only one MunmapReplacement is supported. After setting an
-  // MunmapReplacement you must call RemoveMunmapReplacement before
-  // calling SetMunmapReplacement again.
-  typedef MallocHook_MunmapReplacement MunmapReplacement;
-  inline static bool SetMunmapReplacement(MunmapReplacement hook) {
-    return MallocHook_SetMunmapReplacement(hook);
-  }
-  inline static bool RemoveMunmapReplacement(MunmapReplacement hook) {
-    return MallocHook_RemoveMunmapReplacement(hook);
-  }
-  inline static bool InvokeMunmapReplacement(const void* p,
-                                             size_t size,
-                                             int* result);
-
-  // The MunmapHook is invoked whenever a region of memory is unmapped.
-  typedef MallocHook_MunmapHook MunmapHook;
-  inline static bool AddMunmapHook(MunmapHook hook) {
-    return MallocHook_AddMunmapHook(hook);
-  }
-  inline static bool RemoveMunmapHook(MunmapHook hook) {
-    return MallocHook_RemoveMunmapHook(hook);
-  }
-  inline static void InvokeMunmapHook(const void* p, size_t size);
-
-  // The MremapHook is invoked whenever a region of memory is remapped.
-  typedef MallocHook_MremapHook MremapHook;
-  inline static bool AddMremapHook(MremapHook hook) {
-    return MallocHook_AddMremapHook(hook);
-  }
-  inline static bool RemoveMremapHook(MremapHook hook) {
-    return MallocHook_RemoveMremapHook(hook);
-  }
-  inline static void InvokeMremapHook(const void* result,
-                                      const void* old_addr,
-                                      size_t old_size,
-                                      size_t new_size,
-                                      int flags,
-                                      const void* new_addr);
-
-  // The PreSbrkHook is invoked just before sbrk is called -- except when
-  // the increment is 0.  This is because sbrk(0) is often called
-  // to get the top of the memory stack, and is not actually a
-  // memory-allocation call.  It may be useful in memory-limited contexts,
-  // to catch allocations that will exceed the limit and take outside
-  // actions to increase such a limit.
-  typedef MallocHook_PreSbrkHook PreSbrkHook;
-  inline static bool AddPreSbrkHook(PreSbrkHook hook) {
-    return MallocHook_AddPreSbrkHook(hook);
-  }
-  inline static bool RemovePreSbrkHook(PreSbrkHook hook) {
-    return MallocHook_RemovePreSbrkHook(hook);
-  }
-  inline static void InvokePreSbrkHook(ptrdiff_t increment);
-
-  // The SbrkHook is invoked whenever sbrk is called -- except when
-  // the increment is 0.  This is because sbrk(0) is often called
-  // to get the top of the memory stack, and is not actually a
-  // memory-allocation call.
-  typedef MallocHook_SbrkHook SbrkHook;
-  inline static bool AddSbrkHook(SbrkHook hook) {
-    return MallocHook_AddSbrkHook(hook);
-  }
-  inline static bool RemoveSbrkHook(SbrkHook hook) {
-    return MallocHook_RemoveSbrkHook(hook);
-  }
-  inline static void InvokeSbrkHook(const void* result, ptrdiff_t increment);
-
-  // Get the current stack trace.  Try to skip all routines up to and
-  // and including the caller of MallocHook::Invoke*.
-  // Use "skip_count" (similarly to GetStackTrace from stacktrace.h)
-  // as a hint about how many routines to skip if better information
-  // is not available.
-  inline static int GetCallerStackTrace(void** result, int max_depth,
-                                        int skip_count) {
-    return MallocHook_GetCallerStackTrace(result, max_depth, skip_count);
-  }
-
-  // Unhooked versions of mmap() and munmap().   These should be used
-  // only by experts, since they bypass heapchecking, etc.
-  // Note: These do not run hooks, but they still use the MmapReplacement
-  // and MunmapReplacement.
-  static void* UnhookedMMap(void *start, size_t length, int prot, int flags,
-                            int fd, off_t offset);
-  static int UnhookedMUnmap(void *start, size_t length);
-
-  // The following are DEPRECATED.
-  inline static NewHook GetNewHook();
-  inline static NewHook SetNewHook(NewHook hook) {
-    return MallocHook_SetNewHook(hook);
-  }
-
-  inline static DeleteHook GetDeleteHook();
-  inline static DeleteHook SetDeleteHook(DeleteHook hook) {
-    return MallocHook_SetDeleteHook(hook);
-  }
-
-  inline static PreMmapHook GetPreMmapHook();
-  inline static PreMmapHook SetPreMmapHook(PreMmapHook hook) {
-    return MallocHook_SetPreMmapHook(hook);
-  }
-
-  inline static MmapHook GetMmapHook();
-  inline static MmapHook SetMmapHook(MmapHook hook) {
-    return MallocHook_SetMmapHook(hook);
-  }
-
-  inline static MunmapHook GetMunmapHook();
-  inline static MunmapHook SetMunmapHook(MunmapHook hook) {
-    return MallocHook_SetMunmapHook(hook);
-  }
-
-  inline static MremapHook GetMremapHook();
-  inline static MremapHook SetMremapHook(MremapHook hook) {
-    return MallocHook_SetMremapHook(hook);
-  }
-
-  inline static PreSbrkHook GetPreSbrkHook();
-  inline static PreSbrkHook SetPreSbrkHook(PreSbrkHook hook) {
-    return MallocHook_SetPreSbrkHook(hook);
-  }
-
-  inline static SbrkHook GetSbrkHook();
-  inline static SbrkHook SetSbrkHook(SbrkHook hook) {
-    return MallocHook_SetSbrkHook(hook);
-  }
-  // End of DEPRECATED methods.
-
- private:
-  // Slow path versions of Invoke*Hook.
-  static void InvokeNewHookSlow(const void* p, size_t s);
-  static void InvokeDeleteHookSlow(const void* p);
-  static void InvokePreMmapHookSlow(const void* start,
-                                    size_t size,
-                                    int protection,
-                                    int flags,
-                                    int fd,
-                                    off_t offset);
-  static void InvokeMmapHookSlow(const void* result,
-                                 const void* start,
-                                 size_t size,
-                                 int protection,
-                                 int flags,
-                                 int fd,
-                                 off_t offset);
-  static bool InvokeMmapReplacementSlow(const void* start,
-                                        size_t size,
-                                        int protection,
-                                        int flags,
-                                        int fd,
-                                        off_t offset,
-                                        void** result);
-  static void InvokeMunmapHookSlow(const void* p, size_t size);
-  static bool InvokeMunmapReplacementSlow(const void* p,
-                                          size_t size,
-                                          int* result);
-  static void InvokeMremapHookSlow(const void* result,
-                                   const void* old_addr,
-                                   size_t old_size,
-                                   size_t new_size,
-                                   int flags,
-                                   const void* new_addr);
-  static void InvokePreSbrkHookSlow(ptrdiff_t increment);
-  static void InvokeSbrkHookSlow(const void* result, ptrdiff_t increment);
-};
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-
-#endif /* _MALLOC_HOOK_H_ */
diff --git a/third_party/tcmalloc/chromium/src/gperftools/malloc_hook_c.h b/third_party/tcmalloc/chromium/src/gperftools/malloc_hook_c.h
deleted file mode 100644
index 56337e15..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/malloc_hook_c.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * --
- * Author: Craig Silverstein
- *
- * C shims for the C++ malloc_hook.h.  See malloc_hook.h for details
- * on how to use these.
- */
-
-#ifndef _MALLOC_HOOK_C_H_
-#define _MALLOC_HOOK_C_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-
-/* Annoying stuff for windows; makes sure clients can import these functions */
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Get the current stack trace.  Try to skip all routines up to and
- * and including the caller of MallocHook::Invoke*.
- * Use "skip_count" (similarly to GetStackTrace from stacktrace.h)
- * as a hint about how many routines to skip if better information
- * is not available.
- */
-PERFTOOLS_DLL_DECL
-int MallocHook_GetCallerStackTrace(void** result, int max_depth,
-                                   int skip_count);
-
-/* The MallocHook_{Add,Remove}*Hook functions return 1 on success and 0 on
- * failure.
- */
-
-typedef void (*MallocHook_NewHook)(const void* ptr, size_t size);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddNewHook(MallocHook_NewHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveNewHook(MallocHook_NewHook hook);
-
-typedef void (*MallocHook_DeleteHook)(const void* ptr);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddDeleteHook(MallocHook_DeleteHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveDeleteHook(MallocHook_DeleteHook hook);
-
-typedef void (*MallocHook_PreMmapHook)(const void *start,
-                                       size_t size,
-                                       int protection,
-                                       int flags,
-                                       int fd,
-                                       off_t offset);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddPreMmapHook(MallocHook_PreMmapHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemovePreMmapHook(MallocHook_PreMmapHook hook);
-
-typedef void (*MallocHook_MmapHook)(const void* result,
-                                    const void* start,
-                                    size_t size,
-                                    int protection,
-                                    int flags,
-                                    int fd,
-                                    off_t offset);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddMmapHook(MallocHook_MmapHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveMmapHook(MallocHook_MmapHook hook);
-
-typedef int (*MallocHook_MmapReplacement)(const void* start,
-                                          size_t size,
-                                          int protection,
-                                          int flags,
-                                          int fd,
-                                          off_t offset,
-                                          void** result);
-int MallocHook_SetMmapReplacement(MallocHook_MmapReplacement hook);
-int MallocHook_RemoveMmapReplacement(MallocHook_MmapReplacement hook);
-
-typedef void (*MallocHook_MunmapHook)(const void* ptr, size_t size);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddMunmapHook(MallocHook_MunmapHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveMunmapHook(MallocHook_MunmapHook hook);
-
-typedef int (*MallocHook_MunmapReplacement)(const void* ptr,
-                                            size_t size,
-                                            int* result);
-int MallocHook_SetMunmapReplacement(MallocHook_MunmapReplacement hook);
-int MallocHook_RemoveMunmapReplacement(MallocHook_MunmapReplacement hook);
-
-typedef void (*MallocHook_MremapHook)(const void* result,
-                                      const void* old_addr,
-                                      size_t old_size,
-                                      size_t new_size,
-                                      int flags,
-                                      const void* new_addr);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddMremapHook(MallocHook_MremapHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveMremapHook(MallocHook_MremapHook hook);
-
-typedef void (*MallocHook_PreSbrkHook)(ptrdiff_t increment);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddPreSbrkHook(MallocHook_PreSbrkHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemovePreSbrkHook(MallocHook_PreSbrkHook hook);
-
-typedef void (*MallocHook_SbrkHook)(const void* result, ptrdiff_t increment);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddSbrkHook(MallocHook_SbrkHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveSbrkHook(MallocHook_SbrkHook hook);
-
-/* The following are DEPRECATED. */
-PERFTOOLS_DLL_DECL
-MallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_PreMmapHook MallocHook_SetPreMmapHook(MallocHook_PreMmapHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_MmapHook MallocHook_SetMmapHook(MallocHook_MmapHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_MunmapHook MallocHook_SetMunmapHook(MallocHook_MunmapHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_MremapHook MallocHook_SetMremapHook(MallocHook_MremapHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_PreSbrkHook MallocHook_SetPreSbrkHook(MallocHook_PreSbrkHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook);
-/* End of DEPRECATED functions. */
-
-#ifdef __cplusplus
-}   // extern "C"
-#endif
-
-#endif /* _MALLOC_HOOK_C_H_ */
diff --git a/third_party/tcmalloc/chromium/src/gperftools/nallocx.h b/third_party/tcmalloc/chromium/src/gperftools/nallocx.h
deleted file mode 100644
index 01f874ca..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/nallocx.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _NALLOCX_H_
-#define _NALLOCX_H_
-#include <stddef.h>
-
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#  define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#  define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MALLOCX_LG_ALIGN(la) ((int)(la))
-
-/*
- * The nallocx function allocates no memory, but it performs the same size
- * computation as the malloc function, and returns the real size of the
- * allocation that would result from the equivalent malloc function call.
- * nallocx is a malloc extension originally implemented by jemalloc:
- * http://www.unix.com/man-page/freebsd/3/nallocx/
- *
- * Note, we only support MALLOCX_LG_ALIGN flag and nothing else.
- */
-PERFTOOLS_DLL_DECL size_t nallocx(size_t size, int flags);
-
-/* same as above but never weak */
-PERFTOOLS_DLL_DECL size_t tc_nallocx(size_t size, int flags);
-
-#ifdef __cplusplus
-}   /* extern "C" */
-#endif
-
-#endif /* _NALLOCX_H_ */
diff --git a/third_party/tcmalloc/chromium/src/gperftools/profiler.h b/third_party/tcmalloc/chromium/src/gperftools/profiler.h
deleted file mode 100644
index 1e7eb12..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/profiler.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- *
- * Module for CPU profiling based on periodic pc-sampling.
- *
- * For full(er) information, see docs/cpuprofile.html
- *
- * This module is linked into your program with
- * no slowdown caused by this unless you activate the profiler
- * using one of the following methods:
- *
- *    1. Before starting the program, set the environment variable
- *       "CPUPROFILE" to be the name of the file to which the profile
- *       data should be written.
- *
- *    2. Programmatically, start and stop the profiler using the
- *       routines "ProfilerStart(filename)" and "ProfilerStop()".
- *
- *
- * (Note: if using linux 2.4 or earlier, only the main thread may be
- * profiled.)
- *
- * Use pprof to view the resulting profile output.
- *    % pprof <path_to_executable> <profile_file_name>
- *    % pprof --gv  <path_to_executable> <profile_file_name>
- *
- * These functions are thread-safe.
- */
-
-#ifndef BASE_PROFILER_H_
-#define BASE_PROFILER_H_
-
-#include <time.h>       /* For time_t */
-
-/* Annoying stuff for windows; makes sure clients can import these functions */
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-/* All this code should be usable from within C apps. */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Profiler options, for use with ProfilerStartWithOptions.  To use:
- *
- *   struct ProfilerOptions options;
- *   memset(&options, 0, sizeof options);
- *
- * then fill in fields as needed.
- *
- * This structure is intended to be usable from C code, so no constructor
- * is provided to initialize it.  (Use memset as described above).
- */
-struct ProfilerOptions {
-  /* Filter function and argument.
-   *
-   * If filter_in_thread is not NULL, when a profiling tick is delivered
-   * the profiler will call:
-   *
-   *   (*filter_in_thread)(filter_in_thread_arg)
-   *
-   * If it returns nonzero, the sample will be included in the profile.
-   * Note that filter_in_thread runs in a signal handler, so must be
-   * async-signal-safe.
-   *
-   * A typical use would be to set up filter results for each thread
-   * in the system before starting the profiler, then to make
-   * filter_in_thread be a very simple function which retrieves those
-   * results in an async-signal-safe way.  Retrieval could be done
-   * using thread-specific data, or using a shared data structure that
-   * supports async-signal-safe lookups.
-   */
-  int (*filter_in_thread)(void *arg);
-  void *filter_in_thread_arg;
-};
-
-/* Start profiling and write profile info into fname, discarding any
- * existing profiling data in that file.
- *
- * This is equivalent to calling ProfilerStartWithOptions(fname, NULL).
- */
-PERFTOOLS_DLL_DECL int ProfilerStart(const char* fname);
-
-/* Start profiling and write profile into fname, discarding any
- * existing profiling data in that file.
- *
- * The profiler is configured using the options given by 'options'.
- * Options which are not specified are given default values.
- *
- * 'options' may be NULL, in which case all are given default values.
- *
- * Returns nonzero if profiling was started successfully, or zero else.
- */
-PERFTOOLS_DLL_DECL int ProfilerStartWithOptions(
-    const char *fname, const struct ProfilerOptions *options);
-
-/* Stop profiling. Can be started again with ProfilerStart(), but
- * the currently accumulated profiling data will be cleared.
- */
-PERFTOOLS_DLL_DECL void ProfilerStop(void);
-
-/* Flush any currently buffered profiling state to the profile file.
- * Has no effect if the profiler has not been started.
- */
-PERFTOOLS_DLL_DECL void ProfilerFlush(void);
-
-
-/* DEPRECATED: these functions were used to enable/disable profiling
- * in the current thread, but no longer do anything.
- */
-PERFTOOLS_DLL_DECL void ProfilerEnable(void);
-PERFTOOLS_DLL_DECL void ProfilerDisable(void);
-
-/* Returns nonzero if profile is currently enabled, zero if it's not. */
-PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads(void);
-
-/* Routine for registering new threads with the profiler.
- */
-PERFTOOLS_DLL_DECL void ProfilerRegisterThread(void);
-
-/* Stores state about profiler's current status into "*state". */
-struct ProfilerState {
-  int    enabled;             /* Is profiling currently enabled? */
-  time_t start_time;          /* If enabled, when was profiling started? */
-  char   profile_name[1024];  /* Name of profile file being written, or '\0' */
-  int    samples_gathered;    /* Number of samples gathered so far (or 0) */
-};
-PERFTOOLS_DLL_DECL void ProfilerGetCurrentState(struct ProfilerState* state);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  /* BASE_PROFILER_H_ */
diff --git a/third_party/tcmalloc/chromium/src/gperftools/stacktrace.h b/third_party/tcmalloc/chromium/src/gperftools/stacktrace.h
deleted file mode 100644
index 2b9c5a13..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/stacktrace.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Routines to extract the current stack trace.  These functions are
-// thread-safe.
-
-#ifndef GOOGLE_STACKTRACE_H_
-#define GOOGLE_STACKTRACE_H_
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-
-// Skips the most recent "skip_count" stack frames (also skips the
-// frame generated for the "GetStackFrames" routine itself), and then
-// records the pc values for up to the next "max_depth" frames in
-// "result", and the corresponding stack frame sizes in "sizes".
-// Returns the number of values recorded in "result"/"sizes".
-//
-// Example:
-//      main() { foo(); }
-//      foo() { bar(); }
-//      bar() {
-//        void* result[10];
-//        int sizes[10];
-//        int depth = GetStackFrames(result, sizes, 10, 1);
-//      }
-//
-// The GetStackFrames call will skip the frame for "bar".  It will
-// return 2 and will produce pc values that map to the following
-// procedures:
-//      result[0]       foo
-//      result[1]       main
-// (Actually, there may be a few more entries after "main" to account for
-// startup procedures.)
-// And corresponding stack frame sizes will also be recorded:
-//    sizes[0]       16
-//    sizes[1]       16
-// (Stack frame sizes of 16 above are just for illustration purposes.)
-// Stack frame sizes of 0 or less indicate that those frame sizes couldn't
-// be identified.
-//
-// This routine may return fewer stack frame entries than are
-// available. Also note that "result" and "sizes" must both be non-NULL.
-extern PERFTOOLS_DLL_DECL int GetStackFrames(void** result, int* sizes, int max_depth,
-                          int skip_count);
-
-// Same as above, but to be used from a signal handler. The "uc" parameter
-// should be the pointer to ucontext_t which was passed as the 3rd parameter
-// to sa_sigaction signal handler. It may help the unwinder to get a
-// better stack trace under certain conditions. The "uc" may safely be NULL.
-extern PERFTOOLS_DLL_DECL int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
-                                     int skip_count, const void *uc);
-
-// This is similar to the GetStackFrames routine, except that it returns
-// the stack trace only, and not the stack frame sizes as well.
-// Example:
-//      main() { foo(); }
-//      foo() { bar(); }
-//      bar() {
-//        void* result[10];
-//        int depth = GetStackTrace(result, 10, 1);
-//      }
-//
-// This produces:
-//      result[0]       foo
-//      result[1]       main
-//           ....       ...
-//
-// "result" must not be NULL.
-extern PERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,
-                                            int skip_count);
-
-// Same as above, but to be used from a signal handler. The "uc" parameter
-// should be the pointer to ucontext_t which was passed as the 3rd parameter
-// to sa_sigaction signal handler. It may help the unwinder to get a
-// better stack trace under certain conditions. The "uc" may safely be NULL.
-extern PERFTOOLS_DLL_DECL int GetStackTraceWithContext(void** result, int max_depth,
-                                    int skip_count, const void *uc);
-
-#endif /* GOOGLE_STACKTRACE_H_ */
diff --git a/third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h b/third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h
deleted file mode 100644
index 91b32ae..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h
+++ /dev/null
@@ -1,189 +0,0 @@
-// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat <opensource@google.com>
- *         .h file by Craig Silverstein <opensource@google.com>
- */
-
-#ifndef TCMALLOC_TCMALLOC_H_
-#define TCMALLOC_TCMALLOC_H_
-
-#include <stddef.h> /* for size_t */
-#ifdef __cplusplus
-#include <new> /* for std::nothrow_t, std::align_val_t */
-#endif
-
-/* Define the version number so folks can check against it */
-#define TC_VERSION_MAJOR 2
-#define TC_VERSION_MINOR 7
-#define TC_VERSION_PATCH ""
-#define TC_VERSION_STRING "gperftools 2.7"
-
-/* For struct mallinfo, if it's defined. */
-#if HAVE_STRUCT_MALLINFO
-#include <malloc.h>
-#endif
-
-#ifndef PERFTOOLS_NOTHROW
-
-#if __cplusplus >= 201103L
-#define PERFTOOLS_NOTHROW noexcept
-#elif defined(__cplusplus)
-#define PERFTOOLS_NOTHROW throw()
-#else
-#ifdef __GNUC__
-#define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
-#else
-#define PERFTOOLS_NOTHROW
-#endif
-#endif
-
-#endif
-
-// When passed to mallopt() as first argument causes it to return
-// TC_MALLOPT_IS_OVERRIDDEN_BY_TCMALLOC. Used to detect the sanity of the
-// overriding mechanisms at runtime.
-#define TC_MALLOPT_IS_OVERRIDDEN_BY_TCMALLOC 0xbeef42
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-#ifdef _WIN32
-#define PERFTOOLS_DLL_DECL __declspec(dllimport)
-#else
-#define PERFTOOLS_DLL_DECL
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Returns a human-readable version string.  If major, minor,
- * and/or patch are not NULL, they are set to the major version,
- * minor version, and patch-code (a string, usually "").
- */
-PERFTOOLS_DLL_DECL const char* tc_version(int* major,
-                                          int* minor,
-                                          const char** patch) PERFTOOLS_NOTHROW;
-
-PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_free_sized(void* ptr, size_t size) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
-
-PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
-                                     size_t __size) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
-                                         size_t align,
-                                         size_t size) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
-
-PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
-#if HAVE_STRUCT_MALLINFO
-PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW;
-#endif
-
-/*
- * This is an alias for MallocExtension::instance()->GetAllocatedSize().
- * It is equivalent to
- *    OS X: malloc_size()
- *    glibc: malloc_usable_size()
- *    Windows: _msize()
- */
-PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
-
-#ifdef __cplusplus
-PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void* tc_new(size_t size);
-PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size, const std::nothrow_t&)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
-PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::nothrow_t&)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p,
-                                             size_t size) PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::nothrow_t&)
-    PERFTOOLS_NOTHROW;
-
-#if 1 && __cplusplus >= 201703L
-PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
-PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size,
-                                                std::align_val_t al,
-                                                const std::nothrow_t&)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p,
-                                                size_t size,
-                                                std::align_val_t al)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p,
-                                                  std::align_val_t al,
-                                                  const std::nothrow_t&)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
-PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size,
-                                                     std::align_val_t al,
-                                                     const std::nothrow_t&)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p,
-                                                     size_t size,
-                                                     std::align_val_t al)
-    PERFTOOLS_NOTHROW;
-PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p,
-                                                       std::align_val_t al,
-                                                       const std::nothrow_t&)
-    PERFTOOLS_NOTHROW;
-#endif
-}
-#endif
-
-/* We're only un-defining for public */
-#if !defined(GPERFTOOLS_CONFIG_H_)
-
-#undef PERFTOOLS_NOTHROW
-
-#endif /* GPERFTOOLS_CONFIG_H_ */
-
-#endif /* #ifndef TCMALLOC_TCMALLOC_H_ */
diff --git a/third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h.in b/third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h.in
deleted file mode 100644
index 84ac8fa5..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h.in
+++ /dev/null
@@ -1,163 +0,0 @@
-// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat <opensource@google.com>
- *         .h file by Craig Silverstein <opensource@google.com>
- */
-
-#ifndef TCMALLOC_TCMALLOC_H_
-#define TCMALLOC_TCMALLOC_H_
-
-#include <stddef.h>                     /* for size_t */
-#ifdef __cplusplus
-#include <new>                          /* for std::nothrow_t, std::align_val_t */
-#endif
-
-/* Define the version number so folks can check against it */
-#define TC_VERSION_MAJOR  @TC_VERSION_MAJOR@
-#define TC_VERSION_MINOR  @TC_VERSION_MINOR@
-#define TC_VERSION_PATCH  "@TC_VERSION_PATCH@"
-#define TC_VERSION_STRING "gperftools @TC_VERSION_MAJOR@.@TC_VERSION_MINOR@@TC_VERSION_PATCH@"
-
-/* For struct mallinfo, if it's defined. */
-#if @ac_cv_have_struct_mallinfo@
-# include <malloc.h>
-#endif
-
-#ifndef PERFTOOLS_NOTHROW
-
-#if __cplusplus >= 201103L
-#define PERFTOOLS_NOTHROW noexcept
-#elif defined(__cplusplus)
-#define PERFTOOLS_NOTHROW throw()
-#else
-# ifdef __GNUC__
-#  define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
-# else
-#  define PERFTOOLS_NOTHROW
-# endif
-#endif
-
-#endif
-
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-  /*
-   * Returns a human-readable version string.  If major, minor,
-   * and/or patch are not NULL, they are set to the major version,
-   * minor version, and patch-code (a string, usually "").
-   */
-  PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
-                                            const char** patch) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
-                                       size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
-                                           size_t align, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
-#if @ac_cv_have_struct_mallinfo@
-  PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW;
-#endif
-
-  /*
-   * This is an alias for MallocExtension::instance()->GetAllocatedSize().
-   * It is equivalent to
-   *    OS X: malloc_size()
-   *    glibc: malloc_usable_size()
-   *    Windows: _msize()
-   */
-  PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
-
-#ifdef __cplusplus
-  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_new(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-
-#if @ac_cv_have_std_align_val_t@ && __cplusplus >= 201703L
-  PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t al,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t al,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t al,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-#endif
-}
-#endif
-
-/* We're only un-defining for public */
-#if !defined(GPERFTOOLS_CONFIG_H_)
-
-#undef PERFTOOLS_NOTHROW
-
-#endif /* GPERFTOOLS_CONFIG_H_ */
-
-#endif  /* #ifndef TCMALLOC_TCMALLOC_H_ */
diff --git a/third_party/tcmalloc/chromium/src/heap-checker-bcad.cc b/third_party/tcmalloc/chromium/src/heap-checker-bcad.cc
deleted file mode 100644
index e32bd818..0000000
--- a/third_party/tcmalloc/chromium/src/heap-checker-bcad.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Maxim Lifantsev
-//
-// A file to ensure that components of heap leak checker run before
-// all global object constructors and after all global object
-// destructors.
-//
-// This file must be the last library any binary links against.
-// Otherwise, the heap checker may not be able to run early enough to
-// catalog all the global objects in your program.  If this happens,
-// and later in the program you allocate memory and have one of these
-// "uncataloged" global objects point to it, the heap checker will
-// consider that allocation to be a leak, even though it's not (since
-// the allocated object is reachable from global data and hence "live").
-
-#include <gperftools/malloc_extension.h>
-#include "base/abort.h"
-
-// A dummy variable to refer from heap-checker.cc.  This is to make
-// sure this file is not optimized out by the linker.
-bool heap_leak_checker_bcad_variable;
-
-extern void HeapLeakChecker_AfterDestructors();  // in heap-checker.cc
-
-// A helper class to ensure that some components of heap leak checking
-// can happen before construction and after destruction
-// of all global/static objects.
-class HeapLeakCheckerGlobalPrePost {
- public:
-  HeapLeakCheckerGlobalPrePost() {
-    if (count_ == 0) {
-      // The 'new int' will ensure that we have run an initial malloc
-      // hook, which will set up the heap checker via
-      // MallocHook_InitAtFirstAllocation_HeapLeakChecker.  See malloc_hook.cc.
-      // This is done in this roundabout fashion in order to avoid self-deadlock
-      // if we directly called HeapLeakChecker_BeforeConstructors here.
-      delete new int;
-      // This needs to be called before the first allocation of an STL
-      // object, but after libc is done setting up threads (because it
-      // calls setenv, which requires a thread-aware errno).  By
-      // putting it here, we hope it's the first bit of code executed
-      // after the libc global-constructor code.
-      MallocExtension::Initialize();
-    }
-    ++count_;
-  }
-  ~HeapLeakCheckerGlobalPrePost() {
-    if (count_ <= 0)  tcmalloc::Abort();
-    --count_;
-    if (count_ == 0)  HeapLeakChecker_AfterDestructors();
-  }
- private:
-  // Counter of constructions/destructions of objects of this class
-  // (just in case there are more than one of them).
-  static int count_;
-};
-
-int HeapLeakCheckerGlobalPrePost::count_ = 0;
-
-// The early-construction/late-destruction global object.
-static const HeapLeakCheckerGlobalPrePost heap_leak_checker_global_pre_post;
diff --git a/third_party/tcmalloc/chromium/src/heap-checker.cc b/third_party/tcmalloc/chromium/src/heap-checker.cc
deleted file mode 100755
index 918194f2..0000000
--- a/third_party/tcmalloc/chromium/src/heap-checker.cc
+++ /dev/null
@@ -1,2389 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Maxim Lifantsev
-//
-
-#include "config.h"
-
-#include <fcntl.h>    // for O_RDONLY (we use syscall to do actual reads)
-#include <string.h>
-#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#ifdef HAVE_PTHREAD
-#include <pthread.h>
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <assert.h>
-
-#if defined(HAVE_LINUX_PTRACE_H)
-#include <linux/ptrace.h>
-#endif
-#ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#endif
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
-#include <wtypes.h>
-#include <winbase.h>
-#undef ERROR     // windows defines these as macros, which can cause trouble
-#undef max
-#undef min
-#endif
-
-#include <string>
-#include <vector>
-#include <map>
-#include <set>
-#include <algorithm>
-#include <functional>
-
-#include <gperftools/heap-checker.h>
-
-#include "base/basictypes.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include <gperftools/stacktrace.h>
-#include "base/commandlineflags.h"
-#include "base/elfcore.h"              // for i386_regs
-#include "base/thread_lister.h"
-#include "heap-profile-table.h"
-#include "base/low_level_alloc.h"
-#include "malloc_hook-inl.h"
-#include <gperftools/malloc_hook.h>
-#include <gperftools/malloc_extension.h>
-#include "maybe_threads.h"
-#include "memory_region_map.h"
-#include "base/spinlock.h"
-#include "base/sysinfo.h"
-#include "base/stl_allocator.h"
-
-using std::string;
-using std::basic_string;
-using std::pair;
-using std::map;
-using std::set;
-using std::vector;
-using std::swap;
-using std::make_pair;
-using std::min;
-using std::max;
-using std::less;
-using std::char_traits;
-
-// If current process is being ptrace()d, 'TracerPid' in /proc/self/status
-// will be non-zero.
-static bool IsDebuggerAttached(void) {    // only works under linux, probably
-  char buf[256];   // TracerPid comes relatively earlier in status output
-  int fd = open("/proc/self/status", O_RDONLY);
-  if (fd == -1) {
-    return false;  // Can't tell for sure.
-  }
-  const int len = read(fd, buf, sizeof(buf));
-  bool rc = false;
-  if (len > 0) {
-    const char *const kTracerPid = "TracerPid:\t";
-    buf[len - 1] = '\0';
-    const char *p = strstr(buf, kTracerPid);
-    if (p != NULL) {
-      rc = (strncmp(p + strlen(kTracerPid), "0\n", 2) != 0);
-    }
-  }
-  close(fd);
-  return rc;
-}
-
-// This is the default if you don't link in -lprofiler
-extern "C" {
-ATTRIBUTE_WEAK PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads();
-int ProfilingIsEnabledForAllThreads() { return false; }
-}
-
-//----------------------------------------------------------------------
-// Flags that control heap-checking
-//----------------------------------------------------------------------
-
-DEFINE_string(heap_check,
-              EnvToString("HEAPCHECK", ""),
-              "The heap leak checking to be done over the whole executable: "
-              "\"minimal\", \"normal\", \"strict\", "
-              "\"draconian\", \"as-is\", and \"local\" "
-              " or the empty string are the supported choices. "
-              "(See HeapLeakChecker_InternalInitStart for details.)");
-
-DEFINE_bool(heap_check_report, true, "Obsolete");
-
-DEFINE_bool(heap_check_before_constructors,
-            true,
-            "deprecated; pretty much always true now");
-
-DEFINE_bool(heap_check_after_destructors,
-            EnvToBool("HEAP_CHECK_AFTER_DESTRUCTORS", false),
-            "If overall heap check is to end after global destructors "
-            "or right after all REGISTER_HEAPCHECK_CLEANUP's");
-
-DEFINE_bool(heap_check_strict_check, true, "Obsolete");
-
-DEFINE_bool(heap_check_ignore_global_live,
-            EnvToBool("HEAP_CHECK_IGNORE_GLOBAL_LIVE", true),
-            "If overall heap check is to ignore heap objects reachable "
-            "from the global data");
-
-DEFINE_bool(heap_check_identify_leaks,
-            EnvToBool("HEAP_CHECK_IDENTIFY_LEAKS", false),
-            "If heap check should generate the addresses of the leaked "
-            "objects in the memory leak profiles.  This may be useful "
-            "in tracking down leaks where only a small fraction of "
-            "objects allocated at the same stack trace are leaked.");
-
-DEFINE_bool(heap_check_ignore_thread_live,
-            EnvToBool("HEAP_CHECK_IGNORE_THREAD_LIVE", true),
-            "If set to true, objects reachable from thread stacks "
-            "and registers are not reported as leaks");
-
-DEFINE_bool(heap_check_test_pointer_alignment,
-            EnvToBool("HEAP_CHECK_TEST_POINTER_ALIGNMENT", false),
-            "Set to true to check if the found leak can be due to "
-            "use of unaligned pointers");
-
-// Alignment at which all pointers in memory are supposed to be located;
-// use 1 if any alignment is ok.
-// heap_check_test_pointer_alignment flag guides if we try the value of 1.
-// The larger it can be, the lesser is the chance of missing real leaks.
-static const size_t kPointerSourceAlignment = sizeof(void*);
-DEFINE_int32(heap_check_pointer_source_alignment,
-	     EnvToInt("HEAP_CHECK_POINTER_SOURCE_ALIGNMENT",
-                      kPointerSourceAlignment),
-             "Alignment at which all pointers in memory are supposed to be "
-             "located.  Use 1 if any alignment is ok.");
-
-// A reasonable default to handle pointers inside of typical class objects:
-// Too low and we won't be able to traverse pointers to normally-used
-// nested objects and base parts of multiple-inherited objects.
-// Too high and it will both slow down leak checking (FindInsideAlloc
-// in HaveOnHeapLocked will get slower when there are large on-heap objects)
-// and make it probabilistically more likely to miss leaks
-// of large-sized objects.
-static const int64 kHeapCheckMaxPointerOffset = 1024;
-DEFINE_int64(heap_check_max_pointer_offset,
-	     EnvToInt("HEAP_CHECK_MAX_POINTER_OFFSET",
-                      kHeapCheckMaxPointerOffset),
-             "Largest pointer offset for which we traverse "
-             "pointers going inside of heap allocated objects. "
-             "Set to -1 to use the actual largest heap object size.");
-
-DEFINE_bool(heap_check_run_under_gdb,
-            EnvToBool("HEAP_CHECK_RUN_UNDER_GDB", false),
-            "If false, turns off heap-checking library when running under gdb "
-            "(normally, set to 'true' only when debugging the heap-checker)");
-
-DEFINE_int32(heap_check_delay_seconds, 0,
-             "Number of seconds to delay on-exit heap checking."
-             " If you set this flag,"
-             " you may also want to set exit_timeout_seconds in order to"
-             " avoid exit timeouts.\n"
-             "NOTE: This flag is to be used only to help diagnose issues"
-             " where it is suspected that the heap checker is reporting"
-             " false leaks that will disappear if the heap checker delays"
-             " its checks. Report any such issues to the heap-checker"
-             " maintainer(s).");
-
-//----------------------------------------------------------------------
-
-DEFINE_string(heap_profile_pprof,
-              EnvToString("PPROF_PATH", "pprof"),
-              "OBSOLETE; not used");
-
-DEFINE_string(heap_check_dump_directory,
-              EnvToString("HEAP_CHECK_DUMP_DIRECTORY", "/tmp"),
-              "Directory to put heap-checker leak dump information");
-
-
-//----------------------------------------------------------------------
-// HeapLeakChecker global data
-//----------------------------------------------------------------------
-
-// Global lock for all the global data of this module.
-static SpinLock heap_checker_lock(SpinLock::LINKER_INITIALIZED);
-
-//----------------------------------------------------------------------
-
-// Heap profile prefix for leak checking profiles.
-// Gets assigned once when leak checking is turned on, then never modified.
-static const string* profile_name_prefix = NULL;
-
-// Whole-program heap leak checker.
-// Gets assigned once when leak checking is turned on,
-// then main_heap_checker is never deleted.
-static HeapLeakChecker* main_heap_checker = NULL;
-
-// Whether we will use main_heap_checker to do a check at program exit
-// automatically. In any case user can ask for more checks on main_heap_checker
-// via GlobalChecker().
-static bool do_main_heap_check = false;
-
-// The heap profile we use to collect info about the heap.
-// This is created in HeapLeakChecker::BeforeConstructorsLocked
-// together with setting heap_checker_on (below) to true
-// and registering our new/delete malloc hooks;
-// similarly all are unset in HeapLeakChecker::TurnItselfOffLocked.
-static HeapProfileTable* heap_profile = NULL;
-
-// If we are doing (or going to do) any kind of heap-checking.
-static bool heap_checker_on = false;
-
-// pid of the process that does whole-program heap leak checking
-static pid_t heap_checker_pid = 0;
-
-// If we did heap profiling during global constructors execution
-static bool constructor_heap_profiling = false;
-
-// RAW_VLOG level we dump key INFO messages at.  If you want to turn
-// off these messages, set the environment variable PERFTOOLS_VERBOSE=-1.
-static const int heap_checker_info_level = 0;
-
-//----------------------------------------------------------------------
-// HeapLeakChecker's own memory allocator that is
-// independent of the normal program allocator.
-//----------------------------------------------------------------------
-
-// Wrapper of LowLevelAlloc for STL_Allocator and direct use.
-// We always access this class under held heap_checker_lock,
-// this allows us to in particular protect the period when threads are stopped
-// at random spots with TCMalloc_ListAllProcessThreads by heap_checker_lock,
-// w/o worrying about the lock in LowLevelAlloc::Arena.
-// We rely on the fact that we use an own arena with an own lock here.
-class HeapLeakChecker::Allocator {
- public:
-  static void Init() {
-    RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-    RAW_DCHECK(arena_ == NULL, "");
-    arena_ = LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
-  }
-  static void Shutdown() {
-    RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-    if (!LowLevelAlloc::DeleteArena(arena_)  ||  alloc_count_ != 0) {
-      RAW_LOG(FATAL, "Internal heap checker leak of %d objects", alloc_count_);
-    }
-  }
-  static int alloc_count() {
-    RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-    return alloc_count_;
-  }
-  static void* Allocate(size_t n) {
-    RAW_DCHECK(arena_  &&  heap_checker_lock.IsHeld(), "");
-    void* p = LowLevelAlloc::AllocWithArena(n, arena_);
-    if (p) alloc_count_ += 1;
-    return p;
-  }
-  static void Free(void* p) {
-    RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-    if (p) alloc_count_ -= 1;
-    LowLevelAlloc::Free(p);
-  }
-  static void Free(void* p, size_t /* n */) {
-    Free(p);
-  }
-  // destruct, free, and make *p to be NULL
-  template<typename T> static void DeleteAndNull(T** p) {
-    (*p)->~T();
-    Free(*p);
-    *p = NULL;
-  }
-  template<typename T> static void DeleteAndNullIfNot(T** p) {
-    if (*p != NULL) DeleteAndNull(p);
-  }
- private:
-  static LowLevelAlloc::Arena* arena_;
-  static int alloc_count_;
-};
-
-LowLevelAlloc::Arena* HeapLeakChecker::Allocator::arena_ = NULL;
-int HeapLeakChecker::Allocator::alloc_count_ = 0;
-
-//----------------------------------------------------------------------
-// HeapLeakChecker live object tracking components
-//----------------------------------------------------------------------
-
-// Cases of live object placement we distinguish
-enum ObjectPlacement {
-  MUST_BE_ON_HEAP,   // Must point to a live object of the matching size in the
-                     // heap_profile map of the heap when we get to it
-  IGNORED_ON_HEAP,   // Is a live (ignored) object on heap
-  MAYBE_LIVE,        // Is a piece of writable memory from /proc/self/maps
-  IN_GLOBAL_DATA,    // Is part of global data region of the executable
-  THREAD_DATA,       // Part of a thread stack and a thread descriptor with TLS
-  THREAD_REGISTERS,  // Values in registers of some thread
-};
-
-// Information about an allocated object
-struct AllocObject {
-  const void* ptr;        // the object
-  uintptr_t size;         // its size
-  ObjectPlacement place;  // where ptr points to
-
-  AllocObject(const void* p, size_t s, ObjectPlacement l)
-    : ptr(p), size(s), place(l) { }
-};
-
-// All objects (memory ranges) ignored via HeapLeakChecker::IgnoreObject
-// Key is the object's address; value is its size.
-typedef map<uintptr_t, size_t, less<uintptr_t>,
-            STL_Allocator<pair<const uintptr_t, size_t>,
-                          HeapLeakChecker::Allocator>
-           > IgnoredObjectsMap;
-static IgnoredObjectsMap* ignored_objects = NULL;
-
-// All objects (memory ranges) that we consider to be the sources of pointers
-// to live (not leaked) objects.
-// At different times this holds (what can be reached from) global data regions
-// and the objects we've been told to ignore.
-// For any AllocObject::ptr "live_objects" is supposed to contain at most one
-// record at any time. We maintain this by checking with the heap_profile map
-// of the heap and removing the live heap objects we've handled from it.
-// This vector is maintained as a stack and the frontier of reachable
-// live heap objects in our flood traversal of them.
-typedef vector<AllocObject,
-               STL_Allocator<AllocObject, HeapLeakChecker::Allocator>
-              > LiveObjectsStack;
-static LiveObjectsStack* live_objects = NULL;
-
-// A special string type that uses my allocator
-typedef basic_string<char, char_traits<char>,
-                     STL_Allocator<char, HeapLeakChecker::Allocator>
-                    > HCL_string;
-
-// A placeholder to fill-in the starting values for live_objects
-// for each library so we can keep the library-name association for logging.
-typedef map<HCL_string, LiveObjectsStack, less<HCL_string>,
-            STL_Allocator<pair<const HCL_string, LiveObjectsStack>,
-                          HeapLeakChecker::Allocator>
-           > LibraryLiveObjectsStacks;
-static LibraryLiveObjectsStacks* library_live_objects = NULL;
-
-// Value stored in the map of disabled address ranges;
-// its key is the end of the address range.
-// We'll ignore allocations with a return address in a disabled range
-// if the address occurs at 'max_depth' or less in the stack trace.
-struct HeapLeakChecker::RangeValue {
-  uintptr_t start_address;  // the start of the range
-  int       max_depth;      // the maximal stack depth to disable at
-};
-typedef map<uintptr_t, HeapLeakChecker::RangeValue, less<uintptr_t>,
-            STL_Allocator<pair<const uintptr_t, HeapLeakChecker::RangeValue>,
-                          HeapLeakChecker::Allocator>
-           > DisabledRangeMap;
-// The disabled program counter address ranges for profile dumping
-// that are registered with HeapLeakChecker::DisableChecksFromToLocked.
-static DisabledRangeMap* disabled_ranges = NULL;
-
-// Set of stack tops.
-// These are used to consider live only appropriate chunks of the memory areas
-// that are used for stacks (and maybe thread-specific data as well)
-// so that we do not treat pointers from outdated stack frames as live.
-typedef set<uintptr_t, less<uintptr_t>,
-            STL_Allocator<uintptr_t, HeapLeakChecker::Allocator>
-           > StackTopSet;
-static StackTopSet* stack_tops = NULL;
-
-// A map of ranges of code addresses for the system libraries
-// that can mmap/mremap/sbrk-allocate memory regions for stacks
-// and thread-local storage that we want to consider as live global data.
-// Maps from the end address to the start address.
-typedef map<uintptr_t, uintptr_t, less<uintptr_t>,
-            STL_Allocator<pair<const uintptr_t, uintptr_t>,
-                          HeapLeakChecker::Allocator>
-           > GlobalRegionCallerRangeMap;
-static GlobalRegionCallerRangeMap* global_region_caller_ranges = NULL;
-
-// TODO(maxim): make our big data structs into own modules
-
-// Disabler is implemented by keeping track of a per-thread count
-// of active Disabler objects.  Any objects allocated while the
-// count > 0 are not reported.
-
-#ifdef HAVE_TLS
-
-static __thread int thread_disable_counter
-// The "inital exec" model is faster than the default TLS model, at
-// the cost you can't dlopen this library.  But dlopen on heap-checker
-// doesn't work anyway -- it must run before main -- so this is a good
-// trade-off.
-# if defined(HAVE___ATTRIBUTE__) && \
-    !(defined(__GNUC__) && !defined(__clang__) && defined(__arm__))
-   __attribute__ ((tls_model ("initial-exec")))
-# endif
-    ;
-inline int get_thread_disable_counter() {
-  return thread_disable_counter;
-}
-inline void set_thread_disable_counter(int value) {
-  thread_disable_counter = value;
-}
-
-#else  // #ifdef HAVE_TLS
-
-static pthread_key_t thread_disable_counter_key;
-static int main_thread_counter;   // storage for use before main()
-static bool use_main_thread_counter = true;
-
-// TODO(csilvers): this is called from NewHook, in the middle of malloc().
-// If perftools_pthread_getspecific calls malloc, that will lead to an
-// infinite loop.  I don't know how to fix that, so I hope it never happens!
-inline int get_thread_disable_counter() {
-  if (use_main_thread_counter)  // means we're running really early
-    return main_thread_counter;
-  void* p = perftools_pthread_getspecific(thread_disable_counter_key);
-  return (intptr_t)p;   // kinda evil: store the counter directly in the void*
-}
-
-inline void set_thread_disable_counter(int value) {
-  if (use_main_thread_counter) {   // means we're running really early
-    main_thread_counter = value;
-    return;
-  }
-  intptr_t pointer_sized_value = value;
-  // kinda evil: store the counter directly in the void*
-  void* p = (void*)pointer_sized_value;
-  // NOTE: this may call malloc, which will call NewHook which will call
-  // get_thread_disable_counter() which will call pthread_getspecific().  I
-  // don't know if anything bad can happen if we call getspecific() in the
-  // middle of a setspecific() call.  It seems to work ok in practice...
-  perftools_pthread_setspecific(thread_disable_counter_key, p);
-}
-
-// The idea here is that this initializer will run pretty late: after
-// pthreads have been totally set up.  At this point we can call
-// pthreads routines, so we set those up.
-class InitThreadDisableCounter {
- public:
-  InitThreadDisableCounter() {
-    perftools_pthread_key_create(&thread_disable_counter_key, NULL);
-    // Set up the main thread's value, which we have a special variable for.
-    void* p = (void*)(intptr_t)main_thread_counter;   // store the counter directly
-    perftools_pthread_setspecific(thread_disable_counter_key, p);
-    use_main_thread_counter = false;
-  }
-};
-InitThreadDisableCounter init_thread_disable_counter;
-
-#endif  // #ifdef HAVE_TLS
-
-HeapLeakChecker::Disabler::Disabler() {
-  // It is faster to unconditionally increment the thread-local
-  // counter than to check whether or not heap-checking is on
-  // in a thread-safe manner.
-  int counter = get_thread_disable_counter();
-  set_thread_disable_counter(counter + 1);
-  RAW_VLOG(10, "Increasing thread disable counter to %d", counter + 1);
-}
-
-HeapLeakChecker::Disabler::~Disabler() {
-  int counter = get_thread_disable_counter();
-  RAW_DCHECK(counter > 0, "");
-  if (counter > 0) {
-    set_thread_disable_counter(counter - 1);
-    RAW_VLOG(10, "Decreasing thread disable counter to %d", counter);
-  } else {
-    RAW_VLOG(0, "Thread disable counter underflow : %d", counter);
-  }
-}
-
-//----------------------------------------------------------------------
-
-// The size of the largest heap object allocated so far.
-static size_t max_heap_object_size = 0;
-// The possible range of addresses that can point
-// into one of the elements of heap_objects.
-static uintptr_t min_heap_address = uintptr_t(-1LL);
-static uintptr_t max_heap_address = 0;
-
-//----------------------------------------------------------------------
-
-// Simple casting helpers for uintptr_t and void*:
-template<typename T>
-inline static const void* AsPtr(T addr) {
-  return reinterpret_cast<void*>(addr);
-}
-inline static uintptr_t AsInt(const void* ptr) {
-  return reinterpret_cast<uintptr_t>(ptr);
-}
-
-//----------------------------------------------------------------------
-
-// We've seen reports that strstr causes heap-checker crashes in some
-// libc's (?):
-//    http://code.google.com/p/gperftools/issues/detail?id=263
-// It's simple enough to use our own.  This is not in time-critical code.
-static const char* hc_strstr(const char* s1, const char* s2) {
-  const size_t len = strlen(s2);
-  RAW_CHECK(len > 0, "Unexpected empty string passed to strstr()");
-  for (const char* p = strchr(s1, *s2); p != NULL; p = strchr(p+1, *s2)) {
-    if (strncmp(p, s2, len) == 0) {
-      return p;
-    }
-  }
-  return NULL;
-}
-
-//----------------------------------------------------------------------
-
-// Our hooks for MallocHook
-static void NewHook(const void* ptr, size_t size) {
-  if (ptr != NULL) {
-    const int counter = get_thread_disable_counter();
-    const bool ignore = (counter > 0);
-    RAW_VLOG(16, "Recording Alloc: %p of %" PRIuS "; %d", ptr, size,
-             int(counter));
-
-    // Fetch the caller's stack trace before acquiring heap_checker_lock.
-    void* stack[HeapProfileTable::kMaxStackDepth];
-    int depth = HeapProfileTable::GetCallerStackTrace(0, stack);
-
-    { SpinLockHolder l(&heap_checker_lock);
-      if (size > max_heap_object_size) max_heap_object_size = size;
-      uintptr_t addr = AsInt(ptr);
-      if (addr < min_heap_address) min_heap_address = addr;
-      addr += size;
-      if (addr > max_heap_address) max_heap_address = addr;
-      if (heap_checker_on) {
-        heap_profile->RecordAlloc(ptr, size, depth, stack);
-        if (ignore) {
-          heap_profile->MarkAsIgnored(ptr);
-        }
-      }
-    }
-    RAW_VLOG(17, "Alloc Recorded: %p of %" PRIuS "", ptr, size);
-  }
-}
-
-static void DeleteHook(const void* ptr) {
-  if (ptr != NULL) {
-    RAW_VLOG(16, "Recording Free %p", ptr);
-    { SpinLockHolder l(&heap_checker_lock);
-      if (heap_checker_on) heap_profile->RecordFree(ptr);
-    }
-    RAW_VLOG(17, "Free Recorded: %p", ptr);
-  }
-}
-
-//----------------------------------------------------------------------
-
-enum StackDirection {
-  GROWS_TOWARDS_HIGH_ADDRESSES,
-  GROWS_TOWARDS_LOW_ADDRESSES,
-  UNKNOWN_DIRECTION
-};
-
-// Determine which way the stack grows:
-
-static StackDirection ATTRIBUTE_NOINLINE GetStackDirection(
-    const uintptr_t *const ptr) {
-  uintptr_t x;
-  if (&x < ptr)
-    return GROWS_TOWARDS_LOW_ADDRESSES;
-  if (ptr < &x)
-    return GROWS_TOWARDS_HIGH_ADDRESSES;
-
-  RAW_CHECK(0, "");  // Couldn't determine the stack direction.
-
-  return UNKNOWN_DIRECTION;
-}
-
-// Direction of stack growth (will initialize via GetStackDirection())
-static StackDirection stack_direction = UNKNOWN_DIRECTION;
-
-// This routine is called for every thread stack we know about to register it.
-static void RegisterStackLocked(const void* top_ptr) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_DCHECK(MemoryRegionMap::LockIsHeld(), "");
-  RAW_VLOG(10, "Thread stack at %p", top_ptr);
-  uintptr_t top = AsInt(top_ptr);
-  stack_tops->insert(top);  // add for later use
-
-  // make sure stack_direction is initialized
-  if (stack_direction == UNKNOWN_DIRECTION) {
-    stack_direction = GetStackDirection(&top);
-  }
-
-  // Find memory region with this stack
-  MemoryRegionMap::Region region;
-  if (MemoryRegionMap::FindAndMarkStackRegion(top, &region)) {
-    // Make the proper portion of the stack live:
-    if (stack_direction == GROWS_TOWARDS_LOW_ADDRESSES) {
-      RAW_VLOG(11, "Live stack at %p of %" PRIuPTR " bytes",
-                  top_ptr, region.end_addr - top);
-      live_objects->push_back(AllocObject(top_ptr, region.end_addr - top,
-                                          THREAD_DATA));
-    } else {  // GROWS_TOWARDS_HIGH_ADDRESSES
-      RAW_VLOG(11, "Live stack at %p of %" PRIuPTR " bytes",
-                  AsPtr(region.start_addr),
-                  top - region.start_addr);
-      live_objects->push_back(AllocObject(AsPtr(region.start_addr),
-                                          top - region.start_addr,
-                                          THREAD_DATA));
-    }
-  // not in MemoryRegionMap, look in library_live_objects:
-  } else if (FLAGS_heap_check_ignore_global_live) {
-    for (LibraryLiveObjectsStacks::iterator lib = library_live_objects->begin();
-         lib != library_live_objects->end(); ++lib) {
-      for (LiveObjectsStack::iterator span = lib->second.begin();
-           span != lib->second.end(); ++span) {
-        uintptr_t start = AsInt(span->ptr);
-        uintptr_t end = start + span->size;
-        if (start <= top  &&  top < end) {
-          RAW_VLOG(11, "Stack at %p is inside /proc/self/maps chunk %p..%p",
-                      top_ptr, AsPtr(start), AsPtr(end));
-          // Shrink start..end region by chopping away the memory regions in
-          // MemoryRegionMap that land in it to undo merging of regions
-          // in /proc/self/maps, so that we correctly identify what portion
-          // of start..end is actually the stack region.
-          uintptr_t stack_start = start;
-          uintptr_t stack_end = end;
-          // can optimize-away this loop, but it does not run often
-          RAW_DCHECK(MemoryRegionMap::LockIsHeld(), "");
-          for (MemoryRegionMap::RegionIterator r =
-                 MemoryRegionMap::BeginRegionLocked();
-               r != MemoryRegionMap::EndRegionLocked(); ++r) {
-            if (top < r->start_addr  &&  r->start_addr < stack_end) {
-              stack_end = r->start_addr;
-            }
-            if (stack_start < r->end_addr  &&  r->end_addr <= top) {
-              stack_start = r->end_addr;
-            }
-          }
-          if (stack_start != start  ||  stack_end != end) {
-            RAW_VLOG(11, "Stack at %p is actually inside memory chunk %p..%p",
-                        top_ptr, AsPtr(stack_start), AsPtr(stack_end));
-          }
-          // Make the proper portion of the stack live:
-          if (stack_direction == GROWS_TOWARDS_LOW_ADDRESSES) {
-            RAW_VLOG(11, "Live stack at %p of %" PRIuPTR " bytes",
-                        top_ptr, stack_end - top);
-            live_objects->push_back(
-              AllocObject(top_ptr, stack_end - top, THREAD_DATA));
-          } else {  // GROWS_TOWARDS_HIGH_ADDRESSES
-            RAW_VLOG(11, "Live stack at %p of %" PRIuPTR " bytes",
-                        AsPtr(stack_start), top - stack_start);
-            live_objects->push_back(
-              AllocObject(AsPtr(stack_start), top - stack_start, THREAD_DATA));
-          }
-          lib->second.erase(span);  // kill the rest of the region
-          // Put the non-stack part(s) of the region back:
-          if (stack_start != start) {
-            lib->second.push_back(AllocObject(AsPtr(start), stack_start - start,
-                                  MAYBE_LIVE));
-          }
-          if (stack_end != end) {
-            lib->second.push_back(AllocObject(AsPtr(stack_end), end - stack_end,
-                                  MAYBE_LIVE));
-          }
-          return;
-        }
-      }
-    }
-    RAW_LOG(ERROR, "Memory region for stack at %p not found. "
-                   "Will likely report false leak positives.", top_ptr);
-  }
-}
-
-// Iterator for heap allocation map data to make ignored objects "live"
-// (i.e., treated as roots for the mark-and-sweep phase)
-static void MakeIgnoredObjectsLiveCallbackLocked(
-    const void* ptr, const HeapProfileTable::AllocInfo& info) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  if (info.ignored) {
-    live_objects->push_back(AllocObject(ptr, info.object_size,
-                                        MUST_BE_ON_HEAP));
-  }
-}
-
-// Iterator for heap allocation map data to make objects allocated from
-// disabled regions of code to be live.
-static void MakeDisabledLiveCallbackLocked(
-    const void* ptr, const HeapProfileTable::AllocInfo& info) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  bool stack_disable = false;
-  bool range_disable = false;
-  for (int depth = 0; depth < info.stack_depth; depth++) {
-    uintptr_t addr = AsInt(info.call_stack[depth]);
-    if (disabled_ranges) {
-      DisabledRangeMap::const_iterator iter
-        = disabled_ranges->upper_bound(addr);
-      if (iter != disabled_ranges->end()) {
-        RAW_DCHECK(iter->first > addr, "");
-        if (iter->second.start_address < addr  &&
-            iter->second.max_depth > depth) {
-          range_disable = true;  // in range; dropping
-          break;
-        }
-      }
-    }
-  }
-  if (stack_disable || range_disable) {
-    uintptr_t start_address = AsInt(ptr);
-    uintptr_t end_address = start_address + info.object_size;
-    StackTopSet::const_iterator iter
-      = stack_tops->lower_bound(start_address);
-    if (iter != stack_tops->end()) {
-      RAW_DCHECK(*iter >= start_address, "");
-      if (*iter < end_address) {
-        // We do not disable (treat as live) whole allocated regions
-        // if they are used to hold thread call stacks
-        // (i.e. when we find a stack inside).
-        // The reason is that we'll treat as live the currently used
-        // stack portions anyway (see RegisterStackLocked),
-        // and the rest of the region where the stack lives can well
-        // contain outdated stack variables which are not live anymore,
-        // hence should not be treated as such.
-        RAW_VLOG(11, "Not %s-disabling %" PRIuS " bytes at %p"
-                    ": have stack inside: %p",
-                    (stack_disable ? "stack" : "range"),
-                    info.object_size, ptr, AsPtr(*iter));
-        return;
-      }
-    }
-    RAW_VLOG(11, "%s-disabling %" PRIuS " bytes at %p",
-                (stack_disable ? "Stack" : "Range"), info.object_size, ptr);
-    live_objects->push_back(AllocObject(ptr, info.object_size,
-                                        MUST_BE_ON_HEAP));
-  }
-}
-
-static const char kUnnamedProcSelfMapEntry[] = "UNNAMED";
-
-// This function takes some fields from a /proc/self/maps line:
-//
-//   start_address  start address of a memory region.
-//   end_address    end address of a memory region
-//   permissions    rwx + private/shared bit
-//   filename       filename of the mapped file
-//
-// If the region is not writeable, then it cannot have any heap
-// pointers in it, otherwise we record it as a candidate live region
-// to get filtered later.
-static void RecordGlobalDataLocked(uintptr_t start_address,
-                                   uintptr_t end_address,
-                                   const char* permissions,
-                                   const char* filename) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  // Ignore non-writeable regions.
-  if (strchr(permissions, 'w') == NULL) return;
-  if (filename == NULL  ||  *filename == '\0') {
-    filename = kUnnamedProcSelfMapEntry;
-  }
-  RAW_VLOG(11, "Looking into %s: 0x%" PRIxPTR "..0x%" PRIxPTR,
-              filename, start_address, end_address);
-  (*library_live_objects)[filename].
-    push_back(AllocObject(AsPtr(start_address),
-                          end_address - start_address,
-                          MAYBE_LIVE));
-}
-
-// See if 'library' from /proc/self/maps has base name 'library_base'
-// i.e. contains it and has '.' or '-' after it.
-static bool IsLibraryNamed(const char* library, const char* library_base) {
-  const char* p = hc_strstr(library, library_base);
-  size_t sz = strlen(library_base);
-  return p != NULL  &&  (p[sz] == '.'  ||  p[sz] == '-');
-}
-
-// static
-void HeapLeakChecker::DisableLibraryAllocsLocked(const char* library,
-                                                 uintptr_t start_address,
-                                                 uintptr_t end_address) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  int depth = 0;
-  // TODO(maxim): maybe this should be extended to also use objdump
-  //              and pick the text portion of the library more precisely.
-  if (IsLibraryNamed(library, "/libpthread")  ||
-        // libpthread has a lot of small "system" leaks we don't care about.
-        // In particular it allocates memory to store data supplied via
-        // pthread_setspecific (which can be the only pointer to a heap object).
-      IsLibraryNamed(library, "/libdl")  ||
-        // library loaders leak some "system" heap that we don't care about
-      IsLibraryNamed(library, "/libcrypto")  ||
-        // Sometimes libcrypto of OpenSSH is compiled with -fomit-frame-pointer
-        // (any library can be, of course, but this one often is because speed
-        // is so important for making crypto usable).  We ignore all its
-        // allocations because we can't see the call stacks.  We'd prefer
-        // to ignore allocations done in files/symbols that match
-        // "default_malloc_ex|default_realloc_ex"
-        // but that doesn't work when the end-result binary is stripped.
-      IsLibraryNamed(library, "/libjvm")  ||
-        // JVM has a lot of leaks we don't care about.
-      IsLibraryNamed(library, "/libzip")
-        // The JVM leaks java.util.zip.Inflater after loading classes.
-     ) {
-    depth = 1;  // only disable allocation calls directly from the library code
-  } else if (IsLibraryNamed(library, "/ld")
-               // library loader leaks some "system" heap
-               // (e.g. thread-local storage) that we don't care about
-            ) {
-    depth = 2;  // disable allocation calls directly from the library code
-                // and at depth 2 from it.
-    // We need depth 2 here solely because of a libc bug that
-    // forces us to jump through __memalign_hook and MemalignOverride hoops
-    // in tcmalloc.cc.
-    // Those buggy __libc_memalign() calls are in ld-linux.so and happen for
-    // thread-local storage allocations that we want to ignore here.
-    // We go with the depth-2 hack as a workaround for this libc bug:
-    // otherwise we'd need to extend MallocHook interface
-    // so that correct stack depth adjustment can be propagated from
-    // the exceptional case of MemalignOverride.
-    // Using depth 2 here should not mask real leaks because ld-linux.so
-    // does not call user code.
-  }
-  if (depth) {
-    RAW_VLOG(10, "Disabling allocations from %s at depth %d:", library, depth);
-    DisableChecksFromToLocked(AsPtr(start_address), AsPtr(end_address), depth);
-    if (IsLibraryNamed(library, "/libpthread")  ||
-        IsLibraryNamed(library, "/libdl")  ||
-        IsLibraryNamed(library, "/ld")) {
-      RAW_VLOG(10, "Global memory regions made by %s will be live data",
-                  library);
-      if (global_region_caller_ranges == NULL) {
-        global_region_caller_ranges =
-          new(Allocator::Allocate(sizeof(GlobalRegionCallerRangeMap)))
-            GlobalRegionCallerRangeMap;
-      }
-      global_region_caller_ranges
-        ->insert(make_pair(end_address, start_address));
-    }
-  }
-}
-
-// static
-HeapLeakChecker::ProcMapsResult HeapLeakChecker::UseProcMapsLocked(
-                                  ProcMapsTask proc_maps_task) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  // Need to provide own scratch memory to ProcMapsIterator:
-  ProcMapsIterator::Buffer buffer;
-  ProcMapsIterator it(0, &buffer);
-  if (!it.Valid()) {
-    int errsv = errno;
-    RAW_LOG(ERROR, "Could not open /proc/self/maps: errno=%d. "
-                   "Libraries will not be handled correctly.", errsv);
-    return CANT_OPEN_PROC_MAPS;
-  }
-  uint64 start_address, end_address, file_offset;
-  int64 inode;
-  char *permissions, *filename;
-  bool saw_shared_lib = false;
-  bool saw_nonzero_inode = false;
-  bool saw_shared_lib_with_nonzero_inode = false;
-  while (it.Next(&start_address, &end_address, &permissions,
-                 &file_offset, &inode, &filename)) {
-    if (start_address >= end_address) {
-      // Warn if a line we can be interested in is ill-formed:
-      if (inode != 0) {
-        RAW_LOG(ERROR, "Errors reading /proc/self/maps. "
-                       "Some global memory regions will not "
-                       "be handled correctly.");
-      }
-      // Silently skip other ill-formed lines: some are possible
-      // probably due to the interplay of how /proc/self/maps is updated
-      // while we read it in chunks in ProcMapsIterator and
-      // do things in this loop.
-      continue;
-    }
-    // Determine if any shared libraries are present (this is the same
-    // list of extensions as is found in pprof).  We want to ignore
-    // 'fake' libraries with inode 0 when determining.  However, some
-    // systems don't share inodes via /proc, so we turn off this check
-    // if we don't see any evidence that we're getting inode info.
-    if (inode != 0) {
-      saw_nonzero_inode = true;
-    }
-    if ((hc_strstr(filename, "lib") && hc_strstr(filename, ".so")) ||
-        hc_strstr(filename, ".dll") ||
-        // not all .dylib filenames start with lib. .dylib is big enough
-        // that we are unlikely to get false matches just checking that.
-        hc_strstr(filename, ".dylib") || hc_strstr(filename, ".bundle")) {
-      saw_shared_lib = true;
-      if (inode != 0) {
-        saw_shared_lib_with_nonzero_inode = true;
-      }
-    }
-
-    switch (proc_maps_task) {
-      case DISABLE_LIBRARY_ALLOCS:
-        // All lines starting like
-        // "401dc000-4030f000 r??p 00132000 03:01 13991972  lib/bin"
-        // identify a data and code sections of a shared library or our binary
-        if (inode != 0 && strncmp(permissions, "r-xp", 4) == 0) {
-          DisableLibraryAllocsLocked(filename, start_address, end_address);
-        }
-        break;
-      case RECORD_GLOBAL_DATA:
-        RecordGlobalDataLocked(start_address, end_address,
-                               permissions, filename);
-        break;
-      default:
-        RAW_CHECK(0, "");
-    }
-  }
-  // If /proc/self/maps is reporting inodes properly (we saw a
-  // non-zero inode), then we only say we saw a shared lib if we saw a
-  // 'real' one, with a non-zero inode.
-  if (saw_nonzero_inode) {
-    saw_shared_lib = saw_shared_lib_with_nonzero_inode;
-  }
-  if (!saw_shared_lib) {
-    RAW_LOG(ERROR, "No shared libs detected. Will likely report false leak "
-                   "positives for statically linked executables.");
-    return NO_SHARED_LIBS_IN_PROC_MAPS;
-  }
-  return PROC_MAPS_USED;
-}
-
-// Total number and size of live objects dropped from the profile;
-// (re)initialized in IgnoreAllLiveObjectsLocked.
-static int64 live_objects_total;
-static int64 live_bytes_total;
-
-// pid of the thread that is doing the current leak check
-// (protected by our lock; IgnoreAllLiveObjectsLocked sets it)
-static pid_t self_thread_pid = 0;
-
-// Status of our thread listing callback execution
-// (protected by our lock; used from within IgnoreAllLiveObjectsLocked)
-static enum {
-  CALLBACK_NOT_STARTED,
-  CALLBACK_STARTED,
-  CALLBACK_COMPLETED,
-} thread_listing_status = CALLBACK_NOT_STARTED;
-
-// Ideally to avoid deadlocks this function should not result in any libc
-// or other function calls that might need to lock a mutex:
-// It is called when all threads of a process are stopped
-// at arbitrary points thus potentially holding those locks.
-//
-// In practice we are calling some simple i/o and sprintf-type library functions
-// for logging messages, but use only our own LowLevelAlloc::Arena allocator.
-//
-// This is known to be buggy: the library i/o function calls are able to cause
-// deadlocks when they request a lock that a stopped thread happens to hold.
-// This issue as far as we know have so far not resulted in any deadlocks
-// in practice, so for now we are taking our chance that the deadlocks
-// have insignificant frequency.
-//
-// If such deadlocks become a problem we should make the i/o calls
-// into appropriately direct system calls (or eliminate them),
-// in particular write() is not safe and vsnprintf() is potentially dangerous
-// due to reliance on locale functions (these are called through RAW_LOG
-// and in other ways).
-//
-
-#if defined(HAVE_LINUX_PTRACE_H) && defined(HAVE_SYS_SYSCALL_H) && defined(DUMPER)
-# if (defined(__i386__) || defined(__x86_64))
-#  define THREAD_REGS i386_regs
-# elif defined(__PPC__)
-#  define THREAD_REGS ppc_regs
-# endif
-#endif
-
-/*static*/ int HeapLeakChecker::IgnoreLiveThreadsLocked(void* parameter,
-                                                        int num_threads,
-                                                        pid_t* thread_pids,
-                                                        va_list /*ap*/) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  thread_listing_status = CALLBACK_STARTED;
-  RAW_VLOG(11, "Found %d threads (from pid %d)", num_threads, getpid());
-
-  if (FLAGS_heap_check_ignore_global_live) {
-    UseProcMapsLocked(RECORD_GLOBAL_DATA);
-  }
-
-  // We put the registers from other threads here
-  // to make pointers stored in them live.
-  vector<void*, STL_Allocator<void*, Allocator> > thread_registers;
-
-  int failures = 0;
-  for (int i = 0; i < num_threads; ++i) {
-    // the leak checking thread itself is handled
-    // specially via self_thread_stack, not here:
-    if (thread_pids[i] == self_thread_pid) continue;
-    RAW_VLOG(11, "Handling thread with pid %d", thread_pids[i]);
-#ifdef THREAD_REGS
-    THREAD_REGS thread_regs;
-#define sys_ptrace(r, p, a, d)  syscall(SYS_ptrace, (r), (p), (a), (d))
-    // We use sys_ptrace to avoid thread locking
-    // because this is called from TCMalloc_ListAllProcessThreads
-    // when all but this thread are suspended.
-    if (sys_ptrace(PTRACE_GETREGS, thread_pids[i], NULL, &thread_regs) == 0) {
-      // Need to use SP to get all the data from the very last stack frame:
-      COMPILE_ASSERT(sizeof(thread_regs.SP) == sizeof(void*),
-                     SP_register_does_not_look_like_a_pointer);
-      RegisterStackLocked(reinterpret_cast<void*>(thread_regs.SP));
-      // Make registers live (just in case PTRACE_ATTACH resulted in some
-      // register pointers still being in the registers and not on the stack):
-      for (void** p = reinterpret_cast<void**>(&thread_regs);
-           p < reinterpret_cast<void**>(&thread_regs + 1); ++p) {
-        RAW_VLOG(12, "Thread register %p", *p);
-        thread_registers.push_back(*p);
-      }
-    } else {
-      failures += 1;
-    }
-#else
-    failures += 1;
-#endif
-  }
-  // Use all the collected thread (stack) liveness sources:
-  IgnoreLiveObjectsLocked("threads stack data", "");
-  if (thread_registers.size()) {
-    // Make thread registers be live heap data sources.
-    // we rely here on the fact that vector is in one memory chunk:
-    RAW_VLOG(11, "Live registers at %p of %" PRIuS " bytes",
-                &thread_registers[0], thread_registers.size() * sizeof(void*));
-    live_objects->push_back(AllocObject(&thread_registers[0],
-                                        thread_registers.size() * sizeof(void*),
-                                        THREAD_REGISTERS));
-    IgnoreLiveObjectsLocked("threads register data", "");
-  }
-  // Do all other liveness walking while all threads are stopped:
-  IgnoreNonThreadLiveObjectsLocked();
-  // Can now resume the threads:
-  TCMalloc_ResumeAllProcessThreads(num_threads, thread_pids);
-  thread_listing_status = CALLBACK_COMPLETED;
-  return failures;
-}
-
-// Stack top of the thread that is doing the current leak check
-// (protected by our lock; IgnoreAllLiveObjectsLocked sets it)
-static const void* self_thread_stack_top;
-
-// static
-void HeapLeakChecker::IgnoreNonThreadLiveObjectsLocked() {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_DCHECK(MemoryRegionMap::LockIsHeld(), "");
-  RAW_VLOG(11, "Handling self thread with pid %d", self_thread_pid);
-  // Register our own stack:
-
-  // Important that all stack ranges (including the one here)
-  // are known before we start looking at them
-  // in MakeDisabledLiveCallbackLocked:
-  RegisterStackLocked(self_thread_stack_top);
-  IgnoreLiveObjectsLocked("stack data", "");
-
-  // Make objects we were told to ignore live:
-  if (ignored_objects) {
-    for (IgnoredObjectsMap::const_iterator object = ignored_objects->begin();
-         object != ignored_objects->end(); ++object) {
-      const void* ptr = AsPtr(object->first);
-      RAW_VLOG(11, "Ignored live object at %p of %" PRIuS " bytes",
-                  ptr, object->second);
-      live_objects->
-        push_back(AllocObject(ptr, object->second, MUST_BE_ON_HEAP));
-      // we do this liveness check for ignored_objects before doing any
-      // live heap walking to make sure it does not fail needlessly:
-      size_t object_size;
-      if (!(heap_profile->FindAlloc(ptr, &object_size)  &&
-            object->second == object_size)) {
-        RAW_LOG(FATAL, "Object at %p of %" PRIuS " bytes from an"
-                       " IgnoreObject() has disappeared", ptr, object->second);
-      }
-    }
-    IgnoreLiveObjectsLocked("ignored objects", "");
-  }
-
-  // Treat objects that were allocated when a Disabler was live as
-  // roots.  I.e., if X was allocated while a Disabler was active,
-  // and Y is reachable from X, arrange that neither X nor Y are
-  // treated as leaks.
-  heap_profile->IterateAllocs(MakeIgnoredObjectsLiveCallbackLocked);
-  IgnoreLiveObjectsLocked("disabled objects", "");
-
-  // Make code-address-disabled objects live and ignored:
-  // This in particular makes all thread-specific data live
-  // because the basic data structure to hold pointers to thread-specific data
-  // is allocated from libpthreads and we have range-disabled that
-  // library code with UseProcMapsLocked(DISABLE_LIBRARY_ALLOCS);
-  // so now we declare all thread-specific data reachable from there as live.
-  heap_profile->IterateAllocs(MakeDisabledLiveCallbackLocked);
-  IgnoreLiveObjectsLocked("disabled code", "");
-
-  // Actually make global data live:
-  if (FLAGS_heap_check_ignore_global_live) {
-    bool have_null_region_callers = false;
-    for (LibraryLiveObjectsStacks::iterator l = library_live_objects->begin();
-         l != library_live_objects->end(); ++l) {
-      RAW_CHECK(live_objects->empty(), "");
-      // Process library_live_objects in l->second
-      // filtering them by MemoryRegionMap:
-      // It's safe to iterate over MemoryRegionMap
-      // w/o locks here as we are inside MemoryRegionMap::Lock():
-      RAW_DCHECK(MemoryRegionMap::LockIsHeld(), "");
-      // The only change to MemoryRegionMap possible in this loop
-      // is region addition as a result of allocating more memory
-      // for live_objects. This won't invalidate the RegionIterator
-      // or the intent of the loop.
-      // --see the comment by MemoryRegionMap::BeginRegionLocked().
-      for (MemoryRegionMap::RegionIterator region =
-             MemoryRegionMap::BeginRegionLocked();
-           region != MemoryRegionMap::EndRegionLocked(); ++region) {
-        // "region" from MemoryRegionMap is to be subtracted from
-        // (tentatively live) regions in l->second
-        // if it has a stack inside or it was allocated by
-        // a non-special caller (not one covered by a range
-        // in global_region_caller_ranges).
-        // This will in particular exclude all memory chunks used
-        // by the heap itself as well as what's been allocated with
-        // any allocator on top of mmap.
-        bool subtract = true;
-        if (!region->is_stack  &&  global_region_caller_ranges) {
-          if (region->caller() == static_cast<uintptr_t>(NULL)) {
-            have_null_region_callers = true;
-          } else {
-            GlobalRegionCallerRangeMap::const_iterator iter
-              = global_region_caller_ranges->upper_bound(region->caller());
-            if (iter != global_region_caller_ranges->end()) {
-              RAW_DCHECK(iter->first > region->caller(), "");
-              if (iter->second < region->caller()) {  // in special region
-                subtract = false;
-              }
-            }
-          }
-        }
-        if (subtract) {
-          // The loop puts the result of filtering l->second into live_objects:
-          for (LiveObjectsStack::const_iterator i = l->second.begin();
-               i != l->second.end(); ++i) {
-            // subtract *region from *i
-            uintptr_t start = AsInt(i->ptr);
-            uintptr_t end = start + i->size;
-            if (region->start_addr <= start  &&  end <= region->end_addr) {
-              // full deletion due to subsumption
-            } else if (start < region->start_addr  &&
-                       region->end_addr < end) {  // cutting-out split
-              live_objects->push_back(AllocObject(i->ptr,
-                                                  region->start_addr - start,
-                                                  IN_GLOBAL_DATA));
-              live_objects->push_back(AllocObject(AsPtr(region->end_addr),
-                                                  end - region->end_addr,
-                                                  IN_GLOBAL_DATA));
-            } else if (region->end_addr > start  &&
-                       region->start_addr <= start) {  // cut from start
-              live_objects->push_back(AllocObject(AsPtr(region->end_addr),
-                                                  end - region->end_addr,
-                                                  IN_GLOBAL_DATA));
-            } else if (region->start_addr > start  &&
-                       region->start_addr < end) {  // cut from end
-              live_objects->push_back(AllocObject(i->ptr,
-                                                  region->start_addr - start,
-                                                  IN_GLOBAL_DATA));
-            } else {  // pass: no intersection
-              live_objects->push_back(AllocObject(i->ptr, i->size,
-                                                  IN_GLOBAL_DATA));
-            }
-          }
-          // Move live_objects back into l->second
-          // for filtering by the next region.
-          live_objects->swap(l->second);
-          live_objects->clear();
-        }
-      }
-      // Now get and use live_objects from the final version of l->second:
-      if (VLOG_IS_ON(11)) {
-        for (LiveObjectsStack::const_iterator i = l->second.begin();
-             i != l->second.end(); ++i) {
-          RAW_VLOG(11, "Library live region at %p of %" PRIuPTR " bytes",
-                      i->ptr, i->size);
-        }
-      }
-      live_objects->swap(l->second);
-      IgnoreLiveObjectsLocked("in globals of\n  ", l->first.c_str());
-    }
-    if (have_null_region_callers) {
-      RAW_LOG(ERROR, "Have memory regions w/o callers: "
-                     "might report false leaks");
-    }
-    Allocator::DeleteAndNull(&library_live_objects);
-  }
-}
-
-// Callback for TCMalloc_ListAllProcessThreads in IgnoreAllLiveObjectsLocked below
-// to test/verify that we have just the one main thread, in which case
-// we can do everything in that main thread,
-// so that CPU profiler can collect all its samples.
-// Returns the number of threads in the process.
-static int IsOneThread(void* parameter, int num_threads,
-                       pid_t* thread_pids, va_list ap) {
-  if (num_threads != 1) {
-    RAW_LOG(WARNING, "Have threads: Won't CPU-profile the bulk of leak "
-                     "checking work happening in IgnoreLiveThreadsLocked!");
-  }
-  TCMalloc_ResumeAllProcessThreads(num_threads, thread_pids);
-  return num_threads;
-}
-
-// Dummy for IgnoreAllLiveObjectsLocked below.
-// Making it global helps with compiler warnings.
-static va_list dummy_ap;
-
-// static
-void HeapLeakChecker::IgnoreAllLiveObjectsLocked(const void* self_stack_top) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_CHECK(live_objects == NULL, "");
-  live_objects = new(Allocator::Allocate(sizeof(LiveObjectsStack)))
-                   LiveObjectsStack;
-  stack_tops = new(Allocator::Allocate(sizeof(StackTopSet))) StackTopSet;
-  // reset the counts
-  live_objects_total = 0;
-  live_bytes_total = 0;
-  // Reduce max_heap_object_size to FLAGS_heap_check_max_pointer_offset
-  // for the time of leak check.
-  // FLAGS_heap_check_max_pointer_offset caps max_heap_object_size
-  // to manage reasonably low chances of random bytes
-  // appearing to be pointing into large actually leaked heap objects.
-  const size_t old_max_heap_object_size = max_heap_object_size;
-  max_heap_object_size = (
-    FLAGS_heap_check_max_pointer_offset != -1
-    ? min(size_t(FLAGS_heap_check_max_pointer_offset), max_heap_object_size)
-    : max_heap_object_size);
-  // Record global data as live:
-  if (FLAGS_heap_check_ignore_global_live) {
-    library_live_objects =
-      new(Allocator::Allocate(sizeof(LibraryLiveObjectsStacks)))
-        LibraryLiveObjectsStacks;
-  }
-  // Ignore all thread stacks:
-  thread_listing_status = CALLBACK_NOT_STARTED;
-  bool need_to_ignore_non_thread_objects = true;
-  self_thread_pid = getpid();
-  self_thread_stack_top = self_stack_top;
-  if (FLAGS_heap_check_ignore_thread_live) {
-    // In case we are doing CPU profiling we'd like to do all the work
-    // in the main thread, not in the special thread created by
-    // TCMalloc_ListAllProcessThreads, so that CPU profiler can
-    // collect all its samples.  The machinery of
-    // TCMalloc_ListAllProcessThreads conflicts with the CPU profiler
-    // by also relying on signals and ::sigaction.  We can do this
-    // (run everything in the main thread) safely only if there's just
-    // the main thread itself in our process.  This variable reflects
-    // these two conditions:
-    bool want_and_can_run_in_main_thread =
-      ProfilingIsEnabledForAllThreads()  &&
-      TCMalloc_ListAllProcessThreads(NULL, IsOneThread) == 1;
-    // When the normal path of TCMalloc_ListAllProcessThreads below is taken,
-    // we fully suspend the threads right here before any liveness checking
-    // and keep them suspended for the whole time of liveness checking
-    // inside of the IgnoreLiveThreadsLocked callback.
-    // (The threads can't (de)allocate due to lock on the delete hook but
-    //  if not suspended they could still mess with the pointer
-    //  graph while we walk it).
-    int r = want_and_can_run_in_main_thread
-            ? IgnoreLiveThreadsLocked(NULL, 1, &self_thread_pid, dummy_ap)
-            : TCMalloc_ListAllProcessThreads(NULL, IgnoreLiveThreadsLocked);
-    need_to_ignore_non_thread_objects = r < 0;
-    if (r < 0) {
-      RAW_LOG(WARNING, "Thread finding failed with %d errno=%d", r, errno);
-      if (thread_listing_status == CALLBACK_COMPLETED) {
-        RAW_LOG(INFO, "Thread finding callback "
-                      "finished ok; hopefully everything is fine");
-        need_to_ignore_non_thread_objects = false;
-      } else if (thread_listing_status == CALLBACK_STARTED) {
-        RAW_LOG(FATAL, "Thread finding callback was "
-                       "interrupted or crashed; can't fix this");
-      } else {  // CALLBACK_NOT_STARTED
-        RAW_LOG(ERROR, "Could not find thread stacks. "
-                       "Will likely report false leak positives.");
-      }
-    } else if (r != 0) {
-      RAW_LOG(ERROR, "Thread stacks not found for %d threads. "
-                     "Will likely report false leak positives.", r);
-    } else {
-      RAW_VLOG(11, "Thread stacks appear to be found for all threads");
-    }
-  } else {
-    RAW_LOG(WARNING, "Not looking for thread stacks; "
-                     "objects reachable only from there "
-                     "will be reported as leaks");
-  }
-  // Do all other live data ignoring here if we did not do it
-  // within thread listing callback with all threads stopped.
-  if (need_to_ignore_non_thread_objects) {
-    if (FLAGS_heap_check_ignore_global_live) {
-      UseProcMapsLocked(RECORD_GLOBAL_DATA);
-    }
-    IgnoreNonThreadLiveObjectsLocked();
-  }
-  if (live_objects_total) {
-    RAW_VLOG(10, "Ignoring %" PRId64 " reachable objects of %" PRId64 " bytes",
-                live_objects_total, live_bytes_total);
-  }
-  // Free these: we made them here and heap_profile never saw them
-  Allocator::DeleteAndNull(&live_objects);
-  Allocator::DeleteAndNull(&stack_tops);
-  max_heap_object_size = old_max_heap_object_size;  // reset this var
-}
-
-// Alignment at which we should consider pointer positions
-// in IgnoreLiveObjectsLocked. Will normally use the value of
-// FLAGS_heap_check_pointer_source_alignment.
-static size_t pointer_source_alignment = kPointerSourceAlignment;
-// Global lock for HeapLeakChecker::DoNoLeaks
-// to protect pointer_source_alignment.
-static SpinLock alignment_checker_lock(SpinLock::LINKER_INITIALIZED);
-
-// This function changes the live bits in the heap_profile-table's state:
-// we only record the live objects to be skipped.
-//
-// When checking if a byte sequence points to a heap object we use
-// HeapProfileTable::FindInsideAlloc to handle both pointers to
-// the start and inside of heap-allocated objects.
-// The "inside" case needs to be checked to support
-// at least the following relatively common cases:
-// - C++ arrays allocated with new FooClass[size] for classes
-//   with destructors have their size recorded in a sizeof(int) field
-//   before the place normal pointers point to.
-// - basic_string<>-s for e.g. the C++ library of gcc 3.4
-//   have the meta-info in basic_string<...>::_Rep recorded
-//   before the place normal pointers point to.
-// - Multiple-inherited objects have their pointers when cast to
-//   different base classes pointing inside of the actually
-//   allocated object.
-// - Sometimes reachability pointers point to member objects of heap objects,
-//   and then those member objects point to the full heap object.
-// - Third party UnicodeString: it stores a 32-bit refcount
-//   (in both 32-bit and 64-bit binaries) as the first uint32
-//   in the allocated memory and a normal pointer points at
-//   the second uint32 behind the refcount.
-// By finding these additional objects here
-// we slightly increase the chance to mistake random memory bytes
-// for a pointer and miss a leak in a particular run of a binary.
-//
-/*static*/ void HeapLeakChecker::IgnoreLiveObjectsLocked(const char* name,
-                                                         const char* name2) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  int64 live_object_count = 0;
-  int64 live_byte_count = 0;
-  while (!live_objects->empty()) {
-    const char* object =
-      reinterpret_cast<const char*>(live_objects->back().ptr);
-    size_t size = live_objects->back().size;
-    const ObjectPlacement place = live_objects->back().place;
-    live_objects->pop_back();
-    if (place == MUST_BE_ON_HEAP  &&  heap_profile->MarkAsLive(object)) {
-      live_object_count += 1;
-      live_byte_count += size;
-    }
-    RAW_VLOG(13, "Looking for heap pointers in %p of %" PRIuS " bytes",
-                object, size);
-    const char* const whole_object = object;
-    size_t const whole_size = size;
-    // Try interpretting any byte sequence in object,size as a heap pointer:
-    const size_t remainder = AsInt(object) % pointer_source_alignment;
-    if (remainder) {
-      object += pointer_source_alignment - remainder;
-      if (size >= pointer_source_alignment - remainder) {
-        size -= pointer_source_alignment - remainder;
-      } else {
-        size = 0;
-      }
-    }
-    if (size < sizeof(void*)) continue;
-
-#ifdef NO_FRAME_POINTER
-    // Frame pointer omission requires us to use libunwind, which uses direct
-    // mmap and munmap system calls, and that needs special handling.
-    if (name2 == kUnnamedProcSelfMapEntry) {
-      static const uintptr_t page_mask = ~(getpagesize() - 1);
-      const uintptr_t addr = reinterpret_cast<uintptr_t>(object);
-      if ((addr & page_mask) == 0 && (size & page_mask) == 0) {
-        // This is an object we slurped from /proc/self/maps.
-        // It may or may not be readable at this point.
-        //
-        // In case all the above conditions made a mistake, and the object is
-        // not related to libunwind, we also verify that it's not readable
-        // before ignoring it.
-        if (msync(const_cast<char*>(object), size, MS_ASYNC) != 0) {
-          // Skip unreadable object, so we don't crash trying to sweep it.
-          RAW_VLOG(0, "Ignoring inaccessible object [%p, %p) "
-                   "(msync error %d (%s))",
-                   object, object + size, errno, strerror(errno));
-          continue;
-        }
-      }
-    }
-#endif
-
-    const char* const max_object = object + size - sizeof(void*);
-    while (object <= max_object) {
-      // potentially unaligned load:
-      const uintptr_t addr = *reinterpret_cast<const uintptr_t*>(object);
-      // Do fast check before the more expensive HaveOnHeapLocked lookup:
-      // this code runs for all memory words that are potentially pointers:
-      const bool can_be_on_heap =
-        // Order tests by the likelyhood of the test failing in 64/32 bit modes.
-        // Yes, this matters: we either lose 5..6% speed in 32 bit mode
-        // (which is already slower) or by a factor of 1.5..1.91 in 64 bit mode.
-        // After the alignment test got dropped the above performance figures
-        // must have changed; might need to revisit this.
-#if defined(__x86_64__)
-        addr <= max_heap_address  &&  // <= is for 0-sized object with max addr
-        min_heap_address <= addr;
-#else
-        min_heap_address <= addr  &&
-        addr <= max_heap_address;  // <= is for 0-sized object with max addr
-#endif
-      if (can_be_on_heap) {
-        const void* ptr = reinterpret_cast<const void*>(addr);
-        // Too expensive (inner loop): manually uncomment when debugging:
-        // RAW_VLOG(17, "Trying pointer to %p at %p", ptr, object);
-        size_t object_size;
-        if (HaveOnHeapLocked(&ptr, &object_size)  &&
-            heap_profile->MarkAsLive(ptr)) {
-          // We take the (hopefully low) risk here of encountering by accident
-          // a byte sequence in memory that matches an address of
-          // a heap object which is in fact leaked.
-          // I.e. in very rare and probably not repeatable/lasting cases
-          // we might miss some real heap memory leaks.
-          RAW_VLOG(14, "Found pointer to %p of %" PRIuS " bytes at %p "
-                      "inside %p of size %" PRIuS "",
-                      ptr, object_size, object, whole_object, whole_size);
-          if (VLOG_IS_ON(15)) {
-            // log call stacks to help debug how come something is not a leak
-            HeapProfileTable::AllocInfo alloc;
-            if (!heap_profile->FindAllocDetails(ptr, &alloc)) {
-              RAW_LOG(FATAL, "FindAllocDetails failed on ptr %p", ptr);
-            }
-            RAW_LOG(INFO, "New live %p object's alloc stack:", ptr);
-            for (int i = 0; i < alloc.stack_depth; ++i) {
-              RAW_LOG(INFO, "  @ %p", alloc.call_stack[i]);
-            }
-          }
-          live_object_count += 1;
-          live_byte_count += object_size;
-          live_objects->push_back(AllocObject(ptr, object_size,
-                                              IGNORED_ON_HEAP));
-        }
-      }
-      object += pointer_source_alignment;
-    }
-  }
-  live_objects_total += live_object_count;
-  live_bytes_total += live_byte_count;
-  if (live_object_count) {
-    RAW_VLOG(10, "Removed %" PRId64 " live heap objects of %" PRId64 " bytes: %s%s",
-                live_object_count, live_byte_count, name, name2);
-  }
-}
-
-//----------------------------------------------------------------------
-// HeapLeakChecker leak check disabling components
-//----------------------------------------------------------------------
-
-// static
-void HeapLeakChecker::DisableChecksIn(const char* pattern) {
-  RAW_LOG(WARNING, "DisableChecksIn(%s) is ignored", pattern);
-}
-
-// static
-void HeapLeakChecker::DoIgnoreObject(const void* ptr) {
-  SpinLockHolder l(&heap_checker_lock);
-  if (!heap_checker_on) return;
-  size_t object_size;
-  if (!HaveOnHeapLocked(&ptr, &object_size)) {
-    RAW_LOG(ERROR, "No live heap object at %p to ignore", ptr);
-  } else {
-    RAW_VLOG(10, "Going to ignore live object at %p of %" PRIuS " bytes",
-                ptr, object_size);
-    if (ignored_objects == NULL)  {
-      ignored_objects = new(Allocator::Allocate(sizeof(IgnoredObjectsMap)))
-                          IgnoredObjectsMap;
-    }
-    if (!ignored_objects->insert(make_pair(AsInt(ptr), object_size)).second) {
-      RAW_LOG(WARNING, "Object at %p is already being ignored", ptr);
-    }
-  }
-}
-
-// static
-void HeapLeakChecker::UnIgnoreObject(const void* ptr) {
-  SpinLockHolder l(&heap_checker_lock);
-  if (!heap_checker_on) return;
-  size_t object_size;
-  if (!HaveOnHeapLocked(&ptr, &object_size)) {
-    RAW_LOG(FATAL, "No live heap object at %p to un-ignore", ptr);
-  } else {
-    bool found = false;
-    if (ignored_objects) {
-      IgnoredObjectsMap::iterator object = ignored_objects->find(AsInt(ptr));
-      if (object != ignored_objects->end()  &&  object_size == object->second) {
-        ignored_objects->erase(object);
-        found = true;
-        RAW_VLOG(10, "Now not going to ignore live object "
-                    "at %p of %" PRIuS " bytes", ptr, object_size);
-      }
-    }
-    if (!found)  RAW_LOG(FATAL, "Object at %p has not been ignored", ptr);
-  }
-}
-
-//----------------------------------------------------------------------
-// HeapLeakChecker non-static functions
-//----------------------------------------------------------------------
-
-char* HeapLeakChecker::MakeProfileNameLocked() {
-  RAW_DCHECK(lock_->IsHeld(), "");
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  const int len = profile_name_prefix->size() + strlen(name_) + 5 +
-                  strlen(HeapProfileTable::kFileExt) + 1;
-  char* file_name = reinterpret_cast<char*>(Allocator::Allocate(len));
-  snprintf(file_name, len, "%s.%s-end%s",
-           profile_name_prefix->c_str(), name_,
-           HeapProfileTable::kFileExt);
-  return file_name;
-}
-
-void HeapLeakChecker::Create(const char *name, bool make_start_snapshot) {
-  SpinLockHolder l(lock_);
-  name_ = NULL;  // checker is inactive
-  start_snapshot_ = NULL;
-  has_checked_ = false;
-  inuse_bytes_increase_ = 0;
-  inuse_allocs_increase_ = 0;
-  keep_profiles_ = false;
-  char* n = new char[strlen(name) + 1];   // do this before we lock
-  IgnoreObject(n);  // otherwise it might be treated as live due to our stack
-  { // Heap activity in other threads is paused for this whole scope.
-    SpinLockHolder al(&alignment_checker_lock);
-    SpinLockHolder hl(&heap_checker_lock);
-    MemoryRegionMap::LockHolder ml;
-    if (heap_checker_on  &&  profile_name_prefix != NULL) {
-      RAW_DCHECK(strchr(name, '/') == NULL, "must be a simple name");
-      memcpy(n, name, strlen(name) + 1);
-      name_ = n;  // checker is active
-      if (make_start_snapshot) {
-        start_snapshot_ = heap_profile->TakeSnapshot();
-      }
-
-      const HeapProfileTable::Stats& t = heap_profile->total();
-      const size_t start_inuse_bytes = t.alloc_size - t.free_size;
-      const size_t start_inuse_allocs = t.allocs - t.frees;
-      RAW_VLOG(10, "Start check \"%s\" profile: %" PRIuS " bytes "
-               "in %" PRIuS " objects",
-               name_, start_inuse_bytes, start_inuse_allocs);
-    } else {
-      RAW_LOG(WARNING, "Heap checker is not active, "
-                       "hence checker \"%s\" will do nothing!", name);
-    RAW_LOG(WARNING, "To activate set the HEAPCHECK environment variable.\n");
-    }
-  }
-  if (name_ == NULL) {
-    UnIgnoreObject(n);
-    delete[] n;  // must be done after we unlock
-  }
-}
-
-HeapLeakChecker::HeapLeakChecker(const char *name) : lock_(new SpinLock) {
-  RAW_DCHECK(strcmp(name, "_main_") != 0, "_main_ is reserved");
-  Create(name, true/*create start_snapshot_*/);
-}
-
-HeapLeakChecker::HeapLeakChecker() : lock_(new SpinLock) {
-  if (FLAGS_heap_check_before_constructors) {
-    // We want to check for leaks of objects allocated during global
-    // constructors (i.e., objects allocated already).  So we do not
-    // create a baseline snapshot and hence check for leaks of objects
-    // that may have already been created.
-    Create("_main_", false);
-  } else {
-    // We want to ignore leaks of objects allocated during global
-    // constructors (i.e., objects allocated already).  So we snapshot
-    // the current heap contents and use them as a baseline that is
-    // not reported by the leak checker.
-    Create("_main_", true);
-  }
-}
-
-ssize_t HeapLeakChecker::BytesLeaked() const {
-  SpinLockHolder l(lock_);
-  if (!has_checked_) {
-    RAW_LOG(FATAL, "*NoLeaks|SameHeap must execute before this call");
-  }
-  return inuse_bytes_increase_;
-}
-
-ssize_t HeapLeakChecker::ObjectsLeaked() const {
-  SpinLockHolder l(lock_);
-  if (!has_checked_) {
-    RAW_LOG(FATAL, "*NoLeaks|SameHeap must execute before this call");
-  }
-  return inuse_allocs_increase_;
-}
-
-// Save pid of main thread for using in naming dump files
-static int32 main_thread_pid = getpid();
-#ifdef HAVE_PROGRAM_INVOCATION_NAME
-#ifdef __UCLIBC__
-extern const char* program_invocation_name;
-extern const char* program_invocation_short_name;
-#else
-extern char* program_invocation_name;
-extern char* program_invocation_short_name;
-#endif
-static const char* invocation_name() { return program_invocation_short_name; }
-static string invocation_path() { return program_invocation_name; }
-#else
-static const char* invocation_name() { return "<your binary>"; }
-static string invocation_path() { return "<your binary>"; }
-#endif
-
-// Prints commands that users can run to get more information
-// about the reported leaks.
-static void SuggestPprofCommand(const char* pprof_file_arg) {
-  // Extra help information to print for the user when the test is
-  // being run in a way where the straightforward pprof command will
-  // not suffice.
-  string extra_help;
-
-  // Common header info to print for remote runs
-  const string remote_header =
-      "This program is being executed remotely and therefore the pprof\n"
-      "command printed above will not work.  Either run this program\n"
-      "locally, or adjust the pprof command as follows to allow it to\n"
-      "work on your local machine:\n";
-
-  // Extra command for fetching remote data
-  string fetch_cmd;
-
-  RAW_LOG(WARNING,
-          "\n\n"
-          "If the preceding stack traces are not enough to find "
-          "the leaks, try running THIS shell command:\n\n"
-          "%s%s %s \"%s\" --inuse_objects --lines --heapcheck "
-          " --edgefraction=1e-10 --nodefraction=1e-10 --gv\n"
-          "\n"
-          "%s"
-          "If you are still puzzled about why the leaks are "
-          "there, try rerunning this program with "
-          "HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with "
-          "HEAP_CHECK_MAX_POINTER_OFFSET=-1\n"
-          "If the leak report occurs in a small fraction of runs, "
-          "try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB "
-          "or with TCMALLOC_RECLAIM_MEMORY=false, "  // only works for debugalloc
-          "it might help find leaks more repeatably\n",
-          fetch_cmd.c_str(),
-          "pprof",           // works as long as pprof is on your path
-          invocation_path().c_str(),
-          pprof_file_arg,
-          extra_help.c_str()
-          );
-}
-
-bool HeapLeakChecker::DoNoLeaks(ShouldSymbolize should_symbolize) {
-  SpinLockHolder l(lock_);
-  // The locking also helps us keep the messages
-  // for the two checks close together.
-  SpinLockHolder al(&alignment_checker_lock);
-
-  // thread-safe: protected by alignment_checker_lock
-  static bool have_disabled_hooks_for_symbolize = false;
-  // Once we've checked for leaks and symbolized the results once, it's
-  // not safe to do it again.  This is because in order to symbolize
-  // safely, we had to disable all the malloc hooks here, so we no
-  // longer can be confident we've collected all the data we need.
-  if (have_disabled_hooks_for_symbolize) {
-    RAW_LOG(FATAL, "Must not call heap leak checker manually after "
-            " program-exit's automatic check.");
-  }
-
-  HeapProfileTable::Snapshot* leaks = NULL;
-  char* pprof_file = NULL;
-
-  {
-    // Heap activity in other threads is paused during this function
-    // (i.e. until we got all profile difference info).
-    SpinLockHolder hl(&heap_checker_lock);
-    if (heap_checker_on == false) {
-      if (name_ != NULL) {  // leak checking enabled when created the checker
-        RAW_LOG(WARNING, "Heap leak checker got turned off after checker "
-                "\"%s\" has been created, no leak check is being done for it!",
-                name_);
-      }
-      return true;
-    }
-
-    // Update global_region_caller_ranges. They may need to change since
-    // e.g. initialization because shared libraries might have been loaded or
-    // unloaded.
-    Allocator::DeleteAndNullIfNot(&global_region_caller_ranges);
-    ProcMapsResult pm_result = UseProcMapsLocked(DISABLE_LIBRARY_ALLOCS);
-    RAW_CHECK(pm_result == PROC_MAPS_USED, "");
-
-    // Keep track of number of internally allocated objects so we
-    // can detect leaks in the heap-leak-checket itself
-    const int initial_allocs = Allocator::alloc_count();
-
-    if (name_ == NULL) {
-      RAW_LOG(FATAL, "Heap leak checker must not be turned on "
-              "after construction of a HeapLeakChecker");
-    }
-
-    MemoryRegionMap::LockHolder ml;
-    int a_local_var;  // Use our stack ptr to make stack data live:
-
-    // Make the heap profile, other threads are locked out.
-    HeapProfileTable::Snapshot* base =
-        reinterpret_cast<HeapProfileTable::Snapshot*>(start_snapshot_);
-    RAW_DCHECK(FLAGS_heap_check_pointer_source_alignment > 0, "");
-    pointer_source_alignment = FLAGS_heap_check_pointer_source_alignment;
-    IgnoreAllLiveObjectsLocked(&a_local_var);
-    leaks = heap_profile->NonLiveSnapshot(base);
-
-    inuse_bytes_increase_ = static_cast<ssize_t>(leaks->total().alloc_size);
-    inuse_allocs_increase_ = static_cast<ssize_t>(leaks->total().allocs);
-    if (leaks->Empty()) {
-      heap_profile->ReleaseSnapshot(leaks);
-      leaks = NULL;
-
-      // We can only check for internal leaks along the no-user-leak
-      // path since in the leak path we temporarily release
-      // heap_checker_lock and another thread can come in and disturb
-      // allocation counts.
-      if (Allocator::alloc_count() != initial_allocs) {
-        RAW_LOG(FATAL, "Internal HeapChecker leak of %d objects ; %d -> %d",
-                Allocator::alloc_count() - initial_allocs,
-                initial_allocs, Allocator::alloc_count());
-      }
-    } else if (FLAGS_heap_check_test_pointer_alignment) {
-      if (pointer_source_alignment == 1) {
-        RAW_LOG(WARNING, "--heap_check_test_pointer_alignment has no effect: "
-                "--heap_check_pointer_source_alignment was already set to 1");
-      } else {
-        // Try with reduced pointer aligment
-        pointer_source_alignment = 1;
-        IgnoreAllLiveObjectsLocked(&a_local_var);
-        HeapProfileTable::Snapshot* leaks_wo_align =
-            heap_profile->NonLiveSnapshot(base);
-        pointer_source_alignment = FLAGS_heap_check_pointer_source_alignment;
-        if (leaks_wo_align->Empty()) {
-          RAW_LOG(WARNING, "Found no leaks without pointer alignment: "
-                  "something might be placing pointers at "
-                  "unaligned addresses! This needs to be fixed.");
-        } else {
-          RAW_LOG(INFO, "Found leaks without pointer alignment as well: "
-                  "unaligned pointers must not be the cause of leaks.");
-          RAW_LOG(INFO, "--heap_check_test_pointer_alignment did not help "
-                  "to diagnose the leaks.");
-        }
-        heap_profile->ReleaseSnapshot(leaks_wo_align);
-      }
-    }
-
-    if (leaks != NULL) {
-      pprof_file = MakeProfileNameLocked();
-    }
-  }
-
-  has_checked_ = true;
-  if (leaks == NULL) {
-    if (FLAGS_heap_check_max_pointer_offset == -1) {
-      RAW_LOG(WARNING,
-              "Found no leaks without max_pointer_offset restriction: "
-              "it's possible that the default value of "
-              "heap_check_max_pointer_offset flag is too low. "
-              "Do you use pointers with larger than that offsets "
-              "pointing in the middle of heap-allocated objects?");
-    }
-    const HeapProfileTable::Stats& stats = heap_profile->total();
-    RAW_VLOG(heap_checker_info_level,
-             "No leaks found for check \"%s\" "
-             "(but no 100%% guarantee that there aren't any): "
-             "found %" PRId64 " reachable heap objects of %" PRId64 " bytes",
-             name_,
-             int64(stats.allocs - stats.frees),
-             int64(stats.alloc_size - stats.free_size));
-  } else {
-    if (should_symbolize == SYMBOLIZE) {
-      // To turn addresses into symbols, we need to fork, which is a
-      // problem if both parent and child end up trying to call the
-      // same malloc-hooks we've set up, at the same time.  To avoid
-      // trouble, we turn off the hooks before symbolizing.  Note that
-      // this makes it unsafe to ever leak-report again!  Luckily, we
-      // typically only want to report once in a program's run, at the
-      // very end.
-      if (MallocHook::GetNewHook() == NewHook)
-        MallocHook::SetNewHook(NULL);
-      if (MallocHook::GetDeleteHook() == DeleteHook)
-        MallocHook::SetDeleteHook(NULL);
-      MemoryRegionMap::Shutdown();
-      // Make sure all the hooks really got unset:
-      RAW_CHECK(MallocHook::GetNewHook() == NULL, "");
-      RAW_CHECK(MallocHook::GetDeleteHook() == NULL, "");
-      RAW_CHECK(MallocHook::GetMmapHook() == NULL, "");
-      RAW_CHECK(MallocHook::GetSbrkHook() == NULL, "");
-      have_disabled_hooks_for_symbolize = true;
-      leaks->ReportLeaks(name_, pprof_file, true);  // true = should_symbolize
-    } else {
-      leaks->ReportLeaks(name_, pprof_file, false);
-    }
-    if (FLAGS_heap_check_identify_leaks) {
-      leaks->ReportIndividualObjects();
-    }
-
-    SuggestPprofCommand(pprof_file);
-
-    {
-      SpinLockHolder hl(&heap_checker_lock);
-      heap_profile->ReleaseSnapshot(leaks);
-      Allocator::Free(pprof_file);
-    }
-  }
-
-  return (leaks == NULL);
-}
-
-HeapLeakChecker::~HeapLeakChecker() {
-  if (name_ != NULL) {  // had leak checking enabled when created the checker
-    if (!has_checked_) {
-      RAW_LOG(FATAL, "Some *NoLeaks|SameHeap method"
-                     " must be called on any created HeapLeakChecker");
-    }
-
-    // Deallocate any snapshot taken at start
-    if (start_snapshot_ != NULL) {
-      SpinLockHolder l(&heap_checker_lock);
-      heap_profile->ReleaseSnapshot(
-          reinterpret_cast<HeapProfileTable::Snapshot*>(start_snapshot_));
-    }
-
-    UnIgnoreObject(name_);
-    delete[] name_;
-    name_ = NULL;
-  }
-  delete lock_;
-}
-
-//----------------------------------------------------------------------
-// HeapLeakChecker overall heap check components
-//----------------------------------------------------------------------
-
-// static
-bool HeapLeakChecker::IsActive() {
-  SpinLockHolder l(&heap_checker_lock);
-  return heap_checker_on;
-}
-
-vector<HeapCleaner::void_function>* HeapCleaner::heap_cleanups_ = NULL;
-
-// When a HeapCleaner object is intialized, add its function to the static list
-// of cleaners to be run before leaks checking.
-HeapCleaner::HeapCleaner(void_function f) {
-  if (heap_cleanups_ == NULL)
-    heap_cleanups_ = new vector<HeapCleaner::void_function>;
-  heap_cleanups_->push_back(f);
-}
-
-// Run all of the cleanup functions and delete the vector.
-void HeapCleaner::RunHeapCleanups() {
-  if (!heap_cleanups_)
-    return;
-  for (int i = 0; i < heap_cleanups_->size(); i++) {
-    void (*f)(void) = (*heap_cleanups_)[i];
-    f();
-  }
-  delete heap_cleanups_;
-  heap_cleanups_ = NULL;
-}
-
-// Program exit heap cleanup registered as a module object destructor.
-// Will not get executed when we crash on a signal.
-//
-void HeapLeakChecker_RunHeapCleanups() {
-  if (FLAGS_heap_check == "local")   // don't check heap in this mode
-    return;
-  { SpinLockHolder l(&heap_checker_lock);
-    // can get here (via forks?) with other pids
-    if (heap_checker_pid != getpid()) return;
-  }
-  HeapCleaner::RunHeapCleanups();
-  if (!FLAGS_heap_check_after_destructors) HeapLeakChecker::DoMainHeapCheck();
-}
-
-static bool internal_init_start_has_run = false;
-
-// Called exactly once, before main() (but hopefully just before).
-// This picks a good unique name for the dumped leak checking heap profiles.
-//
-// Because we crash when InternalInitStart is called more than once,
-// it's fine that we hold heap_checker_lock only around pieces of
-// this function: this is still enough for thread-safety w.r.t. other functions
-// of this module.
-// We can't hold heap_checker_lock throughout because it would deadlock
-// on a memory allocation since our new/delete hooks can be on.
-//
-void HeapLeakChecker_InternalInitStart() {
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_CHECK(!internal_init_start_has_run,
-              "Heap-check constructor called twice.  Perhaps you both linked"
-              " in the heap checker, and also used LD_PRELOAD to load it?");
-    internal_init_start_has_run = true;
-
-#ifdef ADDRESS_SANITIZER
-    // AddressSanitizer's custom malloc conflicts with HeapChecker.
-    FLAGS_heap_check = "";
-#endif
-
-    if (FLAGS_heap_check.empty()) {
-      // turns out we do not need checking in the end; can stop profiling
-      HeapLeakChecker::TurnItselfOffLocked();
-      return;
-    } else if (RunningOnValgrind()) {
-      // There is no point in trying -- we'll just fail.
-      RAW_LOG(WARNING, "Can't run under Valgrind; will turn itself off");
-      HeapLeakChecker::TurnItselfOffLocked();
-      return;
-    }
-  }
-
-  // Changing this to false can be useful when debugging heap-checker itself:
-  if (!FLAGS_heap_check_run_under_gdb && IsDebuggerAttached()) {
-    RAW_LOG(WARNING, "Someone is ptrace()ing us; will turn itself off");
-    SpinLockHolder l(&heap_checker_lock);
-    HeapLeakChecker::TurnItselfOffLocked();
-    return;
-  }
-
-  { SpinLockHolder l(&heap_checker_lock);
-    if (!constructor_heap_profiling) {
-      RAW_LOG(FATAL, "Can not start so late. You have to enable heap checking "
-	             "with HEAPCHECK=<mode>.");
-    }
-  }
-
-  // Set all flags
-  RAW_DCHECK(FLAGS_heap_check_pointer_source_alignment > 0, "");
-  if (FLAGS_heap_check == "minimal") {
-    // The least we can check.
-    FLAGS_heap_check_before_constructors = false;  // from after main
-                                                   // (ignore more)
-    FLAGS_heap_check_after_destructors = false;  // to after cleanup
-                                                 // (most data is live)
-    FLAGS_heap_check_ignore_thread_live = true;  // ignore all live
-    FLAGS_heap_check_ignore_global_live = true;  // ignore all live
-  } else if (FLAGS_heap_check == "normal") {
-    // Faster than 'minimal' and not much stricter.
-    FLAGS_heap_check_before_constructors = true;  // from no profile (fast)
-    FLAGS_heap_check_after_destructors = false;  // to after cleanup
-                                                 // (most data is live)
-    FLAGS_heap_check_ignore_thread_live = true;  // ignore all live
-    FLAGS_heap_check_ignore_global_live = true;  // ignore all live
-  } else if (FLAGS_heap_check == "strict") {
-    // A bit stricter than 'normal': global destructors must fully clean up
-    // after themselves if they are present.
-    FLAGS_heap_check_before_constructors = true;  // from no profile (fast)
-    FLAGS_heap_check_after_destructors = true;  // to after destructors
-                                                // (less data live)
-    FLAGS_heap_check_ignore_thread_live = true;  // ignore all live
-    FLAGS_heap_check_ignore_global_live = true;  // ignore all live
-  } else if (FLAGS_heap_check == "draconian") {
-    // Drop not very portable and not very exact live heap flooding.
-    FLAGS_heap_check_before_constructors = true;  // from no profile (fast)
-    FLAGS_heap_check_after_destructors = true;  // to after destructors
-                                                // (need them)
-    FLAGS_heap_check_ignore_thread_live = false;  // no live flood (stricter)
-    FLAGS_heap_check_ignore_global_live = false;  // no live flood (stricter)
-  } else if (FLAGS_heap_check == "as-is") {
-    // do nothing: use other flags as is
-  } else if (FLAGS_heap_check == "local") {
-    // do nothing
-  } else {
-    RAW_LOG(FATAL, "Unsupported heap_check flag: %s",
-                   FLAGS_heap_check.c_str());
-  }
-  // FreeBSD doesn't seem to honor atexit execution order:
-  //    http://code.google.com/p/gperftools/issues/detail?id=375
-  // Since heap-checking before destructors depends on atexit running
-  // at the right time, on FreeBSD we always check after, even in the
-  // less strict modes.  This just means FreeBSD is always a bit
-  // stricter in its checking than other OSes.
-  // This now appears to be the case in other OSes as well;
-  // so always check afterwards.
-  FLAGS_heap_check_after_destructors = true;
-
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_DCHECK(heap_checker_pid == getpid(), "");
-    heap_checker_on = true;
-    RAW_DCHECK(heap_profile, "");
-    HeapLeakChecker::ProcMapsResult pm_result = HeapLeakChecker::UseProcMapsLocked(HeapLeakChecker::DISABLE_LIBRARY_ALLOCS);
-      // might neeed to do this more than once
-      // if one later dynamically loads libraries that we want disabled
-    if (pm_result != HeapLeakChecker::PROC_MAPS_USED) {  // can't function
-      HeapLeakChecker::TurnItselfOffLocked();
-      return;
-    }
-  }
-
-  // make a good place and name for heap profile leak dumps
-  string* profile_prefix =
-    new string(FLAGS_heap_check_dump_directory + "/" + invocation_name());
-
-  // Finalize prefix for dumping leak checking profiles.
-  const int32 our_pid = getpid();   // safest to call getpid() outside lock
-  { SpinLockHolder l(&heap_checker_lock);
-    // main_thread_pid might still be 0 if this function is being called before
-    // global constructors.  In that case, our pid *is* the main pid.
-    if (main_thread_pid == 0)
-      main_thread_pid = our_pid;
-  }
-  char pid_buf[15];
-  snprintf(pid_buf, sizeof(pid_buf), ".%d", main_thread_pid);
-  *profile_prefix += pid_buf;
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_DCHECK(profile_name_prefix == NULL, "");
-    profile_name_prefix = profile_prefix;
-  }
-
-  // Make sure new/delete hooks are installed properly
-  // and heap profiler is indeed able to keep track
-  // of the objects being allocated.
-  // We test this to make sure we are indeed checking for leaks.
-  char* test_str = new char[5];
-  size_t size;
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_CHECK(heap_profile->FindAlloc(test_str, &size),
-              "our own new/delete not linked?");
-  }
-  delete[] test_str;
-  { SpinLockHolder l(&heap_checker_lock);
-    // This check can fail when it should not if another thread allocates
-    // into this same spot right this moment,
-    // which is unlikely since this code runs in InitGoogle.
-    RAW_CHECK(!heap_profile->FindAlloc(test_str, &size),
-              "our own new/delete not linked?");
-  }
-  // If we crash in the above code, it probably means that
-  // "nm <this_binary> | grep new" will show that tcmalloc's new/delete
-  // implementation did not get linked-in into this binary
-  // (i.e. nm will list __builtin_new and __builtin_vec_new as undefined).
-  // If this happens, it is a BUILD bug to be fixed.
-
-  RAW_VLOG(heap_checker_info_level,
-           "WARNING: Perftools heap leak checker is active "
-           "-- Performance may suffer");
-
-  if (FLAGS_heap_check != "local") {
-    HeapLeakChecker* main_hc = new HeapLeakChecker();
-    SpinLockHolder l(&heap_checker_lock);
-    RAW_DCHECK(main_heap_checker == NULL,
-               "Repeated creation of main_heap_checker");
-    main_heap_checker = main_hc;
-    do_main_heap_check = true;
-  }
-
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_CHECK(heap_checker_on  &&  constructor_heap_profiling,
-              "Leak checking is expected to be fully turned on now");
-  }
-
-  // For binaries built in debug mode, this will set release queue of
-  // debugallocation.cc to 100M to make it less likely for real leaks to
-  // be hidden due to reuse of heap memory object addresses.
-  // Running a test with --malloc_reclaim_memory=0 would help find leaks even
-  // better, but the test might run out of memory as a result.
-  // The scenario is that a heap object at address X is allocated and freed,
-  // but some other data-structure still retains a pointer to X.
-  // Then the same heap memory is used for another object, which is leaked,
-  // but the leak is not noticed due to the pointer to the original object at X.
-  // TODO(csilvers): support this in some manner.
-#if 0
-  SetCommandLineOptionWithMode("max_free_queue_size", "104857600",  // 100M
-                               SET_FLAG_IF_DEFAULT);
-#endif
-}
-
-// We want this to run early as well, but not so early as
-// ::BeforeConstructors (we want flag assignments to have already
-// happened, for instance).  Initializer-registration does the trick.
-REGISTER_MODULE_INITIALIZER(init_start, HeapLeakChecker_InternalInitStart());
-REGISTER_MODULE_DESTRUCTOR(init_start, HeapLeakChecker_RunHeapCleanups());
-
-// static
-bool HeapLeakChecker::NoGlobalLeaksMaybeSymbolize(
-    ShouldSymbolize should_symbolize) {
-  // we never delete or change main_heap_checker once it's set:
-  HeapLeakChecker* main_hc = GlobalChecker();
-  if (main_hc) {
-    RAW_VLOG(10, "Checking for whole-program memory leaks");
-    return main_hc->DoNoLeaks(should_symbolize);
-  }
-  return true;
-}
-
-// static
-bool HeapLeakChecker::DoMainHeapCheck() {
-  if (FLAGS_heap_check_delay_seconds > 0) {
-    sleep(FLAGS_heap_check_delay_seconds);
-  }
-  { SpinLockHolder l(&heap_checker_lock);
-    if (!do_main_heap_check) return false;
-    RAW_DCHECK(heap_checker_pid == getpid(), "");
-    do_main_heap_check = false;  // will do it now; no need to do it more
-  }
-
-  // The program is over, so it's safe to symbolize addresses (which
-  // requires a fork) because no serious work is expected to be done
-  // after this.  Symbolizing is really useful -- knowing what
-  // function has a leak is better than knowing just an address --
-  // and while we can only safely symbolize once in a program run,
-  // now is the time (after all, there's no "later" that would be better).
-  if (!NoGlobalLeaksMaybeSymbolize(SYMBOLIZE)) {
-    if (FLAGS_heap_check_identify_leaks) {
-      RAW_LOG(FATAL, "Whole-program memory leaks found.");
-    }
-    RAW_LOG(ERROR, "Exiting with error code (instead of crashing) "
-                   "because of whole-program memory leaks");
-    _exit(1);    // we don't want to call atexit() routines!
-  }
-  return true;
-}
-
-// static
-HeapLeakChecker* HeapLeakChecker::GlobalChecker() {
-  SpinLockHolder l(&heap_checker_lock);
-  return main_heap_checker;
-}
-
-// static
-bool HeapLeakChecker::NoGlobalLeaks() {
-  // symbolizing requires a fork, which isn't safe to do in general.
-  return NoGlobalLeaksMaybeSymbolize(DO_NOT_SYMBOLIZE);
-}
-
-// static
-void HeapLeakChecker::CancelGlobalCheck() {
-  SpinLockHolder l(&heap_checker_lock);
-  if (do_main_heap_check) {
-    RAW_VLOG(heap_checker_info_level,
-             "Canceling the automatic at-exit whole-program memory leak check");
-    do_main_heap_check = false;
-  }
-}
-
-// static
-void HeapLeakChecker::BeforeConstructorsLocked() {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_CHECK(!constructor_heap_profiling,
-            "BeforeConstructorsLocked called multiple times");
-#ifdef ADDRESS_SANITIZER
-  // AddressSanitizer's custom malloc conflicts with HeapChecker.
-  return;
-#endif
-  // Set hooks early to crash if 'new' gets called before we make heap_profile,
-  // and make sure no other hooks existed:
-  RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
-  RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
-  constructor_heap_profiling = true;
-  MemoryRegionMap::Init(1, /* use_buckets */ false);
-    // Set up MemoryRegionMap with (at least) one caller stack frame to record
-    // (important that it's done before HeapProfileTable creation below).
-  Allocator::Init();
-  RAW_CHECK(heap_profile == NULL, "");
-  heap_profile = new(Allocator::Allocate(sizeof(HeapProfileTable)))
-      HeapProfileTable(&Allocator::Allocate, &Allocator::Free,
-                       /* profile_mmap */ false);
-  RAW_VLOG(10, "Starting tracking the heap");
-  heap_checker_on = true;
-}
-
-// static
-void HeapLeakChecker::TurnItselfOffLocked() {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  // Set FLAGS_heap_check to "", for users who test for it
-  if (!FLAGS_heap_check.empty())  // be a noop in the common case
-    FLAGS_heap_check.clear();     // because clear() could allocate memory
-  if (constructor_heap_profiling) {
-    RAW_CHECK(heap_checker_on, "");
-    RAW_VLOG(heap_checker_info_level, "Turning perftools heap leak checking off");
-    heap_checker_on = false;
-    // Unset our hooks checking they were set:
-    RAW_CHECK(MallocHook::RemoveNewHook(&NewHook), "");
-    RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), "");
-    Allocator::DeleteAndNull(&heap_profile);
-    // free our optional global data:
-    Allocator::DeleteAndNullIfNot(&ignored_objects);
-    Allocator::DeleteAndNullIfNot(&disabled_ranges);
-    Allocator::DeleteAndNullIfNot(&global_region_caller_ranges);
-    Allocator::Shutdown();
-    MemoryRegionMap::Shutdown();
-  }
-  RAW_CHECK(!heap_checker_on, "");
-}
-
-extern bool heap_leak_checker_bcad_variable;  // in heap-checker-bcad.cc
-
-static bool has_called_before_constructors = false;
-
-// TODO(maxim): inline this function with
-// MallocHook_InitAtFirstAllocation_HeapLeakChecker, and also rename
-// HeapLeakChecker::BeforeConstructorsLocked.
-void HeapLeakChecker_BeforeConstructors() {
-  SpinLockHolder l(&heap_checker_lock);
-  // We can be called from several places: the first mmap/sbrk/alloc call
-  // or the first global c-tor from heap-checker-bcad.cc:
-  // Do not re-execute initialization:
-  if (has_called_before_constructors) return;
-  has_called_before_constructors = true;
-
-  heap_checker_pid = getpid();  // set it always
-  heap_leak_checker_bcad_variable = true;
-  // just to reference it, so that heap-checker-bcad.o is linked in
-
-  // This function can be called *very* early, before the normal
-  // global-constructor that sets FLAGS_verbose.  Set it manually now,
-  // so the RAW_LOG messages here are controllable.
-  const char* verbose_str = GetenvBeforeMain("PERFTOOLS_VERBOSE");
-  if (verbose_str && atoi(verbose_str)) {  // different than the default of 0?
-    FLAGS_verbose = atoi(verbose_str);
-  }
-
-  bool need_heap_check = true;
-  // The user indicates a desire for heap-checking via the HEAPCHECK
-  // environment variable.  If it's not set, there's no way to do
-  // heap-checking.
-  if (!GetenvBeforeMain("HEAPCHECK")) {
-    need_heap_check = false;
-  }
-#ifdef HAVE_GETEUID
-  if (need_heap_check && getuid() != geteuid()) {
-    // heap-checker writes out files.  Thus, for security reasons, we don't
-    // recognize the env. var. to turn on heap-checking if we're setuid.
-    RAW_LOG(WARNING, ("HeapChecker: ignoring HEAPCHECK because "
-                      "program seems to be setuid\n"));
-    need_heap_check = false;
-  }
-#endif
-  if (need_heap_check) {
-    HeapLeakChecker::BeforeConstructorsLocked();
-  }
-}
-
-// This function overrides the weak function defined in malloc_hook.cc and
-// called by one of the initial malloc hooks (malloc_hook.cc) when the very
-// first memory allocation or an mmap/sbrk happens.  This ensures that
-// HeapLeakChecker is initialized and installs all its hooks early enough to
-// track absolutely all memory allocations and all memory region acquisitions
-// via mmap and sbrk.
-extern "C" void MallocHook_InitAtFirstAllocation_HeapLeakChecker() {
-  HeapLeakChecker_BeforeConstructors();
-}
-
-// This function is executed after all global object destructors run.
-void HeapLeakChecker_AfterDestructors() {
-  { SpinLockHolder l(&heap_checker_lock);
-    // can get here (via forks?) with other pids
-    if (heap_checker_pid != getpid()) return;
-  }
-  if (FLAGS_heap_check_after_destructors) {
-    if (HeapLeakChecker::DoMainHeapCheck()) {
-      const struct timespec sleep_time = { 0, 500000000 };  // 500 ms
-      nanosleep(&sleep_time, NULL);
-        // Need this hack to wait for other pthreads to exit.
-        // Otherwise tcmalloc find errors
-        // on a free() call from pthreads.
-    }
-  }
-  SpinLockHolder l(&heap_checker_lock);
-  RAW_CHECK(!do_main_heap_check, "should have done it");
-}
-
-//----------------------------------------------------------------------
-// HeapLeakChecker disabling helpers
-//----------------------------------------------------------------------
-
-// These functions are at the end of the file to prevent their inlining:
-
-// static
-void HeapLeakChecker::DisableChecksFromToLocked(const void* start_address,
-                                                const void* end_address,
-                                                int max_depth) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_DCHECK(start_address < end_address, "");
-  if (disabled_ranges == NULL) {
-    disabled_ranges = new(Allocator::Allocate(sizeof(DisabledRangeMap)))
-                        DisabledRangeMap;
-  }
-  RangeValue value;
-  value.start_address = AsInt(start_address);
-  value.max_depth = max_depth;
-  if (disabled_ranges->insert(make_pair(AsInt(end_address), value)).second) {
-    RAW_VLOG(10, "Disabling leak checking in stack traces "
-                "under frame addresses between %p..%p",
-                start_address, end_address);
-  } else {  // check that this is just a verbatim repetition
-    RangeValue const& val = disabled_ranges->find(AsInt(end_address))->second;
-    if (val.max_depth != value.max_depth  ||
-        val.start_address != value.start_address) {
-      RAW_LOG(FATAL, "Two DisableChecksToHereFrom calls conflict: "
-                     "(%p, %p, %d) vs. (%p, %p, %d)",
-                     AsPtr(val.start_address), end_address, val.max_depth,
-                     start_address, end_address, max_depth);
-    }
-  }
-}
-
-// static
-inline bool HeapLeakChecker::HaveOnHeapLocked(const void** ptr,
-                                              size_t* object_size) {
-  // Commented-out because HaveOnHeapLocked is very performance-critical:
-  // RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  const uintptr_t addr = AsInt(*ptr);
-  if (heap_profile->FindInsideAlloc(
-        *ptr, max_heap_object_size, ptr, object_size)) {
-    RAW_VLOG(16, "Got pointer into %p at +%" PRIuPTR " offset",
-             *ptr, addr - AsInt(*ptr));
-    return true;
-  }
-  return false;
-}
-
-// static
-const void* HeapLeakChecker::GetAllocCaller(void* ptr) {
-  // this is used only in the unittest, so the heavy checks are fine
-  HeapProfileTable::AllocInfo info;
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_CHECK(heap_profile->FindAllocDetails(ptr, &info), "");
-  }
-  RAW_CHECK(info.stack_depth >= 1, "");
-  return info.call_stack[0];
-}
diff --git a/third_party/tcmalloc/chromium/src/heap-profile-stats.h b/third_party/tcmalloc/chromium/src/heap-profile-stats.h
deleted file mode 100644
index ae45d588..0000000
--- a/third_party/tcmalloc/chromium/src/heap-profile-stats.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2013, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file defines structs to accumulate memory allocation and deallocation
-// counts.  These structs are commonly used for malloc (in HeapProfileTable)
-// and mmap (in MemoryRegionMap).
-
-// A bucket is data structure for heap profiling to store a pair of a stack
-// trace and counts of (de)allocation.  Buckets are stored in a hash table
-// which is declared as "HeapProfileBucket**".
-//
-// A hash value is computed from a stack trace.  Collision in the hash table
-// is resolved by separate chaining with linked lists.  The links in the list
-// are implemented with the member "HeapProfileBucket* next".
-//
-// A structure of a hash table HeapProfileBucket** bucket_table would be like:
-// bucket_table[0] => NULL
-// bucket_table[1] => HeapProfileBucket() => HeapProfileBucket() => NULL
-// ...
-// bucket_table[i] => HeapProfileBucket() => NULL
-// ...
-// bucket_table[n] => HeapProfileBucket() => NULL
-
-#ifndef HEAP_PROFILE_STATS_H_
-#define HEAP_PROFILE_STATS_H_
-
-struct HeapProfileStats {
-  // Returns true if the two HeapProfileStats are semantically equal.
-  bool Equivalent(const HeapProfileStats& other) const {
-    return allocs - frees == other.allocs - other.frees &&
-        alloc_size - free_size == other.alloc_size - other.free_size;
-  }
-
-  int32 allocs;      // Number of allocation calls.
-  int32 frees;       // Number of free calls.
-  int64 alloc_size;  // Total size of all allocated objects so far.
-  int64 free_size;   // Total size of all freed objects so far.
-};
-
-// Allocation and deallocation statistics per each stack trace.
-struct HeapProfileBucket : public HeapProfileStats {
-  // Longest stack trace we record.
-  static const int kMaxStackDepth = 32;
-
-  uintptr_t hash;           // Hash value of the stack trace.
-  int depth;                // Depth of stack trace.
-  const void** stack;       // Stack trace.
-  HeapProfileBucket* next;  // Next entry in hash-table.
-};
-
-#endif  // HEAP_PROFILE_STATS_H_
diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.cc b/third_party/tcmalloc/chromium/src/heap-profile-table.cc
deleted file mode 100644
index cffe809..0000000
--- a/third_party/tcmalloc/chromium/src/heap-profile-table.cc
+++ /dev/null
@@ -1,632 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//         Maxim Lifantsev (refactoring)
-//
-
-#include <config.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>   // for write()
-#endif
-#include <fcntl.h>    // for open()
-#ifdef HAVE_GLOB_H
-#include <glob.h>
-#ifndef GLOB_NOMATCH  // true on some old cygwins
-# define GLOB_NOMATCH 0
-#endif
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h> // for PRIxPTR
-#endif
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif
-#include <errno.h>
-#include <stdarg.h>
-#include <string>
-#include <map>
-#include <algorithm>  // for sort(), equal(), and copy()
-
-#include "heap-profile-table.h"
-
-#include "base/logging.h"
-#include "raw_printer.h"
-#include "symbolize.h"
-#include <gperftools/stacktrace.h>
-#include <gperftools/malloc_hook.h>
-#include "memory_region_map.h"
-#include "base/commandlineflags.h"
-#include "base/logging.h"    // for the RawFD I/O commands
-#include "base/sysinfo.h"
-
-using std::sort;
-using std::equal;
-using std::copy;
-using std::string;
-using std::map;
-
-using tcmalloc::FillProcSelfMaps;   // from sysinfo.h
-using tcmalloc::DumpProcSelfMaps;   // from sysinfo.h
-
-//----------------------------------------------------------------------
-
-DEFINE_bool(cleanup_old_heap_profiles,
-            EnvToBool("HEAP_PROFILE_CLEANUP", true),
-            "At initialization time, delete old heap profiles.");
-
-DEFINE_int32(heap_check_max_leaks,
-             EnvToInt("HEAP_CHECK_MAX_LEAKS", 20),
-             "The maximum number of leak reports to print.");
-
-//----------------------------------------------------------------------
-
-// header of the dumped heap profile
-static const char kProfileHeader[] = "heap profile: ";
-static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n";
-
-//----------------------------------------------------------------------
-
-const char HeapProfileTable::kFileExt[] = ".heap";
-
-//----------------------------------------------------------------------
-
-static const int kHashTableSize = 179999;   // Size for bucket_table_.
-/*static*/ const int HeapProfileTable::kMaxStackDepth;
-
-//----------------------------------------------------------------------
-
-// We strip out different number of stack frames in debug mode
-// because less inlining happens in that case
-#ifdef NDEBUG
-static const int kStripFrames = 2;
-#else
-static const int kStripFrames = 3;
-#endif
-
-// For sorting Stats or Buckets by in-use space
-static bool ByAllocatedSpace(HeapProfileTable::Stats* a,
-                             HeapProfileTable::Stats* b) {
-  // Return true iff "a" has more allocated space than "b"
-  return (a->alloc_size - a->free_size) > (b->alloc_size - b->free_size);
-}
-
-//----------------------------------------------------------------------
-
-HeapProfileTable::HeapProfileTable(Allocator alloc,
-                                   DeAllocator dealloc,
-                                   bool profile_mmap)
-    : alloc_(alloc),
-      dealloc_(dealloc),
-      profile_mmap_(profile_mmap),
-      bucket_table_(NULL),
-      num_buckets_(0),
-      address_map_(NULL) {
-  // Make a hash table for buckets.
-  const int table_bytes = kHashTableSize * sizeof(*bucket_table_);
-  bucket_table_ = static_cast<Bucket**>(alloc_(table_bytes));
-  memset(bucket_table_, 0, table_bytes);
-
-  // Make an allocation map.
-  address_map_ =
-      new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_);
-
-  // Initialize.
-  memset(&total_, 0, sizeof(total_));
-  num_buckets_ = 0;
-}
-
-HeapProfileTable::~HeapProfileTable() {
-  // Free the allocation map.
-  address_map_->~AllocationMap();
-  dealloc_(address_map_);
-  address_map_ = NULL;
-
-  // Free the hash table.
-  for (int i = 0; i < kHashTableSize; i++) {
-    for (Bucket* curr = bucket_table_[i]; curr != 0; /**/) {
-      Bucket* bucket = curr;
-      curr = curr->next;
-      dealloc_(bucket->stack);
-      dealloc_(bucket);
-    }
-  }
-  dealloc_(bucket_table_);
-  bucket_table_ = NULL;
-}
-
-HeapProfileTable::Bucket* HeapProfileTable::GetBucket(int depth,
-                                                      const void* const key[]) {
-  // Make hash-value
-  uintptr_t h = 0;
-  for (int i = 0; i < depth; i++) {
-    h += reinterpret_cast<uintptr_t>(key[i]);
-    h += h << 10;
-    h ^= h >> 6;
-  }
-  h += h << 3;
-  h ^= h >> 11;
-
-  // Lookup stack trace in table
-  unsigned int buck = ((unsigned int) h) % kHashTableSize;
-  for (Bucket* b = bucket_table_[buck]; b != 0; b = b->next) {
-    if ((b->hash == h) &&
-        (b->depth == depth) &&
-        equal(key, key + depth, b->stack)) {
-      return b;
-    }
-  }
-
-  // Create new bucket
-  const size_t key_size = sizeof(key[0]) * depth;
-  const void** kcopy = reinterpret_cast<const void**>(alloc_(key_size));
-  copy(key, key + depth, kcopy);
-  Bucket* b = reinterpret_cast<Bucket*>(alloc_(sizeof(Bucket)));
-  memset(b, 0, sizeof(*b));
-  b->hash  = h;
-  b->depth = depth;
-  b->stack = kcopy;
-  b->next  = bucket_table_[buck];
-  bucket_table_[buck] = b;
-  num_buckets_++;
-  return b;
-}
-
-int HeapProfileTable::GetCallerStackTrace(
-    int skip_count, void* stack[kMaxStackDepth]) {
-  return MallocHook::GetCallerStackTrace(
-      stack, kMaxStackDepth, kStripFrames + skip_count + 1);
-}
-
-void HeapProfileTable::RecordAlloc(
-    const void* ptr, size_t bytes, int stack_depth,
-    const void* const call_stack[]) {
-  Bucket* b = GetBucket(stack_depth, call_stack);
-  b->allocs++;
-  b->alloc_size += bytes;
-  total_.allocs++;
-  total_.alloc_size += bytes;
-
-  AllocValue v;
-  v.set_bucket(b);  // also did set_live(false); set_ignore(false)
-  v.bytes = bytes;
-  address_map_->Insert(ptr, v);
-}
-
-void HeapProfileTable::RecordFree(const void* ptr) {
-  AllocValue v;
-  if (address_map_->FindAndRemove(ptr, &v)) {
-    Bucket* b = v.bucket();
-    b->frees++;
-    b->free_size += v.bytes;
-    total_.frees++;
-    total_.free_size += v.bytes;
-  }
-}
-
-bool HeapProfileTable::FindAlloc(const void* ptr, size_t* object_size) const {
-  const AllocValue* alloc_value = address_map_->Find(ptr);
-  if (alloc_value != NULL) *object_size = alloc_value->bytes;
-  return alloc_value != NULL;
-}
-
-bool HeapProfileTable::FindAllocDetails(const void* ptr,
-                                        AllocInfo* info) const {
-  const AllocValue* alloc_value = address_map_->Find(ptr);
-  if (alloc_value != NULL) {
-    info->object_size = alloc_value->bytes;
-    info->call_stack = alloc_value->bucket()->stack;
-    info->stack_depth = alloc_value->bucket()->depth;
-  }
-  return alloc_value != NULL;
-}
-
-bool HeapProfileTable::FindInsideAlloc(const void* ptr,
-                                       size_t max_size,
-                                       const void** object_ptr,
-                                       size_t* object_size) const {
-  const AllocValue* alloc_value =
-    address_map_->FindInside(&AllocValueSize, max_size, ptr, object_ptr);
-  if (alloc_value != NULL) *object_size = alloc_value->bytes;
-  return alloc_value != NULL;
-}
-
-bool HeapProfileTable::MarkAsLive(const void* ptr) {
-  AllocValue* alloc = address_map_->FindMutable(ptr);
-  if (alloc && !alloc->live()) {
-    alloc->set_live(true);
-    return true;
-  }
-  return false;
-}
-
-void HeapProfileTable::MarkAsIgnored(const void* ptr) {
-  AllocValue* alloc = address_map_->FindMutable(ptr);
-  if (alloc) {
-    alloc->set_ignore(true);
-  }
-}
-
-// We'd be happier using snprintfer, but we don't to reduce dependencies.
-int HeapProfileTable::UnparseBucket(const Bucket& b,
-                                    char* buf, int buflen, int bufsize,
-                                    const char* extra,
-                                    Stats* profile_stats) {
-  if (profile_stats != NULL) {
-    profile_stats->allocs += b.allocs;
-    profile_stats->alloc_size += b.alloc_size;
-    profile_stats->frees += b.frees;
-    profile_stats->free_size += b.free_size;
-  }
-  int printed =
-    snprintf(buf + buflen, bufsize - buflen, "%6d: %8" PRId64 " [%6d: %8" PRId64 "] @%s",
-             b.allocs - b.frees,
-             b.alloc_size - b.free_size,
-             b.allocs,
-             b.alloc_size,
-             extra);
-  // If it looks like the snprintf failed, ignore the fact we printed anything
-  if (printed < 0 || printed >= bufsize - buflen) return buflen;
-  buflen += printed;
-  for (int d = 0; d < b.depth; d++) {
-    printed = snprintf(buf + buflen, bufsize - buflen, " 0x%08" PRIxPTR,
-                       reinterpret_cast<uintptr_t>(b.stack[d]));
-    if (printed < 0 || printed >= bufsize - buflen) return buflen;
-    buflen += printed;
-  }
-  printed = snprintf(buf + buflen, bufsize - buflen, "\n");
-  if (printed < 0 || printed >= bufsize - buflen) return buflen;
-  buflen += printed;
-  return buflen;
-}
-
-HeapProfileTable::Bucket**
-HeapProfileTable::MakeSortedBucketList() const {
-  Bucket** list = static_cast<Bucket**>(alloc_(sizeof(Bucket) * num_buckets_));
-
-  int bucket_count = 0;
-  for (int i = 0; i < kHashTableSize; i++) {
-    for (Bucket* curr = bucket_table_[i]; curr != 0; curr = curr->next) {
-      list[bucket_count++] = curr;
-    }
-  }
-  RAW_DCHECK(bucket_count == num_buckets_, "");
-
-  sort(list, list + num_buckets_, ByAllocatedSpace);
-
-  return list;
-}
-
-void HeapProfileTable::IterateOrderedAllocContexts(
-    AllocContextIterator callback) const {
-  Bucket** list = MakeSortedBucketList();
-  AllocContextInfo info;
-  for (int i = 0; i < num_buckets_; ++i) {
-    *static_cast<Stats*>(&info) = *static_cast<Stats*>(list[i]);
-    info.stack_depth = list[i]->depth;
-    info.call_stack = list[i]->stack;
-    callback(info);
-  }
-  dealloc_(list);
-}
-
-int HeapProfileTable::FillOrderedProfile(char buf[], int size) const {
-  Bucket** list = MakeSortedBucketList();
-
-  // Our file format is "bucket, bucket, ..., bucket, proc_self_maps_info".
-  // In the cases buf is too small, we'd rather leave out the last
-  // buckets than leave out the /proc/self/maps info.  To ensure that,
-  // we actually print the /proc/self/maps info first, then move it to
-  // the end of the buffer, then write the bucket info into whatever
-  // is remaining, and then move the maps info one last time to close
-  // any gaps.  Whew!
-  int map_length = snprintf(buf, size, "%s", kProcSelfMapsHeader);
-  if (map_length < 0 || map_length >= size) {
-      dealloc_(list);
-      return 0;
-  }
-  bool dummy;   // "wrote_all" -- did /proc/self/maps fit in its entirety?
-  map_length += FillProcSelfMaps(buf + map_length, size - map_length, &dummy);
-  RAW_DCHECK(map_length <= size, "");
-  char* const map_start = buf + size - map_length;      // move to end
-  memmove(map_start, buf, map_length);
-  size -= map_length;
-
-  Stats stats;
-  memset(&stats, 0, sizeof(stats));
-  int bucket_length = snprintf(buf, size, "%s", kProfileHeader);
-  if (bucket_length < 0 || bucket_length >= size) {
-      dealloc_(list);
-      return 0;
-  }
-  bucket_length = UnparseBucket(total_, buf, bucket_length, size,
-                                " heapprofile", &stats);
-
-  // Dump the mmap list first.
-  if (profile_mmap_) {
-    BufferArgs buffer(buf, bucket_length, size);
-    MemoryRegionMap::IterateBuckets<BufferArgs*>(DumpBucketIterator, &buffer);
-    bucket_length = buffer.buflen;
-  }
-
-  for (int i = 0; i < num_buckets_; i++) {
-    bucket_length = UnparseBucket(*list[i], buf, bucket_length, size, "",
-                                  &stats);
-  }
-  RAW_DCHECK(bucket_length < size, "");
-
-  dealloc_(list);
-
-  RAW_DCHECK(buf + bucket_length <= map_start, "");
-  memmove(buf + bucket_length, map_start, map_length);  // close the gap
-
-  return bucket_length + map_length;
-}
-
-// static
-void HeapProfileTable::DumpBucketIterator(const Bucket* bucket,
-                                          BufferArgs* args) {
-  args->buflen = UnparseBucket(*bucket, args->buf, args->buflen, args->bufsize,
-                               "", NULL);
-}
-
-inline
-void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v,
-                                           const DumpArgs& args) {
-  if (v->live()) {
-    v->set_live(false);
-    return;
-  }
-  if (v->ignore()) {
-    return;
-  }
-  Bucket b;
-  memset(&b, 0, sizeof(b));
-  b.allocs = 1;
-  b.alloc_size = v->bytes;
-  b.depth = v->bucket()->depth;
-  b.stack = v->bucket()->stack;
-  char buf[1024];
-  int len = UnparseBucket(b, buf, 0, sizeof(buf), "", args.profile_stats);
-  RawWrite(args.fd, buf, len);
-}
-
-// Callback from NonLiveSnapshot; adds entry to arg->dest
-// if not the entry is not live and is not present in arg->base.
-void HeapProfileTable::AddIfNonLive(const void* ptr, AllocValue* v,
-                                    AddNonLiveArgs* arg) {
-  if (v->live()) {
-    v->set_live(false);
-  } else {
-    if (arg->base != NULL && arg->base->map_.Find(ptr) != NULL) {
-      // Present in arg->base, so do not save
-    } else {
-      arg->dest->Add(ptr, *v);
-    }
-  }
-}
-
-bool HeapProfileTable::WriteProfile(const char* file_name,
-                                    const Bucket& total,
-                                    AllocationMap* allocations) {
-  RAW_VLOG(1, "Dumping non-live heap profile to %s", file_name);
-  RawFD fd = RawOpenForWriting(file_name);
-  if (fd == kIllegalRawFD) {
-    RAW_LOG(ERROR, "Failed dumping filtered heap profile to %s", file_name);
-    return false;
-  }
-  RawWrite(fd, kProfileHeader, strlen(kProfileHeader));
-  char buf[512];
-  int len = UnparseBucket(total, buf, 0, sizeof(buf), " heapprofile", NULL);
-  RawWrite(fd, buf, len);
-  const DumpArgs args(fd, NULL);
-  allocations->Iterate<const DumpArgs&>(DumpNonLiveIterator, args);
-  RawWrite(fd, kProcSelfMapsHeader, strlen(kProcSelfMapsHeader));
-  DumpProcSelfMaps(fd);
-  RawClose(fd);
-  return true;
-}
-
-void HeapProfileTable::CleanupOldProfiles(const char* prefix) {
-  if (!FLAGS_cleanup_old_heap_profiles)
-    return;
-  char buf[1000];
-  snprintf(buf, 1000,"%s.%05d.", prefix, getpid());
-  string pattern = string(buf) + ".*" + kFileExt;
-
-#if defined(HAVE_GLOB_H)
-  glob_t g;
-  const int r = glob(pattern.c_str(), GLOB_ERR, NULL, &g);
-  if (r == 0 || r == GLOB_NOMATCH) {
-    const int prefix_length = strlen(prefix);
-    for (int i = 0; i < g.gl_pathc; i++) {
-      const char* fname = g.gl_pathv[i];
-      if ((strlen(fname) >= prefix_length) &&
-          (memcmp(fname, prefix, prefix_length) == 0)) {
-        RAW_VLOG(1, "Removing old heap profile %s", fname);
-        unlink(fname);
-      }
-    }
-  }
-  globfree(&g);
-#else   /* HAVE_GLOB_H */
-  RAW_LOG(WARNING, "Unable to remove old heap profiles (can't run glob())");
-#endif
-}
-
-HeapProfileTable::Snapshot* HeapProfileTable::TakeSnapshot() {
-  Snapshot* s = new (alloc_(sizeof(Snapshot))) Snapshot(alloc_, dealloc_);
-  address_map_->Iterate(AddToSnapshot, s);
-  return s;
-}
-
-void HeapProfileTable::ReleaseSnapshot(Snapshot* s) {
-  s->~Snapshot();
-  dealloc_(s);
-}
-
-// Callback from TakeSnapshot; adds a single entry to snapshot
-void HeapProfileTable::AddToSnapshot(const void* ptr, AllocValue* v,
-                                     Snapshot* snapshot) {
-  snapshot->Add(ptr, *v);
-}
-
-HeapProfileTable::Snapshot* HeapProfileTable::NonLiveSnapshot(
-    Snapshot* base) {
-  RAW_VLOG(2, "NonLiveSnapshot input: %d %d\n",
-           int(total_.allocs - total_.frees),
-           int(total_.alloc_size - total_.free_size));
-
-  Snapshot* s = new (alloc_(sizeof(Snapshot))) Snapshot(alloc_, dealloc_);
-  AddNonLiveArgs args;
-  args.dest = s;
-  args.base = base;
-  address_map_->Iterate<AddNonLiveArgs*>(AddIfNonLive, &args);
-  RAW_VLOG(2, "NonLiveSnapshot output: %d %d\n",
-           int(s->total_.allocs - s->total_.frees),
-           int(s->total_.alloc_size - s->total_.free_size));
-  return s;
-}
-
-// Information kept per unique bucket seen
-struct HeapProfileTable::Snapshot::Entry {
-  int count;
-  int bytes;
-  Bucket* bucket;
-  Entry() : count(0), bytes(0) { }
-
-  // Order by decreasing bytes
-  bool operator<(const Entry& x) const {
-    return this->bytes > x.bytes;
-  }
-};
-
-// State used to generate leak report.  We keep a mapping from Bucket pointer
-// the collected stats for that bucket.
-struct HeapProfileTable::Snapshot::ReportState {
-  map<Bucket*, Entry> buckets_;
-};
-
-// Callback from ReportLeaks; updates ReportState.
-void HeapProfileTable::Snapshot::ReportCallback(const void* ptr,
-                                                AllocValue* v,
-                                                ReportState* state) {
-  Entry* e = &state->buckets_[v->bucket()]; // Creates empty Entry first time
-  e->bucket = v->bucket();
-  e->count++;
-  e->bytes += v->bytes;
-}
-
-void HeapProfileTable::Snapshot::ReportLeaks(const char* checker_name,
-                                             const char* filename,
-                                             bool should_symbolize) {
-  // This is only used by the heap leak checker, but is intimately
-  // tied to the allocation map that belongs in this module and is
-  // therefore placed here.
-  RAW_LOG(ERROR, "Leak check %s detected leaks of %" PRIuS " bytes "
-          "in %" PRIuS " objects",
-          checker_name,
-          size_t(total_.alloc_size),
-          size_t(total_.allocs));
-
-  // Group objects by Bucket
-  ReportState state;
-  map_.Iterate(&ReportCallback, &state);
-
-  // Sort buckets by decreasing leaked size
-  const int n = state.buckets_.size();
-  Entry* entries = new Entry[n];
-  int dst = 0;
-  for (map<Bucket*,Entry>::const_iterator iter = state.buckets_.begin();
-       iter != state.buckets_.end();
-       ++iter) {
-    entries[dst++] = iter->second;
-  }
-  sort(entries, entries + n);
-
-  // Report a bounded number of leaks to keep the leak report from
-  // growing too long.
-  const int to_report =
-      (FLAGS_heap_check_max_leaks > 0 &&
-       n > FLAGS_heap_check_max_leaks) ? FLAGS_heap_check_max_leaks : n;
-  RAW_LOG(ERROR, "The %d largest leaks:", to_report);
-
-  // Print
-  SymbolTable symbolization_table;
-  for (int i = 0; i < to_report; i++) {
-    const Entry& e = entries[i];
-    for (int j = 0; j < e.bucket->depth; j++) {
-      symbolization_table.Add(e.bucket->stack[j]);
-    }
-  }
-  static const int kBufSize = 2<<10;
-  char buffer[kBufSize];
-  if (should_symbolize)
-    symbolization_table.Symbolize();
-  for (int i = 0; i < to_report; i++) {
-    const Entry& e = entries[i];
-    base::RawPrinter printer(buffer, kBufSize);
-    printer.Printf("Leak of %d bytes in %d objects allocated from:\n",
-                   e.bytes, e.count);
-    for (int j = 0; j < e.bucket->depth; j++) {
-      const void* pc = e.bucket->stack[j];
-      printer.Printf("\t@ %" PRIxPTR " %s\n",
-          reinterpret_cast<uintptr_t>(pc), symbolization_table.GetSymbol(pc));
-    }
-    RAW_LOG(ERROR, "%s", buffer);
-  }
-
-  if (to_report < n) {
-    RAW_LOG(ERROR, "Skipping leaks numbered %d..%d",
-            to_report, n-1);
-  }
-  delete[] entries;
-
-  // TODO: Dump the sorted Entry list instead of dumping raw data?
-  // (should be much shorter)
-  if (!HeapProfileTable::WriteProfile(filename, total_, &map_)) {
-    RAW_LOG(ERROR, "Could not write pprof profile to %s", filename);
-  }
-}
-
-void HeapProfileTable::Snapshot::ReportObject(const void* ptr,
-                                              AllocValue* v,
-                                              char* unused) {
-  // Perhaps also log the allocation stack trace (unsymbolized)
-  // on this line in case somebody finds it useful.
-  RAW_LOG(ERROR, "leaked %" PRIuS " byte object %p", v->bytes, ptr);
-}
-
-void HeapProfileTable::Snapshot::ReportIndividualObjects() {
-  char unused;
-  map_.Iterate(ReportObject, &unused);
-}
diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.h b/third_party/tcmalloc/chromium/src/heap-profile-table.h
deleted file mode 100644
index de3d98f1..0000000
--- a/third_party/tcmalloc/chromium/src/heap-profile-table.h
+++ /dev/null
@@ -1,403 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//         Maxim Lifantsev (refactoring)
-//
-
-#ifndef BASE_HEAP_PROFILE_TABLE_H_
-#define BASE_HEAP_PROFILE_TABLE_H_
-
-#include "addressmap-inl.h"
-#include "base/basictypes.h"
-#include "base/logging.h"   // for RawFD
-#include "heap-profile-stats.h"
-
-// Table to maintain a heap profile data inside,
-// i.e. the set of currently active heap memory allocations.
-// thread-unsafe and non-reentrant code:
-// each instance object must be used by one thread
-// at a time w/o self-recursion.
-//
-// TODO(maxim): add a unittest for this class.
-class HeapProfileTable {
- public:
-
-  // Extension to be used for heap pforile files.
-  static const char kFileExt[];
-
-  // Longest stack trace we record.
-  static const int kMaxStackDepth = 32;
-
-  // data types ----------------------------
-
-  // Profile stats.
-  typedef HeapProfileStats Stats;
-
-  // Info we can return about an allocation.
-  struct AllocInfo {
-    size_t object_size;  // size of the allocation
-    const void* const* call_stack;  // call stack that made the allocation call
-    int stack_depth;  // depth of call_stack
-    bool live;
-    bool ignored;
-  };
-
-  // Info we return about an allocation context.
-  // An allocation context is a unique caller stack trace
-  // of an allocation operation.
-  struct AllocContextInfo : public Stats {
-    int stack_depth;                // Depth of stack trace
-    const void* const* call_stack;  // Stack trace
-  };
-
-  // Memory (de)allocator interface we'll use.
-  typedef void* (*Allocator)(size_t size);
-  typedef void  (*DeAllocator)(void* ptr);
-
-  // interface ---------------------------
-
-  HeapProfileTable(Allocator alloc, DeAllocator dealloc, bool profile_mmap);
-
-  HeapProfileTable(const HeapProfileTable&) = delete;
-  HeapProfileTable& operator=(const HeapProfileTable&) = delete;
-
-  ~HeapProfileTable();
-
-  // Collect the stack trace for the function that asked to do the
-  // allocation for passing to RecordAlloc() below.
-  //
-  // The stack trace is stored in 'stack'. The stack depth is returned.
-  //
-  // 'skip_count' gives the number of stack frames between this call
-  // and the memory allocation function.
-  static int GetCallerStackTrace(int skip_count, void* stack[kMaxStackDepth]);
-
-  // Record an allocation at 'ptr' of 'bytes' bytes.  'stack_depth'
-  // and 'call_stack' identifying the function that requested the
-  // allocation. They can be generated using GetCallerStackTrace() above.
-  void RecordAlloc(const void* ptr, size_t bytes,
-                   int stack_depth, const void* const call_stack[]);
-
-  // Record the deallocation of memory at 'ptr'.
-  void RecordFree(const void* ptr);
-
-  // Return true iff we have recorded an allocation at 'ptr'.
-  // If yes, fill *object_size with the allocation byte size.
-  bool FindAlloc(const void* ptr, size_t* object_size) const;
-  // Same as FindAlloc, but fills all of *info.
-  bool FindAllocDetails(const void* ptr, AllocInfo* info) const;
-
-  // Return true iff "ptr" points into a recorded allocation
-  // If yes, fill *object_ptr with the actual allocation address
-  // and *object_size with the allocation byte size.
-  // max_size specifies largest currently possible allocation size.
-  bool FindInsideAlloc(const void* ptr, size_t max_size,
-                       const void** object_ptr, size_t* object_size) const;
-
-  // If "ptr" points to a recorded allocation and it's not marked as live
-  // mark it as live and return true. Else return false.
-  // All allocations start as non-live.
-  bool MarkAsLive(const void* ptr);
-
-  // If "ptr" points to a recorded allocation, mark it as "ignored".
-  // Ignored objects are treated like other objects, except that they
-  // are skipped in heap checking reports.
-  void MarkAsIgnored(const void* ptr);
-
-  // Return current total (de)allocation statistics.  It doesn't contain
-  // mmap'ed regions.
-  const Stats& total() const { return total_; }
-
-  // Allocation data iteration callback: gets passed object pointer and
-  // fully-filled AllocInfo.
-  typedef void (*AllocIterator)(const void* ptr, const AllocInfo& info);
-
-  // Iterate over the allocation profile data calling "callback"
-  // for every allocation.
-  void IterateAllocs(AllocIterator callback) const {
-    address_map_->Iterate(MapArgsAllocIterator, callback);
-  }
-
-  // Allocation context profile data iteration callback
-  typedef void (*AllocContextIterator)(const AllocContextInfo& info);
-
-  // Iterate over the allocation context profile data calling "callback"
-  // for every allocation context. Allocation contexts are ordered by the
-  // size of allocated space.
-  void IterateOrderedAllocContexts(AllocContextIterator callback) const;
-
-  // Fill profile data into buffer 'buf' of size 'size'
-  // and return the actual size occupied by the dump in 'buf'.
-  // The profile buckets are dumped in the decreasing order
-  // of currently allocated bytes.
-  // We do not provision for 0-terminating 'buf'.
-  int FillOrderedProfile(char buf[], int size) const;
-
-  // Cleanup any old profile files matching prefix + ".*" + kFileExt.
-  static void CleanupOldProfiles(const char* prefix);
-
-  // Return a snapshot of the current contents of *this.
-  // Caller must call ReleaseSnapshot() on result when no longer needed.
-  // The result is only valid while this exists and until
-  // the snapshot is discarded by calling ReleaseSnapshot().
-  class Snapshot;
-  Snapshot* TakeSnapshot();
-
-  // Release a previously taken snapshot.  snapshot must not
-  // be used after this call.
-  void ReleaseSnapshot(Snapshot* snapshot);
-
-  // Return a snapshot of every non-live, non-ignored object in *this.
-  // If "base" is non-NULL, skip any objects present in "base".
-  // As a side-effect, clears the "live" bit on every live object in *this.
-  // Caller must call ReleaseSnapshot() on result when no longer needed.
-  Snapshot* NonLiveSnapshot(Snapshot* base);
-
- private:
-
-  // data types ----------------------------
-
-  // Hash table bucket to hold (de)allocation stats
-  // for a given allocation call stack trace.
-  typedef HeapProfileBucket Bucket;
-
-  // Info stored in the address map
-  struct AllocValue {
-    // Access to the stack-trace bucket
-    Bucket* bucket() const {
-      return reinterpret_cast<Bucket*>(bucket_rep & ~uintptr_t(kMask));
-    }
-    // This also does set_live(false).
-    void set_bucket(Bucket* b) { bucket_rep = reinterpret_cast<uintptr_t>(b); }
-    size_t  bytes;   // Number of bytes in this allocation
-
-    // Access to the allocation liveness flag (for leak checking)
-    bool live() const { return bucket_rep & kLive; }
-    void set_live(bool l) {
-      bucket_rep = (bucket_rep & ~uintptr_t(kLive)) | (l ? kLive : 0);
-    }
-
-    // Should this allocation be ignored if it looks like a leak?
-    bool ignore() const { return bucket_rep & kIgnore; }
-    void set_ignore(bool r) {
-      bucket_rep = (bucket_rep & ~uintptr_t(kIgnore)) | (r ? kIgnore : 0);
-    }
-
-   private:
-    // We store a few bits in the bottom bits of bucket_rep.
-    // (Alignment is at least four, so we have at least two bits.)
-    static const int kLive = 1;
-    static const int kIgnore = 2;
-    static const int kMask = kLive | kIgnore;
-
-    uintptr_t bucket_rep;
-  };
-
-  // helper for FindInsideAlloc
-  static size_t AllocValueSize(const AllocValue& v) { return v.bytes; }
-
-  typedef AddressMap<AllocValue> AllocationMap;
-
-  // Arguments that need to be passed DumpBucketIterator callback below.
-  struct BufferArgs {
-    BufferArgs(char* buf_arg, int buflen_arg, int bufsize_arg)
-        : buf(buf_arg),
-          buflen(buflen_arg),
-          bufsize(bufsize_arg) {
-    }
-
-    BufferArgs(const BufferArgs&) = delete;
-    BufferArgs& operator=(const BufferArgs&) = delete;
-
-    char* buf;
-    int buflen;
-    int bufsize;
-  };
-
-  // Arguments that need to be passed DumpNonLiveIterator callback below.
-  struct DumpArgs {
-    DumpArgs(RawFD fd_arg, Stats* profile_stats_arg)
-        : fd(fd_arg),
-          profile_stats(profile_stats_arg) {
-    }
-
-    RawFD fd;  // file to write to
-    Stats* profile_stats;  // stats to update (may be NULL)
-  };
-
-  // helpers ----------------------------
-
-  // Unparse bucket b and print its portion of profile dump into buf.
-  // We return the amount of space in buf that we use.  We start printing
-  // at buf + buflen, and promise not to go beyond buf + bufsize.
-  // We do not provision for 0-terminating 'buf'.
-  //
-  // If profile_stats is non-NULL, we update *profile_stats by
-  // counting bucket b.
-  //
-  // "extra" is appended to the unparsed bucket.  Typically it is empty,
-  // but may be set to something like " heapprofile" for the total
-  // bucket to indicate the type of the profile.
-  static int UnparseBucket(const Bucket& b,
-                           char* buf, int buflen, int bufsize,
-                           const char* extra,
-                           Stats* profile_stats);
-
-  // Get the bucket for the caller stack trace 'key' of depth 'depth'
-  // creating the bucket if needed.
-  Bucket* GetBucket(int depth, const void* const key[]);
-
-  // Helper for IterateAllocs to do callback signature conversion
-  // from AllocationMap::Iterate to AllocIterator.
-  static void MapArgsAllocIterator(const void* ptr, AllocValue* v,
-                                   AllocIterator callback) {
-    AllocInfo info;
-    info.object_size = v->bytes;
-    info.call_stack = v->bucket()->stack;
-    info.stack_depth = v->bucket()->depth;
-    info.live = v->live();
-    info.ignored = v->ignore();
-    callback(ptr, info);
-  }
-
-  // Helper to dump a bucket.
-  inline static void DumpBucketIterator(const Bucket* bucket,
-                                        BufferArgs* args);
-
-  // Helper for DumpNonLiveProfile to do object-granularity
-  // heap profile dumping. It gets passed to AllocationMap::Iterate.
-  inline static void DumpNonLiveIterator(const void* ptr, AllocValue* v,
-                                         const DumpArgs& args);
-
-  // Helper for IterateOrderedAllocContexts and FillOrderedProfile.
-  // Creates a sorted list of Buckets whose length is num_buckets_.
-  // The caller is responsible for deallocating the returned list.
-  Bucket** MakeSortedBucketList() const;
-
-  // Helper for TakeSnapshot.  Saves object to snapshot.
-  static void AddToSnapshot(const void* ptr, AllocValue* v, Snapshot* s);
-
-  // Arguments passed to AddIfNonLive
-  struct AddNonLiveArgs {
-    Snapshot* dest;
-    Snapshot* base;
-  };
-
-  // Helper for NonLiveSnapshot.  Adds the object to the destination
-  // snapshot if it is non-live.
-  static void AddIfNonLive(const void* ptr, AllocValue* v,
-                           AddNonLiveArgs* arg);
-
-  // Write contents of "*allocations" as a heap profile to
-  // "file_name".  "total" must contain the total of all entries in
-  // "*allocations".
-  static bool WriteProfile(const char* file_name,
-                           const Bucket& total,
-                           AllocationMap* allocations);
-
-  // data ----------------------------
-
-  // Memory (de)allocator that we use.
-  Allocator alloc_;
-  DeAllocator dealloc_;
-
-  // Overall profile stats; we use only the Stats part,
-  // but make it a Bucket to pass to UnparseBucket.
-  Bucket total_;
-
-  bool profile_mmap_;
-
-  // Bucket hash table for malloc.
-  // We hand-craft one instead of using one of the pre-written
-  // ones because we do not want to use malloc when operating on the table.
-  // It is only few lines of code, so no big deal.
-  Bucket** bucket_table_;
-  int num_buckets_;
-
-  // Map of all currently allocated objects and mapped regions we know about.
-  AllocationMap* address_map_;
-};
-
-class HeapProfileTable::Snapshot {
- public:
-  Snapshot(const Snapshot&) = delete;
-  Snapshot& operator=(const Snapshot&) = delete;
-
-  const Stats& total() const { return total_; }
-
-  // Report anything in this snapshot as a leak.
-  // May use new/delete for temporary storage.
-  // If should_symbolize is true, will fork (which is not threadsafe)
-  // to turn addresses into symbol names.  Set to false for maximum safety.
-  // Also writes a heap profile to "filename" that contains
-  // all of the objects in this snapshot.
-  void ReportLeaks(const char* checker_name, const char* filename,
-                   bool should_symbolize);
-
-  // Report the addresses of all leaked objects.
-  // May use new/delete for temporary storage.
-  void ReportIndividualObjects();
-
-  bool Empty() const {
-    return (total_.allocs == 0) && (total_.alloc_size == 0);
-  }
-
- private:
-  friend class HeapProfileTable;
-
-  // Total count/size are stored in a Bucket so we can reuse UnparseBucket
-  Bucket total_;
-
-  // We share the Buckets managed by the parent table, but have our
-  // own object->bucket map.
-  AllocationMap map_;
-
-  Snapshot(Allocator alloc, DeAllocator dealloc) : map_(alloc, dealloc) {
-    memset(&total_, 0, sizeof(total_));
-  }
-
-  // Callback used to populate a Snapshot object with entries found
-  // in another allocation map.
-  inline void Add(const void* ptr, const AllocValue& v) {
-    map_.Insert(ptr, v);
-    total_.allocs++;
-    total_.alloc_size += v.bytes;
-  }
-
-  // Helpers for sorting and generating leak reports
-  struct Entry;
-  struct ReportState;
-  static void ReportCallback(const void* ptr, AllocValue* v, ReportState*);
-  static void ReportObject(const void* ptr, AllocValue* v, char*);
-};
-
-#endif  // BASE_HEAP_PROFILE_TABLE_H_
diff --git a/third_party/tcmalloc/chromium/src/heap-profiler.cc b/third_party/tcmalloc/chromium/src/heap-profiler.cc
deleted file mode 100644
index b46bd547..0000000
--- a/third_party/tcmalloc/chromium/src/heap-profiler.cc
+++ /dev/null
@@ -1,623 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// TODO: Log large allocations
-
-#include <config.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>    // for open()
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <signal.h>
-
-#include <algorithm>
-#include <string>
-
-#include <gperftools/heap-profiler.h>
-
-#include "base/logging.h"
-#include "base/basictypes.h"   // for PRId64, among other things
-#include "base/googleinit.h"
-#include "base/commandlineflags.h"
-#include "malloc_hook-inl.h"
-#include "tcmalloc_guard.h"
-#include <gperftools/malloc_hook.h>
-#include <gperftools/malloc_extension.h>
-#include "base/spinlock.h"
-#include "base/low_level_alloc.h"
-#include "base/sysinfo.h"      // for GetUniquePathFromEnv()
-#include "heap-profile-table.h"
-#include "memory_region_map.h"
-
-
-#ifndef	PATH_MAX
-#ifdef MAXPATHLEN
-#define	PATH_MAX	MAXPATHLEN
-#else
-#define	PATH_MAX	4096         // seems conservative for max filename len!
-#endif
-#endif
-
-using STL_NAMESPACE::string;
-using STL_NAMESPACE::sort;
-
-//----------------------------------------------------------------------
-// Flags that control heap-profiling
-//
-// The thread-safety of the profiler depends on these being immutable
-// after main starts, so don't change them.
-//----------------------------------------------------------------------
-
-DEFINE_int64(heap_profile_allocation_interval,
-             EnvToInt64("HEAP_PROFILE_ALLOCATION_INTERVAL", 1 << 30 /*1GB*/),
-             "If non-zero, dump heap profiling information once every "
-             "specified number of bytes allocated by the program since "
-             "the last dump.");
-DEFINE_int64(heap_profile_deallocation_interval,
-             EnvToInt64("HEAP_PROFILE_DEALLOCATION_INTERVAL", 0),
-             "If non-zero, dump heap profiling information once every "
-             "specified number of bytes deallocated by the program "
-             "since the last dump.");
-// We could also add flags that report whenever inuse_bytes changes by
-// X or -X, but there hasn't been a need for that yet, so we haven't.
-DEFINE_int64(heap_profile_inuse_interval,
-             EnvToInt64("HEAP_PROFILE_INUSE_INTERVAL", 100 << 20 /*100MB*/),
-             "If non-zero, dump heap profiling information whenever "
-             "the high-water memory usage mark increases by the specified "
-             "number of bytes.");
-DEFINE_int64(heap_profile_time_interval,
-             EnvToInt64("HEAP_PROFILE_TIME_INTERVAL", 0),
-             "If non-zero, dump heap profiling information once every "
-             "specified number of seconds since the last dump.");
-DEFINE_bool(mmap_log,
-            EnvToBool("HEAP_PROFILE_MMAP_LOG", false),
-            "Should mmap/munmap calls be logged?");
-DEFINE_bool(mmap_profile,
-            EnvToBool("HEAP_PROFILE_MMAP", false),
-            "If heap-profiling is on, also profile mmap, mremap, and sbrk)");
-DEFINE_bool(only_mmap_profile,
-            EnvToBool("HEAP_PROFILE_ONLY_MMAP", false),
-            "If heap-profiling is on, only profile mmap, mremap, and sbrk; "
-            "do not profile malloc/new/etc");
-
-
-//----------------------------------------------------------------------
-// Locking
-//----------------------------------------------------------------------
-
-// A pthread_mutex has way too much lock contention to be used here.
-//
-// I would like to use Mutex, but it can call malloc(),
-// which can cause us to fall into an infinite recursion.
-//
-// So we use a simple spinlock.
-static SpinLock heap_lock(SpinLock::LINKER_INITIALIZED);
-
-//----------------------------------------------------------------------
-// Simple allocator for heap profiler's internal memory
-//----------------------------------------------------------------------
-
-static LowLevelAlloc::Arena *heap_profiler_memory;
-
-static void* ProfilerMalloc(size_t bytes) {
-  return LowLevelAlloc::AllocWithArena(bytes, heap_profiler_memory);
-}
-static void ProfilerFree(void* p) {
-  LowLevelAlloc::Free(p);
-}
-
-// We use buffers of this size in DoGetHeapProfile.
-static const int kProfileBufferSize = 1 << 20;
-
-// This is a last-ditch buffer we use in DumpProfileLocked in case we
-// can't allocate more memory from ProfilerMalloc.  We expect this
-// will be used by HeapProfileEndWriter when the application has to
-// exit due to out-of-memory.  This buffer is allocated in
-// HeapProfilerStart.  Access to this must be protected by heap_lock.
-static char* global_profiler_buffer = NULL;
-
-
-//----------------------------------------------------------------------
-// Profiling control/state data
-//----------------------------------------------------------------------
-
-// Access to all of these is protected by heap_lock.
-static bool  is_on = false;           // If are on as a subsytem.
-static bool  dumping = false;         // Dumping status to prevent recursion
-static char* filename_prefix = NULL;  // Prefix used for profile file names
-                                      // (NULL if no need for dumping yet)
-static int   dump_count = 0;          // How many dumps so far
-static int64 last_dump_alloc = 0;     // alloc_size when did we last dump
-static int64 last_dump_free = 0;      // free_size when did we last dump
-static int64 high_water_mark = 0;     // In-use-bytes at last high-water dump
-static int64 last_dump_time = 0;      // The time of the last dump
-
-static HeapProfileTable* heap_profile = NULL;  // the heap profile table
-
-//----------------------------------------------------------------------
-// Profile generation
-//----------------------------------------------------------------------
-
-// Input must be a buffer of size at least 1MB.
-static char* DoGetHeapProfileLocked(char* buf, int buflen) {
-  // We used to be smarter about estimating the required memory and
-  // then capping it to 1MB and generating the profile into that.
-  if (buf == NULL || buflen < 1)
-    return NULL;
-
-  RAW_DCHECK(heap_lock.IsHeld(), "");
-  int bytes_written = 0;
-  if (is_on) {
-    HeapProfileTable::Stats const stats = heap_profile->total();
-    (void)stats;   // avoid an unused-variable warning in non-debug mode.
-    bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
-    // FillOrderedProfile should not reduce the set of active mmap-ed regions,
-    // hence MemoryRegionMap will let us remove everything we've added above:
-    RAW_DCHECK(stats.Equivalent(heap_profile->total()), "");
-    // if this fails, we somehow removed by FillOrderedProfile
-    // more than we have added.
-  }
-  buf[bytes_written] = '\0';
-  RAW_DCHECK(bytes_written == strlen(buf), "");
-
-  return buf;
-}
-
-extern "C" char* GetHeapProfile() {
-  // Use normal malloc: we return the profile to the user to free it:
-  char* buffer = reinterpret_cast<char*>(malloc(kProfileBufferSize));
-  SpinLockHolder l(&heap_lock);
-  return DoGetHeapProfileLocked(buffer, kProfileBufferSize);
-}
-
-// defined below
-static void NewHook(const void* ptr, size_t size);
-static void DeleteHook(const void* ptr);
-
-// Helper for HeapProfilerDump.
-static void DumpProfileLocked(const char* reason) {
-  RAW_DCHECK(heap_lock.IsHeld(), "");
-  RAW_DCHECK(is_on, "");
-  RAW_DCHECK(!dumping, "");
-
-  if (filename_prefix == NULL) return;  // we do not yet need dumping
-
-  dumping = true;
-
-  // Make file name
-  char file_name[1000];
-  dump_count++;
-  snprintf(file_name, sizeof(file_name), "%s.%05d.%04d%s",
-           filename_prefix, getpid(), dump_count, HeapProfileTable::kFileExt);
-
-  // Dump the profile
-  RAW_VLOG(0, "Dumping heap profile to %s (%s)", file_name, reason);
-  // We must use file routines that don't access memory, since we hold
-  // a memory lock now.
-  RawFD fd = RawOpenForWriting(file_name);
-  if (fd == kIllegalRawFD) {
-    RAW_LOG(ERROR, "Failed dumping heap profile to %s", file_name);
-    dumping = false;
-    return;
-  }
-
-  // This case may be impossible, but it's best to be safe.
-  // It's safe to use the global buffer: we're protected by heap_lock.
-  if (global_profiler_buffer == NULL) {
-    global_profiler_buffer =
-        reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
-  }
-
-  char* profile = DoGetHeapProfileLocked(global_profiler_buffer,
-                                         kProfileBufferSize);
-  RawWrite(fd, profile, strlen(profile));
-  RawClose(fd);
-
-  dumping = false;
-}
-
-//----------------------------------------------------------------------
-// Profile collection
-//----------------------------------------------------------------------
-
-// Dump a profile after either an allocation or deallocation, if
-// the memory use has changed enough since the last dump.
-static void MaybeDumpProfileLocked() {
-  if (!dumping) {
-    const HeapProfileTable::Stats& total = heap_profile->total();
-    const int64 inuse_bytes = total.alloc_size - total.free_size;
-    bool need_to_dump = false;
-    char buf[128];
-
-    if (FLAGS_heap_profile_allocation_interval > 0 &&
-        total.alloc_size >=
-        last_dump_alloc + FLAGS_heap_profile_allocation_interval) {
-      snprintf(buf, sizeof(buf), ("%" PRId64 " MB allocated cumulatively, "
-                                  "%" PRId64 " MB currently in use"),
-               total.alloc_size >> 20, inuse_bytes >> 20);
-      need_to_dump = true;
-    } else if (FLAGS_heap_profile_deallocation_interval > 0 &&
-               total.free_size >=
-               last_dump_free + FLAGS_heap_profile_deallocation_interval) {
-      snprintf(buf, sizeof(buf), ("%" PRId64 " MB freed cumulatively, "
-                                  "%" PRId64 " MB currently in use"),
-               total.free_size >> 20, inuse_bytes >> 20);
-      need_to_dump = true;
-    } else if (FLAGS_heap_profile_inuse_interval > 0 &&
-               inuse_bytes >
-               high_water_mark + FLAGS_heap_profile_inuse_interval) {
-      snprintf(buf, sizeof(buf), "%" PRId64 " MB currently in use",
-               inuse_bytes >> 20);
-      need_to_dump = true;
-    } else if (FLAGS_heap_profile_time_interval > 0 ) {
-      int64 current_time = time(NULL);
-      if (current_time - last_dump_time >=
-          FLAGS_heap_profile_time_interval) {
-        snprintf(buf, sizeof(buf), "%" PRId64 " sec since the last dump",
-                 current_time - last_dump_time);
-        need_to_dump = true;
-        last_dump_time = current_time;
-      }
-    }
-    if (need_to_dump) {
-      DumpProfileLocked(buf);
-
-      last_dump_alloc = total.alloc_size;
-      last_dump_free = total.free_size;
-      if (inuse_bytes > high_water_mark)
-        high_water_mark = inuse_bytes;
-    }
-  }
-}
-
-// Record an allocation in the profile.
-static void RecordAlloc(const void* ptr, size_t bytes, int skip_count) {
-  // Take the stack trace outside the critical section.
-  void* stack[HeapProfileTable::kMaxStackDepth];
-  int depth = HeapProfileTable::GetCallerStackTrace(skip_count + 1, stack);
-  SpinLockHolder l(&heap_lock);
-  if (is_on) {
-    heap_profile->RecordAlloc(ptr, bytes, depth, stack);
-    MaybeDumpProfileLocked();
-  }
-}
-
-// Record a deallocation in the profile.
-static void RecordFree(const void* ptr) {
-  SpinLockHolder l(&heap_lock);
-  if (is_on) {
-    heap_profile->RecordFree(ptr);
-    MaybeDumpProfileLocked();
-  }
-}
-
-//----------------------------------------------------------------------
-// Allocation/deallocation hooks for MallocHook
-//----------------------------------------------------------------------
-
-// static
-void NewHook(const void* ptr, size_t size) {
-  if (ptr != NULL) RecordAlloc(ptr, size, 0);
-}
-
-// static
-void DeleteHook(const void* ptr) {
-  if (ptr != NULL) RecordFree(ptr);
-}
-
-// TODO(jandrews): Re-enable stack tracing
-#ifdef TODO_REENABLE_STACK_TRACING
-static void RawInfoStackDumper(const char* message, void*) {
-  RAW_LOG(INFO, "%.*s", static_cast<int>(strlen(message) - 1), message);
-  // -1 is to chop the \n which will be added by RAW_LOG
-}
-#endif
-
-static void MmapHook(const void* result, const void* start, size_t size,
-                     int prot, int flags, int fd, off_t offset) {
-  if (FLAGS_mmap_log) {  // log it
-    // We use PRIxS not just '%p' to avoid deadlocks
-    // in pretty-printing of NULL as "nil".
-    // TODO(maxim): instead should use a safe snprintf reimplementation
-    RAW_LOG(INFO,
-            "mmap(start=0x%" PRIxPTR ", len=%" PRIuS ", prot=0x%x, flags=0x%x, "
-            "fd=%d, offset=0x%x) = 0x%" PRIxPTR "",
-            (uintptr_t) start, size, prot, flags, fd, (unsigned int) offset,
-            (uintptr_t) result);
-#ifdef TODO_REENABLE_STACK_TRACING
-    DumpStackTrace(1, RawInfoStackDumper, NULL);
-#endif
-  }
-}
-
-static void MremapHook(const void* result, const void* old_addr,
-                       size_t old_size, size_t new_size,
-                       int flags, const void* new_addr) {
-  if (FLAGS_mmap_log) {  // log it
-    // We use PRIxS not just '%p' to avoid deadlocks
-    // in pretty-printing of NULL as "nil".
-    // TODO(maxim): instead should use a safe snprintf reimplementation
-    RAW_LOG(INFO,
-            "mremap(old_addr=0x%" PRIxPTR ", old_size=%" PRIuS ", "
-            "new_size=%" PRIuS ", flags=0x%x, new_addr=0x%" PRIxPTR ") = "
-            "0x%" PRIxPTR "",
-            (uintptr_t) old_addr, old_size, new_size, flags,
-            (uintptr_t) new_addr, (uintptr_t) result);
-#ifdef TODO_REENABLE_STACK_TRACING
-    DumpStackTrace(1, RawInfoStackDumper, NULL);
-#endif
-  }
-}
-
-static void MunmapHook(const void* ptr, size_t size) {
-  if (FLAGS_mmap_log) {  // log it
-    // We use PRIxS not just '%p' to avoid deadlocks
-    // in pretty-printing of NULL as "nil".
-    // TODO(maxim): instead should use a safe snprintf reimplementation
-    RAW_LOG(INFO, "munmap(start=0x%" PRIxPTR ", len=%" PRIuS ")",
-                  (uintptr_t) ptr, size);
-#ifdef TODO_REENABLE_STACK_TRACING
-    DumpStackTrace(1, RawInfoStackDumper, NULL);
-#endif
-  }
-}
-
-static void SbrkHook(const void* result, ptrdiff_t increment) {
-  if (FLAGS_mmap_log) {  // log it
-    RAW_LOG(INFO, "sbrk(inc=%" PRIdS ") = 0x%" PRIxPTR "",
-                  increment, (uintptr_t) result);
-#ifdef TODO_REENABLE_STACK_TRACING
-    DumpStackTrace(1, RawInfoStackDumper, NULL);
-#endif
-  }
-}
-
-//----------------------------------------------------------------------
-// Starting/stopping/dumping
-//----------------------------------------------------------------------
-
-extern "C" void HeapProfilerStart(const char* prefix) {
-  SpinLockHolder l(&heap_lock);
-
-  if (is_on) return;
-
-  is_on = true;
-
-  RAW_VLOG(0, "Starting tracking the heap");
-
-  // This should be done before the hooks are set up, since it should
-  // call new, and we want that to be accounted for correctly.
-  MallocExtension::Initialize();
-
-  if (FLAGS_only_mmap_profile) {
-    FLAGS_mmap_profile = true;
-  }
-
-  if (FLAGS_mmap_profile) {
-    // Ask MemoryRegionMap to record all mmap, mremap, and sbrk
-    // call stack traces of at least size kMaxStackDepth:
-    MemoryRegionMap::Init(HeapProfileTable::kMaxStackDepth,
-                          /* use_buckets */ true);
-  }
-
-  if (FLAGS_mmap_log) {
-    // Install our hooks to do the logging:
-    RAW_CHECK(MallocHook::AddMmapHook(&MmapHook), "");
-    RAW_CHECK(MallocHook::AddMremapHook(&MremapHook), "");
-    RAW_CHECK(MallocHook::AddMunmapHook(&MunmapHook), "");
-    RAW_CHECK(MallocHook::AddSbrkHook(&SbrkHook), "");
-  }
-
-  heap_profiler_memory =
-    LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
-
-  // Reserve space now for the heap profiler, so we can still write a
-  // heap profile even if the application runs out of memory.
-  global_profiler_buffer =
-      reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
-
-  heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable)))
-      HeapProfileTable(ProfilerMalloc, ProfilerFree, FLAGS_mmap_profile);
-
-  last_dump_alloc = 0;
-  last_dump_free = 0;
-  high_water_mark = 0;
-  last_dump_time = 0;
-
-  // We do not reset dump_count so if the user does a sequence of
-  // HeapProfilerStart/HeapProfileStop, we will get a continuous
-  // sequence of profiles.
-
-  if (FLAGS_only_mmap_profile == false) {
-    // Now set the hooks that capture new/delete and malloc/free.
-    RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
-    RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
-  }
-
-  // Copy filename prefix
-  RAW_DCHECK(filename_prefix == NULL, "");
-  const int prefix_length = strlen(prefix);
-  filename_prefix = reinterpret_cast<char*>(ProfilerMalloc(prefix_length + 1));
-  memcpy(filename_prefix, prefix, prefix_length);
-  filename_prefix[prefix_length] = '\0';
-}
-
-extern "C" int IsHeapProfilerRunning() {
-  SpinLockHolder l(&heap_lock);
-  return is_on ? 1 : 0;   // return an int, because C code doesn't have bool
-}
-
-extern "C" void HeapProfilerStop() {
-  SpinLockHolder l(&heap_lock);
-
-  if (!is_on) return;
-
-  if (FLAGS_only_mmap_profile == false) {
-    // Unset our new/delete hooks, checking they were set:
-    RAW_CHECK(MallocHook::RemoveNewHook(&NewHook), "");
-    RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), "");
-  }
-  if (FLAGS_mmap_log) {
-    // Restore mmap/sbrk hooks, checking that our hooks were set:
-    RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), "");
-    RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), "");
-    RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), "");
-    RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
-  }
-
-  // free profile
-  heap_profile->~HeapProfileTable();
-  ProfilerFree(heap_profile);
-  heap_profile = NULL;
-
-  // free output-buffer memory
-  ProfilerFree(global_profiler_buffer);
-
-  // free prefix
-  ProfilerFree(filename_prefix);
-  filename_prefix = NULL;
-
-  if (!LowLevelAlloc::DeleteArena(heap_profiler_memory)) {
-    RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
-  }
-
-  if (FLAGS_mmap_profile) {
-    MemoryRegionMap::Shutdown();
-  }
-
-  is_on = false;
-}
-
-extern "C" void HeapProfilerDump(const char *reason) {
-  SpinLockHolder l(&heap_lock);
-  if (is_on && !dumping) {
-    DumpProfileLocked(reason);
-  }
-}
-
-// Signal handler that is registered when a user selectable signal
-// number is defined in the environment variable HEAPPROFILESIGNAL.
-static void HeapProfilerDumpSignal(int signal_number) {
-  (void)signal_number;
-  if (!heap_lock.TryLock()) {
-    return;
-  }
-  if (is_on && !dumping) {
-    DumpProfileLocked("signal");
-  }
-  heap_lock.Unlock();
-}
-
-
-//----------------------------------------------------------------------
-// Initialization/finalization code
-//----------------------------------------------------------------------
-#if defined(ENABLE_PROFILING)
-// Initialization code
-static void HeapProfilerInit() {
-  // Everything after this point is for setting up the profiler based on envvar
-  char fname[PATH_MAX];
-  if (!GetUniquePathFromEnv("HEAPPROFILE", fname)) {
-    return;
-  }
-  // We do a uid check so we don't write out files in a setuid executable.
-#ifdef HAVE_GETEUID
-  if (getuid() != geteuid()) {
-    RAW_LOG(WARNING, ("HeapProfiler: ignoring HEAPPROFILE because "
-                      "program seems to be setuid\n"));
-    return;
-  }
-#endif
-
-  char *signal_number_str = getenv("HEAPPROFILESIGNAL");
-  if (signal_number_str != NULL) {
-    long int signal_number = strtol(signal_number_str, NULL, 10);
-    intptr_t old_signal_handler = reinterpret_cast<intptr_t>(signal(signal_number, HeapProfilerDumpSignal));
-    if (old_signal_handler == reinterpret_cast<intptr_t>(SIG_ERR)) {
-      RAW_LOG(FATAL, "Failed to set signal. Perhaps signal number %s is invalid\n", signal_number_str);
-    } else if (old_signal_handler == 0) {
-      RAW_LOG(INFO,"Using signal %d as heap profiling switch", signal_number);
-    } else {
-      RAW_LOG(FATAL, "Signal %d already in use\n", signal_number);
-    }
-  }
-
-  HeapProfileTable::CleanupOldProfiles(fname);
-
-  HeapProfilerStart(fname);
-}
-
-// class used for finalization -- dumps the heap-profile at program exit
-struct HeapProfileEndWriter {
-  ~HeapProfileEndWriter() {
-    char buf[128];
-    if (heap_profile) {
-      const HeapProfileTable::Stats& total = heap_profile->total();
-      const int64 inuse_bytes = total.alloc_size - total.free_size;
-
-      if ((inuse_bytes >> 20) > 0) {
-        snprintf(buf, sizeof(buf), ("Exiting, %" PRId64 " MB in use"),
-                 inuse_bytes >> 20);
-      } else if ((inuse_bytes >> 10) > 0) {
-        snprintf(buf, sizeof(buf), ("Exiting, %" PRId64 " kB in use"),
-                 inuse_bytes >> 10);
-      } else {
-        snprintf(buf, sizeof(buf), ("Exiting, %" PRId64 " bytes in use"),
-                 inuse_bytes);
-      }
-    } else {
-      snprintf(buf, sizeof(buf), ("Exiting"));
-    }
-    HeapProfilerDump(buf);
-  }
-};
-
-// We want to make sure tcmalloc is up and running before starting the profiler
-static const TCMallocGuard tcmalloc_initializer;
-REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
-static HeapProfileEndWriter heap_profile_end_writer;
-#endif  // defined(ENABLE_PROFILING)
diff --git a/third_party/tcmalloc/chromium/src/internal_logging.cc b/third_party/tcmalloc/chromium/src/internal_logging.cc
deleted file mode 100644
index 2b462de8..0000000
--- a/third_party/tcmalloc/chromium/src/internal_logging.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-#include "internal_logging.h"
-#include <stdarg.h>                     // for va_end, va_start
-#include <stdio.h>                      // for vsnprintf, va_list, etc
-#include <stdlib.h>                     // for abort
-#include <string.h>                     // for strlen, memcpy
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for write()
-#endif
-
-#include <gperftools/malloc_extension.h>
-#include "base/abort.h"
-#include "base/logging.h"   // for perftools_vsnprintf
-#include "base/spinlock.h"              // for SpinLockHolder, SpinLock
-
-// Variables for storing crash output.  Allocated statically since we
-// may not be able to heap-allocate while crashing.
-static SpinLock crash_lock(base::LINKER_INITIALIZED);
-static bool crashed = false;
-static const int kStatsBufferSize = 16 << 10;
-static char stats_buffer[kStatsBufferSize] = { 0 };
-
-namespace tcmalloc {
-
-static void WriteMessage(const char* msg, int length) {
-  write(STDERR_FILENO, msg, length);
-}
-
-void (*log_message_writer)(const char* msg, int length) = WriteMessage;
-
-
-class Logger {
- public:
-  bool Add(const LogItem& item);
-  bool AddStr(const char* str, int n);
-  bool AddNum(uint64_t num, int base);  // base must be 10 or 16.
-
-  static const int kBufSize = 200;
-  char* p_;
-  char* end_;
-  char buf_[kBufSize];
-};
-
-void Log(LogMode mode, const char* filename, int line,
-         LogItem a, LogItem b, LogItem c, LogItem d) {
-  Logger state;
-  state.p_ = state.buf_;
-  state.end_ = state.buf_ + sizeof(state.buf_);
-  state.AddStr(filename, strlen(filename))
-      && state.AddStr(":", 1)
-      && state.AddNum(line, 10)
-      && state.AddStr("]", 1)
-      && state.Add(a)
-      && state.Add(b)
-      && state.Add(c)
-      && state.Add(d);
-
-  // Teminate with newline
-  if (state.p_ >= state.end_) {
-    state.p_ = state.end_ - 1;
-  }
-  *state.p_ = '\n';
-  state.p_++;
-
-  int msglen = state.p_ - state.buf_;
-  if (mode == kLog) {
-    (*log_message_writer)(state.buf_, msglen);
-    return;
-  }
-
-  bool first_crash = false;
-  {
-    SpinLockHolder l(&crash_lock);
-    if (!crashed) {
-      crashed = true;
-      first_crash = true;
-    }
-  }
-
-  (*log_message_writer)(state.buf_, msglen);
-  if (first_crash && mode == kCrashWithStats) {
-    MallocExtension::instance()->GetStats(stats_buffer, kStatsBufferSize);
-    (*log_message_writer)(stats_buffer, strlen(stats_buffer));
-  }
-
-  Abort();
-}
-
-bool Logger::Add(const LogItem& item) {
-  // Separate items with spaces
-  if (p_ < end_) {
-    *p_ = ' ';
-    p_++;
-  }
-
-  switch (item.tag_) {
-    case LogItem::kStr:
-      return AddStr(item.u_.str, strlen(item.u_.str));
-    case LogItem::kUnsigned:
-      return AddNum(item.u_.unum, 10);
-    case LogItem::kSigned:
-      if (item.u_.snum < 0) {
-        // The cast to uint64_t is intentionally before the negation
-        // so that we do not attempt to negate -2^63.
-        return AddStr("-", 1)
-            && AddNum(- static_cast<uint64_t>(item.u_.snum), 10);
-      } else {
-        return AddNum(static_cast<uint64_t>(item.u_.snum), 10);
-      }
-    case LogItem::kPtr:
-      return AddStr("0x", 2)
-          && AddNum(reinterpret_cast<uintptr_t>(item.u_.ptr), 16);
-    default:
-      return false;
-  }
-}
-
-bool Logger::AddStr(const char* str, int n) {
-  if (end_ - p_ < n) {
-    return false;
-  } else {
-    memcpy(p_, str, n);
-    p_ += n;
-    return true;
-  }
-}
-
-bool Logger::AddNum(uint64_t num, int base) {
-  static const char kDigits[] = "0123456789abcdef";
-  char space[22];  // more than enough for 2^64 in smallest supported base (10)
-  char* end = space + sizeof(space);
-  char* pos = end;
-  do {
-    pos--;
-    *pos = kDigits[num % base];
-    num /= base;
-  } while (num > 0 && pos > space);
-  return AddStr(pos, end - pos);
-}
-
-}  // end tcmalloc namespace
-
-void TCMalloc_Printer::printf(const char* format, ...) {
-  if (left_ > 0) {
-    va_list ap;
-    va_start(ap, format);
-    const int r = perftools_vsnprintf(buf_, left_, format, ap);
-    va_end(ap);
-    if (r < 0) {
-      // Perhaps an old glibc that returns -1 on truncation?
-      left_ = 0;
-    } else if (r > left_) {
-      // Truncation
-      left_ = 0;
-    } else {
-      left_ -= r;
-      buf_ += r;
-    }
-  }
-}
diff --git a/third_party/tcmalloc/chromium/src/internal_logging.h b/third_party/tcmalloc/chromium/src/internal_logging.h
deleted file mode 100644
index a3fa519..0000000
--- a/third_party/tcmalloc/chromium/src/internal_logging.h
+++ /dev/null
@@ -1,153 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// Internal logging and related utility routines.
-
-#ifndef TCMALLOC_INTERNAL_LOGGING_H_
-#define TCMALLOC_INTERNAL_LOGGING_H_
-
-#include <config.h>
-#include <stddef.h>                     // for size_t
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-
-//-------------------------------------------------------------------
-// Utility routines
-//-------------------------------------------------------------------
-
-// Safe logging helper: we write directly to the stderr file
-// descriptor and avoid FILE buffering because that may invoke
-// malloc().
-//
-// Example:
-//   Log(kLog, __FILE__, __LINE__, "error", bytes);
-
-namespace tcmalloc {
-enum LogMode {
-  kLog,                       // Just print the message
-  kCrash,                     // Print the message and crash
-  kCrashWithStats             // Print the message, some stats, and crash
-};
-
-class Logger;
-
-// A LogItem holds any of the argument types that can be passed to Log()
-class LogItem {
- public:
-  LogItem()                     : tag_(kEnd)      { }
-  LogItem(const char* v)        : tag_(kStr)      { u_.str = v; }
-  LogItem(int v)                : tag_(kSigned)   { u_.snum = v; }
-  LogItem(long v)               : tag_(kSigned)   { u_.snum = v; }
-  LogItem(long long v)          : tag_(kSigned)   { u_.snum = v; }
-  LogItem(unsigned int v)       : tag_(kUnsigned) { u_.unum = v; }
-  LogItem(unsigned long v)      : tag_(kUnsigned) { u_.unum = v; }
-  LogItem(unsigned long long v) : tag_(kUnsigned) { u_.unum = v; }
-  LogItem(const void* v)        : tag_(kPtr)      { u_.ptr = v; }
- private:
-  friend class Logger;
-  enum Tag {
-    kStr,
-    kSigned,
-    kUnsigned,
-    kPtr,
-    kEnd
-  };
-  Tag tag_;
-  union {
-    const char* str;
-    const void* ptr;
-    int64_t snum;
-    uint64_t unum;
-  } u_;
-};
-
-extern PERFTOOLS_DLL_DECL void Log(LogMode mode, const char* filename, int line,
-                LogItem a, LogItem b = LogItem(),
-                LogItem c = LogItem(), LogItem d = LogItem());
-
-// Tests can override this function to collect logging messages.
-extern PERFTOOLS_DLL_DECL void (*log_message_writer)(const char* msg, int length);
-
-}  // end tcmalloc namespace
-
-// Like assert(), but executed even in NDEBUG mode
-#undef CHECK_CONDITION
-#define CHECK_CONDITION(cond)                                            \
-do {                                                                     \
-  if (!(cond)) {                                                         \
-    ::tcmalloc::Log(::tcmalloc::kCrash, __FILE__, __LINE__, #cond);      \
-  }                                                                      \
-} while (0)
-
-#define CHECK_CONDITION_PRINT(cond, str)                            \
-  do {                                                              \
-    if (!(cond)) {                                                  \
-      ::tcmalloc::Log(::tcmalloc::kCrash, __FILE__, __LINE__, str); \
-    }                                                               \
-  } while (0)
-
-// Our own version of assert() so we can avoid hanging by trying to do
-// all kinds of goofy printing while holding the malloc lock.
-#ifndef NDEBUG
-#define ASSERT(cond) CHECK_CONDITION(cond)
-#define ASSERT_PRINT(cond, str) CHECK_CONDITION_PRINT(cond, str)
-#else
-#define ASSERT(cond) ((void) 0)
-#define ASSERT_PRINT(cond, str) ((void)0)
-#endif
-
-// Print into buffer
-class TCMalloc_Printer {
- private:
-  char* buf_;           // Where should we write next
-  int   left_;          // Space left in buffer (including space for \0)
-
- public:
-  // REQUIRES: "length > 0"
-  TCMalloc_Printer(char* buf, int length) : buf_(buf), left_(length) {
-    buf[0] = '\0';
-  }
-
-  void printf(const char* format, ...)
-#ifdef HAVE___ATTRIBUTE__
-    __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
-;
-};
-
-#endif  // TCMALLOC_INTERNAL_LOGGING_H_
diff --git a/third_party/tcmalloc/chromium/src/libc_override.h b/third_party/tcmalloc/chromium/src/libc_override.h
deleted file mode 100644
index 2fd58bf0..0000000
--- a/third_party/tcmalloc/chromium/src/libc_override.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// This .h file imports the code that causes tcmalloc to override libc
-// versions of malloc/free/new/delete/etc.  That is, it provides the
-// logic that makes it so calls to malloc(10) go through tcmalloc,
-// rather than the default (libc) malloc.
-//
-// This file also provides a method: ReplaceSystemAlloc(), that every
-// libc_override_*.h file it #includes is required to provide.  This
-// is called when first setting up tcmalloc -- that is, when a global
-// constructor in tcmalloc.cc is executed -- to do any initialization
-// work that may be required for this OS.  (Note we cannot entirely
-// control when tcmalloc is initialized, and the system may do some
-// mallocs and frees before this routine is called.)  It may be a
-// noop.
-//
-// Every libc has its own way of doing this, and sometimes the compiler
-// matters too, so we have a different file for each libc, and often
-// for different compilers and OS's.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_INL_H_
-#define TCMALLOC_LIBC_OVERRIDE_INL_H_
-
-#include <config.h>
-#ifdef HAVE_FEATURES_H
-#include <features.h>   // for __GLIBC__
-#endif
-#include <gperftools/tcmalloc.h>
-
-#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
-#define CPP_NOTHROW noexcept
-#define CPP_BADALLOC
-#else
-#define CPP_NOTHROW throw()
-#define CPP_BADALLOC throw(std::bad_alloc)
-#endif
-
-static void ReplaceSystemAlloc();  // defined in the .h files below
-
-#if defined(TCMALLOC_DONT_REPLACE_SYSTEM_ALLOC)
-// TCMALLOC_DONT_REPLACE_SYSTEM_ALLOC has the following semantic:
-//  - tcmalloc with all its tc_* (tc_malloc, tc_free) symbols is being built
-//    and linked as usual.
-//  - the default system allocator symbols (malloc, free, operator new) are NOT
-//    overridden. The embedded must take care of routing them to tc_* symbols.
-// This no-op #if block effectively prevents the inclusion of the
-// libc_override_* headers below.
-static void ReplaceSystemAlloc() {}
-
-// For windows, there are two ways to get tcmalloc.  If we're
-// patching, then src/windows/patch_function.cc will do the necessary
-// overriding here.  Otherwise, we doing the 'redefine' trick, where
-// we remove malloc/new/etc from mscvcrt.dll, and just need to define
-// them now.
-#elif defined(_WIN32) && defined(WIN32_DO_PATCHING)
-void PatchWindowsFunctions();   // in src/windows/patch_function.cc
-static void ReplaceSystemAlloc() { PatchWindowsFunctions(); }
-
-#elif defined(_WIN32) && !defined(WIN32_DO_PATCHING)
-// "libc_override_redefine.h" is included in the original gperftools.  But,
-// we define allocator functions in Chromium's base/allocator/allocator_shim.cc
-// on Windows.  We don't include libc_override_redefine.h here.
-// ReplaceSystemAlloc() is defined here instead.
-static void ReplaceSystemAlloc() {}
-
-#elif defined(__APPLE__)
-#include "libc_override_osx.h"
-
-#elif defined(__GLIBC__)
-#include "libc_override_glibc.h"
-
-// Not all gcc systems necessarily support weak symbols, but all the
-// ones I know of do, so for now just assume they all do.
-#elif defined(__GNUC__)
-#include "libc_override_gcc_and_weak.h"
-
-#else
-#error Need to add support for your libc/OS here
-
-#endif
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_INL_H_
diff --git a/third_party/tcmalloc/chromium/src/libc_override_gcc_and_weak.h b/third_party/tcmalloc/chromium/src/libc_override_gcc_and_weak.h
deleted file mode 100644
index 6875164..0000000
--- a/third_party/tcmalloc/chromium/src/libc_override_gcc_and_weak.h
+++ /dev/null
@@ -1,244 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Used to override malloc routines on systems that define the
-// memory allocation routines to be weak symbols in their libc
-// (almost all unix-based systems are like this), on gcc, which
-// suppports the 'alias' attribute.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_GCC_AND_WEAK_INL_H_
-#define TCMALLOC_LIBC_OVERRIDE_GCC_AND_WEAK_INL_H_
-
-#ifdef HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>    // for __THROW
-#endif
-#include <gperftools/tcmalloc.h>
-
-#include "getenv_safe.h" // TCMallocGetenvSafe
-#include "base/commandlineflags.h"
-
-#ifndef __THROW    // I guess we're not on a glibc-like system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-#ifndef __GNUC__
-# error libc_override_gcc_and_weak.h is for gcc distributions only.
-#endif
-
-#define ALIAS(tc_fn)   __attribute__ ((alias (#tc_fn), used))
-
-void* operator new(size_t size) CPP_BADALLOC  ALIAS(tc_new);
-void operator delete(void* p) CPP_NOTHROW     ALIAS(tc_delete);
-void* operator new[](size_t size) CPP_BADALLOC ALIAS(tc_newarray);
-void operator delete[](void* p) CPP_NOTHROW   ALIAS(tc_deletearray);
-void* operator new(size_t size, const std::nothrow_t& nt) CPP_NOTHROW
-                                              ALIAS(tc_new_nothrow);
-void* operator new[](size_t size, const std::nothrow_t& nt) CPP_NOTHROW
-                                              ALIAS(tc_newarray_nothrow);
-void operator delete(void* p, const std::nothrow_t& nt) CPP_NOTHROW
-                                              ALIAS(tc_delete_nothrow);
-void operator delete[](void* p, const std::nothrow_t& nt) CPP_NOTHROW
-                                              ALIAS(tc_deletearray_nothrow);
-
-#if defined(ENABLE_SIZED_DELETE)
-
-void operator delete(void *p, size_t size) CPP_NOTHROW
-    ALIAS(tc_delete_sized);
-void operator delete[](void *p, size_t size) CPP_NOTHROW
-    ALIAS(tc_deletearray_sized);
-
-#elif defined(ENABLE_DYNAMIC_SIZED_DELETE) && \
-  (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
-
-static void delegate_sized_delete(void *p, size_t s) {
-  (operator delete)(p);
-}
-
-static void delegate_sized_deletearray(void *p, size_t s) {
-  (operator delete[])(p);
-}
-
-extern "C" __attribute__((weak))
-int tcmalloc_sized_delete_enabled(void);
-
-static bool sized_delete_enabled(void) {
-  if (tcmalloc_sized_delete_enabled != 0) {
-    return !!tcmalloc_sized_delete_enabled();
-  }
-
-  const char *flag = TCMallocGetenvSafe("TCMALLOC_ENABLE_SIZED_DELETE");
-  return tcmalloc::commandlineflags::StringToBool(flag, false);
-}
-
-extern "C" {
-
-static void *resolve_delete_sized(void) {
-  if (sized_delete_enabled()) {
-    return reinterpret_cast<void *>(tc_delete_sized);
-  }
-  return reinterpret_cast<void *>(delegate_sized_delete);
-}
-
-static void *resolve_deletearray_sized(void) {
-  if (sized_delete_enabled()) {
-    return reinterpret_cast<void *>(tc_deletearray_sized);
-  }
-  return reinterpret_cast<void *>(delegate_sized_deletearray);
-}
-
-}
-
-void operator delete(void *p, size_t size) CPP_NOTHROW
-  __attribute__((ifunc("resolve_delete_sized")));
-void operator delete[](void *p, size_t size) CPP_NOTHROW
-  __attribute__((ifunc("resolve_deletearray_sized")));
-
-#else /* !ENABLE_SIZED_DELETE && !ENABLE_DYN_SIZED_DELETE */
-
-void operator delete(void *p, size_t size) CPP_NOTHROW
-  ALIAS(tc_delete);
-void operator delete[](void *p, size_t size) CPP_NOTHROW
-  ALIAS(tc_deletearray);
-
-#endif /* !ENABLE_SIZED_DELETE && !ENABLE_DYN_SIZED_DELETE */
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-void* operator new(size_t size, std::align_val_t al)
-    ALIAS(tc_new_aligned);
-void operator delete(void* p, std::align_val_t al) CPP_NOTHROW
-    ALIAS(tc_delete_aligned);
-void* operator new[](size_t size, std::align_val_t al)
-    ALIAS(tc_newarray_aligned);
-void operator delete[](void* p, std::align_val_t al) CPP_NOTHROW
-    ALIAS(tc_deletearray_aligned);
-void* operator new(size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
-    ALIAS(tc_new_aligned_nothrow);
-void* operator new[](size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
-    ALIAS(tc_newarray_aligned_nothrow);
-void operator delete(void* p, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
-    ALIAS(tc_delete_aligned_nothrow);
-void operator delete[](void* p, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
-    ALIAS(tc_deletearray_aligned_nothrow);
-
-#if defined(ENABLE_SIZED_DELETE)
-
-void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-    ALIAS(tc_delete_sized_aligned);
-void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-    ALIAS(tc_deletearray_sized_aligned);
-
-#else /* defined(ENABLE_SIZED_DELETE) */
-
-#if defined(ENABLE_DYNAMIC_SIZED_DELETE) && \
-  (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
-
-static void delegate_sized_aligned_delete(void *p, size_t s, std::align_val_t al) {
-  (operator delete)(p, al);
-}
-
-static void delegate_sized_aligned_deletearray(void *p, size_t s, std::align_val_t al) {
-  (operator delete[])(p, al);
-}
-
-extern "C" {
-
-static void *resolve_delete_sized_aligned(void) {
-  if (sized_delete_enabled()) {
-    return reinterpret_cast<void *>(tc_delete_sized_aligned);
-  }
-  return reinterpret_cast<void *>(delegate_sized_aligned_delete);
-}
-
-static void *resolve_deletearray_sized_aligned(void) {
-  if (sized_delete_enabled()) {
-    return reinterpret_cast<void *>(tc_deletearray_sized_aligned);
-  }
-  return reinterpret_cast<void *>(delegate_sized_aligned_deletearray);
-}
-
-}
-
-void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-  __attribute__((ifunc("resolve_delete_sized_aligned")));
-void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-  __attribute__((ifunc("resolve_deletearray_sized_aligned")));
-
-#else /* defined(ENABLE_DYN_SIZED_DELETE) */
-
-void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-  ALIAS(tc_delete);
-void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-  ALIAS(tc_deletearray);
-
-#endif /* defined(ENABLE_DYN_SIZED_DELETE) */
-
-#endif /* defined(ENABLE_SIZED_DELETE) */
-
-#endif /* defined(ENABLE_ALIGNED_NEW_DELETE) */
-
-extern "C" {
-  void* malloc(size_t size) __THROW               ALIAS(tc_malloc);
-  void free(void* ptr) __THROW                    ALIAS(tc_free);
-  void* realloc(void* ptr, size_t size) __THROW   ALIAS(tc_realloc);
-  void* calloc(size_t n, size_t size) __THROW     ALIAS(tc_calloc);
-  void cfree(void* ptr) __THROW                   ALIAS(tc_cfree);
-  void* memalign(size_t align, size_t s) __THROW  ALIAS(tc_memalign);
-  void* aligned_alloc(size_t align, size_t s) __THROW ALIAS(tc_memalign);
-  void* valloc(size_t size) __THROW               ALIAS(tc_valloc);
-  void* pvalloc(size_t size) __THROW              ALIAS(tc_pvalloc);
-  int posix_memalign(void** r, size_t a, size_t s) __THROW
-      ALIAS(tc_posix_memalign);
-#ifndef __UCLIBC__
-  void malloc_stats(void) __THROW                 ALIAS(tc_malloc_stats);
-#endif
-  int mallopt(int cmd, int value) __THROW         ALIAS(tc_mallopt);
-#ifdef HAVE_STRUCT_MALLINFO
-  struct mallinfo mallinfo(void) __THROW          ALIAS(tc_mallinfo);
-#endif
-  size_t malloc_size(void* p) __THROW             ALIAS(tc_malloc_size);
-#if defined(__ANDROID__)
-  size_t malloc_usable_size(const void* p) __THROW
-         ALIAS(tc_malloc_size);
-#else
-  size_t malloc_usable_size(void* p) __THROW      ALIAS(tc_malloc_size);
-#endif
-}   // extern "C"
-
-#undef ALIAS
-
-// No need to do anything at tcmalloc-registration time: we do it all
-// via overriding weak symbols (at link time).
-static void ReplaceSystemAlloc() { }
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_GCC_AND_WEAK_INL_H_
diff --git a/third_party/tcmalloc/chromium/src/libc_override_glibc.h b/third_party/tcmalloc/chromium/src/libc_override_glibc.h
deleted file mode 100644
index 3269213..0000000
--- a/third_party/tcmalloc/chromium/src/libc_override_glibc.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Used to override malloc routines on systems that are using glibc.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_GLIBC_INL_H_
-#define TCMALLOC_LIBC_OVERRIDE_GLIBC_INL_H_
-
-#include <config.h>
-#include <features.h>     // for __GLIBC__
-#include <gperftools/tcmalloc.h>
-
-#ifndef __GLIBC__
-# error libc_override_glibc.h is for glibc distributions only.
-#endif
-
-// In glibc, the memory-allocation methods are weak symbols, so we can
-// just override them with our own.  If we're using gcc, we can use
-// __attribute__((alias)) to do the overriding easily (exception:
-// Mach-O, which doesn't support aliases).  Otherwise we have to use a
-// function call.
-#if !defined(__GNUC__) || defined(__MACH__)
-
-// This also defines ReplaceSystemAlloc().
-# include "libc_override_redefine.h"  // defines functions malloc()/etc
-
-#else  // #if !defined(__GNUC__) || defined(__MACH__)
-
-// If we get here, we're a gcc system, so do all the overriding we do
-// with gcc.  This does the overriding of all the 'normal' memory
-// allocation.  This also defines ReplaceSystemAlloc().
-# include "libc_override_gcc_and_weak.h"
-
-// We also have to do some glibc-specific overriding.  Some library
-// routines on RedHat 9 allocate memory using malloc() and free it
-// using __libc_free() (or vice-versa).  Since we provide our own
-// implementations of malloc/free, we need to make sure that the
-// __libc_XXX variants (defined as part of glibc) also point to the
-// same implementations.  Since it only matters for redhat, we
-// do it inside the gcc #ifdef, since redhat uses gcc.
-// TODO(csilvers): only do this if we detect we're an old enough glibc?
-
-#define ALIAS(tc_fn)   __attribute__ ((alias (#tc_fn)))
-extern "C" {
-  void* __libc_malloc(size_t size)                ALIAS(tc_malloc);
-  void __libc_free(void* ptr)                     ALIAS(tc_free);
-  void* __libc_realloc(void* ptr, size_t size)    ALIAS(tc_realloc);
-  void* __libc_calloc(size_t n, size_t size)      ALIAS(tc_calloc);
-  void __libc_cfree(void* ptr)                    ALIAS(tc_cfree);
-  void* __libc_memalign(size_t align, size_t s)   ALIAS(tc_memalign);
-  void* __libc_valloc(size_t size)                ALIAS(tc_valloc);
-  void* __libc_pvalloc(size_t size)               ALIAS(tc_pvalloc);
-  int __posix_memalign(void** r, size_t a, size_t s)  ALIAS(tc_posix_memalign);
-}   // extern "C"
-#undef ALIAS
-
-#endif  // #if defined(__GNUC__) && !defined(__MACH__)
-
-// No need to write ReplaceSystemAlloc(); one of the #includes above
-// did it for us.
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_GLIBC_INL_H_
diff --git a/third_party/tcmalloc/chromium/src/libc_override_osx.h b/third_party/tcmalloc/chromium/src/libc_override_osx.h
deleted file mode 100644
index 9d5d6115..0000000
--- a/third_party/tcmalloc/chromium/src/libc_override_osx.h
+++ /dev/null
@@ -1,308 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Used to override malloc routines on OS X systems.  We use the
-// malloc-zone functionality built into OS X to register our malloc
-// routine.
-//
-// 1) We used to use the normal 'override weak libc malloc/etc'
-// technique for OS X.  This is not optimal because mach does not
-// support the 'alias' attribute, so we had to have forwarding
-// functions.  It also does not work very well with OS X shared
-// libraries (dylibs) -- in general, the shared libs don't use
-// tcmalloc unless run with the DYLD_FORCE_FLAT_NAMESPACE envvar.
-//
-// 2) Another approach would be to use an interposition array:
-//      static const interpose_t interposers[] __attribute__((section("__DATA, __interpose"))) = {
-//        { (void *)tc_malloc, (void *)malloc },
-//        { (void *)tc_free, (void *)free },
-//      };
-// This requires the user to set the DYLD_INSERT_LIBRARIES envvar, so
-// is not much better.
-//
-// 3) Registering a new malloc zone avoids all these issues:
-//  http://www.opensource.apple.com/source/Libc/Libc-583/include/malloc/malloc.h
-//  http://www.opensource.apple.com/source/Libc/Libc-583/gen/malloc.c
-// If we make tcmalloc the default malloc zone (undocumented but
-// possible) then all new allocs use it, even those in shared
-// libraries.  Allocs done before tcmalloc was installed, or in libs
-// that aren't using tcmalloc for some reason, will correctly go
-// through the malloc-zone interface when free-ing, and will pick up
-// the libc free rather than tcmalloc free.  So it should "never"
-// cause a crash (famous last words).
-//
-// 4) The routines one must define for one's own malloc have changed
-// between OS X versions.  This requires some hoops on our part, but
-// is only really annoying when it comes to posix_memalign.  The right
-// behavior there depends on what OS version tcmalloc was compiled on,
-// but also what OS version the program is running on.  For now, we
-// punt and don't implement our own posix_memalign.  Apps that really
-// care can use tc_posix_memalign directly.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_OSX_INL_H_
-#define TCMALLOC_LIBC_OVERRIDE_OSX_INL_H_
-
-#include <config.h>
-#ifdef HAVE_FEATURES_H
-#include <features.h>
-#endif
-#include <gperftools/tcmalloc.h>
-
-#if !defined(__APPLE__)
-# error libc_override_glibc-osx.h is for OS X distributions only.
-#endif
-
-#include <AvailabilityMacros.h>
-#include <malloc/malloc.h>
-
-namespace tcmalloc {
-  void CentralCacheLockAll();
-  void CentralCacheUnlockAll();
-}
-
-// from AvailabilityMacros.h
-#if defined(MAC_OS_X_VERSION_10_6) && \
-    MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
-extern "C" {
-  // This function is only available on 10.6 (and later) but the
-  // LibSystem headers do not use AvailabilityMacros.h to handle weak
-  // importing automatically.  This prototype is a copy of the one in
-  // <malloc/malloc.h> with the WEAK_IMPORT_ATTRBIUTE added.
-  extern malloc_zone_t *malloc_default_purgeable_zone(void)
-      WEAK_IMPORT_ATTRIBUTE;
-}
-#endif
-
-// We need to provide wrappers around all the libc functions.
-namespace {
-size_t mz_size(malloc_zone_t* zone, const void* ptr) {
-  if (MallocExtension::instance()->GetOwnership(ptr) != MallocExtension::kOwned)
-    return 0;  // malloc_zone semantics: return 0 if we don't own the memory
-
-  // TODO(csilvers): change this method to take a const void*, one day.
-  return MallocExtension::instance()->GetAllocatedSize(const_cast<void*>(ptr));
-}
-
-void* mz_malloc(malloc_zone_t* zone, size_t size) {
-  return tc_malloc(size);
-}
-
-void* mz_calloc(malloc_zone_t* zone, size_t num_items, size_t size) {
-  return tc_calloc(num_items, size);
-}
-
-void* mz_valloc(malloc_zone_t* zone, size_t size) {
-  return tc_valloc(size);
-}
-
-void mz_free(malloc_zone_t* zone, void* ptr) {
-  return tc_free(ptr);
-}
-
-void* mz_realloc(malloc_zone_t* zone, void* ptr, size_t size) {
-  return tc_realloc(ptr, size);
-}
-
-void* mz_memalign(malloc_zone_t* zone, size_t align, size_t size) {
-  return tc_memalign(align, size);
-}
-
-void mz_destroy(malloc_zone_t* zone) {
-  // A no-op -- we will not be destroyed!
-}
-
-// malloc_introspection callbacks.  I'm not clear on what all of these do.
-kern_return_t mi_enumerator(task_t task, void *,
-                            unsigned type_mask, vm_address_t zone_address,
-                            memory_reader_t reader,
-                            vm_range_recorder_t recorder) {
-  // Should enumerate all the pointers we have.  Seems like a lot of work.
-  return KERN_FAILURE;
-}
-
-size_t mi_good_size(malloc_zone_t *zone, size_t size) {
-  // I think it's always safe to return size, but we maybe could do better.
-  return size;
-}
-
-boolean_t mi_check(malloc_zone_t *zone) {
-  return MallocExtension::instance()->VerifyAllMemory();
-}
-
-void mi_print(malloc_zone_t *zone, boolean_t verbose) {
-  int bufsize = 8192;
-  if (verbose)
-    bufsize = 102400;   // I picked this size arbitrarily
-  char* buffer = new char[bufsize];
-  MallocExtension::instance()->GetStats(buffer, bufsize);
-  fprintf(stdout, "%s", buffer);
-  delete[] buffer;
-}
-
-void mi_log(malloc_zone_t *zone, void *address) {
-  // I don't think we support anything like this
-}
-
-void mi_force_lock(malloc_zone_t *zone) {
-  tcmalloc::CentralCacheLockAll();
-}
-
-void mi_force_unlock(malloc_zone_t *zone) {
-  tcmalloc::CentralCacheUnlockAll();
-}
-
-void mi_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) {
-  // TODO(csilvers): figure out how to fill these out
-  stats->blocks_in_use = 0;
-  stats->size_in_use = 0;
-  stats->max_size_in_use = 0;
-  stats->size_allocated = 0;
-}
-
-boolean_t mi_zone_locked(malloc_zone_t *zone) {
-  return false;  // Hopefully unneeded by us!
-}
-
-}  // unnamed namespace
-
-// OS X doesn't have pvalloc, cfree, malloc_statc, etc, so we can just
-// define our own. :-)  OS X supplies posix_memalign in some versions
-// but not others, either strongly or weakly linked, in a way that's
-// difficult enough to code to correctly, that I just don't try to
-// support either memalign() or posix_memalign().  If you need them
-// and are willing to code to tcmalloc, you can use tc_posix_memalign().
-extern "C" {
-  void  cfree(void* p)                   { tc_cfree(p);               }
-  void* pvalloc(size_t s)                { return tc_pvalloc(s);      }
-  void malloc_stats(void)                { tc_malloc_stats();         }
-  int mallopt(int cmd, int v)            { return tc_mallopt(cmd, v); }
-  // No struct mallinfo on OS X, so don't define mallinfo().
-  // An alias for malloc_size(), which OS X defines.
-  size_t malloc_usable_size(void* p)     { return tc_malloc_size(p); }
-}  // extern "C"
-
-static malloc_zone_t *get_default_zone() {
-   malloc_zone_t **zones = NULL;
-   unsigned int num_zones = 0;
-
-   /*
-    * On OSX 10.12, malloc_default_zone returns a special zone that is not
-    * present in the list of registered zones. That zone uses a "lite zone"
-    * if one is present (apparently enabled when malloc stack logging is
-    * enabled), or the first registered zone otherwise. In practice this
-    * means unless malloc stack logging is enabled, the first registered
-    * zone is the default.
-    * So get the list of zones to get the first one, instead of relying on
-    * malloc_default_zone.
-    */
-   if (KERN_SUCCESS != malloc_get_all_zones(0, NULL, (vm_address_t**) &zones,
-                                            &num_zones)) {
-       /* Reset the value in case the failure happened after it was set. */
-       num_zones = 0;
-   }
-
-   if (num_zones)
-     return zones[0];
-
-   return malloc_default_zone();
-}
-
-
-static void ReplaceSystemAlloc() {
-  static malloc_introspection_t tcmalloc_introspection;
-  memset(&tcmalloc_introspection, 0, sizeof(tcmalloc_introspection));
-
-  tcmalloc_introspection.enumerator = &mi_enumerator;
-  tcmalloc_introspection.good_size = &mi_good_size;
-  tcmalloc_introspection.check = &mi_check;
-  tcmalloc_introspection.print = &mi_print;
-  tcmalloc_introspection.log = &mi_log;
-  tcmalloc_introspection.force_lock = &mi_force_lock;
-  tcmalloc_introspection.force_unlock = &mi_force_unlock;
-
-  static malloc_zone_t tcmalloc_zone;
-  memset(&tcmalloc_zone, 0, sizeof(malloc_zone_t));
-
-  // Start with a version 4 zone which is used for OS X 10.4 and 10.5.
-  tcmalloc_zone.version = 4;
-  tcmalloc_zone.zone_name = "tcmalloc";
-  tcmalloc_zone.size = &mz_size;
-  tcmalloc_zone.malloc = &mz_malloc;
-  tcmalloc_zone.calloc = &mz_calloc;
-  tcmalloc_zone.valloc = &mz_valloc;
-  tcmalloc_zone.free = &mz_free;
-  tcmalloc_zone.realloc = &mz_realloc;
-  tcmalloc_zone.destroy = &mz_destroy;
-  tcmalloc_zone.batch_malloc = NULL;
-  tcmalloc_zone.batch_free = NULL;
-  tcmalloc_zone.introspect = &tcmalloc_introspection;
-
-  // from AvailabilityMacros.h
-#if defined(MAC_OS_X_VERSION_10_6) && \
-    MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
-  // Switch to version 6 on OSX 10.6 to support memalign.
-  tcmalloc_zone.version = 6;
-  tcmalloc_zone.free_definite_size = NULL;
-  tcmalloc_zone.memalign = &mz_memalign;
-  tcmalloc_introspection.zone_locked = &mi_zone_locked;
-
-  // Request the default purgable zone to force its creation. The
-  // current default zone is registered with the purgable zone for
-  // doing tiny and small allocs.  Sadly, it assumes that the default
-  // zone is the szone implementation from OS X and will crash if it
-  // isn't.  By creating the zone now, this will be true and changing
-  // the default zone won't cause a problem.  This only needs to
-  // happen when actually running on OS X 10.6 and higher (note the
-  // ifdef above only checks if we were *compiled* with 10.6 or
-  // higher; at runtime we have to check if this symbol is defined.)
-  if (malloc_default_purgeable_zone) {
-    malloc_default_purgeable_zone();
-  }
-#endif
-
-  // Register the tcmalloc zone. At this point, it will not be the
-  // default zone.
-  malloc_zone_register(&tcmalloc_zone);
-
-  // Unregister and reregister the default zone.  Unregistering swaps
-  // the specified zone with the last one registered which for the
-  // default zone makes the more recently registered zone the default
-  // zone.  The default zone is then re-registered to ensure that
-  // allocations made from it earlier will be handled correctly.
-  // Things are not guaranteed to work that way, but it's how they work now.
-  malloc_zone_t *default_zone = get_default_zone();
-  malloc_zone_unregister(default_zone);
-  malloc_zone_register(default_zone);
-}
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_OSX_INL_H_
diff --git a/third_party/tcmalloc/chromium/src/libc_override_redefine.h b/third_party/tcmalloc/chromium/src/libc_override_redefine.h
deleted file mode 100644
index 4d61b25..0000000
--- a/third_party/tcmalloc/chromium/src/libc_override_redefine.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Used on systems that don't have their own definition of
-// malloc/new/etc.  (Typically this will be a windows msvcrt.dll that
-// has been edited to remove the definitions.)  We can just define our
-// own as normal functions.
-//
-// This should also work on systems were all the malloc routines are
-// defined as weak symbols, and there's no support for aliasing.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_REDEFINE_H_
-#define TCMALLOC_LIBC_OVERRIDE_REDEFINE_H_
-
-void* operator new(size_t size)                  { return tc_new(size);       }
-void operator delete(void* p) CPP_NOTHROW        { tc_delete(p);              }
-void* operator new[](size_t size)                { return tc_newarray(size);  }
-void operator delete[](void* p) CPP_NOTHROW      { tc_deletearray(p);         }
-void* operator new(size_t size, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_new_nothrow(size, nt);
-}
-void* operator new[](size_t size, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_newarray_nothrow(size, nt);
-}
-void operator delete(void* ptr, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_delete_nothrow(ptr, nt);
-}
-void operator delete[](void* ptr, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_deletearray_nothrow(ptr, nt);
-}
-
-#ifdef ENABLE_SIZED_DELETE
-void operator delete(void* p, size_t s) CPP_NOTHROW  { tc_delete_sized(p, s);     }
-void operator delete[](void* p, size_t s) CPP_NOTHROW{ tc_deletearray_sized(p, s);}
-#endif
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-void* operator new(size_t size, std::align_val_t al) {
-  return tc_new_aligned(size, al);
-}
-void operator delete(void* p, std::align_val_t al) CPP_NOTHROW {
-  tc_delete_aligned(p, al);
-}
-void* operator new[](size_t size, std::align_val_t al) {
-  return tc_newarray_aligned(size, al);
-}
-void operator delete[](void* p, std::align_val_t al) CPP_NOTHROW {
-  tc_deletearray_aligned(p, al);
-}
-void* operator new(size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_new_aligned_nothrow(size, al, nt);
-}
-void* operator new[](size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_newarray_aligned_nothrow(size, al, nt);
-}
-void operator delete(void* ptr, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_delete_aligned_nothrow(ptr, al, nt);
-}
-void operator delete[](void* ptr, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_deletearray_aligned_nothrow(ptr, al, nt);
-}
-
-#ifdef ENABLE_SIZED_DELETE
-void operator delete(void* p, size_t s, std::align_val_t al) CPP_NOTHROW {
-  tc_delete_sized_aligned(p, s, al);
-}
-void operator delete[](void* p, size_t s, std::align_val_t al) CPP_NOTHROW {
-  tc_deletearray_sized_aligned(p, s, al);
-}
-#endif
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-extern "C" {
-  void* malloc(size_t s)                         { return tc_malloc(s);       }
-  void  free(void* p)                            { tc_free(p);                }
-  void* realloc(void* p, size_t s)               { return tc_realloc(p, s);   }
-  void* calloc(size_t n, size_t s)               { return tc_calloc(n, s);    }
-  void  cfree(void* p)                           { tc_cfree(p);               }
-  void* memalign(size_t a, size_t s)             { return tc_memalign(a, s);  }
-  void* aligned_alloc(size_t a, size_t s)        { return tc_memalign(a, s);  }
-  void* valloc(size_t s)                         { return tc_valloc(s);       }
-  void* pvalloc(size_t s)                        { return tc_pvalloc(s);      }
-  int posix_memalign(void** r, size_t a, size_t s)         {
-    return tc_posix_memalign(r, a, s);
-  }
-  void malloc_stats(void)                        { tc_malloc_stats();         }
-  int mallopt(int cmd, int v)                    { return tc_mallopt(cmd, v); }
-#ifdef HAVE_STRUCT_MALLINFO
-  struct mallinfo mallinfo(void)                 { return tc_mallinfo();      }
-#endif
-  size_t malloc_size(void* p)                    { return tc_malloc_size(p); }
-  size_t malloc_usable_size(void* p)             { return tc_malloc_size(p); }
-}  // extern "C"
-
-// No need to do anything at tcmalloc-registration time: we do it all
-// via overriding weak symbols (at link time).
-static void ReplaceSystemAlloc() { }
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_REDEFINE_H_
diff --git a/third_party/tcmalloc/chromium/src/linked_list.h b/third_party/tcmalloc/chromium/src/linked_list.h
deleted file mode 100644
index f25b6f89..0000000
--- a/third_party/tcmalloc/chromium/src/linked_list.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// Some very basic linked list functions for dealing with using void * as
-// storage.
-
-#ifndef TCMALLOC_LINKED_LIST_H_
-#define TCMALLOC_LINKED_LIST_H_
-
-#include <stddef.h>
-
-namespace tcmalloc {
-
-inline void *SLL_Next(void *t) {
-  return *(reinterpret_cast<void**>(t));
-}
-
-inline void SLL_SetNext(void *t, void *n) {
-  *(reinterpret_cast<void**>(t)) = n;
-}
-
-inline void SLL_Push(void **list, void *element) {
-  void *next = *list;
-  *list = element;
-  SLL_SetNext(element, next);
-}
-
-inline void *SLL_Pop(void **list) {
-  void *result = *list;
-  *list = SLL_Next(*list);
-  return result;
-}
-
-inline bool SLL_TryPop(void **list, void **rv) {
-  void *result = *list;
-  if (!result) {
-    return false;
-  }
-  void *next = SLL_Next(*list);
-  *list = next;
-  *rv = result;
-  return true;
-}
-
-// Remove N elements from a linked list to which head points.  head will be
-// modified to point to the new head.  start and end will point to the first
-// and last nodes of the range.  Note that end will point to NULL after this
-// function is called.
-inline void SLL_PopRange(void **head, int N, void **start, void **end) {
-  if (N == 0) {
-    *start = NULL;
-    *end = NULL;
-    return;
-  }
-
-  void *tmp = *head;
-  for (int i = 1; i < N; ++i) {
-    tmp = SLL_Next(tmp);
-  }
-
-  *start = *head;
-  *end = tmp;
-  *head = SLL_Next(tmp);
-  // Unlink range from list.
-  SLL_SetNext(tmp, NULL);
-}
-
-inline void SLL_PushRange(void **head, void *start, void *end) {
-  if (!start) return;
-  SLL_SetNext(end, *head);
-  *head = start;
-}
-
-inline size_t SLL_Size(void *head) {
-  int count = 0;
-  while (head) {
-    count++;
-    head = SLL_Next(head);
-  }
-  return count;
-}
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_LINKED_LIST_H_
diff --git a/third_party/tcmalloc/chromium/src/malloc_extension.cc b/third_party/tcmalloc/chromium/src/malloc_extension.cc
deleted file mode 100644
index 90b2a78..0000000
--- a/third_party/tcmalloc/chromium/src/malloc_extension.cc
+++ /dev/null
@@ -1,382 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-#include <atomic>
-#include <string>
-#include "base/dynamic_annotations.h"
-#include "base/sysinfo.h"    // for FillProcSelfMaps
-#ifndef NO_HEAP_CHECK
-#include "gperftools/heap-checker.h"
-#endif
-#include "gperftools/malloc_extension.h"
-#include "gperftools/malloc_extension_c.h"
-#include "maybe_threads.h"
-#include "base/googleinit.h"
-
-using STL_NAMESPACE::string;
-using STL_NAMESPACE::vector;
-
-static void DumpAddressMap(string* result) {
-  *result += "\nMAPPED_LIBRARIES:\n";
-  // We keep doubling until we get a fit
-  const size_t old_resultlen = result->size();
-  for (int amap_size = 10240; amap_size < 10000000; amap_size *= 2) {
-    result->resize(old_resultlen + amap_size);
-    bool wrote_all = false;
-    const int bytes_written =
-        tcmalloc::FillProcSelfMaps(&((*result)[old_resultlen]), amap_size,
-                                   &wrote_all);
-    if (wrote_all) {   // we fit!
-      (*result)[old_resultlen + bytes_written] = '\0';
-      result->resize(old_resultlen + bytes_written);
-      return;
-    }
-  }
-  result->reserve(old_resultlen);   // just don't print anything
-}
-
-// Note: this routine is meant to be called before threads are spawned.
-void MallocExtension::Initialize() {
-  static bool initialize_called = false;
-
-  if (initialize_called) return;
-  initialize_called = true;
-
-#ifdef __GLIBC__
-  // GNU libc++ versions 3.3 and 3.4 obey the environment variables
-  // GLIBCPP_FORCE_NEW and GLIBCXX_FORCE_NEW respectively.  Setting
-  // one of these variables forces the STL default allocator to call
-  // new() or delete() for each allocation or deletion.  Otherwise
-  // the STL allocator tries to avoid the high cost of doing
-  // allocations by pooling memory internally.  However, tcmalloc
-  // does allocations really fast, especially for the types of small
-  // items one sees in STL, so it's better off just using us.
-  // TODO: control whether we do this via an environment variable?
-  setenv("GLIBCPP_FORCE_NEW", "1", false /* no overwrite*/);
-  setenv("GLIBCXX_FORCE_NEW", "1", false /* no overwrite*/);
-
-  // Now we need to make the setenv 'stick', which it may not do since
-  // the env is flakey before main() is called.  But luckily stl only
-  // looks at this env var the first time it tries to do an alloc, and
-  // caches what it finds.  So we just cause an stl alloc here.
-  string dummy("I need to be allocated");
-  dummy += "!";         // so the definition of dummy isn't optimized out
-#endif  /* __GLIBC__ */
-}
-
-// SysAllocator implementation
-SysAllocator::~SysAllocator() {}
-
-// Default implementation -- does nothing
-MallocExtension::~MallocExtension() { }
-bool MallocExtension::VerifyAllMemory() { return true; }
-bool MallocExtension::VerifyNewMemory(const void* p) { return true; }
-bool MallocExtension::VerifyArrayNewMemory(const void* p) { return true; }
-bool MallocExtension::VerifyMallocMemory(const void* p) { return true; }
-
-bool MallocExtension::GetNumericProperty(const char* property, size_t* value) {
-  return false;
-}
-
-bool MallocExtension::SetNumericProperty(const char* property, size_t value) {
-  return false;
-}
-
-void MallocExtension::GetStats(char* buffer, int length) {
-  assert(length > 0);
-  buffer[0] = '\0';
-}
-
-bool MallocExtension::MallocMemoryStats(int* blocks, size_t* total,
-                                       int histogram[kMallocHistogramSize]) {
-  *blocks = 0;
-  *total = 0;
-  memset(histogram, 0, sizeof(*histogram) * kMallocHistogramSize);
-  return true;
-}
-
-void** MallocExtension::ReadStackTraces(int* sample_period) {
-  return NULL;
-}
-
-void** MallocExtension::ReadHeapGrowthStackTraces() {
-  return NULL;
-}
-
-void MallocExtension::MarkThreadIdle() {
-  // Default implementation does nothing
-}
-
-void MallocExtension::MarkThreadBusy() {
-  // Default implementation does nothing
-}
-
-SysAllocator* MallocExtension::GetSystemAllocator() {
-  return NULL;
-}
-
-void MallocExtension::SetSystemAllocator(SysAllocator *a) {
-  // Default implementation does nothing
-}
-
-void MallocExtension::ReleaseToSystem(size_t num_bytes) {
-  // Default implementation does nothing
-}
-
-void MallocExtension::ReleaseFreeMemory() {
-  ReleaseToSystem(static_cast<size_t>(-1));   // SIZE_T_MAX
-}
-
-void MallocExtension::SetMemoryReleaseRate(double rate) {
-  // Default implementation does nothing
-}
-
-double MallocExtension::GetMemoryReleaseRate() {
-  return -1.0;
-}
-
-size_t MallocExtension::GetEstimatedAllocatedSize(size_t size) {
-  return size;
-}
-
-size_t MallocExtension::GetAllocatedSize(const void* p) {
-  assert(GetOwnership(p) != kNotOwned);
-  return 0;
-}
-
-MallocExtension::Ownership MallocExtension::GetOwnership(const void* p) {
-  return kUnknownOwnership;
-}
-
-void MallocExtension::GetFreeListSizes(
-    vector<MallocExtension::FreeListInfo>* v) {
-  v->clear();
-}
-
-size_t MallocExtension::GetThreadCacheSize() {
-  return 0;
-}
-
-void MallocExtension::MarkThreadTemporarilyIdle() {
-  // Default implementation does nothing
-}
-
-// The current malloc extension object.
-
-std::atomic<MallocExtension*> MallocExtension::current_instance_;
-
-// static
-MallocExtension* MallocExtension::InitModule() {
-  MallocExtension* instance = new MallocExtension;
-#ifndef NO_HEAP_CHECK
-  HeapLeakChecker::IgnoreObject(instance);
-#endif
-  current_instance_.store(instance, std::memory_order_release);
-  return instance;
-}
-
-void MallocExtension::Register(MallocExtension* implementation) {
-  InitModuleOnce();
-  // When running under valgrind, our custom malloc is replaced with
-  // valgrind's one and malloc extensions will not work.  (Note:
-  // callers should be responsible for checking that they are the
-  // malloc that is really being run, before calling Register.  This
-  // is just here as an extra sanity check.)
-  if (!RunningOnValgrind()) {
-    current_instance_.store(implementation, std::memory_order_release);
-  }
-}
-
-// -----------------------------------------------------------------------
-// Heap sampling support
-// -----------------------------------------------------------------------
-
-namespace {
-
-// Accessors
-uintptr_t Count(void** entry) {
-  return reinterpret_cast<uintptr_t>(entry[0]);
-}
-uintptr_t Size(void** entry) {
-  return reinterpret_cast<uintptr_t>(entry[1]);
-}
-uintptr_t Depth(void** entry) {
-  return reinterpret_cast<uintptr_t>(entry[2]);
-}
-void* PC(void** entry, int i) {
-  return entry[3+i];
-}
-
-void PrintCountAndSize(MallocExtensionWriter* writer,
-                       uintptr_t count, uintptr_t size) {
-  char buf[100];
-  snprintf(buf, sizeof(buf),
-           "%6" PRIu64 ": %8" PRIu64 " [%6" PRIu64 ": %8" PRIu64 "] @",
-           static_cast<uint64>(count),
-           static_cast<uint64>(size),
-           static_cast<uint64>(count),
-           static_cast<uint64>(size));
-  writer->append(buf, strlen(buf));
-}
-
-void PrintHeader(MallocExtensionWriter* writer,
-                 const char* label, void** entries) {
-  // Compute the total count and total size
-  uintptr_t total_count = 0;
-  uintptr_t total_size = 0;
-  for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
-    total_count += Count(entry);
-    total_size += Size(entry);
-  }
-
-  const char* const kTitle = "heap profile: ";
-  writer->append(kTitle, strlen(kTitle));
-  PrintCountAndSize(writer, total_count, total_size);
-  writer->append(" ", 1);
-  writer->append(label, strlen(label));
-  writer->append("\n", 1);
-}
-
-void PrintStackEntry(MallocExtensionWriter* writer, void** entry) {
-  PrintCountAndSize(writer, Count(entry), Size(entry));
-
-  for (int i = 0; i < Depth(entry); i++) {
-    char buf[32];
-    snprintf(buf, sizeof(buf), " %p", PC(entry, i));
-    writer->append(buf, strlen(buf));
-  }
-  writer->append("\n", 1);
-}
-
-}
-
-void MallocExtension::GetHeapSample(MallocExtensionWriter* writer) {
-  int sample_period = 0;
-  void** entries = ReadStackTraces(&sample_period);
-  if (entries == NULL) {
-    const char* const kErrorMsg =
-        "This malloc implementation does not support sampling.\n"
-        "As of 2005/01/26, only tcmalloc supports sampling, and\n"
-        "you are probably running a binary that does not use\n"
-        "tcmalloc.\n";
-    writer->append(kErrorMsg, strlen(kErrorMsg));
-    return;
-  }
-
-  char label[32];
-  sprintf(label, "heap_v2/%d", sample_period);
-  PrintHeader(writer, label, entries);
-  for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
-    PrintStackEntry(writer, entry);
-  }
-  delete[] entries;
-
-  DumpAddressMap(writer);
-}
-
-void MallocExtension::GetHeapGrowthStacks(MallocExtensionWriter* writer) {
-  void** entries = ReadHeapGrowthStackTraces();
-  if (entries == NULL) {
-    const char* const kErrorMsg =
-        "This malloc implementation does not support "
-        "ReadHeapGrowthStackTraces().\n"
-        "As of 2005/09/27, only tcmalloc supports this, and you\n"
-        "are probably running a binary that does not use tcmalloc.\n";
-    writer->append(kErrorMsg, strlen(kErrorMsg));
-    return;
-  }
-
-  // Do not canonicalize the stack entries, so that we get a
-  // time-ordered list of stack traces, which may be useful if the
-  // client wants to focus on the latest stack traces.
-  PrintHeader(writer, "growth", entries);
-  for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
-    PrintStackEntry(writer, entry);
-  }
-  delete[] entries;
-
-  DumpAddressMap(writer);
-}
-
-void MallocExtension::Ranges(void* arg, RangeFunction func) {
-  // No callbacks by default
-}
-
-// These are C shims that work on the current instance.
-
-#define C_SHIM(fn, retval, paramlist, arglist)          \
-  extern "C" PERFTOOLS_DLL_DECL retval MallocExtension_##fn paramlist {    \
-    return MallocExtension::instance()->fn arglist;     \
-  }
-
-C_SHIM(VerifyAllMemory, int, (void), ());
-C_SHIM(VerifyNewMemory, int, (const void* p), (p));
-C_SHIM(VerifyArrayNewMemory, int, (const void* p), (p));
-C_SHIM(VerifyMallocMemory, int, (const void* p), (p));
-C_SHIM(MallocMemoryStats, int,
-       (int* blocks, size_t* total, int histogram[kMallocHistogramSize]),
-       (blocks, total, histogram));
-
-C_SHIM(GetStats, void,
-       (char* buffer, int buffer_length), (buffer, buffer_length));
-C_SHIM(GetNumericProperty, int,
-       (const char* property, size_t* value), (property, value));
-C_SHIM(SetNumericProperty, int,
-       (const char* property, size_t value), (property, value));
-
-C_SHIM(MarkThreadIdle, void, (void), ());
-C_SHIM(MarkThreadBusy, void, (void), ());
-C_SHIM(ReleaseFreeMemory, void, (void), ());
-C_SHIM(ReleaseToSystem, void, (size_t num_bytes), (num_bytes));
-C_SHIM(GetEstimatedAllocatedSize, size_t, (size_t size), (size));
-C_SHIM(GetAllocatedSize, size_t, (const void* p), (p));
-C_SHIM(GetThreadCacheSize, size_t, (void), ());
-C_SHIM(MarkThreadTemporarilyIdle, void, (void), ());
-
-// Can't use the shim here because of the need to translate the enums.
-extern "C"
-MallocExtension_Ownership MallocExtension_GetOwnership(const void* p) {
-  return static_cast<MallocExtension_Ownership>(
-      MallocExtension::instance()->GetOwnership(p));
-}
diff --git a/third_party/tcmalloc/chromium/src/malloc_hook-inl.h b/third_party/tcmalloc/chromium/src/malloc_hook-inl.h
deleted file mode 100644
index 30375d6..0000000
--- a/third_party/tcmalloc/chromium/src/malloc_hook-inl.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// This has the implementation details of malloc_hook that are needed
-// to use malloc-hook inside the tcmalloc system.  It does not hold
-// any of the client-facing calls that are used to add new hooks.
-
-#ifndef _MALLOC_HOOK_INL_H_
-#define _MALLOC_HOOK_INL_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-#include "base/atomicops.h"
-#include "base/basictypes.h"
-#include <gperftools/malloc_hook.h>
-
-#include "common.h" // for UNLIKELY
-
-namespace base { namespace internal {
-
-// Capacity of 8 means that HookList is 9 words.
-static const int kHookListCapacity = 8;
-// last entry is reserved for deprecated "singular" hooks. So we have
-// 7 "normal" hooks per list
-static const int kHookListMaxValues = 7;
-static const int kHookListSingularIdx = 7;
-
-// HookList: a class that provides synchronized insertions and removals and
-// lockless traversal.  Most of the implementation is in malloc_hook.cc.
-template <typename T>
-struct PERFTOOLS_DLL_DECL HookList {
-  COMPILE_ASSERT(sizeof(T) <= sizeof(AtomicWord), T_should_fit_in_AtomicWord);
-
-  // Adds value to the list.  Note that duplicates are allowed.  Thread-safe and
-  // blocking (acquires hooklist_spinlock).  Returns true on success; false
-  // otherwise (failures include invalid value and no space left).
-  bool Add(T value);
-
-  void FixupPrivEndLocked();
-
-  // Removes the first entry matching value from the list.  Thread-safe and
-  // blocking (acquires hooklist_spinlock).  Returns true on success; false
-  // otherwise (failures include invalid value and no value found).
-  bool Remove(T value);
-
-  // Store up to n values of the list in output_array, and return the number of
-  // elements stored.  Thread-safe and non-blocking.  This is fast (one memory
-  // access) if the list is empty.
-  int Traverse(T* output_array, int n) const;
-
-  // Fast inline implementation for fast path of Invoke*Hook.
-  bool empty() const {
-    return base::subtle::NoBarrier_Load(&priv_end) == 0;
-  }
-
-  // Used purely to handle deprecated singular hooks
-  T GetSingular() const {
-    const AtomicWord *place = &priv_data[kHookListSingularIdx];
-    return bit_cast<T>(base::subtle::NoBarrier_Load(place));
-  }
-
-  T ExchangeSingular(T new_val);
-
-  // This internal data is not private so that the class is an aggregate and can
-  // be initialized by the linker.  Don't access this directly.  Use the
-  // INIT_HOOK_LIST macro in malloc_hook.cc.
-
-  // One more than the index of the last valid element in priv_data.  During
-  // 'Remove' this may be past the last valid element in priv_data, but
-  // subsequent values will be 0.
-  //
-  // Index kHookListCapacity-1 is reserved as 'deprecated' single hook pointer
-  AtomicWord priv_end;
-  AtomicWord priv_data[kHookListCapacity];
-};
-
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::NewHook> new_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::DeleteHook> delete_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::PreMmapHook> premmap_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MmapHook> mmap_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MmapReplacement> mmap_replacement_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MunmapHook> munmap_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MunmapReplacement> munmap_replacement_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MremapHook> mremap_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::PreSbrkHook> presbrk_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::SbrkHook> sbrk_hooks_;
-
-} }  // namespace base::internal
-
-// The following method is DEPRECATED
-inline MallocHook::NewHook MallocHook::GetNewHook() {
-  return base::internal::new_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeNewHook(const void* p, size_t s) {
-  if (PREDICT_FALSE(!base::internal::new_hooks_.empty())) {
-    InvokeNewHookSlow(p, s);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::DeleteHook MallocHook::GetDeleteHook() {
-  return base::internal::delete_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeDeleteHook(const void* p) {
-  if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
-    InvokeDeleteHookSlow(p);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::PreMmapHook MallocHook::GetPreMmapHook() {
-  return base::internal::premmap_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokePreMmapHook(const void* start,
-                                          size_t size,
-                                          int protection,
-                                          int flags,
-                                          int fd,
-                                          off_t offset) {
-  if (!base::internal::premmap_hooks_.empty()) {
-    InvokePreMmapHookSlow(start, size, protection, flags, fd, offset);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::MmapHook MallocHook::GetMmapHook() {
-  return base::internal::mmap_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeMmapHook(const void* result,
-                                       const void* start,
-                                       size_t size,
-                                       int protection,
-                                       int flags,
-                                       int fd,
-                                       off_t offset) {
-  if (!base::internal::mmap_hooks_.empty()) {
-    InvokeMmapHookSlow(result, start, size, protection, flags, fd, offset);
-  }
-}
-
-inline bool MallocHook::InvokeMmapReplacement(const void* start,
-                                              size_t size,
-                                              int protection,
-                                              int flags,
-                                              int fd,
-                                              off_t offset,
-                                              void** result) {
-  if (!base::internal::mmap_replacement_.empty()) {
-    return InvokeMmapReplacementSlow(start, size,
-                                     protection, flags,
-                                     fd, offset,
-                                     result);
-  }
-  return false;
-}
-
-// The following method is DEPRECATED
-inline MallocHook::MunmapHook MallocHook::GetMunmapHook() {
-  return base::internal::munmap_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeMunmapHook(const void* p, size_t size) {
-  if (!base::internal::munmap_hooks_.empty()) {
-    InvokeMunmapHookSlow(p, size);
-  }
-}
-
-inline bool MallocHook::InvokeMunmapReplacement(
-    const void* p, size_t size, int* result) {
-  if (!base::internal::mmap_replacement_.empty()) {
-    return InvokeMunmapReplacementSlow(p, size, result);
-  }
-  return false;
-}
-
-// The following method is DEPRECATED
-inline MallocHook::MremapHook MallocHook::GetMremapHook() {
-  return base::internal::mremap_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeMremapHook(const void* result,
-                                         const void* old_addr,
-                                         size_t old_size,
-                                         size_t new_size,
-                                         int flags,
-                                         const void* new_addr) {
-  if (!base::internal::mremap_hooks_.empty()) {
-    InvokeMremapHookSlow(result, old_addr, old_size, new_size, flags, new_addr);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::PreSbrkHook MallocHook::GetPreSbrkHook() {
-  return base::internal::presbrk_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokePreSbrkHook(ptrdiff_t increment) {
-  if (!base::internal::presbrk_hooks_.empty() && increment != 0) {
-    InvokePreSbrkHookSlow(increment);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::SbrkHook MallocHook::GetSbrkHook() {
-  return base::internal::sbrk_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeSbrkHook(const void* result,
-                                       ptrdiff_t increment) {
-  if (!base::internal::sbrk_hooks_.empty() && increment != 0) {
-    InvokeSbrkHookSlow(result, increment);
-  }
-}
-
-#endif /* _MALLOC_HOOK_INL_H_ */
diff --git a/third_party/tcmalloc/chromium/src/malloc_hook.cc b/third_party/tcmalloc/chromium/src/malloc_hook.cc
deleted file mode 100644
index 64c2165..0000000
--- a/third_party/tcmalloc/chromium/src/malloc_hook.cc
+++ /dev/null
@@ -1,711 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-
-// Disable the glibc prototype of mremap(), as older versions of the
-// system headers define this function with only four arguments,
-// whereas newer versions allow an optional fifth argument:
-#ifdef HAVE_MMAP
-# define mremap glibc_mremap
-# include <sys/mman.h>
-# undef mremap
-#endif
-
-#include <stddef.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <algorithm>
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "maybe_emergency_malloc.h"
-#include "maybe_threads.h"
-#include "malloc_hook-inl.h"
-#include <gperftools/malloc_hook.h>
-
-// This #ifdef should almost never be set.  Set NO_TCMALLOC_SAMPLES if
-// you're porting to a system where you really can't get a stacktrace.
-#ifdef NO_TCMALLOC_SAMPLES
-  // We use #define so code compiles even if you #include stacktrace.h somehow.
-# define GetStackTrace(stack, depth, skip)  (0)
-#else
-# include <gperftools/stacktrace.h>
-#endif
-
-// __THROW is defined in glibc systems.  It means, counter-intuitively,
-// "This function will never throw an exception."  It's an optional
-// optimization tool, but we may need to use it to match glibc prototypes.
-#ifndef __THROW    // I guess we're not on a glibc system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-using std::copy;
-
-
-// Declaration of default weak initialization function, that can be overridden
-// by linking-in a strong definition (as heap-checker.cc does).  This is
-// extern "C" so that it doesn't trigger gold's --detect-odr-violations warning,
-// which only looks at C++ symbols.
-//
-// This function is declared here as weak, and defined later, rather than a more
-// straightforward simple weak definition, as a workround for an icc compiler
-// issue ((Intel reference 290819).  This issue causes icc to resolve weak
-// symbols too early, at compile rather than link time.  By declaring it (weak)
-// here, then defining it below after its use, we can avoid the problem.
-extern "C" {
-ATTRIBUTE_WEAK void MallocHook_InitAtFirstAllocation_HeapLeakChecker();
-}
-
-namespace {
-
-void RemoveInitialHooksAndCallInitializers();  // below.
-
-pthread_once_t once = PTHREAD_ONCE_INIT;
-
-// These hooks are installed in MallocHook as the only initial hooks.  The first
-// hook that is called will run RemoveInitialHooksAndCallInitializers (see the
-// definition below) and then redispatch to any malloc hooks installed by
-// RemoveInitialHooksAndCallInitializers.
-//
-// Note(llib): there is a possibility of a race in the event that there are
-// multiple threads running before the first allocation.  This is pretty
-// difficult to achieve, but if it is then multiple threads may concurrently do
-// allocations.  The first caller will call
-// RemoveInitialHooksAndCallInitializers via one of the initial hooks.  A
-// concurrent allocation may, depending on timing either:
-// * still have its initial malloc hook installed, run that and block on waiting
-//   for the first caller to finish its call to
-//   RemoveInitialHooksAndCallInitializers, and proceed normally.
-// * occur some time during the RemoveInitialHooksAndCallInitializers call, at
-//   which point there could be no initial hooks and the subsequent hooks that
-//   are about to be set up by RemoveInitialHooksAndCallInitializers haven't
-//   been installed yet.  I think the worst we can get is that some allocations
-//   will not get reported to some hooks set by the initializers called from
-//   RemoveInitialHooksAndCallInitializers.
-
-void InitialNewHook(const void* ptr, size_t size) {
-  perftools_pthread_once(&once, &RemoveInitialHooksAndCallInitializers);
-  MallocHook::InvokeNewHook(ptr, size);
-}
-
-void InitialPreMMapHook(const void* start,
-                               size_t size,
-                               int protection,
-                               int flags,
-                               int fd,
-                               off_t offset) {
-  perftools_pthread_once(&once, &RemoveInitialHooksAndCallInitializers);
-  MallocHook::InvokePreMmapHook(start, size, protection, flags, fd, offset);
-}
-
-void InitialPreSbrkHook(ptrdiff_t increment) {
-  perftools_pthread_once(&once, &RemoveInitialHooksAndCallInitializers);
-  MallocHook::InvokePreSbrkHook(increment);
-}
-
-// This function is called at most once by one of the above initial malloc
-// hooks.  It removes all initial hooks and initializes all other clients that
-// want to get control at the very first memory allocation.  The initializers
-// may assume that the initial malloc hooks have been removed.  The initializers
-// may set up malloc hooks and allocate memory.
-void RemoveInitialHooksAndCallInitializers() {
-  RAW_CHECK(MallocHook::RemoveNewHook(&InitialNewHook), "");
-  RAW_CHECK(MallocHook::RemovePreMmapHook(&InitialPreMMapHook), "");
-  RAW_CHECK(MallocHook::RemovePreSbrkHook(&InitialPreSbrkHook), "");
-
-  // HeapLeakChecker is currently the only module that needs to get control on
-  // the first memory allocation, but one can add other modules by following the
-  // same weak/strong function pattern.
-  MallocHook_InitAtFirstAllocation_HeapLeakChecker();
-}
-
-}  // namespace
-
-// Weak default initialization function that must go after its use.
-extern "C" void MallocHook_InitAtFirstAllocation_HeapLeakChecker() {
-  // Do nothing.
-}
-
-namespace base { namespace internal {
-
-// This lock is shared between all implementations of HookList::Add & Remove.
-// The potential for contention is very small.  This needs to be a SpinLock and
-// not a Mutex since it's possible for Mutex locking to allocate memory (e.g.,
-// per-thread allocation in debug builds), which could cause infinite recursion.
-static SpinLock hooklist_spinlock(base::LINKER_INITIALIZED);
-
-template <typename T>
-bool HookList<T>::Add(T value_as_t) {
-  AtomicWord value = bit_cast<AtomicWord>(value_as_t);
-  if (value == 0) {
-    return false;
-  }
-  SpinLockHolder l(&hooklist_spinlock);
-  // Find the first slot in data that is 0.
-  int index = 0;
-  while ((index < kHookListMaxValues) &&
-         (base::subtle::NoBarrier_Load(&priv_data[index]) != 0)) {
-    ++index;
-  }
-  if (index == kHookListMaxValues) {
-    return false;
-  }
-  AtomicWord prev_num_hooks = base::subtle::Acquire_Load(&priv_end);
-  base::subtle::NoBarrier_Store(&priv_data[index], value);
-  if (prev_num_hooks <= index) {
-    base::subtle::NoBarrier_Store(&priv_end, index + 1);
-  }
-  return true;
-}
-
-template <typename T>
-void HookList<T>::FixupPrivEndLocked() {
-  AtomicWord hooks_end = base::subtle::NoBarrier_Load(&priv_end);
-  while ((hooks_end > 0) &&
-         (base::subtle::NoBarrier_Load(&priv_data[hooks_end - 1]) == 0)) {
-    --hooks_end;
-  }
-  base::subtle::NoBarrier_Store(&priv_end, hooks_end);
-}
-
-template <typename T>
-bool HookList<T>::Remove(T value_as_t) {
-  if (value_as_t == 0) {
-    return false;
-  }
-  SpinLockHolder l(&hooklist_spinlock);
-  AtomicWord hooks_end = base::subtle::NoBarrier_Load(&priv_end);
-  int index = 0;
-  while (index < hooks_end && value_as_t != bit_cast<T>(
-             base::subtle::NoBarrier_Load(&priv_data[index]))) {
-    ++index;
-  }
-  if (index == hooks_end) {
-    return false;
-  }
-  base::subtle::NoBarrier_Store(&priv_data[index], 0);
-  FixupPrivEndLocked();
-  return true;
-}
-
-template <typename T>
-int HookList<T>::Traverse(T* output_array, int n) const {
-  AtomicWord hooks_end = base::subtle::Acquire_Load(&priv_end);
-  int actual_hooks_end = 0;
-  for (int i = 0; i < hooks_end && n > 0; ++i) {
-    AtomicWord data = base::subtle::Acquire_Load(&priv_data[i]);
-    if (data != 0) {
-      *output_array++ = bit_cast<T>(data);
-      ++actual_hooks_end;
-      --n;
-    }
-  }
-  return actual_hooks_end;
-}
-
-template <typename T>
-T HookList<T>::ExchangeSingular(T value_as_t) {
-  AtomicWord value = bit_cast<AtomicWord>(value_as_t);
-  AtomicWord old_value;
-  SpinLockHolder l(&hooklist_spinlock);
-  old_value = base::subtle::NoBarrier_Load(&priv_data[kHookListSingularIdx]);
-  base::subtle::NoBarrier_Store(&priv_data[kHookListSingularIdx], value);
-  if (value != 0) {
-    base::subtle::NoBarrier_Store(&priv_end, kHookListSingularIdx + 1);
-  } else {
-    FixupPrivEndLocked();
-  }
-  return bit_cast<T>(old_value);
-}
-
-// Initialize a HookList (optionally with the given initial_value in index 0).
-#define INIT_HOOK_LIST { 0 }
-#define INIT_HOOK_LIST_WITH_VALUE(initial_value)                \
-  { 1, { reinterpret_cast<AtomicWord>(initial_value) } }
-
-// Explicit instantiation for malloc_hook_test.cc.  This ensures all the methods
-// are instantiated.
-template struct HookList<MallocHook::NewHook>;
-
-HookList<MallocHook::NewHook> new_hooks_ =
-    INIT_HOOK_LIST_WITH_VALUE(&InitialNewHook);
-HookList<MallocHook::DeleteHook> delete_hooks_ = INIT_HOOK_LIST;
-HookList<MallocHook::PreMmapHook> premmap_hooks_ =
-    INIT_HOOK_LIST_WITH_VALUE(&InitialPreMMapHook);
-HookList<MallocHook::MmapHook> mmap_hooks_ = INIT_HOOK_LIST;
-HookList<MallocHook::MunmapHook> munmap_hooks_ = INIT_HOOK_LIST;
-HookList<MallocHook::MremapHook> mremap_hooks_ = INIT_HOOK_LIST;
-HookList<MallocHook::PreSbrkHook> presbrk_hooks_ =
-    INIT_HOOK_LIST_WITH_VALUE(InitialPreSbrkHook);
-HookList<MallocHook::SbrkHook> sbrk_hooks_ = INIT_HOOK_LIST;
-
-// These lists contain either 0 or 1 hooks.
-HookList<MallocHook::MmapReplacement> mmap_replacement_ = { 0 };
-HookList<MallocHook::MunmapReplacement> munmap_replacement_ = { 0 };
-
-#undef INIT_HOOK_LIST_WITH_VALUE
-#undef INIT_HOOK_LIST
-
-} }  // namespace base::internal
-
-using base::internal::kHookListMaxValues;
-using base::internal::new_hooks_;
-using base::internal::delete_hooks_;
-using base::internal::premmap_hooks_;
-using base::internal::mmap_hooks_;
-using base::internal::mmap_replacement_;
-using base::internal::munmap_hooks_;
-using base::internal::munmap_replacement_;
-using base::internal::mremap_hooks_;
-using base::internal::presbrk_hooks_;
-using base::internal::sbrk_hooks_;
-
-// These are available as C bindings as well as C++, hence their
-// definition outside the MallocHook class.
-extern "C"
-int MallocHook_AddNewHook(MallocHook_NewHook hook) {
-  RAW_VLOG(10, "AddNewHook(%p)", hook);
-  return new_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveNewHook(MallocHook_NewHook hook) {
-  RAW_VLOG(10, "RemoveNewHook(%p)", hook);
-  return new_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddDeleteHook(MallocHook_DeleteHook hook) {
-  RAW_VLOG(10, "AddDeleteHook(%p)", hook);
-  return delete_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveDeleteHook(MallocHook_DeleteHook hook) {
-  RAW_VLOG(10, "RemoveDeleteHook(%p)", hook);
-  return delete_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddPreMmapHook(MallocHook_PreMmapHook hook) {
-  RAW_VLOG(10, "AddPreMmapHook(%p)", hook);
-  return premmap_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemovePreMmapHook(MallocHook_PreMmapHook hook) {
-  RAW_VLOG(10, "RemovePreMmapHook(%p)", hook);
-  return premmap_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_SetMmapReplacement(MallocHook_MmapReplacement hook) {
-  RAW_VLOG(10, "SetMmapReplacement(%p)", hook);
-  // NOTE this is a best effort CHECK. Concurrent sets could succeed since
-  // this test is outside of the Add spin lock.
-  RAW_CHECK(mmap_replacement_.empty(), "Only one MMapReplacement is allowed.");
-  return mmap_replacement_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMmapReplacement(MallocHook_MmapReplacement hook) {
-  RAW_VLOG(10, "RemoveMmapReplacement(%p)", hook);
-  return mmap_replacement_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddMmapHook(MallocHook_MmapHook hook) {
-  RAW_VLOG(10, "AddMmapHook(%p)", hook);
-  return mmap_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMmapHook(MallocHook_MmapHook hook) {
-  RAW_VLOG(10, "RemoveMmapHook(%p)", hook);
-  return mmap_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddMunmapHook(MallocHook_MunmapHook hook) {
-  RAW_VLOG(10, "AddMunmapHook(%p)", hook);
-  return munmap_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMunmapHook(MallocHook_MunmapHook hook) {
-  RAW_VLOG(10, "RemoveMunmapHook(%p)", hook);
-  return munmap_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_SetMunmapReplacement(MallocHook_MunmapReplacement hook) {
-  RAW_VLOG(10, "SetMunmapReplacement(%p)", hook);
-  // NOTE this is a best effort CHECK. Concurrent sets could succeed since
-  // this test is outside of the Add spin lock.
-  RAW_CHECK(munmap_replacement_.empty(),
-            "Only one MunmapReplacement is allowed.");
-  return munmap_replacement_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMunmapReplacement(MallocHook_MunmapReplacement hook) {
-  RAW_VLOG(10, "RemoveMunmapReplacement(%p)", hook);
-  return munmap_replacement_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddMremapHook(MallocHook_MremapHook hook) {
-  RAW_VLOG(10, "AddMremapHook(%p)", hook);
-  return mremap_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMremapHook(MallocHook_MremapHook hook) {
-  RAW_VLOG(10, "RemoveMremapHook(%p)", hook);
-  return mremap_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddPreSbrkHook(MallocHook_PreSbrkHook hook) {
-  RAW_VLOG(10, "AddPreSbrkHook(%p)", hook);
-  return presbrk_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemovePreSbrkHook(MallocHook_PreSbrkHook hook) {
-  RAW_VLOG(10, "RemovePreSbrkHook(%p)", hook);
-  return presbrk_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddSbrkHook(MallocHook_SbrkHook hook) {
-  RAW_VLOG(10, "AddSbrkHook(%p)", hook);
-  return sbrk_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveSbrkHook(MallocHook_SbrkHook hook) {
-  RAW_VLOG(10, "RemoveSbrkHook(%p)", hook);
-  return sbrk_hooks_.Remove(hook);
-}
-
-// The code below is DEPRECATED.
-extern "C"
-MallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook) {
-  RAW_VLOG(10, "SetNewHook(%p)", hook);
-  return new_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook) {
-  RAW_VLOG(10, "SetDeleteHook(%p)", hook);
-  return delete_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_PreMmapHook MallocHook_SetPreMmapHook(MallocHook_PreMmapHook hook) {
-  RAW_VLOG(10, "SetPreMmapHook(%p)", hook);
-  return premmap_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_MmapHook MallocHook_SetMmapHook(MallocHook_MmapHook hook) {
-  RAW_VLOG(10, "SetMmapHook(%p)", hook);
-  return mmap_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_MunmapHook MallocHook_SetMunmapHook(MallocHook_MunmapHook hook) {
-  RAW_VLOG(10, "SetMunmapHook(%p)", hook);
-  return munmap_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_MremapHook MallocHook_SetMremapHook(MallocHook_MremapHook hook) {
-  RAW_VLOG(10, "SetMremapHook(%p)", hook);
-  return mremap_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_PreSbrkHook MallocHook_SetPreSbrkHook(MallocHook_PreSbrkHook hook) {
-  RAW_VLOG(10, "SetPreSbrkHook(%p)", hook);
-  return presbrk_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook) {
-  RAW_VLOG(10, "SetSbrkHook(%p)", hook);
-  return sbrk_hooks_.ExchangeSingular(hook);
-}
-// End of DEPRECATED code section.
-
-// Note: embedding the function calls inside the traversal of HookList would be
-// very confusing, as it is legal for a hook to remove itself and add other
-// hooks.  Doing traversal first, and then calling the hooks ensures we only
-// call the hooks registered at the start.
-#define INVOKE_HOOKS(HookType, hook_list, args) do {                    \
-    HookType hooks[kHookListMaxValues];                                 \
-    int num_hooks = hook_list.Traverse(hooks, kHookListMaxValues);      \
-    for (int i = 0; i < num_hooks; ++i) {                               \
-      (*hooks[i])args;                                                  \
-    }                                                                   \
-  } while (0)
-
-// There should only be one replacement. Return the result of the first
-// one, or false if there is none.
-#define INVOKE_REPLACEMENT(HookType, hook_list, args) do {              \
-    HookType hooks[kHookListMaxValues];                                 \
-    int num_hooks = hook_list.Traverse(hooks, kHookListMaxValues);      \
-    return (num_hooks > 0 && (*hooks[0])args);                          \
-  } while (0)
-
-
-void MallocHook::InvokeNewHookSlow(const void* p, size_t s) {
-  if (tcmalloc::IsEmergencyPtr(p)) {
-    return;
-  }
-  INVOKE_HOOKS(NewHook, new_hooks_, (p, s));
-}
-
-void MallocHook::InvokeDeleteHookSlow(const void* p) {
-  if (tcmalloc::IsEmergencyPtr(p)) {
-    return;
-  }
-  INVOKE_HOOKS(DeleteHook, delete_hooks_, (p));
-}
-
-void MallocHook::InvokePreMmapHookSlow(const void* start,
-                                       size_t size,
-                                       int protection,
-                                       int flags,
-                                       int fd,
-                                       off_t offset) {
-  INVOKE_HOOKS(PreMmapHook, premmap_hooks_, (start, size, protection, flags, fd,
-                                            offset));
-}
-
-void MallocHook::InvokeMmapHookSlow(const void* result,
-                                    const void* start,
-                                    size_t size,
-                                    int protection,
-                                    int flags,
-                                    int fd,
-                                    off_t offset) {
-  INVOKE_HOOKS(MmapHook, mmap_hooks_, (result, start, size, protection, flags,
-                                       fd, offset));
-}
-
-bool MallocHook::InvokeMmapReplacementSlow(const void* start,
-                                           size_t size,
-                                           int protection,
-                                           int flags,
-                                           int fd,
-                                           off_t offset,
-                                           void** result) {
-  INVOKE_REPLACEMENT(MmapReplacement, mmap_replacement_,
-                      (start, size, protection, flags, fd, offset, result));
-}
-
-void MallocHook::InvokeMunmapHookSlow(const void* p, size_t s) {
-  INVOKE_HOOKS(MunmapHook, munmap_hooks_, (p, s));
-}
-
-bool MallocHook::InvokeMunmapReplacementSlow(const void* p,
-                                             size_t s,
-                                             int* result) {
-  INVOKE_REPLACEMENT(MunmapReplacement, munmap_replacement_, (p, s, result));
-}
-
-void MallocHook::InvokeMremapHookSlow(const void* result,
-                                      const void* old_addr,
-                                      size_t old_size,
-                                      size_t new_size,
-                                      int flags,
-                                      const void* new_addr) {
-  INVOKE_HOOKS(MremapHook, mremap_hooks_, (result, old_addr, old_size, new_size,
-                                           flags, new_addr));
-}
-
-void MallocHook::InvokePreSbrkHookSlow(ptrdiff_t increment) {
-  INVOKE_HOOKS(PreSbrkHook, presbrk_hooks_, (increment));
-}
-
-void MallocHook::InvokeSbrkHookSlow(const void* result, ptrdiff_t increment) {
-  INVOKE_HOOKS(SbrkHook, sbrk_hooks_, (result, increment));
-}
-
-#undef INVOKE_HOOKS
-
-#ifndef NO_TCMALLOC_SAMPLES
-
-DEFINE_ATTRIBUTE_SECTION_VARS(google_malloc);
-DECLARE_ATTRIBUTE_SECTION_VARS(google_malloc);
-  // actual functions are in debugallocation.cc or tcmalloc.cc
-DEFINE_ATTRIBUTE_SECTION_VARS(malloc_hook);
-DECLARE_ATTRIBUTE_SECTION_VARS(malloc_hook);
-  // actual functions are in this file, malloc_hook.cc, and low_level_alloc.cc
-
-#define ADDR_IN_ATTRIBUTE_SECTION(addr, name) \
-  (reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_START(name)) <= \
-     reinterpret_cast<uintptr_t>(addr) && \
-   reinterpret_cast<uintptr_t>(addr) < \
-     reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_STOP(name)))
-
-// Return true iff 'caller' is a return address within a function
-// that calls one of our hooks via MallocHook:Invoke*.
-// A helper for GetCallerStackTrace.
-static inline bool InHookCaller(const void* caller) {
-  return ADDR_IN_ATTRIBUTE_SECTION(caller, google_malloc) ||
-         ADDR_IN_ATTRIBUTE_SECTION(caller, malloc_hook);
-  // We can use one section for everything except tcmalloc_or_debug
-  // due to its special linkage mode, which prevents merging of the sections.
-}
-
-#undef ADDR_IN_ATTRIBUTE_SECTION
-
-static bool checked_sections = false;
-
-static inline void CheckInHookCaller() {
-  if (!checked_sections) {
-    INIT_ATTRIBUTE_SECTION_VARS(google_malloc);
-    if (ATTRIBUTE_SECTION_START(google_malloc) ==
-        ATTRIBUTE_SECTION_STOP(google_malloc)) {
-      RAW_LOG(ERROR, "google_malloc section is missing, "
-                     "thus InHookCaller is broken!");
-    }
-    INIT_ATTRIBUTE_SECTION_VARS(malloc_hook);
-    if (ATTRIBUTE_SECTION_START(malloc_hook) ==
-        ATTRIBUTE_SECTION_STOP(malloc_hook)) {
-      RAW_LOG(ERROR, "malloc_hook section is missing, "
-                     "thus InHookCaller is broken!");
-    }
-    checked_sections = true;
-  }
-}
-
-#endif // !NO_TCMALLOC_SAMPLES
-
-// We can improve behavior/compactness of this function
-// if we pass a generic test function (with a generic arg)
-// into the implementations for GetStackTrace instead of the skip_count.
-extern "C" int MallocHook_GetCallerStackTrace(void** result, int max_depth,
-                                              int skip_count) {
-#if defined(NO_TCMALLOC_SAMPLES)
-  return 0;
-#elif !defined(HAVE_ATTRIBUTE_SECTION_START)
-  // Fall back to GetStackTrace and good old but fragile frame skip counts.
-  // Note: this path is inaccurate when a hook is not called directly by an
-  // allocation function but is daisy-chained through another hook,
-  // search for MallocHook::(Get|Set|Invoke)* to find such cases.
-  return GetStackTrace(result, max_depth, skip_count + int(DEBUG_MODE));
-  // due to -foptimize-sibling-calls in opt mode
-  // there's no need for extra frame skip here then
-#else
-  CheckInHookCaller();
-  // MallocHook caller determination via InHookCaller works, use it:
-  static const int kMaxSkip = 32 + 6 + 3;
-    // Constant tuned to do just one GetStackTrace call below in practice
-    // and not get many frames that we don't actually need:
-    // currently max passsed max_depth is 32,
-    // max passed/needed skip_count is 6
-    // and 3 is to account for some hook daisy chaining.
-  static const int kStackSize = kMaxSkip + 1;
-  void* stack[kStackSize];
-  int depth = GetStackTrace(stack, kStackSize, 1);  // skip this function frame
-  if (depth == 0)   // silenty propagate cases when GetStackTrace does not work
-    return 0;
-  for (int i = 0; i < depth; ++i) {  // stack[0] is our immediate caller
-    if (InHookCaller(stack[i])) {
-      // fast-path to slow-path calls may be implemented by compiler
-      // as non-tail calls. Causing two functions on stack trace to be
-      // inside google_malloc. In such case we're skipping to
-      // outermost such frame since this is where malloc stack frames
-      // really start.
-      while (i + 1 < depth && InHookCaller(stack[i+1])) {
-        i++;
-      }
-      RAW_VLOG(10, "Found hooked allocator at %d: %p <- %p",
-                   i, stack[i], stack[i+1]);
-      i += 1;  // skip hook caller frame
-      depth -= i;  // correct depth
-      if (depth > max_depth) depth = max_depth;
-      copy(stack + i, stack + i + depth, result);
-      if (depth < max_depth  &&  depth + i == kStackSize) {
-        // get frames for the missing depth
-        depth +=
-          GetStackTrace(result + depth, max_depth - depth, 1 + kStackSize);
-      }
-      return depth;
-    }
-  }
-  RAW_LOG(WARNING, "Hooked allocator frame not found, returning empty trace");
-    // If this happens try increasing kMaxSkip
-    // or else something must be wrong with InHookCaller,
-    // e.g. for every section used in InHookCaller
-    // all functions in that section must be inside the same library.
-  return 0;
-#endif
-}
-
-// On systems where we know how, we override mmap/munmap/mremap/sbrk
-// to provide support for calling the related hooks (in addition,
-// of course, to doing what these functions normally do).
-
-#if defined(__linux)
-# include "malloc_hook_mmap_linux.h"
-
-#elif defined(__FreeBSD__)
-# include "malloc_hook_mmap_freebsd.h"
-
-#else
-
-/*static*/void* MallocHook::UnhookedMMap(void *start, size_t length, int prot,
-                                         int flags, int fd, off_t offset) {
-  void* result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = mmap(start, length, prot, flags, fd, offset);
-  }
-  return result;
-}
-
-/*static*/int MallocHook::UnhookedMUnmap(void *start, size_t length) {
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    result = munmap(start, length);
-  }
-  return result;
-}
-
-#endif
diff --git a/third_party/tcmalloc/chromium/src/malloc_hook_mmap_freebsd.h b/third_party/tcmalloc/chromium/src/malloc_hook_mmap_freebsd.h
deleted file mode 100644
index 8575dcc7..0000000
--- a/third_party/tcmalloc/chromium/src/malloc_hook_mmap_freebsd.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Override mmap/munmap/mremap/sbrk to provide support for calling the
-// related hooks (in addition, of course, to doing what these
-// functions normally do).
-
-#ifndef __FreeBSD__
-# error Should only be including malloc_hook_mmap_freebsd.h on FreeBSD systems.
-#endif
-
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <dlfcn.h>
-
-// Make sure mmap doesn't get #define'd away by <sys/mman.h>
-#undef mmap
-
-// According to the FreeBSD documentation, use syscall if you do not
-// need 64-bit alignment otherwise use __syscall. Indeed, syscall
-// doesn't work correctly in most situations on 64-bit. It's return
-// type is 'int' so for things like SYS_mmap, it actually truncates
-// the returned address to 32-bits.
-#if defined(__amd64__) || defined(__x86_64__)
-# define MALLOC_HOOK_SYSCALL __syscall
-#else
-# define MALLOC_HOOK_SYSCALL syscall
-#endif
-
-
-extern "C" {
-  void* mmap(void *start, size_t length,int prot, int flags,
-             int fd, off_t offset) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  int munmap(void* start, size_t length) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  void* sbrk(intptr_t increment) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-}
-
-static inline void* do_mmap(void *start, size_t length,
-                            int prot, int flags,
-                            int fd, off_t offset) __THROW {
-  return (void *)MALLOC_HOOK_SYSCALL(SYS_mmap,
-                                     start, length, prot, flags, fd, offset);
-}
-
-static inline void* do_sbrk(intptr_t increment) {
-  static void *(*libc_sbrk)(intptr_t);
-  if (libc_sbrk == NULL)
-    libc_sbrk = (void *(*)(intptr_t))dlsym(RTLD_NEXT, "sbrk");
-
-  return libc_sbrk(increment);
-}
-
-
-extern "C" void* mmap(void *start, size_t length, int prot, int flags,
-                      int fd, off_t offset) __THROW {
-  MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset);
-  void *result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap(start, length, prot, flags, fd,
-                       static_cast<size_t>(offset)); // avoid sign extension
-  }
-  MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);
-  return result;
-}
-
-extern "C" int munmap(void* start, size_t length) __THROW {
-  MallocHook::InvokeMunmapHook(start, length);
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    result = MALLOC_HOOK_SYSCALL(SYS_munmap, start, length);
-  }
-
-  return result;
-}
-
-extern "C" void* sbrk(intptr_t increment) __THROW {
-  MallocHook::InvokePreSbrkHook(increment);
-  void *result = do_sbrk(increment);
-  MallocHook::InvokeSbrkHook(result, increment);
-  return result;
-}
-
-/*static*/void* MallocHook::UnhookedMMap(void *start, size_t length, int prot,
-                                         int flags, int fd, off_t offset) {
-  void* result;
-  if (!MallocHook::InvokeMmapReplacement(
-	  start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap(start, length, prot, flags, fd, offset);
-  }
-
-  return result;
-}
-
-/*static*/int MallocHook::UnhookedMUnmap(void *start, size_t length) {
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    result = MALLOC_HOOK_SYSCALL(SYS_munmap, start, length);
-  }
-  return result;
-}
-
-#undef MALLOC_HOOK_SYSCALL
diff --git a/third_party/tcmalloc/chromium/src/malloc_hook_mmap_linux.h b/third_party/tcmalloc/chromium/src/malloc_hook_mmap_linux.h
deleted file mode 100644
index 17415aa..0000000
--- a/third_party/tcmalloc/chromium/src/malloc_hook_mmap_linux.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-// We define mmap() and mmap64(), which somewhat reimplements libc's mmap
-// syscall stubs.  Unfortunately libc only exports the stubs via weak symbols
-// (which we're overriding with our mmap64() and mmap() wrappers) so we can't
-// just call through to them.
-
-#ifndef __linux
-# error Should only be including malloc_hook_mmap_linux.h on linux systems.
-#endif
-
-#include <unistd.h>
-#include <syscall.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include "base/linux_syscall_support.h"
-
-// The x86-32 case and the x86-64 case differ:
-// 32b has a mmap2() syscall, 64b does not.
-// 64b and 32b have different calling conventions for mmap().
-
-// I test for 64-bit first so I don't have to do things like
-// '#if (defined(__mips__) && !defined(__MIPS64__))' as a mips32 check.
-#if defined(__x86_64__) \
-    || defined(__PPC64__) \
-    || defined(__aarch64__) \
-    || (defined(_MIPS_SIM) && (_MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32)) \
-    || defined(__s390__)
-
-static inline void* do_mmap64(void *start, size_t length,
-                              int prot, int flags,
-                              int fd, __off64_t offset) __THROW {
-  // The original gperftools uses sys_mmap() here.  But, it is not allowed by
-  // Chromium's sandbox.
-  return (void*)syscall(SYS_mmap, start, length, prot, flags, fd, offset);
-}
-
-#define MALLOC_HOOK_HAVE_DO_MMAP64 1
-
-#elif defined(__i386__) || defined(__PPC__) || defined(__mips__) || \
-      defined(__arm__)
-
-static inline void* do_mmap64(void *start, size_t length,
-                              int prot, int flags,
-                              int fd, __off64_t offset) __THROW {
-  void *result;
-
-  // Try mmap2() unless it's not supported
-  static bool have_mmap2 = true;
-  if (have_mmap2) {
-    static int pagesize = 0;
-    if (!pagesize) pagesize = getpagesize();
-
-    // Check that the offset is page aligned
-    if (offset & (pagesize - 1)) {
-      result = MAP_FAILED;
-      errno = EINVAL;
-      goto out;
-    }
-
-    result = (void *)syscall(SYS_mmap2,
-                             start, length, prot, flags, fd,
-                             (off_t) (offset / pagesize));
-    if (result != MAP_FAILED || errno != ENOSYS)  goto out;
-
-    // We don't have mmap2() after all - don't bother trying it in future
-    have_mmap2 = false;
-  }
-
-  if (((off_t)offset) != offset) {
-    // If we're trying to map a 64-bit offset, fail now since we don't
-    // have 64-bit mmap() support.
-    result = MAP_FAILED;
-    errno = EINVAL;
-    goto out;
-  }
-
-#ifdef __NR_mmap
-  {
-    // Fall back to old 32-bit offset mmap() call
-    // Old syscall interface cannot handle six args, so pass in an array
-    int32 args[6] = { (int32) start, (int32) length, prot, flags, fd,
-                      (int32)(off_t) offset };
-    result = (void *)syscall(SYS_mmap, args);
-  }
-#else
-  // Some Linux ports like ARM EABI Linux has no mmap, just mmap2.
-  result = MAP_FAILED;
-#endif
-
- out:
-  return result;
-}
-
-#define MALLOC_HOOK_HAVE_DO_MMAP64 1
-
-#endif  // #if defined(__x86_64__)
-
-
-#ifdef MALLOC_HOOK_HAVE_DO_MMAP64
-
-// We use do_mmap64 abstraction to put MallocHook::InvokeMmapHook
-// calls right into mmap and mmap64, so that the stack frames in the caller's
-// stack are at the same offsets for all the calls of memory allocating
-// functions.
-
-// Put all callers of MallocHook::Invoke* in this module into
-// malloc_hook section,
-// so that MallocHook::GetCallerStackTrace can function accurately:
-
-// Make sure mmap doesn't get #define'd away by <sys/mman.h>
-# undef mmap
-
-extern "C" {
-  void* mmap64(void *start, size_t length, int prot, int flags,
-               int fd, __off64_t offset  ) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  void* mmap(void *start, size_t length,int prot, int flags,
-             int fd, off_t offset) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  int munmap(void* start, size_t length) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  void* mremap(void* old_addr, size_t old_size, size_t new_size,
-               int flags, ...) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  void* sbrk(intptr_t increment) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-}
-
-extern "C" void* mmap64(void *start, size_t length, int prot, int flags,
-                        int fd, __off64_t offset) __THROW {
-  MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset);
-  void *result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap64(start, length, prot, flags, fd, offset);
-  }
-  MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);
-  return result;
-}
-
-# if !defined(__USE_FILE_OFFSET64) || !defined(__REDIRECT_NTH)
-
-extern "C" void* mmap(void *start, size_t length, int prot, int flags,
-                      int fd, off_t offset) __THROW {
-  MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset);
-  void *result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap64(start, length, prot, flags, fd,
-                       static_cast<size_t>(offset)); // avoid sign extension
-  }
-  MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);
-  return result;
-}
-
-# endif  // !defined(__USE_FILE_OFFSET64) || !defined(__REDIRECT_NTH)
-
-extern "C" int munmap(void* start, size_t length) __THROW {
-  MallocHook::InvokeMunmapHook(start, length);
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    // The original gperftools uses sys_munmap() here.  But, it is not allowed
-    // by Chromium's sandbox.
-    result = syscall(SYS_munmap, start, length);
-  }
-  return result;
-}
-
-extern "C" void* mremap(void* old_addr, size_t old_size, size_t new_size,
-                        int flags, ...) __THROW {
-  va_list ap;
-  va_start(ap, flags);
-  void *new_address = va_arg(ap, void *);
-  va_end(ap);
-  // The original gperftools uses sys_mremap() here.  But, it is not allowed by
-  // Chromium's sandbox.
-  void* result = (void*)syscall(SYS_mremap, old_addr, old_size, new_size, flags,
-                                new_address);
-  MallocHook::InvokeMremapHook(result, old_addr, old_size, new_size, flags,
-                               new_address);
-  return result;
-}
-
-#ifndef __UCLIBC__
-// libc's version:
-extern "C" void* __sbrk(intptr_t increment);
-
-extern "C" void* sbrk(intptr_t increment) __THROW {
-  MallocHook::InvokePreSbrkHook(increment);
-  void *result = __sbrk(increment);
-  MallocHook::InvokeSbrkHook(result, increment);
-  return result;
-}
-
-#endif
-
-/*static*/void* MallocHook::UnhookedMMap(void *start, size_t length, int prot,
-                                         int flags, int fd, off_t offset) {
-  void* result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap64(start, length, prot, flags, fd, offset);
-  }
-  return result;
-}
-
-/*static*/int MallocHook::UnhookedMUnmap(void *start, size_t length) {
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    result = syscall(SYS_munmap, start, length);
-  }
-  return result;
-}
-
-#undef MALLOC_HOOK_HAVE_DO_MMAP64
-
-#endif  // #ifdef MALLOC_HOOK_HAVE_DO_MMAP64
diff --git a/third_party/tcmalloc/chromium/src/maybe_emergency_malloc.h b/third_party/tcmalloc/chromium/src/maybe_emergency_malloc.h
deleted file mode 100644
index 250ecf0..0000000
--- a/third_party/tcmalloc/chromium/src/maybe_emergency_malloc.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef MAYBE_EMERGENCY_MALLOC_H
-#define MAYBE_EMERGENCY_MALLOC_H
-
-#include "config.h"
-
-#ifdef ENABLE_EMERGENCY_MALLOC
-
-#include "emergency_malloc.h"
-
-#else
-
-namespace tcmalloc {
-  static inline void *EmergencyMalloc(size_t size) {return NULL;}
-  static inline void EmergencyFree(void *p) {}
-  static inline void *EmergencyCalloc(size_t n, size_t elem_size) {return NULL;}
-  static inline void *EmergencyRealloc(void *old_ptr, size_t new_size) {return NULL;}
-
-  static inline bool IsEmergencyPtr(const void *_ptr) {
-    return false;
-  }
-}
-
-#endif // ENABLE_EMERGENCY_MALLOC
-
-#endif
diff --git a/third_party/tcmalloc/chromium/src/maybe_threads.cc b/third_party/tcmalloc/chromium/src/maybe_threads.cc
deleted file mode 100644
index ef7e582..0000000
--- a/third_party/tcmalloc/chromium/src/maybe_threads.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Menage <opensource@google.com>
-//
-// Some wrappers for pthread functions so that we can be LD_PRELOADed
-// against non-pthreads apps.
-//
-// This module will behave very strangely if some pthreads functions
-// exist and others don't.
-
-#include "config.h"
-#include <assert.h>
-#include <string.h>    // for memcmp
-#include <stdio.h>     // for __isthreaded on FreeBSD
-// We don't actually need strings. But including this header seems to
-// stop the compiler trying to short-circuit our pthreads existence
-// tests and claiming that the address of a function is always
-// non-zero. I have no idea why ...
-#include <string>
-#include "maybe_threads.h"
-#include "base/basictypes.h"
-#include "base/logging.h"
-
-// __THROW is defined in glibc systems.  It means, counter-intuitively,
-// "This function will never throw an exception."  It's an optional
-// optimization tool, but we may need to use it to match glibc prototypes.
-#ifndef __THROW    // I guess we're not on a glibc system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-// These are the methods we're going to conditionally include.
-extern "C" {
-  int pthread_key_create (pthread_key_t*, void (*)(void*))
-      __THROW ATTRIBUTE_WEAK;
-  int pthread_key_delete (pthread_key_t)
-      __THROW ATTRIBUTE_WEAK;
-  void *pthread_getspecific(pthread_key_t)
-      __THROW ATTRIBUTE_WEAK;
-  int pthread_setspecific(pthread_key_t, const void*)
-      __THROW ATTRIBUTE_WEAK;
-  int pthread_once(pthread_once_t *, void (*)(void))
-      ATTRIBUTE_WEAK;
-#ifdef HAVE_FORK
-  int pthread_atfork(void (*__prepare) (void),
-                     void (*__parent) (void),
-                     void (*__child) (void))
-    __THROW ATTRIBUTE_WEAK;
-#endif
-}
-
-#define MAX_PERTHREAD_VALS 16
-static void *perftools_pthread_specific_vals[MAX_PERTHREAD_VALS];
-static int next_key;
-
-// NOTE: it's similar to bitcast defined in basic_types.h with
-// exception of ignoring sizes mismatch
-template <typename T1, typename T2>
-static T2 memcpy_cast(const T1 &input) {
-  T2 output;
-  size_t s = sizeof(input);
-  if (sizeof(output) < s) {
-    s = sizeof(output);
-  }
-  memcpy(&output, &input, s);
-  return output;
-}
-
-int perftools_pthread_key_create(pthread_key_t *key,
-                                 void (*destr_function) (void *)) {
-  if (pthread_key_create) {
-    return pthread_key_create(key, destr_function);
-  } else {
-    assert(next_key < MAX_PERTHREAD_VALS);
-    *key = memcpy_cast<int, pthread_key_t>(next_key++);
-    return 0;
-  }
-}
-
-int perftools_pthread_key_delete(pthread_key_t key) {
-  if (pthread_key_delete) {
-    return pthread_key_delete(key);
-  } else {
-    return 0;
-  }
-}
-
-void *perftools_pthread_getspecific(pthread_key_t key) {
-  if (pthread_getspecific) {
-    return pthread_getspecific(key);
-  } else {
-    return perftools_pthread_specific_vals[memcpy_cast<pthread_key_t, int>(key)];
-  }
-}
-
-int perftools_pthread_setspecific(pthread_key_t key, void *val) {
-  if (pthread_setspecific) {
-    return pthread_setspecific(key, val);
-  } else {
-    perftools_pthread_specific_vals[memcpy_cast<pthread_key_t, int>(key)] = val;
-    return 0;
-  }
-}
-
-
-static pthread_once_t pthread_once_init = PTHREAD_ONCE_INIT;
-int perftools_pthread_once(pthread_once_t *ctl,
-                           void  (*init_routine) (void)) {
-#ifdef __FreeBSD__
-  // On __FreeBSD__, calling pthread_once on a system that is not
-  // linked with -pthread is silently a noop. :-( Luckily, we have a
-  // workaround: FreeBSD exposes __isthreaded in <stdio.h>, which is
-  // set to 1 when the first thread is spawned.  So on those systems,
-  // we can use our own separate pthreads-once mechanism, which is
-  // used until __isthreaded is 1 (which will never be true if the app
-  // is not linked with -pthread).
-  static bool pthread_once_ran_before_threads = false;
-  if (pthread_once_ran_before_threads) {
-    return 0;
-  }
-  if (!__isthreaded) {
-    init_routine();
-    pthread_once_ran_before_threads = true;
-    return 0;
-  }
-#endif
-  if (pthread_once) {
-    return pthread_once(ctl, init_routine);
-  } else {
-    if (memcmp(ctl, &pthread_once_init, sizeof(*ctl)) == 0) {
-      init_routine();
-      ++*(char*)(ctl);        // make it so it's no longer equal to init
-    }
-    return 0;
-  }
-}
-
-#ifdef HAVE_FORK
-
-void perftools_pthread_atfork(void (*before)(),
-                              void (*parent_after)(),
-                              void (*child_after)()) {
-  if (pthread_atfork) {
-    int rv = pthread_atfork(before, parent_after, child_after);
-    CHECK(rv == 0);
-  }
-}
-
-#endif
diff --git a/third_party/tcmalloc/chromium/src/maybe_threads.h b/third_party/tcmalloc/chromium/src/maybe_threads.h
deleted file mode 100644
index c6cfdf7..0000000
--- a/third_party/tcmalloc/chromium/src/maybe_threads.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Menage <opensource@google.com>
-
-//-------------------------------------------------------------------
-// Some wrappers for pthread functions so that we can be LD_PRELOADed
-// against non-pthreads apps.
-//-------------------------------------------------------------------
-
-#ifndef GOOGLE_MAYBE_THREADS_H_
-#define GOOGLE_MAYBE_THREADS_H_
-
-#ifdef HAVE_PTHREAD
-#include <pthread.h>
-#endif
-
-int perftools_pthread_key_create(pthread_key_t *key,
-                                 void (*destr_function) (void *));
-int perftools_pthread_key_delete(pthread_key_t key);
-void *perftools_pthread_getspecific(pthread_key_t key);
-int perftools_pthread_setspecific(pthread_key_t key, void *val);
-int perftools_pthread_once(pthread_once_t *ctl,
-                           void  (*init_routine) (void));
-
-// Our wrapper for pthread_atfork. Does _nothing_ when there are no
-// threads. See static_vars.cc:SetupAtForkLocksHandler for only user
-// of this.
-void perftools_pthread_atfork(void (*before)(),
-                              void (*parent_after)(),
-                              void (*child_after)());
-
-#endif  /* GOOGLE_MAYBE_THREADS_H_ */
diff --git a/third_party/tcmalloc/chromium/src/memfs_malloc.cc b/third_party/tcmalloc/chromium/src/memfs_malloc.cc
deleted file mode 100644
index b01aa5ee..0000000
--- a/third_party/tcmalloc/chromium/src/memfs_malloc.cc
+++ /dev/null
@@ -1,272 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Arun Sharma
-//
-// A tcmalloc system allocator that uses a memory based filesystem such as
-// tmpfs or hugetlbfs
-//
-// Since these only exist on linux, we only register this allocator there.
-
-#ifdef __linux
-
-#include <config.h>
-#include <errno.h>                      // for errno, EINVAL
-#include <inttypes.h>                   // for PRId64
-#include <limits.h>                     // for PATH_MAX
-#include <stddef.h>                     // for size_t, NULL
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for int64_t, uintptr_t
-#endif
-#include <stdio.h>                      // for snprintf
-#include <stdlib.h>                     // for mkstemp
-#include <string.h>                     // for strerror
-#include <sys/mman.h>                   // for mmap, MAP_FAILED, etc
-#include <sys/statfs.h>                 // for fstatfs, statfs
-#include <unistd.h>                     // for ftruncate, off_t, unlink
-#include <new>                          // for operator new
-#include <string>
-
-#include <gperftools/malloc_extension.h>
-#include "base/basictypes.h"
-#include "base/googleinit.h"
-#include "base/sysinfo.h"
-#include "internal_logging.h"
-
-// TODO(sanjay): Move the code below into the tcmalloc namespace
-using tcmalloc::kLog;
-using tcmalloc::kCrash;
-using tcmalloc::Log;
-using std::string;
-
-DEFINE_string(memfs_malloc_path, EnvToString("TCMALLOC_MEMFS_MALLOC_PATH", ""),
-              "Path where hugetlbfs or tmpfs is mounted. The caller is "
-              "responsible for ensuring that the path is unique and does "
-              "not conflict with another process");
-DEFINE_int64(memfs_malloc_limit_mb,
-             EnvToInt("TCMALLOC_MEMFS_LIMIT_MB", 0),
-             "Limit total allocation size to the "
-             "specified number of MiB.  0 == no limit.");
-DEFINE_bool(memfs_malloc_abort_on_fail,
-            EnvToBool("TCMALLOC_MEMFS_ABORT_ON_FAIL", false),
-            "abort whenever memfs_malloc fails to satisfy an allocation "
-            "for any reason.");
-DEFINE_bool(memfs_malloc_ignore_mmap_fail,
-            EnvToBool("TCMALLOC_MEMFS_IGNORE_MMAP_FAIL", false),
-            "Ignore failures from mmap");
-DEFINE_bool(memfs_malloc_map_private,
-            EnvToBool("TCMALLOC_MEMFS_MAP_PRIVATE", false),
-	    "Use MAP_PRIVATE with mmap");
-
-// Hugetlbfs based allocator for tcmalloc
-class HugetlbSysAllocator: public SysAllocator {
-public:
-  explicit HugetlbSysAllocator(SysAllocator* fallback)
-    : failed_(true),  // To disable allocator until Initialize() is called.
-      big_page_size_(0),
-      hugetlb_fd_(-1),
-      hugetlb_base_(0),
-      fallback_(fallback) {
-  }
-
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-  bool Initialize();
-
-  bool failed_;          // Whether failed to allocate memory.
-
-private:
-  void* AllocInternal(size_t size, size_t *actual_size, size_t alignment);
-
-  int64 big_page_size_;
-  int hugetlb_fd_;       // file descriptor for hugetlb
-  off_t hugetlb_base_;
-
-  SysAllocator* fallback_;  // Default system allocator to fall back to.
-};
-static union {
-  char buf[sizeof(HugetlbSysAllocator)];
-  void *ptr;
-} hugetlb_space;
-
-// No locking needed here since we assume that tcmalloc calls
-// us with an internal lock held (see tcmalloc/system-alloc.cc).
-void* HugetlbSysAllocator::Alloc(size_t size, size_t *actual_size,
-                                 size_t alignment) {
-  if (failed_) {
-    return fallback_->Alloc(size, actual_size, alignment);
-  }
-
-  // We don't respond to allocation requests smaller than big_page_size_ unless
-  // the caller is ok to take more than they asked for. Used by MetaDataAlloc.
-  if (actual_size == NULL && size < big_page_size_) {
-    return fallback_->Alloc(size, actual_size, alignment);
-  }
-
-  // Enforce huge page alignment.  Be careful to deal with overflow.
-  size_t new_alignment = alignment;
-  if (new_alignment < big_page_size_) new_alignment = big_page_size_;
-  size_t aligned_size = ((size + new_alignment - 1) /
-                         new_alignment) * new_alignment;
-  if (aligned_size < size) {
-    return fallback_->Alloc(size, actual_size, alignment);
-  }
-
-  void* result = AllocInternal(aligned_size, actual_size, new_alignment);
-  if (result != NULL) {
-    return result;
-  }
-  Log(kLog, __FILE__, __LINE__,
-      "HugetlbSysAllocator: (failed, allocated)", failed_, hugetlb_base_);
-  if (FLAGS_memfs_malloc_abort_on_fail) {
-    Log(kCrash, __FILE__, __LINE__,
-        "memfs_malloc_abort_on_fail is set");
-  }
-  return fallback_->Alloc(size, actual_size, alignment);
-}
-
-void* HugetlbSysAllocator::AllocInternal(size_t size, size_t* actual_size,
-                                         size_t alignment) {
-  // Ask for extra memory if alignment > pagesize
-  size_t extra = 0;
-  if (alignment > big_page_size_) {
-    extra = alignment - big_page_size_;
-  }
-
-  // Test if this allocation would put us over the limit.
-  off_t limit = FLAGS_memfs_malloc_limit_mb*1024*1024;
-  if (limit > 0 && hugetlb_base_ + size + extra > limit) {
-    // Disable the allocator when there's less than one page left.
-    if (limit - hugetlb_base_ < big_page_size_) {
-      Log(kLog, __FILE__, __LINE__, "reached memfs_malloc_limit_mb");
-      failed_ = true;
-    }
-    else {
-      Log(kLog, __FILE__, __LINE__,
-          "alloc too large (size, bytes left)", size, limit-hugetlb_base_);
-    }
-    return NULL;
-  }
-
-  // This is not needed for hugetlbfs, but needed for tmpfs.  Annoyingly
-  // hugetlbfs returns EINVAL for ftruncate.
-  int ret = ftruncate(hugetlb_fd_, hugetlb_base_ + size + extra);
-  if (ret != 0 && errno != EINVAL) {
-    Log(kLog, __FILE__, __LINE__,
-        "ftruncate failed", strerror(errno));
-    failed_ = true;
-    return NULL;
-  }
-
-  // Note: size + extra does not overflow since:
-  //            size + alignment < (1<<NBITS).
-  // and        extra <= alignment
-  // therefore  size + extra < (1<<NBITS)
-  void *result;
-  result = mmap(0, size + extra, PROT_WRITE|PROT_READ,
-                FLAGS_memfs_malloc_map_private ? MAP_PRIVATE : MAP_SHARED,
-                hugetlb_fd_, hugetlb_base_);
-  if (result == reinterpret_cast<void*>(MAP_FAILED)) {
-    if (!FLAGS_memfs_malloc_ignore_mmap_fail) {
-      Log(kLog, __FILE__, __LINE__,
-          "mmap failed (size, error)", size + extra, strerror(errno));
-      failed_ = true;
-    }
-    return NULL;
-  }
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-
-  // Adjust the return memory so it is aligned
-  size_t adjust = 0;
-  if ((ptr & (alignment - 1)) != 0) {
-    adjust = alignment - (ptr & (alignment - 1));
-  }
-  ptr += adjust;
-  hugetlb_base_ += (size + extra);
-
-  if (actual_size) {
-    *actual_size = size + extra - adjust;
-  }
-
-  return reinterpret_cast<void*>(ptr);
-}
-
-bool HugetlbSysAllocator::Initialize() {
-  char path[PATH_MAX];
-  const int pathlen = FLAGS_memfs_malloc_path.size();
-  if (pathlen + 8 > sizeof(path)) {
-    Log(kCrash, __FILE__, __LINE__, "XX fatal: memfs_malloc_path too long");
-    return false;
-  }
-  memcpy(path, FLAGS_memfs_malloc_path.data(), pathlen);
-  memcpy(path + pathlen, ".XXXXXX", 8);  // Also copies terminating \0
-
-  int hugetlb_fd = mkstemp(path);
-  if (hugetlb_fd == -1) {
-    Log(kLog, __FILE__, __LINE__,
-        "warning: unable to create memfs_malloc_path",
-        path, strerror(errno));
-    return false;
-  }
-
-  // Cleanup memory on process exit
-  if (unlink(path) == -1) {
-    Log(kCrash, __FILE__, __LINE__,
-        "fatal: error unlinking memfs_malloc_path", path, strerror(errno));
-    return false;
-  }
-
-  // Use fstatfs to figure out the default page size for memfs
-  struct statfs sfs;
-  if (fstatfs(hugetlb_fd, &sfs) == -1) {
-    Log(kCrash, __FILE__, __LINE__,
-        "fatal: error fstatfs of memfs_malloc_path", strerror(errno));
-    return false;
-  }
-  int64 page_size = sfs.f_bsize;
-
-  hugetlb_fd_ = hugetlb_fd;
-  big_page_size_ = page_size;
-  failed_ = false;
-  return true;
-}
-
-REGISTER_MODULE_INITIALIZER(memfs_malloc, {
-  if (FLAGS_memfs_malloc_path.length()) {
-    SysAllocator* alloc = MallocExtension::instance()->GetSystemAllocator();
-    HugetlbSysAllocator* hp =
-      new (hugetlb_space.buf) HugetlbSysAllocator(alloc);
-    if (hp->Initialize()) {
-      MallocExtension::instance()->SetSystemAllocator(hp);
-    }
-  }
-});
-
-#endif   /* ifdef __linux */
diff --git a/third_party/tcmalloc/chromium/src/memory_region_map.cc b/third_party/tcmalloc/chromium/src/memory_region_map.cc
deleted file mode 100644
index 06b6fb0..0000000
--- a/third_party/tcmalloc/chromium/src/memory_region_map.cc
+++ /dev/null
@@ -1,838 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Maxim Lifantsev
- */
-
-//
-// Background and key design points of MemoryRegionMap.
-//
-// MemoryRegionMap is a low-level module with quite atypical requirements that
-// result in some degree of non-triviality of the implementation and design.
-//
-// MemoryRegionMap collects info about *all* memory regions created with
-// mmap, munmap, mremap, sbrk.
-// They key word above is 'all': all that are happening in a process
-// during its lifetime frequently starting even before global object
-// constructor execution.
-//
-// This is needed by the primary client of MemoryRegionMap:
-// HeapLeakChecker uses the regions and the associated stack traces
-// to figure out what part of the memory is the heap:
-// if MemoryRegionMap were to miss some (early) regions, leak checking would
-// stop working correctly.
-//
-// To accomplish the goal of functioning before/during global object
-// constructor execution MemoryRegionMap is done as a singleton service
-// that relies on own on-demand initialized static constructor-less data,
-// and only relies on other low-level modules that can also function properly
-// even before global object constructors run.
-//
-// Accomplishing the goal of collecting data about all mmap, munmap, mremap,
-// sbrk occurrences is a more involved: conceptually to do this one needs to
-// record some bits of data in particular about any mmap or sbrk call,
-// but to do that one needs to allocate memory for that data at some point,
-// but all memory allocations in the end themselves come from an mmap
-// or sbrk call (that's how the address space of the process grows).
-//
-// Also note that we need to do all the above recording from
-// within an mmap/sbrk hook which is sometimes/frequently is made by a memory
-// allocator, including the allocator MemoryRegionMap itself must rely on.
-// In the case of heap-checker usage this includes even the very first
-// mmap/sbrk call happening in the program: heap-checker gets activated due to
-// a link-time installed mmap/sbrk hook and it initializes MemoryRegionMap
-// and asks it to record info about this very first call right from that
-// very first hook invocation.
-//
-// MemoryRegionMap is doing its memory allocations via LowLevelAlloc:
-// unlike more complex standard memory allocator, LowLevelAlloc cooperates with
-// MemoryRegionMap by not holding any of its own locks while it calls mmap
-// to get memory, thus we are able to call LowLevelAlloc from
-// our mmap/sbrk hooks without causing a deadlock in it.
-// For the same reason of deadlock prevention the locking in MemoryRegionMap
-// itself is write-recursive which is an exception to Google's mutex usage.
-//
-// We still need to break the infinite cycle of mmap calling our hook,
-// which asks LowLevelAlloc for memory to record this mmap,
-// which (sometimes) causes mmap, which calls our hook, and so on.
-// We do this as follows: on a recursive call of MemoryRegionMap's
-// mmap/sbrk/mremap hook we record the data about the allocation in a
-// static fixed-sized stack (saved_regions and saved_buckets), when the
-// recursion unwinds but before returning from the outer hook call we unwind
-// this stack and move the data from saved_regions and saved_buckets to its
-// permanent place in the RegionSet and "bucket_table" respectively,
-// which can cause more allocations and mmap-s and recursion and unwinding,
-// but the whole process ends eventually due to the fact that for the small
-// allocations we are doing LowLevelAlloc reuses one mmap call and parcels out
-// the memory it created to satisfy several of our allocation requests.
-//
-
-// ========================================================================= //
-
-#include <config.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#elif !defined(MAP_FAILED)
-#define MAP_FAILED -1  // the only thing we need from mman.h
-#endif
-#ifdef HAVE_PTHREAD
-#include <pthread.h>   // for pthread_t, pthread_self()
-#endif
-#include <stddef.h>
-
-#include <algorithm>
-#include <set>
-
-#include "memory_region_map.h"
-
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include "base/low_level_alloc.h"
-#include "malloc_hook-inl.h"
-
-#include <gperftools/stacktrace.h>
-#include <gperftools/malloc_hook.h>
-
-// MREMAP_FIXED is a linux extension.  How it's used in this file,
-// setting it to 0 is equivalent to saying, "This feature isn't
-// supported", which is right.
-#ifndef MREMAP_FIXED
-# define MREMAP_FIXED  0
-#endif
-
-using std::max;
-
-// ========================================================================= //
-
-int MemoryRegionMap::client_count_ = 0;
-int MemoryRegionMap::max_stack_depth_ = 0;
-MemoryRegionMap::RegionSet* MemoryRegionMap::regions_ = NULL;
-LowLevelAlloc::Arena* MemoryRegionMap::arena_ = NULL;
-SpinLock MemoryRegionMap::lock_(SpinLock::LINKER_INITIALIZED);
-SpinLock MemoryRegionMap::owner_lock_(  // ACQUIRED_AFTER(lock_)
-    SpinLock::LINKER_INITIALIZED);
-int MemoryRegionMap::recursion_count_ = 0;  // GUARDED_BY(owner_lock_)
-pthread_t MemoryRegionMap::lock_owner_tid_;  // GUARDED_BY(owner_lock_)
-int64 MemoryRegionMap::map_size_ = 0;
-int64 MemoryRegionMap::unmap_size_ = 0;
-HeapProfileBucket** MemoryRegionMap::bucket_table_ = NULL;  // GUARDED_BY(lock_)
-int MemoryRegionMap::num_buckets_ = 0;  // GUARDED_BY(lock_)
-int MemoryRegionMap::saved_buckets_count_ = 0;  // GUARDED_BY(lock_)
-HeapProfileBucket MemoryRegionMap::saved_buckets_[20];  // GUARDED_BY(lock_)
-
-// GUARDED_BY(lock_)
-const void* MemoryRegionMap::saved_buckets_keys_[20][kMaxStackDepth];
-
-// ========================================================================= //
-
-// Simple hook into execution of global object constructors,
-// so that we do not call pthread_self() when it does not yet work.
-static bool libpthread_initialized = false;
-REGISTER_MODULE_INITIALIZER(libpthread_initialized_setter,
-                            libpthread_initialized = true);
-
-static inline bool current_thread_is(pthread_t should_be) {
-  // Before main() runs, there's only one thread, so we're always that thread
-  if (!libpthread_initialized) return true;
-  // this starts working only sometime well into global constructor execution:
-  return pthread_equal(pthread_self(), should_be);
-}
-
-// ========================================================================= //
-
-// Constructor-less place-holder to store a RegionSet in.
-union MemoryRegionMap::RegionSetRep {
-  char rep[sizeof(RegionSet)];
-  void* align_it;  // do not need a better alignment for 'rep' than this
-  RegionSet* region_set() { return reinterpret_cast<RegionSet*>(rep); }
-};
-
-// The bytes where MemoryRegionMap::regions_ will point to.
-// We use RegionSetRep with noop c-tor so that global construction
-// does not interfere.
-static MemoryRegionMap::RegionSetRep regions_rep;
-
-// ========================================================================= //
-
-// Has InsertRegionLocked been called recursively
-// (or rather should we *not* use regions_ to record a hooked mmap).
-static bool recursive_insert = false;
-
-void MemoryRegionMap::Init(int max_stack_depth, bool use_buckets) {
-  RAW_VLOG(10, "MemoryRegionMap Init");
-  RAW_CHECK(max_stack_depth >= 0, "");
-  // Make sure we don't overflow the memory in region stacks:
-  RAW_CHECK(max_stack_depth <= kMaxStackDepth,
-            "need to increase kMaxStackDepth?");
-  Lock();
-  client_count_ += 1;
-  max_stack_depth_ = max(max_stack_depth_, max_stack_depth);
-  if (client_count_ > 1) {
-    // not first client: already did initialization-proper
-    Unlock();
-    RAW_VLOG(10, "MemoryRegionMap Init increment done");
-    return;
-  }
-  // Set our hooks and make sure they were installed:
-  RAW_CHECK(MallocHook::AddMmapHook(&MmapHook), "");
-  RAW_CHECK(MallocHook::AddMremapHook(&MremapHook), "");
-  RAW_CHECK(MallocHook::AddSbrkHook(&SbrkHook), "");
-  RAW_CHECK(MallocHook::AddMunmapHook(&MunmapHook), "");
-  // We need to set recursive_insert since the NewArena call itself
-  // will already do some allocations with mmap which our hooks will catch
-  // recursive_insert allows us to buffer info about these mmap calls.
-  // Note that Init() can be (and is) sometimes called
-  // already from within an mmap/sbrk hook.
-  recursive_insert = true;
-  arena_ = LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
-  recursive_insert = false;
-  HandleSavedRegionsLocked(&InsertRegionLocked);  // flush the buffered ones
-    // Can't instead use HandleSavedRegionsLocked(&DoInsertRegionLocked) before
-    // recursive_insert = false; as InsertRegionLocked will also construct
-    // regions_ on demand for us.
-  if (use_buckets) {
-    const int table_bytes = kHashTableSize * sizeof(*bucket_table_);
-    recursive_insert = true;
-    bucket_table_ = static_cast<HeapProfileBucket**>(
-        MyAllocator::Allocate(table_bytes));
-    recursive_insert = false;
-    memset(bucket_table_, 0, table_bytes);
-    num_buckets_ = 0;
-  }
-  if (regions_ == NULL) {  // init regions_
-    InitRegionSetLocked();
-  }
-  Unlock();
-  RAW_VLOG(10, "MemoryRegionMap Init done");
-}
-
-bool MemoryRegionMap::Shutdown() {
-  RAW_VLOG(10, "MemoryRegionMap Shutdown");
-  Lock();
-  RAW_CHECK(client_count_ > 0, "");
-  client_count_ -= 1;
-  if (client_count_ != 0) {  // not last client; need not really shutdown
-    Unlock();
-    RAW_VLOG(10, "MemoryRegionMap Shutdown decrement done");
-    return true;
-  }
-  if (bucket_table_ != NULL) {
-    for (int i = 0; i < kHashTableSize; i++) {
-      for (HeapProfileBucket* curr = bucket_table_[i]; curr != 0; /**/) {
-        HeapProfileBucket* bucket = curr;
-        curr = curr->next;
-        MyAllocator::Free(bucket->stack, 0);
-        MyAllocator::Free(bucket, 0);
-      }
-    }
-    MyAllocator::Free(bucket_table_, 0);
-    num_buckets_ = 0;
-    bucket_table_ = NULL;
-  }
-  RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), "");
-  RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), "");
-  RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), "");
-  RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
-  if (regions_) regions_->~RegionSet();
-  regions_ = NULL;
-  bool deleted_arena = LowLevelAlloc::DeleteArena(arena_);
-  if (deleted_arena) {
-    arena_ = 0;
-  } else {
-    RAW_LOG(WARNING, "Can't delete LowLevelAlloc arena: it's being used");
-  }
-  Unlock();
-  RAW_VLOG(10, "MemoryRegionMap Shutdown done");
-  return deleted_arena;
-}
-
-bool MemoryRegionMap::IsRecordingLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  return client_count_ > 0;
-}
-
-// Invariants (once libpthread_initialized is true):
-//   * While lock_ is not held, recursion_count_ is 0 (and
-//     lock_owner_tid_ is the previous owner, but we don't rely on
-//     that).
-//   * recursion_count_ and lock_owner_tid_ are only written while
-//     both lock_ and owner_lock_ are held. They may be read under
-//     just owner_lock_.
-//   * At entry and exit of Lock() and Unlock(), the current thread
-//     owns lock_ iff pthread_equal(lock_owner_tid_, pthread_self())
-//     && recursion_count_ > 0.
-void MemoryRegionMap::Lock() {
-  {
-    SpinLockHolder l(&owner_lock_);
-    if (recursion_count_ > 0 && current_thread_is(lock_owner_tid_)) {
-      RAW_CHECK(lock_.IsHeld(), "Invariants violated");
-      recursion_count_++;
-      RAW_CHECK(recursion_count_ <= 5,
-                "recursive lock nesting unexpectedly deep");
-      return;
-    }
-  }
-  lock_.Lock();
-  {
-    SpinLockHolder l(&owner_lock_);
-    RAW_CHECK(recursion_count_ == 0,
-              "Last Unlock didn't reset recursion_count_");
-    if (libpthread_initialized)
-      lock_owner_tid_ = pthread_self();
-    recursion_count_ = 1;
-  }
-}
-
-void MemoryRegionMap::Unlock() {
-  SpinLockHolder l(&owner_lock_);
-  RAW_CHECK(recursion_count_ >  0, "unlock when not held");
-  RAW_CHECK(lock_.IsHeld(),
-            "unlock when not held, and recursion_count_ is wrong");
-  RAW_CHECK(current_thread_is(lock_owner_tid_), "unlock by non-holder");
-  recursion_count_--;
-  if (recursion_count_ == 0) {
-    lock_.Unlock();
-  }
-}
-
-bool MemoryRegionMap::LockIsHeld() {
-  SpinLockHolder l(&owner_lock_);
-  return lock_.IsHeld()  &&  current_thread_is(lock_owner_tid_);
-}
-
-const MemoryRegionMap::Region*
-MemoryRegionMap::DoFindRegionLocked(uintptr_t addr) {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  if (regions_ != NULL) {
-    Region sample;
-    sample.SetRegionSetKey(addr);
-    RegionSet::iterator region = regions_->lower_bound(sample);
-    if (region != regions_->end()) {
-      RAW_CHECK(addr <= region->end_addr, "");
-      if (region->start_addr <= addr  &&  addr < region->end_addr) {
-        return &(*region);
-      }
-    }
-  }
-  return NULL;
-}
-
-bool MemoryRegionMap::FindRegion(uintptr_t addr, Region* result) {
-  Lock();
-  const Region* region = DoFindRegionLocked(addr);
-  if (region != NULL) *result = *region;  // create it as an independent copy
-  Unlock();
-  return region != NULL;
-}
-
-bool MemoryRegionMap::FindAndMarkStackRegion(uintptr_t stack_top,
-                                             Region* result) {
-  Lock();
-  const Region* region = DoFindRegionLocked(stack_top);
-  if (region != NULL) {
-    RAW_VLOG(10, "Stack at %p is inside region %p..%p",
-                reinterpret_cast<void*>(stack_top),
-                reinterpret_cast<void*>(region->start_addr),
-                reinterpret_cast<void*>(region->end_addr));
-    const_cast<Region*>(region)->set_is_stack();  // now we know
-      // cast is safe (set_is_stack does not change the set ordering key)
-    *result = *region;  // create *result as an independent copy
-  }
-  Unlock();
-  return region != NULL;
-}
-
-HeapProfileBucket* MemoryRegionMap::GetBucket(int depth,
-                                              const void* const key[]) {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  // Make hash-value
-  uintptr_t hash = 0;
-  for (int i = 0; i < depth; i++) {
-    hash += reinterpret_cast<uintptr_t>(key[i]);
-    hash += hash << 10;
-    hash ^= hash >> 6;
-  }
-  hash += hash << 3;
-  hash ^= hash >> 11;
-
-  // Lookup stack trace in table
-  unsigned int hash_index = (static_cast<unsigned int>(hash)) % kHashTableSize;
-  for (HeapProfileBucket* bucket = bucket_table_[hash_index];
-       bucket != 0;
-       bucket = bucket->next) {
-    if ((bucket->hash == hash) && (bucket->depth == depth) &&
-        std::equal(key, key + depth, bucket->stack)) {
-      return bucket;
-    }
-  }
-
-  // Create new bucket
-  const size_t key_size = sizeof(key[0]) * depth;
-  HeapProfileBucket* bucket;
-  if (recursive_insert) {  // recursion: save in saved_buckets_
-    const void** key_copy = saved_buckets_keys_[saved_buckets_count_];
-    std::copy(key, key + depth, key_copy);
-    bucket = &saved_buckets_[saved_buckets_count_];
-    memset(bucket, 0, sizeof(*bucket));
-    ++saved_buckets_count_;
-    bucket->stack = key_copy;
-    bucket->next  = NULL;
-  } else {
-    recursive_insert = true;
-    const void** key_copy = static_cast<const void**>(
-        MyAllocator::Allocate(key_size));
-    recursive_insert = false;
-    std::copy(key, key + depth, key_copy);
-    recursive_insert = true;
-    bucket = static_cast<HeapProfileBucket*>(
-        MyAllocator::Allocate(sizeof(HeapProfileBucket)));
-    recursive_insert = false;
-    memset(bucket, 0, sizeof(*bucket));
-    bucket->stack = key_copy;
-    bucket->next  = bucket_table_[hash_index];
-  }
-  bucket->hash = hash;
-  bucket->depth = depth;
-  bucket_table_[hash_index] = bucket;
-  ++num_buckets_;
-  return bucket;
-}
-
-MemoryRegionMap::RegionIterator MemoryRegionMap::BeginRegionLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  RAW_CHECK(regions_ != NULL, "");
-  return regions_->begin();
-}
-
-MemoryRegionMap::RegionIterator MemoryRegionMap::EndRegionLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  RAW_CHECK(regions_ != NULL, "");
-  return regions_->end();
-}
-
-inline void MemoryRegionMap::DoInsertRegionLocked(const Region& region) {
-  RAW_VLOG(12, "Inserting region %p..%p from %p",
-              reinterpret_cast<void*>(region.start_addr),
-              reinterpret_cast<void*>(region.end_addr),
-              reinterpret_cast<void*>(region.caller()));
-  RegionSet::const_iterator i = regions_->lower_bound(region);
-  if (i != regions_->end() && i->start_addr <= region.start_addr) {
-    RAW_DCHECK(region.end_addr <= i->end_addr, "");  // lower_bound ensures this
-    return;  // 'region' is a subset of an already recorded region; do nothing
-    // We can be stricter and allow this only when *i has been created via
-    // an mmap with MAP_NORESERVE flag set.
-  }
-  if (DEBUG_MODE) {
-    RAW_CHECK(i == regions_->end()  ||  !region.Overlaps(*i),
-              "Wow, overlapping memory regions");
-    Region sample;
-    sample.SetRegionSetKey(region.start_addr);
-    i = regions_->lower_bound(sample);
-    RAW_CHECK(i == regions_->end()  ||  !region.Overlaps(*i),
-              "Wow, overlapping memory regions");
-  }
-  region.AssertIsConsistent();  // just making sure
-  // This inserts and allocates permanent storage for region
-  // and its call stack data: it's safe to do it now:
-  regions_->insert(region);
-  RAW_VLOG(12, "Inserted region %p..%p :",
-              reinterpret_cast<void*>(region.start_addr),
-              reinterpret_cast<void*>(region.end_addr));
-  if (VLOG_IS_ON(12))  LogAllLocked();
-}
-
-// These variables are local to MemoryRegionMap::InsertRegionLocked()
-// and MemoryRegionMap::HandleSavedRegionsLocked()
-// and are file-level to ensure that they are initialized at load time.
-
-// Number of unprocessed region inserts.
-static int saved_regions_count = 0;
-
-// Unprocessed inserts (must be big enough to hold all allocations that can
-// be caused by a InsertRegionLocked call).
-// Region has no constructor, so that c-tor execution does not interfere
-// with the any-time use of the static memory behind saved_regions.
-static MemoryRegionMap::Region saved_regions[20];
-
-inline void MemoryRegionMap::HandleSavedRegionsLocked(
-              void (*insert_func)(const Region& region)) {
-  while (saved_regions_count > 0) {
-    // Making a local-var copy of the region argument to insert_func
-    // including its stack (w/o doing any memory allocations) is important:
-    // in many cases the memory in saved_regions
-    // will get written-to during the (*insert_func)(r) call below.
-    Region r = saved_regions[--saved_regions_count];
-    (*insert_func)(r);
-  }
-}
-
-void MemoryRegionMap::RestoreSavedBucketsLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  while (saved_buckets_count_ > 0) {
-    HeapProfileBucket bucket = saved_buckets_[--saved_buckets_count_];
-    unsigned int hash_index =
-        static_cast<unsigned int>(bucket.hash) % kHashTableSize;
-    bool is_found = false;
-    for (HeapProfileBucket* curr = bucket_table_[hash_index];
-         curr != 0;
-         curr = curr->next) {
-      if ((curr->hash == bucket.hash) && (curr->depth == bucket.depth) &&
-          std::equal(bucket.stack, bucket.stack + bucket.depth, curr->stack)) {
-        curr->allocs += bucket.allocs;
-        curr->alloc_size += bucket.alloc_size;
-        curr->frees += bucket.frees;
-        curr->free_size += bucket.free_size;
-        is_found = true;
-        break;
-      }
-    }
-    if (is_found) continue;
-
-    const size_t key_size = sizeof(bucket.stack[0]) * bucket.depth;
-    const void** key_copy = static_cast<const void**>(
-        MyAllocator::Allocate(key_size));
-    std::copy(bucket.stack, bucket.stack + bucket.depth, key_copy);
-    HeapProfileBucket* new_bucket = static_cast<HeapProfileBucket*>(
-        MyAllocator::Allocate(sizeof(HeapProfileBucket)));
-    memset(new_bucket, 0, sizeof(*new_bucket));
-    new_bucket->hash = bucket.hash;
-    new_bucket->depth = bucket.depth;
-    new_bucket->stack = key_copy;
-    new_bucket->next = bucket_table_[hash_index];
-    bucket_table_[hash_index] = new_bucket;
-    ++num_buckets_;
-  }
-}
-
-inline void MemoryRegionMap::InitRegionSetLocked() {
-  RAW_VLOG(12, "Initializing region set");
-  regions_ = regions_rep.region_set();
-  recursive_insert = true;
-  new (regions_) RegionSet();
-  HandleSavedRegionsLocked(&DoInsertRegionLocked);
-  recursive_insert = false;
-}
-
-inline void MemoryRegionMap::InsertRegionLocked(const Region& region) {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  // We can be called recursively, because RegionSet constructor
-  // and DoInsertRegionLocked() (called below) can call the allocator.
-  // recursive_insert tells us if that's the case. When this happens,
-  // region insertion information is recorded in saved_regions[],
-  // and taken into account when the recursion unwinds.
-  // Do the insert:
-  if (recursive_insert) {  // recursion: save in saved_regions
-    RAW_VLOG(12, "Saving recursive insert of region %p..%p from %p",
-                reinterpret_cast<void*>(region.start_addr),
-                reinterpret_cast<void*>(region.end_addr),
-                reinterpret_cast<void*>(region.caller()));
-    RAW_CHECK(saved_regions_count < arraysize(saved_regions), "");
-    // Copy 'region' to saved_regions[saved_regions_count]
-    // together with the contents of its call_stack,
-    // then increment saved_regions_count.
-    saved_regions[saved_regions_count++] = region;
-  } else {  // not a recusrive call
-    if (regions_ == NULL) {  // init regions_
-      InitRegionSetLocked();
-    }
-    recursive_insert = true;
-    // Do the actual insertion work to put new regions into regions_:
-    DoInsertRegionLocked(region);
-    HandleSavedRegionsLocked(&DoInsertRegionLocked);
-    recursive_insert = false;
-  }
-}
-
-// We strip out different number of stack frames in debug mode
-// because less inlining happens in that case
-#ifdef NDEBUG
-static const int kStripFrames = 1;
-#else
-static const int kStripFrames = 3;
-#endif
-
-void MemoryRegionMap::RecordRegionAddition(const void* start, size_t size) {
-  // Record start/end info about this memory acquisition call in a new region:
-  Region region;
-  region.Create(start, size);
-  // First get the call stack info into the local varible 'region':
-  int depth = 0;
-  // NOTE: libunwind also does mmap and very much likely while holding
-  // it's own lock(s). So some threads may first take libunwind lock,
-  // and then take region map lock (necessary to record mmap done from
-  // inside libunwind). On the other hand other thread(s) may do
-  // normal mmap. Which would call this method to record it. Which
-  // would then proceed with installing that record to region map
-  // while holding region map lock. That may cause mmap from our own
-  // internal allocators, so attempt to unwind in this case may cause
-  // reverse order of taking libuwind and region map locks. Which is
-  // obvious deadlock.
-  //
-  // Thankfully, we can easily detect if we're holding region map lock
-  // and avoid recording backtrace in this (rare and largely
-  // irrelevant) case. By doing this we "declare" that thread needing
-  // both locks must take region map lock last. In other words we do
-  // not allow taking libuwind lock when we already have region map
-  // lock. Note, this is generally impossible when somebody tries to
-  // mix cpu profiling and heap checking/profiling, because cpu
-  // profiler grabs backtraces at arbitrary places. But at least such
-  // combination is rarer and less relevant.
-  if (max_stack_depth_ > 0 && !LockIsHeld()) {
-    depth = MallocHook::GetCallerStackTrace(const_cast<void**>(region.call_stack),
-                                            max_stack_depth_, kStripFrames + 1);
-  }
-  region.set_call_stack_depth(depth);  // record stack info fully
-  RAW_VLOG(10, "New global region %p..%p from %p",
-              reinterpret_cast<void*>(region.start_addr),
-              reinterpret_cast<void*>(region.end_addr),
-              reinterpret_cast<void*>(region.caller()));
-  // Note: none of the above allocates memory.
-  Lock();  // recursively lock
-  map_size_ += size;
-  InsertRegionLocked(region);
-    // This will (eventually) allocate storage for and copy over the stack data
-    // from region.call_stack_data_ that is pointed by region.call_stack().
-  if (bucket_table_ != NULL) {
-    HeapProfileBucket* b = GetBucket(depth, region.call_stack);
-    ++b->allocs;
-    b->alloc_size += size;
-    if (!recursive_insert) {
-      recursive_insert = true;
-      RestoreSavedBucketsLocked();
-      recursive_insert = false;
-    }
-  }
-  Unlock();
-}
-
-void MemoryRegionMap::RecordRegionRemoval(const void* start, size_t size) {
-  Lock();
-  if (recursive_insert) {
-    // First remove the removed region from saved_regions, if it's
-    // there, to prevent overrunning saved_regions in recursive
-    // map/unmap call sequences, and also from later inserting regions
-    // which have already been unmapped.
-    uintptr_t start_addr = reinterpret_cast<uintptr_t>(start);
-    uintptr_t end_addr = start_addr + size;
-    int put_pos = 0;
-    int old_count = saved_regions_count;
-    for (int i = 0; i < old_count; ++i, ++put_pos) {
-      Region& r = saved_regions[i];
-      if (r.start_addr == start_addr && r.end_addr == end_addr) {
-        // An exact match, so it's safe to remove.
-        RecordRegionRemovalInBucket(r.call_stack_depth, r.call_stack, size);
-        --saved_regions_count;
-        --put_pos;
-        RAW_VLOG(10, ("Insta-Removing saved region %p..%p; "
-                     "now have %d saved regions"),
-                 reinterpret_cast<void*>(start_addr),
-                 reinterpret_cast<void*>(end_addr),
-                 saved_regions_count);
-      } else {
-        if (put_pos < i) {
-          saved_regions[put_pos] = saved_regions[i];
-        }
-      }
-    }
-  }
-  if (regions_ == NULL) {  // We must have just unset the hooks,
-                           // but this thread was already inside the hook.
-    Unlock();
-    return;
-  }
-  if (!recursive_insert) {
-    HandleSavedRegionsLocked(&InsertRegionLocked);
-  }
-    // first handle adding saved regions if any
-  uintptr_t start_addr = reinterpret_cast<uintptr_t>(start);
-  uintptr_t end_addr = start_addr + size;
-  // subtract start_addr, end_addr from all the regions
-  RAW_VLOG(10, "Removing global region %p..%p; have %" PRIuS " regions",
-              reinterpret_cast<void*>(start_addr),
-              reinterpret_cast<void*>(end_addr),
-              regions_->size());
-  Region sample;
-  sample.SetRegionSetKey(start_addr);
-  // Only iterate over the regions that might overlap start_addr..end_addr:
-  for (RegionSet::iterator region = regions_->lower_bound(sample);
-       region != regions_->end()  &&  region->start_addr < end_addr;
-       /*noop*/) {
-    RAW_VLOG(13, "Looking at region %p..%p",
-                reinterpret_cast<void*>(region->start_addr),
-                reinterpret_cast<void*>(region->end_addr));
-    if (start_addr <= region->start_addr  &&
-        region->end_addr <= end_addr) {  // full deletion
-      RAW_VLOG(12, "Deleting region %p..%p",
-                  reinterpret_cast<void*>(region->start_addr),
-                  reinterpret_cast<void*>(region->end_addr));
-      RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
-                                  region->end_addr - region->start_addr);
-      RegionSet::iterator d = region;
-      ++region;
-      regions_->erase(d);
-      continue;
-    } else if (region->start_addr < start_addr  &&
-               end_addr < region->end_addr) {  // cutting-out split
-      RAW_VLOG(12, "Splitting region %p..%p in two",
-                  reinterpret_cast<void*>(region->start_addr),
-                  reinterpret_cast<void*>(region->end_addr));
-      RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
-                                  end_addr - start_addr);
-      // Make another region for the start portion:
-      // The new region has to be the start portion because we can't
-      // just modify region->end_addr as it's the sorting key.
-      Region r = *region;
-      r.set_end_addr(start_addr);
-      InsertRegionLocked(r);
-      // cut *region from start:
-      const_cast<Region&>(*region).set_start_addr(end_addr);
-    } else if (end_addr > region->start_addr  &&
-               start_addr <= region->start_addr) {  // cut from start
-      RAW_VLOG(12, "Start-chopping region %p..%p",
-                  reinterpret_cast<void*>(region->start_addr),
-                  reinterpret_cast<void*>(region->end_addr));
-      RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
-                                  end_addr - region->start_addr);
-      const_cast<Region&>(*region).set_start_addr(end_addr);
-    } else if (start_addr > region->start_addr  &&
-               start_addr < region->end_addr) {  // cut from end
-      RAW_VLOG(12, "End-chopping region %p..%p",
-                  reinterpret_cast<void*>(region->start_addr),
-                  reinterpret_cast<void*>(region->end_addr));
-      RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
-                                  region->end_addr - start_addr);
-      // Can't just modify region->end_addr (it's the sorting key):
-      Region r = *region;
-      r.set_end_addr(start_addr);
-      RegionSet::iterator d = region;
-      ++region;
-      // It's safe to erase before inserting since r is independent of *d:
-      // r contains an own copy of the call stack:
-      regions_->erase(d);
-      InsertRegionLocked(r);
-      continue;
-    }
-    ++region;
-  }
-  RAW_VLOG(12, "Removed region %p..%p; have %" PRIuS " regions",
-              reinterpret_cast<void*>(start_addr),
-              reinterpret_cast<void*>(end_addr),
-              regions_->size());
-  if (VLOG_IS_ON(12))  LogAllLocked();
-  unmap_size_ += size;
-  Unlock();
-}
-
-void MemoryRegionMap::RecordRegionRemovalInBucket(int depth,
-                                                  const void* const stack[],
-                                                  size_t size) {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  if (bucket_table_ == NULL) return;
-  HeapProfileBucket* b = GetBucket(depth, stack);
-  ++b->frees;
-  b->free_size += size;
-}
-
-void MemoryRegionMap::MmapHook(const void* result,
-                               const void* start, size_t size,
-                               int prot, int flags,
-                               int fd, off_t offset) {
-  // TODO(maxim): replace all 0x%" PRIxS " by %p when RAW_VLOG uses a safe
-  // snprintf reimplementation that does not malloc to pretty-print NULL
-  RAW_VLOG(10, "MMap = 0x%" PRIxPTR " of %" PRIuS " at %" PRIu64 " "
-              "prot %d flags %d fd %d offs %" PRId64,
-              reinterpret_cast<uintptr_t>(result), size,
-              reinterpret_cast<uint64>(start), prot, flags, fd,
-              static_cast<int64>(offset));
-  if (result != reinterpret_cast<void*>(MAP_FAILED)  &&  size != 0) {
-    RecordRegionAddition(result, size);
-  }
-}
-
-void MemoryRegionMap::MunmapHook(const void* ptr, size_t size) {
-  RAW_VLOG(10, "MUnmap of %p %" PRIuS "", ptr, size);
-  if (size != 0) {
-    RecordRegionRemoval(ptr, size);
-  }
-}
-
-void MemoryRegionMap::MremapHook(const void* result,
-                                 const void* old_addr, size_t old_size,
-                                 size_t new_size, int flags,
-                                 const void* new_addr) {
-  RAW_VLOG(10, "MRemap = 0x%" PRIxPTR " of 0x%" PRIxPTR " %" PRIuS " "
-              "to %" PRIuS " flags %d new_addr=0x%" PRIxPTR,
-              (uintptr_t)result, (uintptr_t)old_addr,
-               old_size, new_size, flags,
-               flags & MREMAP_FIXED ? (uintptr_t)new_addr : 0);
-  if (result != reinterpret_cast<void*>(-1)) {
-    RecordRegionRemoval(old_addr, old_size);
-    RecordRegionAddition(result, new_size);
-  }
-}
-
-void MemoryRegionMap::SbrkHook(const void* result, ptrdiff_t increment) {
-  RAW_VLOG(10, "Sbrk = 0x%" PRIxPTR " of %" PRIdS "", (uintptr_t)result, increment);
-  if (result != reinterpret_cast<void*>(-1)) {
-    if (increment > 0) {
-      void* new_end = sbrk(0);
-      RecordRegionAddition(result, reinterpret_cast<uintptr_t>(new_end) -
-                                   reinterpret_cast<uintptr_t>(result));
-    } else if (increment < 0) {
-      void* new_end = sbrk(0);
-      RecordRegionRemoval(new_end, reinterpret_cast<uintptr_t>(result) -
-                                   reinterpret_cast<uintptr_t>(new_end));
-    }
-  }
-}
-
-void MemoryRegionMap::LogAllLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  RAW_LOG(INFO, "List of regions:");
-  uintptr_t previous = 0;
-  for (RegionSet::const_iterator r = regions_->begin();
-       r != regions_->end(); ++r) {
-    RAW_LOG(INFO, "Memory region 0x%" PRIxPTR "..0x%" PRIxPTR " "
-                  "from 0x%" PRIxPTR " stack=%d",
-                  r->start_addr, r->end_addr, r->caller(), r->is_stack);
-    RAW_CHECK(previous < r->end_addr, "wow, we messed up the set order");
-      // this must be caused by uncontrolled recursive operations on regions_
-    previous = r->end_addr;
-  }
-  RAW_LOG(INFO, "End of regions list");
-}
diff --git a/third_party/tcmalloc/chromium/src/memory_region_map.h b/third_party/tcmalloc/chromium/src/memory_region_map.h
deleted file mode 100644
index 103ad5b..0000000
--- a/third_party/tcmalloc/chromium/src/memory_region_map.h
+++ /dev/null
@@ -1,419 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Maxim Lifantsev
- */
-
-#ifndef BASE_MEMORY_REGION_MAP_H_
-#define BASE_MEMORY_REGION_MAP_H_
-
-#include <config.h>
-
-#ifdef HAVE_PTHREAD
-#include <pthread.h>
-#endif
-#include <stddef.h>
-#include <set>
-#include "base/stl_allocator.h"
-#include "base/spinlock.h"
-#include "base/thread_annotations.h"
-#include "base/low_level_alloc.h"
-#include "heap-profile-stats.h"
-
-// TODO(maxim): add a unittest:
-//  execute a bunch of mmaps and compare memory map what strace logs
-//  execute a bunch of mmap/munmup and compare memory map with
-//  own accounting of what those mmaps generated
-
-// Thread-safe class to collect and query the map of all memory regions
-// in a process that have been created with mmap, munmap, mremap, sbrk.
-// For each memory region, we keep track of (and provide to users)
-// the stack trace that allocated that memory region.
-// The recorded stack trace depth is bounded by
-// a user-supplied max_stack_depth parameter of Init().
-// After initialization with Init()
-// (which can happened even before global object constructor execution)
-// we collect the map by installing and monitoring MallocHook-s
-// to mmap, munmap, mremap, sbrk.
-// At any time one can query this map via provided interface.
-// For more details on the design of MemoryRegionMap
-// see the comment at the top of our .cc file.
-class MemoryRegionMap {
- private:
-  // Max call stack recording depth supported by Init().  Set it to be
-  // high enough for all our clients.  Note: we do not define storage
-  // for this (doing that requires special handling in windows), so
-  // don't take the address of it!
-  static const int kMaxStackDepth = 32;
-
-  // Size of the hash table of buckets.  A structure of the bucket table is
-  // described in heap-profile-stats.h.
-  static const int kHashTableSize = 179999;
-
- public:
-  MemoryRegionMap(const MemoryRegionMap&) = delete;
-  MemoryRegionMap& operator=(const MemoryRegionMap&) = delete;
-
-  // interface ================================================================
-
-  // Every client of MemoryRegionMap must call Init() before first use,
-  // and Shutdown() after last use.  This allows us to reference count
-  // this (singleton) class properly.  MemoryRegionMap assumes it's the
-  // only client of MallocHooks, so a client can only register other
-  // MallocHooks after calling Init() and must unregister them before
-  // calling Shutdown().
-
-  // Initialize this module to record memory allocation stack traces.
-  // Stack traces that have more than "max_stack_depth" frames
-  // are automatically shrunk to "max_stack_depth" when they are recorded.
-  // Init() can be called more than once w/o harm, largest max_stack_depth
-  // will be the effective one.
-  // When "use_buckets" is true, then counts of mmap and munmap sizes will be
-  // recorded with each stack trace.  If Init() is called more than once, then
-  // counting will be effective after any call contained "use_buckets" of true.
-  // It will install mmap, munmap, mremap, sbrk hooks
-  // and initialize arena_ and our hook and locks, hence one can use
-  // MemoryRegionMap::Lock()/Unlock() to manage the locks.
-  // Uses Lock/Unlock inside.
-  static void Init(int max_stack_depth, bool use_buckets);
-
-  // Try to shutdown this module undoing what Init() did.
-  // Returns true iff could do full shutdown (or it was not attempted).
-  // Full shutdown is attempted when the number of Shutdown() calls equals
-  // the number of Init() calls.
-  static bool Shutdown();
-
-  // Return true if MemoryRegionMap is initialized and recording, i.e. when
-  // then number of Init() calls are more than the number of Shutdown() calls.
-  static bool IsRecordingLocked();
-
-  // Locks to protect our internal data structures.
-  // These also protect use of arena_ if our Init() has been done.
-  // The lock is recursive.
-  static void Lock() EXCLUSIVE_LOCK_FUNCTION(lock_);
-  static void Unlock() UNLOCK_FUNCTION(lock_);
-
-  // Returns true when the lock is held by this thread (for use in RAW_CHECK-s).
-  static bool LockIsHeld();
-
-  // Locker object that acquires the MemoryRegionMap::Lock
-  // for the duration of its lifetime (a C++ scope).
-  class LockHolder {
-   public:
-    LockHolder() { Lock(); }
-
-    LockHolder(const LockHolder&) = delete;
-    LockHolder& operator=(const LockHolder&) = delete;
-
-    ~LockHolder() { Unlock(); }
-  };
-
-  // A memory region that we know about through malloc_hook-s.
-  // This is essentially an interface through which MemoryRegionMap
-  // exports the collected data to its clients.  Thread-compatible.
-  struct Region {
-    uintptr_t start_addr;  // region start address
-    uintptr_t end_addr;  // region end address
-    int call_stack_depth;  // number of caller stack frames that we saved
-    const void* call_stack[kMaxStackDepth];  // caller address stack array
-                                             // filled to call_stack_depth size
-    bool is_stack;  // does this region contain a thread's stack:
-                    // a user of MemoryRegionMap supplies this info
-
-    // Convenience accessor for call_stack[0],
-    // i.e. (the program counter of) the immediate caller
-    // of this region's allocation function,
-    // but it also returns NULL when call_stack_depth is 0,
-    // i.e whe we weren't able to get the call stack.
-    // This usually happens in recursive calls, when the stack-unwinder
-    // calls mmap() which in turn calls the stack-unwinder.
-    uintptr_t caller() const {
-      return reinterpret_cast<uintptr_t>(call_stack_depth >= 1
-                                         ? call_stack[0] : NULL);
-    }
-
-    // Return true iff this region overlaps region x.
-    bool Overlaps(const Region& x) const {
-      return start_addr < x.end_addr  &&  end_addr > x.start_addr;
-    }
-
-   private:  // helpers for MemoryRegionMap
-    friend class MemoryRegionMap;
-
-    // The ways we create Region-s:
-    void Create(const void* start, size_t size) {
-      start_addr = reinterpret_cast<uintptr_t>(start);
-      end_addr = start_addr + size;
-      is_stack = false;  // not a stack till marked such
-      call_stack_depth = 0;
-      AssertIsConsistent();
-    }
-    void set_call_stack_depth(int depth) {
-      RAW_DCHECK(call_stack_depth == 0, "");  // only one such set is allowed
-      call_stack_depth = depth;
-      AssertIsConsistent();
-    }
-
-    // The ways we modify Region-s:
-    void set_is_stack() { is_stack = true; }
-    void set_start_addr(uintptr_t addr) {
-      start_addr = addr;
-      AssertIsConsistent();
-    }
-    void set_end_addr(uintptr_t addr) {
-      end_addr = addr;
-      AssertIsConsistent();
-    }
-
-    // Verifies that *this contains consistent data, crashes if not the case.
-    void AssertIsConsistent() const {
-      RAW_DCHECK(start_addr < end_addr, "");
-      RAW_DCHECK(call_stack_depth >= 0  &&
-                 call_stack_depth <= kMaxStackDepth, "");
-    }
-
-    // Post-default construction helper to make a Region suitable
-    // for searching in RegionSet regions_.
-    void SetRegionSetKey(uintptr_t addr) {
-      // make sure *this has no usable data:
-      if (DEBUG_MODE) memset(this, 0xFF, sizeof(*this));
-      end_addr = addr;
-    }
-
-    // Note: call_stack[kMaxStackDepth] as a member lets us make Region
-    // a simple self-contained struct with correctly behaving bit-vise copying.
-    // This simplifies the code of this module but wastes some memory:
-    // in most-often use case of this module (leak checking)
-    // only one call_stack element out of kMaxStackDepth is actually needed.
-    // Making the storage for call_stack variable-sized,
-    // substantially complicates memory management for the Region-s:
-    // as they need to be created and manipulated for some time
-    // w/o any memory allocations, yet are also given out to the users.
-  };
-
-  // Find the region that covers addr and write its data into *result if found,
-  // in which case *result gets filled so that it stays fully functional
-  // even when the underlying region gets removed from MemoryRegionMap.
-  // Returns success. Uses Lock/Unlock inside.
-  static bool FindRegion(uintptr_t addr, Region* result);
-
-  // Find the region that contains stack_top, mark that region as
-  // a stack region, and write its data into *result if found,
-  // in which case *result gets filled so that it stays fully functional
-  // even when the underlying region gets removed from MemoryRegionMap.
-  // Returns success. Uses Lock/Unlock inside.
-  static bool FindAndMarkStackRegion(uintptr_t stack_top, Region* result);
-
-  // Iterate over the buckets which store mmap and munmap counts per stack
-  // trace.  It calls "callback" for each bucket, and passes "arg" to it.
-  template<class Type>
-  static void IterateBuckets(void (*callback)(const HeapProfileBucket*, Type),
-                             Type arg);
-
-  // Get the bucket whose caller stack trace is "key".  The stack trace is
-  // used to a depth of "depth" at most.  The requested bucket is created if
-  // needed.
-  // The bucket table is described in heap-profile-stats.h.
-  static HeapProfileBucket* GetBucket(int depth, const void* const key[]);
-
- private:  // our internal types ==============================================
-
-  // Region comparator for sorting with STL
-  struct RegionCmp {
-    bool operator()(const Region& x, const Region& y) const {
-      return x.end_addr < y.end_addr;
-    }
-  };
-
-  // We allocate STL objects in our own arena.
-  struct MyAllocator {
-    static void *Allocate(size_t n) {
-      return LowLevelAlloc::AllocWithArena(n, arena_);
-    }
-    static void Free(const void *p, size_t /* n */) {
-      LowLevelAlloc::Free(const_cast<void*>(p));
-    }
-  };
-
-  // Set of the memory regions
-  typedef std::set<Region, RegionCmp,
-              STL_Allocator<Region, MyAllocator> > RegionSet;
-
- public:  // more in-depth interface ==========================================
-
-  // STL iterator with values of Region
-  typedef RegionSet::const_iterator RegionIterator;
-
-  // Return the begin/end iterators to all the regions.
-  // These need Lock/Unlock protection around their whole usage (loop).
-  // Even when the same thread causes modifications during such a loop
-  // (which are permitted due to recursive locking)
-  // the loop iterator will still be valid as long as its region
-  // has not been deleted, but EndRegionLocked should be
-  // re-evaluated whenever the set of regions has changed.
-  static RegionIterator BeginRegionLocked();
-  static RegionIterator EndRegionLocked();
-
-  // Return the accumulated sizes of mapped and unmapped regions.
-  static int64 MapSize() { return map_size_; }
-  static int64 UnmapSize() { return unmap_size_; }
-
-  // Effectively private type from our .cc =================================
-  // public to let us declare global objects:
-  union RegionSetRep;
-
- private:
-  // representation ===========================================================
-
-  // Counter of clients of this module that have called Init().
-  static int client_count_;
-
-  // Maximal number of caller stack frames to save (>= 0).
-  static int max_stack_depth_;
-
-  // Arena used for our allocations in regions_.
-  static LowLevelAlloc::Arena* arena_;
-
-  // Set of the mmap/sbrk/mremap-ed memory regions
-  // To be accessed *only* when Lock() is held.
-  // Hence we protect the non-recursive lock used inside of arena_
-  // with our recursive Lock(). This lets a user prevent deadlocks
-  // when threads are stopped by TCMalloc_ListAllProcessThreads at random spots
-  // simply by acquiring our recursive Lock() before that.
-  static RegionSet* regions_;
-
-  // Lock to protect regions_ and buckets_ variables and the data behind.
-  static SpinLock lock_;
-  // Lock to protect the recursive lock itself.
-  static SpinLock owner_lock_;
-
-  // Recursion count for the recursive lock.
-  static int recursion_count_;
-  // The thread id of the thread that's inside the recursive lock.
-  static pthread_t lock_owner_tid_;
-
-  // Total size of all mapped pages so far
-  static int64 map_size_;
-  // Total size of all unmapped pages so far
-  static int64 unmap_size_;
-
-  // Bucket hash table which is described in heap-profile-stats.h.
-  static HeapProfileBucket** bucket_table_ GUARDED_BY(lock_);
-  static int num_buckets_ GUARDED_BY(lock_);
-
-  // The following members are local to MemoryRegionMap::GetBucket()
-  // and MemoryRegionMap::HandleSavedBucketsLocked()
-  // and are file-level to ensure that they are initialized at load time.
-  //
-  // These are used as temporary storage to break the infinite cycle of mmap
-  // calling our hook which (sometimes) causes mmap.  It must be a static
-  // fixed-size array.  The size 20 is just an expected value for safety.
-  // The details are described in memory_region_map.cc.
-
-  // Number of unprocessed bucket inserts.
-  static int saved_buckets_count_ GUARDED_BY(lock_);
-
-  // Unprocessed inserts (must be big enough to hold all mmaps that can be
-  // caused by a GetBucket call).
-  // Bucket has no constructor, so that c-tor execution does not interfere
-  // with the any-time use of the static memory behind saved_buckets.
-  static HeapProfileBucket saved_buckets_[20] GUARDED_BY(lock_);
-
-  static const void* saved_buckets_keys_[20][kMaxStackDepth] GUARDED_BY(lock_);
-
-  // helpers ==================================================================
-
-  // Helper for FindRegion and FindAndMarkStackRegion:
-  // returns the region covering 'addr' or NULL; assumes our lock_ is held.
-  static const Region* DoFindRegionLocked(uintptr_t addr);
-
-  // Verifying wrapper around regions_->insert(region)
-  // To be called to do InsertRegionLocked's work only!
-  inline static void DoInsertRegionLocked(const Region& region);
-  // Handle regions saved by InsertRegionLocked into a tmp static array
-  // by calling insert_func on them.
-  inline static void HandleSavedRegionsLocked(
-                       void (*insert_func)(const Region& region));
-
-  // Restore buckets saved in a tmp static array by GetBucket to the bucket
-  // table where all buckets eventually should be.
-  static void RestoreSavedBucketsLocked();
-
-  // Initialize RegionSet regions_.
-  inline static void InitRegionSetLocked();
-
-  // Wrapper around DoInsertRegionLocked
-  // that handles the case of recursive allocator calls.
-  inline static void InsertRegionLocked(const Region& region);
-
-  // Record addition of a memory region at address "start" of size "size"
-  // (called from our mmap/mremap/sbrk hooks).
-  static void RecordRegionAddition(const void* start, size_t size);
-  // Record deletion of a memory region at address "start" of size "size"
-  // (called from our munmap/mremap/sbrk hooks).
-  static void RecordRegionRemoval(const void* start, size_t size);
-
-  // Record deletion of a memory region of size "size" in a bucket whose
-  // caller stack trace is "key".  The stack trace is used to a depth of
-  // "depth" at most.
-  static void RecordRegionRemovalInBucket(int depth,
-                                          const void* const key[],
-                                          size_t size);
-
-  // Hooks for MallocHook
-  static void MmapHook(const void* result,
-                       const void* start, size_t size,
-                       int prot, int flags,
-                       int fd, off_t offset);
-  static void MunmapHook(const void* ptr, size_t size);
-  static void MremapHook(const void* result, const void* old_addr,
-                         size_t old_size, size_t new_size, int flags,
-                         const void* new_addr);
-  static void SbrkHook(const void* result, ptrdiff_t increment);
-
-  // Log all memory regions; Useful for debugging only.
-  // Assumes Lock() is held
-  static void LogAllLocked();
-};
-
-template <class Type>
-void MemoryRegionMap::IterateBuckets(
-    void (*callback)(const HeapProfileBucket*, Type), Type callback_arg) {
-  for (int index = 0; index < kHashTableSize; index++) {
-    for (HeapProfileBucket* bucket = bucket_table_[index];
-         bucket != NULL;
-         bucket = bucket->next) {
-      callback(bucket, callback_arg);
-    }
-  }
-}
-
-#endif  // BASE_MEMORY_REGION_MAP_H_
diff --git a/third_party/tcmalloc/chromium/src/packed-cache-inl.h b/third_party/tcmalloc/chromium/src/packed-cache-inl.h
deleted file mode 100644
index 3353fad..0000000
--- a/third_party/tcmalloc/chromium/src/packed-cache-inl.h
+++ /dev/null
@@ -1,218 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Geoff Pike
-//
-// This file provides a minimal cache that can hold a <key, value> pair
-// with little if any wasted space.  The types of the key and value
-// must be unsigned integral types or at least have unsigned semantics
-// for >>, casting, and similar operations.
-//
-// Synchronization is not provided.  However, the cache is implemented
-// as an array of cache entries whose type is chosen at compile time.
-// If a[i] is atomic on your hardware for the chosen array type then
-// raciness will not necessarily lead to bugginess.  The cache entries
-// must be large enough to hold a partial key and a value packed
-// together.  The partial keys are bit strings of length
-// kKeybits - kHashbits, and the values are bit strings of length kValuebits.
-//
-// In an effort to use minimal space, every cache entry represents
-// some <key, value> pair; the class provides no way to mark a cache
-// entry as empty or uninitialized.  In practice, you may want to have
-// reserved keys or values to get around this limitation.  For example, in
-// tcmalloc's PageID-to-sizeclass cache, a value of 0 is used as
-// "unknown sizeclass."
-//
-// Usage Considerations
-// --------------------
-//
-// kHashbits controls the size of the cache.  The best value for
-// kHashbits will of course depend on the application.  Perhaps try
-// tuning the value of kHashbits by measuring different values on your
-// favorite benchmark.  Also remember not to be a pig; other
-// programs that need resources may suffer if you are.
-//
-// The main uses for this class will be when performance is
-// critical and there's a convenient type to hold the cache's
-// entries.  As described above, the number of bits required
-// for a cache entry is (kKeybits - kHashbits) + kValuebits.  Suppose
-// kKeybits + kValuebits is 43.  Then it probably makes sense to
-// chose kHashbits >= 11 so that cache entries fit in a uint32.
-//
-// On the other hand, suppose kKeybits = kValuebits = 64.  Then
-// using this class may be less worthwhile.  You'll probably
-// be using 128 bits for each entry anyway, so maybe just pick
-// a hash function, H, and use an array indexed by H(key):
-//    void Put(K key, V value) { a_[H(key)] = pair<K, V>(key, value); }
-//    V GetOrDefault(K key, V default) { const pair<K, V> &p = a_[H(key)]; ... }
-//    etc.
-//
-// Further Details
-// ---------------
-//
-// For caches used only by one thread, the following is true:
-// 1. For a cache c,
-//      (c.Put(key, value), c.GetOrDefault(key, 0)) == value
-//    and
-//      (c.Put(key, value), <...>, c.GetOrDefault(key, 0)) == value
-//    if the elided code contains no c.Put calls.
-//
-// 2. Has(key) will return false if no <key, value> pair with that key
-//    has ever been Put.  However, a newly initialized cache will have
-//    some <key, value> pairs already present.  When you create a new
-//    cache, you must specify an "initial value."  The initialization
-//    procedure is equivalent to Clear(initial_value), which is
-//    equivalent to Put(k, initial_value) for all keys k from 0 to
-//    2^kHashbits - 1.
-//
-// 3. If key and key' differ then the only way Put(key, value) may
-//    cause Has(key') to change is that Has(key') may change from true to
-//    false. Furthermore, a Put() call that doesn't change Has(key')
-//    doesn't change GetOrDefault(key', ...) either.
-//
-// Implementation details:
-//
-// This is a direct-mapped cache with 2^kHashbits entries; the hash
-// function simply takes the low bits of the key.  We store whole keys
-// if a whole key plus a whole value fits in an entry.  Otherwise, an
-// entry is the high bits of a key and a value, packed together.
-// E.g., a 20 bit key and a 7 bit value only require a uint16 for each
-// entry if kHashbits >= 11.
-//
-// Alternatives to this scheme will be added as needed.
-
-#ifndef TCMALLOC_PACKED_CACHE_INL_H_
-#define TCMALLOC_PACKED_CACHE_INL_H_
-
-#include "config.h"
-#include <stddef.h>                     // for size_t
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uintptr_t
-#endif
-#include "base/basictypes.h"
-#include "common.h"
-#include "internal_logging.h"
-
-// A safe way of doing "(1 << n) - 1" -- without worrying about overflow
-// Note this will all be resolved to a constant expression at compile-time
-#define N_ONES_(IntType, N)                                     \
-  ( (N) == 0 ? 0 : ((static_cast<IntType>(1) << ((N)-1))-1 +    \
-                    (static_cast<IntType>(1) << ((N)-1))) )
-
-// The types K and V provide upper bounds on the number of valid keys
-// and values, but we explicitly require the keys to be less than
-// 2^kKeybits and the values to be less than 2^kValuebits.  The size
-// of the table is controlled by kHashbits, and the type of each entry
-// in the cache is uintptr_t (native machine word).  See also the big
-// comment at the top of the file.
-template <int kKeybits>
-class PackedCache {
- public:
-  typedef uintptr_t T;
-  typedef uintptr_t K;
-  typedef uint32 V;
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-  // Decrease the size map cache if running in the small memory mode.
-  static const int kHashbits = 12;
-#else
-  // We don't want the hash map to occupy 512K memory at Chromium, so
-  // kHashbits is decreased from 16 to 12.
-  static const int kHashbits = 12;
-#endif
-  static const int kValuebits = 7;
-  // one bit after value bits
-  static const int kInvalidMask = 0x80;
-
-  explicit PackedCache() {
-    COMPILE_ASSERT(kKeybits + kValuebits + 1 <= 8 * sizeof(T), use_whole_keys);
-    COMPILE_ASSERT(kHashbits <= kKeybits, hash_function);
-    COMPILE_ASSERT(kHashbits >= kValuebits + 1, small_values_space);
-    Clear();
-  }
-
-  bool TryGet(K key, V* out) const {
-    // As with other code in this class, we touch array_ as few times
-    // as we can.  Assuming entries are read atomically then certain
-    // races are harmless.
-    ASSERT(key == (key & kKeyMask));
-    T hash = Hash(key);
-    T expected_entry = key;
-    expected_entry &= ~N_ONES_(T, kHashbits);
-    T entry = array_[hash];
-    entry ^= expected_entry;
-    if (PREDICT_FALSE(entry >= (1 << kValuebits))) {
-      return false;
-    }
-    *out = static_cast<V>(entry);
-    return true;
-  }
-
-  void Clear() {
-    // sets 'invalid' bit in every byte, include value byte
-    memset(const_cast<T* >(array_), kInvalidMask, sizeof(array_));
-  }
-
-  void Put(K key, V value) {
-    ASSERT(key == (key & kKeyMask));
-    ASSERT(value == (value & kValueMask));
-    array_[Hash(key)] = KeyToUpper(key) | value;
-  }
-
-  void Invalidate(K key) {
-    ASSERT(key == (key & kKeyMask));
-    array_[Hash(key)] = KeyToUpper(key) | kInvalidMask;
-  }
-
- private:
-  // we just wipe all hash bits out of key. I.e. clear lower
-  // kHashbits. We rely on compiler knowing value of Hash(k).
-  static T KeyToUpper(K k) {
-    return static_cast<T>(k) ^ Hash(k);
-  }
-
-  static T Hash(K key) {
-    return static_cast<T>(key) & N_ONES_(size_t, kHashbits);
-  }
-
-  // For masking a K.
-  static const K kKeyMask = N_ONES_(K, kKeybits);
-
-  // For masking a V or a T.
-  static const V kValueMask = N_ONES_(V, kValuebits);
-
-  // array_ is the cache.  Its elements are volatile because any
-  // thread can write any array element at any time.
-  volatile T array_[1 << kHashbits];
-};
-
-#undef N_ONES_
-
-#endif  // TCMALLOC_PACKED_CACHE_INL_H_
diff --git a/third_party/tcmalloc/chromium/src/page_heap.cc b/third_party/tcmalloc/chromium/src/page_heap.cc
deleted file mode 100644
index 7dd5646..0000000
--- a/third_party/tcmalloc/chromium/src/page_heap.cc
+++ /dev/null
@@ -1,726 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>                   // for PRIuPTR
-#endif
-#include <errno.h>                      // for ENOMEM, errno
-#include <gperftools/malloc_extension.h>      // for MallocRange, etc
-#include "base/basictypes.h"
-#include "base/commandlineflags.h"
-#include "internal_logging.h"  // for ASSERT, TCMalloc_Printer, etc
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "static_vars.h"       // for Static
-#include "system-alloc.h"      // for TCMalloc_SystemAlloc, etc
-
-DEFINE_double(tcmalloc_release_rate,
-              EnvToDouble("TCMALLOC_RELEASE_RATE", 1.0),
-              "Rate at which we release unused memory to the system.  "
-              "Zero means we never release memory back to the system.  "
-              "Increase this flag to return memory faster; decrease it "
-              "to return memory slower.  Reasonable rates are in the "
-              "range [0,10]");
-
-DEFINE_int64(tcmalloc_heap_limit_mb,
-              EnvToInt("TCMALLOC_HEAP_LIMIT_MB", 0),
-              "Limit total size of the process heap to the "
-              "specified number of MiB. "
-              "When we approach the limit the memory is released "
-              "to the system more aggressively (more minor page faults). "
-              "Zero means to allocate as long as system allows.");
-
-namespace tcmalloc {
-
-PageHeap::PageHeap()
-    : pagemap_(MetaDataAlloc),
-      scavenge_counter_(0),
-      // Start scavenging at kMaxPages list
-      release_index_(kMaxPages),
-      aggressive_decommit_(false) {
-  COMPILE_ASSERT(kClassSizesMax <= (1 << PageMapCache::kValuebits), valuebits);
-  for (int i = 0; i < kMaxPages; i++) {
-    DLL_Init(&free_[i].normal);
-    DLL_Init(&free_[i].returned);
-  }
-}
-
-Span* PageHeap::SearchFreeAndLargeLists(Length n) {
-  ASSERT(Check());
-  ASSERT(n > 0);
-
-  // Find first size >= n that has a non-empty list
-  for (Length s = n; s <= kMaxPages; s++) {
-    Span* ll = &free_[s - 1].normal;
-    // If we're lucky, ll is non-empty, meaning it has a suitable span.
-    if (!DLL_IsEmpty(ll)) {
-      ASSERT(ll->next->location == Span::ON_NORMAL_FREELIST);
-      return Carve(ll->next, n);
-    }
-    // Alternatively, maybe there's a usable returned span.
-    ll = &free_[s - 1].returned;
-    if (!DLL_IsEmpty(ll)) {
-      // We did not call EnsureLimit before, to avoid releasing the span
-      // that will be taken immediately back.
-      // Calling EnsureLimit here is not very expensive, as it fails only if
-      // there is no more normal spans (and it fails efficiently)
-      // or SystemRelease does not work (there is probably no returned spans).
-      if (EnsureLimit(n)) {
-        // ll may have became empty due to coalescing
-        if (!DLL_IsEmpty(ll)) {
-          ASSERT(ll->next->location == Span::ON_RETURNED_FREELIST);
-          return Carve(ll->next, n);
-        }
-      }
-    }
-  }
-  // No luck in free lists, our last chance is in a larger class.
-  return AllocLarge(n);  // May be NULL
-}
-
-static const size_t kForcedCoalesceInterval = 128*1024*1024;
-
-Span* PageHeap::New(Length n) {
-  ASSERT(Check());
-  ASSERT(n > 0);
-
-  Span* result = SearchFreeAndLargeLists(n);
-  if (result != NULL)
-    return result;
-
-  if (stats_.free_bytes != 0 && stats_.unmapped_bytes != 0
-      && stats_.free_bytes + stats_.unmapped_bytes >= stats_.system_bytes / 4
-      && (stats_.system_bytes / kForcedCoalesceInterval
-          != (stats_.system_bytes + (n << kPageShift)) / kForcedCoalesceInterval)) {
-    // We're about to grow heap, but there are lots of free pages.
-    // tcmalloc's design decision to keep unmapped and free spans
-    // separately and never coalesce them means that sometimes there
-    // can be free pages span of sufficient size, but it consists of
-    // "segments" of different type so page heap search cannot find
-    // it. In order to prevent growing heap and wasting memory in such
-    // case we're going to unmap all free pages. So that all free
-    // spans are maximally coalesced.
-    //
-    // We're also limiting 'rate' of going into this path to be at
-    // most once per 128 megs of heap growth. Otherwise programs that
-    // grow heap frequently (and that means by small amount) could be
-    // penalized with higher count of minor page faults.
-    //
-    // See also large_heap_fragmentation_unittest.cc and
-    // https://code.google.com/p/gperftools/issues/detail?id=368
-    ReleaseAtLeastNPages(static_cast<Length>(0x7fffffff));
-
-    // then try again. If we are forced to grow heap because of large
-    // spans fragmentation and not because of problem described above,
-    // then at the very least we've just unmapped free but
-    // insufficiently big large spans back to OS. So in case of really
-    // unlucky memory fragmentation we'll be consuming virtual address
-    // space, but not real memory
-    result = SearchFreeAndLargeLists(n);
-    if (result != NULL) return result;
-  }
-
-  // Grow the heap and try again.
-  if (!GrowHeap(n)) {
-    ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
-    ASSERT(Check());
-    // underlying SysAllocator likely set ENOMEM but we can get here
-    // due to EnsureLimit so we set it here too.
-    //
-    // Setting errno to ENOMEM here allows us to avoid dealing with it
-    // in fast-path.
-    errno = ENOMEM;
-    return NULL;
-  }
-  return SearchFreeAndLargeLists(n);
-}
-
-Span* PageHeap::AllocLarge(Length n) {
-  Span *best = NULL;
-  Span *best_normal = NULL;
-
-  // Create a Span to use as an upper bound.
-  Span bound;
-  bound.start = 0;
-  bound.length = n;
-
-  // First search the NORMAL spans..
-  SpanSet::iterator place = large_normal_.upper_bound(SpanPtrWithLength(&bound));
-  if (place != large_normal_.end()) {
-    best = place->span;
-    best_normal = best;
-    ASSERT(best->location == Span::ON_NORMAL_FREELIST);
-  }
-
-  // Try to find better fit from RETURNED spans.
-  place = large_returned_.upper_bound(SpanPtrWithLength(&bound));
-  if (place != large_returned_.end()) {
-    Span *c = place->span;
-    ASSERT(c->location == Span::ON_RETURNED_FREELIST);
-    if (best_normal == NULL
-        || c->length < best->length
-        || (c->length == best->length && c->start < best->start))
-      best = place->span;
-  }
-
-  if (best == best_normal) {
-    return best == NULL ? NULL : Carve(best, n);
-  }
-
-  // best comes from RETURNED set.
-
-  if (EnsureLimit(n, false)) {
-    return Carve(best, n);
-  }
-
-  if (EnsureLimit(n, true)) {
-    // best could have been destroyed by coalescing.
-    // best_normal is not a best-fit, and it could be destroyed as well.
-    // We retry, the limit is already ensured:
-    return AllocLarge(n);
-  }
-
-  // If best_normal existed, EnsureLimit would succeeded:
-  ASSERT(best_normal == NULL);
-  // We are not allowed to take best from returned list.
-  return NULL;
-}
-
-Span* PageHeap::Split(Span* span, Length n) {
-  ASSERT(0 < n);
-  ASSERT(n < span->length);
-  ASSERT(span->location == Span::IN_USE);
-  ASSERT(span->sizeclass == 0);
-  Event(span, 'T', n);
-
-  const int extra = span->length - n;
-  Span* leftover = NewSpan(span->start + n, extra);
-  ASSERT(leftover->location == Span::IN_USE);
-  Event(leftover, 'U', extra);
-  RecordSpan(leftover);
-  pagemap_.set(span->start + n - 1, span); // Update map from pageid to span
-  span->length = n;
-
-  return leftover;
-}
-
-void PageHeap::CommitSpan(Span* span) {
-  ++stats_.commit_count;
-
-  TCMalloc_SystemCommit(reinterpret_cast<void*>(span->start << kPageShift),
-                        static_cast<size_t>(span->length << kPageShift));
-  stats_.committed_bytes += span->length << kPageShift;
-  stats_.total_commit_bytes += (span->length << kPageShift);
-}
-
-bool PageHeap::DecommitSpan(Span* span) {
-  ++stats_.decommit_count;
-
-  bool rv = TCMalloc_SystemRelease(reinterpret_cast<void*>(span->start << kPageShift),
-                                   static_cast<size_t>(span->length << kPageShift));
-  if (rv) {
-    stats_.committed_bytes -= span->length << kPageShift;
-    stats_.total_decommit_bytes += (span->length << kPageShift);
-  }
-
-  return rv;
-}
-
-Span* PageHeap::Carve(Span* span, Length n) {
-  ASSERT(n > 0);
-  ASSERT(span->location != Span::IN_USE);
-  const int old_location = span->location;
-  RemoveFromFreeList(span);
-  span->location = Span::IN_USE;
-  Event(span, 'A', n);
-
-  const int extra = span->length - n;
-  ASSERT(extra >= 0);
-  if (extra > 0) {
-    Span* leftover = NewSpan(span->start + n, extra);
-    leftover->location = old_location;
-    Event(leftover, 'S', extra);
-    RecordSpan(leftover);
-
-    // The previous span of |leftover| was just splitted -- no need to
-    // coalesce them. The next span of |leftover| was not previously coalesced
-    // with |span|, i.e. is NULL or has got location other than |old_location|.
-#ifndef NDEBUG
-    const PageID p = leftover->start;
-    const Length len = leftover->length;
-    Span* next = GetDescriptor(p+len);
-    ASSERT (next == NULL ||
-            next->location == Span::IN_USE ||
-            next->location != leftover->location);
-#endif
-
-    PrependToFreeList(leftover);  // Skip coalescing - no candidates possible
-    span->length = n;
-    pagemap_.set(span->start + n - 1, span);
-  }
-  ASSERT(Check());
-  if (old_location == Span::ON_RETURNED_FREELIST) {
-    // We need to recommit this address space.
-    CommitSpan(span);
-  }
-  ASSERT(span->location == Span::IN_USE);
-  ASSERT(span->length == n);
-  ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
-  return span;
-}
-
-void PageHeap::Delete(Span* span) {
-  ASSERT(Check());
-  ASSERT(span->location == Span::IN_USE);
-  ASSERT(span->length > 0);
-  ASSERT(GetDescriptor(span->start) == span);
-  ASSERT(GetDescriptor(span->start + span->length - 1) == span);
-  const Length n = span->length;
-  span->sizeclass = 0;
-  span->sample = 0;
-  span->location = Span::ON_NORMAL_FREELIST;
-  Event(span, 'D', span->length);
-  MergeIntoFreeList(span);  // Coalesces if possible
-  IncrementalScavenge(n);
-  ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
-  ASSERT(Check());
-}
-
-// Given span we're about to free and other span (still on free list),
-// checks if 'other' span is mergable with 'span'. If it is, removes
-// other span from free list, performs aggressive decommit if
-// necessary and returns 'other' span. Otherwise 'other' span cannot
-// be merged and is left untouched. In that case NULL is returned.
-Span* PageHeap::CheckAndHandlePreMerge(Span* span, Span* other) {
-  if (other == NULL) {
-    return other;
-  }
-  // if we're in aggressive decommit mode and span is decommitted,
-  // then we try to decommit adjacent span.
-  if (aggressive_decommit_ && other->location == Span::ON_NORMAL_FREELIST
-      && span->location == Span::ON_RETURNED_FREELIST) {
-    bool worked = DecommitSpan(other);
-    if (!worked) {
-      return NULL;
-    }
-  } else if (other->location != span->location) {
-    return NULL;
-  }
-
-  RemoveFromFreeList(other);
-  return other;
-}
-
-void PageHeap::MergeIntoFreeList(Span* span) {
-  ASSERT(span->location != Span::IN_USE);
-
-  // Coalesce -- we guarantee that "p" != 0, so no bounds checking
-  // necessary.  We do not bother resetting the stale pagemap
-  // entries for the pieces we are merging together because we only
-  // care about the pagemap entries for the boundaries.
-  //
-  // Note: depending on aggressive_decommit_ mode we allow only
-  // similar spans to be coalesced.
-  //
-  // The following applies if aggressive_decommit_ is enabled:
-  //
-  // TODO(jar): "Always decommit" causes some extra calls to commit when we are
-  // called in GrowHeap() during an allocation :-/.  We need to eval the cost of
-  // that oscillation, and possibly do something to reduce it.
-
-  // TODO(jar): We need a better strategy for deciding to commit, or decommit,
-  // based on memory usage and free heap sizes.
-
-  const PageID p = span->start;
-  const Length n = span->length;
-
-  if (aggressive_decommit_ && span->location == Span::ON_NORMAL_FREELIST) {
-    if (DecommitSpan(span)) {
-      span->location = Span::ON_RETURNED_FREELIST;
-    }
-  }
-
-  Span* prev = CheckAndHandlePreMerge(span, GetDescriptor(p-1));
-  if (prev != NULL) {
-    // Merge preceding span into this span
-    ASSERT(prev->start + prev->length == p);
-    const Length len = prev->length;
-    DeleteSpan(prev);
-    span->start -= len;
-    span->length += len;
-    pagemap_.set(span->start, span);
-    Event(span, 'L', len);
-  }
-  Span* next = CheckAndHandlePreMerge(span, GetDescriptor(p+n));
-  if (next != NULL) {
-    // Merge next span into this span
-    ASSERT(next->start == p+n);
-    const Length len = next->length;
-    DeleteSpan(next);
-    span->length += len;
-    pagemap_.set(span->start + span->length - 1, span);
-    Event(span, 'R', len);
-  }
-
-  PrependToFreeList(span);
-}
-
-void PageHeap::PrependToFreeList(Span* span) {
-  ASSERT(span->location != Span::IN_USE);
-  if (span->location == Span::ON_NORMAL_FREELIST)
-    stats_.free_bytes += (span->length << kPageShift);
-  else
-    stats_.unmapped_bytes += (span->length << kPageShift);
-
-  if (span->length > kMaxPages) {
-    SpanSet *set = &large_normal_;
-    if (span->location == Span::ON_RETURNED_FREELIST)
-      set = &large_returned_;
-    std::pair<SpanSet::iterator, bool> p =
-        set->insert(SpanPtrWithLength(span));
-    ASSERT(p.second); // We never have duplicates since span->start is unique.
-    span->SetSpanSetIterator(p.first);
-    return;
-  }
-
-  SpanList* list = &free_[span->length - 1];
-  if (span->location == Span::ON_NORMAL_FREELIST) {
-    DLL_Prepend(&list->normal, span);
-  } else {
-    DLL_Prepend(&list->returned, span);
-  }
-}
-
-void PageHeap::RemoveFromFreeList(Span* span) {
-  ASSERT(span->location != Span::IN_USE);
-  if (span->location == Span::ON_NORMAL_FREELIST) {
-    stats_.free_bytes -= (span->length << kPageShift);
-  } else {
-    stats_.unmapped_bytes -= (span->length << kPageShift);
-  }
-  if (span->length > kMaxPages) {
-    SpanSet *set = &large_normal_;
-    if (span->location == Span::ON_RETURNED_FREELIST)
-      set = &large_returned_;
-    SpanSet::iterator iter = span->ExtractSpanSetIterator();
-    ASSERT(iter->span == span);
-    ASSERT(set->find(SpanPtrWithLength(span)) == iter);
-    set->erase(iter);
-  } else {
-    DLL_Remove(span);
-  }
-}
-
-void PageHeap::IncrementalScavenge(Length n) {
-  // Fast path; not yet time to release memory
-  scavenge_counter_ -= n;
-  if (scavenge_counter_ >= 0) return;  // Not yet time to scavenge
-
-  const double rate = FLAGS_tcmalloc_release_rate;
-  if (rate <= 1e-6) {
-    // Tiny release rate means that releasing is disabled.
-    scavenge_counter_ = kDefaultReleaseDelay;
-    return;
-  }
-
-  ++stats_.scavenge_count;
-
-  Length released_pages = ReleaseAtLeastNPages(1);
-
-  if (released_pages == 0) {
-    // Nothing to scavenge, delay for a while.
-    scavenge_counter_ = kDefaultReleaseDelay;
-  } else {
-    // Compute how long to wait until we return memory.
-    // FLAGS_tcmalloc_release_rate==1 means wait for 1000 pages
-    // after releasing one page.
-    const double mult = 1000.0 / rate;
-    double wait = mult * static_cast<double>(released_pages);
-    if (wait > kMaxReleaseDelay) {
-      // Avoid overflow and bound to reasonable range.
-      wait = kMaxReleaseDelay;
-    }
-    scavenge_counter_ = static_cast<int64_t>(wait);
-  }
-}
-
-Length PageHeap::ReleaseSpan(Span* s) {
-  ASSERT(s->location == Span::ON_NORMAL_FREELIST);
-
-  if (DecommitSpan(s)) {
-    RemoveFromFreeList(s);
-    const Length n = s->length;
-    s->location = Span::ON_RETURNED_FREELIST;
-    MergeIntoFreeList(s);  // Coalesces if possible.
-    return n;
-  }
-
-  return 0;
-}
-
-Length PageHeap::ReleaseAtLeastNPages(Length num_pages) {
-  Length released_pages = 0;
-
-  // Round robin through the lists of free spans, releasing a
-  // span from each list.  Stop after releasing at least num_pages
-  // or when there is nothing more to release.
-  while (released_pages < num_pages && stats_.free_bytes > 0) {
-    for (int i = 0; i < kMaxPages+1 && released_pages < num_pages;
-         i++, release_index_++) {
-      Span *s;
-      if (release_index_ > kMaxPages) release_index_ = 0;
-
-      if (release_index_ == kMaxPages) {
-        if (large_normal_.empty()) {
-          continue;
-        }
-        s = (large_normal_.begin())->span;
-      } else {
-        SpanList* slist = &free_[release_index_];
-        if (DLL_IsEmpty(&slist->normal)) {
-          continue;
-        }
-        s = slist->normal.prev;
-      }
-      // TODO(todd) if the remaining number of pages to release
-      // is significantly smaller than s->length, and s is on the
-      // large freelist, should we carve s instead of releasing?
-      // the whole thing?
-      Length released_len = ReleaseSpan(s);
-      // Some systems do not support release
-      if (released_len == 0) return released_pages;
-      released_pages += released_len;
-    }
-  }
-  return released_pages;
-}
-
-bool PageHeap::EnsureLimit(Length n, bool withRelease)
-{
-  Length limit = (FLAGS_tcmalloc_heap_limit_mb*1024*1024) >> kPageShift;
-  if (limit == 0) return true; //there is no limit
-
-  // We do not use stats_.system_bytes because it does not take
-  // MetaDataAllocs into account.
-  Length takenPages = TCMalloc_SystemTaken >> kPageShift;
-  //XXX takenPages may be slightly bigger than limit for two reasons:
-  //* MetaDataAllocs ignore the limit (it is not easy to handle
-  //  out of memory there)
-  //* sys_alloc may round allocation up to huge page size,
-  //  although smaller limit was ensured
-
-  ASSERT(takenPages >= stats_.unmapped_bytes >> kPageShift);
-  takenPages -= stats_.unmapped_bytes >> kPageShift;
-
-  if (takenPages + n > limit && withRelease) {
-    takenPages -= ReleaseAtLeastNPages(takenPages + n - limit);
-  }
-
-  return takenPages + n <= limit;
-}
-
-void PageHeap::RegisterSizeClass(Span* span, uint32 sc) {
-  // Associate span object with all interior pages as well
-  ASSERT(span->location == Span::IN_USE);
-  ASSERT(GetDescriptor(span->start) == span);
-  ASSERT(GetDescriptor(span->start+span->length-1) == span);
-  Event(span, 'C', sc);
-  span->sizeclass = sc;
-  for (Length i = 1; i < span->length-1; i++) {
-    pagemap_.set(span->start+i, span);
-  }
-}
-
-void PageHeap::GetSmallSpanStats(SmallSpanStats* result) {
-  for (int i = 0; i < kMaxPages; i++) {
-    result->normal_length[i] = DLL_Length(&free_[i].normal);
-    result->returned_length[i] = DLL_Length(&free_[i].returned);
-  }
-}
-
-void PageHeap::GetLargeSpanStats(LargeSpanStats* result) {
-  result->spans = 0;
-  result->normal_pages = 0;
-  result->returned_pages = 0;
-  for (SpanSet::iterator it = large_normal_.begin(); it != large_normal_.end(); ++it) {
-    result->normal_pages += it->length;
-    result->spans++;
-  }
-  for (SpanSet::iterator it = large_returned_.begin(); it != large_returned_.end(); ++it) {
-    result->returned_pages += it->length;
-    result->spans++;
-  }
-}
-
-bool PageHeap::GetNextRange(PageID start, base::MallocRange* r) {
-  Span* span = reinterpret_cast<Span*>(pagemap_.Next(start));
-  if (span == NULL) {
-    return false;
-  }
-  r->address = span->start << kPageShift;
-  r->length = span->length << kPageShift;
-  r->fraction = 0;
-  switch (span->location) {
-    case Span::IN_USE:
-      r->type = base::MallocRange::INUSE;
-      r->fraction = 1;
-      if (span->sizeclass > 0) {
-        // Only some of the objects in this span may be in use.
-        const size_t osize = Static::sizemap()->class_to_size(span->sizeclass);
-        r->fraction = (1.0 * osize * span->refcount) / r->length;
-      }
-      break;
-    case Span::ON_NORMAL_FREELIST:
-      r->type = base::MallocRange::FREE;
-      break;
-    case Span::ON_RETURNED_FREELIST:
-      r->type = base::MallocRange::UNMAPPED;
-      break;
-    default:
-      r->type = base::MallocRange::UNKNOWN;
-      break;
-  }
-  return true;
-}
-
-static void RecordGrowth(size_t growth) {
-  StackTrace* t = Static::stacktrace_allocator()->New();
-  t->depth = GetStackTrace(t->stack, kMaxStackDepth-1, 3);
-  t->size = growth;
-  t->stack[kMaxStackDepth-1] = reinterpret_cast<void*>(Static::growth_stacks());
-  Static::set_growth_stacks(t);
-}
-
-bool PageHeap::GrowHeap(Length n) {
-  ASSERT(kMaxPages >= kMinSystemAlloc);
-  if (n > kMaxValidPages) return false;
-  Length ask = (n>kMinSystemAlloc) ? n : static_cast<Length>(kMinSystemAlloc);
-  size_t actual_size;
-  void* ptr = NULL;
-  if (EnsureLimit(ask)) {
-      ptr = TCMalloc_SystemAlloc(ask << kPageShift, &actual_size, kPageSize);
-  }
-  if (ptr == NULL) {
-    if (n < ask) {
-      // Try growing just "n" pages
-      ask = n;
-      if (EnsureLimit(ask)) {
-        ptr = TCMalloc_SystemAlloc(ask << kPageShift, &actual_size, kPageSize);
-      }
-    }
-    if (ptr == NULL) return false;
-  }
-  ask = actual_size >> kPageShift;
-  RecordGrowth(ask << kPageShift);
-
-  ++stats_.reserve_count;
-  ++stats_.commit_count;
-
-  uint64_t old_system_bytes = stats_.system_bytes;
-  stats_.system_bytes += (ask << kPageShift);
-  stats_.committed_bytes += (ask << kPageShift);
-
-  stats_.total_commit_bytes += (ask << kPageShift);
-  stats_.total_reserve_bytes += (ask << kPageShift);
-
-  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-  ASSERT(p > 0);
-
-  // If we have already a lot of pages allocated, just pre allocate a bunch of
-  // memory for the page map. This prevents fragmentation by pagemap metadata
-  // when a program keeps allocating and freeing large blocks.
-
-  if (old_system_bytes < kPageMapBigAllocationThreshold
-      && stats_.system_bytes >= kPageMapBigAllocationThreshold) {
-    pagemap_.PreallocateMoreMemory();
-  }
-
-  // Make sure pagemap_ has entries for all of the new pages.
-  // Plus ensure one before and one after so coalescing code
-  // does not need bounds-checking.
-  if (pagemap_.Ensure(p-1, ask+2)) {
-    // Pretend the new area is allocated and then Delete() it to cause
-    // any necessary coalescing to occur.
-    Span* span = NewSpan(p, ask);
-    RecordSpan(span);
-    Delete(span);
-    ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
-    ASSERT(Check());
-    return true;
-  } else {
-    // We could not allocate memory within "pagemap_"
-    // TODO: Once we can return memory to the system, return the new span
-    return false;
-  }
-}
-
-bool PageHeap::Check() {
-  return true;
-}
-
-bool PageHeap::CheckExpensive() {
-  bool result = Check();
-  CheckSet(&large_normal_, kMaxPages + 1, Span::ON_NORMAL_FREELIST);
-  CheckSet(&large_returned_, kMaxPages + 1, Span::ON_RETURNED_FREELIST);
-  for (int s = 1; s <= kMaxPages; s++) {
-    CheckList(&free_[s - 1].normal, s, s, Span::ON_NORMAL_FREELIST);
-    CheckList(&free_[s - 1].returned, s, s, Span::ON_RETURNED_FREELIST);
-  }
-  return result;
-}
-
-bool PageHeap::CheckList(Span* list, Length min_pages, Length max_pages,
-                         int freelist) {
-  for (Span* s = list->next; s != list; s = s->next) {
-    CHECK_CONDITION(s->location == freelist);  // NORMAL or RETURNED
-    CHECK_CONDITION(s->length >= min_pages);
-    CHECK_CONDITION(s->length <= max_pages);
-    CHECK_CONDITION(GetDescriptor(s->start) == s);
-    CHECK_CONDITION(GetDescriptor(s->start+s->length-1) == s);
-  }
-  return true;
-}
-
-bool PageHeap::CheckSet(SpanSet* spanset, Length min_pages,int freelist) {
-  for (SpanSet::iterator it = spanset->begin(); it != spanset->end(); ++it) {
-    Span* s = it->span;
-    CHECK_CONDITION(s->length == it->length);
-    CHECK_CONDITION(s->location == freelist);  // NORMAL or RETURNED
-    CHECK_CONDITION(s->length >= min_pages);
-    CHECK_CONDITION(GetDescriptor(s->start) == s);
-    CHECK_CONDITION(GetDescriptor(s->start+s->length-1) == s);
-  }
-  return true;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/page_heap.h b/third_party/tcmalloc/chromium/src/page_heap.h
deleted file mode 100644
index 2d39a35..0000000
--- a/third_party/tcmalloc/chromium/src/page_heap.h
+++ /dev/null
@@ -1,348 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#ifndef TCMALLOC_PAGE_HEAP_H_
-#define TCMALLOC_PAGE_HEAP_H_
-
-#include <config.h>
-#include <stddef.h>                     // for size_t
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uint64_t, int64_t, uint16_t
-#endif
-#include <gperftools/malloc_extension.h>
-#include "base/basictypes.h"
-#include "common.h"
-#include "packed-cache-inl.h"
-#include "pagemap.h"
-#include "span.h"
-
-// We need to dllexport PageHeap just for the unittest.  MSVC complains
-// that we don't dllexport the PageHeap members, but we don't need to
-// test those, so I just suppress this warning.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4251)
-#endif
-
-// This #ifdef should almost never be set.  Set NO_TCMALLOC_SAMPLES if
-// you're porting to a system where you really can't get a stacktrace.
-// Because we control the definition of GetStackTrace, all clients of
-// GetStackTrace should #include us rather than stacktrace.h.
-#ifdef NO_TCMALLOC_SAMPLES
-  // We use #define so code compiles even if you #include stacktrace.h somehow.
-# define GetStackTrace(stack, depth, skip)  (0)
-#else
-# include <gperftools/stacktrace.h>
-#endif
-
-namespace base {
-struct MallocRange;
-}
-
-namespace tcmalloc {
-
-// -------------------------------------------------------------------------
-// Map from page-id to per-page data
-// -------------------------------------------------------------------------
-
-// We use PageMap2<> for 32-bit and PageMap3<> for 64-bit machines.
-// We also use a simple one-level cache for hot PageID-to-sizeclass mappings,
-// because sometimes the sizeclass is all the information we need.
-
-// Selector class -- general selector uses 3-level map
-template <int BITS> class MapSelector {
- public:
-  typedef TCMalloc_PageMap3<BITS-kPageShift> Type;
-};
-
-// A two-level map for 32-bit machines
-template <> class MapSelector<32> {
- public:
-  typedef TCMalloc_PageMap2<32-kPageShift> Type;
-};
-
-// -------------------------------------------------------------------------
-// Page-level allocator
-//  * Eager coalescing
-//
-// Heap for page-level allocation.  We allow allocating and freeing a
-// contiguous runs of pages (called a "span").
-// -------------------------------------------------------------------------
-
-class PERFTOOLS_DLL_DECL PageHeap {
- public:
-  PageHeap();
-
-  // Allocate a run of "n" pages.  Returns zero if out of memory.
-  // Caller should not pass "n == 0" -- instead, n should have
-  // been rounded up already.
-  Span* New(Length n);
-
-  // Delete the span "[p, p+n-1]".
-  // REQUIRES: span was returned by earlier call to New() and
-  //           has not yet been deleted.
-  void Delete(Span* span);
-
-  // Mark an allocated span as being used for small objects of the
-  // specified size-class.
-  // REQUIRES: span was returned by an earlier call to New()
-  //           and has not yet been deleted.
-  void RegisterSizeClass(Span* span, uint32 sc);
-
-  // Split an allocated span into two spans: one of length "n" pages
-  // followed by another span of length "span->length - n" pages.
-  // Modifies "*span" to point to the first span of length "n" pages.
-  // Returns a pointer to the second span.
-  //
-  // REQUIRES: "0 < n < span->length"
-  // REQUIRES: span->location == IN_USE
-  // REQUIRES: span->sizeclass == 0
-  Span* Split(Span* span, Length n);
-
-  // Return the descriptor for the specified page.  Returns NULL if
-  // this PageID was not allocated previously.
-  inline ATTRIBUTE_ALWAYS_INLINE
-  Span* GetDescriptor(PageID p) const {
-    return reinterpret_cast<Span*>(pagemap_.get(p));
-  }
-
-  // If this page heap is managing a range with starting page # >= start,
-  // store info about the range in *r and return true.  Else return false.
-  bool GetNextRange(PageID start, base::MallocRange* r);
-
-  // Page heap statistics
-  struct Stats {
-    Stats() : system_bytes(0), free_bytes(0), unmapped_bytes(0), committed_bytes(0),
-        scavenge_count(0), commit_count(0), total_commit_bytes(0),
-        decommit_count(0), total_decommit_bytes(0),
-        reserve_count(0), total_reserve_bytes(0) {}
-    uint64_t system_bytes;    // Total bytes allocated from system
-    uint64_t free_bytes;      // Total bytes on normal freelists
-    uint64_t unmapped_bytes;  // Total bytes on returned freelists
-    uint64_t committed_bytes;  // Bytes committed, always <= system_bytes_.
-
-    uint64_t scavenge_count;   // Number of times scavagened flush pages
-
-    uint64_t commit_count;          // Number of virtual memory commits
-    uint64_t total_commit_bytes;    // Bytes committed in lifetime of process
-    uint64_t decommit_count;        // Number of virtual memory decommits
-    uint64_t total_decommit_bytes;  // Bytes decommitted in lifetime of process
-
-    uint64_t reserve_count;         // Number of virtual memory reserves
-    uint64_t total_reserve_bytes;   // Bytes reserved in lifetime of process
-  };
-  inline Stats stats() const { return stats_; }
-
-  struct SmallSpanStats {
-    // For each free list of small spans, the length (in spans) of the
-    // normal and returned free lists for that size.
-    //
-    // NOTE: index 'i' accounts the number of spans of length 'i + 1'.
-    int64 normal_length[kMaxPages];
-    int64 returned_length[kMaxPages];
-  };
-  void GetSmallSpanStats(SmallSpanStats* result);
-
-  // Stats for free large spans (i.e., spans with more than kMaxPages pages).
-  struct LargeSpanStats {
-    int64 spans;           // Number of such spans
-    int64 normal_pages;    // Combined page length of normal large spans
-    int64 returned_pages;  // Combined page length of unmapped spans
-  };
-  void GetLargeSpanStats(LargeSpanStats* result);
-
-  bool Check();
-  // Like Check() but does some more comprehensive checking.
-  bool CheckExpensive();
-  bool CheckList(Span* list, Length min_pages, Length max_pages,
-                 int freelist);  // ON_NORMAL_FREELIST or ON_RETURNED_FREELIST
-  bool CheckSet(SpanSet *s, Length min_pages, int freelist);
-
-  // Try to release at least num_pages for reuse by the OS.  Returns
-  // the actual number of pages released, which may be less than
-  // num_pages if there weren't enough pages to release. The result
-  // may also be larger than num_pages since page_heap might decide to
-  // release one large range instead of fragmenting it into two
-  // smaller released and unreleased ranges.
-  Length ReleaseAtLeastNPages(Length num_pages);
-
-  // Reads and writes to pagemap_cache_ do not require locking.
-  bool TryGetSizeClass(PageID p, uint32* out) const {
-    return pagemap_cache_.TryGet(p, out);
-  }
-  void SetCachedSizeClass(PageID p, uint32 cl) {
-    ASSERT(cl != 0);
-    pagemap_cache_.Put(p, cl);
-  }
-  void InvalidateCachedSizeClass(PageID p) { pagemap_cache_.Invalidate(p); }
-  uint32 GetSizeClassOrZero(PageID p) const {
-    uint32 cached_value;
-    if (!TryGetSizeClass(p, &cached_value)) {
-      cached_value = 0;
-    }
-    return cached_value;
-  }
-
-  bool GetAggressiveDecommit(void) {return aggressive_decommit_;}
-  void SetAggressiveDecommit(bool aggressive_decommit) {
-    aggressive_decommit_ = aggressive_decommit;
-  }
-
- private:
-  // Allocates a big block of memory for the pagemap once we reach more than
-  // 128MB
-  static const size_t kPageMapBigAllocationThreshold = 128 << 20;
-
-  // Minimum number of pages to fetch from system at a time.  Must be
-  // significantly bigger than kBlockSize to amortize system-call
-  // overhead, and also to reduce external fragementation.  Also, we
-  // should keep this value big because various incarnations of Linux
-  // have small limits on the number of mmap() regions per
-  // address-space.
-  // REQUIRED: kMinSystemAlloc <= kMaxPages;
-  static const int kMinSystemAlloc = kMaxPages;
-
-  // Never delay scavenging for more than the following number of
-  // deallocated pages.  With 4K pages, this comes to 4GB of
-  // deallocation.
-  // Chrome:  Changed to 64MB
-  static const int kMaxReleaseDelay = 1 << 14;
-
-  // If there is nothing to release, wait for so many pages before
-  // scavenging again.  With 4K pages, this comes to 1GB of memory.
-  // Chrome:  Changed to 16MB
-  static const int kDefaultReleaseDelay = 1 << 12;
-
-  // Pick the appropriate map and cache types based on pointer size
-  typedef MapSelector<kAddressBits>::Type PageMap;
-  typedef PackedCache<kAddressBits - kPageShift> PageMapCache;
-  mutable PageMapCache pagemap_cache_;
-  PageMap pagemap_;
-
-  // We segregate spans of a given size into two circular linked
-  // lists: one for normal spans, and one for spans whose memory
-  // has been returned to the system.
-  struct SpanList {
-    Span        normal;
-    Span        returned;
-  };
-
-  // Sets of spans with length > kMaxPages.
-  //
-  // Rather than using a linked list, we use sets here for efficient
-  // best-fit search.
-  SpanSet large_normal_;
-  SpanSet large_returned_;
-
-  // Array mapping from span length to a doubly linked list of free spans
-  //
-  // NOTE: index 'i' stores spans of length 'i + 1'.
-  SpanList free_[kMaxPages];
-
-  // Statistics on system, free, and unmapped bytes
-  Stats stats_;
-
-  Span* SearchFreeAndLargeLists(Length n);
-
-  bool GrowHeap(Length n);
-
-  // REQUIRES: span->length >= n
-  // REQUIRES: span->location != IN_USE
-  // Remove span from its free list, and move any leftover part of
-  // span into appropriate free lists.  Also update "span" to have
-  // length exactly "n" and mark it as non-free so it can be returned
-  // to the client.  After all that, decrease free_pages_ by n and
-  // return span.
-  Span* Carve(Span* span, Length n);
-
-  void RecordSpan(Span* span) {
-    pagemap_.set(span->start, span);
-    if (span->length > 1) {
-      pagemap_.set(span->start + span->length - 1, span);
-    }
-  }
-
-  // Allocate a large span of length == n.  If successful, returns a
-  // span of exactly the specified length.  Else, returns NULL.
-  Span* AllocLarge(Length n);
-
-  // Coalesce span with neighboring spans if possible, prepend to
-  // appropriate free list, and adjust stats.
-  void MergeIntoFreeList(Span* span);
-
-  // Commit the span.
-  void CommitSpan(Span* span);
-
-  // Decommit the span.
-  bool DecommitSpan(Span* span);
-
-  // Prepends span to appropriate free list, and adjusts stats.
-  void PrependToFreeList(Span* span);
-
-  // Removes span from its free list, and adjust stats.
-  void RemoveFromFreeList(Span* span);
-
-  // Incrementally release some memory to the system.
-  // IncrementalScavenge(n) is called whenever n pages are freed.
-  void IncrementalScavenge(Length n);
-
-  // Attempts to decommit 's' and move it to the returned freelist.
-  //
-  // Returns the length of the Span or zero if release failed.
-  //
-  // REQUIRES: 's' must be on the NORMAL freelist.
-  Length ReleaseSpan(Span *s);
-
-  // Checks if we are allowed to take more memory from the system.
-  // If limit is reached and allowRelease is true, tries to release
-  // some unused spans.
-  bool EnsureLimit(Length n, bool allowRelease = true);
-
-  Span* CheckAndHandlePreMerge(Span *span, Span *other);
-
-  // Number of pages to deallocate before doing more scavenging
-  int64_t scavenge_counter_;
-
-  // Index of last free list where we released memory to the OS.
-  int release_index_;
-
-  bool aggressive_decommit_;
-};
-
-}  // namespace tcmalloc
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-#endif  // TCMALLOC_PAGE_HEAP_H_
diff --git a/third_party/tcmalloc/chromium/src/page_heap_allocator.h b/third_party/tcmalloc/chromium/src/page_heap_allocator.h
deleted file mode 100644
index add1701..0000000
--- a/third_party/tcmalloc/chromium/src/page_heap_allocator.h
+++ /dev/null
@@ -1,178 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#ifndef TCMALLOC_PAGE_HEAP_ALLOCATOR_H_
-#define TCMALLOC_PAGE_HEAP_ALLOCATOR_H_
-
-#include <stddef.h>                     // for NULL, size_t
-
-#include "common.h"            // for MetaDataAlloc
-#include "free_list.h"         // for FL_Push/FL_Pop
-#include "internal_logging.h"  // for ASSERT
-
-namespace tcmalloc {
-
-// Simple allocator for objects of a specified type.  External locking
-// is required before accessing one of these objects.
-template <class T>
-class PageHeapAllocator {
- public:
-  // We use an explicit Init function because these variables are statically
-  // allocated and their constructors might not have run by the time some
-  // other static variable tries to allocate memory.
-  void Init() {
-    ASSERT(sizeof(T) <= kAllocIncrement);
-    inuse_ = 0;
-    free_area_ = NULL;
-    free_avail_ = 0;
-    free_list_ = NULL;
-    // Reserve some space at the beginning to avoid fragmentation.
-    Delete(New());
-  }
-
-  T* New() {
-    // Consult free list
-    void* result;
-    if (free_list_ != NULL) {
-      result = FL_Pop(&free_list_);
-    } else {
-      if (free_avail_ < sizeof(T)) {
-        // Need more room. We assume that MetaDataAlloc returns
-        // suitably aligned memory.
-        free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));
-        if (free_area_ == NULL) {
-          Log(kCrash, __FILE__, __LINE__,
-              "FATAL ERROR: Out of memory trying to allocate internal "
-              "tcmalloc data (bytes, object-size)",
-              kAllocIncrement, sizeof(T));
-        }
-        free_avail_ = kAllocIncrement;
-      }
-      result = free_area_;
-      free_area_ += sizeof(T);
-      free_avail_ -= sizeof(T);
-    }
-    inuse_++;
-    return reinterpret_cast<T*>(result);
-  }
-
-  void Delete(T* p) {
-    FL_Push(&free_list_, p);
-    inuse_--;
-  }
-
-  int inuse() const { return inuse_; }
-
- private:
-  // How much to allocate from system at a time
-  static const int kAllocIncrement = 128 << 10;
-
-  // Free area from which to carve new objects
-  char* free_area_;
-  size_t free_avail_;
-
-  // Free list of already carved objects
-  void* free_list_;
-
-  // Number of allocated but unfreed objects
-  int inuse_;
-};
-
-// STL-compatible allocator which forwards allocations to a PageHeapAllocator.
-//
-// Like PageHeapAllocator, this requires external synchronization. To avoid multiple
-// separate STLPageHeapAllocator<T> from sharing the same underlying PageHeapAllocator<T>,
-// the |LockingTag| template argument should be used. Template instantiations with
-// different locking tags can safely be used concurrently.
-template <typename T, class LockingTag>
-class STLPageHeapAllocator {
- public:
-  typedef size_t     size_type;
-  typedef ptrdiff_t  difference_type;
-  typedef T*         pointer;
-  typedef const T*   const_pointer;
-  typedef T&         reference;
-  typedef const T&   const_reference;
-  typedef T          value_type;
-
-  template <class T1> struct rebind {
-    typedef STLPageHeapAllocator<T1, LockingTag> other;
-  };
-
-  STLPageHeapAllocator() { }
-  STLPageHeapAllocator(const STLPageHeapAllocator&) { }
-  template <class T1> STLPageHeapAllocator(const STLPageHeapAllocator<T1, LockingTag>&) { }
-  ~STLPageHeapAllocator() { }
-
-  pointer address(reference x) const { return &x; }
-  const_pointer address(const_reference x) const { return &x; }
-
-  size_type max_size() const { return size_t(-1) / sizeof(T); }
-
-  void construct(pointer p, const T& val) { ::new(p) T(val); }
-  void construct(pointer p) { ::new(p) T(); }
-  void destroy(pointer p) { p->~T(); }
-
-  // There's no state, so these allocators are always equal
-  bool operator==(const STLPageHeapAllocator&) const { return true; }
-  bool operator!=(const STLPageHeapAllocator&) const { return false; }
-
-  pointer allocate(size_type n, const void* = 0) {
-    if (!underlying_.initialized) {
-      underlying_.allocator.Init();
-      underlying_.initialized = true;
-    }
-
-    CHECK_CONDITION(n == 1);
-    return underlying_.allocator.New();
-  }
-  void deallocate(pointer p, size_type n) {
-    CHECK_CONDITION(n == 1);
-    underlying_.allocator.Delete(p);
-  }
-
- private:
-  struct Storage {
-    PageHeapAllocator<T> allocator;
-    bool initialized;
-  };
-  static Storage underlying_;
-};
-
-template <typename T, class LockingTag>
-typename STLPageHeapAllocator<T, LockingTag>::Storage
-    STLPageHeapAllocator<T, LockingTag>::underlying_;
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_PAGE_HEAP_ALLOCATOR_H_
diff --git a/third_party/tcmalloc/chromium/src/pagemap.h b/third_party/tcmalloc/chromium/src/pagemap.h
deleted file mode 100644
index 68b2d24c..0000000
--- a/third_party/tcmalloc/chromium/src/pagemap.h
+++ /dev/null
@@ -1,328 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// A data structure used by the caching malloc.  It maps from page# to
-// a pointer that contains info about that page.  We use two
-// representations: one for 32-bit addresses, and another for 64 bit
-// addresses.  Both representations provide the same interface.  The
-// first representation is implemented as a flat array, the seconds as
-// a three-level radix tree that strips away approximately 1/3rd of
-// the bits every time.
-//
-// The BITS parameter should be the number of bits required to hold
-// a page number.  E.g., with 32 bit pointers and 4K pages (i.e.,
-// page offset fits in lower 12 bits), BITS == 20.
-
-#ifndef TCMALLOC_PAGEMAP_H_
-#define TCMALLOC_PAGEMAP_H_
-
-#include "config.h"
-
-#include <stddef.h>                     // for NULL, size_t
-#include <string.h>                     // for memset
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-#include "internal_logging.h"  // for ASSERT
-
-// Single-level array
-template <int BITS>
-class TCMalloc_PageMap1 {
- private:
-  static const int LENGTH = 1 << BITS;
-
-  void** array_;
-
- public:
-  typedef uintptr_t Number;
-
-  explicit TCMalloc_PageMap1(void* (*allocator)(size_t)) {
-    array_ = reinterpret_cast<void**>((*allocator)(sizeof(void*) << BITS));
-    memset(array_, 0, sizeof(void*) << BITS);
-  }
-
-  // Ensure that the map contains initialized entries "x .. x+n-1".
-  // Returns true if successful, false if we could not allocate memory.
-  bool Ensure(Number x, size_t n) {
-    // Nothing to do since flat array was allocated at start.  All
-    // that's left is to check for overflow (that is, we don't want to
-    // ensure a number y where array_[y] would be an out-of-bounds
-    // access).
-    return n <= LENGTH - x;   // an overflow-free way to do "x + n <= LENGTH"
-  }
-
-  void PreallocateMoreMemory() {}
-
-  // Return the current value for KEY.  Returns NULL if not yet set,
-  // or if k is out of range.
-  ATTRIBUTE_ALWAYS_INLINE
-  void* get(Number k) const {
-    if ((k >> BITS) > 0) {
-      return NULL;
-    }
-    return array_[k];
-  }
-
-  // REQUIRES "k" is in range "[0,2^BITS-1]".
-  // REQUIRES "k" has been ensured before.
-  //
-  // Sets the value 'v' for key 'k'.
-  void set(Number k, void* v) {
-    array_[k] = v;
-  }
-
-  // Return the first non-NULL pointer found in this map for
-  // a page number >= k.  Returns NULL if no such number is found.
-  void* Next(Number k) const {
-    while (k < (1 << BITS)) {
-      if (array_[k] != NULL) return array_[k];
-      k++;
-    }
-    return NULL;
-  }
-};
-
-// Two-level radix tree
-template <int BITS>
-class TCMalloc_PageMap2 {
- private:
-  static const int LEAF_BITS = (BITS + 1) / 2;
-  static const int LEAF_LENGTH = 1 << LEAF_BITS;
-
-  static const int ROOT_BITS = BITS - LEAF_BITS;
-  static const int ROOT_LENGTH = 1 << ROOT_BITS;
-
-  // Leaf node
-  struct Leaf {
-    void* values[LEAF_LENGTH];
-  };
-
-  Leaf* root_[ROOT_LENGTH];             // Pointers to child nodes
-  void* (*allocator_)(size_t);          // Memory allocator
-
- public:
-  typedef uintptr_t Number;
-
-  explicit TCMalloc_PageMap2(void* (*allocator)(size_t)) {
-    allocator_ = allocator;
-    memset(root_, 0, sizeof(root_));
-  }
-
-  ATTRIBUTE_ALWAYS_INLINE
-  void* get(Number k) const {
-    const Number i1 = k >> LEAF_BITS;
-    const Number i2 = k & (LEAF_LENGTH-1);
-    if ((k >> BITS) > 0 || root_[i1] == NULL) {
-      return NULL;
-    }
-    return root_[i1]->values[i2];
-  }
-
-  void set(Number k, void* v) {
-    const Number i1 = k >> LEAF_BITS;
-    const Number i2 = k & (LEAF_LENGTH-1);
-    ASSERT(i1 < ROOT_LENGTH);
-    root_[i1]->values[i2] = v;
-  }
-
-  bool Ensure(Number start, size_t n) {
-    for (Number key = start; key <= start + n - 1; ) {
-      const Number i1 = key >> LEAF_BITS;
-
-      // Check for overflow
-      if (i1 >= ROOT_LENGTH)
-        return false;
-
-      // Make 2nd level node if necessary
-      if (root_[i1] == NULL) {
-        Leaf* leaf = reinterpret_cast<Leaf*>((*allocator_)(sizeof(Leaf)));
-        if (leaf == NULL) return false;
-        memset(leaf, 0, sizeof(*leaf));
-        root_[i1] = leaf;
-      }
-
-      // Advance key past whatever is covered by this leaf node
-      key = ((key >> LEAF_BITS) + 1) << LEAF_BITS;
-    }
-    return true;
-  }
-
-  void PreallocateMoreMemory() {
-    // Allocate enough to keep track of all possible pages
-    if (BITS < 20) {
-      Ensure(0, Number(1) << BITS);
-    }
-  }
-
-  void* Next(Number k) const {
-    while (k < (Number(1) << BITS)) {
-      const Number i1 = k >> LEAF_BITS;
-      Leaf* leaf = root_[i1];
-      if (leaf != NULL) {
-        // Scan forward in leaf
-        for (Number i2 = k & (LEAF_LENGTH - 1); i2 < LEAF_LENGTH; i2++) {
-          if (leaf->values[i2] != NULL) {
-            return leaf->values[i2];
-          }
-        }
-      }
-      // Skip to next top-level entry
-      k = (i1 + 1) << LEAF_BITS;
-    }
-    return NULL;
-  }
-};
-
-// Three-level radix tree
-template <int BITS>
-class TCMalloc_PageMap3 {
- private:
-  // How many bits should we consume at each interior level
-  static const int INTERIOR_BITS = (BITS + 2) / 3; // Round-up
-  static const int INTERIOR_LENGTH = 1 << INTERIOR_BITS;
-
-  // How many bits should we consume at leaf level
-  static const int LEAF_BITS = BITS - 2*INTERIOR_BITS;
-  static const int LEAF_LENGTH = 1 << LEAF_BITS;
-
-  // Interior node
-  struct Node {
-    Node* ptrs[INTERIOR_LENGTH];
-  };
-
-  // Leaf node
-  struct Leaf {
-    void* values[LEAF_LENGTH];
-  };
-
-  Node  root_;                          // Root of radix tree
-  void* (*allocator_)(size_t);          // Memory allocator
-
-  Node* NewNode() {
-    Node* result = reinterpret_cast<Node*>((*allocator_)(sizeof(Node)));
-    if (result != NULL) {
-      memset(result, 0, sizeof(*result));
-    }
-    return result;
-  }
-
- public:
-  typedef uintptr_t Number;
-
-  explicit TCMalloc_PageMap3(void* (*allocator)(size_t)) {
-    allocator_ = allocator;
-    memset(&root_, 0, sizeof(root_));
-  }
-
-  ATTRIBUTE_ALWAYS_INLINE
-  void* get(Number k) const {
-    const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS);
-    const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1);
-    const Number i3 = k & (LEAF_LENGTH-1);
-    if ((k >> BITS) > 0 ||
-        root_.ptrs[i1] == NULL || root_.ptrs[i1]->ptrs[i2] == NULL) {
-      return NULL;
-    }
-    return reinterpret_cast<Leaf*>(root_.ptrs[i1]->ptrs[i2])->values[i3];
-  }
-
-  void set(Number k, void* v) {
-    ASSERT(k >> BITS == 0);
-    const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS);
-    const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1);
-    const Number i3 = k & (LEAF_LENGTH-1);
-    reinterpret_cast<Leaf*>(root_.ptrs[i1]->ptrs[i2])->values[i3] = v;
-  }
-
-  bool Ensure(Number start, size_t n) {
-    for (Number key = start; key <= start + n - 1; ) {
-      const Number i1 = key >> (LEAF_BITS + INTERIOR_BITS);
-      const Number i2 = (key >> LEAF_BITS) & (INTERIOR_LENGTH-1);
-
-      // Check for overflow
-      if (i1 >= INTERIOR_LENGTH || i2 >= INTERIOR_LENGTH)
-        return false;
-
-      // Make 2nd level node if necessary
-      if (root_.ptrs[i1] == NULL) {
-        Node* n = NewNode();
-        if (n == NULL) return false;
-        root_.ptrs[i1] = n;
-      }
-
-      // Make leaf node if necessary
-      if (root_.ptrs[i1]->ptrs[i2] == NULL) {
-        Leaf* leaf = reinterpret_cast<Leaf*>((*allocator_)(sizeof(Leaf)));
-        if (leaf == NULL) return false;
-        memset(leaf, 0, sizeof(*leaf));
-        root_.ptrs[i1]->ptrs[i2] = reinterpret_cast<Node*>(leaf);
-      }
-
-      // Advance key past whatever is covered by this leaf node
-      key = ((key >> LEAF_BITS) + 1) << LEAF_BITS;
-    }
-    return true;
-  }
-
-  void PreallocateMoreMemory() {
-  }
-
-  void* Next(Number k) const {
-    while (k < (Number(1) << BITS)) {
-      const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS);
-      const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1);
-      if (root_.ptrs[i1] == NULL) {
-        // Advance to next top-level entry
-        k = (i1 + 1) << (LEAF_BITS + INTERIOR_BITS);
-      } else {
-        Leaf* leaf = reinterpret_cast<Leaf*>(root_.ptrs[i1]->ptrs[i2]);
-        if (leaf != NULL) {
-          for (Number i3 = (k & (LEAF_LENGTH-1)); i3 < LEAF_LENGTH; i3++) {
-            if (leaf->values[i3] != NULL) {
-              return leaf->values[i3];
-            }
-          }
-        }
-        // Advance to next interior entry
-        k = ((k >> LEAF_BITS) + 1) << LEAF_BITS;
-      }
-    }
-    return NULL;
-  }
-};
-
-#endif  // TCMALLOC_PAGEMAP_H_
diff --git a/third_party/tcmalloc/chromium/src/pprof b/third_party/tcmalloc/chromium/src/pprof
deleted file mode 100755
index 9e18fc6..0000000
--- a/third_party/tcmalloc/chromium/src/pprof
+++ /dev/null
@@ -1,5580 +0,0 @@
-#! /usr/bin/env perl
-
-# Copyright (c) 1998-2007, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Program for printing the profile generated by common/profiler.cc,
-# or by the heap profiler (common/debugallocation.cc)
-#
-# The profile contains a sequence of entries of the form:
-#       <count> <stack trace>
-# This program parses the profile, and generates user-readable
-# output.
-#
-# Examples:
-#
-# % tools/pprof "program" "profile"
-#   Enters "interactive" mode
-#
-# % tools/pprof --text "program" "profile"
-#   Generates one line per procedure
-#
-# % tools/pprof --gv "program" "profile"
-#   Generates annotated call-graph and displays via "gv"
-#
-# % tools/pprof --gv --focus=Mutex "program" "profile"
-#   Restrict to code paths that involve an entry that matches "Mutex"
-#
-# % tools/pprof --gv --focus=Mutex --ignore=string "program" "profile"
-#   Restrict to code paths that involve an entry that matches "Mutex"
-#   and does not match "string"
-#
-# % tools/pprof --list=IBF_CheckDocid "program" "profile"
-#   Generates disassembly listing of all routines with at least one
-#   sample that match the --list=<regexp> pattern.  The listing is
-#   annotated with the flat and cumulative sample counts at each line.
-#
-# % tools/pprof --disasm=IBF_CheckDocid "program" "profile"
-#   Generates disassembly listing of all routines with at least one
-#   sample that match the --disasm=<regexp> pattern.  The listing is
-#   annotated with the flat and cumulative sample counts at each PC value.
-#
-# TODO: Use color to indicate files?
-
-use strict;
-use warnings;
-use Getopt::Long;
-use Cwd;
-use POSIX;
-
-my $PPROF_VERSION = "2.0";
-
-# These are the object tools we use which can come from a
-# user-specified location using --tools, from the PPROF_TOOLS
-# environment variable, or from the environment.
-my %obj_tool_map = (
-  "objdump" => "objdump",
-  "nm" => "nm",
-  "addr2line" => "addr2line",
-  "c++filt" => "c++filt",
-  ## ConfigureObjTools may add architecture-specific entries:
-  #"nm_pdb" => "nm-pdb",       # for reading windows (PDB-format) executables
-  #"addr2line_pdb" => "addr2line-pdb",                                # ditto
-  #"otool" => "otool",         # equivalent of objdump on OS X
-);
-# NOTE: these are lists, so you can put in commandline flags if you want.
-my @DOT = ("dot");          # leave non-absolute, since it may be in /usr/local
-my @GV = ("gv");
-my @EVINCE = ("evince");    # could also be xpdf or perhaps acroread
-my @KCACHEGRIND = ("kcachegrind");
-my @PS2PDF = ("ps2pdf");
-# These are used for dynamic profiles
-my @URL_FETCHER = ("curl", "-s");
-
-# These are the web pages that servers need to support for dynamic profiles
-my $HEAP_PAGE = "/pprof/heap";
-my $PROFILE_PAGE = "/pprof/profile";   # must support cgi-param "?seconds=#"
-my $PMUPROFILE_PAGE = "/pprof/pmuprofile(?:\\?.*)?"; # must support cgi-param
-                                                # ?seconds=#&event=x&period=n
-my $GROWTH_PAGE = "/pprof/growth";
-my $CONTENTION_PAGE = "/pprof/contention";
-my $WALL_PAGE = "/pprof/wall(?:\\?.*)?";  # accepts options like namefilter
-my $FILTEREDPROFILE_PAGE = "/pprof/filteredprofile(?:\\?.*)?";
-my $CENSUSPROFILE_PAGE = "/pprof/censusprofile(?:\\?.*)?"; # must support cgi-param
-                                                       # "?seconds=#",
-                                                       # "?tags_regexp=#" and
-                                                       # "?type=#".
-my $SYMBOL_PAGE = "/pprof/symbol";     # must support symbol lookup via POST
-my $PROGRAM_NAME_PAGE = "/pprof/cmdline";
-
-# These are the web pages that can be named on the command line.
-# All the alternatives must begin with /.
-my $PROFILES = "($HEAP_PAGE|$PROFILE_PAGE|$PMUPROFILE_PAGE|" .
-               "$GROWTH_PAGE|$CONTENTION_PAGE|$WALL_PAGE|" .
-               "$FILTEREDPROFILE_PAGE|$CENSUSPROFILE_PAGE)";
-
-# default binary name
-my $UNKNOWN_BINARY = "(unknown)";
-
-# There is a pervasive dependency on the length (in hex characters,
-# i.e., nibbles) of an address, distinguishing between 32-bit and
-# 64-bit profiles.  To err on the safe size, default to 64-bit here:
-my $address_length = 16;
-
-my $dev_null = "/dev/null";
-if (! -e $dev_null && $^O =~ /MSWin/) {    # $^O is the OS perl was built for
-  $dev_null = "nul";
-}
-
-# A list of paths to search for shared object files
-my @prefix_list = ();
-
-# Special routine name that should not have any symbols.
-# Used as separator to parse "addr2line -i" output.
-my $sep_symbol = '_fini';
-my $sep_address = undef;
-
-my @stackTraces;
-
-##### Argument parsing #####
-
-sub usage_string {
-  return <<EOF;
-Usage:
-$0 [options] <program> <profiles>
-   <profiles> is a space separated list of profile names.
-$0 [options] <symbolized-profiles>
-   <symbolized-profiles> is a list of profile files where each file contains
-   the necessary symbol mappings  as well as profile data (likely generated
-   with --raw).
-$0 [options] <profile>
-   <profile> is a remote form.  Symbols are obtained from host:port$SYMBOL_PAGE
-
-   Each name can be:
-   /path/to/profile        - a path to a profile file
-   host:port[/<service>]   - a location of a service to get profile from
-
-   The /<service> can be $HEAP_PAGE, $PROFILE_PAGE, /pprof/pmuprofile,
-                         $GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall,
-                         $CENSUSPROFILE_PAGE, or /pprof/filteredprofile.
-   For instance:
-     $0 http://myserver.com:80$HEAP_PAGE
-   If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling).
-$0 --symbols <program>
-   Maps addresses to symbol names.  In this mode, stdin should be a
-   list of library mappings, in the same format as is found in the heap-
-   and cpu-profile files (this loosely matches that of /proc/self/maps
-   on linux), followed by a list of hex addresses to map, one per line.
-
-   For more help with querying remote servers, including how to add the
-   necessary server-side support code, see this filename (or one like it):
-
-   /usr/doc/gperftools-$PPROF_VERSION/pprof_remote_servers.html
-
-Options:
-   --cum               Sort by cumulative data
-   --base=<base>       Subtract <base> from <profile> before display
-   --interactive       Run in interactive mode (interactive "help" gives help) [default]
-   --seconds=<n>       Length of time for dynamic profiles [default=30 secs]
-   --add_lib=<file>    Read additional symbols and line info from the given library
-   --lib_prefix=<dir>  Comma separated list of library path prefixes
-   --no_strip_temp     Do not strip template arguments from function names
-
-Reporting Granularity:
-   --addresses         Report at address level
-   --lines             Report at source line level
-   --functions         Report at function level [default]
-   --files             Report at source file level
-
-Output type:
-   --text              Generate text report
-   --stacks            Generate stack traces similar to the heap profiler (requires --text)
-   --callgrind         Generate callgrind format to stdout
-   --gv                Generate Postscript and display
-   --evince            Generate PDF and display
-   --web               Generate SVG and display
-   --list=<regexp>     Generate source listing of matching routines
-   --disasm=<regexp>   Generate disassembly of matching routines
-   --symbols           Print demangled symbol names found at given addresses
-   --dot               Generate DOT file to stdout
-   --ps                Generate Postscript to stdout
-   --pdf               Generate PDF to stdout
-   --svg               Generate SVG to stdout
-   --gif               Generate GIF to stdout
-   --raw               Generate symbolized pprof data (useful with remote fetch)
-   --collapsed         Generate collapsed stacks for building flame graphs
-                       (see http://www.brendangregg.com/flamegraphs.html)
-
-Heap-Profile Options:
-   --inuse_space       Display in-use (mega)bytes [default]
-   --inuse_objects     Display in-use objects
-   --alloc_space       Display allocated (mega)bytes
-   --alloc_objects     Display allocated objects
-   --show_bytes        Display space in bytes
-   --drop_negative     Ignore negative differences
-
-Contention-profile options:
-   --total_delay       Display total delay at each region [default]
-   --contentions       Display number of delays at each region
-   --mean_delay        Display mean delay at each region
-
-Call-graph Options:
-   --nodecount=<n>     Show at most so many nodes [default=80]
-   --nodefraction=<f>  Hide nodes below <f>*total [default=.005]
-   --edgefraction=<f>  Hide edges below <f>*total [default=.001]
-   --maxdegree=<n>     Max incoming/outgoing edges per node [default=8]
-   --focus=<regexp>    Focus on nodes matching <regexp>
-   --ignore=<regexp>   Ignore nodes matching <regexp>
-   --scale=<n>         Set GV scaling [default=0]
-   --heapcheck         Make nodes with non-0 object counts
-                       (i.e. direct leak generators) more visible
-
-Miscellaneous:
-   --no-auto-signal-frm Automatically drop 2nd frame that is always same (cpu-only)
-                       (assuming that it is artifact of bad stack captures
-                        which include signal handler frames)
-   --show_addresses    Always show addresses when applicable
-   --tools=<prefix or binary:fullpath>[,...]   \$PATH for object tool pathnames
-   --test              Run unit tests
-   --help              This message
-   --version           Version information
-
-Environment Variables:
-   PPROF_TMPDIR        Profiles directory. Defaults to \$HOME/pprof
-   PPROF_TOOLS         Prefix for object tools pathnames
-
-Examples:
-
-$0 /bin/ls ls.prof
-                       Enters "interactive" mode
-$0 --text /bin/ls ls.prof
-                       Outputs one line per procedure
-$0 --web /bin/ls ls.prof
-                       Displays annotated call-graph in web browser
-$0 --gv /bin/ls ls.prof
-                       Displays annotated call-graph via 'gv'
-$0 --gv --focus=Mutex /bin/ls ls.prof
-                       Restricts to code paths including a .*Mutex.* entry
-$0 --gv --focus=Mutex --ignore=string /bin/ls ls.prof
-                       Code paths including Mutex but not string
-$0 --list=getdir /bin/ls ls.prof
-                       (Per-line) annotated source listing for getdir()
-$0 --disasm=getdir /bin/ls ls.prof
-                       (Per-PC) annotated disassembly for getdir()
-
-$0 http://localhost:1234/
-                       Enters "interactive" mode
-$0 --text localhost:1234
-                       Outputs one line per procedure for localhost:1234
-$0 --raw localhost:1234 > ./local.raw
-$0 --text ./local.raw
-                       Fetches a remote profile for later analysis and then
-                       analyzes it in text mode.
-EOF
-}
-
-sub version_string {
-  return <<EOF
-pprof (part of gperftools $PPROF_VERSION)
-
-Copyright 1998-2007 Google Inc.
-
-This is BSD licensed software; see the source for copying conditions
-and license information.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE.
-EOF
-}
-
-sub usage {
-  my $msg = shift;
-  print STDERR "$msg\n\n";
-  print STDERR usage_string();
-  exit(1);
-}
-
-sub Init() {
-  # Setup tmp-file name and handler to clean it up.
-  # We do this in the very beginning so that we can use
-  # error() and cleanup() function anytime here after.
-  $main::tmpfile_sym = "/tmp/pprof$$.sym";
-  $main::tmpfile_ps = "/tmp/pprof$$";
-  $main::next_tmpfile = 0;
-  $SIG{'INT'} = \&sighandler;
-
-  # Cache from filename/linenumber to source code
-  $main::source_cache = ();
-
-  $main::opt_help = 0;
-  $main::opt_version = 0;
-  $main::opt_show_addresses = 0;
-  $main::opt_no_auto_signal_frames = 0;
-
-  $main::opt_cum = 0;
-  $main::opt_base = '';
-  $main::opt_addresses = 0;
-  $main::opt_lines = 0;
-  $main::opt_functions = 0;
-  $main::opt_files = 0;
-  $main::opt_lib_prefix = "";
-
-  $main::opt_text = 0;
-  $main::opt_stacks = 0;
-  $main::opt_callgrind = 0;
-  $main::opt_list = "";
-  $main::opt_disasm = "";
-  $main::opt_symbols = 0;
-  $main::opt_gv = 0;
-  $main::opt_evince = 0;
-  $main::opt_web = 0;
-  $main::opt_dot = 0;
-  $main::opt_ps = 0;
-  $main::opt_pdf = 0;
-  $main::opt_gif = 0;
-  $main::opt_svg = 0;
-  $main::opt_raw = 0;
-  $main::opt_collapsed = 0;
-
-  $main::opt_nodecount = 80;
-  $main::opt_nodefraction = 0.005;
-  $main::opt_edgefraction = 0.001;
-  $main::opt_maxdegree = 8;
-  $main::opt_focus = '';
-  $main::opt_ignore = '';
-  $main::opt_scale = 0;
-  $main::opt_heapcheck = 0;
-  $main::opt_seconds = 30;
-  $main::opt_lib = "";
-
-  $main::opt_inuse_space   = 0;
-  $main::opt_inuse_objects = 0;
-  $main::opt_alloc_space   = 0;
-  $main::opt_alloc_objects = 0;
-  $main::opt_show_bytes    = 0;
-  $main::opt_drop_negative = 0;
-  $main::opt_interactive   = 0;
-
-  $main::opt_total_delay = 0;
-  $main::opt_contentions = 0;
-  $main::opt_mean_delay = 0;
-
-  $main::opt_tools   = "";
-  $main::opt_debug   = 0;
-  $main::opt_test    = 0;
-
-  # Do not strip template argument in function names
-  $main::opt_no_strip_temp = 0;
-
-  # These are undocumented flags used only by unittests.
-  $main::opt_test_stride = 0;
-
-  # Are we using $SYMBOL_PAGE?
-  $main::use_symbol_page = 0;
-
-  # Files returned by TempName.
-  %main::tempnames = ();
-
-  # Type of profile we are dealing with
-  # Supported types:
-  #     cpu
-  #     heap
-  #     growth
-  #     contention
-  $main::profile_type = '';     # Empty type means "unknown"
-
-  GetOptions("help!"          => \$main::opt_help,
-             "version!"       => \$main::opt_version,
-             "show_addresses!"=> \$main::opt_show_addresses,
-             "no-auto-signal-frm!"=> \$main::opt_no_auto_signal_frames,
-             "cum!"           => \$main::opt_cum,
-             "base=s"         => \$main::opt_base,
-             "seconds=i"      => \$main::opt_seconds,
-             "add_lib=s"      => \$main::opt_lib,
-             "lib_prefix=s"   => \$main::opt_lib_prefix,
-             "functions!"     => \$main::opt_functions,
-             "lines!"         => \$main::opt_lines,
-             "addresses!"     => \$main::opt_addresses,
-             "files!"         => \$main::opt_files,
-             "text!"          => \$main::opt_text,
-             "stacks!"        => \$main::opt_stacks,
-             "callgrind!"     => \$main::opt_callgrind,
-             "list=s"         => \$main::opt_list,
-             "disasm=s"       => \$main::opt_disasm,
-             "symbols!"       => \$main::opt_symbols,
-             "gv!"            => \$main::opt_gv,
-             "evince!"        => \$main::opt_evince,
-             "web!"           => \$main::opt_web,
-             "dot!"           => \$main::opt_dot,
-             "ps!"            => \$main::opt_ps,
-             "pdf!"           => \$main::opt_pdf,
-             "svg!"           => \$main::opt_svg,
-             "gif!"           => \$main::opt_gif,
-             "raw!"           => \$main::opt_raw,
-             "collapsed!"     => \$main::opt_collapsed,
-             "interactive!"   => \$main::opt_interactive,
-             "nodecount=i"    => \$main::opt_nodecount,
-             "nodefraction=f" => \$main::opt_nodefraction,
-             "edgefraction=f" => \$main::opt_edgefraction,
-             "maxdegree=i"    => \$main::opt_maxdegree,
-             "focus=s"        => \$main::opt_focus,
-             "ignore=s"       => \$main::opt_ignore,
-             "scale=i"        => \$main::opt_scale,
-             "heapcheck"      => \$main::opt_heapcheck,
-             "inuse_space!"   => \$main::opt_inuse_space,
-             "inuse_objects!" => \$main::opt_inuse_objects,
-             "alloc_space!"   => \$main::opt_alloc_space,
-             "alloc_objects!" => \$main::opt_alloc_objects,
-             "show_bytes!"    => \$main::opt_show_bytes,
-             "drop_negative!" => \$main::opt_drop_negative,
-             "total_delay!"   => \$main::opt_total_delay,
-             "contentions!"   => \$main::opt_contentions,
-             "mean_delay!"    => \$main::opt_mean_delay,
-             "tools=s"        => \$main::opt_tools,
-             "no_strip_temp!" => \$main::opt_no_strip_temp,
-             "test!"          => \$main::opt_test,
-             "debug!"         => \$main::opt_debug,
-             # Undocumented flags used only by unittests:
-             "test_stride=i"  => \$main::opt_test_stride,
-      ) || usage("Invalid option(s)");
-
-  # Deal with the standard --help and --version
-  if ($main::opt_help) {
-    print usage_string();
-    exit(0);
-  }
-
-  if ($main::opt_version) {
-    print version_string();
-    exit(0);
-  }
-
-  # Disassembly/listing/symbols mode requires address-level info
-  if ($main::opt_disasm || $main::opt_list || $main::opt_symbols) {
-    $main::opt_functions = 0;
-    $main::opt_lines = 0;
-    $main::opt_addresses = 1;
-    $main::opt_files = 0;
-  }
-
-  # Check heap-profiling flags
-  if ($main::opt_inuse_space +
-      $main::opt_inuse_objects +
-      $main::opt_alloc_space +
-      $main::opt_alloc_objects > 1) {
-    usage("Specify at most on of --inuse/--alloc options");
-  }
-
-  # Check output granularities
-  my $grains =
-      $main::opt_functions +
-      $main::opt_lines +
-      $main::opt_addresses +
-      $main::opt_files +
-      0;
-  if ($grains > 1) {
-    usage("Only specify one output granularity option");
-  }
-  if ($grains == 0) {
-    $main::opt_functions = 1;
-  }
-
-  # Check output modes
-  my $modes =
-      $main::opt_text +
-      $main::opt_callgrind +
-      ($main::opt_list eq '' ? 0 : 1) +
-      ($main::opt_disasm eq '' ? 0 : 1) +
-      ($main::opt_symbols == 0 ? 0 : 1) +
-      $main::opt_gv +
-      $main::opt_evince +
-      $main::opt_web +
-      $main::opt_dot +
-      $main::opt_ps +
-      $main::opt_pdf +
-      $main::opt_svg +
-      $main::opt_gif +
-      $main::opt_raw +
-      $main::opt_collapsed +
-      $main::opt_interactive +
-      0;
-  if ($modes > 1) {
-    usage("Only specify one output mode");
-  }
-  if ($modes == 0) {
-    if (-t STDOUT) {  # If STDOUT is a tty, activate interactive mode
-      $main::opt_interactive = 1;
-    } else {
-      $main::opt_text = 1;
-    }
-  }
-
-  if ($main::opt_test) {
-    RunUnitTests();
-    # Should not return
-    exit(1);
-  }
-
-  # Binary name and profile arguments list
-  $main::prog = "";
-  @main::pfile_args = ();
-
-  # Remote profiling without a binary (using $SYMBOL_PAGE instead)
-  if (@ARGV > 0) {
-    if (IsProfileURL($ARGV[0])) {
-      printf STDERR "Using remote profile at $ARGV[0].\n";
-      $main::use_symbol_page = 1;
-    } elsif (IsSymbolizedProfileFile($ARGV[0])) {
-      $main::use_symbolized_profile = 1;
-      $main::prog = $UNKNOWN_BINARY;  # will be set later from the profile file
-    }
-  }
-
-  if ($main::use_symbol_page || $main::use_symbolized_profile) {
-    # We don't need a binary!
-    my %disabled = ('--lines' => $main::opt_lines,
-                    '--disasm' => $main::opt_disasm);
-    for my $option (keys %disabled) {
-      usage("$option cannot be used without a binary") if $disabled{$option};
-    }
-    # Set $main::prog later...
-    scalar(@ARGV) || usage("Did not specify profile file");
-  } elsif ($main::opt_symbols) {
-    # --symbols needs a binary-name (to run nm on, etc) but not profiles
-    $main::prog = shift(@ARGV) || usage("Did not specify program");
-  } else {
-    $main::prog = shift(@ARGV) || usage("Did not specify program");
-    scalar(@ARGV) || usage("Did not specify profile file");
-  }
-
-  # Parse profile file/location arguments
-  foreach my $farg (@ARGV) {
-    if ($farg =~ m/(.*)\@([0-9]+)(|\/.*)$/ ) {
-      my $machine = $1;
-      my $num_machines = $2;
-      my $path = $3;
-      for (my $i = 0; $i < $num_machines; $i++) {
-        unshift(@main::pfile_args, "$i.$machine$path");
-      }
-    } else {
-      unshift(@main::pfile_args, $farg);
-    }
-  }
-
-  if ($main::use_symbol_page) {
-    unless (IsProfileURL($main::pfile_args[0])) {
-      error("The first profile should be a remote form to use $SYMBOL_PAGE\n");
-    }
-    CheckSymbolPage();
-    $main::prog = FetchProgramName();
-  } elsif (!$main::use_symbolized_profile) {  # may not need objtools!
-    ConfigureObjTools($main::prog)
-  }
-
-  # Break the opt_lib_prefix into the prefix_list array
-  @prefix_list = split (',', $main::opt_lib_prefix);
-
-  # Remove trailing / from the prefixes, in the list to prevent
-  # searching things like /my/path//lib/mylib.so
-  foreach (@prefix_list) {
-    s|/+$||;
-  }
-}
-
-sub Main() {
-  Init();
-  $main::collected_profile = undef;
-  @main::profile_files = ();
-  $main::op_time = time();
-
-  # Printing symbols is special and requires a lot less info that most.
-  if ($main::opt_symbols) {
-    PrintSymbols(*STDIN);   # Get /proc/maps and symbols output from stdin
-    return;
-  }
-
-  # Fetch all profile data
-  FetchDynamicProfiles();
-
-  # this will hold symbols that we read from the profile files
-  my $symbol_map = {};
-
-  # Read one profile, pick the last item on the list
-  my $data = ReadProfile($main::prog, pop(@main::profile_files));
-  my $profile = $data->{profile};
-  my $pcs = $data->{pcs};
-  my $libs = $data->{libs};   # Info about main program and shared libraries
-  $symbol_map = MergeSymbols($symbol_map, $data->{symbols});
-
-  # Add additional profiles, if available.
-  if (scalar(@main::profile_files) > 0) {
-    foreach my $pname (@main::profile_files) {
-      my $data2 = ReadProfile($main::prog, $pname);
-      $profile = AddProfile($profile, $data2->{profile});
-      $pcs = AddPcs($pcs, $data2->{pcs});
-      $symbol_map = MergeSymbols($symbol_map, $data2->{symbols});
-    }
-  }
-
-  # Subtract base from profile, if specified
-  if ($main::opt_base ne '') {
-    my $base = ReadProfile($main::prog, $main::opt_base);
-    $profile = SubtractProfile($profile, $base->{profile});
-    $pcs = AddPcs($pcs, $base->{pcs});
-    $symbol_map = MergeSymbols($symbol_map, $base->{symbols});
-  }
-
-  # Get total data in profile
-  my $total = TotalProfile($profile);
-
-  # Collect symbols
-  my $symbols;
-  if ($main::use_symbolized_profile) {
-    $symbols = FetchSymbols($pcs, $symbol_map);
-  } elsif ($main::use_symbol_page) {
-    $symbols = FetchSymbols($pcs);
-  } else {
-    # TODO(csilvers): $libs uses the /proc/self/maps data from profile1,
-    # which may differ from the data from subsequent profiles, especially
-    # if they were run on different machines.  Use appropriate libs for
-    # each pc somehow.
-    $symbols = ExtractSymbols($libs, $pcs);
-  }
-
-  # Remove uniniteresting stack items
-  $profile = RemoveUninterestingFrames($symbols, $profile);
-
-  # Focus?
-  if ($main::opt_focus ne '') {
-    $profile = FocusProfile($symbols, $profile, $main::opt_focus);
-  }
-
-  # Ignore?
-  if ($main::opt_ignore ne '') {
-    $profile = IgnoreProfile($symbols, $profile, $main::opt_ignore);
-  }
-
-  my $calls = ExtractCalls($symbols, $profile);
-
-  # Reduce profiles to required output granularity, and also clean
-  # each stack trace so a given entry exists at most once.
-  my $reduced = ReduceProfile($symbols, $profile);
-
-  # Get derived profiles
-  my $flat = FlatProfile($reduced);
-  my $cumulative = CumulativeProfile($reduced);
-
-  # Print
-  if (!$main::opt_interactive) {
-    if ($main::opt_disasm) {
-      PrintDisassembly($libs, $flat, $cumulative, $main::opt_disasm);
-    } elsif ($main::opt_list) {
-      PrintListing($total, $libs, $flat, $cumulative, $main::opt_list, 0);
-    } elsif ($main::opt_text) {
-      # Make sure the output is empty when have nothing to report
-      # (only matters when --heapcheck is given but we must be
-      # compatible with old branches that did not pass --heapcheck always):
-      if ($total != 0) {
-        printf("Total: %s %s\n", Unparse($total), Units());
-      }
-      if ($main::opt_stacks) {
-        printf("Stacks:\n\n");
-        PrintStacksForText($symbols, $profile);
-      }
-      PrintText($symbols, $flat, $cumulative, -1);
-    } elsif ($main::opt_raw) {
-      PrintSymbolizedProfile($symbols, $profile, $main::prog);
-    } elsif ($main::opt_collapsed) {
-      PrintCollapsedStacks($symbols, $profile);
-    } elsif ($main::opt_callgrind) {
-      PrintCallgrind($calls);
-    } else {
-      if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) {
-        if ($main::opt_gv) {
-          RunGV(TempName($main::next_tmpfile, "ps"), "");
-        } elsif ($main::opt_evince) {
-          RunEvince(TempName($main::next_tmpfile, "pdf"), "");
-        } elsif ($main::opt_web) {
-          my $tmp = TempName($main::next_tmpfile, "svg");
-          RunWeb($tmp);
-          # The command we run might hand the file name off
-          # to an already running browser instance and then exit.
-          # Normally, we'd remove $tmp on exit (right now),
-          # but fork a child to remove $tmp a little later, so that the
-          # browser has time to load it first.
-          delete $main::tempnames{$tmp};
-          if (fork() == 0) {
-            sleep 5;
-            unlink($tmp);
-            exit(0);
-          }
-        }
-      } else {
-        cleanup();
-        exit(1);
-      }
-    }
-  } else {
-    InteractiveMode($profile, $symbols, $libs, $total);
-  }
-
-  cleanup();
-  exit(0);
-}
-
-##### Entry Point #####
-
-Main();
-
-# Temporary code to detect if we're running on a Goobuntu system.
-# These systems don't have the right stuff installed for the special
-# Readline libraries to work, so as a temporary workaround, we default
-# to using the normal stdio code, rather than the fancier readline-based
-# code
-sub ReadlineMightFail {
-  if (-e '/lib/libtermcap.so.2') {
-    return 0;  # libtermcap exists, so readline should be okay
-  } else {
-    return 1;
-  }
-}
-
-sub RunGV {
-  my $fname = shift;
-  my $bg = shift;       # "" or " &" if we should run in background
-  if (!system(ShellEscape(@GV, "--version") . " >$dev_null 2>&1")) {
-    # Options using double dash are supported by this gv version.
-    # Also, turn on noantialias to better handle bug in gv for
-    # postscript files with large dimensions.
-    # TODO: Maybe we should not pass the --noantialias flag
-    # if the gv version is known to work properly without the flag.
-    system(ShellEscape(@GV, "--scale=$main::opt_scale", "--noantialias", $fname)
-           . $bg);
-  } else {
-    # Old gv version - only supports options that use single dash.
-    print STDERR ShellEscape(@GV, "-scale", $main::opt_scale) . "\n";
-    system(ShellEscape(@GV, "-scale", "$main::opt_scale", $fname) . $bg);
-  }
-}
-
-sub RunEvince {
-  my $fname = shift;
-  my $bg = shift;       # "" or " &" if we should run in background
-  system(ShellEscape(@EVINCE, $fname) . $bg);
-}
-
-sub RunWeb {
-  my $fname = shift;
-  print STDERR "Loading web page file:///$fname\n";
-
-  if (`uname` =~ /Darwin/) {
-    # OS X: open will use standard preference for SVG files.
-    system("/usr/bin/open", $fname);
-    return;
-  }
-
-  if (`uname` =~ /MINGW/) {
-    # Windows(MinGW): open will use standard preference for SVG files.
-    system("cmd", "/c", "start", $fname);
-    return;
-  }
-
-  # Some kind of Unix; try generic symlinks, then specific browsers.
-  # (Stop once we find one.)
-  # Works best if the browser is already running.
-  my @alt = (
-    "/etc/alternatives/gnome-www-browser",
-    "/etc/alternatives/x-www-browser",
-    "google-chrome",
-    "firefox",
-  );
-  foreach my $b (@alt) {
-    if (system($b, $fname) == 0) {
-      return;
-    }
-  }
-
-  print STDERR "Could not load web browser.\n";
-}
-
-sub RunKcachegrind {
-  my $fname = shift;
-  my $bg = shift;       # "" or " &" if we should run in background
-  print STDERR "Starting '@KCACHEGRIND " . $fname . $bg . "'\n";
-  system(ShellEscape(@KCACHEGRIND, $fname) . $bg);
-}
-
-
-##### Interactive helper routines #####
-
-sub InteractiveMode {
-  $| = 1;  # Make output unbuffered for interactive mode
-  my ($orig_profile, $symbols, $libs, $total) = @_;
-
-  print STDERR "Welcome to pprof!  For help, type 'help'.\n";
-
-  # Use ReadLine if it's installed and input comes from a console.
-  if ( -t STDIN &&
-       !ReadlineMightFail() &&
-       defined(eval {require Term::ReadLine}) ) {
-    my $term = new Term::ReadLine 'pprof';
-    while ( defined ($_ = $term->readline('(pprof) '))) {
-      $term->addhistory($_) if /\S/;
-      if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {
-        last;    # exit when we get an interactive command to quit
-      }
-    }
-  } else {       # don't have readline
-    while (1) {
-      print STDERR "(pprof) ";
-      $_ = <STDIN>;
-      last if ! defined $_ ;
-      s/\r//g;         # turn windows-looking lines into unix-looking lines
-
-      # Save some flags that might be reset by InteractiveCommand()
-      my $save_opt_lines = $main::opt_lines;
-
-      if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {
-        last;    # exit when we get an interactive command to quit
-      }
-
-      # Restore flags
-      $main::opt_lines = $save_opt_lines;
-    }
-  }
-}
-
-# Takes two args: orig profile, and command to run.
-# Returns 1 if we should keep going, or 0 if we were asked to quit
-sub InteractiveCommand {
-  my($orig_profile, $symbols, $libs, $total, $command) = @_;
-  $_ = $command;                # just to make future m//'s easier
-  if (!defined($_)) {
-    print STDERR "\n";
-    return 0;
-  }
-  if (m/^\s*quit/) {
-    return 0;
-  }
-  if (m/^\s*help/) {
-    InteractiveHelpMessage();
-    return 1;
-  }
-  # Clear all the mode options -- mode is controlled by "$command"
-  $main::opt_text = 0;
-  $main::opt_callgrind = 0;
-  $main::opt_disasm = 0;
-  $main::opt_list = 0;
-  $main::opt_gv = 0;
-  $main::opt_evince = 0;
-  $main::opt_cum = 0;
-
-  if (m/^\s*(text|top)(\d*)\s*(.*)/) {
-    $main::opt_text = 1;
-
-    my $line_limit = ($2 ne "") ? int($2) : 10;
-
-    my $routine;
-    my $ignore;
-    ($routine, $ignore) = ParseInteractiveArgs($3);
-
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    PrintText($symbols, $flat, $cumulative, $line_limit);
-    return 1;
-  }
-  if (m/^\s*callgrind\s*([^ \n]*)/) {
-    $main::opt_callgrind = 1;
-
-    # Get derived profiles
-    my $calls = ExtractCalls($symbols, $orig_profile);
-    my $filename = $1;
-    if ( $1 eq '' ) {
-      $filename = TempName($main::next_tmpfile, "callgrind");
-    }
-    PrintCallgrind($calls, $filename);
-    if ( $1 eq '' ) {
-      RunKcachegrind($filename, " & ");
-      $main::next_tmpfile++;
-    }
-
-    return 1;
-  }
-  if (m/^\s*(web)?list\s*(.+)/) {
-    my $html = (defined($1) && ($1 eq "web"));
-    $main::opt_list = 1;
-
-    my $routine;
-    my $ignore;
-    ($routine, $ignore) = ParseInteractiveArgs($2);
-
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    PrintListing($total, $libs, $flat, $cumulative, $routine, $html);
-    return 1;
-  }
-  if (m/^\s*disasm\s*(.+)/) {
-    $main::opt_disasm = 1;
-
-    my $routine;
-    my $ignore;
-    ($routine, $ignore) = ParseInteractiveArgs($1);
-
-    # Process current profile to account for various settings
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    PrintDisassembly($libs, $flat, $cumulative, $routine);
-    return 1;
-  }
-  if (m/^\s*(gv|web|evince)\s*(.*)/) {
-    $main::opt_gv = 0;
-    $main::opt_evince = 0;
-    $main::opt_web = 0;
-    if ($1 eq "gv") {
-      $main::opt_gv = 1;
-    } elsif ($1 eq "evince") {
-      $main::opt_evince = 1;
-    } elsif ($1 eq "web") {
-      $main::opt_web = 1;
-    }
-
-    my $focus;
-    my $ignore;
-    ($focus, $ignore) = ParseInteractiveArgs($2);
-
-    # Process current profile to account for various settings
-    my $profile = ProcessProfile($total, $orig_profile, $symbols,
-                                 $focus, $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) {
-      if ($main::opt_gv) {
-        RunGV(TempName($main::next_tmpfile, "ps"), " &");
-      } elsif ($main::opt_evince) {
-        RunEvince(TempName($main::next_tmpfile, "pdf"), " &");
-      } elsif ($main::opt_web) {
-        RunWeb(TempName($main::next_tmpfile, "svg"));
-      }
-      $main::next_tmpfile++;
-    }
-    return 1;
-  }
-  if (m/^\s*$/) {
-    return 1;
-  }
-  print STDERR "Unknown command: try 'help'.\n";
-  return 1;
-}
-
-
-sub ProcessProfile {
-  my $total_count = shift;
-  my $orig_profile = shift;
-  my $symbols = shift;
-  my $focus = shift;
-  my $ignore = shift;
-
-  # Process current profile to account for various settings
-  my $profile = $orig_profile;
-  printf("Total: %s %s\n", Unparse($total_count), Units());
-  if ($focus ne '') {
-    $profile = FocusProfile($symbols, $profile, $focus);
-    my $focus_count = TotalProfile($profile);
-    printf("After focusing on '%s': %s %s of %s (%0.1f%%)\n",
-           $focus,
-           Unparse($focus_count), Units(),
-           Unparse($total_count), ($focus_count*100.0) / $total_count);
-  }
-  if ($ignore ne '') {
-    $profile = IgnoreProfile($symbols, $profile, $ignore);
-    my $ignore_count = TotalProfile($profile);
-    printf("After ignoring '%s': %s %s of %s (%0.1f%%)\n",
-           $ignore,
-           Unparse($ignore_count), Units(),
-           Unparse($total_count),
-           ($ignore_count*100.0) / $total_count);
-  }
-
-  return $profile;
-}
-
-sub InteractiveHelpMessage {
-  print STDERR <<ENDOFHELP;
-Interactive pprof mode
-
-Commands:
-  gv
-  gv [focus] [-ignore1] [-ignore2]
-      Show graphical hierarchical display of current profile.  Without
-      any arguments, shows all samples in the profile.  With the optional
-      "focus" argument, restricts the samples shown to just those where
-      the "focus" regular expression matches a routine name on the stack
-      trace.
-
-  web
-  web [focus] [-ignore1] [-ignore2]
-      Like GV, but displays profile in your web browser instead of using
-      Ghostview. Works best if your web browser is already running.
-      To change the browser that gets used:
-      On Linux, set the /etc/alternatives/gnome-www-browser symlink.
-      On OS X, change the Finder association for SVG files.
-
-  list [routine_regexp] [-ignore1] [-ignore2]
-      Show source listing of routines whose names match "routine_regexp"
-
-  weblist [routine_regexp] [-ignore1] [-ignore2]
-     Displays a source listing of routines whose names match "routine_regexp"
-     in a web browser.  You can click on source lines to view the
-     corresponding disassembly.
-
-  top [--cum] [-ignore1] [-ignore2]
-  top20 [--cum] [-ignore1] [-ignore2]
-  top37 [--cum] [-ignore1] [-ignore2]
-      Show top lines ordered by flat profile count, or cumulative count
-      if --cum is specified.  If a number is present after 'top', the
-      top K routines will be shown (defaults to showing the top 10)
-
-  disasm [routine_regexp] [-ignore1] [-ignore2]
-      Show disassembly of routines whose names match "routine_regexp",
-      annotated with sample counts.
-
-  callgrind
-  callgrind [filename]
-      Generates callgrind file. If no filename is given, kcachegrind is called.
-
-  help - This listing
-  quit or ^D - End pprof
-
-For commands that accept optional -ignore tags, samples where any routine in
-the stack trace matches the regular expression in any of the -ignore
-parameters will be ignored.
-
-Further pprof details are available at this location (or one similar):
-
- /usr/doc/gperftools-$PPROF_VERSION/cpu_profiler.html
- /usr/doc/gperftools-$PPROF_VERSION/heap_profiler.html
-
-ENDOFHELP
-}
-sub ParseInteractiveArgs {
-  my $args = shift;
-  my $focus = "";
-  my $ignore = "";
-  my @x = split(/ +/, $args);
-  foreach $a (@x) {
-    if ($a =~ m/^(--|-)lines$/) {
-      $main::opt_lines = 1;
-    } elsif ($a =~ m/^(--|-)cum$/) {
-      $main::opt_cum = 1;
-    } elsif ($a =~ m/^-(.*)/) {
-      $ignore .= (($ignore ne "") ? "|" : "" ) . $1;
-    } else {
-      $focus .= (($focus ne "") ? "|" : "" ) . $a;
-    }
-  }
-  if ($ignore ne "") {
-    print STDERR "Ignoring samples in call stacks that match '$ignore'\n";
-  }
-  return ($focus, $ignore);
-}
-
-##### Output code #####
-
-sub TempName {
-  my $fnum = shift;
-  my $ext = shift;
-  my $file = "$main::tmpfile_ps.$fnum.$ext";
-  $main::tempnames{$file} = 1;
-  return $file;
-}
-
-# Print profile data in packed binary format (64-bit) to standard out
-sub PrintProfileData {
-  my $profile = shift;
-  my $big_endian = pack("L", 1) eq pack("N", 1);
-  # print header (64-bit style)
-  # (zero) (header-size) (version) (sample-period) (zero)
-  if ($big_endian) {
-    print pack('L*', 0, 0, 0, 3, 0, 0, 0, 1, 0, 0);
-  }
-  else {
-    print pack('L*', 0, 0, 3, 0, 0, 0, 1, 0, 0, 0);
-  }
-
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    if ($#addrs >= 0) {
-      my $depth = $#addrs + 1;
-      # int(foo / 2**32) is the only reliable way to get rid of bottom
-      # 32 bits on both 32- and 64-bit systems.
-      if ($big_endian) {
-        print pack('L*', int($count / 2**32), $count & 0xFFFFFFFF);
-        print pack('L*', int($depth / 2**32), $depth & 0xFFFFFFFF);
-      }
-      else {
-        print pack('L*', $count & 0xFFFFFFFF, int($count / 2**32));
-        print pack('L*', $depth & 0xFFFFFFFF, int($depth / 2**32));
-      }
-
-      foreach my $full_addr (@addrs) {
-        my $addr = $full_addr;
-        $addr =~ s/0x0*//;  # strip off leading 0x, zeroes
-        if (length($addr) > 16) {
-          print STDERR "Invalid address in profile: $full_addr\n";
-          next;
-        }
-        my $low_addr = substr($addr, -8);       # get last 8 hex chars
-        my $high_addr = substr($addr, -16, 8);  # get up to 8 more hex chars
-        if ($big_endian) {
-          print pack('L*', hex('0x' . $high_addr), hex('0x' . $low_addr));
-        }
-        else {
-          print pack('L*', hex('0x' . $low_addr), hex('0x' . $high_addr));
-        }
-      }
-    }
-  }
-}
-
-# Print symbols and profile data
-sub PrintSymbolizedProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $prog = shift;
-
-  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $symbol_marker = $&;
-
-  print '--- ', $symbol_marker, "\n";
-  if (defined($prog)) {
-    print 'binary=', $prog, "\n";
-  }
-  while (my ($pc, $name) = each(%{$symbols})) {
-    my $sep = ' ';
-    print '0x', $pc;
-    # We have a list of function names, which include the inlined
-    # calls.  They are separated (and terminated) by --, which is
-    # illegal in function names.
-    for (my $j = 2; $j <= $#{$name}; $j += 3) {
-      print $sep, $name->[$j];
-      $sep = '--';
-    }
-    print "\n";
-  }
-  print '---', "\n";
-
-  $PROFILE_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $profile_marker = $&;
-  print '--- ', $profile_marker, "\n";
-  if (defined($main::collected_profile)) {
-    # if used with remote fetch, simply dump the collected profile to output.
-    open(SRC, "<$main::collected_profile");
-    while (<SRC>) {
-      print $_;
-    }
-    close(SRC);
-  } else {
-    # dump a cpu-format profile to standard out
-    PrintProfileData($profile);
-  }
-}
-
-# Print text output
-sub PrintText {
-  my $symbols = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $line_limit = shift;
-
-  if ($main::opt_stacks && @stackTraces) {
-      foreach (sort { (split " ", $b)[1] <=> (split " ", $a)[1]; } @stackTraces) {
-	  print "$_\n" if $main::opt_debug;
-	  my ($n1, $s1, $n2, $s2, @addrs) = split;
-	  print "Leak of $s1 bytes in $n1 objects allocated from:\n";
-	  foreach my $pcstr (@addrs) {
-	      $pcstr =~ s/^0x//;
-	      my $sym;
-	      if (! defined $symbols->{$pcstr}) {
-		  $sym = "unknown";
-	      } else {
-		  $sym = "$symbols->{$pcstr}[0] $symbols->{$pcstr}[1]";
-	      }
-	      print "\t@ $pcstr $sym\n";
-	  }
-      }
-      print "\n";
-  }
-
-  my $total = TotalProfile($flat);
-
-  # Which profile to sort by?
-  my $s = $main::opt_cum ? $cumulative : $flat;
-
-  my $running_sum = 0;
-  my $lines = 0;
-  foreach my $k (sort { GetEntry($s, $b) <=> GetEntry($s, $a) || $a cmp $b }
-                 keys(%{$cumulative})) {
-    my $f = GetEntry($flat, $k);
-    my $c = GetEntry($cumulative, $k);
-    $running_sum += $f;
-
-    my $sym = $k;
-    if (exists($symbols->{$k})) {
-      $sym = $symbols->{$k}->[0] . " " . $symbols->{$k}->[1];
-      if ($main::opt_addresses) {
-        $sym = $k . " " . $sym;
-      }
-    }
-
-    if ($f != 0 || $c != 0) {
-      printf("%8s %6s %6s %8s %6s %s\n",
-             Unparse($f),
-             Percent($f, $total),
-             Percent($running_sum, $total),
-             Unparse($c),
-             Percent($c, $total),
-             $sym);
-    }
-    $lines++;
-    last if ($line_limit >= 0 && $lines >= $line_limit);
-  }
-}
-
-# Callgrind format has a compression for repeated function and file
-# names.  You show the name the first time, and just use its number
-# subsequently.  This can cut down the file to about a third or a
-# quarter of its uncompressed size.  $key and $val are the key/value
-# pair that would normally be printed by callgrind; $map is a map from
-# value to number.
-sub CompressedCGName {
-  my($key, $val, $map) = @_;
-  my $idx = $map->{$val};
-  # For very short keys, providing an index hurts rather than helps.
-  if (length($val) <= 3) {
-    return "$key=$val\n";
-  } elsif (defined($idx)) {
-    return "$key=($idx)\n";
-  } else {
-    # scalar(keys $map) gives the number of items in the map.
-    $idx = scalar(keys(%{$map})) + 1;
-    $map->{$val} = $idx;
-    return "$key=($idx) $val\n";
-  }
-}
-
-# Print the call graph in a way that's suiteable for callgrind.
-sub PrintCallgrind {
-  my $calls = shift;
-  my $filename;
-  my %filename_to_index_map;
-  my %fnname_to_index_map;
-
-  if ($main::opt_interactive) {
-    $filename = shift;
-    print STDERR "Writing callgrind file to '$filename'.\n"
-  } else {
-    $filename = "&STDOUT";
-  }
-  open(CG, ">$filename");
-  print CG ("events: Hits\n\n");
-  foreach my $call ( map { $_->[0] }
-                     sort { $a->[1] cmp $b ->[1] ||
-                            $a->[2] <=> $b->[2] }
-                     map { /([^:]+):(\d+):([^ ]+)( -> ([^:]+):(\d+):(.+))?/;
-                           [$_, $1, $2] }
-                     keys %$calls ) {
-    my $count = int($calls->{$call});
-    $call =~ /([^:]+):(\d+):([^ ]+)( -> ([^:]+):(\d+):(.+))?/;
-    my ( $caller_file, $caller_line, $caller_function,
-         $callee_file, $callee_line, $callee_function ) =
-       ( $1, $2, $3, $5, $6, $7 );
-
-    # TODO(csilvers): for better compression, collect all the
-    # caller/callee_files and functions first, before printing
-    # anything, and only compress those referenced more than once.
-    print CG CompressedCGName("fl", $caller_file, \%filename_to_index_map);
-    print CG CompressedCGName("fn", $caller_function, \%fnname_to_index_map);
-    if (defined $6) {
-      print CG CompressedCGName("cfl", $callee_file, \%filename_to_index_map);
-      print CG CompressedCGName("cfn", $callee_function, \%fnname_to_index_map);
-      print CG ("calls=$count $callee_line\n");
-    }
-    print CG ("$caller_line $count\n\n");
-  }
-}
-
-# Print disassembly for all all routines that match $main::opt_disasm
-sub PrintDisassembly {
-  my $libs = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $disasm_opts = shift;
-
-  my $total = TotalProfile($flat);
-
-  foreach my $lib (@{$libs}) {
-    my $symbol_table = GetProcedureBoundaries($lib->[0], $disasm_opts);
-    my $offset = AddressSub($lib->[1], $lib->[3]);
-    foreach my $routine (sort ByName keys(%{$symbol_table})) {
-      my $start_addr = $symbol_table->{$routine}->[0];
-      my $end_addr = $symbol_table->{$routine}->[1];
-      # See if there are any samples in this routine
-      my $length = hex(AddressSub($end_addr, $start_addr));
-      my $addr = AddressAdd($start_addr, $offset);
-      for (my $i = 0; $i < $length; $i++) {
-        if (defined($cumulative->{$addr})) {
-          PrintDisassembledFunction($lib->[0], $offset,
-                                    $routine, $flat, $cumulative,
-                                    $start_addr, $end_addr, $total);
-          last;
-        }
-        $addr = AddressInc($addr);
-      }
-    }
-  }
-}
-
-# Return reference to array of tuples of the form:
-#       [start_address, filename, linenumber, instruction, limit_address]
-# E.g.,
-#       ["0x806c43d", "/foo/bar.cc", 131, "ret", "0x806c440"]
-sub Disassemble {
-  my $prog = shift;
-  my $offset = shift;
-  my $start_addr = shift;
-  my $end_addr = shift;
-
-  my $objdump = $obj_tool_map{"objdump"};
-  my $cmd = ShellEscape($objdump, "-C", "-d", "-l", "--no-show-raw-insn",
-                        "--start-address=0x$start_addr",
-                        "--stop-address=0x$end_addr", $prog);
-  open(OBJDUMP, "$cmd |") || error("$cmd: $!\n");
-  my @result = ();
-  my $filename = "";
-  my $linenumber = -1;
-  my $last = ["", "", "", ""];
-  while (<OBJDUMP>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    chop;
-    if (m|\s*([^:\s]+):(\d+)\s*$|) {
-      # Location line of the form:
-      #   <filename>:<linenumber>
-      $filename = $1;
-      $linenumber = $2;
-    } elsif (m/^ +([0-9a-f]+):\s*(.*)/) {
-      # Disassembly line -- zero-extend address to full length
-      my $addr = HexExtend($1);
-      my $k = AddressAdd($addr, $offset);
-      $last->[4] = $k;   # Store ending address for previous instruction
-      $last = [$k, $filename, $linenumber, $2, $end_addr];
-      push(@result, $last);
-    }
-  }
-  close(OBJDUMP);
-  return @result;
-}
-
-# The input file should contain lines of the form /proc/maps-like
-# output (same format as expected from the profiles) or that looks
-# like hex addresses (like "0xDEADBEEF").  We will parse all
-# /proc/maps output, and for all the hex addresses, we will output
-# "short" symbol names, one per line, in the same order as the input.
-sub PrintSymbols {
-  my $maps_and_symbols_file = shift;
-
-  # ParseLibraries expects pcs to be in a set.  Fine by us...
-  my @pclist = ();   # pcs in sorted order
-  my $pcs = {};
-  my $map = "";
-  foreach my $line (<$maps_and_symbols_file>) {
-    $line =~ s/\r//g;    # turn windows-looking lines into unix-looking lines
-    if ($line =~ /\b(0x[0-9a-f]+)\b/i) {
-      push(@pclist, HexExtend($1));
-      $pcs->{$pclist[-1]} = 1;
-    } else {
-      $map .= $line;
-    }
-  }
-
-  my $libs = ParseLibraries($main::prog, $map, $pcs);
-  my $symbols = ExtractSymbols($libs, $pcs);
-
-  foreach my $pc (@pclist) {
-    # ->[0] is the shortname, ->[2] is the full name
-    print(($symbols->{$pc}->[0] || "??") . "\n");
-  }
-}
-
-
-# For sorting functions by name
-sub ByName {
-  return ShortFunctionName($a) cmp ShortFunctionName($b);
-}
-
-# Print source-listing for all all routines that match $list_opts
-sub PrintListing {
-  my $total = shift;
-  my $libs = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $list_opts = shift;
-  my $html = shift;
-
-  my $output = \*STDOUT;
-  my $fname = "";
-
-  if ($html) {
-    # Arrange to write the output to a temporary file
-    $fname = TempName($main::next_tmpfile, "html");
-    $main::next_tmpfile++;
-    if (!open(TEMP, ">$fname")) {
-      print STDERR "$fname: $!\n";
-      return;
-    }
-    $output = \*TEMP;
-    print $output HtmlListingHeader();
-    printf $output ("<div class=\"legend\">%s<br>Total: %s %s</div>\n",
-                    $main::prog, Unparse($total), Units());
-  }
-
-  my $listed = 0;
-  foreach my $lib (@{$libs}) {
-    my $symbol_table = GetProcedureBoundaries($lib->[0], $list_opts);
-    my $offset = AddressSub($lib->[1], $lib->[3]);
-    foreach my $routine (sort ByName keys(%{$symbol_table})) {
-      # Print if there are any samples in this routine
-      my $start_addr = $symbol_table->{$routine}->[0];
-      my $end_addr = $symbol_table->{$routine}->[1];
-      my $length = hex(AddressSub($end_addr, $start_addr));
-      my $addr = AddressAdd($start_addr, $offset);
-      for (my $i = 0; $i < $length; $i++) {
-        if (defined($cumulative->{$addr})) {
-          $listed += PrintSource(
-            $lib->[0], $offset,
-            $routine, $flat, $cumulative,
-            $start_addr, $end_addr,
-            $html,
-            $output);
-          last;
-        }
-        $addr = AddressInc($addr);
-      }
-    }
-  }
-
-  if ($html) {
-    if ($listed > 0) {
-      print $output HtmlListingFooter();
-      close($output);
-      RunWeb($fname);
-    } else {
-      close($output);
-      unlink($fname);
-    }
-  }
-}
-
-sub HtmlListingHeader {
-  return <<'EOF';
-<DOCTYPE html>
-<html>
-<head>
-<title>Pprof listing</title>
-<style type="text/css">
-body {
-  font-family: sans-serif;
-}
-h1 {
-  font-size: 1.5em;
-  margin-bottom: 4px;
-}
-.legend {
-  font-size: 1.25em;
-}
-.line {
-  color: #aaaaaa;
-}
-.nop {
-  color: #aaaaaa;
-}
-.unimportant {
-  color: #cccccc;
-}
-.disasmloc {
-  color: #000000;
-}
-.deadsrc {
-  cursor: pointer;
-}
-.deadsrc:hover {
-  background-color: #eeeeee;
-}
-.livesrc {
-  color: #0000ff;
-  cursor: pointer;
-}
-.livesrc:hover {
-  background-color: #eeeeee;
-}
-.asm {
-  color: #008800;
-  display: none;
-}
-</style>
-<script type="text/javascript">
-function pprof_toggle_asm(e) {
-  var target;
-  if (!e) e = window.event;
-  if (e.target) target = e.target;
-  else if (e.srcElement) target = e.srcElement;
-
-  if (target) {
-    var asm = target.nextSibling;
-    if (asm && asm.className == "asm") {
-      asm.style.display = (asm.style.display == "block" ? "" : "block");
-      e.preventDefault();
-      return false;
-    }
-  }
-}
-</script>
-</head>
-<body>
-EOF
-}
-
-sub HtmlListingFooter {
-  return <<'EOF';
-</body>
-</html>
-EOF
-}
-
-sub HtmlEscape {
-  my $text = shift;
-  $text =~ s/&/&amp;/g;
-  $text =~ s/</&lt;/g;
-  $text =~ s/>/&gt;/g;
-  return $text;
-}
-
-# Returns the indentation of the line, if it has any non-whitespace
-# characters.  Otherwise, returns -1.
-sub Indentation {
-  my $line = shift;
-  if (m/^(\s*)\S/) {
-    return length($1);
-  } else {
-    return -1;
-  }
-}
-
-# If the symbol table contains inlining info, Disassemble() may tag an
-# instruction with a location inside an inlined function.  But for
-# source listings, we prefer to use the location in the function we
-# are listing.  So use MapToSymbols() to fetch full location
-# information for each instruction and then pick out the first
-# location from a location list (location list contains callers before
-# callees in case of inlining).
-#
-# After this routine has run, each entry in $instructions contains:
-#   [0] start address
-#   [1] filename for function we are listing
-#   [2] line number for function we are listing
-#   [3] disassembly
-#   [4] limit address
-#   [5] most specific filename (may be different from [1] due to inlining)
-#   [6] most specific line number (may be different from [2] due to inlining)
-sub GetTopLevelLineNumbers {
-  my ($lib, $offset, $instructions) = @_;
-  my $pcs = [];
-  for (my $i = 0; $i <= $#{$instructions}; $i++) {
-    push(@{$pcs}, $instructions->[$i]->[0]);
-  }
-  my $symbols = {};
-  MapToSymbols($lib, $offset, $pcs, $symbols);
-  for (my $i = 0; $i <= $#{$instructions}; $i++) {
-    my $e = $instructions->[$i];
-    push(@{$e}, $e->[1]);
-    push(@{$e}, $e->[2]);
-    my $addr = $e->[0];
-    my $sym = $symbols->{$addr};
-    if (defined($sym)) {
-      if ($#{$sym} >= 2 && $sym->[1] =~ m/^(.*):(\d+)$/) {
-        $e->[1] = $1;  # File name
-        $e->[2] = $2;  # Line number
-      }
-    }
-  }
-}
-
-# Print source-listing for one routine
-sub PrintSource {
-  my $prog = shift;
-  my $offset = shift;
-  my $routine = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $start_addr = shift;
-  my $end_addr = shift;
-  my $html = shift;
-  my $output = shift;
-
-  # Disassemble all instructions (just to get line numbers)
-  my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);
-  GetTopLevelLineNumbers($prog, $offset, \@instructions);
-
-  # Hack 1: assume that the first source file encountered in the
-  # disassembly contains the routine
-  my $filename = undef;
-  for (my $i = 0; $i <= $#instructions; $i++) {
-    if ($instructions[$i]->[2] >= 0) {
-      $filename = $instructions[$i]->[1];
-      last;
-    }
-  }
-  if (!defined($filename)) {
-    print STDERR "no filename found in $routine\n";
-    return 0;
-  }
-
-  # Hack 2: assume that the largest line number from $filename is the
-  # end of the procedure.  This is typically safe since if P1 contains
-  # an inlined call to P2, then P2 usually occurs earlier in the
-  # source file.  If this does not work, we might have to compute a
-  # density profile or just print all regions we find.
-  my $lastline = 0;
-  for (my $i = 0; $i <= $#instructions; $i++) {
-    my $f = $instructions[$i]->[1];
-    my $l = $instructions[$i]->[2];
-    if (($f eq $filename) && ($l > $lastline)) {
-      $lastline = $l;
-    }
-  }
-
-  # Hack 3: assume the first source location from "filename" is the start of
-  # the source code.
-  my $firstline = 1;
-  for (my $i = 0; $i <= $#instructions; $i++) {
-    if ($instructions[$i]->[1] eq $filename) {
-      $firstline = $instructions[$i]->[2];
-      last;
-    }
-  }
-
-  # Hack 4: Extend last line forward until its indentation is less than
-  # the indentation we saw on $firstline
-  my $oldlastline = $lastline;
-  {
-    if (!open(FILE, "<$filename")) {
-      print STDERR "$filename: $!\n";
-      return 0;
-    }
-    my $l = 0;
-    my $first_indentation = -1;
-    while (<FILE>) {
-      s/\r//g;         # turn windows-looking lines into unix-looking lines
-      $l++;
-      my $indent = Indentation($_);
-      if ($l >= $firstline) {
-        if ($first_indentation < 0 && $indent >= 0) {
-          $first_indentation = $indent;
-          last if ($first_indentation == 0);
-        }
-      }
-      if ($l >= $lastline && $indent >= 0) {
-        if ($indent >= $first_indentation) {
-          $lastline = $l+1;
-        } else {
-          last;
-        }
-      }
-    }
-    close(FILE);
-  }
-
-  # Assign all samples to the range $firstline,$lastline,
-  # Hack 4: If an instruction does not occur in the range, its samples
-  # are moved to the next instruction that occurs in the range.
-  my $samples1 = {};        # Map from line number to flat count
-  my $samples2 = {};        # Map from line number to cumulative count
-  my $running1 = 0;         # Unassigned flat counts
-  my $running2 = 0;         # Unassigned cumulative counts
-  my $total1 = 0;           # Total flat counts
-  my $total2 = 0;           # Total cumulative counts
-  my %disasm = ();          # Map from line number to disassembly
-  my $running_disasm = "";  # Unassigned disassembly
-  my $skip_marker = "---\n";
-  if ($html) {
-    $skip_marker = "";
-    for (my $l = $firstline; $l <= $lastline; $l++) {
-      $disasm{$l} = "";
-    }
-  }
-  my $last_dis_filename = '';
-  my $last_dis_linenum = -1;
-  my $last_touched_line = -1;  # To detect gaps in disassembly for a line
-  foreach my $e (@instructions) {
-    # Add up counts for all address that fall inside this instruction
-    my $c1 = 0;
-    my $c2 = 0;
-    for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) {
-      $c1 += GetEntry($flat, $a);
-      $c2 += GetEntry($cumulative, $a);
-    }
-
-    if ($html) {
-      my $dis = sprintf("      %6s %6s \t\t%8s: %s ",
-                        HtmlPrintNumber($c1),
-                        HtmlPrintNumber($c2),
-                        UnparseAddress($offset, $e->[0]),
-                        CleanDisassembly($e->[3]));
-      
-      # Append the most specific source line associated with this instruction
-      if (length($dis) < 80) { $dis .= (' ' x (80 - length($dis))) };
-      $dis = HtmlEscape($dis);
-      my $f = $e->[5];
-      my $l = $e->[6];
-      if ($f ne $last_dis_filename) {
-        $dis .= sprintf("<span class=disasmloc>%s:%d</span>", 
-                        HtmlEscape(CleanFileName($f)), $l);
-      } elsif ($l ne $last_dis_linenum) {
-        # De-emphasize the unchanged file name portion
-        $dis .= sprintf("<span class=unimportant>%s</span>" .
-                        "<span class=disasmloc>:%d</span>", 
-                        HtmlEscape(CleanFileName($f)), $l);
-      } else {
-        # De-emphasize the entire location
-        $dis .= sprintf("<span class=unimportant>%s:%d</span>", 
-                        HtmlEscape(CleanFileName($f)), $l);
-      }
-      $last_dis_filename = $f;
-      $last_dis_linenum = $l;
-      $running_disasm .= $dis;
-      $running_disasm .= "\n";
-    }
-
-    $running1 += $c1;
-    $running2 += $c2;
-    $total1 += $c1;
-    $total2 += $c2;
-    my $file = $e->[1];
-    my $line = $e->[2];
-    if (($file eq $filename) &&
-        ($line >= $firstline) &&
-        ($line <= $lastline)) {
-      # Assign all accumulated samples to this line
-      AddEntry($samples1, $line, $running1);
-      AddEntry($samples2, $line, $running2);
-      $running1 = 0;
-      $running2 = 0;
-      if ($html) {
-        if ($line != $last_touched_line && $disasm{$line} ne '') {
-          $disasm{$line} .= "\n";
-        }
-        $disasm{$line} .= $running_disasm;
-        $running_disasm = '';
-        $last_touched_line = $line;
-      }
-    }
-  }
-
-  # Assign any leftover samples to $lastline
-  AddEntry($samples1, $lastline, $running1);
-  AddEntry($samples2, $lastline, $running2);
-  if ($html) {
-    if ($lastline != $last_touched_line && $disasm{$lastline} ne '') {
-      $disasm{$lastline} .= "\n";
-    }
-    $disasm{$lastline} .= $running_disasm;
-  }
-
-  if ($html) {
-    printf $output (
-      "<h1>%s</h1>%s\n<pre onClick=\"pprof_toggle_asm()\">\n" .
-      "Total:%6s %6s (flat / cumulative %s)\n",
-      HtmlEscape(ShortFunctionName($routine)),
-      HtmlEscape(CleanFileName($filename)),
-      Unparse($total1),
-      Unparse($total2),
-      Units());
-  } else {
-    printf $output (
-      "ROUTINE ====================== %s in %s\n" .
-      "%6s %6s Total %s (flat / cumulative)\n",
-      ShortFunctionName($routine),
-      CleanFileName($filename),
-      Unparse($total1),
-      Unparse($total2),
-      Units());
-  }
-  if (!open(FILE, "<$filename")) {
-    print STDERR "$filename: $!\n";
-    return 0;
-  }
-  my $l = 0;
-  while (<FILE>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    $l++;
-    if ($l >= $firstline - 5 &&
-        (($l <= $oldlastline + 5) || ($l <= $lastline))) {
-      chop;
-      my $text = $_;
-      if ($l == $firstline) { print $output $skip_marker; }
-      my $n1 = GetEntry($samples1, $l);
-      my $n2 = GetEntry($samples2, $l);
-      if ($html) {
-        # Emit a span that has one of the following classes:
-        #    livesrc -- has samples
-        #    deadsrc -- has disassembly, but with no samples
-        #    nop     -- has no matching disasembly
-        # Also emit an optional span containing disassembly.
-        my $dis = $disasm{$l};
-        my $asm = "";
-        if (defined($dis) && $dis ne '') {
-          $asm = "<span class=\"asm\">" . $dis . "</span>";
-        }
-        my $source_class = (($n1 + $n2 > 0) 
-                            ? "livesrc" 
-                            : (($asm ne "") ? "deadsrc" : "nop"));
-        printf $output (
-          "<span class=\"line\">%5d</span> " .
-          "<span class=\"%s\">%6s %6s %s</span>%s\n",
-          $l, $source_class,
-          HtmlPrintNumber($n1),
-          HtmlPrintNumber($n2),
-          HtmlEscape($text),
-          $asm);
-      } else {
-        printf $output(
-          "%6s %6s %4d: %s\n",
-          UnparseAlt($n1),
-          UnparseAlt($n2),
-          $l,
-          $text);
-      }
-      if ($l == $lastline)  { print $output $skip_marker; }
-    };
-  }
-  close(FILE);
-  if ($html) {
-    print $output "</pre>\n";
-  }
-  return 1;
-}
-
-# Return the source line for the specified file/linenumber.
-# Returns undef if not found.
-sub SourceLine {
-  my $file = shift;
-  my $line = shift;
-
-  # Look in cache
-  if (!defined($main::source_cache{$file})) {
-    if (100 < scalar keys(%main::source_cache)) {
-      # Clear the cache when it gets too big
-      $main::source_cache = ();
-    }
-
-    # Read all lines from the file
-    if (!open(FILE, "<$file")) {
-      print STDERR "$file: $!\n";
-      $main::source_cache{$file} = [];  # Cache the negative result
-      return undef;
-    }
-    my $lines = [];
-    push(@{$lines}, "");        # So we can use 1-based line numbers as indices
-    while (<FILE>) {
-      push(@{$lines}, $_);
-    }
-    close(FILE);
-
-    # Save the lines in the cache
-    $main::source_cache{$file} = $lines;
-  }
-
-  my $lines = $main::source_cache{$file};
-  if (($line < 0) || ($line > $#{$lines})) {
-    return undef;
-  } else {
-    return $lines->[$line];
-  }
-}
-
-# Print disassembly for one routine with interspersed source if available
-sub PrintDisassembledFunction {
-  my $prog = shift;
-  my $offset = shift;
-  my $routine = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $start_addr = shift;
-  my $end_addr = shift;
-  my $total = shift;
-
-  # Disassemble all instructions
-  my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);
-
-  # Make array of counts per instruction
-  my @flat_count = ();
-  my @cum_count = ();
-  my $flat_total = 0;
-  my $cum_total = 0;
-  foreach my $e (@instructions) {
-    # Add up counts for all address that fall inside this instruction
-    my $c1 = 0;
-    my $c2 = 0;
-    for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) {
-      $c1 += GetEntry($flat, $a);
-      $c2 += GetEntry($cumulative, $a);
-    }
-    push(@flat_count, $c1);
-    push(@cum_count, $c2);
-    $flat_total += $c1;
-    $cum_total += $c2;
-  }
-
-  # Print header with total counts
-  printf("ROUTINE ====================== %s\n" .
-         "%6s %6s %s (flat, cumulative) %.1f%% of total\n",
-         ShortFunctionName($routine),
-         Unparse($flat_total),
-         Unparse($cum_total),
-         Units(),
-         ($cum_total * 100.0) / $total);
-
-  # Process instructions in order
-  my $current_file = "";
-  for (my $i = 0; $i <= $#instructions; ) {
-    my $e = $instructions[$i];
-
-    # Print the new file name whenever we switch files
-    if ($e->[1] ne $current_file) {
-      $current_file = $e->[1];
-      my $fname = $current_file;
-      $fname =~ s|^\./||;   # Trim leading "./"
-
-      # Shorten long file names
-      if (length($fname) >= 58) {
-        $fname = "..." . substr($fname, -55);
-      }
-      printf("-------------------- %s\n", $fname);
-    }
-
-    # TODO: Compute range of lines to print together to deal with
-    # small reorderings.
-    my $first_line = $e->[2];
-    my $last_line = $first_line;
-    my %flat_sum = ();
-    my %cum_sum = ();
-    for (my $l = $first_line; $l <= $last_line; $l++) {
-      $flat_sum{$l} = 0;
-      $cum_sum{$l} = 0;
-    }
-
-    # Find run of instructions for this range of source lines
-    my $first_inst = $i;
-    while (($i <= $#instructions) &&
-           ($instructions[$i]->[2] >= $first_line) &&
-           ($instructions[$i]->[2] <= $last_line)) {
-      $e = $instructions[$i];
-      $flat_sum{$e->[2]} += $flat_count[$i];
-      $cum_sum{$e->[2]} += $cum_count[$i];
-      $i++;
-    }
-    my $last_inst = $i - 1;
-
-    # Print source lines
-    for (my $l = $first_line; $l <= $last_line; $l++) {
-      my $line = SourceLine($current_file, $l);
-      if (!defined($line)) {
-        $line = "?\n";
-        next;
-      } else {
-        $line =~ s/^\s+//;
-      }
-      printf("%6s %6s %5d: %s",
-             UnparseAlt($flat_sum{$l}),
-             UnparseAlt($cum_sum{$l}),
-             $l,
-             $line);
-    }
-
-    # Print disassembly
-    for (my $x = $first_inst; $x <= $last_inst; $x++) {
-      my $e = $instructions[$x];
-      printf("%6s %6s    %8s: %6s\n",
-             UnparseAlt($flat_count[$x]),
-             UnparseAlt($cum_count[$x]),
-             UnparseAddress($offset, $e->[0]),
-             CleanDisassembly($e->[3]));
-    }
-  }
-}
-
-# Print DOT graph
-sub PrintDot {
-  my $prog = shift;
-  my $symbols = shift;
-  my $raw = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $overall_total = shift;
-
-  # Get total
-  my $local_total = TotalProfile($flat);
-  my $nodelimit = int($main::opt_nodefraction * $local_total);
-  my $edgelimit = int($main::opt_edgefraction * $local_total);
-  my $nodecount = $main::opt_nodecount;
-
-  # Find nodes to include
-  my @list = (sort { abs(GetEntry($cumulative, $b)) <=>
-                     abs(GetEntry($cumulative, $a))
-                     || $a cmp $b }
-              keys(%{$cumulative}));
-  my $last = $nodecount - 1;
-  if ($last > $#list) {
-    $last = $#list;
-  }
-  while (($last >= 0) &&
-         (abs(GetEntry($cumulative, $list[$last])) <= $nodelimit)) {
-    $last--;
-  }
-  if ($last < 0) {
-    print STDERR "No nodes to print\n";
-    return 0;
-  }
-
-  if ($nodelimit > 0 || $edgelimit > 0) {
-    printf STDERR ("Dropping nodes with <= %s %s; edges with <= %s abs(%s)\n",
-                   Unparse($nodelimit), Units(),
-                   Unparse($edgelimit), Units());
-  }
-
-  # Open DOT output file
-  my $output;
-  my $escaped_dot = ShellEscape(@DOT);
-  my $escaped_ps2pdf = ShellEscape(@PS2PDF);
-  if ($main::opt_gv) {
-    my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, "ps"));
-    $output = "| $escaped_dot -Tps2 >$escaped_outfile";
-  } elsif ($main::opt_evince) {
-    my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, "pdf"));
-    $output = "| $escaped_dot -Tps2 | $escaped_ps2pdf - $escaped_outfile";
-  } elsif ($main::opt_ps) {
-    $output = "| $escaped_dot -Tps2";
-  } elsif ($main::opt_pdf) {
-    $output = "| $escaped_dot -Tps2 | $escaped_ps2pdf - -";
-  } elsif ($main::opt_web || $main::opt_svg) {
-    # We need to post-process the SVG, so write to a temporary file always.
-    my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, "svg"));
-    $output = "| $escaped_dot -Tsvg >$escaped_outfile";
-  } elsif ($main::opt_gif) {
-    $output = "| $escaped_dot -Tgif";
-  } else {
-    $output = ">&STDOUT";
-  }
-  open(DOT, $output) || error("$output: $!\n");
-
-  # Title
-  printf DOT ("digraph \"%s; %s %s\" {\n",
-              $prog,
-              Unparse($overall_total),
-              Units());
-  if ($main::opt_pdf) {
-    # The output is more printable if we set the page size for dot.
-    printf DOT ("size=\"8,11\"\n");
-  }
-  printf DOT ("node [width=0.375,height=0.25];\n");
-
-  # Print legend
-  printf DOT ("Legend [shape=box,fontsize=24,shape=plaintext," .
-              "label=\"%s\\l%s\\l%s\\l%s\\l%s\\l\"];\n",
-              $prog,
-              sprintf("Total %s: %s", Units(), Unparse($overall_total)),
-              sprintf("Focusing on: %s", Unparse($local_total)),
-              sprintf("Dropped nodes with <= %s abs(%s)",
-                      Unparse($nodelimit), Units()),
-              sprintf("Dropped edges with <= %s %s",
-                      Unparse($edgelimit), Units())
-              );
-
-  # Print nodes
-  my %node = ();
-  my $nextnode = 1;
-  foreach my $a (@list[0..$last]) {
-    # Pick font size
-    my $f = GetEntry($flat, $a);
-    my $c = GetEntry($cumulative, $a);
-
-    my $fs = 8;
-    if ($local_total > 0) {
-      $fs = 8 + (50.0 * sqrt(abs($f * 1.0 / $local_total)));
-    }
-
-    $node{$a} = $nextnode++;
-    my $sym = $a;
-    $sym =~ s/\s+/\\n/g;
-    $sym =~ s/::/\\n/g;
-
-    # Extra cumulative info to print for non-leaves
-    my $extra = "";
-    if ($f != $c) {
-      $extra = sprintf("\\rof %s (%s)",
-                       Unparse($c),
-                       Percent($c, $local_total));
-    }
-    my $style = "";
-    if ($main::opt_heapcheck) {
-      if ($f > 0) {
-        # make leak-causing nodes more visible (add a background)
-        $style = ",style=filled,fillcolor=gray"
-      } elsif ($f < 0) {
-        # make anti-leak-causing nodes (which almost never occur)
-        # stand out as well (triple border)
-        $style = ",peripheries=3"
-      }
-    }
-
-    printf DOT ("N%d [label=\"%s\\n%s (%s)%s\\r" .
-                "\",shape=box,fontsize=%.1f%s];\n",
-                $node{$a},
-                $sym,
-                Unparse($f),
-                Percent($f, $local_total),
-                $extra,
-                $fs,
-                $style,
-               );
-  }
-
-  # Get edges and counts per edge
-  my %edge = ();
-  my $n;
-  my $fullname_to_shortname_map = {};
-  FillFullnameToShortnameMap($symbols, $fullname_to_shortname_map);
-  foreach my $k (keys(%{$raw})) {
-    # TODO: omit low %age edges
-    $n = $raw->{$k};
-    my @translated = TranslateStack($symbols, $fullname_to_shortname_map, $k);
-    for (my $i = 1; $i <= $#translated; $i++) {
-      my $src = $translated[$i];
-      my $dst = $translated[$i-1];
-      #next if ($src eq $dst);  # Avoid self-edges?
-      if (exists($node{$src}) && exists($node{$dst})) {
-        my $edge_label = "$src\001$dst";
-        if (!exists($edge{$edge_label})) {
-          $edge{$edge_label} = 0;
-        }
-        $edge{$edge_label} += $n;
-      }
-    }
-  }
-
-  # Print edges (process in order of decreasing counts)
-  my %indegree = ();   # Number of incoming edges added per node so far
-  my %outdegree = ();  # Number of outgoing edges added per node so far
-  foreach my $e (sort { $edge{$b} <=> $edge{$a} } keys(%edge)) {
-    my @x = split(/\001/, $e);
-    $n = $edge{$e};
-
-    # Initialize degree of kept incoming and outgoing edges if necessary
-    my $src = $x[0];
-    my $dst = $x[1];
-    if (!exists($outdegree{$src})) { $outdegree{$src} = 0; }
-    if (!exists($indegree{$dst})) { $indegree{$dst} = 0; }
-
-    my $keep;
-    if ($indegree{$dst} == 0) {
-      # Keep edge if needed for reachability
-      $keep = 1;
-    } elsif (abs($n) <= $edgelimit) {
-      # Drop if we are below --edgefraction
-      $keep = 0;
-    } elsif ($outdegree{$src} >= $main::opt_maxdegree ||
-             $indegree{$dst} >= $main::opt_maxdegree) {
-      # Keep limited number of in/out edges per node
-      $keep = 0;
-    } else {
-      $keep = 1;
-    }
-
-    if ($keep) {
-      $outdegree{$src}++;
-      $indegree{$dst}++;
-
-      # Compute line width based on edge count
-      my $fraction = abs($local_total ? (3 * ($n / $local_total)) : 0);
-      if ($fraction > 1) { $fraction = 1; }
-      my $w = $fraction * 2;
-      if ($w < 1 && ($main::opt_web || $main::opt_svg)) {
-        # SVG output treats line widths < 1 poorly.
-        $w = 1;
-      }
-
-      # Dot sometimes segfaults if given edge weights that are too large, so
-      # we cap the weights at a large value
-      my $edgeweight = abs($n) ** 0.7;
-      if ($edgeweight > 100000) { $edgeweight = 100000; }
-      $edgeweight = int($edgeweight);
-
-      my $style = sprintf("setlinewidth(%f)", $w);
-      if ($x[1] =~ m/\(inline\)/) {
-        $style .= ",dashed";
-      }
-
-      # Use a slightly squashed function of the edge count as the weight
-      printf DOT ("N%s -> N%s [label=%s, weight=%d, style=\"%s\"];\n",
-                  $node{$x[0]},
-                  $node{$x[1]},
-                  Unparse($n),
-                  $edgeweight,
-                  $style);
-    }
-  }
-
-  print DOT ("}\n");
-  close(DOT);
-
-  if ($main::opt_web || $main::opt_svg) {
-    # Rewrite SVG to be more usable inside web browser.
-    RewriteSvg(TempName($main::next_tmpfile, "svg"));
-  }
-
-  return 1;
-}
-
-sub RewriteSvg {
-  my $svgfile = shift;
-
-  open(SVG, $svgfile) || die "open temp svg: $!";
-  my @svg = <SVG>;
-  close(SVG);
-  unlink $svgfile;
-  my $svg = join('', @svg);
-
-  # Dot's SVG output is
-  #
-  #    <svg width="___" height="___"
-  #     viewBox="___" xmlns=...>
-  #    <g id="graph0" transform="...">
-  #    ...
-  #    </g>
-  #    </svg>
-  #
-  # Change it to
-  #
-  #    <svg width="100%" height="100%"
-  #     xmlns=...>
-  #    $svg_javascript
-  #    <g id="viewport" transform="translate(0,0)">
-  #    <g id="graph0" transform="...">
-  #    ...
-  #    </g>
-  #    </g>
-  #    </svg>
-
-  # Fix width, height; drop viewBox.
-  $svg =~ s/(?s)<svg width="[^"]+" height="[^"]+"(.*?)viewBox="[^"]+"/<svg width="100%" height="100%"$1/;
-
-  # Insert script, viewport <g> above first <g>
-  my $svg_javascript = SvgJavascript();
-  my $viewport = "<g id=\"viewport\" transform=\"translate(0,0)\">\n";
-  $svg =~ s/<g id="graph\d"/$svg_javascript$viewport$&/;
-
-  # Insert final </g> above </svg>.
-  $svg =~ s/(.*)(<\/svg>)/$1<\/g>$2/;
-  $svg =~ s/<g id="graph\d"(.*?)/<g id="viewport"$1/;
-
-  if ($main::opt_svg) {
-    # --svg: write to standard output.
-    print $svg;
-  } else {
-    # Write back to temporary file.
-    open(SVG, ">$svgfile") || die "open $svgfile: $!";
-    print SVG $svg;
-    close(SVG);
-  }
-}
-
-sub SvgJavascript {
-  return <<'EOF';
-<script type="text/ecmascript"><![CDATA[
-// SVGPan
-// http://www.cyberz.org/blog/2009/12/08/svgpan-a-javascript-svg-panzoomdrag-library/
-// Local modification: if(true || ...) below to force panning, never moving.
-
-/**
- *  SVGPan library 1.2
- * ====================
- *
- * Given an unique existing element with id "viewport", including the
- * the library into any SVG adds the following capabilities:
- *
- *  - Mouse panning
- *  - Mouse zooming (using the wheel)
- *  - Object dargging
- *
- * Known issues:
- *
- *  - Zooming (while panning) on Safari has still some issues
- *
- * Releases:
- *
- * 1.2, Sat Mar 20 08:42:50 GMT 2010, Zeng Xiaohui
- *	Fixed a bug with browser mouse handler interaction
- *
- * 1.1, Wed Feb  3 17:39:33 GMT 2010, Zeng Xiaohui
- *	Updated the zoom code to support the mouse wheel on Safari/Chrome
- *
- * 1.0, Andrea Leofreddi
- *	First release
- *
- * This code is licensed under the following BSD license:
- *
- * Copyright 2009-2010 Andrea Leofreddi <a.leofreddi@itcharm.com>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice, this list of
- *       conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright notice, this list
- *       of conditions and the following disclaimer in the documentation and/or other materials
- *       provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY Andrea Leofreddi ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Andrea Leofreddi OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of Andrea Leofreddi.
- */
-
-var root = document.documentElement;
-
-var state = 'none', stateTarget, stateOrigin, stateTf;
-
-setupHandlers(root);
-
-/**
- * Register handlers
- */
-function setupHandlers(root){
-	setAttributes(root, {
-		"onmouseup" : "add(evt)",
-		"onmousedown" : "handleMouseDown(evt)",
-		"onmousemove" : "handleMouseMove(evt)",
-		"onmouseup" : "handleMouseUp(evt)",
-		//"onmouseout" : "handleMouseUp(evt)", // Decomment this to stop the pan functionality when dragging out of the SVG element
-	});
-
-	if(navigator.userAgent.toLowerCase().indexOf('webkit') >= 0)
-		window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari
-	else
-		window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
-
-	var g = svgDoc.getElementById("svg");
-	g.width = "100%";
-	g.height = "100%";
-}
-
-/**
- * Instance an SVGPoint object with given event coordinates.
- */
-function getEventPoint(evt) {
-	var p = root.createSVGPoint();
-
-	p.x = evt.clientX;
-	p.y = evt.clientY;
-
-	return p;
-}
-
-/**
- * Sets the current transform matrix of an element.
- */
-function setCTM(element, matrix) {
-	var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
-
-	element.setAttribute("transform", s);
-}
-
-/**
- * Dumps a matrix to a string (useful for debug).
- */
-function dumpMatrix(matrix) {
-	var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\n  " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\n  0, 0, 1 ]";
-
-	return s;
-}
-
-/**
- * Sets attributes of an element.
- */
-function setAttributes(element, attributes){
-	for (i in attributes)
-		element.setAttributeNS(null, i, attributes[i]);
-}
-
-/**
- * Handle mouse move event.
- */
-function handleMouseWheel(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	var delta;
-
-	if(evt.wheelDelta)
-		delta = evt.wheelDelta / 3600; // Chrome/Safari
-	else
-		delta = evt.detail / -90; // Mozilla
-
-	var z = 1 + delta; // Zoom factor: 0.9/1.1
-
-	var g = svgDoc.getElementById("viewport");
-
-	var p = getEventPoint(evt);
-
-	p = p.matrixTransform(g.getCTM().inverse());
-
-	// Compute new scale matrix in current mouse position
-	var k = root.createSVGMatrix().translate(p.x, p.y).scale(z).translate(-p.x, -p.y);
-
-        setCTM(g, g.getCTM().multiply(k));
-
-	stateTf = stateTf.multiply(k.inverse());
-}
-
-/**
- * Handle mouse move event.
- */
-function handleMouseMove(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	var g = svgDoc.getElementById("viewport");
-
-	if(state == 'pan') {
-		// Pan mode
-		var p = getEventPoint(evt).matrixTransform(stateTf);
-
-		setCTM(g, stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
-	} else if(state == 'move') {
-		// Move mode
-		var p = getEventPoint(evt).matrixTransform(g.getCTM().inverse());
-
-		setCTM(stateTarget, root.createSVGMatrix().translate(p.x - stateOrigin.x, p.y - stateOrigin.y).multiply(g.getCTM().inverse()).multiply(stateTarget.getCTM()));
-
-		stateOrigin = p;
-	}
-}
-
-/**
- * Handle click event.
- */
-function handleMouseDown(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	var g = svgDoc.getElementById("viewport");
-
-	if(true || evt.target.tagName == "svg") {
-		// Pan mode
-		state = 'pan';
-
-		stateTf = g.getCTM().inverse();
-
-		stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
-	} else {
-		// Move mode
-		state = 'move';
-
-		stateTarget = evt.target;
-
-		stateTf = g.getCTM().inverse();
-
-		stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
-	}
-}
-
-/**
- * Handle mouse button release event.
- */
-function handleMouseUp(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	if(state == 'pan' || state == 'move') {
-		// Quit pan mode
-		state = '';
-	}
-}
-
-]]></script>
-EOF
-}
-
-# Provides a map from fullname to shortname for cases where the
-# shortname is ambiguous.  The symlist has both the fullname and
-# shortname for all symbols, which is usually fine, but sometimes --
-# such as overloaded functions -- two different fullnames can map to
-# the same shortname.  In that case, we use the address of the
-# function to disambiguate the two.  This function fills in a map that
-# maps fullnames to modified shortnames in such cases.  If a fullname
-# is not present in the map, the 'normal' shortname provided by the
-# symlist is the appropriate one to use.
-sub FillFullnameToShortnameMap {
-  my $symbols = shift;
-  my $fullname_to_shortname_map = shift;
-  my $shortnames_seen_once = {};
-  my $shortnames_seen_more_than_once = {};
-
-  foreach my $symlist (values(%{$symbols})) {
-    # TODO(csilvers): deal with inlined symbols too.
-    my $shortname = $symlist->[0];
-    my $fullname = $symlist->[2];
-    if ($fullname !~ /<[0-9a-fA-F]+>$/) {  # fullname doesn't end in an address
-      next;       # the only collisions we care about are when addresses differ
-    }
-    if (defined($shortnames_seen_once->{$shortname}) &&
-        $shortnames_seen_once->{$shortname} ne $fullname) {
-      $shortnames_seen_more_than_once->{$shortname} = 1;
-    } else {
-      $shortnames_seen_once->{$shortname} = $fullname;
-    }
-  }
-
-  foreach my $symlist (values(%{$symbols})) {
-    my $shortname = $symlist->[0];
-    my $fullname = $symlist->[2];
-    # TODO(csilvers): take in a list of addresses we care about, and only
-    # store in the map if $symlist->[1] is in that list.  Saves space.
-    next if defined($fullname_to_shortname_map->{$fullname});
-    if (defined($shortnames_seen_more_than_once->{$shortname})) {
-      if ($fullname =~ /<0*([^>]*)>$/) {   # fullname has address at end of it
-        $fullname_to_shortname_map->{$fullname} = "$shortname\@$1";
-      }
-    }
-  }
-}
-
-# Return a small number that identifies the argument.
-# Multiple calls with the same argument will return the same number.
-# Calls with different arguments will return different numbers.
-sub ShortIdFor {
-  my $key = shift;
-  my $id = $main::uniqueid{$key};
-  if (!defined($id)) {
-    $id = keys(%main::uniqueid) + 1;
-    $main::uniqueid{$key} = $id;
-  }
-  return $id;
-}
-
-# Translate a stack of addresses into a stack of symbols
-sub TranslateStack {
-  my $symbols = shift;
-  my $fullname_to_shortname_map = shift;
-  my $k = shift;
-
-  my @addrs = split(/\n/, $k);
-  my @result = ();
-  for (my $i = 0; $i <= $#addrs; $i++) {
-    my $a = $addrs[$i];
-
-    # Skip large addresses since they sometimes show up as fake entries on RH9
-    if (length($a) > 8 && $a gt "7fffffffffffffff") {
-      next;
-    }
-
-    if ($main::opt_disasm || $main::opt_list) {
-      # We want just the address for the key
-      push(@result, $a);
-      next;
-    }
-
-    my $symlist = $symbols->{$a};
-    if (!defined($symlist)) {
-      $symlist = [$a, "", $a];
-    }
-
-    # We can have a sequence of symbols for a particular entry
-    # (more than one symbol in the case of inlining).  Callers
-    # come before callees in symlist, so walk backwards since
-    # the translated stack should contain callees before callers.
-    for (my $j = $#{$symlist}; $j >= 2; $j -= 3) {
-      my $func = $symlist->[$j-2];
-      my $fileline = $symlist->[$j-1];
-      my $fullfunc = $symlist->[$j];
-      if (defined($fullname_to_shortname_map->{$fullfunc})) {
-        $func = $fullname_to_shortname_map->{$fullfunc};
-      }
-      if ($j > 2) {
-        $func = "$func (inline)";
-      }
-
-      # Do not merge nodes corresponding to Callback::Run since that
-      # causes confusing cycles in dot display.  Instead, we synthesize
-      # a unique name for this frame per caller.
-      if ($func =~ m/Callback.*::Run$/) {
-        my $caller = ($i > 0) ? $addrs[$i-1] : 0;
-        $func = "Run#" . ShortIdFor($caller);
-      }
-
-      if ($main::opt_addresses) {
-        push(@result, "$a $func $fileline");
-      } elsif ($main::opt_lines) {
-        if ($func eq '??' && $fileline eq '??:0') {
-          push(@result, "$a");
-        } elsif (!$main::opt_show_addresses) {
-          push(@result, "$func $fileline");
-        } else {
-          push(@result, "$func $fileline ($a)");
-        }
-      } elsif ($main::opt_functions) {
-        if ($func eq '??') {
-          push(@result, "$a");
-        } elsif (!$main::opt_show_addresses) {
-          push(@result, $func);
-        } else {
-          push(@result, "$func ($a)");
-        }
-      } elsif ($main::opt_files) {
-        if ($fileline eq '??:0' || $fileline eq '') {
-          push(@result, "$a");
-        } else {
-          my $f = $fileline;
-          $f =~ s/:\d+$//;
-          push(@result, $f);
-        }
-      } else {
-        push(@result, $a);
-        last;  # Do not print inlined info
-      }
-    }
-  }
-
-  # print join(",", @addrs), " => ", join(",", @result), "\n";
-  return @result;
-}
-
-# Generate percent string for a number and a total
-sub Percent {
-  my $num = shift;
-  my $tot = shift;
-  if ($tot != 0) {
-    return sprintf("%.1f%%", $num * 100.0 / $tot);
-  } else {
-    return ($num == 0) ? "nan" : (($num > 0) ? "+inf" : "-inf");
-  }
-}
-
-# Generate pretty-printed form of number
-sub Unparse {
-  my $num = shift;
-  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
-    if ($main::opt_inuse_objects || $main::opt_alloc_objects) {
-      return sprintf("%d", $num);
-    } else {
-      if ($main::opt_show_bytes) {
-        return sprintf("%d", $num);
-      } else {
-        return sprintf("%.1f", $num / 1048576.0);
-      }
-    }
-  } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {
-    return sprintf("%.3f", $num / 1e9); # Convert nanoseconds to seconds
-  } else {
-    return sprintf("%d", $num);
-  }
-}
-
-# Alternate pretty-printed form: 0 maps to "."
-sub UnparseAlt {
-  my $num = shift;
-  if ($num == 0) {
-    return ".";
-  } else {
-    return Unparse($num);
-  }
-}
-
-# Alternate pretty-printed form: 0 maps to ""
-sub HtmlPrintNumber {
-  my $num = shift;
-  if ($num == 0) {
-    return "";
-  } else {
-    return Unparse($num);
-  }
-}
-
-# Return output units
-sub Units {
-  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
-    if ($main::opt_inuse_objects || $main::opt_alloc_objects) {
-      return "objects";
-    } else {
-      if ($main::opt_show_bytes) {
-        return "B";
-      } else {
-        return "MB";
-      }
-    }
-  } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {
-    return "seconds";
-  } else {
-    return "samples";
-  }
-}
-
-##### Profile manipulation code #####
-
-# Generate flattened profile:
-# If count is charged to stack [a,b,c,d], in generated profile,
-# it will be charged to [a]
-sub FlatProfile {
-  my $profile = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    if ($#addrs >= 0) {
-      AddEntry($result, $addrs[0], $count);
-    }
-  }
-  return $result;
-}
-
-# Generate cumulative profile:
-# If count is charged to stack [a,b,c,d], in generated profile,
-# it will be charged to [a], [b], [c], [d]
-sub CumulativeProfile {
-  my $profile = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    foreach my $a (@addrs) {
-      AddEntry($result, $a, $count);
-    }
-  }
-  return $result;
-}
-
-# If the second-youngest PC on the stack is always the same, returns
-# that pc.  Otherwise, returns undef.
-sub IsSecondPcAlwaysTheSame {
-  my $profile = shift;
-
-  my $second_pc = undef;
-  foreach my $k (keys(%{$profile})) {
-    my @addrs = split(/\n/, $k);
-    if ($#addrs < 1) {
-      return undef;
-    }
-    if (not defined $second_pc) {
-      $second_pc = $addrs[1];
-    } else {
-      if ($second_pc ne $addrs[1]) {
-        return undef;
-      }
-    }
-  }
-  return $second_pc;
-}
-
-sub ExtractSymbolLocationInlineStack {
-  my $symbols = shift;
-  my $address = shift;
-  my $stack = shift;
-  # 'addr2line' outputs "??:0" for unknown locations; we do the
-  # same to be consistent.
-  if (exists $symbols->{$address}) {
-    my @localinlinestack = @{$symbols->{$address}};
-    for (my $i = $#localinlinestack; $i > 0; $i-=3) {
-      my $file = $localinlinestack[$i-1];
-      my $fn = $localinlinestack[$i-2];
-      if ($file eq "?" || $file eq ":0") {
-        $file = "??:0";
-      }
-      my $suffix = "[inline]";
-      if ($i == 2) {
-        $suffix = "";
-      }
-      push (@$stack, $file.":".$fn.$suffix);
-    }
-  }
-  else {
-      push (@$stack, "??:0:unknown");
-  }
-}
-
-sub ExtractSymbolNameInlineStack {
-  my $symbols = shift;
-  my $address = shift;
-
-  my @stack = ();
-
-  if (exists $symbols->{$address}) {
-    my @localinlinestack = @{$symbols->{$address}};
-    for (my $i = $#localinlinestack; $i > 0; $i-=3) {
-      my $file = $localinlinestack[$i-1];
-      my $fn = $localinlinestack[$i-0];
-
-      if ($file eq "?" || $file eq ":0") {
-        $file = "??:0";
-      }
-      if ($fn eq '??') {
-        # If we can't get the symbol name, at least use the file information.
-        $fn = $file;
-      }
-      my $suffix = "[inline]";
-      if ($i == 2) {
-        $suffix = "";
-      }
-      push (@stack, $fn.$suffix);
-    }
-  }
-  else {
-    # If we can't get a symbol name, at least fill in the address.
-    push (@stack, $address);
-  }
-
-  return @stack;
-}
-
-sub ExtractSymbolLocation {
-  my $symbols = shift;
-  my $address = shift;
-  # 'addr2line' outputs "??:0" for unknown locations; we do the
-  # same to be consistent.
-  my $location = "??:0:unknown";
-  if (exists $symbols->{$address}) {
-    my $file = $symbols->{$address}->[1];
-    if ($file eq "?" || $file eq ":0") {
-      $file = "??:0"
-    }
-    $location = $file . ":" . $symbols->{$address}->[0];
-  }
-  return $location;
-}
-
-# Extracts a graph of calls.
-sub ExtractCalls {
-  my $symbols = shift;
-  my $profile = shift;
-  my $calls = {};
-  while( my ($stack_trace, $count) = each %$profile ) {
-    my @address = split(/\n/, $stack_trace);
-    my @stack = ();
-    ExtractSymbolLocationInlineStack($symbols, $address[0], \@stack);
-    for (my $i = 1; $i <= $#address; $i++) {
-      ExtractSymbolLocationInlineStack($symbols, $address[$i], \@stack);
-    }
-    AddEntry($calls, $stack[0], $count);
-    for (my $i = 1; $i < $#address; $i++) {
-      AddEntry($calls, "$stack[$i] -> $stack[$i-1]", $count);
-    }
-  }
-  return $calls;
-}
-
-sub PrintStacksForText {
-  my $symbols = shift;
-  my $profile = shift;
-
-  while (my ($stack_trace, $count) = each %$profile) {
-    my @address = split(/\n/, $stack_trace);
-    for (my $i = 0; $i <= $#address; $i++) {
-      $address[$i] = sprintf("(%s) %s", $address[$i], ExtractSymbolLocation($symbols, $address[$i]));
-    }
-    printf("%-8d %s\n\n", $count, join("\n         ", @address));
-  }
-}
-
-sub PrintCollapsedStacks {
-  my $symbols = shift;
-  my $profile = shift;
-
-  while (my ($stack_trace, $count) = each %$profile) {
-    my @address = split(/\n/, $stack_trace);
-    my @names = reverse ( map { ExtractSymbolNameInlineStack($symbols, $_) } @address );
-    printf("%s %d\n", join(";", @names), $count);
-  }
-}
-
-sub RemoveUninterestingFrames {
-  my $symbols = shift;
-  my $profile = shift;
-
-  # List of function names to skip
-  my %skip = ();
-  my $skip_regexp = 'NOMATCH';
-  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
-    foreach my $name ('calloc',
-                      'cfree',
-                      'malloc',
-                      'free',
-                      'memalign',
-                      'posix_memalign',
-                      'pvalloc',
-                      'valloc',
-                      'realloc',
-                      'tc_calloc',
-                      'tc_cfree',
-                      'tc_malloc',
-                      'tc_free',
-                      'tc_memalign',
-                      'tc_posix_memalign',
-                      'tc_pvalloc',
-                      'tc_valloc',
-                      'tc_realloc',
-                      'tc_new',
-                      'tc_delete',
-                      'tc_newarray',
-                      'tc_deletearray',
-                      'tc_new_nothrow',
-                      'tc_newarray_nothrow',
-                      'do_malloc',
-                      '::do_malloc',   # new name -- got moved to an unnamed ns
-                      '::do_malloc_or_cpp_alloc',
-                      'DoSampledAllocation',
-                      'simple_alloc::allocate',
-                      '__malloc_alloc_template::allocate',
-                      '__builtin_delete',
-                      '__builtin_new',
-                      '__builtin_vec_delete',
-                      '__builtin_vec_new',
-                      'operator new',
-                      'operator new[]',
-                      # The entry to our memory-allocation routines on OS X
-                      'malloc_zone_malloc',
-                      'malloc_zone_calloc',
-                      'malloc_zone_valloc',
-                      'malloc_zone_realloc',
-                      'malloc_zone_memalign',
-                      'malloc_zone_free',
-                      # These mark the beginning/end of our custom sections
-                      '__start_google_malloc',
-                      '__stop_google_malloc',
-                      '__start_malloc_hook',
-                      '__stop_malloc_hook') {
-      $skip{$name} = 1;
-      $skip{"_" . $name} = 1;   # Mach (OS X) adds a _ prefix to everything
-    }
-    # TODO: Remove TCMalloc once everything has been
-    # moved into the tcmalloc:: namespace and we have flushed
-    # old code out of the system.
-    $skip_regexp = "TCMalloc|^tcmalloc::";
-  } elsif ($main::profile_type eq 'contention') {
-    foreach my $vname ('base::RecordLockProfileData',
-                       'base::SubmitMutexProfileData',
-                       'base::SubmitSpinLockProfileData',
-                       'Mutex::Unlock',
-                       'Mutex::UnlockSlow',
-                       'Mutex::ReaderUnlock',
-                       'MutexLock::~MutexLock',
-                       'SpinLock::Unlock',
-                       'SpinLock::SlowUnlock',
-                       'SpinLockHolder::~SpinLockHolder') {
-      $skip{$vname} = 1;
-    }
-  } elsif ($main::profile_type eq 'cpu' && !$main::opt_no_auto_signal_frames) {
-    # Drop signal handlers used for CPU profile collection
-    # TODO(dpeng): this should not be necessary; it's taken
-    # care of by the general 2nd-pc mechanism below.
-    foreach my $name ('ProfileData::Add',           # historical
-                      'ProfileData::prof_handler',  # historical
-                      'CpuProfiler::prof_handler',
-                      '__FRAME_END__',
-                      '__pthread_sighandler',
-                      '__restore') {
-      $skip{$name} = 1;
-    }
-  } else {
-    # Nothing skipped for unknown types
-  }
-
-  if ($main::profile_type eq 'cpu') {
-    # If all the second-youngest program counters are the same,
-    # this STRONGLY suggests that it is an artifact of measurement,
-    # i.e., stack frames pushed by the CPU profiler signal handler.
-    # Hence, we delete them.
-    # (The topmost PC is read from the signal structure, not from
-    # the stack, so it does not get involved.)
-    while (my $second_pc = IsSecondPcAlwaysTheSame($profile)) {
-      my $result = {};
-      my $func = '';
-      if (exists($symbols->{$second_pc})) {
-        $second_pc = $symbols->{$second_pc}->[0];
-      }
-      if ($main::opt_no_auto_signal_frames) {
-        print STDERR "All second stack frames are same: `$second_pc'.\nMight be stack trace capturing bug.\n";
-        last;
-      }
-      print STDERR "Removing $second_pc from all stack traces.\n";
-      foreach my $k (keys(%{$profile})) {
-        my $count = $profile->{$k};
-        my @addrs = split(/\n/, $k);
-        my $topaddr = POSIX::strtoul($addrs[0], 16);
-        splice @addrs, 1, 1;
-        if ($#addrs > 1) {
-          my $subtopaddr = POSIX::strtoul($addrs[1], 16);
-          if ($subtopaddr + 1 == $topaddr) {
-            splice @addrs, 1, 1;
-          }
-        }
-        my $reduced_path = join("\n", @addrs);
-        AddEntry($result, $reduced_path, $count);
-      }
-      $profile = $result;
-    }
-  }
-
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    my @path = ();
-    foreach my $a (@addrs) {
-      if (exists($symbols->{$a})) {
-        my $func = $symbols->{$a}->[0];
-        if ($skip{$func} || ($func =~ m/$skip_regexp/)) {
-          next;
-        }
-      }
-      push(@path, $a);
-    }
-    my $reduced_path = join("\n", @path);
-    AddEntry($result, $reduced_path, $count);
-  }
-  return $result;
-}
-
-# Reduce profile to granularity given by user
-sub ReduceProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $result = {};
-  my $fullname_to_shortname_map = {};
-  FillFullnameToShortnameMap($symbols, $fullname_to_shortname_map);
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @translated = TranslateStack($symbols, $fullname_to_shortname_map, $k);
-    my @path = ();
-    my %seen = ();
-    $seen{''} = 1;      # So that empty keys are skipped
-    foreach my $e (@translated) {
-      # To avoid double-counting due to recursion, skip a stack-trace
-      # entry if it has already been seen
-      if (!$seen{$e}) {
-        $seen{$e} = 1;
-        push(@path, $e);
-      }
-    }
-    my $reduced_path = join("\n", @path);
-    AddEntry($result, $reduced_path, $count);
-  }
-  return $result;
-}
-
-# Does the specified symbol array match the regexp?
-sub SymbolMatches {
-  my $sym = shift;
-  my $re = shift;
-  if (defined($sym)) {
-    for (my $i = 0; $i < $#{$sym}; $i += 3) {
-      if ($sym->[$i] =~ m/$re/ || $sym->[$i+1] =~ m/$re/) {
-        return 1;
-      }
-    }
-  }
-  return 0;
-}
-
-# Focus only on paths involving specified regexps
-sub FocusProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $focus = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    foreach my $a (@addrs) {
-      # Reply if it matches either the address/shortname/fileline
-      if (($a =~ m/$focus/) || SymbolMatches($symbols->{$a}, $focus)) {
-        AddEntry($result, $k, $count);
-        last;
-      }
-    }
-  }
-  return $result;
-}
-
-# Focus only on paths not involving specified regexps
-sub IgnoreProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $ignore = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    my $matched = 0;
-    foreach my $a (@addrs) {
-      # Reply if it matches either the address/shortname/fileline
-      if (($a =~ m/$ignore/) || SymbolMatches($symbols->{$a}, $ignore)) {
-        $matched = 1;
-        last;
-      }
-    }
-    if (!$matched) {
-      AddEntry($result, $k, $count);
-    }
-  }
-  return $result;
-}
-
-# Get total count in profile
-sub TotalProfile {
-  my $profile = shift;
-  my $result = 0;
-  foreach my $k (keys(%{$profile})) {
-    $result += $profile->{$k};
-  }
-  return $result;
-}
-
-# Add A to B
-sub AddProfile {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  # add all keys in A
-  foreach my $k (keys(%{$A})) {
-    my $v = $A->{$k};
-    AddEntry($R, $k, $v);
-  }
-  # add all keys in B
-  foreach my $k (keys(%{$B})) {
-    my $v = $B->{$k};
-    AddEntry($R, $k, $v);
-  }
-  return $R;
-}
-
-# Merges symbol maps
-sub MergeSymbols {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  foreach my $k (keys(%{$A})) {
-    $R->{$k} = $A->{$k};
-  }
-  if (defined($B)) {
-    foreach my $k (keys(%{$B})) {
-      $R->{$k} = $B->{$k};
-    }
-  }
-  return $R;
-}
-
-
-# Add A to B
-sub AddPcs {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  # add all keys in A
-  foreach my $k (keys(%{$A})) {
-    $R->{$k} = 1
-  }
-  # add all keys in B
-  foreach my $k (keys(%{$B})) {
-    $R->{$k} = 1
-  }
-  return $R;
-}
-
-# Subtract B from A
-sub SubtractProfile {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  foreach my $k (keys(%{$A})) {
-    my $v = $A->{$k} - GetEntry($B, $k);
-    if ($v < 0 && $main::opt_drop_negative) {
-      $v = 0;
-    }
-    AddEntry($R, $k, $v);
-  }
-  if (!$main::opt_drop_negative) {
-    # Take care of when subtracted profile has more entries
-    foreach my $k (keys(%{$B})) {
-      if (!exists($A->{$k})) {
-        AddEntry($R, $k, 0 - $B->{$k});
-      }
-    }
-  }
-  return $R;
-}
-
-# Get entry from profile; zero if not present
-sub GetEntry {
-  my $profile = shift;
-  my $k = shift;
-  if (exists($profile->{$k})) {
-    return $profile->{$k};
-  } else {
-    return 0;
-  }
-}
-
-# Add entry to specified profile
-sub AddEntry {
-  my $profile = shift;
-  my $k = shift;
-  my $n = shift;
-  if (!exists($profile->{$k})) {
-    $profile->{$k} = 0;
-  }
-  $profile->{$k} += $n;
-}
-
-# Add a stack of entries to specified profile, and add them to the $pcs
-# list.
-sub AddEntries {
-  my $profile = shift;
-  my $pcs = shift;
-  my $stack = shift;
-  my $count = shift;
-  my @k = ();
-
-  foreach my $e (split(/\s+/, $stack)) {
-    my $pc = HexExtend($e);
-    $pcs->{$pc} = 1;
-    push @k, $pc;
-  }
-  AddEntry($profile, (join "\n", @k), $count);
-}
-
-##### Code to profile a server dynamically #####
-
-sub CheckSymbolPage {
-  my $url = SymbolPageURL();
-  my $command = ShellEscape(@URL_FETCHER, $url);
-  open(SYMBOL, "$command |") or error($command);
-  my $line = <SYMBOL>;
-  $line =~ s/\r//g;         # turn windows-looking lines into unix-looking lines
-  close(SYMBOL);
-  unless (defined($line)) {
-    error("$url doesn't exist\n");
-  }
-
-  if ($line =~ /^num_symbols:\s+(\d+)$/) {
-    if ($1 == 0) {
-      error("Stripped binary. No symbols available.\n");
-    }
-  } else {
-    error("Failed to get the number of symbols from $url\n");
-  }
-}
-
-sub IsProfileURL {
-  my $profile_name = shift;
-  if (-f $profile_name) {
-    printf STDERR "Using local file $profile_name.\n";
-    return 0;
-  }
-  return 1;
-}
-
-sub ParseProfileURL {
-  my $profile_name = shift;
-
-  if (!defined($profile_name) || $profile_name eq "") {
-    return ();
-  }
-
-  # Split profile URL - matches all non-empty strings, so no test.
-  $profile_name =~ m,^(https?://)?([^/]+)(.*?)(/|$PROFILES)?$,;
-
-  my $proto = $1 || "http://";
-  my $hostport = $2;
-  my $prefix = $3;
-  my $profile = $4 || "/";
-
-  my $host = $hostport;
-  $host =~ s/:.*//;
-
-  my $baseurl = "$proto$hostport$prefix";
-  return ($host, $baseurl, $profile);
-}
-
-# We fetch symbols from the first profile argument.
-sub SymbolPageURL {
-  my ($host, $baseURL, $path) = ParseProfileURL($main::pfile_args[0]);
-  return "$baseURL$SYMBOL_PAGE";
-}
-
-sub FetchProgramName() {
-  my ($host, $baseURL, $path) = ParseProfileURL($main::pfile_args[0]);
-  my $url = "$baseURL$PROGRAM_NAME_PAGE";
-  my $command_line = ShellEscape(@URL_FETCHER, $url);
-  open(CMDLINE, "$command_line |") or error($command_line);
-  my $cmdline = <CMDLINE>;
-  $cmdline =~ s/\r//g;   # turn windows-looking lines into unix-looking lines
-  close(CMDLINE);
-  error("Failed to get program name from $url\n") unless defined($cmdline);
-  $cmdline =~ s/\x00.+//;  # Remove argv[1] and latters.
-  $cmdline =~ s!\n!!g;  # Remove LFs.
-  return $cmdline;
-}
-
-# Gee, curl's -L (--location) option isn't reliable at least
-# with its 7.12.3 version.  Curl will forget to post data if
-# there is a redirection.  This function is a workaround for
-# curl.  Redirection happens on borg hosts.
-sub ResolveRedirectionForCurl {
-  my $url = shift;
-  my $command_line = ShellEscape(@URL_FETCHER, "--head", $url);
-  open(CMDLINE, "$command_line |") or error($command_line);
-  while (<CMDLINE>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    if (/^Location: (.*)/) {
-      $url = $1;
-    }
-  }
-  close(CMDLINE);
-  return $url;
-}
-
-# Add a timeout flat to URL_FETCHER.  Returns a new list.
-sub AddFetchTimeout {
-  my $timeout = shift;
-  my @fetcher = @_;
-  if (defined($timeout)) {
-    if (join(" ", @fetcher) =~ m/\bcurl -s/) {
-      push(@fetcher, "--max-time", sprintf("%d", $timeout));
-    } elsif (join(" ", @fetcher) =~ m/\brpcget\b/) {
-      push(@fetcher, sprintf("--deadline=%d", $timeout));
-    }
-  }
-  return @fetcher;
-}
-
-# Reads a symbol map from the file handle name given as $1, returning
-# the resulting symbol map.  Also processes variables relating to symbols.
-# Currently, the only variable processed is 'binary=<value>' which updates
-# $main::prog to have the correct program name.
-sub ReadSymbols {
-  my $in = shift;
-  my $map = {};
-  while (<$in>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    # Removes all the leading zeroes from the symbols, see comment below.
-    if (m/^0x0*([0-9a-f]+)\s+(.+)/) {
-      $map->{$1} = $2;
-    } elsif (m/^---/) {
-      last;
-    } elsif (m/^([a-z][^=]*)=(.*)$/ ) {
-      my ($variable, $value) = ($1, $2);
-      for ($variable, $value) {
-        s/^\s+//;
-        s/\s+$//;
-      }
-      if ($variable eq "binary") {
-        if ($main::prog ne $UNKNOWN_BINARY && $main::prog ne $value) {
-          printf STDERR ("Warning: Mismatched binary name '%s', using '%s'.\n",
-                         $main::prog, $value);
-        }
-        $main::prog = $value;
-      } else {
-        printf STDERR ("Ignoring unknown variable in symbols list: " .
-            "'%s' = '%s'\n", $variable, $value);
-      }
-    }
-  }
-  return $map;
-}
-
-# Fetches and processes symbols to prepare them for use in the profile output
-# code.  If the optional 'symbol_map' arg is not given, fetches symbols from
-# $SYMBOL_PAGE for all PC values found in profile.  Otherwise, the raw symbols
-# are assumed to have already been fetched into 'symbol_map' and are simply
-# extracted and processed.
-sub FetchSymbols {
-  my $pcset = shift;
-  my $symbol_map = shift;
-
-  my %seen = ();
-  my @pcs = grep { !$seen{$_}++ } keys(%$pcset);  # uniq
-
-  if (!defined($symbol_map)) {
-    my $post_data = join("+", sort((map {"0x" . "$_"} @pcs)));
-
-    open(POSTFILE, ">$main::tmpfile_sym");
-    print POSTFILE $post_data;
-    close(POSTFILE);
-
-    my $url = SymbolPageURL();
-
-    my $command_line;
-    if (join(" ", @URL_FETCHER) =~ m/\bcurl -s/) {
-      $url = ResolveRedirectionForCurl($url);
-      $command_line = ShellEscape(@URL_FETCHER, "-d", "\@$main::tmpfile_sym",
-                                  $url);
-    } else {
-      $command_line = (ShellEscape(@URL_FETCHER, "--post", $url)
-                       . " < " . ShellEscape($main::tmpfile_sym));
-    }
-    # We use c++filt in case $SYMBOL_PAGE gives us mangled symbols.
-    my $escaped_cppfilt = ShellEscape($obj_tool_map{"c++filt"});
-    open(SYMBOL, "$command_line | $escaped_cppfilt |") or error($command_line);
-    $symbol_map = ReadSymbols(*SYMBOL{IO});
-    close(SYMBOL);
-  }
-
-  my $symbols = {};
-  foreach my $pc (@pcs) {
-    my $fullname;
-    # For 64 bits binaries, symbols are extracted with 8 leading zeroes.
-    # Then /symbol reads the long symbols in as uint64, and outputs
-    # the result with a "0x%08llx" format which get rid of the zeroes.
-    # By removing all the leading zeroes in both $pc and the symbols from
-    # /symbol, the symbols match and are retrievable from the map.
-    my $shortpc = $pc;
-    $shortpc =~ s/^0*//;
-    # Each line may have a list of names, which includes the function
-    # and also other functions it has inlined.  They are separated (in
-    # PrintSymbolizedProfile), by --, which is illegal in function names.
-    my $fullnames;
-    if (defined($symbol_map->{$shortpc})) {
-      $fullnames = $symbol_map->{$shortpc};
-    } else {
-      $fullnames = "0x" . $pc;  # Just use addresses
-    }
-    my $sym = [];
-    $symbols->{$pc} = $sym;
-    foreach my $fullname (split("--", $fullnames)) {
-      my $name = ShortFunctionName($fullname);
-      push(@{$sym}, $name, "?", $fullname);
-    }
-  }
-  return $symbols;
-}
-
-sub BaseName {
-  my $file_name = shift;
-  $file_name =~ s!^.*/!!;  # Remove directory name
-  return $file_name;
-}
-
-sub MakeProfileBaseName {
-  my ($binary_name, $profile_name) = @_;
-  my ($host, $baseURL, $path) = ParseProfileURL($profile_name);
-  my $binary_shortname = BaseName($binary_name);
-  return sprintf("%s.%s.%s",
-                 $binary_shortname, $main::op_time, $host);
-}
-
-sub FetchDynamicProfile {
-  my $binary_name = shift;
-  my $profile_name = shift;
-  my $fetch_name_only = shift;
-  my $encourage_patience = shift;
-
-  if (!IsProfileURL($profile_name)) {
-    return $profile_name;
-  } else {
-    my ($host, $baseURL, $path) = ParseProfileURL($profile_name);
-    if ($path eq "" || $path eq "/") {
-      # Missing type specifier defaults to cpu-profile
-      $path = $PROFILE_PAGE;
-    }
-
-    my $profile_file = MakeProfileBaseName($binary_name, $profile_name);
-
-    my $url = "$baseURL$path";
-    my $fetch_timeout = undef;
-    if ($path =~ m/$PROFILE_PAGE|$PMUPROFILE_PAGE/) {
-      if ($path =~ m/[?]/) {
-        $url .= "&";
-      } else {
-        $url .= "?";
-      }
-      $url .= sprintf("seconds=%d", $main::opt_seconds);
-      $fetch_timeout = $main::opt_seconds * 1.01 + 60;
-    } else {
-      # For non-CPU profiles, we add a type-extension to
-      # the target profile file name.
-      my $suffix = $path;
-      $suffix =~ s,/,.,g;
-      $profile_file .= $suffix;
-    }
-
-    my $profile_dir = $ENV{"PPROF_TMPDIR"} || ($ENV{HOME} . "/pprof");
-    if (! -d $profile_dir) {
-      mkdir($profile_dir)
-          || die("Unable to create profile directory $profile_dir: $!\n");
-    }
-    my $tmp_profile = "$profile_dir/.tmp.$profile_file";
-    my $real_profile = "$profile_dir/$profile_file";
-
-    if ($fetch_name_only > 0) {
-      return $real_profile;
-    }
-
-    my @fetcher = AddFetchTimeout($fetch_timeout, @URL_FETCHER);
-    my $cmd = ShellEscape(@fetcher, $url) . " > " . ShellEscape($tmp_profile);
-    if ($path =~ m/$PROFILE_PAGE|$PMUPROFILE_PAGE|$CENSUSPROFILE_PAGE/){
-      print STDERR "Gathering CPU profile from $url for $main::opt_seconds seconds to\n  ${real_profile}\n";
-      if ($encourage_patience) {
-        print STDERR "Be patient...\n";
-      }
-    } else {
-      print STDERR "Fetching $path profile from $url to\n  ${real_profile}\n";
-    }
-
-    (system($cmd) == 0) || error("Failed to get profile: $cmd: $!\n");
-    (system("mv", $tmp_profile, $real_profile) == 0) || error("Unable to rename profile\n");
-    print STDERR "Wrote profile to $real_profile\n";
-    $main::collected_profile = $real_profile;
-    return $main::collected_profile;
-  }
-}
-
-# Collect profiles in parallel
-sub FetchDynamicProfiles {
-  my $items = scalar(@main::pfile_args);
-  my $levels = log($items) / log(2);
-
-  if ($items == 1) {
-    $main::profile_files[0] = FetchDynamicProfile($main::prog, $main::pfile_args[0], 0, 1);
-  } else {
-    # math rounding issues
-    if ((2 ** $levels) < $items) {
-     $levels++;
-    }
-    my $count = scalar(@main::pfile_args);
-    for (my $i = 0; $i < $count; $i++) {
-      $main::profile_files[$i] = FetchDynamicProfile($main::prog, $main::pfile_args[$i], 1, 0);
-    }
-    print STDERR "Fetching $count profiles, Be patient...\n";
-    FetchDynamicProfilesRecurse($levels, 0, 0);
-    $main::collected_profile = join(" \\\n    ", @main::profile_files);
-  }
-}
-
-# Recursively fork a process to get enough processes
-# collecting profiles
-sub FetchDynamicProfilesRecurse {
-  my $maxlevel = shift;
-  my $level = shift;
-  my $position = shift;
-
-  if (my $pid = fork()) {
-    $position = 0 | ($position << 1);
-    TryCollectProfile($maxlevel, $level, $position);
-    wait;
-  } else {
-    $position = 1 | ($position << 1);
-    TryCollectProfile($maxlevel, $level, $position);
-    cleanup();
-    exit(0);
-  }
-}
-
-# Collect a single profile
-sub TryCollectProfile {
-  my $maxlevel = shift;
-  my $level = shift;
-  my $position = shift;
-
-  if ($level >= ($maxlevel - 1)) {
-    if ($position < scalar(@main::pfile_args)) {
-      FetchDynamicProfile($main::prog, $main::pfile_args[$position], 0, 0);
-    }
-  } else {
-    FetchDynamicProfilesRecurse($maxlevel, $level+1, $position);
-  }
-}
-
-##### Parsing code #####
-
-# Provide a small streaming-read module to handle very large
-# cpu-profile files.  Stream in chunks along a sliding window.
-# Provides an interface to get one 'slot', correctly handling
-# endian-ness differences.  A slot is one 32-bit or 64-bit word
-# (depending on the input profile).  We tell endianness and bit-size
-# for the profile by looking at the first 8 bytes: in cpu profiles,
-# the second slot is always 3 (we'll accept anything that's not 0).
-BEGIN {
-  package CpuProfileStream;
-
-  sub new {
-    my ($class, $file, $fname) = @_;
-    my $self = { file        => $file,
-                 base        => 0,
-                 stride      => 512 * 1024,   # must be a multiple of bitsize/8
-                 slots       => [],
-                 unpack_code => "",           # N for big-endian, V for little
-                 perl_is_64bit => 1,          # matters if profile is 64-bit
-    };
-    bless $self, $class;
-    # Let unittests adjust the stride
-    if ($main::opt_test_stride > 0) {
-      $self->{stride} = $main::opt_test_stride;
-    }
-    # Read the first two slots to figure out bitsize and endianness.
-    my $slots = $self->{slots};
-    my $str;
-    read($self->{file}, $str, 8);
-    # Set the global $address_length based on what we see here.
-    # 8 is 32-bit (8 hexadecimal chars); 16 is 64-bit (16 hexadecimal chars).
-    $address_length = ($str eq (chr(0)x8)) ? 16 : 8;
-    if ($address_length == 8) {
-      if (substr($str, 6, 2) eq chr(0)x2) {
-        $self->{unpack_code} = 'V';  # Little-endian.
-      } elsif (substr($str, 4, 2) eq chr(0)x2) {
-        $self->{unpack_code} = 'N';  # Big-endian
-      } else {
-        ::error("$fname: header size >= 2**16\n");
-      }
-      @$slots = unpack($self->{unpack_code} . "*", $str);
-    } else {
-      # If we're a 64-bit profile, check if we're a 64-bit-capable
-      # perl.  Otherwise, each slot will be represented as a float
-      # instead of an int64, losing precision and making all the
-      # 64-bit addresses wrong.  We won't complain yet, but will
-      # later if we ever see a value that doesn't fit in 32 bits.
-      my $has_q = 0;
-      eval { $has_q = pack("Q", "1") ? 1 : 1; };
-      if (!$has_q) {
-        $self->{perl_is_64bit} = 0;
-      }
-      read($self->{file}, $str, 8);
-      if (substr($str, 4, 4) eq chr(0)x4) {
-        # We'd love to use 'Q', but it's a) not universal, b) not endian-proof.
-        $self->{unpack_code} = 'V';  # Little-endian.
-      } elsif (substr($str, 0, 4) eq chr(0)x4) {
-        $self->{unpack_code} = 'N';  # Big-endian
-      } else {
-        ::error("$fname: header size >= 2**32\n");
-      }
-      my @pair = unpack($self->{unpack_code} . "*", $str);
-      # Since we know one of the pair is 0, it's fine to just add them.
-      @$slots = (0, $pair[0] + $pair[1]);
-    }
-    return $self;
-  }
-
-  # Load more data when we access slots->get(X) which is not yet in memory.
-  sub overflow {
-    my ($self) = @_;
-    my $slots = $self->{slots};
-    $self->{base} += $#$slots + 1;   # skip over data we're replacing
-    my $str;
-    read($self->{file}, $str, $self->{stride});
-    if ($address_length == 8) {      # the 32-bit case
-      # This is the easy case: unpack provides 32-bit unpacking primitives.
-      @$slots = unpack($self->{unpack_code} . "*", $str);
-    } else {
-      # We need to unpack 32 bits at a time and combine.
-      my @b32_values = unpack($self->{unpack_code} . "*", $str);
-      my @b64_values = ();
-      for (my $i = 0; $i < $#b32_values; $i += 2) {
-        # TODO(csilvers): if this is a 32-bit perl, the math below
-        #    could end up in a too-large int, which perl will promote
-        #    to a double, losing necessary precision.  Deal with that.
-        #    Right now, we just die.
-        my ($lo, $hi) = ($b32_values[$i], $b32_values[$i+1]);
-        if ($self->{unpack_code} eq 'N') {    # big-endian
-          ($lo, $hi) = ($hi, $lo);
-        }
-        my $value = $lo + $hi * (2**32);
-        if (!$self->{perl_is_64bit} &&   # check value is exactly represented
-            (($value % (2**32)) != $lo || int($value / (2**32)) != $hi)) {
-          ::error("Need a 64-bit perl to process this 64-bit profile.\n");
-        }
-        push(@b64_values, $value);
-      }
-      @$slots = @b64_values;
-    }
-  }
-
-  # Access the i-th long in the file (logically), or -1 at EOF.
-  sub get {
-    my ($self, $idx) = @_;
-    my $slots = $self->{slots};
-    while ($#$slots >= 0) {
-      if ($idx < $self->{base}) {
-        # The only time we expect a reference to $slots[$i - something]
-        # after referencing $slots[$i] is reading the very first header.
-        # Since $stride > |header|, that shouldn't cause any lookback
-        # errors.  And everything after the header is sequential.
-        print STDERR "Unexpected look-back reading CPU profile";
-        return -1;   # shrug, don't know what better to return
-      } elsif ($idx > $self->{base} + $#$slots) {
-        $self->overflow();
-      } else {
-        return $slots->[$idx - $self->{base}];
-      }
-    }
-    # If we get here, $slots is [], which means we've reached EOF
-    return -1;  # unique since slots is supposed to hold unsigned numbers
-  }
-}
-
-# Reads the top, 'header' section of a profile, and returns the last
-# line of the header, commonly called a 'header line'.  The header
-# section of a profile consists of zero or more 'command' lines that
-# are instructions to pprof, which pprof executes when reading the
-# header.  All 'command' lines start with a %.  After the command
-# lines is the 'header line', which is a profile-specific line that
-# indicates what type of profile it is, and perhaps other global
-# information about the profile.  For instance, here's a header line
-# for a heap profile:
-#   heap profile:     53:    38236 [  5525:  1284029] @ heapprofile
-# For historical reasons, the CPU profile does not contain a text-
-# readable header line.  If the profile looks like a CPU profile,
-# this function returns "".  If no header line could be found, this
-# function returns undef.
-#
-# The following commands are recognized:
-#   %warn -- emit the rest of this line to stderr, prefixed by 'WARNING:'
-#
-# The input file should be in binmode.
-sub ReadProfileHeader {
-  local *PROFILE = shift;
-  my $firstchar = "";
-  my $line = "";
-  read(PROFILE, $firstchar, 1);
-  seek(PROFILE, -1, 1);                    # unread the firstchar
-  if ($firstchar !~ /[[:print:]]/) {       # is not a text character
-    return "";
-  }
-  while (defined($line = <PROFILE>)) {
-    $line =~ s/\r//g;   # turn windows-looking lines into unix-looking lines
-    if ($line =~ /^%warn\s+(.*)/) {        # 'warn' command
-      # Note this matches both '%warn blah\n' and '%warn\n'.
-      print STDERR "WARNING: $1\n";        # print the rest of the line
-    } elsif ($line =~ /^%/) {
-      print STDERR "Ignoring unknown command from profile header: $line";
-    } else {
-      # End of commands, must be the header line.
-      return $line;
-    }
-  }
-  return undef;     # got to EOF without seeing a header line
-}
-
-sub IsSymbolizedProfileFile {
-  my $file_name = shift;
-  if (!(-e $file_name) || !(-r $file_name)) {
-    return 0;
-  }
-  # Check if the file contains a symbol-section marker.
-  open(TFILE, "<$file_name");
-  binmode TFILE;
-  my $firstline = ReadProfileHeader(*TFILE);
-  close(TFILE);
-  if (!$firstline) {
-    return 0;
-  }
-  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $symbol_marker = $&;
-  return $firstline =~ /^--- *$symbol_marker/;
-}
-
-# Parse profile generated by common/profiler.cc and return a reference
-# to a map:
-#      $result->{version}     Version number of profile file
-#      $result->{period}      Sampling period (in microseconds)
-#      $result->{profile}     Profile object
-#      $result->{map}         Memory map info from profile
-#      $result->{pcs}         Hash of all PC values seen, key is hex address
-sub ReadProfile {
-  my $prog = shift;
-  my $fname = shift;
-  my $result;            # return value
-
-  $CONTENTION_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $contention_marker = $&;
-  $GROWTH_PAGE  =~ m,[^/]+$,;    # matches everything after the last slash
-  my $growth_marker = $&;
-  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $symbol_marker = $&;
-  $PROFILE_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $profile_marker = $&;
-
-  # Look at first line to see if it is a heap or a CPU profile.
-  # CPU profile may start with no header at all, and just binary data
-  # (starting with \0\0\0\0) -- in that case, don't try to read the
-  # whole firstline, since it may be gigabytes(!) of data.
-  open(PROFILE, "<$fname") || error("$fname: $!\n");
-  binmode PROFILE;      # New perls do UTF-8 processing
-  my $header = ReadProfileHeader(*PROFILE);
-  if (!defined($header)) {   # means "at EOF"
-    error("Profile is empty.\n");
-  }
-
-  my $symbols;
-  if ($header =~ m/^--- *$symbol_marker/o) {
-    # Verify that the user asked for a symbolized profile
-    if (!$main::use_symbolized_profile) {
-      # we have both a binary and symbolized profiles, abort
-      error("FATAL ERROR: Symbolized profile\n   $fname\ncannot be used with " .
-            "a binary arg. Try again without passing\n   $prog\n");
-    }
-    # Read the symbol section of the symbolized profile file.
-    $symbols = ReadSymbols(*PROFILE{IO});
-    # Read the next line to get the header for the remaining profile.
-    $header = ReadProfileHeader(*PROFILE) || "";
-  }
-
-  $main::profile_type = '';
-  if ($header =~ m/^heap profile:.*$growth_marker/o) {
-    $main::profile_type = 'growth';
-    $result =  ReadHeapProfile($prog, *PROFILE, $header);
-  } elsif ($header =~ m/^heap profile:/) {
-    $main::profile_type = 'heap';
-    $result =  ReadHeapProfile($prog, *PROFILE, $header);
-  } elsif ($header =~ m/^--- *$contention_marker/o) {
-    $main::profile_type = 'contention';
-    $result = ReadSynchProfile($prog, *PROFILE);
-  } elsif ($header =~ m/^--- *Stacks:/) {
-    print STDERR
-      "Old format contention profile: mistakenly reports " .
-      "condition variable signals as lock contentions.\n";
-    $main::profile_type = 'contention';
-    $result = ReadSynchProfile($prog, *PROFILE);
-  } elsif ($header =~ m/^--- *$profile_marker/) {
-    # the binary cpu profile data starts immediately after this line
-    $main::profile_type = 'cpu';
-    $result = ReadCPUProfile($prog, $fname, *PROFILE);
-  } else {
-    if (defined($symbols)) {
-      # a symbolized profile contains a format we don't recognize, bail out
-      error("$fname: Cannot recognize profile section after symbols.\n");
-    }
-    # no ascii header present -- must be a CPU profile
-    $main::profile_type = 'cpu';
-    $result = ReadCPUProfile($prog, $fname, *PROFILE);
-  }
-
-  close(PROFILE);
-
-  # if we got symbols along with the profile, return those as well
-  if (defined($symbols)) {
-    $result->{symbols} = $symbols;
-  }
-
-  return $result;
-}
-
-# Subtract one from caller pc so we map back to call instr.
-# However, don't do this if we're reading a symbolized profile
-# file, in which case the subtract-one was done when the file
-# was written.
-#
-# We apply the same logic to all readers, though ReadCPUProfile uses an
-# independent implementation.
-sub FixCallerAddresses {
-  my $stack = shift;
-  if ($main::use_symbolized_profile) {
-    return $stack;
-  } else {
-    $stack =~ /(\s)/;
-    my $delimiter = $1;
-    my @addrs = split(' ', $stack);
-    my @fixedaddrs;
-    $#fixedaddrs = $#addrs;
-    if ($#addrs >= 0) {
-      $fixedaddrs[0] = $addrs[0];
-    }
-    for (my $i = 1; $i <= $#addrs; $i++) {
-      $fixedaddrs[$i] = AddressSub($addrs[$i], "0x1");
-    }
-    return join $delimiter, @fixedaddrs;
-  }
-}
-
-# CPU profile reader
-sub ReadCPUProfile {
-  my $prog = shift;
-  my $fname = shift;       # just used for logging
-  local *PROFILE = shift;
-  my $version;
-  my $period;
-  my $i;
-  my $profile = {};
-  my $pcs = {};
-
-  # Parse string into array of slots.
-  my $slots = CpuProfileStream->new(*PROFILE, $fname);
-
-  # Read header.  The current header version is a 5-element structure
-  # containing:
-  #   0: header count (always 0)
-  #   1: header "words" (after this one: 3)
-  #   2: format version (0)
-  #   3: sampling period (usec)
-  #   4: unused padding (always 0)
-  if ($slots->get(0) != 0 ) {
-    error("$fname: not a profile file, or old format profile file\n");
-  }
-  $i = 2 + $slots->get(1);
-  $version = $slots->get(2);
-  $period = $slots->get(3);
-  # Do some sanity checking on these header values.
-  if ($version > (2**32) || $period > (2**32) || $i > (2**32) || $i < 5) {
-    error("$fname: not a profile file, or corrupted profile file\n");
-  }
-
-  # Parse profile
-  while ($slots->get($i) != -1) {
-    my $n = $slots->get($i++);
-    my $d = $slots->get($i++);
-    if ($d > (2**16)) {  # TODO(csilvers): what's a reasonable max-stack-depth?
-      my $addr = sprintf("0%o", $i * ($address_length == 8 ? 4 : 8));
-      print STDERR "At index $i (address $addr):\n";
-      error("$fname: stack trace depth >= 2**32\n");
-    }
-    if ($slots->get($i) == 0) {
-      # End of profile data marker
-      $i += $d;
-      last;
-    }
-
-    # Make key out of the stack entries
-    my @k = ();
-    for (my $j = 0; $j < $d; $j++) {
-      my $pc = $slots->get($i+$j);
-      # Subtract one from caller pc so we map back to call instr.
-      # However, don't do this if we're reading a symbolized profile
-      # file, in which case the subtract-one was done when the file
-      # was written.
-      if ($j > 0 && !$main::use_symbolized_profile) {
-        $pc--;
-      }
-      $pc = sprintf("%0*x", $address_length, $pc);
-      $pcs->{$pc} = 1;
-      push @k, $pc;
-    }
-
-    AddEntry($profile, (join "\n", @k), $n);
-    $i += $d;
-  }
-
-  # Parse map
-  my $map = '';
-  seek(PROFILE, $i * ($address_length / 2), 0);
-  read(PROFILE, $map, (stat PROFILE)[7]);
-
-  my $r = {};
-  $r->{version} = $version;
-  $r->{period} = $period;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-
-  return $r;
-}
-
-sub ReadHeapProfile {
-  my $prog = shift;
-  local *PROFILE = shift;
-  my $header = shift;
-
-  my $index = 1;
-  if ($main::opt_inuse_space) {
-    $index = 1;
-  } elsif ($main::opt_inuse_objects) {
-    $index = 0;
-  } elsif ($main::opt_alloc_space) {
-    $index = 3;
-  } elsif ($main::opt_alloc_objects) {
-    $index = 2;
-  }
-
-  # Find the type of this profile.  The header line looks like:
-  #    heap profile:   1246:  8800744 [  1246:  8800744] @ <heap-url>/266053
-  # There are two pairs <count: size>, the first inuse objects/space, and the
-  # second allocated objects/space.  This is followed optionally by a profile
-  # type, and if that is present, optionally by a sampling frequency.
-  # For remote heap profiles (v1):
-  # The interpretation of the sampling frequency is that the profiler, for
-  # each sample, calculates a uniformly distributed random integer less than
-  # the given value, and records the next sample after that many bytes have
-  # been allocated.  Therefore, the expected sample interval is half of the
-  # given frequency.  By default, if not specified, the expected sample
-  # interval is 128KB.  Only remote-heap-page profiles are adjusted for
-  # sample size.
-  # For remote heap profiles (v2):
-  # The sampling frequency is the rate of a Poisson process. This means that
-  # the probability of sampling an allocation of size X with sampling rate Y
-  # is 1 - exp(-X/Y)
-  # For version 2, a typical header line might look like this:
-  # heap profile:   1922: 127792360 [  1922: 127792360] @ <heap-url>_v2/524288
-  # the trailing number (524288) is the sampling rate. (Version 1 showed
-  # double the 'rate' here)
-  my $sampling_algorithm = 0;
-  my $sample_adjustment = 0;
-  chomp($header);
-  my $type = "unknown";
-  if ($header =~ m"^heap profile:\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\](\s*@\s*([^/]*)(/(\d+))?)?") {
-    if (defined($6) && ($6 ne '')) {
-      $type = $6;
-      my $sample_period = $8;
-      # $type is "heapprofile" for profiles generated by the
-      # heap-profiler, and either "heap" or "heap_v2" for profiles
-      # generated by sampling directly within tcmalloc.  It can also
-      # be "growth" for heap-growth profiles.  The first is typically
-      # found for profiles generated locally, and the others for
-      # remote profiles.
-      if (($type eq "heapprofile") || ($type !~ /heap/) ) {
-        # No need to adjust for the sampling rate with heap-profiler-derived data
-        $sampling_algorithm = 0;
-      } elsif ($type =~ /_v2/) {
-        $sampling_algorithm = 2;     # version 2 sampling
-        if (defined($sample_period) && ($sample_period ne '')) {
-          $sample_adjustment = int($sample_period);
-        }
-      } else {
-        $sampling_algorithm = 1;     # version 1 sampling
-        if (defined($sample_period) && ($sample_period ne '')) {
-          $sample_adjustment = int($sample_period)/2;
-        }
-      }
-    } else {
-      # We detect whether or not this is a remote-heap profile by checking
-      # that the total-allocated stats ($n2,$s2) are exactly the
-      # same as the in-use stats ($n1,$s1).  It is remotely conceivable
-      # that a non-remote-heap profile may pass this check, but it is hard
-      # to imagine how that could happen.
-      # In this case it's so old it's guaranteed to be remote-heap version 1.
-      my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4);
-      if (($n1 == $n2) && ($s1 == $s2)) {
-        # This is likely to be a remote-heap based sample profile
-        $sampling_algorithm = 1;
-      }
-    }
-  }
-
-  if ($sampling_algorithm > 0) {
-    # For remote-heap generated profiles, adjust the counts and sizes to
-    # account for the sample rate (we sample once every 128KB by default).
-    if ($sample_adjustment == 0) {
-      # Turn on profile adjustment.
-      $sample_adjustment = 128*1024;
-      print STDERR "Adjusting heap profiles for 1-in-128KB sampling rate\n";
-    } else {
-      printf STDERR ("Adjusting heap profiles for 1-in-%d sampling rate\n",
-                     $sample_adjustment);
-    }
-    if ($sampling_algorithm > 1) {
-      # We don't bother printing anything for the original version (version 1)
-      printf STDERR "Heap version $sampling_algorithm\n";
-    }
-  }
-
-  my $profile = {};
-  my $pcs = {};
-  my $map = "";
-
-  while (<PROFILE>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    if (/^MAPPED_LIBRARIES:/) {
-      # Read the /proc/self/maps data
-      while (<PROFILE>) {
-        s/\r//g;         # turn windows-looking lines into unix-looking lines
-        $map .= $_;
-      }
-      last;
-    }
-
-    if (/^--- Memory map:/) {
-      # Read /proc/self/maps data as formatted by DumpAddressMap()
-      my $buildvar = "";
-      while (<PROFILE>) {
-        s/\r//g;         # turn windows-looking lines into unix-looking lines
-        # Parse "build=<dir>" specification if supplied
-        if (m/^\s*build=(.*)\n/) {
-          $buildvar = $1;
-        }
-
-        # Expand "$build" variable if available
-        $_ =~ s/\$build\b/$buildvar/g;
-
-        $map .= $_;
-      }
-      last;
-    }
-
-    # Read entry of the form:
-    #  <count1>: <bytes1> [<count2>: <bytes2>] @ a1 a2 a3 ... an
-    s/^\s*//;
-    s/\s*$//;
-    if (m/^\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\]\s+@\s+(.*)$/) {
-      my $stack = $5;
-      my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4);
-
-      if ($sample_adjustment) {
-        if ($sampling_algorithm == 2) {
-          # Remote-heap version 2
-          # The sampling frequency is the rate of a Poisson process.
-          # This means that the probability of sampling an allocation of
-          # size X with sampling rate Y is 1 - exp(-X/Y)
-          if ($n1 != 0) {
-            my $ratio = (($s1*1.0)/$n1)/($sample_adjustment);
-            my $scale_factor = 1/(1 - exp(-$ratio));
-            $n1 *= $scale_factor;
-            $s1 *= $scale_factor;
-          }
-          if ($n2 != 0) {
-            my $ratio = (($s2*1.0)/$n2)/($sample_adjustment);
-            my $scale_factor = 1/(1 - exp(-$ratio));
-            $n2 *= $scale_factor;
-            $s2 *= $scale_factor;
-          }
-        } else {
-          # Remote-heap version 1
-          my $ratio;
-          $ratio = (($s1*1.0)/$n1)/($sample_adjustment);
-          if ($ratio < 1) {
-            $n1 /= $ratio;
-            $s1 /= $ratio;
-          }
-          $ratio = (($s2*1.0)/$n2)/($sample_adjustment);
-          if ($ratio < 1) {
-            $n2 /= $ratio;
-            $s2 /= $ratio;
-          }
-        }
-      }
-
-      my @counts = ($n1, $s1, $n2, $s2);
-      $stack = FixCallerAddresses($stack);
-      push @stackTraces, "$n1 $s1 $n2 $s2 $stack";
-      AddEntries($profile, $pcs, $stack, $counts[$index]);
-    }
-  }
-
-  my $r = {};
-  $r->{version} = "heap";
-  $r->{period} = 1;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-  return $r;
-}
-
-sub ReadSynchProfile {
-  my $prog = shift;
-  local *PROFILE = shift;
-  my $header = shift;
-
-  my $map = '';
-  my $profile = {};
-  my $pcs = {};
-  my $sampling_period = 1;
-  my $cyclespernanosec = 2.8;   # Default assumption for old binaries
-  my $seen_clockrate = 0;
-  my $line;
-
-  my $index = 0;
-  if ($main::opt_total_delay) {
-    $index = 0;
-  } elsif ($main::opt_contentions) {
-    $index = 1;
-  } elsif ($main::opt_mean_delay) {
-    $index = 2;
-  }
-
-  while ( $line = <PROFILE> ) {
-    $line =~ s/\r//g;      # turn windows-looking lines into unix-looking lines
-    if ( $line =~ /^\s*(\d+)\s+(\d+) \@\s*(.*?)\s*$/ ) {
-      my ($cycles, $count, $stack) = ($1, $2, $3);
-
-      # Convert cycles to nanoseconds
-      $cycles /= $cyclespernanosec;
-
-      # Adjust for sampling done by application
-      $cycles *= $sampling_period;
-      $count *= $sampling_period;
-
-      my @values = ($cycles, $count, $cycles / $count);
-      AddEntries($profile, $pcs, FixCallerAddresses($stack), $values[$index]);
-
-    } elsif ( $line =~ /^(slow release).*thread \d+  \@\s*(.*?)\s*$/ ||
-              $line =~ /^\s*(\d+) \@\s*(.*?)\s*$/ ) {
-      my ($cycles, $stack) = ($1, $2);
-      if ($cycles !~ /^\d+$/) {
-        next;
-      }
-
-      # Convert cycles to nanoseconds
-      $cycles /= $cyclespernanosec;
-
-      # Adjust for sampling done by application
-      $cycles *= $sampling_period;
-
-      AddEntries($profile, $pcs, FixCallerAddresses($stack), $cycles);
-
-    } elsif ( $line =~ m/^([a-z][^=]*)=(.*)$/ ) {
-      my ($variable, $value) = ($1,$2);
-      for ($variable, $value) {
-        s/^\s+//;
-        s/\s+$//;
-      }
-      if ($variable eq "cycles/second") {
-        $cyclespernanosec = $value / 1e9;
-        $seen_clockrate = 1;
-      } elsif ($variable eq "sampling period") {
-        $sampling_period = $value;
-      } elsif ($variable eq "ms since reset") {
-        # Currently nothing is done with this value in pprof
-        # So we just silently ignore it for now
-      } elsif ($variable eq "discarded samples") {
-        # Currently nothing is done with this value in pprof
-        # So we just silently ignore it for now
-      } else {
-        printf STDERR ("Ignoring unnknown variable in /contention output: " .
-                       "'%s' = '%s'\n",$variable,$value);
-      }
-    } else {
-      # Memory map entry
-      $map .= $line;
-    }
-  }
-
-  if (!$seen_clockrate) {
-    printf STDERR ("No cycles/second entry in profile; Guessing %.1f GHz\n",
-                   $cyclespernanosec);
-  }
-
-  my $r = {};
-  $r->{version} = 0;
-  $r->{period} = $sampling_period;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-  return $r;
-}
-
-# Given a hex value in the form "0x1abcd" or "1abcd", return either
-# "0001abcd" or "000000000001abcd", depending on the current (global)
-# address length.
-sub HexExtend {
-  my $addr = shift;
-
-  $addr =~ s/^(0x)?0*//;
-  my $zeros_needed = $address_length - length($addr);
-  if ($zeros_needed < 0) {
-    printf STDERR "Warning: address $addr is longer than address length $address_length\n";
-    return $addr;
-  }
-  return ("0" x $zeros_needed) . $addr;
-}
-
-##### Symbol extraction #####
-
-# Aggressively search the lib_prefix values for the given library
-# If all else fails, just return the name of the library unmodified.
-# If the lib_prefix is "/my/path,/other/path" and $file is "/lib/dir/mylib.so"
-# it will search the following locations in this order, until it finds a file:
-#   /my/path/lib/dir/mylib.so
-#   /other/path/lib/dir/mylib.so
-#   /my/path/dir/mylib.so
-#   /other/path/dir/mylib.so
-#   /my/path/mylib.so
-#   /other/path/mylib.so
-#   /lib/dir/mylib.so              (returned as last resort)
-sub FindLibrary {
-  my $file = shift;
-  my $suffix = $file;
-
-  # Search for the library as described above
-  do {
-    foreach my $prefix (@prefix_list) {
-      my $fullpath = $prefix . $suffix;
-      if (-e $fullpath) {
-        return $fullpath;
-      }
-    }
-  } while ($suffix =~ s|^/[^/]+/|/|);
-  return $file;
-}
-
-# Return path to library with debugging symbols.
-# For libc libraries, the copy in /usr/lib/debug contains debugging symbols
-sub DebuggingLibrary {
-  my $file = shift;
-  if ($file =~ m|^/| && -f "/usr/lib/debug$file") {
-    return "/usr/lib/debug$file";
-  }
-  if ($file =~ m|^/| && -f "/usr/lib/debug$file.debug") {
-    return "/usr/lib/debug$file.debug";
-  }
-  return undef;
-}
-
-# Parse text section header of a library using objdump
-sub ParseTextSectionHeaderFromObjdump {
-  my $lib = shift;
-
-  my $size = undef;
-  my $vma;
-  my $file_offset;
-  # Get objdump output from the library file to figure out how to
-  # map between mapped addresses and addresses in the library.
-  my $cmd = ShellEscape($obj_tool_map{"objdump"}, "-h", $lib);
-  open(OBJDUMP, "$cmd |") || error("$cmd: $!\n");
-  while (<OBJDUMP>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    # Idx Name          Size      VMA       LMA       File off  Algn
-    #  10 .text         00104b2c  420156f0  420156f0  000156f0  2**4
-    # For 64-bit objects, VMA and LMA will be 16 hex digits, size and file
-    # offset may still be 8.  But AddressSub below will still handle that.
-    my @x = split;
-    if (($#x >= 6) && ($x[1] eq '.text')) {
-      $size = $x[2];
-      $vma = $x[3];
-      $file_offset = $x[5];
-      last;
-    }
-  }
-  close(OBJDUMP);
-
-  if (!defined($size)) {
-    return undef;
-  }
-
-  my $r = {};
-  $r->{size} = $size;
-  $r->{vma} = $vma;
-  $r->{file_offset} = $file_offset;
-
-  return $r;
-}
-
-# Parse text section header of a library using otool (on OS X)
-sub ParseTextSectionHeaderFromOtool {
-  my $lib = shift;
-
-  my $size = undef;
-  my $vma = undef;
-  my $file_offset = undef;
-  # Get otool output from the library file to figure out how to
-  # map between mapped addresses and addresses in the library.
-  my $command = ShellEscape($obj_tool_map{"otool"}, "-l", $lib);
-  open(OTOOL, "$command |") || error("$command: $!\n");
-  my $cmd = "";
-  my $sectname = "";
-  my $segname = "";
-  foreach my $line (<OTOOL>) {
-    $line =~ s/\r//g;      # turn windows-looking lines into unix-looking lines
-    # Load command <#>
-    #       cmd LC_SEGMENT
-    # [...]
-    # Section
-    #   sectname __text
-    #    segname __TEXT
-    #       addr 0x000009f8
-    #       size 0x00018b9e
-    #     offset 2552
-    #      align 2^2 (4)
-    # We will need to strip off the leading 0x from the hex addresses,
-    # and convert the offset into hex.
-    if ($line =~ /Load command/) {
-      $cmd = "";
-      $sectname = "";
-      $segname = "";
-    } elsif ($line =~ /Section/) {
-      $sectname = "";
-      $segname = "";
-    } elsif ($line =~ /cmd (\w+)/) {
-      $cmd = $1;
-    } elsif ($line =~ /sectname (\w+)/) {
-      $sectname = $1;
-    } elsif ($line =~ /segname (\w+)/) {
-      $segname = $1;
-    } elsif (!(($cmd eq "LC_SEGMENT" || $cmd eq "LC_SEGMENT_64") &&
-               $sectname eq "__text" &&
-               $segname eq "__TEXT")) {
-      next;
-    } elsif ($line =~ /\baddr 0x([0-9a-fA-F]+)/) {
-      $vma = $1;
-    } elsif ($line =~ /\bsize 0x([0-9a-fA-F]+)/) {
-      $size = $1;
-    } elsif ($line =~ /\boffset ([0-9]+)/) {
-      $file_offset = sprintf("%016x", $1);
-    }
-    if (defined($vma) && defined($size) && defined($file_offset)) {
-      last;
-    }
-  }
-  close(OTOOL);
-
-  if (!defined($vma) || !defined($size) || !defined($file_offset)) {
-     return undef;
-  }
-
-  my $r = {};
-  $r->{size} = $size;
-  $r->{vma} = $vma;
-  $r->{file_offset} = $file_offset;
-
-  return $r;
-}
-
-sub ParseTextSectionHeader {
-  # obj_tool_map("otool") is only defined if we're in a Mach-O environment
-  if (defined($obj_tool_map{"otool"})) {
-    my $r = ParseTextSectionHeaderFromOtool(@_);
-    if (defined($r)){
-      return $r;
-    }
-  }
-  # If otool doesn't work, or we don't have it, fall back to objdump
-  return ParseTextSectionHeaderFromObjdump(@_);
-}
-
-# Split /proc/pid/maps dump into a list of libraries
-sub ParseLibraries {
-  return if $main::use_symbol_page;  # We don't need libraries info.
-  my $prog = Cwd::abs_path(shift);
-  my $map = shift;
-  my $pcs = shift;
-
-  my $result = [];
-  my $h = "[a-f0-9]+";
-  my $zero_offset = HexExtend("0");
-
-  my $buildvar = "";
-  foreach my $l (split("\n", $map)) {
-    if ($l =~ m/^\s*build=(.*)$/) {
-      $buildvar = $1;
-    }
-
-    my $start;
-    my $finish;
-    my $offset;
-    my $lib;
-    if ($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(.+\.(so|dll|dylib|bundle|node)((\.\d+)+\w*(\.\d+){0,3})?)$/i) {
-      # Full line from /proc/self/maps.  Example:
-      #   40000000-40015000 r-xp 00000000 03:01 12845071   /lib/ld-2.3.2.so
-      $start = HexExtend($1);
-      $finish = HexExtend($2);
-      $offset = HexExtend($3);
-      $lib = $4;
-      $lib =~ s|\\|/|g;     # turn windows-style paths into unix-style paths
-    } elsif ($l =~ /^\s*($h)-($h):\s*(\S+\.so(\.\d+)*)/) {
-      # Cooked line from DumpAddressMap.  Example:
-      #   40000000-40015000: /lib/ld-2.3.2.so
-      $start = HexExtend($1);
-      $finish = HexExtend($2);
-      $offset = $zero_offset;
-      $lib = $3;
-    } elsif (($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(\S+)$/i) && ($4 eq $prog)) {
-      # PIEs and address space randomization do not play well with our
-      # default assumption that main executable is at lowest
-      # addresses. So we're detecting main executable in
-      # /proc/self/maps as well.
-      $start = HexExtend($1);
-      $finish = HexExtend($2);
-      $offset = HexExtend($3);
-      $lib = $4;
-      $lib =~ s|\\|/|g;     # turn windows-style paths into unix-style paths
-    } else {
-      next;
-    }
-
-    # Expand "$build" variable if available
-    $lib =~ s/\$build\b/$buildvar/g;
-
-    $lib = FindLibrary($lib);
-
-    # Check for pre-relocated libraries, which use pre-relocated symbol tables
-    # and thus require adjusting the offset that we'll use to translate
-    # VM addresses into symbol table addresses.
-    # Only do this if we're not going to fetch the symbol table from a
-    # debugging copy of the library.
-    if (!DebuggingLibrary($lib)) {
-      my $text = ParseTextSectionHeader($lib);
-      if (defined($text)) {
-         my $vma_offset = AddressSub($text->{vma}, $text->{file_offset});
-         $offset = AddressAdd($offset, $vma_offset);
-      }
-    }
-
-    push(@{$result}, [$lib, $start, $finish, $offset]);
-  }
-
-  # Append special entry for additional library (not relocated)
-  if ($main::opt_lib ne "") {
-    my $text = ParseTextSectionHeader($main::opt_lib);
-    if (defined($text)) {
-       my $start = $text->{vma};
-       my $finish = AddressAdd($start, $text->{size});
-
-       push(@{$result}, [$main::opt_lib, $start, $finish, $start]);
-    }
-  }
-
-  # Append special entry for the main program.  This covers
-  # 0..max_pc_value_seen, so that we assume pc values not found in one
-  # of the library ranges will be treated as coming from the main
-  # program binary.
-  my $min_pc = HexExtend("0");
-  my $max_pc = $min_pc;          # find the maximal PC value in any sample
-  foreach my $pc (keys(%{$pcs})) {
-    if (HexExtend($pc) gt $max_pc) { $max_pc = HexExtend($pc); }
-  }
-  push(@{$result}, [$prog, $min_pc, $max_pc, $zero_offset]);
-
-  return $result;
-}
-
-# Add two hex addresses of length $address_length.
-# Run pprof --test for unit test if this is changed.
-sub AddressAdd {
-  my $addr1 = shift;
-  my $addr2 = shift;
-  my $sum;
-
-  if ($address_length == 8) {
-    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:
-    $sum = (hex($addr1)+hex($addr2)) % (0x10000000 * 16);
-    return sprintf("%08x", $sum);
-
-  } else {
-    # Do the addition in 7-nibble chunks to trivialize carry handling.
-
-    if ($main::opt_debug and $main::opt_test) {
-      print STDERR "AddressAdd $addr1 + $addr2 = ";
-    }
-
-    my $a1 = substr($addr1,-7);
-    $addr1 = substr($addr1,0,-7);
-    my $a2 = substr($addr2,-7);
-    $addr2 = substr($addr2,0,-7);
-    $sum = hex($a1) + hex($a2);
-    my $c = 0;
-    if ($sum > 0xfffffff) {
-      $c = 1;
-      $sum -= 0x10000000;
-    }
-    my $r = sprintf("%07x", $sum);
-
-    $a1 = substr($addr1,-7);
-    $addr1 = substr($addr1,0,-7);
-    $a2 = substr($addr2,-7);
-    $addr2 = substr($addr2,0,-7);
-    $sum = hex($a1) + hex($a2) + $c;
-    $c = 0;
-    if ($sum > 0xfffffff) {
-      $c = 1;
-      $sum -= 0x10000000;
-    }
-    $r = sprintf("%07x", $sum) . $r;
-
-    $sum = hex($addr1) + hex($addr2) + $c;
-    if ($sum > 0xff) { $sum -= 0x100; }
-    $r = sprintf("%02x", $sum) . $r;
-
-    if ($main::opt_debug and $main::opt_test) { print STDERR "$r\n"; }
-
-    return $r;
-  }
-}
-
-
-# Subtract two hex addresses of length $address_length.
-# Run pprof --test for unit test if this is changed.
-sub AddressSub {
-  my $addr1 = shift;
-  my $addr2 = shift;
-  my $diff;
-
-  if ($address_length == 8) {
-    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:
-    $diff = (hex($addr1)-hex($addr2)) % (0x10000000 * 16);
-    return sprintf("%08x", $diff);
-
-  } else {
-    # Do the addition in 7-nibble chunks to trivialize borrow handling.
-    # if ($main::opt_debug) { print STDERR "AddressSub $addr1 - $addr2 = "; }
-
-    my $a1 = hex(substr($addr1,-7));
-    $addr1 = substr($addr1,0,-7);
-    my $a2 = hex(substr($addr2,-7));
-    $addr2 = substr($addr2,0,-7);
-    my $b = 0;
-    if ($a2 > $a1) {
-      $b = 1;
-      $a1 += 0x10000000;
-    }
-    $diff = $a1 - $a2;
-    my $r = sprintf("%07x", $diff);
-
-    $a1 = hex(substr($addr1,-7));
-    $addr1 = substr($addr1,0,-7);
-    $a2 = hex(substr($addr2,-7)) + $b;
-    $addr2 = substr($addr2,0,-7);
-    $b = 0;
-    if ($a2 > $a1) {
-      $b = 1;
-      $a1 += 0x10000000;
-    }
-    $diff = $a1 - $a2;
-    $r = sprintf("%07x", $diff) . $r;
-
-    $a1 = hex($addr1);
-    $a2 = hex($addr2) + $b;
-    if ($a2 > $a1) { $a1 += 0x100; }
-    $diff = $a1 - $a2;
-    $r = sprintf("%02x", $diff) . $r;
-
-    # if ($main::opt_debug) { print STDERR "$r\n"; }
-
-    return $r;
-  }
-}
-
-# Increment a hex addresses of length $address_length.
-# Run pprof --test for unit test if this is changed.
-sub AddressInc {
-  my $addr = shift;
-  my $sum;
-
-  if ($address_length == 8) {
-    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:
-    $sum = (hex($addr)+1) % (0x10000000 * 16);
-    return sprintf("%08x", $sum);
-
-  } else {
-    # Do the addition in 7-nibble chunks to trivialize carry handling.
-    # We are always doing this to step through the addresses in a function,
-    # and will almost never overflow the first chunk, so we check for this
-    # case and exit early.
-
-    # if ($main::opt_debug) { print STDERR "AddressInc $addr1 = "; }
-
-    my $a1 = substr($addr,-7);
-    $addr = substr($addr,0,-7);
-    $sum = hex($a1) + 1;
-    my $r = sprintf("%07x", $sum);
-    if ($sum <= 0xfffffff) {
-      $r = $addr . $r;
-      # if ($main::opt_debug) { print STDERR "$r\n"; }
-      return HexExtend($r);
-    } else {
-      $r = "0000000";
-    }
-
-    $a1 = substr($addr,-7);
-    $addr = substr($addr,0,-7);
-    $sum = hex($a1) + 1;
-    $r = sprintf("%07x", $sum) . $r;
-    if ($sum <= 0xfffffff) {
-      $r = $addr . $r;
-      # if ($main::opt_debug) { print STDERR "$r\n"; }
-      return HexExtend($r);
-    } else {
-      $r = "00000000000000";
-    }
-
-    $sum = hex($addr) + 1;
-    if ($sum > 0xff) { $sum -= 0x100; }
-    $r = sprintf("%02x", $sum) . $r;
-
-    # if ($main::opt_debug) { print STDERR "$r\n"; }
-    return $r;
-  }
-}
-
-# Extract symbols for all PC values found in profile
-sub ExtractSymbols {
-  my $libs = shift;
-  my $pcset = shift;
-
-  my $symbols = {};
-
-  # Map each PC value to the containing library.  To make this faster,
-  # we sort libraries by their starting pc value (highest first), and
-  # advance through the libraries as we advance the pc.  Sometimes the
-  # addresses of libraries may overlap with the addresses of the main
-  # binary, so to make sure the libraries 'win', we iterate over the
-  # libraries in reverse order (which assumes the binary doesn't start
-  # in the middle of a library, which seems a fair assumption).
-  my @pcs = (sort { $a cmp $b } keys(%{$pcset}));  # pcset is 0-extended strings
-  foreach my $lib (sort {$b->[1] cmp $a->[1]} @{$libs}) {
-    my $libname = $lib->[0];
-    my $start = $lib->[1];
-    my $finish = $lib->[2];
-    my $offset = $lib->[3];
-
-    # Get list of pcs that belong in this library.
-    my $contained = [];
-    my ($start_pc_index, $finish_pc_index);
-    # Find smallest finish_pc_index such that $finish < $pc[$finish_pc_index].
-    for ($finish_pc_index = $#pcs + 1; $finish_pc_index > 0;
-         $finish_pc_index--) {
-      last if $pcs[$finish_pc_index - 1] le $finish;
-    }
-    # Find smallest start_pc_index such that $start <= $pc[$start_pc_index].
-    for ($start_pc_index = $finish_pc_index; $start_pc_index > 0;
-         $start_pc_index--) {
-      last if $pcs[$start_pc_index - 1] lt $start;
-    }
-    # This keeps PC values higher than $pc[$finish_pc_index] in @pcs,
-    # in case there are overlaps in libraries and the main binary.
-    @{$contained} = splice(@pcs, $start_pc_index,
-                           $finish_pc_index - $start_pc_index);
-    # Map to symbols
-    MapToSymbols($libname, AddressSub($start, $offset), $contained, $symbols);
-  }
-
-  return $symbols;
-}
-
-# Map list of PC values to symbols for a given image
-sub MapToSymbols {
-  my $image = shift;
-  my $offset = shift;
-  my $pclist = shift;
-  my $symbols = shift;
-
-  my $debug = 0;
-
-  # For libc (and other) libraries, the copy in /usr/lib/debug contains debugging symbols
-  my $debugging = DebuggingLibrary($image);
-  if ($debugging) {
-    $image = $debugging;
-  }
-
-  # Ignore empty binaries
-  if ($#{$pclist} < 0) { return; }
-
-  # Figure out the addr2line command to use
-  my $addr2line = $obj_tool_map{"addr2line"};
-  my $cmd = ShellEscape($addr2line, "-f", "-C", "-e", $image);
-  if (exists $obj_tool_map{"addr2line_pdb"}) {
-    $addr2line = $obj_tool_map{"addr2line_pdb"};
-    $cmd = ShellEscape($addr2line, "--demangle", "-f", "-C", "-e", $image);
-  }
-
-  # If "addr2line" isn't installed on the system at all, just use
-  # nm to get what info we can (function names, but not line numbers).
-  if (system(ShellEscape($addr2line, "--help") . " >$dev_null 2>&1") != 0) {
-    MapSymbolsWithNM($image, $offset, $pclist, $symbols);
-    return;
-  }
-
-  # "addr2line -i" can produce a variable number of lines per input
-  # address, with no separator that allows us to tell when data for
-  # the next address starts.  So we find the address for a special
-  # symbol (_fini) and interleave this address between all real
-  # addresses passed to addr2line.  The name of this special symbol
-  # can then be used as a separator.
-  $sep_address = undef;  # May be filled in by MapSymbolsWithNM()
-  my $nm_symbols = {};
-  MapSymbolsWithNM($image, $offset, $pclist, $nm_symbols);
-  if (defined($sep_address)) {
-    # Only add " -i" to addr2line if the binary supports it.
-    # addr2line --help returns 0, but not if it sees an unknown flag first.
-    if (system("$cmd -i --help >$dev_null 2>&1") == 0) {
-      $cmd .= " -i";
-    } else {
-      $sep_address = undef;   # no need for sep_address if we don't support -i
-    }
-  }
-
-  # Make file with all PC values with intervening 'sep_address' so
-  # that we can reliably detect the end of inlined function list
-  open(ADDRESSES, ">$main::tmpfile_sym") || error("$main::tmpfile_sym: $!\n");
-  if ($debug) { print("---- $image ---\n"); }
-  for (my $i = 0; $i <= $#{$pclist}; $i++) {
-    # addr2line always reads hex addresses, and does not need '0x' prefix.
-    if ($debug) { printf STDERR ("%s\n", $pclist->[$i]); }
-    printf ADDRESSES ("%s\n", AddressSub($pclist->[$i], $offset));
-    if (defined($sep_address)) {
-      printf ADDRESSES ("%s\n", $sep_address);
-    }
-  }
-  close(ADDRESSES);
-  if ($debug) {
-    print("----\n");
-    system("cat", $main::tmpfile_sym);
-    print("---- $cmd ---\n");
-    system("$cmd < " . ShellEscape($main::tmpfile_sym));
-    print("----\n");
-  }
-
-  open(SYMBOLS, "$cmd <" . ShellEscape($main::tmpfile_sym) . " |")
-      || error("$cmd: $!\n");
-  my $count = 0;   # Index in pclist
-  while (<SYMBOLS>) {
-    # Read fullfunction and filelineinfo from next pair of lines
-    s/\r?\n$//g;
-    my $fullfunction = $_;
-    $_ = <SYMBOLS>;
-    s/\r?\n$//g;
-    my $filelinenum = $_;
-
-    if (defined($sep_address) && $fullfunction eq $sep_symbol) {
-      # Terminating marker for data for this address
-      $count++;
-      next;
-    }
-
-    $filelinenum =~ s|\\|/|g; # turn windows-style paths into unix-style paths
-
-    # Remove discriminator markers as this comes after the line number and
-    # confuses the rest of this script.
-    $filelinenum =~ s/ \(discriminator \d+\)$//;
-    # Convert unknown line numbers into line 0.
-    $filelinenum =~ s/:\?$/:0/;
-
-    my $pcstr = $pclist->[$count];
-    my $function = ShortFunctionName($fullfunction);
-    my $nms = $nm_symbols->{$pcstr};
-    if (defined($nms)) {
-      if ($fullfunction eq '??') {
-        # nm found a symbol for us.
-        $function = $nms->[0];
-        $fullfunction = $nms->[2];
-      } else {
-	# MapSymbolsWithNM tags each routine with its starting address,
-	# useful in case the image has multiple occurrences of this
-	# routine.  (It uses a syntax that resembles template paramters,
-	# that are automatically stripped out by ShortFunctionName().)
-	# addr2line does not provide the same information.  So we check
-	# if nm disambiguated our symbol, and if so take the annotated
-	# (nm) version of the routine-name.  TODO(csilvers): this won't
-	# catch overloaded, inlined symbols, which nm doesn't see.
-	# Better would be to do a check similar to nm's, in this fn.
-	if ($nms->[2] =~ m/^\Q$function\E/) {  # sanity check it's the right fn
-	  $function = $nms->[0];
-	  $fullfunction = $nms->[2];
-	}
-      }
-    }
-    
-    # Prepend to accumulated symbols for pcstr
-    # (so that caller comes before callee)
-    my $sym = $symbols->{$pcstr};
-    if (!defined($sym)) {
-      $sym = [];
-      $symbols->{$pcstr} = $sym;
-    }
-    unshift(@{$sym}, $function, $filelinenum, $fullfunction);
-    if ($debug) { printf STDERR ("%s => [%s]\n", $pcstr, join(" ", @{$sym})); }
-    if (!defined($sep_address)) {
-      # Inlining is off, so this entry ends immediately
-      $count++;
-    }
-  }
-  close(SYMBOLS);
-}
-
-# Use nm to map the list of referenced PCs to symbols.  Return true iff we
-# are able to read procedure information via nm.
-sub MapSymbolsWithNM {
-  my $image = shift;
-  my $offset = shift;
-  my $pclist = shift;
-  my $symbols = shift;
-
-  # Get nm output sorted by increasing address
-  my $symbol_table = GetProcedureBoundaries($image, ".");
-  if (!%{$symbol_table}) {
-    return 0;
-  }
-  # Start addresses are already the right length (8 or 16 hex digits).
-  my @names = sort { $symbol_table->{$a}->[0] cmp $symbol_table->{$b}->[0] }
-    keys(%{$symbol_table});
-
-  if ($#names < 0) {
-    # No symbols: just use addresses
-    foreach my $pc (@{$pclist}) {
-      my $pcstr = "0x" . $pc;
-      $symbols->{$pc} = [$pcstr, "?", $pcstr];
-    }
-    return 0;
-  }
-
-  # Sort addresses so we can do a join against nm output
-  my $index = 0;
-  my $fullname = $names[0];
-  my $name = ShortFunctionName($fullname);
-  foreach my $pc (sort { $a cmp $b } @{$pclist}) {
-    # Adjust for mapped offset
-    my $mpc = AddressSub($pc, $offset);
-    while (($index < $#names) && ($mpc ge $symbol_table->{$fullname}->[1])){
-      $index++;
-      $fullname = $names[$index];
-      $name = ShortFunctionName($fullname);
-    }
-    if ($mpc lt $symbol_table->{$fullname}->[1]) {
-      $symbols->{$pc} = [$name, "?", $fullname];
-    } else {
-      my $pcstr = "0x" . $pc;
-      $symbols->{$pc} = [$pcstr, "?", $pcstr];
-    }
-  }
-  return 1;
-}
-
-sub ShortFunctionName {
-  my $function = shift;
-  while ($function =~ s/\([^()]*\)(\s*const)?//g) { }   # Argument types
-  $function =~ s/<[0-9a-f]*>$//g;                # Remove Address
-  if (!$main::opt_no_strip_temp) {
-      while ($function =~ s/<[^<>]*>//g)  { }   # Remove template arguments
-  }
-  $function =~ s/^.*\s+(\w+::)/$1/;          # Remove leading type
-  return $function;
-}
-
-# Trim overly long symbols found in disassembler output
-sub CleanDisassembly {
-  my $d = shift;
-  while ($d =~ s/\([^()%]*\)(\s*const)?//g) { } # Argument types, not (%rax)
-  while ($d =~ s/(\w+)<[^<>]*>/$1/g)  { }       # Remove template arguments
-  return $d;
-}
-
-# Clean file name for display
-sub CleanFileName {
-  my ($f) = @_;
-  $f =~ s|^/proc/self/cwd/||;
-  $f =~ s|^\./||;
-  return $f;
-}
-
-# Make address relative to section and clean up for display
-sub UnparseAddress {
-  my ($offset, $address) = @_;
-  $address = AddressSub($address, $offset);
-  $address =~ s/^0x//;
-  $address =~ s/^0*//;
-  return $address;
-}
-
-##### Miscellaneous #####
-
-# Find the right versions of the above object tools to use.  The
-# argument is the program file being analyzed, and should be an ELF
-# 32-bit or ELF 64-bit executable file.  The location of the tools
-# is determined by considering the following options in this order:
-#   1) --tools option, if set
-#   2) PPROF_TOOLS environment variable, if set
-#   3) the environment
-sub ConfigureObjTools {
-  my $prog_file = shift;
-
-  # Check for the existence of $prog_file because /usr/bin/file does not
-  # predictably return error status in prod.
-  (-e $prog_file)  || error("$prog_file does not exist.\n");
-
-  my $file_type = undef;
-  if (-e "/usr/bin/file") {
-    # Follow symlinks (at least for systems where "file" supports that).
-    my $escaped_prog_file = ShellEscape($prog_file);
-    $file_type = `/usr/bin/file -L $escaped_prog_file 2>$dev_null ||
-                  /usr/bin/file $escaped_prog_file`;
-  } elsif ($^O == "MSWin32") {
-    $file_type = "MS Windows";
-  } else {
-    print STDERR "WARNING: Can't determine the file type of $prog_file";
-  }
-
-  if ($file_type =~ /64-bit/) {
-    # Change $address_length to 16 if the program file is ELF 64-bit.
-    # We can't detect this from many (most?) heap or lock contention
-    # profiles, since the actual addresses referenced are generally in low
-    # memory even for 64-bit programs.
-    $address_length = 16;
-  }
-
-  if ($file_type =~ /MS Windows/) {
-    # For windows, we provide a version of nm and addr2line as part of
-    # the opensource release, which is capable of parsing
-    # Windows-style PDB executables.  It should live in the path, or
-    # in the same directory as pprof.
-    $obj_tool_map{"nm_pdb"} = "nm-pdb";
-    $obj_tool_map{"addr2line_pdb"} = "addr2line-pdb";
-  }
-
-  if ($file_type =~ /Mach-O/) {
-    # OS X uses otool to examine Mach-O files, rather than objdump.
-    $obj_tool_map{"otool"} = "otool";
-    $obj_tool_map{"addr2line"} = "false";  # no addr2line
-    $obj_tool_map{"objdump"} = "false";  # no objdump
-  }
-
-  # Go fill in %obj_tool_map with the pathnames to use:
-  foreach my $tool (keys %obj_tool_map) {
-    $obj_tool_map{$tool} = ConfigureTool($obj_tool_map{$tool});
-  }
-}
-
-# Returns the path of a caller-specified object tool.  If --tools or
-# PPROF_TOOLS are specified, then returns the full path to the tool
-# with that prefix.  Otherwise, returns the path unmodified (which
-# means we will look for it on PATH).
-sub ConfigureTool {
-  my $tool = shift;
-  my $path;
-
-  # --tools (or $PPROF_TOOLS) is a comma separated list, where each
-  # item is either a) a pathname prefix, or b) a map of the form
-  # <tool>:<path>.  First we look for an entry of type (b) for our
-  # tool.  If one is found, we use it.  Otherwise, we consider all the
-  # pathname prefixes in turn, until one yields an existing file.  If
-  # none does, we use a default path.
-  my $tools = $main::opt_tools || $ENV{"PPROF_TOOLS"} || "";
-  if ($tools =~ m/(,|^)\Q$tool\E:([^,]*)/) {
-    $path = $2;
-    # TODO(csilvers): sanity-check that $path exists?  Hard if it's relative.
-  } elsif ($tools ne '') {
-    foreach my $prefix (split(',', $tools)) {
-      next if ($prefix =~ /:/);    # ignore "tool:fullpath" entries in the list
-      if (-x $prefix . $tool) {
-        $path = $prefix . $tool;
-        last;
-      }
-    }
-    if (!$path) {
-      error("No '$tool' found with prefix specified by " .
-            "--tools (or \$PPROF_TOOLS) '$tools'\n");
-    }
-  } else {
-    # ... otherwise use the version that exists in the same directory as
-    # pprof.  If there's nothing there, use $PATH.
-    $0 =~ m,[^/]*$,;     # this is everything after the last slash
-    my $dirname = $`;    # this is everything up to and including the last slash
-    if (-x "$dirname$tool") {
-      $path = "$dirname$tool";
-    } else { 
-      $path = $tool;
-    }
-  }
-  if ($main::opt_debug) { print STDERR "Using '$path' for '$tool'.\n"; }
-  return $path;
-}
-
-sub ShellEscape {
-  my @escaped_words = ();
-  foreach my $word (@_) {
-    my $escaped_word = $word;
-    if ($word =~ m![^a-zA-Z0-9/.,_=-]!) {  # check for anything not in whitelist
-      $escaped_word =~ s/'/'\\''/;
-      $escaped_word = "'$escaped_word'";
-    }
-    push(@escaped_words, $escaped_word);
-  }
-  return join(" ", @escaped_words);
-}
-
-sub cleanup {
-  unlink($main::tmpfile_sym);
-  unlink(keys %main::tempnames);
-
-  # We leave any collected profiles in $HOME/pprof in case the user wants
-  # to look at them later.  We print a message informing them of this.
-  if ((scalar(@main::profile_files) > 0) &&
-      defined($main::collected_profile)) {
-    if (scalar(@main::profile_files) == 1) {
-      print STDERR "Dynamically gathered profile is in $main::collected_profile\n";
-    }
-    print STDERR "If you want to investigate this profile further, you can do:\n";
-    print STDERR "\n";
-    print STDERR "  $0 \\\n";
-    print STDERR "    $main::prog \\\n";
-    print STDERR "    $main::collected_profile\n";
-    print STDERR "\n";
-  }
-}
-
-sub sighandler {
-  cleanup();
-  exit(1);
-}
-
-sub error {
-  my $msg = shift;
-  print STDERR $msg;
-  cleanup();
-  exit(1);
-}
-
-
-# Run $nm_command and get all the resulting procedure boundaries whose
-# names match "$regexp" and returns them in a hashtable mapping from
-# procedure name to a two-element vector of [start address, end address]
-sub GetProcedureBoundariesViaNm {
-  my $escaped_nm_command = shift;    # shell-escaped
-  my $regexp = shift;
-  my $image = shift;
-
-  my $symbol_table = {};
-  open(NM, "$escaped_nm_command |") || error("$escaped_nm_command: $!\n");
-  my $last_start = "0";
-  my $routine = "";
-  while (<NM>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    if (m/^\s*([0-9a-f]+) (.) (..*)/) {
-      my $start_val = $1;
-      my $type = $2;
-      my $this_routine = $3;
-
-      # It's possible for two symbols to share the same address, if
-      # one is a zero-length variable (like __start_google_malloc) or
-      # one symbol is a weak alias to another (like __libc_malloc).
-      # In such cases, we want to ignore all values except for the
-      # actual symbol, which in nm-speak has type "T".  The logic
-      # below does this, though it's a bit tricky: what happens when
-      # we have a series of lines with the same address, is the first
-      # one gets queued up to be processed.  However, it won't
-      # *actually* be processed until later, when we read a line with
-      # a different address.  That means that as long as we're reading
-      # lines with the same address, we have a chance to replace that
-      # item in the queue, which we do whenever we see a 'T' entry --
-      # that is, a line with type 'T'.  If we never see a 'T' entry,
-      # we'll just go ahead and process the first entry (which never
-      # got touched in the queue), and ignore the others.
-      if ($start_val eq $last_start && $type =~ /t/i) {
-        # We are the 'T' symbol at this address, replace previous symbol.
-        $routine = $this_routine;
-        next;
-      } elsif ($start_val eq $last_start) {
-        # We're not the 'T' symbol at this address, so ignore us.
-        next;
-      }
-
-      if ($this_routine eq $sep_symbol) {
-        $sep_address = HexExtend($start_val);
-      }
-
-      # Tag this routine with the starting address in case the image
-      # has multiple occurrences of this routine.  We use a syntax
-      # that resembles template paramters that are automatically
-      # stripped out by ShortFunctionName()
-      $this_routine .= "<$start_val>";
-
-      if (defined($routine) && $routine =~ m/$regexp/) {
-        $symbol_table->{$routine} = [HexExtend($last_start),
-                                     HexExtend($start_val)];
-      }
-      $last_start = $start_val;
-      $routine = $this_routine;
-    } elsif (m/^Loaded image name: (.+)/) {
-      # The win32 nm workalike emits information about the binary it is using.
-      if ($main::opt_debug) { print STDERR "Using Image $1\n"; }
-    } elsif (m/^PDB file name: (.+)/) {
-      # The win32 nm workalike emits information about the pdb it is using.
-      if ($main::opt_debug) { print STDERR "Using PDB $1\n"; }
-    }
-  }
-  close(NM);
-  # Handle the last line in the nm output.  Unfortunately, we don't know
-  # how big this last symbol is, because we don't know how big the file
-  # is.  For now, we just give it a size of 0.
-  # TODO(csilvers): do better here.
-  if (defined($routine) && $routine =~ m/$regexp/) {
-    $symbol_table->{$routine} = [HexExtend($last_start),
-                                 HexExtend($last_start)];
-  }
-
-  # Verify if addr2line can find the $sep_symbol.  If not, we use objdump
-  # to find the address for the $sep_symbol on code section which addr2line
-  # can find.
-  if (defined($sep_address)){
-    my $start_val = $sep_address;
-    my $addr2line = $obj_tool_map{"addr2line"};
-    my $cmd = ShellEscape($addr2line, "-f", "-C", "-e", $image, "-i");
-    open(FINI, "echo $start_val | $cmd  |")
-         || error("echo $start_val | $cmd: $!\n");
-    $_ = <FINI>;
-    s/\r?\n$//g;
-    my $fini = $_;
-    close(FINI);
-    if ($fini ne $sep_symbol){
-      my $objdump =  $obj_tool_map{"objdump"};
-      $cmd = ShellEscape($objdump, "-d", $image);
-      my $grep = ShellEscape("grep", $sep_symbol);
-      my $tail = ShellEscape("tail", "-n", "1");
-      open(FINI, "$cmd | $grep | $tail |")
-           || error("$cmd | $grep | $tail: $!\n");
-      s/\r//g; # turn windows-looking lines into unix-looking lines
-      my $data = <FINI>;
-      if (defined($data)){
-        ($start_val, $fini) = split(/ </,$data);
-      }
-      close(FINI);
-    }
-    $sep_address = HexExtend($start_val);
-  }
-
-  return $symbol_table;
-}
-
-# Gets the procedure boundaries for all routines in "$image" whose names
-# match "$regexp" and returns them in a hashtable mapping from procedure
-# name to a two-element vector of [start address, end address].
-# Will return an empty map if nm is not installed or not working properly.
-sub GetProcedureBoundaries {
-  my $image = shift;
-  my $regexp = shift;
-
-  # If $image doesn't start with /, then put ./ in front of it.  This works
-  # around an obnoxious bug in our probing of nm -f behavior.
-  # "nm -f $image" is supposed to fail on GNU nm, but if:
-  #
-  # a. $image starts with [BbSsPp] (for example, bin/foo/bar), AND
-  # b. you have a.out in your current directory (a not uncommon occurrence)
-  #
-  # then "nm -f $image" succeeds because -f only looks at the first letter of
-  # the argument, which looks valid because it's [BbSsPp], and then since
-  # there's no image provided, it looks for a.out and finds it.
-  #
-  # This regex makes sure that $image starts with . or /, forcing the -f
-  # parsing to fail since . and / are not valid formats.
-  $image =~ s#^[^/]#./$&#;
-
-  # For libc libraries, the copy in /usr/lib/debug contains debugging symbols
-  my $debugging = DebuggingLibrary($image);
-  if ($debugging) {
-    $image = $debugging;
-  }
-
-  my $nm = $obj_tool_map{"nm"};
-  my $cppfilt = $obj_tool_map{"c++filt"};
-
-  # nm can fail for two reasons: 1) $image isn't a debug library; 2) nm
-  # binary doesn't support --demangle.  In addition, for OS X we need
-  # to use the -f flag to get 'flat' nm output (otherwise we don't sort
-  # properly and get incorrect results).  Unfortunately, GNU nm uses -f
-  # in an incompatible way.  So first we test whether our nm supports
-  # --demangle and -f.
-  my $demangle_flag = "";
-  my $cppfilt_flag = "";
-  my $to_devnull = ">$dev_null 2>&1";
-  if (system(ShellEscape($nm, "--demangle", "image") . $to_devnull) == 0) {
-    # In this mode, we do "nm --demangle <foo>"
-    $demangle_flag = "--demangle";
-    $cppfilt_flag = "";
-  } elsif (system(ShellEscape($cppfilt, $image) . $to_devnull) == 0) {
-    # In this mode, we do "nm <foo> | c++filt"
-    $cppfilt_flag = " | " . ShellEscape($cppfilt);
-  };
-  my $flatten_flag = "";
-  if (system(ShellEscape($nm, "-f", $image) . $to_devnull) == 0) {
-    $flatten_flag = "-f";
-  }
-
-  # Finally, in the case $imagie isn't a debug library, we try again with
-  # -D to at least get *exported* symbols.  If we can't use --demangle,
-  # we use c++filt instead, if it exists on this system.
-  my @nm_commands = (ShellEscape($nm, "-n", $flatten_flag, $demangle_flag,
-                                 $image) . " 2>$dev_null $cppfilt_flag",
-                     ShellEscape($nm, "-D", "-n", $flatten_flag, $demangle_flag,
-                                 $image) . " 2>$dev_null $cppfilt_flag",
-                     # 6nm is for Go binaries
-                     ShellEscape("6nm", "$image") . " 2>$dev_null | sort",
-                     );
-
-  # If the executable is an MS Windows PDB-format executable, we'll
-  # have set up obj_tool_map("nm_pdb").  In this case, we actually
-  # want to use both unix nm and windows-specific nm_pdb, since
-  # PDB-format executables can apparently include dwarf .o files.
-  if (exists $obj_tool_map{"nm_pdb"}) {
-    push(@nm_commands,
-         ShellEscape($obj_tool_map{"nm_pdb"}, "--demangle", $image)
-         . " 2>$dev_null");
-  }
-
-  foreach my $nm_command (@nm_commands) {
-    my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp, $image);
-    return $symbol_table if (%{$symbol_table});
-  }
-  my $symbol_table = {};
-  return $symbol_table;
-}
-
-
-# The test vectors for AddressAdd/Sub/Inc are 8-16-nibble hex strings.
-# To make them more readable, we add underscores at interesting places.
-# This routine removes the underscores, producing the canonical representation
-# used by pprof to represent addresses, particularly in the tested routines.
-sub CanonicalHex {
-  my $arg = shift;
-  return join '', (split '_',$arg);
-}
-
-
-# Unit test for AddressAdd:
-sub AddressAddUnitTest {
-  my $test_data_8 = shift;
-  my $test_data_16 = shift;
-  my $error_count = 0;
-  my $fail_count = 0;
-  my $pass_count = 0;
-  # print STDERR "AddressAddUnitTest: ", 1+$#{$test_data_8}, " tests\n";
-
-  # First a few 8-nibble addresses.  Note that this implementation uses
-  # plain old arithmetic, so a quick sanity check along with verifying what
-  # happens to overflow (we want it to wrap):
-  $address_length = 8;
-  foreach my $row (@{$test_data_8}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressAdd ($row->[0], $row->[1]);
-    if ($sum ne $row->[2]) {
-      printf STDERR "ERROR: %s != %s + %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[2];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressAdd 32-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count = $fail_count;
-  $fail_count = 0;
-  $pass_count = 0;
-
-  # Now 16-nibble addresses.
-  $address_length = 16;
-  foreach my $row (@{$test_data_16}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressAdd (CanonicalHex($row->[0]), CanonicalHex($row->[1]));
-    my $expected = join '', (split '_',$row->[2]);
-    if ($sum ne CanonicalHex($row->[2])) {
-      printf STDERR "ERROR: %s != %s + %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[2];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressAdd 64-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count += $fail_count;
-
-  return $error_count;
-}
-
-
-# Unit test for AddressSub:
-sub AddressSubUnitTest {
-  my $test_data_8 = shift;
-  my $test_data_16 = shift;
-  my $error_count = 0;
-  my $fail_count = 0;
-  my $pass_count = 0;
-  # print STDERR "AddressSubUnitTest: ", 1+$#{$test_data_8}, " tests\n";
-
-  # First a few 8-nibble addresses.  Note that this implementation uses
-  # plain old arithmetic, so a quick sanity check along with verifying what
-  # happens to overflow (we want it to wrap):
-  $address_length = 8;
-  foreach my $row (@{$test_data_8}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressSub ($row->[0], $row->[1]);
-    if ($sum ne $row->[3]) {
-      printf STDERR "ERROR: %s != %s - %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[3];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressSub 32-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count = $fail_count;
-  $fail_count = 0;
-  $pass_count = 0;
-
-  # Now 16-nibble addresses.
-  $address_length = 16;
-  foreach my $row (@{$test_data_16}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressSub (CanonicalHex($row->[0]), CanonicalHex($row->[1]));
-    if ($sum ne CanonicalHex($row->[3])) {
-      printf STDERR "ERROR: %s != %s - %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[3];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressSub 64-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count += $fail_count;
-
-  return $error_count;
-}
-
-
-# Unit test for AddressInc:
-sub AddressIncUnitTest {
-  my $test_data_8 = shift;
-  my $test_data_16 = shift;
-  my $error_count = 0;
-  my $fail_count = 0;
-  my $pass_count = 0;
-  # print STDERR "AddressIncUnitTest: ", 1+$#{$test_data_8}, " tests\n";
-
-  # First a few 8-nibble addresses.  Note that this implementation uses
-  # plain old arithmetic, so a quick sanity check along with verifying what
-  # happens to overflow (we want it to wrap):
-  $address_length = 8;
-  foreach my $row (@{$test_data_8}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressInc ($row->[0]);
-    if ($sum ne $row->[4]) {
-      printf STDERR "ERROR: %s != %s + 1 = %s\n", $sum,
-             $row->[0], $row->[4];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressInc 32-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count = $fail_count;
-  $fail_count = 0;
-  $pass_count = 0;
-
-  # Now 16-nibble addresses.
-  $address_length = 16;
-  foreach my $row (@{$test_data_16}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressInc (CanonicalHex($row->[0]));
-    if ($sum ne CanonicalHex($row->[4])) {
-      printf STDERR "ERROR: %s != %s + 1 = %s\n", $sum,
-             $row->[0], $row->[4];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressInc 64-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count += $fail_count;
-
-  return $error_count;
-}
-
-
-# Driver for unit tests.
-# Currently just the address add/subtract/increment routines for 64-bit.
-sub RunUnitTests {
-  my $error_count = 0;
-
-  # This is a list of tuples [a, b, a+b, a-b, a+1]
-  my $unit_test_data_8 = [
-    [qw(aaaaaaaa 50505050 fafafafa 5a5a5a5a aaaaaaab)],
-    [qw(50505050 aaaaaaaa fafafafa a5a5a5a6 50505051)],
-    [qw(ffffffff aaaaaaaa aaaaaaa9 55555555 00000000)],
-    [qw(00000001 ffffffff 00000000 00000002 00000002)],
-    [qw(00000001 fffffff0 fffffff1 00000011 00000002)],
-  ];
-  my $unit_test_data_16 = [
-    # The implementation handles data in 7-nibble chunks, so those are the
-    # interesting boundaries.
-    [qw(aaaaaaaa 50505050
-        00_000000f_afafafa 00_0000005_a5a5a5a 00_000000a_aaaaaab)],
-    [qw(50505050 aaaaaaaa
-        00_000000f_afafafa ff_ffffffa_5a5a5a6 00_0000005_0505051)],
-    [qw(ffffffff aaaaaaaa
-        00_000001a_aaaaaa9 00_0000005_5555555 00_0000010_0000000)],
-    [qw(00000001 ffffffff
-        00_0000010_0000000 ff_ffffff0_0000002 00_0000000_0000002)],
-    [qw(00000001 fffffff0
-        00_000000f_ffffff1 ff_ffffff0_0000011 00_0000000_0000002)],
-
-    [qw(00_a00000a_aaaaaaa 50505050
-        00_a00000f_afafafa 00_a000005_a5a5a5a 00_a00000a_aaaaaab)],
-    [qw(0f_fff0005_0505050 aaaaaaaa
-        0f_fff000f_afafafa 0f_ffefffa_5a5a5a6 0f_fff0005_0505051)],
-    [qw(00_000000f_fffffff 01_800000a_aaaaaaa
-        01_800001a_aaaaaa9 fe_8000005_5555555 00_0000010_0000000)],
-    [qw(00_0000000_0000001 ff_fffffff_fffffff
-        00_0000000_0000000 00_0000000_0000002 00_0000000_0000002)],
-    [qw(00_0000000_0000001 ff_fffffff_ffffff0
-        ff_fffffff_ffffff1 00_0000000_0000011 00_0000000_0000002)],
-  ];
-
-  $error_count += AddressAddUnitTest($unit_test_data_8, $unit_test_data_16);
-  $error_count += AddressSubUnitTest($unit_test_data_8, $unit_test_data_16);
-  $error_count += AddressIncUnitTest($unit_test_data_8, $unit_test_data_16);
-  if ($error_count > 0) {
-    print STDERR $error_count, " errors: FAILED\n";
-  } else {
-    print STDERR "PASS\n";
-  }
-  exit ($error_count);
-}
diff --git a/third_party/tcmalloc/chromium/src/profile-handler.cc b/third_party/tcmalloc/chromium/src/profile-handler.cc
deleted file mode 100644
index c7a80a80..0000000
--- a/third_party/tcmalloc/chromium/src/profile-handler.cc
+++ /dev/null
@@ -1,585 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//         Nabeel Mian
-//
-// Implements management of profile timers and the corresponding signal handler.
-
-#include "config.h"
-#include "profile-handler.h"
-
-#if !(defined(__CYGWIN__) || defined(__CYGWIN32__))
-
-#include <stdio.h>
-#include <errno.h>
-#include <sys/time.h>
-
-#include <list>
-#include <string>
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-// for timer_{create,settime} and associated typedefs & constants
-#include <time.h>
-// for sys_gettid
-#include "base/linux_syscall_support.h"
-// for perftools_pthread_key_create
-#include "maybe_threads.h"
-#endif
-
-#include "base/dynamic_annotations.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "maybe_threads.h"
-
-using std::list;
-using std::string;
-
-// This structure is used by ProfileHandlerRegisterCallback and
-// ProfileHandlerUnregisterCallback as a handle to a registered callback.
-struct ProfileHandlerToken {
-  // Sets the callback and associated arg.
-  ProfileHandlerToken(ProfileHandlerCallback cb, void* cb_arg)
-      : callback(cb),
-        callback_arg(cb_arg) {
-  }
-
-  // Callback function to be invoked on receiving a profile timer interrupt.
-  ProfileHandlerCallback callback;
-  // Argument for the callback function.
-  void* callback_arg;
-};
-
-// Blocks a signal from being delivered to the current thread while the object
-// is alive. Unblocks it upon destruction.
-class ScopedSignalBlocker {
- public:
-  ScopedSignalBlocker(int signo) {
-    sigemptyset(&sig_set_);
-    sigaddset(&sig_set_, signo);
-    RAW_CHECK(sigprocmask(SIG_BLOCK, &sig_set_, NULL) == 0,
-              "sigprocmask (block)");
-  }
-  ~ScopedSignalBlocker() {
-    RAW_CHECK(sigprocmask(SIG_UNBLOCK, &sig_set_, NULL) == 0,
-              "sigprocmask (unblock)");
-  }
-
- private:
-  sigset_t sig_set_;
-};
-
-// This class manages profile timers and associated signal handler. This is a
-// a singleton.
-class ProfileHandler {
- public:
-  // Registers the current thread with the profile handler.
-  void RegisterThread();
-
-  // Registers a callback routine to receive profile timer ticks. The returned
-  // token is to be used when unregistering this callback and must not be
-  // deleted by the caller.
-  ProfileHandlerToken* RegisterCallback(ProfileHandlerCallback callback,
-                                        void* callback_arg);
-
-  // Unregisters a previously registered callback. Expects the token returned
-  // by the corresponding RegisterCallback routine.
-  void UnregisterCallback(ProfileHandlerToken* token)
-      NO_THREAD_SAFETY_ANALYSIS;
-
-  // Unregisters all the callbacks and stops the timer(s).
-  void Reset();
-
-  // Gets the current state of profile handler.
-  void GetState(ProfileHandlerState* state);
-
-  // Initializes and returns the ProfileHandler singleton.
-  static ProfileHandler* Instance();
-
-  ProfileHandler(const ProfileHandler&) = delete;
-  ProfileHandler& operator=(const ProfileHandler&) = delete;
-
- private:
-  ProfileHandler();
-  ~ProfileHandler();
-
-  // Largest allowed frequency.
-  static const int32 kMaxFrequency = 4000;
-  // Default frequency.
-  static const int32 kDefaultFrequency = 100;
-
-  // ProfileHandler singleton.
-  static ProfileHandler* instance_;
-
-  // pthread_once_t for one time initialization of ProfileHandler singleton.
-  static pthread_once_t once_;
-
-  // Initializes the ProfileHandler singleton via GoogleOnceInit.
-  static void Init();
-
-  // Timer state as configured previously.
-  bool timer_running_;
-
-  // The number of profiling signal interrupts received.
-  int64 interrupts_ GUARDED_BY(signal_lock_);
-
-  // Profiling signal interrupt frequency, read-only after construction.
-  int32 frequency_;
-
-  // ITIMER_PROF (which uses SIGPROF), or ITIMER_REAL (which uses SIGALRM).
-  // Translated into an equivalent choice of clock if per_thread_timer_enabled_
-  // is true.
-  int timer_type_;
-
-  // Signal number for timer signal.
-  int signal_number_;
-
-  // Counts the number of callbacks registered.
-  int32 callback_count_ GUARDED_BY(control_lock_);
-
-  // Is profiling allowed at all?
-  bool allowed_;
-
-  // Must be false if HAVE_LINUX_SIGEV_THREAD_ID is not defined.
-  bool per_thread_timer_enabled_;
-
-#ifdef HAVE_LINUX_SIGEV_THREAD_ID
-  // this is used to destroy per-thread profiling timers on thread
-  // termination
-  pthread_key_t thread_timer_key;
-#endif
-
-  // This lock serializes the registration of threads and protects the
-  // callbacks_ list below.
-  // Locking order:
-  // In the context of a signal handler, acquire signal_lock_ to walk the
-  // callback list. Otherwise, acquire control_lock_, disable the signal
-  // handler and then acquire signal_lock_.
-  SpinLock control_lock_ ACQUIRED_BEFORE(signal_lock_);
-  SpinLock signal_lock_;
-
-  // Holds the list of registered callbacks. We expect the list to be pretty
-  // small. Currently, the cpu profiler (base/profiler) and thread module
-  // (base/thread.h) are the only two components registering callbacks.
-  // Following are the locking requirements for callbacks_:
-  // For read-write access outside the SIGPROF handler:
-  //  - Acquire control_lock_
-  //  - Disable SIGPROF handler.
-  //  - Acquire signal_lock_
-  // For read-only access in the context of SIGPROF handler
-  // (Read-write access is *not allowed* in the SIGPROF handler)
-  //  - Acquire signal_lock_
-  // For read-only access outside SIGPROF handler:
-  //  - Acquire control_lock_
-  typedef list<ProfileHandlerToken*> CallbackList;
-  typedef CallbackList::iterator CallbackIterator;
-  CallbackList callbacks_ GUARDED_BY(signal_lock_);
-
-  // Starts or stops the interval timer.
-  // Will ignore any requests to enable or disable when
-  // per_thread_timer_enabled_ is true.
-  void UpdateTimer(bool enable) EXCLUSIVE_LOCKS_REQUIRED(signal_lock_);
-
-  // Returns true if the handler is not being used by something else.
-  // This checks the kernel's signal handler table.
-  bool IsSignalHandlerAvailable();
-
-  // Signal handler. Iterates over and calls all the registered callbacks.
-  static void SignalHandler(int sig, siginfo_t* sinfo, void* ucontext);
-};
-
-ProfileHandler* ProfileHandler::instance_ = NULL;
-pthread_once_t ProfileHandler::once_ = PTHREAD_ONCE_INIT;
-
-const int32 ProfileHandler::kMaxFrequency;
-const int32 ProfileHandler::kDefaultFrequency;
-
-// If we are LD_PRELOAD-ed against a non-pthreads app, then these functions
-// won't be defined.  We declare them here, for that case (with weak linkage)
-// which will cause the non-definition to resolve to NULL.  We can then check
-// for NULL or not in Instance.
-extern "C" {
-int pthread_once(pthread_once_t *, void (*)(void)) ATTRIBUTE_WEAK;
-int pthread_kill(pthread_t thread_id, int signo) ATTRIBUTE_WEAK;
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-int timer_create(clockid_t clockid, struct sigevent* evp,
-                 timer_t* timerid) ATTRIBUTE_WEAK;
-int timer_delete(timer_t timerid) ATTRIBUTE_WEAK;
-int timer_settime(timer_t timerid, int flags, const struct itimerspec* value,
-                  struct itimerspec* ovalue) ATTRIBUTE_WEAK;
-#endif
-}
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-
-struct timer_id_holder {
-  timer_t timerid;
-  timer_id_holder(timer_t _timerid) : timerid(_timerid) {}
-};
-
-extern "C" {
-  static void ThreadTimerDestructor(void *arg) {
-    if (!arg) {
-      return;
-    }
-    timer_id_holder *holder = static_cast<timer_id_holder *>(arg);
-    timer_delete(holder->timerid);
-    delete holder;
-  }
-}
-
-static void CreateThreadTimerKey(pthread_key_t *pkey) {
-  int rv = perftools_pthread_key_create(pkey, ThreadTimerDestructor);
-  if (rv) {
-    RAW_LOG(FATAL, "aborting due to pthread_key_create error: %s", strerror(rv));
-  }
-}
-
-static void StartLinuxThreadTimer(int timer_type, int signal_number,
-                                  int32 frequency, pthread_key_t timer_key) {
-  int rv;
-  struct sigevent sevp;
-  timer_t timerid;
-  struct itimerspec its;
-  memset(&sevp, 0, sizeof(sevp));
-  sevp.sigev_notify = SIGEV_THREAD_ID;
-  sevp._sigev_un._tid = sys_gettid();
-  sevp.sigev_signo = signal_number;
-  clockid_t clock = CLOCK_THREAD_CPUTIME_ID;
-  if (timer_type == ITIMER_REAL) {
-    clock = CLOCK_MONOTONIC;
-  }
-  rv = timer_create(clock, &sevp, &timerid);
-  if (rv) {
-    RAW_LOG(FATAL, "aborting due to timer_create error: %s", strerror(errno));
-  }
-
-  timer_id_holder *holder = new timer_id_holder(timerid);
-  rv = perftools_pthread_setspecific(timer_key, holder);
-  if (rv) {
-    RAW_LOG(FATAL, "aborting due to pthread_setspecific error: %s", strerror(rv));
-  }
-
-  its.it_interval.tv_sec = 0;
-  its.it_interval.tv_nsec = 1000000000 / frequency;
-  its.it_value = its.it_interval;
-  rv = timer_settime(timerid, 0, &its, 0);
-  if (rv) {
-    RAW_LOG(FATAL, "aborting due to timer_settime error: %s", strerror(errno));
-  }
-}
-#endif
-
-void ProfileHandler::Init() {
-  instance_ = new ProfileHandler();
-}
-
-ProfileHandler* ProfileHandler::Instance() {
-  if (pthread_once) {
-    pthread_once(&once_, Init);
-  }
-  if (instance_ == NULL) {
-    // This will be true on systems that don't link in pthreads,
-    // including on FreeBSD where pthread_once has a non-zero address
-    // (but doesn't do anything) even when pthreads isn't linked in.
-    Init();
-    assert(instance_ != NULL);
-  }
-  return instance_;
-}
-
-ProfileHandler::ProfileHandler()
-    : timer_running_(false),
-      interrupts_(0),
-      callback_count_(0),
-      allowed_(true),
-      per_thread_timer_enabled_(false) {
-  SpinLockHolder cl(&control_lock_);
-
-  timer_type_ = (getenv("CPUPROFILE_REALTIME") ? ITIMER_REAL : ITIMER_PROF);
-  signal_number_ = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
-
-  // Get frequency of interrupts (if specified)
-  char junk;
-  const char* fr = getenv("CPUPROFILE_FREQUENCY");
-  if (fr != NULL && (sscanf(fr, "%u%c", &frequency_, &junk) == 1) &&
-      (frequency_ > 0)) {
-    // Limit to kMaxFrequency
-    frequency_ = (frequency_ > kMaxFrequency) ? kMaxFrequency : frequency_;
-  } else {
-    frequency_ = kDefaultFrequency;
-  }
-
-  if (!allowed_) {
-    return;
-  }
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-  // Do this early because we might be overriding signal number.
-
-  const char *per_thread = getenv("CPUPROFILE_PER_THREAD_TIMERS");
-  const char *signal_number = getenv("CPUPROFILE_TIMER_SIGNAL");
-
-  if (per_thread || signal_number) {
-    if (timer_create && pthread_once) {
-      CreateThreadTimerKey(&thread_timer_key);
-      per_thread_timer_enabled_ = true;
-      // Override signal number if requested.
-      if (signal_number) {
-        signal_number_ = strtol(signal_number, NULL, 0);
-      }
-    } else {
-      RAW_LOG(INFO,
-              "Ignoring CPUPROFILE_PER_THREAD_TIMERS and\n"
-              " CPUPROFILE_TIMER_SIGNAL due to lack of timer_create().\n"
-              " Preload or link to librt.so for this to work");
-    }
-  }
-#endif
-
-  // If something else is using the signal handler,
-  // assume it has priority over us and stop.
-  if (!IsSignalHandlerAvailable()) {
-    RAW_LOG(INFO, "Disabling profiler because signal %d handler is already in use.",
-            signal_number_);
-    allowed_ = false;
-    return;
-  }
-
-  // Install the signal handler.
-  struct sigaction sa;
-  sa.sa_sigaction = SignalHandler;
-  sa.sa_flags = SA_RESTART | SA_SIGINFO;
-  sigemptyset(&sa.sa_mask);
-  RAW_CHECK(sigaction(signal_number_, &sa, NULL) == 0, "sigprof (enable)");
-}
-
-ProfileHandler::~ProfileHandler() {
-  Reset();
-#ifdef HAVE_LINUX_SIGEV_THREAD_ID
-  if (per_thread_timer_enabled_) {
-    perftools_pthread_key_delete(thread_timer_key);
-  }
-#endif
-}
-
-void ProfileHandler::RegisterThread() {
-  SpinLockHolder cl(&control_lock_);
-
-  if (!allowed_) {
-    return;
-  }
-
-  // Record the thread identifier and start the timer if profiling is on.
-  ScopedSignalBlocker block(signal_number_);
-  SpinLockHolder sl(&signal_lock_);
-#if HAVE_LINUX_SIGEV_THREAD_ID
-  if (per_thread_timer_enabled_) {
-    StartLinuxThreadTimer(timer_type_, signal_number_, frequency_,
-                          thread_timer_key);
-    return;
-  }
-#endif
-  UpdateTimer(callback_count_ > 0);
-}
-
-ProfileHandlerToken* ProfileHandler::RegisterCallback(
-    ProfileHandlerCallback callback, void* callback_arg) {
-
-  ProfileHandlerToken* token = new ProfileHandlerToken(callback, callback_arg);
-
-  SpinLockHolder cl(&control_lock_);
-  {
-    ScopedSignalBlocker block(signal_number_);
-    SpinLockHolder sl(&signal_lock_);
-    callbacks_.push_back(token);
-    ++callback_count_;
-    UpdateTimer(true);
-  }
-  return token;
-}
-
-void ProfileHandler::UnregisterCallback(ProfileHandlerToken* token) {
-  SpinLockHolder cl(&control_lock_);
-  for (CallbackIterator it = callbacks_.begin(); it != callbacks_.end();
-       ++it) {
-    if ((*it) == token) {
-      RAW_CHECK(callback_count_ > 0, "Invalid callback count");
-      {
-        ScopedSignalBlocker block(signal_number_);
-        SpinLockHolder sl(&signal_lock_);
-        delete *it;
-        callbacks_.erase(it);
-        --callback_count_;
-        if (callback_count_ == 0)
-          UpdateTimer(false);
-      }
-      return;
-    }
-  }
-  // Unknown token.
-  RAW_LOG(FATAL, "Invalid token");
-}
-
-void ProfileHandler::Reset() {
-  SpinLockHolder cl(&control_lock_);
-  {
-    ScopedSignalBlocker block(signal_number_);
-    SpinLockHolder sl(&signal_lock_);
-    CallbackIterator it = callbacks_.begin();
-    while (it != callbacks_.end()) {
-      CallbackIterator tmp = it;
-      ++it;
-      delete *tmp;
-      callbacks_.erase(tmp);
-    }
-    callback_count_ = 0;
-    UpdateTimer(false);
-  }
-}
-
-void ProfileHandler::GetState(ProfileHandlerState* state) {
-  SpinLockHolder cl(&control_lock_);
-  {
-    ScopedSignalBlocker block(signal_number_);
-    SpinLockHolder sl(&signal_lock_);  // Protects interrupts_.
-    state->interrupts = interrupts_;
-  }
-  state->frequency = frequency_;
-  state->callback_count = callback_count_;
-  state->allowed = allowed_;
-}
-
-void ProfileHandler::UpdateTimer(bool enable) {
-  if (per_thread_timer_enabled_) {
-    // Ignore any attempts to disable it because that's not supported, and it's
-    // always enabled so enabling is always a NOP.
-    return;
-  }
-
-  if (enable == timer_running_) {
-    return;
-  }
-  timer_running_ = enable;
-
-  struct itimerval timer;
-  static const int kMillion = 1000000;
-  int interval_usec = enable ? kMillion / frequency_ : 0;
-  timer.it_interval.tv_sec = interval_usec / kMillion;
-  timer.it_interval.tv_usec = interval_usec % kMillion;
-  timer.it_value = timer.it_interval;
-  setitimer(timer_type_, &timer, 0);
-}
-
-bool ProfileHandler::IsSignalHandlerAvailable() {
-  struct sigaction sa;
-  RAW_CHECK(sigaction(signal_number_, NULL, &sa) == 0, "is-signal-handler avail");
-
-  // We only take over the handler if the current one is unset.
-  // It must be SIG_IGN or SIG_DFL, not some other function.
-  // SIG_IGN must be allowed because when profiling is allowed but
-  // not actively in use, this code keeps the handler set to SIG_IGN.
-  // That setting will be inherited across fork+exec.  In order for
-  // any child to be able to use profiling, SIG_IGN must be treated
-  // as available.
-  return sa.sa_handler == SIG_IGN || sa.sa_handler == SIG_DFL;
-}
-
-void ProfileHandler::SignalHandler(int sig, siginfo_t* sinfo, void* ucontext) {
-  int saved_errno = errno;
-  // At this moment, instance_ must be initialized because the handler is
-  // enabled in RegisterThread or RegisterCallback only after
-  // ProfileHandler::Instance runs.
-  ProfileHandler* instance = ANNOTATE_UNPROTECTED_READ(instance_);
-  RAW_CHECK(instance != NULL, "ProfileHandler is not initialized");
-  {
-    SpinLockHolder sl(&instance->signal_lock_);
-    ++instance->interrupts_;
-    for (CallbackIterator it = instance->callbacks_.begin();
-         it != instance->callbacks_.end();
-         ++it) {
-      (*it)->callback(sig, sinfo, ucontext, (*it)->callback_arg);
-    }
-  }
-  errno = saved_errno;
-}
-
-// This module initializer registers the main thread, so it must be
-// executed in the context of the main thread.
-REGISTER_MODULE_INITIALIZER(profile_main, ProfileHandlerRegisterThread());
-
-void ProfileHandlerRegisterThread() {
-  ProfileHandler::Instance()->RegisterThread();
-}
-
-ProfileHandlerToken* ProfileHandlerRegisterCallback(
-    ProfileHandlerCallback callback, void* callback_arg) {
-  return ProfileHandler::Instance()->RegisterCallback(callback, callback_arg);
-}
-
-void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token) {
-  ProfileHandler::Instance()->UnregisterCallback(token);
-}
-
-void ProfileHandlerReset() {
-  return ProfileHandler::Instance()->Reset();
-}
-
-void ProfileHandlerGetState(ProfileHandlerState* state) {
-  ProfileHandler::Instance()->GetState(state);
-}
-
-#else  // OS_CYGWIN
-
-// ITIMER_PROF doesn't work under cygwin.  ITIMER_REAL is available, but doesn't
-// work as well for profiling, and also interferes with alarm().  Because of
-// these issues, unless a specific need is identified, profiler support is
-// disabled under Cygwin.
-void ProfileHandlerRegisterThread() {
-}
-
-ProfileHandlerToken* ProfileHandlerRegisterCallback(
-    ProfileHandlerCallback callback, void* callback_arg) {
-  return NULL;
-}
-
-void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token) {
-}
-
-void ProfileHandlerReset() {
-}
-
-void ProfileHandlerGetState(ProfileHandlerState* state) {
-}
-
-#endif  // OS_CYGWIN
diff --git a/third_party/tcmalloc/chromium/src/profile-handler.h b/third_party/tcmalloc/chromium/src/profile-handler.h
deleted file mode 100644
index 3eae169..0000000
--- a/third_party/tcmalloc/chromium/src/profile-handler.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Nabeel Mian
- *
- * This module manages the cpu profile timers and the associated interrupt
- * handler. When enabled, all threads in the program are profiled.
- *
- * Any component interested in receiving a profile timer interrupt can do so by
- * registering a callback. All registered callbacks must be async-signal-safe.
- *
- * Note: This module requires the sole ownership of the configured timer and
- * signal. The timer defaults to ITIMER_PROF, can be changed to ITIMER_REAL by
- * the environment variable CPUPROFILE_REALTIME, or is changed to a POSIX timer
- * with CPUPROFILE_PER_THREAD_TIMERS. The signal defaults to SIGPROF/SIGALRM to
- * match the choice of timer and can be set to an arbitrary value using
- * CPUPROFILE_TIMER_SIGNAL with CPUPROFILE_PER_THREAD_TIMERS.
- */
-
-#ifndef BASE_PROFILE_HANDLER_H_
-#define BASE_PROFILE_HANDLER_H_
-
-#include "config.h"
-#include <signal.h>
-#ifdef COMPILER_MSVC
-#include "conflict-signal.h"
-#endif
-#include "base/basictypes.h"
-
-/* Forward declaration. */
-struct ProfileHandlerToken;
-
-/*
- * Callback function to be used with ProfilefHandlerRegisterCallback. This
- * function will be called in the context of SIGPROF signal handler and must
- * be async-signal-safe. The first three arguments are the values provided by
- * the SIGPROF signal handler. We use void* to avoid using ucontext_t on
- * non-POSIX systems.
- *
- * Requirements:
- * - Callback must be async-signal-safe.
- * - None of the functions in ProfileHandler are async-signal-safe. Therefore,
- *   callback function *must* not call any of the ProfileHandler functions.
- * - Callback is not required to be re-entrant. At most one instance of
- *   callback can run at a time.
- *
- * Notes:
- * - The SIGPROF signal handler saves and restores errno, so the callback
- *   doesn't need to.
- * - Callback code *must* not acquire lock(s) to serialize access to data shared
- *   with the code outside the signal handler (callback must be
- *   async-signal-safe). If such a serialization is needed, follow the model
- *   used by profiler.cc:
- *
- *   When code other than the signal handler modifies the shared data it must:
- *   - Acquire lock.
- *   - Unregister the callback with the ProfileHandler.
- *   - Modify shared data.
- *   - Re-register the callback.
- *   - Release lock.
- *   and the callback code gets a lockless, read-write access to the data.
- */
-typedef void (*ProfileHandlerCallback)(int sig, siginfo_t* sig_info,
-                                       void* ucontext, void* callback_arg);
-
-/*
- * Registers a new thread with profile handler and should be called only once
- * per thread. The main thread is registered at program startup. This routine
- * is called by the Thread module in google3/thread whenever a new thread is
- * created. This function is not async-signal-safe.
- */
-void ProfileHandlerRegisterThread();
-
-/*
- * Registers a callback routine. This callback function will be called in the
- * context of SIGPROF handler, so must be async-signal-safe. The returned token
- * is to be used when unregistering this callback via
- * ProfileHandlerUnregisterCallback. Registering the first callback enables
- * the SIGPROF signal handler. Caller must not free the returned token. This
- * function is not async-signal-safe.
- */
-ProfileHandlerToken* ProfileHandlerRegisterCallback(
-    ProfileHandlerCallback callback, void* callback_arg);
-
-/*
- * Unregisters a previously registered callback. Expects the token returned
- * by the corresponding ProfileHandlerRegisterCallback and asserts that the
- * passed token is valid. Unregistering the last callback disables the SIGPROF
- * signal handler. It waits for the currently running callback to
- * complete before returning. This function is not async-signal-safe.
- */
-void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token);
-
-/*
- * FOR TESTING ONLY
- * Unregisters all the callbacks, stops the timers (if shared) and disables the
- * SIGPROF handler. All the threads, including the main thread, need to be
- * re-registered after this call. This function is not async-signal-safe.
- */
-void ProfileHandlerReset();
-
-/*
- * Stores profile handler's current state. This function is not
- * async-signal-safe.
- */
-struct ProfileHandlerState {
-  int32 frequency;  /* Profiling frequency */
-  int32 callback_count;  /* Number of callbacks registered */
-  int64 interrupts;  /* Number of interrupts received */
-  bool allowed; /* Profiling is allowed */
-};
-void ProfileHandlerGetState(struct ProfileHandlerState* state);
-
-#endif  /* BASE_PROFILE_HANDLER_H_ */
diff --git a/third_party/tcmalloc/chromium/src/profiledata.cc b/third_party/tcmalloc/chromium/src/profiledata.cc
deleted file mode 100644
index 8b05d3a..0000000
--- a/third_party/tcmalloc/chromium/src/profiledata.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Sanjay Ghemawat
-//         Chris Demetriou (refactoring)
-//
-// Collect profiling data.
-
-#include <config.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <sys/time.h>
-#include <string.h>
-#include <fcntl.h>
-
-#include "profiledata.h"
-
-#include "base/logging.h"
-#include "base/sysinfo.h"
-
-// All of these are initialized in profiledata.h.
-const int ProfileData::kMaxStackDepth;
-const int ProfileData::kAssociativity;
-const int ProfileData::kBuckets;
-const int ProfileData::kBufferLength;
-
-ProfileData::Options::Options()
-    : frequency_(1) {
-}
-
-// This function is safe to call from asynchronous signals (but is not
-// re-entrant).  However, that's not part of its public interface.
-void ProfileData::Evict(const Entry& entry) {
-  const int d = entry.depth;
-  const int nslots = d + 2;     // Number of slots needed in eviction buffer
-  if (num_evicted_ + nslots > kBufferLength) {
-    FlushEvicted();
-    assert(num_evicted_ == 0);
-    assert(nslots <= kBufferLength);
-  }
-  evict_[num_evicted_++] = entry.count;
-  evict_[num_evicted_++] = d;
-  memcpy(&evict_[num_evicted_], entry.stack, d * sizeof(Slot));
-  num_evicted_ += d;
-}
-
-ProfileData::ProfileData()
-    : hash_(0),
-      evict_(0),
-      num_evicted_(0),
-      out_(-1),
-      count_(0),
-      evictions_(0),
-      total_bytes_(0),
-      fname_(0),
-      start_time_(0) {
-}
-
-bool ProfileData::Start(const char* fname,
-                        const ProfileData::Options& options) {
-  if (enabled()) {
-    return false;
-  }
-
-  // Open output file and initialize various data structures
-  int fd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0666);
-  if (fd < 0) {
-    // Can't open outfile for write
-    return false;
-  }
-
-  start_time_ = time(NULL);
-  fname_ = strdup(fname);
-
-  // Reset counters
-  num_evicted_ = 0;
-  count_       = 0;
-  evictions_   = 0;
-  total_bytes_ = 0;
-
-  hash_ = new Bucket[kBuckets];
-  evict_ = new Slot[kBufferLength];
-  memset(hash_, 0, sizeof(hash_[0]) * kBuckets);
-
-  // Record special entries
-  evict_[num_evicted_++] = 0;                     // count for header
-  evict_[num_evicted_++] = 3;                     // depth for header
-  evict_[num_evicted_++] = 0;                     // Version number
-  CHECK_NE(0, options.frequency());
-  int period = 1000000 / options.frequency();
-  evict_[num_evicted_++] = period;                // Period (microseconds)
-  evict_[num_evicted_++] = 0;                     // Padding
-
-  out_ = fd;
-
-  return true;
-}
-
-ProfileData::~ProfileData() {
-  Stop();
-}
-
-// Dump /proc/maps data to fd.  Copied from heap-profile-table.cc.
-#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)
-
-static void FDWrite(int fd, const char* buf, size_t len) {
-  while (len > 0) {
-    ssize_t r;
-    NO_INTR(r = write(fd, buf, len));
-    RAW_CHECK(r >= 0, "write failed");
-    buf += r;
-    len -= r;
-  }
-}
-
-static void DumpProcSelfMaps(int fd) {
-  ProcMapsIterator::Buffer iterbuf;
-  ProcMapsIterator it(0, &iterbuf);   // 0 means "current pid"
-
-  uint64 start, end, offset;
-  int64 inode;
-  char *flags, *filename;
-  ProcMapsIterator::Buffer linebuf;
-  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
-    int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_),
-                                start, end, flags, offset, inode, filename,
-                                0);
-    FDWrite(fd, linebuf.buf_, written);
-  }
-}
-
-void ProfileData::Stop() {
-  if (!enabled()) {
-    return;
-  }
-
-  // Move data from hash table to eviction buffer
-  for (int b = 0; b < kBuckets; b++) {
-    Bucket* bucket = &hash_[b];
-    for (int a = 0; a < kAssociativity; a++) {
-      if (bucket->entry[a].count > 0) {
-        Evict(bucket->entry[a]);
-      }
-    }
-  }
-
-  if (num_evicted_ + 3 > kBufferLength) {
-    // Ensure there is enough room for end of data marker
-    FlushEvicted();
-  }
-
-  // Write end of data marker
-  evict_[num_evicted_++] = 0;         // count
-  evict_[num_evicted_++] = 1;         // depth
-  evict_[num_evicted_++] = 0;         // end of data marker
-  FlushEvicted();
-
-  // Dump "/proc/self/maps" so we get list of mapped shared libraries
-  DumpProcSelfMaps(out_);
-
-  Reset();
-  fprintf(stderr, "PROFILE: interrupts/evictions/bytes = %d/%d/%" PRIuS "\n",
-          count_, evictions_, total_bytes_);
-}
-
-void ProfileData::Reset() {
-  if (!enabled()) {
-    return;
-  }
-
-  // Don't reset count_, evictions_, or total_bytes_ here.  They're used
-  // by Stop to print information about the profile after reset, and are
-  // cleared by Start when starting a new profile.
-  close(out_);
-  delete[] hash_;
-  hash_ = 0;
-  delete[] evict_;
-  evict_ = 0;
-  num_evicted_ = 0;
-  free(fname_);
-  fname_ = 0;
-  start_time_ = 0;
-
-  out_ = -1;
-}
-
-// This function is safe to call from asynchronous signals (but is not
-// re-entrant).  However, that's not part of its public interface.
-void ProfileData::GetCurrentState(State* state) const {
-  if (enabled()) {
-    state->enabled = true;
-    state->start_time = start_time_;
-    state->samples_gathered = count_;
-    int buf_size = sizeof(state->profile_name);
-    strncpy(state->profile_name, fname_, buf_size);
-    state->profile_name[buf_size-1] = '\0';
-  } else {
-    state->enabled = false;
-    state->start_time = 0;
-    state->samples_gathered = 0;
-    state->profile_name[0] = '\0';
-  }
-}
-
-// This function is safe to call from asynchronous signals (but is not
-// re-entrant).  However, that's not part of its public interface.
-void ProfileData::FlushTable() {
-  if (!enabled()) {
-    return;
-  }
-
-  // Move data from hash table to eviction buffer
-  for (int b = 0; b < kBuckets; b++) {
-    Bucket* bucket = &hash_[b];
-    for (int a = 0; a < kAssociativity; a++) {
-      if (bucket->entry[a].count > 0) {
-        Evict(bucket->entry[a]);
-        bucket->entry[a].depth = 0;
-        bucket->entry[a].count = 0;
-      }
-    }
-  }
-
-  // Write out all pending data
-  FlushEvicted();
-}
-
-void ProfileData::Add(int depth, const void* const* stack) {
-  if (!enabled()) {
-    return;
-  }
-
-  if (depth > kMaxStackDepth) depth = kMaxStackDepth;
-  RAW_CHECK(depth > 0, "ProfileData::Add depth <= 0");
-
-  // Make hash-value
-  Slot h = 0;
-  for (int i = 0; i < depth; i++) {
-    Slot slot = reinterpret_cast<Slot>(stack[i]);
-    h = (h << 8) | (h >> (8*(sizeof(h)-1)));
-    h += (slot * 31) + (slot * 7) + (slot * 3);
-  }
-
-  count_++;
-
-  // See if table already has an entry for this trace
-  bool done = false;
-  Bucket* bucket = &hash_[h % kBuckets];
-  for (int a = 0; a < kAssociativity; a++) {
-    Entry* e = &bucket->entry[a];
-    if (e->depth == depth) {
-      bool match = true;
-      for (int i = 0; i < depth; i++) {
-        if (e->stack[i] != reinterpret_cast<Slot>(stack[i])) {
-          match = false;
-          break;
-        }
-      }
-      if (match) {
-        e->count++;
-        done = true;
-        break;
-      }
-    }
-  }
-
-  if (!done) {
-    // Evict entry with smallest count
-    Entry* e = &bucket->entry[0];
-    for (int a = 1; a < kAssociativity; a++) {
-      if (bucket->entry[a].count < e->count) {
-        e = &bucket->entry[a];
-      }
-    }
-    if (e->count > 0) {
-      evictions_++;
-      Evict(*e);
-    }
-
-    // Use the newly evicted entry
-    e->depth = depth;
-    e->count = 1;
-    for (int i = 0; i < depth; i++) {
-      e->stack[i] = reinterpret_cast<Slot>(stack[i]);
-    }
-  }
-}
-
-// This function is safe to call from asynchronous signals (but is not
-// re-entrant).  However, that's not part of its public interface.
-void ProfileData::FlushEvicted() {
-  if (num_evicted_ > 0) {
-    const char* buf = reinterpret_cast<char*>(evict_);
-    size_t bytes = sizeof(evict_[0]) * num_evicted_;
-    total_bytes_ += bytes;
-    FDWrite(out_, buf, bytes);
-  }
-  num_evicted_ = 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/profiledata.h b/third_party/tcmalloc/chromium/src/profiledata.h
deleted file mode 100644
index 18acf50..0000000
--- a/third_party/tcmalloc/chromium/src/profiledata.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Sanjay Ghemawat
-//         Chris Demetriou (refactoring)
-//
-// Collect profiling data.
-//
-// The profile data file format is documented in
-// docs/cpuprofile-fileformat.html
-
-
-#ifndef BASE_PROFILEDATA_H_
-#define BASE_PROFILEDATA_H_
-
-#include <config.h>
-#include <time.h>   // for time_t
-#include <stdint.h>
-#include "base/basictypes.h"
-
-// A class that accumulates profile samples and writes them to a file.
-//
-// Each sample contains a stack trace and a count.  Memory usage is
-// reduced by combining profile samples that have the same stack trace
-// by adding up the associated counts.
-//
-// Profile data is accumulated in a bounded amount of memory, and will
-// flushed to a file as necessary to stay within the memory limit.
-//
-// Use of this class assumes external synchronization.  The exact
-// requirements of that synchronization are that:
-//
-//  - 'Add' may be called from asynchronous signals, but is not
-//    re-entrant.
-//
-//  - None of 'Start', 'Stop', 'Reset', 'Flush', and 'Add' may be
-//    called at the same time.
-//
-//  - 'Start', 'Stop', or 'Reset' should not be called while 'Enabled'
-//     or 'GetCurrent' are running, and vice versa.
-//
-// A profiler which uses asyncronous signals to add samples will
-// typically use two locks to protect this data structure:
-//
-//  - A SpinLock which is held over all calls except for the 'Add'
-//    call made from the signal handler.
-//
-//  - A SpinLock which is held over calls to 'Start', 'Stop', 'Reset',
-//    'Flush', and 'Add'.  (This SpinLock should be acquired after
-//    the first SpinLock in all cases where both are needed.)
-class ProfileData {
- public:
-  struct State {
-    bool     enabled;             // Is profiling currently enabled?
-    time_t   start_time;          // If enabled, when was profiling started?
-    char     profile_name[1024];  // Name of file being written, or '\0'
-    int      samples_gathered;    // Number of samples gathered to far (or 0)
-  };
-
-  class Options {
-   public:
-    Options();
-
-    // Get and set the sample frequency.
-    int frequency() const {
-      return frequency_;
-    }
-    void set_frequency(int frequency) {
-      frequency_ = frequency;
-    }
-
-   private:
-    int      frequency_;                  // Sample frequency.
-  };
-
-  static const int kMaxStackDepth = 64;  // Max stack depth stored in profile
-
-  ProfileData();
-
-  ProfileData(const ProfileData&) = delete;
-  ProfileData& operator=(const ProfileData&) = delete;
-
-  ~ProfileData();
-
-  // If data collection is not already enabled start to collect data
-  // into fname.  Parameters related to this profiling run are specified
-  // by 'options'.
-  //
-  // Returns true if data collection could be started, otherwise (if an
-  // error occurred or if data collection was already enabled) returns
-  // false.
-  bool Start(const char *fname, const Options& options);
-
-  // If data collection is enabled, stop data collection and write the
-  // data to disk.
-  void Stop();
-
-  // Stop data collection without writing anything else to disk, and
-  // discard any collected data.
-  void Reset();
-
-  // If data collection is enabled, record a sample with 'depth'
-  // entries from 'stack'.  (depth must be > 0.)  At most
-  // kMaxStackDepth stack entries will be recorded, starting with
-  // stack[0].
-  //
-  // This function is safe to call from asynchronous signals (but is
-  // not re-entrant).
-  void Add(int depth, const void* const* stack);
-
-  // If data collection is enabled, write the data to disk (and leave
-  // the collector enabled).
-  void FlushTable();
-
-  // Is data collection currently enabled?
-  bool enabled() const { return out_ >= 0; }
-
-  // Get the current state of the data collector.
-  void GetCurrentState(State* state) const;
-
- private:
-  static const int kAssociativity = 4;          // For hashtable
-  static const int kBuckets = 1 << 10;          // For hashtable
-  static const int kBufferLength = 1 << 18;     // For eviction buffer
-
-  // Type of slots: each slot can be either a count, or a PC value
-  typedef uintptr_t Slot;
-
-  // Hash-table/eviction-buffer entry (a.k.a. a sample)
-  struct Entry {
-    Slot count;                  // Number of hits
-    Slot depth;                  // Stack depth
-    Slot stack[kMaxStackDepth];  // Stack contents
-  };
-
-  // Hash table bucket
-  struct Bucket {
-    Entry entry[kAssociativity];
-  };
-
-  Bucket*       hash_;          // hash table
-  Slot*         evict_;         // evicted entries
-  int           num_evicted_;   // how many evicted entries?
-  int           out_;           // fd for output file.
-  int           count_;         // How many samples recorded
-  int           evictions_;     // How many evictions
-  size_t        total_bytes_;   // How much output
-  char*         fname_;         // Profile file name
-  time_t        start_time_;    // Start time, or 0
-
-  // Move 'entry' to the eviction buffer.
-  void Evict(const Entry& entry);
-
-  // Write contents of eviction buffer to disk.
-  void FlushEvicted();
-};
-
-#endif  // BASE_PROFILEDATA_H_
diff --git a/third_party/tcmalloc/chromium/src/profiler.cc b/third_party/tcmalloc/chromium/src/profiler.cc
deleted file mode 100644
index f4f5990..0000000
--- a/third_party/tcmalloc/chromium/src/profiler.cc
+++ /dev/null
@@ -1,431 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//         Chris Demetriou (refactoring)
-//
-// Profile current program by sampling stack-trace every so often
-
-#include "config.h"
-#include "getpc.h"      // should be first to get the _GNU_SOURCE dfn
-#include <signal.h>
-#include <assert.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>  // for getpid()
-#endif
-#if defined(HAVE_SYS_UCONTEXT_H)
-#include <sys/ucontext.h>
-#elif defined(HAVE_UCONTEXT_H)
-#include <ucontext.h>
-#elif defined(HAVE_CYGWIN_SIGNAL_H)
-#include <cygwin/signal.h>
-typedef ucontext ucontext_t;
-#else
-typedef int ucontext_t;   // just to quiet the compiler, mostly
-#endif
-#include <sys/time.h>
-#include <string>
-#include <gperftools/profiler.h>
-#include <gperftools/stacktrace.h>
-#include "base/commandlineflags.h"
-#include "base/logging.h"
-#include "base/googleinit.h"
-#include "base/spinlock.h"
-#include "base/sysinfo.h"             /* for GetUniquePathFromEnv, etc */
-#include "profiledata.h"
-#include "profile-handler.h"
-#ifdef HAVE_CONFLICT_SIGNAL_H
-#include "conflict-signal.h"          /* used on msvc machines */
-#endif
-
-using std::string;
-
-DEFINE_bool(cpu_profiler_unittest,
-            EnvToBool("PERFTOOLS_UNITTEST", true),
-            "Determines whether or not we are running under the \
-             control of a unit test. This allows us to include or \
-			 exclude certain behaviours.");
-
-// Collects up all profile data. This is a singleton, which is
-// initialized by a constructor at startup. If no cpu profiler
-// signal is specified then the profiler lifecycle is either
-// manaully controlled via the API or attached to the scope of
-// the singleton (program scope). Otherwise the cpu toggle is
-// used to allow for user selectable control via signal generation.
-// This is very useful for profiling a daemon process without
-// having to start and stop the daemon or having to modify the
-// source code to use the cpu profiler API.
-class CpuProfiler {
- public:
-  CpuProfiler();
-  ~CpuProfiler();
-
-  // Start profiler to write profile info into fname
-  bool Start(const char* fname, const ProfilerOptions* options);
-
-  // Stop profiling and write the data to disk.
-  void Stop();
-
-  // Write the data to disk (and continue profiling).
-  void FlushTable();
-
-  bool Enabled();
-
-  void GetCurrentState(ProfilerState* state);
-
-  static CpuProfiler instance_;
-
- private:
-  // This lock implements the locking requirements described in the ProfileData
-  // documentation, specifically:
-  //
-  // lock_ is held all over all collector_ method calls except for the 'Add'
-  // call made from the signal handler, to protect against concurrent use of
-  // collector_'s control routines. Code other than signal handler must
-  // unregister the signal handler before calling any collector_ method.
-  // 'Add' method in the collector is protected by a guarantee from
-  // ProfileHandle that only one instance of prof_handler can run at a time.
-  SpinLock      lock_;
-  ProfileData   collector_;
-
-  // Filter function and its argument, if any.  (NULL means include all
-  // samples).  Set at start, read-only while running.  Written while holding
-  // lock_, read and executed in the context of SIGPROF interrupt.
-  int           (*filter_)(void*);
-  void*         filter_arg_;
-
-  // Opaque token returned by the profile handler. To be used when calling
-  // ProfileHandlerUnregisterCallback.
-  ProfileHandlerToken* prof_handler_token_;
-
-  // Sets up a callback to receive SIGPROF interrupt.
-  void EnableHandler();
-
-  // Disables receiving SIGPROF interrupt.
-  void DisableHandler();
-
-  // Signal handler that records the interrupted pc in the profile data.
-  static void prof_handler(int sig, siginfo_t*, void* signal_ucontext,
-                           void* cpu_profiler);
-};
-
-// Signal handler that is registered when a user selectable signal
-// number is defined in the environment variable CPUPROFILESIGNAL.
-static void CpuProfilerSwitch(int signal_number)
-{
-    bool static started = false;
-	static unsigned profile_count = 0;
-    static char base_profile_name[1024] = "\0";
-
-	if (base_profile_name[0] == '\0') {
-    	if (!GetUniquePathFromEnv("CPUPROFILE", base_profile_name)) {
-        	RAW_LOG(FATAL,"Cpu profiler switch is registered but no CPUPROFILE is defined");
-        	return;
-    	}
-	}
-    if (!started) 
-    {
-    	char full_profile_name[1024];
-
-		snprintf(full_profile_name, sizeof(full_profile_name), "%s.%u",
-                 base_profile_name, profile_count++);
-
-        if(!ProfilerStart(full_profile_name))
-        {
-            RAW_LOG(FATAL, "Can't turn on cpu profiling for '%s': %s\n",
-                    full_profile_name, strerror(errno));
-        }
-    }
-    else    
-    {
-        ProfilerStop();
-    }
-    started = !started;
-}
-
-// Profile data structure singleton: Constructor will check to see if
-// profiling should be enabled.  Destructor will write profile data
-// out to disk.
-CpuProfiler CpuProfiler::instance_;
-
-// Initialize profiling: activated if getenv("CPUPROFILE") exists.
-CpuProfiler::CpuProfiler()
-    : prof_handler_token_(NULL) {
-  // TODO(cgd) Move this code *out* of the CpuProfile constructor into a
-  // separate object responsible for initialization. With ProfileHandler there
-  // is no need to limit the number of profilers.
-  if (getenv("CPUPROFILE") == NULL) {
-    if (!FLAGS_cpu_profiler_unittest) {
-      RAW_LOG(WARNING, "CPU profiler linked but no valid CPUPROFILE environment variable found\n");
-    }
-    return;
-  }
-
-  // We don't enable profiling if setuid -- it's a security risk
-#ifdef HAVE_GETEUID
-  if (getuid() != geteuid()) {
-    if (!FLAGS_cpu_profiler_unittest) {
-      RAW_LOG(WARNING, "Cannot perform CPU profiling when running with setuid\n");
-    }
-    return;
-  }
-#endif
-
-  char *signal_number_str = getenv("CPUPROFILESIGNAL");
-  if (signal_number_str != NULL) {
-    long int signal_number = strtol(signal_number_str, NULL, 10);
-    if (signal_number >= 1 && signal_number <= 64) {
-      intptr_t old_signal_handler = reinterpret_cast<intptr_t>(signal(signal_number, CpuProfilerSwitch));
-      if (old_signal_handler == 0) {
-        RAW_LOG(INFO,"Using signal %d as cpu profiling switch", signal_number);
-      } else {
-        RAW_LOG(FATAL, "Signal %d already in use\n", signal_number);
-      }
-    } else {
-      RAW_LOG(FATAL, "Signal number %s is invalid\n", signal_number_str);
-    }
-  } else {
-    char fname[PATH_MAX];
-    if (!GetUniquePathFromEnv("CPUPROFILE", fname)) {
-      if (!FLAGS_cpu_profiler_unittest) {
-        RAW_LOG(WARNING, "CPU profiler linked but no valid CPUPROFILE environment variable found\n");
-      }
-      return;
-	}
-
-    if (!Start(fname, NULL)) {
-      RAW_LOG(FATAL, "Can't turn on cpu profiling for '%s': %s\n",
-              fname, strerror(errno));
-    }
-  }
-}
-
-bool CpuProfiler::Start(const char* fname, const ProfilerOptions* options) {
-  SpinLockHolder cl(&lock_);
-
-  if (collector_.enabled()) {
-    return false;
-  }
-
-  ProfileHandlerState prof_handler_state;
-  ProfileHandlerGetState(&prof_handler_state);
-
-  ProfileData::Options collector_options;
-  collector_options.set_frequency(prof_handler_state.frequency);
-  if (!collector_.Start(fname, collector_options)) {
-    return false;
-  }
-
-  filter_ = NULL;
-  if (options != NULL && options->filter_in_thread != NULL) {
-    filter_ = options->filter_in_thread;
-    filter_arg_ = options->filter_in_thread_arg;
-  }
-
-  // Setup handler for SIGPROF interrupts
-  EnableHandler();
-
-  return true;
-}
-
-CpuProfiler::~CpuProfiler() {
-  Stop();
-}
-
-// Stop profiling and write out any collected profile data
-void CpuProfiler::Stop() {
-  SpinLockHolder cl(&lock_);
-
-  if (!collector_.enabled()) {
-    return;
-  }
-
-  // Unregister prof_handler to stop receiving SIGPROF interrupts before
-  // stopping the collector.
-  DisableHandler();
-
-  // DisableHandler waits for the currently running callback to complete and
-  // guarantees no future invocations. It is safe to stop the collector.
-  collector_.Stop();
-}
-
-void CpuProfiler::FlushTable() {
-  SpinLockHolder cl(&lock_);
-
-  if (!collector_.enabled()) {
-    return;
-  }
-
-  // Unregister prof_handler to stop receiving SIGPROF interrupts before
-  // flushing the profile data.
-  DisableHandler();
-
-  // DisableHandler waits for the currently running callback to complete and
-  // guarantees no future invocations. It is safe to flush the profile data.
-  collector_.FlushTable();
-
-  EnableHandler();
-}
-
-bool CpuProfiler::Enabled() {
-  SpinLockHolder cl(&lock_);
-  return collector_.enabled();
-}
-
-void CpuProfiler::GetCurrentState(ProfilerState* state) {
-  ProfileData::State collector_state;
-  {
-    SpinLockHolder cl(&lock_);
-    collector_.GetCurrentState(&collector_state);
-  }
-
-  state->enabled = collector_state.enabled;
-  state->start_time = static_cast<time_t>(collector_state.start_time);
-  state->samples_gathered = collector_state.samples_gathered;
-  int buf_size = sizeof(state->profile_name);
-  strncpy(state->profile_name, collector_state.profile_name, buf_size);
-  state->profile_name[buf_size-1] = '\0';
-}
-
-void CpuProfiler::EnableHandler() {
-  RAW_CHECK(prof_handler_token_ == NULL, "SIGPROF handler already registered");
-  prof_handler_token_ = ProfileHandlerRegisterCallback(prof_handler, this);
-  RAW_CHECK(prof_handler_token_ != NULL, "Failed to set up SIGPROF handler");
-}
-
-void CpuProfiler::DisableHandler() {
-  RAW_CHECK(prof_handler_token_ != NULL, "SIGPROF handler is not registered");
-  ProfileHandlerUnregisterCallback(prof_handler_token_);
-  prof_handler_token_ = NULL;
-}
-
-// Signal handler that records the pc in the profile-data structure. We do no
-// synchronization here.  profile-handler.cc guarantees that at most one
-// instance of prof_handler() will run at a time. All other routines that
-// access the data touched by prof_handler() disable this signal handler before
-// accessing the data and therefore cannot execute concurrently with
-// prof_handler().
-void CpuProfiler::prof_handler(int sig, siginfo_t*, void* signal_ucontext,
-                               void* cpu_profiler) {
-  CpuProfiler* instance = static_cast<CpuProfiler*>(cpu_profiler);
-
-  if (instance->filter_ == NULL ||
-      (*instance->filter_)(instance->filter_arg_)) {
-    void* stack[ProfileData::kMaxStackDepth];
-
-    // Under frame-pointer-based unwinding at least on x86, the
-    // top-most active routine doesn't show up as a normal frame, but
-    // as the "pc" value in the signal handler context.
-    stack[0] = GetPC(*reinterpret_cast<ucontext_t*>(signal_ucontext));
-
-    // We skip the top three stack trace entries (this function,
-    // SignalHandler::SignalHandler and one signal handler frame)
-    // since they are artifacts of profiling and should not be
-    // measured.  Other profiling related frames may be removed by
-    // "pprof" at analysis time.  Instead of skipping the top frames,
-    // we could skip nothing, but that would increase the profile size
-    // unnecessarily.
-    int depth = GetStackTraceWithContext(stack + 1, arraysize(stack) - 1,
-                                         3, signal_ucontext);
-
-    void **used_stack;
-    if (depth > 0 && stack[1] == stack[0]) {
-      // in case of non-frame-pointer-based unwinding we will get
-      // duplicate of PC in stack[1], which we don't want
-      used_stack = stack + 1;
-    } else {
-      used_stack = stack;
-      depth++;  // To account for pc value in stack[0];
-    }
-
-    instance->collector_.Add(depth, used_stack);
-  }
-}
-
-#if !(defined(__CYGWIN__) || defined(__CYGWIN32__))
-
-extern "C" PERFTOOLS_DLL_DECL void ProfilerRegisterThread() {
-  ProfileHandlerRegisterThread();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void ProfilerFlush() {
-  CpuProfiler::instance_.FlushTable();
-}
-
-extern "C" PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads() {
-  return CpuProfiler::instance_.Enabled();
-}
-
-extern "C" PERFTOOLS_DLL_DECL int ProfilerStart(const char* fname) {
-  return CpuProfiler::instance_.Start(fname, NULL);
-}
-
-extern "C" PERFTOOLS_DLL_DECL int ProfilerStartWithOptions(
-    const char *fname, const ProfilerOptions *options) {
-  return CpuProfiler::instance_.Start(fname, options);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void ProfilerStop() {
-  CpuProfiler::instance_.Stop();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void ProfilerGetCurrentState(
-    ProfilerState* state) {
-  CpuProfiler::instance_.GetCurrentState(state);
-}
-
-#else  // OS_CYGWIN
-
-// ITIMER_PROF doesn't work under cygwin.  ITIMER_REAL is available, but doesn't
-// work as well for profiling, and also interferes with alarm().  Because of
-// these issues, unless a specific need is identified, profiler support is
-// disabled under Cygwin.
-extern "C" void ProfilerRegisterThread() { }
-extern "C" void ProfilerFlush() { }
-extern "C" int ProfilingIsEnabledForAllThreads() { return 0; }
-extern "C" int ProfilerStart(const char* fname) { return 0; }
-extern "C" int ProfilerStartWithOptions(const char *fname,
-                                        const ProfilerOptions *options) {
-  return 0;
-}
-extern "C" void ProfilerStop() { }
-extern "C" void ProfilerGetCurrentState(ProfilerState* state) {
-  memset(state, 0, sizeof(*state));
-}
-
-#endif  // OS_CYGWIN
-
-// DEPRECATED routines
-extern "C" PERFTOOLS_DLL_DECL void ProfilerEnable() { }
-extern "C" PERFTOOLS_DLL_DECL void ProfilerDisable() { }
diff --git a/third_party/tcmalloc/chromium/src/raw_printer.cc b/third_party/tcmalloc/chromium/src/raw_printer.cc
deleted file mode 100644
index 3cf028e..0000000
--- a/third_party/tcmalloc/chromium/src/raw_printer.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: sanjay@google.com (Sanjay Ghemawat)
-
-#include <config.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include "raw_printer.h"
-#include "base/logging.h"
-
-namespace base {
-
-RawPrinter::RawPrinter(char* buf, int length)
-    : base_(buf),
-      ptr_(buf),
-      limit_(buf + length - 1) {
-  RAW_DCHECK(length > 0, "");
-  *ptr_ = '\0';
-  *limit_ = '\0';
-}
-
-void RawPrinter::Printf(const char* format, ...) {
-  if (limit_ > ptr_) {
-    va_list ap;
-    va_start(ap, format);
-    int avail = limit_ - ptr_;
-    // We pass avail+1 to vsnprintf() since that routine needs room
-    // to store the trailing \0.
-    const int r = perftools_vsnprintf(ptr_, avail+1, format, ap);
-    va_end(ap);
-    if (r < 0) {
-      // Perhaps an old glibc that returns -1 on truncation?
-      ptr_ = limit_;
-    } else if (r > avail) {
-      // Truncation
-      ptr_ = limit_;
-    } else {
-      ptr_ += r;
-    }
-  }
-}
-
-}
diff --git a/third_party/tcmalloc/chromium/src/raw_printer.h b/third_party/tcmalloc/chromium/src/raw_printer.h
deleted file mode 100644
index bfc8be80..0000000
--- a/third_party/tcmalloc/chromium/src/raw_printer.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// A printf() wrapper that writes into a fixed length buffer.
-// Useful in low-level code that does not want to use allocating
-// routines like StringPrintf().
-//
-// The implementation currently uses vsnprintf().  This seems to
-// be fine for use in many low-level contexts, but we may need to
-// rethink this decision if we hit a problem with it calling
-// down into malloc() etc.
-
-#ifndef BASE_RAW_PRINTER_H_
-#define BASE_RAW_PRINTER_H_
-
-#include <config.h>
-#include "base/basictypes.h"
-
-namespace base {
-
-class RawPrinter {
- public:
-  // REQUIRES: "length > 0"
-  // Will printf any data added to this into "buf[0,length-1]" and
-  // will arrange to always keep buf[] null-terminated.
-  RawPrinter(char* buf, int length);
-
-  RawPrinter(const RawPrinter&) = delete;
-  RawPrinter& operator=(const RawPrinter&) = delete;
-
-  // Return the number of bytes that have been appended to the string
-  // so far.  Does not count any bytes that were dropped due to overflow.
-  int length() const { return (ptr_ - base_); }
-
-  // Return the number of bytes that can be added to this.
-  int space_left() const { return (limit_ - ptr_); }
-
-  // Format the supplied arguments according to the "format" string
-  // and append to this.  Will silently truncate the output if it does
-  // not fit.
-  void Printf(const char* format, ...)
-#ifdef HAVE___ATTRIBUTE__
-  __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
-;
-
- private:
-  // We can write into [ptr_ .. limit_-1].
-  // *limit_ is also writable, but reserved for a terminating \0
-  // in case we overflow.
-  //
-  // Invariants: *ptr_ == \0
-  // Invariants: *limit_ == \0
-  char* base_;          // Initial pointer
-  char* ptr_;           // Where should we write next
-  char* limit_;         // One past last non-\0 char we can write
-};
-
-}
-
-#endif  // BASE_RAW_PRINTER_H_
diff --git a/third_party/tcmalloc/chromium/src/sampler.cc b/third_party/tcmalloc/chromium/src/sampler.cc
deleted file mode 100644
index 6337826..0000000
--- a/third_party/tcmalloc/chromium/src/sampler.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Daniel Ford
-
-#include "sampler.h"
-
-#include <math.h>
-#include <algorithm>  // For min()
-
-using std::min;
-
-namespace tcmalloc {
-
-// The approximate gap in bytes between sampling actions.
-// I.e., we take one sample approximately once every
-// tcmalloc_sample_parameter bytes of allocation
-// i.e. about once every 512KB if value is 1<<19.
-#ifdef NO_TCMALLOC_SAMPLES
-std::atomic<size_t> Sampler::tcmalloc_sample_parameter_(0);
-#else
-std::atomic<size_t> Sampler::tcmalloc_sample_parameter_(
-    EnvToInt64("TCMALLOC_SAMPLE_PARAMETER", 0));
-#endif
-
-// Static
-size_t Sampler::GetSamplePeriod() {
-  return tcmalloc_sample_parameter_.load();
-}
-
-// Static
-void Sampler::SetSamplePeriod(size_t period) {
-  tcmalloc_sample_parameter_.store(period);
-}
-
-// Run this before using your sampler
-void Sampler::Init(uint64_t seed) {
-  ASSERT(seed != 0);
-
-  // Initialize PRNG
-  rnd_ = seed;
-  // Step it forward 20 times for good measure
-  for (int i = 0; i < 20; i++) {
-    rnd_ = NextRandom(rnd_);
-  }
-  // Initialize counter
-  bytes_until_sample_ = PickNextSamplingPoint();
-}
-
-#define MAX_SSIZE (static_cast<ssize_t>(static_cast<size_t>(static_cast<ssize_t>(-1)) >> 1))
-
-// Generates a geometric variable with the specified mean (512K by default).
-// This is done by generating a random number between 0 and 1 and applying
-// the inverse cumulative distribution function for an exponential.
-// Specifically: Let m be the inverse of the sample period, then
-// the probability distribution function is m*exp(-mx) so the CDF is
-// p = 1 - exp(-mx), so
-// q = 1 - p = exp(-mx)
-// log_e(q) = -mx
-// -log_e(q)/m = x
-// log_2(q) * (-log_e(2) * 1/m) = x
-// In the code, q is actually in the range 1 to 2**26, hence the -26 below
-ssize_t Sampler::PickNextSamplingPoint() {
-  size_t sampling_period = GetSamplePeriod();
-  if (sampling_period == 0) {
-    // In this case, we don't want to sample ever, and the larger a
-    // value we put here, the longer until we hit the slow path
-    // again. However, we have to support the flag changing at
-    // runtime, so pick something reasonably large (to keep overhead
-    // low) but small enough that we'll eventually start to sample
-    // again.
-    return 16 << 20;
-  }
-
-  rnd_ = NextRandom(rnd_);
-  // Take the top 26 bits as the random number
-  // (This plus the 1<<58 sampling bound give a max possible step of
-  // 5194297183973780480 bytes.)
-  const uint64_t prng_mod_power = 48;  // Number of bits in prng
-  // The uint32_t cast is to prevent a (hard-to-reproduce) NAN
-  // under piii debug for some binaries.
-  double q = static_cast<uint32_t>(rnd_ >> (prng_mod_power - 26)) + 1.0;
-  // Put the computed p-value through the CDF of a geometric.
-  double interval = (log2(q) - 26) * (-log(2.0) * sampling_period);
-
-  // Very large values of interval overflow ssize_t. If we happen to
-  // hit such improbable condition, we simply cheat and clamp interval
-  // to largest supported value.
-  return static_cast<ssize_t>(
-      std::min(interval, static_cast<double>(MAX_SSIZE)));
-}
-
-bool Sampler::RecordAllocationSlow(size_t k) {
-  if (!initialized_) {
-    initialized_ = true;
-    Init(reinterpret_cast<uintptr_t>(this));
-    if (static_cast<size_t>(bytes_until_sample_) >= k) {
-      bytes_until_sample_ -= k;
-      return true;
-    }
-  }
-  bytes_until_sample_ = PickNextSamplingPoint();
-  return GetSamplePeriod() == 0;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/sampler.h b/third_party/tcmalloc/chromium/src/sampler.h
deleted file mode 100644
index 735e4f00..0000000
--- a/third_party/tcmalloc/chromium/src/sampler.h
+++ /dev/null
@@ -1,235 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Daniel Ford
-
-#ifndef TCMALLOC_SAMPLER_H_
-#define TCMALLOC_SAMPLER_H_
-
-#include "config.h"
-#include <stddef.h>                     // for size_t
-#include <atomic>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uint64_t, uint32_t, int32_t
-#endif
-#include <string.h>                     // for memcpy
-#include "base/basictypes.h"  // for ASSERT
-#include "internal_logging.h"  // for ASSERT
-#include "static_vars.h"
-
-namespace tcmalloc {
-
-//-------------------------------------------------------------------
-// Sampler to decide when to create a sample trace for an allocation
-// Not thread safe: Each thread should have it's own sampler object.
-// Caller must use external synchronization if used
-// from multiple threads.
-//
-// With 512K average sample step (the default):
-//  the probability of sampling a 4K allocation is about 0.00778
-//  the probability of sampling a 1MB allocation is about 0.865
-//  the probability of sampling a 1GB allocation is about 1.00000
-// In general, the probablity of sampling is an allocation of size X
-// given a flag value of Y (default 1M) is:
-//  1 - e^(-X/Y)
-//
-// With 128K average sample step:
-//  the probability of sampling a 1MB allocation is about 0.99966
-//  the probability of sampling a 1GB allocation is about 1.0
-//  (about 1 - 2**(-26))
-// With 1M average sample step:
-//  the probability of sampling a 4K allocation is about 0.00390
-//  the probability of sampling a 1MB allocation is about 0.632
-//  the probability of sampling a 1GB allocation is about 1.0
-//
-// The sampler works by representing memory as a long stream from
-// which allocations are taken. Some of the bytes in this stream are
-// marked and if an allocation includes a marked byte then it is
-// sampled. Bytes are marked according to a Poisson point process
-// with each byte being marked independently with probability
-// p = 1/tcmalloc_sample_parameter.  This makes the probability
-// of sampling an allocation of X bytes equal to the CDF of
-// a geometric with mean tcmalloc_sample_parameter. (ie. the
-// probability that at least one byte in the range is marked). This
-// is accurately given by the CDF of the corresponding exponential
-// distribution : 1 - e^(-X/tcmalloc_sample_parameter_)
-// Independence of the byte marking ensures independence of
-// the sampling of each allocation.
-//
-// This scheme is implemented by noting that, starting from any
-// fixed place, the number of bytes until the next marked byte
-// is geometrically distributed. This number is recorded as
-// bytes_until_sample_.  Every allocation subtracts from this
-// number until it is less than 0. When this happens the current
-// allocation is sampled.
-//
-// When an allocation occurs, bytes_until_sample_ is reset to
-// a new independtly sampled geometric number of bytes. The
-// memoryless property of the point process means that this may
-// be taken as the number of bytes after the end of the current
-// allocation until the next marked byte. This ensures that
-// very large allocations which would intersect many marked bytes
-// only result in a single call to PickNextSamplingPoint.
-//-------------------------------------------------------------------
-
-class SamplerTest;
-
-class PERFTOOLS_DLL_DECL Sampler {
- public:
-  // Initialize this sampler.
-  void Init(uint64_t seed);
-
-  // Record allocation of "k" bytes.  Return true if no further work
-  // is need, and false if allocation needed to be sampled.
-  bool RecordAllocation(size_t k);
-
-  // Same as above (but faster), except:
-  // a) REQUIRES(k < std::numeric_limits<ssize_t>::max())
-  // b) if this returns false, you must call RecordAllocation
-  //    to confirm if sampling truly needed.
-  //
-  // The point of this function is to only deal with common case of no
-  // sampling and let caller (which is in malloc fast-path) to
-  // "escalate" to fuller and slower logic only if necessary.
-  bool TryRecordAllocationFast(size_t k);
-
-  // Generate a geometric with mean tcmalloc_sample_parameter_.
-  ssize_t PickNextSamplingPoint();
-
-  // Returns the current sample period.
-  static size_t GetSamplePeriod();
-
-  // Updates the sample period.
-  static void SetSamplePeriod(size_t period);
-
-  // The following are public for the purposes of testing
-  static uint64_t NextRandom(uint64_t rnd_);  // Returns the next prng value
-
-  // C++03 requires that types stored in TLS be POD.  As a result, you must
-  // initialize these members to {0, 0, false} before using this class!
-  //
-  // TODO(ahh): C++11 support will let us make these private.
-
-  // Bytes until we sample next.
-  //
-  // More specifically when bytes_until_sample_ is X, we can allocate
-  // X bytes without triggering sampling; on the (X+1)th allocated
-  // byte, the containing allocation will be sampled.
-  //
-  // Always non-negative with only very brief exceptions (see
-  // DecrementFast{,Finish}, so casting to size_t is ok.
-  ssize_t bytes_until_sample_;
-  uint64_t rnd_;  // Cheap random number generator
-  bool initialized_;
-
- private:
-  friend class SamplerTest;
-  bool RecordAllocationSlow(size_t k);
-  static std::atomic<size_t> tcmalloc_sample_parameter_;
-};
-
-inline bool Sampler::RecordAllocation(size_t k) {
-  // The first time we enter this function we expect bytes_until_sample_
-  // to be zero, and we must call SampleAllocationSlow() to ensure
-  // proper initialization of static vars.
-  ASSERT(Static::IsInited() || bytes_until_sample_ == 0);
-
-  // Note that we have to deal with arbitrarily large values of k
-  // here. Thus we're upcasting bytes_until_sample_ to unsigned rather
-  // than the other way around. And this is why this code cannot be
-  // merged with DecrementFast code below.
-  if (static_cast<size_t>(bytes_until_sample_) < k) {
-    bool result = RecordAllocationSlow(k);
-    ASSERT(Static::IsInited());
-    return result;
-  } else {
-    bytes_until_sample_ -= k;
-    ASSERT(Static::IsInited());
-    return true;
-  }
-}
-
-inline bool Sampler::TryRecordAllocationFast(size_t k) {
-  // For efficiency reason, we're testing bytes_until_sample_ after
-  // decrementing it by k. This allows compiler to do sub <reg>, <mem>
-  // followed by conditional jump on sign. But it is correct only if k
-  // is actually smaller than largest ssize_t value. Otherwise
-  // converting k to signed value overflows.
-  //
-  // It would be great for generated code to be sub <reg>, <mem>
-  // followed by conditional jump on 'carry', which would work for
-  // arbitrary values of k, but there seem to be no way to express
-  // that in C++.
-  //
-  // Our API contract explicitly states that only small values of k
-  // are permitted. And thus it makes sense to assert on that.
-  ASSERT(static_cast<ssize_t>(k) >= 0);
-
-  bytes_until_sample_ -= static_cast<ssize_t>(k);
-  if (PREDICT_FALSE(bytes_until_sample_ < 0)) {
-    // Note, we undo sampling counter update, since we're not actually
-    // handling slow path in the "needs sampling" case (calling
-    // RecordAllocationSlow to reset counter). And we do that in order
-    // to avoid non-tail calls in malloc fast-path. See also comments
-    // on declaration inside Sampler class.
-    //
-    // volatile is used here to improve compiler's choice of
-    // instuctions. We know that this path is very rare and that there
-    // is no need to keep previous value of bytes_until_sample_ in
-    // register. This helps compiler generate slightly more efficient
-    // sub <reg>, <mem> instruction for subtraction above.
-    volatile ssize_t *ptr =
-        const_cast<volatile ssize_t *>(&bytes_until_sample_);
-    *ptr += k;
-    return false;
-  }
-  return true;
-}
-
-// Inline functions which are public for testing purposes
-
-// Returns the next prng value.
-// pRNG is: aX+b mod c with a = 0x5DEECE66D, b =  0xB, c = 1<<48
-// This is the lrand64 generator.
-inline uint64_t Sampler::NextRandom(uint64_t rnd) {
-  const uint64_t prng_mult = 0x5DEECE66DULL;
-  const uint64_t prng_add = 0xB;
-  const uint64_t prng_mod_power = 48;
-  const uint64_t prng_mod_mask =
-      ~((~static_cast<uint64_t>(0)) << prng_mod_power);
-  return (prng_mult * rnd + prng_add) & prng_mod_mask;
-}
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_SAMPLER_H_
diff --git a/third_party/tcmalloc/chromium/src/solaris/libstdc++.la b/third_party/tcmalloc/chromium/src/solaris/libstdc++.la
deleted file mode 100644
index 3edf425..0000000
--- a/third_party/tcmalloc/chromium/src/solaris/libstdc++.la
+++ /dev/null
@@ -1,51 +0,0 @@
-# libstdc++.la - a libtool library file
-# Generated by ltmain.sh - GNU libtool 1.4a-GCC3.0 (1.641.2.256 2001/05/28 20:09:07 with GCC-local changes)
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# ---
-# NOTE: This file lives in /usr/sfw/lib on Solaris 10.  Unfortunately,
-# due to an apparent bug in the Solaris 10 6/06 release,
-# /usr/sfw/lib/libstdc++.la is empty.  Below is the correct content,
-# according to
-#    http://forum.java.sun.com/thread.jspa?threadID=5073150
-# By passing LDFLAGS='-Lsrc/solaris' to configure, make will pick up
-# this copy of the file rather than the empty copy in /usr/sfw/lib.
-#
-# Also see
-#   http://www.technicalarticles.org/index.php/Compiling_MySQL_5.0_on_Solaris_10
-#
-# Note: this is for 32-bit systems.  If you have a 64-bit system,
-# uncomment the appropriate dependency_libs line below.
-# ----
-
-# The name that we can dlopen(3).
-dlname='libstdc++.so.6'
-
-# Names of this library.
-library_names='libstdc++.so.6.0.3 libstdc++.so.6 libstdc++.so'
-
-# The name of the static archive.
-old_library='libstdc++.a'
-
-# Libraries that this one depends upon.
-# 32-bit version:
-dependency_libs='-lc -lm -L/usr/sfw/lib -lgcc_s'
-# 64-bit version:
-#dependency_libs='-L/lib/64 -lc -lm -L/usr/sfw/lib/64 -lgcc_s'
-
-# Version information for libstdc++.
-current=6
-age=0
-revision=3
-
-# Is this an already installed library?
-installed=yes
-
-# Files to dlopen/dlpreopen
-dlopen=''
-dlpreopen=''
-
-# Directory that this library needs to be installed in:
-libdir='/usr/sfw/lib'
diff --git a/third_party/tcmalloc/chromium/src/span.cc b/third_party/tcmalloc/chromium/src/span.cc
deleted file mode 100644
index 4d08964..0000000
--- a/third_party/tcmalloc/chromium/src/span.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-#include "span.h"
-
-#include <string.h>                     // for NULL, memset
-
-#include "internal_logging.h"  // for ASSERT
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "static_vars.h"       // for Static
-
-namespace tcmalloc {
-
-#ifdef SPAN_HISTORY
-void Event(Span* span, char op, int v = 0) {
-  span->history[span->nexthistory] = op;
-  span->value[span->nexthistory] = v;
-  span->nexthistory++;
-  if (span->nexthistory == sizeof(span->history)) span->nexthistory = 0;
-}
-#endif
-
-Span* NewSpan(PageID p, Length len) {
-  Span* result = Static::span_allocator()->New();
-  memset(result, 0, sizeof(*result));
-  result->start = p;
-  result->length = len;
-#ifdef SPAN_HISTORY
-  result->nexthistory = 0;
-#endif
-  return result;
-}
-
-void DeleteSpan(Span* span) {
-#ifndef NDEBUG
-  // In debug mode, trash the contents of deleted Spans
-  memset(span, 0x3f, sizeof(*span));
-#endif
-  Static::span_allocator()->Delete(span);
-}
-
-void DLL_Init(Span* list) {
-  list->next = list;
-  list->prev = list;
-}
-
-void DLL_Remove(Span* span) {
-  span->prev->next = span->next;
-  span->next->prev = span->prev;
-  span->prev = NULL;
-  span->next = NULL;
-}
-
-int DLL_Length(const Span* list) {
-  int result = 0;
-  for (Span* s = list->next; s != list; s = s->next) {
-    result++;
-  }
-  return result;
-}
-
-void DLL_Prepend(Span* list, Span* span) {
-  ASSERT(span->next == NULL);
-  ASSERT(span->prev == NULL);
-  span->next = list->next;
-  span->prev = list;
-  list->next->prev = span;
-  list->next = span;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/span.h b/third_party/tcmalloc/chromium/src/span.h
deleted file mode 100644
index ca3f710f..0000000
--- a/third_party/tcmalloc/chromium/src/span.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// A Span is a contiguous run of pages.
-
-#ifndef TCMALLOC_SPAN_H_
-#define TCMALLOC_SPAN_H_
-
-#include <config.h>
-#include <set>
-#include "common.h"
-#include "base/logging.h"
-#include "page_heap_allocator.h"
-
-namespace tcmalloc {
-
-struct SpanBestFitLess;
-struct Span;
-
-// Store a pointer to a span along with a cached copy of its length.
-// These are used as set elements to improve the performance of
-// comparisons during tree traversal: the lengths are inline with the
-// tree nodes and thus avoid expensive cache misses to dereference
-// the actual Span objects in most cases.
-struct SpanPtrWithLength {
-  explicit SpanPtrWithLength(Span* s);
-
-  Span* span;
-  Length length;
-};
-typedef std::set<SpanPtrWithLength, SpanBestFitLess, STLPageHeapAllocator<SpanPtrWithLength, void> > SpanSet;
-
-// Comparator for best-fit search, with address order as a tie-breaker.
-struct SpanBestFitLess {
-  bool operator()(SpanPtrWithLength a, SpanPtrWithLength b) const;
-};
-
-// Information kept for a span (a contiguous run of pages).
-struct Span {
-  PageID        start;          // Starting page number
-  Length        length;         // Number of pages in span
-  Span*         next;           // Used when in link list
-  Span*         prev;           // Used when in link list
-  union {
-    void* objects;              // Linked list of free objects
-
-    // Span may contain iterator pointing back at SpanSet entry of
-    // this span into set of large spans. It is used to quickly delete
-    // spans from those sets. span_iter_space is space for such
-    // iterator which lifetime is controlled explicitly.
-    char span_iter_space[sizeof(SpanSet::iterator)];
-  };
-  unsigned int  refcount : 16;  // Number of non-free objects
-  unsigned int  sizeclass : 8;  // Size-class for small objects (or 0)
-  unsigned int  location : 2;   // Is the span on a freelist, and if so, which?
-  unsigned int  sample : 1;     // Sampled object?
-  bool          has_span_iter : 1; // Iff span_iter_space has valid
-                                   // iterator. Only for debug builds.
-
-  // Sets iterator stored in span_iter_space.
-  // Requires has_span_iter == 0.
-  void SetSpanSetIterator(const SpanSet::iterator& iter);
-  // Copies out and destroys iterator stored in span_iter_space.
-  SpanSet::iterator ExtractSpanSetIterator();
-
-#undef SPAN_HISTORY
-#ifdef SPAN_HISTORY
-  // For debugging, we can keep a log events per span
-  int nexthistory;
-  char history[64];
-  int value[64];
-#endif
-
-  // What freelist the span is on: IN_USE if on none, or normal or returned
-  enum { IN_USE, ON_NORMAL_FREELIST, ON_RETURNED_FREELIST };
-};
-
-#ifdef SPAN_HISTORY
-void Event(Span* span, char op, int v = 0);
-#else
-#define Event(s,o,v) ((void) 0)
-#endif
-
-inline SpanPtrWithLength::SpanPtrWithLength(Span* s)
-    : span(s),
-      length(s->length) {
-}
-
-inline bool SpanBestFitLess::operator()(SpanPtrWithLength a, SpanPtrWithLength b) const {
-  if (a.length < b.length)
-    return true;
-  if (a.length > b.length)
-    return false;
-  return a.span->start < b.span->start;
-}
-
-inline void Span::SetSpanSetIterator(const SpanSet::iterator& iter) {
-  ASSERT(!has_span_iter);
-  has_span_iter = 1;
-
-  new (span_iter_space) SpanSet::iterator(iter);
-}
-
-inline SpanSet::iterator Span::ExtractSpanSetIterator() {
-  typedef SpanSet::iterator iterator_type;
-
-  ASSERT(has_span_iter);
-  has_span_iter = 0;
-
-  iterator_type* this_iter =
-    reinterpret_cast<iterator_type*>(span_iter_space);
-  iterator_type retval = *this_iter;
-  this_iter->~iterator_type();
-  return retval;
-}
-
-// Allocator/deallocator for spans
-Span* NewSpan(PageID p, Length len);
-void DeleteSpan(Span* span);
-
-// -------------------------------------------------------------------------
-// Doubly linked list of spans.
-// -------------------------------------------------------------------------
-
-// Initialize *list to an empty list.
-void DLL_Init(Span* list);
-
-// Remove 'span' from the linked list in which it resides, updating the
-// pointers of adjacent Spans and setting span's next and prev to NULL.
-void DLL_Remove(Span* span);
-
-// Return true iff "list" is empty.
-inline bool DLL_IsEmpty(const Span* list) {
-  return list->next == list;
-}
-
-// Add span to the front of list.
-void DLL_Prepend(Span* list, Span* span);
-
-// Return the length of the linked list. O(n)
-int DLL_Length(const Span* list);
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_SPAN_H_
diff --git a/third_party/tcmalloc/chromium/src/stack_trace_table.cc b/third_party/tcmalloc/chromium/src/stack_trace_table.cc
deleted file mode 100644
index 1862124..0000000
--- a/third_party/tcmalloc/chromium/src/stack_trace_table.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Andrew Fikes
-
-#include <config.h>
-#include "stack_trace_table.h"
-#include <string.h>                     // for NULL, memset
-#include "base/spinlock.h"              // for SpinLockHolder
-#include "common.h"            // for StackTrace
-#include "internal_logging.h"  // for ASSERT, Log
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "static_vars.h"       // for Static
-
-namespace tcmalloc {
-
-bool StackTraceTable::Bucket::KeyEqual(uintptr_t h,
-                                       const StackTrace& t) const {
-  const bool eq = (this->hash == h && this->trace.depth == t.depth);
-  for (int i = 0; eq && i < t.depth; ++i) {
-    if (this->trace.stack[i] != t.stack[i]) {
-      return false;
-    }
-  }
-  return eq;
-}
-
-StackTraceTable::StackTraceTable()
-    : error_(false),
-      depth_total_(0),
-      bucket_total_(0),
-      table_(new Bucket*[kHashTableSize]()) {
-  memset(table_, 0, kHashTableSize * sizeof(Bucket*));
-}
-
-StackTraceTable::~StackTraceTable() {
-  delete[] table_;
-}
-
-void StackTraceTable::AddTrace(const StackTrace& t) {
-  if (error_) {
-    return;
-  }
-
-  // Hash function borrowed from base/heap-profile-table.cc
-  uintptr_t h = 0;
-  for (int i = 0; i < t.depth; ++i) {
-    h += reinterpret_cast<uintptr_t>(t.stack[i]);
-    h += h << 10;
-    h ^= h >> 6;
-  }
-  h += h << 3;
-  h ^= h >> 11;
-
-  const int idx = h % kHashTableSize;
-
-  Bucket* b = table_[idx];
-  while (b != NULL && !b->KeyEqual(h, t)) {
-    b = b->next;
-  }
-  if (b != NULL) {
-    b->count++;
-    b->trace.size += t.size;  // keep cumulative size
-  } else {
-    depth_total_ += t.depth;
-    bucket_total_++;
-    b = Static::bucket_allocator()->New();
-    if (b == NULL) {
-      Log(kLog, __FILE__, __LINE__,
-          "tcmalloc: could not allocate bucket", sizeof(*b));
-      error_ = true;
-    } else {
-      b->hash = h;
-      b->trace = t;
-      b->count = 1;
-      b->next = table_[idx];
-      table_[idx] = b;
-    }
-  }
-}
-
-void** StackTraceTable::ReadStackTracesAndClear() {
-  if (error_) {
-    return NULL;
-  }
-
-  // Allocate output array
-  const int out_len = bucket_total_ * 3 + depth_total_ + 1;
-  void** out = new void*[out_len];
-  if (out == NULL) {
-    Log(kLog, __FILE__, __LINE__,
-        "tcmalloc: allocation failed for stack traces",
-        out_len * sizeof(*out));
-    return NULL;
-  }
-
-  // Fill output array
-  int idx = 0;
-  for (int i = 0; i < kHashTableSize; ++i) {
-    Bucket* b = table_[i];
-    while (b != NULL) {
-      out[idx++] = reinterpret_cast<void*>(static_cast<uintptr_t>(b->count));
-      out[idx++] = reinterpret_cast<void*>(b->trace.size);  // cumulative size
-      out[idx++] = reinterpret_cast<void*>(b->trace.depth);
-      for (int d = 0; d < b->trace.depth; ++d) {
-        out[idx++] = b->trace.stack[d];
-      }
-      b = b->next;
-    }
-  }
-  out[idx++] = NULL;
-  ASSERT(idx == out_len);
-
-  // Clear state
-  error_ = false;
-  depth_total_ = 0;
-  bucket_total_ = 0;
-  SpinLockHolder h(Static::pageheap_lock());
-  for (int i = 0; i < kHashTableSize; ++i) {
-    Bucket* b = table_[i];
-    while (b != NULL) {
-      Bucket* next = b->next;
-      Static::bucket_allocator()->Delete(b);
-      b = next;
-    }
-    table_[i] = NULL;
-  }
-
-  return out;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/stack_trace_table.h b/third_party/tcmalloc/chromium/src/stack_trace_table.h
deleted file mode 100644
index e289771..0000000
--- a/third_party/tcmalloc/chromium/src/stack_trace_table.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Andrew Fikes
-//
-// Utility class for coalescing sampled stack traces.  Not thread-safe.
-
-#ifndef TCMALLOC_STACK_TRACE_TABLE_H_
-#define TCMALLOC_STACK_TRACE_TABLE_H_
-
-#include <config.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uintptr_t
-#endif
-#include "common.h"
-
-namespace tcmalloc {
-
-class PERFTOOLS_DLL_DECL StackTraceTable {
- public:
-  // REQUIRES: L < pageheap_lock
-  StackTraceTable();
-  ~StackTraceTable();
-
-  // Adds stack trace "t" to table.
-  //
-  // REQUIRES: L >= pageheap_lock
-  void AddTrace(const StackTrace& t);
-
-  // Returns stack traces formatted per MallocExtension guidelines.
-  // May return NULL on error.  Clears state before returning.
-  //
-  // REQUIRES: L < pageheap_lock
-  void** ReadStackTracesAndClear();
-
-  // Exposed for PageHeapAllocator
-  struct Bucket {
-    // Key
-    uintptr_t hash;
-    StackTrace trace;
-
-    // Payload
-    int count;
-    Bucket* next;
-
-    bool KeyEqual(uintptr_t h, const StackTrace& t) const;
-  };
-
-  // For testing
-  int depth_total() const { return depth_total_; }
-  int bucket_total() const { return bucket_total_; }
-
- private:
-  static const int kHashTableSize = 1 << 14; // => table_ is 128k
-
-  bool error_;
-  int depth_total_;
-  int bucket_total_;
-  Bucket** table_;
-};
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_STACK_TRACE_TABLE_H_
diff --git a/third_party/tcmalloc/chromium/src/stacktrace.cc b/third_party/tcmalloc/chromium/src/stacktrace.cc
deleted file mode 100644
index 36381da3..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace.cc
+++ /dev/null
@@ -1,395 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Produce stack trace.
-//
-// There are three different ways we can try to get the stack trace:
-//
-// 1) Our hand-coded stack-unwinder.  This depends on a certain stack
-//    layout, which is used by gcc (and those systems using a
-//    gcc-compatible ABI) on x86 systems, at least since gcc 2.95.
-//    It uses the frame pointer to do its work.
-//
-// 2) The libunwind library.  This is still in development, and as a
-//    separate library adds a new dependency, abut doesn't need a frame
-//    pointer.  It also doesn't call malloc.
-//
-// 3) The gdb unwinder -- also the one used by the c++ exception code.
-//    It's obviously well-tested, but has a fatal flaw: it can call
-//    malloc() from the unwinder.  This is a problem because we're
-//    trying to use the unwinder to instrument malloc().
-//
-// Note: if you add a new implementation here, make sure it works
-// correctly when GetStackTrace() is called with max_depth == 0.
-// Some code may do that.
-
-#include <config.h>
-#include <stdlib.h> // for getenv
-#include <string.h> // for strcmp
-#include <stdio.h> // for fprintf
-#include "gperftools/stacktrace.h"
-#include "base/commandlineflags.h"
-#include "base/googleinit.h"
-#include "getenv_safe.h"
-
-
-// we're using plain struct and not class to avoid any possible issues
-// during initialization. Struct of pointers is easy to init at
-// link-time.
-struct GetStackImplementation {
-  int (*GetStackFramesPtr)(void** result, int* sizes, int max_depth,
-                           int skip_count);
-
-  int (*GetStackFramesWithContextPtr)(void** result, int* sizes, int max_depth,
-                                      int skip_count, const void *uc);
-
-  int (*GetStackTracePtr)(void** result, int max_depth,
-                          int skip_count);
-
-  int (*GetStackTraceWithContextPtr)(void** result, int max_depth,
-                                  int skip_count, const void *uc);
-
-  const char *name;
-};
-
-// ppc and i386 implementations prefer arch-specific asm implementations.
-// arm's asm implementation is broken
-#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \
-    defined(__PPC__)
-#if !defined(NO_FRAME_POINTER)
-#define TCMALLOC_DONT_PREFER_LIBUNWIND
-#endif
-#endif
-
-#undef UNWIND_APPROACH_SET
-
-#if defined(TCMALLOC_ENABLE_INSTRUMENT_STACKTRACE)
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME) || \
-    !defined(UNWIND_APPROACH_SET)
-#define STACKTRACE_INL_HEADER "stacktrace_instrument-inl.h"
-#define GST_SUFFIX instrument
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_instrument
-#if !defined(UNWIND_APPROACH_SET)
-#define UNWIND_APPROACH_SET
-static GetStackImplementation* get_stack_impl = &impl__instrument;
-#endif
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME || !UNWIND_APPROACH_SET
-#endif
-
-// The Windows case -- probably cygwin and mingw will use one of the
-// x86-includes above, but if not, we can fall back to windows intrinsics.
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || \
-    defined(__MINGW32__)
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME) || \
-    !defined(UNWIND_APPROACH_SET)
-#define STACKTRACE_INL_HEADER "stacktrace_win32-inl.h"
-#define GST_SUFFIX win32
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_win32
-#if !defined(UNWIND_APPROACH_SET)
-#define UNWIND_APPROACH_SET
-static GetStackImplementation* get_stack_impl = &impl__win32;
-#endif
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME || !UNWIND_APPROACH_SET
-#endif
-
-#if defined(__i386__) || defined(__x86_64__)
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME) || \
-    (!defined(UNWIND_APPROACH_SET) && defined(TCMALLOC_DONT_PREFER_LIBUNWIND))
-#define STACKTRACE_INL_HEADER "stacktrace_x86-inl.h"
-#define GST_SUFFIX x86
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_x86
-#if !defined(UNWIND_APPROACH_SET) && defined(TCMALLOC_DONT_PREFER_LIBUNWIND)
-#define UNWIND_APPROACH_SET
-static GetStackImplementation* get_stack_impl = &impl__x86;
-#endif
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME || !UNWIND_APPROACH_SET
-#endif // i386 || x86_64
-
-#if defined(__ppc__) || defined(__PPC__)
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME) || \
-    (!defined(UNWIND_APPROACH_SET) && defined(TCMALLOC_DONT_PREFER_LIBUNWIND))
-#if defined(__linux__)
-#define STACKTRACE_INL_HEADER "stacktrace_powerpc-linux-inl.h"
-#else
-#define STACKTRACE_INL_HEADER "stacktrace_powerpc-darwin-inl.h"
-#endif
-#define GST_SUFFIX ppc
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_ppc
-#if !defined(UNWIND_APPROACH_SET) && defined(TCMALLOC_DONT_PREFER_LIBUNWIND)
-#define UNWIND_APPROACH_SET
-static GetStackImplementation* get_stack_impl = &impl__ppc;
-#endif
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME || !UNWIND_APPROACH_SET
-#endif
-
-// libunwind uses __thread so we check for both libunwind.h and
-// __thread support
-#if defined(HAVE_LIBUNWIND_H) && defined(HAVE_TLS)
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME) || \
-    !defined(UNWIND_APPROACH_SET)
-#define STACKTRACE_INL_HEADER "stacktrace_libunwind-inl.h"
-#define GST_SUFFIX libunwind
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_libunwind
-#if !defined(UNWIND_APPROACH_SET)
-#define UNWIND_APPROACH_SET
-static GetStackImplementation* get_stack_impl = &impl__libunwind;
-#endif
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME || !UNWIND_APPROACH_SET
-#endif  // HAVE_LIBUNWIND_H
-
-#ifdef HAVE_UNWIND_BACKTRACE
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME) || \
-    !defined(UNWIND_APPROACH_SET)
-#define STACKTRACE_INL_HEADER "stacktrace_libgcc-inl.h"
-#define GST_SUFFIX libgcc
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_libgcc
-#if !defined(UNWIND_APPROACH_SET)
-#define UNWIND_APPROACH_SET
-static GetStackImplementation* get_stack_impl = &impl__libgcc;
-#endif
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME || !UNWIND_APPROACH_SET
-#endif
-
-#if HAVE_DECL_BACKTRACE
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME) || \
-    !defined(UNWIND_APPROACH_SET)
-#define STACKTRACE_INL_HEADER "stacktrace_generic-inl.h"
-#define GST_SUFFIX generic
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_generic
-#if !defined(UNWIND_APPROACH_SET)
-#define UNWIND_APPROACH_SET
-static GetStackImplementation* get_stack_impl = &impl__generic;
-#endif
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME || !UNWIND_APPROACH_SET
-#endif
-
-#if defined(__arm__)
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME) || \
-    !defined(UNWIND_APPROACH_SET)
-#define STACKTRACE_INL_HEADER "stacktrace_arm-inl.h"
-#define GST_SUFFIX arm
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_arm
-#if !defined(UNWIND_APPROACH_SET)
-#define UNWIND_APPROACH_SET
-static GetStackImplementation* get_stack_impl = &impl__arm;
-#endif
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME || !UNWIND_APPROACH_SET
-#endif
-
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME)
-
-static GetStackImplementation *all_impls[] = {
-#ifdef HAVE_GST_libgcc
-  &impl__libgcc,
-#endif
-#ifdef HAVE_GST_generic
-  &impl__generic,
-#endif
-#ifdef HAVE_GST_libunwind
-  &impl__libunwind,
-#endif
-#ifdef HAVE_GST_x86
-  &impl__x86,
-#endif
-#ifdef HAVE_GST_arm
-  &impl__arm,
-#endif
-#ifdef HAVE_GST_ppc
-  &impl__ppc,
-#endif
-#ifdef HAVE_GST_instrument
-  &impl__instrument,
-#endif
-#ifdef HAVE_GST_win32
-  &impl__win32,
-#endif
-  NULL
-};
-
-static bool get_stack_impl_inited;
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME
-
-#if 0
-// This is for the benefit of code analysis tools that may have
-// trouble with the computed #include above.
-# include "stacktrace_x86-inl.h"
-# include "stacktrace_libunwind-inl.h"
-# include "stacktrace_generic-inl.h"
-# include "stacktrace_powerpc-inl.h"
-# include "stacktrace_win32-inl.h"
-# include "stacktrace_arm-inl.h"
-# include "stacktrace_instrument-inl.h"
-#elif !defined(UNWIND_APPROACH_SET)
-#error Cannot calculate stack trace: will need to write for your environment
-#endif
-
-static int ATTRIBUTE_NOINLINE frame_forcer(int rv) {
-  return rv;
-}
-
-static void init_default_stack_impl_inner(void);
-
-namespace tcmalloc {
-  bool EnterStacktraceScope(void);
-  void LeaveStacktraceScope(void);
-}
-
-namespace {
-  using tcmalloc::EnterStacktraceScope;
-  using tcmalloc::LeaveStacktraceScope;
-
-  class StacktraceScope {
-    bool stacktrace_allowed;
-  public:
-    StacktraceScope() {
-      stacktrace_allowed = true;
-      stacktrace_allowed = EnterStacktraceScope();
-    }
-    bool IsStacktraceAllowed() {
-      return stacktrace_allowed;
-    }
-    ~StacktraceScope() {
-      if (stacktrace_allowed) {
-        LeaveStacktraceScope();
-      }
-    }
-  };
-}
-
-PERFTOOLS_DLL_DECL int GetStackFrames(void** result, int* sizes, int max_depth,
-                                      int skip_count) {
-  StacktraceScope scope;
-  if (!scope.IsStacktraceAllowed()) {
-    return 0;
-  }
-  init_default_stack_impl_inner();
-  return frame_forcer(get_stack_impl->GetStackFramesPtr(result, sizes, max_depth, skip_count));
-}
-
-PERFTOOLS_DLL_DECL int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
-                                                 int skip_count, const void *uc) {
-  StacktraceScope scope;
-  if (!scope.IsStacktraceAllowed()) {
-    return 0;
-  }
-  init_default_stack_impl_inner();
-  return frame_forcer(get_stack_impl->GetStackFramesWithContextPtr(
-                        result, sizes, max_depth,
-                        skip_count, uc));
-}
-
-PERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,
-                                     int skip_count) {
-  StacktraceScope scope;
-  if (!scope.IsStacktraceAllowed()) {
-    return 0;
-  }
-  init_default_stack_impl_inner();
-  return frame_forcer(get_stack_impl->GetStackTracePtr(result, max_depth, skip_count));
-}
-
-PERFTOOLS_DLL_DECL int GetStackTraceWithContext(void** result, int max_depth,
-                                                int skip_count, const void *uc) {
-  StacktraceScope scope;
-  if (!scope.IsStacktraceAllowed()) {
-    return 0;
-  }
-  init_default_stack_impl_inner();
-  return frame_forcer(get_stack_impl->GetStackTraceWithContextPtr(
-                        result, max_depth, skip_count, uc));
-}
-
-#if defined(TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME)
-
-static void init_default_stack_impl_inner(void) {
-  if (get_stack_impl_inited) {
-    return;
-  }
-  get_stack_impl_inited = true;
-  const char *val = TCMallocGetenvSafe("TCMALLOC_STACKTRACE_METHOD");
-  if (!val || !*val) {
-    return;
-  }
-  for (GetStackImplementation **p = all_impls; *p; p++) {
-    GetStackImplementation *c = *p;
-    if (strcmp(c->name, val) == 0) {
-      get_stack_impl = c;
-      return;
-    }
-  }
-  fprintf(stderr, "Unknown or unsupported stacktrace method requested: %s. Ignoring it\n", val);
-}
-
-static void init_default_stack_impl(void) {
-  init_default_stack_impl_inner();
-  if (EnvToBool("TCMALLOC_STACKTRACE_METHOD_VERBOSE", false)) {
-    fprintf(stderr, "Chosen stacktrace method is %s\nSupported methods:\n", get_stack_impl->name);
-    for (GetStackImplementation **p = all_impls; *p; p++) {
-      GetStackImplementation *c = *p;
-      fprintf(stderr, "* %s\n", c->name);
-    }
-    fputs("\n", stderr);
-  }
-}
-
-REGISTER_MODULE_INITIALIZER(stacktrace_init_default_stack_impl, init_default_stack_impl());
-
-#else
-
-static void init_default_stack_impl_inner(void) {}
-
-#endif  // TCMALLOC_SELECT_UNWIND_METHOD_AT_RUNTIME
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_arm-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_arm-inl.h
deleted file mode 100644
index 1586b8f..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_arm-inl.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Doug Kwan
-// This is inspired by Craig Silverstein's PowerPC stacktrace code.
-//
-
-#ifndef BASE_STACKTRACE_ARM_INL_H_
-#define BASE_STACKTRACE_ARM_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <stdint.h>   // for uintptr_t
-#include "base/basictypes.h"  // for NULL
-#include <gperftools/stacktrace.h>
-
-// WARNING:
-// This only works if all your code is in either ARM or THUMB mode.  With
-// interworking, the frame pointer of the caller can either be in r11 (ARM
-// mode) or r7 (THUMB mode).  A callee only saves the frame pointer of its
-// mode in a fixed location on its stack frame.  If the caller is a different
-// mode, there is no easy way to find the frame pointer.  It can either be
-// still in the designated register or saved on stack along with other callee
-// saved registers.
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING>
-static void **NextStackFrame(void **old_sp) {
-  void **new_sp = (void**) old_sp[-1];
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp) return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp) return NULL;
-    // And allow frames upto about 1MB.
-    if ((new_sp > old_sp)
-        && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
-  }
-  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
-  return new_sp;
-}
-
-// This ensures that GetStackTrace stes up the Link Register properly.
-#ifdef __GNUC__
-void StacktraceArmDummyFunction() __attribute__((noinline));
-void StacktraceArmDummyFunction() { __asm__ volatile(""); }
-#else
-# error StacktraceArmDummyFunction() needs to be ported to this platform.
-#endif
-#endif  // BASE_STACKTRACE_ARM_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-#ifdef __GNUC__
-  void **sp = reinterpret_cast<void**>(__builtin_frame_address(0));
-#else
-# error reading stack point not yet supported on this platform.
-#endif
-
-  // On ARM, the return address is stored in the link register (r14).
-  // This is not saved on the stack frame of a leaf function.  To
-  // simplify code that reads return addresses, we call a dummy
-  // function so that the return address of this function is also
-  // stored in the stack frame.  This works at least for gcc.
-  StacktraceArmDummyFunction();
-
-  skip_count++; // skip parent frame due to indirection in stacktrace.cc
-
-  int n = 0;
-  while (sp && n < max_depth) {
-    // The GetStackFrames routine is called when we are in some
-    // informational context (the failure signal handler for example).
-    // Use the non-strict unwinding rules to produce a stack trace
-    // that is as complete as possible (even if it contains a few bogus
-    // entries in some rare cases).
-    void **next_sp = NextStackFrame<IS_STACK_FRAMES == 0>(sp);
-
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n] = *sp;
-
-#if IS_STACK_FRAMES
-      if (next_sp > sp) {
-        sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    sp = next_sp;
-  }
-  return n;
-}
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_generic-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_generic-inl.h
deleted file mode 100644
index 7d7c22d9..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_generic-inl.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Portable implementation - just use glibc
-//
-// Note:  The glibc implementation may cause a call to malloc.
-// This can cause a deadlock in HeapProfiler.
-
-#ifndef BASE_STACKTRACE_GENERIC_INL_H_
-#define BASE_STACKTRACE_GENERIC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <execinfo.h>
-#include <string.h>
-#include "gperftools/stacktrace.h"
-#endif  // BASE_STACKTRACE_GENERIC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  static const int kStackLength = 64;
-  void * stack[kStackLength];
-  int size;
-
-  size = backtrace(stack, kStackLength);
-  skip_count += 2;  // we want to skip the current and it's parent frame as well
-  int result_count = size - skip_count;
-  if (result_count < 0)
-    result_count = 0;
-  if (result_count > max_depth)
-    result_count = max_depth;
-  for (int i = 0; i < result_count; i++)
-    result[i] = stack[i + skip_count];
-
-#if IS_STACK_FRAMES
-  // No implementation for finding out the stack frame sizes yet.
-  memset(sizes, 0, sizeof(*sizes) * result_count);
-#endif
-
-  return result_count;
-}
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_impl_setup-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_impl_setup-inl.h
deleted file mode 100644
index 698c5b38..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_impl_setup-inl.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// NOTE: this is NOT to be #include-d normally. It's internal
-// implementation detail of stacktrace.cc
-//
-
-// Copyright (c) 2014, gperftools Contributors.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Aliaksey Kandratsenka <alk@tut.by>
-//
-//  based on stacktrace.cc and stacktrace_config.h by Sanjay Ghemawat
-//  and Paul Pluzhnikov from Google Inc
-
-#define SIS_CONCAT2(a, b) a##b
-#define SIS_CONCAT(a, b) SIS_CONCAT2(a,b)
-
-#define SIS_STRINGIFY(a) SIS_STRINGIFY2(a)
-#define SIS_STRINGIFY2(a) #a
-
-#define IS_STACK_FRAMES 0
-#define IS_WITH_CONTEXT 0
-#define GET_STACK_TRACE_OR_FRAMES \
-  SIS_CONCAT(GetStackTrace_, GST_SUFFIX)(void **result, int max_depth, int skip_count)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-#define IS_STACK_FRAMES 1
-#define IS_WITH_CONTEXT 0
-#define GET_STACK_TRACE_OR_FRAMES \
-  SIS_CONCAT(GetStackFrames_, GST_SUFFIX)(void **result, int *sizes, int max_depth, int skip_count)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-#define IS_STACK_FRAMES 0
-#define IS_WITH_CONTEXT 1
-#define GET_STACK_TRACE_OR_FRAMES \
-  SIS_CONCAT(GetStackTraceWithContext_, GST_SUFFIX)(void **result, int max_depth, \
-                                                   int skip_count, const void *ucp)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-#define IS_STACK_FRAMES 1
-#define IS_WITH_CONTEXT 1
-#define GET_STACK_TRACE_OR_FRAMES \
-  SIS_CONCAT(GetStackFramesWithContext_, GST_SUFFIX)(void **result, int *sizes, int max_depth, \
-                                                    int skip_count, const void *ucp)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-static GetStackImplementation SIS_CONCAT(impl__,GST_SUFFIX) = {
-  SIS_CONCAT(GetStackFrames_, GST_SUFFIX),
-  SIS_CONCAT(GetStackFramesWithContext_, GST_SUFFIX),
-  SIS_CONCAT(GetStackTrace_, GST_SUFFIX),
-  SIS_CONCAT(GetStackTraceWithContext_, GST_SUFFIX),
-  SIS_STRINGIFY(GST_SUFFIX)
-};
-
-#undef SIS_CONCAT2
-#undef SIS_CONCAT
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_instrument-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_instrument-inl.h
deleted file mode 100755
index c631765c..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_instrument-inl.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2013, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Jean Lee <xiaoyur347@gmail.com>
-// based on gcc Code-Gen-Options "-finstrument-functions" listed in
-// http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html .
-// Should run configure with CXXFLAGS="-finstrument-functions".
-
-// This file is a backtrace implementation for systems :
-// * The glibc implementation of backtrace() may cause a call to malloc,
-//   and cause a deadlock in HeapProfiler.
-// * The libunwind implementation prints no backtrace.
-
-// The backtrace arrays are stored in "thread_back_trace" variable.
-// Maybe to use thread local storage is better and should save memorys.
-
-#ifndef BASE_STACKTRACE_INSTRUMENT_INL_H_
-#define BASE_STACKTRACE_INSTRUMENT_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <execinfo.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include "gperftools/stacktrace.h"
-
-#define gettid() syscall(__NR_gettid)
-#ifndef __x86_64__
-#define MAX_THREAD (32768)
-#else
-#define MAX_THREAD (65536)
-#endif
-#define MAX_DEPTH  (30)
-#define ATTRIBUTE_NOINSTRUMENT __attribute__ ((no_instrument_function))
-
-typedef struct {
-  int   stack_depth;
-  void* frame[MAX_DEPTH];
-}BACK_TRACE;
-
-static BACK_TRACE thread_back_trace[MAX_THREAD];
-extern "C" {
-void __cyg_profile_func_enter(void *func_address,
-                              void *call_site) ATTRIBUTE_NOINSTRUMENT;
-void __cyg_profile_func_enter(void *func_address, void *call_site) {
-  (void)func_address;
-
-  BACK_TRACE* backtrace = thread_back_trace + gettid();
-  int stack_depth = backtrace->stack_depth;
-  backtrace->stack_depth = stack_depth + 1;
-  if ( stack_depth >= MAX_DEPTH ) {
-    return;
-  }
-  backtrace->frame[stack_depth] = call_site;
-}
-
-void __cyg_profile_func_exit(void *func_address,
-                             void *call_site) ATTRIBUTE_NOINSTRUMENT;
-void __cyg_profile_func_exit(void *func_address, void *call_site) {
-  (void)func_address;
-  (void)call_site;
-
-  BACK_TRACE* backtrace = thread_back_trace + gettid();
-  int stack_depth = backtrace->stack_depth;
-  backtrace->stack_depth = stack_depth - 1;
-  if ( stack_depth >= MAX_DEPTH ) {
-    return;
-  }
-  backtrace->frame[stack_depth] = 0;
-}
-}  // extern "C"
-
-static int cyg_backtrace(void **buffer, int size) {
-  BACK_TRACE* backtrace = thread_back_trace + gettid();
-  int stack_depth = backtrace->stack_depth;
-  if ( stack_depth >= MAX_DEPTH ) {
-    stack_depth = MAX_DEPTH;
-  }
-  int nSize = (size > stack_depth) ? stack_depth : size;
-  for (int i = 0; i < nSize; i++) {
-  buffer[i] = backtrace->frame[nSize - i - 1];
-  }
-
-  return nSize;
-}
-
-#endif  // BASE_STACKTRACE_INSTRUMENT_INL_H_
-
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  static const int kStackLength = 64;
-  void * stack[kStackLength];
-  int size;
-  memset(stack, 0, sizeof(stack));
-
-  size = cyg_backtrace(stack, kStackLength);
-  skip_count += 2;  // we want to skip the current and parent frame as well
-  int result_count = size - skip_count;
-  if (result_count < 0)
-    result_count = 0;
-  if (result_count > max_depth)
-    result_count = max_depth;
-  for (int i = 0; i < result_count; i++)
-    result[i] = stack[i + skip_count];
-
-#if IS_STACK_FRAMES
-  // No implementation for finding out the stack frame sizes yet.
-  memset(sizes, 0, sizeof(*sizes) * result_count);
-#endif
-
-  return result_count;
-}
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_libgcc-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_libgcc-inl.h
deleted file mode 100644
index ce9cf51..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_libgcc-inl.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2016, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file implements backtrace capturing via libgcc's
-// _Unwind_Backtrace. This generally works almost always. It will fail
-// sometimes when we're trying to capture backtrace from signal
-// handler (i.e. in cpu profiler) while some C++ code is throwing
-// exception.
-
-#ifndef BASE_STACKTRACE_LIBGCC_INL_H_
-#define BASE_STACKTRACE_LIBGCC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-extern "C" {
-#include <assert.h>
-#include <string.h>   // for memset()
-}
-
-#include <unwind.h>
-
-#include "gperftools/stacktrace.h"
-
-struct libgcc_backtrace_data {
-  void **array;
-  int skip;
-  int pos;
-  int limit;
-};
-
-static _Unwind_Reason_Code libgcc_backtrace_helper(struct _Unwind_Context *ctx,
-                                                   void *_data) {
-  libgcc_backtrace_data *data =
-    reinterpret_cast<libgcc_backtrace_data *>(_data);
-
-  if (data->skip > 0) {
-    data->skip--;
-    return _URC_NO_REASON;
-  }
-
-  if (data->pos < data->limit) {
-    void *ip = reinterpret_cast<void *>(_Unwind_GetIP(ctx));;
-    data->array[data->pos++] = ip;
-  }
-
-  return _URC_NO_REASON;
-}
-
-#endif  // BASE_STACKTRACE_LIBGCC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  libgcc_backtrace_data data;
-  data.array = result;
-  // we're also skipping current and parent's frame
-  data.skip = skip_count + 2;
-  data.pos = 0;
-  data.limit = max_depth;
-
-  _Unwind_Backtrace(libgcc_backtrace_helper, &data);
-
-  if (data.pos > 1 && data.array[data.pos - 1] == NULL)
-    --data.pos;
-
-#if IS_STACK_FRAMES
-  // No implementation for finding out the stack frame sizes.
-  memset(sizes, 0, sizeof(*sizes) * data.pos);
-#endif
-
-  return data.pos;
-}
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_libunwind-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_libunwind-inl.h
deleted file mode 100644
index 6f361ecd..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_libunwind-inl.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Arun Sharma
-//
-// Produce stack trace using libunwind
-
-#ifndef BASE_STACKTRACE_LIBINWIND_INL_H_
-#define BASE_STACKTRACE_LIBINWIND_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-// We only need local unwinder.
-#define UNW_LOCAL_ONLY
-
-extern "C" {
-#include <assert.h>
-#include <string.h>   // for memset()
-#include <libunwind.h>
-}
-#include "gperftools/stacktrace.h"
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-
-// Sometimes, we can try to get a stack trace from within a stack
-// trace, because libunwind can call mmap (maybe indirectly via an
-// internal mmap based memory allocator), and that mmap gets trapped
-// and causes a stack-trace request.  If were to try to honor that
-// recursive request, we'd end up with infinite recursion or deadlock.
-// Luckily, it's safe to ignore those subsequent traces.  In such
-// cases, we return 0 to indicate the situation.
-static __thread int recursive ATTR_INITIAL_EXEC;
-
-#if defined(TCMALLOC_ENABLE_UNWIND_FROM_UCONTEXT) && (defined(__i386__) || defined(__x86_64__)) && defined(__GNU_LIBRARY__)
-#define BASE_STACKTRACE_UNW_CONTEXT_IS_UCONTEXT 1
-#endif
-
-#endif  // BASE_STACKTRACE_LIBINWIND_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  void *ip;
-  int n = 0;
-  unw_cursor_t cursor;
-  unw_context_t uc;
-#if IS_STACK_FRAMES
-  unw_word_t sp = 0, next_sp = 0;
-#endif
-
-  if (recursive) {
-    return 0;
-  }
-  ++recursive;
-
-#if (IS_WITH_CONTEXT && defined(BASE_STACKTRACE_UNW_CONTEXT_IS_UCONTEXT))
-  if (ucp) {
-    uc = *(static_cast<unw_context_t *>(const_cast<void *>(ucp)));
-    /* this is a bit weird. profiler.cc calls us with signal's ucontext
-     * yet passing us 2 as skip_count and essentially assuming we won't
-     * use ucontext. */
-    /* In order to fix that I'm going to assume that if ucp is
-     * non-null we're asked to ignore skip_count in case we're
-     * able to use ucp */
-    skip_count = 0;
-  } else {
-    unw_getcontext(&uc);
-    skip_count += 2;         // Do not include current and parent frame
-  }
-#else
-  unw_getcontext(&uc);
-  skip_count += 2;         // Do not include current and parent frame
-#endif
-
-  int ret = unw_init_local(&cursor, &uc);
-  assert(ret >= 0);
-
-  while (skip_count--) {
-    if (unw_step(&cursor) <= 0) {
-      goto out;
-    }
-#if IS_STACK_FRAMES
-    if (unw_get_reg(&cursor, UNW_REG_SP, &next_sp)) {
-      goto out;
-    }
-#endif
-  }
-
-  while (n < max_depth) {
-    if (unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip) < 0) {
-      break;
-    }
-#if IS_STACK_FRAMES
-    sizes[n] = 0;
-#endif
-    result[n++] = ip;
-    if (unw_step(&cursor) <= 0) {
-      break;
-    }
-#if IS_STACK_FRAMES
-    sp = next_sp;
-    if (unw_get_reg(&cursor, UNW_REG_SP, &next_sp) , 0) {
-      break;
-    }
-    sizes[n - 1] = next_sp - sp;
-#endif
-  }
-out:
-  --recursive;
-  return n;
-}
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_powerpc-darwin-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_powerpc-darwin-inl.h
deleted file mode 100644
index c4c2edb..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_powerpc-darwin-inl.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Produce stack trace.  ABI documentation reference can be found at:
-// * PowerPC32 ABI: https://www.power.org/documentation/
-// power-architecture-32-bit-abi-supplement-1-0-embeddedlinuxunified/
-// * PowerPC64 ABI:
-// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
-
-#ifndef BASE_STACKTRACE_POWERPC_INL_H_
-#define BASE_STACKTRACE_POWERPC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <stdint.h>   // for uintptr_t
-#include <stdlib.h>   // for NULL
-#include <gperftools/stacktrace.h>
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING>
-static void **NextStackFrame(void **old_sp) {
-  void **new_sp = (void **) *old_sp;
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp) return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp) return NULL;
-    // And allow frames upto about 1MB.
-    if ((new_sp > old_sp)
-        && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
-  }
-  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
-  return new_sp;
-}
-
-// This ensures that GetStackTrace stes up the Link Register properly.
-void StacktracePowerPCDummyFunction() __attribute__((noinline));
-void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
-#endif  // BASE_STACKTRACE_POWERPC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-int GET_STACK_TRACE_OR_FRAMES {
-  void **sp;
-  // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
-  // and Darwin 8.8.1 (Tiger) use as 1.38.  This means we have to use a
-  // different asm syntax.  I don't know quite the best way to discriminate
-  // systems using the old as from the new one; I've gone with __APPLE__.
-  // TODO(csilvers): use autoconf instead, to look for 'as --version' == 1 or 2
-  __asm__ volatile ("mr %0,r1" : "=r" (sp));
-
-  // On PowerPC, the "Link Register" or "Link Record" (LR), is a stack
-  // entry that holds the return address of the subroutine call (what
-  // instruction we run after our function finishes).  This is the
-  // same as the stack-pointer of our parent routine, which is what we
-  // want here.  While the compiler will always(?) set up LR for
-  // subroutine calls, it may not for leaf functions (such as this one).
-  // This routine forces the compiler (at least gcc) to push it anyway.
-  StacktracePowerPCDummyFunction();
-
-#if IS_STACK_FRAMES
-  // Note we do *not* increment skip_count here for the SYSV ABI.  If
-  // we did, the list of stack frames wouldn't properly match up with
-  // the list of return addresses.  Note this means the top pc entry
-  // is probably bogus for linux/ppc (and other SYSV-ABI systems).
-#else
-  // The LR save area is used by the callee, so the top entry is bogus.
-  skip_count++;
-#endif
-
-  int n = 0;
-  while (sp && n < max_depth) {
-    // The GetStackFrames routine is called when we are in some
-    // informational context (the failure signal handler for example).
-    // Use the non-strict unwinding rules to produce a stack trace
-    // that is as complete as possible (even if it contains a few
-    // bogus entries in some rare cases).
-    void **next_sp = NextStackFrame<!IS_STACK_FRAMES>(sp);
-
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      // PowerPC has 3 main ABIs, which say where in the stack the
-      // Link Register is.  For DARWIN and AIX (used by apple and
-      // linux ppc64), it's in sp[2].  For SYSV (used by linux ppc),
-      // it's in sp[1].
-#if defined(__PPC64__)
-      // This check is in case the compiler doesn't define _CALL_AIX/etc.
-      result[n] = *(sp+2);
-#elif defined(__linux)
-      // This check is in case the compiler doesn't define _CALL_SYSV.
-      result[n] = *(sp+1);
-#endif
-
-#if IS_STACK_FRAMES
-      if (next_sp > sp) {
-        sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    sp = next_sp;
-  }
-  return n;
-}
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_powerpc-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_powerpc-inl.h
deleted file mode 100644
index 811d6cc9..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_powerpc-inl.h
+++ /dev/null
@@ -1,176 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// Produce stack trace.  I'm guessing (hoping!) the code is much like
-// for x86.  For apple machines, at least, it seems to be; see
-//    http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html
-//    http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
-// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882
-
-#ifndef BASE_STACKTRACE_POWERPC_INL_H_
-#define BASE_STACKTRACE_POWERPC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <stdint.h>   // for uintptr_t
-#include <stdlib.h>   // for NULL
-#include <gperftools/stacktrace.h>
-
-struct layout_ppc {
-  struct layout_ppc *next;
-#if defined(__APPLE__) || (defined(__linux) && defined(__PPC64__))
-  long condition_register;
-#endif
-  void *return_addr;
-};
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING>
-static layout_ppc *NextStackFrame(layout_ppc *current) {
-  uintptr_t old_sp = (uintptr_t)(current);
-  uintptr_t new_sp = (uintptr_t)(current->next);
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp)
-      return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if (new_sp - old_sp > 100000)
-      return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp)
-      return NULL;
-    // And allow frames upto about 1MB.
-    if ((new_sp > old_sp) && (new_sp - old_sp > 1000000))
-      return NULL;
-  }
-  if (new_sp & (sizeof(void *) - 1))
-    return NULL;
-  return current->next;
-}
-
-// This ensures that GetStackTrace stes up the Link Register properly.
-void StacktracePowerPCDummyFunction() __attribute__((noinline));
-void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
-#endif  // BASE_STACKTRACE_POWERPC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// Load instruction used on top-of-stack get.
-#if defined(__PPC64__) || defined(__LP64__)
-# define LOAD "ld"
-#else
-# define LOAD "lwz"
-#endif
-
-#if defined(__linux__) && defined(__PPC__)
-# define TOP_STACK "%0,0(1)"
-#elif defined(__MACH__) && defined(__APPLE__)
-// Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
-// and Darwin 8.8.1 (Tiger) use as 1.38.  This means we have to use a
-// different asm syntax.  I don't know quite the best way to discriminate
-// systems using the old as from the new one; I've gone with __APPLE__.
-// TODO(csilvers): use autoconf instead, to look for 'as --version' == 1 or 2
-# define TOP_STACK "%0,0(r1)"
-#endif
-
-
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  layout_ppc *current;
-  int n;
-
-  // Force GCC to spill LR.
-  asm volatile ("" : "=l"(current));
-
-  // Get the address on top-of-stack
-  asm volatile (LOAD " " TOP_STACK : "=r"(current));
-
-  StacktracePowerPCDummyFunction();
-
-  n = 0;
-  skip_count++; // skip parent's frame due to indirection in
-                // stacktrace.cc
-  while (current && n < max_depth) {
-
-    // The GetStackFrames routine is called when we are in some
-    // informational context (the failure signal handler for example).
-    // Use the non-strict unwinding rules to produce a stack trace
-    // that is as complete as possible (even if it contains a few
-    // bogus entries in some rare cases).
-    layout_ppc *next = NextStackFrame<!IS_STACK_FRAMES>(current);
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n] = current->return_addr;
-#if IS_STACK_FRAMES
-      if (next > current) {
-        sizes[n] = (uintptr_t)next - (uintptr_t)current;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    current = next;
-  }
-
-  // It's possible the second-last stack frame can't return
-  // (that is, it's __libc_start_main), in which case
-  // the CRT startup code will have set its LR to 'NULL'.
-  if (n > 0 && result[n-1] == NULL)
-    n--;
-
-  return n;
-}
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_powerpc-linux-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_powerpc-linux-inl.h
deleted file mode 100644
index a301a46..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_powerpc-linux-inl.h
+++ /dev/null
@@ -1,231 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// Produce stack trace.  ABI documentation reference can be found at:
-// * PowerPC32 ABI: https://www.power.org/documentation/
-// power-architecture-32-bit-abi-supplement-1-0-embeddedlinuxunified/
-// * PowerPC64 ABI:
-// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
-
-#ifndef BASE_STACKTRACE_POWERPC_INL_H_
-#define BASE_STACKTRACE_POWERPC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <stdint.h>   // for uintptr_t
-#include <stdlib.h>   // for NULL
-#include <signal.h>  // for siginfo_t
-#include <gperftools/stacktrace.h>
-#include <base/vdso_support.h>
-
-#if defined(HAVE_SYS_UCONTEXT_H)
-#include <sys/ucontext.h>
-#elif defined(HAVE_UCONTEXT_H)
-#include <ucontext.h>  // for ucontext_t
-#endif
-
-// PowerPC64 Little Endian follows BE wrt. backchain, condition register,
-// and LR save area, so no need to adjust the reading struct.
-struct layout_ppc {
-  struct layout_ppc *next;
-#ifdef __PPC64__
-  long condition_register;
-#endif
-  void *return_addr;
-};
-
-// Signal callbacks are handled by the vDSO symbol:
-//
-// * PowerPC64 Linux (arch/powerpc/kernel/vdso64/sigtramp.S):
-//   __kernel_sigtramp_rt64
-// * PowerPC32 Linux (arch/powerpc/kernel/vdso32/sigtramp.S):
-//   __kernel_sigtramp32
-//   __kernel_sigtramp_rt32
-//
-// So a backtrace may need to specially handling if the symbol readed is
-// the signal trampoline.
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING>
-static layout_ppc *NextStackFrame(layout_ppc *current) {
-  uintptr_t old_sp = (uintptr_t)(current);
-  uintptr_t new_sp = (uintptr_t)(current->next);
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp)
-      return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if (new_sp - old_sp > 100000)
-      return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp)
-      return NULL;
-    // And allow frames upto about 1MB.
-    if ((new_sp > old_sp) && (new_sp - old_sp > 1000000))
-      return NULL;
-  }
-  if (new_sp & (sizeof(void *) - 1))
-    return NULL;
-  return current->next;
-}
-
-// This ensures that GetStackTrace stes up the Link Register properly.
-void StacktracePowerPCDummyFunction() __attribute__((noinline));
-void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
-#endif  // BASE_STACKTRACE_POWERPC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// Load instruction used on top-of-stack get.
-#if defined(__PPC64__) || defined(__LP64__)
-# define LOAD "ld"
-#else
-# define LOAD "lwz"
-#endif
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  layout_ppc *current;
-  int n;
-
-  // Get the address on top-of-stack
-  current = reinterpret_cast<layout_ppc*> (__builtin_frame_address (0));
-  // And ignore the current symbol
-  current = current->next;
-
-  StacktracePowerPCDummyFunction();
-
-  n = 0;
-  skip_count++; // skip parent's frame due to indirection in
-                // stacktrace.cc
-
-  base::VDSOSupport vdso;
-  base::ElfMemImage::SymbolInfo rt_sigreturn_symbol_info;
-#ifdef __PPC64__
-  const void *sigtramp64_vdso = 0;
-  if (vdso.LookupSymbol("__kernel_sigtramp_rt64", "LINUX_2.6.15", STT_NOTYPE,
-                        &rt_sigreturn_symbol_info))
-    sigtramp64_vdso = rt_sigreturn_symbol_info.address;
-#else
-  const void *sigtramp32_vdso = 0;
-  if (vdso.LookupSymbol("__kernel_sigtramp32", "LINUX_2.6.15", STT_NOTYPE,
-                        &rt_sigreturn_symbol_info))
-    sigtramp32_vdso = rt_sigreturn_symbol_info.address;
-  const void *sigtramp32_rt_vdso = 0;
-  if (vdso.LookupSymbol("__kernel_sigtramp_rt32", "LINUX_2.6.15", STT_NOTYPE,
-                        &rt_sigreturn_symbol_info))
-    sigtramp32_rt_vdso = rt_sigreturn_symbol_info.address;
-#endif
-
-  while (current && n < max_depth) {
-
-    // The GetStackFrames routine is called when we are in some
-    // informational context (the failure signal handler for example).
-    // Use the non-strict unwinding rules to produce a stack trace
-    // that is as complete as possible (even if it contains a few
-    // bogus entries in some rare cases).
-    layout_ppc *next = NextStackFrame<!IS_STACK_FRAMES>(current);
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n] = current->return_addr;
-#ifdef __PPC64__
-      if (sigtramp64_vdso && (sigtramp64_vdso == current->return_addr)) {
-        struct signal_frame_64 {
-          char dummy[128];
-          ucontext_t uc;
-        // We don't care about the rest, since the IP value is at 'uc' field.
-        } *sigframe = reinterpret_cast<signal_frame_64*>(current);
-        result[n] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP];
-      }
-#else
-      if (sigtramp32_vdso && (sigtramp32_vdso == current->return_addr)) {
-        struct signal_frame_32 {
-          char dummy[64];
-          struct sigcontext sctx;
-          mcontext_t mctx;
-          // We don't care about the rest, since IP value is at 'mctx' field.
-        } *sigframe = reinterpret_cast<signal_frame_32*>(current);
-        result[n] = (void*) sigframe->mctx.gregs[PT_NIP];
-      } else if (sigtramp32_rt_vdso && (sigtramp32_rt_vdso == current->return_addr)) {
-        struct rt_signal_frame_32 {
-          char dummy[64 + 16];
-          siginfo_t info;
-          ucontext_t uc;
-          // We don't care about the rest, since IP value is at 'uc' field.A
-        } *sigframe = reinterpret_cast<rt_signal_frame_32*>(current);
-        result[n] = (void*) sigframe->uc.uc_mcontext.uc_regs->gregs[PT_NIP];
-      }
-#endif
-
-#if IS_STACK_FRAMES
-      if (next > current) {
-        sizes[n] = (uintptr_t)next - (uintptr_t)current;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    current = next;
-  }
-
-  // It's possible the second-last stack frame can't return
-  // (that is, it's __libc_start_main), in which case
-  // the CRT startup code will have set its LR to 'NULL'.
-  if (n > 0 && result[n-1] == NULL)
-    n--;
-
-  return n;
-}
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_win32-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_win32-inl.h
deleted file mode 100644
index 663e9a5..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_win32-inl.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Produces a stack trace for Windows.  Normally, one could use
-// stacktrace_x86-inl.h or stacktrace_x86_64-inl.h -- and indeed, that
-// should work for binaries compiled using MSVC in "debug" mode.
-// However, in "release" mode, Windows uses frame-pointer
-// optimization, which makes getting a stack trace very difficult.
-//
-// There are several approaches one can take.  One is to use Windows
-// intrinsics like StackWalk64.  These can work, but have restrictions
-// on how successful they can be.  Another attempt is to write a
-// version of stacktrace_x86-inl.h that has heuristic support for
-// dealing with FPO, similar to what WinDbg does (see
-// http://www.nynaeve.net/?p=97).
-//
-// The solution we've ended up doing is to call the undocumented
-// windows function RtlCaptureStackBackTrace, which probably doesn't
-// work with FPO but at least is fast, and doesn't require a symbol
-// server.
-//
-// This code is inspired by a patch from David Vitek:
-//   http://code.google.com/p/gperftools/issues/detail?id=83
-
-#ifndef BASE_STACKTRACE_WIN32_INL_H_
-#define BASE_STACKTRACE_WIN32_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include "config.h"
-#include <windows.h>    // for GetProcAddress and GetModuleHandle
-#include <assert.h>
-
-typedef USHORT NTAPI RtlCaptureStackBackTrace_Function(
-    IN ULONG frames_to_skip,
-    IN ULONG frames_to_capture,
-    OUT PVOID *backtrace,
-    OUT PULONG backtrace_hash);
-
-// Load the function we need at static init time, where we don't have
-// to worry about someone else holding the loader's lock.
-static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =
-   (RtlCaptureStackBackTrace_Function*)
-   GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
-
-static int GetStackTrace_win32(void** result, int max_depth,
-                               int skip_count) {
-  if (!RtlCaptureStackBackTrace_fn) {
-    // TODO(csilvers): should we log an error here?
-    return 0;     // can't find a stacktrace with no function to call
-  }
-  return (int)RtlCaptureStackBackTrace_fn(skip_count + 3, max_depth,
-                                          result, 0);
-}
-
-static int not_implemented(void) {
-  assert(0 == "Not yet implemented");
-  return 0;
-}
-
-static int GetStackFrames_win32(void** /* pcs */,
-                                int* /* sizes */,
-                                int /* max_depth */,
-                                int /* skip_count */) {
-  return not_implemented();
-}
-
-static int GetStackFramesWithContext_win32(void** result, int* sizes, int max_depth,
-                                           int skip_count, const void *uc) {
-  return not_implemented();
-}
-
-static int GetStackTraceWithContext_win32(void** result, int max_depth,
-                                          int skip_count, const void *uc) {
-  return not_implemented();
-}
-
-
-#endif  // BASE_STACKTRACE_WIN32_INL_H_
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h
deleted file mode 100644
index 46eb5d8..0000000
--- a/third_party/tcmalloc/chromium/src/stacktrace_x86-inl.h
+++ /dev/null
@@ -1,354 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Produce stack trace
-
-#ifndef BASE_STACKTRACE_X86_INL_H_
-#define BASE_STACKTRACE_X86_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include "config.h"
-#include <stdlib.h>   // for NULL
-#include <assert.h>
-#if defined(HAVE_SYS_UCONTEXT_H)
-#include <sys/ucontext.h>
-#elif defined(HAVE_UCONTEXT_H)
-#include <ucontext.h>  // for ucontext_t
-#elif defined(HAVE_CYGWIN_SIGNAL_H)
-// cygwin/signal.h has a buglet where it uses pthread_attr_t without
-// #including <pthread.h> itself.  So we have to do it.
-# ifdef HAVE_PTHREAD
-# include <pthread.h>
-# endif
-#include <cygwin/signal.h>
-typedef ucontext ucontext_t;
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>   // for uintptr_t
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h> // for msync
-#include "base/vdso_support.h"
-#endif
-
-#include "gperftools/stacktrace.h"
-
-#if defined(__linux__) && defined(__i386__) && defined(__ELF__) && defined(HAVE_MMAP)
-// Count "push %reg" instructions in VDSO __kernel_vsyscall(),
-// preceding "syscall" or "sysenter".
-// If __kernel_vsyscall uses frame pointer, answer 0.
-//
-// kMaxBytes tells how many instruction bytes of __kernel_vsyscall
-// to analyze before giving up. Up to kMaxBytes+1 bytes of
-// instructions could be accessed.
-//
-// Here are known __kernel_vsyscall instruction sequences:
-//
-// SYSENTER (linux-2.6.26/arch/x86/vdso/vdso32/sysenter.S).
-// Used on Intel.
-//  0xffffe400 <__kernel_vsyscall+0>:       push   %ecx
-//  0xffffe401 <__kernel_vsyscall+1>:       push   %edx
-//  0xffffe402 <__kernel_vsyscall+2>:       push   %ebp
-//  0xffffe403 <__kernel_vsyscall+3>:       mov    %esp,%ebp
-//  0xffffe405 <__kernel_vsyscall+5>:       sysenter
-//
-// SYSCALL (see linux-2.6.26/arch/x86/vdso/vdso32/syscall.S).
-// Used on AMD.
-//  0xffffe400 <__kernel_vsyscall+0>:       push   %ebp
-//  0xffffe401 <__kernel_vsyscall+1>:       mov    %ecx,%ebp
-//  0xffffe403 <__kernel_vsyscall+3>:       syscall
-//
-// i386 (see linux-2.6.26/arch/x86/vdso/vdso32/int80.S)
-//  0xffffe400 <__kernel_vsyscall+0>:       int $0x80
-//  0xffffe401 <__kernel_vsyscall+1>:       ret
-//
-static const int kMaxBytes = 10;
-
-// We use assert()s instead of DCHECK()s -- this is too low level
-// for DCHECK().
-
-static int CountPushInstructions(const unsigned char *const addr) {
-  int result = 0;
-  for (int i = 0; i < kMaxBytes; ++i) {
-    if (addr[i] == 0x89) {
-      // "mov reg,reg"
-      if (addr[i + 1] == 0xE5) {
-        // Found "mov %esp,%ebp".
-        return 0;
-      }
-      ++i;  // Skip register encoding byte.
-    } else if (addr[i] == 0x0F &&
-               (addr[i + 1] == 0x34 || addr[i + 1] == 0x05)) {
-      // Found "sysenter" or "syscall".
-      return result;
-    } else if ((addr[i] & 0xF0) == 0x50) {
-      // Found "push %reg".
-      ++result;
-    } else if (addr[i] == 0xCD && addr[i + 1] == 0x80) {
-      // Found "int $0x80"
-      assert(result == 0);
-      return 0;
-    } else {
-      // Unexpected instruction.
-      assert(0 == "unexpected instruction in __kernel_vsyscall");
-      return 0;
-    }
-  }
-  // Unexpected: didn't find SYSENTER or SYSCALL in
-  // [__kernel_vsyscall, __kernel_vsyscall + kMaxBytes) interval.
-  assert(0 == "did not find SYSENTER or SYSCALL in __kernel_vsyscall");
-  return 0;
-}
-#endif
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING, bool WITH_CONTEXT>
-static void **NextStackFrame(void **old_sp, const void *uc) {
-  void **new_sp = (void **) *old_sp;
-
-#if defined(__linux__) && defined(__i386__) && defined(HAVE_VDSO_SUPPORT)
-  if (WITH_CONTEXT && uc != NULL) {
-    // How many "push %reg" instructions are there at __kernel_vsyscall?
-    // This is constant for a given kernel and processor, so compute
-    // it only once.
-    static int num_push_instructions = -1;  // Sentinel: not computed yet.
-    // Initialize with sentinel value: __kernel_rt_sigreturn can not possibly
-    // be there.
-    static const unsigned char *kernel_rt_sigreturn_address = NULL;
-    static const unsigned char *kernel_vsyscall_address = NULL;
-    if (num_push_instructions == -1) {
-      base::VDSOSupport vdso;
-      if (vdso.IsPresent()) {
-        base::VDSOSupport::SymbolInfo rt_sigreturn_symbol_info;
-        base::VDSOSupport::SymbolInfo vsyscall_symbol_info;
-        if (!vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_2.5",
-                               STT_FUNC, &rt_sigreturn_symbol_info) ||
-            !vdso.LookupSymbol("__kernel_vsyscall", "LINUX_2.5",
-                               STT_FUNC, &vsyscall_symbol_info) ||
-            rt_sigreturn_symbol_info.address == NULL ||
-            vsyscall_symbol_info.address == NULL) {
-          // Unexpected: 32-bit VDSO is present, yet one of the expected
-          // symbols is missing or NULL.
-          assert(0 == "VDSO is present, but doesn't have expected symbols");
-          num_push_instructions = 0;
-        } else {
-          kernel_rt_sigreturn_address =
-              reinterpret_cast<const unsigned char *>(
-                  rt_sigreturn_symbol_info.address);
-          kernel_vsyscall_address =
-              reinterpret_cast<const unsigned char *>(
-                  vsyscall_symbol_info.address);
-          num_push_instructions =
-              CountPushInstructions(kernel_vsyscall_address);
-        }
-      } else {
-        num_push_instructions = 0;
-      }
-    }
-    if (num_push_instructions != 0 && kernel_rt_sigreturn_address != NULL &&
-        old_sp[1] == kernel_rt_sigreturn_address) {
-      const ucontext_t *ucv = static_cast<const ucontext_t *>(uc);
-      // This kernel does not use frame pointer in its VDSO code,
-      // and so %ebp is not suitable for unwinding.
-      void **const reg_ebp =
-          reinterpret_cast<void **>(ucv->uc_mcontext.gregs[REG_EBP]);
-      const unsigned char *const reg_eip =
-          reinterpret_cast<unsigned char *>(ucv->uc_mcontext.gregs[REG_EIP]);
-      if (new_sp == reg_ebp &&
-          kernel_vsyscall_address <= reg_eip &&
-          reg_eip - kernel_vsyscall_address < kMaxBytes) {
-        // We "stepped up" to __kernel_vsyscall, but %ebp is not usable.
-        // Restore from 'ucv' instead.
-        void **const reg_esp =
-            reinterpret_cast<void **>(ucv->uc_mcontext.gregs[REG_ESP]);
-        // Check that alleged %esp is not NULL and is reasonably aligned.
-        if (reg_esp &&
-            ((uintptr_t)reg_esp & (sizeof(reg_esp) - 1)) == 0) {
-          // Check that alleged %esp is actually readable. This is to prevent
-          // "double fault" in case we hit the first fault due to e.g. stack
-          // corruption.
-          //
-          // page_size is linker-initalized to avoid async-unsafe locking
-          // that GCC would otherwise insert (__cxa_guard_acquire etc).
-          static int page_size;
-          if (page_size == 0) {
-            // First time through.
-            page_size = getpagesize();
-          }
-          void *const reg_esp_aligned =
-              reinterpret_cast<void *>(
-                  (uintptr_t)(reg_esp + num_push_instructions - 1) &
-                  ~(page_size - 1));
-          if (msync(reg_esp_aligned, page_size, MS_ASYNC) == 0) {
-            // Alleged %esp is readable, use it for further unwinding.
-            new_sp = reinterpret_cast<void **>(
-                reg_esp[num_push_instructions - 1]);
-          }
-        }
-      }
-    }
-  }
-#endif
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp) return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp) return NULL;
-    if (new_sp > old_sp) {
-      // And allow frames upto about 1MB.
-      const uintptr_t delta = (uintptr_t)new_sp - (uintptr_t)old_sp;
-      const uintptr_t acceptable_delta = 1000000;
-      if (delta > acceptable_delta) {
-        return NULL;
-      }
-    }
-  }
-  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
-#ifdef __i386__
-  // On 64-bit machines, the stack pointer can be very close to
-  // 0xffffffff, so we explicitly check for a pointer into the
-  // last two pages in the address space
-  if ((uintptr_t)new_sp >= 0xffffe000) return NULL;
-#endif
-#ifdef HAVE_MMAP
-  if (!STRICT_UNWINDING) {
-    // Lax sanity checks cause a crash on AMD-based machines with
-    // VDSO-enabled kernels.
-    // Make an extra sanity check to insure new_sp is readable.
-    // Note: NextStackFrame<false>() is only called while the program
-    //       is already on its last leg, so it's ok to be slow here.
-    static int page_size = getpagesize();
-    void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1));
-    if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1)
-      return NULL;
-  }
-#endif
-  return new_sp;
-}
-
-#endif  // BASE_STACKTRACE_X86_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-
-static int GET_STACK_TRACE_OR_FRAMES {
-  void **sp;
-#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) || __llvm__
-  // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8.
-  // It's always correct on llvm, and the techniques below aren't (in
-  // particular, llvm-gcc will make a copy of pcs, so it's not in sp[2]),
-  // so we also prefer __builtin_frame_address when running under llvm.
-  sp = reinterpret_cast<void**>(__builtin_frame_address(0));
-#elif defined(__i386__)
-  // Stack frame format:
-  //    sp[0]   pointer to previous frame
-  //    sp[1]   caller address
-  //    sp[2]   first argument
-  //    ...
-  // NOTE: This will break under llvm, since result is a copy and not in sp[2]
-  sp = (void **)&result - 2;
-#elif defined(__x86_64__)
-  unsigned long rbp;
-  // Move the value of the register %rbp into the local variable rbp.
-  // We need 'volatile' to prevent this instruction from getting moved
-  // around during optimization to before function prologue is done.
-  // An alternative way to achieve this
-  // would be (before this __asm__ instruction) to call Noop() defined as
-  //   static void Noop() __attribute__ ((noinline));  // prevent inlining
-  //   static void Noop() { asm(""); }  // prevent optimizing-away
-  __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
-  // Arguments are passed in registers on x86-64, so we can't just
-  // offset from &result
-  sp = (void **) rbp;
-#else
-# error Using stacktrace_x86-inl.h on a non x86 architecture!
-#endif
-
-  skip_count++; // skip parent's frame due to indirection in stacktrace.cc
-
-  int n = 0;
-  while (sp && n < max_depth) {
-    if (*(sp+1) == reinterpret_cast<void *>(0)) {
-      // In 64-bit code, we often see a frame that
-      // points to itself and has a return address of 0.
-      break;
-    }
-#if !IS_WITH_CONTEXT
-    const void *const ucp = NULL;
-#endif
-    void **next_sp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(sp, ucp);
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n] = *(sp+1);
-#if IS_STACK_FRAMES
-      if (next_sp > sp) {
-        sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    sp = next_sp;
-  }
-  return n;
-}
diff --git a/third_party/tcmalloc/chromium/src/static_vars.cc b/third_party/tcmalloc/chromium/src/static_vars.cc
deleted file mode 100644
index 73beb154..0000000
--- a/third_party/tcmalloc/chromium/src/static_vars.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Ken Ashcraft <opensource@google.com>
-
-#include <config.h>
-#include "static_vars.h"
-#include <stddef.h>                     // for NULL
-#include <new>                          // for operator new
-#ifdef HAVE_PTHREAD
-#include <pthread.h>                    // for pthread_atfork
-#endif
-#include "internal_logging.h"  // for CHECK_CONDITION
-#include "common.h"
-#include "sampler.h"           // for Sampler
-#include "getenv_safe.h"       // TCMallocGetenvSafe
-#include "base/googleinit.h"
-#include "maybe_threads.h"
-
-namespace tcmalloc {
-
-#if defined(HAVE_FORK) && defined(HAVE_PTHREAD)
-// These following two functions are registered via pthread_atfork to make
-// sure the central_cache locks remain in a consisten state in the forked
-// version of the thread.
-
-void CentralCacheLockAll() NO_THREAD_SAFETY_ANALYSIS
-{
-  Static::pageheap_lock()->Lock();
-  for (int i = 0; i < Static::num_size_classes(); ++i)
-    Static::central_cache()[i].Lock();
-}
-
-void CentralCacheUnlockAll() NO_THREAD_SAFETY_ANALYSIS
-{
-  for (int i = 0; i < Static::num_size_classes(); ++i)
-    Static::central_cache()[i].Unlock();
-  Static::pageheap_lock()->Unlock();
-}
-#endif
-
-bool Static::inited_;
-SpinLock Static::pageheap_lock_(SpinLock::LINKER_INITIALIZED);
-SizeMap Static::sizemap_;
-CentralFreeListPadded Static::central_cache_[kClassSizesMax];
-PageHeapAllocator<Span> Static::span_allocator_;
-PageHeapAllocator<StackTrace> Static::stacktrace_allocator_;
-Span Static::sampled_objects_;
-PageHeapAllocator<StackTraceTable::Bucket> Static::bucket_allocator_;
-StackTrace* Static::growth_stacks_ = NULL;
-Static::PageHeapStorage Static::pageheap_;
-
-void Static::InitStaticVars() {
-  sizemap_.Init();
-  span_allocator_.Init();
-  span_allocator_.New(); // Reduce cache conflicts
-  span_allocator_.New(); // Reduce cache conflicts
-  stacktrace_allocator_.Init();
-  bucket_allocator_.Init();
-  // Do a bit of sanitizing: make sure central_cache is aligned properly
-  CHECK_CONDITION((sizeof(central_cache_[0]) % 64) == 0);
-  for (int i = 0; i < num_size_classes(); ++i) {
-    central_cache_[i].Init(i);
-  }
-
-  new (&pageheap_.memory) PageHeap;
-
-  bool aggressive_decommit = tcmalloc::commandlineflags::StringToBool(
-      TCMallocGetenvSafe("TCMALLOC_AGGRESSIVE_DECOMMIT"), true);
-
-  pageheap()->SetAggressiveDecommit(aggressive_decommit);
-
-  inited_ = true;
-
-  DLL_Init(&sampled_objects_);
-}
-
-void Static::InitLateMaybeRecursive() {
-#if defined(HAVE_FORK) && defined(HAVE_PTHREAD) \
-  && !defined(__APPLE__) && !defined(TCMALLOC_NO_ATFORK)
-  // OSX has it's own way of handling atfork in malloc (see
-  // libc_override_osx.h).
-  //
-  // For other OSes we do pthread_atfork even if standard seemingly
-  // discourages pthread_atfork, asking apps to do only
-  // async-signal-safe calls between fork and exec.
-  //
-  // We're deliberately attempting to register atfork handlers as part
-  // of malloc initialization. So very early. This ensures that our
-  // handler is called last and that means fork will try to grab
-  // tcmalloc locks last avoiding possible issues with many other
-  // locks that are held around calls to malloc. I.e. if we don't do
-  // that, fork() grabbing malloc lock before such other lock would be
-  // prone to deadlock, if some other thread holds other lock and
-  // calls malloc.
-  //
-  // We still leave some way of disabling it via
-  // -DTCMALLOC_NO_ATFORK. It looks like on glibc even with fully
-  // static binaries malloc is really initialized very early. But I
-  // can see how combination of static linking and other libc-s could
-  // be less fortunate and allow some early app constructors to run
-  // before malloc is ever called.
-
-  perftools_pthread_atfork(
-    CentralCacheLockAll,    // parent calls before fork
-    CentralCacheUnlockAll,  // parent calls after fork
-    CentralCacheUnlockAll); // child calls after fork
-#endif
-
-#ifndef NDEBUG
-  // pthread_atfork above may malloc sometimes. Lets ensure we test
-  // that malloc works from here.
-  free(malloc(1));
-#endif
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/static_vars.h b/third_party/tcmalloc/chromium/src/static_vars.h
deleted file mode 100644
index 3eeae0f..0000000
--- a/third_party/tcmalloc/chromium/src/static_vars.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Ken Ashcraft <opensource@google.com>
-//
-// Static variables shared by multiple classes.
-
-#ifndef TCMALLOC_STATIC_VARS_H_
-#define TCMALLOC_STATIC_VARS_H_
-
-#include <config.h>
-#include "base/basictypes.h"
-#include "base/spinlock.h"
-#include "central_freelist.h"
-#include "common.h"
-#include "page_heap.h"
-#include "page_heap_allocator.h"
-#include "span.h"
-#include "stack_trace_table.h"
-
-namespace tcmalloc {
-
-class Static {
- public:
-  // Linker initialized, so this lock can be accessed at any time.
-  static SpinLock* pageheap_lock() { return &pageheap_lock_; }
-
-  // Must be called before calling any of the accessors below.
-  static void InitStaticVars();
-  static void InitLateMaybeRecursive();
-
-  // Central cache -- an array of free-lists, one per size-class.
-  // We have a separate lock per free-list to reduce contention.
-  static CentralFreeListPadded* central_cache() { return central_cache_; }
-
-  static SizeMap* sizemap() { return &sizemap_; }
-
-  static unsigned num_size_classes() { return sizemap_.num_size_classes; }
-
-  //////////////////////////////////////////////////////////////////////
-  // In addition to the explicit initialization comment, the variables below
-  // must be protected by pageheap_lock.
-
-  // Page-level allocator.
-  static PageHeap* pageheap() { return reinterpret_cast<PageHeap *>(&pageheap_.memory); }
-
-  static PageHeapAllocator<Span>* span_allocator() { return &span_allocator_; }
-
-  static PageHeapAllocator<StackTrace>* stacktrace_allocator() {
-    return &stacktrace_allocator_;
-  }
-
-  static StackTrace* growth_stacks() { return growth_stacks_; }
-  static void set_growth_stacks(StackTrace* s) { growth_stacks_ = s; }
-
-  // State kept for sampled allocations (/pprof/heap support)
-  static Span* sampled_objects() { return &sampled_objects_; }
-  static PageHeapAllocator<StackTraceTable::Bucket>* bucket_allocator() {
-    return &bucket_allocator_;
-  }
-
-  // Check if InitStaticVars() has been run.
-  static bool IsInited() { return inited_; }
-
- private:
-  // some unit tests depend on this and link to static vars
-  // imperfectly. Thus we keep those unhidden for now. Thankfully
-  // they're not performance-critical.
-  /* ATTRIBUTE_HIDDEN */ static bool inited_;
-  /* ATTRIBUTE_HIDDEN */ static SpinLock pageheap_lock_;
-
-  // These static variables require explicit initialization.  We cannot
-  // count on their constructors to do any initialization because other
-  // static variables may try to allocate memory before these variables
-  // can run their constructors.
-
-  ATTRIBUTE_HIDDEN static SizeMap sizemap_;
-  ATTRIBUTE_HIDDEN static CentralFreeListPadded central_cache_[kClassSizesMax];
-  ATTRIBUTE_HIDDEN static PageHeapAllocator<Span> span_allocator_;
-  ATTRIBUTE_HIDDEN static PageHeapAllocator<StackTrace> stacktrace_allocator_;
-  ATTRIBUTE_HIDDEN static Span sampled_objects_;
-  ATTRIBUTE_HIDDEN static PageHeapAllocator<StackTraceTable::Bucket> bucket_allocator_;
-
-  // Linked list of stack traces recorded every time we allocated memory
-  // from the system.  Useful for finding allocation sites that cause
-  // increase in the footprint of the system.  The linked list pointer
-  // is stored in trace->stack[kMaxStackDepth-1].
-  ATTRIBUTE_HIDDEN static StackTrace* growth_stacks_;
-
-  // PageHeap uses a constructor for initialization.  Like the members above,
-  // we can't depend on initialization order, so pageheap is new'd
-  // into this buffer.
-  union PageHeapStorage {
-    char memory[sizeof(PageHeap)];
-    uintptr_t extra;  // To force alignment
-  };
-  ATTRIBUTE_HIDDEN static PageHeapStorage pageheap_;
-};
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_STATIC_VARS_H_
diff --git a/third_party/tcmalloc/chromium/src/symbolize.cc b/third_party/tcmalloc/chromium/src/symbolize.cc
deleted file mode 100755
index ab5bcad..0000000
--- a/third_party/tcmalloc/chromium/src/symbolize.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This forks out to pprof to do the actual symbolizing.  We might
-// be better off writing our own in C++.
-
-#include "config.h"
-#include "symbolize.h"
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>   // for write()
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>   // for socketpair() -- needed by Symbolize
-#endif
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>   // for wait() -- needed by Symbolize
-#endif
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif
-#ifdef __MACH__
-#include <mach-o/dyld.h>   // for GetProgramInvocationName()
-#include <limits.h>        // for PATH_MAX
-#endif
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-#include <io.h>            // for get_osfhandle()
-#endif
-#include <string>
-#include "base/commandlineflags.h"
-#include "base/logging.h"
-#include "base/sysinfo.h"
-#if defined(__FreeBSD__)
-#include <sys/sysctl.h>
-#endif
-
-using std::string;
-using tcmalloc::DumpProcSelfMaps;   // from sysinfo.h
-
-
-DEFINE_string(symbolize_pprof,
-              EnvToString("PPROF_PATH", "pprof"),
-              "Path to pprof to call for reporting function names.");
-
-// Returns NULL if we're on an OS where we can't get the invocation name.
-// Using a static var is ok because we're not called from a thread.
-static const char* GetProgramInvocationName() {
-#if defined(HAVE_PROGRAM_INVOCATION_NAME)
-#ifdef __UCLIBC__
-  extern const char* program_invocation_name; // uclibc provides this
-#else
-  extern char* program_invocation_name;  // gcc provides this
-#endif
-  return program_invocation_name;
-#elif defined(__MACH__)
-  // We don't want to allocate memory for this since we may be
-  // calculating it when memory is corrupted.
-  static char program_invocation_name[PATH_MAX];
-  if (program_invocation_name[0] == '\0') {  // first time calculating
-    uint32_t length = sizeof(program_invocation_name);
-    if (_NSGetExecutablePath(program_invocation_name, &length))
-      return NULL;
-  }
-  return program_invocation_name;
-#elif defined(__FreeBSD__)
-  static char program_invocation_name[PATH_MAX];
-  size_t len = sizeof(program_invocation_name);
-  static const int name[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
-  if (!sysctl(name, 4, program_invocation_name, &len, NULL, 0))
-    return program_invocation_name;
-  return NULL;
-#else
-  return NULL;   // figure out a way to get argv[0]
-#endif
-}
-
-// Prints an error message when you can't run Symbolize().
-static void PrintError(const char* reason) {
-  RAW_LOG(ERROR,
-          "*** WARNING: Cannot convert addresses to symbols in output below.\n"
-          "*** Reason: %s\n"
-          "*** If you cannot fix this, try running pprof directly.\n",
-          reason);
-}
-
-void SymbolTable::Add(const void* addr) {
-  symbolization_table_[addr] = "";
-}
-
-const char* SymbolTable::GetSymbol(const void* addr) {
-  return symbolization_table_[addr];
-}
-
-// Updates symbolization_table with the pointers to symbol names corresponding
-// to its keys. The symbol names are stored in out, which is allocated and
-// freed by the caller of this routine.
-// Note that the forking/etc is not thread-safe or re-entrant.  That's
-// ok for the purpose we need -- reporting leaks detected by heap-checker
-// -- but be careful if you decide to use this routine for other purposes.
-// Returns number of symbols read on error.  If can't symbolize, returns 0
-// and emits an error message about why.
-int SymbolTable::Symbolize() {
-#if !defined(HAVE_UNISTD_H)  || !defined(HAVE_SYS_SOCKET_H) || !defined(HAVE_SYS_WAIT_H)
-  PrintError("Perftools does not know how to call a sub-process on this O/S");
-  return 0;
-#else
-  const char* argv0 = GetProgramInvocationName();
-  if (argv0 == NULL) {  // can't call symbolize if we can't figure out our name
-    PrintError("Cannot figure out the name of this executable (argv0)");
-    return 0;
-  }
-  if (access(FLAGS_symbolize_pprof, R_OK) != 0) {
-    PrintError("Cannot find 'pprof' (is PPROF_PATH set correctly?)");
-    return 0;
-  }
-
-  // All this work is to do two-way communication.  ugh.
-  int *child_in = NULL;   // file descriptors
-  int *child_out = NULL;  // for now, we don't worry about child_err
-  int child_fds[5][2];    // socketpair may be called up to five times below
-
-  // The client program may close its stdin and/or stdout and/or stderr
-  // thus allowing socketpair to reuse file descriptors 0, 1 or 2.
-  // In this case the communication between the forked processes may be broken
-  // if either the parent or the child tries to close or duplicate these
-  // descriptors. The loop below produces two pairs of file descriptors, each
-  // greater than 2 (stderr).
-  for (int i = 0; i < 5; i++) {
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, child_fds[i]) == -1) {
-      for (int j = 0; j < i; j++) {
-        close(child_fds[j][0]);
-        close(child_fds[j][1]);
-        PrintError("Cannot create a socket pair");
-      }
-      return 0;
-    } else {
-      if ((child_fds[i][0] > 2) && (child_fds[i][1] > 2)) {
-        if (child_in == NULL) {
-          child_in = child_fds[i];
-        } else {
-          child_out = child_fds[i];
-          for (int j = 0; j < i; j++) {
-            if (child_fds[j] == child_in) continue;
-            close(child_fds[j][0]);
-            close(child_fds[j][1]);
-          }
-          break;
-        }
-      }
-    }
-  }
-
-  switch (fork()) {
-    case -1: {  // error
-      close(child_in[0]);
-      close(child_in[1]);
-      close(child_out[0]);
-      close(child_out[1]);
-      PrintError("Unknown error calling fork()");
-      return 0;
-    }
-    case 0: {  // child
-      close(child_in[1]);   // child uses the 0's, parent uses the 1's
-      close(child_out[1]);  // child uses the 0's, parent uses the 1's
-      close(0);
-      close(1);
-      if (dup2(child_in[0], 0) == -1) _exit(1);
-      if (dup2(child_out[0], 1) == -1) _exit(2);
-      // Unset vars that might cause trouble when we fork
-      unsetenv("CPUPROFILE");
-      unsetenv("HEAPPROFILE");
-      unsetenv("HEAPCHECK");
-      unsetenv("PERFTOOLS_VERBOSE");
-      execlp(FLAGS_symbolize_pprof, FLAGS_symbolize_pprof,
-             "--symbols", argv0, NULL);
-      _exit(3);  // if execvp fails, it's bad news for us
-    }
-    default: {  // parent
-      close(child_in[0]);   // child uses the 0's, parent uses the 1's
-      close(child_out[0]);  // child uses the 0's, parent uses the 1's
-#ifdef HAVE_POLL_H
-      // Waiting for 1ms seems to give the OS time to notice any errors.
-      poll(0, 0, 1);
-      // For maximum safety, we check to make sure the execlp
-      // succeeded before trying to write.  (Otherwise we'll get a
-      // SIGPIPE.)  For systems without poll.h, we'll just skip this
-      // check, and trust that the user set PPROF_PATH correctly!
-      struct pollfd pfd = { child_in[1], POLLOUT, 0 };
-      if (!poll(&pfd, 1, 0) || !(pfd.revents & POLLOUT) ||
-          (pfd.revents & (POLLHUP|POLLERR))) {
-        PrintError("Cannot run 'pprof' (is PPROF_PATH set correctly?)");
-        return 0;
-      }
-#endif
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-      // On cygwin, DumpProcSelfMaps() takes a HANDLE, not an fd.  Convert.
-      const HANDLE symbols_handle = (HANDLE) get_osfhandle(child_in[1]);
-      DumpProcSelfMaps(symbols_handle);
-#else
-      DumpProcSelfMaps(child_in[1]);  // what pprof expects on stdin
-#endif
-
-      // Allocate 24 bytes = ("0x" + 8 bytes + "\n" + overhead) for each
-      // address to feed to pprof.
-      const int kOutBufSize = 24 * symbolization_table_.size();
-      char *pprof_buffer = new char[kOutBufSize];
-      int written = 0;
-      for (SymbolMap::const_iterator iter = symbolization_table_.begin();
-           iter != symbolization_table_.end(); ++iter) {
-        written += snprintf(pprof_buffer + written, kOutBufSize - written,
-                 // pprof expects format to be 0xXXXXXX
-                 "0x%" PRIxPTR "\n", reinterpret_cast<uintptr_t>(iter->first));
-      }
-      write(child_in[1], pprof_buffer, strlen(pprof_buffer));
-      close(child_in[1]);             // that's all we need to write
-      delete[] pprof_buffer;
-
-      const int kSymbolBufferSize = kSymbolSize * symbolization_table_.size();
-      int total_bytes_read = 0;
-      delete[] symbol_buffer_;
-      symbol_buffer_ = new char[kSymbolBufferSize];
-      memset(symbol_buffer_, '\0', kSymbolBufferSize);
-      while (1) {
-        int bytes_read = read(child_out[1], symbol_buffer_ + total_bytes_read,
-                              kSymbolBufferSize - total_bytes_read);
-        if (bytes_read < 0) {
-          close(child_out[1]);
-          PrintError("Cannot read data from pprof");
-          return 0;
-        } else if (bytes_read == 0) {
-          close(child_out[1]);
-          wait(NULL);
-          break;
-        } else {
-          total_bytes_read += bytes_read;
-        }
-      }
-      // We have successfully read the output of pprof into out.  Make sure
-      // the last symbol is full (we can tell because it ends with a \n).
-      if (total_bytes_read == 0 || symbol_buffer_[total_bytes_read - 1] != '\n')
-        return 0;
-      // make the symbolization_table_ values point to the output vector
-      SymbolMap::iterator fill = symbolization_table_.begin();
-      int num_symbols = 0;
-      const char *current_name = symbol_buffer_;
-      for (int i = 0; i < total_bytes_read; i++) {
-        if (symbol_buffer_[i] == '\n') {
-          fill->second = current_name;
-          symbol_buffer_[i] = '\0';
-          current_name = symbol_buffer_ + i + 1;
-          fill++;
-          num_symbols++;
-        }
-      }
-      return num_symbols;
-    }
-  }
-  PrintError("Unkown error (should never occur!)");
-  return 0;  // shouldn't be reachable
-#endif
-}
diff --git a/third_party/tcmalloc/chromium/src/symbolize.h b/third_party/tcmalloc/chromium/src/symbolize.h
deleted file mode 100644
index 728d073..0000000
--- a/third_party/tcmalloc/chromium/src/symbolize.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-
-#ifndef TCMALLOC_SYMBOLIZE_H_
-#define TCMALLOC_SYMBOLIZE_H_
-
-#include "config.h"
-#ifdef HAVE_STDINT_H
-#include <stdint.h>  // for uintptr_t
-#endif
-#include <stddef.h>  // for NULL
-#include <map>
-
-using std::map;
-
-// SymbolTable encapsulates the address operations necessary for stack trace
-// symbolization. A common use-case is to Add() the addresses from one or
-// several stack traces to a table, call Symbolize() once and use GetSymbol()
-// to get the symbol names for pretty-printing the stack traces.
-class SymbolTable {
- public:
-  SymbolTable()
-    : symbol_buffer_(NULL) {}
-  ~SymbolTable() {
-    delete[] symbol_buffer_;
-  }
-
-  // Adds an address to the table. This may overwrite a currently known symbol
-  // name, so Add() should not generally be called after Symbolize().
-  void Add(const void* addr);
-
-  // Returns the symbol name for addr, if the given address was added before
-  // the last successful call to Symbolize(). Otherwise may return an empty
-  // c-string.
-  const char* GetSymbol(const void* addr);
-
-  // Obtains the symbol names for the addresses stored in the table and returns
-  // the number of addresses actually symbolized.
-  int Symbolize();
-
- private:
-  typedef map<const void*, const char*> SymbolMap;
-
-  // An average size of memory allocated for a stack trace symbol.
-  static const int kSymbolSize = 1024;
-
-  // Map from addresses to symbol names.
-  SymbolMap symbolization_table_;
-
-  // Pointer to the buffer that stores the symbol names.
-  char *symbol_buffer_;
-};
-
-#endif  // TCMALLOC_SYMBOLIZE_H_
diff --git a/third_party/tcmalloc/chromium/src/system-alloc.cc b/third_party/tcmalloc/chromium/src/system-alloc.cc
deleted file mode 100644
index 0dc8ab7..0000000
--- a/third_party/tcmalloc/chromium/src/system-alloc.cc
+++ /dev/null
@@ -1,727 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-
-#include <config.h>
-#include <errno.h>                      // for EAGAIN, errno
-#include <fcntl.h>                      // for open, O_RDWR
-#include <stddef.h>                     // for size_t, NULL, ptrdiff_t
-#if defined HAVE_STDINT_H
-#include <stdint.h>                     // for uintptr_t, intptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>                   // for munmap, mmap, MADV_DONTNEED, etc
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                     // for sbrk, getpagesize, off_t
-#endif
-#include <gperftools/malloc_extension.h>
-#include <new>  // for operator new
-#include "base/basictypes.h"
-#include "base/commandlineflags.h"
-#include "base/spinlock.h"  // for SpinLockHolder, SpinLock, etc
-#include "build/build_config.h"
-#include "common.h"
-#include "internal_logging.h"
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-// Linux added support for MADV_FREE in 4.5 but we aren't ready to use it
-// yet. Among other things, using compile-time detection leads to poor
-// results when compiling on a system with MADV_FREE and running on a
-// system without it. See https://github.com/gperftools/gperftools/issues/780.
-#if defined(__linux__) && defined(MADV_FREE) && !defined(TCMALLOC_USE_MADV_FREE)
-# undef MADV_FREE
-#endif
-
-// MADV_FREE is specifically designed for use by malloc(), but only
-// FreeBSD supports it; in linux we fall back to the somewhat inferior
-// MADV_DONTNEED.
-#if !defined(MADV_FREE) && defined(MADV_DONTNEED)
-# define MADV_FREE  MADV_DONTNEED
-#endif
-
-// Solaris has a bug where it doesn't declare madvise() for C++.
-//    http://www.opensolaris.org/jive/thread.jspa?threadID=21035&tstart=0
-#if defined(__sun) && defined(__SVR4)
-# include <sys/types.h>    // for caddr_t
-  extern "C" { extern int madvise(caddr_t, size_t, int); }
-#endif
-
-// Set kDebugMode mode so that we can have use C++ conditionals
-// instead of preprocessor conditionals.
-#ifdef NDEBUG
-static const bool kDebugMode = false;
-#else
-static const bool kDebugMode = true;
-#endif
-
-// TODO(sanjay): Move the code below into the tcmalloc namespace
-using tcmalloc::kCrash;
-using tcmalloc::kLog;
-using tcmalloc::Log;
-
-// Check that no bit is set at position ADDRESS_BITS or higher.
-static bool CheckAddressBits(uintptr_t ptr) {
-  bool always_ok = (kAddressBits == 8 * sizeof(void*));
-  // this is a bit insane but otherwise we get compiler warning about
-  // shifting right by word size even if this code is dead :(
-  int shift_bits = always_ok ? 0 : kAddressBits;
-  return always_ok || ((ptr >> shift_bits) == 0);
-}
-
-namespace {
-
-#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__x86_64__)
-#define ASLR_IS_SUPPORTED
-#endif
-
-#if defined(ASLR_IS_SUPPORTED)
-// From libdieharder, public domain library by Bob Jenkins (rngav.c).
-// Described at http://burtleburtle.net/bob/rand/smallprng.html.
-// Not cryptographically secure, but good enough for what we need.
-typedef uint32_t u4;
-struct ranctx {
-  u4 a;
-  u4 b;
-  u4 c;
-  u4 d;
-};
-
-#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
-
-u4 ranval(ranctx* x) {
-  /* xxx: the generator being tested */
-  u4 e = x->a - rot(x->b, 27);
-  x->a = x->b ^ rot(x->c, 17);
-  x->b = x->c + x->d;
-  x->c = x->d + e;
-  x->d = e + x->a;
-  return x->d;
-}
-
-void raninit(ranctx* x, u4 seed) {
-  u4 i;
-  x->a = 0xf1ea5eed;
-  x->b = x->c = x->d = seed;
-  for (i = 0; i < 20; ++i) {
-    (void)ranval(x);
-  }
-}
-
-// If the kernel cannot honor the hint in arch_get_unmapped_area_topdown, it
-// will simply ignore it. So we give a hint that has a good chance of
-// working.
-// The mmap top-down allocator will normally allocate below TASK_SIZE - gap,
-// with a gap that depends on the max stack size. See x86/mm/mmap.c. We
-// should make allocations that are below this area, which would be
-// 0x7ffbf8000000.
-// We use 0x3ffffffff000 as the mask so that we only "pollute" half of the
-// address space. In the unlikely case where fragmentation would become an
-// issue, the kernel will still have another half to use.
-const uint64_t kRandomAddressMask = 0x3ffffffff000ULL;
-
-#endif  // defined(ASLR_IS_SUPPORTED)
-
-// Give a random "hint" that is suitable for use with mmap(). This cannot make
-// mmap fail, as the kernel will simply not follow the hint if it can't.
-// However, this will create address space fragmentation.  Currently, we only
-// implement it on x86_64, where we have a 47 bits userland address space and
-// fragmentation is not an issue.
-void* GetRandomAddrHint() {
-#if !defined(ASLR_IS_SUPPORTED)
-  return NULL;
-#else
-  // Note: we are protected by the general TCMalloc_SystemAlloc spinlock. Given
-  // the nature of what we're doing, it wouldn't be critical if we weren't for
-  // ctx, but it is for the "initialized" variable.
-  // It's nice to share the state between threads, because scheduling will add
-  // some randomness to the succession of ranval() calls.
-  static ranctx ctx;
-  static bool initialized = false;
-  if (!initialized) {
-    initialized = true;
-    // We really want this to be a stack variable and don't want any compiler
-    // optimization. We're using its address as a poor-man source of
-    // randomness.
-    volatile char c;
-    // Pre-initialize our seed with a "random" address in case /dev/urandom is
-    // not available.
-    uint32_t seed =
-        (reinterpret_cast<uint64_t>(&c) >> 32) ^ reinterpret_cast<uint64_t>(&c);
-    int urandom_fd = open("/dev/urandom", O_RDONLY);
-    if (urandom_fd >= 0) {
-      const ssize_t length = read(urandom_fd, &seed, sizeof(seed));
-      ASSERT(length == sizeof(seed));
-      int ret = close(urandom_fd);
-      ASSERT(ret == 0);
-    }
-    raninit(&ctx, seed);
-  }
-  uint64_t random_address =
-      (static_cast<uint64_t>(ranval(&ctx)) << 32) | ranval(&ctx);
-  // A bit-wise "and" won't bias our random distribution because of all the 0xfs
-  // in the high-order bits.
-  random_address &= kRandomAddressMask;
-  return reinterpret_cast<void*>(random_address);
-#endif  // ASLR_IS_SUPPORTED
-}
-
-// Allocate |length| bytes of memory using mmap(). The memory will be
-// readable and writeable, but not executable.
-// Like mmap(), we will return MAP_FAILED on failure.
-// |is_aslr_enabled| controls address space layout randomization. When true, we
-// will put the first mapping at a random address and will then try to grow it.
-// If it's not possible to grow an existing mapping, a new one will be created.
-void* AllocWithMmap(size_t length, bool is_aslr_enabled) {
-  // Note: we are protected by the general TCMalloc_SystemAlloc spinlock.
-  static void* address_hint = NULL;
-#if defined(ASLR_IS_SUPPORTED)
-  if (is_aslr_enabled &&
-      (!address_hint ||
-       reinterpret_cast<uint64_t>(address_hint) & ~kRandomAddressMask)) {
-    address_hint = GetRandomAddrHint();
-  }
-#endif  // ASLR_IS_SUPPORTED
-
-  // address_hint is likely to make us grow an existing mapping.
-  void* result = mmap(address_hint, length, PROT_READ | PROT_WRITE,
-                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-#if defined(ASLR_IS_SUPPORTED)
-  if (result == address_hint) {
-    // If mmap() succeeded at a address_hint, our next mmap() will try to grow
-    // the current mapping as long as it's compatible with our ASLR mask.
-    // This has been done for performance reasons, see https://crbug.com/173371.
-    // It should be possible to strike a better balance between performance
-    // and security but will be done at a later date.
-    // If this overflows, it could only set address_hint to NULL, which is
-    // what we want (and can't happen on the currently supported architecture).
-    address_hint = static_cast<char*>(result) + length;
-  } else {
-    // mmap failed or a collision prevented the kernel from honoring the hint,
-    // reset the hint.
-    address_hint = NULL;
-  }
-#endif  // ASLR_IS_SUPPORTED
-  return result;
-}
-
-}  // Anonymous namespace.
-
-COMPILE_ASSERT(kAddressBits <= 8 * sizeof(void*),
-               address_bits_larger_than_pointer_size);
-
-#if defined(HAVE_MMAP) || defined(MADV_FREE)
-#ifdef HAVE_GETPAGESIZE
-static size_t pagesize = 0;
-#endif
-#endif
-
-// The current system allocator
-SysAllocator* tcmalloc_sys_alloc = NULL;
-
-// Number of bytes taken from system.
-size_t TCMalloc_SystemTaken = 0;
-
-// Configuration parameters.
-DEFINE_int32(malloc_devmem_start,
-             EnvToInt("TCMALLOC_DEVMEM_START", 0),
-             "Physical memory starting location in MB for /dev/mem allocation."
-             "  Setting this to 0 disables /dev/mem allocation");
-DEFINE_int32(malloc_devmem_limit,
-             EnvToInt("TCMALLOC_DEVMEM_LIMIT", 0),
-             "Physical memory limit location in MB for /dev/mem allocation."
-             "  Setting this to 0 means no limit.");
-DEFINE_bool(malloc_skip_sbrk,
-            EnvToBool("TCMALLOC_SKIP_SBRK", false),
-            "Whether sbrk can be used to obtain memory.");
-DEFINE_bool(malloc_skip_mmap,
-            EnvToBool("TCMALLOC_SKIP_MMAP", false),
-            "Whether mmap can be used to obtain memory.");
-DEFINE_bool(malloc_disable_memory_release,
-            EnvToBool("TCMALLOC_DISABLE_MEMORY_RELEASE", false),
-            "Whether MADV_FREE/MADV_DONTNEED should be used"
-            " to return unused memory to the system.");
-
-DEFINE_bool(malloc_random_allocator,
-#if defined(ASLR_IS_SUPPORTED)
-            EnvToBool("TCMALLOC_ASLR", true),
-#else
-            EnvToBool("TCMALLOC_ASLR", false),
-#endif
-            "Whether to randomize the address space via mmap().");
-
-// static allocators
-class SbrkSysAllocator : public SysAllocator {
-public:
-  SbrkSysAllocator() : SysAllocator() {
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-};
-static union {
-  char buf[sizeof(SbrkSysAllocator)];
-  void *ptr;
-} sbrk_space;
-
-class MmapSysAllocator : public SysAllocator {
-public:
-  MmapSysAllocator() : SysAllocator() {
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-};
-static union {
-  char buf[sizeof(MmapSysAllocator)];
-  void *ptr;
-} mmap_space;
-
-class DevMemSysAllocator : public SysAllocator {
-public:
-  DevMemSysAllocator() : SysAllocator() {
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-};
-
-class DefaultSysAllocator : public SysAllocator {
- public:
-  DefaultSysAllocator() : SysAllocator() {
-    for (int i = 0; i < kMaxAllocators; i++) {
-      failed_[i] = true;
-      allocs_[i] = NULL;
-      names_[i] = NULL;
-    }
-  }
-  void SetChildAllocator(SysAllocator* alloc, unsigned int index,
-                         const char* name) {
-    if (index < kMaxAllocators && alloc != NULL) {
-      allocs_[index] = alloc;
-      failed_[index] = false;
-      names_[index] = name;
-    }
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-
- private:
-  static const int kMaxAllocators = 2;
-  bool failed_[kMaxAllocators];
-  SysAllocator* allocs_[kMaxAllocators];
-  const char* names_[kMaxAllocators];
-};
-static union {
-  char buf[sizeof(DefaultSysAllocator)];
-  void *ptr;
-} default_space;
-static const char sbrk_name[] = "SbrkSysAllocator";
-static const char mmap_name[] = "MmapSysAllocator";
-
-
-void* SbrkSysAllocator::Alloc(size_t size, size_t *actual_size,
-                              size_t alignment) {
-#if !defined(HAVE_SBRK) || defined(__UCLIBC__)
-  return NULL;
-#else
-  // Check if we should use sbrk allocation.
-  // FLAGS_malloc_skip_sbrk starts out as false (its uninitialized
-  // state) and eventually gets initialized to the specified value.  Note
-  // that this code runs for a while before the flags are initialized.
-  // That means that even if this flag is set to true, some (initial)
-  // memory will be allocated with sbrk before the flag takes effect.
-  if (FLAGS_malloc_skip_sbrk) {
-    return NULL;
-  }
-
-  // sbrk will release memory if passed a negative number, so we do
-  // a strict check here
-  if (static_cast<ptrdiff_t>(size + alignment) < 0) return NULL;
-
-  // This doesn't overflow because TCMalloc_SystemAlloc has already
-  // tested for overflow at the alignment boundary.
-  size = ((size + alignment - 1) / alignment) * alignment;
-
-  // "actual_size" indicates that the bytes from the returned pointer
-  // p up to and including (p + actual_size - 1) have been allocated.
-  if (actual_size) {
-    *actual_size = size;
-  }
-
-  // Check that we we're not asking for so much more memory that we'd
-  // wrap around the end of the virtual address space.  (This seems
-  // like something sbrk() should check for us, and indeed opensolaris
-  // does, but glibc does not:
-  //    http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/sys/sbrk.c?a=true
-  //    http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/libc/misc/sbrk.c?rev=1.1.2.1&content-type=text/plain&cvsroot=glibc
-  // Without this check, sbrk may succeed when it ought to fail.)
-  if (reinterpret_cast<intptr_t>(sbrk(0)) + size < size) {
-    return NULL;
-  }
-
-  void* result = sbrk(size);
-  if (result == reinterpret_cast<void*>(-1)) {
-    return NULL;
-  }
-
-  // Is it aligned?
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-  if ((ptr & (alignment-1)) == 0)  return result;
-
-  // Try to get more memory for alignment
-  size_t extra = alignment - (ptr & (alignment-1));
-  void* r2 = sbrk(extra);
-  if (reinterpret_cast<uintptr_t>(r2) == (ptr + size)) {
-    // Contiguous with previous result
-    return reinterpret_cast<void*>(ptr + extra);
-  }
-
-  // Give up and ask for "size + alignment - 1" bytes so
-  // that we can find an aligned region within it.
-  result = sbrk(size + alignment - 1);
-  if (result == reinterpret_cast<void*>(-1)) {
-    return NULL;
-  }
-  ptr = reinterpret_cast<uintptr_t>(result);
-  if ((ptr & (alignment-1)) != 0) {
-    ptr += alignment - (ptr & (alignment-1));
-  }
-  return reinterpret_cast<void*>(ptr);
-#endif  // HAVE_SBRK
-}
-
-void* MmapSysAllocator::Alloc(size_t size, size_t *actual_size,
-                              size_t alignment) {
-#ifndef HAVE_MMAP
-  return NULL;
-#else
-  // Check if we should use mmap allocation.
-  // FLAGS_malloc_skip_mmap starts out as false (its uninitialized
-  // state) and eventually gets initialized to the specified value.  Note
-  // that this code runs for a while before the flags are initialized.
-  // Chances are we never get here before the flags are initialized since
-  // sbrk is used until the heap is exhausted (before mmap is used).
-  if (FLAGS_malloc_skip_mmap) {
-    return NULL;
-  }
-
-  // Enforce page alignment
-  if (pagesize == 0) pagesize = getpagesize();
-  if (alignment < pagesize) alignment = pagesize;
-  size_t aligned_size = ((size + alignment - 1) / alignment) * alignment;
-  if (aligned_size < size) {
-    return NULL;
-  }
-  size = aligned_size;
-
-  // "actual_size" indicates that the bytes from the returned pointer
-  // p up to and including (p + actual_size - 1) have been allocated.
-  if (actual_size) {
-    *actual_size = size;
-  }
-
-  // Ask for extra memory if alignment > pagesize
-  size_t extra = 0;
-  if (alignment > pagesize) {
-    extra = alignment - pagesize;
-  }
-
-  // Note: size + extra does not overflow since:
-  //            size + alignment < (1<<NBITS).
-  // and        extra <= alignment
-  // therefore  size + extra < (1<<NBITS)
-  void* result = AllocWithMmap(size + extra, FLAGS_malloc_random_allocator);
-  if (result == reinterpret_cast<void*>(MAP_FAILED)) {
-    return NULL;
-  }
-
-  // Adjust the return memory so it is aligned
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-  size_t adjust = 0;
-  if ((ptr & (alignment - 1)) != 0) {
-    adjust = alignment - (ptr & (alignment - 1));
-  }
-
-  // Return the unused memory to the system
-  if (adjust > 0) {
-    munmap(reinterpret_cast<void*>(ptr), adjust);
-  }
-  if (adjust < extra) {
-    munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust);
-  }
-
-  ptr += adjust;
-  return reinterpret_cast<void*>(ptr);
-#endif  // HAVE_MMAP
-}
-
-void* DevMemSysAllocator::Alloc(size_t size, size_t *actual_size,
-                                size_t alignment) {
-#ifndef HAVE_MMAP
-  return NULL;
-#else
-  static bool initialized = false;
-  static off_t physmem_base;  // next physical memory address to allocate
-  static off_t physmem_limit; // maximum physical address allowed
-  static int physmem_fd;      // file descriptor for /dev/mem
-
-  // Check if we should use /dev/mem allocation.  Note that it may take
-  // a while to get this flag initialized, so meanwhile we fall back to
-  // the next allocator.  (It looks like 7MB gets allocated before
-  // this flag gets initialized -khr.)
-  if (FLAGS_malloc_devmem_start == 0) {
-    // NOTE: not a devmem_failure - we'd like TCMalloc_SystemAlloc to
-    // try us again next time.
-    return NULL;
-  }
-
-  if (!initialized) {
-    physmem_fd = open("/dev/mem", O_RDWR);
-    if (physmem_fd < 0) {
-      return NULL;
-    }
-    physmem_base = FLAGS_malloc_devmem_start*1024LL*1024LL;
-    physmem_limit = FLAGS_malloc_devmem_limit*1024LL*1024LL;
-    initialized = true;
-  }
-
-  // Enforce page alignment
-  if (pagesize == 0) pagesize = getpagesize();
-  if (alignment < pagesize) alignment = pagesize;
-  size_t aligned_size = ((size + alignment - 1) / alignment) * alignment;
-  if (aligned_size < size) {
-    return NULL;
-  }
-  size = aligned_size;
-
-  // "actual_size" indicates that the bytes from the returned pointer
-  // p up to and including (p + actual_size - 1) have been allocated.
-  if (actual_size) {
-    *actual_size = size;
-  }
-
-  // Ask for extra memory if alignment > pagesize
-  size_t extra = 0;
-  if (alignment > pagesize) {
-    extra = alignment - pagesize;
-  }
-
-  // check to see if we have any memory left
-  if (physmem_limit != 0 &&
-      ((size + extra) > (physmem_limit - physmem_base))) {
-    return NULL;
-  }
-
-  // Note: size + extra does not overflow since:
-  //            size + alignment < (1<<NBITS).
-  // and        extra <= alignment
-  // therefore  size + extra < (1<<NBITS)
-  void *result = mmap(0, size + extra, PROT_WRITE|PROT_READ,
-                      MAP_SHARED, physmem_fd, physmem_base);
-  if (result == reinterpret_cast<void*>(MAP_FAILED)) {
-    return NULL;
-  }
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-
-  // Adjust the return memory so it is aligned
-  size_t adjust = 0;
-  if ((ptr & (alignment - 1)) != 0) {
-    adjust = alignment - (ptr & (alignment - 1));
-  }
-
-  // Return the unused virtual memory to the system
-  if (adjust > 0) {
-    munmap(reinterpret_cast<void*>(ptr), adjust);
-  }
-  if (adjust < extra) {
-    munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust);
-  }
-
-  ptr += adjust;
-  physmem_base += adjust + size;
-
-  return reinterpret_cast<void*>(ptr);
-#endif  // HAVE_MMAP
-}
-
-void* DefaultSysAllocator::Alloc(size_t size, size_t *actual_size,
-                                 size_t alignment) {
-  for (int i = 0; i < kMaxAllocators; i++) {
-    if (!failed_[i] && allocs_[i] != NULL) {
-      void* result = allocs_[i]->Alloc(size, actual_size, alignment);
-      if (result != NULL) {
-        return result;
-      }
-      failed_[i] = true;
-    }
-  }
-  // After both failed, reset "failed_" to false so that a single failed
-  // allocation won't make the allocator never work again.
-  for (int i = 0; i < kMaxAllocators; i++) {
-    failed_[i] = false;
-  }
-  return NULL;
-}
-
-ATTRIBUTE_WEAK ATTRIBUTE_NOINLINE
-SysAllocator *tc_get_sysalloc_override(SysAllocator *def)
-{
-  return def;
-}
-
-static bool system_alloc_inited = false;
-void InitSystemAllocators(void) {
-  MmapSysAllocator *mmap = new (mmap_space.buf) MmapSysAllocator();
-  SbrkSysAllocator *sbrk = new (sbrk_space.buf) SbrkSysAllocator();
-
-  // In 64-bit debug mode, place the mmap allocator first since it
-  // allocates pointers that do not fit in 32 bits and therefore gives
-  // us better testing of code's 64-bit correctness.  It also leads to
-  // less false negatives in heap-checking code.  (Numbers are less
-  // likely to look like pointers and therefore the conservative gc in
-  // the heap-checker is less likely to misinterpret a number as a
-  // pointer).
-  DefaultSysAllocator *sdef = new (default_space.buf) DefaultSysAllocator();
-// Unfortunately, this code runs before flags are initialized. So
-// we can't use FLAGS_malloc_random_allocator.
-#if defined(ASLR_IS_SUPPORTED)
-  // Our only random allocator is mmap.
-  sdef->SetChildAllocator(mmap, 0, mmap_name);
-#else
-  if (kDebugMode && sizeof(void*) > 4) {
-    sdef->SetChildAllocator(mmap, 0, mmap_name);
-    sdef->SetChildAllocator(sbrk, 1, sbrk_name);
-  } else {
-    sdef->SetChildAllocator(sbrk, 0, sbrk_name);
-    sdef->SetChildAllocator(mmap, 1, mmap_name);
-  }
-#endif  // ASLR_IS_SUPPORTED
-  tcmalloc_sys_alloc = tc_get_sysalloc_override(sdef);
-}
-
-void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
-                           size_t alignment) {
-  // Discard requests that overflow
-  if (size + alignment < size) return NULL;
-
-  static SpinLock spinlock(SpinLock::LINKER_INITIALIZED);
-  SpinLockHolder lock_holder(&spinlock);
-
-  if (!system_alloc_inited) {
-    InitSystemAllocators();
-    system_alloc_inited = true;
-  }
-
-  // Enforce minimum alignment
-  if (alignment < sizeof(MemoryAligner)) alignment = sizeof(MemoryAligner);
-
-  size_t actual_size_storage;
-  if (actual_size == NULL) {
-    actual_size = &actual_size_storage;
-  }
-
-  void* result = tcmalloc_sys_alloc->Alloc(size, actual_size, alignment);
-  if (result != NULL) {
-    CHECK_CONDITION(
-      CheckAddressBits(reinterpret_cast<uintptr_t>(result) + *actual_size - 1));
-    TCMalloc_SystemTaken += *actual_size;
-  }
-  return result;
-}
-
-void TCMalloc_SystemAddGuard(void* start, size_t size) {
-#ifdef HAVE_GETPAGESIZE
-  if (pagesize == 0)
-    pagesize = getpagesize();
-
-  if (size < pagesize || (reinterpret_cast<size_t>(start) % pagesize) != 0) {
-    Log(kCrash, __FILE__, __LINE__,
-        "FATAL ERROR: alloc size (%d) < pagesize (%d), or start address (%p) "
-        "is not page aligned\n",
-        size, pagesize, start);
-    return;
-  }
-
-  if (mprotect(start, pagesize, PROT_NONE)) {
-    Log(kCrash, __FILE__, __LINE__,
-        "FATAL ERROR: mprotect(%p, %d, PROT_NONE) failed: %s\n", start,
-        pagesize, strerror(errno));
-  }
-#endif
-}
-
-bool TCMalloc_SystemRelease(void* start, size_t length) {
-#ifdef MADV_FREE
-  if (FLAGS_malloc_devmem_start) {
-    // It's not safe to use MADV_FREE/MADV_DONTNEED if we've been
-    // mapping /dev/mem for heap memory.
-    return false;
-  }
-  if (FLAGS_malloc_disable_memory_release) return false;
-  if (pagesize == 0) pagesize = getpagesize();
-  const size_t pagemask = pagesize - 1;
-
-  size_t new_start = reinterpret_cast<size_t>(start);
-  size_t end = new_start + length;
-  size_t new_end = end;
-
-  // Round up the starting address and round down the ending address
-  // to be page aligned:
-  new_start = (new_start + pagesize - 1) & ~pagemask;
-  new_end = new_end & ~pagemask;
-
-  ASSERT((new_start & pagemask) == 0);
-  ASSERT((new_end & pagemask) == 0);
-  ASSERT(new_start >= reinterpret_cast<size_t>(start));
-  ASSERT(new_end <= end);
-
-  if (new_end > new_start) {
-    int result;
-    do {
-      result = madvise(reinterpret_cast<char*>(new_start),
-          new_end - new_start, MADV_FREE);
-    } while (result == -1 && errno == EAGAIN);
-
-    return result != -1;
-  }
-#endif
-  return false;
-}
-
-void TCMalloc_SystemCommit(void* start, size_t length) {
-  // Nothing to do here.  TCMalloc_SystemRelease does not alter pages
-  // such that they need to be re-committed before they can be used by the
-  // application.
-}
diff --git a/third_party/tcmalloc/chromium/src/system-alloc.h b/third_party/tcmalloc/chromium/src/system-alloc.h
deleted file mode 100644
index 2471f21..0000000
--- a/third_party/tcmalloc/chromium/src/system-alloc.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Routine that uses sbrk/mmap to allocate memory from the system.
-// Useful for implementing malloc.
-
-#ifndef TCMALLOC_SYSTEM_ALLOC_H_
-#define TCMALLOC_SYSTEM_ALLOC_H_
-
-#include <config.h>
-#include <stddef.h>                     // for size_t
-
-class SysAllocator;
-
-// REQUIRES: "alignment" is a power of two or "0" to indicate default alignment
-//
-// Allocate and return "N" bytes of zeroed memory.
-//
-// If actual_bytes is NULL then the returned memory is exactly the
-// requested size.  If actual bytes is non-NULL then the allocator
-// may optionally return more bytes than asked for (i.e. return an
-// entire "huge" page if a huge page allocator is in use).
-//
-// The returned pointer is a multiple of "alignment" if non-zero. The
-// returned pointer will always be aligned suitably for holding a
-// void*, double, or size_t. In addition, if this platform defines
-// CACHELINE_ALIGNED, the return pointer will always be cacheline
-// aligned.
-//
-// Returns NULL when out of memory.
-extern PERFTOOLS_DLL_DECL
-void* TCMalloc_SystemAlloc(size_t bytes, size_t *actual_bytes,
-			   size_t alignment = 0);
-
-// This call is a hint to the operating system that the pages
-// contained in the specified range of memory will not be used for a
-// while, and can be released for use by other processes or the OS.
-// Pages which are released in this way may be destroyed (zeroed) by
-// the OS.  The benefit of this function is that it frees memory for
-// use by the system, the cost is that the pages are faulted back into
-// the address space next time they are touched, which can impact
-// performance.  (Only pages fully covered by the memory region will
-// be released, partial pages will not.)
-//
-// Returns false if release failed or not supported.
-extern PERFTOOLS_DLL_DECL
-bool TCMalloc_SystemRelease(void* start, size_t length);
-
-// Called to ressurect memory which has been previously released
-// to the system via TCMalloc_SystemRelease.  An attempt to
-// commit a page that is already committed does not cause this
-// function to fail.
-extern PERFTOOLS_DLL_DECL
-void TCMalloc_SystemCommit(void* start, size_t length);
-
-// Guards the first page in the supplied range of memory. It crashes the
-// program if the guard page cannot be added.
-extern void TCMalloc_SystemAddGuard(void* start, size_t size);
-
-// The current system allocator.
-extern PERFTOOLS_DLL_DECL SysAllocator* tcmalloc_sys_alloc;
-
-// Number of bytes taken from system.
-extern PERFTOOLS_DLL_DECL size_t TCMalloc_SystemTaken;
-
-#endif /* TCMALLOC_SYSTEM_ALLOC_H_ */
diff --git a/third_party/tcmalloc/chromium/src/tcmalloc.cc b/third_party/tcmalloc/chromium/src/tcmalloc.cc
deleted file mode 100644
index 559082a..0000000
--- a/third_party/tcmalloc/chromium/src/tcmalloc.cc
+++ /dev/null
@@ -1,2265 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// A malloc that uses a per-thread cache to satisfy small malloc requests.
-// (The time for malloc/free of a small object drops from 300 ns to 50 ns.)
-//
-// See docs/tcmalloc.html for a high-level
-// description of how this malloc works.
-//
-// SYNCHRONIZATION
-//  1. The thread-specific lists are accessed without acquiring any locks.
-//     This is safe because each such list is only accessed by one thread.
-//  2. We have a lock per central free-list, and hold it while manipulating
-//     the central free list for a particular size.
-//  3. The central page allocator is protected by "pageheap_lock".
-//  4. The pagemap (which maps from page-number to descriptor),
-//     can be read without holding any locks, and written while holding
-//     the "pageheap_lock".
-//  5. To improve performance, a subset of the information one can get
-//     from the pagemap is cached in a data structure, pagemap_cache_,
-//     that atomically reads and writes its entries.  This cache can be
-//     read and written without locking.
-//
-//     This multi-threaded access to the pagemap is safe for fairly
-//     subtle reasons.  We basically assume that when an object X is
-//     allocated by thread A and deallocated by thread B, there must
-//     have been appropriate synchronization in the handoff of object
-//     X from thread A to thread B.  The same logic applies to pagemap_cache_.
-//
-// THE PAGEID-TO-SIZECLASS CACHE
-// Hot PageID-to-sizeclass mappings are held by pagemap_cache_.  If this cache
-// returns 0 for a particular PageID then that means "no information," not that
-// the sizeclass is 0.  The cache may have stale information for pages that do
-// not hold the beginning of any free()'able object.  Staleness is eliminated
-// in Populate() for pages with sizeclass > 0 objects, and in do_malloc() and
-// do_memalign() for all other relevant pages.
-//
-// PAGEMAP
-// -------
-// Page map contains a mapping from page id to Span.
-//
-// If Span s occupies pages [p..q],
-//      pagemap[p] == s
-//      pagemap[q] == s
-//      pagemap[p+1..q-1] are undefined
-//      pagemap[p-1] and pagemap[q+1] are defined:
-//         NULL if the corresponding page is not yet in the address space.
-//         Otherwise it points to a Span.  This span may be free
-//         or allocated.  If free, it is in one of pageheap's freelist.
-//
-// TODO: Bias reclamation to larger addresses
-// TODO: implement mallinfo/mallopt
-// TODO: Better testing
-//
-// 9/28/2003 (new page-level allocator replaces ptmalloc2):
-// * malloc/free of small objects goes from ~300 ns to ~50 ns.
-// * allocation of a reasonably complicated struct
-//   goes from about 1100 ns to about 300 ns.
-
-#include "config.h"
-// At least for gcc on Linux/i386 and Linux/amd64 not adding throw()
-// to tc_xxx functions actually ends up generating better code.
-#define PERFTOOLS_NOTHROW
-#include <gperftools/tcmalloc.h>
-
-#include <errno.h>                      // for ENOMEM, EINVAL, errno
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-#include <stddef.h>                     // for size_t, NULL
-#include <stdlib.h>                     // for getenv
-#include <string.h>                     // for strcmp, memset, strlen, etc
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                     // for getpagesize, write, etc
-#endif
-#include <algorithm>                    // for max, min
-#include <limits>                       // for numeric_limits
-#include <new>                          // for nothrow_t (ptr only), etc
-#include <vector>                       // for vector
-
-#include <gperftools/malloc_extension.h>
-#include <gperftools/malloc_hook.h>         // for MallocHook
-#include <gperftools/nallocx.h>
-#include "base/basictypes.h"            // for int64
-#include "base/commandlineflags.h"      // for RegisterFlagValidator, etc
-#include "base/dynamic_annotations.h"   // for RunningOnValgrind
-#include "base/spinlock.h"              // for SpinLockHolder
-#include "central_freelist.h"  // for CentralFreeListPadded
-#include "common.h"            // for StackTrace, kPageShift, etc
-#include "free_list.h"         // for FL_Init
-#include "internal_logging.h"  // for ASSERT, TCMalloc_Printer, etc
-#include "malloc_hook-inl.h"       // for MallocHook::InvokeNewHook, etc
-#include "page_heap.h"         // for PageHeap, PageHeap::Stats
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "sampler.h"              // for Sampler
-#include "span.h"              // for Span, DLL_Prepend, etc
-#include "stack_trace_table.h"  // for StackTraceTable
-#include "static_vars.h"       // for Static
-#include "system-alloc.h"      // for DumpSystemAllocatorStats, etc
-#include "tcmalloc_guard.h"    // for TCMallocGuard
-#include "thread_cache.h"      // for ThreadCache
-
-#include "maybe_emergency_malloc.h"
-
-#if (defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)) && !defined(WIN32_OVERRIDE_ALLOCATORS)
-# define WIN32_DO_PATCHING 1
-#endif
-
-// Some windows file somewhere (at least on cygwin) #define's small (!)
-#undef small
-
-using STL_NAMESPACE::max;
-using STL_NAMESPACE::min;
-using STL_NAMESPACE::numeric_limits;
-using STL_NAMESPACE::vector;
-
-#include "libc_override.h"
-
-using tcmalloc::AlignmentForSize;
-using tcmalloc::kCrash;
-using tcmalloc::kCrashWithStats;
-using tcmalloc::kLog;
-using tcmalloc::Log;
-using tcmalloc::PageHeap;
-using tcmalloc::PageHeapAllocator;
-using tcmalloc::Sampler;
-using tcmalloc::SizeMap;
-using tcmalloc::Span;
-using tcmalloc::StackTrace;
-using tcmalloc::Static;
-using tcmalloc::ThreadCache;
-
-DECLARE_double(tcmalloc_release_rate);
-
-// Those common architectures are known to be safe w.r.t. aliasing function
-// with "extra" unused args to function with fewer arguments (e.g.
-// tc_delete_nothrow being aliased to tc_delete).
-//
-// Benefit of aliasing is relatively moderate. It reduces instruction
-// cache pressure a bit (not relevant for largely unused
-// tc_delete_nothrow, but is potentially relevant for
-// tc_delete_aligned (or sized)). It also used to be the case that gcc
-// 5+ optimization for merging identical functions kicked in and
-// "screwed" one of the otherwise identical functions with extra
-// jump. I am not able to reproduce that anymore.
-#if !defined(__i386__) && !defined(__x86_64__) && \
-    !defined(__ppc__) && !defined(__PPC__) && \
-    !defined(__aarch64__) && !defined(__mips__) && !defined(__arm__)
-#undef TCMALLOC_NO_ALIASES
-#define TCMALLOC_NO_ALIASES
-#endif
-
-#if defined(__GNUC__) && defined(__ELF__) && !defined(TCMALLOC_NO_ALIASES)
-#define TC_ALIAS(name) __attribute__((alias(#name)))
-#endif
-
-// For windows, the printf we use to report large allocs is
-// potentially dangerous: it could cause a malloc that would cause an
-// infinite loop.  So by default we set the threshold to a huge number
-// on windows, so this bad situation will never trigger.  You can
-// always set TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD manually if you
-// want this functionality.
-#ifdef _WIN32
-const int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 62;
-#else
-const int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 30;
-#endif
-DEFINE_int64(tcmalloc_large_alloc_report_threshold,
-             EnvToInt64("TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD",
-                        kDefaultLargeAllocReportThreshold),
-             "Allocations larger than this value cause a stack "
-             "trace to be dumped to stderr.  The threshold for "
-             "dumping stack traces is increased by a factor of 1.125 "
-             "every time we print a message so that the threshold "
-             "automatically goes up by a factor of ~1000 every 60 "
-             "messages.  This bounds the amount of extra logging "
-             "generated by this flag.  Default value of this flag "
-             "is very large and therefore you should see no extra "
-             "logging unless the flag is overridden.  Set to 0 to "
-             "disable reporting entirely.");
-
-
-// We already declared these functions in tcmalloc.h, but we have to
-// declare them again to give them an ATTRIBUTE_SECTION: we want to
-// put all callers of MallocHook::Invoke* in this module into
-// ATTRIBUTE_SECTION(google_malloc) section, so that
-// MallocHook::GetCallerStackTrace can function accurately.
-#ifndef _WIN32   // windows doesn't have attribute_section, so don't bother
-extern "C" {
-  void* tc_malloc(size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_free(void* ptr) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_free_sized(void* ptr, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_cfree(void* ptr) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-  void* tc_memalign(size_t __alignment, size_t __size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  int tc_posix_memalign(void** ptr, size_t align, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-  void tc_malloc_stats(void) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-#ifdef HAVE_STRUCT_MALLINFO
-  struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-#endif
-
-  void* tc_new(size_t size)
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete(void* p) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_newarray(size_t size)
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray(void* p) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-  // And the nothrow variants of these:
-  void* tc_new_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_newarray_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  // Surprisingly, standard C++ library implementations use a
-  // nothrow-delete internally.  See, eg:
-  // http://www.dinkumware.com/manuals/?manual=compleat&page=new.html
-  void tc_delete_nothrow(void* ptr, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_nothrow(void* ptr, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-  void* tc_new_aligned(size_t size, std::align_val_t al)
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_newarray_aligned(size_t size, std::align_val_t al)
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-  // And the nothrow variants of these:
-  void* tc_new_aligned_nothrow(size_t size, std::align_val_t al, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete_aligned_nothrow(void* ptr, std::align_val_t al, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_aligned_nothrow(void* ptr, std::align_val_t al, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-  // Some non-standard extensions that we support.
-
-  // This is equivalent to
-  //    OS X: malloc_size()
-  //    glibc: malloc_usable_size()
-  //    Windows: _msize()
-  size_t tc_malloc_size(void* p) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-  void* tc_malloc_skip_new_handler(size_t size)
-      ATTRIBUTE_SECTION(google_malloc);
-}  // extern "C"
-#endif  // #ifndef _WIN32
-
-// ----------------------- IMPLEMENTATION -------------------------------
-
-static int tc_new_mode = 0;  // See tc_set_new_mode().
-
-// Routines such as free() and realloc() catch some erroneous pointers
-// passed to them, and invoke the below when they do.  (An erroneous pointer
-// won't be caught if it's within a valid span or a stale span for which
-// the pagemap cache has a non-zero sizeclass.) This is a cheap (source-editing
-// required) kind of exception handling for these routines.
-namespace {
-ATTRIBUTE_NOINLINE void InvalidFree(void* ptr) {
-  if (tcmalloc::IsEmergencyPtr(ptr)) {
-    tcmalloc::EmergencyFree(ptr);
-    return;
-  }
-  Log(kCrash, __FILE__, __LINE__, "Attempt to free invalid pointer", ptr);
-}
-
-size_t InvalidGetSizeForRealloc(const void* old_ptr) {
-  Log(kCrash, __FILE__, __LINE__,
-      "Attempt to realloc invalid pointer", old_ptr);
-  return 0;
-}
-
-size_t InvalidGetAllocatedSize(const void* ptr) {
-  Log(kCrash, __FILE__, __LINE__,
-      "Attempt to get the size of an invalid pointer", ptr);
-  return 0;
-}
-
-#if defined(TCMALLOC_DISABLE_HUGE_ALLOCATIONS)
-// For security reasons, we want to limit the size of allocations.
-// See crbug.com/169327.
-inline bool IsAllocSizePermitted(size_t alloc_size) {
-  // Never allow an allocation larger than what can be indexed via an int.
-  // Remove kPageSize to account for various rounding, padding and to have a
-  // small margin.
-  return alloc_size <= ((std::numeric_limits<int>::max)() - kPageSize);
-}
-#endif
-
-}  // unnamed namespace
-
-// Extract interesting stats
-struct TCMallocStats {
-  uint64_t thread_bytes;      // Bytes in thread caches
-  uint64_t central_bytes;     // Bytes in central cache
-  uint64_t transfer_bytes;    // Bytes in central transfer cache
-  uint64_t metadata_bytes;    // Bytes alloced for metadata
-  PageHeap::Stats pageheap;   // Stats from page heap
-};
-
-// Get stats into "r".  Also, if class_count != NULL, class_count[k]
-// will be set to the total number of objects of size class k in the
-// central cache, transfer cache, and per-thread caches. If small_spans
-// is non-NULL, it is filled.  Same for large_spans.
-static void ExtractStats(TCMallocStats* r, uint64_t* class_count,
-                         PageHeap::SmallSpanStats* small_spans,
-                         PageHeap::LargeSpanStats* large_spans) {
-  r->central_bytes = 0;
-  r->transfer_bytes = 0;
-  for (int cl = 0; cl < Static::num_size_classes(); ++cl) {
-    const int length = Static::central_cache()[cl].length();
-    const int tc_length = Static::central_cache()[cl].tc_length();
-    const size_t cache_overhead = Static::central_cache()[cl].OverheadBytes();
-    const size_t size = static_cast<uint64_t>(
-        Static::sizemap()->ByteSizeForClass(cl));
-    r->central_bytes += (size * length) + cache_overhead;
-    r->transfer_bytes += (size * tc_length);
-    if (class_count) {
-      // Sum the lengths of all per-class freelists, except the per-thread
-      // freelists, which get counted when we call GetThreadStats(), below.
-      class_count[cl] = length + tc_length;
-    }
-
-  }
-
-  // Add stats from per-thread heaps
-  r->thread_bytes = 0;
-  { // scope
-    SpinLockHolder h(Static::pageheap_lock());
-    ThreadCache::GetThreadStats(&r->thread_bytes, class_count);
-    r->metadata_bytes = tcmalloc::metadata_system_bytes();
-    r->pageheap = Static::pageheap()->stats();
-    if (small_spans != NULL) {
-      Static::pageheap()->GetSmallSpanStats(small_spans);
-    }
-    if (large_spans != NULL) {
-      Static::pageheap()->GetLargeSpanStats(large_spans);
-    }
-  }
-}
-
-static double PagesToMiB(uint64_t pages) {
-  return (pages << kPageShift) / 1048576.0;
-}
-
-// WRITE stats to "out"
-static void DumpStats(TCMalloc_Printer* out, int level) {
-  TCMallocStats stats;
-  uint64_t class_count[kClassSizesMax];
-  PageHeap::SmallSpanStats small;
-  PageHeap::LargeSpanStats large;
-  if (level >= 2) {
-    ExtractStats(&stats, class_count, &small, &large);
-  } else {
-    ExtractStats(&stats, NULL, NULL, NULL);
-  }
-
-  static const double MiB = 1048576.0;
-
-  const uint64_t virtual_memory_used = (stats.pageheap.system_bytes
-                                        + stats.metadata_bytes);
-  const uint64_t physical_memory_used = (virtual_memory_used
-                                         - stats.pageheap.unmapped_bytes);
-  const uint64_t bytes_in_use_by_app = (physical_memory_used
-                                        - stats.metadata_bytes
-                                        - stats.pageheap.free_bytes
-                                        - stats.central_bytes
-                                        - stats.transfer_bytes
-                                        - stats.thread_bytes);
-
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-  out->printf(
-      "NOTE:  SMALL MEMORY MODEL IS IN USE, PERFORMANCE MAY SUFFER.\n");
-#endif
-  out->printf(
-      "------------------------------------------------\n"
-      "MALLOC:   %12" PRIu64 " (%7.1f MiB) Bytes in use by application\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in page heap freelist\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in central cache freelist\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in transfer cache freelist\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in thread cache freelists\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in malloc metadata\n"
-      "MALLOC:   ------------\n"
-      "MALLOC: = %12" PRIu64 " (%7.1f MiB) Actual memory used (physical + swap)\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes released to OS (aka unmapped)\n"
-      "MALLOC:   ------------\n"
-      "MALLOC: = %12" PRIu64 " (%7.1f MiB) Virtual address space used\n"
-      "MALLOC:\n"
-      "MALLOC:   %12" PRIu64 "              Spans in use\n"
-      "MALLOC:   %12" PRIu64 "              Thread heaps in use\n"
-      "MALLOC:   %12" PRIu64 "              Tcmalloc page size\n"
-      "------------------------------------------------\n"
-      "Call ReleaseFreeMemory() to release freelist memory to the OS"
-      " (via madvise()).\n"
-      "Bytes released to the OS take up virtual address space"
-      " but no physical memory.\n",
-      bytes_in_use_by_app, bytes_in_use_by_app / MiB,
-      stats.pageheap.free_bytes, stats.pageheap.free_bytes / MiB,
-      stats.central_bytes, stats.central_bytes / MiB,
-      stats.transfer_bytes, stats.transfer_bytes / MiB,
-      stats.thread_bytes, stats.thread_bytes / MiB,
-      stats.metadata_bytes, stats.metadata_bytes / MiB,
-      physical_memory_used, physical_memory_used / MiB,
-      stats.pageheap.unmapped_bytes, stats.pageheap.unmapped_bytes / MiB,
-      virtual_memory_used, virtual_memory_used / MiB,
-      uint64_t(Static::span_allocator()->inuse()),
-      uint64_t(ThreadCache::HeapsInUse()),
-      uint64_t(kPageSize));
-
-  if (level >= 2) {
-    out->printf("------------------------------------------------\n");
-    out->printf("Total size of freelists for per-thread caches,\n");
-    out->printf("transfer cache, and central cache, by size class\n");
-    out->printf("------------------------------------------------\n");
-    uint64_t cumulative = 0;
-    for (uint32 cl = 0; cl < Static::num_size_classes(); ++cl) {
-      if (class_count[cl] > 0) {
-        size_t cl_size = Static::sizemap()->ByteSizeForClass(cl);
-        uint64_t class_bytes = class_count[cl] * cl_size;
-        cumulative += class_bytes;
-        out->printf("class %3d [ %8" PRIuS " bytes ] : "
-                "%8" PRIu64 " objs; %5.1f MiB; %5.1f cum MiB\n",
-                cl, cl_size,
-                class_count[cl],
-                class_bytes / MiB,
-                cumulative / MiB);
-      }
-    }
-
-    // append page heap info
-    int nonempty_sizes = 0;
-    for (int s = 0; s < kMaxPages; s++) {
-      if (small.normal_length[s] + small.returned_length[s] > 0) {
-        nonempty_sizes++;
-      }
-    }
-    out->printf("------------------------------------------------\n");
-    out->printf("PageHeap: %d sizes; %6.1f MiB free; %6.1f MiB unmapped\n",
-                nonempty_sizes, stats.pageheap.free_bytes / MiB,
-                stats.pageheap.unmapped_bytes / MiB);
-    out->printf("------------------------------------------------\n");
-    uint64_t total_normal = 0;
-    uint64_t total_returned = 0;
-    for (int s = 1; s <= kMaxPages; s++) {
-      const int n_length = small.normal_length[s - 1];
-      const int r_length = small.returned_length[s - 1];
-      if (n_length + r_length > 0) {
-        uint64_t n_pages = s * n_length;
-        uint64_t r_pages = s * r_length;
-        total_normal += n_pages;
-        total_returned += r_pages;
-        out->printf("%6u pages * %6u spans ~ %6.1f MiB; %6.1f MiB cum"
-                    "; unmapped: %6.1f MiB; %6.1f MiB cum\n",
-                    s,
-                    (n_length + r_length),
-                    PagesToMiB(n_pages + r_pages),
-                    PagesToMiB(total_normal + total_returned),
-                    PagesToMiB(r_pages),
-                    PagesToMiB(total_returned));
-      }
-    }
-
-    total_normal += large.normal_pages;
-    total_returned += large.returned_pages;
-    out->printf(">%-5u large * %6u spans ~ %6.1f MiB; %6.1f MiB cum"
-                "; unmapped: %6.1f MiB; %6.1f MiB cum\n",
-                static_cast<unsigned int>(kMaxPages),
-                static_cast<unsigned int>(large.spans),
-                PagesToMiB(large.normal_pages + large.returned_pages),
-                PagesToMiB(total_normal + total_returned),
-                PagesToMiB(large.returned_pages),
-                PagesToMiB(total_returned));
-  }
-}
-
-static void PrintStats(int level) {
-  const int kBufferSize = 16 << 10;
-  char* buffer = new char[kBufferSize];
-  TCMalloc_Printer printer(buffer, kBufferSize);
-  DumpStats(&printer, level);
-  write(STDERR_FILENO, buffer, strlen(buffer));
-  delete[] buffer;
-}
-
-static void** DumpHeapGrowthStackTraces() {
-  // Count how much space we need
-  int needed_slots = 0;
-  {
-    SpinLockHolder h(Static::pageheap_lock());
-    for (StackTrace* t = Static::growth_stacks();
-         t != NULL;
-         t = reinterpret_cast<StackTrace*>(
-             t->stack[tcmalloc::kMaxStackDepth-1])) {
-      needed_slots += 3 + t->depth;
-    }
-    needed_slots += 100;            // Slop in case list grows
-    needed_slots += needed_slots/8; // An extra 12.5% slop
-  }
-
-  void** result = new void*[needed_slots];
-  if (result == NULL) {
-    Log(kLog, __FILE__, __LINE__,
-        "tcmalloc: allocation failed for stack trace slots",
-        needed_slots * sizeof(*result));
-    return NULL;
-  }
-
-  SpinLockHolder h(Static::pageheap_lock());
-  int used_slots = 0;
-  for (StackTrace* t = Static::growth_stacks();
-       t != NULL;
-       t = reinterpret_cast<StackTrace*>(
-           t->stack[tcmalloc::kMaxStackDepth-1])) {
-    ASSERT(used_slots < needed_slots);  // Need to leave room for terminator
-    if (used_slots + 3 + t->depth >= needed_slots) {
-      // No more room
-      break;
-    }
-
-    result[used_slots+0] = reinterpret_cast<void*>(static_cast<uintptr_t>(1));
-    result[used_slots+1] = reinterpret_cast<void*>(t->size);
-    result[used_slots+2] = reinterpret_cast<void*>(t->depth);
-    for (int d = 0; d < t->depth; d++) {
-      result[used_slots+3+d] = t->stack[d];
-    }
-    used_slots += 3 + t->depth;
-  }
-  result[used_slots] = reinterpret_cast<void*>(static_cast<uintptr_t>(0));
-  return result;
-}
-
-static void IterateOverRanges(void* arg, MallocExtension::RangeFunction func) {
-  PageID page = 1;  // Some code may assume that page==0 is never used
-  bool done = false;
-  while (!done) {
-    // Accumulate a small number of ranges in a local buffer
-    static const int kNumRanges = 16;
-    static base::MallocRange ranges[kNumRanges];
-    int n = 0;
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      while (n < kNumRanges) {
-        if (!Static::pageheap()->GetNextRange(page, &ranges[n])) {
-          done = true;
-          break;
-        } else {
-          uintptr_t limit = ranges[n].address + ranges[n].length;
-          page = (limit + kPageSize - 1) >> kPageShift;
-          n++;
-        }
-      }
-    }
-
-    for (int i = 0; i < n; i++) {
-      (*func)(arg, &ranges[i]);
-    }
-  }
-}
-
-// TCMalloc's support for extra malloc interfaces
-class TCMallocImplementation : public MallocExtension {
- private:
-  // ReleaseToSystem() might release more than the requested bytes because
-  // the page heap releases at the span granularity, and spans are of wildly
-  // different sizes.  This member keeps track of the extra bytes bytes
-  // released so that the app can periodically call ReleaseToSystem() to
-  // release memory at a constant rate.
-  // NOTE: Protected by Static::pageheap_lock().
-  size_t extra_bytes_released_;
-
- public:
-  TCMallocImplementation()
-      : extra_bytes_released_(0) {
-  }
-
-  virtual void GetStats(char* buffer, int buffer_length) {
-    ASSERT(buffer_length > 0);
-    TCMalloc_Printer printer(buffer, buffer_length);
-
-    // Print level one stats unless lots of space is available
-    if (buffer_length < 10000) {
-      DumpStats(&printer, 1);
-    } else {
-      DumpStats(&printer, 2);
-    }
-  }
-
-  // We may print an extra, tcmalloc-specific warning message here.
-  virtual void GetHeapSample(MallocExtensionWriter* writer) {
-    if (Sampler::GetSamplePeriod() == 0) {
-      const char* const kWarningMsg =
-          "%warn\n"
-          "%warn This heap profile does not have any data in it, because\n"
-          "%warn the application was run with heap sampling turned off.\n"
-          "%warn To get useful data from GetHeapSample(), you must\n"
-          "%warn set the environment variable TCMALLOC_SAMPLE_PARAMETER to\n"
-          "%warn a positive sampling period, such as 524288.\n"
-          "%warn\n";
-      writer->append(kWarningMsg, strlen(kWarningMsg));
-    }
-    MallocExtension::GetHeapSample(writer);
-  }
-
-  virtual void** ReadStackTraces(int* sample_period) {
-    tcmalloc::StackTraceTable table;
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      Span* sampled = Static::sampled_objects();
-      for (Span* s = sampled->next; s != sampled; s = s->next) {
-        table.AddTrace(*reinterpret_cast<StackTrace*>(s->objects));
-      }
-    }
-    *sample_period = ThreadCache::GetCache()->GetSamplePeriod();
-    return table.ReadStackTracesAndClear(); // grabs and releases pageheap_lock
-  }
-
-  virtual void** ReadHeapGrowthStackTraces() {
-    return DumpHeapGrowthStackTraces();
-  }
-
-  virtual size_t GetThreadCacheSize() {
-    ThreadCache* tc = ThreadCache::GetCacheIfPresent();
-    if (!tc)
-      return 0;
-    return tc->Size();
-  }
-
-  virtual void MarkThreadTemporarilyIdle() {
-    ThreadCache::BecomeTemporarilyIdle();
-  }
-
-  virtual void Ranges(void* arg, RangeFunction func) {
-    IterateOverRanges(arg, func);
-  }
-
-  virtual bool GetNumericProperty(const char* name, size_t* value) {
-    ASSERT(name != NULL);
-
-    if (strcmp(name, "generic.current_allocated_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.pageheap.system_bytes
-               - stats.thread_bytes
-               - stats.central_bytes
-               - stats.transfer_bytes
-               - stats.pageheap.free_bytes
-               - stats.pageheap.unmapped_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "generic.heap_size") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.pageheap.system_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "generic.total_physical_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.pageheap.system_bytes + stats.metadata_bytes -
-               stats.pageheap.unmapped_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.slack_bytes") == 0) {
-      // Kept for backwards compatibility.  Now defined externally as:
-      //    pageheap_free_bytes + pageheap_unmapped_bytes.
-      SpinLockHolder l(Static::pageheap_lock());
-      PageHeap::Stats stats = Static::pageheap()->stats();
-      *value = stats.free_bytes + stats.unmapped_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.central_cache_free_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.central_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.transfer_cache_free_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.transfer_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.thread_cache_free_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.thread_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_free_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().free_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_unmapped_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().unmapped_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_committed_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().committed_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_scavenge_count") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().scavenge_count;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_commit_count") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().commit_count;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_total_commit_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().total_commit_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_decommit_count") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().decommit_count;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_total_decommit_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().total_decommit_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_reserve_count") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().reserve_count;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_total_reserve_bytes") == 0) {
-        SpinLockHolder l(Static::pageheap_lock());
-        *value = Static::pageheap()->stats().total_reserve_bytes;
-        return true;
-    }
-
-    if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = ThreadCache::overall_thread_cache_size();
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.current_total_thread_cache_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.thread_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.aggressive_memory_decommit") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = size_t(Static::pageheap()->GetAggressiveDecommit());
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.sampling_period_bytes") == 0) {
-      *value = Sampler::GetSamplePeriod();
-      return true;
-    }
-
-    return false;
-  }
-
-  virtual bool SetNumericProperty(const char* name, size_t value) {
-    ASSERT(name != NULL);
-
-    if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      ThreadCache::set_overall_thread_cache_size(value);
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.aggressive_memory_decommit") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      Static::pageheap()->SetAggressiveDecommit(value != 0);
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.sampling_period_bytes") == 0) {
-      Sampler::SetSamplePeriod(value);
-      return true;
-    }
-
-    return false;
-  }
-
-  virtual void MarkThreadIdle() {
-    ThreadCache::BecomeIdle();
-  }
-
-  virtual void MarkThreadBusy();  // Implemented below
-
-  virtual SysAllocator* GetSystemAllocator() {
-    SpinLockHolder h(Static::pageheap_lock());
-    return tcmalloc_sys_alloc;
-  }
-
-  virtual void SetSystemAllocator(SysAllocator* alloc) {
-    SpinLockHolder h(Static::pageheap_lock());
-    tcmalloc_sys_alloc = alloc;
-  }
-
-  virtual void ReleaseToSystem(size_t num_bytes) {
-    SpinLockHolder h(Static::pageheap_lock());
-    if (num_bytes <= extra_bytes_released_) {
-      // We released too much on a prior call, so don't release any
-      // more this time.
-      extra_bytes_released_ = extra_bytes_released_ - num_bytes;
-      return;
-    }
-    num_bytes = num_bytes - extra_bytes_released_;
-    // num_bytes might be less than one page.  If we pass zero to
-    // ReleaseAtLeastNPages, it won't do anything, so we release a whole
-    // page now and let extra_bytes_released_ smooth it out over time.
-    Length num_pages = max<Length>(num_bytes >> kPageShift, 1);
-    size_t bytes_released = Static::pageheap()->ReleaseAtLeastNPages(
-        num_pages) << kPageShift;
-    if (bytes_released > num_bytes) {
-      extra_bytes_released_ = bytes_released - num_bytes;
-    } else {
-      // The PageHeap wasn't able to release num_bytes.  Don't try to
-      // compensate with a big release next time.  Specifically,
-      // ReleaseFreeMemory() calls ReleaseToSystem(LONG_MAX).
-      extra_bytes_released_ = 0;
-    }
-  }
-
-  virtual void SetMemoryReleaseRate(double rate) {
-    FLAGS_tcmalloc_release_rate = rate;
-  }
-
-  virtual double GetMemoryReleaseRate() {
-    return FLAGS_tcmalloc_release_rate;
-  }
-  virtual size_t GetEstimatedAllocatedSize(size_t size);
-
-  // This just calls GetSizeWithCallback, but because that's in an
-  // unnamed namespace, we need to move the definition below it in the
-  // file.
-  virtual size_t GetAllocatedSize(const void* ptr);
-
-  // This duplicates some of the logic in GetSizeWithCallback, but is
-  // faster.  This is important on OS X, where this function is called
-  // on every allocation operation.
-  virtual Ownership GetOwnership(const void* ptr) {
-    const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-    // The rest of tcmalloc assumes that all allocated pointers use at
-    // most kAddressBits bits.  If ptr doesn't, then it definitely
-    // wasn't alloacted by tcmalloc.
-    if ((p >> (kAddressBits - kPageShift)) > 0) {
-      return kNotOwned;
-    }
-    uint32 cl;
-    if (Static::pageheap()->TryGetSizeClass(p, &cl)) {
-      return kOwned;
-    }
-    const Span *span = Static::pageheap()->GetDescriptor(p);
-    return span ? kOwned : kNotOwned;
-  }
-
-  virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {
-    static const char kCentralCacheType[] = "tcmalloc.central";
-    static const char kTransferCacheType[] = "tcmalloc.transfer";
-    static const char kThreadCacheType[] = "tcmalloc.thread";
-    static const char kPageHeapType[] = "tcmalloc.page";
-    static const char kPageHeapUnmappedType[] = "tcmalloc.page_unmapped";
-    static const char kLargeSpanType[] = "tcmalloc.large";
-    static const char kLargeUnmappedSpanType[] = "tcmalloc.large_unmapped";
-
-    v->clear();
-
-    // central class information
-    int64 prev_class_size = 0;
-    for (int cl = 1; cl < Static::num_size_classes(); ++cl) {
-      size_t class_size = Static::sizemap()->ByteSizeForClass(cl);
-      MallocExtension::FreeListInfo i;
-      i.min_object_size = prev_class_size + 1;
-      i.max_object_size = class_size;
-      i.total_bytes_free =
-          Static::central_cache()[cl].length() * class_size;
-      i.type = kCentralCacheType;
-      v->push_back(i);
-
-      // transfer cache
-      i.total_bytes_free =
-          Static::central_cache()[cl].tc_length() * class_size;
-      i.type = kTransferCacheType;
-      v->push_back(i);
-
-      prev_class_size = Static::sizemap()->ByteSizeForClass(cl);
-    }
-
-    // Add stats from per-thread heaps
-    uint64_t class_count[kClassSizesMax];
-    memset(class_count, 0, sizeof(class_count));
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      uint64_t thread_bytes = 0;
-      ThreadCache::GetThreadStats(&thread_bytes, class_count);
-    }
-
-    prev_class_size = 0;
-    for (int cl = 1; cl < Static::num_size_classes(); ++cl) {
-      MallocExtension::FreeListInfo i;
-      i.min_object_size = prev_class_size + 1;
-      i.max_object_size = Static::sizemap()->ByteSizeForClass(cl);
-      i.total_bytes_free =
-          class_count[cl] * Static::sizemap()->ByteSizeForClass(cl);
-      i.type = kThreadCacheType;
-      v->push_back(i);
-
-      prev_class_size = Static::sizemap()->ByteSizeForClass(cl);
-    }
-
-    // append page heap info
-    PageHeap::SmallSpanStats small;
-    PageHeap::LargeSpanStats large;
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      Static::pageheap()->GetSmallSpanStats(&small);
-      Static::pageheap()->GetLargeSpanStats(&large);
-    }
-
-    // large spans: mapped
-    MallocExtension::FreeListInfo span_info;
-    span_info.type = kLargeSpanType;
-    span_info.max_object_size = (numeric_limits<size_t>::max)();
-    span_info.min_object_size = kMaxPages << kPageShift;
-    span_info.total_bytes_free = large.normal_pages << kPageShift;
-    v->push_back(span_info);
-
-    // large spans: unmapped
-    span_info.type = kLargeUnmappedSpanType;
-    span_info.total_bytes_free = large.returned_pages << kPageShift;
-    v->push_back(span_info);
-
-    // small spans
-    for (int s = 1; s <= kMaxPages; s++) {
-      MallocExtension::FreeListInfo i;
-      i.max_object_size = (s << kPageShift);
-      i.min_object_size = ((s - 1) << kPageShift);
-
-      i.type = kPageHeapType;
-      i.total_bytes_free = (s << kPageShift) * small.normal_length[s - 1];
-      v->push_back(i);
-
-      i.type = kPageHeapUnmappedType;
-      i.total_bytes_free = (s << kPageShift) * small.returned_length[s - 1];
-      v->push_back(i);
-    }
-  }
-};
-
-static inline ATTRIBUTE_ALWAYS_INLINE
-size_t align_size_up(size_t size, size_t align) {
-  ASSERT(align <= kPageSize);
-  size_t new_size = (size + align - 1) & ~(align - 1);
-  if (PREDICT_FALSE(new_size == 0)) {
-    // Note, new_size == 0 catches both integer overflow and size
-    // being 0.
-    if (size == 0) {
-      new_size = align;
-    } else {
-      new_size = size;
-    }
-  }
-  return new_size;
-}
-
-// Puts in *cl size class that is suitable for allocation of size bytes with
-// align alignment. Returns true if such size class exists and false otherwise.
-static bool size_class_with_alignment(size_t size, size_t align, uint32_t* cl) {
-  if (PREDICT_FALSE(align > kPageSize)) {
-    return false;
-  }
-  size = align_size_up(size, align);
-  if (PREDICT_FALSE(!Static::sizemap()->GetSizeClass(size, cl))) {
-    return false;
-  }
-  ASSERT((Static::sizemap()->class_to_size(*cl) & (align - 1)) == 0);
-  return true;
-}
-
-// nallocx slow path. Moved to a separate function because
-// ThreadCache::InitModule is not inlined which would cause nallocx to
-// become non-leaf function with stack frame and stack spills.
-static ATTRIBUTE_NOINLINE size_t nallocx_slow(size_t size, int flags) {
-  if (PREDICT_FALSE(!Static::IsInited())) ThreadCache::InitModule();
-
-  size_t align = static_cast<size_t>(1ull << (flags & 0x3f));
-  uint32 cl;
-  bool ok = size_class_with_alignment(size, align, &cl);
-  if (ok) {
-    return Static::sizemap()->ByteSizeForClass(cl);
-  } else {
-    return tcmalloc::pages(size) << kPageShift;
-  }
-}
-
-// The nallocx function allocates no memory, but it performs the same size
-// computation as the malloc function, and returns the real size of the
-// allocation that would result from the equivalent malloc function call.
-// nallocx is a malloc extension originally implemented by jemalloc:
-// http://www.unix.com/man-page/freebsd/3/nallocx/
-extern "C" PERFTOOLS_DLL_DECL
-size_t tc_nallocx(size_t size, int flags) {
-  if (PREDICT_FALSE(flags != 0)) {
-    return nallocx_slow(size, flags);
-  }
-  uint32 cl;
-  // size class 0 is only possible if malloc is not yet initialized
-  if (Static::sizemap()->GetSizeClass(size, &cl) && cl != 0) {
-    return Static::sizemap()->ByteSizeForClass(cl);
-  } else {
-    return nallocx_slow(size, 0);
-  }
-}
-
-extern "C" PERFTOOLS_DLL_DECL
-size_t nallocx(size_t size, int flags)
-#ifdef TC_ALIAS
-  TC_ALIAS(tc_nallocx);
-#else
-{
-  return nallocx_slow(size, flags);
-}
-#endif
-
-
-size_t TCMallocImplementation::GetEstimatedAllocatedSize(size_t size) {
-  return tc_nallocx(size, 0);
-}
-
-// The constructor allocates an object to ensure that initialization
-// runs before main(), and therefore we do not have a chance to become
-// multi-threaded before initialization.  We also create the TSD key
-// here.  Presumably by the time this constructor runs, glibc is in
-// good enough shape to handle pthread_key_create().
-//
-// The constructor also takes the opportunity to tell STL to use
-// tcmalloc.  We want to do this early, before construct time, so
-// all user STL allocations go through tcmalloc (which works really
-// well for STL).
-//
-// The destructor prints stats when the program exits.
-static int tcmallocguard_refcount = 0;  // no lock needed: runs before main()
-TCMallocGuard::TCMallocGuard() {
-  if (tcmallocguard_refcount++ == 0) {
-    ReplaceSystemAlloc();    // defined in libc_override_*.h
-    tc_free(tc_malloc(1));
-    ThreadCache::InitTSD();
-    tc_free(tc_malloc(1));
-    // Either we, or debugallocation.cc, or valgrind will control memory
-    // management.  We register our extension if we're the winner.
-#ifdef TCMALLOC_USING_DEBUGALLOCATION
-    // Let debugallocation register its extension.
-#else
-    if (RunningOnValgrind()) {
-      // Let Valgrind uses its own malloc (so don't register our extension).
-    } else {
-      MallocExtension::Register(new TCMallocImplementation);
-    }
-#endif
-  }
-}
-
-TCMallocGuard::~TCMallocGuard() {
-  if (--tcmallocguard_refcount == 0) {
-    const char* env = NULL;
-    if (!RunningOnValgrind()) {
-      // Valgrind uses it's own malloc so we cannot do MALLOCSTATS
-      env = getenv("MALLOCSTATS");
-    }
-    if (env != NULL) {
-      int level = atoi(env);
-      if (level < 1) level = 1;
-      PrintStats(level);
-    }
-  }
-}
-#ifndef WIN32_OVERRIDE_ALLOCATORS
-static TCMallocGuard module_enter_exit_hook;
-#endif
-
-//-------------------------------------------------------------------
-// Helpers for the exported routines below
-//-------------------------------------------------------------------
-
-static inline bool CheckCachedSizeClass(void *ptr) {
-  PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-  uint32 cached_value;
-  if (!Static::pageheap()->TryGetSizeClass(p, &cached_value)) {
-    return true;
-  }
-  return cached_value == Static::pageheap()->GetDescriptor(p)->sizeclass;
-}
-
-static inline ATTRIBUTE_ALWAYS_INLINE void* CheckedMallocResult(void* result) {
-  ASSERT(result == NULL || CheckCachedSizeClass(result));
-  return result;
-}
-
-static inline ATTRIBUTE_ALWAYS_INLINE void* SpanToMallocResult(Span *span) {
-  Static::pageheap()->InvalidateCachedSizeClass(span->start);
-  return CheckedMallocResult(
-      reinterpret_cast<void*>(span->start << kPageShift));
-}
-
-static void* DoSampledAllocation(size_t size) {
-#ifndef NO_TCMALLOC_SAMPLES
-  // Grab the stack trace outside the heap lock
-  StackTrace tmp;
-  tmp.depth = GetStackTrace(tmp.stack, tcmalloc::kMaxStackDepth, 1);
-  tmp.size = size;
-
-  SpinLockHolder h(Static::pageheap_lock());
-  // Allocate span
-  Span *span = Static::pageheap()->New(tcmalloc::pages(size == 0 ? 1 : size));
-  if (PREDICT_FALSE(span == NULL)) {
-    return NULL;
-  }
-
-  // Allocate stack trace
-  StackTrace *stack = Static::stacktrace_allocator()->New();
-  if (PREDICT_FALSE(stack == NULL)) {
-    // Sampling failed because of lack of memory
-    return span;
-  }
-  *stack = tmp;
-  span->sample = 1;
-  span->objects = stack;
-  tcmalloc::DLL_Prepend(Static::sampled_objects(), span);
-
-  return SpanToMallocResult(span);
-#else
-  abort();
-#endif
-}
-
-namespace {
-
-typedef void* (*malloc_fn)(void *arg);
-
-SpinLock set_new_handler_lock(SpinLock::LINKER_INITIALIZED);
-
-void* handle_oom(malloc_fn retry_fn,
-                 void* retry_arg,
-                 bool from_operator,
-                 bool nothrow) {
-  // we hit out of memory condition, usually if it happens we've
-  // called sbrk or mmap and failed, and thus errno is set. But there
-  // is support for setting up custom system allocator or setting up
-  // page heap size limit, in which cases errno may remain
-  // untouched.
-  //
-  // So we set errno here. C++ operator new doesn't require ENOMEM to
-  // be set, but doesn't forbid it too (and often C++ oom does happen
-  // with ENOMEM set).
-  errno = ENOMEM;
-  if (!from_operator && !tc_new_mode) {
-    // we're out of memory in C library function (malloc etc) and no
-    // "new mode" forced on us. Just return NULL
-    return NULL;
-  }
-  // we're OOM in operator new or "new mode" is set. We might have to
-  // call new_handle and maybe retry allocation.
-
-  for (;;) {
-    // Get the current new handler.  NB: this function is not
-    // thread-safe.  We make a feeble stab at making it so here, but
-    // this lock only protects against tcmalloc interfering with
-    // itself, not with other libraries calling set_new_handler.
-    std::new_handler nh;
-    {
-      SpinLockHolder h(&set_new_handler_lock);
-      nh = std::set_new_handler(0);
-      (void) std::set_new_handler(nh);
-    }
-#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
-    if (!nh) {
-      return NULL;
-    }
-    // Since exceptions are disabled, we don't really know if new_handler
-    // failed.  Assume it will abort if it fails.
-    (*nh)();
-#else
-    // If no new_handler is established, the allocation failed.
-    if (!nh) {
-      if (nothrow) {
-        return NULL;
-      }
-      throw std::bad_alloc();
-    }
-    // Otherwise, try the new_handler.  If it returns, retry the
-    // allocation.  If it throws std::bad_alloc, fail the allocation.
-    // if it throws something else, don't interfere.
-    try {
-      (*nh)();
-    } catch (const std::bad_alloc&) {
-      if (!nothrow) throw;
-      return NULL;
-    }
-#endif  // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
-
-    // we get here if new_handler returns successfully. So we retry
-    // allocation.
-    void* rv = retry_fn(retry_arg);
-    if (rv != NULL) {
-      return rv;
-    }
-
-    // if allocation failed again we go to next loop iteration
-  }
-}
-
-// Copy of FLAGS_tcmalloc_large_alloc_report_threshold with
-// automatic increases factored in.
-static int64_t large_alloc_threshold =
-  (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold
-   ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold);
-
-static void ReportLargeAlloc(Length num_pages, void* result) {
-  StackTrace stack;
-  stack.depth = GetStackTrace(stack.stack, tcmalloc::kMaxStackDepth, 1);
-
-  static const int N = 1000;
-  char buffer[N];
-  TCMalloc_Printer printer(buffer, N);
-  printer.printf("tcmalloc: large alloc %" PRIu64 " bytes == %p @ ",
-                 static_cast<uint64>(num_pages) << kPageShift,
-                 result);
-  for (int i = 0; i < stack.depth; i++) {
-    printer.printf(" %p", stack.stack[i]);
-  }
-  printer.printf("\n");
-  write(STDERR_FILENO, buffer, strlen(buffer));
-}
-
-// Must be called with the page lock held.
-inline bool should_report_large(Length num_pages) {
-  const int64 threshold = large_alloc_threshold;
-  if (threshold > 0 && num_pages >= (threshold >> kPageShift)) {
-    // Increase the threshold by 1/8 every time we generate a report.
-    // We cap the threshold at 8GiB to avoid overflow problems.
-    large_alloc_threshold = (threshold + threshold/8 < 8ll<<30
-                             ? threshold + threshold/8 : 8ll<<30);
-    return true;
-  }
-  return false;
-}
-
-// Helper for do_malloc().
-static void* do_malloc_pages(ThreadCache* heap, size_t size) {
-  void* result;
-  bool report_large;
-
-  Length num_pages = tcmalloc::pages(size);
-
-  // Chromium profiling.  Measurements in March 2013 suggest this
-  // imposes a small enough runtime cost that there's no reason to
-  // try to optimize it.
-  heap->AddToByteAllocatedTotal(size);
-
-  // NOTE: we're passing original size here as opposed to rounded-up
-  // size as we do in do_malloc_small. The difference is small here
-  // (at most 4k out of at least 256k). And not rounding up saves us
-  // from possibility of overflow, which rounding up could produce.
-  //
-  // See https://github.com/gperftools/gperftools/issues/723
-  if (heap->SampleAllocation(size)) {
-    result = DoSampledAllocation(size);
-
-    SpinLockHolder h(Static::pageheap_lock());
-    report_large = should_report_large(num_pages);
-  } else {
-    SpinLockHolder h(Static::pageheap_lock());
-    Span* span = Static::pageheap()->New(num_pages);
-    result = (PREDICT_FALSE(span == NULL) ? NULL : SpanToMallocResult(span));
-    report_large = should_report_large(num_pages);
-  }
-
-  if (report_large) {
-    ReportLargeAlloc(num_pages, result);
-  }
-  return result;
-}
-
-static void *nop_oom_handler(size_t size) {
-  return NULL;
-}
-
-ATTRIBUTE_ALWAYS_INLINE inline void* do_malloc(size_t size) {
-#if defined(TCMALLOC_DISABLE_HUGE_ALLOCATIONS)
-  if (!IsAllocSizePermitted(size)) {
-    errno = ENOMEM;
-    return NULL;
-  }
-#endif
-
-  if (PREDICT_FALSE(ThreadCache::IsUseEmergencyMalloc())) {
-    return tcmalloc::EmergencyMalloc(size);
-  }
-
-  // note: it will force initialization of malloc if necessary
-  ThreadCache* cache = ThreadCache::GetCache();
-  uint32 cl;
-
-  ASSERT(Static::IsInited());
-  ASSERT(cache != NULL);
-
-  if (PREDICT_FALSE(!Static::sizemap()->GetSizeClass(size, &cl))) {
-    return do_malloc_pages(cache, size);
-  }
-
-  // TODO(jar): If this has any detectable performance impact, it can be
-  // optimized by only tallying sizes if the profiler was activated to recall
-  // these tallies.  I don't think this is performance critical, but we really
-  // should measure it.
-  cache->AddToByteAllocatedTotal(size);  // Chromium profiling.
-
-  size_t allocated_size = Static::sizemap()->class_to_size(cl);
-  if (PREDICT_FALSE(cache->SampleAllocation(allocated_size))) {
-    return DoSampledAllocation(size);
-  }
-
-  // The common case, and also the simplest.  This just pops the
-  // size-appropriate freelist, after replenishing it if it's empty.
-  return CheckedMallocResult(
-      cache->Allocate(allocated_size, cl, nop_oom_handler));
-}
-
-static void *retry_malloc(void* size) {
-  return do_malloc(reinterpret_cast<size_t>(size));
-}
-
-ATTRIBUTE_ALWAYS_INLINE inline void* do_malloc_or_cpp_alloc(size_t size) {
-  void *rv = do_malloc(size);
-  if (PREDICT_TRUE(rv != NULL)) {
-    return rv;
-  }
-  return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
-                    false, true);
-}
-
-ATTRIBUTE_ALWAYS_INLINE inline void* do_calloc(size_t n, size_t elem_size) {
-  // Overflow check
-  const size_t size = n * elem_size;
-  if (elem_size != 0 && size / elem_size != n) return NULL;
-
-  void* result = do_malloc_or_cpp_alloc(size);
-  if (result != NULL) {
-    memset(result, 0, size);
-  }
-  return result;
-}
-
-// If ptr is NULL, do nothing.  Otherwise invoke the given function.
-inline void free_null_or_invalid(void* ptr, void (*invalid_free_fn)(void*)) {
-  if (ptr != NULL) {
-    (*invalid_free_fn)(ptr);
-  }
-}
-
-static ATTRIBUTE_NOINLINE void do_free_pages(Span* span, void* ptr) {
-  // Check to see if the object is in use.
-  CHECK_CONDITION_PRINT(span->location == Span::IN_USE,
-                        "Object was not in-use");
-  CHECK_CONDITION_PRINT(
-      span->start << kPageShift == reinterpret_cast<uintptr_t>(ptr),
-      "Pointer is not pointing to the start of a span");
-
-  SpinLockHolder h(Static::pageheap_lock());
-  if (span->sample) {
-    StackTrace* st = reinterpret_cast<StackTrace*>(span->objects);
-    tcmalloc::DLL_Remove(span);
-    Static::stacktrace_allocator()->Delete(st);
-    span->objects = NULL;
-  }
-  Static::pageheap()->Delete(span);
-}
-
-// Helper for the object deletion (free, delete, etc.).  Inputs:
-//   ptr is object to be freed
-//   invalid_free_fn is a function that gets invoked on certain "bad frees"
-//
-// We can usually detect the case where ptr is not pointing to a page that
-// tcmalloc is using, and in those cases we invoke invalid_free_fn.
-ATTRIBUTE_ALWAYS_INLINE inline
-void do_free_with_callback(void* ptr,
-                           void (*invalid_free_fn)(void*),
-                           bool use_hint, size_t size_hint) {
-  ThreadCache* heap = ThreadCache::GetCacheIfPresent();
-
-  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-  uint32 cl;
-
-#ifndef NO_TCMALLOC_SAMPLES
-  // we only pass size hint when ptr is not page aligned. Which
-  // implies that it must be very small object.
-  ASSERT(!use_hint || size_hint < kPageSize);
-#endif
-
-  if (!use_hint || PREDICT_FALSE(!Static::sizemap()->GetSizeClass(size_hint, &cl))) {
-    // if we're in sized delete, but size is too large, no need to
-    // probe size cache
-    bool cache_hit = !use_hint && Static::pageheap()->TryGetSizeClass(p, &cl);
-    if (PREDICT_FALSE(!cache_hit)) {
-      Span* span  = Static::pageheap()->GetDescriptor(p);
-      if (PREDICT_FALSE(!span)) {
-        // span can be NULL because the pointer passed in is NULL or invalid
-        // (not something returned by malloc or friends), or because the
-        // pointer was allocated with some other allocator besides
-        // tcmalloc.  The latter can happen if tcmalloc is linked in via
-        // a dynamic library, but is not listed last on the link line.
-        // In that case, libraries after it on the link line will
-        // allocate with libc malloc, but free with tcmalloc's free.
-        free_null_or_invalid(ptr, invalid_free_fn);
-        return;
-      }
-      cl = span->sizeclass;
-      if (PREDICT_FALSE(cl == 0)) {
-        ASSERT(reinterpret_cast<uintptr_t>(ptr) % kPageSize == 0);
-        ASSERT(span != NULL && span->start == p);
-        do_free_pages(span, ptr);
-        return;
-      }
-      if (!use_hint) {
-        Static::pageheap()->SetCachedSizeClass(p, cl);
-      }
-    }
-  }
-
-  if (PREDICT_TRUE(heap != NULL)) {
-    ASSERT(Static::IsInited());
-    // If we've hit initialized thread cache, so we're done.
-    heap->Deallocate(ptr, cl);
-    return;
-  }
-
-  if (PREDICT_FALSE(!Static::IsInited())) {
-    // if free was called very early we've could have missed the case
-    // of invalid or nullptr free. I.e. because probing size classes
-    // cache could return bogus result (cl = 0 as of this
-    // writing). But since there is no way we could be dealing with
-    // ptr we've allocated, since successfull malloc implies IsInited,
-    // we can just call "invalid free" handling code.
-    free_null_or_invalid(ptr, invalid_free_fn);
-    return;
-  }
-
-  // Otherwise, delete directly into central cache
-  tcmalloc::FL_Init(ptr);
-  Static::central_cache()[cl].InsertRange(ptr, ptr, 1);
-}
-
-// The default "do_free" that uses the default callback.
-ATTRIBUTE_ALWAYS_INLINE inline void do_free(void* ptr) {
-  return do_free_with_callback(ptr, &InvalidFree, false, 0);
-}
-
-// NOTE: some logic here is duplicated in GetOwnership (above), for
-// speed.  If you change this function, look at that one too.
-inline size_t GetSizeWithCallback(const void* ptr,
-                                  size_t (*invalid_getsize_fn)(const void*)) {
-  if (ptr == NULL)
-    return 0;
-  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-  uint32 cl;
-  if (Static::pageheap()->TryGetSizeClass(p, &cl)) {
-    return Static::sizemap()->ByteSizeForClass(cl);
-  }
-
-  const Span *span = Static::pageheap()->GetDescriptor(p);
-  if (PREDICT_FALSE(span == NULL)) {  // means we do not own this memory
-    return (*invalid_getsize_fn)(ptr);
-  }
-
-  if (span->sizeclass != 0) {
-    return Static::sizemap()->ByteSizeForClass(span->sizeclass);
-  }
-
-  if (span->sample) {
-    size_t orig_size = reinterpret_cast<StackTrace*>(span->objects)->size;
-    return tc_nallocx(orig_size, 0);
-  }
-
-  return span->length << kPageShift;
-}
-
-// This lets you call back to a given function pointer if ptr is invalid.
-// It is used primarily by windows code which wants a specialized callback.
-ATTRIBUTE_ALWAYS_INLINE inline void* do_realloc_with_callback(
-    void* old_ptr, size_t new_size,
-    void (*invalid_free_fn)(void*),
-    size_t (*invalid_get_size_fn)(const void*)) {
-  // Get the size of the old entry
-  const size_t old_size = GetSizeWithCallback(old_ptr, invalid_get_size_fn);
-
-  // Reallocate if the new size is larger than the old size,
-  // or if the new size is significantly smaller than the old size.
-  // We do hysteresis to avoid resizing ping-pongs:
-  //    . If we need to grow, grow to max(new_size, old_size * 1.X)
-  //    . Don't shrink unless new_size < old_size * 0.Y
-  // X and Y trade-off time for wasted space.  For now we do 1.25 and 0.5.
-  const size_t min_growth = min(old_size / 4,
-      (std::numeric_limits<size_t>::max)() - old_size);  // Avoid overflow.
-  const size_t lower_bound_to_grow = old_size + min_growth;
-  const size_t upper_bound_to_shrink = old_size / 2ul;
-  if ((new_size > old_size) || (new_size < upper_bound_to_shrink)) {
-    // Need to reallocate.
-    void* new_ptr = NULL;
-
-    if (new_size > old_size && new_size < lower_bound_to_grow) {
-      new_ptr = do_malloc_or_cpp_alloc(lower_bound_to_grow);
-    }
-    if (new_ptr == NULL) {
-      // Either new_size is not a tiny increment, or last do_malloc failed.
-      new_ptr = do_malloc_or_cpp_alloc(new_size);
-    }
-    if (PREDICT_FALSE(new_ptr == NULL)) {
-      return NULL;
-    }
-    MallocHook::InvokeNewHook(new_ptr, new_size);
-    memcpy(new_ptr, old_ptr, ((old_size < new_size) ? old_size : new_size));
-    MallocHook::InvokeDeleteHook(old_ptr);
-    // We could use a variant of do_free() that leverages the fact
-    // that we already know the sizeclass of old_ptr.  The benefit
-    // would be small, so don't bother.
-    do_free_with_callback(old_ptr, invalid_free_fn, false, 0);
-    return new_ptr;
-  } else {
-    // We still need to call hooks to report the updated size:
-    MallocHook::InvokeDeleteHook(old_ptr);
-    MallocHook::InvokeNewHook(old_ptr, new_size);
-    return old_ptr;
-  }
-}
-
-ATTRIBUTE_ALWAYS_INLINE inline void* do_realloc(void* old_ptr, size_t new_size) {
-  return do_realloc_with_callback(old_ptr, new_size,
-                                  &InvalidFree, &InvalidGetSizeForRealloc);
-}
-
-static ATTRIBUTE_ALWAYS_INLINE inline
-void* do_memalign_pages(size_t align, size_t size) {
-  ASSERT((align & (align - 1)) == 0);
-  ASSERT(align > kPageSize);
-  if (size + align < size) return NULL;         // Overflow
-
-  if (PREDICT_FALSE(Static::pageheap() == NULL)) ThreadCache::InitModule();
-
-  // Allocate at least one byte to avoid boundary conditions below
-  if (size == 0) size = 1;
-
-  // We will allocate directly from the page heap
-  SpinLockHolder h(Static::pageheap_lock());
-
-  // Allocate extra pages and carve off an aligned portion
-  const Length alloc = tcmalloc::pages(size + align);
-  Span* span = Static::pageheap()->New(alloc);
-  if (PREDICT_FALSE(span == NULL)) return NULL;
-
-  // Skip starting portion so that we end up aligned
-  Length skip = 0;
-  while ((((span->start+skip) << kPageShift) & (align - 1)) != 0) {
-    skip++;
-  }
-  ASSERT(skip < alloc);
-  if (skip > 0) {
-    Span* rest = Static::pageheap()->Split(span, skip);
-    Static::pageheap()->Delete(span);
-    span = rest;
-  }
-
-  // Skip trailing portion that we do not need to return
-  const Length needed = tcmalloc::pages(size);
-  ASSERT(span->length >= needed);
-  if (span->length > needed) {
-    Span* trailer = Static::pageheap()->Split(span, needed);
-    Static::pageheap()->Delete(trailer);
-  }
-  return SpanToMallocResult(span);
-}
-
-// Helpers for use by exported routines below:
-
-inline void do_malloc_stats() {
-  PrintStats(1);
-}
-
-inline int do_mallopt(int cmd, int value) {
-  if (cmd == TC_MALLOPT_IS_OVERRIDDEN_BY_TCMALLOC)
-    return TC_MALLOPT_IS_OVERRIDDEN_BY_TCMALLOC;
-
-  // 1 is the success return value according to man mallopt(). However (see the
-  // BUGS section in the manpage), most implementations return always 1.
-  // This code is just complying with that (buggy) expectation.
-  return 1;
-}
-
-#ifdef HAVE_STRUCT_MALLINFO
-inline struct mallinfo do_mallinfo() {
-  TCMallocStats stats;
-  ExtractStats(&stats, NULL, NULL, NULL);
-
-  // Just some of the fields are filled in.
-  struct mallinfo info;
-  memset(&info, 0, sizeof(info));
-
-  // Unfortunately, the struct contains "int" field, so some of the
-  // size values will be truncated.
-  info.arena     = static_cast<int>(stats.pageheap.system_bytes);
-  info.fsmblks   = static_cast<int>(stats.thread_bytes
-                                    + stats.central_bytes
-                                    + stats.transfer_bytes);
-  info.fordblks  = static_cast<int>(stats.pageheap.free_bytes +
-                                    stats.pageheap.unmapped_bytes);
-  info.uordblks  = static_cast<int>(stats.pageheap.system_bytes
-                                    - stats.thread_bytes
-                                    - stats.central_bytes
-                                    - stats.transfer_bytes
-                                    - stats.pageheap.free_bytes
-                                    - stats.pageheap.unmapped_bytes);
-
-  return info;
-}
-#endif  // HAVE_STRUCT_MALLINFO
-
-}  // end unnamed namespace
-
-// As promised, the definition of this function, declared above.
-size_t TCMallocImplementation::GetAllocatedSize(const void* ptr) {
-  if (ptr == NULL)
-    return 0;
-  ASSERT(TCMallocImplementation::GetOwnership(ptr)
-         != TCMallocImplementation::kNotOwned);
-  return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize);
-}
-
-void TCMallocImplementation::MarkThreadBusy() {
-  // Allocate to force the creation of a thread cache, but avoid
-  // invoking any hooks.
-  do_free(do_malloc(0));
-}
-
-//-------------------------------------------------------------------
-// Exported routines
-//-------------------------------------------------------------------
-
-extern "C" PERFTOOLS_DLL_DECL const char* tc_version(
-    int* major, int* minor, const char** patch) PERFTOOLS_NOTHROW {
-  if (major) *major = TC_VERSION_MAJOR;
-  if (minor) *minor = TC_VERSION_MINOR;
-  if (patch) *patch = TC_VERSION_PATCH;
-  return TC_VERSION_STRING;
-}
-
-// This function behaves similarly to MSVC's _set_new_mode.
-// If flag is 0 (default), calls to malloc will behave normally.
-// If flag is 1, calls to malloc will behave like calls to new,
-// and the std_new_handler will be invoked on failure.
-// Returns the previous mode.
-extern "C" PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW {
-  int old_mode = tc_new_mode;
-  tc_new_mode = flag;
-  return old_mode;
-}
-
-extern "C" PERFTOOLS_DLL_DECL int tc_query_new_mode() PERFTOOLS_NOTHROW {
-  return tc_new_mode;
-}
-
-#ifndef TCMALLOC_USING_DEBUGALLOCATION  // debugallocation.cc defines its own
-
-// CAVEAT: The code structure below ensures that MallocHook methods are always
-//         called from the stack frame of the invoked allocation function.
-//         heap-checker.cc depends on this to start a stack trace from
-//         the call to the (de)allocation function.
-
-namespace tcmalloc {
-
-
-static ATTRIBUTE_SECTION(google_malloc)
-void invoke_hooks_and_free(void *ptr) {
-  MallocHook::InvokeDeleteHook(ptr);
-  do_free(ptr);
-}
-
-ATTRIBUTE_SECTION(google_malloc)
-void* cpp_throw_oom(size_t size) {
-  return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
-                    true, false);
-}
-
-ATTRIBUTE_SECTION(google_malloc)
-void* cpp_nothrow_oom(size_t size) {
-  return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
-                    true, true);
-}
-
-ATTRIBUTE_SECTION(google_malloc)
-void* malloc_oom(size_t size) {
-  return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
-                    false, true);
-}
-
-// tcmalloc::allocate_full_XXX is called by fast-path malloc when some
-// complex handling is needed (such as fetching object from central
-// freelist or malloc sampling). It contains all 'operator new' logic,
-// as opposed to malloc_fast_path which only deals with important
-// subset of cases.
-//
-// Note that this is under tcmalloc namespace so that pprof
-// can automatically filter it out of growthz/heapz profiles.
-//
-// We have slightly fancy setup because we need to call hooks from
-// function in 'google_malloc' section and we cannot place template
-// into this section. Thus 3 separate functions 'built' by macros.
-//
-// Also note that we're carefully orchestrating for
-// MallocHook::GetCallerStackTrace to work even if compiler isn't
-// optimizing tail calls (e.g. -O0 is given). We still require
-// ATTRIBUTE_ALWAYS_INLINE to work for that case, but it was seen to
-// work for -O0 -fno-inline across both GCC and clang. I.e. in this
-// case we'll get stack frame for tc_new, followed by stack frame for
-// allocate_full_cpp_throw_oom, followed by hooks machinery and user
-// code's stack frames. So GetCallerStackTrace will find 2
-// subsequent stack frames in google_malloc section and correctly
-// 'cut' stack trace just before tc_new.
-template <void* OOMHandler(size_t)>
-ATTRIBUTE_ALWAYS_INLINE inline
-static void* do_allocate_full(size_t size) {
-  void* p = do_malloc(size);
-  if (PREDICT_FALSE(p == NULL)) {
-    p = OOMHandler(size);
-  }
-  MallocHook::InvokeNewHook(p, size);
-  return CheckedMallocResult(p);
-}
-
-#define AF(oom) \
-  ATTRIBUTE_SECTION(google_malloc)   \
-  void* allocate_full_##oom(size_t size) {   \
-    return do_allocate_full<oom>(size);     \
-  }
-
-AF(cpp_throw_oom)
-AF(cpp_nothrow_oom)
-AF(malloc_oom)
-
-#undef AF
-
-template <void* OOMHandler(size_t)>
-static ATTRIBUTE_ALWAYS_INLINE inline void* dispatch_allocate_full(size_t size) {
-  if (OOMHandler == cpp_throw_oom) {
-    return allocate_full_cpp_throw_oom(size);
-  }
-  if (OOMHandler == cpp_nothrow_oom) {
-    return allocate_full_cpp_nothrow_oom(size);
-  }
-  ASSERT(OOMHandler == malloc_oom);
-  return allocate_full_malloc_oom(size);
-}
-
-struct retry_memalign_data {
-  size_t align;
-  size_t size;
-};
-
-static void *retry_do_memalign(void *arg) {
-  retry_memalign_data *data = static_cast<retry_memalign_data *>(arg);
-  return do_memalign_pages(data->align, data->size);
-}
-
-static ATTRIBUTE_SECTION(google_malloc)
-void* memalign_pages(size_t align, size_t size,
-                     bool from_operator, bool nothrow) {
-  void *rv = do_memalign_pages(align, size);
-  if (PREDICT_FALSE(rv == NULL)) {
-    retry_memalign_data data;
-    data.align = align;
-    data.size = size;
-    rv = handle_oom(retry_do_memalign, &data,
-                    from_operator, nothrow);
-  }
-  MallocHook::InvokeNewHook(rv, size);
-  return CheckedMallocResult(rv);
-}
-
-} // namespace tcmalloc
-
-// This is quick, fast-path-only implementation of malloc/new. It is
-// designed to only have support for fast-path. It checks if more
-// complex handling is needed (such as a pageheap allocation or
-// sampling) and only performs allocation if none of those uncommon
-// conditions hold. When we have one of those odd cases it simply
-// tail-calls to one of tcmalloc::allocate_full_XXX defined above.
-//
-// Such approach was found to be quite effective. Generated code for
-// tc_{new,malloc} either succeeds quickly or tail-calls to
-// allocate_full. Terseness of the source and lack of
-// non-tail calls enables compiler to produce better code. Also
-// produced code is short enough to enable effort-less human
-// comprehension. Which itself led to elimination of various checks
-// that were not necessary for fast-path.
-template <void* OOMHandler(size_t)>
-ATTRIBUTE_ALWAYS_INLINE inline
-static void * malloc_fast_path(size_t size) {
-  if (PREDICT_FALSE(!base::internal::new_hooks_.empty())) {
-    return tcmalloc::dispatch_allocate_full<OOMHandler>(size);
-  }
-
-  ThreadCache *cache = ThreadCache::GetFastPathCache();
-
-  if (PREDICT_FALSE(cache == NULL)) {
-    return tcmalloc::dispatch_allocate_full<OOMHandler>(size);
-  }
-
-  uint32 cl;
-  if (PREDICT_FALSE(!Static::sizemap()->GetSizeClass(size, &cl))) {
-    return tcmalloc::dispatch_allocate_full<OOMHandler>(size);
-  }
-
-  size_t allocated_size = Static::sizemap()->ByteSizeForClass(cl);
-
-  if (PREDICT_FALSE(!cache->TryRecordAllocationFast(allocated_size))) {
-    return tcmalloc::dispatch_allocate_full<OOMHandler>(size);
-  }
-
-  return CheckedMallocResult(cache->Allocate(allocated_size, cl, OOMHandler));
-}
-
-template <void* OOMHandler(size_t)>
-ATTRIBUTE_ALWAYS_INLINE inline
-static void* memalign_fast_path(size_t align, size_t size) {
-  if (PREDICT_FALSE(align > kPageSize)) {
-    if (OOMHandler == tcmalloc::cpp_throw_oom) {
-      return tcmalloc::memalign_pages(align, size, true, false);
-    } else if (OOMHandler == tcmalloc::cpp_nothrow_oom) {
-      return tcmalloc::memalign_pages(align, size, true, true);
-    } else {
-      ASSERT(OOMHandler == tcmalloc::malloc_oom);
-      return tcmalloc::memalign_pages(align, size, false, true);
-    }
-  }
-
-  // Everything with alignment <= kPageSize we can easily delegate to
-  // regular malloc
-
-  return malloc_fast_path<OOMHandler>(align_size_up(size, align));
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void* tc_malloc(size_t size) PERFTOOLS_NOTHROW {
-  return malloc_fast_path<tcmalloc::malloc_oom>(size);
-}
-
-static ATTRIBUTE_ALWAYS_INLINE inline
-void free_fast_path(void *ptr) {
-  if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
-    tcmalloc::invoke_hooks_and_free(ptr);
-    return;
-  }
-  do_free(ptr);
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void tc_free(void* ptr) PERFTOOLS_NOTHROW {
-  free_fast_path(ptr);
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW {
-  if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
-    tcmalloc::invoke_hooks_and_free(ptr);
-    return;
-  }
-#ifndef NO_TCMALLOC_SAMPLES
-  // if ptr is kPageSize-aligned, then it could be sampled allocation,
-  // thus we don't trust hint and just do plain free. It also handles
-  // nullptr for us.
-  if (PREDICT_FALSE((reinterpret_cast<uintptr_t>(ptr) & (kPageSize-1)) == 0)) {
-    tc_free(ptr);
-    return;
-  }
-#else
-  if (!ptr) {
-    return;
-  }
-#endif
-  do_free_with_callback(ptr, &InvalidFree, true, size);
-}
-
-#ifdef TC_ALIAS
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void *p, size_t size) PERFTOOLS_NOTHROW
-  TC_ALIAS(tc_free_sized);
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void *p, size_t size) PERFTOOLS_NOTHROW
-  TC_ALIAS(tc_free_sized);
-
-#else
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void *p, size_t size) PERFTOOLS_NOTHROW {
-  tc_free_sized(p, size);
-}
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void *p, size_t size) PERFTOOLS_NOTHROW {
-  tc_free_sized(p, size);
-}
-
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_calloc(size_t n,
-                                              size_t elem_size) PERFTOOLS_NOTHROW {
-  if (ThreadCache::IsUseEmergencyMalloc()) {
-    return tcmalloc::EmergencyCalloc(n, elem_size);
-  }
-  void* result = do_calloc(n, elem_size);
-  MallocHook::InvokeNewHook(result, n * elem_size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_free);
-#else
-{
-  free_fast_path(ptr);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_realloc(void* old_ptr,
-                                               size_t new_size) PERFTOOLS_NOTHROW {
-  if (old_ptr == NULL) {
-    void* result = do_malloc_or_cpp_alloc(new_size);
-    MallocHook::InvokeNewHook(result, new_size);
-    return result;
-  }
-  if (new_size == 0) {
-    MallocHook::InvokeDeleteHook(old_ptr);
-    do_free(old_ptr);
-    return NULL;
-  }
-  if (PREDICT_FALSE(tcmalloc::IsEmergencyPtr(old_ptr))) {
-    return tcmalloc::EmergencyRealloc(old_ptr, new_size);
-  }
-  return do_realloc(old_ptr, new_size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void* tc_new(size_t size) {
-  return malloc_fast_path<tcmalloc::cpp_throw_oom>(size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void* tc_new_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  return malloc_fast_path<tcmalloc::cpp_nothrow_oom>(size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_free);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-// Standard C++ library implementations define and use this
-// (via ::operator delete(ptr, nothrow)).
-// But it's really the same as normal delete, so we just do the same thing.
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_free);
-#else
-{
-  if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
-    tcmalloc::invoke_hooks_and_free(p);
-    return;
-  }
-  do_free(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size)
-#ifdef TC_ALIAS
-TC_ALIAS(tc_new);
-#else
-{
-  return malloc_fast_path<tcmalloc::cpp_throw_oom>(size);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::nothrow_t&)
-    PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_new_nothrow);
-#else
-{
-  return malloc_fast_path<tcmalloc::cpp_nothrow_oom>(size);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_free);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete_nothrow);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void* tc_memalign(size_t align, size_t size) PERFTOOLS_NOTHROW {
-  return memalign_fast_path<tcmalloc::malloc_oom>(align, size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL int tc_posix_memalign(
-    void** result_ptr, size_t align, size_t size) PERFTOOLS_NOTHROW {
-  if (((align % sizeof(void*)) != 0) ||
-      ((align & (align - 1)) != 0) ||
-      (align == 0)) {
-    return EINVAL;
-  }
-
-  void* result = tc_memalign(align, size);
-  if (PREDICT_FALSE(result == NULL)) {
-    return ENOMEM;
-  } else {
-    *result_ptr = result;
-    return 0;
-  }
-}
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t align) {
-  return memalign_fast_path<tcmalloc::cpp_throw_oom>(static_cast<size_t>(align), size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t align, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  return memalign_fast_path<tcmalloc::cpp_nothrow_oom>(static_cast<size_t>(align), size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-// There is no easy way to obtain the actual size used by do_memalign to allocate aligned storage, so for now
-// just ignore the size. It might get useful in the future.
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t align) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t align)
-#ifdef TC_ALIAS
-TC_ALIAS(tc_new_aligned);
-#else
-{
-  return memalign_fast_path<tcmalloc::cpp_throw_oom>(static_cast<size_t>(align), size);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t align, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_new_aligned_nothrow);
-#else
-{
-  return memalign_fast_path<tcmalloc::cpp_nothrow_oom>(static_cast<size_t>(align), size);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete_aligned);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-// There is no easy way to obtain the actual size used by do_memalign to allocate aligned storage, so for now
-// just ignore the size. It might get useful in the future.
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t align) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete_sized_aligned);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete_aligned_nothrow);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-static size_t pagesize = 0;
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_valloc(size_t size) PERFTOOLS_NOTHROW {
-  // Allocate page-aligned object of length >= size bytes
-  if (pagesize == 0) pagesize = getpagesize();
-  return tc_memalign(pagesize, size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t size) PERFTOOLS_NOTHROW {
-  // Round up size to a multiple of pagesize
-  if (pagesize == 0) pagesize = getpagesize();
-  if (size == 0) {     // pvalloc(0) should allocate one page, according to
-    size = pagesize;   // http://man.free4web.biz/man3/libmpatrol.3.html
-  }
-  size = (size + pagesize - 1) & ~(pagesize - 1);
-  return tc_memalign(pagesize, size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW {
-  do_malloc_stats();
-}
-
-extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW {
-  return do_mallopt(cmd, value);
-}
-
-#ifdef HAVE_STRUCT_MALLINFO
-extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW {
-  return do_mallinfo();
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW {
-  return MallocExtension::instance()->GetAllocatedSize(ptr);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size)  PERFTOOLS_NOTHROW {
-  void* result = do_malloc(size);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-#endif  // TCMALLOC_USING_DEBUGALLOCATION
diff --git a/third_party/tcmalloc/chromium/src/tcmalloc.h b/third_party/tcmalloc/chromium/src/tcmalloc.h
deleted file mode 100644
index 25cf982..0000000
--- a/third_party/tcmalloc/chromium/src/tcmalloc.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Some obscure memory-allocation routines may not be declared on all
-// systems.  In those cases, we'll just declare them ourselves.
-// This file is meant to be used only internally, for unittests.
-
-#include <config.h>
-
-#ifndef _XOPEN_SOURCE
-# define _XOPEN_SOURCE 600  // for posix_memalign
-#endif
-#include <stdlib.h>         // for posix_memalign
-// FreeBSD has malloc.h, but complains if you use it
-#if defined(HAVE_MALLOC_H) && !defined(__FreeBSD__)
-#include <malloc.h>         // for memalign, valloc, pvalloc
-#endif
-
-// __THROW is defined in glibc systems.  It means, counter-intuitively,
-// "This function will never throw an exception."  It's an optional
-// optimization tool, but we may need to use it to match glibc prototypes.
-#ifndef __THROW    // I guess we're not on a glibc system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-#if !HAVE_CFREE_SYMBOL
-extern "C" void cfree(void* ptr) __THROW;
-#endif
-#if !HAVE_DECL_POSIX_MEMALIGN
-extern "C" int posix_memalign(void** ptr, size_t align, size_t size) __THROW;
-#endif
-#if !HAVE_DECL_MEMALIGN
-extern "C" void* memalign(size_t __alignment, size_t __size) __THROW;
-#endif
-#if !HAVE_DECL_VALLOC
-extern "C" void* valloc(size_t __size) __THROW;
-#endif
-#if !HAVE_DECL_PVALLOC
-extern "C" void* pvalloc(size_t __size) __THROW;
-#endif
diff --git a/third_party/tcmalloc/chromium/src/tcmalloc_guard.h b/third_party/tcmalloc/chromium/src/tcmalloc_guard.h
deleted file mode 100644
index 84952ba..0000000
--- a/third_party/tcmalloc/chromium/src/tcmalloc_guard.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// We expose the TCMallocGuard class -- which initializes the tcmalloc
-// allocator -- so classes that need to be sure tcmalloc is loaded
-// before they do stuff -- notably heap-profiler -- can.  To use this
-// create a static TCMallocGuard instance at the top of a file where
-// you need tcmalloc to be initialized before global constructors run.
-
-#ifndef TCMALLOC_TCMALLOC_GUARD_H_
-#define TCMALLOC_TCMALLOC_GUARD_H_
-
-class TCMallocGuard {
- public:
-  TCMallocGuard();
-  ~TCMallocGuard();
-};
-
-#endif  // TCMALLOC_TCMALLOC_GUARD_H_
diff --git a/third_party/tcmalloc/chromium/src/tests/addressmap_unittest.cc b/third_party/tcmalloc/chromium/src/tests/addressmap_unittest.cc
deleted file mode 100644
index a847dd6f..0000000
--- a/third_party/tcmalloc/chromium/src/tests/addressmap_unittest.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-
-#include <stdlib.h>   // for rand()
-#include <vector>
-#include <set>
-#include <algorithm>
-#include <utility>
-#include "addressmap-inl.h"
-#include "base/logging.h"
-#include "base/commandlineflags.h"
-
-DEFINE_int32(iters, 20, "Number of test iterations");
-DEFINE_int32(N, 100000,  "Number of elements to test per iteration");
-
-using std::pair;
-using std::make_pair;
-using std::vector;
-using std::set;
-using std::random_shuffle;
-
-struct UniformRandomNumberGenerator {
-  size_t Uniform(size_t max_size) {
-    if (max_size == 0)
-      return 0;
-    return rand() % max_size;   // not a great random-number fn, but portable
-  }
-};
-static UniformRandomNumberGenerator rnd;
-
-
-// pair of associated value and object size
-typedef pair<int, size_t> ValueT;
-
-struct PtrAndSize {
-  char* ptr;
-  size_t size;
-  PtrAndSize(char* p, size_t s) : ptr(p), size(s) {}
-};
-
-size_t SizeFunc(const ValueT& v) { return v.second; }
-
-static void SetCheckCallback(const void* ptr, ValueT* val,
-                             set<pair<const void*, int> >* check_set) {
-  check_set->insert(make_pair(ptr, val->first));
-}
-
-int main(int argc, char** argv) {
-  // Get a bunch of pointers
-  const int N = FLAGS_N;
-  static const int kMaxRealSize = 49;
-  // 100Mb to stress not finding previous object (AddressMap's cluster is 1Mb):
-  static const size_t kMaxSize = 100*1000*1000;
-  vector<PtrAndSize> ptrs_and_sizes;
-  for (int i = 0; i < N; ++i) {
-    size_t s = rnd.Uniform(kMaxRealSize);
-    ptrs_and_sizes.push_back(PtrAndSize(new char[s], s));
-  }
-
-  for (int x = 0; x < FLAGS_iters; ++x) {
-    RAW_LOG(INFO, "Iteration %d/%d...\n", x, FLAGS_iters);
-
-    // Permute pointers to get rid of allocation order issues
-    random_shuffle(ptrs_and_sizes.begin(), ptrs_and_sizes.end());
-
-    AddressMap<ValueT> map(malloc, free);
-    const ValueT* result;
-    const void* res_p;
-
-    // Insert a bunch of entries
-    for (int i = 0; i < N; ++i) {
-      char* p = ptrs_and_sizes[i].ptr;
-      CHECK(!map.Find(p));
-      int offs = rnd.Uniform(ptrs_and_sizes[i].size);
-      CHECK(!map.FindInside(&SizeFunc, kMaxSize, p + offs, &res_p));
-      map.Insert(p, make_pair(i, ptrs_and_sizes[i].size));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i);
-      CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));
-      CHECK_EQ(res_p, p);
-      CHECK_EQ(result->first, i);
-      map.Insert(p, make_pair(i + N, ptrs_and_sizes[i].size));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + N);
-    }
-
-    // Delete the even entries
-    for (int i = 0; i < N; i += 2) {
-      void* p = ptrs_and_sizes[i].ptr;
-      ValueT removed;
-      CHECK(map.FindAndRemove(p, &removed));
-      CHECK_EQ(removed.first, i + N);
-    }
-
-    // Lookup the odd entries and adjust them
-    for (int i = 1; i < N; i += 2) {
-      char* p = ptrs_and_sizes[i].ptr;
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + N);
-      int offs = rnd.Uniform(ptrs_and_sizes[i].size);
-      CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));
-      CHECK_EQ(res_p, p);
-      CHECK_EQ(result->first, i + N);
-      map.Insert(p, make_pair(i + 2*N, ptrs_and_sizes[i].size));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + 2*N);
-    }
-
-    // Insert even entries back
-    for (int i = 0; i < N; i += 2) {
-      char* p = ptrs_and_sizes[i].ptr;
-      int offs = rnd.Uniform(ptrs_and_sizes[i].size);
-      CHECK(!map.FindInside(&SizeFunc, kMaxSize, p + offs, &res_p));
-      map.Insert(p, make_pair(i + 2*N, ptrs_and_sizes[i].size));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + 2*N);
-      CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));
-      CHECK_EQ(res_p, p);
-      CHECK_EQ(result->first, i + 2*N);
-    }
-
-    // Check all entries
-    set<pair<const void*, int> > check_set;
-    map.Iterate(SetCheckCallback, &check_set);
-    CHECK_EQ(check_set.size(), N);
-    for (int i = 0; i < N; ++i) {
-      void* p = ptrs_and_sizes[i].ptr;
-      check_set.erase(make_pair(p, i + 2*N));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + 2*N);
-    }
-    CHECK_EQ(check_set.size(), 0);
-  }
-
-  for (int i = 0; i < N; ++i) {
-    delete[] ptrs_and_sizes[i].ptr;
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/atomicops_unittest.cc b/third_party/tcmalloc/chromium/src/tests/atomicops_unittest.cc
deleted file mode 100644
index 76aae2e..0000000
--- a/third_party/tcmalloc/chromium/src/tests/atomicops_unittest.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-#include <stdio.h>
-#include "base/logging.h"
-#include "base/atomicops.h"
-
-#define GG_ULONGLONG(x)  static_cast<uint64>(x)
-
-
-#define NUM_BITS(T) (sizeof(T) * 8)
-
-
-template <class AtomicType>
-static void TestCompareAndSwap(AtomicType (*compare_and_swap_func)
-                               (volatile AtomicType*, AtomicType, AtomicType)) {
-  AtomicType value = 0;
-  AtomicType prev = (*compare_and_swap_func)(&value, 0, 1);
-  ASSERT_EQ(1, value);
-  ASSERT_EQ(0, prev);
-
-  // Use test value that has non-zero bits in both halves, more for testing
-  // 64-bit implementation on 32-bit platforms.
-  const AtomicType k_test_val = (GG_ULONGLONG(1) <<
-                                 (NUM_BITS(AtomicType) - 2)) + 11;
-  value = k_test_val;
-  prev = (*compare_and_swap_func)(&value, 0, 5);
-  ASSERT_EQ(k_test_val, value);
-  ASSERT_EQ(k_test_val, prev);
-
-  value = k_test_val;
-  prev = (*compare_and_swap_func)(&value, k_test_val, 5);
-  ASSERT_EQ(5, value);
-  ASSERT_EQ(k_test_val, prev);
-}
-
-
-template <class AtomicType>
-static void TestAtomicExchange(AtomicType (*atomic_exchange_func)
-                               (volatile AtomicType*, AtomicType)) {
-  AtomicType value = 0;
-  AtomicType new_value = (*atomic_exchange_func)(&value, 1);
-  ASSERT_EQ(1, value);
-  ASSERT_EQ(0, new_value);
-
-  // Use test value that has non-zero bits in both halves, more for testing
-  // 64-bit implementation on 32-bit platforms.
-  const AtomicType k_test_val = (GG_ULONGLONG(1) <<
-                                 (NUM_BITS(AtomicType) - 2)) + 11;
-  value = k_test_val;
-  new_value = (*atomic_exchange_func)(&value, k_test_val);
-  ASSERT_EQ(k_test_val, value);
-  ASSERT_EQ(k_test_val, new_value);
-
-  value = k_test_val;
-  new_value = (*atomic_exchange_func)(&value, 5);
-  ASSERT_EQ(5, value);
-  ASSERT_EQ(k_test_val, new_value);
-}
-
-
-// This is a simple sanity check that values are correct. Not testing
-// atomicity
-template <class AtomicType>
-static void TestStore() {
-  const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL);
-  const AtomicType kVal2 = static_cast<AtomicType>(-1);
-
-  AtomicType value;
-
-  base::subtle::NoBarrier_Store(&value, kVal1);
-  ASSERT_EQ(kVal1, value);
-  base::subtle::NoBarrier_Store(&value, kVal2);
-  ASSERT_EQ(kVal2, value);
-
-  base::subtle::Release_Store(&value, kVal1);
-  ASSERT_EQ(kVal1, value);
-  base::subtle::Release_Store(&value, kVal2);
-  ASSERT_EQ(kVal2, value);
-}
-
-// This is a simple sanity check that values are correct. Not testing
-// atomicity
-template <class AtomicType>
-static void TestLoad() {
-  const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL);
-  const AtomicType kVal2 = static_cast<AtomicType>(-1);
-
-  AtomicType value;
-
-  value = kVal1;
-  ASSERT_EQ(kVal1, base::subtle::NoBarrier_Load(&value));
-  value = kVal2;
-  ASSERT_EQ(kVal2, base::subtle::NoBarrier_Load(&value));
-
-  value = kVal1;
-  ASSERT_EQ(kVal1, base::subtle::Acquire_Load(&value));
-  value = kVal2;
-  ASSERT_EQ(kVal2, base::subtle::Acquire_Load(&value));
-}
-
-template <class AtomicType>
-static void TestAtomicOps() {
-  TestCompareAndSwap<AtomicType>(base::subtle::NoBarrier_CompareAndSwap);
-  TestCompareAndSwap<AtomicType>(base::subtle::Acquire_CompareAndSwap);
-  TestCompareAndSwap<AtomicType>(base::subtle::Release_CompareAndSwap);
-
-  TestAtomicExchange<AtomicType>(base::subtle::NoBarrier_AtomicExchange);
-  TestAtomicExchange<AtomicType>(base::subtle::Acquire_AtomicExchange);
-  TestAtomicExchange<AtomicType>(base::subtle::Release_AtomicExchange);
-
-  TestStore<AtomicType>();
-  TestLoad<AtomicType>();
-}
-
-int main(int argc, char** argv) {
-  TestAtomicOps<AtomicWord>();
-  TestAtomicOps<Atomic32>();
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/current_allocated_bytes_test.cc b/third_party/tcmalloc/chromium/src/tests/current_allocated_bytes_test.cc
deleted file mode 100644
index 49b7dc3..0000000
--- a/third_party/tcmalloc/chromium/src/tests/current_allocated_bytes_test.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// ---
-//
-// Author: Craig Silverstein
-
-// This tests the accounting done by tcmalloc.  When we allocate and
-// free a small buffer, the number of bytes used by the application
-// before the alloc+free should match the number of bytes used after.
-// However, the internal data structures used by tcmalloc will be
-// quite different -- new spans will have been allocated, etc.  This
-// is, thus, a simple test that we account properly for the internal
-// data structures, so that we report the actual application-used
-// bytes properly.
-
-#include "config_for_unittests.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <gperftools/malloc_extension.h>
-#include "base/logging.h"
-
-int main() {
-  // We don't do accounting right when using debugallocation.cc, so
-  // turn off the test then.  TODO(csilvers): get this working too.
-#ifdef NDEBUG
-  static const char kCurrent[] = "generic.current_allocated_bytes";
-
-  size_t before_bytes, after_bytes;
-  MallocExtension::instance()->GetNumericProperty(kCurrent, &before_bytes);
-  free(malloc(200));
-  MallocExtension::instance()->GetNumericProperty(kCurrent, &after_bytes);
-
-  CHECK_EQ(before_bytes, after_bytes);
-#endif
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/debugallocation_test.cc b/third_party/tcmalloc/chromium/src/tests/debugallocation_test.cc
deleted file mode 100644
index d935dbb1..0000000
--- a/third_party/tcmalloc/chromium/src/tests/debugallocation_test.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Fred Akalin
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h> // for memcmp
-#include <vector>
-#include "gperftools/malloc_extension.h"
-#include "gperftools/tcmalloc.h"
-#include "base/logging.h"
-
-using std::vector;
-
-vector<void (*)()> g_testlist;  // the tests to run
-
-#define TEST(a, b)                                      \
-  struct Test_##a##_##b {                               \
-    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
-    static void Run();                                  \
-  };                                                    \
-  static Test_##a##_##b g_test_##a##_##b;               \
-  void Test_##a##_##b::Run()
-
-
-static int RUN_ALL_TESTS() {
-  vector<void (*)()>::const_iterator it;
-  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
-    (*it)();   // The test will error-exit if there's a problem.
-  }
-  fprintf(stderr, "\nPassed %d tests\n\nPASS\n",
-          static_cast<int>(g_testlist.size()));
-  return 0;
-}
-
-// The death tests are meant to be run from a shell-script driver, which
-// passes in an integer saying which death test to run.  We store that
-// test-to-run here, and in the macro use a counter to see when we get
-// to that test, so we can run it.
-static int test_to_run = 0;     // set in main() based on argv
-static int test_counter = 0;    // incremented every time the macro is called
-#define IF_DEBUG_EXPECT_DEATH(statement, regex) do {    \
-  if (test_counter++ == test_to_run) {                  \
-    fprintf(stderr, "Expected regex:%s\n", regex);      \
-    statement;                                          \
-  }                                                     \
-} while (false)
-
-// This flag won't be compiled in in opt mode.
-DECLARE_int32(max_free_queue_size);
-
-// Test match as well as mismatch rules.  But do not test on OS X; on
-// OS X the OS converts new/new[] to malloc before it gets to us, so
-// we are unable to catch these mismatch errors.
-#ifndef __APPLE__
-TEST(DebugAllocationTest, DeallocMismatch) {
-  // malloc can be matched only by free
-  // new can be matched only by delete and delete(nothrow)
-  // new[] can be matched only by delete[] and delete[](nothrow)
-  // new(nothrow) can be matched only by delete and delete(nothrow)
-  // new(nothrow)[] can be matched only by delete[] and delete[](nothrow)
-
-  // Allocate with malloc.
-  {
-    int* x = static_cast<int*>(malloc(sizeof(*x)));
-    IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete");
-    IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]");
-    // Should work fine.
-    free(x);
-  }
-
-  // Allocate with new.
-  {
-    int* x = new int;
-    int* y = new int;
-    IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
-    IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]");
-    delete x;
-    ::operator delete(y, std::nothrow);
-  }
-
-  // Allocate with new[].
-  {
-    int* x = new int[1];
-    int* y = new int[1];
-    IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
-    IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete");
-    delete [] x;
-    ::operator delete[](y, std::nothrow);
-  }
-
-  // Allocate with new(nothrow).
-  {
-    int* x = new(std::nothrow) int;
-    int* y = new(std::nothrow) int;
-    IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
-    IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]");
-    delete x;
-    ::operator delete(y, std::nothrow);
-  }
-
-  // Allocate with new(nothrow)[].
-  {
-    int* x = new(std::nothrow) int[1];
-    int* y = new(std::nothrow) int[1];
-    IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
-    IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete");
-    delete [] x;
-    ::operator delete[](y, std::nothrow);
-  }
-}
-#endif  // #ifdef OS_MACOSX
-
-TEST(DebugAllocationTest, DoubleFree) {
-  int* pint = new int;
-  delete pint;
-  IF_DEBUG_EXPECT_DEATH(delete pint, "has been already deallocated");
-}
-
-TEST(DebugAllocationTest, StompBefore) {
-  int* pint = new int;
-#ifndef NDEBUG   // don't stomp memory if we're not in a position to detect it
-  pint[-1] = 5;
-  IF_DEBUG_EXPECT_DEATH(delete pint, "a word before object");
-#endif
-}
-
-TEST(DebugAllocationTest, StompAfter) {
-  int* pint = new int;
-#ifndef NDEBUG   // don't stomp memory if we're not in a position to detect it
-  pint[1] = 5;
-  IF_DEBUG_EXPECT_DEATH(delete pint, "a word after object");
-#endif
-}
-
-TEST(DebugAllocationTest, FreeQueueTest) {
-  // Verify that the allocator doesn't return blocks that were recently freed.
-  int* x = new int;
-  int* old_x = x;
-  delete x;
-  x = new int;
-  #if 1
-    // This check should not be read as a universal guarantee of behavior.  If
-    // other threads are executing, it would be theoretically possible for this
-    // check to fail despite the efforts of debugallocation.cc to the contrary.
-    // It should always hold under the controlled conditions of this unittest,
-    // however.
-    EXPECT_NE(x, old_x);  // Allocator shouldn't return recently freed blocks
-  #else
-    // The below check passes, but since it isn't *required* to pass, I've left
-    // it commented out.
-    // EXPECT_EQ(x, old_x);
-  #endif
-  old_x = NULL;  // avoid breaking opt build with an unused variable warning.
-  delete x;
-}
-
-TEST(DebugAllocationTest, DanglingPointerWriteTest) {
-  // This test can only be run if debugging.
-  //
-  // If not debugging, the 'new' following the dangling write might not be
-  // safe.  When debugging, we expect the (trashed) deleted block to be on the
-  // list of recently-freed blocks, so the following 'new' will be safe.
-#if 1
-  int* x = new int;
-  delete x;
-  int poisoned_x_value = *x;
-  *x = 1;  // a dangling write.
-
-  char* s = new char[FLAGS_max_free_queue_size];
-  // When we delete s, we push the storage that was previously allocated to x
-  // off the end of the free queue.  At that point, the write to that memory
-  // will be detected.
-  IF_DEBUG_EXPECT_DEATH(delete [] s, "Memory was written to after being freed.");
-
-  // restore the poisoned value of x so that we can delete s without causing a
-  // crash.
-  *x = poisoned_x_value;
-  delete [] s;
-#endif
-}
-
-TEST(DebugAllocationTest, DanglingWriteAtExitTest) {
-  int *x = new int;
-  delete x;
-  int old_x_value = *x;
-  *x = 1;
-  // verify that dangling writes are caught at program termination if the
-  // corrupted block never got pushed off of the end of the free queue.
-  IF_DEBUG_EXPECT_DEATH(exit(0), "Memory was written to after being freed.");
-  *x = old_x_value;  // restore x so that the test can exit successfully.
-}
-
-TEST(DebugAllocationTest, StackTraceWithDanglingWriteAtExitTest) {
-  int *x = new int;
-  delete x;
-  int old_x_value = *x;
-  *x = 1;
-  // verify that we also get a stack trace when we have a dangling write.
-  // The " @ " is part of the stack trace output.
-  IF_DEBUG_EXPECT_DEATH(exit(0), " @ .*main");
-  *x = old_x_value;  // restore x so that the test can exit successfully.
-}
-
-static size_t CurrentlyAllocatedBytes() {
-  size_t value;
-  CHECK(MallocExtension::instance()->GetNumericProperty(
-            "generic.current_allocated_bytes", &value));
-  return value;
-}
-
-TEST(DebugAllocationTest, CurrentlyAllocated) {
-  // Clear the free queue
-#if 1
-  FLAGS_max_free_queue_size = 0;
-  // Force a round-trip through the queue management code so that the
-  // new size is seen and the queue of recently-freed blocks is flushed.
-  free(malloc(1));
-  FLAGS_max_free_queue_size = 1048576;
-#endif
-
-  // Free something and check that it disappears from allocated bytes
-  // immediately.
-  char* p = new char[1000];
-  size_t after_malloc = CurrentlyAllocatedBytes();
-  delete[] p;
-  size_t after_free = CurrentlyAllocatedBytes();
-  EXPECT_LE(after_free, after_malloc - 1000);
-}
-
-TEST(DebugAllocationTest, GetAllocatedSizeTest) {
-#if 1
-  // When debug_allocation is in effect, GetAllocatedSize should return
-  // exactly requested size, since debug_allocation doesn't allow users
-  // to write more than that.
-  for (int i = 0; i < 10; ++i) {
-    void *p = malloc(i);
-    EXPECT_EQ(i, MallocExtension::instance()->GetAllocatedSize(p));
-    free(p);
-  }
-#endif
-  void* a = malloc(1000);
-  EXPECT_GE(MallocExtension::instance()->GetAllocatedSize(a), 1000);
-  // This is just a sanity check.  If we allocated too much, alloc is broken
-  EXPECT_LE(MallocExtension::instance()->GetAllocatedSize(a), 5000);
-  EXPECT_GE(MallocExtension::instance()->GetEstimatedAllocatedSize(1000), 1000);
-  free(a);
-}
-
-TEST(DebugAllocationTest, HugeAlloc) {
-  // This must not be a const variable so it doesn't form an
-  // integral-constant-expression which can be *statically* rejected by the
-  // compiler as too large for the allocation.
-  size_t kTooBig = ~static_cast<size_t>(0);
-  void* a = NULL;
-
-#ifndef NDEBUG
-
-  a = malloc(kTooBig);
-  EXPECT_EQ(NULL, a);
-
-  // kAlsoTooBig is small enough not to get caught by debugallocation's check,
-  // but will still fall through to tcmalloc's check. This must also be
-  // a non-const variable. See kTooBig for more details.
-  size_t kAlsoTooBig = kTooBig - 1024;
-
-  a = malloc(kAlsoTooBig);
-  EXPECT_EQ(NULL, a);
-#endif
-}
-
-// based on test program contributed by mikesart@gmail.com aka
-// mikesart@valvesoftware.com. See issue-464.
-TEST(DebugAllocationTest, ReallocAfterMemalign) {
-  char stuff[50];
-  memset(stuff, 0x11, sizeof(stuff));
-  void *p = tc_memalign(16, sizeof(stuff));
-  EXPECT_NE(p, NULL);
-  memcpy(stuff, p, sizeof(stuff));
-
-  p = realloc(p, sizeof(stuff) + 10);
-  EXPECT_NE(p, NULL);
-
-  int rv = memcmp(stuff, p, sizeof(stuff));
-  EXPECT_EQ(rv, 0);
-}
-
-int main(int argc, char** argv) {
-  // If you run without args, we run the non-death parts of the test.
-  // Otherwise, argv[1] should be a number saying which death-test
-  // to run.  We will output a regexp we expect the death-message
-  // to include, and then run the given death test (which hopefully
-  // will produce that error message).  If argv[1] > the number of
-  // death tests, we will run only the non-death parts.  One way to
-  // tell when you are done with all tests is when no 'expected
-  // regexp' message is printed for a given argv[1].
-  if (argc < 2) {
-    test_to_run = -1;   // will never match
-  } else {
-    test_to_run = atoi(argv[1]);
-  }
-  return RUN_ALL_TESTS();
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/debugallocation_test.sh b/third_party/tcmalloc/chromium/src/tests/debugallocation_test.sh
deleted file mode 100755
index 0f94ad0..0000000
--- a/third_party/tcmalloc/chromium/src/tests/debugallocation_test.sh
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2009, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# ---
-# Author: Craig Silverstein
-
-BINDIR="${BINDIR:-.}"
-# We expect PPROF_PATH to be set in the environment.
-# If not, we set it to some reasonable value
-export PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir]"
-  echo "       By default, unittest_dir=$BINDIR"
-  exit 1
-fi
-
-DEBUGALLOCATION_TEST="${1:-$BINDIR/debugallocation_test}"
-
-num_failures=0
-
-# Run the i-th death test and make sure the test has the expected
-# regexp.  We can depend on the first line of the output being
-#    Expected regex:<regex>
-# Evaluates to "done" if we are not actually a death-test (so $1 is
-# too big a number, and we can stop).  Evaluates to "" otherwise.
-# Increments num_failures if the death test does not succeed.
-OneDeathTest() {
-  "$DEBUGALLOCATION_TEST" "$1" 2>&1 | {
-    regex_line='dummy'
-    # Normally the regex_line is the first line of output, but not
-    # always (if tcmalloc itself does any logging to stderr).
-    while test -n "$regex_line"; do
-      read regex_line
-      regex=`expr "$regex_line" : "Expected regex:\(.*\)"`
-      test -n "$regex" && break   # found the regex line
-    done
-    test -z "$regex" && echo "done" || grep "$regex" 2>&1
-  }
-}
-
-death_test_num=0   # which death test to run
-while :; do        # same as 'while true', but more portable
-  echo -n "Running death test $death_test_num..."
-  output="`OneDeathTest $death_test_num`"
-  case $output in
-     # Empty string means grep didn't find anything.
-     "")      echo "FAILED"; num_failures=`expr $num_failures + 1`;;
-     "done"*) echo "done with death tests"; break;;
-     # Any other string means grep found something, like it ought to.
-     *)       echo "OK";;
-  esac
-  death_test_num=`expr $death_test_num + 1`
-done
-
-# Test the non-death parts of the test too
-echo -n "Running non-death tests..."
-if "$DEBUGALLOCATION_TEST"; then
-  echo "OK"
-else
-  echo "FAILED"
-  num_failures=`expr $num_failures + 1`
-fi
-
-if [ "$num_failures" = 0 ]; then
-  echo "PASS"
-else
-  echo "Failed with $num_failures failures"
-fi
-exit $num_failures
diff --git a/third_party/tcmalloc/chromium/src/tests/frag_unittest.cc b/third_party/tcmalloc/chromium/src/tests/frag_unittest.cc
deleted file mode 100644
index c4016f9..0000000
--- a/third_party/tcmalloc/chromium/src/tests/frag_unittest.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2003, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Test speed of handling fragmented heap
-
-#include "config_for_unittests.h"
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/time.h>           // for struct timeval
-#include <sys/resource.h>       // for getrusage
-#endif
-#ifdef _WIN32
-#include <windows.h>            // for GetTickCount()
-#endif
-#include <vector>
-#include "base/logging.h"
-#include "common.h"
-#include <gperftools/malloc_extension.h>
-
-using std::vector;
-
-int main(int argc, char** argv) {
-  // Make kAllocSize one page larger than the maximum small object size.
-  static const int kAllocSize = kMaxSize + kPageSize;
-  // Allocate 400MB in total.
-  static const int kTotalAlloc = 400 << 20;
-  static const int kAllocIterations = kTotalAlloc / kAllocSize;
-
-  // Allocate lots of objects
-  vector<char*> saved(kAllocIterations);
-  for (int i = 0; i < kAllocIterations; i++) {
-    saved[i] = new char[kAllocSize];
-  }
-
-  // Check the current "slack".
-  size_t slack_before;
-  MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
-                                                  &slack_before);
-
-  // Free alternating ones to fragment heap
-  size_t free_bytes = 0;
-  for (int i = 0; i < saved.size(); i += 2) {
-    delete[] saved[i];
-    free_bytes += kAllocSize;
-  }
-
-  // Check that slack delta is within 10% of expected.
-  size_t slack_after;
-  MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
-                                                  &slack_after);
-  CHECK_GE(slack_after, slack_before);
-  size_t slack = slack_after - slack_before;
-
-  CHECK_GT(double(slack), 0.9*free_bytes);
-  CHECK_LT(double(slack), 1.1*free_bytes);
-
-  // Dump malloc stats
-  static const int kBufSize = 1<<20;
-  char* buffer = new char[kBufSize];
-  MallocExtension::instance()->GetStats(buffer, kBufSize);
-  VLOG(1, "%s", buffer);
-  delete[] buffer;
-
-  // Now do timing tests
-  for (int i = 0; i < 5; i++) {
-    static const int kIterations = 100000;
-#ifdef HAVE_SYS_RESOURCE_H
-    struct rusage r;
-    getrusage(RUSAGE_SELF, &r);    // figure out user-time spent on this
-    struct timeval tv_start = r.ru_utime;
-#elif defined(_WIN32)
-    long long int tv_start = GetTickCount();
-#else
-# error No way to calculate time on your system
-#endif
-
-    for (int i = 0; i < kIterations; i++) {
-      size_t s;
-      MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
-                                                      &s);
-    }
-
-#ifdef HAVE_SYS_RESOURCE_H
-    getrusage(RUSAGE_SELF, &r);
-    struct timeval tv_end = r.ru_utime;
-    int64 sumsec = static_cast<int64>(tv_end.tv_sec) - tv_start.tv_sec;
-    int64 sumusec = static_cast<int64>(tv_end.tv_usec) - tv_start.tv_usec;
-#elif defined(_WIN32)
-    long long int tv_end = GetTickCount();
-    int64 sumsec = (tv_end - tv_start) / 1000;
-    // Resolution in windows is only to the millisecond, alas
-    int64 sumusec = ((tv_end - tv_start) % 1000) * 1000;
-#else
-# error No way to calculate time on your system
-#endif
-    fprintf(stderr, "getproperty: %6.1f ns/call\n",
-            (sumsec * 1e9 + sumusec * 1e3) / kIterations);
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/getpc_test.cc b/third_party/tcmalloc/chromium/src/tests/getpc_test.cc
deleted file mode 100644
index d75e40b..0000000
--- a/third_party/tcmalloc/chromium/src/tests/getpc_test.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This verifies that GetPC works correctly.  This test uses a minimum
-// of Google infrastructure, to make it very easy to port to various
-// O/Ses and CPUs and test that GetPC is working.
-
-#include "config.h"
-#include "getpc.h"        // should be first to get the _GNU_SOURCE dfn
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <sys/time.h>     // for setitimer
-
-// Needs to be volatile so compiler doesn't try to optimize it away
-static volatile void* getpc_retval = NULL;    // what GetPC returns
-static volatile bool prof_handler_called = false;
-
-static void prof_handler(int sig, siginfo_t*, void* signal_ucontext) {
-  if (!prof_handler_called)
-    getpc_retval = GetPC(*reinterpret_cast<ucontext_t*>(signal_ucontext));
-  prof_handler_called = true;  // only store the retval once
-}
-
-static void RoutineCallingTheSignal() {
-  struct sigaction sa;
-  sa.sa_sigaction = prof_handler;
-  sa.sa_flags = SA_RESTART | SA_SIGINFO;
-  sigemptyset(&sa.sa_mask);
-  if (sigaction(SIGPROF, &sa, NULL) != 0) {
-    perror("sigaction");
-    exit(1);
-  }
-
-  struct itimerval timer;
-  timer.it_interval.tv_sec = 0;
-  timer.it_interval.tv_usec = 1000;
-  timer.it_value = timer.it_interval;
-  setitimer(ITIMER_PROF, &timer, 0);
-
-  // Now we need to do some work for a while, that doesn't call any
-  // other functions, so we can be guaranteed that when the SIGPROF
-  // fires, we're the routine executing.
-  int r = 0;
-  for (int i = 0; !prof_handler_called; ++i) {
-    for (int j = 0; j < i; j++) {
-      r ^= i;
-      r <<= 1;
-      r ^= j;
-      r >>= 1;
-    }
-  }
-
-  // Now make sure the above loop doesn't get optimized out
-  srand(r);
-}
-
-// This is an upper bound of how many bytes the instructions for
-// RoutineCallingTheSignal might be.  There's probably a more
-// principled way to do this, but I don't know how portable it would be.
-// (The function is 372 bytes when compiled with -g on Mac OS X 10.4.
-// I can imagine it would be even bigger in 64-bit architectures.)
-const int kRoutineSize = 512 * sizeof(void*)/4;    // allow 1024 for 64-bit
-
-int main(int argc, char** argv) {
-  RoutineCallingTheSignal();
-
-  // Annoyingly, C++ disallows casting pointer-to-function to
-  // pointer-to-object, so we use a C-style cast instead.
-  char* expected = (char*)&RoutineCallingTheSignal;
-  char* actual = (char*)getpc_retval;
-
-  // For ia64, ppc64v1, and parisc64, the function pointer is actually
-  // a struct.  For instance, ia64's dl-fptr.h:
-  //   struct fdesc {          /* An FDESC is a function descriptor.  */
-  //      ElfW(Addr) ip;      /* code entry point */
-  //      ElfW(Addr) gp;      /* global pointer */
-  //   };
-  // We want the code entry point.
-  // NOTE: ppc64 ELFv2 (Little Endian) does not have function pointers
-#if defined(__ia64) || \
-    (defined(__powerpc64__) && _CALL_ELF != 2)
-  expected = ((char**)expected)[0];         // this is "ip"
-#endif
-
-  if (actual < expected || actual > expected + kRoutineSize) {
-    printf("Test FAILED: actual PC: %p, expected PC: %p\n", actual, expected);
-    return 1;
-  } else {
-    printf("PASS\n");
-    return 0;
-  }
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/heap-checker-death_unittest.sh b/third_party/tcmalloc/chromium/src/tests/heap-checker-death_unittest.sh
deleted file mode 100755
index 69db0c9e0..0000000
--- a/third_party/tcmalloc/chromium/src/tests/heap-checker-death_unittest.sh
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/bin/sh
-# Copyright (c) 2005, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Maxim Lifantsev
-#
-# Run the heap checker unittest in a mode where it is supposed to crash and
-# return an error if it doesn't.
-
-# We expect BINDIR to be set in the environment.
-# If not, we set it to some reasonable value.
-BINDIR="${BINDIR:-.}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir]"
-  echo "       By default, unittest_dir=$BINDIR"
-  exit 1
-fi
-
-EXE="${1:-$BINDIR/heap-checker_unittest}"
-TMPDIR="/tmp/heap_check_death_info"
-
-ALARM() {
-  # You need perl to run pprof, so I assume it's installed
-  perl -e '
-    $timeout=$ARGV[0]; shift;
-    $retval = 255;   # the default retval, for the case where we timed out
-    eval {           # need to run in an eval-block to trigger during system()
-      local $SIG{ALRM} = sub { die "alarm\n" };  # \n is required!
-      alarm $timeout;
-      $retval = system(@ARGV);
-      # Make retval bash-style: exit status, or 128+n if terminated by signal n
-      $retval = ($retval & 127) ? (128 + $retval) : ($retval >> 8);
-      alarm 0;
-    };
-    exit $retval;  # return system()-retval, or 255 if system() never returned
-' "$@"
-}
-
-# $1: timeout for alarm;
-# $2: regexp of expected exit code(s);
-# $3: regexp to match a line in the output;
-# $4: regexp to not match a line in the output;
-# $5+ args to pass to $EXE
-Test() {
-  # Note: make sure these varnames don't conflict with any vars outside Test()!
-  timeout="$1"
-  shift
-  expected_ec="$1"
-  shift
-  expected_regexp="$1"
-  shift
-  unexpected_regexp="$1"
-  shift
-
-  echo -n "Testing $EXE with $@ ... "
-  output="$TMPDIR/output"
-  ALARM $timeout env "$@" $EXE > "$output" 2>&1
-  actual_ec=$?
-  ec_ok=`expr "$actual_ec" : "$expected_ec$" >/dev/null || echo false`
-  matches_ok=`test -z "$expected_regexp" || \
-              grep "$expected_regexp" "$output" >/dev/null 2>&1 || echo false`
-  negmatches_ok=`test -z "$unexpected_regexp" || \
-                 ! grep "$unexpected_regexp" "$output" >/dev/null 2>&1 || echo false`
-  if $ec_ok && $matches_ok && $negmatches_ok; then
-    echo "PASS"
-    return 0  # 0: success
-  fi
-  # If we get here, we failed.  Now we just need to report why
-  echo "FAIL"
-  if [ $actual_ec -eq 255 ]; then  # 255 == SIGTERM due to $ALARM
-    echo "Test was taking unexpectedly long time to run and so we aborted it."
-    echo "Try the test case manually or raise the timeout from $timeout"
-    echo "to distinguish test slowness from a real problem."
-  else
-    $ec_ok || \
-      echo "Wrong exit code: expected: '$expected_ec'; actual: $actual_ec"
-    $matches_ok || \
-      echo "Output did not match '$expected_regexp'"
-    $negmatches_ok || \
-      echo "Output unexpectedly matched '$unexpected_regexp'"
-  fi
-  echo "Output from failed run:"
-  echo "---"
-  cat "$output"
-  echo "---"
-  return 1  # 1: failure
-}
-
-TMPDIR=/tmp/heap_check_death_info
-rm -rf $TMPDIR || exit 1
-mkdir $TMPDIR || exit 2
-
-export HEAPCHECK=strict       # default mode
-
-# These invocations should pass (0 == PASS):
-
-# This tests that turning leak-checker off dynamically works fine
-Test 120 0 "^PASS$" "" HEAPCHECK="" || exit 1
-
-# This disables threads so we can cause leaks reliably and test finding them
-Test 120 0 "^PASS$" "" HEAP_CHECKER_TEST_NO_THREADS=1 || exit 2
-
-# Test that --test_cancel_global_check works
-Test 20 0 "Canceling .* whole-program .* leak check$" "" \
-  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK=1 || exit 3
-Test 20 0 "Canceling .* whole-program .* leak check$" "" \
-  HEAP_CHECKER_TEST_TEST_LOOP_LEAK=1 HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK=1 || exit 4
-
-# Test that very early log messages are present and controllable:
-EARLY_MSG="Starting tracking the heap$"
-
-Test 60 0 "$EARLY_MSG" "" \
-  HEAPCHECK="" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
-  PERFTOOLS_VERBOSE=10 || exit 5
-Test 60 0 "MemoryRegionMap Init$" "" \
-  HEAPCHECK="" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
-  PERFTOOLS_VERBOSE=11 || exit 6
-Test 60 0 "" "$EARLY_MSG" \
-  HEAPCHECK="" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
-  PERFTOOLS_VERBOSE=-11 || exit 7
-
-# These invocations should fail with very high probability,
-# rather than return 0 or hang (1 == exit(1), 134 == abort(), 139 = SIGSEGV):
-
-Test 60 1 "Exiting .* because of .* leaks$" "" \
-  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 || exit 8
-Test 60 1 "Exiting .* because of .* leaks$" "" \
-  HEAP_CHECKER_TEST_TEST_LOOP_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 || exit 9
-
-# Test that we produce a reasonable textual leak report.
-Test 60 1 "MakeALeak" "" \
-          HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
-  || exit 10
-
-# Test that very early log messages are present and controllable:
-Test 60 1 "Starting tracking the heap$" "" \
-  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 PERFTOOLS_VERBOSE=10 \
-  || exit 11
-Test 60 1 "" "Starting tracking the heap" \
-  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 PERFTOOLS_VERBOSE=-10 \
-  || exit 12
-
-cd /    # so we're not in TMPDIR when we delete it
-rm -rf $TMPDIR
-
-echo "PASS"
-
-exit 0
diff --git a/third_party/tcmalloc/chromium/src/tests/heap-checker_unittest.cc b/third_party/tcmalloc/chromium/src/tests/heap-checker_unittest.cc
deleted file mode 100644
index ee60af5..0000000
--- a/third_party/tcmalloc/chromium/src/tests/heap-checker_unittest.cc
+++ /dev/null
@@ -1,1538 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Maxim Lifantsev
-//
-// Running:
-// ./heap-checker_unittest
-//
-// If the unittest crashes because it can't find pprof, try:
-// PPROF_PATH=/usr/local/someplace/bin/pprof ./heap-checker_unittest
-//
-// To test that the whole-program heap checker will actually cause a leak, try:
-// HEAPCHECK_TEST_LEAK= ./heap-checker_unittest
-// HEAPCHECK_TEST_LOOP_LEAK= ./heap-checker_unittest
-//
-// Note: Both of the above commands *should* abort with an error message.
-
-// CAVEAT: Do not use vector<> and string on-heap objects in this test,
-// otherwise the test can sometimes fail for tricky leak checks
-// when we want some allocated object not to be found live by the heap checker.
-// This can happen with memory allocators like tcmalloc that can allocate
-// heap objects back to back without any book-keeping data in between.
-// What happens is that end-of-storage pointers of a live vector
-// (or a string depending on the STL implementation used)
-// can happen to point to that other heap-allocated
-// object that is not reachable otherwise and that
-// we don't want to be reachable.
-//
-// The implication of this for real leak checking
-// is just one more chance for the liveness flood to be inexact
-// (see the comment in our .h file).
-
-#include "config_for_unittests.h"
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uint16_t (ISO naming madness)
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uint16_t might be defined
-#endif
-#include <sys/types.h>
-#include <stdlib.h>
-#include <errno.h>              // errno
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>             // for sleep(), geteuid()
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#include <fcntl.h>              // for open(), close()
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>           // backtrace
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>                // getgrent, getgrnam
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-
-#include <algorithm>
-#include <iostream>             // for cout
-#include <iomanip>              // for hex
-#include <list>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/commandlineflags.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include "base/commandlineflags.h"
-#include "base/thread_lister.h"
-#include <gperftools/heap-checker.h>
-#include "memory_region_map.h"
-#include <gperftools/malloc_extension.h>
-#include <gperftools/stacktrace.h>
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-using namespace std;
-
-// ========================================================================= //
-
-// TODO(maxim): write a shell script to test that these indeed crash us
-//              (i.e. we do detect leaks)
-//              Maybe add more such crash tests.
-
-DEFINE_bool(test_leak,
-            EnvToBool("HEAP_CHECKER_TEST_TEST_LEAK", false),
-            "If should cause a leak crash");
-DEFINE_bool(test_loop_leak,
-            EnvToBool("HEAP_CHECKER_TEST_TEST_LOOP_LEAK", false),
-            "If should cause a looped leak crash");
-DEFINE_bool(test_register_leak,
-            EnvToBool("HEAP_CHECKER_TEST_TEST_REGISTER_LEAK", false),
-            "If should cause a leak crash by hiding a pointer "
-            "that is only in a register");
-DEFINE_bool(test_cancel_global_check,
-            EnvToBool("HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK", false),
-            "If should test HeapLeakChecker::CancelGlobalCheck "
-            "when --test_leak or --test_loop_leak are given; "
-            "the test should not fail then");
-DEFINE_bool(maybe_stripped,
-            EnvToBool("HEAP_CHECKER_TEST_MAYBE_STRIPPED", true),
-            "If we think we can be a stripped binary");
-DEFINE_bool(interfering_threads,
-            EnvToBool("HEAP_CHECKER_TEST_INTERFERING_THREADS", true),
-            "If we should use threads trying "
-            "to interfere with leak checking");
-DEFINE_bool(hoarding_threads,
-            EnvToBool("HEAP_CHECKER_TEST_HOARDING_THREADS", true),
-            "If threads (usually the manager thread) are known "
-            "to retain some old state in their global buffers, "
-            "so that it's hard to force leaks when threads are around");
-            // TODO(maxim): Chage the default to false
-            // when the standard environment used NTPL threads:
-            // they do not seem to have this problem.
-DEFINE_bool(no_threads,
-            EnvToBool("HEAP_CHECKER_TEST_NO_THREADS", false),
-            "If we should not use any threads");
-            // This is used so we can make can_create_leaks_reliably true
-            // for any pthread implementation and test with that.
-
-DECLARE_int64(heap_check_max_pointer_offset);   // heap-checker.cc
-DECLARE_string(heap_check);  // in heap-checker.cc
-
-#define WARN_IF(cond, msg)   LOG_IF(WARNING, cond, msg)
-
-// This is an evil macro!  Be very careful using it...
-#undef VLOG          // and we start by evilling overriding logging.h VLOG
-#define VLOG(lvl)    if (FLAGS_verbose >= (lvl))  cout << "\n"
-// This is, likewise, evil
-#define LOGF         VLOG(INFO)
-
-static void RunHeapBusyThreads();  // below
-
-
-class Closure {
- public:
-  virtual ~Closure() { }
-  virtual void Run() = 0;
-};
-
-class Callback0 : public Closure {
- public:
-  typedef void (*FunctionSignature)();
-
-  inline Callback0(FunctionSignature f) : f_(f) {}
-  virtual void Run() { (*f_)(); delete this; }
-
- private:
-  FunctionSignature f_;
-};
-
-template <class P1> class Callback1 : public Closure {
- public:
-  typedef void (*FunctionSignature)(P1);
-
-  inline Callback1<P1>(FunctionSignature f, P1 p1) : f_(f), p1_(p1) {}
-  virtual void Run() { (*f_)(p1_); delete this; }
-
- private:
-  FunctionSignature f_;
-  P1 p1_;
-};
-
-template <class P1, class P2> class Callback2 : public Closure {
- public:
-  typedef void (*FunctionSignature)(P1,P2);
-
-  inline Callback2<P1,P2>(FunctionSignature f, P1 p1, P2 p2) : f_(f), p1_(p1), p2_(p2) {}
-  virtual void Run() { (*f_)(p1_, p2_); delete this; }
-
- private:
-  FunctionSignature f_;
-  P1 p1_;
-  P2 p2_;
-};
-
-inline Callback0* NewCallback(void (*function)()) {
-  return new Callback0(function);
-}
-
-template <class P1>
-inline Callback1<P1>* NewCallback(void (*function)(P1), P1 p1) {
-  return new Callback1<P1>(function, p1);
-}
-
-template <class P1, class P2>
-inline Callback2<P1,P2>* NewCallback(void (*function)(P1,P2), P1 p1, P2 p2) {
-  return new Callback2<P1,P2>(function, p1, p2);
-}
-
-
-// Set to true at end of main, so threads know.  Not entirely thread-safe!,
-// but probably good enough.
-static bool g_have_exited_main = false;
-
-// If we can reliably create leaks (i.e. make leaked object
-// really unreachable from any global data).
-static bool can_create_leaks_reliably = false;
-
-// We use a simple allocation wrapper
-// to make sure we wipe out the newly allocated objects
-// in case they still happened to contain some pointer data
-// accidentally left by the memory allocator.
-struct Initialized { };
-static Initialized initialized;
-void* operator new(size_t size, const Initialized&) {
-  // Below we use "p = new(initialized) Foo[1];" and  "delete[] p;"
-  // instead of "p = new(initialized) Foo;"
-  // when we need to delete an allocated object.
-  void* p = malloc(size);
-  memset(p, 0, size);
-  return p;
-}
-void* operator new[](size_t size, const Initialized&) {
-  char* p = new char[size];
-  memset(p, 0, size);
-  return p;
-}
-
-static void DoWipeStack(int n);  // defined below
-static void WipeStack() { DoWipeStack(20); }
-
-static void Pause() {
-  poll(NULL, 0, 77);  // time for thread activity in HeapBusyThreadBody
-
-  // Indirectly test malloc_extension.*:
-  CHECK(MallocExtension::instance()->VerifyAllMemory());
-  int blocks;
-  size_t total;
-  int histogram[kMallocHistogramSize];
-  if (MallocExtension::instance()
-       ->MallocMemoryStats(&blocks, &total, histogram)  &&  total != 0) {
-    VLOG(3) << "Malloc stats: " << blocks << " blocks of "
-            << total << " bytes";
-    for (int i = 0; i < kMallocHistogramSize; ++i) {
-      if (histogram[i]) {
-        VLOG(3) << "  Malloc histogram at " << i << " : " << histogram[i];
-      }
-    }
-  }
-  WipeStack();  // e.g. MallocExtension::VerifyAllMemory
-                // can leave pointers to heap objects on stack
-}
-
-// Make gcc think a pointer is "used"
-template <class T>
-static void Use(T** foo) {
-  VLOG(2) << "Dummy-using " << static_cast<void*>(*foo) << " at " << foo;
-}
-
-// Arbitrary value, but not such that xor'ing with it is likely
-// to map one valid pointer to another valid pointer:
-static const uintptr_t kHideMask =
-  static_cast<uintptr_t>(0xF03A5F7BF03A5F7BLL);
-
-// Helpers to hide a pointer from live data traversal.
-// We just xor the pointer so that (with high probability)
-// it's not a valid address of a heap object anymore.
-// Both Hide and UnHide must be executed within RunHidden() below
-// to prevent leaving stale data on active stack that can be a pointer
-// to a heap object that is not actually reachable via live variables.
-// (UnHide might leave heap pointer value for an object
-//  that will be deallocated but later another object
-//  can be allocated at the same heap address.)
-template <class T>
-static void Hide(T** ptr) {
-  // we cast values, not dereferenced pointers, so no aliasing issues:
-  *ptr = reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(*ptr) ^ kHideMask);
-  VLOG(2) << "hid: " << static_cast<void*>(*ptr);
-}
-
-template <class T>
-static void UnHide(T** ptr) {
-  VLOG(2) << "unhiding: " << static_cast<void*>(*ptr);
-  // we cast values, not dereferenced pointers, so no aliasing issues:
-  *ptr = reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(*ptr) ^ kHideMask);
-}
-
-static void LogHidden(const char* message, const void* ptr) {
-  LOGF << message << " : "
-       << ptr << " ^ " << reinterpret_cast<void*>(kHideMask) << endl;
-}
-
-// volatile to fool the compiler against inlining the calls to these
-void (*volatile run_hidden_ptr)(Closure* c, int n);
-void (*volatile wipe_stack_ptr)(int n);
-
-static void DoRunHidden(Closure* c, int n) {
-  if (n) {
-    VLOG(10) << "Level " << n << " at " << &n;
-    (*run_hidden_ptr)(c, n-1);
-    (*wipe_stack_ptr)(n);
-    sleep(0);  // undo -foptimize-sibling-calls
-  } else {
-    c->Run();
-  }
-}
-
-/*static*/ void DoWipeStack(int n) {
-  VLOG(10) << "Wipe level " << n << " at " << &n;
-  if (n) {
-    const int sz = 30;
-    volatile int arr[sz] ATTRIBUTE_UNUSED;
-    for (int i = 0; i < sz; ++i) arr[i] = 0;
-    (*wipe_stack_ptr)(n-1);
-    sleep(0);  // undo -foptimize-sibling-calls
-  }
-}
-
-// This executes closure c several stack frames down from the current one
-// and then makes an effort to also wipe out the stack data that was used by
-// the closure.
-// This way we prevent leak checker from finding any temporary pointers
-// of the closure execution on the stack and deciding that
-// these pointers (and the pointed objects) are still live.
-static void RunHidden(Closure* c) {
-  DoRunHidden(c, 15);
-  DoWipeStack(20);
-}
-
-static void DoAllocHidden(size_t size, void** ptr) {
-  void* p = new(initialized) char[size];
-  Hide(&p);
-  Use(&p);  // use only hidden versions
-  VLOG(2) << "Allocated hidden " << p << " at " << &p;
-  *ptr = p;  // assign the hidden versions
-}
-
-static void* AllocHidden(size_t size) {
-  void* r;
-  RunHidden(NewCallback(DoAllocHidden, size, &r));
-  return r;
-}
-
-static void DoDeAllocHidden(void** ptr) {
-  Use(ptr);  // use only hidden versions
-  void* p = *ptr;
-  VLOG(2) << "Deallocating hidden " << p;
-  UnHide(&p);
-  delete [] reinterpret_cast<char*>(p);
-}
-
-static void DeAllocHidden(void** ptr) {
-  RunHidden(NewCallback(DoDeAllocHidden, ptr));
-  *ptr = NULL;
-  Use(ptr);
-}
-
-void PreventHeapReclaiming(size_t size) {
-#ifdef NDEBUG
-  if (true) {
-    static void** no_reclaim_list = NULL;
-    CHECK(size >= sizeof(void*));
-    // We can't use malloc_reclaim_memory flag in opt mode as debugallocation.cc
-    // is not used. Instead we allocate a bunch of heap objects that are
-    // of the same size as what we are going to leak to ensure that the object
-    // we are about to leak is not at the same address as some old allocated
-    // and freed object that might still have pointers leading to it.
-    for (int i = 0; i < 100; ++i) {
-      void** p = reinterpret_cast<void**>(new(initialized) char[size]);
-      p[0] = no_reclaim_list;
-      no_reclaim_list = p;
-    }
-  }
-#endif
-}
-
-static bool RunSilent(HeapLeakChecker* check,
-                      bool (HeapLeakChecker::* func)()) {
-  // By default, don't print the 'we detected a leak' message in the
-  // cases we're expecting a leak (we still print when --v is >= 1).
-  // This way, the logging output is less confusing: we only print
-  // "we detected a leak", and how to diagnose it, for *unexpected* leaks.
-  int32 old_FLAGS_verbose = FLAGS_verbose;
-  if (!VLOG_IS_ON(1))             // not on a verbose setting
-    FLAGS_verbose = FATAL;        // only log fatal errors
-  const bool retval = (check->*func)();
-  FLAGS_verbose = old_FLAGS_verbose;
-  return retval;
-}
-
-#define RUN_SILENT(check, func)  RunSilent(&(check), &HeapLeakChecker::func)
-
-enum CheckType { SAME_HEAP, NO_LEAKS };
-
-static void VerifyLeaks(HeapLeakChecker* check, CheckType type,
-                        int leaked_bytes, int leaked_objects) {
-  WipeStack();  // to help with can_create_leaks_reliably
-  const bool no_leaks =
-    type == NO_LEAKS ? RUN_SILENT(*check, BriefNoLeaks)
-                     : RUN_SILENT(*check, BriefSameHeap);
-  if (can_create_leaks_reliably) {
-    // these might still fail occasionally, but it should be very rare
-    CHECK_EQ(no_leaks, false);
-    CHECK_EQ(check->BytesLeaked(), leaked_bytes);
-    CHECK_EQ(check->ObjectsLeaked(), leaked_objects);
-  } else {
-    WARN_IF(no_leaks != false,
-            "Expected leaks not found: "
-            "Some liveness flood must be too optimistic");
-  }
-}
-
-// not deallocates
-static void TestHeapLeakCheckerDeathSimple() {
-  HeapLeakChecker check("death_simple");
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  void* bar = AllocHidden(300);
-  Use(&bar);
-  LogHidden("Leaking", foo);
-  LogHidden("Leaking", bar);
-  Pause();
-  VerifyLeaks(&check, NO_LEAKS, 300 + 100 * sizeof(int), 2);
-  DeAllocHidden(&foo);
-  DeAllocHidden(&bar);
-}
-
-static void MakeDeathLoop(void** arr1, void** arr2) {
-  PreventHeapReclaiming(2 * sizeof(void*));
-  void** a1 = new(initialized) void*[2];
-  void** a2 = new(initialized) void*[2];
-  a1[1] = reinterpret_cast<void*>(a2);
-  a2[1] = reinterpret_cast<void*>(a1);
-  Hide(&a1);
-  Hide(&a2);
-  Use(&a1);
-  Use(&a2);
-  VLOG(2) << "Made hidden loop at " << &a1 << " to " << arr1;
-  *arr1 = a1;
-  *arr2 = a2;
-}
-
-// not deallocates two objects linked together
-static void TestHeapLeakCheckerDeathLoop() {
-  HeapLeakChecker check("death_loop");
-  void* arr1;
-  void* arr2;
-  RunHidden(NewCallback(MakeDeathLoop, &arr1, &arr2));
-  Use(&arr1);
-  Use(&arr2);
-  LogHidden("Leaking", arr1);
-  LogHidden("Leaking", arr2);
-  Pause();
-  VerifyLeaks(&check, NO_LEAKS, 4 * sizeof(void*), 2);
-  DeAllocHidden(&arr1);
-  DeAllocHidden(&arr2);
-}
-
-// deallocates more than allocates
-static void TestHeapLeakCheckerDeathInverse() {
-  void* bar = AllocHidden(250 * sizeof(int));
-  Use(&bar);
-  LogHidden("Pre leaking", bar);
-  Pause();
-  HeapLeakChecker check("death_inverse");
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  LogHidden("Leaking", foo);
-  DeAllocHidden(&bar);
-  Pause();
-  VerifyLeaks(&check, SAME_HEAP,
-              100 * static_cast<int64>(sizeof(int)),
-              1);
-  DeAllocHidden(&foo);
-}
-
-// deallocates more than allocates
-static void TestHeapLeakCheckerDeathNoLeaks() {
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  void* bar = AllocHidden(250 * sizeof(int));
-  Use(&bar);
-  HeapLeakChecker check("death_noleaks");
-  DeAllocHidden(&bar);
-  CHECK_EQ(check.BriefNoLeaks(), true);
-  DeAllocHidden(&foo);
-}
-
-// have less objecs
-static void TestHeapLeakCheckerDeathCountLess() {
-  void* bar1 = AllocHidden(50 * sizeof(int));
-  Use(&bar1);
-  void* bar2 = AllocHidden(50 * sizeof(int));
-  Use(&bar2);
-  LogHidden("Pre leaking", bar1);
-  LogHidden("Pre leaking", bar2);
-  Pause();
-  HeapLeakChecker check("death_count_less");
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  LogHidden("Leaking", foo);
-  DeAllocHidden(&bar1);
-  DeAllocHidden(&bar2);
-  Pause();
-  VerifyLeaks(&check, SAME_HEAP,
-              100 * sizeof(int),
-              1);
-  DeAllocHidden(&foo);
-}
-
-// have more objecs
-static void TestHeapLeakCheckerDeathCountMore() {
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  LogHidden("Pre leaking", foo);
-  Pause();
-  HeapLeakChecker check("death_count_more");
-  void* bar1 = AllocHidden(50 * sizeof(int));
-  Use(&bar1);
-  void* bar2 = AllocHidden(50 * sizeof(int));
-  Use(&bar2);
-  LogHidden("Leaking", bar1);
-  LogHidden("Leaking", bar2);
-  DeAllocHidden(&foo);
-  Pause();
-  VerifyLeaks(&check, SAME_HEAP,
-              100 * sizeof(int),
-              2);
-  DeAllocHidden(&bar1);
-  DeAllocHidden(&bar2);
-}
-
-static void TestHiddenPointer() {
-  int i;
-  void* foo = &i;
-  HiddenPointer<void> p(foo);
-  CHECK_EQ(foo, p.get());
-
-  // Confirm pointer doesn't appear to contain a byte sequence
-  // that == the pointer.  We don't really need to test that
-  // the xor trick itself works, as without it nothing in this
-  // test suite would work.  See the Hide/Unhide/*Hidden* set
-  // of helper methods.
-  void **pvoid = reinterpret_cast<void**>(&p);
-  CHECK_NE(foo, *pvoid);
-}
-
-// simple tests that deallocate what they allocated
-static void TestHeapLeakChecker() {
-  { HeapLeakChecker check("trivial");
-    int foo = 5;
-    int* p = &foo;
-    Use(&p);
-    Pause();
-    CHECK(check.BriefSameHeap());
-  }
-  Pause();
-  { HeapLeakChecker check("simple");
-    void* foo = AllocHidden(100 * sizeof(int));
-    Use(&foo);
-    void* bar = AllocHidden(200 * sizeof(int));
-    Use(&bar);
-    DeAllocHidden(&foo);
-    DeAllocHidden(&bar);
-    Pause();
-    CHECK(check.BriefSameHeap());
-  }
-}
-
-// no false positives
-static void TestHeapLeakCheckerNoFalsePositives() {
-  { HeapLeakChecker check("trivial_p");
-    int foo = 5;
-    int* p = &foo;
-    Use(&p);
-    Pause();
-    CHECK(check.BriefSameHeap());
-  }
-  Pause();
-  { HeapLeakChecker check("simple_p");
-    void* foo = AllocHidden(100 * sizeof(int));
-    Use(&foo);
-    void* bar = AllocHidden(200 * sizeof(int));
-    Use(&bar);
-    DeAllocHidden(&foo);
-    DeAllocHidden(&bar);
-    Pause();
-    CHECK(check.SameHeap());
-  }
-}
-
-// test that we detect leaks when we have same total # of bytes and
-// objects, but different individual object sizes
-static void TestLeakButTotalsMatch() {
-  void* bar1 = AllocHidden(240 * sizeof(int));
-  Use(&bar1);
-  void* bar2 = AllocHidden(160 * sizeof(int));
-  Use(&bar2);
-  LogHidden("Pre leaking", bar1);
-  LogHidden("Pre leaking", bar2);
-  Pause();
-  HeapLeakChecker check("trick");
-  void* foo1 = AllocHidden(280 * sizeof(int));
-  Use(&foo1);
-  void* foo2 = AllocHidden(120 * sizeof(int));
-  Use(&foo2);
-  LogHidden("Leaking", foo1);
-  LogHidden("Leaking", foo2);
-  DeAllocHidden(&bar1);
-  DeAllocHidden(&bar2);
-  Pause();
-
-  // foo1 and foo2 leaked
-  VerifyLeaks(&check, NO_LEAKS, (280+120)*sizeof(int), 2);
-
-  DeAllocHidden(&foo1);
-  DeAllocHidden(&foo2);
-}
-
-// no false negatives from pprof
-static void TestHeapLeakCheckerDeathTrick() {
-  void* bar1 = AllocHidden(240 * sizeof(int));
-  Use(&bar1);
-  void* bar2 = AllocHidden(160 * sizeof(int));
-  Use(&bar2);
-  HeapLeakChecker check("death_trick");
-  DeAllocHidden(&bar1);
-  DeAllocHidden(&bar2);
-  void* foo1 = AllocHidden(280 * sizeof(int));
-  Use(&foo1);
-  void* foo2 = AllocHidden(120 * sizeof(int));
-  Use(&foo2);
-  // TODO(maxim): use the above if we make pprof work in automated test runs
-  if (!FLAGS_maybe_stripped) {
-    CHECK_EQ(RUN_SILENT(check, SameHeap), false);
-      // pprof checking should catch the leak
-  } else {
-    WARN_IF(RUN_SILENT(check, SameHeap) != false,
-            "death_trick leak is not caught; "
-            "we must be using a stripped binary");
-  }
-  DeAllocHidden(&foo1);
-  DeAllocHidden(&foo2);
-}
-
-// simple leak
-static void TransLeaks() {
-  AllocHidden(1 * sizeof(char));
-}
-
-// range-based disabling using Disabler
-static void ScopedDisabledLeaks() {
-  HeapLeakChecker::Disabler disabler;
-  AllocHidden(3 * sizeof(int));
-  TransLeaks();
-  (void)malloc(10);  // Direct leak
-}
-
-// have different disabled leaks
-static void* RunDisabledLeaks(void* a) {
-  ScopedDisabledLeaks();
-  return a;
-}
-
-// have different disabled leaks inside of a thread
-static void ThreadDisabledLeaks() {
-  if (FLAGS_no_threads)  return;
-  pthread_t tid;
-  pthread_attr_t attr;
-  CHECK_EQ(pthread_attr_init(&attr), 0);
-  CHECK_EQ(pthread_create(&tid, &attr, RunDisabledLeaks, NULL), 0);
-  void* res;
-  CHECK_EQ(pthread_join(tid, &res), 0);
-}
-
-// different disabled leaks (some in threads)
-static void TestHeapLeakCheckerDisabling() {
-  HeapLeakChecker check("disabling");
-
-  RunDisabledLeaks(NULL);
-  RunDisabledLeaks(NULL);
-  ThreadDisabledLeaks();
-  RunDisabledLeaks(NULL);
-  ThreadDisabledLeaks();
-  ThreadDisabledLeaks();
-
-  Pause();
-
-  CHECK(check.SameHeap());
-}
-
-typedef set<int> IntSet;
-
-static int some_ints[] = { 1, 2, 3, 21, 22, 23, 24, 25 };
-
-static void DoTestSTLAlloc() {
-  IntSet* x = new(initialized) IntSet[1];
-  *x = IntSet(some_ints, some_ints + 6);
-  for (int i = 0; i < 1000; i++) {
-    x->insert(i*3);
-  }
-  delete [] x;
-}
-
-// Check that normal STL usage does not result in a leak report.
-// (In particular we test that there's no complex STL's own allocator
-// running on top of our allocator with hooks to heap profiler
-// that can result in false leak report in this case.)
-static void TestSTLAlloc() {
-  HeapLeakChecker check("stl");
-  RunHidden(NewCallback(DoTestSTLAlloc));
-  CHECK_EQ(check.BriefSameHeap(), true);
-}
-
-static void DoTestSTLAllocInverse(IntSet** setx) {
-  IntSet* x = new(initialized) IntSet[1];
-  *x = IntSet(some_ints, some_ints + 3);
-  for (int i = 0; i < 100; i++) {
-    x->insert(i*2);
-  }
-  Hide(&x);
-  *setx = x;
-}
-
-static void FreeTestSTLAllocInverse(IntSet** setx) {
-  IntSet* x = *setx;
-  UnHide(&x);
-  delete [] x;
-}
-
-// Check that normal leaked STL usage *does* result in a leak report.
-// (In particular we test that there's no complex STL's own allocator
-// running on top of our allocator with hooks to heap profiler
-// that can result in false absence of leak report in this case.)
-static void TestSTLAllocInverse() {
-  HeapLeakChecker check("death_inverse_stl");
-  IntSet* x;
-  RunHidden(NewCallback(DoTestSTLAllocInverse, &x));
-  LogHidden("Leaking", x);
-  if (can_create_leaks_reliably) {
-    WipeStack();  // to help with can_create_leaks_reliably
-    // these might still fail occasionally, but it should be very rare
-    CHECK_EQ(RUN_SILENT(check, BriefNoLeaks), false);
-    CHECK_GE(check.BytesLeaked(), 100 * sizeof(int));
-    CHECK_GE(check.ObjectsLeaked(), 100);
-      // assumes set<>s are represented by some kind of binary tree
-      // or something else allocating >=1 heap object per set object
-  } else {
-    WARN_IF(RUN_SILENT(check, BriefNoLeaks) != false,
-            "Expected leaks not found: "
-            "Some liveness flood must be too optimistic");
-  }
-  RunHidden(NewCallback(FreeTestSTLAllocInverse, &x));
-}
-
-template<class Alloc>
-static void DirectTestSTLAlloc(Alloc allocator, const char* name) {
-  HeapLeakChecker check((string("direct_stl-") + name).c_str());
-  static const int kSize = 1000;
-  typename Alloc::pointer ptrs[kSize];
-  for (int i = 0; i < kSize; ++i) {
-    typename Alloc::pointer p = allocator.allocate(i*3+1);
-    HeapLeakChecker::IgnoreObject(p);
-    // This will crash if p is not known to heap profiler:
-    // (i.e. STL's "allocator" does not have a direct hook to heap profiler)
-    HeapLeakChecker::UnIgnoreObject(p);
-    ptrs[i] = p;
-  }
-  for (int i = 0; i < kSize; ++i) {
-    allocator.deallocate(ptrs[i], i*3+1);
-    ptrs[i] = NULL;
-  }
-  CHECK(check.BriefSameHeap());  // just in case
-}
-
-static struct group* grp = NULL;
-static const int kKeys = 50;
-static pthread_key_t key[kKeys];
-
-static void KeyFree(void* ptr) {
-  delete [] reinterpret_cast<char*>(ptr);
-}
-
-static bool key_init_has_run = false;
-
-static void KeyInit() {
-  for (int i = 0; i < kKeys; ++i) {
-    CHECK_EQ(pthread_key_create(&key[i], KeyFree), 0);
-    VLOG(2) << "pthread key " << i << " : " << key[i];
-  }
-  key_init_has_run = true;   // needed for a sanity-check
-}
-
-// force various C library static and thread-specific allocations
-static void TestLibCAllocate() {
-  CHECK(key_init_has_run);
-  for (int i = 0; i < kKeys; ++i) {
-    void* p = pthread_getspecific(key[i]);
-    if (NULL == p) {
-      if (i == 0) {
-        // Test-logging inside threads which (potentially) creates and uses
-        // thread-local data inside standard C++ library:
-        VLOG(0) << "Adding pthread-specifics for thread " << pthread_self()
-                << " pid " << getpid();
-      }
-      p = new(initialized) char[77 + i];
-      VLOG(2) << "pthread specific " << i << " : " << p;
-      pthread_setspecific(key[i], p);
-    }
-  }
-
-  strerror(errno);
-  const time_t now = time(NULL);
-  ctime(&now);
-#ifdef HAVE_EXECINFO_H
-  void *stack[1];
-  backtrace(stack, 1);
-#endif
-#ifdef HAVE_GRP_H
-  gid_t gid = getgid();
-  getgrgid(gid);
-  if (grp == NULL)  grp = getgrent();  // a race condition here is okay
-  getgrnam(grp->gr_name);
-#endif
-#ifdef HAVE_PWD_H
-  getpwuid(geteuid());
-#endif
-}
-
-// Continuous random heap memory activity to try to disrupt heap checking.
-static void* HeapBusyThreadBody(void* a) {
-  const int thread_num = reinterpret_cast<intptr_t>(a);
-  VLOG(0) << "A new HeapBusyThread " << thread_num;
-  TestLibCAllocate();
-
-  int user = 0;
-  // Try to hide ptr from heap checker in a CPU register:
-  // Here we are just making a best effort to put the only pointer
-  // to a heap object into a thread register to test
-  // the thread-register finding machinery in the heap checker.
-#if defined(__i386__) && defined(__GNUC__)
-  register int** ptr asm("esi");
-#elif defined(__x86_64__) && defined(__GNUC__)
-  register int** ptr asm("r15");
-#else
-  register int** ptr;
-#endif
-  ptr = NULL;
-  typedef set<int> Set;
-  Set s1;
-  while (1) {
-    // TestLibCAllocate() calls libc functions that don't work so well
-    // after main() has exited.  So we just don't do the test then.
-    if (!g_have_exited_main)
-      TestLibCAllocate();
-
-    if (ptr == NULL) {
-      ptr = new(initialized) int*[1];
-      *ptr = new(initialized) int[1];
-    }
-    set<int>* s2 = new(initialized) set<int>[1];
-    s1.insert(random());
-    s2->insert(*s1.begin());
-    user += *s2->begin();
-    **ptr += user;
-    if (random() % 51 == 0) {
-      s1.clear();
-      if (random() % 2 == 0) {
-        s1.~Set();
-        new(&s1) Set;
-      }
-    }
-    VLOG(3) << pthread_self() << " (" << getpid() << "): in wait: "
-            << ptr << ", " << *ptr << "; " << s1.size();
-    VLOG(2) << pthread_self() << " (" << getpid() << "): in wait, ptr = "
-            << reinterpret_cast<void*>(
-                 reinterpret_cast<uintptr_t>(ptr) ^ kHideMask)
-            << "^" << reinterpret_cast<void*>(kHideMask);
-    if (FLAGS_test_register_leak  &&  thread_num % 5 == 0) {
-      // Hide the register "ptr" value with an xor mask.
-      // If one provides --test_register_leak flag, the test should
-      // (with very high probability) crash on some leak check
-      // with a leak report (of some x * sizeof(int) + y * sizeof(int*) bytes)
-      // pointing at the two lines above in this function
-      // with "new(initialized) int" in them as the allocators
-      // of the leaked objects.
-      // CAVEAT: We can't really prevent a compiler to save some
-      // temporary values of "ptr" on the stack and thus let us find
-      // the heap objects not via the register.
-      // Hence it's normal if for certain compilers or optimization modes
-      // --test_register_leak does not cause a leak crash of the above form
-      // (this happens e.g. for gcc 4.0.1 in opt mode).
-      ptr = reinterpret_cast<int **>(
-          reinterpret_cast<uintptr_t>(ptr) ^ kHideMask);
-      // busy loop to get the thread interrupted at:
-      for (int i = 1; i < 10000000; ++i)  user += (1 + user * user * 5) / i;
-      ptr = reinterpret_cast<int **>(
-          reinterpret_cast<uintptr_t>(ptr) ^ kHideMask);
-    } else {
-      poll(NULL, 0, random() % 100);
-    }
-    VLOG(2) << pthread_self() << ": continuing";
-    if (random() % 3 == 0) {
-      delete [] *ptr;
-      delete [] ptr;
-      ptr = NULL;
-    }
-    delete [] s2;
-  }
-  return a;
-}
-
-static void RunHeapBusyThreads() {
-  KeyInit();
-  if (!FLAGS_interfering_threads || FLAGS_no_threads)  return;
-
-  const int n = 17;  // make many threads
-
-  pthread_t tid;
-  pthread_attr_t attr;
-  CHECK_EQ(pthread_attr_init(&attr), 0);
-  // make them and let them run
-  for (int i = 0; i < n; ++i) {
-    VLOG(0) << "Creating extra thread " << i + 1;
-    CHECK(pthread_create(&tid, &attr, HeapBusyThreadBody,
-                         reinterpret_cast<void*>(i)) == 0);
-  }
-
-  Pause();
-  Pause();
-}
-
-// ========================================================================= //
-
-// This code section is to test that objects that are reachable from global
-// variables are not reported as leaks
-// as well as that (Un)IgnoreObject work for such objects fine.
-
-// An object making functions:
-// returns a "weird" pointer to a new object for which
-// it's worth checking that the object is reachable via that pointer.
-typedef void* (*ObjMakerFunc)();
-static list<ObjMakerFunc> obj_makers;  // list of registered object makers
-
-// Helper macro to register an object making function
-// 'name' is an identifier of this object maker,
-// 'body' is its function body that must declare
-//        pointer 'p' to the nex object to return.
-// Usage example:
-//   REGISTER_OBJ_MAKER(trivial, int* p = new(initialized) int;)
-#define REGISTER_OBJ_MAKER(name, body) \
-  void* ObjMaker_##name##_() { \
-    VLOG(1) << "Obj making " << #name; \
-    body; \
-    return p; \
-  } \
-  static ObjMakerRegistrar maker_reg_##name##__(&ObjMaker_##name##_);
-// helper class for REGISTER_OBJ_MAKER
-struct ObjMakerRegistrar {
-  ObjMakerRegistrar(ObjMakerFunc obj_maker) { obj_makers.push_back(obj_maker); }
-};
-
-// List of the objects/pointers made with all the obj_makers
-// to test reachability via global data pointers during leak checks.
-static list<void*>* live_objects = new list<void*>;
-  // pointer so that it does not get destructed on exit
-
-// Exerciser for one ObjMakerFunc.
-static void TestPointerReach(ObjMakerFunc obj_maker) {
-  HeapLeakChecker::IgnoreObject(obj_maker());  // test IgnoreObject
-
-  void* obj = obj_maker();
-  HeapLeakChecker::IgnoreObject(obj);
-  HeapLeakChecker::UnIgnoreObject(obj);  // test UnIgnoreObject
-  HeapLeakChecker::IgnoreObject(obj);  // not to need deletion for obj
-
-  live_objects->push_back(obj_maker());  // test reachability at leak check
-}
-
-// Test all ObjMakerFunc registred via REGISTER_OBJ_MAKER.
-static void TestObjMakers() {
-  for (list<ObjMakerFunc>::const_iterator i = obj_makers.begin();
-       i != obj_makers.end(); ++i) {
-    TestPointerReach(*i);
-    TestPointerReach(*i);  // a couple more times would not hurt
-    TestPointerReach(*i);
-  }
-}
-
-// A dummy class to mimic allocation behavior of string-s.
-template<class T>
-struct Array {
-  Array() {
-    size = 3 + random() % 30;
-    ptr = new(initialized) T[size];
-  }
-  ~Array() { delete [] ptr; }
-  Array(const Array& x) {
-    size = x.size;
-    ptr = new(initialized) T[size];
-    for (size_t i = 0; i < size; ++i) {
-      ptr[i] = x.ptr[i];
-    }
-  }
-  void operator=(const Array& x) {
-    delete [] ptr;
-    size = x.size;
-    ptr = new(initialized) T[size];
-    for (size_t i = 0; i < size; ++i) {
-      ptr[i] = x.ptr[i];
-    }
-  }
-  void append(const Array& x) {
-    T* p = new(initialized) T[size + x.size];
-    for (size_t i = 0; i < size; ++i) {
-      p[i] = ptr[i];
-    }
-    for (size_t i = 0; i < x.size; ++i) {
-      p[size+i] = x.ptr[i];
-    }
-    size += x.size;
-    delete [] ptr;
-    ptr = p;
-  }
- private:
-  size_t size;
-  T* ptr;
-};
-
-// to test pointers to objects, built-in arrays, string, etc:
-REGISTER_OBJ_MAKER(plain, int* p = new(initialized) int;)
-REGISTER_OBJ_MAKER(int_array_1, int* p = new(initialized) int[1];)
-REGISTER_OBJ_MAKER(int_array, int* p = new(initialized) int[10];)
-REGISTER_OBJ_MAKER(string, Array<char>* p = new(initialized) Array<char>();)
-REGISTER_OBJ_MAKER(string_array,
-                   Array<char>* p = new(initialized) Array<char>[5];)
-REGISTER_OBJ_MAKER(char_array, char* p = new(initialized) char[5];)
-REGISTER_OBJ_MAKER(appended_string,
-  Array<char>* p = new Array<char>();
-  p->append(Array<char>());
-)
-REGISTER_OBJ_MAKER(plain_ptr, int** p = new(initialized) int*;)
-REGISTER_OBJ_MAKER(linking_ptr,
-  int** p = new(initialized) int*;
-  *p = new(initialized) int;
-)
-
-// small objects:
-REGISTER_OBJ_MAKER(0_sized, void* p = malloc(0);)  // 0-sized object (important)
-REGISTER_OBJ_MAKER(1_sized, void* p = malloc(1);)
-REGISTER_OBJ_MAKER(2_sized, void* p = malloc(2);)
-REGISTER_OBJ_MAKER(3_sized, void* p = malloc(3);)
-REGISTER_OBJ_MAKER(4_sized, void* p = malloc(4);)
-
-static int set_data[] = { 1, 2, 3, 4, 5, 6, 7, 21, 22, 23, 24, 25, 26, 27 };
-static set<int> live_leak_set(set_data, set_data+7);
-static const set<int> live_leak_const_set(set_data, set_data+14);
-
-REGISTER_OBJ_MAKER(set,
-  set<int>* p = new(initialized) set<int>(set_data, set_data + 13);
-)
-
-class ClassA {
- public:
-  explicit ClassA(int a) : ptr(NULL) { }
-  mutable char* ptr;
-};
-static const ClassA live_leak_mutable(1);
-
-template<class C>
-class TClass {
- public:
-  explicit TClass(int a) : ptr(NULL) { }
-  mutable C val;
-  mutable C* ptr;
-};
-static const TClass<Array<char> > live_leak_templ_mutable(1);
-
-class ClassB {
- public:
-  ClassB() { }
-  char b[7];
-  virtual void f() { }
-  virtual ~ClassB() { }
-};
-
-class ClassB2 {
- public:
-  ClassB2() { }
-  char b2[11];
-  virtual void f2() { }
-  virtual ~ClassB2() { }
-};
-
-class ClassD1 : public ClassB {
-  char d1[15];
-  virtual void f() { }
-};
-
-class ClassD2 : public ClassB2 {
-  char d2[19];
-  virtual void f2() { }
-};
-
-class ClassD : public ClassD1, public ClassD2 {
-  char d[3];
-  virtual void f() { }
-  virtual void f2() { }
-};
-
-// to test pointers to objects of base subclasses:
-
-REGISTER_OBJ_MAKER(B,  ClassB*  p = new(initialized) ClassB;)
-REGISTER_OBJ_MAKER(D1, ClassD1* p = new(initialized) ClassD1;)
-REGISTER_OBJ_MAKER(D2, ClassD2* p = new(initialized) ClassD2;)
-REGISTER_OBJ_MAKER(D,  ClassD*  p = new(initialized) ClassD;)
-
-REGISTER_OBJ_MAKER(D1_as_B,  ClassB*  p = new(initialized) ClassD1;)
-REGISTER_OBJ_MAKER(D2_as_B2, ClassB2* p = new(initialized) ClassD2;)
-REGISTER_OBJ_MAKER(D_as_B,   ClassB*  p = new(initialized)  ClassD;)
-REGISTER_OBJ_MAKER(D_as_D1,  ClassD1* p = new(initialized) ClassD;)
-// inside-object pointers:
-REGISTER_OBJ_MAKER(D_as_B2,  ClassB2* p = new(initialized) ClassD;)
-REGISTER_OBJ_MAKER(D_as_D2,  ClassD2* p = new(initialized) ClassD;)
-
-class InterfaceA {
- public:
-  virtual void A() = 0;
-  virtual ~InterfaceA() { }
- protected:
-  InterfaceA() { }
-};
-
-class InterfaceB {
- public:
-  virtual void B() = 0;
-  virtual ~InterfaceB() { }
- protected:
-  InterfaceB() { }
-};
-
-class InterfaceC : public InterfaceA {
- public:
-  virtual void C() = 0;
-  virtual ~InterfaceC() { }
- protected:
-  InterfaceC() { }
-};
-
-class ClassMltD1 : public ClassB, public InterfaceB, public InterfaceC {
- public:
-  char d1[11];
-  virtual void f() { }
-  virtual void A() { }
-  virtual void B() { }
-  virtual void C() { }
-};
-
-class ClassMltD2 : public InterfaceA, public InterfaceB, public ClassB {
- public:
-  char d2[15];
-  virtual void f() { }
-  virtual void A() { }
-  virtual void B() { }
-};
-
-// to specifically test heap reachability under
-// inerface-only multiple inheritance (some use inside-object pointers):
-REGISTER_OBJ_MAKER(MltD1,       ClassMltD1* p = new(initialized) ClassMltD1;)
-REGISTER_OBJ_MAKER(MltD1_as_B,  ClassB*     p = new(initialized) ClassMltD1;)
-REGISTER_OBJ_MAKER(MltD1_as_IA, InterfaceA* p = new(initialized) ClassMltD1;)
-REGISTER_OBJ_MAKER(MltD1_as_IB, InterfaceB* p = new(initialized) ClassMltD1;)
-REGISTER_OBJ_MAKER(MltD1_as_IC, InterfaceC* p = new(initialized) ClassMltD1;)
-
-REGISTER_OBJ_MAKER(MltD2,       ClassMltD2* p = new(initialized) ClassMltD2;)
-REGISTER_OBJ_MAKER(MltD2_as_B,  ClassB*     p = new(initialized) ClassMltD2;)
-REGISTER_OBJ_MAKER(MltD2_as_IA, InterfaceA* p = new(initialized) ClassMltD2;)
-REGISTER_OBJ_MAKER(MltD2_as_IB, InterfaceB* p = new(initialized) ClassMltD2;)
-
-// to mimic UnicodeString defined in third_party/icu,
-// which store a platform-independent-sized refcount in the first
-// few bytes and keeps a pointer pointing behind the refcount.
-REGISTER_OBJ_MAKER(unicode_string,
-  char* p = new char[sizeof(uint32) * 10];
-  p += sizeof(uint32);
-)
-// similar, but for platform-dependent-sized refcount
-REGISTER_OBJ_MAKER(ref_counted,
-  char* p = new char[sizeof(int) * 20];
-  p += sizeof(int);
-)
-
-struct Nesting {
-  struct Inner {
-    Nesting* parent;
-    Inner(Nesting* p) : parent(p) {}
-  };
-  Inner i0;
-  char n1[5];
-  Inner i1;
-  char n2[11];
-  Inner i2;
-  char n3[27];
-  Inner i3;
-  Nesting() : i0(this), i1(this), i2(this), i3(this) {}
-};
-
-// to test inside-object pointers pointing at objects nested into heap objects:
-REGISTER_OBJ_MAKER(nesting_i0, Nesting::Inner* p = &((new Nesting())->i0);)
-REGISTER_OBJ_MAKER(nesting_i1, Nesting::Inner* p = &((new Nesting())->i1);)
-REGISTER_OBJ_MAKER(nesting_i2, Nesting::Inner* p = &((new Nesting())->i2);)
-REGISTER_OBJ_MAKER(nesting_i3, Nesting::Inner* p = &((new Nesting())->i3);)
-
-void (* volatile init_forcer)(...);
-
-// allocate many objects reachable from global data
-static void TestHeapLeakCheckerLiveness() {
-  live_leak_mutable.ptr = new(initialized) char[77];
-  live_leak_templ_mutable.ptr = new(initialized) Array<char>();
-  live_leak_templ_mutable.val = Array<char>();
-
-  // smart compiler may see that live_leak_mutable is not used
-  // anywhere so .ptr assignment is not used.
-  //
-  // We force compiler to assume that it is used by having function
-  // variable (set to 0 which hopefully won't be known to compiler)
-  // which gets address of those objects. So compiler has to assume
-  // that .ptr is used.
-  if (init_forcer) {
-    init_forcer(&live_leak_mutable, &live_leak_templ_mutable);
-  }
-  TestObjMakers();
-}
-
-// ========================================================================= //
-
-// Get address (PC value) following the mmap call into addr_after_mmap_call
-static void* Mmapper(uintptr_t* addr_after_mmap_call) {
-  void* r = mmap(NULL, 100, PROT_READ|PROT_WRITE,
-                 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-  // Get current PC value into addr_after_mmap_call
-  void* stack[1];
-  CHECK_EQ(GetStackTrace(stack, 1, 0), 1);
-  *addr_after_mmap_call = reinterpret_cast<uintptr_t>(stack[0]);
-  sleep(0);  // undo -foptimize-sibling-calls
-  return r;
-}
-
-// On PPC64 the stacktrace returned by GetStatcTrace contains the function
-// address from .text segment while function pointers points to ODP entries.
-// The following code decodes the ODP to get the actual symbol address.
-#if defined(__linux) && defined(__PPC64__) && (_CALL_ELF != 2)
-static inline uintptr_t GetFunctionAddress (void* (*func)(uintptr_t*))
-{
-  struct odp_entry_t {
-    unsigned long int symbol;
-    unsigned long int toc;
-    unsigned long int env;
-  } *odp_entry = reinterpret_cast<odp_entry_t*>(func);
-
-  return static_cast<uintptr_t>(odp_entry->symbol);
-}
-#else
-static inline uintptr_t GetFunctionAddress (void* (*func)(uintptr_t*))
-{
-  return reinterpret_cast<uintptr_t>(func);
-}
-#endif
-
-// to trick complier into preventing inlining
-static void* (*mmapper_addr)(uintptr_t* addr) = &Mmapper;
-
-// TODO(maxim): copy/move this to memory_region_map_unittest
-// TODO(maxim): expand this test to include mmap64, mremap and sbrk calls.
-static void VerifyMemoryRegionMapStackGet() {
-  uintptr_t caller_addr_limit;
-  void* addr = (*mmapper_addr)(&caller_addr_limit);
-  uintptr_t caller = 0;
-  { MemoryRegionMap::LockHolder l;
-    for (MemoryRegionMap::RegionIterator
-           i = MemoryRegionMap::BeginRegionLocked();
-           i != MemoryRegionMap::EndRegionLocked(); ++i) {
-      if (i->start_addr == reinterpret_cast<uintptr_t>(addr)) {
-        CHECK_EQ(caller, 0);
-        caller = i->caller();
-      }
-    }
-  }
-  // caller must point into Mmapper function:
-  if (!(GetFunctionAddress(mmapper_addr) <= caller  &&
-        caller < caller_addr_limit)) {
-    LOGF << std::hex << "0x" << caller
-         << " does not seem to point into code of function Mmapper at "
-         << "0x" << reinterpret_cast<uintptr_t>(mmapper_addr)
-         << "! Stack frame collection must be off in MemoryRegionMap!";
-    LOG(FATAL, "\n");
-  }
-  munmap(addr, 100);
-}
-
-static void* Mallocer(uintptr_t* addr_after_malloc_call) {
-  void* r = malloc(100);
-  sleep(0);  // undo -foptimize-sibling-calls
-  // Get current PC value into addr_after_malloc_call
-  void* stack[1];
-  CHECK_EQ(GetStackTrace(stack, 1, 0), 1);
-  *addr_after_malloc_call = reinterpret_cast<uintptr_t>(stack[0]);
-  return r;
-}
-
-// to trick compiler into preventing inlining
-static void* (* volatile mallocer_addr)(uintptr_t* addr) = &Mallocer;
-
-// non-static for friendship with HeapProfiler
-// TODO(maxim): expand this test to include
-// realloc, calloc, memalign, valloc, pvalloc, new, and new[].
-extern void VerifyHeapProfileTableStackGet() {
-  uintptr_t caller_addr_limit;
-  void* addr = (*mallocer_addr)(&caller_addr_limit);
-  uintptr_t caller =
-    reinterpret_cast<uintptr_t>(HeapLeakChecker::GetAllocCaller(addr));
-  // caller must point into Mallocer function:
-  if (!(GetFunctionAddress(mallocer_addr) <= caller  &&
-        caller < caller_addr_limit)) {
-    LOGF << std::hex << "0x" << caller
-         << " does not seem to point into code of function Mallocer at "
-         << "0x" << reinterpret_cast<uintptr_t>(mallocer_addr)
-         << "! Stack frame collection must be off in heap profiler!";
-    LOG(FATAL, "\n");
-  }
-  free(addr);
-}
-
-// ========================================================================= //
-
-static void MakeALeak(void** arr) {
-  PreventHeapReclaiming(10 * sizeof(int));
-  void* a = new(initialized) int[10];
-  Hide(&a);
-  *arr = a;
-}
-
-// Helper to do 'return 0;' inside main(): insted we do 'return Pass();'
-static int Pass() {
-  fprintf(stdout, "PASS\n");
-  g_have_exited_main = true;
-  return 0;
-}
-
-int main(int argc, char** argv) {
-  run_hidden_ptr = DoRunHidden;
-  wipe_stack_ptr = DoWipeStack;
-  if (!HeapLeakChecker::IsActive()) {
-    CHECK_EQ(FLAGS_heap_check, "");
-    LOG(WARNING, "HeapLeakChecker got turned off; we won't test much...");
-  } else {
-    VerifyMemoryRegionMapStackGet();
-    VerifyHeapProfileTableStackGet();
-  }
-
-  KeyInit();
-
-  // glibc 2.4, on x86_64 at least, has a lock-ordering bug, which
-  // means deadlock is possible when one thread calls dl_open at the
-  // same time another thread is calling dl_iterate_phdr.  libunwind
-  // calls dl_iterate_phdr, and TestLibCAllocate calls dl_open (or the
-  // various syscalls in it do), at least the first time it's run.
-  // To avoid the deadlock, we run TestLibCAllocate once before getting
-  // multi-threaded.
-  // TODO(csilvers): once libc is fixed, or libunwind can work around it,
-  //                 get rid of this early call.  We *want* our test to
-  //                 find potential problems like this one!
-  TestLibCAllocate();
-
-  if (FLAGS_interfering_threads) {
-    RunHeapBusyThreads();  // add interference early
-  }
-  TestLibCAllocate();
-
-  LOGF << "In main(): heap_check=" << FLAGS_heap_check << endl;
-
-  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good
-
-  if (FLAGS_test_leak) {
-    void* arr;
-    RunHidden(NewCallback(MakeALeak, &arr));
-    Use(&arr);
-    LogHidden("Leaking", arr);
-    if (FLAGS_test_cancel_global_check) {
-      HeapLeakChecker::CancelGlobalCheck();
-    } else {
-      // Verify we can call NoGlobalLeaks repeatedly without deadlocking
-      HeapLeakChecker::NoGlobalLeaks();
-      HeapLeakChecker::NoGlobalLeaks();
-    }
-    return Pass();
-      // whole-program leak-check should (with very high probability)
-      // catch the leak of arr (10 * sizeof(int) bytes)
-      // (when !FLAGS_test_cancel_global_check)
-  }
-
-  if (FLAGS_test_loop_leak) {
-    void* arr1;
-    void* arr2;
-    RunHidden(NewCallback(MakeDeathLoop, &arr1, &arr2));
-    Use(&arr1);
-    Use(&arr2);
-    LogHidden("Loop leaking", arr1);
-    LogHidden("Loop leaking", arr2);
-    if (FLAGS_test_cancel_global_check) {
-      HeapLeakChecker::CancelGlobalCheck();
-    } else {
-      // Verify we can call NoGlobalLeaks repeatedly without deadlocking
-      HeapLeakChecker::NoGlobalLeaks();
-      HeapLeakChecker::NoGlobalLeaks();
-    }
-    return Pass();
-      // whole-program leak-check should (with very high probability)
-      // catch the leak of arr1 and arr2 (4 * sizeof(void*) bytes)
-      // (when !FLAGS_test_cancel_global_check)
-  }
-
-  if (FLAGS_test_register_leak) {
-    // make us fail only where the .sh test expects:
-    Pause();
-    for (int i = 0; i < 100; ++i) {  // give it some time to crash
-      CHECK(HeapLeakChecker::NoGlobalLeaks());
-      Pause();
-    }
-    return Pass();
-  }
-
-  TestHeapLeakCheckerLiveness();
-
-  HeapLeakChecker heap_check("all");
-
-  TestHiddenPointer();
-
-  TestHeapLeakChecker();
-  Pause();
-  TestLeakButTotalsMatch();
-  Pause();
-
-  TestHeapLeakCheckerDeathSimple();
-  Pause();
-  TestHeapLeakCheckerDeathLoop();
-  Pause();
-  TestHeapLeakCheckerDeathInverse();
-  Pause();
-  TestHeapLeakCheckerDeathNoLeaks();
-  Pause();
-  TestHeapLeakCheckerDeathCountLess();
-  Pause();
-  TestHeapLeakCheckerDeathCountMore();
-  Pause();
-
-  TestHeapLeakCheckerDeathTrick();
-  Pause();
-
-  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good
-
-  TestHeapLeakCheckerNoFalsePositives();
-  Pause();
-
-  TestHeapLeakCheckerDisabling();
-  Pause();
-
-  TestSTLAlloc();
-  Pause();
-  TestSTLAllocInverse();
-  Pause();
-
-  // Test that various STL allocators work.  Some of these are redundant, but
-  // we don't know how STL might change in the future.  For example,
-  // http://wiki/Main/StringNeStdString.
-#define DTSL(a) { DirectTestSTLAlloc(a, #a); \
-                  Pause(); }
-  DTSL(std::allocator<char>());
-  DTSL(std::allocator<int>());
-  DTSL(std::string().get_allocator());
-  DTSL(string().get_allocator());
-  DTSL(vector<int>().get_allocator());
-  DTSL(vector<double>().get_allocator());
-  DTSL(vector<vector<int> >().get_allocator());
-  DTSL(vector<string>().get_allocator());
-  DTSL((map<string, string>().get_allocator()));
-  DTSL((map<string, int>().get_allocator()));
-  DTSL(set<char>().get_allocator());
-#undef DTSL
-
-  TestLibCAllocate();
-  Pause();
-
-  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good
-
-  Pause();
-
-  if (!FLAGS_maybe_stripped) {
-    CHECK(heap_check.SameHeap());
-  } else {
-    WARN_IF(heap_check.SameHeap() != true,
-            "overall leaks are caught; we must be using a stripped binary");
-  }
-
-  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good
-
-  return Pass();
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/heap-checker_unittest.sh b/third_party/tcmalloc/chromium/src/tests/heap-checker_unittest.sh
deleted file mode 100755
index 3c9c0e9..0000000
--- a/third_party/tcmalloc/chromium/src/tests/heap-checker_unittest.sh
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2005, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Craig Silverstein
-#
-# Runs the heap-checker unittest with various environment variables.
-# This is necessary because we turn on features like the heap profiler
-# and heap checker via environment variables.  This test makes sure
-# they all play well together.
-
-# We expect BINDIR and PPROF_PATH to be set in the environment.
-# If not, we set them to some reasonable values
-BINDIR="${BINDIR:-.}"
-PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir] [path to pprof]"
-  echo "       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
-  exit 1
-fi
-
-HEAP_CHECKER="${1:-$BINDIR/heap-checker_unittest}"
-PPROF_PATH="${2:-$PPROF_PATH}"
-
-TMPDIR=/tmp/heap_check_info
-rm -rf $TMPDIR || exit 2
-mkdir $TMPDIR || exit 3
-
-# $1: value of heap-check env. var.
-run_check() {
-    export PPROF_PATH="$PPROF_PATH"
-    [ -n "$1" ] && export HEAPCHECK="$1" || unset HEAPPROFILE
-
-    echo -n "Testing $HEAP_CHECKER with HEAPCHECK=$1 ... "
-    if $HEAP_CHECKER > $TMPDIR/output 2>&1; then
-      echo "OK"
-    else
-      echo "FAILED"
-      echo "Output from the failed run:"
-      echo "----"
-      cat $TMPDIR/output
-      echo "----"      
-      exit 4
-    fi
-
-    # If we set HEAPPROFILE, then we expect it to actually have emitted
-    # a profile.  Check that it did.
-    if [ -n "$HEAPPROFILE" ]; then
-      [ -e "$HEAPPROFILE.0001.heap" ] || exit 5
-    fi
-}
-
-run_check ""
-run_check "local"
-run_check "normal"
-run_check "strict"
-
-rm -rf $TMPDIR      # clean up
-
-echo "PASS"
diff --git a/third_party/tcmalloc/chromium/src/tests/heap-profiler_unittest.cc b/third_party/tcmalloc/chromium/src/tests/heap-profiler_unittest.cc
deleted file mode 100644
index 33178132..0000000
--- a/third_party/tcmalloc/chromium/src/tests/heap-profiler_unittest.cc
+++ /dev/null
@@ -1,168 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// A small program that just exercises our heap profiler by allocating
-// memory and letting the heap-profiler emit a profile.  We don't test
-// threads (TODO).  By itself, this unittest tests that the heap-profiler
-// doesn't crash on simple programs, but its output can be analyzed by
-// another testing script to actually verify correctness.  See, eg,
-// heap-profiler_unittest.sh.
-
-#include "config_for_unittests.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>                  // for mkdir()
-#include <sys/stat.h>               // for mkdir() on freebsd and os x
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                 // for fork()
-#endif
-#include <sys/wait.h>               // for wait()
-#include <string>
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include <gperftools/heap-profiler.h>
-
-using std::string;
-
-static const int kMaxCount = 100000;
-int* g_array[kMaxCount];              // an array of int-vectors
-
-static ATTRIBUTE_NOINLINE void Allocate(int start, int end, int size) {
-  // NOTE: we're using this to prevent gcc 5 from merging otherwise
-  // identical Allocate & Allocate2 functions.
-  VLOG(10, "Allocate");
-  for (int i = start; i < end; ++i) {
-    if (i < kMaxCount)
-      g_array[i] = new int[size];
-  }
-}
-
-static ATTRIBUTE_NOINLINE void Allocate2(int start, int end, int size) {
-  VLOG(10, "Allocate2");
-  for (int i = start; i < end; ++i) {
-    if (i < kMaxCount)
-      g_array[i] = new int[size];
-  }
-}
-
-static void Deallocate(int start, int end) {
-  for (int i = start; i < end; ++i) {
-    delete[] g_array[i];
-    g_array[i] = 0;
-  }
-}
-
-static void TestHeapProfilerStartStopIsRunning() {
-  // If you run this with whole-program heap-profiling on, than
-  // IsHeapProfilerRunning should return true.
-  if (!IsHeapProfilerRunning()) {
-    const char* tmpdir = getenv("TMPDIR");
-    if (tmpdir == NULL)
-      tmpdir = "/tmp";
-    mkdir(tmpdir, 0755);     // if necessary
-    HeapProfilerStart((string(tmpdir) + "/start_stop").c_str());
-    CHECK(IsHeapProfilerRunning());
-
-    Allocate(0, 40, 100);
-    Deallocate(0, 40);
-
-    HeapProfilerStop();
-    CHECK(!IsHeapProfilerRunning());
-  }
-}
-
-static void TestDumpHeapProfiler() {
-  // If you run this with whole-program heap-profiling on, than
-  // IsHeapProfilerRunning should return true.
-  if (!IsHeapProfilerRunning()) {
-    const char* tmpdir = getenv("TMPDIR");
-    if (tmpdir == NULL)
-      tmpdir = "/tmp";
-    mkdir(tmpdir, 0755);     // if necessary
-    HeapProfilerStart((string(tmpdir) + "/dump").c_str());
-    CHECK(IsHeapProfilerRunning());
-
-    Allocate(0, 40, 100);
-    Deallocate(0, 40);
-
-    char* output = GetHeapProfile();
-    free(output);
-    HeapProfilerStop();
-  }
-}
-
-
-int main(int argc, char** argv) {
-  if (argc > 2 || (argc == 2 && argv[1][0] == '-')) {
-    printf("USAGE: %s [number of children to fork]\n", argv[0]);
-    exit(0);
-  }
-  int num_forks = 0;
-  if (argc == 2) {
-    num_forks = atoi(argv[1]);
-  }
-
-  TestHeapProfilerStartStopIsRunning();
-  TestDumpHeapProfiler();
-
-  Allocate(0, 40, 100);
-  Deallocate(0, 40);
-
-  Allocate(0, 40, 100);
-  Allocate(0, 40, 100);
-  Allocate2(40, 400, 1000);
-  Allocate2(400, 1000, 10000);
-  Deallocate(0, 1000);
-
-  Allocate(0, 100, 100000);
-  Deallocate(0, 10);
-  Deallocate(10, 20);
-  Deallocate(90, 100);
-  Deallocate(20, 90);
-
-  while (num_forks-- > 0) {
-    switch (fork()) {
-      case -1:
-        printf("FORK failed!\n");
-        return 1;
-      case 0:             // child
-        return execl(argv[0], argv[0], NULL);   // run child with no args
-      default:
-        wait(NULL);       // we'll let the kids run one at a time
-    }
-  }
-
-  printf("DONE.\n");
-
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/heap-profiler_unittest.sh b/third_party/tcmalloc/chromium/src/tests/heap-profiler_unittest.sh
deleted file mode 100755
index 91af04f..0000000
--- a/third_party/tcmalloc/chromium/src/tests/heap-profiler_unittest.sh
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2005, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Craig Silverstein
-#
-# Runs the heap-profiler unittest and makes sure the profile looks appropriate.
-#
-# We run under the assumption that if $HEAP_PROFILER is run with --help,
-# it prints a usage line of the form
-#   USAGE: <actual executable being run> [...]
-#
-# This is because libtool sometimes turns the 'executable' into a
-# shell script which runs an actual binary somewhere else.
-
-# We expect BINDIR and PPROF_PATH to be set in the environment.
-# If not, we set them to some reasonable values
-BINDIR="${BINDIR:-.}"
-PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir] [path to pprof]"
-  echo "       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
-  exit 1
-fi
-
-HEAP_PROFILER="${1:-$BINDIR/heap-profiler_unittest}"
-PPROF="${2:-$PPROF_PATH}"
-TEST_TMPDIR=`mktemp -d /tmp/heap-profiler_unittest.XXXXXX`
-
-# It's meaningful to the profiler, so make sure we know its state
-unset HEAPPROFILE
-
-num_failures=0
-
-# Given one profile (to check the contents of that profile) or two
-# profiles (to check the diff between the profiles), and a function
-# name, verify that the function name takes up at least 90% of the
-# allocated memory.  The function name is actually specified first.
-VerifyMemFunction() {
-  function="$1"
-  shift
-
-  # get program name.  Note we have to unset HEAPPROFILE so running
-  # help doesn't overwrite existing profiles.
-  exec=`unset HEAPPROFILE; $HEAP_PROFILER --help | awk '{print $2; exit;}'`
-
-  if [ $# = 2 ]; then
-    [ -f "$1" ] || { echo "Profile not found: $1"; exit 1; }
-    [ -f "$2" ] || { echo "Profile not found: $2"; exit 1; }
-    $PPROF --base="$1" $exec "$2" >"$TEST_TMPDIR/output.pprof" 2>&1
-  else
-    [ -f "$1" ] || { echo "Profile not found: $1"; exit 1; }
-    $PPROF $exec "$1" >"$TEST_TMPDIR/output.pprof" 2>&1
-  fi
-
-  cat "$TEST_TMPDIR/output.pprof" \
-      | tr -d % | awk '$6 ~ /^'$function'$/ && $2 > 90 {exit 1;}'
-  if [ $? != 1 ]; then
-    echo
-    echo "--- Test failed for $function: didn't account for 90% of executable memory"
-    echo "--- Program output:"
-    cat "$TEST_TMPDIR/output"
-    echo "--- pprof output:"
-    cat "$TEST_TMPDIR/output.pprof"
-    echo "---"
-    num_failures=`expr $num_failures + 1`
-  fi
-}
-
-VerifyOutputContains() {
-  text="$1"
-
-  if ! grep "$text" "$TEST_TMPDIR/output" >/dev/null 2>&1; then
-    echo "--- Test failed: output does not contain '$text'"
-    echo "--- Program output:"
-    cat "$TEST_TMPDIR/output"
-    echo "---"
-    num_failures=`expr $num_failures + 1`
-  fi
-}
-
-HEAPPROFILE="$TEST_TMPDIR/test"
-HEAP_PROFILE_INUSE_INTERVAL="10240"   # need this to be 10Kb
-HEAP_PROFILE_ALLOCATION_INTERVAL="$HEAP_PROFILE_INUSE_INTERVAL"
-HEAP_PROFILE_DEALLOCATION_INTERVAL="$HEAP_PROFILE_INUSE_INTERVAL"
-export HEAPPROFILE
-export HEAP_PROFILE_INUSE_INTERVAL
-export HEAP_PROFILE_ALLOCATION_INTERVAL
-export HEAP_PROFILE_DEALLOCATION_INTERVAL
-
-# We make the unittest run a child process, to test that the child
-# process doesn't try to write a heap profile as well and step on the
-# parent's toes.  If it does, we expect the parent-test to fail.
-$HEAP_PROFILER 1 >$TEST_TMPDIR/output 2>&1     # run program, with 1 child proc
-
-VerifyMemFunction Allocate2 "$HEAPPROFILE.1329.heap"
-VerifyMemFunction Allocate "$HEAPPROFILE.1448.heap" "$HEAPPROFILE.1548.heap"
-
-# Check the child process got to emit its own profile as well.
-VerifyMemFunction Allocate2 "$HEAPPROFILE"_*.1329.heap
-VerifyMemFunction Allocate "$HEAPPROFILE"_*.1448.heap "$HEAPPROFILE"_*.1548.heap
-
-# Make sure we logged both about allocating and deallocating memory
-VerifyOutputContains "62 MB allocated"
-VerifyOutputContains "62 MB freed"
-
-# Now try running without --heap_profile specified, to allow
-# testing of the HeapProfileStart/Stop functionality.
-$HEAP_PROFILER >"$TEST_TMPDIR/output2" 2>&1
-
-rm -rf $TEST_TMPDIR      # clean up
-
-if [ $num_failures = 0 ]; then
-  echo "PASS"
-else
-  echo "Tests finished with $num_failures failures"
-fi
-exit $num_failures
diff --git a/third_party/tcmalloc/chromium/src/tests/large_heap_fragmentation_unittest.cc b/third_party/tcmalloc/chromium/src/tests/large_heap_fragmentation_unittest.cc
deleted file mode 100644
index 0886599..0000000
--- a/third_party/tcmalloc/chromium/src/tests/large_heap_fragmentation_unittest.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This is a unit test for exercising fragmentation of large (over 1
-// meg) page spans. It makes sure that allocations/releases of
-// increasing memory chunks do not blowup memory
-// usage. See also https://code.google.com/p/gperftools/issues/detail?id=368
-
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "base/logging.h"
-#include "common.h"
-#include <gperftools/malloc_extension.h>
-
-
-int main (int argc, char** argv) {
-  for (int pass = 1; pass <= 3; pass++) {
-    size_t size = 100*1024*1024;
-    while (size < 500*1024*1024) {
-      void *ptr = malloc(size);
-      free(ptr);
-      size += 20000;
-
-      size_t heap_size = static_cast<size_t>(-1);
-      MallocExtension::instance()->GetNumericProperty("generic.heap_size",
-                                                      &heap_size);
-
-
-      CHECK_LT(heap_size, 1*1024*1024*1024);
-    }
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/low_level_alloc_unittest.cc b/third_party/tcmalloc/chromium/src/tests/low_level_alloc_unittest.cc
deleted file mode 100644
index e3cb5552..0000000
--- a/third_party/tcmalloc/chromium/src/tests/low_level_alloc_unittest.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// A test for low_level_alloc.cc
-
-#include <stdio.h>
-#include <map>
-#include "base/low_level_alloc.h"
-#include "base/logging.h"
-#include <gperftools/malloc_hook.h>
-
-using std::map;
-
-// a block of memory obtained from the allocator
-struct BlockDesc {
-  char *ptr;      // pointer to memory
-  int len;        // number of bytes
-  int fill;       // filled with data starting with this
-};
-
-// Check that the pattern placed in the block d
-// by RandomizeBlockDesc is still there.
-static void CheckBlockDesc(const BlockDesc &d) {
-  for (int i = 0; i != d.len; i++) {
-    CHECK((d.ptr[i] & 0xff) == ((d.fill + i) & 0xff));
-  }
-}
-
-// Fill the block "*d" with a pattern
-// starting with a random byte.
-static void RandomizeBlockDesc(BlockDesc *d) {
-  d->fill = rand() & 0xff;
-  for (int i = 0; i != d->len; i++) {
-    d->ptr[i] = (d->fill + i) & 0xff;
-  }
-}
-
-// Use to indicate to the malloc hooks that
-// this calls is from LowLevelAlloc.
-static bool using_low_level_alloc = false;
-
-// n times, toss a coin, and based on the outcome
-// either allocate a new block or deallocate an old block.
-// New blocks are placed in a map with a random key
-// and initialized with RandomizeBlockDesc().
-// If keys conflict, the older block is freed.
-// Old blocks are always checked with CheckBlockDesc()
-// before being freed.  At the end of the run,
-// all remaining allocated blocks are freed.
-// If use_new_arena is true, use a fresh arena, and then delete it.
-// If call_malloc_hook is true and user_arena is true,
-// allocations and deallocations are reported via the MallocHook
-// interface.
-static void Test(bool use_new_arena, bool call_malloc_hook, int n) {
-  typedef map<int, BlockDesc> AllocMap;
-  AllocMap allocated;
-  AllocMap::iterator it;
-  BlockDesc block_desc;
-  int rnd;
-  LowLevelAlloc::Arena *arena = 0;
-  if (use_new_arena) {
-    int32 flags = call_malloc_hook?  LowLevelAlloc::kCallMallocHook :  0;
-    arena = LowLevelAlloc::NewArena(flags, LowLevelAlloc::DefaultArena());
-  }
-  for (int i = 0; i != n; i++) {
-    if (i != 0 && i % 10000 == 0) {
-      printf(".");
-      fflush(stdout);
-    }
-
-    switch(rand() & 1) {      // toss a coin
-    case 0:     // coin came up heads: add a block
-      using_low_level_alloc = true;
-      block_desc.len = rand() & 0x3fff;
-      block_desc.ptr =
-        reinterpret_cast<char *>(
-                        arena == 0
-                        ? LowLevelAlloc::Alloc(block_desc.len)
-                        : LowLevelAlloc::AllocWithArena(block_desc.len, arena));
-      using_low_level_alloc = false;
-      RandomizeBlockDesc(&block_desc);
-      rnd = rand();
-      it = allocated.find(rnd);
-      if (it != allocated.end()) {
-        CheckBlockDesc(it->second);
-        using_low_level_alloc = true;
-        LowLevelAlloc::Free(it->second.ptr);
-        using_low_level_alloc = false;
-        it->second = block_desc;
-      } else {
-        allocated[rnd] = block_desc;
-      }
-      break;
-    case 1:     // coin came up tails: remove a block
-      it = allocated.begin();
-      if (it != allocated.end()) {
-        CheckBlockDesc(it->second);
-        using_low_level_alloc = true;
-        LowLevelAlloc::Free(it->second.ptr);
-        using_low_level_alloc = false;
-        allocated.erase(it);
-      }
-      break;
-    }
-  }
-  // remove all remaniing blocks
-  while ((it = allocated.begin()) != allocated.end()) {
-    CheckBlockDesc(it->second);
-    using_low_level_alloc = true;
-    LowLevelAlloc::Free(it->second.ptr);
-    using_low_level_alloc = false;
-    allocated.erase(it);
-  }
-  if (use_new_arena) {
-    CHECK(LowLevelAlloc::DeleteArena(arena));
-  }
-}
-
-// used for counting allocates and frees
-static int32 allocates;
-static int32 frees;
-
-// called on each alloc if kCallMallocHook specified
-static void AllocHook(const void *p, size_t size) {
-  if (using_low_level_alloc) {
-    allocates++;
-  }
-}
-
-// called on each free if kCallMallocHook specified
-static void FreeHook(const void *p) {
-  if (using_low_level_alloc) {
-    frees++;
-  }
-}
-
-int main(int argc, char *argv[]) {
-  // This is needed by maybe_threads_unittest.sh, which parses argv[0]
-  // to figure out what directory low_level_alloc_unittest is in.
-  if (argc != 1) {
-    fprintf(stderr, "USAGE: %s\n", argv[0]);
-    return 1;
-  }
-
-  CHECK(MallocHook::AddNewHook(&AllocHook));
-  CHECK(MallocHook::AddDeleteHook(&FreeHook));
-  CHECK_EQ(allocates, 0);
-  CHECK_EQ(frees, 0);
-  Test(false, false, 50000);
-  CHECK_NE(allocates, 0);   // default arena calls hooks
-  CHECK_NE(frees, 0);
-  for (int i = 0; i != 16; i++) {
-    bool call_hooks = ((i & 1) == 1);
-    allocates = 0;
-    frees = 0;
-    Test(true, call_hooks, 15000);
-    if (call_hooks) {
-      CHECK_GT(allocates, 5000); // arena calls hooks
-      CHECK_GT(frees, 5000);
-    } else {
-      CHECK_EQ(allocates, 0);    // arena doesn't call hooks
-      CHECK_EQ(frees, 0);
-    }
-  }
-  printf("\nPASS\n");
-  CHECK(MallocHook::RemoveNewHook(&AllocHook));
-  CHECK(MallocHook::RemoveDeleteHook(&FreeHook));
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/malloc_extension_c_test.c b/third_party/tcmalloc/chromium/src/tests/malloc_extension_c_test.c
deleted file mode 100644
index 278fdb7..0000000
--- a/third_party/tcmalloc/chromium/src/tests/malloc_extension_c_test.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Craig Silverstein
- *
- * This tests the c shims: malloc_extension_c.h and malloc_hook_c.h.
- * Mostly, we'll just care that these shims compile under gcc
- * (*not* g++!)
- *
- * NOTE: this is C code, not C++ code!
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>   /* for size_t */
-#include <gperftools/malloc_extension_c.h>
-#include <gperftools/malloc_hook_c.h>
-
-#define FAIL(msg) do {                          \
-  fprintf(stderr, "FATAL ERROR: %s\n", msg);    \
-  exit(1);                                      \
-} while (0)
-
-static int g_new_hook_calls = 0;
-static int g_delete_hook_calls = 0;
-
-void TestNewHook(const void* ptr, size_t size) {
-  g_new_hook_calls++;
-}
-
-void TestDeleteHook(const void* ptr) {
-  g_delete_hook_calls++;
-}
-
-static
-void *forced_malloc(size_t size)
-{
-  extern void *tc_malloc(size_t);
-  void *rv = tc_malloc(size);
-  if (!rv) {
-    FAIL("malloc is not supposed to fail here");
-  }
-  return rv;
-}
-
-void TestMallocHook(void) {
-  /* TODO(csilvers): figure out why we get:
-   * E0100 00:00:00.000000  7383 malloc_hook.cc:244] RAW: google_malloc section is missing, thus InHookCaller is broken!
-   */
-#if 0
-  void* result[5];
-
-  if (MallocHook_GetCallerStackTrace(result, sizeof(result)/sizeof(*result),
-                                     0) < 2) {  /* should have this and main */
-    FAIL("GetCallerStackTrace failed");
-  }
-#endif
-
-  if (!MallocHook_AddNewHook(&TestNewHook)) {
-    FAIL("Failed to add new hook");
-  }
-  if (!MallocHook_AddDeleteHook(&TestDeleteHook)) {
-    FAIL("Failed to add delete hook");
-  }
-
-  free(forced_malloc(10));
-  free(forced_malloc(20));
-  if (g_new_hook_calls != 2) {
-    FAIL("Wrong number of calls to the new hook");
-  }
-  if (g_delete_hook_calls != 2) {
-    FAIL("Wrong number of calls to the delete hook");
-  }
-  if (!MallocHook_RemoveNewHook(&TestNewHook)) {
-    FAIL("Failed to remove new hook");
-  }
-  if (!MallocHook_RemoveDeleteHook(&TestDeleteHook)) {
-    FAIL("Failed to remove delete hook");
-  }
-
-  free(forced_malloc(10));
-  free(forced_malloc(20));
-  if (g_new_hook_calls != 2) {
-    FAIL("Wrong number of calls to the new hook");
-  }
-
-  MallocHook_SetNewHook(&TestNewHook);
-  MallocHook_SetDeleteHook(&TestDeleteHook);
-
-  free(forced_malloc(10));
-  free(forced_malloc(20));
-  if (g_new_hook_calls != 4) {
-    FAIL("Wrong number of calls to the singular new hook");
-  }
-
-  if (MallocHook_SetNewHook(NULL) == NULL) {
-    FAIL("Failed to set new hook");
-  }
-  if (MallocHook_SetDeleteHook(NULL) == NULL) {
-    FAIL("Failed to set delete hook");
-  }
-}
-
-void TestMallocExtension(void) {
-  int blocks;
-  size_t total;
-  int hist[64];
-  char buffer[200];
-  char* x = (char*)malloc(10);
-
-  MallocExtension_VerifyAllMemory();
-  MallocExtension_VerifyMallocMemory(x);
-  MallocExtension_MallocMemoryStats(&blocks, &total, hist);
-  MallocExtension_GetStats(buffer, sizeof(buffer));
-  if (!MallocExtension_GetNumericProperty("generic.current_allocated_bytes",
-                                          &total)) {
-    FAIL("GetNumericProperty failed for generic.current_allocated_bytes");
-  }
-  if (total < 10) {
-    FAIL("GetNumericProperty had bad return for generic.current_allocated_bytes");
-  }
-  if (!MallocExtension_GetNumericProperty("generic.current_allocated_bytes",
-                                          &total)) {
-    FAIL("GetNumericProperty failed for generic.current_allocated_bytes");
-  }
-  MallocExtension_MarkThreadIdle();
-  MallocExtension_MarkThreadBusy();
-  MallocExtension_ReleaseToSystem(1);
-  MallocExtension_ReleaseFreeMemory();
-  if (MallocExtension_GetEstimatedAllocatedSize(10) < 10) {
-    FAIL("GetEstimatedAllocatedSize returned a bad value (too small)");
-  }
-  if (MallocExtension_GetAllocatedSize(x) < 10) {
-    FAIL("GetEstimatedAllocatedSize returned a bad value (too small)");
-  }
-  if (MallocExtension_GetOwnership(x) != MallocExtension_kOwned) {
-    FAIL("DidAllocatePtr returned a bad value (kNotOwned)");
-  }
-  /* TODO(csilvers): this relies on undocumented behavior that
-     GetOwnership works on stack-allocated variables.  Use a better test. */
-  if (MallocExtension_GetOwnership(hist) != MallocExtension_kNotOwned) {
-    FAIL("DidAllocatePtr returned a bad value (kOwned)");
-  }
-
-  free(x);
-}
-
-int main(int argc, char** argv) {
-  TestMallocHook();
-  TestMallocExtension();
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/malloc_extension_test.cc b/third_party/tcmalloc/chromium/src/tests/malloc_extension_test.cc
deleted file mode 100644
index 31c4968..0000000
--- a/third_party/tcmalloc/chromium/src/tests/malloc_extension_test.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// Simple test of malloc_extension.  Includes test of C shims.
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#include <sys/types.h>
-#include "base/logging.h"
-#include <gperftools/malloc_extension.h>
-#include <gperftools/malloc_extension_c.h>
-
-int main(int argc, char** argv) {
-  void* a = malloc(1000);
-
-  size_t cxx_bytes_used, c_bytes_used;
-  ASSERT_TRUE(MallocExtension::instance()->GetNumericProperty(
-      "generic.current_allocated_bytes", &cxx_bytes_used));
-  ASSERT_TRUE(MallocExtension_GetNumericProperty(
-      "generic.current_allocated_bytes", &c_bytes_used));
-  ASSERT_GT(cxx_bytes_used, 1000);
-  ASSERT_EQ(cxx_bytes_used, c_bytes_used);
-
-  ASSERT_TRUE(MallocExtension::instance()->VerifyAllMemory());
-  ASSERT_TRUE(MallocExtension_VerifyAllMemory());
-
-  ASSERT_EQ(MallocExtension::kOwned,
-            MallocExtension::instance()->GetOwnership(a));
-  // TODO(csilvers): this relies on undocumented behavior that
-  // GetOwnership works on stack-allocated variables.  Use a better test.
-  ASSERT_EQ(MallocExtension::kNotOwned,
-            MallocExtension::instance()->GetOwnership(&cxx_bytes_used));
-  ASSERT_EQ(MallocExtension::kNotOwned,
-            MallocExtension::instance()->GetOwnership(NULL));
-  ASSERT_GE(MallocExtension::instance()->GetAllocatedSize(a), 1000);
-  // This is just a sanity check.  If we allocated too much, tcmalloc is broken
-  ASSERT_LE(MallocExtension::instance()->GetAllocatedSize(a), 5000);
-  ASSERT_GE(MallocExtension::instance()->GetEstimatedAllocatedSize(1000), 1000);
-
-  for (int i = 0; i < 10; ++i) {
-    void *p = malloc(i);
-    ASSERT_GE(MallocExtension::instance()->GetAllocatedSize(p),
-             MallocExtension::instance()->GetEstimatedAllocatedSize(i));
-    free(p);
-  }
-
-  // Check the c-shim version too.
-  ASSERT_EQ(MallocExtension_kOwned, MallocExtension_GetOwnership(a));
-  ASSERT_EQ(MallocExtension_kNotOwned,
-            MallocExtension_GetOwnership(&cxx_bytes_used));
-  ASSERT_EQ(MallocExtension_kNotOwned, MallocExtension_GetOwnership(NULL));
-  ASSERT_GE(MallocExtension_GetAllocatedSize(a), 1000);
-  ASSERT_LE(MallocExtension_GetAllocatedSize(a), 5000);
-  ASSERT_GE(MallocExtension_GetEstimatedAllocatedSize(1000), 1000);
-
-  free(a);
-
-  // Verify that the .cc file and .h file have the same enum values.
-  ASSERT_EQ(static_cast<int>(MallocExtension::kUnknownOwnership),
-            static_cast<int>(MallocExtension_kUnknownOwnership));
-  ASSERT_EQ(static_cast<int>(MallocExtension::kOwned),
-            static_cast<int>(MallocExtension_kOwned));
-  ASSERT_EQ(static_cast<int>(MallocExtension::kNotOwned),
-            static_cast<int>(MallocExtension_kNotOwned));
-
-  printf("DONE\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/malloc_hook_test.cc b/third_party/tcmalloc/chromium/src/tests/malloc_hook_test.cc
deleted file mode 100644
index a5cd860..0000000
--- a/third_party/tcmalloc/chromium/src/tests/malloc_hook_test.cc
+++ /dev/null
@@ -1,367 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ----
-// Author: llib@google.com (Bill Clarke)
-
-#include "config_for_unittests.h"
-#include <assert.h>
-#include <stdio.h>
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for sleep()
-#endif
-#include <algorithm>
-#include <string>
-#include <vector>
-#include <gperftools/malloc_hook.h>
-#include "malloc_hook-inl.h"
-#include "base/logging.h"
-#include "base/simple_mutex.h"
-#include "base/sysinfo.h"
-#include "tests/testutil.h"
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-namespace {
-
-using std::string;
-using std::vector;
-
-vector<void (*)()> g_testlist;  // the tests to run
-
-#define TEST(a, b)                                      \
-  struct Test_##a##_##b {                               \
-    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
-    static void Run();                                  \
-  };                                                    \
-  static Test_##a##_##b g_test_##a##_##b;               \
-  void Test_##a##_##b::Run()
-
-
-static int RUN_ALL_TESTS() {
-  vector<void (*)()>::const_iterator it;
-  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
-    (*it)();   // The test will error-exit if there's a problem.
-  }
-  fprintf(stderr, "\nPassed %d tests\n\nPASS\n",
-          static_cast<int>(g_testlist.size()));
-  return 0;
-}
-
-void Sleep(int seconds) {
-#ifdef _MSC_VER
-  _sleep(seconds * 1000);   // Windows's _sleep takes milliseconds argument
-#else
-  sleep(seconds);
-#endif
-}
-
-using std::min;
-using base::internal::kHookListMaxValues;
-
-// Since HookList is a template and is defined in malloc_hook.cc, we can only
-// use an instantiation of it from malloc_hook.cc.  We then reinterpret those
-// values as integers for testing.
-typedef base::internal::HookList<MallocHook::NewHook> TestHookList;
-
-int TestHookList_Traverse(const TestHookList& list, uintptr_t* output_array, int n) {
-  MallocHook::NewHook values_as_hooks[kHookListMaxValues];
-  int result = list.Traverse(values_as_hooks, min(n, kHookListMaxValues));
-  for (int i = 0; i < result; ++i) {
-    output_array[i] = reinterpret_cast<const uintptr_t>(*values_as_hooks[i]);
-  }
-  return result;
-}
-
-bool TestHookList_Add(TestHookList* list, int val) {
-  return list->Add(reinterpret_cast<MallocHook::NewHook>(val));
-}
-
-bool TestHookList_Remove(TestHookList* list, int val) {
-  return list->Remove(reinterpret_cast<MallocHook::NewHook>(val));
-}
-
-// Note that this is almost the same as INIT_HOOK_LIST in malloc_hook.cc without
-// the cast.
-#define INIT_HOOK_LIST(initial_value) { 1, { initial_value } }
-
-TEST(HookListTest, InitialValueExists) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(1, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(69, values[0]);
-  EXPECT_EQ(1, list.priv_end);
-}
-
-TEST(HookListTest, CanRemoveInitialValue) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  ASSERT_TRUE(TestHookList_Remove(&list, 69));
-  EXPECT_EQ(0, list.priv_end);
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(0, TestHookList_Traverse(list, values, 2));
-}
-
-TEST(HookListTest, AddAppends) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  ASSERT_TRUE(TestHookList_Add(&list, 42));
-  EXPECT_EQ(2, list.priv_end);
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(2, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(69, values[0]);
-  EXPECT_EQ(42, values[1]);
-}
-
-TEST(HookListTest, RemoveWorksAndWillClearSize) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  ASSERT_TRUE(TestHookList_Add(&list, 42));
-
-  ASSERT_TRUE(TestHookList_Remove(&list, 69));
-  EXPECT_EQ(2, list.priv_end);
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(1, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(42, values[0]);
-
-  ASSERT_TRUE(TestHookList_Remove(&list, 42));
-  EXPECT_EQ(0, list.priv_end);
-  EXPECT_EQ(0, TestHookList_Traverse(list, values, 2));
-}
-
-TEST(HookListTest, AddPrependsAfterRemove) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  ASSERT_TRUE(TestHookList_Add(&list, 42));
-
-  ASSERT_TRUE(TestHookList_Remove(&list, 69));
-  EXPECT_EQ(2, list.priv_end);
-
-  ASSERT_TRUE(TestHookList_Add(&list, 7));
-  EXPECT_EQ(2, list.priv_end);
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(2, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(7, values[0]);
-  EXPECT_EQ(42, values[1]);
-}
-
-TEST(HookListTest, InvalidAddRejected) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  EXPECT_FALSE(TestHookList_Add(&list, 0));
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(1, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(69, values[0]);
-  EXPECT_EQ(1, list.priv_end);
-}
-
-TEST(HookListTest, FillUpTheList) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  int num_inserts = 0;
-  while (TestHookList_Add(&list, ++num_inserts))
-    ;
-  EXPECT_EQ(kHookListMaxValues, num_inserts);
-  EXPECT_EQ(kHookListMaxValues, list.priv_end);
-
-  uintptr_t values[kHookListMaxValues + 1];
-  EXPECT_EQ(kHookListMaxValues, TestHookList_Traverse(list, values,
-                                                      kHookListMaxValues));
-  EXPECT_EQ(69, values[0]);
-  for (int i = 1; i < kHookListMaxValues; ++i) {
-    EXPECT_EQ(i, values[i]);
-  }
-}
-
-void MultithreadedTestThread(TestHookList* list, int shift,
-                             int thread_num) {
-  string message;
-  char buf[64];
-  for (int i = 1; i < 1000; ++i) {
-    // In each loop, we insert a unique value, check it exists, remove it, and
-    // check it doesn't exist.  We also record some stats to log at the end of
-    // each thread.  Each insertion location and the length of the list is
-    // non-deterministic (except for the very first one, over all threads, and
-    // after the very last one the list should be empty).
-    int value = (i << shift) + thread_num;
-    EXPECT_TRUE(TestHookList_Add(list, value));
-    sched_yield();  // Ensure some more interleaving.
-    uintptr_t values[kHookListMaxValues + 1];
-    int num_values = TestHookList_Traverse(*list, values, kHookListMaxValues);
-    EXPECT_LT(0, num_values);
-    int value_index;
-    for (value_index = 0;
-         value_index < num_values && values[value_index] != value;
-         ++value_index)
-      ;
-    EXPECT_LT(value_index, num_values);  // Should have found value.
-    snprintf(buf, sizeof(buf), "[%d/%d; ", value_index, num_values);
-    message += buf;
-    sched_yield();
-    EXPECT_TRUE(TestHookList_Remove(list, value));
-    sched_yield();
-    num_values = TestHookList_Traverse(*list, values, kHookListMaxValues);
-    for (value_index = 0;
-         value_index < num_values && values[value_index] != value;
-         ++value_index)
-      ;
-    EXPECT_EQ(value_index, num_values);  // Should not have found value.
-    snprintf(buf, sizeof(buf), "%d]", num_values);
-    message += buf;
-    sched_yield();
-  }
-  fprintf(stderr, "thread %d: %s\n", thread_num, message.c_str());
-}
-
-static volatile int num_threads_remaining;
-static TestHookList list = INIT_HOOK_LIST(69);
-static Mutex threadcount_lock;
-
-void MultithreadedTestThreadRunner(int thread_num) {
-  // Wait for all threads to start running.
-  {
-    MutexLock ml(&threadcount_lock);
-    assert(num_threads_remaining > 0);
-    --num_threads_remaining;
-
-    // We should use condvars and the like, but for this test, we'll
-    // go simple and busy-wait.
-    while (num_threads_remaining > 0) {
-      threadcount_lock.Unlock();
-      Sleep(1);
-      threadcount_lock.Lock();
-    }
-  }
-
-  // shift is the smallest number such that (1<<shift) > kHookListMaxValues
-  int shift = 0;
-  for (int i = kHookListMaxValues; i > 0; i >>= 1)
-    shift += 1;
-
-  MultithreadedTestThread(&list, shift, thread_num);
-}
-
-
-TEST(HookListTest, MultithreadedTest) {
-  ASSERT_TRUE(TestHookList_Remove(&list, 69));
-  ASSERT_EQ(0, list.priv_end);
-
-  // Run kHookListMaxValues thread, each running MultithreadedTestThread.
-  // First, we need to set up the rest of the globals.
-  num_threads_remaining = kHookListMaxValues;   // a global var
-  RunManyThreadsWithId(&MultithreadedTestThreadRunner, num_threads_remaining,
-                       1 << 15);
-
-  uintptr_t values[kHookListMaxValues + 1];
-  EXPECT_EQ(0, TestHookList_Traverse(list, values, kHookListMaxValues));
-  EXPECT_EQ(0, list.priv_end);
-}
-
-// We only do mmap-hooking on (some) linux systems.
-#if defined(HAVE_MMAP) && defined(__linux) && \
-    (defined(__i386__) || defined(__x86_64__) || defined(__PPC__))
-
-int mmap_calls = 0;
-int mmap_matching_calls = 0;
-int munmap_calls = 0;
-int munmap_matching_calls = 0;
-const int kMmapMagicFd = 1;
-void* const kMmapMagicPointer = reinterpret_cast<void*>(1);
-
-int MmapReplacement(const void* start,
-                     size_t size,
-                     int protection,
-                     int flags,
-                     int fd,
-                     off_t offset,
-                     void** result) {
-  ++mmap_calls;
-  if (fd == kMmapMagicFd) {
-    ++mmap_matching_calls;
-    *result = kMmapMagicPointer;
-    return true;
-  }
-  return false;
-}
-
-int MunmapReplacement(const void* ptr, size_t size, int* result) {
-  ++munmap_calls;
-  if (ptr == kMmapMagicPointer) {
-    ++munmap_matching_calls;
-    *result = 0;
-    return true;
-  }
-  return false;
-}
-
-TEST(MallocMookTest, MmapReplacements) {
-  mmap_calls = mmap_matching_calls = munmap_calls = munmap_matching_calls = 0;
-  MallocHook::SetMmapReplacement(&MmapReplacement);
-  MallocHook::SetMunmapReplacement(&MunmapReplacement);
-  EXPECT_EQ(kMmapMagicPointer, mmap(NULL, 1, PROT_READ, MAP_PRIVATE,
-                                    kMmapMagicFd, 0));
-  EXPECT_EQ(1, mmap_matching_calls);
-
-  char* ptr = reinterpret_cast<char*>(
-      mmap(NULL, 1, PROT_READ | PROT_WRITE,
-           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
-  EXPECT_EQ(2, mmap_calls);
-  EXPECT_EQ(1, mmap_matching_calls);
-  ASSERT_NE(MAP_FAILED, ptr);
-  *ptr = 'a';
-
-  EXPECT_EQ(0, munmap(kMmapMagicPointer, 1));
-  EXPECT_EQ(1, munmap_calls);
-  EXPECT_EQ(1, munmap_matching_calls);
-
-  EXPECT_EQ(0, munmap(ptr, 1));
-  EXPECT_EQ(2, munmap_calls);
-  EXPECT_EQ(1, munmap_matching_calls);
-
-  // The DEATH test below is flaky, because we've just munmapped the memory,
-  // making it available for mmap()ing again. There is no guarantee that it
-  // will stay unmapped, and in fact it gets reused ~10% of the time.
-  // It the area is reused, then not only we don't die, but we also corrupt
-  // whoever owns that memory now.
-  // EXPECT_DEATH(*ptr = 'a', "SIGSEGV");
-}
-#endif  // #ifdef HAVE_MMAP && linux && ...
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  return RUN_ALL_TESTS();
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/markidle_unittest.cc b/third_party/tcmalloc/chromium/src/tests/markidle_unittest.cc
deleted file mode 100644
index 92b4cc4a..0000000
--- a/third_party/tcmalloc/chromium/src/tests/markidle_unittest.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2003, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// MallocExtension::MarkThreadIdle() testing
-#include <stdio.h>
-
-#include "config_for_unittests.h"
-#include "base/logging.h"
-#include <gperftools/malloc_extension.h>
-#include "tests/testutil.h"   // for RunThread()
-
-// Helper routine to do lots of allocations
-static void TestAllocation() {
-  static const int kNum = 100;
-  void* ptr[kNum];
-  for (int size = 8; size <= 65536; size*=2) {
-    for (int i = 0; i < kNum; i++) {
-      ptr[i] = malloc(size);
-    }
-    for (int i = 0; i < kNum; i++) {
-      free(ptr[i]);
-    }
-  }
-}
-
-// Routine that does a bunch of MarkThreadIdle() calls in sequence
-// without any intervening allocations
-static void MultipleIdleCalls() {
-  for (int i = 0; i < 4; i++) {
-    MallocExtension::instance()->MarkThreadIdle();
-  }
-}
-
-// Routine that does a bunch of MarkThreadIdle() calls in sequence
-// with intervening allocations
-static void MultipleIdleNonIdlePhases() {
-  for (int i = 0; i < 4; i++) {
-    TestAllocation();
-    MallocExtension::instance()->MarkThreadIdle();
-  }
-}
-
-// Get current thread cache usage
-static size_t GetTotalThreadCacheSize() {
-  size_t result;
-  CHECK(MallocExtension::instance()->GetNumericProperty(
-            "tcmalloc.current_total_thread_cache_bytes",
-            &result));
-  return result;
-}
-
-// Check that MarkThreadIdle() actually reduces the amount
-// of per-thread memory.
-static void TestIdleUsage() {
-  const size_t original = GetTotalThreadCacheSize();
-
-  TestAllocation();
-  const size_t post_allocation = GetTotalThreadCacheSize();
-  CHECK_GT(post_allocation, original);
-
-  MallocExtension::instance()->MarkThreadIdle();
-  const size_t post_idle = GetTotalThreadCacheSize();
-  CHECK_LE(post_idle, original);
-
-  // Log after testing because logging can allocate heap memory.
-  VLOG(0, "Original usage: %" PRIuS "\n", original);
-  VLOG(0, "Post allocation: %" PRIuS "\n", post_allocation);
-  VLOG(0, "Post idle: %" PRIuS "\n", post_idle);
-}
-
-static void TestTemporarilyIdleUsage() {
-  const size_t original = MallocExtension::instance()->GetThreadCacheSize();
-
-  TestAllocation();
-  const size_t post_allocation = MallocExtension::instance()->GetThreadCacheSize();
-  CHECK_GT(post_allocation, original);
-
-  MallocExtension::instance()->MarkThreadIdle();
-  const size_t post_idle = MallocExtension::instance()->GetThreadCacheSize();
-  CHECK_EQ(post_idle, 0);
-
-  // Log after testing because logging can allocate heap memory.
-  VLOG(0, "Original usage: %" PRIuS "\n", original);
-  VLOG(0, "Post allocation: %" PRIuS "\n", post_allocation);
-  VLOG(0, "Post idle: %" PRIuS "\n", post_idle);
-}
-
-int main(int argc, char** argv) {
-  RunThread(&TestIdleUsage);
-  RunThread(&TestAllocation);
-  RunThread(&MultipleIdleCalls);
-  RunThread(&MultipleIdleNonIdlePhases);
-  RunThread(&TestTemporarilyIdleUsage);
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/maybe_threads_unittest.sh b/third_party/tcmalloc/chromium/src/tests/maybe_threads_unittest.sh
deleted file mode 100755
index 77b3b788..0000000
--- a/third_party/tcmalloc/chromium/src/tests/maybe_threads_unittest.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2007, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Craig Silverstein
-#
-# maybe_threads.cc was written to allow LD_PRELOAD=libtcmalloc.so to
-# work even on binaries that were not linked with pthreads.  This
-# unittest tests that, by running low_level_alloc_unittest with an
-# LD_PRELOAD.  (low_level_alloc_unittest was chosen because it doesn't
-# link in tcmalloc.)
-#
-# We assume all the .so files are in the same directory as both
-# addressmap_unittest and profiler1_unittest.  The reason we need
-# profiler1_unittest is because it's instrumented to show the directory
-# it's "really" in when run without any args.  In practice this will either
-# be BINDIR, or, when using libtool, BINDIR/.lib.
-
-# We expect BINDIR to be set in the environment.
-# If not, we set them to some reasonable values.
-BINDIR="${BINDIR:-.}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir]"
-  echo "       By default, unittest_dir=$BINDIR"
-  exit 1
-fi
-
-UNITTEST_DIR=${1:-$BINDIR}
-
-# Figure out the "real" unittest directory.  Also holds the .so files.
-UNITTEST_DIR=`$UNITTEST_DIR/low_level_alloc_unittest --help 2>&1 \
-              | awk '{print $2; exit;}' \
-              | xargs dirname`
-
-# Figure out where libtcmalloc lives.   It should be in UNITTEST_DIR,
-# but with libtool it might be in a subdir.
-if [ -r "$UNITTEST_DIR/libtcmalloc_minimal.so" ]; then
-  LIB_PATH="$UNITTEST_DIR/libtcmalloc_minimal.so"
-elif [ -r "$UNITTEST_DIR/.libs/libtcmalloc_minimal.so" ]; then
-  LIB_PATH="$UNITTEST_DIR/.libs/libtcmalloc_minimal.so"
-elif [ -r "$UNITTEST_DIR/libtcmalloc_minimal.dylib" ]; then   # for os x
-  LIB_PATH="$UNITTEST_DIR/libtcmalloc_minimal.dylib"
-elif [ -r "$UNITTEST_DIR/.libs/libtcmalloc_minimal.dylib" ]; then
-  LIB_PATH="$UNITTEST_DIR/.libs/libtcmalloc_minimal.dylib"
-else
-  echo "Cannot run $0: cannot find libtcmalloc_minimal.so"
-  exit 2
-fi
-
-LD_PRELOAD="$LIB_PATH" $UNITTEST_DIR/low_level_alloc_unittest
diff --git a/third_party/tcmalloc/chromium/src/tests/memalign_unittest.cc b/third_party/tcmalloc/chromium/src/tests/memalign_unittest.cc
deleted file mode 100644
index 309a3df..0000000
--- a/third_party/tcmalloc/chromium/src/tests/memalign_unittest.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2004, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Check memalign related routines.
-//
-// We can't really do a huge amount of checking, but at the very
-// least, the following code checks that return values are properly
-// aligned, and that writing into the objects works.
-
-#include "config_for_unittests.h"
-
-// Complicated ordering requirements.  tcmalloc.h defines (indirectly)
-// _POSIX_C_SOURCE, which it needs so stdlib.h defines posix_memalign.
-// unistd.h, on the other hand, requires _POSIX_C_SOURCE to be unset,
-// at least on Mac OS X, in order to define getpagesize.  The solution
-// is to #include unistd.h first.  This is safe because unistd.h
-// doesn't sub-include stdlib.h, so we'll still get posix_memalign
-// when we #include stdlib.h.  Blah.
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>        // for getpagesize()
-#endif
-#include "tcmalloc.h"      // must come early, to pick up posix_memalign
-#include <assert.h>
-#include <stdlib.h>        // defines posix_memalign
-#include <stdio.h>         // for the printf at the end
-#ifdef HAVE_STDINT_H
-#include <stdint.h>        // for uintptr_t
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>        // for getpagesize()
-#endif
-// Malloc can be in several places on older versions of OS X.
-#if defined(HAVE_MALLOC_H)
-#include <malloc.h>        // for memalign() and valloc()
-#elif defined(HAVE_MALLOC_MALLOC_H)
-#include <malloc/malloc.h>
-#elif defined(HAVE_SYS_MALLOC_H)
-#include <sys/malloc.h>
-#endif
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "tests/testutil.h"
-
-
-// Return the next interesting size/delta to check.  Returns -1 if no more.
-static int NextSize(int size) {
-  if (size < 100) {
-    return size+1;
-  } else if (size < 1048576) {
-    // Find next power of two
-    int power = 1;
-    while (power < size) {
-      power <<= 1;
-    }
-
-    // Yield (power-1, power, power+1)
-    if (size < power-1) {
-      return power-1;
-    } else if (size == power-1) {
-      return power;
-    } else {
-      assert(size == power);
-      return power+1;
-    }
-  } else {
-    return -1;
-  }
-}
-
-// Shortform for cast
-static uintptr_t Number(void* p) {
-  return reinterpret_cast<uintptr_t>(p);
-}
-
-// Check alignment
-static void CheckAlignment(void* p, int align) {
-  if ((Number(p) & (align-1)) != 0)
-    LOG(FATAL, "wrong alignment; wanted 0x%x; got %p\n", align, p);
-}
-
-// Fill a buffer of the specified size with a predetermined pattern
-static void Fill(void* p, int n, char seed) {
-  unsigned char* buffer = reinterpret_cast<unsigned char*>(p);
-  for (int i = 0; i < n; i++) {
-    buffer[i] = ((seed + i) & 0xff);
-  }
-}
-
-// Check that the specified buffer has the predetermined pattern
-// generated by Fill()
-static bool Valid(const void* p, int n, char seed) {
-  const unsigned char* buffer = reinterpret_cast<const unsigned char*>(p);
-  for (int i = 0; i < n; i++) {
-    if (buffer[i] != ((seed + i) & 0xff)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-int main(int argc, char** argv) {
-  SetTestResourceLimit();
-
-  // Try allocating data with a bunch of alignments and sizes
-  for (int a = 1; a < 1048576; a *= 2) {
-    for (int s = 0; s != -1; s = NextSize(s)) {
-      void* ptr = memalign(a, s);
-      CheckAlignment(ptr, a);
-      Fill(ptr, s, 'x');
-      CHECK(Valid(ptr, s, 'x'));
-      free(ptr);
-
-      if ((a >= sizeof(void*)) && ((a & (a-1)) == 0)) {
-        CHECK(posix_memalign(&ptr, a, s) == 0);
-        CheckAlignment(ptr, a);
-        Fill(ptr, s, 'y');
-        CHECK(Valid(ptr, s, 'y'));
-        free(ptr);
-      }
-    }
-  }
-
-  {
-    // Check various corner cases
-    void* p1 = memalign(1<<20, 1<<19);
-    void* p2 = memalign(1<<19, 1<<19);
-    void* p3 = memalign(1<<21, 1<<19);
-    CheckAlignment(p1, 1<<20);
-    CheckAlignment(p2, 1<<19);
-    CheckAlignment(p3, 1<<21);
-    Fill(p1, 1<<19, 'a');
-    Fill(p2, 1<<19, 'b');
-    Fill(p3, 1<<19, 'c');
-    CHECK(Valid(p1, 1<<19, 'a'));
-    CHECK(Valid(p2, 1<<19, 'b'));
-    CHECK(Valid(p3, 1<<19, 'c'));
-    free(p1);
-    free(p2);
-    free(p3);
-  }
-
-  {
-    // posix_memalign
-    void* ptr;
-    CHECK(posix_memalign(&ptr, 0, 1) == EINVAL);
-    CHECK(posix_memalign(&ptr, sizeof(void*)/2, 1) == EINVAL);
-    CHECK(posix_memalign(&ptr, sizeof(void*)+1, 1) == EINVAL);
-    CHECK(posix_memalign(&ptr, 4097, 1) == EINVAL);
-
-    // Grab some memory so that the big allocation below will definitely fail.
-    void* p_small = malloc(4*1048576);
-    CHECK(p_small != NULL);
-
-    // Make sure overflow is returned as ENOMEM
-    const size_t zero = 0;
-    static const size_t kMinusNTimes = 10;
-    for ( size_t i = 1; i < kMinusNTimes; ++i ) {
-      int r = posix_memalign(&ptr, 1024, zero - i);
-      CHECK(r == ENOMEM);
-    }
-
-    free(p_small);
-  }
-
-  const int pagesize = getpagesize();
-  {
-    // valloc
-    for (int s = 0; s != -1; s = NextSize(s)) {
-      void* p = valloc(s);
-      CheckAlignment(p, pagesize);
-      Fill(p, s, 'v');
-      CHECK(Valid(p, s, 'v'));
-      free(p);
-    }
-  }
-
-  {
-    // pvalloc
-    for (int s = 0; s != -1; s = NextSize(s)) {
-      void* p = pvalloc(s);
-      CheckAlignment(p, pagesize);
-      int alloc_needed = ((s + pagesize - 1) / pagesize) * pagesize;
-      Fill(p, alloc_needed, 'x');
-      CHECK(Valid(p, alloc_needed, 'x'));
-      free(p);
-    }
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/packed-cache_test.cc b/third_party/tcmalloc/chromium/src/tests/packed-cache_test.cc
deleted file mode 100644
index 3984594c..0000000
--- a/third_party/tcmalloc/chromium/src/tests/packed-cache_test.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Geoff Pike
-
-#include <stdio.h>
-#include "base/logging.h"
-#include "packed-cache-inl.h"
-
-static const int kHashbits = PackedCache<20>::kHashbits;
-
-template <int kKeybits>
-static size_t MustGet(const PackedCache<kKeybits>& cache, uintptr_t key) {
-  uint32 rv;
-  CHECK(cache.TryGet(key, &rv));
-  return rv;
-}
-
-template <int kKeybits>
-static size_t Has(const PackedCache<kKeybits>& cache, uintptr_t key) {
-  uint32 dummy;
-  return cache.TryGet(key, &dummy);
-}
-
-// A basic sanity test.
-void PackedCacheTest_basic() {
-  PackedCache<20> cache;
-
-  CHECK(!Has(cache, 0));
-  cache.Put(0, 17);
-  CHECK(Has(cache, 0));
-  CHECK_EQ(MustGet(cache, 0), 17);
-
-  cache.Put(19, 99);
-  CHECK_EQ(MustGet(cache, 0), 17);
-  CHECK_EQ(MustGet(cache, 19), 99);
-
-  // Knock <0, 17> out by using a conflicting key.
-  cache.Put(1 << kHashbits, 22);
-  CHECK(!Has(cache, 0));
-  CHECK_EQ(MustGet(cache, 1 << kHashbits), 22);
-
-  cache.Invalidate(19);
-  CHECK(!Has(cache, 19));
-  CHECK(!Has(cache, 0));
-  CHECK(Has(cache, 1 << kHashbits));
-}
-
-int main(int argc, char **argv) {
-  PackedCacheTest_basic();
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/page_heap_test.cc b/third_party/tcmalloc/chromium/src/tests/page_heap_test.cc
deleted file mode 100644
index e82a1da..0000000
--- a/third_party/tcmalloc/chromium/src/tests/page_heap_test.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright 2009 Google Inc. All Rights Reserved.
-// Author: fikes@google.com (Andrew Fikes)
-//
-// Use of this source code is governed by a BSD-style license that can
-// be found in the LICENSE file.
-
-#include "config_for_unittests.h"
-#include "page_heap.h"
-#include "system-alloc.h"
-#include <stdio.h>
-#include "base/logging.h"
-#include "common.h"
-
-DECLARE_int64(tcmalloc_heap_limit_mb);
-
-namespace {
-
-// The system will only release memory if the block size is equal or hight than
-// system page size.
-static bool HaveSystemRelease =
-    TCMalloc_SystemRelease(
-      TCMalloc_SystemAlloc(getpagesize(), NULL, 0), getpagesize());
-
-static void CheckStats(const tcmalloc::PageHeap* ph,
-                       uint64_t system_pages,
-                       uint64_t free_pages,
-                       uint64_t unmapped_pages) {
-  tcmalloc::PageHeap::Stats stats = ph->stats();
-
-  if (!HaveSystemRelease) {
-    free_pages += unmapped_pages;
-    unmapped_pages = 0;
-  }
-
-  EXPECT_EQ(system_pages, stats.system_bytes >> kPageShift);
-  EXPECT_EQ(free_pages, stats.free_bytes >> kPageShift);
-  EXPECT_EQ(unmapped_pages, stats.unmapped_bytes >> kPageShift);
-}
-
-static void TestPageHeap_Stats() {
-  tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();
-
-  // Empty page heap
-  CheckStats(ph, 0, 0, 0);
-
-  // Allocate a span 's1'
-  tcmalloc::Span* s1 = ph->New(256);
-  CheckStats(ph, 256, 0, 0);
-
-  // Split span 's1' into 's1', 's2'.  Delete 's2'
-  tcmalloc::Span* s2 = ph->Split(s1, 128);
-  ph->Delete(s2);
-  CheckStats(ph, 256, 128, 0);
-
-  // Unmap deleted span 's2'
-  ph->ReleaseAtLeastNPages(1);
-  CheckStats(ph, 256, 0, 128);
-
-  // Delete span 's1'
-  ph->Delete(s1);
-  CheckStats(ph, 256, 128, 128);
-
-  delete ph;
-}
-
-static void TestPageHeap_Limit() {
-  tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();
-
-  CHECK_EQ(kMaxPages, 1 << (20 - kPageShift));
-
-  // We do not know much is taken from the system for other purposes,
-  // so we detect the proper limit:
-  {
-    FLAGS_tcmalloc_heap_limit_mb = 1;
-    tcmalloc::Span* s = NULL;
-    while((s = ph->New(kMaxPages)) == NULL) {
-      FLAGS_tcmalloc_heap_limit_mb++;
-    }
-    FLAGS_tcmalloc_heap_limit_mb += 9;
-    ph->Delete(s);
-    // We are [10, 11) mb from the limit now.
-  }
-
-  // Test AllocLarge and GrowHeap first:
-  {
-    tcmalloc::Span * spans[10];
-    for (int i=0; i<10; ++i) {
-      spans[i] = ph->New(kMaxPages);
-      EXPECT_NE(spans[i], NULL);
-    }
-    EXPECT_EQ(ph->New(kMaxPages), NULL);
-
-    for (int i=0; i<10; i += 2) {
-      ph->Delete(spans[i]);
-    }
-
-    tcmalloc::Span *defragmented = ph->New(5 * kMaxPages);
-
-    if (HaveSystemRelease) {
-      // EnsureLimit should release deleted normal spans
-      EXPECT_NE(defragmented, NULL);
-      EXPECT_TRUE(ph->CheckExpensive());
-      ph->Delete(defragmented);
-    }
-    else
-    {
-      EXPECT_EQ(defragmented, NULL);
-      EXPECT_TRUE(ph->CheckExpensive());
-    }
-
-    for (int i=1; i<10; i += 2) {
-      ph->Delete(spans[i]);
-    }
-  }
-
-  // Once again, testing small lists this time (twice smaller spans):
-  {
-    tcmalloc::Span * spans[20];
-    for (int i=0; i<20; ++i) {
-      spans[i] = ph->New(kMaxPages >> 1);
-      EXPECT_NE(spans[i], NULL);
-    }
-    // one more half size allocation may be possible:
-    tcmalloc::Span * lastHalf = ph->New(kMaxPages >> 1);
-    EXPECT_EQ(ph->New(kMaxPages >> 1), NULL);
-
-    for (int i=0; i<20; i += 2) {
-      ph->Delete(spans[i]);
-    }
-
-    for(Length len = kMaxPages >> 2; len < 5 * kMaxPages; len = len << 1)
-    {
-      if(len <= kMaxPages >> 1 || HaveSystemRelease) {
-        tcmalloc::Span *s = ph->New(len);
-        EXPECT_NE(s, NULL);
-        ph->Delete(s);
-      }
-    }
-
-    EXPECT_TRUE(ph->CheckExpensive());
-
-    for (int i=1; i<20; i += 2) {
-      ph->Delete(spans[i]);
-    }
-
-    if (lastHalf != NULL) {
-      ph->Delete(lastHalf);
-    }
-  }
-
-  delete ph;
-}
-
-}  // namespace
-
-int main(int argc, char **argv) {
-  TestPageHeap_Stats();
-  TestPageHeap_Limit();
-  printf("PASS\n");
-  // on windows as part of library destructors we call getenv which
-  // calls malloc which fails due to our exhausted heap limit. It then
-  // causes fancy stack overflow because log message we're printing
-  // for failed allocation somehow cause malloc calls too
-  //
-  // To keep us out of trouble we just drop malloc limit
-  FLAGS_tcmalloc_heap_limit_mb = 0;
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/pagemap_unittest.cc b/third_party/tcmalloc/chromium/src/tests/pagemap_unittest.cc
deleted file mode 100644
index 88d46e7..0000000
--- a/third_party/tcmalloc/chromium/src/tests/pagemap_unittest.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2003, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#include <stdlib.h>
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get intptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place intptr_t might be defined
-#endif
-#include <sys/types.h>
-#include <vector>
-#include "base/logging.h"
-#include "pagemap.h"
-
-using std::vector;
-
-static void Permute(vector<intptr_t>* elements) {
-  if (elements->empty())
-    return;
-  const size_t num_elements = elements->size();
-  for (size_t i = num_elements - 1; i > 0; --i) {
-    const size_t newpos = rand() % (i + 1);
-    const intptr_t tmp = (*elements)[i];   // swap
-    (*elements)[i] = (*elements)[newpos];
-    (*elements)[newpos] = tmp;
-  }
-}
-
-// Note: we leak memory every time a map is constructed, so do not
-// create too many maps.
-
-// Test specified map type
-template <class Type>
-void TestMap(int limit, bool limit_is_below_the_overflow_boundary) {
-  RAW_LOG(INFO, "Running test with %d iterations...\n", limit);
-
-  { // Test sequential ensure/assignment
-    Type map(malloc);
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      map.Ensure(i, 1);
-      map.set(i, (void*)(i+1));
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-  }
-
-  { // Test bulk Ensure
-    Type map(malloc);
-    map.Ensure(0, limit);
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      map.set(i, (void*)(i+1));
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-  }
-
-  // Test that we correctly notice overflow
-  {
-    Type map(malloc);
-    CHECK_EQ(map.Ensure(limit, limit+1), limit_is_below_the_overflow_boundary);
-  }
-
-  { // Test randomized accesses
-    srand(301);   // srand isn't great, but it's portable
-    vector<intptr_t> elements;
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) elements.push_back(i);
-    Permute(&elements);
-
-    Type map(malloc);
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      map.Ensure(elements[i], 1);
-      map.set(elements[i], (void*)(elements[i]+1));
-      CHECK_EQ(map.get(elements[i]), (void*)(elements[i]+1));
-    }
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-  }
-}
-
-// REQUIRES: BITS==10, i.e., valid range is [0,1023].
-// Representations for different types will end up being:
-//    PageMap1: array[1024]
-//    PageMap2: array[32][32]
-//    PageMap3: array[16][16][4]
-template <class Type>
-void TestNext(const char* name) {
-  RAW_LOG(ERROR, "Running NextTest %s\n", name);
-  Type map(malloc);
-  char a, b, c, d, e;
-
-  // When map is empty
-  CHECK(map.Next(0) == NULL);
-  CHECK(map.Next(5) == NULL);
-  CHECK(map.Next(1<<30) == NULL);
-
-  // Add a single value
-  map.Ensure(40, 1);
-  map.set(40, &a);
-  CHECK(map.Next(0) == &a);
-  CHECK(map.Next(39) == &a);
-  CHECK(map.Next(40) == &a);
-  CHECK(map.Next(41) == NULL);
-  CHECK(map.Next(1<<30) == NULL);
-
-  // Add a few values
-  map.Ensure(41, 1);
-  map.Ensure(100, 3);
-  map.set(41, &b);
-  map.set(100, &c);
-  map.set(101, &d);
-  map.set(102, &e);
-  CHECK(map.Next(0) == &a);
-  CHECK(map.Next(39) == &a);
-  CHECK(map.Next(40) == &a);
-  CHECK(map.Next(41) == &b);
-  CHECK(map.Next(42) == &c);
-  CHECK(map.Next(63) == &c);
-  CHECK(map.Next(64) == &c);
-  CHECK(map.Next(65) == &c);
-  CHECK(map.Next(99) == &c);
-  CHECK(map.Next(100) == &c);
-  CHECK(map.Next(101) == &d);
-  CHECK(map.Next(102) == &e);
-  CHECK(map.Next(103) == NULL);
-}
-
-int main(int argc, char** argv) {
-  TestMap< TCMalloc_PageMap1<10> > (100, true);
-  TestMap< TCMalloc_PageMap1<10> > (1 << 10, false);
-  TestMap< TCMalloc_PageMap2<20> > (100, true);
-  TestMap< TCMalloc_PageMap2<20> > (1 << 20, false);
-  TestMap< TCMalloc_PageMap3<20> > (100, true);
-  TestMap< TCMalloc_PageMap3<20> > (1 << 20, false);
-
-  TestNext< TCMalloc_PageMap1<10> >("PageMap1");
-  TestNext< TCMalloc_PageMap2<10> >("PageMap2");
-  TestNext< TCMalloc_PageMap3<10> >("PageMap3");
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/profile-handler_unittest.cc b/third_party/tcmalloc/chromium/src/tests/profile-handler_unittest.cc
deleted file mode 100644
index a8afbca..0000000
--- a/third_party/tcmalloc/chromium/src/tests/profile-handler_unittest.cc
+++ /dev/null
@@ -1,398 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright 2009 Google Inc. All Rights Reserved.
-// Author: Nabeel Mian (nabeelmian@google.com)
-//         Chris Demetriou (cgd@google.com)
-//
-// Use of this source code is governed by a BSD-style license that can
-// be found in the LICENSE file.
-//
-//
-// This file contains the unit tests for profile-handler.h interface.
-
-#include "config.h"
-#include "profile-handler.h"
-
-#include <assert.h>
-#include <pthread.h>
-#include <sys/time.h>
-#include <time.h>
-#include "base/logging.h"
-#include "base/simple_mutex.h"
-
-// Some helpful macros for the test class
-#define TEST_F(cls, fn)    void cls :: fn()
-
-// Do we expect the profiler to be enabled?
-DEFINE_bool(test_profiler_enabled, true,
-            "expect profiler to be enabled during tests");
-
-namespace {
-
-// TODO(csilvers): error-checking on the pthreads routines
-class Thread {
- public:
-  Thread() : joinable_(false) { }
-  virtual ~Thread() { }
-  void SetJoinable(bool value) { joinable_ = value; }
-  void Start() {
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-    pthread_attr_setdetachstate(&attr, joinable_ ? PTHREAD_CREATE_JOINABLE
-                                                 : PTHREAD_CREATE_DETACHED);
-    pthread_create(&thread_, &attr, &DoRun, this);
-    pthread_attr_destroy(&attr);
-  }
-  void Join()  {
-    assert(joinable_);
-    pthread_join(thread_, NULL);
-  }
-  virtual void Run() = 0;
- private:
-  static void* DoRun(void* cls) {
-    ProfileHandlerRegisterThread();
-    reinterpret_cast<Thread*>(cls)->Run();
-    return NULL;
-  }
-  pthread_t thread_;
-  bool joinable_;
-};
-
-// Sleep interval in nano secs. ITIMER_PROF goes off only afer the specified CPU
-// time is consumed. Under heavy load this process may no get scheduled in a
-// timely fashion. Therefore, give enough time (20x of ProfileHandle timer
-// interval 10ms (100Hz)) for this process to accumulate enought CPU time to get
-// a profile tick.
-int kSleepInterval = 200000000;
-
-// Sleep interval in nano secs. To ensure that if the timer has expired it is
-// reset.
-int kTimerResetInterval = 5000000;
-
-static bool linux_per_thread_timers_mode_ = false;
-static int timer_type_ = ITIMER_PROF;
-
-// Delays processing by the specified number of nano seconds. 'delay_ns'
-// must be less than the number of nano seconds in a second (1000000000).
-void Delay(int delay_ns) {
-  static const int kNumNSecInSecond = 1000000000;
-  EXPECT_LT(delay_ns, kNumNSecInSecond);
-  struct timespec delay = { 0, delay_ns };
-  nanosleep(&delay, 0);
-}
-
-// Checks whether the profile timer is enabled for the current thread.
-bool IsTimerEnabled() {
-  itimerval current_timer;
-  EXPECT_EQ(0, getitimer(timer_type_, &current_timer));
-  if ((current_timer.it_value.tv_sec == 0) &&
-      (current_timer.it_value.tv_usec != 0)) {
-    // May be the timer has expired. Sleep for a bit and check again.
-    Delay(kTimerResetInterval);
-    EXPECT_EQ(0, getitimer(timer_type_, &current_timer));
-  }
-  return (current_timer.it_value.tv_sec != 0 ||
-          current_timer.it_value.tv_usec != 0);
-}
-
-// Dummy worker thread to accumulate cpu time.
-class BusyThread : public Thread {
- public:
-  BusyThread() : stop_work_(false) {
-  }
-
-  // Setter/Getters
-  bool stop_work() {
-    MutexLock lock(&mu_);
-    return stop_work_;
-  }
-  void set_stop_work(bool stop_work) {
-    MutexLock lock(&mu_);
-    stop_work_ = stop_work;
-  }
-
- private:
-  // Protects stop_work_ below.
-  Mutex mu_;
-  // Whether to stop work?
-  bool stop_work_;
-
-  // Do work until asked to stop.
-  void Run() {
-    while (!stop_work()) {
-    }
-  }
-};
-
-class NullThread : public Thread {
- private:
-  void Run() {
-  }
-};
-
-// Signal handler which tracks the profile timer ticks.
-static void TickCounter(int sig, siginfo_t* sig_info, void *vuc,
-                        void* tick_counter) {
-  int* counter = static_cast<int*>(tick_counter);
-  ++(*counter);
-}
-
-// This class tests the profile-handler.h interface.
-class ProfileHandlerTest {
- protected:
-
-  // Determines the timer type.
-  static void SetUpTestCase() {
-    timer_type_ = (getenv("CPUPROFILE_REALTIME") ? ITIMER_REAL : ITIMER_PROF);
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-    linux_per_thread_timers_mode_ = (getenv("CPUPROFILE_PER_THREAD_TIMERS") != NULL);
-    const char *signal_number = getenv("CPUPROFILE_TIMER_SIGNAL");
-    if (signal_number) {
-      //signal_number_ = strtol(signal_number, NULL, 0);
-      linux_per_thread_timers_mode_ = true;
-      Delay(kTimerResetInterval);
-    }
-#endif
-  }
-
-  // Sets up the profile timers and SIGPROF/SIGALRM handler in a known state.
-  // It does the following:
-  // 1. Unregisters all the callbacks, stops the timer and clears out
-  //    timer_sharing state in the ProfileHandler. This clears out any state
-  //    left behind by the previous test or during module initialization when
-  //    the test program was started.
-  // 3. Starts a busy worker thread to accumulate CPU usage.
-  virtual void SetUp() {
-    // Reset the state of ProfileHandler between each test. This unregisters
-    // all callbacks and stops the timer.
-    ProfileHandlerReset();
-    EXPECT_EQ(0, GetCallbackCount());
-    VerifyDisabled();
-    // Start worker to accumulate cpu usage.
-    StartWorker();
-  }
-
-  virtual void TearDown() {
-    ProfileHandlerReset();
-    // Stops the worker thread.
-    StopWorker();
-  }
-
-  // Starts a busy worker thread to accumulate cpu time. There should be only
-  // one busy worker running. This is required for the case where there are
-  // separate timers for each thread.
-  void StartWorker() {
-    busy_worker_ = new BusyThread();
-    busy_worker_->SetJoinable(true);
-    busy_worker_->Start();
-    // Wait for worker to start up and register with the ProfileHandler.
-    // TODO(nabeelmian) This may not work under very heavy load.
-    Delay(kSleepInterval);
-  }
-
-  // Stops the worker thread.
-  void StopWorker() {
-    busy_worker_->set_stop_work(true);
-    busy_worker_->Join();
-    delete busy_worker_;
-  }
-
-  // Gets the number of callbacks registered with the ProfileHandler.
-  uint32 GetCallbackCount() {
-    ProfileHandlerState state;
-    ProfileHandlerGetState(&state);
-    return state.callback_count;
-  }
-
-  // Gets the current ProfileHandler interrupt count.
-  uint64 GetInterruptCount() {
-    ProfileHandlerState state;
-    ProfileHandlerGetState(&state);
-    return state.interrupts;
-  }
-
-  // Verifies that a callback is correctly registered and receiving
-  // profile ticks.
-  void VerifyRegistration(const int& tick_counter) {
-    // Check the callback count.
-    EXPECT_GT(GetCallbackCount(), 0);
-    // Check that the profile timer is enabled.
-    EXPECT_EQ(FLAGS_test_profiler_enabled, linux_per_thread_timers_mode_ || IsTimerEnabled());
-    uint64 interrupts_before = GetInterruptCount();
-    // Sleep for a bit and check that tick counter is making progress.
-    int old_tick_count = tick_counter;
-    Delay(kSleepInterval);
-    int new_tick_count = tick_counter;
-    uint64 interrupts_after = GetInterruptCount();
-    if (FLAGS_test_profiler_enabled) {
-      EXPECT_GT(new_tick_count, old_tick_count);
-      EXPECT_GT(interrupts_after, interrupts_before);
-    } else {
-      EXPECT_EQ(new_tick_count, old_tick_count);
-      EXPECT_EQ(interrupts_after, interrupts_before);
-    }
-  }
-
-  // Verifies that a callback is not receiving profile ticks.
-  void VerifyUnregistration(const int& tick_counter) {
-    // Sleep for a bit and check that tick counter is not making progress.
-    int old_tick_count = tick_counter;
-    Delay(kSleepInterval);
-    int new_tick_count = tick_counter;
-    EXPECT_EQ(old_tick_count, new_tick_count);
-    // If no callbacks, timer should be disabled.
-    if (GetCallbackCount() == 0) {
-      EXPECT_FALSE(IsTimerEnabled());
-    }
-  }
-
-  // Verifies that the timer is disabled. Expects the worker to be running.
-  void VerifyDisabled() {
-    // Check that the callback count is 0.
-    EXPECT_EQ(0, GetCallbackCount());
-    // Check that the timer is disabled.
-    EXPECT_FALSE(IsTimerEnabled());
-    // Verify that the ProfileHandler is not accumulating profile ticks.
-    uint64 interrupts_before = GetInterruptCount();
-    Delay(kSleepInterval);
-    uint64 interrupts_after = GetInterruptCount();
-    EXPECT_EQ(interrupts_before, interrupts_after);
-  }
-
-  // Registers a callback and waits for kTimerResetInterval for timers to get
-  // reset.
-  ProfileHandlerToken* RegisterCallback(void* callback_arg) {
-    ProfileHandlerToken* token = ProfileHandlerRegisterCallback(
-        TickCounter, callback_arg);
-    Delay(kTimerResetInterval);
-    return token;
-  }
-
-  // Unregisters a callback and waits for kTimerResetInterval for timers to get
-  // reset.
-  void UnregisterCallback(ProfileHandlerToken* token) {
-    ProfileHandlerUnregisterCallback(token);
-    Delay(kTimerResetInterval);
-  }
-
-  // Busy worker thread to accumulate cpu usage.
-  BusyThread* busy_worker_;
-
- private:
-  // The tests to run
-  void RegisterUnregisterCallback();
-  void MultipleCallbacks();
-  void Reset();
-  void RegisterCallbackBeforeThread();
-
- public:
-#define RUN(test)  do {                         \
-    printf("Running %s\n", #test);              \
-    ProfileHandlerTest pht;                     \
-    pht.SetUp();                                \
-    pht.test();                                 \
-    pht.TearDown();                             \
-} while (0)
-
-  static int RUN_ALL_TESTS() {
-    SetUpTestCase();
-    RUN(RegisterUnregisterCallback);
-    RUN(MultipleCallbacks);
-    RUN(Reset);
-    RUN(RegisterCallbackBeforeThread);
-    printf("Done\n");
-    return 0;
-  }
-};
-
-// Verifies ProfileHandlerRegisterCallback and
-// ProfileHandlerUnregisterCallback.
-TEST_F(ProfileHandlerTest, RegisterUnregisterCallback) {
-  int tick_count = 0;
-  ProfileHandlerToken* token = RegisterCallback(&tick_count);
-  VerifyRegistration(tick_count);
-  UnregisterCallback(token);
-  VerifyUnregistration(tick_count);
-}
-
-// Verifies that multiple callbacks can be registered.
-TEST_F(ProfileHandlerTest, MultipleCallbacks) {
-  // Register first callback.
-  int first_tick_count = 0;
-  ProfileHandlerToken* token1 = RegisterCallback(&first_tick_count);
-  // Check that callback was registered correctly.
-  VerifyRegistration(first_tick_count);
-  EXPECT_EQ(1, GetCallbackCount());
-
-  // Register second callback.
-  int second_tick_count = 0;
-  ProfileHandlerToken* token2 = RegisterCallback(&second_tick_count);
-  // Check that callback was registered correctly.
-  VerifyRegistration(second_tick_count);
-  EXPECT_EQ(2, GetCallbackCount());
-
-  // Unregister first callback.
-  UnregisterCallback(token1);
-  VerifyUnregistration(first_tick_count);
-  EXPECT_EQ(1, GetCallbackCount());
-  // Verify that second callback is still registered.
-  VerifyRegistration(second_tick_count);
-
-  // Unregister second callback.
-  UnregisterCallback(token2);
-  VerifyUnregistration(second_tick_count);
-  EXPECT_EQ(0, GetCallbackCount());
-
-  // Verify that the timers is correctly disabled.
-  if (!linux_per_thread_timers_mode_) VerifyDisabled();
-}
-
-// Verifies ProfileHandlerReset
-TEST_F(ProfileHandlerTest, Reset) {
-  // Verify that the profile timer interrupt is disabled.
-  if (!linux_per_thread_timers_mode_) VerifyDisabled();
-  int first_tick_count = 0;
-  RegisterCallback(&first_tick_count);
-  VerifyRegistration(first_tick_count);
-  EXPECT_EQ(1, GetCallbackCount());
-
-  // Register second callback.
-  int second_tick_count = 0;
-  RegisterCallback(&second_tick_count);
-  VerifyRegistration(second_tick_count);
-  EXPECT_EQ(2, GetCallbackCount());
-
-  // Reset the profile handler and verify that callback were correctly
-  // unregistered and the timer is disabled.
-  ProfileHandlerReset();
-  VerifyUnregistration(first_tick_count);
-  VerifyUnregistration(second_tick_count);
-  if (!linux_per_thread_timers_mode_) VerifyDisabled();
-}
-
-// Verifies that ProfileHandler correctly handles a case where a callback was
-// registered before the second thread started.
-TEST_F(ProfileHandlerTest, RegisterCallbackBeforeThread) {
-  // Stop the worker.
-  StopWorker();
-  // Unregister all existing callbacks and stop the timer.
-  ProfileHandlerReset();
-  EXPECT_EQ(0, GetCallbackCount());
-  VerifyDisabled();
-
-  // Start the worker.
-  StartWorker();
-  // Register a callback and check that profile ticks are being delivered and
-  // the timer is enabled.
-  int tick_count = 0;
-  RegisterCallback(&tick_count);
-  EXPECT_EQ(1, GetCallbackCount());
-  VerifyRegistration(tick_count);
-  EXPECT_EQ(FLAGS_test_profiler_enabled, linux_per_thread_timers_mode_ || IsTimerEnabled());
-}
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  return ProfileHandlerTest::RUN_ALL_TESTS();
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/profiledata_unittest.cc b/third_party/tcmalloc/chromium/src/tests/profiledata_unittest.cc
deleted file mode 100644
index 3286b9c8..0000000
--- a/third_party/tcmalloc/chromium/src/tests/profiledata_unittest.cc
+++ /dev/null
@@ -1,612 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Chris Demetriou
-//
-// This file contains the unit tests for the ProfileData class.
-
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uintptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uintptr_t might be defined
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <string.h>
-#include <string>
-
-#include "profiledata.h"
-
-#include "base/commandlineflags.h"
-#include "base/logging.h"
-
-using std::string;
-
-// Some helpful macros for the test class
-#define TEST_F(cls, fn)    void cls :: fn()
-
-namespace {
-
-template<typename T> class scoped_array {
- public:
-  scoped_array(T* data) : data_(data) { }
-  ~scoped_array() { delete[] data_; }
-  T* get() { return data_; }
-  T& operator[](int i) { return data_[i]; }
- private:
-  T* const data_;
-};
-
-// Re-runs fn until it doesn't cause EINTR.
-#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
-
-// Read up to "count" bytes from file descriptor "fd" into the buffer
-// starting at "buf" while handling short reads and EINTR.  On
-// success, return the number of bytes read.  Otherwise, return -1.
-static ssize_t ReadPersistent(const int fd, void *buf, const size_t count) {
-  CHECK_GE(fd, 0);
-  char *buf0 = reinterpret_cast<char *>(buf);
-  ssize_t num_bytes = 0;
-  while (num_bytes < count) {
-    ssize_t len;
-    NO_INTR(len = read(fd, buf0 + num_bytes, count - num_bytes));
-    if (len < 0) {  // There was an error other than EINTR.
-      return -1;
-    }
-    if (len == 0) {  // Reached EOF.
-      break;
-    }
-    num_bytes += len;
-  }
-  CHECK(num_bytes <= count);
-  return num_bytes;
-}
-
-// Thin wrapper around a file descriptor so that the file descriptor
-// gets closed for sure.
-struct FileDescriptor {
-  const int fd_;
-  explicit FileDescriptor(int fd) : fd_(fd) {}
-  ~FileDescriptor() {
-    if (fd_ >= 0) {
-      NO_INTR(close(fd_));
-    }
-  }
-  int get() { return fd_; }
-};
-
-// must be the same as with ProfileData::Slot.
-typedef uintptr_t ProfileDataSlot;
-
-// Quick and dirty function to make a number into a void* for use in a
-// sample.
-inline void* V(intptr_t x) { return reinterpret_cast<void*>(x); }
-
-// String returned by ProfileDataChecker helper functions to indicate success.
-const char kNoError[] = "";
-
-class ProfileDataChecker {
- public:
-  ProfileDataChecker() {
-    const char* tmpdir = getenv("TMPDIR");
-    if (tmpdir == NULL)
-      tmpdir = "/tmp";
-    mkdir(tmpdir, 0755);     // if necessary
-    filename_ = string(tmpdir) + "/profiledata_unittest.tmp";
-  }
-
-  string filename() const { return filename_; }
-
-  // Checks the first 'num_slots' profile data slots in the file
-  // against the data pointed to by 'slots'.  Returns kNoError if the
-  // data matched, otherwise returns an indication of the cause of the
-  // mismatch.
-  string Check(const ProfileDataSlot* slots, int num_slots) {
-    return CheckWithSkips(slots, num_slots, NULL, 0);
-  }
-
-  // Checks the first 'num_slots' profile data slots in the file
-  // against the data pointed to by 'slots', skipping over entries
-  // described by 'skips' and 'num_skips'.
-  //
-  // 'skips' must be a sorted list of (0-based) slot numbers to be
-  // skipped, of length 'num_skips'.  Note that 'num_slots' includes
-  // any skipped slots, i.e., the first 'num_slots' profile data slots
-  // will be considered, but some may be skipped.
-  //
-  // Returns kNoError if the data matched, otherwise returns an
-  // indication of the cause of the mismatch.
-  string CheckWithSkips(const ProfileDataSlot* slots, int num_slots,
-                        const int* skips, int num_skips);
-
-  // Validate that a profile is correctly formed.  The profile is
-  // assumed to have been created by the same kind of binary (e.g.,
-  // same slot size, same endian, etc.) as is validating the profile.
-  //
-  // Returns kNoError if the profile appears valid, otherwise returns
-  // an indication of the problem with the profile.
-  string ValidateProfile();
-
- private:
-  string filename_;
-};
-
-string ProfileDataChecker::CheckWithSkips(const ProfileDataSlot* slots,
-                                          int num_slots, const int* skips,
-                                          int num_skips) {
-  FileDescriptor fd(open(filename_.c_str(), O_RDONLY));
-  if (fd.get() < 0)
-    return "file open error";
-
-  scoped_array<ProfileDataSlot> filedata(new ProfileDataSlot[num_slots]);
-  size_t expected_bytes = num_slots * sizeof filedata[0];
-  ssize_t bytes_read = ReadPersistent(fd.get(), filedata.get(), expected_bytes);
-  if (expected_bytes != bytes_read)
-    return "file too small";
-
-  for (int i = 0; i < num_slots; i++) {
-    if (num_skips > 0 && *skips == i) {
-      num_skips--;
-      skips++;
-      continue;
-    }
-    if (slots[i] != filedata[i])
-      return "data mismatch";
-  }
-  return kNoError;
-}
-
-string ProfileDataChecker::ValidateProfile() {
-  FileDescriptor fd(open(filename_.c_str(), O_RDONLY));
-  if (fd.get() < 0)
-    return "file open error";
-
-  struct stat statbuf;
-  if (fstat(fd.get(), &statbuf) != 0)
-    return "fstat error";
-  if (statbuf.st_size != static_cast<ssize_t>(statbuf.st_size))
-    return "file impossibly large";
-  ssize_t filesize = statbuf.st_size;
-
-  scoped_array<char> filedata(new char[filesize]);
-  if (ReadPersistent(fd.get(), filedata.get(), filesize) != filesize)
-    return "read of whole file failed";
-
-  // Must have enough data for the header and the trailer.
-  if (filesize < (5 + 3) * sizeof(ProfileDataSlot))
-    return "not enough data in profile for header + trailer";
-
-  // Check the header
-  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[0] != 0)
-    return "error in header: non-zero count";
-  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[1] != 3)
-    return "error in header: num_slots != 3";
-  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[2] != 0)
-    return "error in header: non-zero format version";
-  // Period (slot 3) can have any value.
-  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[4] != 0)
-    return "error in header: non-zero padding value";
-  ssize_t cur_offset = 5 * sizeof(ProfileDataSlot);
-
-  // While there are samples, skip them.  Each sample consists of
-  // at least three slots.
-  bool seen_trailer = false;
-  while (!seen_trailer) {
-    if (cur_offset > filesize - 3 * sizeof(ProfileDataSlot))
-      return "truncated sample header";
-    ProfileDataSlot* sample =
-        reinterpret_cast<ProfileDataSlot*>(filedata.get() + cur_offset);
-    ProfileDataSlot slots_this_sample = 2 + sample[1];
-    ssize_t size_this_sample = slots_this_sample * sizeof(ProfileDataSlot);
-    if (cur_offset > filesize - size_this_sample)
-      return "truncated sample";
-
-    if (sample[0] == 0 && sample[1] == 1 && sample[2] == 0) {
-      seen_trailer = true;
-    } else {
-      if (sample[0] < 1)
-        return "error in sample: sample count < 1";
-      if (sample[1] < 1)
-        return "error in sample: num_pcs < 1";
-      for (int i = 2; i < slots_this_sample; i++) {
-        if (sample[i] == 0)
-          return "error in sample: NULL PC";
-      }
-    }
-    cur_offset += size_this_sample;
-  }
-
-  // There must be at least one line in the (text) list of mapped objects,
-  // and it must be terminated by a newline.  Note, the use of newline
-  // here and below Might not be reasonable on non-UNIX systems.
-  if (cur_offset >= filesize)
-    return "no list of mapped objects";
-  if (filedata[filesize - 1] != '\n')
-    return "profile did not end with a complete line";
-
-  while (cur_offset < filesize) {
-    char* line_start = filedata.get() + cur_offset;
-
-    // Find the end of the line, and replace it with a NUL for easier
-    // scanning.
-    char* line_end = strchr(line_start, '\n');
-    *line_end = '\0';
-
-    // Advance past any leading space.  It's allowed in some lines,
-    // but not in others.
-    bool has_leading_space = false;
-    char* line_cur = line_start;
-    while (*line_cur == ' ') {
-      has_leading_space = true;
-      line_cur++;
-    }
-
-    bool found_match = false;
-
-    // Check for build lines.
-    if (!found_match) {
-      found_match = (strncmp(line_cur, "build=", 6) == 0);
-      // Anything may follow "build=", and leading space is allowed.
-    }
-
-    // A line from ProcMapsIterator::FormatLine, of the form:
-    //
-    // 40000000-40015000 r-xp 00000000 03:01 12845071   /lib/ld-2.3.2.so
-    //
-    // Leading space is not allowed.  The filename may be omitted or
-    // may consist of multiple words, so we scan only up to the
-    // space before the filename.
-    if (!found_match) {
-      int chars_scanned = -1;
-      sscanf(line_cur, "%*x-%*x %*c%*c%*c%*c %*x %*x:%*x %*d %n",
-             &chars_scanned);
-      found_match = (chars_scanned > 0 && !has_leading_space);
-    }
-
-    // A line from DumpAddressMap, of the form:
-    //
-    // 40000000-40015000: /lib/ld-2.3.2.so
-    //
-    // Leading space is allowed.  The filename may be omitted or may
-    // consist of multiple words, so we scan only up to the space
-    // before the filename.
-    if (!found_match) {
-      int chars_scanned = -1;
-      sscanf(line_cur, "%*x-%*x: %n", &chars_scanned);
-      found_match = (chars_scanned > 0);
-    }
-
-    if (!found_match)
-      return "unrecognized line in text section";
-
-    cur_offset += (line_end - line_start) + 1;
-  }
-
-  return kNoError;
-}
-
-class ProfileDataTest {
- protected:
-  void ExpectStopped() {
-    EXPECT_FALSE(collector_.enabled());
-  }
-
-  void ExpectRunningSamples(int samples) {
-    ProfileData::State state;
-    collector_.GetCurrentState(&state);
-    EXPECT_TRUE(state.enabled);
-    EXPECT_EQ(samples, state.samples_gathered);
-  }
-
-  void ExpectSameState(const ProfileData::State& before,
-                       const ProfileData::State& after) {
-    EXPECT_EQ(before.enabled, after.enabled);
-    EXPECT_EQ(before.samples_gathered, after.samples_gathered);
-    EXPECT_EQ(before.start_time, after.start_time);
-    EXPECT_STREQ(before.profile_name, after.profile_name);
-  }
-
-  ProfileData        collector_;
-  ProfileDataChecker checker_;
-
- private:
-  // The tests to run
-  void OpsWhenStopped();
-  void StartStopEmpty();
-  void StartStopNoOptionsEmpty();
-  void StartWhenStarted();
-  void StartStopEmpty2();
-  void CollectOne();
-  void CollectTwoMatching();
-  void CollectTwoFlush();
-  void StartResetRestart();
-
- public:
-#define RUN(test)  do {                         \
-    printf("Running %s\n", #test);              \
-    ProfileDataTest pdt;                        \
-    pdt.test();                                 \
-} while (0)
-
-  static int RUN_ALL_TESTS() {
-    RUN(OpsWhenStopped);
-    RUN(StartStopEmpty);
-    RUN(StartWhenStarted);
-    RUN(StartStopEmpty2);
-    RUN(CollectOne);
-    RUN(CollectTwoMatching);
-    RUN(CollectTwoFlush);
-    RUN(StartResetRestart);
-    RUN(StartStopNoOptionsEmpty);
-    return 0;
-  }
-};
-
-// Check that various operations are safe when stopped.
-TEST_F(ProfileDataTest, OpsWhenStopped) {
-  ExpectStopped();
-  EXPECT_FALSE(collector_.enabled());
-
-  // Verify that state is disabled, all-empty/all-0
-  ProfileData::State state_before;
-  collector_.GetCurrentState(&state_before);
-  EXPECT_FALSE(state_before.enabled);
-  EXPECT_EQ(0, state_before.samples_gathered);
-  EXPECT_EQ(0, state_before.start_time);
-  EXPECT_STREQ("", state_before.profile_name);
-
-  // Safe to call stop again.
-  collector_.Stop();
-
-  // Safe to call FlushTable.
-  collector_.FlushTable();
-
-  // Safe to call Add.
-  const void *trace[] = { V(100), V(101), V(102), V(103), V(104) };
-  collector_.Add(arraysize(trace), trace);
-
-  ProfileData::State state_after;
-  collector_.GetCurrentState(&state_after);
-
-  ExpectSameState(state_before, state_after);
-}
-
-// Start and Stop, collecting no samples.  Verify output contents.
-TEST_F(ProfileDataTest, StartStopEmpty) {
-  const int frequency = 1;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-// Start and Stop with no options, collecting no samples.  Verify
-// output contents.
-TEST_F(ProfileDataTest, StartStopNoOptionsEmpty) {
-  // We're not requesting a specific period, implementation can do
-  // whatever it likes.
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 0 /* skipped */, 0,        // binary header
-    0, 1, 0                             // binary trailer
-  };
-  int slots_to_skip[] = { 3 };
-
-  ExpectStopped();
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(),
-                               ProfileData::Options()));
-  ExpectRunningSamples(0);
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.CheckWithSkips(slots, arraysize(slots),
-                                              slots_to_skip,
-                                              arraysize(slots_to_skip)));
-}
-
-// Start after already started.  Should return false and not impact
-// collected data or state.
-TEST_F(ProfileDataTest, StartWhenStarted) {
-  const int frequency = 1;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    0, 1, 0                             // binary trailer
-  };
-
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-
-  ProfileData::State state_before;
-  collector_.GetCurrentState(&state_before);
-
-  options.set_frequency(frequency * 2);
-  CHECK(!collector_.Start("foobar", options));
-
-  ProfileData::State state_after;
-  collector_.GetCurrentState(&state_after);
-  ExpectSameState(state_before, state_after);
-
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-// Like StartStopEmpty, but uses a different file name and frequency.
-TEST_F(ProfileDataTest, StartStopEmpty2) {
-  const int frequency = 2;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-TEST_F(ProfileDataTest, CollectOne) {
-  const int frequency = 2;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    1, 5, 100, 101, 102, 103, 104,      // our sample
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-
-  const void *trace[] = { V(100), V(101), V(102), V(103), V(104) };
-  collector_.Add(arraysize(trace), trace);
-  ExpectRunningSamples(1);
-
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-TEST_F(ProfileDataTest, CollectTwoMatching) {
-  const int frequency = 2;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    2, 5, 100, 201, 302, 403, 504,      // our two samples
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-
-  for (int i = 0; i < 2; ++i) {
-    const void *trace[] = { V(100), V(201), V(302), V(403), V(504) };
-    collector_.Add(arraysize(trace), trace);
-    ExpectRunningSamples(i + 1);
-  }
-
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-TEST_F(ProfileDataTest, CollectTwoFlush) {
-  const int frequency = 2;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    1, 5, 100, 201, 302, 403, 504,      // first sample (flushed)
-    1, 5, 100, 201, 302, 403, 504,      // second identical sample
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-
-  const void *trace[] = { V(100), V(201), V(302), V(403), V(504) };
-
-  collector_.Add(arraysize(trace), trace);
-  ExpectRunningSamples(1);
-  collector_.FlushTable();
-
-  collector_.Add(arraysize(trace), trace);
-  ExpectRunningSamples(2);
-
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-// Start then reset, verify that the result is *not* a valid profile.
-// Then start again and make sure the result is OK.
-TEST_F(ProfileDataTest, StartResetRestart) {
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(1);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-  collector_.Reset();
-  ExpectStopped();
-  // We expect the resulting file to be empty.  This is a minimal test
-  // of ValidateProfile.
-  EXPECT_NE(kNoError, checker_.ValidateProfile());
-
-  struct stat statbuf;
-  EXPECT_EQ(0, stat(checker_.filename().c_str(), &statbuf));
-  EXPECT_EQ(0, statbuf.st_size);
-
-  const int frequency = 2;  // Different frequency than used above.
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    0, 1, 0                             // binary trailer
-  };
-
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  int rc = ProfileDataTest::RUN_ALL_TESTS();
-  printf("%s\n", rc == 0 ? "PASS" : "FAIL");
-  return rc;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/profiler_unittest.cc b/third_party/tcmalloc/chromium/src/tests/profiler_unittest.cc
deleted file mode 100644
index dfc653f0..0000000
--- a/third_party/tcmalloc/chromium/src/tests/profiler_unittest.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// Does some simple arithmetic and a few libc routines, so we can profile it.
-// Define WITH_THREADS to add pthread functionality as well (otherwise, btw,
-// the num_threads argument to this program is ingored).
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                 // for fork()
-#endif
-#include <sys/wait.h>               // for wait()
-#include "gperftools/profiler.h"
-#include "base/simple_mutex.h"
-#include "tests/testutil.h"
-
-static volatile int result = 0;
-static int g_iters = 0;   // argv[1]
-
-Mutex mutex(Mutex::LINKER_INITIALIZED);
-
-static void test_other_thread() {
-#ifndef NO_THREADS
-  ProfilerRegisterThread();
-
-  int i, m;
-  char b[128];
-  MutexLock ml(&mutex);
-  for (m = 0; m < 1000000; ++m) {          // run millions of times
-    for (i = 0; i < g_iters; ++i ) {
-      result ^= i;
-    }
-    snprintf(b, sizeof(b), "other: %d", result);  // get some libc action
-  }
-#endif
-}
-
-static void test_main_thread() {
-  int i, m;
-  char b[128];
-  MutexLock ml(&mutex);
-  for (m = 0; m < 1000000; ++m) {          // run millions of times
-    for (i = 0; i < g_iters; ++i ) {
-      result ^= i;
-    }
-    snprintf(b, sizeof(b), "same: %d", result);  // get some libc action
-  }
-}
-
-int main(int argc, char** argv) {
-  if ( argc <= 1 ) {
-    fprintf(stderr, "USAGE: %s <iters> [num_threads] [filename]\n", argv[0]);
-    fprintf(stderr, "   iters: How many million times to run the XOR test.\n");
-    fprintf(stderr, "   num_threads: how many concurrent threads.\n");
-    fprintf(stderr, "                0 or 1 for single-threaded mode,\n");
-    fprintf(stderr, "                -# to fork instead of thread.\n");
-    fprintf(stderr, "   filename: The name of the output profile.\n");
-    fprintf(stderr, ("             If you don't specify, set CPUPROFILE "
-                     "in the environment instead!\n"));
-    return 1;
-  }
-
-  g_iters = atoi(argv[1]);
-  int num_threads = 1;
-  const char* filename = NULL;
-  if (argc > 2) {
-    num_threads = atoi(argv[2]);
-  }
-  if (argc > 3) {
-    filename = argv[3];
-  }
-
-  if (filename) {
-    ProfilerStart(filename);
-  }
-
-  test_main_thread();
-
-  ProfilerFlush();                           // just because we can
-
-  // The other threads, if any, will run only half as long as the main thread
-  if(num_threads > 0) {
-    RunManyThreads(test_other_thread, num_threads);
-  } else {
-  // Or maybe they asked to fork.  The fork test is only interesting
-  // when we use CPUPROFILE to name, so check for that
-#ifdef HAVE_UNISTD_H
-    for (; num_threads < 0; ++num_threads) {   // -<num_threads> to fork
-      if (filename) {
-        printf("FORK test only makes sense when no filename is specified.\n");
-        return 2;
-      }
-      switch (fork()) {
-        case -1:
-          printf("FORK failed!\n");
-          return 1;
-        case 0:             // child
-          return execl(argv[0], argv[0], argv[1], NULL);
-        default:
-          wait(NULL);       // we'll let the kids run one at a time
-      }
-    }
-#else
-    fprintf(stderr, "%s was compiled without support for fork() and exec()\n", argv[0]);
-#endif
-  }
-
-  test_main_thread();
-
-  if (filename) {
-    ProfilerStop();
-  }
-
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/profiler_unittest.sh b/third_party/tcmalloc/chromium/src/tests/profiler_unittest.sh
deleted file mode 100755
index 4085f2c..0000000
--- a/third_party/tcmalloc/chromium/src/tests/profiler_unittest.sh
+++ /dev/null
@@ -1,269 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2005, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Craig Silverstein
-#
-# Runs the 4 profiler unittests and makes sure their profiles look
-# appropriate.  We expect two commandline args, as described below.
-#
-# We run under the assumption that if $PROFILER1 is run with no
-# arguments, it prints a usage line of the form
-#   USAGE: <actual executable being run> [...]
-#
-# This is because libtool sometimes turns the 'executable' into a
-# shell script which runs an actual binary somewhere else.
-
-# We expect BINDIR and PPROF_PATH to be set in the environment.
-# If not, we set them to some reasonable values
-BINDIR="${BINDIR:-.}"
-PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir] [path to pprof]"
-  echo "       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
-  exit 1
-fi
-
-TMPDIR=/tmp/profile_info
-
-UNITTEST_DIR=${1:-$BINDIR}
-PPROF=${2:-$PPROF_PATH}
-
-# We test the sliding-window functionality of the cpu-profile reader
-# by using a small stride, forcing lots of reads.
-PPROF_FLAGS="--test_stride=128"
-
-PROFILER1="$UNITTEST_DIR/profiler1_unittest"
-PROFILER2="$UNITTEST_DIR/profiler2_unittest"
-PROFILER3="$UNITTEST_DIR/profiler3_unittest"
-PROFILER4="$UNITTEST_DIR/profiler4_unittest"
-
-# Unfortunately, for us, libtool can replace executables with a shell
-# script that does some work before calling the 'real' executable
-# under a different name.  We need the 'real' executable name to run
-# pprof on it.  We've constructed all the binaries used in this
-# unittest so when they are called with no arguments, they report
-# their argv[0], which is the real binary name.
-Realname() {
-  "$1" 2>&1 | awk '{print $2; exit;}'
-}
-
-PROFILER1_REALNAME=`Realname "$PROFILER1"`
-PROFILER2_REALNAME=`Realname "$PROFILER2"`
-PROFILER3_REALNAME=`Realname "$PROFILER3"`
-PROFILER4_REALNAME=`Realname "$PROFILER4"`
-
-# It's meaningful to the profiler, so make sure we know its state
-unset CPUPROFILE
-
-# Some output/logging in the profiler can cause issues when running the unit
-# tests. For example, logging a warning when the profiler is detected as being
-# present but no CPUPROFILE is specified in the environment. Especially when
-# we are checking for a silent run or specific timing constraints are being
-# checked. So set the env variable signifying that we are running in a unit
-# test environment.
-PERFTOOLS_UNITTEST=1 
-
-rm -rf "$TMPDIR"
-mkdir "$TMPDIR" || exit 2
-
-num_failures=0
-
-RegisterFailure() {
-  num_failures=`expr $num_failures + 1`
-}
-
-# Takes two filenames representing profiles, with their executable scripts,
-# and a multiplier, and verifies that the 'contentful' functions in each
-# profile take the same time (possibly scaled by the given multiplier). It
-# used to be "same" meant within 50%, after adding an noise-reducing X units
-# to each value.  But even that would often spuriously fail, so now it's
-# "both non-zero". We're pretty forgiving.
-VerifySimilar() {
-  prof1="$TMPDIR/$1"
-  exec1="$2"
-  prof2="$TMPDIR/$3"
-  exec2="$4"
-  mult="$5"
-
-  # We are careful not to put exec1 and exec2 in quotes, because if
-  # they are the empty string, it means we want to use the 1-arg
-  # version of pprof.
-  mthread1=`"$PPROF" $PPROF_FLAGS $exec1 "$prof1" | grep test_main_thread | awk '{print $1}'`
-  mthread2=`"$PPROF" $PPROF_FLAGS $exec2 "$prof2" | grep test_main_thread | awk '{print $1}'`
-  mthread1_plus=`expr $mthread1 + 5`
-  mthread2_plus=`expr $mthread2 + 5`
-  if [ -z "$mthread1" ] || [ -z "$mthread2" ] || \
-     [ "$mthread1" -le 0 -o "$mthread2" -le 0 ]
-#    || [ `expr $mthread1_plus \* $mult` -gt `expr $mthread2_plus \* 2` -o \
-#         `expr $mthread1_plus \* $mult \* 2` -lt `expr $mthread2_plus` ]
-  then
-    echo
-    echo ">>> profile on $exec1 vs $exec2 with multiplier $mult failed:"
-    echo "Actual times (in profiling units) were '$mthread1' vs. '$mthread2'"
-    echo
-    RegisterFailure
-  fi
-}
-
-# Takes two filenames representing profiles, and optionally their
-# executable scripts (these may be empty if the profiles include
-# symbols), and verifies that the two profiles are identical.
-VerifyIdentical() {
-  prof1="$TMPDIR/$1"
-  exec1="$2"
-  prof2="$TMPDIR/$3"
-  exec2="$4"
-
-  # We are careful not to put exec1 and exec2 in quotes, because if
-  # they are the empty string, it means we want to use the 1-arg
-  # version of pprof.
-  "$PPROF" $PPROF_FLAGS $exec1 "$prof1" > "$TMPDIR/out1"
-  "$PPROF" $PPROF_FLAGS $exec2 "$prof2" > "$TMPDIR/out2"
-  diff=`diff "$TMPDIR/out1" "$TMPDIR/out2"`
-
-  if [ ! -z "$diff" ]; then
-    echo
-    echo ">>> profile doesn't match, args: $exec1 $prof1 vs. $exec2 $prof2"
-    echo ">>> Diff:"
-    echo "$diff"
-    echo
-    RegisterFailure
-  fi
-}
-
-# Takes a filename representing a profile, with its executable,
-# and a multiplier, and verifies that the main-thread function takes
-# the same amount of time as the other-threads function (possibly scaled
-# by the given multiplier).  Figuring out the multiplier can be tricky,
-# since by design the main thread runs twice as long as each of the
-# 'other' threads!  It used to be "same" meant within 50%, after adding an 
-# noise-reducing X units to each value.  But even that would often
-# spuriously fail, so now it's "both non-zero".  We're pretty forgiving.
-VerifyAcrossThreads() {
-  prof1="$TMPDIR/$1"
-  # We need to run the script with no args to get the actual exe name
-  exec1="$2"
-  mult="$3"
-
-  # We are careful not to put exec1 in quotes, because if it is the
-  # empty string, it means we want to use the 1-arg version of pprof.
-  mthread=`$PPROF $PPROF_FLAGS $exec1 "$prof1" | grep test_main_thread | awk '{print $1}'`
-  othread=`$PPROF $PPROF_FLAGS $exec1 "$prof1" | grep test_other_thread | awk '{print $1}'`
-  if [ -z "$mthread" ] || [ -z "$othread" ] || \
-     [ "$mthread" -le 0 -o "$othread" -le 0 ]
-#    || [ `expr $mthread \* $mult \* 3` -gt `expr $othread \* 10` -o \
-#         `expr $mthread \* $mult \* 10` -lt `expr $othread \* 3` ]
-  then
-    echo
-    echo ">>> profile on $exec1 (main vs thread) with multiplier $mult failed:"
-    echo "Actual times (in profiling units) were '$mthread' vs. '$othread'"
-    echo
-    RegisterFailure
-  fi
-}
-
-echo
-echo ">>> WARNING <<<"
-echo "This test looks at timing information to determine correctness."
-echo "If your system is loaded, the test may spuriously fail."
-echo "If the test does fail with an 'Actual times' error, try running again."
-echo
-
-# profiler1 is a non-threaded version
-"$PROFILER1" 50 1 "$TMPDIR/p1" || RegisterFailure
-"$PROFILER1" 100 1 "$TMPDIR/p2" || RegisterFailure
-VerifySimilar p1 "$PROFILER1_REALNAME" p2 "$PROFILER1_REALNAME" 2
-
-# Verify the same thing works if we statically link
-"$PROFILER2" 50 1 "$TMPDIR/p3" || RegisterFailure
-"$PROFILER2" 100 1 "$TMPDIR/p4" || RegisterFailure
-VerifySimilar p3 "$PROFILER2_REALNAME" p4 "$PROFILER2_REALNAME" 2
-
-# Verify the same thing works if we specify via CPUPROFILE
-CPUPROFILE="$TMPDIR/p5" "$PROFILER2" 50 || RegisterFailure
-CPUPROFILE="$TMPDIR/p6" "$PROFILER2" 100 || RegisterFailure
-VerifySimilar p5 "$PROFILER2_REALNAME" p6 "$PROFILER2_REALNAME" 2
-
-CPUPROFILE="$TMPDIR/p5b" "$PROFILER3" 30 || RegisterFailure
-CPUPROFILE="$TMPDIR/p5c" "$PROFILER3" 60 || RegisterFailure
-VerifySimilar p5b "$PROFILER3_REALNAME" p5c "$PROFILER3_REALNAME" 2
-
-# Now try what happens when we use threads
-"$PROFILER3" 30 2 "$TMPDIR/p7" || RegisterFailure
-"$PROFILER3" 60 2 "$TMPDIR/p8" || RegisterFailure
-VerifySimilar p7 "$PROFILER3_REALNAME" p8 "$PROFILER3_REALNAME" 2
-
-"$PROFILER4" 30 2 "$TMPDIR/p9" || RegisterFailure
-"$PROFILER4" 60 2 "$TMPDIR/p10" || RegisterFailure
-VerifySimilar p9 "$PROFILER4_REALNAME" p10 "$PROFILER4_REALNAME" 2
-
-# More threads!
-"$PROFILER4" 25 3 "$TMPDIR/p9" || RegisterFailure
-"$PROFILER4" 50 3 "$TMPDIR/p10" || RegisterFailure
-VerifySimilar p9 "$PROFILER4_REALNAME" p10 "$PROFILER4_REALNAME" 2
-
-# Compare how much time the main thread takes compared to the other threads
-# Recall the main thread runs twice as long as the other threads, by design.
-"$PROFILER4" 20 4 "$TMPDIR/p11" || RegisterFailure
-VerifyAcrossThreads p11 "$PROFILER4_REALNAME" 2
-
-# Test symbol save and restore
-"$PROFILER1" 50 1 "$TMPDIR/p12" || RegisterFailure
-"$PPROF" $PPROF_FLAGS "$PROFILER1_REALNAME" "$TMPDIR/p12" --raw \
-    >"$TMPDIR/p13" 2>/dev/null || RegisterFailure
-VerifyIdentical p12 "$PROFILER1_REALNAME" p13 "" || RegisterFailure
-
-"$PROFILER3" 30 2 "$TMPDIR/p14" || RegisterFailure
-"$PPROF" $PPROF_FLAGS "$PROFILER3_REALNAME" "$TMPDIR/p14" --raw \
-    >"$TMPDIR/p15" 2>/dev/null || RegisterFailure
-VerifyIdentical p14 "$PROFILER3_REALNAME" p15 "" || RegisterFailure
-
-# Test using ITIMER_REAL instead of ITIMER_PROF.
-env CPUPROFILE_REALTIME=1 "$PROFILER3" 30 2 "$TMPDIR/p16" || RegisterFailure
-env CPUPROFILE_REALTIME=1 "$PROFILER3" 60 2 "$TMPDIR/p17" || RegisterFailure
-VerifySimilar p16 "$PROFILER3_REALNAME" p17 "$PROFILER3_REALNAME" 2
-
-
-# Make sure that when we have a process with a fork, the profiles don't
-# clobber each other
-CPUPROFILE="$TMPDIR/pfork" "$PROFILER1" 1 -2 || RegisterFailure
-n=`ls $TMPDIR/pfork* | wc -l`
-if [ $n != 3 ]; then
-  echo "FORK test FAILED: expected 3 profiles (for main + 2 children), found $n"
-  num_failures=`expr $num_failures + 1`
-fi
-
-rm -rf "$TMPDIR"      # clean up
-
-echo "Tests finished with $num_failures failures"
-exit $num_failures
diff --git a/third_party/tcmalloc/chromium/src/tests/raw_printer_test.cc b/third_party/tcmalloc/chromium/src/tests/raw_printer_test.cc
deleted file mode 100644
index 2c7be6ac0..0000000
--- a/third_party/tcmalloc/chromium/src/tests/raw_printer_test.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright 2009 Google Inc. All Rights Reserved.
-// Author: sanjay@google.com (Sanjay Ghemawat)
-//
-// Use of this source code is governed by a BSD-style license that can
-// be found in the LICENSE file.
-
-#include "raw_printer.h"
-#include <stdio.h>
-#include <string>
-#include "base/logging.h"
-
-using std::string;
-
-#define TEST(a, b)  void TEST_##a##_##b()
-#define RUN_TEST(a, b)  TEST_##a##_##b()
-
-TEST(RawPrinter, Empty) {
-  char buffer[1];
-  base::RawPrinter printer(buffer, arraysize(buffer));
-  CHECK_EQ(0, printer.length());
-  CHECK_EQ(string(""), buffer);
-  CHECK_EQ(0, printer.space_left());
-  printer.Printf("foo");
-  CHECK_EQ(string(""), string(buffer));
-  CHECK_EQ(0, printer.length());
-  CHECK_EQ(0, printer.space_left());
-}
-
-TEST(RawPrinter, PartiallyFilled) {
-  char buffer[100];
-  base::RawPrinter printer(buffer, arraysize(buffer));
-  printer.Printf("%s %s", "hello", "world");
-  CHECK_EQ(string("hello world"), string(buffer));
-  CHECK_EQ(11, printer.length());
-  CHECK_LT(0, printer.space_left());
-}
-
-TEST(RawPrinter, Truncated) {
-  char buffer[3];
-  base::RawPrinter printer(buffer, arraysize(buffer));
-  printer.Printf("%d", 12345678);
-  CHECK_EQ(string("12"), string(buffer));
-  CHECK_EQ(2, printer.length());
-  CHECK_EQ(0, printer.space_left());
-}
-
-TEST(RawPrinter, ExactlyFilled) {
-  char buffer[12];
-  base::RawPrinter printer(buffer, arraysize(buffer));
-  printer.Printf("%s %s", "hello", "world");
-  CHECK_EQ(string("hello world"), string(buffer));
-  CHECK_EQ(11, printer.length());
-  CHECK_EQ(0, printer.space_left());
-}
-
-int main(int argc, char **argv) {
-  RUN_TEST(RawPrinter, Empty);
-  RUN_TEST(RawPrinter, PartiallyFilled);
-  RUN_TEST(RawPrinter, Truncated);
-  RUN_TEST(RawPrinter, ExactlyFilled);
-  printf("PASS\n");
-  return 0;   // 0 means success
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/realloc_unittest.cc b/third_party/tcmalloc/chromium/src/tests/realloc_unittest.cc
deleted file mode 100644
index e3d7b59..0000000
--- a/third_party/tcmalloc/chromium/src/tests/realloc_unittest.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2004, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Test realloc() functionality
-
-#include "config_for_unittests.h"
-#include <assert.h>                     // for assert
-#include <stdio.h>
-#include <stddef.h>                     // for size_t, NULL
-#include <stdlib.h>                     // for free, malloc, realloc
-#include <algorithm>                    // for min
-#include "base/logging.h"
-
-using std::min;
-
-
-// Fill a buffer of the specified size with a predetermined pattern
-static void Fill(unsigned char* buffer, int n) {
-  for (int i = 0; i < n; i++) {
-    buffer[i] = (i & 0xff);
-  }
-}
-
-// Check that the specified buffer has the predetermined pattern
-// generated by Fill()
-static bool Valid(unsigned char* buffer, int n) {
-  for (int i = 0; i < n; i++) {
-    if (buffer[i] != (i & 0xff)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-// Return the next interesting size/delta to check.  Returns -1 if no more.
-static int NextSize(int size) {
-  if (size < 100) {
-    return size+1;
-  } else if (size < 100000) {
-    // Find next power of two
-    int power = 1;
-    while (power < size) {
-      power <<= 1;
-    }
-
-    // Yield (power-1, power, power+1)
-    if (size < power-1) {
-      return power-1;
-    } else if (size == power-1) {
-      return power;
-    } else {
-      assert(size == power);
-      return power+1;
-    }
-  } else {
-    return -1;
-  }
-}
-
-int main(int argc, char** argv) {
-  for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) {
-    for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) {
-      unsigned char* src = (unsigned char*) malloc(src_size);
-      Fill(src, src_size);
-      unsigned char* dst = (unsigned char*) realloc(src, dst_size);
-      CHECK(Valid(dst, min(src_size, dst_size)));
-      Fill(dst, dst_size);
-      CHECK(Valid(dst, dst_size));
-      if (dst != NULL) free(dst);
-    }
-  }
-
-  // Now make sure realloc works correctly even when we overflow the
-  // packed cache, so some entries are evicted from the cache.
-  // The cache has 2^12 entries, keyed by page number.
-  const int kNumEntries = 1 << 14;
-  int** p = (int**)malloc(sizeof(*p) * kNumEntries);
-  int sum = 0;
-  for (int i = 0; i < kNumEntries; i++) {
-    p[i] = (int*)malloc(8192);   // no page size is likely to be bigger
-    p[i][1000] = i;              // use memory deep in the heart of p
-  }
-  for (int i = 0; i < kNumEntries; i++) {
-    p[i] = (int*)realloc(p[i], 9000);
-  }
-  for (int i = 0; i < kNumEntries; i++) {
-    sum += p[i][1000];
-    free(p[i]);
-  }
-  CHECK_EQ(kNumEntries/2 * (kNumEntries - 1), sum);  // assume kNE is even
-  free(p);
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/sampler_test.cc b/third_party/tcmalloc/chromium/src/tests/sampler_test.cc
deleted file mode 100755
index e0d24d4..0000000
--- a/third_party/tcmalloc/chromium/src/tests/sampler_test.cc
+++ /dev/null
@@ -1,631 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Daniel Ford
-//
-// Checks basic properties of the sampler
-
-#include "config_for_unittests.h"
-#include <stdlib.h>        // defines posix_memalign
-#include <stdio.h>         // for the printf at the end
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uintptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uintptr_t might be defined
-#endif
-#include <sys/types.h>
-#include <iostream>
-#include <algorithm>
-#include <vector>
-#include <string>
-#include <math.h>
-#include "base/logging.h"
-#include "base/commandlineflags.h"
-#include "sampler.h"       // The Sampler class being tested
-
-using std::sort;
-using std::min;
-using std::max;
-using std::vector;
-using std::abs;
-
-vector<void (*)()> g_testlist;  // the tests to run
-
-#define TEST(a, b)                                      \
-  struct Test_##a##_##b {                               \
-    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
-    static void Run();                                  \
-  };                                                    \
-  static Test_##a##_##b g_test_##a##_##b;               \
-  void Test_##a##_##b::Run()
-
-
-static int RUN_ALL_TESTS() {
-  vector<void (*)()>::const_iterator it;
-  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
-    (*it)();   // The test will error-exit if there's a problem.
-  }
-  fprintf(stderr, "\nPassed %d tests\n\nPASS\n", (int)g_testlist.size());
-  return 0;
-}
-
-#undef LOG   // defined in base/logging.h
-// Ideally, we'd put the newline at the end, but this hack puts the
-// newline at the end of the previous log message, which is good enough :-)
-#define LOG(level)  std::cerr << "\n"
-
-static std::string StringPrintf(const char* format, ...) {
-  char buf[256];   // should be big enough for all logging
-  va_list ap;
-  va_start(ap, format);
-  perftools_vsnprintf(buf, sizeof(buf), format, ap);
-  va_end(ap);
-  return buf;
-}
-
-namespace {
-template<typename T> class scoped_array {
- public:
-  scoped_array(T* p) : p_(p) { }
-  ~scoped_array() { delete[] p_; }
-  const T* get() const { return p_; }
-  T* get() { return p_; }
-  T& operator[](int i) { return p_[i]; }
- private:
-  T* p_;
-};
-}
-
-// Note that these tests are stochastic.
-// This mean that the chance of correct code passing the test is,
-// in the case of 5 standard deviations:
-// kSigmas=5:    ~99.99994267%
-// in the case of 4 standard deviations:
-// kSigmas=4:    ~99.993666%
-static const double kSigmas = 4;
-static const size_t kSamplingInterval = 512*1024;
-
-// Tests that GetSamplePeriod returns the expected value
-// which is 1<<19
-TEST(Sampler, TestGetSamplePeriod) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t sample_period;
-  sample_period = sampler.GetSamplePeriod();
-  CHECK_GT(sample_period, 0);
-}
-
-// Tests of the quality of the random numbers generated
-// This uses the Anderson Darling test for uniformity.
-// See "Evaluating the Anderson-Darling Distribution" by Marsaglia
-// for details.
-
-// Short cut version of ADinf(z), z>0 (from Marsaglia)
-// This returns the p-value for Anderson Darling statistic in
-// the limit as n-> infinity. For finite n, apply the error fix below.
-double AndersonDarlingInf(double z) {
-  if (z < 2) {
-    return exp(-1.2337141 / z) / sqrt(z) * (2.00012 + (0.247105 -
-                (0.0649821 - (0.0347962 - (0.011672 - 0.00168691
-                * z) * z) * z) * z) * z);
-  }
-  return exp( - exp(1.0776 - (2.30695 - (0.43424 - (0.082433 -
-                    (0.008056 - 0.0003146 * z) * z) * z) * z) * z));
-}
-
-// Corrects the approximation error in AndersonDarlingInf for small values of n
-// Add this to AndersonDarlingInf to get a better approximation
-// (from Marsaglia)
-double AndersonDarlingErrFix(int n, double x) {
-  if (x > 0.8) {
-    return (-130.2137 + (745.2337 - (1705.091 - (1950.646 -
-            (1116.360 - 255.7844 * x) * x) * x) * x) * x) / n;
-  }
-  double cutoff = 0.01265 + 0.1757 / n;
-  double t;
-  if (x < cutoff) {
-    t = x / cutoff;
-    t = sqrt(t) * (1 - t) * (49 * t - 102);
-    return t * (0.0037 / (n * n) + 0.00078 / n + 0.00006) / n;
-  } else {
-    t = (x - cutoff) / (0.8 - cutoff);
-    t = -0.00022633 + (6.54034 - (14.6538 - (14.458 - (8.259 - 1.91864
-          * t) * t) * t) * t) * t;
-    return t * (0.04213 + 0.01365 / n) / n;
-  }
-}
-
-// Returns the AndersonDarling p-value given n and the value of the statistic
-double AndersonDarlingPValue(int n, double z) {
-  double ad = AndersonDarlingInf(z);
-  double errfix = AndersonDarlingErrFix(n, ad);
-  return ad + errfix;
-}
-
-double AndersonDarlingStatistic(int n, double* random_sample) {
-  double ad_sum = 0;
-  for (int i = 0; i < n; i++) {
-    ad_sum += (2*i + 1) * log(random_sample[i] * (1 - random_sample[n-1-i]));
-  }
-  double ad_statistic = - n - 1/static_cast<double>(n) * ad_sum;
-  return ad_statistic;
-}
-
-// Tests if the array of doubles is uniformly distributed.
-// Returns the p-value of the Anderson Darling Statistic
-// for the given set of sorted random doubles
-// See "Evaluating the Anderson-Darling Distribution" by
-// Marsaglia and Marsaglia for details.
-double AndersonDarlingTest(int n, double* random_sample) {
-  double ad_statistic = AndersonDarlingStatistic(n, random_sample);
-  LOG(INFO) << StringPrintf("AD stat = %f, n=%d\n", ad_statistic, n);
-  double p = AndersonDarlingPValue(n, ad_statistic);
-  return p;
-}
-
-// Test the AD Test. The value of the statistic should go to zero as n->infty
-// Not run as part of regular tests
-void ADTestTest(int n) {
-  scoped_array<double> random_sample(new double[n]);
-  for (int i = 0; i < n; i++) {
-    random_sample[i] = (i+0.01)/n;
-  }
-  sort(random_sample.get(), random_sample.get() + n);
-  double ad_stat = AndersonDarlingStatistic(n, random_sample.get());
-  LOG(INFO) << StringPrintf("Testing the AD test. n=%d, ad_stat = %f",
-                            n, ad_stat);
-}
-
-// Print the CDF of the distribution of the Anderson-Darling Statistic
-// Used for checking the Anderson-Darling Test
-// Not run as part of regular tests
-void ADCDF() {
-  for (int i = 1; i < 40; i++) {
-    double x = i/10.0;
-    LOG(INFO) << "x= " << x << "  adpv= "
-              << AndersonDarlingPValue(100, x) << ", "
-              << AndersonDarlingPValue(1000, x);
-  }
-}
-
-// Testing that NextRandom generates uniform
-// random numbers.
-// Applies the Anderson-Darling test for uniformity
-void TestNextRandom(int n) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t x = 1;
-  // This assumes that the prng returns 48 bit numbers
-  uint64_t max_prng_value = static_cast<uint64_t>(1)<<48;
-  // Initialize
-  for (int i = 1; i <= 20; i++) {  // 20 mimics sampler.Init()
-    x = sampler.NextRandom(x);
-  }
-  scoped_array<uint64_t> int_random_sample(new uint64_t[n]);
-  // Collect samples
-  for (int i = 0; i < n; i++) {
-    int_random_sample[i] = x;
-    x = sampler.NextRandom(x);
-  }
-  // First sort them...
-  sort(int_random_sample.get(), int_random_sample.get() + n);
-  scoped_array<double> random_sample(new double[n]);
-  // Convert them to uniform randoms (in the range [0,1])
-  for (int i = 0; i < n; i++) {
-    random_sample[i] = static_cast<double>(int_random_sample[i])/max_prng_value;
-  }
-  // Now compute the Anderson-Darling statistic
-  double ad_pvalue = AndersonDarlingTest(n, random_sample.get());
-  LOG(INFO) << StringPrintf("pvalue for AndersonDarlingTest "
-                            "with n= %d is p= %f\n", n, ad_pvalue);
-  CHECK_GT(min(ad_pvalue, 1 - ad_pvalue), 0.0001);
-  //           << StringPrintf("prng is not uniform, %d\n", n);
-}
-
-
-TEST(Sampler, TestNextRandom_MultipleValues) {
-  TestNextRandom(10);  // Check short-range correlation
-  TestNextRandom(100);
-  TestNextRandom(1000);
-  TestNextRandom(10000);  // Make sure there's no systematic error
-}
-
-// Tests that PickNextSamplePeriod generates
-// geometrically distributed random numbers.
-// First converts to uniforms then applied the
-// Anderson-Darling test for uniformity.
-void TestPickNextSample(int n) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  scoped_array<uint64_t> int_random_sample(new uint64_t[n]);
-  int sample_period = sampler.GetSamplePeriod();
-  int ones_count = 0;
-  for (int i = 0; i < n; i++) {
-    int_random_sample[i] = sampler.PickNextSamplingPoint();
-    CHECK_GE(int_random_sample[i], 1);
-    if (int_random_sample[i] == 1) {
-      ones_count += 1;
-    }
-    CHECK_LT(ones_count, 4); // << " out of " << i << " samples.";
-  }
-  // First sort them...
-  sort(int_random_sample.get(), int_random_sample.get() + n);
-  scoped_array<double> random_sample(new double[n]);
-  // Convert them to uniform random numbers
-  // by applying the geometric CDF
-  for (int i = 0; i < n; i++) {
-    random_sample[i] = 1 - exp(-static_cast<double>(int_random_sample[i])
-                           / sample_period);
-  }
-  // Now compute the Anderson-Darling statistic
-  double geom_ad_pvalue = AndersonDarlingTest(n, random_sample.get());
-  LOG(INFO) << StringPrintf("pvalue for geometric AndersonDarlingTest "
-                             "with n= %d is p= %f\n", n, geom_ad_pvalue);
-  CHECK_GT(min(geom_ad_pvalue, 1 - geom_ad_pvalue), 0.0001);
-      //          << "PickNextSamplingPoint does not produce good "
-      //             "geometric/exponential random numbers\n";
-}
-
-TEST(Sampler, TestPickNextSample_MultipleValues) {
-  TestPickNextSample(10);  // Make sure the first few are good (enough)
-  TestPickNextSample(100);
-  TestPickNextSample(1000);
-  TestPickNextSample(10000);  // Make sure there's no systematic error
-}
-
-
-// This is superceeded by the Anderson-Darling Test
-// and it not run now.
-// Tests how fast nearby values are spread out with  LRand64
-// The purpose of this code is to determine how many
-// steps to apply to the seed during initialization
-void TestLRand64Spread() {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t current_value;
-  printf("Testing LRand64 Spread\n");
-  for (int i = 1; i < 10; i++) {
-    printf("%d ", i);
-    current_value = i;
-    for (int j = 1; j < 100; j++) {
-      current_value = sampler.NextRandom(current_value);
-    }
-    LOG(INFO) << current_value;
-  }
-}
-
-
-// Futher tests
-
-bool CheckMean(size_t mean, int num_samples) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  size_t total = 0;
-  for (int i = 0; i < num_samples; i++) {
-    total += sampler.PickNextSamplingPoint();
-  }
-  double empirical_mean = total / static_cast<double>(num_samples);
-  double expected_sd = mean / pow(num_samples * 1.0, 0.5);
-  return(fabs(mean-empirical_mean) < expected_sd * kSigmas);
-}
-
-// Prints a sequence so you can look at the distribution
-void OutputSequence(int sequence_length) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  size_t next_step;
-  for (int i = 0; i< sequence_length; i++) {
-    next_step = sampler.PickNextSamplingPoint();
-    LOG(INFO) << next_step;
-  }
-}
-
-
-double StandardDeviationsErrorInSample(
-              int total_samples, int picked_samples,
-              int alloc_size, int sampling_interval) {
-  double p = 1 - exp(-(static_cast<double>(alloc_size) / sampling_interval));
-  double expected_samples = total_samples * p;
-  double sd = pow(p*(1-p)*total_samples, 0.5);
-  return((picked_samples - expected_samples) / sd);
-}
-
-TEST(Sampler, LargeAndSmallAllocs_CombinedTest) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  int counter_big = 0;
-  int counter_small = 0;
-  int size_big = 129*8*1024+1;
-  int size_small = 1024*8;
-  int num_iters = 128*4*8;
-  // Allocate in mixed chunks
-  for (int i = 0; i < num_iters; i++) {
-    if (!sampler.RecordAllocation(size_big)) {
-      counter_big += 1;
-    }
-    for (int i = 0; i < 129; i++) {
-      if (!sampler.RecordAllocation(size_small)) {
-        counter_small += 1;
-      }
-    }
-  }
-  // Now test that there are the right number of each
-  double large_allocs_sds =
-     StandardDeviationsErrorInSample(num_iters, counter_big,
-                                     size_big, kSamplingInterval);
-  double small_allocs_sds =
-     StandardDeviationsErrorInSample(num_iters*129, counter_small,
-                                     size_small, kSamplingInterval);
-  LOG(INFO) << StringPrintf("large_allocs_sds = %f\n", large_allocs_sds);
-  LOG(INFO) << StringPrintf("small_allocs_sds = %f\n", small_allocs_sds);
-  CHECK_LE(fabs(large_allocs_sds), kSigmas);
-  CHECK_LE(fabs(small_allocs_sds), kSigmas);
-}
-
-// Tests whether the mean is about right over 1000 samples
-TEST(Sampler, IsMeanRight) {
-  CHECK(CheckMean(kSamplingInterval, 1000));
-}
-
-// This flag is for the OldSampler class to use
-const int64 FLAGS_mock_tcmalloc_sample_parameter = 1<<19;
-
-// A cut down and slightly refactored version of the old Sampler
-class OldSampler {
- public:
-  void Init(uint32_t seed);
-  void Cleanup() {}
-
-  // Record allocation of "k" bytes.  Return true iff allocation
-  // should be sampled
-  bool SampleAllocation(size_t k);
-
-  // Generate a geometric with mean 1M (or FLAG value)
-  void PickNextSample(size_t k);
-
-  // Initialize the statics for the Sample class
-  static void InitStatics() {
-    sample_period = 1048583;
-  }
-  size_t bytes_until_sample_;
-
- private:
-  uint32_t rnd_;                   // Cheap random number generator
-  static uint64_t sample_period;
-  // Should be a prime just above a power of 2:
-  // 2, 5, 11, 17, 37, 67, 131, 257,
-  // 521, 1031, 2053, 4099, 8209, 16411,
-  // 32771, 65537, 131101, 262147, 524309, 1048583,
-  // 2097169, 4194319, 8388617, 16777259, 33554467
-};
-
-// Statics for OldSampler
-uint64_t OldSampler::sample_period;
-
-void OldSampler::Init(uint32_t seed) {
-  // Initialize PRNG -- run it for a bit to get to good values
-  if (seed != 0) {
-    rnd_ = seed;
-  } else {
-    rnd_ = 12345;
-  }
-  bytes_until_sample_ = 0;
-  for (int i = 0; i < 100; i++) {
-    PickNextSample(sample_period * 2);
-  }
-};
-
-// A cut-down version of the old PickNextSampleRoutine
-void OldSampler::PickNextSample(size_t k) {
-  // Make next "random" number
-  // x^32+x^22+x^2+x^1+1 is a primitive polynomial for random numbers
-  static const uint32_t kPoly = (1 << 22) | (1 << 2) | (1 << 1) | (1 << 0);
-  uint32_t r = rnd_;
-  rnd_ = (r << 1) ^ ((static_cast<int32_t>(r) >> 31) & kPoly);
-
-  // Next point is "rnd_ % (sample_period)".  I.e., average
-  // increment is "sample_period/2".
-  const int flag_value = FLAGS_mock_tcmalloc_sample_parameter;
-  static int last_flag_value = -1;
-
-  if (flag_value != last_flag_value) {
-    // There should be a spinlock here, but this code is
-    // for benchmarking only.
-    sample_period = 1048583;
-    last_flag_value = flag_value;
-  }
-
-  bytes_until_sample_ += rnd_ % sample_period;
-
-  if (k > (static_cast<size_t>(-1) >> 2)) {
-    // If the user has asked for a huge allocation then it is possible
-    // for the code below to loop infinitely.  Just return (note that
-    // this throws off the sampling accuracy somewhat, but a user who
-    // is allocating more than 1G of memory at a time can live with a
-    // minor inaccuracy in profiling of small allocations, and also
-    // would rather not wait for the loop below to terminate).
-    return;
-  }
-
-  while (bytes_until_sample_ < k) {
-    // Increase bytes_until_sample_ by enough average sampling periods
-    // (sample_period >> 1) to allow us to sample past the current
-    // allocation.
-    bytes_until_sample_ += (sample_period >> 1);
-  }
-
-  bytes_until_sample_ -= k;
-}
-
-inline bool OldSampler::SampleAllocation(size_t k) {
-  if (bytes_until_sample_ < k) {
-    PickNextSample(k);
-    return true;
-  } else {
-    bytes_until_sample_ -= k;
-    return false;
-  }
-}
-
-// This checks that the stated maximum value for the
-// tcmalloc_sample_parameter flag never overflows bytes_until_sample_
-TEST(Sampler, bytes_until_sample_Overflow_Underflow) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t one = 1;
-  // sample_parameter = 0;  // To test the edge case
-  uint64_t sample_parameter_array[4] = {0, 1, one<<19, one<<58};
-  for (int i = 0; i < 4; i++) {
-    uint64_t sample_parameter = sample_parameter_array[i];
-    LOG(INFO) << "sample_parameter = " << sample_parameter;
-    double sample_scaling = - log(2.0) * sample_parameter;
-    // Take the top 26 bits as the random number
-    // (This plus the 1<<26 sampling bound give a max step possible of
-    // 1209424308 bytes.)
-    const uint64_t prng_mod_power = 48;  // Number of bits in prng
-
-    // First, check the largest_prng value
-    uint64_t largest_prng_value = (static_cast<uint64_t>(1)<<48) - 1;
-    double q = (largest_prng_value >> (prng_mod_power - 26)) + 1.0;
-    LOG(INFO) << StringPrintf("q = %f\n", q);
-    LOG(INFO) << StringPrintf("log2(q) = %f\n", log(q)/log(2.0));
-    uint64_t smallest_sample_step
-        = static_cast<uint64_t>(min(log2(q) - 26, 0.0)
-                                * sample_scaling + 1);
-    LOG(INFO) << "Smallest sample step is " << smallest_sample_step;
-    uint64_t cutoff = static_cast<uint64_t>(10)
-                      * (sample_parameter/(one<<24) + 1);
-    LOG(INFO) << "Acceptable value is < " << cutoff;
-    // This checks that the answer is "small" and positive
-    CHECK_LE(smallest_sample_step, cutoff);
-
-    // Next, check with the smallest prng value
-    uint64_t smallest_prng_value = 0;
-    q = (smallest_prng_value >> (prng_mod_power - 26)) + 1.0;
-    LOG(INFO) << StringPrintf("q = %f\n", q);
-    uint64_t largest_sample_step
-        = static_cast<uint64_t>(min(log2(q) - 26, 0.0)
-                                * sample_scaling + 1);
-    LOG(INFO) << "Largest sample step is " << largest_sample_step;
-    CHECK_LE(largest_sample_step, one<<63);
-    CHECK_GE(largest_sample_step, smallest_sample_step);
-  }
-}
-
-
-// Test that NextRand is in the right range.  Unfortunately, this is a
-// stochastic test which could miss problems.
-TEST(Sampler, NextRand_range) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t one = 1;
-  // The next number should be (one << 48) - 1
-  uint64_t max_value = (one << 48) - 1;
-  uint64_t x = (one << 55);
-  int n = 22;  // 27;
-  LOG(INFO) << "Running sampler.NextRandom 1<<" << n << " times";
-  for (int i = 1; i <= (1<<n); i++) {  // 20 mimics sampler.Init()
-    x = sampler.NextRandom(x);
-    CHECK_LE(x, max_value);
-  }
-}
-
-// Tests certain arithmetic operations to make sure they compute what we
-// expect them too (for testing across different platforms)
-TEST(Sampler, arithmetic_1) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t rnd;  // our 48 bit random number, which we don't trust
-  const uint64_t prng_mod_power = 48;
-  uint64_t one = 1;
-  rnd = one;
-  uint64_t max_value = (one << 48) - 1;
-  for (int i = 1; i <= (1>>27); i++) {  // 20 mimics sampler.Init()
-    rnd = sampler.NextRandom(rnd);
-    CHECK_LE(rnd, max_value);
-    double q = (rnd >> (prng_mod_power - 26)) + 1.0;
-    CHECK_GE(q, 0); // << rnd << "  " << prng_mod_power;
-  }
-  // Test some potentially out of bounds value for rnd
-  for (int i = 1; i <= 63; i++) {
-    rnd = one << i;
-    double q = (rnd >> (prng_mod_power - 26)) + 1.0;
-    LOG(INFO) << "rnd = " << rnd << " i=" << i << " q=" << q;
-    CHECK_GE(q, 0);
-    //        << " rnd=" << rnd << "  i=" << i << " prng_mod_power" << prng_mod_power;
-  }
-}
-
-void test_arithmetic(uint64_t rnd) {
-  const uint64_t prng_mod_power = 48;  // Number of bits in prng
-  uint64_t shifted_rnd = rnd >> (prng_mod_power - 26);
-  CHECK_GE(shifted_rnd, 0);
-  CHECK_LT(shifted_rnd, (1<<26));
-  LOG(INFO) << shifted_rnd;
-  LOG(INFO) << static_cast<double>(shifted_rnd);
-  CHECK_GE(static_cast<double>(static_cast<uint32_t>(shifted_rnd)), 0);
-      //      << " rnd=" << rnd << "  srnd=" << shifted_rnd;
-  CHECK_GE(static_cast<double>(shifted_rnd), 0);
-      //      << " rnd=" << rnd << "  srnd=" << shifted_rnd;
-  double q = static_cast<double>(shifted_rnd) + 1.0;
-  CHECK_GT(q, 0);
-}
-
-// Tests certain arithmetic operations to make sure they compute what we
-// expect them too (for testing across different platforms)
-// know bad values under with -c dbg --cpu piii for _some_ binaries:
-// rnd=227453640600554
-// shifted_rnd=54229173
-// (hard to reproduce)
-TEST(Sampler, arithmetic_2) {
-  uint64_t rnd = 227453640600554LL;
-  test_arithmetic(rnd);
-}
-
-
-// It's not really a test, but it's good to know
-TEST(Sample, size_of_class) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  LOG(INFO) << "Size of Sampler class is: " << sizeof(tcmalloc::Sampler);
-  LOG(INFO) << "Size of Sampler object is: " << sizeof(sampler);
-}
-
-// Make sure sampling is enabled, or the tests won't work right.
-DECLARE_int64(tcmalloc_sample_parameter);
-
-int main(int argc, char **argv) {
-  if (FLAGS_tcmalloc_sample_parameter == 0)
-    FLAGS_tcmalloc_sample_parameter = 524288;
-  return RUN_ALL_TESTS();
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/sampling_test.cc b/third_party/tcmalloc/chromium/src/tests/sampling_test.cc
deleted file mode 100644
index 729aba8..0000000
--- a/third_party/tcmalloc/chromium/src/tests/sampling_test.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This tests ReadStackTraces and ReadGrowthStackTraces.  It does this
-// by doing a bunch of allocations and then calling those functions.
-// A driver shell-script can call this, and then call pprof, and
-// verify the expected output.  The output is written to
-// argv[1].heap and argv[1].growth
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-#include "base/logging.h"
-#include <gperftools/malloc_extension.h>
-
-using std::string;
-
-extern "C" void* AllocateAllocate() ATTRIBUTE_NOINLINE;
-
-extern "C" void* AllocateAllocate() {
-  // The VLOG's are mostly to discourage inlining
-  VLOG(1, "Allocating some more");
-  void* p = malloc(10000);
-  VLOG(1, "Done allocating");
-  return p;
-}
-
-static void WriteStringToFile(const string& s, const string& filename) {
-  FILE* fp = fopen(filename.c_str(), "w");
-  fwrite(s.data(), 1, s.length(), fp);
-  fclose(fp);
-}
-
-int main(int argc, char** argv) {
-  if (argc < 2) {
-    fprintf(stderr, "USAGE: %s <base of output files>\n", argv[0]);
-    exit(1);
-  }
-  for (int i = 0; i < 8000; i++) {
-    AllocateAllocate();
-  }
-
-  string s;
-  MallocExtension::instance()->GetHeapSample(&s);
-  WriteStringToFile(s, string(argv[1]) + ".heap");
-
-  s.clear();
-  MallocExtension::instance()->GetHeapGrowthStacks(&s);
-  WriteStringToFile(s, string(argv[1]) + ".growth");
-
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/sampling_test.sh b/third_party/tcmalloc/chromium/src/tests/sampling_test.sh
deleted file mode 100755
index 2a58426..0000000
--- a/third_party/tcmalloc/chromium/src/tests/sampling_test.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2008, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# ---
-# Author: Craig Silverstein
-#
-# This is a test that tcmalloc creates, and pprof reads, sampling data
-# correctly: both for the heap profile (ReadStackTraces) and for
-# growth in the heap sized (ReadGrowthStackTraces).
-
-BINDIR="${BINDIR:-.}"
-PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir] [path to pprof]"
-  echo "       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
-  exit 1
-fi
-
-SAMPLING_TEST="${1:-$BINDIR/sampling_test}"
-PPROF="${2:-$PPROF_PATH}"
-OUTDIR="/tmp/sampling_test_dir"
-
-# libtool is annoying, and puts the actual executable in a different
-# directory, replacing the seeming-executable with a shell script.
-# We use the error output of sampling_test to indicate its real location
-SAMPLING_TEST_BINARY=`"$SAMPLING_TEST" 2>&1 | awk '/USAGE/ {print $2; exit;}'`
-
-# A kludge for cygwin.  Unfortunately, 'test -f' says that 'foo' exists
-# even when it doesn't, and only foo.exe exists.  Other unix utilities
-# (like nm) need you to say 'foo.exe'.  We use one such utility, cat, to
-# see what the *real* binary name is.
-if ! cat "$SAMPLING_TEST_BINARY" >/dev/null 2>&1; then
-  SAMPLING_TEST_BINARY="$SAMPLING_TEST_BINARY".exe
-fi
-
-die() {    # runs the command given as arguments, and then dies.
-    echo "FAILED.  Output from $@"
-    echo "----"
-    "$@"
-    echo "----"
-    exit 1
-}
-
-rm -rf "$OUTDIR" || die "Unable to delete $OUTDIR"
-mkdir "$OUTDIR" || die "Unable to create $OUTDIR"
-
-# This puts the output into out.heap and out.growth.  It allocates
-# 8*10^7 bytes of memory, which is 76M.  Because we sample, the
-# estimate may be a bit high or a bit low: we accept anything from
-# 50M to 99M.
-"$SAMPLING_TEST" "$OUTDIR/out"
-
-echo "Testing heap output..."
-"$PPROF" --text "$SAMPLING_TEST_BINARY" "$OUTDIR/out.heap" \
-   | grep '[5-9][0-9]\.[0-9][ 0-9.%]*_*AllocateAllocate' >/dev/null \
-   || die "$PPROF" --text "$SAMPLING_TEST_BINARY" "$OUTDIR/out.heap"
-echo "OK"
-
-echo "Testing growth output..."
-"$PPROF" --text "$SAMPLING_TEST_BINARY" "$OUTDIR/out.growth" \
-   | grep '[5-9][0-9]\.[0-9][ 0-9.%]*_*AllocateAllocate' >/dev/null \
-   || die "$PPROF" --text "$SAMPLING_TEST_BINARY" "$OUTDIR/out.growth"
-echo "OK"
-
-echo "PASS"
diff --git a/third_party/tcmalloc/chromium/src/tests/simple_compat_test.cc b/third_party/tcmalloc/chromium/src/tests/simple_compat_test.cc
deleted file mode 100644
index 24583a0..0000000
--- a/third_party/tcmalloc/chromium/src/tests/simple_compat_test.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This just verifies that we can compile code that #includes stuff
-// via the backwards-compatibility 'google/' #include-dir.  It does
-// not include config.h on purpose, to better simulate a perftools
-// client.
-
-#include <stddef.h>
-#include <stdio.h>
-
-#define GPERFTOOLS_SUPPRESS_LEGACY_WARNING
-
-#include <google/heap-checker.h>
-#include <google/heap-profiler.h>
-#include <google/malloc_extension.h>
-#include <google/malloc_extension_c.h>
-#include <google/malloc_hook.h>
-#include <google/malloc_hook_c.h>
-#include <google/profiler.h>
-#include <google/stacktrace.h>
-#include <google/tcmalloc.h>
-
-// We don't link in -lprofiler for this test, so be sure not to make
-// any function calls that require the cpu-profiler code.  The
-// heap-profiler is ok.
-
-HeapLeakChecker::Disabler* heap_checker_h;
-void (*heap_profiler_h)(const char*) = &HeapProfilerStart;
-MallocExtension::Ownership malloc_extension_h;
-MallocExtension_Ownership malloc_extension_c_h;
-MallocHook::NewHook* malloc_hook_h;
-MallocHook_NewHook* malloc_hook_c_h;
-ProfilerOptions* profiler_h;
-int (*stacktrace_h)(void**, int, int) = &GetStackTrace;
-void* (*tcmalloc_h)(size_t) = &tc_new;
-
-int main(int argc, char** argv) {
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/stack_trace_table_test.cc b/third_party/tcmalloc/chromium/src/tests/stack_trace_table_test.cc
deleted file mode 100644
index 3cacd2d..0000000
--- a/third_party/tcmalloc/chromium/src/tests/stack_trace_table_test.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright 2009 Google Inc. All Rights Reserved.
-// Author: fikes@google.com (Andrew Fikes)
-//
-// Use of this source code is governed by a BSD-style license that can
-// be found in the LICENSE file.
-
-
-#include "config_for_unittests.h"
-#include <stdio.h>   // for puts()
-#include "stack_trace_table.h"
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "static_vars.h"
-
-#undef ARRAYSIZE   // may be defined on, eg, windows
-#define ARRAYSIZE(a)  ( sizeof(a) / sizeof(*(a)) )
-
-static void CheckTracesAndReset(tcmalloc::StackTraceTable* table,
-                        const uintptr_t* expected, int len) {
-  void** entries = table->ReadStackTracesAndClear();
-  for (int i = 0; i < len; ++i) {
-    CHECK_EQ(reinterpret_cast<uintptr_t>(entries[i]), expected[i]);
-  }
-  delete[] entries;
-}
-
-static void AddTrace(tcmalloc::StackTraceTable* table,
-                     const tcmalloc::StackTrace& t) {
-  // Normally we'd need this lock, but since the test is single-threaded
-  // we don't.  I comment it out on windows because the DLL-decl thing
-  // is really annoying in this case.
-#ifndef _MSC_VER
-  SpinLockHolder h(tcmalloc::Static::pageheap_lock());
-#endif
-  table->AddTrace(t);
-}
-
-int main(int argc, char **argv) {
-  tcmalloc::StackTraceTable table;
-
-  // Empty table
-  CHECK_EQ(table.depth_total(), 0);
-  CHECK_EQ(table.bucket_total(), 0);
-  static const uintptr_t k1[] = {0};
-  CheckTracesAndReset(&table, k1, ARRAYSIZE(k1));
-
-  tcmalloc::StackTrace t1;
-  t1.size = static_cast<uintptr_t>(1024);
-  t1.depth = static_cast<uintptr_t>(2);
-  t1.stack[0] = reinterpret_cast<void*>(1);
-  t1.stack[1] = reinterpret_cast<void*>(2);
-
-
-  tcmalloc::StackTrace t2;
-  t2.size = static_cast<uintptr_t>(512);
-  t2.depth = static_cast<uintptr_t>(2);
-  t2.stack[0] = reinterpret_cast<void*>(2);
-  t2.stack[1] = reinterpret_cast<void*>(1);
-
-  // Table w/ just t1
-  AddTrace(&table, t1);
-  CHECK_EQ(table.depth_total(), 2);
-  CHECK_EQ(table.bucket_total(), 1);
-  static const uintptr_t k2[] = {1, 1024, 2, 1, 2, 0};
-  CheckTracesAndReset(&table, k2, ARRAYSIZE(k2));
-
-  // Table w/ t1, t2
-  AddTrace(&table, t1);
-  AddTrace(&table, t2);
-  CHECK_EQ(table.depth_total(), 4);
-  CHECK_EQ(table.bucket_total(), 2);
-  static const uintptr_t k3[] = {1, 1024, 2, 1, 2, 1,  512, 2, 2, 1, 0};
-  CheckTracesAndReset(&table, k3, ARRAYSIZE(k3));
-
-  // Table w/ 2 x t1, 1 x t2
-  AddTrace(&table, t1);
-  AddTrace(&table, t2);
-  AddTrace(&table, t1);
-  CHECK_EQ(table.depth_total(), 4);
-  CHECK_EQ(table.bucket_total(), 2);
-  static const uintptr_t k4[] = {2, 2048, 2, 1, 2, 1,  512, 2, 2, 1, 0};
-  CheckTracesAndReset(&table, k4, ARRAYSIZE(k4));
-
-  // Same stack as t1, but w/ different size
-  tcmalloc::StackTrace t3;
-  t3.size = static_cast<uintptr_t>(2);
-  t3.depth = static_cast<uintptr_t>(2);
-  t3.stack[0] = reinterpret_cast<void*>(1);
-  t3.stack[1] = reinterpret_cast<void*>(2);
-
-  // Table w/ t1, t3
-  AddTrace(&table, t1);
-  AddTrace(&table, t3);
-  CHECK_EQ(table.depth_total(), 2);
-  CHECK_EQ(table.bucket_total(), 1);
-  static const uintptr_t k5[] = {2, 1026, 2, 1, 2, 0};
-  CheckTracesAndReset(&table, k5, ARRAYSIZE(k5));
-
-  puts("PASS");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/stacktrace_unittest.cc b/third_party/tcmalloc/chromium/src/tests/stacktrace_unittest.cc
deleted file mode 100644
index 3c9f7353..0000000
--- a/third_party/tcmalloc/chromium/src/tests/stacktrace_unittest.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "config_for_unittests.h"
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include "base/commandlineflags.h"
-#include "base/logging.h"
-#include <gperftools/stacktrace.h>
-
-namespace {
-
-// Obtain a backtrace, verify that the expected callers are present in the
-// backtrace, and maybe print the backtrace to stdout.
-
-// The sequence of functions whose return addresses we expect to see in the
-// backtrace.
-const int BACKTRACE_STEPS = 6;
-
-struct AddressRange {
-  const void *start, *end;
-};
-
-// Expected function [start,end] range.
-AddressRange expected_range[BACKTRACE_STEPS];
-
-#if __GNUC__
-// Using GCC extension: address of a label can be taken with '&&label'.
-// Start should be a label somewhere before recursive call, end somewhere
-// after it.
-#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange)           \
-  do {                                                                   \
-    (prange)->start = &&start_label;                                     \
-    (prange)->end = &&end_label;                                         \
-    CHECK_LT((prange)->start, (prange)->end);                            \
-  } while (0)
-// This macro expands into "unmovable" code (opaque to GCC), and that
-// prevents GCC from moving a_label up or down in the code.
-// Without it, there is no code following the 'end' label, and GCC
-// (4.3.1, 4.4.0) thinks it safe to assign &&end an address that is before
-// the recursive call.
-#define DECLARE_ADDRESS_LABEL(a_label)                                   \
-  a_label: do { __asm__ __volatile__(""); } while (0)
-// Gcc 4.4.0 may split function into multiple chunks, and the chunk
-// performing recursive call may end up later in the code then the return
-// instruction (this actually happens with FDO).
-// Adjust function range from __builtin_return_address.
-#define ADJUST_ADDRESS_RANGE_FROM_RA(prange)                             \
-  do {                                                                   \
-    void *ra = __builtin_return_address(0);                              \
-    CHECK_LT((prange)->start, ra);                                       \
-    if (ra > (prange)->end) {                                            \
-      printf("Adjusting range from %p..%p to %p..%p\n",                  \
-             (prange)->start, (prange)->end,                             \
-             (prange)->start, ra);                                       \
-      (prange)->end = ra;                                                \
-    }                                                                    \
-  } while (0)
-#else
-// Assume the Check* functions below are not longer than 256 bytes.
-#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange)           \
-  do {                                                                   \
-    (prange)->start = reinterpret_cast<const void *>(&fn);               \
-    (prange)->end = reinterpret_cast<const char *>(&fn) + 256;           \
-  } while (0)
-#define DECLARE_ADDRESS_LABEL(a_label) do { } while (0)
-#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) do { } while (0)
-#endif  // __GNUC__
-
-//-----------------------------------------------------------------------//
-
-void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range)
-{
-  CHECK_GE(ret_addr, range.start);
-  CHECK_LE(ret_addr, range.end);
-}
-
-//-----------------------------------------------------------------------//
-
-void ATTRIBUTE_NOINLINE CheckStackTrace(int);
-void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) {
-  const int STACK_LEN = 10;
-  void *stack[STACK_LEN];
-  int size;
-
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);
-  INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
-  DECLARE_ADDRESS_LABEL(start);
-  size = GetStackTrace(stack, STACK_LEN, 0);
-  printf("Obtained %d stack frames.\n", size);
-  CHECK_GE(size, 1);
-  CHECK_LE(size, STACK_LEN);
-
-#ifdef HAVE_EXECINFO_H
-  {
-    char **strings = backtrace_symbols(stack, size);
-    printf("Obtained %d stack frames.\n", size);
-    for (int i = 0; i < size; i++)
-      printf("%s %p\n", strings[i], stack[i]);
-    printf("CheckStackTrace() addr: %p\n", &CheckStackTrace);
-    free(strings);
-  }
-#endif
-
-  for (int i = 0; i < BACKTRACE_STEPS; i++) {
-    printf("Backtrace %d: expected: %p..%p  actual: %p ... ",
-           i, expected_range[i].start, expected_range[i].end, stack[i]);
-    fflush(stdout);
-    CheckRetAddrIsInFunction(stack[i], expected_range[i]);
-    printf("OK\n");
-  }
-  DECLARE_ADDRESS_LABEL(end);
-}
-
-//-----------------------------------------------------------------------//
-
-/* Dummy functions to make the backtrace more interesting. */
-void ATTRIBUTE_NOINLINE CheckStackTrace4(int i) {
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[2]);
-  INIT_ADDRESS_RANGE(CheckStackTrace4, start, end, &expected_range[1]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTraceLeaf();
-  DECLARE_ADDRESS_LABEL(end);
-}
-void ATTRIBUTE_NOINLINE CheckStackTrace3(int i) {
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[3]);
-  INIT_ADDRESS_RANGE(CheckStackTrace3, start, end, &expected_range[2]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTrace4(j);
-  DECLARE_ADDRESS_LABEL(end);
-}
-void ATTRIBUTE_NOINLINE CheckStackTrace2(int i) {
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[4]);
-  INIT_ADDRESS_RANGE(CheckStackTrace2, start, end, &expected_range[3]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTrace3(j);
-  DECLARE_ADDRESS_LABEL(end);
-}
-void ATTRIBUTE_NOINLINE CheckStackTrace1(int i) {
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[5]);
-  INIT_ADDRESS_RANGE(CheckStackTrace1, start, end, &expected_range[4]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTrace2(j);
-  DECLARE_ADDRESS_LABEL(end);
-}
-void ATTRIBUTE_NOINLINE CheckStackTrace(int i) {
-  INIT_ADDRESS_RANGE(CheckStackTrace, start, end, &expected_range[5]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTrace1(j);
-  DECLARE_ADDRESS_LABEL(end);
-}
-
-}  // namespace
-//-----------------------------------------------------------------------//
-
-int main(int argc, char ** argv) {
-  CheckStackTrace(0);
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/system-alloc_unittest.cc b/third_party/tcmalloc/chromium/src/tests/system-alloc_unittest.cc
deleted file mode 100644
index 4a5f7c08..0000000
--- a/third_party/tcmalloc/chromium/src/tests/system-alloc_unittest.cc
+++ /dev/null
@@ -1,155 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Arun Sharma
-
-#include "config_for_unittests.h"
-#include "system-alloc.h"
-#include <stdio.h>
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uintptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uintptr_t might be defined
-#endif
-#include <sys/types.h>
-#include <algorithm>
-#include <limits>
-#include "base/logging.h"               // for Check_GEImpl, Check_LTImpl, etc
-#include <gperftools/malloc_extension.h>    // for MallocExtension::instance
-#include "common.h"                     // for kAddressBits
-
-class ArraySysAllocator : public SysAllocator {
-public:
-  // Was this allocator invoked at least once?
-  bool invoked_;
-
-  ArraySysAllocator() : SysAllocator() {
-    ptr_ = 0;
-    invoked_ = false;
-  }
-
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment) {
-    invoked_ = true;
-
-    if (size > kArraySize) {
-      return NULL;
-    }
-
-    void *result = &array_[ptr_];
-    uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-
-    if (actual_size) {
-      *actual_size = size;
-    }
-
-    // Try to get more memory for alignment
-    size_t extra = alignment - (ptr & (alignment-1));
-    size += extra;
-    CHECK_LT(ptr_ + size, kArraySize);
-
-    if ((ptr & (alignment-1)) != 0) {
-      ptr += alignment - (ptr & (alignment-1));
-    }
-
-    ptr_ += size;
-    return reinterpret_cast<void *>(ptr);
-  }
-
-  void DumpStats() {
-  }
-
-private:
-  static const int kArraySize = 8 * 1024 * 1024;
-  char array_[kArraySize];
-  // We allocate the next chunk from here
-  int ptr_;
-
-};
-const int ArraySysAllocator::kArraySize;
-ArraySysAllocator a;
-
-static void TestBasicInvoked() {
-  MallocExtension::instance()->SetSystemAllocator(&a);
-
-  // An allocation size that is likely to trigger the system allocator.
-  // XXX: this is implementation specific.
-  char *p = new char[1024 * 1024];
-  delete [] p;
-
-  // Make sure that our allocator was invoked.
-  CHECK(a.invoked_);
-}
-
-#if 0  // could port this to various OSs, but won't bother for now
-TEST(AddressBits, CpuVirtualBits) {
-  // Check that kAddressBits is as least as large as either the number of bits
-  // in a pointer or as the number of virtual bits handled by the processor.
-  // To be effective this test must be run on each processor model.
-  const int kPointerBits = 8 * sizeof(void*);
-  const int kImplementedVirtualBits = NumImplementedVirtualBits();
-
-  CHECK_GE(kAddressBits, std::min(kImplementedVirtualBits, kPointerBits));
-}
-#endif
-
-static void TestBasicRetryFailTest() {
-  // Check with the allocator still works after a failed allocation.
-  //
-  // There is no way to call malloc and guarantee it will fail.  malloc takes a
-  // size_t parameter and the C++ standard does not constrain the size of
-  // size_t.  For example, consider an implementation where size_t is 32 bits
-  // and pointers are 64 bits.
-  //
-  // It is likely, though, that sizeof(size_t) == sizeof(void*).  In that case,
-  // the first allocation here might succeed but the second allocation must
-  // fail.
-  //
-  // If the second allocation succeeds, you will have to rewrite or
-  // disable this test.
-  // The weird parens are to avoid macro-expansion of 'max' on windows.
-  const size_t kHugeSize = (std::numeric_limits<size_t>::max)() / 2;
-  void* p1 = malloc(kHugeSize);
-  void* p2 = malloc(kHugeSize);
-  CHECK(p2 == NULL);
-  if (p1 != NULL) free(p1);
-
-  char* q = new char[1024];
-  CHECK(q != NULL);
-  delete [] q;
-}
-
-int main(int argc, char** argv) {
-  TestBasicInvoked();
-  TestBasicRetryFailTest();
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/tcmalloc_large_unittest.cc b/third_party/tcmalloc/chromium/src/tests/tcmalloc_large_unittest.cc
deleted file mode 100644
index ff22007..0000000
--- a/third_party/tcmalloc/chromium/src/tests/tcmalloc_large_unittest.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Michael Chastain
-//
-// This is a unit test for large allocations in malloc and friends.
-// "Large" means "so large that they overflow the address space".
-// For 32 bits, this means allocations near 2^32 bytes and 2^31 bytes.
-// For 64 bits, this means allocations near 2^64 bytes and 2^63 bytes.
-
-#include <stddef.h>                     // for size_t, NULL
-#include <stdlib.h>                     // for malloc, free, realloc
-#include <stdio.h>
-#include <set>                          // for set, etc
-
-#include "base/logging.h"               // for operator<<, CHECK, etc
-
-using std::set;
-
-// Alloc a size that should always fail.
-
-void TryAllocExpectFail(size_t size) {
-  void* p1 = malloc(size);
-  CHECK(p1 == NULL);
-
-  void* p2 = malloc(1);
-  CHECK(p2 != NULL);
-
-  void* p3 = realloc(p2, size);
-  CHECK(p3 == NULL);
-
-  free(p2);
-}
-
-// Alloc a size that might work and might fail.
-// If it does work, touch some pages.
-
-void TryAllocMightFail(size_t size) {
-  unsigned char* p = static_cast<unsigned char*>(malloc(size));
-  if ( p != NULL ) {
-    unsigned char volatile* vp = p;  // prevent optimizations
-    static const size_t kPoints = 1024;
-
-    for ( size_t i = 0; i < kPoints; ++i ) {
-      vp[i * (size / kPoints)] = static_cast<unsigned char>(i);
-    }
-
-    for ( size_t i = 0; i < kPoints; ++i ) {
-      CHECK(vp[i * (size / kPoints)] == static_cast<unsigned char>(i));
-    }
-
-    vp[size-1] = 'M';
-    CHECK(vp[size-1] == 'M');
-  }
-
-  free(p);
-}
-
-int main (int argc, char** argv) {
-  // Allocate some 0-byte objects.  They better be unique.
-  // 0 bytes is not large but it exercises some paths related to
-  // large-allocation code.
-  {
-    static const int kZeroTimes = 1024;
-    printf("Test malloc(0) x %d\n", kZeroTimes);
-    set<char*> p_set;
-    for ( int i = 0; i < kZeroTimes; ++i ) {
-      char* p = new char;
-      CHECK(p != NULL);
-      CHECK(p_set.find(p) == p_set.end());
-      p_set.insert(p_set.end(), p);
-    }
-    // Just leak the memory.
-  }
-
-  // Grab some memory so that some later allocations are guaranteed to fail.
-  printf("Test small malloc\n");
-  void* p_small = malloc(4*1048576);
-  CHECK(p_small != NULL);
-
-  // Test sizes up near the maximum size_t.
-  // These allocations test the wrap-around code.
-  printf("Test malloc(0 - N)\n");
-  const size_t zero = 0;
-  static const size_t kMinusNTimes = 16384;
-  for ( size_t i = 1; i < kMinusNTimes; ++i ) {
-    TryAllocExpectFail(zero - i);
-  }
-
-  // Test sizes a bit smaller.
-  // The small malloc above guarantees that all these return NULL.
-  printf("Test malloc(0 - 1048576 - N)\n");
-  static const size_t kMinusMBMinusNTimes = 16384;
-  for ( size_t i = 0; i < kMinusMBMinusNTimes; ++i) {
-    TryAllocExpectFail(zero - 1048576 - i);
-  }
-
-  // Test sizes at half of size_t.
-  // These might or might not fail to allocate.
-  printf("Test malloc(max/2 +- N)\n");
-  static const size_t kHalfPlusMinusTimes = 64;
-  const size_t half = (zero - 2) / 2 + 1;
-  for ( size_t i = 0; i < kHalfPlusMinusTimes; ++i) {
-    TryAllocMightFail(half - i);
-    TryAllocMightFail(half + i);
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/tcmalloc_unittest.cc b/third_party/tcmalloc/chromium/src/tests/tcmalloc_unittest.cc
deleted file mode 100644
index 7ab6b90..0000000
--- a/third_party/tcmalloc/chromium/src/tests/tcmalloc_unittest.cc
+++ /dev/null
@@ -1,1645 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Unittest for the TCMalloc implementation.
-//
-// * The test consists of a set of threads.
-// * Each thread maintains a set of allocated objects, with
-//   a bound on the total amount of data in the set.
-// * Each allocated object's contents are generated by
-//   hashing the object pointer, and a generation count
-//   in the object.  This allows us to easily check for
-//   data corruption.
-// * At any given step, the thread can do any of the following:
-//     a. Allocate an object
-//     b. Increment an object's generation count and update
-//        its contents.
-//     c. Pass the object to another thread
-//     d. Free an object
-//   Also, at the end of every step, object(s) are freed to maintain
-//   the memory upper-bound.
-//
-// If this test is compiled with -DDEBUGALLOCATION, then we don't
-// run some tests that test the inner workings of tcmalloc and
-// break on debugallocation: that certain allocations are aligned
-// in a certain way (even though no standard requires it), and that
-// realloc() tries to minimize copying (which debug allocators don't
-// care about).
-
-#include "config_for_unittests.h"
-// Complicated ordering requirements.  tcmalloc.h defines (indirectly)
-// _POSIX_C_SOURCE, which it needs so stdlib.h defines posix_memalign.
-// unistd.h, on the other hand, requires _POSIX_C_SOURCE to be unset,
-// at least on FreeBSD, in order to define sbrk.  The solution
-// is to #include unistd.h first.  This is safe because unistd.h
-// doesn't sub-include stdlib.h, so we'll still get posix_memalign
-// when we #include stdlib.h.  Blah.
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>        // for testing sbrk hooks
-#endif
-#include "tcmalloc.h"      // must come early, to pick up posix_memalign
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>        // for intptr_t
-#endif
-#include <sys/types.h>     // for size_t
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>         // for open; used with mmap-hook test
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>      // for testing mmap hooks
-#endif
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>        // defines pvalloc/etc on cygwin
-#endif
-#include <assert.h>
-#include <vector>
-#include <algorithm>
-#include <string>
-#include <new>
-#include "base/logging.h"
-#include "base/simple_mutex.h"
-#include "gperftools/malloc_hook.h"
-#include "gperftools/malloc_extension.h"
-#include "gperftools/nallocx.h"
-#include "gperftools/tcmalloc.h"
-#include "thread_cache.h"
-#include "system-alloc.h"
-#include "tests/testutil.h"
-
-// Windows doesn't define pvalloc and a few other obsolete unix
-// functions; nor does it define posix_memalign (which is not obsolete).
-#if defined(_WIN32)
-# define cfree free         // don't bother to try to test these obsolete fns
-# define valloc malloc
-# define pvalloc malloc
-// I'd like to map posix_memalign to _aligned_malloc, but _aligned_malloc
-// must be paired with _aligned_free (not normal free), which is too
-// invasive a change to how we allocate memory here.  So just bail
-static bool kOSSupportsMemalign = false;
-static inline void* Memalign(size_t align, size_t size) {
-  //LOG(FATAL) << "memalign not supported on windows";
-  exit(1);
-  return NULL;
-}
-static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
-  //LOG(FATAL) << "posix_memalign not supported on windows";
-  exit(1);
-  return -1;
-}
-
-// OS X defines posix_memalign in some OS versions but not others;
-// it's confusing enough to check that it's easiest to just not to test.
-#elif defined(__APPLE__)
-static bool kOSSupportsMemalign = false;
-static inline void* Memalign(size_t align, size_t size) {
-  //LOG(FATAL) << "memalign not supported on OS X";
-  exit(1);
-  return NULL;
-}
-static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
-  //LOG(FATAL) << "posix_memalign not supported on OS X";
-  exit(1);
-  return -1;
-}
-
-#else
-static bool kOSSupportsMemalign = true;
-static inline void* Memalign(size_t align, size_t size) {
-  return memalign(align, size);
-}
-static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
-  return posix_memalign(ptr, align, size);
-}
-
-#endif
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-#define OVERALIGNMENT 64
-
-struct overaligned_type
-{
-#if defined(__GNUC__)
-  __attribute__((__aligned__(OVERALIGNMENT)))
-#elif defined(_MSC_VER)
-  __declspec(align(OVERALIGNMENT))
-#else
-  alignas(OVERALIGNMENT)
-#endif
-  unsigned char data[OVERALIGNMENT * 2]; // make the object size different from
-                                         // alignment to make sure the correct
-                                         // values are passed to the new/delete
-                                         // implementation functions
-};
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-#define LOGSTREAM   stdout
-
-using std::vector;
-using std::string;
-
-DECLARE_double(tcmalloc_release_rate);
-DECLARE_int32(max_free_queue_size);     // in debugallocation.cc
-DECLARE_int64(tcmalloc_sample_parameter);
-
-struct OOMAbleSysAlloc : public SysAllocator {
-  SysAllocator *child;
-  int simulate_oom;
-
-  void* Alloc(size_t size, size_t* actual_size, size_t alignment) {
-    if (simulate_oom) {
-      return NULL;
-    }
-    return child->Alloc(size, actual_size, alignment);
-  }
-};
-
-static union {
-  char buf[sizeof(OOMAbleSysAlloc)];
-  void *ptr;
-} test_sys_alloc_space;
-
-static OOMAbleSysAlloc* get_test_sys_alloc() {
-  return reinterpret_cast<OOMAbleSysAlloc*>(&test_sys_alloc_space);
-}
-
-void setup_oomable_sys_alloc() {
-  SysAllocator *def = MallocExtension::instance()->GetSystemAllocator();
-
-  OOMAbleSysAlloc *alloc = get_test_sys_alloc();
-  new (alloc) OOMAbleSysAlloc;
-  alloc->child = def;
-
-  MallocExtension::instance()->SetSystemAllocator(alloc);
-}
-
-namespace testing {
-
-static const int FLAGS_numtests = 50000;
-static const int FLAGS_log_every_n_tests = 50000; // log exactly once
-
-// Testing parameters
-static const int FLAGS_lgmaxsize = 16;   // lg() of the max size object to alloc
-static const int FLAGS_numthreads = 10;  // Number of threads
-static const int FLAGS_threadmb = 4;     // Max memory size allocated by thread
-static const int FLAGS_lg_max_memalign = 18; // lg of max alignment for memalign
-
-static const double FLAGS_memalign_min_fraction = 0;    // min expected%
-static const double FLAGS_memalign_max_fraction = 0.4;  // max expected%
-static const double FLAGS_memalign_max_alignment_ratio = 6;  // alignment/size
-
-// Weights of different operations
-static const int FLAGS_allocweight = 50;    // Weight for picking allocation
-static const int FLAGS_freeweight = 50;     // Weight for picking free
-static const int FLAGS_updateweight = 10;   // Weight for picking update
-static const int FLAGS_passweight = 1;      // Weight for passing object
-
-static const int kSizeBits = 8 * sizeof(size_t);
-static const size_t kMaxSize = ~static_cast<size_t>(0);
-static const size_t kMaxSignedSize = ((size_t(1) << (kSizeBits-1)) - 1);
-
-static const size_t kNotTooBig = 100000;
-// We want an allocation that is definitely more than main memory.  OS
-// X has special logic to discard very big allocs before even passing
-// the request along to the user-defined memory allocator; we're not
-// interested in testing their logic, so we have to make sure we're
-// not *too* big.
-static const size_t kTooBig = kMaxSize - 100000;
-
-static int news_handled = 0;
-
-// Global array of threads
-class TesterThread;
-static TesterThread** threads;
-
-// To help with generating random numbers
-class TestHarness {
- private:
-  // Information kept per type
-  struct Type {
-    string      name;
-    int         type;
-    int         weight;
-  };
-
- public:
-  TestHarness(int seed)
-      : types_(new vector<Type>), total_weight_(0), num_tests_(0) {
-    srandom(seed);
-  }
-  ~TestHarness() {
-    delete types_;
-  }
-
-  // Add operation type with specified weight.  When starting a new
-  // iteration, an operation type is picked with probability
-  // proportional to its weight.
-  //
-  // "type" must be non-negative.
-  // "weight" must be non-negative.
-  void AddType(int type, int weight, const char* name);
-
-  // Call this to get the type of operation for the next iteration.
-  // It returns a random operation type from the set of registered
-  // operations.  Returns -1 if tests should finish.
-  int PickType();
-
-  // If n == 0, returns the next pseudo-random number in the range [0 .. 0]
-  // If n != 0, returns the next pseudo-random number in the range [0 .. n)
-  int Uniform(int n) {
-    if (n == 0) {
-      return random() * 0;
-    } else {
-      return random() % n;
-    }
-  }
-  // Pick "base" uniformly from range [0,max_log] and then return
-  // "base" random bits.  The effect is to pick a number in the range
-  // [0,2^max_log-1] with bias towards smaller numbers.
-  int Skewed(int max_log) {
-    const int base = random() % (max_log+1);
-    return random() % (1 << base);
-  }
-
- private:
-  vector<Type>*         types_;         // Registered types
-  int                   total_weight_;  // Total weight of all types
-  int                   num_tests_;     // Num tests run so far
-};
-
-void TestHarness::AddType(int type, int weight, const char* name) {
-  Type t;
-  t.name = name;
-  t.type = type;
-  t.weight = weight;
-  types_->push_back(t);
-  total_weight_ += weight;
-}
-
-int TestHarness::PickType() {
-  if (num_tests_ >= FLAGS_numtests) return -1;
-  num_tests_++;
-
-  assert(total_weight_ > 0);
-  // This is a little skewed if total_weight_ doesn't divide 2^31, but it's close
-  int v = Uniform(total_weight_);
-  int i;
-  for (i = 0; i < types_->size(); i++) {
-    v -= (*types_)[i].weight;
-    if (v < 0) {
-      break;
-    }
-  }
-
-  assert(i < types_->size());
-  if ((num_tests_ % FLAGS_log_every_n_tests) == 0) {
-    fprintf(LOGSTREAM, "  Test %d out of %d: %s\n",
-            num_tests_, FLAGS_numtests, (*types_)[i].name.c_str());
-  }
-  return (*types_)[i].type;
-}
-
-class AllocatorState : public TestHarness {
- public:
-  explicit AllocatorState(int seed) : TestHarness(seed), memalign_fraction_(0) {
-    if (kOSSupportsMemalign) {
-      CHECK_GE(FLAGS_memalign_max_fraction, 0);
-      CHECK_LE(FLAGS_memalign_max_fraction, 1);
-      CHECK_GE(FLAGS_memalign_min_fraction, 0);
-      CHECK_LE(FLAGS_memalign_min_fraction, 1);
-      double delta = FLAGS_memalign_max_fraction - FLAGS_memalign_min_fraction;
-      CHECK_GE(delta, 0);
-      memalign_fraction_ = (Uniform(10000)/10000.0 * delta +
-                            FLAGS_memalign_min_fraction);
-      //fprintf(LOGSTREAM, "memalign fraction: %f\n", memalign_fraction_);
-    }
-  }
-  virtual ~AllocatorState() {}
-
-  // Allocate memory.  Randomly choose between malloc() or posix_memalign().
-  void* alloc(size_t size) {
-    if (Uniform(100) < memalign_fraction_ * 100) {
-      // Try a few times to find a reasonable alignment, or fall back on malloc.
-      for (int i = 0; i < 5; i++) {
-        size_t alignment = 1 << Uniform(FLAGS_lg_max_memalign);
-        if (alignment >= sizeof(intptr_t) &&
-            (size < sizeof(intptr_t) ||
-             alignment < FLAGS_memalign_max_alignment_ratio * size)) {
-          void *result = reinterpret_cast<void*>(static_cast<intptr_t>(0x1234));
-          int err = PosixMemalign(&result, alignment, size);
-          if (err != 0) {
-            CHECK_EQ(err, ENOMEM);
-          }
-          return err == 0 ? result : NULL;
-        }
-      }
-    }
-    return malloc(size);
-  }
-
- private:
-  double memalign_fraction_;
-};
-
-
-// Info kept per thread
-class TesterThread {
- private:
-  // Info kept per allocated object
-  struct Object {
-    char*       ptr;                    // Allocated pointer
-    int         size;                   // Allocated size
-    int         generation;             // Generation counter of object contents
-  };
-
-  Mutex                 lock_;          // For passing in another thread's obj
-  int                   id_;            // My thread id
-  AllocatorState        rnd_;           // For generating random numbers
-  vector<Object>        heap_;          // This thread's heap
-  vector<Object>        passed_;        // Pending objects passed from others
-  size_t                heap_size_;     // Current heap size
-  int                   locks_ok_;      // Number of OK TryLock() ops
-  int                   locks_failed_;  // Number of failed TryLock() ops
-
-  // Type of operations
-  enum Type { ALLOC, FREE, UPDATE, PASS };
-
-  // ACM minimal standard random number generator.  (re-entrant.)
-  class ACMRandom {
-    int32 seed_;
-   public:
-    explicit ACMRandom(int32 seed) { seed_ = seed; }
-    int32 Next() {
-      const int32 M = 2147483647L;   // 2^31-1
-      const int32 A = 16807;
-      // In effect, we are computing seed_ = (seed_ * A) % M, where M = 2^31-1
-      uint32 lo = A * (int32)(seed_ & 0xFFFF);
-      uint32 hi = A * (int32)((uint32)seed_ >> 16);
-      lo += (hi & 0x7FFF) << 16;
-      if (lo > M) {
-        lo &= M;
-        ++lo;
-      }
-      lo += hi >> 15;
-      if (lo > M) {
-        lo &= M;
-        ++lo;
-      }
-      return (seed_ = (int32) lo);
-    }
-  };
-
- public:
-  TesterThread(int id)
-    : id_(id),
-      rnd_(id+1),
-      heap_size_(0),
-      locks_ok_(0),
-      locks_failed_(0) {
-  }
-
-  virtual ~TesterThread() {
-    if (FLAGS_verbose)
-      fprintf(LOGSTREAM, "Thread %2d: locks %6d ok; %6d trylocks failed\n",
-              id_, locks_ok_, locks_failed_);
-    if (locks_ok_ + locks_failed_ >= 1000) {
-      CHECK_LE(locks_failed_, locks_ok_ / 2);
-    }
-  }
-
-  virtual void Run() {
-    rnd_.AddType(ALLOC,  FLAGS_allocweight,   "allocate");
-    rnd_.AddType(FREE,   FLAGS_freeweight,    "free");
-    rnd_.AddType(UPDATE, FLAGS_updateweight,  "update");
-    rnd_.AddType(PASS,   FLAGS_passweight,    "pass");
-
-    while (true) {
-      AcquirePassedObjects();
-
-      switch (rnd_.PickType()) {
-        case ALLOC:   AllocateObject(); break;
-        case FREE:    FreeObject();     break;
-        case UPDATE:  UpdateObject();   break;
-        case PASS:    PassObject();     break;
-        case -1:      goto done;
-        default:      assert(NULL == "Unknown type");
-      }
-
-      ShrinkHeap();
-    }
-
- done:
-    DeleteHeap();
-  }
-
-  // Allocate a new object
-  void AllocateObject() {
-    Object object;
-    object.size = rnd_.Skewed(FLAGS_lgmaxsize);
-    object.ptr = static_cast<char*>(rnd_.alloc(object.size));
-    CHECK(object.ptr);
-    object.generation = 0;
-    FillContents(&object);
-    heap_.push_back(object);
-    heap_size_ += object.size;
-  }
-
-  // Mutate a random object
-  void UpdateObject() {
-    if (heap_.empty()) return;
-    const int index = rnd_.Uniform(heap_.size());
-    CheckContents(heap_[index]);
-    heap_[index].generation++;
-    FillContents(&heap_[index]);
-  }
-
-  // Free a random object
-  void FreeObject() {
-    if (heap_.empty()) return;
-    const int index = rnd_.Uniform(heap_.size());
-    Object object = heap_[index];
-    CheckContents(object);
-    free(object.ptr);
-    heap_size_ -= object.size;
-    heap_[index] = heap_[heap_.size()-1];
-    heap_.pop_back();
-  }
-
-  // Delete all objects in the heap
-  void DeleteHeap() {
-    while (!heap_.empty()) {
-      FreeObject();
-    }
-  }
-
-  // Free objects until our heap is small enough
-  void ShrinkHeap() {
-    while (heap_size_ > FLAGS_threadmb << 20) {
-      assert(!heap_.empty());
-      FreeObject();
-    }
-  }
-
-  // Pass a random object to another thread
-  void PassObject() {
-    // Pick object to pass
-    if (heap_.empty()) return;
-    const int index = rnd_.Uniform(heap_.size());
-    Object object = heap_[index];
-    CheckContents(object);
-
-    // Pick thread to pass
-    const int tid = rnd_.Uniform(FLAGS_numthreads);
-    TesterThread* thread = threads[tid];
-
-    if (thread->lock_.TryLock()) {
-      // Pass the object
-      locks_ok_++;
-      thread->passed_.push_back(object);
-      thread->lock_.Unlock();
-      heap_size_ -= object.size;
-      heap_[index] = heap_[heap_.size()-1];
-      heap_.pop_back();
-    } else {
-      locks_failed_++;
-    }
-  }
-
-  // Grab any objects passed to this thread by another thread
-  void AcquirePassedObjects() {
-    // We do not create unnecessary contention by always using
-    // TryLock().  Plus we unlock immediately after swapping passed
-    // objects into a local vector.
-    vector<Object> copy;
-    { // Locking scope
-      if (!lock_.TryLock()) {
-        locks_failed_++;
-        return;
-      }
-      locks_ok_++;
-      swap(copy, passed_);
-      lock_.Unlock();
-    }
-
-    for (int i = 0; i < copy.size(); ++i) {
-      const Object& object = copy[i];
-      CheckContents(object);
-      heap_.push_back(object);
-      heap_size_ += object.size;
-    }
-  }
-
-  // Fill object contents according to ptr/generation
-  void FillContents(Object* object) {
-    ACMRandom r(reinterpret_cast<intptr_t>(object->ptr) & 0x7fffffff);
-    for (int i = 0; i < object->generation; ++i) {
-      r.Next();
-    }
-    const char c = static_cast<char>(r.Next());
-    memset(object->ptr, c, object->size);
-  }
-
-  // Check object contents
-  void CheckContents(const Object& object) {
-    ACMRandom r(reinterpret_cast<intptr_t>(object.ptr) & 0x7fffffff);
-    for (int i = 0; i < object.generation; ++i) {
-      r.Next();
-    }
-
-    // For large objects, we just check a prefix/suffix
-    const char expected = static_cast<char>(r.Next());
-    const int limit1 = object.size < 32 ? object.size : 32;
-    const int start2 = limit1 > object.size - 32 ? limit1 : object.size - 32;
-    for (int i = 0; i < limit1; ++i) {
-      CHECK_EQ(object.ptr[i], expected);
-    }
-    for (int i = start2; i < object.size; ++i) {
-      CHECK_EQ(object.ptr[i], expected);
-    }
-  }
-};
-
-static void RunThread(int thread_id) {
-  threads[thread_id]->Run();
-}
-
-static void TryHugeAllocation(size_t s, AllocatorState* rnd) {
-  void* p = rnd->alloc(s);
-  CHECK(p == NULL);   // huge allocation s should fail!
-}
-
-static void TestHugeAllocations(AllocatorState* rnd) {
-  // Check that asking for stuff tiny bit smaller than largest possible
-  // size returns NULL.
-  for (size_t i = 0; i < 70000; i += rnd->Uniform(20)) {
-    TryHugeAllocation(kMaxSize - i, rnd);
-  }
-  // Asking for memory sizes near signed/unsigned boundary (kMaxSignedSize)
-  // might work or not, depending on the amount of virtual memory.
-#ifndef DEBUGALLOCATION    // debug allocation takes forever for huge allocs
-  for (size_t i = 0; i < 100; i++) {
-    void* p = NULL;
-    p = rnd->alloc(kMaxSignedSize + i);
-    if (p) free(p);    // if: free(NULL) is not necessarily defined
-    p = rnd->alloc(kMaxSignedSize - i);
-    if (p) free(p);
-  }
-#endif
-
-  // Check that ReleaseFreeMemory has no visible effect (aka, does not
-  // crash the test):
-  MallocExtension* inst = MallocExtension::instance();
-  CHECK(inst);
-  inst->ReleaseFreeMemory();
-}
-
-static void TestCalloc(size_t n, size_t s, bool ok) {
-  char* p = reinterpret_cast<char*>(calloc(n, s));
-  if (FLAGS_verbose)
-    fprintf(LOGSTREAM, "calloc(%" PRIxS ", %" PRIxS "): %p\n", n, s, p);
-  if (!ok) {
-    CHECK(p == NULL);  // calloc(n, s) should not succeed
-  } else {
-    CHECK(p != NULL);  // calloc(n, s) should succeed
-    for (int i = 0; i < n*s; i++) {
-      CHECK(p[i] == '\0');
-    }
-    free(p);
-  }
-}
-
-// This makes sure that reallocing a small number of bytes in either
-// direction doesn't cause us to allocate new memory.
-static void TestRealloc() {
-#ifndef DEBUGALLOCATION  // debug alloc doesn't try to minimize reallocs
-  // When sampling, we always allocate in units of page-size, which
-  // makes reallocs of small sizes do extra work (thus, failing these
-  // checks).  Since sampling is random, we turn off sampling to make
-  // sure that doesn't happen to us here.
-  const int64 old_sample_parameter = FLAGS_tcmalloc_sample_parameter;
-  FLAGS_tcmalloc_sample_parameter = 0;   // turn off sampling
-
-  int start_sizes[] = { 100, 1000, 10000, 100000 };
-  int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 };
-
-  for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) {
-    void* p = malloc(start_sizes[s]);
-    CHECK(p);
-    // The larger the start-size, the larger the non-reallocing delta.
-    for (int d = 0; d < (s+1) * 2; ++d) {
-      void* new_p = realloc(p, start_sizes[s] + deltas[d]);
-      CHECK(p == new_p);  // realloc should not allocate new memory
-    }
-    // Test again, but this time reallocing smaller first.
-    for (int d = 0; d < s*2; ++d) {
-      void* new_p = realloc(p, start_sizes[s] - deltas[d]);
-      CHECK(p == new_p);  // realloc should not allocate new memory
-    }
-    free(p);
-  }
-  FLAGS_tcmalloc_sample_parameter = old_sample_parameter;
-#endif
-}
-
-static void TestNewHandler() {
-  ++news_handled;
-  throw std::bad_alloc();
-}
-
-static void TestOneNew(void* (*func)(size_t)) {
-  // success test
-  try {
-    void* ptr = (*func)(kNotTooBig);
-    if (0 == ptr) {
-      fprintf(LOGSTREAM, "allocation should not have failed.\n");
-      abort();
-    }
-  } catch (...) {
-    fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
-    abort();
-  }
-
-  // failure test
-  // we should always receive a bad_alloc exception
-  try {
-    (*func)(kTooBig);
-    fprintf(LOGSTREAM, "allocation should have failed.\n");
-    abort();
-  } catch (const std::bad_alloc&) {
-    // correct
-  } catch (...) {
-    fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
-    abort();
-  }
-}
-
-static void TestNew(void* (*func)(size_t)) {
-  news_handled = 0;
-
-  // test without new_handler:
-  std::new_handler saved_handler = std::set_new_handler(0);
-  TestOneNew(func);
-
-  // test with new_handler:
-  std::set_new_handler(TestNewHandler);
-  TestOneNew(func);
-  if (news_handled != 1) {
-    fprintf(LOGSTREAM, "new_handler was not called.\n");
-    abort();
-  }
-  std::set_new_handler(saved_handler);
-}
-
-static void TestOneNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {
-  // success test
-  try {
-    void* ptr = (*func)(kNotTooBig, std::nothrow);
-    if (0 == ptr) {
-      fprintf(LOGSTREAM, "allocation should not have failed.\n");
-      abort();
-    }
-  } catch (...) {
-    fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
-    abort();
-  }
-
-  // failure test
-  // we should always receive a bad_alloc exception
-  try {
-    if ((*func)(kTooBig, std::nothrow) != 0) {
-      fprintf(LOGSTREAM, "allocation should have failed.\n");
-      abort();
-    }
-  } catch (...) {
-    fprintf(LOGSTREAM, "nothrow allocation threw unexpected exception.\n");
-    abort();
-  }
-}
-
-static void TestNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {
-  news_handled = 0;
-
-  // test without new_handler:
-  std::new_handler saved_handler = std::set_new_handler(0);
-  TestOneNothrowNew(func);
-
-  // test with new_handler:
-  std::set_new_handler(TestNewHandler);
-  TestOneNothrowNew(func);
-  if (news_handled != 1) {
-    fprintf(LOGSTREAM, "nothrow new_handler was not called.\n");
-    abort();
-  }
-  std::set_new_handler(saved_handler);
-}
-
-
-// These are used as callbacks by the sanity-check.  Set* and Reset*
-// register the hook that counts how many times the associated memory
-// function is called.  After each such call, call Verify* to verify
-// that we used the tcmalloc version of the call, and not the libc.
-// Note the ... in the hook signature: we don't care what arguments
-// the hook takes.
-#define MAKE_HOOK_CALLBACK(hook_type, ...)                              \
-  static volatile int g_##hook_type##_calls = 0;                                 \
-  static void IncrementCallsTo##hook_type(__VA_ARGS__) {                \
-    g_##hook_type##_calls++;                                            \
-  }                                                                     \
-  static void Verify##hook_type##WasCalled() {                          \
-    CHECK_GT(g_##hook_type##_calls, 0);                                 \
-    g_##hook_type##_calls = 0;  /* reset for next call */               \
-  }                                                                     \
-  static void Set##hook_type() {                                        \
-    CHECK(MallocHook::Add##hook_type(                                   \
-        (MallocHook::hook_type)&IncrementCallsTo##hook_type));          \
-  }                                                                     \
-  static void Reset##hook_type() {                                      \
-    CHECK(MallocHook::Remove##hook_type(                                \
-        (MallocHook::hook_type)&IncrementCallsTo##hook_type));          \
-  }
-
-// We do one for each hook typedef in malloc_hook.h
-MAKE_HOOK_CALLBACK(NewHook, const void*, size_t);
-MAKE_HOOK_CALLBACK(DeleteHook, const void*);
-MAKE_HOOK_CALLBACK(MmapHook, const void*, const void*, size_t, int, int, int,
-                   off_t);
-MAKE_HOOK_CALLBACK(MremapHook, const void*, const void*, size_t, size_t, int,
-                   const void*);
-MAKE_HOOK_CALLBACK(MunmapHook, const void *, size_t);
-MAKE_HOOK_CALLBACK(SbrkHook, const void *, ptrdiff_t);
-
-static void TestAlignmentForSize(int size) {
-  fprintf(LOGSTREAM, "Testing alignment of malloc(%d)\n", size);
-  static const int kNum = 100;
-  void* ptrs[kNum];
-  for (int i = 0; i < kNum; i++) {
-    ptrs[i] = malloc(size);
-    uintptr_t p = reinterpret_cast<uintptr_t>(ptrs[i]);
-    CHECK((p % sizeof(void*)) == 0);
-    CHECK((p % sizeof(double)) == 0);
-
-    // Must have 16-byte (or 8-byte in case of -DTCMALLOC_ALIGN_8BYTES)
-    // alignment for large enough objects
-    if (size >= kMinAlign) {
-      CHECK((p % kMinAlign) == 0);
-    }
-  }
-  for (int i = 0; i < kNum; i++) {
-    free(ptrs[i]);
-  }
-}
-
-static void TestMallocAlignment() {
-  for (int lg = 0; lg < 16; lg++) {
-    TestAlignmentForSize((1<<lg) - 1);
-    TestAlignmentForSize((1<<lg) + 0);
-    TestAlignmentForSize((1<<lg) + 1);
-  }
-}
-
-static void TestHugeThreadCache() {
-  fprintf(LOGSTREAM, "==== Testing huge thread cache\n");
-  // More than 2^16 to cause integer overflow of 16 bit counters.
-  static const int kNum = 70000;
-  char** array = new char*[kNum];
-  for (int i = 0; i < kNum; ++i) {
-    array[i] = new char[10];
-  }
-  for (int i = 0; i < kNum; ++i) {
-    delete[] array[i];
-  }
-  delete[] array;
-}
-
-namespace {
-
-struct RangeCallbackState {
-  uintptr_t ptr;
-  base::MallocRange::Type expected_type;
-  size_t min_size;
-  bool matched;
-};
-
-static void RangeCallback(void* arg, const base::MallocRange* r) {
-  RangeCallbackState* state = reinterpret_cast<RangeCallbackState*>(arg);
-  if (state->ptr >= r->address &&
-      state->ptr < r->address + r->length) {
-    if (state->expected_type == base::MallocRange::FREE) {
-      // We are expecting r->type == FREE, but ReleaseMemory
-      // may have already moved us to UNMAPPED state instead (this happens in
-      // approximately 0.1% of executions). Accept either state.
-      CHECK(r->type == base::MallocRange::FREE ||
-            r->type == base::MallocRange::UNMAPPED);
-    } else {
-      CHECK_EQ(r->type, state->expected_type);
-    }
-    CHECK_GE(r->length, state->min_size);
-    state->matched = true;
-  }
-}
-
-// Check that at least one of the callbacks from Ranges() contains
-// the specified address with the specified type, and has size
-// >= min_size.
-static void CheckRangeCallback(void* ptr, base::MallocRange::Type type,
-                               size_t min_size) {
-  RangeCallbackState state;
-  state.ptr = reinterpret_cast<uintptr_t>(ptr);
-  state.expected_type = type;
-  state.min_size = min_size;
-  state.matched = false;
-  MallocExtension::instance()->Ranges(&state, RangeCallback);
-  CHECK(state.matched);
-}
-
-}
-
-static bool HaveSystemRelease =
-    TCMalloc_SystemRelease(TCMalloc_SystemAlloc(kPageSize, NULL, 0), kPageSize);
-
-static void TestRanges() {
-  static const int MB = 1048576;
-  void* a = malloc(MB);
-  void* b = malloc(MB);
-  base::MallocRange::Type releasedType =
-      HaveSystemRelease ? base::MallocRange::UNMAPPED : base::MallocRange::FREE;
-
-  CheckRangeCallback(a, base::MallocRange::INUSE, MB);
-  CheckRangeCallback(b, base::MallocRange::INUSE, MB);
-  free(a);
-  CheckRangeCallback(a, base::MallocRange::FREE, MB);
-  CheckRangeCallback(b, base::MallocRange::INUSE, MB);
-  MallocExtension::instance()->ReleaseFreeMemory();
-  CheckRangeCallback(a, releasedType, MB);
-  CheckRangeCallback(b, base::MallocRange::INUSE, MB);
-  free(b);
-  CheckRangeCallback(a, releasedType, MB);
-  CheckRangeCallback(b, base::MallocRange::FREE, MB);
-}
-
-#ifndef DEBUGALLOCATION
-static size_t GetUnmappedBytes() {
-  size_t bytes;
-  CHECK(MallocExtension::instance()->GetNumericProperty(
-      "tcmalloc.pageheap_unmapped_bytes", &bytes));
-  return bytes;
-}
-#endif
-
-class AggressiveDecommitChanger {
-  size_t old_value_;
-public:
-  AggressiveDecommitChanger(size_t new_value) {
-    MallocExtension *inst = MallocExtension::instance();
-    bool rv = inst->GetNumericProperty("tcmalloc.aggressive_memory_decommit", &old_value_);
-    CHECK_CONDITION(rv);
-    rv = inst->SetNumericProperty("tcmalloc.aggressive_memory_decommit", new_value);
-    CHECK_CONDITION(rv);
-  }
-  ~AggressiveDecommitChanger() {
-    MallocExtension *inst = MallocExtension::instance();
-    bool rv = inst->SetNumericProperty("tcmalloc.aggressive_memory_decommit", old_value_);
-    CHECK_CONDITION(rv);
-  }
-};
-
-static void TestReleaseToSystem() {
-  // Debug allocation mode adds overhead to each allocation which
-  // messes up all the equality tests here.  I just disable the
-  // teset in this mode.  TODO(csilvers): get it to work for debugalloc?
-#ifndef DEBUGALLOCATION
-
-  if(!HaveSystemRelease) return;
-
-  const double old_tcmalloc_release_rate = FLAGS_tcmalloc_release_rate;
-  FLAGS_tcmalloc_release_rate = 0;
-
-  AggressiveDecommitChanger disabler(0);
-
-  static const int MB = 1048576;
-  void* a = malloc(MB);
-  void* b = malloc(MB);
-  MallocExtension::instance()->ReleaseFreeMemory();
-  size_t starting_bytes = GetUnmappedBytes();
-
-  // Calling ReleaseFreeMemory() a second time shouldn't do anything.
-  MallocExtension::instance()->ReleaseFreeMemory();
-  EXPECT_EQ(starting_bytes, GetUnmappedBytes());
-
-  // ReleaseToSystem shouldn't do anything either.
-  MallocExtension::instance()->ReleaseToSystem(MB);
-  EXPECT_EQ(starting_bytes, GetUnmappedBytes());
-
-  free(a);
-
-  // The span to release should be 1MB.
-  MallocExtension::instance()->ReleaseToSystem(MB/2);
-  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
-
-  // Should do nothing since the previous call released too much.
-  MallocExtension::instance()->ReleaseToSystem(MB/4);
-  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
-
-  free(b);
-
-  // Use up the extra MB/4 bytes from 'a' and also release 'b'.
-  MallocExtension::instance()->ReleaseToSystem(MB/2);
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  // Should do nothing since the previous call released too much.
-  MallocExtension::instance()->ReleaseToSystem(MB/2);
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  // Nothing else to release.
-  MallocExtension::instance()->ReleaseFreeMemory();
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  a = malloc(MB);
-  free(a);
-  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
-
-  // Releasing less than a page should still trigger a release.
-  MallocExtension::instance()->ReleaseToSystem(1);
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  FLAGS_tcmalloc_release_rate = old_tcmalloc_release_rate;
-#endif   // #ifndef DEBUGALLOCATION
-}
-
-static void TestAggressiveDecommit() {
-  // Debug allocation mode adds overhead to each allocation which
-  // messes up all the equality tests here.  I just disable the
-  // teset in this mode.
-#ifndef DEBUGALLOCATION
-
-  if(!HaveSystemRelease) return;
-
-  fprintf(LOGSTREAM, "Testing aggressive de-commit\n");
-
-  AggressiveDecommitChanger enabler(1);
-
-  static const int MB = 1048576;
-  void* a = malloc(MB);
-  void* b = malloc(MB);
-
-  size_t starting_bytes = GetUnmappedBytes();
-
-  // ReleaseToSystem shouldn't do anything either.
-  MallocExtension::instance()->ReleaseToSystem(MB);
-  EXPECT_EQ(starting_bytes, GetUnmappedBytes());
-
-  free(a);
-
-  // The span to release should be 1MB.
-  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
-
-  free(b);
-
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  // Nothing else to release.
-  MallocExtension::instance()->ReleaseFreeMemory();
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  a = malloc(MB);
-  free(a);
-
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  fprintf(LOGSTREAM, "Done testing aggressive de-commit\n");
-
-#endif   // #ifndef DEBUGALLOCATION
-}
-
-// On MSVC10, in release mode, the optimizer convinces itself
-// g_no_memory is never changed (I guess it doesn't realize OnNoMemory
-// might be called).  Work around this by setting the var volatile.
-volatile bool g_no_memory = false;
-std::new_handler g_old_handler = NULL;
-static void OnNoMemory() {
-  g_no_memory = true;
-  std::set_new_handler(g_old_handler);
-}
-
-static void TestSetNewMode() {
-  int old_mode = tc_set_new_mode(1);
-
-  g_old_handler = std::set_new_handler(&OnNoMemory);
-  g_no_memory = false;
-  void* ret = malloc(kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_TRUE(g_no_memory);
-
-  g_old_handler = std::set_new_handler(&OnNoMemory);
-  g_no_memory = false;
-  ret = calloc(1, kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_TRUE(g_no_memory);
-
-  g_old_handler = std::set_new_handler(&OnNoMemory);
-  g_no_memory = false;
-  ret = realloc(NULL, kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_TRUE(g_no_memory);
-
-  if (kOSSupportsMemalign) {
-    // Not really important, but must be small enough such that
-    // kAlignment + kTooBig does not overflow.
-    const int kAlignment = 1 << 5;
-
-    g_old_handler = std::set_new_handler(&OnNoMemory);
-    g_no_memory = false;
-    ret = Memalign(kAlignment, kTooBig);
-    EXPECT_EQ(NULL, ret);
-    EXPECT_TRUE(g_no_memory);
-
-    g_old_handler = std::set_new_handler(&OnNoMemory);
-    g_no_memory = false;
-    EXPECT_EQ(ENOMEM,
-              PosixMemalign(&ret, kAlignment, kTooBig));
-    EXPECT_EQ(NULL, ret);
-    EXPECT_TRUE(g_no_memory);
-  }
-
-  tc_set_new_mode(old_mode);
-}
-
-static void TestErrno(void) {
-  void* ret;
-  if (kOSSupportsMemalign) {
-    errno = 0;
-    ret = Memalign(128, kTooBig);
-    EXPECT_EQ(NULL, ret);
-    EXPECT_EQ(ENOMEM, errno);
-  }
-
-  errno = 0;
-  ret = malloc(kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_EQ(ENOMEM, errno);
-
-  errno = 0;
-  ret = tc_malloc_skip_new_handler(kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_EQ(ENOMEM, errno);
-}
-
-
-#ifndef DEBUGALLOCATION
-// Ensure that nallocx works before main.
-struct GlobalNallocx {
-  GlobalNallocx() { CHECK_GT(nallocx(99, 0), 99); }
-} global_nallocx;
-
-#if defined(__GNUC__)
-
-static void check_global_nallocx() __attribute__((constructor));
-static void check_global_nallocx() { CHECK_GT(nallocx(99, 0), 99); }
-
-#endif // __GNUC__
-
-static void TestNAllocX() {
-  for (size_t size = 0; size <= (1 << 20); size += 7) {
-    size_t rounded = nallocx(size, 0);
-    ASSERT_GE(rounded, size);
-    void* ptr = malloc(size);
-    ASSERT_EQ(rounded, MallocExtension::instance()->GetAllocatedSize(ptr));
-    free(ptr);
-  }
-}
-
-static void TestNAllocXAlignment() {
-  for (size_t size = 0; size <= (1 << 20); size += 7) {
-    for (size_t align = 0; align < 10; align++) {
-      size_t rounded = nallocx(size, MALLOCX_LG_ALIGN(align));
-      ASSERT_GE(rounded, size);
-      ASSERT_EQ(rounded % (1 << align), 0);
-      void* ptr = tc_memalign(1 << align, size);
-      ASSERT_EQ(rounded, MallocExtension::instance()->GetAllocatedSize(ptr));
-      free(ptr);
-    }
-  }
-}
-
-static int saw_new_handler_runs;
-static void* volatile oom_test_last_ptr;
-
-static void test_new_handler() {
-  get_test_sys_alloc()->simulate_oom = false;
-  void *ptr = oom_test_last_ptr;
-  oom_test_last_ptr = NULL;
-  ::operator delete[](ptr);
-  saw_new_handler_runs++;
-}
-
-static ATTRIBUTE_NOINLINE void TestNewOOMHandling() {
-  // debug allocator does internal allocations and crashes when such
-  // internal allocation fails. So don't test it.
-  setup_oomable_sys_alloc();
-
-  std::new_handler old = std::set_new_handler(test_new_handler);
-  get_test_sys_alloc()->simulate_oom = true;
-
-  ASSERT_EQ(saw_new_handler_runs, 0);
-
-  for (int i = 0; i < 10240; i++) {
-    oom_test_last_ptr = new char [512];
-    ASSERT_NE(oom_test_last_ptr, NULL);
-    if (saw_new_handler_runs) {
-      break;
-    }
-  }
-
-  ASSERT_GE(saw_new_handler_runs, 1);
-
-  get_test_sys_alloc()->simulate_oom = false;
-  std::set_new_handler(old);
-}
-#endif  // !DEBUGALLOCATION
-
-static int RunAllTests(int argc, char** argv) {
-  // Optional argv[1] is the seed
-  AllocatorState rnd(argc > 1 ? atoi(argv[1]) : 100);
-
-  SetTestResourceLimit();
-
-#ifndef DEBUGALLOCATION
-  TestNewOOMHandling();
-#endif
-
-  // TODO(odo):  This test has been disabled because it is only by luck that it
-  // does not result in fragmentation.  When tcmalloc makes an allocation which
-  // spans previously unused leaves of the pagemap it will allocate and fill in
-  // the leaves to cover the new allocation.  The leaves happen to be 256MiB in
-  // the 64-bit build, and with the sbrk allocator these allocations just
-  // happen to fit in one leaf by luck.  With other allocators (mmap,
-  // memfs_malloc when used with small pages) the allocations generally span
-  // two leaves and this results in a very bad fragmentation pattern with this
-  // code.  The same failure can be forced with the sbrk allocator just by
-  // allocating something on the order of 128MiB prior to starting this test so
-  // that the test allocations straddle a 256MiB boundary.
-
-  // TODO(csilvers): port MemoryUsage() over so the test can use that
-#if 0
-# include <unistd.h>      // for getpid()
-  // Allocate and deallocate blocks of increasing sizes to check if the alloc
-  // metadata fragments the memory. (Do not put other allocations/deallocations
-  // before this test, it may break).
-  {
-    size_t memory_usage = MemoryUsage(getpid());
-    fprintf(LOGSTREAM, "Testing fragmentation\n");
-    for ( int i = 200; i < 240; ++i ) {
-      int size = i << 20;
-      void *test1 = rnd.alloc(size);
-      CHECK(test1);
-      for ( int j = 0; j < size; j += (1 << 12) ) {
-        static_cast<char*>(test1)[j] = 1;
-      }
-      free(test1);
-    }
-    // There may still be a bit of fragmentation at the beginning, until we
-    // reach kPageMapBigAllocationThreshold bytes so we check for
-    // 200 + 240 + margin.
-    CHECK_LT(MemoryUsage(getpid()), memory_usage + (450 << 20) );
-  }
-#endif
-
-  // Check that empty allocation works
-  fprintf(LOGSTREAM, "Testing empty allocation\n");
-  {
-    void* p1 = rnd.alloc(0);
-    CHECK(p1 != NULL);
-    void* p2 = rnd.alloc(0);
-    CHECK(p2 != NULL);
-    CHECK(p1 != p2);
-    free(p1);
-    free(p2);
-  }
-
-  // This code stresses some of the memory allocation via STL.
-  // It may call operator delete(void*, nothrow_t).
-  fprintf(LOGSTREAM, "Testing STL use\n");
-  {
-    std::vector<int> v;
-    v.push_back(1);
-    v.push_back(2);
-    v.push_back(3);
-    v.push_back(0);
-    std::stable_sort(v.begin(), v.end());
-  }
-
-  // Test each of the memory-allocation functions once, just as a sanity-check
-  fprintf(LOGSTREAM, "Sanity-testing all the memory allocation functions\n");
-  {
-    // We use new-hook and delete-hook to verify we actually called the
-    // tcmalloc version of these routines, and not the libc version.
-    SetNewHook();      // defined as part of MAKE_HOOK_CALLBACK, above
-    SetDeleteHook();   // ditto
-
-    void* p1 = malloc(10);
-    CHECK(p1 != NULL);    // force use of this variable
-    VerifyNewHookWasCalled();
-    // Also test the non-standard tc_malloc_size
-    size_t actual_p1_size = tc_malloc_size(p1);
-    CHECK_GE(actual_p1_size, 10);
-    CHECK_LT(actual_p1_size, 100000);   // a reasonable upper-bound, I think
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    p1 = tc_malloc_skip_new_handler(10);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    p1 = calloc(10, 2);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    // We make sure we realloc to a big size, since some systems (OS
-    // X) will notice if the realloced size continues to fit into the
-    // malloc-block and make this a noop if so.
-    p1 = realloc(p1, 30000);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    VerifyDeleteHookWasCalled();
-    cfree(p1);  // synonym for free
-    VerifyDeleteHookWasCalled();
-
-    if (kOSSupportsMemalign) {
-      CHECK_EQ(PosixMemalign(&p1, sizeof(p1), 40), 0);
-      CHECK(p1 != NULL);
-      VerifyNewHookWasCalled();
-      free(p1);
-      VerifyDeleteHookWasCalled();
-
-      p1 = Memalign(sizeof(p1) * 2, 50);
-      CHECK(p1 != NULL);
-      VerifyNewHookWasCalled();
-      free(p1);
-      VerifyDeleteHookWasCalled();
-    }
-
-    // Windows has _aligned_malloc.  Let's test that that's captured too.
-#if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(PERFTOOLS_NO_ALIGNED_MALLOC)
-    p1 = _aligned_malloc(sizeof(p1) * 2, 64);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    _aligned_free(p1);
-    VerifyDeleteHookWasCalled();
-#endif
-
-    p1 = valloc(60);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    p1 = pvalloc(70);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    char* p2 = new char;
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete p2;
-    VerifyDeleteHookWasCalled();
-
-    p2 = new char[100];
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete[] p2;
-    VerifyDeleteHookWasCalled();
-
-    p2 = new(std::nothrow) char;
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete p2;
-    VerifyDeleteHookWasCalled();
-
-    p2 = new(std::nothrow) char[100];
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete[] p2;
-    VerifyDeleteHookWasCalled();
-
-    // Another way of calling operator new
-    p2 = static_cast<char*>(::operator new(100));
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2);
-    VerifyDeleteHookWasCalled();
-
-    // Try to call nothrow's delete too.  Compilers use this.
-    p2 = static_cast<char*>(::operator new(100, std::nothrow));
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, std::nothrow);
-    VerifyDeleteHookWasCalled();
-
-#ifdef ENABLE_SIZED_DELETE
-    p2 = new char;
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, sizeof(char));
-    VerifyDeleteHookWasCalled();
-
-    p2 = new char[100];
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete[](p2, sizeof(char) * 100);
-    VerifyDeleteHookWasCalled();
-#endif
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-    overaligned_type* poveraligned = new overaligned_type;
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = new overaligned_type[10];
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete[] poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = new(std::nothrow) overaligned_type;
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = new(std::nothrow) overaligned_type[10];
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete[] poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    // Another way of calling operator new
-    p2 = static_cast<char*>(::operator new(100, std::align_val_t(OVERALIGNMENT)));
-    CHECK(p2 != NULL);
-    CHECK((((size_t)p2) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, std::align_val_t(OVERALIGNMENT));
-    VerifyDeleteHookWasCalled();
-
-    p2 = static_cast<char*>(::operator new(100, std::align_val_t(OVERALIGNMENT), std::nothrow));
-    CHECK(p2 != NULL);
-    CHECK((((size_t)p2) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, std::align_val_t(OVERALIGNMENT), std::nothrow);
-    VerifyDeleteHookWasCalled();
-
-#ifdef ENABLE_SIZED_DELETE
-    poveraligned = new overaligned_type;
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    ::operator delete(poveraligned, sizeof(overaligned_type), std::align_val_t(OVERALIGNMENT));
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = new overaligned_type[10];
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    ::operator delete[](poveraligned, sizeof(overaligned_type) * 10, std::align_val_t(OVERALIGNMENT));
-    VerifyDeleteHookWasCalled();
-#endif
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-    // Try strdup(), which the system allocates but we must free.  If
-    // all goes well, libc will use our malloc!
-    p2 = strdup("in memory of James Golick");
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    free(p2);
-    VerifyDeleteHookWasCalled();
-
-
-    // Test mmap too: both anonymous mmap and mmap of a file
-    // Note that for right now we only override mmap on linux
-    // systems, so those are the only ones for which we check.
-    SetMmapHook();
-    SetMremapHook();
-    SetMunmapHook();
-#if defined(HAVE_MMAP) && defined(__linux) && \
-       (defined(__i386__) || defined(__x86_64__))
-    int size = 8192*2;
-    p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE,
-              -1, 0);
-    CHECK(p1 != NULL);
-    VerifyMmapHookWasCalled();
-    p1 = mremap(p1, size, size/2, 0);
-    CHECK(p1 != NULL);
-    VerifyMremapHookWasCalled();
-    size /= 2;
-    munmap(p1, size);
-    VerifyMunmapHookWasCalled();
-
-    int fd = open("/dev/zero", O_RDONLY);
-    CHECK_GE(fd, 0);   // make sure the open succeeded
-    p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);
-    CHECK(p1 != NULL);
-    VerifyMmapHookWasCalled();
-    munmap(p1, 8192);
-    VerifyMunmapHookWasCalled();
-    close(fd);
-#else   // this is just to quiet the compiler: make sure all fns are called
-    IncrementCallsToMmapHook(NULL, NULL, 0, 0, 0, 0, 0);
-    IncrementCallsToMunmapHook(NULL, 0);
-    IncrementCallsToMremapHook(NULL, NULL, 0, 0, 0, NULL);
-    VerifyMmapHookWasCalled();
-    VerifyMremapHookWasCalled();
-    VerifyMunmapHookWasCalled();
-#endif
-
-    // Test sbrk
-    SetSbrkHook();
-#if defined(HAVE_SBRK) && defined(__linux) && \
-       (defined(__i386__) || defined(__x86_64__))
-    p1 = sbrk(8192);
-    CHECK(p1 != NULL);
-    VerifySbrkHookWasCalled();
-    p1 = sbrk(-8192);
-    CHECK(p1 != NULL);
-    VerifySbrkHookWasCalled();
-    // However, sbrk hook should *not* be called with sbrk(0)
-    p1 = sbrk(0);
-    CHECK(p1 != NULL);
-    CHECK_EQ(g_SbrkHook_calls, 0);
-#else   // this is just to quiet the compiler: make sure all fns are called
-    IncrementCallsToSbrkHook(NULL, 0);
-    VerifySbrkHookWasCalled();
-#endif
-
-    // Reset the hooks to what they used to be.  These are all
-    // defined as part of MAKE_HOOK_CALLBACK, above.
-    ResetNewHook();
-    ResetDeleteHook();
-    ResetMmapHook();
-    ResetMremapHook();
-    ResetMunmapHook();
-    ResetSbrkHook();
-  }
-
-  // Check that "lots" of memory can be allocated
-  fprintf(LOGSTREAM, "Testing large allocation\n");
-  {
-    const int mb_to_allocate = 100;
-    void* p = rnd.alloc(mb_to_allocate << 20);
-    CHECK(p != NULL);  // could not allocate
-    free(p);
-  }
-
-  TestMallocAlignment();
-
-  // Check calloc() with various arguments
-  fprintf(LOGSTREAM, "Testing calloc\n");
-  TestCalloc(0, 0, true);
-  TestCalloc(0, 1, true);
-  TestCalloc(1, 1, true);
-  TestCalloc(1<<10, 0, true);
-  TestCalloc(1<<20, 0, true);
-  TestCalloc(0, 1<<10, true);
-  TestCalloc(0, 1<<20, true);
-  TestCalloc(1<<20, 2, true);
-  TestCalloc(2, 1<<20, true);
-  TestCalloc(1000, 1000, true);
-
-  TestCalloc(kMaxSize, 2, false);
-  TestCalloc(2, kMaxSize, false);
-  TestCalloc(kMaxSize, kMaxSize, false);
-
-  TestCalloc(kMaxSignedSize, 3, false);
-  TestCalloc(3, kMaxSignedSize, false);
-  TestCalloc(kMaxSignedSize, kMaxSignedSize, false);
-
-  // Test that realloc doesn't always reallocate and copy memory.
-  fprintf(LOGSTREAM, "Testing realloc\n");
-  TestRealloc();
-
-  fprintf(LOGSTREAM, "Testing operator new(nothrow).\n");
-  TestNothrowNew(&::operator new);
-  fprintf(LOGSTREAM, "Testing operator new[](nothrow).\n");
-  TestNothrowNew(&::operator new[]);
-  fprintf(LOGSTREAM, "Testing operator new.\n");
-  TestNew(&::operator new);
-  fprintf(LOGSTREAM, "Testing operator new[].\n");
-  TestNew(&::operator new[]);
-
-  // Create threads
-  fprintf(LOGSTREAM, "Testing threaded allocation/deallocation (%d threads)\n",
-          FLAGS_numthreads);
-  threads = new TesterThread*[FLAGS_numthreads];
-  for (int i = 0; i < FLAGS_numthreads; ++i) {
-    threads[i] = new TesterThread(i);
-  }
-
-  // This runs all the tests at the same time, with a 1M stack size each
-  RunManyThreadsWithId(RunThread, FLAGS_numthreads, 1<<20);
-
-  for (int i = 0; i < FLAGS_numthreads; ++i) delete threads[i];    // Cleanup
-
-  // Do the memory intensive tests after threads are done, since exhausting
-  // the available address space can make pthread_create to fail.
-
-  // Check that huge allocations fail with NULL instead of crashing
-  fprintf(LOGSTREAM, "Testing huge allocations\n");
-  TestHugeAllocations(&rnd);
-
-  // Check that large allocations fail with NULL instead of crashing
-#ifndef DEBUGALLOCATION    // debug allocation takes forever for huge allocs
-  fprintf(LOGSTREAM, "Testing out of memory\n");
-  for (int s = 0; ; s += (10<<20)) {
-    void* large_object = rnd.alloc(s);
-    if (large_object == NULL) break;
-    free(large_object);
-  }
-#endif
-
-  TestHugeThreadCache();
-  TestRanges();
-  TestReleaseToSystem();
-  TestAggressiveDecommit();
-  TestSetNewMode();
-  TestErrno();
-
-// GetAllocatedSize under DEBUGALLOCATION returns the size that we asked for.
-#ifndef DEBUGALLOCATION
-  TestNAllocX();
-  TestNAllocXAlignment();
-#endif
-
-  return 0;
-}
-
-}
-
-using testing::RunAllTests;
-
-int main(int argc, char** argv) {
-#ifdef DEBUGALLOCATION    // debug allocation takes forever for huge allocs
-  FLAGS_max_free_queue_size = 0;  // return freed blocks to tcmalloc immediately
-#endif
-
-  RunAllTests(argc, argv);
-
-  // Test tc_version()
-  fprintf(LOGSTREAM, "Testing tc_version()\n");
-  int major;
-  int minor;
-  const char* patch;
-  char mmp[64];
-  const char* human_version = tc_version(&major, &minor, &patch);
-  snprintf(mmp, sizeof(mmp), "%d.%d%s", major, minor, patch);
-  CHECK(!strcmp(PACKAGE_STRING, human_version));
-  CHECK(!strcmp(PACKAGE_VERSION, mmp));
-
-  fprintf(LOGSTREAM, "PASS\n");
-}
diff --git a/third_party/tcmalloc/chromium/src/tests/tcmalloc_unittest.sh b/third_party/tcmalloc/chromium/src/tests/tcmalloc_unittest.sh
deleted file mode 100755
index 0e7996a..0000000
--- a/third_party/tcmalloc/chromium/src/tests/tcmalloc_unittest.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2013, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Adhemerval Zanella
-#
-# Runs the tcmalloc_unittest with various environment variables.
-# This is necessary because tuning some environment variables
-# (TCMALLOC_TRANSFER_NUM_OBJ for instance) should not change program
-# behavior, just performance.
-
-BINDIR="${BINDIR:-.}"
-TCMALLOC_UNITTEST="${1:-$BINDIR/tcmalloc_unittest}"
-
-TMPDIR=/tmp/tcmalloc_unittest
-rm -rf $TMPDIR || exit 2
-mkdir $TMPDIR || exit 3
-
-run_unittest() {
-    if $TCMALLOC_UNITTEST > $TMPDIR/output 2>&1; then
-      echo "OK"
-    else
-      echo "FAILED"
-      echo "Output from the failed run:"
-      echo "----"
-      cat $TMPDIR/output
-      echo "----"
-      exit 4
-    fi
-}
-
-# $1: value of tcmalloc_unittest env. var.
-run_check_transfer_num_obj() {
-    [ -n "$1" ] && export TCMALLOC_TRANSFER_NUM_OBJ="$1"
-
-    echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_TRANSFER_NUM_OBJ=$1 ... "
-    run_unittest
-}
-
-run_check_transfer_num_obj ""
-run_check_transfer_num_obj "40"
-run_check_transfer_num_obj "4096"
-
-echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_AGGRESSIVE_DECOMMIT=t ... "
-
-TCMALLOC_AGGRESSIVE_DECOMMIT=t run_unittest
-
-echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_HEAP_LIMIT_MB=512 ... "
-
-TCMALLOC_HEAP_LIMIT_MB=512 run_unittest
-
-echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_ENABLE_SIZED_DELETE=t ..."
-
-TCMALLOC_ENABLE_SIZED_DELETE=t run_unittest
-
-echo "PASS"
diff --git a/third_party/tcmalloc/chromium/src/tests/testutil.cc b/third_party/tcmalloc/chromium/src/tests/testutil.cc
deleted file mode 100644
index c2c71cb3..0000000
--- a/third_party/tcmalloc/chromium/src/tests/testutil.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// A few routines that are useful for multiple tests in this directory.
-
-#include "config_for_unittests.h"
-#include <stdlib.h>           // for NULL, abort()
-// On FreeBSD, if you #include <sys/resource.h>, you have to get stdint first.
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-#include "tests/testutil.h"
-
-
-// When compiled 64-bit and run on systems with swap several unittests will end
-// up trying to consume all of RAM+swap, and that can take quite some time.  By
-// limiting the address-space size we get sufficient coverage without blowing
-// out job limits.
-void SetTestResourceLimit() {
-#ifdef HAVE_SYS_RESOURCE_H
-  // The actual resource we need to set varies depending on which flavour of
-  // unix.  On Linux we need RLIMIT_AS because that covers the use of mmap.
-  // Otherwise hopefully RLIMIT_RSS is good enough.  (Unfortunately 64-bit
-  // and 32-bit headers disagree on the type of these constants!)
-#ifdef RLIMIT_AS
-#define USE_RESOURCE RLIMIT_AS
-#else
-#define USE_RESOURCE RLIMIT_RSS
-#endif
-
-  // Restrict the test to 1GiB, which should fit comfortably well on both
-  // 32-bit and 64-bit hosts, and executes in ~1s.
-  const rlim_t kMaxMem = 1<<30;
-
-  struct rlimit rlim;
-  if (getrlimit(USE_RESOURCE, &rlim) == 0) {
-    if (rlim.rlim_cur == RLIM_INFINITY || rlim.rlim_cur > kMaxMem) {
-      rlim.rlim_cur = kMaxMem;
-      setrlimit(USE_RESOURCE, &rlim); // ignore result
-    }
-  }
-#endif  /* HAVE_SYS_RESOURCE_H */
-}
-
-
-struct FunctionAndId {
-  void (*ptr_to_function)(int);
-  int id;
-};
-
-#if defined(NO_THREADS) || !(defined(HAVE_PTHREAD) || defined(_WIN32))
-
-extern "C" void RunThread(void (*fn)()) {
-  (*fn)();
-}
-
-extern "C" void RunManyThreads(void (*fn)(), int count) {
-  // I guess the best we can do is run fn sequentially, 'count' times
-  for (int i = 0; i < count; i++)
-    (*fn)();
-}
-
-extern "C" void RunManyThreadsWithId(void (*fn)(int), int count, int) {
-  for (int i = 0; i < count; i++)
-    (*fn)(i);    // stacksize doesn't make sense in a non-threaded context
-}
-
-#elif defined(_WIN32)
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */
-#endif
-#include <windows.h>
-
-extern "C" {
-  // This helper function has the signature that pthread_create wants.
-  DWORD WINAPI RunFunctionInThread(LPVOID ptr_to_ptr_to_fn) {
-    (**static_cast<void (**)()>(ptr_to_ptr_to_fn))();    // runs fn
-    return 0;
-  }
-
-  DWORD WINAPI RunFunctionInThreadWithId(LPVOID ptr_to_fnid) {
-    FunctionAndId* fn_and_id = static_cast<FunctionAndId*>(ptr_to_fnid);
-    (*fn_and_id->ptr_to_function)(fn_and_id->id);   // runs fn
-    return 0;
-  }
-
-  void RunManyThreads(void (*fn)(), int count) {
-    DWORD dummy;
-    HANDLE* hThread = new HANDLE[count];
-    for (int i = 0; i < count; i++) {
-      hThread[i] = CreateThread(NULL, 0, RunFunctionInThread, &fn, 0, &dummy);
-      if (hThread[i] == NULL)  ExitProcess(i);
-    }
-    WaitForMultipleObjects(count, hThread, TRUE, INFINITE);
-    for (int i = 0; i < count; i++) {
-      CloseHandle(hThread[i]);
-    }
-    delete[] hThread;
-  }
-
-  void RunThread(void (*fn)()) {
-    RunManyThreads(fn, 1);
-  }
-
-  void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize) {
-    DWORD dummy;
-    HANDLE* hThread = new HANDLE[count];
-    FunctionAndId* fn_and_ids = new FunctionAndId[count];
-    for (int i = 0; i < count; i++) {
-      fn_and_ids[i].ptr_to_function = fn;
-      fn_and_ids[i].id = i;
-      hThread[i] = CreateThread(NULL, stacksize, RunFunctionInThreadWithId,
-                                &fn_and_ids[i], 0, &dummy);
-      if (hThread[i] == NULL)  ExitProcess(i);
-    }
-    WaitForMultipleObjects(count, hThread, TRUE, INFINITE);
-    for (int i = 0; i < count; i++) {
-      CloseHandle(hThread[i]);
-    }
-    delete[] fn_and_ids;
-    delete[] hThread;
-  }
-}
-
-#else  // not NO_THREADS, not !HAVE_PTHREAD, not _WIN32
-
-#include <pthread.h>
-
-#define SAFE_PTHREAD(fncall)  do { if ((fncall) != 0) abort(); } while (0)
-
-extern "C" {
-  // This helper function has the signature that pthread_create wants.
-  static void* RunFunctionInThread(void *ptr_to_ptr_to_fn) {
-    (**static_cast<void (**)()>(ptr_to_ptr_to_fn))();    // runs fn
-    return NULL;
-  }
-
-  static void* RunFunctionInThreadWithId(void *ptr_to_fnid) {
-    FunctionAndId* fn_and_id = static_cast<FunctionAndId*>(ptr_to_fnid);
-    (*fn_and_id->ptr_to_function)(fn_and_id->id);   // runs fn
-    return NULL;
-  }
-
-  // Run a function in a thread of its own and wait for it to finish.
-  // This is useful for tcmalloc testing, because each thread is
-  // handled separately in tcmalloc, so there's interesting stuff to
-  // test even if the threads are not running concurrently.
-  void RunThread(void (*fn)()) {
-    pthread_t thr;
-    // Even though fn is on the stack, it's safe to pass a pointer to it,
-    // because we pthread_join immediately (ie, before RunInThread exits).
-    SAFE_PTHREAD(pthread_create(&thr, NULL, RunFunctionInThread, &fn));
-    SAFE_PTHREAD(pthread_join(thr, NULL));
-  }
-
-  void RunManyThreads(void (*fn)(), int count) {
-    pthread_t* thr = new pthread_t[count];
-    for (int i = 0; i < count; i++) {
-      SAFE_PTHREAD(pthread_create(&thr[i], NULL, RunFunctionInThread, &fn));
-    }
-    for (int i = 0; i < count; i++) {
-      SAFE_PTHREAD(pthread_join(thr[i], NULL));
-    }
-    delete[] thr;
-  }
-
-  void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize) {
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-    pthread_attr_setstacksize(&attr, stacksize);
-
-    pthread_t* thr = new pthread_t[count];
-    FunctionAndId* fn_and_ids = new FunctionAndId[count];
-    for (int i = 0; i < count; i++) {
-      fn_and_ids[i].ptr_to_function = fn;
-      fn_and_ids[i].id = i;
-      SAFE_PTHREAD(pthread_create(&thr[i], &attr,
-                                  RunFunctionInThreadWithId, &fn_and_ids[i]));
-    }
-    for (int i = 0; i < count; i++) {
-      SAFE_PTHREAD(pthread_join(thr[i], NULL));
-    }
-    delete[] fn_and_ids;
-    delete[] thr;
-
-    pthread_attr_destroy(&attr);
-  }
-}
-
-#endif
diff --git a/third_party/tcmalloc/chromium/src/tests/testutil.h b/third_party/tcmalloc/chromium/src/tests/testutil.h
deleted file mode 100644
index 071a209..0000000
--- a/third_party/tcmalloc/chromium/src/tests/testutil.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-
-#ifndef TCMALLOC_TOOLS_TESTUTIL_H_
-#define TCMALLOC_TOOLS_TESTUTIL_H_
-
-// Run a function in a thread of its own and wait for it to finish.
-// The function you pass in must have the signature
-//    void MyFunction();
-extern "C" void RunThread(void (*fn)());
-
-// Run a function X times, in X threads, and wait for them all to finish.
-// The function you pass in must have the signature
-//    void MyFunction();
-extern "C" void RunManyThreads(void (*fn)(), int count);
-
-// The 'advanced' version: run a function X times, in X threads, and
-// wait for them all to finish.  Give them all the specified stack-size.
-// (If you're curious why this takes a stacksize and the others don't,
-// it's because the one client of this fn wanted to specify stacksize. :-) )
-// The function you pass in must have the signature
-//    void MyFunction(int idx);
-// where idx is the index of the thread (which of the X threads this is).
-extern "C" void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize);
-
-// When compiled 64-bit and run on systems with swap several unittests will end
-// up trying to consume all of RAM+swap, and that can take quite some time.  By
-// limiting the address-space size we get sufficient coverage without blowing
-// out job limits.
-void SetTestResourceLimit();
-
-#endif  // TCMALLOC_TOOLS_TESTUTIL_H_
diff --git a/third_party/tcmalloc/chromium/src/tests/thread_dealloc_unittest.cc b/third_party/tcmalloc/chromium/src/tests/thread_dealloc_unittest.cc
deleted file mode 100644
index 97615cd..0000000
--- a/third_party/tcmalloc/chromium/src/tests/thread_dealloc_unittest.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2004, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Check that we do not leak memory when cycling through lots of threads.
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for sleep()
-#endif
-#include "base/logging.h"
-#include <gperftools/malloc_extension.h>
-#include "tests/testutil.h"   // for RunThread()
-
-// Size/number of objects to allocate per thread (1 MB per thread)
-static const int kObjectSize = 1024;
-static const int kNumObjects = 1024;
-
-// Number of threads to create and destroy
-static const int kNumThreads = 1000;
-
-// Allocate lots of stuff
-static void AllocStuff() {
-  void** objects = new void*[kNumObjects];
-  for (int i = 0; i < kNumObjects; i++) {
-    objects[i] = malloc(kObjectSize);
-  }
-  for (int i = 0; i < kNumObjects; i++) {
-    free(objects[i]);
-  }
-  delete[] objects;
-}
-
-int main(int argc, char** argv) {
-  static const int kDisplaySize = 1048576;
-  char* display = new char[kDisplaySize];
-
-  for (int i = 0; i < kNumThreads; i++) {
-    RunThread(&AllocStuff);
-
-    if (((i+1) % 200) == 0) {
-      fprintf(stderr, "Iteration: %d of %d\n", (i+1), kNumThreads);
-      MallocExtension::instance()->GetStats(display, kDisplaySize);
-      fprintf(stderr, "%s\n", display);
-    }
-  }
-  delete[] display;
-
-  printf("PASS\n");
-#ifdef HAVE_UNISTD_H
-  sleep(1);     // Prevent exit race problem with glibc
-#endif
-  return 0;
-}
diff --git a/third_party/tcmalloc/chromium/src/third_party/valgrind.h b/third_party/tcmalloc/chromium/src/third_party/valgrind.h
deleted file mode 100644
index 577c59a..0000000
--- a/third_party/tcmalloc/chromium/src/third_party/valgrind.h
+++ /dev/null
@@ -1,3924 +0,0 @@
-/* -*- c -*-
-   ----------------------------------------------------------------
-
-   Notice that the following BSD-style license applies to this one
-   file (valgrind.h) only.  The rest of Valgrind is licensed under the
-   terms of the GNU General Public License, version 2, unless
-   otherwise indicated.  See the COPYING file in the source
-   distribution for details.
-
-   ----------------------------------------------------------------
-
-   This file is part of Valgrind, a dynamic binary instrumentation
-   framework.
-
-   Copyright (C) 2000-2008 Julian Seward.  All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-
-   1. Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-   2. The origin of this software must not be misrepresented; you must 
-      not claim that you wrote the original software.  If you use this 
-      software in a product, an acknowledgment in the product 
-      documentation would be appreciated but is not required.
-
-   3. Altered source versions must be plainly marked as such, and must
-      not be misrepresented as being the original software.
-
-   4. The name of the author may not be used to endorse or promote 
-      products derived from this software without specific prior written 
-      permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-   ----------------------------------------------------------------
-
-   Notice that the above BSD-style license applies to this one file
-   (valgrind.h) only.  The entire rest of Valgrind is licensed under
-   the terms of the GNU General Public License, version 2.  See the
-   COPYING file in the source distribution for details.
-
-   ---------------------------------------------------------------- 
-*/
-
-
-/* This file is for inclusion into client (your!) code.
-
-   You can use these macros to manipulate and query Valgrind's 
-   execution inside your own programs.
-
-   The resulting executables will still run without Valgrind, just a
-   little bit more slowly than they otherwise would, but otherwise
-   unchanged.  When not running on valgrind, each client request
-   consumes very few (eg. 7) instructions, so the resulting performance
-   loss is negligible unless you plan to execute client requests
-   millions of times per second.  Nevertheless, if that is still a
-   problem, you can compile with the NVALGRIND symbol defined (gcc
-   -DNVALGRIND) so that client requests are not even compiled in.  */
-
-#ifndef __VALGRIND_H
-#define __VALGRIND_H
-
-#include <stdarg.h>
-
-/* Nb: this file might be included in a file compiled with -ansi.  So
-   we can't use C++ style "//" comments nor the "asm" keyword (instead
-   use "__asm__"). */
-
-/* Derive some tags indicating what the target platform is.  Note
-   that in this file we're using the compiler's CPP symbols for
-   identifying architectures, which are different to the ones we use
-   within the rest of Valgrind.  Note, __powerpc__ is active for both
-   32 and 64-bit PPC, whereas __powerpc64__ is only active for the
-   latter (on Linux, that is). */
-#undef PLAT_x86_linux
-#undef PLAT_amd64_linux
-#undef PLAT_ppc32_linux
-#undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
-
-#if !defined(_AIX) && defined(__i386__)
-#  define PLAT_x86_linux 1
-#elif !defined(_AIX) && defined(__x86_64__)
-#  define PLAT_amd64_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
-#  define PLAT_ppc32_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
-#  define PLAT_ppc64_linux 1
-#elif defined(_AIX) && defined(__64BIT__)
-#  define PLAT_ppc64_aix5 1
-#elif defined(_AIX) && !defined(__64BIT__)
-#  define PLAT_ppc32_aix5 1
-#endif
-
-
-/* If we're not compiling for our target platform, don't generate
-   any inline asms.  */
-#if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \
-    && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \
-    && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5)
-#  if !defined(NVALGRIND)
-#    define NVALGRIND 1
-#  endif
-#endif
-
-
-/* ------------------------------------------------------------------ */
-/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
-/* in here of use to end-users -- skip to the next section.           */
-/* ------------------------------------------------------------------ */
-
-#if defined(NVALGRIND)
-
-/* Define NVALGRIND to completely remove the Valgrind magic sequence
-   from the compiled code (analogous to NDEBUG's effects on
-   assert()) */
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-   {                                                              \
-      (_zzq_rlval) = (_zzq_default);                              \
-   }
-
-#else  /* ! NVALGRIND */
-
-/* The following defines the magic code sequences which the JITter
-   spots and handles magically.  Don't look too closely at them as
-   they will rot your brain.
-
-   The assembly code sequences for all architectures is in this one
-   file.  This is because this file must be stand-alone, and we don't
-   want to have multiple files.
-
-   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
-   value gets put in the return slot, so that everything works when
-   this is executed not under Valgrind.  Args are passed in a memory
-   block, and so there's no intrinsic limit to the number that could
-   be passed, but it's currently five.
-   
-   The macro args are: 
-      _zzq_rlval    result lvalue
-      _zzq_default  default value (result returned when running on real CPU)
-      _zzq_request  request code
-      _zzq_arg1..5  request params
-
-   The other two macros are used to support function wrapping, and are
-   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
-   guest's NRADDR pseudo-register and whatever other information is
-   needed to safely run the call original from the wrapper: on
-   ppc64-linux, the R2 value at the divert point is also needed.  This
-   information is abstracted into a user-visible type, OrigFn.
-
-   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
-   guest, but guarantees that the branch instruction will not be
-   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
-   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
-   complete inline asm, since it needs to be combined with more magic
-   inline asm stuff to be useful.
-*/
-
-/* ------------------------- x86-linux ------------------------- */
-
-#if defined(PLAT_x86_linux)
-
-typedef
-   struct { 
-      unsigned int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
-                     "roll $29, %%edi ; roll $19, %%edi\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-  { volatile unsigned int _zzq_args[6];                           \
-    volatile unsigned int _zzq_result;                            \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %EDX = client_request ( %EAX ) */         \
-                     "xchgl %%ebx,%%ebx"                          \
-                     : "=d" (_zzq_result)                         \
-                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    volatile unsigned int __addr;                                 \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %EAX = guest_NRADDR */                    \
-                     "xchgl %%ecx,%%ecx"                          \
-                     : "=a" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_CALL_NOREDIR_EAX                                 \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* call-noredir *%EAX */                     \
-                     "xchgl %%edx,%%edx\n\t"
-#endif /* PLAT_x86_linux */
-
-/* ------------------------ amd64-linux ------------------------ */
-
-#if defined(PLAT_amd64_linux)
-
-typedef
-   struct { 
-      unsigned long long int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
-                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-  { volatile unsigned long long int _zzq_args[6];                 \
-    volatile unsigned long long int _zzq_result;                  \
-    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
-    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
-    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
-    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
-    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
-    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %RDX = client_request ( %RAX ) */         \
-                     "xchgq %%rbx,%%rbx"                          \
-                     : "=d" (_zzq_result)                         \
-                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    volatile unsigned long long int __addr;                       \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %RAX = guest_NRADDR */                    \
-                     "xchgq %%rcx,%%rcx"                          \
-                     : "=a" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_CALL_NOREDIR_RAX                                 \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* call-noredir *%RAX */                     \
-                     "xchgq %%rdx,%%rdx\n\t"
-#endif /* PLAT_amd64_linux */
-
-/* ------------------------ ppc32-linux ------------------------ */
-
-#if defined(PLAT_ppc32_linux)
-
-typedef
-   struct { 
-      unsigned int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
-                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  {          unsigned int  _zzq_args[6];                          \
-             unsigned int  _zzq_result;                           \
-             unsigned int* _zzq_ptr;                              \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
-                     "mr 4,%2\n\t" /*ptr*/                        \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"     /*result*/                     \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
-                     : "cc", "memory", "r3", "r4");               \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    unsigned int __addr;                                          \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory", "r3"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-#endif /* PLAT_ppc32_linux */
-
-/* ------------------------ ppc64-linux ------------------------ */
-
-#if defined(PLAT_ppc64_linux)
-
-typedef
-   struct { 
-      unsigned long long int nraddr; /* where's the code? */
-      unsigned long long int r2;  /* what tocptr do we need? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
-                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  {          unsigned long long int  _zzq_args[6];                \
-    register unsigned long long int  _zzq_result __asm__("r3");   \
-    register unsigned long long int* _zzq_ptr __asm__("r4");      \
-    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
-    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
-    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
-    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
-    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
-    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1"                                   \
-                     : "=r" (_zzq_result)                         \
-                     : "0" (_zzq_default), "r" (_zzq_ptr)         \
-                     : "cc", "memory");                           \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    register unsigned long long int __addr __asm__("r3");         \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2"                                   \
-                     : "=r" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR_GPR2 */                \
-                     "or 4,4,4"                                   \
-                     : "=r" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->r2 = __addr;                                       \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-
-#endif /* PLAT_ppc64_linux */
-
-/* ------------------------ ppc32-aix5 ------------------------- */
-
-#if defined(PLAT_ppc32_aix5)
-
-typedef
-   struct { 
-      unsigned int nraddr; /* where's the code? */
-      unsigned int r2;  /* what tocptr do we need? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
-                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  {          unsigned int  _zzq_args[7];                          \
-    register unsigned int  _zzq_result;                           \
-    register unsigned int* _zzq_ptr;                              \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    _zzq_args[6] = (unsigned int)(_zzq_default);                  \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 4,%1\n\t"                                \
-                     "lwz 3, 24(4)\n\t"                           \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_ptr)                             \
-                     : "r3", "r4", "cc", "memory");               \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    register unsigned int __addr;                                 \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR_GPR2 */                \
-                     "or 4,4,4\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->r2 = __addr;                                       \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-
-#endif /* PLAT_ppc32_aix5 */
-
-/* ------------------------ ppc64-aix5 ------------------------- */
-
-#if defined(PLAT_ppc64_aix5)
-
-typedef
-   struct { 
-      unsigned long long int nraddr; /* where's the code? */
-      unsigned long long int r2;  /* what tocptr do we need? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
-                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  {          unsigned long long int  _zzq_args[7];                \
-    register unsigned long long int  _zzq_result;                 \
-    register unsigned long long int* _zzq_ptr;                    \
-    _zzq_args[0] = (unsigned int long long)(_zzq_request);        \
-    _zzq_args[1] = (unsigned int long long)(_zzq_arg1);           \
-    _zzq_args[2] = (unsigned int long long)(_zzq_arg2);           \
-    _zzq_args[3] = (unsigned int long long)(_zzq_arg3);           \
-    _zzq_args[4] = (unsigned int long long)(_zzq_arg4);           \
-    _zzq_args[5] = (unsigned int long long)(_zzq_arg5);           \
-    _zzq_args[6] = (unsigned int long long)(_zzq_default);        \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 4,%1\n\t"                                \
-                     "ld 3, 48(4)\n\t"                            \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_ptr)                             \
-                     : "r3", "r4", "cc", "memory");               \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    register unsigned long long int __addr;                       \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR_GPR2 */                \
-                     "or 4,4,4\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->r2 = __addr;                                       \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-
-#endif /* PLAT_ppc64_aix5 */
-
-/* Insert assembly code for other platforms here... */
-
-#endif /* NVALGRIND */
-
-
-/* ------------------------------------------------------------------ */
-/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
-/* ugly.  It's the least-worst tradeoff I can think of.               */
-/* ------------------------------------------------------------------ */
-
-/* This section defines magic (a.k.a appalling-hack) macros for doing
-   guaranteed-no-redirection macros, so as to get from function
-   wrappers to the functions they are wrapping.  The whole point is to
-   construct standard call sequences, but to do the call itself with a
-   special no-redirect call pseudo-instruction that the JIT
-   understands and handles specially.  This section is long and
-   repetitious, and I can't see a way to make it shorter.
-
-   The naming scheme is as follows:
-
-      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
-
-   'W' stands for "word" and 'v' for "void".  Hence there are
-   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
-   and for each, the possibility of returning a word-typed result, or
-   no result.
-*/
-
-/* Use these to write the name of your wrapper.  NOTE: duplicates
-   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
-
-#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
-   _vgwZU_##soname##_##fnname
-
-#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
-   _vgwZZ_##soname##_##fnname
-
-/* Use this macro from within a wrapper function to collect the
-   context (address and possibly other info) of the original function.
-   Once you have that you can then use it in one of the CALL_FN_
-   macros.  The type of the argument _lval is OrigFn. */
-#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
-
-/* Derivatives of the main macros below, for calling functions
-   returning void. */
-
-#define CALL_FN_v_v(fnptr)                                        \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_v(_junk,fnptr); } while (0)
-
-#define CALL_FN_v_W(fnptr, arg1)                                  \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
-
-#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
-
-#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
-
-/* ------------------------- x86-linux ------------------------- */
-
-#if defined(PLAT_x86_linux)
-
-/* These regs are trashed by the hidden call.  No need to mention eax
-   as gcc can already see that, plus causes gcc to bomb. */
-#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
-
-/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
-   long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      __asm__ volatile(                                           \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $4, %%esp\n"                                       \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      __asm__ volatile(                                           \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $8, %%esp\n"                                       \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      __asm__ volatile(                                           \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $12, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      __asm__ volatile(                                           \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $16, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      __asm__ volatile(                                           \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $20, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      __asm__ volatile(                                           \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $24, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      __asm__ volatile(                                           \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $28, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      __asm__ volatile(                                           \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $32, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      __asm__ volatile(                                           \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $36, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      __asm__ volatile(                                           \
-         "pushl 40(%%eax)\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $40, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11)                          \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      __asm__ volatile(                                           \
-         "pushl 44(%%eax)\n\t"                                    \
-         "pushl 40(%%eax)\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $44, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11,arg12)                    \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      _argvec[12] = (unsigned long)(arg12);                       \
-      __asm__ volatile(                                           \
-         "pushl 48(%%eax)\n\t"                                    \
-         "pushl 44(%%eax)\n\t"                                    \
-         "pushl 40(%%eax)\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $48, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_x86_linux */
-
-/* ------------------------ amd64-linux ------------------------ */
-
-#if defined(PLAT_amd64_linux)
-
-/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
-                            "rdi", "r8", "r9", "r10", "r11"
-
-/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
-   long) == 8. */
-
-/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
-   macros.  In order not to trash the stack redzone, we need to drop
-   %rsp by 128 before the hidden call, and restore afterwards.  The
-   nastyness is that it is only by luck that the stack still appears
-   to be unwindable during the hidden call - since then the behaviour
-   of any routine using this macro does not match what the CFI data
-   says.  Sigh.
-
-   Why is this important?  Imagine that a wrapper has a stack
-   allocated local, and passes to the hidden call, a pointer to it.
-   Because gcc does not know about the hidden call, it may allocate
-   that local in the redzone.  Unfortunately the hidden call may then
-   trash it before it comes to use it.  So we must step clear of the
-   redzone, for the duration of the hidden call, to make it safe.
-
-   Probably the same problem afflicts the other redzone-style ABIs too
-   (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
-   self describing (none of this CFI nonsense) so at least messing
-   with the stack pointer doesn't give a danger of non-unwindable
-   stack. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         "addq $128,%%rsp\n\t"                                    \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $8, %%rsp\n"                                       \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $16, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 72(%%rax)\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $24, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 80(%%rax)\n\t"                                    \
-         "pushq 72(%%rax)\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $32, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 88(%%rax)\n\t"                                    \
-         "pushq 80(%%rax)\n\t"                                    \
-         "pushq 72(%%rax)\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $40, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      _argvec[12] = (unsigned long)(arg12);                       \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 96(%%rax)\n\t"                                    \
-         "pushq 88(%%rax)\n\t"                                    \
-         "pushq 80(%%rax)\n\t"                                    \
-         "pushq 72(%%rax)\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $48, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_amd64_linux */
-
-/* ------------------------ ppc32-linux ------------------------ */
-
-#if defined(PLAT_ppc32_linux)
-
-/* This is useful for finding out about the on-stack stuff:
-
-   extern int f9  ( int,int,int,int,int,int,int,int,int );
-   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
-   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
-   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
-
-   int g9 ( void ) {
-      return f9(11,22,33,44,55,66,77,88,99);
-   }
-   int g10 ( void ) {
-      return f10(11,22,33,44,55,66,77,88,99,110);
-   }
-   int g11 ( void ) {
-      return f11(11,22,33,44,55,66,77,88,99,110,121);
-   }
-   int g12 ( void ) {
-      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
-   }
-*/
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* These CALL_FN_ macros assume that on ppc32-linux, 
-   sizeof(unsigned long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-16\n\t"                                       \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "addi 1,1,16\n\t"                                        \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      _argvec[10] = (unsigned long)arg10;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-16\n\t"                                       \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,12(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "addi 1,1,16\n\t"                                        \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      _argvec[10] = (unsigned long)arg10;                         \
-      _argvec[11] = (unsigned long)arg11;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-32\n\t"                                       \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,16(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,12(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "addi 1,1,32\n\t"                                        \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      _argvec[10] = (unsigned long)arg10;                         \
-      _argvec[11] = (unsigned long)arg11;                         \
-      _argvec[12] = (unsigned long)arg12;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-32\n\t"                                       \
-         /* arg12 */                                              \
-         "lwz 3,48(11)\n\t"                                       \
-         "stw 3,20(1)\n\t"                                        \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,16(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,12(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "addi 1,1,32\n\t"                                        \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc32_linux */
-
-/* ------------------------ ppc64-linux ------------------------ */
-
-#if defined(PLAT_ppc64_linux)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
-   long) == 8. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+0];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1] = (unsigned long)_orig.r2;                       \
-      _argvec[2] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+1];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+2];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+3];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+4];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+5];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+6];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+7];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+8];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+9];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-128\n\t"  /* expand stack frame */            \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         "addi 1,1,128"     /* restore frame */                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+10];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-128\n\t"  /* expand stack frame */            \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         "addi 1,1,128"     /* restore frame */                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+11];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-144\n\t"  /* expand stack frame */            \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         "addi 1,1,144"     /* restore frame */                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+12];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      _argvec[2+12] = (unsigned long)arg12;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-144\n\t"  /* expand stack frame */            \
-         /* arg12 */                                              \
-         "ld  3,96(11)\n\t"                                       \
-         "std 3,136(1)\n\t"                                       \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         "addi 1,1,144"     /* restore frame */                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc64_linux */
-
-/* ------------------------ ppc32-aix5 ------------------------- */
-
-#if defined(PLAT_ppc32_aix5)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* Expand the stack frame, copying enough info that unwinding
-   still works.  Trashes r3. */
-
-#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
-         "addi 1,1,-" #_n_fr "\n\t"                               \
-         "lwz  3," #_n_fr "(1)\n\t"                               \
-         "stw  3,0(1)\n\t"
-
-#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
-         "addi 1,1," #_n_fr "\n\t"
-
-/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
-   long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+0];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1] = (unsigned long)_orig.r2;                       \
-      _argvec[2] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+1];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+2];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+3];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+4];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+5];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t" /* arg2->r4 */                       \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+6];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+7];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+8];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+9];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(64)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+10];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,60(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(64)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+11];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,64(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,60(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(72)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+12];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      _argvec[2+12] = (unsigned long)arg12;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
-         /* arg12 */                                              \
-         "lwz 3,48(11)\n\t"                                       \
-         "stw 3,68(1)\n\t"                                        \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,64(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,60(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(72)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc32_aix5 */
-
-/* ------------------------ ppc64-aix5 ------------------------- */
-
-#if defined(PLAT_ppc64_aix5)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* Expand the stack frame, copying enough info that unwinding
-   still works.  Trashes r3. */
-
-#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
-         "addi 1,1,-" #_n_fr "\n\t"                               \
-         "ld   3," #_n_fr "(1)\n\t"                               \
-         "std  3,0(1)\n\t"
-
-#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
-         "addi 1,1," #_n_fr "\n\t"
-
-/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
-   long) == 8. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+0];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1] = (unsigned long)_orig.r2;                       \
-      _argvec[2] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+1];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+2];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+3];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+4];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+5];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+6];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+7];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+8];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+9];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(128)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+10];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(128)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+11];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(144)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+12];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      _argvec[2+12] = (unsigned long)arg12;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
-         /* arg12 */                                              \
-         "ld  3,96(11)\n\t"                                       \
-         "std 3,136(1)\n\t"                                       \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(144)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc64_aix5 */
-
-
-/* ------------------------------------------------------------------ */
-/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
-/*                                                                    */
-/* ------------------------------------------------------------------ */
-
-/* Some request codes.  There are many more of these, but most are not
-   exposed to end-user view.  These are the public ones, all of the
-   form 0x1000 + small_number.
-
-   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
-   ones start at 0x2000.
-*/
-
-/* These macros are used by tools -- they must be public, but don't
-   embed them into other programs. */
-#define VG_USERREQ_TOOL_BASE(a,b) \
-   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
-#define VG_IS_TOOL_USERREQ(a, b, v) \
-   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
-
-/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! 
-   This enum comprises an ABI exported by Valgrind to programs
-   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
-   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
-typedef
-   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
-          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
-
-          /* These allow any function to be called from the simulated
-             CPU but run on the real CPU.  Nb: the first arg passed to
-             the function is always the ThreadId of the running
-             thread!  So CLIENT_CALL0 actually requires a 1 arg
-             function, etc. */
-          VG_USERREQ__CLIENT_CALL0 = 0x1101,
-          VG_USERREQ__CLIENT_CALL1 = 0x1102,
-          VG_USERREQ__CLIENT_CALL2 = 0x1103,
-          VG_USERREQ__CLIENT_CALL3 = 0x1104,
-
-          /* Can be useful in regression testing suites -- eg. can
-             send Valgrind's output to /dev/null and still count
-             errors. */
-          VG_USERREQ__COUNT_ERRORS = 0x1201,
-
-          /* These are useful and can be interpreted by any tool that
-             tracks malloc() et al, by using vg_replace_malloc.c. */
-          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
-          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
-          /* Memory pool support. */
-          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
-          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
-          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
-          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
-          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
-          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
-          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
-          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
-
-          /* Allow printfs to valgrind log. */
-          VG_USERREQ__PRINTF           = 0x1401,
-          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
-
-          /* Stack support. */
-          VG_USERREQ__STACK_REGISTER   = 0x1501,
-          VG_USERREQ__STACK_DEREGISTER = 0x1502,
-          VG_USERREQ__STACK_CHANGE     = 0x1503
-   } Vg_ClientRequest;
-
-#if !defined(__GNUC__)
-#  define __extension__ /* */
-#endif
-
-/* Returns the number of Valgrinds this code is running under.  That
-   is, 0 if running natively, 1 if running under Valgrind, 2 if
-   running under Valgrind which is running under another Valgrind,
-   etc. */
-#define RUNNING_ON_VALGRIND  __extension__                        \
-   ({unsigned int _qzz_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */,          \
-                               VG_USERREQ__RUNNING_ON_VALGRIND,   \
-                               0, 0, 0, 0, 0);                    \
-    _qzz_res;                                                     \
-   })
-
-
-/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
-   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
-   since it provides a way to make sure valgrind will retranslate the
-   invalidated area.  Returns no value. */
-#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)         \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__DISCARD_TRANSLATIONS,  \
-                               _qzz_addr, _qzz_len, 0, 0, 0);     \
-   }
-
-
-/* These requests are for getting Valgrind itself to print something.
-   Possibly with a backtrace.  This is a really ugly hack. */
-
-#if defined(NVALGRIND)
-
-#  define VALGRIND_PRINTF(...)
-#  define VALGRIND_PRINTF_BACKTRACE(...)
-
-#else /* NVALGRIND */
-
-/* Modern GCC will optimize the static routine out if unused,
-   and unused attribute will shut down warnings about it.  */
-static int VALGRIND_PRINTF(const char *format, ...)
-   __attribute__((format(__printf__, 1, 2), __unused__));
-static int
-VALGRIND_PRINTF(const char *format, ...)
-{
-   unsigned long _qzz_res;
-   va_list vargs;
-   va_start(vargs, format);
-   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
-                              (unsigned long)format, (unsigned long)vargs, 
-                              0, 0, 0);
-   va_end(vargs);
-   return (int)_qzz_res;
-}
-
-static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
-   __attribute__((format(__printf__, 1, 2), __unused__));
-static int
-VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
-{
-   unsigned long _qzz_res;
-   va_list vargs;
-   va_start(vargs, format);
-   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
-                              (unsigned long)format, (unsigned long)vargs, 
-                              0, 0, 0);
-   va_end(vargs);
-   return (int)_qzz_res;
-}
-
-#endif /* NVALGRIND */
-
-
-/* These requests allow control to move from the simulated CPU to the
-   real CPU, calling an arbitary function.
-   
-   Note that the current ThreadId is inserted as the first argument.
-   So this call:
-
-     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
-
-   requires f to have this signature:
-
-     Word f(Word tid, Word arg1, Word arg2)
-
-   where "Word" is a word-sized type.
-
-   Note that these client requests are not entirely reliable.  For example,
-   if you call a function with them that subsequently calls printf(),
-   there's a high chance Valgrind will crash.  Generally, your prospects of
-   these working are made higher if the called function does not refer to
-   any global variables, and does not refer to any libc or other functions
-   (printf et al).  Any kind of entanglement with libc or dynamic linking is
-   likely to have a bad outcome, for tricky reasons which we've grappled
-   with a lot in the past.
-*/
-#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL0,          \
-                               _qyy_fn,                           \
-                               0, 0, 0, 0);                       \
-    _qyy_res;                                                     \
-   })
-
-#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)               \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL1,          \
-                               _qyy_fn,                           \
-                               _qyy_arg1, 0, 0, 0);               \
-    _qyy_res;                                                     \
-   })
-
-#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)    \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL2,          \
-                               _qyy_fn,                           \
-                               _qyy_arg1, _qyy_arg2, 0, 0);       \
-    _qyy_res;                                                     \
-   })
-
-#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL3,          \
-                               _qyy_fn,                           \
-                               _qyy_arg1, _qyy_arg2,              \
-                               _qyy_arg3, 0);                     \
-    _qyy_res;                                                     \
-   })
-
-
-/* Counts the number of errors that have been recorded by a tool.  Nb:
-   the tool must record the errors with VG_(maybe_record_error)() or
-   VG_(unique_error)() for them to be counted. */
-#define VALGRIND_COUNT_ERRORS                                     \
-   __extension__                                                  \
-   ({unsigned int _qyy_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__COUNT_ERRORS,          \
-                               0, 0, 0, 0, 0);                    \
-    _qyy_res;                                                     \
-   })
-
-/* Mark a block of memory as having been allocated by a malloc()-like
-   function.  `addr' is the start of the usable block (ie. after any
-   redzone) `rzB' is redzone size if the allocator can apply redzones;
-   use '0' if not.  Adding redzones makes it more likely Valgrind will spot
-   block overruns.  `is_zeroed' indicates if the memory is zeroed, as it is
-   for calloc().  Put it immediately after the point where a block is
-   allocated. 
-   
-   If you're using Memcheck: If you're allocating memory via superblocks,
-   and then handing out small chunks of each superblock, if you don't have
-   redzones on your small blocks, it's worth marking the superblock with
-   VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are
-   detected.  But if you can put redzones on, it's probably better to not do
-   this, so that messages for small overruns are described in terms of the
-   small block rather than the superblock (but if you have a big overrun
-   that skips over a redzone, you could miss an error this way).  See
-   memcheck/tests/custom_alloc.c for an example.
-
-   WARNING: if your allocator uses malloc() or 'new' to allocate
-   superblocks, rather than mmap() or brk(), this will not work properly --
-   you'll likely get assertion failures during leak detection.  This is
-   because Valgrind doesn't like seeing overlapping heap blocks.  Sorry.
-
-   Nb: block must be freed via a free()-like function specified
-   with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
-#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)    \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MALLOCLIKE_BLOCK,      \
-                               addr, sizeB, rzB, is_zeroed, 0);   \
-   }
-
-/* Mark a block of memory as having been freed by a free()-like function.
-   `rzB' is redzone size;  it must match that given to
-   VALGRIND_MALLOCLIKE_BLOCK.  Memory not freed will be detected by the leak
-   checker.  Put it immediately after the point where the block is freed. */
-#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                        \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__FREELIKE_BLOCK,        \
-                               addr, rzB, 0, 0, 0);               \
-   }
-
-/* Create a memory pool. */
-#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__CREATE_MEMPOOL,        \
-                               pool, rzB, is_zeroed, 0, 0);       \
-   }
-
-/* Destroy a memory pool. */
-#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__DESTROY_MEMPOOL,       \
-                               pool, 0, 0, 0, 0);                 \
-   }
-
-/* Associate a piece of memory with a memory pool. */
-#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_ALLOC,         \
-                               pool, addr, size, 0, 0);           \
-   }
-
-/* Disassociate a piece of memory from a memory pool. */
-#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_FREE,          \
-                               pool, addr, 0, 0, 0);              \
-   }
-
-/* Disassociate any pieces outside a particular range. */
-#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_TRIM,          \
-                               pool, addr, size, 0, 0);           \
-   }
-
-/* Resize and/or move a piece associated with a memory pool. */
-#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MOVE_MEMPOOL,          \
-                               poolA, poolB, 0, 0, 0);            \
-   }
-
-/* Resize and/or move a piece associated with a memory pool. */
-#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_CHANGE,        \
-                               pool, addrA, addrB, size, 0);      \
-   }
-
-/* Return 1 if a mempool exists, else 0. */
-#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
-   ({unsigned int _qzz_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_EXISTS,        \
-                               pool, 0, 0, 0, 0);                 \
-    _qzz_res;                                                     \
-   })
-
-/* Mark a piece of memory as being a stack. Returns a stack id. */
-#define VALGRIND_STACK_REGISTER(start, end)                       \
-   ({unsigned int _qzz_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__STACK_REGISTER,        \
-                               start, end, 0, 0, 0);              \
-    _qzz_res;                                                     \
-   })
-
-/* Unmark the piece of memory associated with a stack id as being a
-   stack. */
-#define VALGRIND_STACK_DEREGISTER(id)                             \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__STACK_DEREGISTER,      \
-                               id, 0, 0, 0, 0);                   \
-   }
-
-/* Change the start and end address of the stack id. */
-#define VALGRIND_STACK_CHANGE(id, start, end)                     \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__STACK_CHANGE,          \
-                               id, start, end, 0, 0);             \
-   }
-
-
-#undef PLAT_x86_linux
-#undef PLAT_amd64_linux
-#undef PLAT_ppc32_linux
-#undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
-
-#endif   /* __VALGRIND_H */
diff --git a/third_party/tcmalloc/chromium/src/thread_cache.cc b/third_party/tcmalloc/chromium/src/thread_cache.cc
deleted file mode 100644
index 4ed9c82f..0000000
--- a/third_party/tcmalloc/chromium/src/thread_cache.cc
+++ /dev/null
@@ -1,542 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Ken Ashcraft <opensource@google.com>
-
-#include <config.h>
-#include "thread_cache.h"
-#include <errno.h>
-#include <string.h>                 // for memcpy
-#include <algorithm>                // for max, min
-#include "base/commandlineflags.h"  // for SpinLockHolder
-#include "base/spinlock.h"          // for SpinLockHolder
-#include "central_freelist.h"       // for CentralFreeListPadded
-#include "getenv_safe.h"            // for TCMallocGetenvSafe
-#include "maybe_threads.h"
-#include "system-alloc.h"
-
-using std::min;
-using std::max;
-
-// Note: this is initialized manually in InitModule to ensure that
-// it's configured at right time
-//
-// DEFINE_int64(tcmalloc_max_total_thread_cache_bytes,
-//              EnvToInt64("TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES",
-//                         kDefaultOverallThreadCacheSize),
-//              "Bound on the total amount of bytes allocated to "
-//              "thread caches. This bound is not strict, so it is possible "
-//              "for the cache to go over this bound in certain circumstances. "
-//              "Maximum value of this flag is capped to 1 GB.");
-
-
-namespace tcmalloc {
-
-static bool phinited = false;
-
-volatile size_t ThreadCache::per_thread_cache_size_ = kMaxThreadCacheSize;
-size_t ThreadCache::overall_thread_cache_size_ = kDefaultOverallThreadCacheSize;
-ssize_t ThreadCache::unclaimed_cache_space_ = kDefaultOverallThreadCacheSize;
-PageHeapAllocator<ThreadCache> threadcache_allocator;
-ThreadCache* ThreadCache::thread_heaps_ = NULL;
-int ThreadCache::thread_heap_count_ = 0;
-ThreadCache* ThreadCache::next_memory_steal_ = NULL;
-#ifdef HAVE_TLS
-__thread ThreadCache::ThreadLocalData ThreadCache::threadlocal_data_
-    ATTR_INITIAL_EXEC CACHELINE_ALIGNED;
-#endif
-bool ThreadCache::tsd_inited_ = false;
-pthread_key_t ThreadCache::heap_key_;
-
-void ThreadCache::Init(pthread_t tid) {
-  size_ = 0;
-  total_bytes_allocated_ = 0;
-
-  max_size_ = 0;
-  IncreaseCacheLimitLocked();
-  if (max_size_ == 0) {
-    // There isn't enough memory to go around.  Just give the minimum to
-    // this thread.
-    SetMaxSize(kMinThreadCacheSize);
-
-    // Take unclaimed_cache_space_ negative.
-    unclaimed_cache_space_ -= kMinThreadCacheSize;
-    ASSERT(unclaimed_cache_space_ < 0);
-  }
-
-  next_ = NULL;
-  prev_ = NULL;
-  tid_  = tid;
-  in_setspecific_ = false;
-  for (uint32 cl = 0; cl < Static::num_size_classes(); ++cl) {
-    list_[cl].Init(Static::sizemap()->class_to_size(cl));
-  }
-
-  uint32_t sampler_seed;
-  memcpy(&sampler_seed, &tid, sizeof(sampler_seed));
-  sampler_.Init(sampler_seed);
-}
-
-void ThreadCache::Cleanup() {
-  // Put unused memory back into central cache
-  for (uint32 cl = 0; cl < Static::num_size_classes(); ++cl) {
-    if (list_[cl].length() > 0) {
-      ReleaseToCentralCache(&list_[cl], cl, list_[cl].length());
-    }
-  }
-}
-
-// Remove some objects of class "cl" from central cache and add to thread heap.
-// On success, return the first object for immediate use; otherwise return NULL.
-void* ThreadCache::FetchFromCentralCache(uint32 cl, int32_t byte_size,
-                                         void *(*oom_handler)(size_t size)) {
-  FreeList* list = &list_[cl];
-  ASSERT(list->empty());
-  const int batch_size = Static::sizemap()->num_objects_to_move(cl);
-
-  const int num_to_move = min<int>(list->max_length(), batch_size);
-  void *start, *end;
-  int fetch_count = Static::central_cache()[cl].RemoveRange(
-      &start, &end, num_to_move);
-
-  if (fetch_count == 0) {
-    ASSERT(start == NULL);
-    return oom_handler(byte_size);
-  }
-  ASSERT(start != NULL);
-
-  if (--fetch_count >= 0) {
-    size_ += byte_size * fetch_count;
-    // Pop the top of the list and add the rest to the freelist.
-    void* second = start;
-    start = FL_Pop(&second);
-    list->PushRange(fetch_count, second, end);
-  }
-
-  // Increase max length slowly up to batch_size.  After that,
-  // increase by batch_size in one shot so that the length is a
-  // multiple of batch_size.
-  if (list->max_length() < batch_size) {
-    list->set_max_length(list->max_length() + 1);
-  } else {
-    // Don't let the list get too long.  In 32 bit builds, the length
-    // is represented by a 16 bit int, so we need to watch out for
-    // integer overflow.
-    int new_length = min<int>(list->max_length() + batch_size,
-                              kMaxDynamicFreeListLength);
-    // The list's max_length must always be a multiple of batch_size,
-    // and kMaxDynamicFreeListLength is not necessarily a multiple
-    // of batch_size.
-    new_length -= new_length % batch_size;
-    ASSERT(new_length % batch_size == 0);
-    list->set_max_length(new_length);
-  }
-  return start;
-}
-
-void ThreadCache::ListTooLong(FreeList* list, uint32 cl) {
-  size_ += list->object_size();
-
-  const int batch_size = Static::sizemap()->num_objects_to_move(cl);
-  ReleaseToCentralCache(list, cl, batch_size);
-
-  // If the list is too long, we need to transfer some number of
-  // objects to the central cache.  Ideally, we would transfer
-  // num_objects_to_move, so the code below tries to make max_length
-  // converge on num_objects_to_move.
-
-  if (list->max_length() < batch_size) {
-    // Slow start the max_length so we don't overreserve.
-    list->set_max_length(list->max_length() + 1);
-  } else if (list->max_length() > batch_size) {
-    // If we consistently go over max_length, shrink max_length.  If we don't
-    // shrink it, some amount of memory will always stay in this freelist.
-    list->set_length_overages(list->length_overages() + 1);
-    if (list->length_overages() > kMaxOverages) {
-      ASSERT(list->max_length() > batch_size);
-      list->set_max_length(list->max_length() - batch_size);
-      list->set_length_overages(0);
-    }
-  }
-
-  if (PREDICT_FALSE(size_ > max_size_)) {
-    Scavenge();
-  }
-}
-
-// Remove some objects of class "cl" from thread heap and add to central cache
-void ThreadCache::ReleaseToCentralCache(FreeList* src, uint32 cl, int N) {
-  ASSERT(src == &list_[cl]);
-  if (N > src->length()) N = src->length();
-  size_t delta_bytes = N * Static::sizemap()->ByteSizeForClass(cl);
-
-  // We return prepackaged chains of the correct size to the central cache.
-  // TODO: Use the same format internally in the thread caches?
-  int batch_size = Static::sizemap()->num_objects_to_move(cl);
-  while (N > batch_size) {
-    void *tail, *head;
-    src->PopRange(batch_size, &head, &tail);
-    Static::central_cache()[cl].InsertRange(head, tail, batch_size);
-    N -= batch_size;
-  }
-  void *tail, *head;
-  src->PopRange(N, &head, &tail);
-  Static::central_cache()[cl].InsertRange(head, tail, N);
-  size_ -= delta_bytes;
-}
-
-// Release idle memory to the central cache
-void ThreadCache::Scavenge() {
-  // If the low-water mark for the free list is L, it means we would
-  // not have had to allocate anything from the central cache even if
-  // we had reduced the free list size by L.  We aim to get closer to
-  // that situation by dropping L/2 nodes from the free list.  This
-  // may not release much memory, but if so we will call scavenge again
-  // pretty soon and the low-water marks will be high on that call.
-  for (int cl = 0; cl < Static::num_size_classes(); cl++) {
-    FreeList* list = &list_[cl];
-    const int lowmark = list->lowwatermark();
-    if (lowmark > 0) {
-      const int drop = (lowmark > 1) ? lowmark/2 : 1;
-      ReleaseToCentralCache(list, cl, drop);
-
-      // Shrink the max length if it isn't used.  Only shrink down to
-      // batch_size -- if the thread was active enough to get the max_length
-      // above batch_size, it will likely be that active again.  If
-      // max_length shinks below batch_size, the thread will have to
-      // go through the slow-start behavior again.  The slow-start is useful
-      // mainly for threads that stay relatively idle for their entire
-      // lifetime.
-      const int batch_size = Static::sizemap()->num_objects_to_move(cl);
-      if (list->max_length() > batch_size) {
-        list->set_max_length(
-            max<int>(list->max_length() - batch_size, batch_size));
-      }
-    }
-    list->clear_lowwatermark();
-  }
-
-  IncreaseCacheLimit();
-}
-
-void ThreadCache::IncreaseCacheLimit() {
-  SpinLockHolder h(Static::pageheap_lock());
-  IncreaseCacheLimitLocked();
-}
-
-void ThreadCache::IncreaseCacheLimitLocked() {
-  if (unclaimed_cache_space_ > 0) {
-    // Possibly make unclaimed_cache_space_ negative.
-    unclaimed_cache_space_ -= kStealAmount;
-    SetMaxSize(max_size_ + kStealAmount);
-    return;
-  }
-  // Don't hold pageheap_lock too long.  Try to steal from 10 other
-  // threads before giving up.  The i < 10 condition also prevents an
-  // infinite loop in case none of the existing thread heaps are
-  // suitable places to steal from.
-  for (int i = 0; i < 10;
-       ++i, next_memory_steal_ = next_memory_steal_->next_) {
-    // Reached the end of the linked list.  Start at the beginning.
-    if (next_memory_steal_ == NULL) {
-      ASSERT(thread_heaps_ != NULL);
-      next_memory_steal_ = thread_heaps_;
-    }
-    if (next_memory_steal_ == this ||
-        next_memory_steal_->max_size_ <= kMinThreadCacheSize) {
-      continue;
-    }
-    next_memory_steal_->SetMaxSize(next_memory_steal_->max_size_ - kStealAmount);
-    SetMaxSize(max_size_ + kStealAmount);
-
-    next_memory_steal_ = next_memory_steal_->next_;
-    return;
-  }
-}
-
-int ThreadCache::GetSamplePeriod() {
-  return sampler_.GetSamplePeriod();
-}
-
-// static
-unsigned int ThreadCache::GetBytesAllocatedOnCurrentThread() {
-  return ThreadCache::GetThreadHeap()->GetTotalBytesAllocated();
-}
-
-void ThreadCache::InitModule() {
-  {
-    SpinLockHolder h(Static::pageheap_lock());
-    if (phinited) {
-      return;
-    }
-    const char *tcb = TCMallocGetenvSafe("TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES");
-    if (tcb) {
-      set_overall_thread_cache_size(strtoll(tcb, NULL, 10));
-    }
-#if defined(TCMALLOC_USE_DOUBLYLINKED_FREELIST)
-    FL_InitPtrMask(reinterpret_cast<uintptr_t>(TCMalloc_SystemAlloc));
-#endif
-    Static::InitStaticVars();
-    threadcache_allocator.Init();
-    phinited = 1;
-  }
-
-  // We do "late" part of initialization without holding lock since
-  // there is chance it'll recurse into malloc
-  Static::InitLateMaybeRecursive();
-}
-
-void ThreadCache::InitTSD() {
-  ASSERT(!tsd_inited_);
-  perftools_pthread_key_create(&heap_key_, DestroyThreadCache);
-  tsd_inited_ = true;
-
-#ifdef PTHREADS_CRASHES_IF_RUN_TOO_EARLY
-  // We may have used a fake pthread_t for the main thread.  Fix it.
-  pthread_t zero;
-  memset(&zero, 0, sizeof(zero));
-  SpinLockHolder h(Static::pageheap_lock());
-  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
-    if (h->tid_ == zero) {
-      h->tid_ = pthread_self();
-    }
-  }
-#endif
-}
-
-ThreadCache* ThreadCache::CreateCacheIfNecessary() {
-  if (!tsd_inited_) {
-#ifndef NDEBUG
-    // tests that freeing nullptr very early is working
-    free(NULL);
-#endif
-
-    InitModule();
-  }
-
-  // Initialize per-thread data if necessary
-  ThreadCache* heap = NULL;
-
-  bool seach_condition = true;
-#ifdef HAVE_TLS
-  static __thread ThreadCache** current_heap_ptr;
-  if (tsd_inited_) {
-    // In most common case we're avoiding expensive linear search
-    // through all heaps (see below). Working TLS enables faster
-    // protection from malloc recursion in pthread_setspecific
-    seach_condition = false;
-
-    if (current_heap_ptr != NULL) {
-      // we're being recursively called by pthread_setspecific below.
-      return *current_heap_ptr;
-    }
-    current_heap_ptr = &heap;
-  }
-#endif
-
-  {
-    SpinLockHolder h(Static::pageheap_lock());
-    // On some old glibc's, and on freebsd's libc (as of freebsd 8.1),
-    // calling pthread routines (even pthread_self) too early could
-    // cause a segfault.  Since we can call pthreads quite early, we
-    // have to protect against that in such situations by making a
-    // 'fake' pthread.  This is not ideal since it doesn't work well
-    // when linking tcmalloc statically with apps that create threads
-    // before main, so we only do it if we have to.
-#ifdef PTHREADS_CRASHES_IF_RUN_TOO_EARLY
-    pthread_t me;
-    if (!tsd_inited_) {
-      memset(&me, 0, sizeof(me));
-    } else {
-      me = pthread_self();
-    }
-#else
-    const pthread_t me = pthread_self();
-#endif
-
-    // This may be a recursive malloc call from pthread_setspecific()
-    // In that case, the heap for this thread has already been created
-    // and added to the linked list.  So we search for that first.
-    if (seach_condition) {
-      for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
-        if (h->tid_ == me) {
-          heap = h;
-          break;
-        }
-      }
-    }
-
-    if (heap == NULL) heap = NewHeap(me);
-  }
-
-  // We call pthread_setspecific() outside the lock because it may
-  // call malloc() recursively.  We check for the recursive call using
-  // the "in_setspecific_" flag so that we can avoid calling
-  // pthread_setspecific() if we are already inside pthread_setspecific().
-  if (!heap->in_setspecific_ && tsd_inited_) {
-    heap->in_setspecific_ = true;
-    perftools_pthread_setspecific(heap_key_, heap);
-#ifdef HAVE_TLS
-    // Also keep a copy in __thread for faster retrieval
-    threadlocal_data_.heap = heap;
-    threadlocal_data_.fast_path_heap = heap;
-#endif
-    heap->in_setspecific_ = false;
-  }
-#ifdef HAVE_TLS
-  current_heap_ptr = NULL;
-#endif
-  return heap;
-}
-
-ThreadCache* ThreadCache::NewHeap(pthread_t tid) {
-  // Create the heap and add it to the linked list
-  ThreadCache *heap = threadcache_allocator.New();
-  heap->Init(tid);
-  heap->next_ = thread_heaps_;
-  heap->prev_ = NULL;
-  if (thread_heaps_ != NULL) {
-    thread_heaps_->prev_ = heap;
-  } else {
-    // This is the only thread heap at the momment.
-    ASSERT(next_memory_steal_ == NULL);
-    next_memory_steal_ = heap;
-  }
-  thread_heaps_ = heap;
-  thread_heap_count_++;
-  return heap;
-}
-
-void ThreadCache::BecomeIdle() {
-  if (!tsd_inited_) return;              // No caches yet
-  ThreadCache* heap = GetThreadHeap();
-  if (heap == NULL) return;             // No thread cache to remove
-  if (heap->in_setspecific_) return;    // Do not disturb the active caller
-
-  heap->in_setspecific_ = true;
-  perftools_pthread_setspecific(heap_key_, NULL);
-#ifdef HAVE_TLS
-  // Also update the copy in __thread
-  threadlocal_data_.heap = NULL;
-  threadlocal_data_.fast_path_heap = NULL;
-#endif
-  heap->in_setspecific_ = false;
-  if (GetThreadHeap() == heap) {
-    // Somehow heap got reinstated by a recursive call to malloc
-    // from pthread_setspecific.  We give up in this case.
-    return;
-  }
-
-  // We can now get rid of the heap
-  DeleteCache(heap);
-}
-
-void ThreadCache::BecomeTemporarilyIdle() {
-  ThreadCache* heap = GetCacheIfPresent();
-  if (heap)
-    heap->Cleanup();
-}
-
-void ThreadCache::DestroyThreadCache(void* ptr) {
-  // Note that "ptr" cannot be NULL since pthread promises not
-  // to invoke the destructor on NULL values, but for safety,
-  // we check anyway.
-  if (ptr == NULL) return;
-#ifdef HAVE_TLS
-  // Prevent fast path of GetThreadHeap() from returning heap.
-  threadlocal_data_.heap = NULL;
-  threadlocal_data_.fast_path_heap = NULL;
-#endif
-  DeleteCache(reinterpret_cast<ThreadCache*>(ptr));
-}
-
-void ThreadCache::DeleteCache(ThreadCache* heap) {
-  // Remove all memory from heap
-  heap->Cleanup();
-
-  // Remove from linked list
-  SpinLockHolder h(Static::pageheap_lock());
-  if (heap->next_ != NULL) heap->next_->prev_ = heap->prev_;
-  if (heap->prev_ != NULL) heap->prev_->next_ = heap->next_;
-  if (thread_heaps_ == heap) thread_heaps_ = heap->next_;
-  thread_heap_count_--;
-
-  if (next_memory_steal_ == heap) next_memory_steal_ = heap->next_;
-  if (next_memory_steal_ == NULL) next_memory_steal_ = thread_heaps_;
-  unclaimed_cache_space_ += heap->max_size_;
-
-  threadcache_allocator.Delete(heap);
-}
-
-void ThreadCache::RecomputePerThreadCacheSize() {
-  // Divide available space across threads
-  int n = thread_heap_count_ > 0 ? thread_heap_count_ : 1;
-  size_t space = overall_thread_cache_size_ / n;
-
-  // Limit to allowed range
-  if (space < kMinThreadCacheSize) space = kMinThreadCacheSize;
-  if (space > kMaxThreadCacheSize) space = kMaxThreadCacheSize;
-
-  double ratio = space / max<double>(1, per_thread_cache_size_);
-  size_t claimed = 0;
-  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
-    // Increasing the total cache size should not circumvent the
-    // slow-start growth of max_size_.
-    if (ratio < 1.0) {
-      h->SetMaxSize(h->max_size_ * ratio);
-    }
-    claimed += h->max_size_;
-  }
-  unclaimed_cache_space_ = overall_thread_cache_size_ - claimed;
-  per_thread_cache_size_ = space;
-}
-
-void ThreadCache::GetThreadStats(uint64_t* total_bytes, uint64_t* class_count) {
-  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
-    *total_bytes += h->Size();
-    if (class_count) {
-      for (int cl = 0; cl < Static::num_size_classes(); ++cl) {
-        class_count[cl] += h->freelist_length(cl);
-      }
-    }
-  }
-}
-
-void ThreadCache::set_overall_thread_cache_size(size_t new_size) {
-  // Clip the value to a reasonable range
-  if (new_size < kMinThreadCacheSize) new_size = kMinThreadCacheSize;
-  if (new_size > (1<<30)) new_size = (1<<30);     // Limit to 1GB
-  overall_thread_cache_size_ = new_size;
-
-  RecomputePerThreadCacheSize();
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/thread_cache.h b/third_party/tcmalloc/chromium/src/thread_cache.h
deleted file mode 100644
index bc0ba93..0000000
--- a/third_party/tcmalloc/chromium/src/thread_cache.h
+++ /dev/null
@@ -1,525 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#ifndef TCMALLOC_THREAD_CACHE_H_
-#define TCMALLOC_THREAD_CACHE_H_
-
-#include <config.h>
-#ifdef HAVE_PTHREAD
-#include <pthread.h>                    // for pthread_t, pthread_key_t
-#endif
-#include <stddef.h>                     // for size_t, NULL
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uint32_t, uint64_t
-#endif
-#include <sys/types.h>  // for ssize_t
-#include "common.h"
-#include "free_list.h"         // for FL_Pop, FL_PopRange, etc
-#include "internal_logging.h"  // for ASSERT, etc
-#include "linked_list.h"
-#include "maybe_threads.h"
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "sampler.h"              // for Sampler
-#include "static_vars.h"          // for Static
-
-namespace tcmalloc {
-
-//-------------------------------------------------------------------
-// Data kept per thread
-//-------------------------------------------------------------------
-
-class ThreadCache {
- public:
-#ifdef HAVE_TLS
-  enum { have_tls = true };
-#else
-  enum { have_tls = false };
-#endif
-
-  void Init(pthread_t tid);
-  void Cleanup();
-
-  // Accessors (mostly just for printing stats)
-  int freelist_length(uint32 cl) const { return list_[cl].length(); }
-
-  // Total byte size in cache
-  size_t Size() const { return size_; }
-
-  // Allocate an object of the given size and class. The size given
-  // must be the same as the size of the class in the size map.
-  void* Allocate(size_t size, uint32 cl, void *(*oom_handler)(size_t size));
-  void Deallocate(void* ptr, uint32 size_class);
-
-  void Scavenge();
-
-  int GetSamplePeriod();
-
-  // Record allocation of "k" bytes.  Return true iff allocation
-  // should be sampled
-  bool SampleAllocation(size_t k);
-
-  bool TryRecordAllocationFast(size_t k);
-
-  // Record additional bytes allocated.
-  void AddToByteAllocatedTotal(size_t k) { total_bytes_allocated_ += k; }
-
-  // Return the total number of bytes allocated from this heap.  The value will
-  // wrap when there is an overflow, and so only the differences between two
-  // values should be relied on (and even then, modulo 2^32).
-  uint32 GetTotalBytesAllocated() const;
-
-  // On the current thread, return GetTotalBytesAllocated().
-  static uint32 GetBytesAllocatedOnCurrentThread();
-
-  static void         InitModule();
-  static void         InitTSD();
-  static ThreadCache* GetThreadHeap();
-  static ThreadCache* GetCache();
-  static ThreadCache* GetCacheIfPresent();
-  static ThreadCache* GetFastPathCache();
-  static ThreadCache* GetCacheWhichMustBePresent();
-  static ThreadCache* CreateCacheIfNecessary();
-  static void         BecomeIdle();
-  static void         BecomeTemporarilyIdle();
-  static void         SetUseEmergencyMalloc();
-  static void         ResetUseEmergencyMalloc();
-  static bool         IsUseEmergencyMalloc();
-
-  // Return the number of thread heaps in use.
-  static inline int HeapsInUse();
-
-  // Adds to *total_bytes the total number of bytes used by all thread heaps.
-  // Also, if class_count is not NULL, it must be an array of size kNumClasses,
-  // and this function will increment each element of class_count by the number
-  // of items in all thread-local freelists of the corresponding size class.
-  // REQUIRES: Static::pageheap_lock is held.
-  static void GetThreadStats(uint64_t* total_bytes, uint64_t* class_count);
-
-  // Sets the total thread cache size to new_size, recomputing the
-  // individual thread cache sizes as necessary.
-  // REQUIRES: Static::pageheap lock is held.
-  static void set_overall_thread_cache_size(size_t new_size);
-  static size_t overall_thread_cache_size() {
-    return overall_thread_cache_size_;
-  }
-
- private:
-  class FreeList {
-   private:
-    void*    list_;       // Linked list of nodes
-
-#ifdef _LP64
-    // On 64-bit hardware, manipulating 16-bit values may be slightly slow.
-    uint32_t length_;      // Current length.
-    uint32_t lowater_;     // Low water mark for list length.
-    uint32_t max_length_;  // Dynamic max list length based on usage.
-    // Tracks the number of times a deallocation has caused
-    // length_ > max_length_.  After the kMaxOverages'th time, max_length_
-    // shrinks and length_overages_ is reset to zero.
-    uint32_t length_overages_;
-#else
-    // If we aren't using 64-bit pointers then pack these into less space.
-    uint16_t length_;
-    uint16_t lowater_;
-    uint16_t max_length_;
-    uint16_t length_overages_;
-#endif
-
-    int32_t size_;
-
-   public:
-    void Init(size_t size) {
-      list_ = NULL;
-      length_ = 0;
-      lowater_ = 0;
-      max_length_ = 1;
-      length_overages_ = 0;
-      size_ = size;
-    }
-
-    // Return current length of list
-    size_t length() const {
-      return length_;
-    }
-
-    int32_t object_size() const {
-      return size_;
-    }
-
-    // Return the maximum length of the list.
-    size_t max_length() const {
-      return max_length_;
-    }
-
-    // Set the maximum length of the list.  If 'new_max' > length(), the
-    // client is responsible for removing objects from the list.
-    void set_max_length(size_t new_max) {
-      max_length_ = new_max;
-    }
-
-    // Return the number of times that length() has gone over max_length().
-    size_t length_overages() const {
-      return length_overages_;
-    }
-
-    void set_length_overages(size_t new_count) {
-      length_overages_ = new_count;
-    }
-
-    // Is list empty?
-    bool empty() const {
-      return list_ == NULL;
-    }
-
-    // Low-water mark management
-    int lowwatermark() const { return lowater_; }
-    void clear_lowwatermark() { lowater_ = length_; }
-
-    uint32_t Push(void* ptr) {
-      uint32_t length = length_ + 1;
-      FL_Push(&list_, ptr);
-      length_ = length;
-      return length;
-    }
-
-    void* Pop() {
-      ASSERT(list_ != NULL);
-      length_--;
-      if (length_ < lowater_) lowater_ = length_;
-      return FL_Pop(&list_);
-    }
-
-    bool TryPop(void **rv) {
-      if (list_ == NULL)
-        return false;
-      *rv = Pop();
-      return true;
-    }
-
-    void* Next() {
-      if (list_ == NULL)
-        return NULL;
-      return FL_Next(list_);
-    }
-
-    void PushRange(int N, void *start, void *end) {
-      FL_PushRange(&list_, start, end);
-      length_ += N;
-    }
-
-    void PopRange(int N, void **start, void **end) {
-      FL_PopRange(&list_, N, start, end);
-      ASSERT(length_ >= N);
-      length_ -= N;
-      if (length_ < lowater_) lowater_ = length_;
-    }
-  };
-
-  // Gets and returns an object from the central cache, and, if possible,
-  // also adds some objects of that size class to this thread cache.
-  void* FetchFromCentralCache(uint32 cl, int32_t byte_size,
-                              void *(*oom_handler)(size_t size));
-
-  void ListTooLong(void* ptr, uint32 cl);
-
-  // Releases some number of items from src.  Adjusts the list's max_length
-  // to eventually converge on num_objects_to_move(cl).
-  void ListTooLong(FreeList* src, uint32 cl);
-
-  // Releases N items from this thread cache.
-  void ReleaseToCentralCache(FreeList* src, uint32 cl, int N);
-
-  void SetMaxSize(int32 new_max_size);
-
-  // Increase max_size_ by reducing unclaimed_cache_space_ or by
-  // reducing the max_size_ of some other thread.  In both cases,
-  // the delta is kStealAmount.
-  void IncreaseCacheLimit();
-  // Same as above but requires Static::pageheap_lock() is held.
-  void IncreaseCacheLimitLocked();
-
-  // If TLS is available, we also store a copy of the per-thread object
-  // in a __thread variable since __thread variables are faster to read
-  // than pthread_getspecific().  We still need pthread_setspecific()
-  // because __thread variables provide no way to run cleanup code when
-  // a thread is destroyed.
-  // We also give a hint to the compiler to use the "initial exec" TLS
-  // model.  This is faster than the default TLS model, at the cost that
-  // you cannot dlopen this library.  (To see the difference, look at
-  // the CPU use of __tls_get_addr with and without this attribute.)
-  // Since we don't really use dlopen in google code -- and using dlopen
-  // on a malloc replacement is asking for trouble in any case -- that's
-  // a good tradeoff for us.
-#ifdef HAVE_TLS
-  struct ThreadLocalData {
-    ThreadCache* fast_path_heap;
-    ThreadCache* heap;
-    bool use_emergency_malloc;
-  };
-  static __thread ThreadLocalData threadlocal_data_
-    CACHELINE_ALIGNED ATTR_INITIAL_EXEC;
-
-#endif
-
-  // Thread-specific key.  Initialization here is somewhat tricky
-  // because some Linux startup code invokes malloc() before it
-  // is in a good enough state to handle pthread_keycreate().
-  // Therefore, we use TSD keys only after tsd_inited is set to true.
-  // Until then, we use a slow path to get the heap object.
-  static ATTRIBUTE_HIDDEN bool tsd_inited_;
-  static pthread_key_t heap_key_;
-
-  // Linked list of heap objects.  Protected by Static::pageheap_lock.
-  static ThreadCache* thread_heaps_;
-  static int thread_heap_count_;
-
-  // A pointer to one of the objects in thread_heaps_.  Represents
-  // the next ThreadCache from which a thread over its max_size_ should
-  // steal memory limit.  Round-robin through all of the objects in
-  // thread_heaps_.  Protected by Static::pageheap_lock.
-  static ThreadCache* next_memory_steal_;
-
-  // Overall thread cache size.  Protected by Static::pageheap_lock.
-  static size_t overall_thread_cache_size_;
-
-  // Global per-thread cache size.  Writes are protected by
-  // Static::pageheap_lock.  Reads are done without any locking, which should be
-  // fine as long as size_t can be written atomically and we don't place
-  // invariants between this variable and other pieces of state.
-  static volatile size_t per_thread_cache_size_;
-
-  // Represents overall_thread_cache_size_ minus the sum of max_size_
-  // across all ThreadCaches.  Protected by Static::pageheap_lock.
-  static ssize_t unclaimed_cache_space_;
-
-  // This class is laid out with the most frequently used fields
-  // first so that hot elements are placed on the same cache line.
-
-  FreeList      list_[kClassSizesMax];     // Array indexed by size-class
-
-  int32         size_;                     // Combined size of data
-  int32         max_size_;                 // size_ > max_size_ --> Scavenge()
-
-  // The following is the tally of bytes allocated on a thread as a response to
-  // any flavor of malloc() call.  The aggegated amount includes all padding to
-  // the smallest class that can hold the request, or to the nearest whole page
-  // when a large allocation is made without using a class.  This sum is
-  // currently used for Chromium profiling, where tallies are kept of the amount
-  // of memory allocated during the running of each task on each thread.
-  uint32 total_bytes_allocated_;  // Total, modulo 2^32.
-
-  // We sample allocations, biased by the size of the allocation
-  Sampler       sampler_;               // A sampler
-
-  pthread_t     tid_;                   // Which thread owns it
-  bool          in_setspecific_;        // In call to pthread_setspecific?
-
-  // Allocate a new heap. REQUIRES: Static::pageheap_lock is held.
-  static ThreadCache* NewHeap(pthread_t tid);
-
-  // Use only as pthread thread-specific destructor function.
-  static void DestroyThreadCache(void* ptr);
-
-  static void DeleteCache(ThreadCache* heap);
-  static void RecomputePerThreadCacheSize();
-
-public:
-
-  // All ThreadCache objects are kept in a linked list (for stats collection)
-  ThreadCache* next_;
-  ThreadCache* prev_;
-
-  // Ensure that this class is cacheline-aligned. This is critical for
-  // performance, as false sharing would negate many of the benefits
-  // of a per-thread cache.
-} CACHELINE_ALIGNED;
-
-// Allocator for thread heaps
-// This is logically part of the ThreadCache class, but MSVC, at
-// least, does not like using ThreadCache as a template argument
-// before the class is fully defined.  So we put it outside the class.
-extern PageHeapAllocator<ThreadCache> threadcache_allocator;
-
-inline int ThreadCache::HeapsInUse() {
-  return threadcache_allocator.inuse();
-}
-
-inline uint32 ThreadCache::GetTotalBytesAllocated() const {
-  return total_bytes_allocated_;
-}
-
-inline ATTRIBUTE_ALWAYS_INLINE void* ThreadCache::Allocate(
-  size_t size, uint32 cl, void *(*oom_handler)(size_t size)) {
-  FreeList* list = &list_[cl];
-
-#ifdef NO_TCMALLOC_SAMPLES
-  size = list->object_size();
-#endif
-
-  ASSERT(size <= kMaxSize);
-  ASSERT(size != 0);
-  ASSERT(size == 0 || size == Static::sizemap()->ByteSizeForClass(cl));
-
-  void* rv;
-  if (!list->TryPop(&rv)) {
-    return FetchFromCentralCache(cl, size, oom_handler);
-  }
-  size_ -= size;
-  return rv;
-}
-
-inline ATTRIBUTE_ALWAYS_INLINE void ThreadCache::Deallocate(void* ptr, uint32 cl) {
-  ASSERT(list_[cl].max_length() > 0);
-  FreeList* list = &list_[cl];
-
-  // This catches back-to-back frees of allocs in the same size
-  // class. A more comprehensive (and expensive) test would be to walk
-  // the entire freelist. But this might be enough to find some bugs.
-  ASSERT(ptr != list->Next());
-
-  uint32_t length = list->Push(ptr);
-
-  if (PREDICT_FALSE(length > list->max_length())) {
-    ListTooLong(list, cl);
-    return;
-  }
-
-  size_ += list->object_size();
-  if (PREDICT_FALSE(size_ > max_size_)){
-    Scavenge();
-  }
-}
-
-inline ThreadCache* ThreadCache::GetThreadHeap() {
-#ifdef HAVE_TLS
-  return threadlocal_data_.heap;
-#else
-  return reinterpret_cast<ThreadCache *>(
-      perftools_pthread_getspecific(heap_key_));
-#endif
-}
-
-inline ThreadCache* ThreadCache::GetCacheWhichMustBePresent() {
-#ifdef HAVE_TLS
-  ASSERT(threadlocal_data_.heap);
-  return threadlocal_data_.heap;
-#else
-  ASSERT(perftools_pthread_getspecific(heap_key_));
-  return reinterpret_cast<ThreadCache *>(
-      perftools_pthread_getspecific(heap_key_));
-#endif
-}
-
-inline ThreadCache* ThreadCache::GetCache() {
-#ifdef HAVE_TLS
-  ThreadCache* ptr = GetThreadHeap();
-#else
-  ThreadCache* ptr = NULL;
-  if (PREDICT_TRUE(tsd_inited_)) {
-    ptr = GetThreadHeap();
-  }
-#endif
-  if (ptr == NULL) ptr = CreateCacheIfNecessary();
-  return ptr;
-}
-
-// In deletion paths, we do not try to create a thread-cache.  This is
-// because we may be in the thread destruction code and may have
-// already cleaned up the cache for this thread.
-inline ThreadCache* ThreadCache::GetCacheIfPresent() {
-#ifndef HAVE_TLS
-  if (PREDICT_FALSE(!tsd_inited_)) return NULL;
-#endif
-  return GetThreadHeap();
-}
-
-inline ThreadCache* ThreadCache::GetFastPathCache() {
-#ifndef HAVE_TLS
-  return GetCacheIfPresent();
-#else
-  return threadlocal_data_.fast_path_heap;
-#endif
-}
-
-inline void ThreadCache::SetUseEmergencyMalloc() {
-#ifdef HAVE_TLS
-  threadlocal_data_.fast_path_heap = NULL;
-  threadlocal_data_.use_emergency_malloc = true;
-#endif
-}
-
-inline void ThreadCache::ResetUseEmergencyMalloc() {
-#ifdef HAVE_TLS
-  ThreadCache *heap = threadlocal_data_.heap;
-  threadlocal_data_.fast_path_heap = heap;
-  threadlocal_data_.use_emergency_malloc = false;
-#endif
-}
-
-inline bool ThreadCache::IsUseEmergencyMalloc() {
-#if defined(HAVE_TLS) && defined(ENABLE_EMERGENCY_MALLOC)
-  return PREDICT_FALSE(threadlocal_data_.use_emergency_malloc);
-#else
-  return false;
-#endif
-}
-
-inline void ThreadCache::SetMaxSize(int32 new_max_size) {
-  max_size_ = new_max_size;
-}
-
-#ifndef NO_TCMALLOC_SAMPLES
-
-inline bool ThreadCache::SampleAllocation(size_t k) {
-  return !sampler_.RecordAllocation(k);
-}
-
-inline bool ThreadCache::TryRecordAllocationFast(size_t k) {
-  return sampler_.TryRecordAllocationFast(k);
-}
-
-#else
-
-inline bool ThreadCache::SampleAllocation(size_t k) {
-  return false;
-}
-
-inline bool ThreadCache::TryRecordAllocationFast(size_t k) {
-  return true;
-}
-
-#endif
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_THREAD_CACHE_H_
diff --git a/third_party/tcmalloc/chromium/src/windows/TODO b/third_party/tcmalloc/chromium/src/windows/TODO
deleted file mode 100644
index 708ec237..0000000
--- a/third_party/tcmalloc/chromium/src/windows/TODO
+++ /dev/null
@@ -1,86 +0,0 @@
-* Get heap-profile-table.cc using DeleteMatchingFiles
-* Get heap-profile-table.cc using FillProcSelfMaps, DumpProcSelfMaps
-* Play around with ExperimentalGetStackTrace
-* Support the windows-level memory-allocation functions?  See
-    /home/build/googleclient/earth/client/tools/memorytracking/client/memorytrace/src/memorytrace.cpp
-    /home/build/googleclient/total_recall/common/sitestep/*
-    http://www.internals.com/articles/apispy/apispy.htm
-    http://www.wheaty.net/APISPY32.zip
-* Verify /proc/xxx/maps:
-    http://www.geocities.com/wah_java_dotnet/procmap/index.html
-* Figure out how to edit the executable IAT so tcmalloc.dll is loaded first
-* Use QueryPerformanceCounter instead of GetTickCount() (also for sparsehash)
-
-----
-More info on windows-level memory-allocation functions:
-   C runtime malloc
-   LocalAlloc
-   GlobalAlloc
-   HeapAlloc
-   VirtualAlloc
-   mmap stuff
-
-malloc, LocalAlloc and GlobalAlloc call HeapAlloc, which calls
-VirtualAlloc when needed, which calls VirtualAllocEx (the __sbrk equiv?)
-
-siggi sez: If you want to do a generic job, you probably need to
-preserve the semantics of all of these Win32 calls:
-   Heap32First
-   Heap32ListFirst
-   Heap32ListNext
-   Heap32Next
-   HeapAlloc
-   HeapCompact
-   HeapCreate
-   HeapCreateTagsW
-   HeapDestroy
-   HeapExtend
-   HeapFree
-   HeapLock
-   HeapQueryInformation
-   HeapQueryTagW
-   HeapReAlloc
-   HeapSetInformation
-   HeapSize
-   HeapSummary
-   HeapUnlock
-   HeapUsage
-   HeapValidate
-   HeapWalk
-
-kernel32.dll export functions and nt.dll export functions:
-   http://www.shorthike.com/svn/trunk/tools_win32/dm/lib/kernel32.def
-   http://undocumented.ntinternals.net/
-
-You can edit the executable IAT to have the patching DLL be the
-first one loaded.
-
-Most complete way to intercept system calls is patch the functions
-(not the IAT).
-
-Microsoft has somee built-in routines for heap-checking:
-   http://support.microsoft.com/kb/268343
-
-----
-Itimer replacement:
-   http://msdn2.microsoft.com/en-us/library/ms712713.aspx
-
-----
-Changes I've had to make to the project file:
-
-0) When creating the project file, click on "no autogenerated files"
-
---- For each project:
-1) Alt-F7 -> General -> [pulldown "all configurations" ] -> Output Directory -> $(SolutionDir)$(ConfigurationName)
-2) Alt-F7 -> General -> [pulldown "all configurations" ] -> Intermediate Directory -> $(ConfigurationName)
-
---- For each .cc file:
-1) Alt-F7 -> C/C++ -> General -> [pulldown "all configurations"] -> Additional Include Directives --> src/windows + src/
-2) Alt-F7 -> C/C++ -> Code Generation -> Runtime Library -> Multi-threaded, debug/release, DLL or not
-
---- For DLL:
-3) Alt-F7 -> Linker -> Input -> [pulldown "all configurations" ] -> Module Definition File -> src\windows\vc7and8.def
---- For binaries depending on a DLL:
-3) Right-click on project -> Project Dependencies -> [add dll]
---- For static binaries (not depending on a DLL)
-3) Alt-F7 -> C/C++ -> Command Line -> [pulldown "all configurations"] -> /D PERFTOOLS_DLL_DECL=
diff --git a/third_party/tcmalloc/chromium/src/windows/addr2line-pdb.c b/third_party/tcmalloc/chromium/src/windows/addr2line-pdb.c
deleted file mode 100644
index ca699d2..0000000
--- a/third_party/tcmalloc/chromium/src/windows/addr2line-pdb.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: David Vitek
- *
- * Dump function addresses using Microsoft debug symbols.  This works
- * on PDB files.  Note that this program will download symbols to
- * c:\websymbols without asking.
- */
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-
-#ifndef _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#ifndef _CRT_SECURE_NO_DEPRECATE
-#define _CRT_SECURE_NO_DEPRECATE
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <windows.h>
-#include <dbghelp.h>
-
-#define SEARCH_CAP (1024*1024)
-#define WEBSYM "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols"
-
-void usage() {
-  fprintf(stderr, "usage: addr2line-pdb "
-          "[-f|--functions] [-C|--demangle] [-e|--exe filename]\n");
-  fprintf(stderr, "(Then list the hex addresses on stdin, one per line)\n");
-}
-
-int main(int argc, char *argv[]) {
-  DWORD  error;
-  HANDLE process;
-  ULONG64 module_base;
-  int i;
-  char* search;
-  char buf[256];   /* Enough to hold one hex address, I trust! */
-  int rv = 0;
-  /* We may add SYMOPT_UNDNAME if --demangle is specified: */
-  DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES;
-  char* filename = "a.out";         /* The default if -e isn't specified */
-  int print_function_name = 0;      /* Set to 1 if -f is specified */
-
-  for (i = 1; i < argc; i++) {
-    if (strcmp(argv[i], "--functions") == 0 || strcmp(argv[i], "-f") == 0) {
-      print_function_name = 1;
-    } else if (strcmp(argv[i], "--demangle") == 0 ||
-               strcmp(argv[i], "-C") == 0) {
-      symopts |= SYMOPT_UNDNAME;
-    } else if (strcmp(argv[i], "--exe") == 0 ||
-               strcmp(argv[i], "-e") == 0) {
-      if (i + 1 >= argc) {
-        fprintf(stderr, "FATAL ERROR: -e must be followed by a filename\n");
-        return 1;
-      }
-      filename = argv[i+1];
-      i++;     /* to skip over filename too */
-    } else if (strcmp(argv[i], "--help") == 0) {
-      usage();
-      exit(0);
-    } else {
-      usage();
-      exit(1);
-    }
-  }
-
-  process = GetCurrentProcess();
-
-  if (!SymInitialize(process, NULL, FALSE)) {
-    error = GetLastError();
-    fprintf(stderr, "SymInitialize returned error : %lu\n", error);
-    return 1;
-  }
-
-  search = malloc(SEARCH_CAP);
-  if (SymGetSearchPath(process, search, SEARCH_CAP)) {
-    if (strlen(search) + sizeof(";" WEBSYM) > SEARCH_CAP) {
-      fprintf(stderr, "Search path too long\n");
-      SymCleanup(process);
-      return 1;
-    }
-    strcat(search, ";" WEBSYM);
-  } else {
-    error = GetLastError();
-    fprintf(stderr, "SymGetSearchPath returned error : %lu\n", error);
-    rv = 1;                   /* An error, but not a fatal one */
-    strcpy(search, WEBSYM);   /* Use a default value */
-  }
-  if (!SymSetSearchPath(process, search)) {
-    error = GetLastError();
-    fprintf(stderr, "SymSetSearchPath returned error : %lu\n", error);
-    rv = 1;                   /* An error, but not a fatal one */
-  }
-
-  SymSetOptions(symopts);
-  module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0);
-  if (!module_base) {
-    /* SymLoadModuleEx failed */
-    error = GetLastError();
-    fprintf(stderr, "SymLoadModuleEx returned error : %lu for %s\n",
-            error, filename);
-    SymCleanup(process);
-    return 1;
-  }
-
-  buf[sizeof(buf)-1] = '\0';  /* Just to be safe */
-  while (fgets(buf, sizeof(buf)-1, stdin)) {
-    /* GNU addr2line seems to just do a strtol and ignore any
-     * weird characters it gets, so we will too.
-     */
-    unsigned __int64 reladdr = _strtoui64(buf, NULL, 16);
-    ULONG64 buffer[(sizeof(SYMBOL_INFO) +
-                    MAX_SYM_NAME*sizeof(TCHAR) +
-                    sizeof(ULONG64) - 1)
-                   / sizeof(ULONG64)];
-    memset(buffer, 0, sizeof(buffer));
-    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
-    IMAGEHLP_LINE64 line;
-    DWORD dummy;
-
-    // Just ignore overflow. In an overflow scenario, the resulting address
-    // will be lower than module_base which hasn't been mapped by any prior
-    // SymLoadModuleEx() command. This will cause SymFromAddr() and
-    // SymGetLineFromAddr64() both to return failures and print the correct
-    // ?? and ??:0 message variant.
-    ULONG64 absaddr = reladdr + module_base;
-
-    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
-    // The length of the name is not including the null-terminating character.
-    pSymbol->MaxNameLen = MAX_SYM_NAME - 1;
-    if (print_function_name) {
-      if (SymFromAddr(process, (DWORD64)absaddr, NULL, pSymbol)) {
-        printf("%s\n", pSymbol->Name);
-      } else {
-        printf("??\n");
-      }
-    }
-    line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
-    if (SymGetLineFromAddr64(process, (DWORD64)absaddr, &dummy, &line)) {
-      printf("%s:%d\n", line.FileName, (int)line.LineNumber);
-    } else {
-      printf("??:0\n");
-    }
-  }
-  SymUnloadModule64(process, module_base);
-  SymCleanup(process);
-  return rv;
-}
diff --git a/third_party/tcmalloc/chromium/src/windows/auto_testing_hook.h b/third_party/tcmalloc/chromium/src/windows/auto_testing_hook.h
deleted file mode 100644
index fc2b710..0000000
--- a/third_party/tcmalloc/chromium/src/windows/auto_testing_hook.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Utility for using SideStep with unit tests.
-
-#ifndef CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
-#define CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "preamble_patcher.h"
-
-#define SIDESTEP_CHK(x)  CHECK(x)
-#define SIDESTEP_EXPECT_TRUE(x)  SIDESTEP_CHK(x)
-
-namespace sidestep {
-
-// Same trick as common/scope_cleanup.h ScopeGuardImplBase
-class AutoTestingHookBase {
- public:
-  virtual ~AutoTestingHookBase() {}
-};
-
-// This is the typedef you normally use for the class, e.g.
-//
-// AutoTestingHook hook = MakeTestingHook(TargetFunc, HookTargetFunc);
-//
-// The 'hook' variable will then be destroyed when it goes out of scope.
-//
-// NOTE: You must not hold this type as a member of another class.  Its
-// destructor will not get called.
-typedef const AutoTestingHookBase& AutoTestingHook;
-
-// This is the class you must use when holding a hook as a member of another
-// class, e.g.
-//
-// public:
-//  AutoTestingHookHolder holder_;
-//  MyClass() : my_hook_holder(MakeTestingHookHolder(Target, Hook)) {}
-class AutoTestingHookHolder {
- public:
-  explicit AutoTestingHookHolder(AutoTestingHookBase* hook) : hook_(hook) {}
-  ~AutoTestingHookHolder() { delete hook_; }
- private:
-  AutoTestingHookHolder() {}  // disallow
-  AutoTestingHookBase* hook_;
-};
-
-// This class helps patch a function, then unpatch it when the object exits
-// scope, and also maintains the pointer to the original function stub.
-//
-// To enable use of the class without having to explicitly provide the
-// type of the function pointers (and instead only providing it
-// implicitly) we use the same trick as ScopeGuard (see
-// common/scope_cleanup.h) uses, so to create a hook you use the MakeHook
-// function rather than a constructor.
-//
-// NOTE:  This function is only safe for e.g. unit tests and _not_ for
-// production code.  See PreamblePatcher class for details.
-template <typename T>
-class AutoTestingHookImpl : public AutoTestingHookBase {
- public:
-  static AutoTestingHookImpl<T> MakeTestingHook(T target_function,
-                                                T replacement_function,
-                                                bool do_it) {
-    return AutoTestingHookImpl<T>(target_function, replacement_function, do_it);
-  }
-
-  static AutoTestingHookImpl<T>* MakeTestingHookHolder(T target_function,
-                                                       T replacement_function,
-                                                       bool do_it) {
-    return new AutoTestingHookImpl<T>(target_function,
-                                      replacement_function, do_it);
-  }
-
-  ~AutoTestingHookImpl() {
-    if (did_it_) {
-      SIDESTEP_CHK(SIDESTEP_SUCCESS == PreamblePatcher::Unpatch(
-          (void*)target_function_, (void*)replacement_function_,
-          (void*)original_function_));
-    }
-  }
-
-  // Returns a pointer to the original function.  To use this method you will
-  // have to explicitly create an AutoTestingHookImpl of the specific
-  // function pointer type (i.e. not use the AutoTestingHook typedef).
-  T original_function() {
-    return original_function_;
-  }
-
- private:
-  AutoTestingHookImpl(T target_function, T replacement_function, bool do_it)
-      : target_function_(target_function),
-        original_function_(NULL),
-        replacement_function_(replacement_function),
-        did_it_(do_it) {
-    if (do_it) {
-      SIDESTEP_CHK(SIDESTEP_SUCCESS == PreamblePatcher::Patch(target_function,
-                                                     replacement_function,
-                                                     &original_function_));
-    }
-  }
-
-  T target_function_;  // always valid
-  T original_function_;  // always valid
-  T replacement_function_;  // always valid
-  bool did_it_;  // Remember if we did it or not...
-};
-
-template <typename T>
-inline AutoTestingHookImpl<T> MakeTestingHook(T target,
-                                              T replacement,
-                                              bool do_it) {
-  return AutoTestingHookImpl<T>::MakeTestingHook(target, replacement, do_it);
-}
-
-template <typename T>
-inline AutoTestingHookImpl<T> MakeTestingHook(T target, T replacement) {
-  return AutoTestingHookImpl<T>::MakeTestingHook(target, replacement, true);
-}
-
-template <typename T>
-inline AutoTestingHookImpl<T>* MakeTestingHookHolder(T target, T replacement) {
-  return AutoTestingHookImpl<T>::MakeTestingHookHolder(target, replacement,
-                                                       true);
-}
-
-};  // namespace sidestep
-
-#endif  // CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
diff --git a/third_party/tcmalloc/chromium/src/windows/config.h b/third_party/tcmalloc/chromium/src/windows/config.h
deleted file mode 100644
index e860bc35..0000000
--- a/third_party/tcmalloc/chromium/src/windows/config.h
+++ /dev/null
@@ -1,367 +0,0 @@
-/* A manual version of config.h fit for windows machines.
- *
- * Use of this source code is governed by a BSD-style license that can
- * be found in the LICENSE file.
- */
-
-/* Sometimes we accidentally #include this config.h instead of the one
-   in .. -- this is particularly true for msys/mingw, which uses the
-   unix config.h but also runs code in the windows directory.
-   */
-#ifdef __MINGW32__
-#include "../config.h"
-#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_
-#endif
-
-#ifndef GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_
-#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_
-/* used by tcmalloc.h */
-#define GPERFTOOLS_CONFIG_H_
-
-/* define this if you are linking tcmalloc statically and overriding the
- * default allocators.
- * For instructions on how to use this mode, see
- * http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b
- */
-/* #undef WIN32_OVERRIDE_ALLOCATORS */
-
-/* Build new/delete operators for overaligned types */
-/* #undef ENABLE_ALIGNED_NEW_DELETE */
-
-/* Build runtime detection for sized delete */
-/* #undef ENABLE_DYNAMIC_SIZED_DELETE */
-
-/* Build sized deletion operators */
-/* #undef ENABLE_SIZED_DELETE */
-
-/* Define to 1 if compiler supports __builtin_expect */
-/* #undef HAVE_BUILTIN_EXPECT */
-
-/* Define to 1 if compiler supports __builtin_stack_pointer */
-/* #undef HAVE_BUILTIN_STACK_POINTER */
-
-/* Define to 1 if you have the <conflict-signal.h> header file. */
-/* #undef HAVE_CONFLICT_SIGNAL_H */
-
-/* Define to 1 if you have the <cygwin/signal.h> header file. */
-/* #undef HAVE_CYGWIN_SIGNAL_H */
-
-/* Define to 1 if you have the declaration of `backtrace', and to 0 if you
-   don't. */
-/* #undef HAVE_DECL_BACKTRACE */
-
-/* Define to 1 if you have the declaration of `cfree', and to 0 if you don't.
-   */
-#define HAVE_DECL_CFREE 0
-
-/* Define to 1 if you have the declaration of `memalign', and to 0 if you
-   don't. */
-#define HAVE_DECL_MEMALIGN 0
-
-/* Define to 1 if you have the declaration of `nanosleep', and to 0 if you
-   don't. */
-#define HAVE_DECL_NANOSLEEP 0
-
-/* Define to 1 if you have the declaration of `posix_memalign', and to 0 if
-   you don't. */
-#define HAVE_DECL_POSIX_MEMALIGN 0
-
-/* Define to 1 if you have the declaration of `pvalloc', and to 0 if you
-   don't. */
-#define HAVE_DECL_PVALLOC 0
-
-/* Define to 1 if you have the declaration of `sleep', and to 0 if you don't.
-   */
-#define HAVE_DECL_SLEEP 0
-
-/* Define to 1 if you have the declaration of `uname', and to 0 if you don't.
-   */
-#define HAVE_DECL_UNAME 0
-
-/* Define to 1 if you have the declaration of `valloc', and to 0 if you don't.
-   */
-#define HAVE_DECL_VALLOC 0
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-/* #undef HAVE_DLFCN_H */
-
-/* Define to 1 if the system has the type `Elf32_Versym'. */
-/* #undef HAVE_ELF32_VERSYM */
-
-/* Define to 1 if you have the <execinfo.h> header file. */
-/* #undef HAVE_EXECINFO_H */
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the <features.h> header file. */
-/* #undef HAVE_FEATURES_H */
-
-/* Define to 1 if you have the `fork' function. */
-/* #undef HAVE_FORK */
-
-/* Define to 1 if you have the `geteuid' function. */
-/* #undef HAVE_GETEUID */
-
-/* Define to 1 if you have the `getpagesize' function. */
-#define HAVE_GETPAGESIZE 1   /* we define it in windows/port.cc */
-
-/* Define to 1 if you have the <glob.h> header file. */
-/* #undef HAVE_GLOB_H */
-
-/* Define to 1 if you have the <grp.h> header file. */
-/* #undef HAVE_GRP_H */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-#define HAVE_INTTYPES_H 1
-#endif
-
-/* Define to 1 if you have the <libunwind.h> header file. */
-/* #undef HAVE_LIBUNWIND_H */
-
-/* Define to 1 if you have the <linux/ptrace.h> header file. */
-/* #undef HAVE_LINUX_PTRACE_H */
-
-/* Define if this is Linux that has SIGEV_THREAD_ID */
-/* #undef HAVE_LINUX_SIGEV_THREAD_ID */
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#define HAVE_MALLOC_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have a working `mmap' system call. */
-/* #undef HAVE_MMAP */
-
-/* define if the compiler implements namespaces */
-#define HAVE_NAMESPACES 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-/* #undef HAVE_POLL_H */
-
-/* define if libc has program_invocation_name */
-/* #undef HAVE_PROGRAM_INVOCATION_NAME */
-
-/* Define if you have POSIX threads libraries and header files. */
-/* #undef HAVE_PTHREAD */
-
-/* defined to 1 if pthread symbols are exposed even without include pthread.h
-   */
-/* #undef HAVE_PTHREAD_DESPITE_ASKING_FOR */
-
-/* Define to 1 if you have the <pwd.h> header file. */
-/* #undef HAVE_PWD_H */
-
-/* Define to 1 if you have the `sbrk' function. */
-/* #undef HAVE_SBRK */
-
-/* Define to 1 if you have the <sched.h> header file. */
-/* #undef HAVE_SCHED_H */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-#define HAVE_STDINT_H 1
-#endif
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-/* #undef HAVE_STRINGS_H */
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if the system has the type `struct mallinfo'. */
-/* #undef HAVE_STRUCT_MALLINFO */
-
-/* Define to 1 if you have the <sys/cdefs.h> header file. */
-/* #undef HAVE_SYS_CDEFS_H */
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-/* #undef HAVE_SYS_PARAM_H */
-
-/* Define to 1 if you have the <sys/prctl.h> header file. */
-/* #undef HAVE_SYS_PRCTL_H */
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-/* #undef HAVE_SYS_RESOURCE_H */
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-/* #undef HAVE_SYS_SOCKET_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-/* #undef HAVE_SYS_SYSCALL_H */
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/ucontext.h> header file. */
-/* #undef HAVE_SYS_UCONTEXT_H */
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-/* #undef HAVE_SYS_WAIT_H */
-
-/* Define to 1 if compiler supports __thread */
-#define HAVE_TLS 1
-
-/* Define to 1 if you have the <ucontext.h> header file. */
-/* #undef HAVE_UCONTEXT_H */
-
-/* Define to 1 if you have the <unistd.h> header file. */
-/* #undef HAVE_UNISTD_H */
-
-/* Whether <unwind.h> contains _Unwind_Backtrace */
-/* #undef HAVE_UNWIND_BACKTRACE */
-
-/* Define to 1 if you have the <unwind.h> header file. */
-/* #undef HAVE_UNWIND_H */
-
-/* Define to 1 if you have the <valgrind.h> header file. */
-/* #undef HAVE_VALGRIND_H */
-
-/* define if your compiler has __attribute__ */
-/* #undef HAVE___ATTRIBUTE__ */
-
-/* define if your compiler supports alignment of functions */
-/* #undef HAVE___ATTRIBUTE__ALIGNED_FN */
-
-/* Define to 1 if compiler supports __environ */
-/* #undef HAVE___ENVIRON */
-
-/* Define to 1 if the system has the type `__int64'. */
-#define HAVE___INT64 1
-
-/* prefix where we look for installed files */
-/* #undef INSTALL_PREFIX */
-
-/* Define to 1 if int32_t is equivalent to intptr_t */
-#ifndef _WIN64
-#define INT32_EQUALS_INTPTR 1
-#endif
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-/* #undef LT_OBJDIR */
-
-/* Name of package */
-#define PACKAGE "gperftools"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "gperftools@googlegroups.com"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "gperftools"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gperftools 2.7"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "gperftools"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.7"
-
-/* How to access the PC from a struct ucontext */
-/* #undef PC_FROM_UCONTEXT */
-
-/* Always the empty-string on non-windows systems. On windows, should be
-   "__declspec(dllexport)". This way, when we compile the dll, we export our
-   functions/classes. It's safe to define this here because config.h is only
-   used internally, to compile the DLL, and every DLL source file #includes
-   "config.h" before anything else. */
-#ifndef PERFTOOLS_DLL_DECL
-# define PERFTOOLS_IS_A_DLL 1   /* not set if you're statically linking */
-# define PERFTOOLS_DLL_DECL __declspec(dllexport)
-# define PERFTOOLS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
-#endif
-
-/* printf format code for printing a size_t and ssize_t */
-#ifdef _WIN64
-#define PRIdS "lld"
-#else
-#define PRIdS "d"
-#endif
-
-/* printf format code for printing a size_t and ssize_t */
-#ifdef _WIN64
-#define PRIuS "llu"
-#else
-#define PRIuS "u"
-#endif
-
-/* printf format code for printing a size_t and ssize_t */
-#ifdef _WIN64
-#define PRIxS "llx"
-#else
-#define PRIxS "x"
-#endif
-
-/* Mark the systems where we know it's bad if pthreads runs too
-   early before main (before threads are initialized, presumably).  */
-#ifdef __FreeBSD__
-#define PTHREADS_CRASHES_IF_RUN_TOO_EARLY 1
-#endif
-
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* the namespace where STL code like vector<> is defined */
-#define STL_NAMESPACE std
-
-/* Define 32K of internal pages size for tcmalloc */
-/* #undef TCMALLOC_32K_PAGES */
-
-/* Define 64K of internal pages size for tcmalloc */
-/* #undef TCMALLOC_64K_PAGES */
-
-/* Define 8 bytes of allocation alignment for tcmalloc */
-/* #undef TCMALLOC_ALIGN_8BYTES */
-
-/* Version number of package */
-#define VERSION "2.7"
-
-/* C99 says: define this to get the PRI... macros from stdint.h */
-#ifndef __STDC_FORMAT_MACROS
-# define __STDC_FORMAT_MACROS 1
-#endif
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-// ---------------------------------------------------------------------
-// Extra stuff not found in config.h.in
-
-// This must be defined before the windows.h is included.  We need at
-// least 0x0400 for mutex.h to have access to TryLock, and at least
-// 0x0501 for patch_functions.cc to have access to GetModuleHandleEx.
-// (This latter is an optimization we could take out if need be.)
-#ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-#define HAVE_SNPRINTF 1
-#endif
-
-// We want to make sure not to ever try to #include heap-checker.h
-#define NO_HEAP_CHECK 1
-
-// TODO(csilvers): include windows/port.h in every relevant source file instead?
-#include "windows/port.h"
-
-#endif  /* GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ */
diff --git a/third_party/tcmalloc/chromium/src/windows/get_mangled_names.cc b/third_party/tcmalloc/chromium/src/windows/get_mangled_names.cc
deleted file mode 100644
index 08bd03b..0000000
--- a/third_party/tcmalloc/chromium/src/windows/get_mangled_names.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-// ---
-// Author: Craig Silverstein (opensource@google.com)
-
-// When you are porting perftools to a new compiler or architecture
-// (win64 vs win32) for instance, you'll need to change the mangled
-// symbol names for operator new and friends at the top of
-// patch_functions.cc.  This file helps you do that.
-//
-// It does this by defining these functions with the proper signature.
-// All you need to do is compile this file and the run dumpbin on it.
-// (See http://msdn.microsoft.com/en-us/library/5x49w699.aspx for more
-// on dumpbin).  To do this in MSVC, use the MSVC commandline shell:
-//    http://msdn.microsoft.com/en-us/library/ms235639(VS.80).aspx)
-//
-// The run:
-//    cl /c get_mangled_names.cc
-//    dumpbin /symbols get_mangled_names.obj
-//
-// It will print out the mangled (and associated unmangled) names of
-// the 8 symbols you need to put at the top of patch_functions.cc
-
-#include <sys/types.h>   // for size_t
-#include <new>           // for nothrow_t
-
-static char m;   // some dummy memory so new doesn't return NULL.
-
-void* operator new(size_t size) { return &m; }
-void operator delete(void* p) throw() { }
-void* operator new[](size_t size) { return &m; }
-void operator delete[](void* p) throw() { }
-
-void* operator new(size_t size, const std::nothrow_t&) throw() { return &m; }
-void operator delete(void* p, const std::nothrow_t&) throw() { }
-void* operator new[](size_t size, const std::nothrow_t&) throw() { return &m; }
-void operator delete[](void* p, const std::nothrow_t&) throw() { }
diff --git a/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h b/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h
deleted file mode 100644
index c7db631..0000000
--- a/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#include <gperftools/tcmalloc.h>
diff --git a/third_party/tcmalloc/chromium/src/windows/gperftools/tcmalloc.h b/third_party/tcmalloc/chromium/src/windows/gperftools/tcmalloc.h
deleted file mode 100644
index 46fb4ea..0000000
--- a/third_party/tcmalloc/chromium/src/windows/gperftools/tcmalloc.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat <opensource@google.com>
- *         .h file by Craig Silverstein <opensource@google.com>
- */
-
-#ifndef TCMALLOC_TCMALLOC_H_
-#define TCMALLOC_TCMALLOC_H_
-
-#include <stddef.h>                     /* for size_t */
-#ifdef __cplusplus
-#include <new>                          /* for std::nothrow_t, std::align_val_t */
-#endif
-
-/* Define the version number so folks can check against it */
-#define TC_VERSION_MAJOR  2
-#define TC_VERSION_MINOR  7
-#define TC_VERSION_PATCH  ""
-#define TC_VERSION_STRING "gperftools 2.7"
-
-#ifndef PERFTOOLS_NOTHROW
-
-#if __cplusplus >= 201103L
-#define PERFTOOLS_NOTHROW noexcept
-#elif defined(__cplusplus)
-#define PERFTOOLS_NOTHROW throw()
-#else
-# ifdef __GNUC__
-#  define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
-# else
-#  define PERFTOOLS_NOTHROW
-# endif
-#endif
-
-#endif
-
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-  /*
-   * Returns a human-readable version string.  If major, minor,
-   * and/or patch are not NULL, they are set to the major version,
-   * minor version, and patch-code (a string, usually "").
-   */
-  PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
-                                            const char** patch) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
-                                       size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
-                                           size_t align, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
-
-  /*
-   * This is an alias for MallocExtension::instance()->GetAllocatedSize().
-   * It is equivalent to
-   *    OS X: malloc_size()
-   *    glibc: malloc_usable_size()
-   *    Windows: _msize()
-   */
-  PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
-
-#ifdef __cplusplus
-  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_new(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-
-#if defined(__cpp_aligned_new) || (defined(_MSVC_LANG) && _MSVC_LANG > 201402L)
-  PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t al,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t al,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t al,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-#endif
-}
-#endif
-
-/* We're only un-defining for public */
-#if !defined(GPERFTOOLS_CONFIG_H_)
-
-#undef PERFTOOLS_NOTHROW
-
-#endif /* GPERFTOOLS_CONFIG_H_ */
-
-#endif  /* #ifndef TCMALLOC_TCMALLOC_H_ */
diff --git a/third_party/tcmalloc/chromium/src/windows/gperftools/tcmalloc.h.in b/third_party/tcmalloc/chromium/src/windows/gperftools/tcmalloc.h.in
deleted file mode 100644
index adb7962..0000000
--- a/third_party/tcmalloc/chromium/src/windows/gperftools/tcmalloc.h.in
+++ /dev/null
@@ -1,155 +0,0 @@
-// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat <opensource@google.com>
- *         .h file by Craig Silverstein <opensource@google.com>
- */
-
-#ifndef TCMALLOC_TCMALLOC_H_
-#define TCMALLOC_TCMALLOC_H_
-
-#include <stddef.h>                     /* for size_t */
-#ifdef __cplusplus
-#include <new>                          /* for std::nothrow_t, std::align_val_t */
-#endif
-
-/* Define the version number so folks can check against it */
-#define TC_VERSION_MAJOR  @TC_VERSION_MAJOR@
-#define TC_VERSION_MINOR  @TC_VERSION_MINOR@
-#define TC_VERSION_PATCH  "@TC_VERSION_PATCH@"
-#define TC_VERSION_STRING "gperftools @TC_VERSION_MAJOR@.@TC_VERSION_MINOR@@TC_VERSION_PATCH@"
-
-#ifndef PERFTOOLS_NOTHROW
-
-#if __cplusplus >= 201103L
-#define PERFTOOLS_NOTHROW noexcept
-#elif defined(__cplusplus)
-#define PERFTOOLS_NOTHROW throw()
-#else
-# ifdef __GNUC__
-#  define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
-# else
-#  define PERFTOOLS_NOTHROW
-# endif
-#endif
-
-#endif
-
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-  /*
-   * Returns a human-readable version string.  If major, minor,
-   * and/or patch are not NULL, they are set to the major version,
-   * minor version, and patch-code (a string, usually "").
-   */
-  PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
-                                            const char** patch) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
-                                       size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
-                                           size_t align, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
-
-  /*
-   * This is an alias for MallocExtension::instance()->GetAllocatedSize().
-   * It is equivalent to
-   *    OS X: malloc_size()
-   *    glibc: malloc_usable_size()
-   *    Windows: _msize()
-   */
-  PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
-
-#ifdef __cplusplus
-  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_new(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-
-#if defined(__cpp_aligned_new) || (defined(_MSVC_LANG) && _MSVC_LANG > 201402L)
-  PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t al,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t al,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t al,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-#endif
-}
-#endif
-
-/* We're only un-defining for public */
-#if !defined(GPERFTOOLS_CONFIG_H_)
-
-#undef PERFTOOLS_NOTHROW
-
-#endif /* GPERFTOOLS_CONFIG_H_ */
-
-#endif  /* #ifndef TCMALLOC_TCMALLOC_H_ */
diff --git a/third_party/tcmalloc/chromium/src/windows/ia32_modrm_map.cc b/third_party/tcmalloc/chromium/src/windows/ia32_modrm_map.cc
deleted file mode 100644
index 142c7cb..0000000
--- a/third_party/tcmalloc/chromium/src/windows/ia32_modrm_map.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Table of relevant information about how to decode the ModR/M byte.
- * Based on information in the IA-32 Intel® Architecture
- * Software Developer's Manual Volume 2: Instruction Set Reference.
- */
-
-#include "mini_disassembler.h"
-#include "mini_disassembler_types.h"
-
-namespace sidestep {
-
-const ModrmEntry MiniDisassembler::s_ia16_modrm_map_[] = {
-// mod == 00
-  /* r/m == 000 */ { false, false, OS_ZERO },
-  /* r/m == 001 */ { false, false, OS_ZERO },
-  /* r/m == 010 */ { false, false, OS_ZERO },
-  /* r/m == 011 */ { false, false, OS_ZERO },
-  /* r/m == 100 */ { false, false, OS_ZERO },
-  /* r/m == 101 */ { false, false, OS_ZERO },
-  /* r/m == 110 */ { true, false, OS_WORD },
-  /* r/m == 111 */ { false, false, OS_ZERO }, 
-// mod == 01
-  /* r/m == 000 */ { true, false, OS_BYTE },
-  /* r/m == 001 */ { true, false, OS_BYTE },
-  /* r/m == 010 */ { true, false, OS_BYTE },
-  /* r/m == 011 */ { true, false, OS_BYTE },
-  /* r/m == 100 */ { true, false, OS_BYTE },
-  /* r/m == 101 */ { true, false, OS_BYTE },
-  /* r/m == 110 */ { true, false, OS_BYTE },
-  /* r/m == 111 */ { true, false, OS_BYTE }, 
-// mod == 10
-  /* r/m == 000 */ { true, false, OS_WORD },
-  /* r/m == 001 */ { true, false, OS_WORD },
-  /* r/m == 010 */ { true, false, OS_WORD },
-  /* r/m == 011 */ { true, false, OS_WORD },
-  /* r/m == 100 */ { true, false, OS_WORD },
-  /* r/m == 101 */ { true, false, OS_WORD },
-  /* r/m == 110 */ { true, false, OS_WORD },
-  /* r/m == 111 */ { true, false, OS_WORD }, 
-// mod == 11
-  /* r/m == 000 */ { false, false, OS_ZERO },
-  /* r/m == 001 */ { false, false, OS_ZERO },
-  /* r/m == 010 */ { false, false, OS_ZERO },
-  /* r/m == 011 */ { false, false, OS_ZERO },
-  /* r/m == 100 */ { false, false, OS_ZERO },
-  /* r/m == 101 */ { false, false, OS_ZERO },
-  /* r/m == 110 */ { false, false, OS_ZERO },
-  /* r/m == 111 */ { false, false, OS_ZERO }
-};
-
-const ModrmEntry MiniDisassembler::s_ia32_modrm_map_[] = {
-// mod == 00
-  /* r/m == 000 */ { false, false, OS_ZERO },
-  /* r/m == 001 */ { false, false, OS_ZERO },
-  /* r/m == 010 */ { false, false, OS_ZERO },
-  /* r/m == 011 */ { false, false, OS_ZERO },
-  /* r/m == 100 */ { false, true, OS_ZERO },
-  /* r/m == 101 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 110 */ { false, false, OS_ZERO },
-  /* r/m == 111 */ { false, false, OS_ZERO }, 
-// mod == 01
-  /* r/m == 000 */ { true, false, OS_BYTE },
-  /* r/m == 001 */ { true, false, OS_BYTE },
-  /* r/m == 010 */ { true, false, OS_BYTE },
-  /* r/m == 011 */ { true, false, OS_BYTE },
-  /* r/m == 100 */ { true, true, OS_BYTE },
-  /* r/m == 101 */ { true, false, OS_BYTE },
-  /* r/m == 110 */ { true, false, OS_BYTE },
-  /* r/m == 111 */ { true, false, OS_BYTE }, 
-// mod == 10
-  /* r/m == 000 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 001 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 010 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 011 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 100 */ { true, true, OS_DOUBLE_WORD },
-  /* r/m == 101 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 110 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 111 */ { true, false, OS_DOUBLE_WORD }, 
-// mod == 11
-  /* r/m == 000 */ { false, false, OS_ZERO },
-  /* r/m == 001 */ { false, false, OS_ZERO },
-  /* r/m == 010 */ { false, false, OS_ZERO },
-  /* r/m == 011 */ { false, false, OS_ZERO },
-  /* r/m == 100 */ { false, false, OS_ZERO },
-  /* r/m == 101 */ { false, false, OS_ZERO },
-  /* r/m == 110 */ { false, false, OS_ZERO },
-  /* r/m == 111 */ { false, false, OS_ZERO },
-};
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/chromium/src/windows/ia32_opcode_map.cc b/third_party/tcmalloc/chromium/src/windows/ia32_opcode_map.cc
deleted file mode 100644
index e14279c..0000000
--- a/third_party/tcmalloc/chromium/src/windows/ia32_opcode_map.cc
+++ /dev/null
@@ -1,1219 +0,0 @@
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Opcode decoding maps.  Based on the IA-32 Intel® Architecture
- * Software Developer's Manual Volume 2: Instruction Set Reference.  Idea
- * for how to lay out the tables in memory taken from the implementation
- * in the Bastard disassembly environment.
- */
-
-#include "mini_disassembler.h"
-
-namespace sidestep {
-
-/*
-* This is the first table to be searched; the first field of each
-* Opcode in the table is either 0 to indicate you're in the
-* right table, or an index to the correct table, in the global
-* map g_pentiumOpcodeMap
-*/
-const Opcode s_first_opcode_byte[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF */ { 1, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x10 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x11 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x12 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x13 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x14 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x15 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x16 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x17 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x18 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x19 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1E */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1F */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x20 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x21 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x22 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x23 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x24 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x25 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x26 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x27 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "daa", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x28 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x29 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "das", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x30 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x31 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x32 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x33 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x34 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x35 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x36 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x37 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "aaa", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x38 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x39 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "aas", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#ifdef _M_X64
-  /* REX Prefixes in 64-bit mode. */
-  /* 0x40 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x41 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x42 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x43 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x44 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x45 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x46 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x47 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x48 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x49 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4A */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4B */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4C */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4D */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4F */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#else
-  /* 0x40 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x41 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x42 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x43 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x44 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x45 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x46 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x47 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x48 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x49 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#endif
-  /* 0x50 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x51 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x52 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x53 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x54 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x55 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x56 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x57 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x58 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x59 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x60 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "pushad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x61 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "popad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x62 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_A, AM_NOT_USED, "bound", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x63 */ { 0, IT_GENERIC, AM_E | OT_W, AM_G | OT_W, AM_NOT_USED, "arpl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x64 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x65 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x66 */ { 0, IT_PREFIX_OPERAND, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x67 */ { 0, IT_PREFIX_ADDRESS, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x68 */ { 0, IT_GENERIC, AM_I | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x69 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I | OT_V, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6A */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I |  OT_B, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6C */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "insb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6D */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "insd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6E */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X | OT_B, AM_NOT_USED, "outsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X | OT_V, AM_NOT_USED, "outsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x70 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x71 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x72 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x73 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x74 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x75 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x76 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x77 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "ja", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x78 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "js", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x79 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7A */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7B */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7C */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7D */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7E */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7F */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x80 */ { 2, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x81 */ { 3, IT_REFERENCE, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x82 */ { 4, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x83 */ { 5, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x84 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x85 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x86 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x87 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x88 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x89 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8C */ { 0, IT_GENERIC, AM_E | OT_W, AM_S | OT_W, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8D */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, "lea", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8E */ { 0, IT_GENERIC, AM_S | OT_W, AM_E | OT_W, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8F */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x90 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "nop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x91 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x92 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x93 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x94 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x95 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x96 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x97 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x98 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cwde", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x99 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cdq", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9A */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, "callf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9B */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wait", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "pushfd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "popfd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9E */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sahf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lahf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_O | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_O | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA2 */ { 0, IT_GENERIC, AM_O | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA3 */ { 0, IT_GENERIC, AM_O | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA4 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, "movsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA5 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, "movsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA6 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, "cmpsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA7 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, "cmpsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAA */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "stosb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAB */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "stosd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X| OT_B, AM_NOT_USED, "lodsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X| OT_V, AM_NOT_USED, "lodsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAE */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_Y | OT_B, AM_NOT_USED, "scasb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_Y | OT_V, AM_NOT_USED, "scasd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB1 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB2 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB3 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#ifdef _M_X64
-  /* 0xB8 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBA */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBB */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBC */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBE */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#else
-  /* 0xB8 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBA */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBB */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBC */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBE */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#endif
-  /* 0xC0 */ { 6, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC1 */ { 7, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC2 */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, "ret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC3 */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC4 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, "les", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, "lds", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC8 */ { 0, IT_GENERIC, AM_I | OT_W, AM_I | OT_B, AM_NOT_USED, "enter", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "leave", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCA */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, "retf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCB */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "retf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "int3", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCD */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "int", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCE */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "into", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCF */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "iret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD0 */ { 8, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD1 */ { 9, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD2 */ { 10, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD3 */ { 11, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD4 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "aam", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD5 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "aad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "xlat", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  
-  // The following 8 lines would be references to the FPU tables, but we currently
-  // do not support the FPU instructions in this disassembler.
-  
-  /* 0xD8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDA */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDB */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDC */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDD */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDE */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDF */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  
-  
-  /* 0xE0 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loopnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE1 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loopz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE2 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE3 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jcxz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE6 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE7 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE8 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE9 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEA */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEB */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_REGISTER | OT_W, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xED */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_W, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEF */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_V, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF0 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lock:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF2 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "repne:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF3 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rep:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF4 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "hlt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cmc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF6 */ { 12, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF7 */ { 13, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "stc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cli", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFB */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFD */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "std", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFE */ { 14, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFF */ { 15, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f[] = {
-  /* 0x0 */ { 16, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 17, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "lar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "lsl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "invd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wbinvd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ud2", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x10 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "movups", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "movsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "movss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "movupd" } },
-  /* 0x11 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movups", true,
-    /* F2h */ { 0, IT_GENERIC, AM_W | OT_SD, AM_V | OT_SD, AM_NOT_USED, "movsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_W | OT_SS, AM_V | OT_SS, AM_NOT_USED, "movss" },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movupd" } },
-  /* 0x12 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhlps" },  // only one of ...
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhlps" },  // ...these two is correct, Intel doesn't specify which
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_S, AM_NOT_USED, "movlpd" } },
-  /* 0x13 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movlps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movlpd" } },
-  /* 0x14 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, "unpcklps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, "unpcklpd" } },
-  /* 0x15 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, "unpckhps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, "unpckhpd" } },
-  /* 0x16 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movhps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlhps" },  // only one of...
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlhps" },  // ...these two is correct, Intel doesn't specify which
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movhpd" } },
-  /* 0x17 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhpd" } },
-  /* 0x18 */ { 18, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x19 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1C */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x20 */ { 0, IT_GENERIC, AM_R | OT_D, AM_C | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x21 */ { 0, IT_GENERIC, AM_R | OT_D, AM_D | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x22 */ { 0, IT_GENERIC, AM_C | OT_D, AM_R | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x23 */ { 0, IT_GENERIC, AM_D | OT_D, AM_R | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x24 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x25 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x26 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x27 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x28 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "movaps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "movapd" } },
-  /* 0x29 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movaps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movapd" } },
-  /* 0x2A */ { 0, IT_GENERIC, AM_V | OT_PS, AM_Q | OT_Q, AM_NOT_USED, "cvtpi2ps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_E | OT_D, AM_NOT_USED, "cvtsi2sd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_E | OT_D, AM_NOT_USED, "cvtsi2ss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_Q | OT_DQ, AM_NOT_USED, "cvtpi2pd" } },
-  /* 0x2B */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movntps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movntpd" } },
-  /* 0x2C */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, "cvttps2pi", true,
-    /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, "cvttsd2si" },
-    /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, "cvttss2si" },
-    /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvttpd2pi" } },
-  /* 0x2D */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, "cvtps2pi", true,
-    /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, "cvtsd2si" },
-    /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, "cvtss2si" },
-    /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvtpd2pi" } },
-  /* 0x2E */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "ucomiss", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "ucomisd" } },
-  /* 0x2F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_SS, AM_NOT_USED, "comiss", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "comisd" } },
-  /* 0x30 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wrmsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x31 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdtsc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x32 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdmsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x33 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdpmc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x34 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sysenter", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x35 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sysexit", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x36 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x37 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x38 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x39 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "movnti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x40 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x41 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x42 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x43 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x44 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x45 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x46 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x47 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmova", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x48 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x49 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4A */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4D */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4E */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4F */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x50 */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PS, AM_NOT_USED, "movmskps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PD, AM_NOT_USED, "movmskpd" } },
-  /* 0x51 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "sqrtps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "sqrtsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "sqrtss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "sqrtpd" } },
-  /* 0x52 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "rsqrtps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "rsqrtss" },
-    /* 66h */ { 0 } },
-  /* 0x53 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "rcpps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "rcpss" },
-    /* 66h */ { 0 } },
-  /* 0x54 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "andps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "andpd" } },
-  /* 0x55 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "andnps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "andnpd" } },
-  /* 0x56 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "orps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "orpd" } },
-  /* 0x57 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "xorps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "xorpd" } },
-  /* 0x58 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "addps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "addsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "addss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "addpd" } },
-  /* 0x59 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "mulps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "mulsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "mulss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "mulpd" } },
-  /* 0x5A */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PS, AM_NOT_USED, "cvtps2pd", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "cvtsd2ss" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "cvtss2sd" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PD, AM_NOT_USED, "cvtpd2ps" } },
-  /* 0x5B */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_DQ, AM_NOT_USED, "cvtdq2ps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, "cvttps2dq" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, "cvtps2dq" } },
-  /* 0x5C */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "subps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "subsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "subss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "subpd" } },
-  /* 0x5D */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "minps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "minsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "minss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "minpd" } },
-  /* 0x5E */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "divps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "divsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "divss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "divpd" } },
-  /* 0x5F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "maxps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "maxsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "maxss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "maxpd" } },
-  /* 0x60 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpcklbw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklbw" } },
-  /* 0x61 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpcklwd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklwd" } },
-  /* 0x62 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckldq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpckldq" } },
-  /* 0x63 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packsswb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "packsswb" } },
-  /* 0x64 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtb" } },
-  /* 0x65 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtw" } },
-  /* 0x66 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtd" } },
-  /* 0x67 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packuswb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "packuswb" } },
-  /* 0x68 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhbw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhbw" } },
-  /* 0x69 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhwd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhwd" } },
-  /* 0x6A */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhdq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhdq" } },
-  /* 0x6B */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packssdw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "packssdw" } },
-  /* 0x6C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklqdq" } },
-  /* 0x6D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklqdq" } },
-  /* 0x6E */ { 0, IT_GENERIC, AM_P | OT_D, AM_E | OT_D, AM_NOT_USED, "movd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_NOT_USED, "movd" } },
-  /* 0x6F */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "movq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "movdqu" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "movdqa" } },
-  /* 0x70 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_I |  OT_B, "pshuf", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshuflw" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshufhw" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshufd" } },
-  /* 0x71 */ { 19, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x72 */ { 20, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x73 */ { 21, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x74 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqb" } },
-  /* 0x75 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqw" } },
-  /* 0x76 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqd" } },
-  /* 0x77 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "emms", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  
-  // The following six opcodes are escapes into the MMX stuff, which this disassembler does not support.
-  /* 0x78 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x79 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7A */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7B */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7C */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7D */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  
-  /* 0x7E */ { 0, IT_GENERIC, AM_E | OT_D, AM_P | OT_D, AM_NOT_USED, "movd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movq" },
-    /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_DQ, AM_NOT_USED, "movd" } },
-  /* 0x7F */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_P | OT_Q, AM_NOT_USED, "movq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movdqu" },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movdqa" } },
-  /* 0x80 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x81 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x82 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x83 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x84 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x85 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x86 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x87 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "ja", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x88 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "js", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x89 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8A */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8B */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8C */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8D */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8E */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8F */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x90 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "seto", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x91 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x92 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x93 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x94 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x95 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x96 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x97 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "seta", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x98 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "sets", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x99 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9A */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9B */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9C */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9D */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9E */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9F */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cpuid", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "bt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, "shld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, "shld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA6 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA7 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rsm", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "bts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAC */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, "shrd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAD */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, "shrd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAE */ { 22, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "cmpxchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "cmpxchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB2 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lss", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "btr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB4 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lfs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB5 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lgs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB6 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, "movzx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB7 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "movzx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ud1", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBA */ { 23, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "btc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBC */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "bsf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBD */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "bsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBE */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, "movsx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "movsx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xadd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "xadd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC2 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, "cmpps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_I | OT_B, "cmpsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W  | OT_SS, AM_I | OT_B, "cmpss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, "cmppd" } },
-  /* 0xC3 */ { 0, IT_GENERIC, AM_E | OT_D, AM_G | OT_D, AM_NOT_USED, "movnti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_E | OT_D, AM_I | OT_B, "pinsrw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_I | OT_B, "pinsrw" } },
-  /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_I | OT_B, "pextrw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_I | OT_B, "pextrw" } },
-  /* 0xC6 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, "shufps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, "shufpd" } },
-  /* 0xC7 */ { 24, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC8 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC9 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCA */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCB */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCC */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCD */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCE */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCF */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrlw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrlw" } },
-  /* 0xD2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrld", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrld" } },
-  /* 0xD3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrlq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrlq" } },
-  /* 0xD4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddq" } },
-  /* 0xD5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmullw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmullw" } },
-  /* 0xD6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "unused without prefix", true,
-    /* F2h */ { 0, IT_GENERIC, AM_P | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movdq2q" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_Q | OT_Q, AM_NOT_USED, "movq2dq" },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movq" } },
-  /* 0xD7 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_NOT_USED, "pmovmskb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_NOT_USED, "pmovmskb" } },
-  /* 0xD8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubusb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubusb" } },
-  /* 0xD9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubusw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubusw" } },
-  /* 0xDA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pminub", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pminub" } },
-  /* 0xDB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pand", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pand" } },
-  /* 0xDC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddusb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddusb" } },
-  /* 0xDD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddusw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddusw" } },
-  /* 0xDE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaxub", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaxub" } },
-  /* 0xDF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pandn", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pandn" } },
-  /* 0xE0 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pavgb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pavgb" } },
-  /* 0xE1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psraw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrqw" } },
-  /* 0xE2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrad", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrad" } },
-  /* 0xE3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pavgw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pavgw" } },
-  /* 0xE4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmulhuw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmulhuw" } },
-  /* 0xE5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmulhuw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmulhw" } },
-  /* 0xE6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvtpd2dq" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_DQ, AM_NOT_USED, "cvtdq2pd" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvttpd2dq" } },
-  /* 0xE7 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movntq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movntdq" } },
-  /* 0xE8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubsb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubsb" } },
-  /* 0xE9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubsw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubsw" } },
-  /* 0xEA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pminsw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pminsw" } },
-  /* 0xEB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "por", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "por" } },
-  /* 0xEC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddsb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddsb" } },
-  /* 0xED */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddsw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddsw" } },
-  /* 0xEE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaxsw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaxsw" } },
-  /* 0xEF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pxor", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pxor" } },
-  /* 0xF0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psllw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psllw" } },
-  /* 0xF2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pslld", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pslld" } },
-  /* 0xF3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psllq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psllq" } },
-  /* 0xF4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmuludq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmuludq" } },
-  /* 0xF5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaddwd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaddwd" } },
-  /* 0xF6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psadbw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psadbw" } },
-  /* 0xF7 */ { 0, IT_GENERIC, AM_P | OT_PI, AM_Q | OT_PI, AM_NOT_USED, "maskmovq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "maskmovdqu" } },
-  /* 0xF8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubb" } },
-  /* 0xF9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubw" } },
-  /* 0xFA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubd" } },
-  /* 0xFB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubq" } },
-  /* 0xFC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddb" } },
-  /* 0xFD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddw" } },
-  /* 0xFE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddd" } },
-  /* 0xFF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f00[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "sldt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "str", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "lldt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "ltr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "verr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "verw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f01[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "sgdt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "sidt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "lgdt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "lidt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "smsw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "lmsw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_M | OT_B, AM_NOT_USED, AM_NOT_USED, "invlpg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f18[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f71[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrlw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrlw" } },
-  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psraw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psraw" } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psllw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psllw" } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f72[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrld", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrld" } },
-  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrad", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrad" } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "pslld", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslld" } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f73[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrlq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrlq" } },
-  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psllq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psllq" } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslldq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslldq" } },
-};
-
-const Opcode s_opcode_byte_after_0fae[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "fxsave", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "fxrstor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ldmxcsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "stmxcsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "mfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clflush/sfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-};
-
-const Opcode s_opcode_byte_after_0fba[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "bt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "bts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "btr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "btc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0fc7[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_Q, AM_NOT_USED, AM_NOT_USED, "cmpxch8b", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_80[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_81[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_82[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_83[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_c0[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_c1[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d0[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d1[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d2[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d3[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_f6[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "not", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "neg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, "mul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, "div", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, "idiv", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_f7[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "not", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "neg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "mul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "div", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "idiv", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_fe[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_ff[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-/*
-* A table of all the other tables, containing some extra information, e.g.
-* how to mask out the byte we're looking at.
-*/
-const OpcodeTable MiniDisassembler::s_ia32_opcode_map_[]={
-  // One-byte opcodes and jumps to larger
-  /*  0 */ {s_first_opcode_byte, 0, 0xff, 0, 0xff},
-  // Two-byte opcodes (second byte)
-  /*  1 */ {s_opcode_byte_after_0f, 0, 0xff, 0, 0xff},
-  // Start of tables for opcodes using ModR/M bits as extension
-  /*  2 */ {s_opcode_byte_after_80, 3, 0x07, 0, 0x07},
-  /*  3 */ {s_opcode_byte_after_81, 3, 0x07, 0, 0x07}, 
-  /*  4 */ {s_opcode_byte_after_82, 3, 0x07, 0, 0x07}, 
-  /*  5 */ {s_opcode_byte_after_83, 3, 0x07, 0, 0x07}, 
-  /*  6 */ {s_opcode_byte_after_c0, 3, 0x07, 0, 0x07}, 
-  /*  7 */ {s_opcode_byte_after_c1, 3, 0x07, 0, 0x07}, 
-  /*  8 */ {s_opcode_byte_after_d0, 3, 0x07, 0, 0x07}, 
-  /*  9 */ {s_opcode_byte_after_d1, 3, 0x07, 0, 0x07}, 
-  /* 10 */ {s_opcode_byte_after_d2, 3, 0x07, 0, 0x07}, 
-  /* 11 */ {s_opcode_byte_after_d3, 3, 0x07, 0, 0x07}, 
-  /* 12 */ {s_opcode_byte_after_f6, 3, 0x07, 0, 0x07}, 
-  /* 13 */ {s_opcode_byte_after_f7, 3, 0x07, 0, 0x07}, 
-  /* 14 */ {s_opcode_byte_after_fe, 3, 0x07, 0, 0x01}, 
-  /* 15 */ {s_opcode_byte_after_ff, 3, 0x07, 0, 0x07}, 
-  /* 16 */ {s_opcode_byte_after_0f00, 3, 0x07, 0, 0x07}, 
-  /* 17 */ {s_opcode_byte_after_0f01, 3, 0x07, 0, 0x07}, 
-  /* 18 */ {s_opcode_byte_after_0f18, 3, 0x07, 0, 0x07}, 
-  /* 19 */ {s_opcode_byte_after_0f71, 3, 0x07, 0, 0x07}, 
-  /* 20 */ {s_opcode_byte_after_0f72, 3, 0x07, 0, 0x07}, 
-  /* 21 */ {s_opcode_byte_after_0f73, 3, 0x07, 0, 0x07}, 
-  /* 22 */ {s_opcode_byte_after_0fae, 3, 0x07, 0, 0x07}, 
-  /* 23 */ {s_opcode_byte_after_0fba, 3, 0x07, 0, 0x07}, 
-  /* 24 */ {s_opcode_byte_after_0fc7, 3, 0x07, 0, 0x01}
-};
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/chromium/src/windows/mingw.h b/third_party/tcmalloc/chromium/src/windows/mingw.h
deleted file mode 100644
index c91a313..0000000
--- a/third_party/tcmalloc/chromium/src/windows/mingw.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Craig Silverstein
- *
- * MinGW is an interesting mix of unix and windows.  We use a normal
- * configure script, but still need the windows port.h to define some
- * stuff that MinGW doesn't support, like pthreads.
- */
-
-#ifndef GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_
-#define GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_
-
-#ifdef __MINGW32__
-
-// Older version of the mingw msvcrt don't define _aligned_malloc
-#if __MSVCRT_VERSION__ < 0x0700
-# define PERFTOOLS_NO_ALIGNED_MALLOC 1
-#endif
-
-// This must be defined before the windows.h is included.  We need at
-// least 0x0400 for mutex.h to have access to TryLock, and at least
-// 0x0501 for patch_functions.cc to have access to GetModuleHandleEx.
-// (This latter is an optimization we could take out if need be.)
-#ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-#endif
-
-#define HAVE_SNPRINTF 1
-
-// Some mingw distributions have a pthreads wrapper, but it doesn't
-// work as well as native windows spinlocks (at least for us).  So
-// pretend the pthreads wrapper doesn't exist, even when it does.
-#ifndef HAVE_PTHREAD_DESPITE_ASKING_FOR
-#undef HAVE_PTHREAD
-#endif
-
-#undef HAVE_FORK
-
-#define HAVE_PID_T
-
-#include "windows/port.h"
-
-#endif  /* __MINGW32__ */
-
-#endif  /* GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_ */
diff --git a/third_party/tcmalloc/chromium/src/windows/mini_disassembler.cc b/third_party/tcmalloc/chromium/src/windows/mini_disassembler.cc
deleted file mode 100644
index 0c620047..0000000
--- a/third_party/tcmalloc/chromium/src/windows/mini_disassembler.cc
+++ /dev/null
@@ -1,432 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Implementation of MiniDisassembler.
- */
-
-#include "mini_disassembler.h"
-
-namespace sidestep {
-
-MiniDisassembler::MiniDisassembler(bool operand_default_is_32_bits,
-                                   bool address_default_is_32_bits)
-    : operand_default_is_32_bits_(operand_default_is_32_bits),
-      address_default_is_32_bits_(address_default_is_32_bits) {
-  Initialize();
-}
-
-MiniDisassembler::MiniDisassembler()
-    : operand_default_is_32_bits_(true),
-      address_default_is_32_bits_(true) {
-  Initialize();
-}
-
-InstructionType MiniDisassembler::Disassemble(
-    unsigned char* start_byte,
-    unsigned int& instruction_bytes) {
-  // Clean up any state from previous invocations.
-  Initialize();
-
-  // Start by processing any prefixes.
-  unsigned char* current_byte = start_byte;
-  unsigned int size = 0;
-  InstructionType instruction_type = ProcessPrefixes(current_byte, size);
-
-  if (IT_UNKNOWN == instruction_type)
-    return instruction_type;
-
-  current_byte += size;
-  size = 0;
-
-  // Invariant: We have stripped all prefixes, and the operand_is_32_bits_
-  // and address_is_32_bits_ flags are correctly set.
-
-  instruction_type = ProcessOpcode(current_byte, 0, size);
-
-  // Check for error processing instruction
-  if ((IT_UNKNOWN == instruction_type_) || (IT_UNUSED == instruction_type_)) {
-    return IT_UNKNOWN;
-  }
-
-  current_byte += size;
-
-  // Invariant: operand_bytes_ indicates the total size of operands
-  // specified by the opcode and/or ModR/M byte and/or SIB byte.
-  // pCurrentByte points to the first byte after the ModR/M byte, or after
-  // the SIB byte if it is present (i.e. the first byte of any operands
-  // encoded in the instruction).
-
-  // We get the total length of any prefixes, the opcode, and the ModR/M and
-  // SIB bytes if present, by taking the difference of the original starting
-  // address and the current byte (which points to the first byte of the
-  // operands if present, or to the first byte of the next instruction if
-  // they are not).  Adding the count of bytes in the operands encoded in
-  // the instruction gives us the full length of the instruction in bytes.
-  instruction_bytes += operand_bytes_ + (current_byte - start_byte);
-
-  // Return the instruction type, which was set by ProcessOpcode().
-  return instruction_type_;
-}
-
-void MiniDisassembler::Initialize() {
-  operand_is_32_bits_ = operand_default_is_32_bits_;
-  address_is_32_bits_ = address_default_is_32_bits_;
-#ifdef _M_X64
-  operand_default_support_64_bits_ = true;
-#else
-  operand_default_support_64_bits_ = false;
-#endif
-  operand_is_64_bits_ = false;
-  operand_bytes_ = 0;
-  have_modrm_ = false;
-  should_decode_modrm_ = false;
-  instruction_type_ = IT_UNKNOWN;
-  got_f2_prefix_ = false;
-  got_f3_prefix_ = false;
-  got_66_prefix_ = false;
-}
-
-InstructionType MiniDisassembler::ProcessPrefixes(unsigned char* start_byte,
-                                                  unsigned int& size) {
-  InstructionType instruction_type = IT_GENERIC;
-  const Opcode& opcode = s_ia32_opcode_map_[0].table_[*start_byte];
-
-  switch (opcode.type_) {
-    case IT_PREFIX_ADDRESS:
-      address_is_32_bits_ = !address_default_is_32_bits_;
-      goto nochangeoperand;
-    case IT_PREFIX_OPERAND:
-      operand_is_32_bits_ = !operand_default_is_32_bits_;
-      nochangeoperand:
-    case IT_PREFIX:
-
-      if (0xF2 == (*start_byte))
-        got_f2_prefix_ = true;
-      else if (0xF3 == (*start_byte))
-        got_f3_prefix_ = true;
-      else if (0x66 == (*start_byte))
-        got_66_prefix_ = true;
-      else if (operand_default_support_64_bits_ && (*start_byte) & 0x48)
-        operand_is_64_bits_ = true;
-
-      instruction_type = opcode.type_;
-      size ++;
-      // we got a prefix, so add one and check next byte
-      ProcessPrefixes(start_byte + 1, size);
-    default:
-      break;   // not a prefix byte
-  }
-
-  return instruction_type;
-}
-
-InstructionType MiniDisassembler::ProcessOpcode(unsigned char* start_byte,
-                                                unsigned int table_index,
-                                                unsigned int& size) {
-  const OpcodeTable& table = s_ia32_opcode_map_[table_index];   // Get our table
-  unsigned char current_byte = (*start_byte) >> table.shift_;
-  current_byte = current_byte & table.mask_;  // Mask out the bits we will use
-
-  // Check whether the byte we have is inside the table we have.
-  if (current_byte < table.min_lim_ || current_byte > table.max_lim_) {
-    instruction_type_ = IT_UNKNOWN;
-    return instruction_type_;
-  }
-
-  const Opcode& opcode = table.table_[current_byte];
-  if (IT_UNUSED == opcode.type_) {
-    // This instruction is not used by the IA-32 ISA, so we indicate
-    // this to the user.  Probably means that we were pointed to
-    // a byte in memory that was not the start of an instruction.
-    instruction_type_ = IT_UNUSED;
-    return instruction_type_;
-  } else if (IT_REFERENCE == opcode.type_) {
-    // We are looking at an opcode that has more bytes (or is continued
-    // in the ModR/M byte).  Recursively find the opcode definition in
-    // the table for the opcode's next byte.
-    size++;
-    ProcessOpcode(start_byte + 1, opcode.table_index_, size);
-    return instruction_type_;
-  }
-
-  const SpecificOpcode* specific_opcode = (SpecificOpcode*)&opcode;
-  if (opcode.is_prefix_dependent_) {
-    if (got_f2_prefix_ && opcode.opcode_if_f2_prefix_.mnemonic_ != 0) {
-      specific_opcode = &opcode.opcode_if_f2_prefix_;
-    } else if (got_f3_prefix_ && opcode.opcode_if_f3_prefix_.mnemonic_ != 0) {
-      specific_opcode = &opcode.opcode_if_f3_prefix_;
-    } else if (got_66_prefix_ && opcode.opcode_if_66_prefix_.mnemonic_ != 0) {
-      specific_opcode = &opcode.opcode_if_66_prefix_;
-    }
-  }
-
-  // Inv: The opcode type is known.
-  instruction_type_ = specific_opcode->type_;
-
-  // Let's process the operand types to see if we have any immediate
-  // operands, and/or a ModR/M byte.
-
-  ProcessOperand(specific_opcode->flag_dest_);
-  ProcessOperand(specific_opcode->flag_source_);
-  ProcessOperand(specific_opcode->flag_aux_);
-
-  // Inv: We have processed the opcode and incremented operand_bytes_
-  // by the number of bytes of any operands specified by the opcode
-  // that are stored in the instruction (not registers etc.).  Now
-  // we need to return the total number of bytes for the opcode and
-  // for the ModR/M or SIB bytes if they are present.
-
-  if (table.mask_ != 0xff) {
-    if (have_modrm_) {
-      // we're looking at a ModR/M byte so we're not going to
-      // count that into the opcode size
-      ProcessModrm(start_byte, size);
-      return IT_GENERIC;
-    } else {
-      // need to count the ModR/M byte even if it's just being
-      // used for opcode extension
-      size++;
-      return IT_GENERIC;
-    }
-  } else {
-    if (have_modrm_) {
-      // The ModR/M byte is the next byte.
-      size++;
-      ProcessModrm(start_byte + 1, size);
-      return IT_GENERIC;
-    } else {
-      size++;
-      return IT_GENERIC;
-    }
-  }
-}
-
-bool MiniDisassembler::ProcessOperand(int flag_operand) {
-  bool succeeded = true;
-  if (AM_NOT_USED == flag_operand)
-    return succeeded;
-
-  // Decide what to do based on the addressing mode.
-  switch (flag_operand & AM_MASK) {
-    // No ModR/M byte indicated by these addressing modes, and no
-    // additional (e.g. immediate) parameters.
-    case AM_A: // Direct address
-    case AM_F: // EFLAGS register
-    case AM_X: // Memory addressed by the DS:SI register pair
-    case AM_Y: // Memory addressed by the ES:DI register pair
-    case AM_IMPLICIT: // Parameter is implicit, occupies no space in
-                       // instruction
-      break;
-
-    // There is a ModR/M byte but it does not necessarily need
-    // to be decoded.
-    case AM_C: // reg field of ModR/M selects a control register
-    case AM_D: // reg field of ModR/M selects a debug register
-    case AM_G: // reg field of ModR/M selects a general register
-    case AM_P: // reg field of ModR/M selects an MMX register
-    case AM_R: // mod field of ModR/M may refer only to a general register
-    case AM_S: // reg field of ModR/M selects a segment register
-    case AM_T: // reg field of ModR/M selects a test register
-    case AM_V: // reg field of ModR/M selects a 128-bit XMM register
-      have_modrm_ = true;
-      break;
-
-    // In these addressing modes, there is a ModR/M byte and it needs to be
-    // decoded. No other (e.g. immediate) params than indicated in ModR/M.
-    case AM_E: // Operand is either a general-purpose register or memory,
-                 // specified by ModR/M byte
-    case AM_M: // ModR/M byte will refer only to memory
-    case AM_Q: // Operand is either an MMX register or memory (complex
-                 // evaluation), specified by ModR/M byte
-    case AM_W: // Operand is either a 128-bit XMM register or memory (complex
-                 // eval), specified by ModR/M byte
-      have_modrm_ = true;
-      should_decode_modrm_ = true;
-      break;
-
-    // These addressing modes specify an immediate or an offset value
-    // directly, so we need to look at the operand type to see how many
-    // bytes.
-    case AM_I: // Immediate data.
-    case AM_J: // Jump to offset.
-    case AM_O: // Operand is at offset.
-      switch (flag_operand & OT_MASK) {
-        case OT_B: // Byte regardless of operand-size attribute.
-          operand_bytes_ += OS_BYTE;
-          break;
-        case OT_C: // Byte or word, depending on operand-size attribute.
-          if (operand_is_32_bits_)
-            operand_bytes_ += OS_WORD;
-          else
-            operand_bytes_ += OS_BYTE;
-          break;
-        case OT_D: // Doubleword, regardless of operand-size attribute.
-          operand_bytes_ += OS_DOUBLE_WORD;
-          break;
-        case OT_DQ: // Double-quadword, regardless of operand-size attribute.
-          operand_bytes_ += OS_DOUBLE_QUAD_WORD;
-          break;
-        case OT_P: // 32-bit or 48-bit pointer, depending on operand-size
-                     // attribute.
-          if (operand_is_32_bits_)
-            operand_bytes_ += OS_48_BIT_POINTER;
-          else
-            operand_bytes_ += OS_32_BIT_POINTER;
-          break;
-        case OT_PS: // 128-bit packed single-precision floating-point data.
-          operand_bytes_ += OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING;
-          break;
-        case OT_Q: // Quadword, regardless of operand-size attribute.
-          operand_bytes_ += OS_QUAD_WORD;
-          break;
-        case OT_S: // 6-byte pseudo-descriptor.
-          operand_bytes_ += OS_PSEUDO_DESCRIPTOR;
-          break;
-        case OT_SD: // Scalar Double-Precision Floating-Point Value
-        case OT_PD: // Unaligned packed double-precision floating point value
-          operand_bytes_ += OS_DOUBLE_PRECISION_FLOATING;
-          break;
-        case OT_SS:
-          // Scalar element of a 128-bit packed single-precision
-          // floating data.
-          // We simply return enItUnknown since we don't have to support
-          // floating point
-          succeeded = false;
-          break;
-        case OT_V: // Word, doubleword or quadword, depending on operand-size 
-                   // attribute.
-          if (operand_is_64_bits_ && flag_operand & AM_I &&
-              flag_operand & IOS_64)
-            operand_bytes_ += OS_QUAD_WORD;
-          else if (operand_is_32_bits_)
-            operand_bytes_ += OS_DOUBLE_WORD;
-          else
-            operand_bytes_ += OS_WORD;
-          break;
-        case OT_W: // Word, regardless of operand-size attribute.
-          operand_bytes_ += OS_WORD;
-          break;
-
-        // Can safely ignore these.
-        case OT_A: // Two one-word operands in memory or two double-word
-                     // operands in memory
-        case OT_PI: // Quadword MMX technology register (e.g. mm0)
-        case OT_SI: // Doubleword integer register (e.g., eax)
-          break;
-
-        default:
-          break;
-      }
-      break;
-
-    default:
-      break;
-  }
-
-  return succeeded;
-}
-
-bool MiniDisassembler::ProcessModrm(unsigned char* start_byte,
-                                    unsigned int& size) {
-  // If we don't need to decode, we just return the size of the ModR/M
-  // byte (there is never a SIB byte in this case).
-  if (!should_decode_modrm_) {
-    size++;
-    return true;
-  }
-
-  // We never care about the reg field, only the combination of the mod
-  // and r/m fields, so let's start by packing those fields together into
-  // 5 bits.
-  unsigned char modrm = (*start_byte);
-  unsigned char mod = modrm & 0xC0; // mask out top two bits to get mod field
-  modrm = modrm & 0x07; // mask out bottom 3 bits to get r/m field
-  mod = mod >> 3; // shift the mod field to the right place
-  modrm = mod | modrm; // combine the r/m and mod fields as discussed
-  mod = mod >> 3; // shift the mod field to bits 2..0
-
-  // Invariant: modrm contains the mod field in bits 4..3 and the r/m field
-  // in bits 2..0, and mod contains the mod field in bits 2..0
-
-  const ModrmEntry* modrm_entry = 0;
-  if (address_is_32_bits_)
-    modrm_entry = &s_ia32_modrm_map_[modrm];
-  else
-    modrm_entry = &s_ia16_modrm_map_[modrm];
-
-  // Invariant: modrm_entry points to information that we need to decode
-  // the ModR/M byte.
-
-  // Add to the count of operand bytes, if the ModR/M byte indicates
-  // that some operands are encoded in the instruction.
-  if (modrm_entry->is_encoded_in_instruction_)
-    operand_bytes_ += modrm_entry->operand_size_;
-
-  // Process the SIB byte if necessary, and return the count
-  // of ModR/M and SIB bytes.
-  if (modrm_entry->use_sib_byte_) {
-    size++;
-    return ProcessSib(start_byte + 1, mod, size);
-  } else {
-    size++;
-    return true;
-  }
-}
-
-bool MiniDisassembler::ProcessSib(unsigned char* start_byte,
-                                  unsigned char mod,
-                                  unsigned int& size) {
-  // get the mod field from the 2..0 bits of the SIB byte
-  unsigned char sib_base = (*start_byte) & 0x07;
-  if (0x05 == sib_base) {
-    switch (mod) {
-    case 0x00: // mod == 00
-    case 0x02: // mod == 10
-      operand_bytes_ += OS_DOUBLE_WORD;
-      break;
-    case 0x01: // mod == 01
-      operand_bytes_ += OS_BYTE;
-      break;
-    case 0x03: // mod == 11
-      // According to the IA-32 docs, there does not seem to be a disp
-      // value for this value of mod
-    default:
-      break;
-    }
-  }
-
-  size++;
-  return true;
-}
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/chromium/src/windows/mini_disassembler.h b/third_party/tcmalloc/chromium/src/windows/mini_disassembler.h
deleted file mode 100644
index 93a522e5..0000000
--- a/third_party/tcmalloc/chromium/src/windows/mini_disassembler.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Definition of MiniDisassembler.
- */
-
-#ifndef GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_H_
-#define GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_H_
-
-#include "config.h"
-#include <windows.h>
-#include "mini_disassembler_types.h"
-
-// compatibility shim
-#include "base/logging.h"
-#define SIDESTEP_ASSERT(cond)  RAW_DCHECK(cond, #cond)
-#define SIDESTEP_LOG(msg)      RAW_VLOG(1, msg)
-
-namespace sidestep {
-
-// This small disassembler is very limited
-// in its functionality, and in fact does only the bare minimum required by the
-// preamble patching utility.  It may be useful for other purposes, however.
-//
-// The limitations include at least the following:
-//  -# No support for coprocessor opcodes, MMX, etc.
-//  -# No machine-readable identification of opcodes or decoding of
-//     assembly parameters. The name of the opcode (as a string) is given,
-//     however, to aid debugging.
-//
-// You may ask what this little disassembler actually does, then?  The answer is
-// that it does the following, which is exactly what the patching utility needs:
-//  -# Indicates if opcode is a jump (any kind) or a return (any kind)
-//     because this is important for the patching utility to determine if
-//     a function is too short or there are jumps too early in it for it
-//     to be preamble patched.
-//  -# The opcode length is always calculated, so that the patching utility
-//     can figure out where the next instruction starts, and whether it
-//     already has enough instructions to replace with the absolute jump
-//     to the patching code.
-//
-// The usage is quite simple; just create a MiniDisassembler and use its
-// Disassemble() method.
-//
-// If you would like to extend this disassembler, please refer to the
-// IA-32 Intel® Architecture Software Developer's Manual Volume 2:
-// Instruction Set Reference for information about operand decoding
-// etc.
-class PERFTOOLS_DLL_DECL MiniDisassembler {
- public:
-
-  // Creates a new instance and sets defaults.
-  //
-  // @param operand_default_32_bits If true, the default operand size is
-  // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.
-  // @param address_default_32_bits If true, the default address size is
-  // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.
-  MiniDisassembler(bool operand_default_32_bits,
-                   bool address_default_32_bits);
-
-  // Equivalent to MiniDisassembler(true, true);
-  MiniDisassembler();
-
-  // Attempts to disassemble a single instruction starting from the
-  // address in memory it is pointed to.
-  //
-  // @param start Address where disassembly should start.
-  // @param instruction_bytes Variable that will be <b>incremented</b> by
-  // the length in bytes of the instruction.
-  // @return enItJump, enItReturn or enItGeneric on success.  enItUnknown
-  // if unable to disassemble, enItUnused if this seems to be an unused
-  // opcode. In the last two (error) cases, cbInstruction will be set
-  // to 0xffffffff.
-  //
-  // @post This instance of the disassembler is ready to be used again,
-  // with unchanged defaults from creation time.
-  InstructionType Disassemble(unsigned char* start, unsigned int& instruction_bytes);
-
- private:
-
-  // Makes the disassembler ready for reuse.
-  void Initialize();
-
-  // Sets the flags for address and operand sizes.
-  // @return Number of prefix bytes.
-  InstructionType ProcessPrefixes(unsigned char* start, unsigned int& size);
-
-  // Sets the flag for whether we have ModR/M, and increments
-  // operand_bytes_ if any are specifies by the opcode directly.
-  // @return Number of opcode bytes.
-  InstructionType ProcessOpcode(unsigned char* start,
-                                unsigned int table,
-                                unsigned int& size);
-
-  // Checks the type of the supplied operand.  Increments
-  // operand_bytes_ if it directly indicates an immediate etc.
-  // operand.  Asserts have_modrm_ if the operand specifies
-  // a ModR/M byte.
-  bool ProcessOperand(int flag_operand);
-
-  // Increments operand_bytes_ by size specified by ModR/M and
-  // by SIB if present.
-  // @return 0 in case of error, 1 if there is just a ModR/M byte,
-  // 2 if there is a ModR/M byte and a SIB byte.
-  bool ProcessModrm(unsigned char* start, unsigned int& size);
-
-  // Processes the SIB byte that it is pointed to.
-  // @param start Pointer to the SIB byte.
-  // @param mod The mod field from the ModR/M byte.
-  // @return 1 to indicate success (indicates 1 SIB byte)
-  bool ProcessSib(unsigned char* start, unsigned char mod, unsigned int& size);
-
-  // The instruction type we have decoded from the opcode.
-  InstructionType instruction_type_;
-
-  // Counts the number of bytes that is occupied by operands in
-  // the current instruction (note: we don't care about how large
-  // operands stored in registers etc. are).
-  unsigned int operand_bytes_;
-
-  // True iff there is a ModR/M byte in this instruction.
-  bool have_modrm_;
-
-  // True iff we need to decode the ModR/M byte (sometimes it just
-  // points to a register, we can tell by the addressing mode).
-  bool should_decode_modrm_;
-
-  // Current operand size is 32 bits if true, 16 bits if false.
-  bool operand_is_32_bits_;
-
-  // Default operand size is 32 bits if true, 16 bits if false.
-  bool operand_default_is_32_bits_;
-
-  // Current address size is 32 bits if true, 16 bits if false.
-  bool address_is_32_bits_;
-
-  // Default address size is 32 bits if true, 16 bits if false.
-  bool address_default_is_32_bits_;
-
-  // Determines if 64 bit operands are supported (x64).
-  bool operand_default_support_64_bits_;
-
-  // Current operand size is 64 bits if true, 32 bits if false.
-  bool operand_is_64_bits_;
-
-  // Huge big opcode table based on the IA-32 manual, defined
-  // in Ia32OpcodeMap.cc
-  static const OpcodeTable s_ia32_opcode_map_[];
-
-  // Somewhat smaller table to help with decoding ModR/M bytes
-  // when 16-bit addressing mode is being used.  Defined in
-  // Ia32ModrmMap.cc
-  static const ModrmEntry s_ia16_modrm_map_[];
-
-  // Somewhat smaller table to help with decoding ModR/M bytes
-  // when 32-bit addressing mode is being used.  Defined in
-  // Ia32ModrmMap.cc
-  static const ModrmEntry s_ia32_modrm_map_[];
-
-  // Indicators of whether we got certain prefixes that certain
-  // silly Intel instructions depend on in nonstandard ways for
-  // their behaviors.
-  bool got_f2_prefix_, got_f3_prefix_, got_66_prefix_;
-};
-
-};  // namespace sidestep
-
-#endif  // GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_H_
diff --git a/third_party/tcmalloc/chromium/src/windows/mini_disassembler_types.h b/third_party/tcmalloc/chromium/src/windows/mini_disassembler_types.h
deleted file mode 100644
index aceecf4..0000000
--- a/third_party/tcmalloc/chromium/src/windows/mini_disassembler_types.h
+++ /dev/null
@@ -1,237 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Several simple types used by the disassembler and some of the patching
- * mechanisms.
- */
-
-#ifndef GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
-#define GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
-
-namespace sidestep {
-
-// Categories of instructions that we care about
-enum InstructionType {
-  // This opcode is not used
-  IT_UNUSED,
-  // This disassembler does not recognize this opcode (error)
-  IT_UNKNOWN,
-  // This is not an instruction but a reference to another table
-  IT_REFERENCE,
-  // This byte is a prefix byte that we can ignore
-  IT_PREFIX,
-  // This is a prefix byte that switches to the nondefault address size
-  IT_PREFIX_ADDRESS,
-  // This is a prefix byte that switches to the nondefault operand size
-  IT_PREFIX_OPERAND,
-  // A jump or call instruction
-  IT_JUMP,
-  // A return instruction
-  IT_RETURN,
-  // Any other type of instruction (in this case we don't care what it is)
-  IT_GENERIC,
-};
-
-// Lists IA-32 operand sizes in multiples of 8 bits
-enum OperandSize {
-  OS_ZERO = 0,
-  OS_BYTE = 1,
-  OS_WORD = 2,
-  OS_DOUBLE_WORD = 4,
-  OS_QUAD_WORD = 8,
-  OS_DOUBLE_QUAD_WORD = 16,
-  OS_32_BIT_POINTER = 32/8,
-  OS_48_BIT_POINTER = 48/8,
-  OS_SINGLE_PRECISION_FLOATING = 32/8,
-  OS_DOUBLE_PRECISION_FLOATING = 64/8,
-  OS_DOUBLE_EXTENDED_PRECISION_FLOATING = 80/8,
-  OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING = 128/8,
-  OS_PSEUDO_DESCRIPTOR = 6
-};
-
-// Operand addressing methods from the IA-32 manual.  The enAmMask value
-// is a mask for the rest.  The other enumeration values are named for the
-// names given to the addressing methods in the manual, e.g. enAm_D is for
-// the D addressing method.
-//
-// The reason we use a full 4 bytes and a mask, is that we need to combine
-// these flags with the enOperandType to store the details
-// on the operand in a single integer.
-enum AddressingMethod {
-  AM_NOT_USED = 0,        // This operand is not used for this instruction
-  AM_MASK = 0x00FF0000,  // Mask for the rest of the values in this enumeration
-  AM_A = 0x00010000,    // A addressing type
-  AM_C = 0x00020000,    // C addressing type
-  AM_D = 0x00030000,    // D addressing type
-  AM_E = 0x00040000,    // E addressing type
-  AM_F = 0x00050000,    // F addressing type
-  AM_G = 0x00060000,    // G addressing type
-  AM_I = 0x00070000,    // I addressing type
-  AM_J = 0x00080000,    // J addressing type
-  AM_M = 0x00090000,    // M addressing type
-  AM_O = 0x000A0000,    // O addressing type
-  AM_P = 0x000B0000,    // P addressing type
-  AM_Q = 0x000C0000,    // Q addressing type
-  AM_R = 0x000D0000,    // R addressing type
-  AM_S = 0x000E0000,    // S addressing type
-  AM_T = 0x000F0000,    // T addressing type
-  AM_V = 0x00100000,    // V addressing type
-  AM_W = 0x00110000,    // W addressing type
-  AM_X = 0x00120000,    // X addressing type
-  AM_Y = 0x00130000,    // Y addressing type
-  AM_REGISTER = 0x00140000,  // Specific register is always used as this op
-  AM_IMPLICIT = 0x00150000,  // An implicit, fixed value is used
-};
-
-// Operand types from the IA-32 manual. The enOtMask value is
-// a mask for the rest. The rest of the values are named for the
-// names given to these operand types in the manual, e.g. enOt_ps
-// is for the ps operand type in the manual.
-//
-// The reason we use a full 4 bytes and a mask, is that we need
-// to combine these flags with the enAddressingMethod to store the details
-// on the operand in a single integer.
-enum OperandType {
-  OT_MASK = 0xFF000000,
-  OT_A = 0x01000000,
-  OT_B = 0x02000000,
-  OT_C = 0x03000000,
-  OT_D = 0x04000000,
-  OT_DQ = 0x05000000,
-  OT_P = 0x06000000,
-  OT_PI = 0x07000000,
-  OT_PS = 0x08000000,  // actually unsupported for (we don't know its size)
-  OT_Q = 0x09000000,
-  OT_S = 0x0A000000,
-  OT_SS = 0x0B000000,
-  OT_SI = 0x0C000000,
-  OT_V = 0x0D000000,
-  OT_W = 0x0E000000,
-  OT_SD = 0x0F000000,  // scalar double-precision floating-point value
-  OT_PD = 0x10000000,  // double-precision floating point
-  // dummy "operand type" for address mode M - which doesn't specify
-  // operand type
-  OT_ADDRESS_MODE_M = 0x80000000
-};
-
-// Flag that indicates if an immediate operand is 64-bits.
-//
-// The Intel 64 and IA-32 Architecture Software Developer's Manual currently
-// defines MOV as the only instruction supporting a 64-bit immediate operand.
-enum ImmediateOperandSize {
-  IOS_MASK = 0x0000F000,
-  IOS_DEFAULT = 0x0,
-  IOS_64 = 0x00001000
-};
-
-// Everything that's in an Opcode (see below) except the three
-// alternative opcode structs for different prefixes.
-struct SpecificOpcode {
-  // Index to continuation table, or 0 if this is the last
-  // byte in the opcode.
-  int table_index_;
-
-  // The opcode type
-  InstructionType type_;
-
-  // Description of the type of the dest, src and aux operands,
-  // put together from enOperandType, enAddressingMethod and 
-  // enImmediateOperandSize flags.
-  int flag_dest_;
-  int flag_source_;
-  int flag_aux_;
-
-  // We indicate the mnemonic for debugging purposes
-  const char* mnemonic_;
-};
-
-// The information we keep in our tables about each of the different
-// valid instructions recognized by the IA-32 architecture.
-struct Opcode {
-  // Index to continuation table, or 0 if this is the last
-  // byte in the opcode.
-  int table_index_;
-
-  // The opcode type
-  InstructionType type_;
-
-  // Description of the type of the dest, src and aux operands,
-  // put together from an enOperandType flag and an enAddressingMethod
-  // flag.
-  unsigned flag_dest_;
-  unsigned flag_source_;
-  unsigned flag_aux_;
-
-  // We indicate the mnemonic for debugging purposes
-  const char* mnemonic_;
-
-  // Alternative opcode info if certain prefixes are specified.
-  // In most cases, all of these are zeroed-out.  Only used if
-  // bPrefixDependent is true.
-  bool is_prefix_dependent_;
-  SpecificOpcode opcode_if_f2_prefix_;
-  SpecificOpcode opcode_if_f3_prefix_;
-  SpecificOpcode opcode_if_66_prefix_;
-};
-
-// Information about each table entry.
-struct OpcodeTable {
-  // Table of instruction entries
-  const Opcode* table_;
-  // How many bytes left to shift ModR/M byte <b>before</b> applying mask
-  unsigned char shift_;
-  // Mask to apply to byte being looked at before comparing to table
-  unsigned char mask_;
-  // Minimum/maximum indexes in table.
-  unsigned char min_lim_;
-  unsigned char max_lim_;
-};
-
-// Information about each entry in table used to decode ModR/M byte.
-struct ModrmEntry {
-  // Is the operand encoded as bytes in the instruction (rather than
-  // if it's e.g. a register in which case it's just encoded in the
-  // ModR/M byte)
-  bool is_encoded_in_instruction_;
-
-  // Is there a SIB byte?  In this case we always need to decode it.
-  bool use_sib_byte_;
-
-  // What is the size of the operand (only important if it's encoded
-  // in the instruction)?
-  OperandSize operand_size_;
-};
-
-};  // namespace sidestep
-
-#endif  // GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
diff --git a/third_party/tcmalloc/chromium/src/windows/nm-pdb.c b/third_party/tcmalloc/chromium/src/windows/nm-pdb.c
deleted file mode 100644
index 95a080d..0000000
--- a/third_party/tcmalloc/chromium/src/windows/nm-pdb.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: David Vitek
- *
- * Dump function addresses using Microsoft debug symbols.  This works
- * on PDB files.  Note that this program will download symbols to
- * c:\websymbols without asking.
- */
-
-#define WIN32_LEAN_AND_MEAN
-#define _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_DEPRECATE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>   // for _strdup
-
-#include <windows.h>
-#include <dbghelp.h>
-
-// Unfortunately, there is no versioning info in dbghelp.h so I can
-// tell whether it has an old-style (circa VC7.1) IMAGEHLP_MODULE64
-// struct, with only a few fields, or a new-style (circa VC8)
-// IMAGEHLP_MODULE64, with lots of fields.  These fields are just used
-// for debugging, so it's fine to just assume the smaller struct, but
-// for most people, using a modern MSVC, the full struct is available.
-// If you are one of those people and would like this extra debugging
-// info, you can uncomment the line below.
-//#define VC8_OR_ABOVE
-
-#define SEARCH_CAP (1024*1024)
-#define WEBSYM "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols"
-
-typedef struct {
-  char *name;
-  ULONG64 addr;
-  ULONG flags;
-} SYM;
-
-typedef struct {
-  ULONG64 module_base;
-  SYM *syms;
-  DWORD syms_len;
-  DWORD syms_cap;
-} SYM_CONTEXT;
-
-static int sym_cmp(const void *_s1, const void *_s2) {
-  const SYM *s1 = (const SYM *)_s1;
-  const SYM *s2 = (const SYM *)_s2;
-
-  if (s1->addr < s2->addr)
-    return -1;
-  if (s1->addr > s2->addr)
-    return 1;
-  return 0;
-}
-
-static BOOL CALLBACK EnumSymProc(PSYMBOL_INFO symbol_info,
-                                 ULONG symbol_size,
-                                 PVOID user_context) {
-  SYM_CONTEXT *ctx = (SYM_CONTEXT*)user_context;
-  if (symbol_info->Address < ctx->module_base ||
-      (symbol_info->Flags & SYMFLAG_TLSREL)) {
-    return TRUE;
-  }
-  if (ctx->syms_len == ctx->syms_cap) {
-    if (!ctx->syms_cap)
-      ctx->syms_cap++;
-    ctx->syms_cap *= 2;
-    ctx->syms = realloc(ctx->syms, sizeof(ctx->syms[0]) * ctx->syms_cap);
-  }
-  ctx->syms[ctx->syms_len].name = _strdup(symbol_info->Name);
-  ctx->syms[ctx->syms_len].addr = symbol_info->Address;
-  ctx->syms[ctx->syms_len].flags = symbol_info->Flags;
-  ctx->syms_len++;
-  return TRUE;
-}
-
-static void MaybePrint(const char* var, const char* description) {
-  if (var[0])
-    printf("%s: %s\n", description, var);
-}
-
-static void PrintAvailability(BOOL var, const char *description) {
-  printf("%s: %s\n", description, (var ? "Available" : "Not available"));
-}
-
-static void ShowSymbolInfo(HANDLE process, ULONG64 module_base) {
-  /* Get module information. */
-  IMAGEHLP_MODULE64 module_info;
-  BOOL getmoduleinfo_rv;
-  printf("Load Address: %I64x\n", module_base);
-  memset(&module_info, 0, sizeof(module_info));
-  module_info.SizeOfStruct = sizeof(module_info);
-  getmoduleinfo_rv = SymGetModuleInfo64(process, module_base, &module_info);
-  if (!getmoduleinfo_rv)  {
-    printf("Error: SymGetModuleInfo64() failed. Error code: %u\n",
-           GetLastError());
-    return;
-  }
-  /* Display information about symbols, based on kind of symbol. */
-  switch (module_info.SymType)  {
-    case SymNone:
-      printf(("No symbols available for the module.\n"));
-      break;
-    case SymExport:
-      printf(("Loaded symbols: Exports\n"));
-      break;
-    case SymCoff:
-      printf(("Loaded symbols: COFF\n"));
-      break;
-    case SymCv:
-      printf(("Loaded symbols: CodeView\n"));
-      break;
-    case SymSym:
-      printf(("Loaded symbols: SYM\n"));
-      break;
-    case SymVirtual:
-      printf(("Loaded symbols: Virtual\n"));
-      break;
-    case SymPdb:
-      printf(("Loaded symbols: PDB\n"));
-      break;
-    case SymDia:
-      printf(("Loaded symbols: DIA\n"));
-      break;
-    case SymDeferred:
-      printf(("Loaded symbols: Deferred\n"));  /* not actually loaded */
-      break;
-    default:
-      printf(("Loaded symbols: Unknown format.\n"));
-      break;
-  }
-
-  MaybePrint("Image name", module_info.ImageName);
-  MaybePrint("Loaded image name", module_info.LoadedImageName);
-#ifdef VC8_OR_ABOVE   /* TODO(csilvers): figure out how to tell */
-  MaybePrint("PDB file name", module_info.LoadedPdbName);
-  if (module_info.PdbUnmatched || module_info.DbgUnmatched)  {
-    /* This can only happen if the debug information is contained in a
-     * separate file (.DBG or .PDB)
-     */
-    printf(("Warning: Unmatched symbols.\n"));
-  }
-#endif
-
-  /* Contents */
-#ifdef VC8_OR_ABOVE   /* TODO(csilvers): figure out how to tell */
-  PrintAvailability("Line numbers", module_info.LineNumbers);
-  PrintAvailability("Global symbols", module_info.GlobalSymbols);
-  PrintAvailability("Type information", module_info.TypeInfo);
-#endif
-}
-
-void usage() {
-  fprintf(stderr, "usage: nm-pdb [-C|--demangle] <module or filename>\n");
-}
-
-int main(int argc, char *argv[]) {
-  DWORD  error;
-  HANDLE process;
-  ULONG64 module_base;
-  SYM_CONTEXT ctx;
-  int i;
-  char* search;
-  char* filename = NULL;
-  int rv = 0;
-  /* We may add SYMOPT_UNDNAME if --demangle is specified: */
-  DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG;
-
-  for (i = 1; i < argc; i++) {
-    if (strcmp(argv[i], "--demangle") == 0 || strcmp(argv[i], "-C") == 0) {
-      symopts |= SYMOPT_UNDNAME;
-    } else if (strcmp(argv[i], "--help") == 0) {
-      usage();
-      exit(0);
-    } else {
-      break;
-    }
-  }
-  if (i != argc - 1) {
-    usage();
-    exit(1);
-  }
-  filename = argv[i];
-
-  process = GetCurrentProcess();
-
-  if (!SymInitialize(process, NULL, FALSE)) {
-    error = GetLastError();
-    fprintf(stderr, "SymInitialize returned error : %d\n", error);
-    return 1;
-  }
-
-  search = malloc(SEARCH_CAP);
-  if (SymGetSearchPath(process, search, SEARCH_CAP)) {
-    if (strlen(search) + sizeof(";" WEBSYM) > SEARCH_CAP) {
-      fprintf(stderr, "Search path too long\n");
-      SymCleanup(process);
-      return 1;
-    }
-    strcat(search, ";" WEBSYM);
-  } else {
-    error = GetLastError();
-    fprintf(stderr, "SymGetSearchPath returned error : %d\n", error);
-    rv = 1;                   /* An error, but not a fatal one */
-    strcpy(search, WEBSYM);   /* Use a default value */
-  }
-  if (!SymSetSearchPath(process, search)) {
-    error = GetLastError();
-    fprintf(stderr, "SymSetSearchPath returned error : %d\n", error);
-    rv = 1;                   /* An error, but not a fatal one */
- }
-
-  SymSetOptions(symopts);
-  module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0);
-  if (!module_base) {
-    /* SymLoadModuleEx failed */
-    error = GetLastError();
-    fprintf(stderr, "SymLoadModuleEx returned error : %d for %s\n",
-            error, filename);
-    SymCleanup(process);
-    return 1;
-  }
-
-  ShowSymbolInfo(process, module_base);
-
-  memset(&ctx, 0, sizeof(ctx));
-  ctx.module_base = module_base;
-  if (!SymEnumSymbols(process, module_base, NULL, EnumSymProc, &ctx)) {
-    error = GetLastError();
-    fprintf(stderr, "SymEnumSymbols returned error: %d\n", error);
-    rv = 1;
-  } else {
-    DWORD j;
-    qsort(ctx.syms, ctx.syms_len, sizeof(ctx.syms[0]), sym_cmp);
-    for (j = 0; j < ctx.syms_len; j++) {
-      printf("%016I64x X %s\n", ctx.syms[j].addr, ctx.syms[j].name);
-    }
-    /* In a perfect world, maybe we'd clean up ctx's memory? */
-  }
-  SymUnloadModule64(process, module_base);
-  SymCleanup(process);
-  return rv;
-}
diff --git a/third_party/tcmalloc/chromium/src/windows/override_functions.cc b/third_party/tcmalloc/chromium/src/windows/override_functions.cc
deleted file mode 100644
index f6f519a..0000000
--- a/third_party/tcmalloc/chromium/src/windows/override_functions.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Mike Belshe
-// 
-// To link tcmalloc into a EXE or DLL statically without using the patching
-// facility, we can take a stock libcmt and remove all the allocator functions.
-// When we relink the EXE/DLL with the modified libcmt and tcmalloc, a few
-// functions are missing.  This file contains the additional overrides which
-// are required in the VS2005 libcmt in order to link the modified libcmt.
-//
-// See also
-// http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b
-
-#include <config.h>
-
-#ifndef _WIN32
-# error You should only be including this file in a windows environment!
-#endif
-
-#ifndef WIN32_OVERRIDE_ALLOCATORS
-# error This file is intended for use when overriding allocators
-#endif
-
-#include "tcmalloc.cc"
-
-extern "C" {
-
-void* _malloc_base(size_t size) {
-  return malloc(size);
-}
-
-void _free_base(void* p) {
-  free(p);
-}
-
-void* _calloc_base(size_t n, size_t size) {
-  return calloc(n, size);
-}
-
-void* _recalloc(void* p, size_t n, size_t size) {
-  void* result = realloc(p, n * size);
-  memset(result, 0, n * size);
-  return result;
-}
-
-void* _calloc_impl(size_t n, size_t size) {
-  return calloc(n, size);
-}
-
-size_t _msize(void* p) {
-  return MallocExtension::instance()->GetAllocatedSize(p);
-}
-
-HANDLE __acrt_heap = nullptr;
-
-bool __acrt_initialize_heap() {
-  new TCMallocGuard();
-  return true;
-}
-
-bool __acrt_uninitialize_heap(bool) {
-  return true;
-}
-
-intptr_t _get_heap_handle() {
-  return 0;
-}
-
-HANDLE __acrt_getheap() {
-  return __acrt_heap;
-}
-
-// The CRT heap initialization stub.
-int _heap_init() {
-  // We intentionally leak this object.  It lasts for the process
-  // lifetime.  Trying to teardown at _heap_term() is so late that
-  // you can't do anything useful anyway.
-  new TCMallocGuard();
-  return 1;
-}
-
-// The CRT heap cleanup stub.
-void _heap_term() {
-}
-
-// We set this to 1 because part of the CRT uses a check of _crtheap != 0
-// to test whether the CRT has been initialized.  Once we've ripped out
-// the allocators from libcmt, we need to provide this definition so that
-// the rest of the CRT is still usable.
-void* _crtheap = reinterpret_cast<void*>(1);
-
-int _set_new_mode(int flag) {
-  return tc_set_new_mode(flag);
-}
-
-int _query_new_mode() {
-  return tc_query_new_mode();
-}
-
-}  // extern "C"
-
-#ifndef NDEBUG
-#undef malloc
-#undef free
-#undef calloc
-int _CrtDbgReport(int, const char*, int, const char*, const char*, ...) {
-  return 0;
-}
-
-int _CrtDbgReportW(int, const wchar_t*, int, const wchar_t*, const wchar_t*, ...) {
-  return 0;
-}
-
-int _CrtSetReportMode(int, int) {
-  return 0;
-}
-
-extern "C" void* _malloc_dbg(size_t size, int , const char*, int) {
-  return malloc(size);
-}
-
-extern "C" void _free_dbg(void* ptr, int) {
-  free(ptr);
-}
-
-extern "C" void* _calloc_dbg(size_t n, size_t size, int, const char*, int) {
-  return calloc(n, size);
-}
-#endif  // NDEBUG
diff --git a/third_party/tcmalloc/chromium/src/windows/patch_functions.cc b/third_party/tcmalloc/chromium/src/windows/patch_functions.cc
deleted file mode 100644
index 5417880..0000000
--- a/third_party/tcmalloc/chromium/src/windows/patch_functions.cc
+++ /dev/null
@@ -1,1081 +0,0 @@
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Craig Silverstein
-//
-// The main purpose of this file is to patch the libc allocation
-// routines (malloc and friends, but also _msize and other
-// windows-specific libc-style routines).  However, we also patch
-// windows routines to do accounting.  We do better at the former than
-// the latter.  Here are some comments from Paul Pluzhnikov about what
-// it might take to do a really good job patching windows routines to
-// keep track of memory usage:
-//
-// "You should intercept at least the following:
-//     HeapCreate HeapDestroy HeapAlloc HeapReAlloc HeapFree
-//     RtlCreateHeap RtlDestroyHeap RtlAllocateHeap RtlFreeHeap
-//     malloc calloc realloc free
-//     malloc_dbg calloc_dbg realloc_dbg free_dbg
-// Some of these call the other ones (but not always), sometimes
-// recursively (i.e. HeapCreate may call HeapAlloc on a different
-// heap, IIRC)."
-//
-// Since Paul didn't mention VirtualAllocEx, he may not have even been
-// considering all the mmap-like functions that windows has (or he may
-// just be ignoring it because he's seen we already patch it).  Of the
-// above, we do not patch the *_dbg functions, and of the windows
-// functions, we only patch HeapAlloc and HeapFree.
-//
-// The *_dbg functions come into play with /MDd, /MTd, and /MLd,
-// probably.  It may be ok to just turn off tcmalloc in those cases --
-// if the user wants the windows debug malloc, they probably don't
-// want tcmalloc!  We should also test with all of /MD, /MT, and /ML,
-// which we're not currently doing.
-
-// TODO(csilvers): try to do better here?  Paul does conclude:
-//                 "Keeping track of all of this was a nightmare."
-
-#ifndef _WIN32
-# error You should only be including windows/patch_functions.cc in a windows environment!
-#endif
-
-#include <config.h>
-
-#ifdef WIN32_OVERRIDE_ALLOCATORS
-#error This file is intended for patching allocators - use override_functions.cc instead.
-#endif
-
-// We use psapi.  Non-MSVC systems will have to link this in themselves.
-#ifdef _MSC_VER
-#pragma comment(lib, "Psapi.lib")
-#endif
-
-// Make sure we always use the 'old' names of the psapi functions.
-#ifndef PSAPI_VERSION
-#define PSAPI_VERSION 1
-#endif
-
-#include <windows.h>
-#include <stdio.h>
-#include <malloc.h>       // for _msize and _expand
-#include <psapi.h>        // for EnumProcessModules, GetModuleInformation, etc.
-#include <set>
-#include <map>
-#include <vector>
-#include <base/logging.h>
-#include "base/spinlock.h"
-#include "gperftools/malloc_hook.h"
-#include "malloc_hook-inl.h"
-#include "preamble_patcher.h"
-
-// The maximum number of modules we allow to be in one executable
-const int kMaxModules = 8182;
-
-// These are hard-coded, unfortunately. :-( They are also probably
-// compiler specific.  See get_mangled_names.cc, in this directory,
-// for instructions on how to update these names for your compiler.
-#ifdef _WIN64
-const char kMangledNew[] = "??2@YAPEAX_K@Z";
-const char kMangledNewArray[] = "??_U@YAPEAX_K@Z";
-const char kMangledDelete[] = "??3@YAXPEAX@Z";
-const char kMangledDeleteArray[] = "??_V@YAXPEAX@Z";
-const char kMangledNewNothrow[] = "??2@YAPEAX_KAEBUnothrow_t@std@@@Z";
-const char kMangledNewArrayNothrow[] = "??_U@YAPEAX_KAEBUnothrow_t@std@@@Z";
-const char kMangledDeleteNothrow[] = "??3@YAXPEAXAEBUnothrow_t@std@@@Z";
-const char kMangledDeleteArrayNothrow[] = "??_V@YAXPEAXAEBUnothrow_t@std@@@Z";
-#else
-const char kMangledNew[] = "??2@YAPAXI@Z";
-const char kMangledNewArray[] = "??_U@YAPAXI@Z";
-const char kMangledDelete[] = "??3@YAXPAX@Z";
-const char kMangledDeleteArray[] = "??_V@YAXPAX@Z";
-const char kMangledNewNothrow[] = "??2@YAPAXIABUnothrow_t@std@@@Z";
-const char kMangledNewArrayNothrow[] = "??_U@YAPAXIABUnothrow_t@std@@@Z";
-const char kMangledDeleteNothrow[] = "??3@YAXPAXABUnothrow_t@std@@@Z";
-const char kMangledDeleteArrayNothrow[] = "??_V@YAXPAXABUnothrow_t@std@@@Z";
-#endif
-
-// This is an unused but exported symbol that we can use to tell the
-// MSVC linker to bring in libtcmalloc, via the /INCLUDE linker flag.
-// Without this, the linker will likely decide that libtcmalloc.dll
-// doesn't add anything to the executable (since it does all its work
-// through patching, which the linker can't see), and ignore it
-// entirely.  (The name 'tcmalloc' is already reserved for a
-// namespace.  I'd rather export a variable named "_tcmalloc", but I
-// couldn't figure out how to get that to work.  This function exports
-// the symbol "__tcmalloc".)
-extern "C" PERFTOOLS_DLL_DECL void _tcmalloc();
-void _tcmalloc() { }
-
-// This is the version needed for windows x64, which has a different
-// decoration scheme which doesn't auto-add a leading underscore.
-extern "C" PERFTOOLS_DLL_DECL void __tcmalloc();
-void __tcmalloc() { }
-
-namespace {    // most everything here is in an unnamed namespace
-
-typedef void (*GenericFnPtr)();
-
-using sidestep::PreamblePatcher;
-
-struct ModuleEntryCopy;   // defined below
-
-// These functions are how we override the memory allocation
-// functions, just like tcmalloc.cc and malloc_hook.cc do.
-
-// This is information about the routines we're patching, for a given
-// module that implements libc memory routines.  A single executable
-// can have several libc implementations running about (in different
-// .dll's), and we need to patch/unpatch them all.  This defines
-// everything except the new functions we're patching in, which
-// are defined in LibcFunctions, below.
-class LibcInfo {
- public:
-  LibcInfo() {
-    memset(this, 0, sizeof(*this));  // easiest way to initialize the array
-  }
-
-  bool patched() const { return is_valid(); }
-  void set_is_valid(bool b) { is_valid_ = b; }
-  // According to http://msdn.microsoft.com/en-us/library/ms684229(VS.85).aspx:
-  // "The load address of a module (lpBaseOfDll) is the same as the HMODULE
-  // value."
-  HMODULE hmodule() const {
-    return reinterpret_cast<HMODULE>(const_cast<void*>(module_base_address_));
-  }
-
-  // Populates all the windows_fn_[] vars based on our module info.
-  // Returns false if windows_fn_ is all NULL's, because there's
-  // nothing to patch.  Also populates the rest of the module_entry
-  // info, such as the module's name.
-  bool PopulateWindowsFn(const ModuleEntryCopy& module_entry);
-
- protected:
-  void CopyFrom(const LibcInfo& that) {
-    if (this == &that)
-      return;
-    this->is_valid_ = that.is_valid_;
-    memcpy(this->windows_fn_, that.windows_fn_, sizeof(windows_fn_));
-    this->module_base_address_ = that.module_base_address_;
-    this->module_base_size_ = that.module_base_size_;
-  }
-
-  enum {
-    kMalloc, kFree, kRealloc, kCalloc,
-    kNew, kNewArray, kDelete, kDeleteArray,
-    kNewNothrow, kNewArrayNothrow, kDeleteNothrow, kDeleteArrayNothrow,
-    // These are windows-only functions from malloc.h
-    k_Msize, k_Expand,
-    // A MS CRT "internal" function, implemented using _calloc_impl
-    k_CallocCrt, kFreeBase,
-    kNumFunctions
-  };
-
-  // I'd like to put these together in a struct (perhaps in the
-  // subclass, so we can put in perftools_fn_ as well), but vc8 seems
-  // to have a bug where it doesn't initialize the struct properly if
-  // we try to take the address of a function that's not yet loaded
-  // from a dll, as is the common case for static_fn_.  So we need
-  // each to be in its own array. :-(
-  static const char* const function_name_[kNumFunctions];
-
-  // This function is only used when statically linking the binary.
-  // In that case, loading malloc/etc from the dll (via
-  // PatchOneModule) won't work, since there are no dlls.  Instead,
-  // you just want to be taking the address of malloc/etc directly.
-  // In the common, non-static-link case, these pointers will all be
-  // NULL, since this initializer runs before msvcrt.dll is loaded.
-  static const GenericFnPtr static_fn_[kNumFunctions];
-
-  // This is the address of the function we are going to patch
-  // (malloc, etc).  Other info about the function is in the
-  // patch-specific subclasses, below.
-  GenericFnPtr windows_fn_[kNumFunctions];
-
-  // This is set to true when this structure is initialized (because
-  // we're patching a new library) and set to false when it's
-  // uninitialized (because we've freed that library).
-  bool is_valid_;
-
-  const void *module_base_address_;
-  size_t module_base_size_;
-
- public:
-  // These shouldn't have to be public, since only subclasses of
-  // LibcInfo need it, but they do.  Maybe something to do with
-  // templates.  Shrug.  I hide them down here so users won't see
-  // them. :-)  (OK, I also need to define ctrgProcAddress late.)
-  bool is_valid() const { return is_valid_; }
-  GenericFnPtr windows_fn(int ifunction) const {
-    return windows_fn_[ifunction];
-  }
-  // These three are needed by ModuleEntryCopy.
-  static const int ctrgProcAddress = kNumFunctions;
-  static GenericFnPtr static_fn(int ifunction) {
-    return static_fn_[ifunction];
-  }
-  static const char* const function_name(int ifunction) {
-    return function_name_[ifunction];
-  }
-};
-
-// Template trickiness: logically, a LibcInfo would include
-// Windows_malloc_, origstub_malloc_, and Perftools_malloc_: for a
-// given module, these three go together.  And in fact,
-// Perftools_malloc_ may need to call origstub_malloc_, which means we
-// either need to change Perftools_malloc_ to take origstub_malloc_ as
-// an argument -- unfortunately impossible since it needs to keep the
-// same API as normal malloc -- or we need to write a different
-// version of Perftools_malloc_ for each LibcInfo instance we create.
-// We choose the second route, and use templates to implement it (we
-// could have also used macros).  So to get multiple versions
-// of the struct, we say "struct<1> var1; struct<2> var2;".  The price
-// we pay is some code duplication, and more annoying, each instance
-// of this var is a separate type.
-template<int> class LibcInfoWithPatchFunctions : public LibcInfo {
- public:
-  // me_info should have had PopulateWindowsFn() called on it, so the
-  // module_* vars and windows_fn_ are set up.
-  bool Patch(const LibcInfo& me_info);
-  void Unpatch();
-
- private:
-  // This holds the original function contents after we patch the function.
-  // This has to be defined static in the subclass, because the perftools_fns
-  // reference origstub_fn_.
-  static GenericFnPtr origstub_fn_[kNumFunctions];
-
-  // This is the function we want to patch in
-  static const GenericFnPtr perftools_fn_[kNumFunctions];
-
-  static void* Perftools_malloc(size_t size) __THROW;
-  static void Perftools_free(void* ptr) __THROW;
-  static void Perftools_free_base(void* ptr) __THROW;
-  static void* Perftools_realloc(void* ptr, size_t size) __THROW;
-  static void* Perftools_calloc(size_t nmemb, size_t size) __THROW;
-  static void* Perftools_new(size_t size);
-  static void* Perftools_newarray(size_t size);
-  static void Perftools_delete(void *ptr);
-  static void Perftools_deletearray(void *ptr);
-  static void* Perftools_new_nothrow(size_t size,
-                                     const std::nothrow_t&) __THROW;
-  static void* Perftools_newarray_nothrow(size_t size,
-                                          const std::nothrow_t&) __THROW;
-  static void Perftools_delete_nothrow(void *ptr,
-                                       const std::nothrow_t&) __THROW;
-  static void Perftools_deletearray_nothrow(void *ptr,
-                                            const std::nothrow_t&) __THROW;
-  static size_t Perftools__msize(void *ptr) __THROW;
-  static void* Perftools__expand(void *ptr, size_t size) __THROW;
-  // malloc.h also defines these functions:
-  //   _aligned_malloc, _aligned_free,
-  //   _recalloc, _aligned_offset_malloc, _aligned_realloc, _aligned_recalloc
-  //   _aligned_offset_realloc, _aligned_offset_recalloc, _malloca, _freea
-  // But they seem pretty obscure, and I'm fine not overriding them for now.
-  // It may be they all call into malloc/free anyway.
-};
-
-// This is a subset of MODDULEENTRY32, that we need for patching.
-struct ModuleEntryCopy {
-  LPVOID  modBaseAddr;     // the same as hmodule
-  DWORD   modBaseSize;
-  // This is not part of MODDULEENTRY32, but is needed to avoid making
-  // windows syscalls while we're holding patch_all_modules_lock (see
-  // lock-inversion comments at patch_all_modules_lock definition, below).
-  GenericFnPtr rgProcAddresses[LibcInfo::ctrgProcAddress];
-
-  ModuleEntryCopy() {
-    modBaseAddr = NULL;
-    modBaseSize = 0;
-    for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++)
-      rgProcAddresses[i] = LibcInfo::static_fn(i);
-  }
-  ModuleEntryCopy(const MODULEINFO& mi) {
-    this->modBaseAddr = mi.lpBaseOfDll;
-    this->modBaseSize = mi.SizeOfImage;
-    LPVOID modEndAddr = (char*)mi.lpBaseOfDll + mi.SizeOfImage;
-    for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++) {
-      FARPROC target = ::GetProcAddress(
-          reinterpret_cast<const HMODULE>(mi.lpBaseOfDll),
-          LibcInfo::function_name(i));
-      // Sometimes a DLL forwards a function to a function in another
-      // DLL.  We don't want to patch those forwarded functions --
-      // they'll get patched when the other DLL is processed.
-      if (target >= modBaseAddr && target < modEndAddr)
-        rgProcAddresses[i] = (GenericFnPtr)target;
-      else
-        rgProcAddresses[i] = (GenericFnPtr)NULL;
-    }
-  }
-};
-
-// This class is easier because there's only one of them.
-class WindowsInfo {
- public:
-  void Patch();
-  void Unpatch();
-
- private:
-  // TODO(csilvers): should we be patching GlobalAlloc/LocalAlloc instead,
-  //                 for pre-XP systems?
-  enum {
-    kHeapAlloc, kHeapFree, kVirtualAllocEx, kVirtualFreeEx,
-    kMapViewOfFileEx, kUnmapViewOfFile, kLoadLibraryExW, kFreeLibrary,
-    kNumFunctions
-  };
-
-  struct FunctionInfo {
-    const char* const name;          // name of fn in a module (eg "malloc")
-    GenericFnPtr windows_fn;         // the fn whose name we call (&malloc)
-    GenericFnPtr origstub_fn;        // original fn contents after we patch
-    const GenericFnPtr perftools_fn; // fn we want to patch in
-  };
-
-  static FunctionInfo function_info_[kNumFunctions];
-
-  // A Windows-API equivalent of malloc and free
-  static LPVOID WINAPI Perftools_HeapAlloc(HANDLE hHeap, DWORD dwFlags,
-                                           DWORD_PTR dwBytes);
-  static BOOL WINAPI Perftools_HeapFree(HANDLE hHeap, DWORD dwFlags,
-                                        LPVOID lpMem);
-  // A Windows-API equivalent of mmap and munmap, for "anonymous regions"
-  static LPVOID WINAPI Perftools_VirtualAllocEx(HANDLE process, LPVOID address,
-                                                SIZE_T size, DWORD type,
-                                                DWORD protect);
-  static BOOL WINAPI Perftools_VirtualFreeEx(HANDLE process, LPVOID address,
-                                             SIZE_T size, DWORD type);
-  // A Windows-API equivalent of mmap and munmap, for actual files
-  static LPVOID WINAPI Perftools_MapViewOfFileEx(HANDLE hFileMappingObject,
-                                                 DWORD dwDesiredAccess,
-                                                 DWORD dwFileOffsetHigh,
-                                                 DWORD dwFileOffsetLow,
-                                                 SIZE_T dwNumberOfBytesToMap,
-                                                 LPVOID lpBaseAddress);
-  static BOOL WINAPI Perftools_UnmapViewOfFile(LPCVOID lpBaseAddress);
-  // We don't need the other 3 variants because they all call this one. */
-  static HMODULE WINAPI Perftools_LoadLibraryExW(LPCWSTR lpFileName,
-                                                 HANDLE hFile,
-                                                 DWORD dwFlags);
-  static BOOL WINAPI Perftools_FreeLibrary(HMODULE hLibModule);
-};
-
-// If you run out, just add a few more to the array.  You'll also need
-// to update the switch statement in PatchOneModule(), and the list in
-// UnpatchWindowsFunctions().
-// main_executable and main_executable_windows are two windows into
-// the same executable.  One is responsible for patching the libc
-// routines that live in the main executable (if any) to use tcmalloc;
-// the other is responsible for patching the windows routines like
-// HeapAlloc/etc to use tcmalloc.
-static LibcInfoWithPatchFunctions<0> main_executable;
-static LibcInfoWithPatchFunctions<1> libc1;
-static LibcInfoWithPatchFunctions<2> libc2;
-static LibcInfoWithPatchFunctions<3> libc3;
-static LibcInfoWithPatchFunctions<4> libc4;
-static LibcInfoWithPatchFunctions<5> libc5;
-static LibcInfoWithPatchFunctions<6> libc6;
-static LibcInfoWithPatchFunctions<7> libc7;
-static LibcInfoWithPatchFunctions<8> libc8;
-static LibcInfo* g_module_libcs[] = {
-  &libc1, &libc2, &libc3, &libc4, &libc5, &libc6, &libc7, &libc8
-};
-static WindowsInfo main_executable_windows;
-
-const char* const LibcInfo::function_name_[] = {
-  "malloc", "free", "realloc", "calloc",
-  kMangledNew, kMangledNewArray, kMangledDelete, kMangledDeleteArray,
-  // Ideally we should patch the nothrow versions of new/delete, but
-  // at least in msvcrt, nothrow-new machine-code is of a type we
-  // can't patch.  Since these are relatively rare, I'm hoping it's ok
-  // not to patch them.  (NULL name turns off patching.)
-  NULL,  // kMangledNewNothrow,
-  NULL,  // kMangledNewArrayNothrow,
-  NULL,  // kMangledDeleteNothrow,
-  NULL,  // kMangledDeleteArrayNothrow,
-  "_msize", "_expand", "_calloc_crt", "_free_base"
-};
-
-// For mingw, I can't patch the new/delete here, because the
-// instructions are too small to patch.  Luckily, they're so small
-// because all they do is call into malloc/free, so they still end up
-// calling tcmalloc routines, and we don't actually lose anything
-// (except maybe some stacktrace goodness) by not patching.
-const GenericFnPtr LibcInfo::static_fn_[] = {
-  (GenericFnPtr)&::malloc,
-  (GenericFnPtr)&::free,
-  (GenericFnPtr)&::realloc,
-  (GenericFnPtr)&::calloc,
-#ifdef __MINGW32__
-  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-#else
-  (GenericFnPtr)(void*(*)(size_t))&::operator new,
-  (GenericFnPtr)(void*(*)(size_t))&::operator new[],
-  (GenericFnPtr)(void(*)(void*))&::operator delete,
-  (GenericFnPtr)(void(*)(void*))&::operator delete[],
-  (GenericFnPtr)
-  (void*(*)(size_t, struct std::nothrow_t const &))&::operator new,
-  (GenericFnPtr)
-  (void*(*)(size_t, struct std::nothrow_t const &))&::operator new[],
-  (GenericFnPtr)
-  (void(*)(void*, struct std::nothrow_t const &))&::operator delete,
-  (GenericFnPtr)
-  (void(*)(void*, struct std::nothrow_t const &))&::operator delete[],
-#endif
-  (GenericFnPtr)&::_msize,
-  (GenericFnPtr)&::_expand,
-  (GenericFnPtr)&::calloc,
-  (GenericFnPtr)&::free
-};
-
-template<int T> GenericFnPtr LibcInfoWithPatchFunctions<T>::origstub_fn_[] = {
-  // This will get filled in at run-time, as patching is done.
-};
-
-template<int T>
-const GenericFnPtr LibcInfoWithPatchFunctions<T>::perftools_fn_[] = {
-  (GenericFnPtr)&Perftools_malloc,
-  (GenericFnPtr)&Perftools_free,
-  (GenericFnPtr)&Perftools_realloc,
-  (GenericFnPtr)&Perftools_calloc,
-  (GenericFnPtr)&Perftools_new,
-  (GenericFnPtr)&Perftools_newarray,
-  (GenericFnPtr)&Perftools_delete,
-  (GenericFnPtr)&Perftools_deletearray,
-  (GenericFnPtr)&Perftools_new_nothrow,
-  (GenericFnPtr)&Perftools_newarray_nothrow,
-  (GenericFnPtr)&Perftools_delete_nothrow,
-  (GenericFnPtr)&Perftools_deletearray_nothrow,
-  (GenericFnPtr)&Perftools__msize,
-  (GenericFnPtr)&Perftools__expand,
-  (GenericFnPtr)&Perftools_calloc,
-  (GenericFnPtr)&Perftools_free_base
-};
-
-/*static*/ WindowsInfo::FunctionInfo WindowsInfo::function_info_[] = {
-  { "HeapAlloc", NULL, NULL, (GenericFnPtr)&Perftools_HeapAlloc },
-  { "HeapFree", NULL, NULL, (GenericFnPtr)&Perftools_HeapFree },
-  { "VirtualAllocEx", NULL, NULL, (GenericFnPtr)&Perftools_VirtualAllocEx },
-  { "VirtualFreeEx", NULL, NULL, (GenericFnPtr)&Perftools_VirtualFreeEx },
-  { "MapViewOfFileEx", NULL, NULL, (GenericFnPtr)&Perftools_MapViewOfFileEx },
-  { "UnmapViewOfFile", NULL, NULL, (GenericFnPtr)&Perftools_UnmapViewOfFile },
-  { "LoadLibraryExW", NULL, NULL, (GenericFnPtr)&Perftools_LoadLibraryExW },
-  { "FreeLibrary", NULL, NULL, (GenericFnPtr)&Perftools_FreeLibrary },
-};
-
-bool LibcInfo::PopulateWindowsFn(const ModuleEntryCopy& module_entry) {
-  // First, store the location of the function to patch before
-  // patching it.  If none of these functions are found in the module,
-  // then this module has no libc in it, and we just return false.
-  for (int i = 0; i < kNumFunctions; i++) {
-    if (!function_name_[i])     // we can turn off patching by unsetting name
-      continue;
-    // The ::GetProcAddress calls were done in the ModuleEntryCopy
-    // constructor, so we don't have to make any windows calls here.
-    const GenericFnPtr fn = module_entry.rgProcAddresses[i];
-    if (fn) {
-      windows_fn_[i] = PreamblePatcher::ResolveTarget(fn);
-    }
-  }
-
-  // Some modules use the same function pointer for new and new[].  If
-  // we find that, set one of the pointers to NULL so we don't double-
-  // patch.  Same may happen with new and nothrow-new, or even new[]
-  // and nothrow-new.  It's easiest just to check each fn-ptr against
-  // every other.
-  for (int i = 0; i < kNumFunctions; i++) {
-    for (int j = i+1; j < kNumFunctions; j++) {
-      if (windows_fn_[i] == windows_fn_[j]) {
-        // We NULL the later one (j), so as to minimize the chances we
-        // NULL kFree and kRealloc.  See comments below.  This is fragile!
-        windows_fn_[j] = NULL;
-      }
-    }
-  }
-
-  // There's always a chance that our module uses the same function
-  // as another module that we've already loaded.  In that case, we
-  // need to set our windows_fn to NULL, to avoid double-patching.
-  for (int ifn = 0; ifn < kNumFunctions; ifn++) {
-    for (int imod = 0;
-         imod < sizeof(g_module_libcs)/sizeof(*g_module_libcs);  imod++) {
-      if (g_module_libcs[imod]->is_valid() &&
-          this->windows_fn(ifn) == g_module_libcs[imod]->windows_fn(ifn)) {
-        windows_fn_[ifn] = NULL;
-      }
-    }
-  }
-
-  bool found_non_null = false;
-  for (int i = 0; i < kNumFunctions; i++) {
-    if (windows_fn_[i])
-      found_non_null = true;
-  }
-  if (!found_non_null)
-    return false;
-
-  // It's important we didn't NULL out windows_fn_[kFree] or [kRealloc].
-  // The reason is, if those are NULL-ed out, we'll never patch them
-  // and thus never get an origstub_fn_ value for them, and when we
-  // try to call origstub_fn_[kFree/kRealloc] in Perftools_free and
-  // Perftools_realloc, below, it will fail.  We could work around
-  // that by adding a pointer from one patch-unit to the other, but we
-  // haven't needed to yet.
-  CHECK(windows_fn_[kFree]);
-  CHECK(windows_fn_[kRealloc]);
-
-  // OK, we successfully populated.  Let's store our member information.
-  module_base_address_ = module_entry.modBaseAddr;
-  module_base_size_ = module_entry.modBaseSize;
-  return true;
-}
-
-template<int T>
-bool LibcInfoWithPatchFunctions<T>::Patch(const LibcInfo& me_info) {
-  CopyFrom(me_info);   // copies the module_entry and the windows_fn_ array
-  for (int i = 0; i < kNumFunctions; i++) {
-    if (windows_fn_[i] && windows_fn_[i] != perftools_fn_[i]) {
-      // if origstub_fn_ is not NULL, it's left around from a previous
-      // patch.  We need to set it to NULL for the new Patch call.
-      //
-      // Note that origstub_fn_ was logically freed by
-      // PreamblePatcher::Unpatch, so we don't have to do anything
-      // about it.
-      origstub_fn_[i] = NULL;   // Patch() will fill this in
-      CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
-               PreamblePatcher::Patch(windows_fn_[i], perftools_fn_[i],
-                                      &origstub_fn_[i]));
-    }
-  }
-  set_is_valid(true);
-  return true;
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Unpatch() {
-  // We have to cast our GenericFnPtrs to void* for unpatch.  This is
-  // contra the C++ spec; we use C-style casts to empahsize that.
-  for (int i = 0; i < kNumFunctions; i++) {
-    if (windows_fn_[i])
-      CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
-               PreamblePatcher::Unpatch((void*)windows_fn_[i],
-                                        (void*)perftools_fn_[i],
-                                        (void*)origstub_fn_[i]));
-  }
-  set_is_valid(false);
-}
-
-void WindowsInfo::Patch() {
-  HMODULE hkernel32 = ::GetModuleHandleA("kernel32");
-  CHECK_NE(hkernel32, NULL);
-
-  // Unlike for libc, we know these exist in our module, so we can get
-  // and patch at the same time.
-  for (int i = 0; i < kNumFunctions; i++) {
-    function_info_[i].windows_fn = (GenericFnPtr)
-        ::GetProcAddress(hkernel32, function_info_[i].name);
-    // If origstub_fn is not NULL, it's left around from a previous
-    // patch.  We need to set it to NULL for the new Patch call.
-    // Since we've patched Unpatch() not to delete origstub_fn_ (it
-    // causes problems in some contexts, though obviously not this
-    // one), we should delete it now, before setting it to NULL.
-    // NOTE: casting from a function to a pointer is contra the C++
-    //       spec.  It's not safe on IA64, but is on i386.  We use
-    //       a C-style cast here to emphasize this is not legal C++.
-    delete[] (char*)(function_info_[i].origstub_fn);
-    function_info_[i].origstub_fn = NULL;  // Patch() will fill this in
-    CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
-             PreamblePatcher::Patch(function_info_[i].windows_fn,
-                                    function_info_[i].perftools_fn,
-                                    &function_info_[i].origstub_fn));
-  }
-}
-
-void WindowsInfo::Unpatch() {
-  // We have to cast our GenericFnPtrs to void* for unpatch.  This is
-  // contra the C++ spec; we use C-style casts to empahsize that.
-  for (int i = 0; i < kNumFunctions; i++) {
-    CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
-             PreamblePatcher::Unpatch((void*)function_info_[i].windows_fn,
-                                      (void*)function_info_[i].perftools_fn,
-                                      (void*)function_info_[i].origstub_fn));
-  }
-}
-
-// You should hold the patch_all_modules_lock when calling this.
-void PatchOneModuleLocked(const LibcInfo& me_info) {
-  // If we don't already have info on this module, let's add it.  This
-  // is where we're sad that each libcX has a different type, so we
-  // can't use an array; instead, we have to use a switch statement.
-  // Patch() returns false if there were no libc functions in the module.
-  for (int i = 0; i < sizeof(g_module_libcs)/sizeof(*g_module_libcs); i++) {
-    if (!g_module_libcs[i]->is_valid()) {   // found an empty spot to add!
-      switch (i) {
-        case 0: libc1.Patch(me_info); return;
-        case 1: libc2.Patch(me_info); return;
-        case 2: libc3.Patch(me_info); return;
-        case 3: libc4.Patch(me_info); return;
-        case 4: libc5.Patch(me_info); return;
-        case 5: libc6.Patch(me_info); return;
-        case 6: libc7.Patch(me_info); return;
-        case 7: libc8.Patch(me_info); return;
-      }
-    }
-  }
-  printf("PERFTOOLS ERROR: Too many modules containing libc in this executable\n");
-}
-
-void PatchMainExecutableLocked() {
-  if (main_executable.patched())
-    return;    // main executable has already been patched
-  ModuleEntryCopy fake_module_entry;   // make a fake one to pass into Patch()
-  // No need to call PopulateModuleEntryProcAddresses on the main executable.
-  main_executable.PopulateWindowsFn(fake_module_entry);
-  main_executable.Patch(main_executable);
-}
-
-// This lock is subject to a subtle and annoying lock inversion
-// problem: it may interact badly with unknown internal windows locks.
-// In particular, windows may be holding a lock when it calls
-// LoadLibraryExW and FreeLibrary, which we've patched.  We have those
-// routines call PatchAllModules, which acquires this lock.  If we
-// make windows system calls while holding this lock, those system
-// calls may need the internal windows locks that are being held in
-// the call to LoadLibraryExW, resulting in deadlock.  The solution is
-// to be very careful not to call *any* windows routines while holding
-// patch_all_modules_lock, inside PatchAllModules().
-static SpinLock patch_all_modules_lock(SpinLock::LINKER_INITIALIZED);
-
-// last_loaded: The set of modules that were loaded the last time
-// PatchAllModules was called.  This is an optimization for only
-// looking at modules that were added or removed from the last call.
-static std::set<HMODULE> *g_last_loaded;
-
-// Iterates over all the modules currently loaded by the executable,
-// according to windows, and makes sure they're all patched.  Most
-// modules will already be in loaded_modules, meaning we have already
-// loaded and either patched them or determined they did not need to
-// be patched.  Others will not, which means we need to patch them
-// (if necessary).  Finally, we have to go through the existing
-// g_module_libcs and see if any of those are *not* in the modules
-// currently loaded by the executable.  If so, we need to invalidate
-// them.  Returns true if we did any work (patching or invalidating),
-// false if we were a noop.  May update loaded_modules as well.
-// NOTE: you must hold the patch_all_modules_lock to access loaded_modules.
-bool PatchAllModules() {
-  std::vector<ModuleEntryCopy> modules;
-  bool made_changes = false;
-
-  const HANDLE hCurrentProcess = GetCurrentProcess();
-  DWORD num_modules = 0;
-  HMODULE hModules[kMaxModules];  // max # of modules we support in one process
-  if (!::EnumProcessModules(hCurrentProcess, hModules, sizeof(hModules),
-                            &num_modules)) {
-    num_modules = 0;
-  }
-  // EnumProcessModules actually set the bytes written into hModules,
-  // so we need to divide to make num_modules actually be a module-count.
-  num_modules /= sizeof(*hModules);
-  if (num_modules >= kMaxModules) {
-    printf("PERFTOOLS ERROR: Too many modules in this executable to try"
-           " to patch them all (if you need to, raise kMaxModules in"
-           " patch_functions.cc).\n");
-    num_modules = kMaxModules;
-  }
-
-  // Now we handle the unpatching of modules we have in g_module_libcs
-  // but that were not found in EnumProcessModules.  We need to
-  // invalidate them.  To speed that up, we store the EnumProcessModules
-  // output in a set.
-  // At the same time, we prepare for the adding of new modules, by
-  // removing from hModules all the modules we know we've already
-  // patched (or decided don't need to be patched).  At the end,
-  // hModules will hold only the modules that we need to consider patching.
-  std::set<HMODULE> currently_loaded_modules;
-  {
-    SpinLockHolder h(&patch_all_modules_lock);
-    if (!g_last_loaded)  g_last_loaded = new std::set<HMODULE>;
-    // At the end of this loop, currently_loaded_modules contains the
-    // full list of EnumProcessModules, and hModules just the ones we
-    // haven't handled yet.
-    for (int i = 0; i < num_modules; ) {
-      currently_loaded_modules.insert(hModules[i]);
-      if (g_last_loaded->count(hModules[i]) > 0) {
-        hModules[i] = hModules[--num_modules];  // replace element i with tail
-      } else {
-        i++;                                    // keep element i
-      }
-    }
-    // Now we do the unpatching/invalidation.
-    for (int i = 0; i < sizeof(g_module_libcs)/sizeof(*g_module_libcs); i++) {
-      if (g_module_libcs[i]->patched() &&
-          currently_loaded_modules.count(g_module_libcs[i]->hmodule()) == 0) {
-        // Means g_module_libcs[i] is no longer loaded (no me32 matched).
-        // We could call Unpatch() here, but why bother?  The module
-        // has gone away, so nobody is going to call into it anyway.
-        g_module_libcs[i]->set_is_valid(false);
-        made_changes = true;
-      }
-    }
-    // Update the loaded module cache.
-    g_last_loaded->swap(currently_loaded_modules);
-  }
-
-  // Now that we know what modules are new, let's get the info we'll
-  // need to patch them.  Note this *cannot* be done while holding the
-  // lock, since it needs to make windows calls (see the lock-inversion
-  // comments before the definition of patch_all_modules_lock).
-  MODULEINFO mi;
-  for (int i = 0; i < num_modules; i++) {
-    if (::GetModuleInformation(hCurrentProcess, hModules[i], &mi, sizeof(mi)))
-      modules.push_back(ModuleEntryCopy(mi));
-  }
-
-  // Now we can do the patching of new modules.
-  {
-    SpinLockHolder h(&patch_all_modules_lock);
-    for (std::vector<ModuleEntryCopy>::iterator it = modules.begin();
-         it != modules.end(); ++it) {
-      LibcInfo libc_info;
-      if (libc_info.PopulateWindowsFn(*it)) { // true==module has libc routines
-        PatchOneModuleLocked(libc_info);
-        made_changes = true;
-      }
-    }
-
-    // Now that we've dealt with the modules (dlls), update the main
-    // executable.  We do this last because PatchMainExecutableLocked
-    // wants to look at how other modules were patched.
-    if (!main_executable.patched()) {
-      PatchMainExecutableLocked();
-      made_changes = true;
-    }
-  }
-  // TODO(csilvers): for this to be reliable, we need to also take
-  // into account if we *would* have patched any modules had they not
-  // already been loaded.  (That is, made_changes should ignore
-  // g_last_loaded.)
-  return made_changes;
-}
-
-
-}  // end unnamed namespace
-
-// ---------------------------------------------------------------------
-// Now that we've done all the patching machinery, let's actually
-// define the functions we're patching in.  Mostly these are
-// simple wrappers around the do_* routines in tcmalloc.cc.
-//
-// In fact, we #include tcmalloc.cc to get at the tcmalloc internal
-// do_* functions, the better to write our own hook functions.
-// U-G-L-Y, I know.  But the alternatives are, perhaps, worse.  This
-// also lets us define _msize(), _expand(), and other windows-specific
-// functions here, using tcmalloc internals, without polluting
-// tcmalloc.cc.
-// -------------------------------------------------------------------
-
-// TODO(csilvers): refactor tcmalloc.cc into two files, so I can link
-// against the file with do_malloc, and ignore the one with malloc.
-#include "tcmalloc.cc"
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_malloc(size_t size) __THROW {
-  return malloc_fast_path<tcmalloc::malloc_oom>(size);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_free(void* ptr) __THROW {
-  MallocHook::InvokeDeleteHook(ptr);
-  // This calls the windows free if do_free decides ptr was not
-  // allocated by tcmalloc.  Note it calls the origstub_free from
-  // *this* templatized instance of LibcInfo.  See "template
-  // trickiness" above.
-  do_free_with_callback(ptr, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_free_base(void* ptr) __THROW{
-  MallocHook::InvokeDeleteHook(ptr);
-  // This calls the windows free if do_free decides ptr was not
-  // allocated by tcmalloc.  Note it calls the origstub_free from
-  // *this* templatized instance of LibcInfo.  See "template
-  // trickiness" above.
-  do_free_with_callback(ptr, (void(*)(void*))origstub_fn_[kFreeBase], false, 0);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_realloc(
-    void* old_ptr, size_t new_size) __THROW {
-  if (old_ptr == NULL) {
-    void* result = do_malloc_or_cpp_alloc(new_size);
-    MallocHook::InvokeNewHook(result, new_size);
-    return result;
-  }
-  if (new_size == 0) {
-    MallocHook::InvokeDeleteHook(old_ptr);
-    do_free_with_callback(old_ptr,
-                          (void (*)(void*))origstub_fn_[kFree], false, 0);
-    return NULL;
-  }
-  return do_realloc_with_callback(
-      old_ptr, new_size,
-      (void (*)(void*))origstub_fn_[kFree],
-      (size_t (*)(const void*))origstub_fn_[k_Msize]);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_calloc(
-    size_t n, size_t elem_size) __THROW {
-  void* result = do_calloc(n, elem_size);
-  MallocHook::InvokeNewHook(result, n * elem_size);
-  return result;
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_new(size_t size) {
-  return malloc_fast_path<tcmalloc::cpp_throw_oom>(size);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_newarray(size_t size) {
-  return malloc_fast_path<tcmalloc::cpp_throw_oom>(size);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_delete(void *p) {
-  MallocHook::InvokeDeleteHook(p);
-  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_deletearray(void *p) {
-  MallocHook::InvokeDeleteHook(p);
-  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_new_nothrow(
-    size_t size, const std::nothrow_t&) __THROW {
-  return malloc_fast_path<tcmalloc::cpp_nothrow_oom>(size);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_newarray_nothrow(
-    size_t size, const std::nothrow_t&) __THROW {
-  return malloc_fast_path<tcmalloc::cpp_nothrow_oom>(size);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_delete_nothrow(
-    void *p, const std::nothrow_t&) __THROW {
-  MallocHook::InvokeDeleteHook(p);
-  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_deletearray_nothrow(
-    void *p, const std::nothrow_t&) __THROW {
-  MallocHook::InvokeDeleteHook(p);
-  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-
-// _msize() lets you figure out how much space is reserved for a
-// pointer, in Windows.  Even if applications don't call it, any DLL
-// with global constructors will call (transitively) something called
-// __dllonexit_lk in order to make sure the destructors get called
-// when the dll unloads.  And that will call msize -- horrible things
-// can ensue if this is not hooked.  Other parts of libc may also call
-// this internally.
-
-template<int T>
-size_t LibcInfoWithPatchFunctions<T>::Perftools__msize(void* ptr) __THROW {
-  return GetSizeWithCallback(ptr, (size_t (*)(const void*))origstub_fn_[k_Msize]);
-}
-
-// We need to define this because internal windows functions like to
-// call into it(?).  _expand() is like realloc but doesn't move the
-// pointer.  We punt, which will cause callers to fall back on realloc.
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools__expand(void *ptr,
-                                                       size_t size) __THROW {
-  return NULL;
-}
-
-LPVOID WINAPI WindowsInfo::Perftools_HeapAlloc(HANDLE hHeap, DWORD dwFlags,
-                                               DWORD_PTR dwBytes) {
-  LPVOID result = ((LPVOID (WINAPI *)(HANDLE, DWORD, DWORD_PTR))
-                   function_info_[kHeapAlloc].origstub_fn)(
-                       hHeap, dwFlags, dwBytes);
-  MallocHook::InvokeNewHook(result, dwBytes);
-  return result;
-}
-
-BOOL WINAPI WindowsInfo::Perftools_HeapFree(HANDLE hHeap, DWORD dwFlags,
-                                            LPVOID lpMem) {
-  MallocHook::InvokeDeleteHook(lpMem);
-  return ((BOOL (WINAPI *)(HANDLE, DWORD, LPVOID))
-          function_info_[kHeapFree].origstub_fn)(
-              hHeap, dwFlags, lpMem);
-}
-
-LPVOID WINAPI WindowsInfo::Perftools_VirtualAllocEx(HANDLE process,
-                                                    LPVOID address,
-                                                    SIZE_T size, DWORD type,
-                                                    DWORD protect) {
-  LPVOID result = ((LPVOID (WINAPI *)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD))
-                   function_info_[kVirtualAllocEx].origstub_fn)(
-                       process, address, size, type, protect);
-  // VirtualAllocEx() seems to be the Windows equivalent of mmap()
-  MallocHook::InvokeMmapHook(result, address, size, protect, type, -1, 0);
-  return result;
-}
-
-BOOL WINAPI WindowsInfo::Perftools_VirtualFreeEx(HANDLE process, LPVOID address,
-                                                 SIZE_T size, DWORD type) {
-  MallocHook::InvokeMunmapHook(address, size);
-  return ((BOOL (WINAPI *)(HANDLE, LPVOID, SIZE_T, DWORD))
-          function_info_[kVirtualFreeEx].origstub_fn)(
-              process, address, size, type);
-}
-
-LPVOID WINAPI WindowsInfo::Perftools_MapViewOfFileEx(
-    HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,
-    DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress) {
-  // For this function pair, you always deallocate the full block of
-  // data that you allocate, so NewHook/DeleteHook is the right API.
-  LPVOID result = ((LPVOID (WINAPI *)(HANDLE, DWORD, DWORD, DWORD,
-                                      SIZE_T, LPVOID))
-                   function_info_[kMapViewOfFileEx].origstub_fn)(
-                       hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh,
-                       dwFileOffsetLow, dwNumberOfBytesToMap, lpBaseAddress);
-  MallocHook::InvokeNewHook(result, dwNumberOfBytesToMap);
-  return result;
-}
-
-BOOL WINAPI WindowsInfo::Perftools_UnmapViewOfFile(LPCVOID lpBaseAddress) {
-  MallocHook::InvokeDeleteHook(lpBaseAddress);
-  return ((BOOL (WINAPI *)(LPCVOID))
-          function_info_[kUnmapViewOfFile].origstub_fn)(
-              lpBaseAddress);
-}
-
-HMODULE WINAPI WindowsInfo::Perftools_LoadLibraryExW(LPCWSTR lpFileName,
-                                                     HANDLE hFile,
-                                                     DWORD dwFlags) {
-  HMODULE rv;
-  // Check to see if the modules is already loaded, flag 0 gets a
-  // reference if it was loaded.  If it was loaded no need to call
-  // PatchAllModules, just increase the reference count to match
-  // what GetModuleHandleExW does internally inside windows.
-  if (::GetModuleHandleExW(0, lpFileName, &rv)) {
-    return rv;
-  } else {
-    // Not already loaded, so load it.
-    rv = ((HMODULE (WINAPI *)(LPCWSTR, HANDLE, DWORD))
-                  function_info_[kLoadLibraryExW].origstub_fn)(
-                      lpFileName, hFile, dwFlags);
-    // This will patch any newly loaded libraries, if patching needs
-    // to be done.
-    PatchAllModules();
-
-    return rv;
-  }
-}
-
-BOOL WINAPI WindowsInfo::Perftools_FreeLibrary(HMODULE hLibModule) {
-  BOOL rv = ((BOOL (WINAPI *)(HMODULE))
-             function_info_[kFreeLibrary].origstub_fn)(hLibModule);
-
-  // Check to see if the module is still loaded by passing the base
-  // address and seeing if it comes back with the same address.  If it
-  // is the same address it's still loaded, so the FreeLibrary() call
-  // was a noop, and there's no need to redo the patching.
-  HMODULE owner = NULL;
-  BOOL result = ::GetModuleHandleExW(
-      (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
-       GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
-      (LPCWSTR)hLibModule,
-      &owner);
-  if (result && owner == hLibModule)
-    return rv;
-
-  PatchAllModules();    // this will fix up the list of patched libraries
-  return rv;
-}
-
-
-// ---------------------------------------------------------------------
-// PatchWindowsFunctions()
-//    This is the function that is exposed to the outside world.
-//    It should be called before the program becomes multi-threaded,
-//    since main_executable_windows.Patch() is not thread-safe.
-// ---------------------------------------------------------------------
-
-void PatchWindowsFunctions() {
-  // This does the libc patching in every module, and the main executable.
-  PatchAllModules();
-  main_executable_windows.Patch();
-}
-
-#if 0
-// It's possible to unpatch all the functions when we are exiting.
-
-// The idea is to handle properly windows-internal data that is
-// allocated before PatchWindowsFunctions is called.  If all
-// destruction happened in reverse order from construction, then we
-// could call UnpatchWindowsFunctions at just the right time, so that
-// that early-allocated data would be freed using the windows
-// allocation functions rather than tcmalloc.  The problem is that
-// windows allocates some structures lazily, so it would allocate them
-// late (using tcmalloc) and then try to deallocate them late as well.
-// So instead of unpatching, we just modify all the tcmalloc routines
-// so they call through to the libc rountines if the memory in
-// question doesn't seem to have been allocated with tcmalloc.  I keep
-// this unpatch code around for reference.
-
-void UnpatchWindowsFunctions() {
-  // We need to go back to the system malloc/etc at global destruct time,
-  // so objects that were constructed before tcmalloc, using the system
-  // malloc, can destroy themselves using the system free.  This depends
-  // on DLLs unloading in the reverse order in which they load!
-  //
-  // We also go back to the default HeapAlloc/etc, just for consistency.
-  // Who knows, it may help avoid weird bugs in some situations.
-  main_executable_windows.Unpatch();
-  main_executable.Unpatch();
-  if (libc1.is_valid()) libc1.Unpatch();
-  if (libc2.is_valid()) libc2.Unpatch();
-  if (libc3.is_valid()) libc3.Unpatch();
-  if (libc4.is_valid()) libc4.Unpatch();
-  if (libc5.is_valid()) libc5.Unpatch();
-  if (libc6.is_valid()) libc6.Unpatch();
-  if (libc7.is_valid()) libc7.Unpatch();
-  if (libc8.is_valid()) libc8.Unpatch();
-}
-#endif
diff --git a/third_party/tcmalloc/chromium/src/windows/port.cc b/third_party/tcmalloc/chromium/src/windows/port.cc
deleted file mode 100644
index 76224a2..0000000
--- a/third_party/tcmalloc/chromium/src/windows/port.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Craig Silverstein
- */
-
-#ifndef _WIN32
-# error You should only be including windows/port.cc in a windows environment!
-#endif
-
-#define NOMINMAX       // so std::max, below, compiles correctly
-#include <config.h>
-#include <string.h>    // for strlen(), memset(), memcmp()
-#include <assert.h>
-#include <stdarg.h>    // for va_list, va_start, va_end
-#include <algorithm>   // for std:{min,max}
-#include <windows.h>
-#include "port.h"
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "internal_logging.h"
-
-// -----------------------------------------------------------------------
-// Basic libraries
-
-PERFTOOLS_DLL_DECL
-int getpagesize() {
-  static int pagesize = 0;
-  if (pagesize == 0) {
-    SYSTEM_INFO system_info;
-    GetSystemInfo(&system_info);
-    pagesize = std::max(system_info.dwPageSize,
-                        system_info.dwAllocationGranularity);
-  }
-  return pagesize;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* __sbrk(ptrdiff_t increment) {
-  LOG(FATAL, "Windows doesn't implement sbrk!\n");
-  return NULL;
-}
-
-// We need to write to 'stderr' without having windows allocate memory.
-// The safest way is via a low-level call like WriteConsoleA().  But
-// even then we need to be sure to print in small bursts so as to not
-// require memory allocation.
-extern "C" PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len) {
-  // Looks like windows allocates for writes of >80 bytes
-  for (int i = 0; i < len; i += 80) {
-    write(STDERR_FILENO, buf + i, std::min(80, len - i));
-  }
-}
-
-
-// -----------------------------------------------------------------------
-// Threads code
-
-// Windows doesn't support pthread_key_create's destr_function, and in
-// fact it's a bit tricky to get code to run when a thread exits.  This
-// is cargo-cult magic from http://www.codeproject.com/threads/tls.asp.
-// This code is for VC++ 7.1 and later; VC++ 6.0 support is possible
-// but more busy-work -- see the webpage for how to do it.  If all
-// this fails, we could use DllMain instead.  The big problem with
-// DllMain is it doesn't run if this code is statically linked into a
-// binary (it also doesn't run if the thread is terminated via
-// TerminateThread, which if we're lucky this routine does).
-
-// Force a reference to _tls_used to make the linker create the TLS directory
-// if it's not already there (that is, even if __declspec(thread) is not used).
-// Force a reference to p_thread_callback_tcmalloc and p_process_term_tcmalloc
-// to prevent whole program optimization from discarding the variables.
-#ifdef _MSC_VER
-#if defined(_M_IX86)
-#pragma comment(linker, "/INCLUDE:__tls_used")
-#pragma comment(linker, "/INCLUDE:_p_thread_callback_tcmalloc")
-#pragma comment(linker, "/INCLUDE:_p_process_term_tcmalloc")
-#elif defined(_M_X64)
-#pragma comment(linker, "/INCLUDE:_tls_used")
-#pragma comment(linker, "/INCLUDE:p_thread_callback_tcmalloc")
-#pragma comment(linker, "/INCLUDE:p_process_term_tcmalloc")
-#endif
-#endif
-
-// When destr_fn eventually runs, it's supposed to take as its
-// argument the tls-value associated with key that pthread_key_create
-// creates.  (Yeah, it sounds confusing but it's really not.)  We
-// store the destr_fn/key pair in this data structure.  Because we
-// store this in a single var, this implies we can only have one
-// destr_fn in a program!  That's enough in practice.  If asserts
-// trigger because we end up needing more, we'll have to turn this
-// into an array.
-struct DestrFnClosure {
-  void (*destr_fn)(void*);
-  pthread_key_t key_for_destr_fn_arg;
-};
-
-static DestrFnClosure destr_fn_info;   // initted to all NULL/0.
-
-static int on_process_term(void) {
-  if (destr_fn_info.destr_fn) {
-    void *ptr = TlsGetValue(destr_fn_info.key_for_destr_fn_arg);
-    // This shouldn't be necessary, but in Release mode, Windows
-    // sometimes trashes the pointer in the TLS slot, so we need to
-    // remove the pointer from the TLS slot before the thread dies.
-    TlsSetValue(destr_fn_info.key_for_destr_fn_arg, NULL);
-    if (ptr)  // pthread semantics say not to call if ptr is NULL
-      (*destr_fn_info.destr_fn)(ptr);
-  }
-  return 0;
-}
-
-static void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv) {
-  if (dwReason == DLL_THREAD_DETACH) {   // thread is being destroyed!
-    on_process_term();
-  }
-}
-
-#ifdef _MSC_VER
-
-// extern "C" suppresses C++ name mangling so we know the symbol names
-// for the linker /INCLUDE:symbol pragmas above.
-extern "C" {
-// This tells the linker to run these functions.
-#pragma data_seg(push, old_seg)
-#pragma data_seg(".CRT$XLB")
-void (NTAPI *p_thread_callback_tcmalloc)(
-    HINSTANCE h, DWORD dwReason, PVOID pv) = on_tls_callback;
-#pragma data_seg(".CRT$XTU")
-int (*p_process_term_tcmalloc)(void) = on_process_term;
-#pragma data_seg(pop, old_seg)
-}  // extern "C"
-
-#else  // #ifdef _MSC_VER  [probably msys/mingw]
-
-// We have to try the DllMain solution here, because we can't use the
-// msvc-specific pragmas.
-BOOL WINAPI DllMain(HINSTANCE h, DWORD dwReason, PVOID pv) {
-  if (dwReason == DLL_THREAD_DETACH)
-    on_tls_callback(h, dwReason, pv);
-  else if (dwReason == DLL_PROCESS_DETACH)
-    on_process_term();
-  return TRUE;
-}
-
-#endif  // #ifdef _MSC_VER
-
-extern "C" pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)) {
-  // Semantics are: we create a new key, and then promise to call
-  // destr_fn with TlsGetValue(key) when the thread is destroyed
-  // (as long as TlsGetValue(key) is not NULL).
-  pthread_key_t key = TlsAlloc();
-  if (destr_fn) {   // register it
-    // If this assert fails, we'll need to support an array of destr_fn_infos
-    assert(destr_fn_info.destr_fn == NULL);
-    destr_fn_info.destr_fn = destr_fn;
-    destr_fn_info.key_for_destr_fn_arg = key;
-  }
-  return key;
-}
-
-// NOTE: this is Win2K and later.  For Win98 we could use a CRITICAL_SECTION...
-extern "C" int perftools_pthread_once(pthread_once_t *once_control,
-                                      void (*init_routine)(void)) {
-  // Try for a fast path first. Note: this should be an acquire semantics read.
-  // It is on x86 and x64, where Windows runs.
-  if (*once_control != 1) {
-    while (true) {
-      switch (InterlockedCompareExchange(once_control, 2, 0)) {
-        case 0:
-          init_routine();
-          InterlockedExchange(once_control, 1);
-          return 0;
-        case 1:
-          // The initializer has already been executed
-          return 0;
-        default:
-          // The initializer is being processed by another thread
-          SwitchToThread();
-      }
-    }
-  }
-  return 0;
-}
-
-
-// -----------------------------------------------------------------------
-// These functions rework existing functions of the same name in the
-// Google codebase.
-
-// A replacement for HeapProfiler::CleanupOldProfiles.
-void DeleteMatchingFiles(const char* prefix, const char* full_glob) {
-  WIN32_FIND_DATAA found;  // that final A is for Ansi (as opposed to Unicode)
-  HANDLE hFind = FindFirstFileA(full_glob, &found);   // A is for Ansi
-  if (hFind != INVALID_HANDLE_VALUE) {
-    const int prefix_length = strlen(prefix);
-    do {
-      const char *fname = found.cFileName;
-      if ((strlen(fname) >= prefix_length) &&
-          (memcmp(fname, prefix, prefix_length) == 0)) {
-        RAW_VLOG(0, "Removing old heap profile %s\n", fname);
-        // TODO(csilvers): we really need to unlink dirname + fname
-        _unlink(fname);
-      }
-    } while (FindNextFileA(hFind, &found) != FALSE);  // A is for Ansi
-    FindClose(hFind);
-  }
-}
diff --git a/third_party/tcmalloc/chromium/src/windows/port.h b/third_party/tcmalloc/chromium/src/windows/port.h
deleted file mode 100644
index eb9702b..0000000
--- a/third_party/tcmalloc/chromium/src/windows/port.h
+++ /dev/null
@@ -1,499 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Craig Silverstein
- *
- * These are some portability typedefs and defines to make it a bit
- * easier to compile this code under VC++.
- *
- * Several of these are taken from glib:
- *    http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
- */
-
-#ifndef GOOGLE_BASE_WINDOWS_H_
-#define GOOGLE_BASE_WINDOWS_H_
-
-/* You should never include this file directly, but always include it
-   from either config.h (MSVC) or mingw.h (MinGW/msys). */
-#if !defined(GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_) && \
-    !defined(GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_)
-# error "port.h should only be included from config.h or mingw.h"
-#endif
-
-#ifdef _WIN32
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */
-#endif
-#include <windows.h>
-#include <io.h>              /* because we so often use open/close/etc */
-#include <direct.h>          /* for _getcwd */
-#include <process.h>         /* for _getpid */
-#include <limits.h>          /* for PATH_MAX */
-#include <stdarg.h>          /* for va_list */
-#include <stdio.h>           /* need this to override stdio's (v)snprintf */
-#include <sys/types.h>       /* for _off_t */
-#include <assert.h>
-#include <stdlib.h>          /* for rand, srand, _strtoxxx */
-
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-#define _TIMESPEC_DEFINED
-#include <time.h>
-#endif
-
-/*
- * 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i)
- * 4244: otherwise we get problems when subtracting two size_t's to an int
- * 4288: VC++7 gets confused when a var is defined in a loop and then after it
- * 4267: too many false positives for "conversion gives possible data loss"
- * 4290: it's ok windows ignores the "throw" directive
- * 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv()
- * 4146: internal_logging.cc intentionally negates an unsigned value
- */
-#ifdef _MSC_VER
-#pragma warning(disable:4018 4244 4288 4267 4290 4996 4146)
-#endif
-
-#ifndef __cplusplus
-/* MSVC does not support C99 */
-# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
-#  ifdef _MSC_VER
-#    define inline __inline
-#  else
-#    define inline static
-#  endif
-# endif
-#endif
-
-#ifdef __cplusplus
-# define EXTERN_C  extern "C"
-#else
-# define EXTERN_C  extern
-#endif
-
-/* ----------------------------------- BASIC TYPES */
-
-#ifndef HAVE_STDINT_H
-#ifndef HAVE___INT64    /* we need to have all the __intX names */
-# error  Do not know how to set up type aliases.  Edit port.h for your system.
-#endif
-
-typedef __int8 int8_t;
-typedef __int16 int16_t;
-typedef __int32 int32_t;
-typedef __int64 int64_t;
-typedef unsigned __int8 uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
-#endif  /* #ifndef HAVE_STDINT_H */
-
-/* I guess MSVC's <types.h> doesn't include ssize_t by default? */
-#ifdef _MSC_VER
-typedef intptr_t ssize_t;
-#endif
-
-/* ----------------------------------- THREADS */
-
-#ifndef HAVE_PTHREAD   /* not true for MSVC, but may be true for MSYS */
-typedef DWORD pthread_t;
-typedef DWORD pthread_key_t;
-typedef LONG pthread_once_t;
-enum { PTHREAD_ONCE_INIT = 0 };   /* important that this be 0! for SpinLock */
-
-inline pthread_t pthread_self(void) {
-  return GetCurrentThreadId();
-}
-
-#ifdef __cplusplus
-inline bool pthread_equal(pthread_t left, pthread_t right) {
-  return left == right;
-}
-
-/*
- * windows/port.h defines compatibility APIs for several .h files, which
- * we therefore shouldn't be #including directly.  This hack keeps us from
- * doing so.  TODO(csilvers): do something more principled.
- */
-#define GOOGLE_MAYBE_THREADS_H_ 1
-/* This replaces maybe_threads.{h,cc} */
-
-EXTERN_C pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*));  /* port.cc */
-
-inline int perftools_pthread_key_create(pthread_key_t *pkey,
-                                        void (*destructor)(void*)) {
-  pthread_key_t key = PthreadKeyCreate(destructor);
-  if (key != TLS_OUT_OF_INDEXES) {
-    *(pkey) = key;
-    return 0;
-  } else {
-    return GetLastError();
-  }
-}
-
-inline void* perftools_pthread_getspecific(DWORD key) {
-  DWORD err = GetLastError();
-  void* rv = TlsGetValue(key);
-  if (err) SetLastError(err);
-  return rv;
-}
-
-inline int perftools_pthread_setspecific(pthread_key_t key, const void *value) {
-  if (TlsSetValue(key, (LPVOID)value))
-    return 0;
-  else
-    return GetLastError();
-}
-
-EXTERN_C int perftools_pthread_once(pthread_once_t *once_control,
-                                    void (*init_routine)(void));
-
-#endif  /* __cplusplus */
-
-inline void sched_yield(void) {
-  Sleep(0);
-}
-
-#endif  /* HAVE_PTHREAD */
-
-/*
- * __declspec(thread) isn't usable in a dll opened via LoadLibrary().
- * But it doesn't work to LoadLibrary() us anyway, because of all the
- * things we need to do before main()!  So this kind of TLS is safe for us.
- */
-#define __thread __declspec(thread)
-
-/*
- * This code is obsolete, but I keep it around in case we are ever in
- * an environment where we can't or don't want to use google spinlocks
- * (from base/spinlock.{h,cc}).  In that case, uncommenting this out,
- * and removing spinlock.cc from the build, should be enough to revert
- * back to using native spinlocks.
- */
-#if 0
-// Windows uses a spinlock internally for its mutexes, making our life easy!
-// However, the Windows spinlock must always be initialized, making life hard,
-// since we want LINKER_INITIALIZED.  We work around this by having the
-// linker initialize a bool to 0, and check that before accessing the mutex.
-// This replaces spinlock.{h,cc}, and all the stuff it depends on (atomicops)
-#ifdef __cplusplus
-class SpinLock {
- public:
-  SpinLock() : initialize_token_(PTHREAD_ONCE_INIT) {}
-  // Used for global SpinLock vars (see base/spinlock.h for more details).
-  enum StaticInitializer { LINKER_INITIALIZED };
-  explicit SpinLock(StaticInitializer) : initialize_token_(PTHREAD_ONCE_INIT) {
-    perftools_pthread_once(&initialize_token_, InitializeMutex);
-  }
-
-  // It's important SpinLock not have a destructor: otherwise we run
-  // into problems when the main thread has exited, but other threads
-  // are still running and try to access a main-thread spinlock.  This
-  // means we leak mutex_ (we should call DeleteCriticalSection()
-  // here).  However, I've verified that all SpinLocks used in
-  // perftools have program-long scope anyway, so the leak is
-  // perfectly fine.  But be aware of this for the future!
-
-  void Lock() {
-    // You'd thionk this would be unnecessary, since we call
-    // InitializeMutex() in our constructor.  But sometimes Lock() can
-    // be called before our constructor is!  This can only happen in
-    // global constructors, when this is a global.  If we live in
-    // bar.cc, and some global constructor in foo.cc calls a routine
-    // in bar.cc that calls this->Lock(), then Lock() may well run
-    // before our global constructor does.  To protect against that,
-    // we do this check.  For SpinLock objects created after main()
-    // has started, this pthread_once call will always be a noop.
-    perftools_pthread_once(&initialize_token_, InitializeMutex);
-    EnterCriticalSection(&mutex_);
-  }
-  void Unlock() {
-    LeaveCriticalSection(&mutex_);
-  }
-
-  // Used in assertion checks: assert(lock.IsHeld()) (see base/spinlock.h).
-  inline bool IsHeld() const {
-    // This works, but probes undocumented internals, so I've commented it out.
-    // c.f. http://msdn.microsoft.com/msdnmag/issues/03/12/CriticalSections/
-    //return mutex_.LockCount>=0 && mutex_.OwningThread==GetCurrentThreadId();
-    return true;
-  }
- private:
-  void InitializeMutex() { InitializeCriticalSection(&mutex_); }
-
-  pthread_once_t initialize_token_;
-  CRITICAL_SECTION mutex_;
-};
-
-class SpinLockHolder {  // Acquires a spinlock for as long as the scope lasts
- private:
-  SpinLock* lock_;
- public:
-  inline explicit SpinLockHolder(SpinLock* l) : lock_(l) { l->Lock(); }
-  inline ~SpinLockHolder() { lock_->Unlock(); }
-};
-#endif  // #ifdef __cplusplus
-
-// This keeps us from using base/spinlock.h's implementation of SpinLock.
-#define BASE_SPINLOCK_H_ 1
-
-#endif  /* #if 0 */
-
-/* ----------------------------------- MMAP and other memory allocation */
-
-#ifndef HAVE_MMAP   /* not true for MSVC, but may be true for msys */
-#define MAP_FAILED  0
-#define MREMAP_FIXED  2  /* the value in linux, though it doesn't really matter */
-/* These, when combined with the mmap invariants below, yield the proper action */
-#define PROT_READ      PAGE_READWRITE
-#define PROT_WRITE     PAGE_READWRITE
-#define MAP_ANONYMOUS  MEM_RESERVE
-#define MAP_PRIVATE    MEM_COMMIT
-#define MAP_SHARED     MEM_RESERVE   /* value of this #define is 100% arbitrary */
-
-#if __STDC__ && !defined(__MINGW32__)
-typedef _off_t off_t;
-#endif
-
-/* VirtualAlloc only replaces for mmap when certain invariants are kept. */
-inline void *mmap(void *addr, size_t length, int prot, int flags,
-                  int fd, off_t offset) {
-  if (addr == NULL && fd == -1 && offset == 0 &&
-      prot == (PROT_READ|PROT_WRITE) && flags == (MAP_PRIVATE|MAP_ANONYMOUS)) {
-    return VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
-  } else {
-    return NULL;
-  }
-}
-
-inline int munmap(void *addr, size_t length) {
-  return VirtualFree(addr, 0, MEM_RELEASE) ? 0 : -1;
-}
-#endif  /* HAVE_MMAP */
-
-/* We could maybe use VirtualAlloc for sbrk as well, but no need */
-inline void *sbrk(intptr_t increment) {
-  // sbrk returns -1 on failure
-  return (void*)-1;
-}
-
-
-/* ----------------------------------- STRING ROUTINES */
-
-/*
- * We can't just use _vsnprintf and _snprintf as drop-in-replacements,
- * because they don't always NUL-terminate. :-(  We also can't use the
- * name vsnprintf, since windows defines that (but not snprintf (!)).
- */
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-/* We can use safe CRT functions, which the required functionality */
-inline int perftools_vsnprintf(char *str, size_t size, const char *format,
-                               va_list ap) {
-  return vsnprintf_s(str, size, _TRUNCATE, format, ap);
-}
-#else
-inline int perftools_vsnprintf(char *str, size_t size, const char *format,
-                               va_list ap) {
-  if (size == 0)        /* not even room for a \0? */
-    return -1;        /* not what C99 says to do, but what windows does */
-  str[size-1] = '\0';
-  return _vsnprintf(str, size-1, format, ap);
-}
-#endif
-
-#ifndef HAVE_SNPRINTF
-inline int snprintf(char *str, size_t size, const char *format, ...) {
-  va_list ap;
-  int r;
-  va_start(ap, format);
-  r = perftools_vsnprintf(str, size, format, ap);
-  va_end(ap);
-  return r;
-}
-#endif
-
-#ifndef HAVE_INTTYPES_H
-#define PRIx64  "I64x"
-#define SCNx64  "I64x"
-#define PRId64  "I64d"
-#define SCNd64  "I64d"
-#define PRIu64  "I64u"
-#ifdef _WIN64
-# define PRIuPTR "llu"
-# define PRIxPTR "llx"
-#else
-# define PRIuPTR "lu"
-# define PRIxPTR "lx"
-#endif
-#endif
-
-/* ----------------------------------- FILE IO */
-
-#ifndef PATH_MAX
-#define PATH_MAX 1024
-#endif
-#ifndef __MINGW32__
-enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
-#endif
-#ifndef O_RDONLY
-#define O_RDONLY  _O_RDONLY
-#endif
-
-#if __STDC__ && !defined(__MINGW32__)
-/* These functions are considered non-standard */
-inline int access(const char *pathname, int mode) {
-  return _access(pathname, mode);
-}
-inline int open(const char *pathname, int flags, int mode = 0) {
-  return _open(pathname, flags, mode);
-}
-inline int close(int fd) {
-  return _close(fd);
-}
-inline ssize_t read(int fd, void *buf, size_t count) {
-  return _read(fd, buf, count);
-}
-inline ssize_t write(int fd, const void *buf, size_t count) {
-  return _write(fd, buf, count);
-}
-inline off_t lseek(int fd, off_t offset, int whence) {
-  return _lseek(fd, offset, whence);
-}
-inline char *getcwd(char *buf, size_t size) {
-  return _getcwd(buf, size);
-}
-inline int mkdir(const char *pathname, int) {
-  return _mkdir(pathname);
-}
-
-inline FILE *popen(const char *command, const char *type) {
-  return _popen(command, type);
-}
-inline int pclose(FILE *stream) {
-  return _pclose(stream);
-}
-#endif
-
-EXTERN_C PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len);
-
-/* ----------------------------------- SYSTEM/PROCESS */
-
-#ifndef HAVE_PID_T
-typedef int pid_t;
-#endif
-
-#if __STDC__ && !defined(__MINGW32__)
-inline pid_t getpid(void) { return _getpid(); }
-#endif
-inline pid_t getppid(void) { return 0; }
-
-/* Handle case when poll is used to simulate sleep. */
-inline int poll(struct pollfd* fds, int nfds, int timeout) {
-  assert(fds == NULL);
-  assert(nfds == 0);
-  Sleep(timeout);
-  return 0;
-}
-
-EXTERN_C PERFTOOLS_DLL_DECL int getpagesize();   /* in port.cc */
-
-/* ----------------------------------- OTHER */
-
-inline void srandom(unsigned int seed) { srand(seed); }
-inline long random(void) { return rand(); }
-
-#ifndef HAVE_DECL_SLEEP
-#define HAVE_DECL_SLEEP 0
-#endif
-
-#if !HAVE_DECL_SLEEP
-inline unsigned int sleep(unsigned int seconds) {
-  Sleep(seconds * 1000);
-  return 0;
-}
-#endif
-
-// mingw64 seems to define timespec (though mingw.org mingw doesn't),
-// protected by the _TIMESPEC_DEFINED macro.
-#ifndef _TIMESPEC_DEFINED
-struct timespec {
-  int tv_sec;
-  int tv_nsec;
-};
-#endif
-
-#ifndef HAVE_DECL_NANOSLEEP
-#define HAVE_DECL_NANOSLEEP 0
-#endif
-
-// latest mingw64 has nanosleep. Earlier mingw and MSVC do not
-#if !HAVE_DECL_NANOSLEEP
-inline int nanosleep(const struct timespec *req, struct timespec *rem) {
-  Sleep(req->tv_sec * 1000 + req->tv_nsec / 1000000);
-  return 0;
-}
-#endif
-
-#ifndef __MINGW32__
-#if defined(_MSC_VER) && _MSC_VER < 1800
-inline long long int strtoll(const char *nptr, char **endptr, int base) {
-    return _strtoi64(nptr, endptr, base);
-}
-inline unsigned long long int strtoull(const char *nptr, char **endptr,
-                                       int base) {
-    return _strtoui64(nptr, endptr, base);
-}
-inline long long int strtoq(const char *nptr, char **endptr, int base) {
-    return _strtoi64(nptr, endptr, base);
-}
-#endif
-inline unsigned long long int strtouq(const char *nptr, char **endptr,
-                                      int base) {
-    return _strtoui64(nptr, endptr, base);
-}
-inline long long atoll(const char *nptr) {
-  return _atoi64(nptr);
-}
-#endif
-
-#define __THROW throw()
-
-/* ----------------------------------- TCMALLOC-SPECIFIC */
-
-/* tcmalloc.cc calls this so we can patch VirtualAlloc() et al. */
-extern void PatchWindowsFunctions();
-
-#endif  /* _WIN32 */
-
-#undef inline
-#undef EXTERN_C
-
-#endif  /* GOOGLE_BASE_WINDOWS_H_ */
diff --git a/third_party/tcmalloc/chromium/src/windows/preamble_patcher.cc b/third_party/tcmalloc/chromium/src/windows/preamble_patcher.cc
deleted file mode 100644
index 9ce08168..0000000
--- a/third_party/tcmalloc/chromium/src/windows/preamble_patcher.cc
+++ /dev/null
@@ -1,736 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- * Author: Scott Francis
- *
- * Implementation of PreamblePatcher
- */
-
-#include "preamble_patcher.h"
-
-#include "mini_disassembler.h"
-
-// compatibility shims
-#include "base/logging.h"
-
-// Definitions of assembly statements we need
-#define ASM_JMP32REL 0xE9
-#define ASM_INT3 0xCC
-#define ASM_JMP32ABS_0 0xFF
-#define ASM_JMP32ABS_1 0x25
-#define ASM_JMP8REL 0xEB
-#define ASM_JCC32REL_0 0x0F
-#define ASM_JCC32REL_1_MASK 0x80
-#define ASM_NOP 0x90
-// X64 opcodes
-#define ASM_REXW 0x48
-#define ASM_MOVRAX_IMM 0xB8
-#define ASM_JMP 0xFF
-#define ASM_JMP_RAX 0xE0
-
-namespace sidestep {
-
-PreamblePatcher::PreamblePage* PreamblePatcher::preamble_pages_ = NULL;
-long PreamblePatcher::granularity_ = 0;
-long PreamblePatcher::pagesize_ = 0;
-bool PreamblePatcher::initialized_ = false;
-
-static const unsigned int kPreamblePageMagic = 0x4347414D; // "MAGC"
-
-// Handle a special case that we see with functions that point into an
-// IAT table (including functions linked statically into the
-// application): these function already starts with ASM_JMP32*.  For
-// instance, malloc() might be implemented as a JMP to __malloc().
-// This function follows the initial JMPs for us, until we get to the
-// place where the actual code is defined.  If we get to STOP_BEFORE,
-// we return the address before stop_before.  The stop_before_trampoline
-// flag is used in 64-bit mode.  If true, we will return the address
-// before a trampoline is detected.  Trampolines are defined as:
-//
-//    nop
-//    mov rax, <replacement_function>
-//    jmp rax
-//
-// See PreamblePatcher::RawPatchWithStub for more information.
-void* PreamblePatcher::ResolveTargetImpl(unsigned char* target,
-                                         unsigned char* stop_before,
-                                         bool stop_before_trampoline) {
-  if (target == NULL)
-    return NULL;
-  while (1) {
-    unsigned char* new_target;
-    if (target[0] == ASM_JMP32REL) {
-      // target[1-4] holds the place the jmp goes to, but it's
-      // relative to the next instruction.
-      int relative_offset;   // Windows guarantees int is 4 bytes
-      SIDESTEP_ASSERT(sizeof(relative_offset) == 4);
-      memcpy(reinterpret_cast<void*>(&relative_offset),
-             reinterpret_cast<void*>(target + 1), 4);
-      new_target = target + 5 + relative_offset;
-    } else if (target[0] == ASM_JMP8REL) {
-      // Visual Studio 7.1 implements new[] as an 8 bit jump to new
-      signed char relative_offset;
-      memcpy(reinterpret_cast<void*>(&relative_offset),
-             reinterpret_cast<void*>(target + 1), 1);
-      new_target = target + 2 + relative_offset;
-    } else if (target[0] == ASM_JMP32ABS_0 &&
-               target[1] == ASM_JMP32ABS_1) {
-    jmp32rel:
-      // Visual studio seems to sometimes do it this way instead of the
-      // previous way.  Not sure what the rules are, but it was happening
-      // with operator new in some binaries.
-      void** new_target_v;
-      if (kIs64BitBinary) {
-        // In 64-bit mode JMPs are RIP-relative, not absolute
-        int target_offset;
-        memcpy(reinterpret_cast<void*>(&target_offset),
-               reinterpret_cast<void*>(target + 2), 4);
-        new_target_v = reinterpret_cast<void**>(target + target_offset + 6);
-      } else {
-        SIDESTEP_ASSERT(sizeof(new_target) == 4);
-        memcpy(&new_target_v, reinterpret_cast<void*>(target + 2), 4);
-      }
-      new_target = reinterpret_cast<unsigned char*>(*new_target_v);
-    } else if (kIs64BitBinary && target[0] == ASM_REXW
-               && target[1] == ASM_JMP32ABS_0
-               && target[2] == ASM_JMP32ABS_1) {
-      // in Visual Studio 2012 we're seeing jump like that:
-      //   rex.W jmpq *0x11d019(%rip)
-      //
-      // according to docs I have, rex prefix is actually unneeded and
-      // can be ignored. I.e. docs say for jumps like that operand
-      // already defaults to 64-bit. But clearly it breaks abs. jump
-      // detection above and we just skip rex
-      target++;
-      goto jmp32rel;
-    } else {
-      break;
-    }
-    if (new_target == stop_before)
-      break;
-    if (stop_before_trampoline && *new_target == ASM_NOP
-        && new_target[1] == ASM_REXW && new_target[2] == ASM_MOVRAX_IMM)
-      break;
-    target = new_target;
-  }
-  return target;
-}
-
-// Special case scoped_ptr to avoid dependency on scoped_ptr below.
-class DeleteUnsignedCharArray {
- public:
-  DeleteUnsignedCharArray(unsigned char* array) : array_(array) {
-  }
-
-  ~DeleteUnsignedCharArray() {
-    if (array_) {
-      PreamblePatcher::FreePreambleBlock(array_);
-    }
-  }
-
-  unsigned char* Release() {
-    unsigned char* temp = array_;
-    array_ = NULL;
-    return temp;
-  }
-
- private:
-  unsigned char* array_;
-};
-
-SideStepError PreamblePatcher::RawPatchWithStubAndProtections(
-    void* target_function, void *replacement_function,
-    unsigned char* preamble_stub, unsigned long stub_size,
-    unsigned long* bytes_needed) {
-  // We need to be able to write to a process-local copy of the first
-  // MAX_PREAMBLE_STUB_SIZE bytes of target_function
-  DWORD old_target_function_protect = 0;
-  BOOL succeeded = ::VirtualProtect(reinterpret_cast<void*>(target_function),
-                                    MAX_PREAMBLE_STUB_SIZE,
-                                    PAGE_EXECUTE_READWRITE,
-                                    &old_target_function_protect);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to make page containing target function "
-                    "copy-on-write.");
-    return SIDESTEP_ACCESS_DENIED;
-  }
-
-  SideStepError error_code = RawPatchWithStub(target_function,
-                                              replacement_function,
-                                              preamble_stub,
-                                              stub_size,
-                                              bytes_needed);
-
-  // Restore the protection of the first MAX_PREAMBLE_STUB_SIZE bytes of
-  // pTargetFunction to what they were before we started goofing around.
-  // We do this regardless of whether the patch succeeded or not.
-  succeeded = ::VirtualProtect(reinterpret_cast<void*>(target_function),
-                               MAX_PREAMBLE_STUB_SIZE,
-                               old_target_function_protect,
-                               &old_target_function_protect);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false &&
-                    "Failed to restore protection to target function.");
-    // We must not return an error here because the function has
-    // likely actually been patched, and returning an error might
-    // cause our client code not to unpatch it.  So we just keep
-    // going.
-  }
-
-  if (SIDESTEP_SUCCESS != error_code) {  // Testing RawPatchWithStub, above
-    SIDESTEP_ASSERT(false);
-    return error_code;
-  }
-
-  // Flush the instruction cache to make sure the processor doesn't execute the
-  // old version of the instructions (before our patch).
-  //
-  // FlushInstructionCache is actually a no-op at least on
-  // single-processor XP machines.  I'm not sure why this is so, but
-  // it is, yet I want to keep the call to the API here for
-  // correctness in case there is a difference in some variants of
-  // Windows/hardware.
-  succeeded = ::FlushInstructionCache(::GetCurrentProcess(),
-                                      target_function,
-                                      MAX_PREAMBLE_STUB_SIZE);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to flush instruction cache.");
-    // We must not return an error here because the function has actually
-    // been patched, and returning an error would likely cause our client
-    // code not to unpatch it.  So we just keep going.
-  }
-
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::RawPatch(void* target_function,
-                                        void* replacement_function,
-                                        void** original_function_stub) {
-  if (!target_function || !replacement_function || !original_function_stub ||
-      (*original_function_stub) || target_function == replacement_function) {
-    SIDESTEP_ASSERT(false && "Preconditions not met");
-    return SIDESTEP_INVALID_PARAMETER;
-  }
-
-  BOOL succeeded = FALSE;
-
-  // First, deal with a special case that we see with functions that
-  // point into an IAT table (including functions linked statically
-  // into the application): these function already starts with
-  // ASM_JMP32REL.  For instance, malloc() might be implemented as a
-  // JMP to __malloc().  In that case, we replace the destination of
-  // the JMP (__malloc), rather than the JMP itself (malloc).  This
-  // way we get the correct behavior no matter how malloc gets called.
-  void* new_target = ResolveTarget(target_function);
-  if (new_target != target_function) {
-    target_function = new_target;
-  }
-
-  // In 64-bit mode, preamble_stub must be within 2GB of target function
-  // so that if target contains a jump, we can translate it.
-  unsigned char* preamble_stub = AllocPreambleBlockNear(target_function);
-  if (!preamble_stub) {
-    SIDESTEP_ASSERT(false && "Unable to allocate preamble-stub.");
-    return SIDESTEP_INSUFFICIENT_BUFFER;
-  }
-
-  // Frees the array at end of scope.
-  DeleteUnsignedCharArray guard_preamble_stub(preamble_stub);
-
-  SideStepError error_code = RawPatchWithStubAndProtections(
-      target_function, replacement_function, preamble_stub,
-      MAX_PREAMBLE_STUB_SIZE, NULL);
-
-  if (SIDESTEP_SUCCESS != error_code) {
-    SIDESTEP_ASSERT(false);
-    return error_code;
-  }
-
-  // Flush the instruction cache to make sure the processor doesn't execute the
-  // old version of the instructions (before our patch).
-  //
-  // FlushInstructionCache is actually a no-op at least on
-  // single-processor XP machines.  I'm not sure why this is so, but
-  // it is, yet I want to keep the call to the API here for
-  // correctness in case there is a difference in some variants of
-  // Windows/hardware.
-  succeeded = ::FlushInstructionCache(::GetCurrentProcess(),
-                                      target_function,
-                                      MAX_PREAMBLE_STUB_SIZE);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to flush instruction cache.");
-    // We must not return an error here because the function has actually
-    // been patched, and returning an error would likely cause our client
-    // code not to unpatch it.  So we just keep going.
-  }
-
-  SIDESTEP_LOG("PreamblePatcher::RawPatch successfully patched.");
-
-  // detach the scoped pointer so the memory is not freed
-  *original_function_stub =
-      reinterpret_cast<void*>(guard_preamble_stub.Release());
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::Unpatch(void* target_function,
-                                       void* replacement_function,
-                                       void* original_function_stub) {
-  SIDESTEP_ASSERT(target_function && replacement_function &&
-                  original_function_stub);
-  if (!target_function || !replacement_function ||
-      !original_function_stub) {
-    return SIDESTEP_INVALID_PARAMETER;
-  }
-
-  // Before unpatching, target_function should be a JMP to
-  // replacement_function.  If it's not, then either it's an error, or
-  // we're falling into the case where the original instruction was a
-  // JMP, and we patched the jumped_to address rather than the JMP
-  // itself.  (For instance, if malloc() is just a JMP to __malloc(),
-  // we patched __malloc() and not malloc().)
-  unsigned char* target = reinterpret_cast<unsigned char*>(target_function);
-  target = reinterpret_cast<unsigned char*>(
-      ResolveTargetImpl(
-          target, reinterpret_cast<unsigned char*>(replacement_function),
-          true));
-  // We should end at the function we patched.  When we patch, we insert
-  // a ASM_JMP32REL instruction, so look for that as a sanity check.
-  if (target[0] != ASM_JMP32REL) {
-    SIDESTEP_ASSERT(false &&
-                    "target_function does not look like it was patched.");
-    return SIDESTEP_INVALID_PARAMETER;
-  }
-
-  const unsigned int kRequiredTargetPatchBytes = 5;
-
-  // We need to be able to write to a process-local copy of the first
-  // kRequiredTargetPatchBytes bytes of target_function
-  DWORD old_target_function_protect = 0;
-  BOOL succeeded = ::VirtualProtect(reinterpret_cast<void*>(target),
-                                    kRequiredTargetPatchBytes,
-                                    PAGE_EXECUTE_READWRITE,
-                                    &old_target_function_protect);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to make page containing target function "
-                    "copy-on-write.");
-    return SIDESTEP_ACCESS_DENIED;
-  }
-
-  unsigned char* preamble_stub = reinterpret_cast<unsigned char*>(
-                                   original_function_stub);
-
-  // Disassemble the preamble of stub and copy the bytes back to target.
-  // If we've done any conditional jumps in the preamble we need to convert
-  // them back to the original REL8 jumps in the target.
-  MiniDisassembler disassembler;
-  unsigned int preamble_bytes = 0;
-  unsigned int target_bytes = 0;
-  while (target_bytes < kRequiredTargetPatchBytes) {
-    unsigned int cur_bytes = 0;
-    InstructionType instruction_type =
-        disassembler.Disassemble(preamble_stub + preamble_bytes, cur_bytes);
-    if (IT_JUMP == instruction_type) {
-      unsigned int jump_bytes = 0;
-      SideStepError jump_ret = SIDESTEP_JUMP_INSTRUCTION;
-      if (IsNearConditionalJump(preamble_stub + preamble_bytes, cur_bytes) ||
-          IsNearRelativeJump(preamble_stub + preamble_bytes, cur_bytes) ||
-          IsNearAbsoluteCall(preamble_stub + preamble_bytes, cur_bytes) ||
-          IsNearRelativeCall(preamble_stub + preamble_bytes, cur_bytes)) {
-        jump_ret = PatchNearJumpOrCall(preamble_stub + preamble_bytes, 
-                                       cur_bytes, target + target_bytes, 
-                                       &jump_bytes, MAX_PREAMBLE_STUB_SIZE);
-      }
-      if (jump_ret == SIDESTEP_JUMP_INSTRUCTION) {
-        SIDESTEP_ASSERT(false &&
-                        "Found unsupported jump instruction in stub!!");
-        return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-      }
-      target_bytes += jump_bytes;
-    } else if (IT_GENERIC == instruction_type) {
-      if (IsMovWithDisplacement(preamble_stub + preamble_bytes, cur_bytes)) {
-        unsigned int mov_bytes = 0;
-        if (PatchMovWithDisplacement(preamble_stub + preamble_bytes, cur_bytes,
-                                     target + target_bytes, &mov_bytes,
-                                     MAX_PREAMBLE_STUB_SIZE)
-                                     != SIDESTEP_SUCCESS) {
-          SIDESTEP_ASSERT(false &&
-                          "Found unsupported generic instruction in stub!!");
-          return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-        }
-      } else {
-        memcpy(reinterpret_cast<void*>(target + target_bytes),
-               reinterpret_cast<void*>(reinterpret_cast<unsigned char*>(
-                   original_function_stub) + preamble_bytes), cur_bytes);
-        target_bytes += cur_bytes;
-      }
-    } else {
-      SIDESTEP_ASSERT(false &&
-                      "Found unsupported instruction in stub!!");
-      return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-    }
-    preamble_bytes += cur_bytes;
-  }
-
-  FreePreambleBlock(reinterpret_cast<unsigned char*>(original_function_stub));
-
-  // Restore the protection of the first kRequiredTargetPatchBytes bytes of
-  // target to what they were before we started goofing around.
-  succeeded = ::VirtualProtect(reinterpret_cast<void*>(target),
-                               kRequiredTargetPatchBytes,
-                               old_target_function_protect,
-                               &old_target_function_protect);
-
-  // Flush the instruction cache to make sure the processor doesn't execute the
-  // old version of the instructions (before our patch).
-  //
-  // See comment on FlushInstructionCache elsewhere in this file.
-  succeeded = ::FlushInstructionCache(::GetCurrentProcess(),
-                                      target,
-                                      MAX_PREAMBLE_STUB_SIZE);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to flush instruction cache.");
-    return SIDESTEP_UNEXPECTED;
-  }
-
-  SIDESTEP_LOG("PreamblePatcher::Unpatch successfully unpatched.");
-  return SIDESTEP_SUCCESS;
-}
-
-void PreamblePatcher::Initialize() {
-  if (!initialized_) {
-    SYSTEM_INFO si = { 0 };
-    ::GetSystemInfo(&si);
-    granularity_ = si.dwAllocationGranularity;
-    pagesize_ = si.dwPageSize;
-    initialized_ = true;
-  }
-}
-
-unsigned char* PreamblePatcher::AllocPreambleBlockNear(void* target) {
-  PreamblePage* preamble_page = preamble_pages_;
-  while (preamble_page != NULL) {
-    if (preamble_page->free_ != NULL) {
-      __int64 val = reinterpret_cast<__int64>(preamble_page) -
-          reinterpret_cast<__int64>(target);
-      if ((val > 0 && val + pagesize_ <= INT_MAX) ||
-          (val < 0 && val >= INT_MIN)) {
-        break;
-      }
-    }
-    preamble_page = preamble_page->next_;
-  }
-
-  // The free_ member of the page is used to store the next available block
-  // of memory to use or NULL if there are no chunks available, in which case
-  // we'll allocate a new page.
-  if (preamble_page == NULL || preamble_page->free_ == NULL) {
-    // Create a new preamble page and initialize the free list
-    preamble_page = reinterpret_cast<PreamblePage*>(AllocPageNear(target));
-    SIDESTEP_ASSERT(preamble_page != NULL && "Could not allocate page!");
-    void** pp = &preamble_page->free_;
-    unsigned char* ptr = reinterpret_cast<unsigned char*>(preamble_page) +
-        MAX_PREAMBLE_STUB_SIZE;
-    unsigned char* limit = reinterpret_cast<unsigned char*>(preamble_page) +
-        pagesize_;
-    while (ptr < limit) {
-      *pp = ptr;
-      pp = reinterpret_cast<void**>(ptr);
-      ptr += MAX_PREAMBLE_STUB_SIZE;
-    }
-    *pp = NULL;
-    // Insert the new page into the list
-    preamble_page->magic_ = kPreamblePageMagic;
-    preamble_page->next_ = preamble_pages_;
-    preamble_pages_ = preamble_page;
-  }
-  unsigned char* ret = reinterpret_cast<unsigned char*>(preamble_page->free_);
-  preamble_page->free_ = *(reinterpret_cast<void**>(preamble_page->free_));
-  return ret;
-}
-
-void PreamblePatcher::FreePreambleBlock(unsigned char* block) {
-  SIDESTEP_ASSERT(block != NULL);
-  SIDESTEP_ASSERT(granularity_ != 0);
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(block);
-  ptr -= ptr & (granularity_ - 1);
-  PreamblePage* preamble_page = reinterpret_cast<PreamblePage*>(ptr);
-  SIDESTEP_ASSERT(preamble_page->magic_ == kPreamblePageMagic);
-  *(reinterpret_cast<void**>(block)) = preamble_page->free_;
-  preamble_page->free_ = block;
-}
-
-void* PreamblePatcher::AllocPageNear(void* target) {
-  MEMORY_BASIC_INFORMATION mbi = { 0 };
-  if (!::VirtualQuery(target, &mbi, sizeof(mbi))) {
-    SIDESTEP_ASSERT(false && "VirtualQuery failed on target address");
-    return 0;
-  }
-  if (initialized_ == false) {
-    PreamblePatcher::Initialize();
-    SIDESTEP_ASSERT(initialized_);
-  }
-  void* pv = NULL;
-  unsigned char* allocation_base = reinterpret_cast<unsigned char*>(
-      mbi.AllocationBase);
-  __int64 i = 1;
-  bool high_target = reinterpret_cast<__int64>(target) > UINT_MAX;
-  while (pv == NULL) {
-    __int64 val = reinterpret_cast<__int64>(allocation_base) -
-        (i * granularity_);
-    if (high_target &&
-        reinterpret_cast<__int64>(target) - val > INT_MAX) {
-        // We're further than 2GB from the target
-      break;
-    } else if (val <= 0) {
-      // Less than 0
-      break;
-    }
-    pv = ::VirtualAlloc(reinterpret_cast<void*>(allocation_base -
-                            (i++ * granularity_)),
-                        pagesize_, MEM_COMMIT | MEM_RESERVE,
-                        PAGE_EXECUTE_READWRITE);
-  }
-
-  // We couldn't allocate low, try to allocate high
-  if (pv == NULL) {
-    i = 1;
-    // Round up to the next multiple of page granularity
-    allocation_base = reinterpret_cast<unsigned char*>(
-        (reinterpret_cast<__int64>(target) &
-        (~(granularity_ - 1))) + granularity_);
-    while (pv == NULL) {
-      __int64 val = reinterpret_cast<__int64>(allocation_base) +
-          (i * granularity_) - reinterpret_cast<__int64>(target);
-      if (val > INT_MAX || val < 0) {
-        // We're too far or we overflowed
-        break;
-      }
-      pv = ::VirtualAlloc(reinterpret_cast<void*>(allocation_base +
-                              (i++ * granularity_)),
-                          pagesize_, MEM_COMMIT | MEM_RESERVE,
-                          PAGE_EXECUTE_READWRITE);
-    }
-  }
-  return pv;
-}
-
-bool PreamblePatcher::IsShortConditionalJump(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return (*(target) & 0x70) == 0x70 && instruction_size == 2;
-}
-
-bool PreamblePatcher::IsShortJump(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return target[0] == 0xeb && instruction_size == 2;
-}
-
-bool PreamblePatcher::IsNearConditionalJump(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return *(target) == 0xf && (*(target + 1) & 0x80) == 0x80 &&
-      instruction_size == 6;
-}
-
-bool PreamblePatcher::IsNearRelativeJump(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return *(target) == 0xe9 && instruction_size == 5;
-}
-
-bool PreamblePatcher::IsNearAbsoluteCall(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return *(target) == 0xff && (*(target + 1) & 0x10) == 0x10 &&
-      instruction_size == 6;
-}
-
-bool PreamblePatcher::IsNearRelativeCall(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return *(target) == 0xe8 && instruction_size == 5;
-}
-
-bool PreamblePatcher::IsMovWithDisplacement(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  // In this case, the ModRM byte's mod field will be 0 and r/m will be 101b (5)
-  return instruction_size == 7 && *target == 0x48 && *(target + 1) == 0x8b &&
-      (*(target + 2) >> 6) == 0 && (*(target + 2) & 0x7) == 5;
-}
-
-SideStepError PreamblePatcher::PatchShortConditionalJump(
-    unsigned char* source,
-    unsigned int instruction_size,
-    unsigned char* target,
-    unsigned int* target_bytes,
-    unsigned int target_size) {
-  // note: rel8 offset is signed. Thus we need to ask for signed char
-  // to negative offsets right
-  unsigned char* original_jump_dest = (source + 2) + static_cast<signed char>(source[1]);
-  unsigned char* stub_jump_from = target + 6;
-  __int64 fixup_jump_offset = original_jump_dest - stub_jump_from;
-  if (fixup_jump_offset > INT_MAX || fixup_jump_offset < INT_MIN) {
-    SIDESTEP_ASSERT(false &&
-                    "Unable to fix up short jump because target"
-                    " is too far away.");
-    return SIDESTEP_JUMP_INSTRUCTION;
-  }
-
-  *target_bytes = 6;
-  if (target_size > *target_bytes) {
-    // Convert the short jump to a near jump.
-    //
-    // 0f 8x xx xx xx xx = Jcc rel32off
-    unsigned short jmpcode = ((0x80 | (source[0] & 0xf)) << 8) | 0x0f;
-    memcpy(reinterpret_cast<void*>(target),
-           reinterpret_cast<void*>(&jmpcode), 2);
-    memcpy(reinterpret_cast<void*>(target + 2),
-           reinterpret_cast<void*>(&fixup_jump_offset), 4);
-  }
-
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::PatchShortJump(
-    unsigned char* source,
-    unsigned int instruction_size,
-    unsigned char* target,
-    unsigned int* target_bytes,
-    unsigned int target_size) {
-  // note: rel8 offset is _signed_. Thus we need signed char here.
-  unsigned char* original_jump_dest = (source + 2) + static_cast<signed char>(source[1]);
-  unsigned char* stub_jump_from = target + 5;
-  __int64 fixup_jump_offset = original_jump_dest - stub_jump_from;
-  if (fixup_jump_offset > INT_MAX || fixup_jump_offset < INT_MIN) {
-    SIDESTEP_ASSERT(false &&
-                    "Unable to fix up short jump because target"
-                    " is too far away.");
-    return SIDESTEP_JUMP_INSTRUCTION;
-  }
-
-  *target_bytes = 5;
-  if (target_size > *target_bytes) {
-    // Convert the short jump to a near jump.
-    //
-    // e9 xx xx xx xx = jmp rel32off
-    target[0] = 0xe9;
-    memcpy(reinterpret_cast<void*>(target + 1),
-           reinterpret_cast<void*>(&fixup_jump_offset), 4);
-  }
-
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::PatchNearJumpOrCall(
-    unsigned char* source,
-    unsigned int instruction_size,
-    unsigned char* target,
-    unsigned int* target_bytes,
-    unsigned int target_size) {
-  SIDESTEP_ASSERT(instruction_size == 5 || instruction_size == 6);
-  unsigned int jmp_offset_in_instruction = instruction_size == 5 ? 1 : 2;
-  unsigned char* original_jump_dest = reinterpret_cast<unsigned char *>(
-      reinterpret_cast<__int64>(source + instruction_size) +
-      *(reinterpret_cast<int*>(source + jmp_offset_in_instruction)));
-  unsigned char* stub_jump_from = target + instruction_size;
-  __int64 fixup_jump_offset = original_jump_dest - stub_jump_from;
-  if (fixup_jump_offset > INT_MAX || fixup_jump_offset < INT_MIN) {
-    SIDESTEP_ASSERT(false &&
-                    "Unable to fix up near jump because target"
-                    " is too far away.");
-    return SIDESTEP_JUMP_INSTRUCTION;
-  }
-
-  if ((fixup_jump_offset < SCHAR_MAX && fixup_jump_offset > SCHAR_MIN)) {
-    *target_bytes = 2;
-    if (target_size > *target_bytes) {
-      // If the new offset is in range, use a short jump instead of a near jump.
-      if (source[0] == ASM_JCC32REL_0 &&
-          (source[1] & ASM_JCC32REL_1_MASK) == ASM_JCC32REL_1_MASK) {
-        unsigned short jmpcode = (static_cast<unsigned char>(
-            fixup_jump_offset) << 8) | (0x70 | (source[1] & 0xf));
-        memcpy(reinterpret_cast<void*>(target),
-               reinterpret_cast<void*>(&jmpcode),
-               2);
-      } else {
-        target[0] = ASM_JMP8REL;
-        target[1] = static_cast<unsigned char>(fixup_jump_offset);
-      }
-    }
-  } else {
-    *target_bytes = instruction_size;
-    if (target_size > *target_bytes) {
-      memcpy(reinterpret_cast<void*>(target),
-             reinterpret_cast<void*>(source),
-             jmp_offset_in_instruction);
-      memcpy(reinterpret_cast<void*>(target + jmp_offset_in_instruction),
-             reinterpret_cast<void*>(&fixup_jump_offset),
-             4);
-    }
-  }
-
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::PatchMovWithDisplacement(
-     unsigned char* source,
-     unsigned int instruction_size,
-     unsigned char* target,
-     unsigned int* target_bytes,
-     unsigned int target_size) {
-  SIDESTEP_ASSERT(instruction_size == 7);
-  const int mov_offset_in_instruction = 3; // 0x48 0x8b 0x0d <offset>
-  unsigned char* original_mov_dest = reinterpret_cast<unsigned char*>(
-      reinterpret_cast<__int64>(source + instruction_size) +
-      *(reinterpret_cast<int*>(source + mov_offset_in_instruction)));
-  unsigned char* stub_mov_from = target + instruction_size;
-  __int64 fixup_mov_offset = original_mov_dest - stub_mov_from;
-  if (fixup_mov_offset > INT_MAX || fixup_mov_offset < INT_MIN) {
-    SIDESTEP_ASSERT(false &&
-        "Unable to fix up near MOV because target is too far away.");
-    return SIDESTEP_UNEXPECTED;
-  }
-  *target_bytes = instruction_size;
-  if (target_size > *target_bytes) {
-    memcpy(reinterpret_cast<void*>(target),
-           reinterpret_cast<void*>(source),
-           mov_offset_in_instruction);
-    memcpy(reinterpret_cast<void*>(target + mov_offset_in_instruction),
-           reinterpret_cast<void*>(&fixup_mov_offset),
-           4);
-  }
-  return SIDESTEP_SUCCESS;
-}
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/chromium/src/windows/preamble_patcher.h b/third_party/tcmalloc/chromium/src/windows/preamble_patcher.h
deleted file mode 100644
index 76f158a1..0000000
--- a/third_party/tcmalloc/chromium/src/windows/preamble_patcher.h
+++ /dev/null
@@ -1,620 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- * Author: Scott Francis
- *
- * Definition of PreamblePatcher
- */
-
-#ifndef GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
-#define GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
-
-#include "config.h"
-#include <windows.h>
-
-// compatibility shim
-#include "base/logging.h"
-#define SIDESTEP_ASSERT(cond)  RAW_DCHECK(cond, #cond)
-#define SIDESTEP_LOG(msg)      RAW_VLOG(1, msg)
-
-// Maximum size of the preamble stub. We overwrite at least the first 5
-// bytes of the function. Considering the worst case scenario, we need 4
-// bytes + the max instruction size + 5 more bytes for our jump back to
-// the original code. With that in mind, 32 is a good number :)
-#ifdef _M_X64
-// In 64-bit mode we may need more room.  In 64-bit mode all jumps must be
-// within +/-2GB of RIP.  Because of this limitation we may need to use a
-// trampoline to jump to the replacement function if it is further than 2GB
-// away from the target. The trampoline is 14 bytes.
-//
-// So 4 bytes + max instruction size (17 bytes) + 5 bytes to jump back to the
-// original code + trampoline size.  64 bytes is a nice number :-)
-#define MAX_PREAMBLE_STUB_SIZE    (64)
-#else
-#define MAX_PREAMBLE_STUB_SIZE    (32)
-#endif
-
-// Determines if this is a 64-bit binary.
-#ifdef _M_X64
-static const bool kIs64BitBinary = true;
-#else
-static const bool kIs64BitBinary = false;
-#endif
-
-namespace sidestep {
-
-// Possible results of patching/unpatching
-enum SideStepError {
-  SIDESTEP_SUCCESS = 0,
-  SIDESTEP_INVALID_PARAMETER,
-  SIDESTEP_INSUFFICIENT_BUFFER,
-  SIDESTEP_JUMP_INSTRUCTION,
-  SIDESTEP_FUNCTION_TOO_SMALL,
-  SIDESTEP_UNSUPPORTED_INSTRUCTION,
-  SIDESTEP_NO_SUCH_MODULE,
-  SIDESTEP_NO_SUCH_FUNCTION,
-  SIDESTEP_ACCESS_DENIED,
-  SIDESTEP_UNEXPECTED,
-};
-
-#define SIDESTEP_TO_HRESULT(error)                      \
-  MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, error)
-
-class DeleteUnsignedCharArray;
-
-// Implements a patching mechanism that overwrites the first few bytes of
-// a function preamble with a jump to our hook function, which is then
-// able to call the original function via a specially-made preamble-stub
-// that imitates the action of the original preamble.
-//
-// NOTE:  This patching mechanism should currently only be used for
-// non-production code, e.g. unit tests, because it is not threadsafe.
-// See the TODO in preamble_patcher_with_stub.cc for instructions on what
-// we need to do before using it in production code; it's fairly simple
-// but unnecessary for now since we only intend to use it in unit tests.
-//
-// To patch a function, use either of the typesafe Patch() methods.  You
-// can unpatch a function using Unpatch().
-//
-// Typical usage goes something like this:
-// @code
-// typedef int (*MyTypesafeFuncPtr)(int x);
-// MyTypesafeFuncPtr original_func_stub;
-// int MyTypesafeFunc(int x) { return x + 1; }
-// int HookMyTypesafeFunc(int x) { return 1 + original_func_stub(x); }
-// 
-// void MyPatchInitializingFunction() {
-//   original_func_stub = PreamblePatcher::Patch(
-//              MyTypesafeFunc, HookMyTypesafeFunc);
-//   if (!original_func_stub) {
-//     // ... error handling ...
-//   }
-//
-//   // ... continue - you have patched the function successfully ...
-// }
-// @endcode
-//
-// Note that there are a number of ways that this method of patching can
-// fail.  The most common are:
-//    - If there is a jump (jxx) instruction in the first 5 bytes of
-//    the function being patched, we cannot patch it because in the
-//    current implementation we do not know how to rewrite relative
-//    jumps after relocating them to the preamble-stub.  Note that
-//    if you really really need to patch a function like this, it
-//    would be possible to add this functionality (but at some cost).
-//    - If there is a return (ret) instruction in the first 5 bytes
-//    we cannot patch the function because it may not be long enough
-//    for the jmp instruction we use to inject our patch.
-//    - If there is another thread currently executing within the bytes
-//    that are copied to the preamble stub, it will crash in an undefined
-//    way.
-//
-// If you get any other error than the above, you're either pointing the
-// patcher at an invalid instruction (e.g. into the middle of a multi-
-// byte instruction, or not at memory containing executable instructions)
-// or, there may be a bug in the disassembler we use to find
-// instruction boundaries.
-//
-// NOTE:  In optimized builds, when you have very trivial functions that
-// the compiler can reason do not have side effects, the compiler may
-// reuse the result of calling the function with a given parameter, which
-// may mean if you patch the function in between your patch will never get
-// invoked.  See preamble_patcher_test.cc for an example.
-class PERFTOOLS_DLL_DECL PreamblePatcher {
- public:
-
-  // This is a typesafe version of RawPatch(), identical in all other
-  // ways than it takes a template parameter indicating the type of the
-  // function being patched.
-  //
-  // @param T The type of the function you are patching. Usually
-  // you will establish this type using a typedef, as in the following
-  // example:
-  // @code
-  // typedef BOOL (WINAPI *MessageBoxPtr)(HWND, LPCTSTR, LPCTSTR, UINT);
-  // MessageBoxPtr original = NULL;
-  // PreamblePatcher::Patch(MessageBox, Hook_MessageBox, &original);
-  // @endcode
-  template <class T>
-  static SideStepError Patch(T target_function,
-                             T replacement_function,
-                             T* original_function_stub) {
-    // NOTE: casting from a function to a pointer is contra the C++
-    //       spec.  It's not safe on IA64, but is on i386.  We use
-    //       a C-style cast here to emphasize this is not legal C++.
-    return RawPatch((void*)(target_function),
-                    (void*)(replacement_function),
-                    (void**)(original_function_stub));
-  }
-
-  // Patches a named function imported from the named module using
-  // preamble patching.  Uses RawPatch() to do the actual patching
-  // work.
-  //
-  // @param T The type of the function you are patching.  Must
-  // exactly match the function you specify using module_name and
-  // function_name.
-  //
-  // @param module_name The name of the module from which the function
-  // is being imported.  Note that the patch will fail if this module
-  // has not already been loaded into the current process.
-  //
-  // @param function_name The name of the function you wish to patch.
-  //
-  // @param replacement_function Your replacement function which
-  // will be called whenever code tries to call the original function.
-  //
-  // @param original_function_stub Pointer to memory that should receive a
-  // pointer that can be used (e.g. in the replacement function) to call the
-  // original function, or NULL to indicate failure.
-  //
-  // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
-  // indicates success.
-  template <class T>
-  static SideStepError Patch(LPCTSTR module_name,
-                             LPCSTR function_name,
-                             T replacement_function,
-                             T* original_function_stub) {
-    SIDESTEP_ASSERT(module_name && function_name);
-    if (!module_name || !function_name) {
-      SIDESTEP_ASSERT(false &&
-                      "You must specify a module name and function name.");
-      return SIDESTEP_INVALID_PARAMETER;
-    }
-    HMODULE module = ::GetModuleHandle(module_name);
-    SIDESTEP_ASSERT(module != NULL);
-    if (!module) {
-      SIDESTEP_ASSERT(false && "Invalid module name.");
-      return SIDESTEP_NO_SUCH_MODULE;
-    }
-    FARPROC existing_function = ::GetProcAddress(module, function_name);
-    if (!existing_function) {
-      SIDESTEP_ASSERT(
-          false && "Did not find any function with that name in the module.");
-      return SIDESTEP_NO_SUCH_FUNCTION;
-    }
-    // NOTE: casting from a function to a pointer is contra the C++
-    //       spec.  It's not safe on IA64, but is on i386.  We use
-    //       a C-style cast here to emphasize this is not legal C++.
-    return RawPatch((void*)existing_function, (void*)replacement_function,
-                    (void**)(original_function_stub));
-  }
-
-  // Patches a function by overwriting its first few bytes with
-  // a jump to a different function.  This is the "worker" function
-  // for each of the typesafe Patch() functions.  In most cases,
-  // it is preferable to use the Patch() functions rather than
-  // this one as they do more checking at compile time.
-  //
-  // @param target_function A pointer to the function that should be
-  // patched.
-  //
-  // @param replacement_function A pointer to the function that should
-  // replace the target function.  The replacement function must have
-  // exactly the same calling convention and parameters as the original
-  // function.
-  //
-  // @param original_function_stub Pointer to memory that should receive a
-  // pointer that can be used (e.g. in the replacement function) to call the
-  // original function, or NULL to indicate failure.
-  //
-  // @param original_function_stub Pointer to memory that should receive a
-  // pointer that can be used (e.g. in the replacement function) to call the
-  // original function, or NULL to indicate failure.
-  //
-  // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
-  // indicates success.
-  //
-  // @note The preamble-stub (the memory pointed to by
-  // *original_function_stub) is allocated on the heap, and (in
-  // production binaries) never destroyed, resulting in a memory leak.  This
-  // will be the case until we implement safe unpatching of a method.
-  // However, it is quite difficult to unpatch a method (because other
-  // threads in the process may be using it) so we are leaving it for now.
-  // See however UnsafeUnpatch, which can be used for binaries where you
-  // know only one thread is running, e.g. unit tests.
-  static SideStepError RawPatch(void* target_function,
-                                void* replacement_function,
-                                void** original_function_stub);
-
-  // Unpatches target_function and deletes the stub that previously could be
-  // used to call the original version of the function.
-  //
-  // DELETES the stub that is passed to the function.
-  //
-  // @param target_function Pointer to the target function which was
-  // previously patched, i.e. a pointer which value should match the value
-  // of the symbol prior to patching it.
-  //
-  // @param replacement_function Pointer to the function target_function
-  // was patched to.
-  //
-  // @param original_function_stub Pointer to the stub returned when
-  // patching, that could be used to call the original version of the
-  // patched function.  This function will also delete the stub, which after
-  // unpatching is useless.
-  //
-  // If your original call was
-  //    Patch(VirtualAlloc, MyVirtualAlloc, &origptr)
-  // then to undo it you would call
-  //    Unpatch(VirtualAlloc, MyVirtualAlloc, origptr);
-  //
-  // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
-  // indicates success.
-  static SideStepError Unpatch(void* target_function,
-                               void* replacement_function,
-                               void* original_function_stub);
-
-  // A helper routine when patching, which follows jmp instructions at
-  // function addresses, to get to the "actual" function contents.
-  // This allows us to identify two functions that are at different
-  // addresses but actually resolve to the same code.
-  //
-  // @param target_function Pointer to a function.
-  //
-  // @return Either target_function (the input parameter), or if
-  // target_function's body consists entirely of a JMP instruction,
-  // the address it JMPs to (or more precisely, the address at the end
-  // of a chain of JMPs).
-  template <class T>
-  static T ResolveTarget(T target_function) {
-    return (T)ResolveTargetImpl((unsigned char*)target_function, NULL);
-  }
-
-  // Allocates a block of memory of size MAX_PREAMBLE_STUB_SIZE that is as
-  // close (within 2GB) as possible to target.  This is done to ensure that 
-  // we can perform a relative jump from target to a trampoline if the 
-  // replacement function is > +-2GB from target.  This means that we only need 
-  // to patch 5 bytes in the target function.
-  //
-  // @param target    Pointer to target function.
-  //
-  // @return  Returns a block of memory of size MAX_PREAMBLE_STUB_SIZE that can
-  //          be used to store a function preamble block.
-  static unsigned char* AllocPreambleBlockNear(void* target);
-
-  // Frees a block allocated by AllocPreambleBlockNear.
-  //
-  // @param block     Block that was returned by AllocPreambleBlockNear.
-  static void FreePreambleBlock(unsigned char* block);
-
- private:
-  friend class DeleteUnsignedCharArray;
-
-   // Used to store data allocated for preamble stubs
-  struct PreamblePage {
-    unsigned int magic_;
-    PreamblePage* next_;
-    // This member points to a linked list of free blocks within the page
-    // or NULL if at the end
-    void* free_;
-  };
-
-  // In 64-bit mode, the replacement function must be within 2GB of the original
-  // target in order to only require 5 bytes for the function patch.  To meet
-  // this requirement we're creating an allocator within this class to
-  // allocate blocks that are within 2GB of a given target. This member is the
-  // head of a linked list of pages used to allocate blocks that are within
-  // 2GB of the target.
-  static PreamblePage* preamble_pages_;
-  
-  // Page granularity
-  static long granularity_;
-
-  // Page size
-  static long pagesize_;
-
-  // Determines if the patcher has been initialized.
-  static bool initialized_;
-
-  // Used to initialize static members.
-  static void Initialize();
-
-  // Patches a function by overwriting its first few bytes with
-  // a jump to a different function.  This is similar to the RawPatch
-  // function except that it uses the stub allocated by the caller
-  // instead of allocating it.
-  //
-  // We call VirtualProtect to make the
-  // target function writable at least for the duration of the call.
-  //
-  // @param target_function A pointer to the function that should be
-  // patched.
-  //
-  // @param replacement_function A pointer to the function that should
-  // replace the target function.  The replacement function must have
-  // exactly the same calling convention and parameters as the original
-  // function.
-  //
-  // @param preamble_stub A pointer to a buffer where the preamble stub
-  // should be copied. The size of the buffer should be sufficient to
-  // hold the preamble bytes.
-  //
-  // @param stub_size Size in bytes of the buffer allocated for the
-  // preamble_stub
-  //
-  // @param bytes_needed Pointer to a variable that receives the minimum
-  // number of bytes required for the stub.  Can be set to NULL if you're
-  // not interested.
-  //
-  // @return An error code indicating the result of patching.
-  static SideStepError RawPatchWithStubAndProtections(
-      void* target_function,
-      void* replacement_function,
-      unsigned char* preamble_stub,
-      unsigned long stub_size,
-      unsigned long* bytes_needed);
-
-  // A helper function used by RawPatchWithStubAndProtections -- it
-  // does everything but the VirtualProtect work.  Defined in
-  // preamble_patcher_with_stub.cc.
-  //
-  // @param target_function A pointer to the function that should be
-  // patched.
-  //
-  // @param replacement_function A pointer to the function that should
-  // replace the target function.  The replacement function must have
-  // exactly the same calling convention and parameters as the original
-  // function.
-  //
-  // @param preamble_stub A pointer to a buffer where the preamble stub
-  // should be copied. The size of the buffer should be sufficient to
-  // hold the preamble bytes.
-  //
-  // @param stub_size Size in bytes of the buffer allocated for the
-  // preamble_stub
-  //
-  // @param bytes_needed Pointer to a variable that receives the minimum
-  // number of bytes required for the stub.  Can be set to NULL if you're
-  // not interested.
-  //
-  // @return An error code indicating the result of patching.
-  static SideStepError RawPatchWithStub(void* target_function,
-                                        void* replacement_function,
-                                        unsigned char* preamble_stub,
-                                        unsigned long stub_size,
-                                        unsigned long* bytes_needed);
-
-
-  // A helper routine when patching, which follows jmp instructions at
-  // function addresses, to get to the "actual" function contents.
-  // This allows us to identify two functions that are at different
-  // addresses but actually resolve to the same code.
-  //
-  // @param target_function Pointer to a function.
-  //
-  // @param stop_before If, when following JMP instructions from
-  // target_function, we get to the address stop, we return
-  // immediately, the address that jumps to stop_before.
-  //
-  // @param stop_before_trampoline  When following JMP instructions from 
-  // target_function, stop before a trampoline is detected.  See comment in
-  // PreamblePatcher::RawPatchWithStub for more information.  This parameter 
-  // has no effect in 32-bit mode.
-  //
-  // @return Either target_function (the input parameter), or if
-  // target_function's body consists entirely of a JMP instruction,
-  // the address it JMPs to (or more precisely, the address at the end
-  // of a chain of JMPs).
-  static void* ResolveTargetImpl(unsigned char* target_function,
-                                 unsigned char* stop_before,
-                                 bool stop_before_trampoline = false);
-
-  // Helper routine that attempts to allocate a page as close (within 2GB)
-  // as possible to target.
-  //
-  // @param target    Pointer to target function.
-  //
-  // @return   Returns an address that is within 2GB of target.
-  static void* AllocPageNear(void* target);
-
-  // Helper routine that determines if a target instruction is a short
-  // conditional jump.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a short conditional jump.
-  static bool IsShortConditionalJump(unsigned char* target,
-                                     unsigned int instruction_size);
-
-  static bool IsShortJump(unsigned char *target, unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a near
-  // conditional jump.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a near conditional jump.
-  static bool IsNearConditionalJump(unsigned char* target,
-                                    unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a near
-  // relative jump.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a near absolute jump.
-  static bool IsNearRelativeJump(unsigned char* target,
-                                 unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a near 
-  // absolute call.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a near absolute call.
-  static bool IsNearAbsoluteCall(unsigned char* target,
-                                 unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a near 
-  // absolute call.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a near absolute call.
-  static bool IsNearRelativeCall(unsigned char* target,
-                                 unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a 64-bit MOV
-  // that uses a RIP-relative displacement.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a MOV with displacement.
-  static bool IsMovWithDisplacement(unsigned char* target,
-                                    unsigned int instruction_size);
-
-  // Helper routine that converts a short conditional jump instruction
-  // to a near conditional jump in a target buffer.  Note that the target
-  // buffer must be within 2GB of the source for the near jump to work.
-  //
-  // A short conditional jump instruction is in the format:
-  // 7x xx = Jcc rel8off
-  //
-  // @param source              Pointer to instruction.
-  //
-  // @param instruction_size    Size of the instruction.
-  //
-  // @param target              Target buffer to write the new instruction.
-  //
-  // @param target_bytes        Pointer to a buffer that contains the size
-  //                            of the target instruction, in bytes.
-  //
-  // @param target_size         Size of the target buffer.
-  //
-  // @return  Returns SIDESTEP_SUCCESS if successful, otherwise an error.
-  static SideStepError PatchShortConditionalJump(unsigned char* source,
-                                                 unsigned int instruction_size,
-                                                 unsigned char* target,
-                                                 unsigned int* target_bytes,
-                                                 unsigned int target_size);
-
-  static SideStepError PatchShortJump(unsigned char* source,
-                                      unsigned int instruction_size,
-                                      unsigned char* target,
-                                      unsigned int* target_bytes,
-                                      unsigned int target_size);
-
-  // Helper routine that converts an instruction that will convert various
-  // jump-like instructions to corresponding instructions in the target buffer.
-  // What this routine does is fix up the relative offsets contained in jump
-  // instructions to point back to the original target routine.  Like with
-  // PatchShortConditionalJump, the target buffer must be within 2GB of the
-  // source.
-  //
-  // We currently handle the following instructions:
-  //
-  // E9 xx xx xx xx     = JMP rel32off
-  // 0F 8x xx xx xx xx  = Jcc rel32off
-  // FF /2 xx xx xx xx  = CALL reg/mem32/mem64
-  // E8 xx xx xx xx     = CALL rel32off
-  //
-  // It should not be hard to update this function to support other
-  // instructions that jump to relative targets.
-  //
-  // @param source              Pointer to instruction.
-  //
-  // @param instruction_size    Size of the instruction.
-  //
-  // @param target              Target buffer to write the new instruction.
-  //
-  // @param target_bytes        Pointer to a buffer that contains the size
-  //                            of the target instruction, in bytes.
-  //
-  // @param target_size         Size of the target buffer.
-  //
-  // @return  Returns SIDESTEP_SUCCESS if successful, otherwise an error.
-  static SideStepError PatchNearJumpOrCall(unsigned char* source,
-                                           unsigned int instruction_size,
-                                           unsigned char* target,
-                                           unsigned int* target_bytes,
-                                           unsigned int target_size);
-  
-  // Helper routine that patches a 64-bit MOV instruction with a RIP-relative
-  // displacement.  The target buffer must be within 2GB of the source.
-  //
-  // 48 8B 0D XX XX XX XX = MOV rel32off
-  //
-  // @param source              Pointer to instruction.
-  //
-  // @param instruction_size    Size of the instruction.
-  //
-  // @param target              Target buffer to write the new instruction.
-  //
-  // @param target_bytes        Pointer to a buffer that contains the size
-  //                            of the target instruction, in bytes.
-  //
-  // @param target_size         Size of the target buffer.
-  //
-  // @return  Returns SIDESTEP_SUCCESS if successful, otherwise an error.
-  static SideStepError PatchMovWithDisplacement(unsigned char* source,
-                                                unsigned int instruction_size,
-                                                unsigned char* target,
-                                                unsigned int* target_bytes,
-                                                unsigned int target_size);
-};
-
-};  // namespace sidestep
-
-#endif  // GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
diff --git a/third_party/tcmalloc/chromium/src/windows/preamble_patcher_test.cc b/third_party/tcmalloc/chromium/src/windows/preamble_patcher_test.cc
deleted file mode 100644
index e4605c6..0000000
--- a/third_party/tcmalloc/chromium/src/windows/preamble_patcher_test.cc
+++ /dev/null
@@ -1,368 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2011, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- * Author: Scott Francis
- *
- * Unit tests for PreamblePatcher
- */
-
-#include "config_for_unittests.h"
-#include "preamble_patcher.h"
-#include "mini_disassembler.h"
-#pragma warning(push)
-#pragma warning(disable:4553)
-#include "auto_testing_hook.h"
-#pragma warning(pop)
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <tchar.h>
-
-// Turning off all optimizations for this file, since the official build's
-// "Whole program optimization" seems to cause the TestPatchUsingDynamicStub
-// test to crash with an access violation.  We debugged this and found
-// that the optimized access a register that is changed by a call to the hook
-// function.
-#pragma optimize("", off)
-
-// A convenience macro to avoid a lot of casting in the tests.
-// I tried to make this a templated function, but windows complained:
-//     error C2782: 'sidestep::SideStepError `anonymous-namespace'::Unpatch(T,T,T *)' : template parameter 'T' is ambiguous
-//        could be 'int (int)'
-//        or       'int (__cdecl *)(int)'
-// My life isn't long enough to try to figure out how to fix this.
-#define UNPATCH(target_function, replacement_function, original_function_stub) \
-  sidestep::PreamblePatcher::Unpatch((void*)(target_function),          \
-                                     (void*)(replacement_function),     \
-                                     (void*)(original_function))
-
-namespace {
-
-// Function for testing - this is what we patch
-//
-// NOTE:  Because of the way the compiler optimizes this function in
-// release builds, we need to use a different input value every time we
-// call it within a function, otherwise the compiler will just reuse the
-// last calculated incremented value.
-int __declspec(noinline) IncrementNumber(int i) {
-#ifdef _M_X64
-  __int64 i2 = i + 1;
-  return (int) i2;
-#else
-   return i + 1;
-#endif
-}
-
-extern "C" int TooShortFunction(int);
-
-extern "C" int JumpShortCondFunction(int);
-
-extern "C" int JumpNearCondFunction(int);
-
-extern "C" int JumpAbsoluteFunction(int);
-
-extern "C" int CallNearRelativeFunction(int);
-
-typedef int (*IncrementingFunc)(int);
-IncrementingFunc original_function = NULL;
-
-int HookIncrementNumber(int i) {
-  SIDESTEP_ASSERT(original_function != NULL);
-  int incremented_once = original_function(i);
-  return incremented_once + 1;
-}
-
-// For the AutoTestingHook test, we can't use original_function, because
-// all that is encapsulated.
-// This function "increments" by 10, just to set it apart from the other
-// functions.
-int __declspec(noinline) AutoHookIncrementNumber(int i) {
-  return i + 10;
-}
-
-};  // namespace
-
-namespace sidestep {
-
-bool TestDisassembler() {
-   unsigned int instruction_size = 0;
-   sidestep::MiniDisassembler disassembler;
-   void * target = reinterpret_cast<unsigned char *>(IncrementNumber);
-   void * new_target = PreamblePatcher::ResolveTarget(target);
-   if (target != new_target)
-      target = new_target;
-
-   while (1) {
-      sidestep::InstructionType instructionType = disassembler.Disassemble(
-         reinterpret_cast<unsigned char *>(target) + instruction_size,
-         instruction_size);
-      if (sidestep::IT_RETURN == instructionType) {
-         return true;
-      }
-   }
-}
-
-bool TestPatchWithLongJump() {
-  original_function = NULL;
-  void *p = ::VirtualAlloc(reinterpret_cast<void *>(0x0000020000000000), 4096,
-                           MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
-  SIDESTEP_EXPECT_TRUE(p != NULL);
-  memset(p, 0xcc, 4096);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(IncrementNumber,
-                                                        (IncrementingFunc) p,
-                                                        &original_function));
-  SIDESTEP_ASSERT((*original_function)(1) == 2);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(IncrementNumber,
-                               (IncrementingFunc)p,
-                               original_function));
-  ::VirtualFree(p, 0, MEM_RELEASE);
-  return true;
-}
-
-bool TestPatchWithPreambleShortCondJump() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(JumpShortCondFunction,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  (*original_function)(1);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(JumpShortCondFunction,
-                               (void*)HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool TestPatchWithPreambleNearRelativeCondJump() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(JumpNearCondFunction,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  (*original_function)(0);
-  (*original_function)(1);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(JumpNearCondFunction,
-                               HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool TestPatchWithPreambleAbsoluteJump() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(JumpAbsoluteFunction,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  (*original_function)(0);
-  (*original_function)(1);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(JumpAbsoluteFunction,
-                               HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool TestPatchWithPreambleNearRelativeCall() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(
-                                                    CallNearRelativeFunction,
-                                                    HookIncrementNumber,
-                                                    &original_function));
-  (*original_function)(0);
-  (*original_function)(1);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(CallNearRelativeFunction,
-                               HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool TestPatchUsingDynamicStub() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 2);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(IncrementNumber,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  SIDESTEP_EXPECT_TRUE(original_function);
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(2) == 4);
-  SIDESTEP_EXPECT_TRUE(original_function(3) == 4);
-
-  // Clearbox test to see that the function has been patched.
-  sidestep::MiniDisassembler disassembler;
-  unsigned int instruction_size = 0;
-  SIDESTEP_EXPECT_TRUE(sidestep::IT_JUMP == disassembler.Disassemble(
-                           reinterpret_cast<unsigned char*>(IncrementNumber),
-                           instruction_size));
-
-  // Since we patched IncrementNumber, its first statement is a
-  // jmp to the hook function.  So verify that we now can not patch
-  // IncrementNumber because it starts with a jump.
-#if 0
-  IncrementingFunc dummy = NULL;
-  // TODO(joi@chromium.org): restore this test once flag is added to
-  // disable JMP following
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_JUMP_INSTRUCTION ==
-                       sidestep::PreamblePatcher::Patch(IncrementNumber,
-                                                        HookIncrementNumber,
-                                                        &dummy));
-
-  // This test disabled because code in preamble_patcher_with_stub.cc
-  // asserts before returning the error code -- so there is no way
-  // to get an error code here, in debug build.
-  dummy = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_FUNCTION_TOO_SMALL ==
-                       sidestep::PreamblePatcher::Patch(TooShortFunction,
-                                                        HookIncrementNumber,
-                                                        &dummy));
-#endif
-
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(IncrementNumber,
-                               HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool PatchThenUnpatch() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(IncrementNumber,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  SIDESTEP_EXPECT_TRUE(original_function);
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 3);
-  SIDESTEP_EXPECT_TRUE(original_function(2) == 3);
-
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(IncrementNumber,
-                               HookIncrementNumber,
-                               original_function));
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(3) == 4);
-
-  return true;
-}
-
-bool AutoTestingHookTest() {
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 2);
-
-  // Inner scope, so we can test what happens when the AutoTestingHook
-  // goes out of scope
-  {
-    AutoTestingHook hook = MakeTestingHook(IncrementNumber,
-                                           AutoHookIncrementNumber);
-    (void) hook;
-    SIDESTEP_EXPECT_TRUE(IncrementNumber(2) == 12);
-  }
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(3) == 4);
-
-  return true;
-}
-
-bool AutoTestingHookInContainerTest() {
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 2);
-
-  // Inner scope, so we can test what happens when the AutoTestingHook
-  // goes out of scope
-  {
-    AutoTestingHookHolder hook(MakeTestingHookHolder(IncrementNumber,
-                                                     AutoHookIncrementNumber));
-    (void) hook;
-    SIDESTEP_EXPECT_TRUE(IncrementNumber(2) == 12);
-  }
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(3) == 4);
-
-  return true;
-}
-
-bool TestPreambleAllocation() {
-  __int64 diff = 0;
-  void* p1 = reinterpret_cast<void*>(0x110000000);
-  void* p2 = reinterpret_cast<void*>(0x810000000);
-  unsigned char* b1 = PreamblePatcher::AllocPreambleBlockNear(p1);
-  SIDESTEP_EXPECT_TRUE(b1 != NULL);
-  diff = reinterpret_cast<__int64>(p1) - reinterpret_cast<__int64>(b1);
-  // Ensure blocks are within 2GB
-  SIDESTEP_EXPECT_TRUE(diff <= INT_MAX && diff >= INT_MIN);
-  unsigned char* b2 = PreamblePatcher::AllocPreambleBlockNear(p2);
-  SIDESTEP_EXPECT_TRUE(b2 != NULL);
-  diff = reinterpret_cast<__int64>(p2) - reinterpret_cast<__int64>(b2);
-  SIDESTEP_EXPECT_TRUE(diff <= INT_MAX && diff >= INT_MIN);
-
-  // Ensure we're reusing free blocks
-  unsigned char* b3 = b1;
-  unsigned char* b4 = b2;
-  PreamblePatcher::FreePreambleBlock(b1);
-  PreamblePatcher::FreePreambleBlock(b2);
-  b1 = PreamblePatcher::AllocPreambleBlockNear(p1);
-  SIDESTEP_EXPECT_TRUE(b1 == b3);
-  b2 = PreamblePatcher::AllocPreambleBlockNear(p2);
-  SIDESTEP_EXPECT_TRUE(b2 == b4);
-  PreamblePatcher::FreePreambleBlock(b1);
-  PreamblePatcher::FreePreambleBlock(b2);
-
-  return true;
-}
-
-bool UnitTests() {
-  return TestPatchWithPreambleNearRelativeCall() &&
-      TestPatchWithPreambleAbsoluteJump() &&
-      TestPatchWithPreambleNearRelativeCondJump() && 
-      TestPatchWithPreambleShortCondJump() &&
-      TestDisassembler() && TestPatchWithLongJump() &&
-      TestPatchUsingDynamicStub() && PatchThenUnpatch() &&
-      AutoTestingHookTest() && AutoTestingHookInContainerTest() &&
-      TestPreambleAllocation();
-}
-
-};  // namespace sidestep
-
-int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
-  if (size == 0)        // not even room for a \0?
-    return -1;          // not what C99 says to do, but what windows does
-  str[size-1] = '\0';
-  return _vsnprintf(str, size-1, format, ap);
-}
-
-int _tmain(int argc, _TCHAR* argv[])
-{
-  bool ret = sidestep::UnitTests();
-  printf("%s\n", ret ? "PASS" : "FAIL");
-  return ret ? 0 : -1;
-}
-
-#pragma optimize("", on)
diff --git a/third_party/tcmalloc/chromium/src/windows/preamble_patcher_with_stub.cc b/third_party/tcmalloc/chromium/src/windows/preamble_patcher_with_stub.cc
deleted file mode 100644
index 23f9d3a..0000000
--- a/third_party/tcmalloc/chromium/src/windows/preamble_patcher_with_stub.cc
+++ /dev/null
@@ -1,302 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- * Author: Scott Francis
- *
- * Implementation of PreamblePatcher
- */
-
-#include "preamble_patcher.h"
-
-#include "mini_disassembler.h"
-
-// Definitions of assembly statements we need
-#define ASM_JMP32REL 0xE9
-#define ASM_INT3 0xCC
-#define ASM_NOP 0x90
-// X64 opcodes
-#define ASM_MOVRAX_IMM 0xB8
-#define ASM_REXW 0x48
-#define ASM_JMP 0xFF
-#define ASM_JMP_RAX 0xE0
-#define ASM_PUSH 0x68
-#define ASM_RET 0xC3
-
-namespace sidestep {
-
-SideStepError PreamblePatcher::RawPatchWithStub(
-    void* target_function,
-    void* replacement_function,
-    unsigned char* preamble_stub,
-    unsigned long stub_size,
-    unsigned long* bytes_needed) {
-  if ((NULL == target_function) ||
-      (NULL == replacement_function) ||
-      (NULL == preamble_stub)) {
-    SIDESTEP_ASSERT(false &&
-                    "Invalid parameters - either pTargetFunction or "
-                    "pReplacementFunction or pPreambleStub were NULL.");
-    return SIDESTEP_INVALID_PARAMETER;
-  }
-
-  // TODO(V7:joi) Siggi and I just had a discussion and decided that both
-  // patching and unpatching are actually unsafe.  We also discussed a
-  // method of making it safe, which is to freeze all other threads in the
-  // process, check their thread context to see if their eip is currently
-  // inside the block of instructions we need to copy to the stub, and if so
-  // wait a bit and try again, then unfreeze all threads once we've patched.
-  // Not implementing this for now since we're only using SideStep for unit
-  // testing, but if we ever use it for production code this is what we
-  // should do.
-  //
-  // NOTE: Stoyan suggests we can write 8 or even 10 bytes atomically using
-  // FPU instructions, and on newer processors we could use cmpxchg8b or
-  // cmpxchg16b. So it might be possible to do the patching/unpatching
-  // atomically and avoid having to freeze other threads.  Note though, that
-  // doing it atomically does not help if one of the other threads happens
-  // to have its eip in the middle of the bytes you change while you change
-  // them.
-  unsigned char* target = reinterpret_cast<unsigned char*>(target_function);
-  unsigned int required_trampoline_bytes = 0;
-  const unsigned int kRequiredStubJumpBytes = 5;
-  const unsigned int kRequiredTargetPatchBytes = 5;
-
-  // Initialize the stub with INT3's just in case.
-  if (stub_size) {
-    memset(preamble_stub, 0xcc, stub_size);
-  }
-  if (kIs64BitBinary) {
-    // In 64-bit mode JMP instructions are always relative to RIP.  If the
-    // replacement - target offset is > 2GB, we can't JMP to the replacement
-    // function.  In this case, we're going to use a trampoline - that is,
-    // we're going to do a relative jump to a small chunk of code in the stub
-    // that will then do the absolute jump to the replacement function.  By
-    // doing this, we only need to patch 5 bytes in the target function, as
-    // opposed to patching 12 bytes if we were to do an absolute jump.
-    //
-    // Note that the first byte of the trampoline is a NOP instruction.  This
-    // is used as a trampoline signature that will be detected when unpatching
-    // the function.
-    //
-    // jmp <trampoline>
-    //
-    // trampoline:
-    //    nop
-    //    mov rax, <replacement_function>
-    //    jmp rax
-    //
-    __int64 replacement_target_offset = reinterpret_cast<__int64>(
-        replacement_function) - reinterpret_cast<__int64>(target) - 5;
-    if (replacement_target_offset > INT_MAX
-        || replacement_target_offset < INT_MIN) {
-      // The stub needs to be within 2GB of the target for the trampoline to
-      // work!
-      __int64 trampoline_offset = reinterpret_cast<__int64>(preamble_stub)
-          - reinterpret_cast<__int64>(target) - 5;
-      if (trampoline_offset > INT_MAX || trampoline_offset < INT_MIN) {
-        // We're screwed.
-        SIDESTEP_ASSERT(false 
-                       && "Preamble stub is too far from target to patch.");
-        return SIDESTEP_UNEXPECTED;
-      }
-      required_trampoline_bytes = 13;
-    }
-  }
-
-  // Let's disassemble the preamble of the target function to see if we can
-  // patch, and to see how much of the preamble we need to take.  We need 5
-  // bytes for our jmp instruction, so let's find the minimum number of
-  // instructions to get 5 bytes.
-  MiniDisassembler disassembler;
-  unsigned int preamble_bytes = 0;
-  unsigned int stub_bytes = 0;
-  while (preamble_bytes < kRequiredTargetPatchBytes) {
-    unsigned int cur_bytes = 0;
-    InstructionType instruction_type =
-        disassembler.Disassemble(target + preamble_bytes, cur_bytes);
-    if (IT_JUMP == instruction_type) {
-      unsigned int jump_bytes = 0;
-      SideStepError jump_ret = SIDESTEP_JUMP_INSTRUCTION;
-      if (IsShortConditionalJump(target + preamble_bytes, cur_bytes)) {
-        jump_ret = PatchShortConditionalJump(target + preamble_bytes, cur_bytes,
-                                             preamble_stub + stub_bytes,
-                                             &jump_bytes,
-                                             stub_size - stub_bytes);
-      } else if (IsShortJump(target + preamble_bytes, cur_bytes)) {
-        jump_ret = PatchShortJump(target + preamble_bytes, cur_bytes,
-                                  preamble_stub + stub_bytes,
-                                  &jump_bytes,
-                                  stub_size - stub_bytes);
-      } else if (IsNearConditionalJump(target + preamble_bytes, cur_bytes) ||
-                 IsNearRelativeJump(target + preamble_bytes, cur_bytes) ||
-                 IsNearAbsoluteCall(target + preamble_bytes, cur_bytes) ||
-                 IsNearRelativeCall(target + preamble_bytes, cur_bytes)) {
-         jump_ret = PatchNearJumpOrCall(target + preamble_bytes, cur_bytes,
-                                        preamble_stub + stub_bytes, &jump_bytes,
-                                        stub_size - stub_bytes);
-      }
-      if (jump_ret != SIDESTEP_SUCCESS) {
-        SIDESTEP_ASSERT(false &&
-                        "Unable to patch because there is an unhandled branch "
-                        "instruction in the initial preamble bytes.");
-        return SIDESTEP_JUMP_INSTRUCTION;
-      }
-      stub_bytes += jump_bytes;
-    } else if (IT_RETURN == instruction_type) {
-      SIDESTEP_ASSERT(false &&
-                      "Unable to patch because function is too short");
-      return SIDESTEP_FUNCTION_TOO_SMALL;
-    } else if (IT_GENERIC == instruction_type) {
-      if (IsMovWithDisplacement(target + preamble_bytes, cur_bytes)) {
-        unsigned int mov_bytes = 0;
-        if (PatchMovWithDisplacement(target + preamble_bytes, cur_bytes,
-                                     preamble_stub + stub_bytes, &mov_bytes,
-                                     stub_size - stub_bytes)
-            != SIDESTEP_SUCCESS) {
-          return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-        }
-        stub_bytes += mov_bytes;
-      } else {
-        memcpy(reinterpret_cast<void*>(preamble_stub + stub_bytes),
-               reinterpret_cast<void*>(target + preamble_bytes), cur_bytes);
-        stub_bytes += cur_bytes;
-      }
-    } else {
-      SIDESTEP_ASSERT(false &&
-                      "Disassembler encountered unsupported instruction "
-                      "(either unused or unknown");
-      return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-    }
-    preamble_bytes += cur_bytes;
-  }
-
-  if (NULL != bytes_needed)
-    *bytes_needed = stub_bytes + kRequiredStubJumpBytes
-        + required_trampoline_bytes;
-
-  // Inv: cbPreamble is the number of bytes (at least 5) that we need to take
-  // from the preamble to have whole instructions that are 5 bytes or more
-  // in size total. The size of the stub required is cbPreamble +
-  // kRequiredStubJumpBytes (5) + required_trampoline_bytes (0 or 13)
-  if (stub_bytes + kRequiredStubJumpBytes + required_trampoline_bytes
-      > stub_size) {
-    SIDESTEP_ASSERT(false);
-    return SIDESTEP_INSUFFICIENT_BUFFER;
-  }
-
-  // Now, make a jmp instruction to the rest of the target function (minus the
-  // preamble bytes we moved into the stub) and copy it into our preamble-stub.
-  // find address to jump to, relative to next address after jmp instruction
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4244)
-#endif
-  int relative_offset_to_target_rest
-      = ((reinterpret_cast<unsigned char*>(target) + preamble_bytes) -
-         (preamble_stub + stub_bytes + kRequiredStubJumpBytes));
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-  // jmp (Jump near, relative, displacement relative to next instruction)
-  preamble_stub[stub_bytes] = ASM_JMP32REL;
-  // copy the address
-  memcpy(reinterpret_cast<void*>(preamble_stub + stub_bytes + 1),
-         reinterpret_cast<void*>(&relative_offset_to_target_rest), 4);
-
-  if (kIs64BitBinary && required_trampoline_bytes != 0) {
-    // Construct the trampoline
-    unsigned int trampoline_pos = stub_bytes + kRequiredStubJumpBytes;
-    preamble_stub[trampoline_pos] = ASM_NOP;
-    preamble_stub[trampoline_pos + 1] = ASM_REXW;
-    preamble_stub[trampoline_pos + 2] = ASM_MOVRAX_IMM;
-    memcpy(reinterpret_cast<void*>(preamble_stub + trampoline_pos + 3),
-           reinterpret_cast<void*>(&replacement_function),
-           sizeof(void *));
-    preamble_stub[trampoline_pos + 11] = ASM_JMP;
-    preamble_stub[trampoline_pos + 12] = ASM_JMP_RAX;
-
-    // Now update replacement_function to point to the trampoline
-    replacement_function = preamble_stub + trampoline_pos;
-  }
-
-  // Inv: preamble_stub points to assembly code that will execute the
-  // original function by first executing the first cbPreamble bytes of the
-  // preamble, then jumping to the rest of the function.
-
-  // Overwrite the first 5 bytes of the target function with a jump to our
-  // replacement function.
-  // (Jump near, relative, displacement relative to next instruction)
-  target[0] = ASM_JMP32REL;
-
-  // Find offset from instruction after jmp, to the replacement function.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4244)
-#endif
-  int offset_to_replacement_function =
-      reinterpret_cast<unsigned char*>(replacement_function) -
-      reinterpret_cast<unsigned char*>(target) - 5;
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-  // complete the jmp instruction
-  memcpy(reinterpret_cast<void*>(target + 1),
-         reinterpret_cast<void*>(&offset_to_replacement_function), 4);
-
-  // Set any remaining bytes that were moved to the preamble-stub to INT3 so
-  // as not to cause confusion (otherwise you might see some strange
-  // instructions if you look at the disassembly, or even invalid
-  // instructions). Also, by doing this, we will break into the debugger if
-  // some code calls into this portion of the code.  If this happens, it
-  // means that this function cannot be patched using this patcher without
-  // further thought.
-  if (preamble_bytes > kRequiredTargetPatchBytes) {
-    memset(reinterpret_cast<void*>(target + kRequiredTargetPatchBytes),
-           ASM_INT3, preamble_bytes - kRequiredTargetPatchBytes);
-  }
-
-  // Inv: The memory pointed to by target_function now points to a relative
-  // jump instruction that jumps over to the preamble_stub.  The preamble
-  // stub contains the first stub_size bytes of the original target
-  // function's preamble code, followed by a relative jump back to the next
-  // instruction after the first cbPreamble bytes.
-  //
-  // In 64-bit mode the memory pointed to by target_function *may* point to a
-  // relative jump instruction that jumps to a trampoline which will then
-  // perform an absolute jump to the replacement function.  The preamble stub
-  // still contains the original target function's preamble code, followed by a
-  // jump back to the instructions after the first preamble bytes.
-  //
-  return SIDESTEP_SUCCESS;
-}
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/chromium/src/windows/shortproc.asm b/third_party/tcmalloc/chromium/src/windows/shortproc.asm
deleted file mode 100644
index 7e8e3d7..0000000
--- a/third_party/tcmalloc/chromium/src/windows/shortproc.asm
+++ /dev/null
@@ -1,169 +0,0 @@
-; Copyright (c) 2011, Google Inc.
-; All rights reserved.
-; 
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions are
-; met:
-; 
-;     * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-;     * Redistributions in binary form must reproduce the above
-; copyright notice, this list of conditions and the following disclaimer
-; in the documentation and/or other materials provided with the
-; distribution.
-;     * Neither the name of Google Inc. nor the names of its
-; contributors may be used to endorse or promote products derived from
-; this software without specific prior written permission.
-; 
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-;
-; ---
-; Author: Scott Francis
-;
-; Unit tests for PreamblePatcher

- 

-.MODEL small

- 

-.CODE

-

-TooShortFunction PROC

-	ret

-TooShortFunction ENDP

-

-JumpShortCondFunction PROC

-	test cl, 1

-	jnz jumpspot

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-jumpspot:

-	nop

-	nop

-	nop

-	nop

-	mov rax, 1

-	ret

-JumpShortCondFunction ENDP

-

-JumpNearCondFunction PROC

-	test cl, 1

-	jnz jumpspot

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-jumpspot:

-	nop

-	nop

-	mov rax, 1

-	ret

-JumpNearCondFunction ENDP

-

-JumpAbsoluteFunction PROC

-	test cl, 1

-	jmp jumpspot

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-jumpspot:

-	nop

-	nop

-	mov rax, 1

-	ret

-JumpAbsoluteFunction ENDP

-

-CallNearRelativeFunction PROC

-	test cl, 1

-	call TooShortFunction

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	nop

-	nop

-	nop

-	ret

-CallNearRelativeFunction ENDP

-

-END

diff --git a/third_party/tcmalloc/chromium/src/windows/system-alloc.cc b/third_party/tcmalloc/chromium/src/windows/system-alloc.cc
deleted file mode 100644
index ea1f17d9..0000000
--- a/third_party/tcmalloc/chromium/src/windows/system-alloc.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (c) 2013, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Petr Hosek
-
-#ifndef _WIN32
-# error You should only be including windows/system-alloc.cc in a windows environment!
-#endif
-
-#include <config.h>
-#include <windows.h>
-#include <algorithm> // std::min
-#include <gperftools/malloc_extension.h>
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "internal_logging.h"
-#include "system-alloc.h"
-
-static SpinLock spinlock(SpinLock::LINKER_INITIALIZED);
-
-// The current system allocator declaration
-SysAllocator* tcmalloc_sys_alloc = NULL;
-// Number of bytes taken from system.
-size_t TCMalloc_SystemTaken = 0;
-
-class VirtualSysAllocator : public SysAllocator {
-public:
-  VirtualSysAllocator() : SysAllocator() {
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-};
-static char virtual_space[sizeof(VirtualSysAllocator)];
-
-// This is mostly like MmapSysAllocator::Alloc, except it does these weird
-// munmap's in the middle of the page, which is forbidden in windows.
-void* VirtualSysAllocator::Alloc(size_t size, size_t *actual_size,
-                                 size_t alignment) {
-  // Align on the pagesize boundary
-  const int pagesize = getpagesize();
-  if (alignment < pagesize) alignment = pagesize;
-  size = ((size + alignment - 1) / alignment) * alignment;
-
-  // Report the total number of bytes the OS actually delivered.  This might be
-  // greater than |size| because of alignment concerns.  The full size is
-  // necessary so that adjacent spans can be coalesced.
-  // TODO(antonm): proper processing of alignments
-  // in actual_size and decommitting.
-  if (actual_size) {
-    *actual_size = size;
-  }
-
-  // We currently do not support alignments larger than the pagesize or
-  // alignments that are not multiples of the pagesize after being floored.
-  // If this ability is needed it can be done by the caller (assuming it knows
-  // the page size).
-  assert(alignment <= pagesize);
-
-  void* result = VirtualAlloc(0, size,
-                              MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
-  if (result == NULL)
-    return NULL;
-
-  // If the result is not aligned memory fragmentation will result which can
-  // lead to pathological memory use.
-  assert((reinterpret_cast<uintptr_t>(result) & (alignment - 1)) == 0);
-
-  return result;
-}
-
-#ifdef _MSC_VER
-
-extern "C" SysAllocator* tc_get_sysalloc_override(SysAllocator *def);
-extern "C" SysAllocator* tc_get_sysalloc_default(SysAllocator *def)
-{
-  return def;
-}
-
-#if defined(_M_IX86)
-#pragma comment(linker, "/alternatename:_tc_get_sysalloc_override=_tc_get_sysalloc_default")
-#elif defined(_M_X64)
-#pragma comment(linker, "/alternatename:tc_get_sysalloc_override=tc_get_sysalloc_default")
-#endif
-
-#else // !_MSC_VER
-
-extern "C" ATTRIBUTE_NOINLINE
-SysAllocator* tc_get_sysalloc_override(SysAllocator *def)
-{
-  return def;
-}
-
-#endif
-
-static bool system_alloc_inited = false;
-void InitSystemAllocators(void) {
-  VirtualSysAllocator *alloc = new (virtual_space) VirtualSysAllocator();
-  tcmalloc_sys_alloc = tc_get_sysalloc_override(alloc);
-}
-
-extern PERFTOOLS_DLL_DECL
-void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
-			   size_t alignment) {
-  SpinLockHolder lock_holder(&spinlock);
-
-  if (!system_alloc_inited) {
-    InitSystemAllocators();
-    system_alloc_inited = true;
-  }
-
-  void* result = tcmalloc_sys_alloc->Alloc(size, actual_size, alignment);
-  if (result != NULL) {
-    if (actual_size) {
-      TCMalloc_SystemTaken += *actual_size;
-    } else {
-      TCMalloc_SystemTaken += size;
-    }
-  }
-  return result;
-}
-
-extern PERFTOOLS_DLL_DECL
-bool TCMalloc_SystemRelease(void* start, size_t length) {
-  if (VirtualFree(start, length, MEM_DECOMMIT))
-    return true;
-
-  // The decommit may fail if the memory region consists of allocations
-  // from more than one call to VirtualAlloc.  In this case, fall back to
-  // using VirtualQuery to retrieve the allocation boundaries and decommit
-  // them each individually.
-
-  char* ptr = static_cast<char*>(start);
-  char* end = ptr + length;
-  MEMORY_BASIC_INFORMATION info;
-  while (ptr < end) {
-    size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
-    assert(resultSize == sizeof(info));
-    size_t decommitSize = std::min<size_t>(info.RegionSize, end - ptr);
-    BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT);
-    assert(success == TRUE);
-    ptr += decommitSize;
-  }
-
-  return true;
-}
-
-extern PERFTOOLS_DLL_DECL
-void TCMalloc_SystemCommit(void* start, size_t length) {
-  if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start)
-    return;
-
-  // The commit may fail if the memory region consists of allocations
-  // from more than one call to VirtualAlloc.  In this case, fall back to
-  // using VirtualQuery to retrieve the allocation boundaries and commit them
-  // each individually.
-
-  char* ptr = static_cast<char*>(start);
-  char* end = ptr + length;
-  MEMORY_BASIC_INFORMATION info;
-  while (ptr < end) {
-    size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
-    assert(resultSize == sizeof(info));
-
-    size_t commitSize = std::min<size_t>(info.RegionSize, end - ptr);
-    void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT,
-                                    PAGE_READWRITE);
-    assert(newAddress == ptr);
-    ptr += commitSize;
-  }
-}
-
-bool RegisterSystemAllocator(SysAllocator *allocator, int priority) {
-  return false;   // we don't allow registration on windows, right now
-}
-
-void DumpSystemAllocatorStats(TCMalloc_Printer* printer) {
-  // We don't dump stats on windows, right now
-}
diff --git a/third_party/tcmalloc/vendor/.gitignore b/third_party/tcmalloc/vendor/.gitignore
deleted file mode 100644
index 42328f2..0000000
--- a/third_party/tcmalloc/vendor/.gitignore
+++ /dev/null
@@ -1,147 +0,0 @@
-*.[oa]
-*.la
-*.lo
-*~
-/*.log
-/*.trs
-/.deps
-/.libs
-/GPATH
-/GRTAGS
-/GSYMS
-/GTAGS
-/ID
-/Makefile
-/Makefile.in
-/aclocal.m4
-/addressmap_unittest
-/addressmap_unittest.exe
-/atomicops_unittest
-/atomicops_unittest.exe
-/autom4te.cache/
-/benchmark/.deps
-/benchmark/.dirstamp
-/binary_trees
-/binary_trees.exe
-/binary_trees_shared
-/binary_trees_shared.exe
-/compile
-/config.guess
-/config.log
-/config.status
-/config.sub
-/configure
-/current_allocated_bytes_test
-/current_allocated_bytes_test.exe
-/debugallocation_test
-/debugallocation_test.sh
-/depcomp
-/frag_unittest
-/frag_unittest.exe
-/getpc_test
-/gperftools-*.tar.gz
-/gperftools-*.zip
-/heap-checker-death_unittest.sh
-/heap-checker_debug_unittest
-/heap-checker_debug_unittest.sh
-/heap-checker_unittest
-/heap-checker_unittest.sh
-/heap-profiler_debug_unittest
-/heap-profiler_debug_unittest.sh
-/heap-profiler_unittest
-/heap-profiler_unittest.sh
-/install-sh
-/libprofiler.pc
-/libtcmalloc.pc
-/libtcmalloc_debug.pc
-/libtcmalloc_minimal.pc
-/libtcmalloc_minimal_debug.pc
-/libtool
-/low_level_alloc_unittest
-/low_level_alloc_unittest.exe
-/ltmain.sh
-/m4/libtool.m4
-/m4/ltoptions.m4
-/m4/ltsugar.m4
-/m4/ltversion.m4
-/m4/lt~obsolete.m4
-/malloc_bench
-/malloc_bench.exe
-/malloc_bench_shared
-/malloc_bench_shared.exe
-/malloc_bench_shared_full
-/malloc_bench_shared_full.exe
-/malloc_extension_c_test
-/malloc_extension_debug_test
-/malloc_extension_test
-/malloc_extension_test.exe
-/malloc_hook_test
-/malloc_hook_test.exe
-/markidle_unittest
-/markidle_unittest.exe
-/maybe_threads_unittest.sh
-/memalign_debug_unittest
-/memalign_unittest
-/missing
-/packed_cache_test
-/packed_cache_test.exe
-/page_heap_test
-/page_heap_test.exe
-/pagemap_unittest
-/pagemap_unittest.exe
-/profile_handler_unittest
-/profiledata_unittest
-/profiler1_unittest
-/profiler2_unittest
-/profiler3_unittest
-/profiler4_unittest
-/profiler_unittest.sh
-/raw_printer_test
-/realloc_debug_unittest
-/realloc_unittest
-/realloc_unittest.exe
-/sampler_debug_test
-/sampler_test
-/sampling_debug_test
-/sampling_debug_test.sh
-/sampling_test
-/sampling_test.sh
-/simple_compat_test
-/src/.deps
-/src/.dirstamp
-/src/base/.deps
-/src/base/.dirstamp
-/src/config.h
-/src/config.h.in
-/src/gperftools/tcmalloc.h
-/src/stamp-h1
-/src/stamp-h1
-/src/tests/.deps
-/src/tests/.dirstamp
-/src/windows/.deps
-/src/windows/.dirstamp
-/stack_trace_table_test
-/stack_trace_table_test.exe
-/stacktrace_unittest
-/system_alloc_unittest
-/tcm_min_asserts_unittest
-/tcm_min_asserts_unittest.exe
-/tcmalloc_and_profiler_unittest
-/tcmalloc_both_unittest
-/tcmalloc_debug_unittest
-/tcmalloc_large_heap_fragmentation_unittest
-/tcmalloc_large_unittest
-/tcmalloc_minimal_debug_unittest
-/tcmalloc_minimal_large_heap_fragmentation_unittest
-/tcmalloc_minimal_large_heap_fragmentation_unittest.exe
-/tcmalloc_minimal_large_unittest
-/tcmalloc_minimal_large_unittest.exe
-/tcmalloc_minimal_unittest
-/tcmalloc_minimal_unittest.exe
-/tcmalloc_unittest
-/tcmalloc_unittest.sh
-/test-driver
-/thread_dealloc_unittest
-/thread_dealloc_unittest.exe
-/unwind_bench
-/unwind_bench.exe
diff --git a/third_party/tcmalloc/vendor/.travis.yml b/third_party/tcmalloc/vendor/.travis.yml
deleted file mode 100644
index 07bf244..0000000
--- a/third_party/tcmalloc/vendor/.travis.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-language: c++
-sudo: required
-dist: trusty
-script: ./autogen.sh && ./configure && make -j`getconf _NPROCESSORS_ONLN` && make check
diff --git a/third_party/tcmalloc/vendor/AUTHORS b/third_party/tcmalloc/vendor/AUTHORS
deleted file mode 100644
index 3995ed4cf..0000000
--- a/third_party/tcmalloc/vendor/AUTHORS
+++ /dev/null
@@ -1,2 +0,0 @@
-google-perftools@googlegroups.com
-
diff --git a/third_party/tcmalloc/vendor/COPYING b/third_party/tcmalloc/vendor/COPYING
deleted file mode 100644
index e4956cfd..0000000
--- a/third_party/tcmalloc/vendor/COPYING
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2005, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/tcmalloc/vendor/ChangeLog b/third_party/tcmalloc/vendor/ChangeLog
deleted file mode 100644
index 92bcb9b9..0000000
--- a/third_party/tcmalloc/vendor/ChangeLog
+++ /dev/null
@@ -1,2 +0,0 @@
-The ChangeLog is auto-generated when releasing.
-If you are seeing this, use 'git log' for a detailed list of changes.
diff --git a/third_party/tcmalloc/vendor/ChangeLog.old b/third_party/tcmalloc/vendor/ChangeLog.old
deleted file mode 100644
index 4b334bea..0000000
--- a/third_party/tcmalloc/vendor/ChangeLog.old
+++ /dev/null
@@ -1,646 +0,0 @@
-Fri Feb 03 15:40:45 2012  Google Inc. <google-perftools@googlegroups.com>
-
-	* gperftools: version 2.0
-	* Renamed the project from google-perftools to gperftools (csilvers)
-	* Renamed the .deb/.rpm packagse from google-perftools to gperftools too
-	* Renamed include directory from google/ to gperftools/ (csilvers)
-	* Changed the 'official' perftools email in setup.py/etc
-	* Renamed google-perftools.sln to gperftools.sln
-	* PORTING: Removed bash-isms & grep -q in heap-checker-death_unittest.sh
-	* Changed copyright text to reflect Google's relinquished ownership
-
-Tue Jan 31 10:43:50 2012    Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.10 release
-	* PORTING: Support for patching assembly on win x86_64! (scott.fr...)
-	* PORTING: Work around atexit-execution-order bug on freebsd (csilvers)
-	* PORTING: Patch _calloc_crt for windows (roger orr)
-	* PORTING: Add C++11 compatibility method for stl allocator (jdennett)
-	* PORTING: use MADV_FREE, not MADV_DONTNEED, on freebsd (csilvers)
-	* PORTING: Don't use SYS_open when not supported on solaris (csilvers)
-	* PORTING: Do not assume uname() returns 0 on success (csilvers)
-	* LSS: Improved ARM support in linux-syscall-support (dougkwan)
-	* LSS: Get rid of unused syscalls in linux-syscall-support (csilvers)
-	* LSS: Fix broken mmap wrapping for ppc (markus)
-	* LSS: Emit .cfi_adjust_cfa_offset when appropriate (ppluzhnikov)
-	* LSS: Be more accurate in register use in __asm__ (markus)
-	* LSS: Fix __asm__ calls to compile under clang (chandlerc)
-	* LSS: Fix ARM inline assembly bug around r7 and swi (lcwu)
-	* No longer log when an allocator fails (csilvers)
-	* void* -> const void* for MallocExtension methods (llib)
-	* Improve HEAP_PROFILE_MMAP and fix bugs with it (dmikurube)
-	* Replace int-based abs with more correct fabs in a test (pmurin)
-
-Thu Dec 22 16:22:45 2011    Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.9 release
-	* Lightweight check for double-frees (blount)
-	* BUGFIX: Fix pprof to exit properly if run with no args (dagitses)
-	* Suggest ASan as a way to diagnose buggy code (ppluzhnikov)
-	* Get rid of unused CACHELINE_SIZE (csilvers)
-	* Replace atexit() calls with global dtors; helps freebsd (csilvers)
-	* Disable heap-checker under AddressSanitizer (kcc)
-	* Fix bug in powerpc stacktracing (ppluzhnikov)
-	* PERF: Use exponential backoff waiting for spinlocks (m3b)
-	* Fix 64-bit nm on 32-bit binaries in pprof (csilvers)
-	* Add ProfileHandlerDisallowForever (rsc)
-	* BUGFIX: Shell escape when forking in pprof (csilvers)
-	* No longer combine overloaded functions in pprof (csilvers)
-	* Fix address-normalizing bug in pprof (csilvers)
-	* More consistently call abort() instead of exit() on failure (csilvers)
-	* Allow NoGlobalLeaks to be safely called more than once (csilvers)
-	* PORTING/BUGFIX: Fix ARM cycleclock to use volatile asm (dougkwan)
-	* PORTING: 64-bit atomic ops for ARMv7 (dougkwan)
-	* PORTING: Implement stacktrace for ARM (dougkwan)
-	* PORTING: Fix malloc_hook_mmap_linux for ARM (dougkwan)
-	* PORTING: Update linux_syscall_support.h for ARM/etc (evannier, sanek)
-	* PORTING: Fix freebsd to work on x86_64 (chapp...@gmail.com)
-	* PORTING: Added additional SYS_mmap fixes for FreeBSD (chappedm)
-	* PORTING: Allow us to compile on OS X 10.6 and run on 10.5 (raltherr)
-	* PORTING: Check for mingw compilers that *do* define timespec
-	* PORTING: Add "support" for MIPS cycletimer
-	* PORTING: Fix fallback cycle-timer to work with Now (dougkwan)
-	* PERF: Move stack trace collecting out of the mutex (taylorc)
-	* PERF: Get the deallocation stack trace outside the mutex (sean)
-	* Make PageHeap dynamically allocated for leak checks (maxim)
-	* BUGFIX: Fix probing of nm -f behavior in pprof (dpeng)
-	* BUGFIX: Fix a race with the CentralFreeList lock before main (sanjay)
-	* Support /pprof/censusprofile url arguments (rajatjain)
-	* Change IgnoreObject to return its argument (nlewycky)
-	* Update malloc-hook files to support more CPUs
-	* BUGFIX: write our own strstr to avoid libc problems (csilvers)
-	* Use simple callgrind compression facility in pprof
-	* Print an error message when we can't run pprof to symbolize (csilvers)
-	* Die in configure when g++ is't installed (csilvers)
-	* DOC: Beef up the documentation a bit about using libunwind (csilvers)
-
-Fri Aug 26 13:29:25 2011    Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.8.3 release
-	* Added back the 'pthreads unsafe early' #define, needed for FreeBSD
-
-Thu Aug 11 15:01:47 2011    Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.8.2 release
-	* Fixed calculation of patchlevel, 'make check' should all pass again
-
-Tue Jul 26 20:57:51 2011    Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.8.1 release
-	* Added an #include to fix compile breakage on latest gcc's
-	* Removed an extra , in the configure.ac script
-
-Fri Jul 15 16:10:51 2011    Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.8 release
-	* PORTING: (Disabled) support for patching mmap on freebsd (chapp...)
-	* PORTING: Support volatile __malloc_hook for glibc 2.14 (csilvers)
-	* PORTING: Use _asm rdtsc and __rdtsc to get cycleclock in windows (koda)
-	* PORTING: Fix fd vs. HANDLE compiler error on cygwin (csilvers)
-	* PORTING: Do not test memalign or double-linking on OS X (csilvers)
-	* PORTING: Actually enable TLS on windows (jontra)
-	* PORTING: Some work to compile under Native Client (krasin)
-	* PORTING: deal with pthread_once w/o -pthread on freebsd (csilvers)
-	* Rearrange libc-overriding to make it easier to port (csilvers)
-	* Display source locations in pprof disassembly (sanjay)
-	* BUGFIX: Actually initialize allocator name (mec)
-	* BUGFIX: Keep track of 'overhead' bytes in malloc reporting (csilvers)
-	* Allow ignoring one object twice in the leak checker (glider)
-	* BUGFIX: top10 in pprof should print 10 lines, not 11 (rsc)
-	* Refactor vdso source files (tipp)
-	* Some documentation cleanups
-	* Document MAX_TOTAL_THREAD_CACHE_SIZE <= 1Gb (nsethi)
-	* Add MallocExtension::GetOwnership(ptr) (csilvers)
-	* BUGFIX: We were leaving out a needed $(top_srcdir) in the Makefile
-	* PORTING: Support getting argv0 on OS X
-	* Add 'weblist' command to pprof: like 'list' but html (sanjay)
-	* Improve source listing in pprof (sanjay)
-	* Cap cache sizes to reduce fragmentation (ruemmler)
-	* Improve performance by capping or increasing sizes (ruemmler)
-	* Add M{,un}mapReplacmenet hooks into MallocHook (ribrdb)
-	* Refactored system allocator logic (gangren)
-	* Include cleanups (csilvers)
-	* Add TCMALLOC_SMALL_BUT_SLOW support (ruemmler)
-	* Clarify that tcmalloc stats are MiB (robinson)
-	* Remove support for non-tcmalloc debugallocation (blount)
-	* Add a new test: malloc_hook_test (csilvers)
-	* Change the configure script to be more crosstool-friendly (mcgrathr)
-	* PORTING: leading-underscore changes to support win64 (csilvers)
-	* Improve debugallocation tc_malloc_size (csilvers)
-	* Extend atomicops.h and cyceclock to use ARM V6+ optimized code (sanek)
-	* Change malloc-hook to use a list-like structure (llib)
-	* Add flag to use MAP_PRIVATE in memfs_malloc (gangren)
-	* Windows support for pprof: nul and /usr/bin/file (csilvers)
-	* TESTING: add test on strdup to tcmalloc_test (csilvers)
-	* Augment heap-checker to deal with no-inode maps (csilvers)
-	* Count .dll/.dylib as shared libs in heap-checker (csilvers)
-	* Disable sys_futex for arm; it's not always reliable (sanek)
-	* PORTING: change lots of windows/port.h macros to functions
-	* BUGFIX: Generate correct version# in tcmalloc.h on windows (csilvers)
-	* PORTING: Some casting to make solaris happier about types (csilvers)
-	* TESTING: Disable debugallocation_test in 'minimal' mode (csilvers)
-	* Rewrite debugallocation to be more modular (csilvers)
-	* Don't try to run the heap-checker under valgrind (ppluzhnikov)
-	* BUGFIX: Make focused stat %'s relative, not absolute (sanjay)
-	* BUGFIX: Don't use '//' comments in a C file (csilvers)
-	* Quiet new-gcc compiler warnings via -Wno-unused-result, etc (csilvers)
-
-Fri Feb 04 15:54:31 2011    Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.7 release
-	* Reduce page map key size under x86_64 by 4.4MB (rus)
-	* Remove a flaky malloc-extension test (fdabek)
-	* Improve the performance of PageHeap::New (ond..., csilvers)
-	* Improve sampling_test with no-inline additions/etc (fdabek)
-	* 16-byte align debug allocs (jyasskin)
-	* Change FillProcSelfMaps to detect out-of-buffer-space (csilvers)
-	* Document the need for sampling to use GetHeapSample (csilvers)
-	* Try to read TSC frequency from tsc_freq_khs (adurbin)
-	* Do better at figuring out if tests are running under gdb (ppluzhnikov)
-	* Improve spinlock contention performance (ruemmler)
-	* Better internal-function list for pprof's /contention (ruemmler)
-	* Speed up GoogleOnce (m3b)
-	* Limit number of incoming/outgoing edges in pprof (sanjay)
-	* Add pprof --evince to go along with --gv (csilvers)
-	* Document the various ways to get heap-profiling information (csilvers)
-	* Separate out synchronization profiling routines (ruemmler)
-	* Improve malloc-stats output to be more understandable (csilvers)
-	* Add support for census profiler in pporf (nabeelmian)
-	* Document how pprof's /symbol must support GET requests (csilvers)
-	* Improve acx_pthread.m4 (ssuomi, liujisi)
-	* Speed up pprof's ExtractSymbols (csilvers)
-	* Ignore some known-leaky (java) libraries in the heap checker (davidyu)
-	* Make kHideMask use all 64 bits in tests (ppluzhnikov)
-	* Clean up pprof input-file handling (csilvers)
-	* BUGFIX: Don't crash if __environ is NULL (csilvers)
-	* BUGFIX: Fix totally broken debugallocation tests (csilvers)
-	* BUGFIX: Fix up fake_VDSO handling for unittest (ppluzhnikov)
-	* BUGFIX: Suppress all large allocs when report threshold is 0 (lexie)
-	* BUGFIX: mmap2 on i386 takes an off_t, not off64_t (csilvers)
-	* PORTING: Add missing PERFTOOLS_DLL_DECL (csilvers)
-	* PORTING: Add stddef.h to make newer gcc's happy (csilvers)
-	* PORTING: Document some tricks for working under OS X (csilvers)
-	* PORTING: Don't try to check valgrind for windows (csilvers)
-	* PORTING: Make array-size a var to compile under clang (chandlerc)
-	* PORTING: No longer hook _aligned_malloc and _aligned_free (csilvers)
-	* PORTING: Quiet some gcc warnings (csilvers)
-	* PORTING: Replace %PRIxPTR with %p to be more portable (csilvers)
-	* PORTING: Support systems that capitalize /proc weirdly (sanek)
-	* PORTING: Treat arm3 the same as arm5t in cycletimer (csilvers)
-	* PORTING: Update windows logging to not allocate memory (csilvers)
-	* PORTING: avoid double-patching newer windows DLLs (roger.orr)
-	* PORTING: get dynamic_annotations.c to work on windows (csilvers)
-	* Add pkg-config .pc files for the 5 libraries we produce (csilvers)
-	* Added proper libtool versioning, so this lib will be 0.1.0 (csilvers)
-	* Moved from autoconf 2.64 to 2.65
-
-Thu Aug  5 12:48:03 PDT 2010  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.6 release
-	* Add tc_malloc_usable_size for compatibility with glibc (csilvers)
-	* Override malloc_usable_size with tc_malloc_usable_size (csilvers)
-	* Default to no automatic heap sampling in tcmalloc (csilvers)
-	* Add -DTCMALLOC_LARGE_PAGES, a possibly faster tcmalloc (rus)
-	* Make some functions extern "C" to avoid false ODR warnings (jyasskin)
-	* pprof: Add SVG-based output (rsc)
-	* pprof: Extend pprof --tools to allow per-tool configs (csilvers)
-	* pprof: Improve support of 64-bit and big-endian profiles (csilvers)
-	* pprof: Add interactive callgrind suport (weidenri...)
-	* pprof: Improve address->function mapping a bit (dpeng)
-	* Better detection of when we're running under valgrind (csilvers)
-	* Better CPU-speed detection under valgrind (saito)
-	* Use, and recommend, -fno-builtin-malloc when compiling (csilvers)
-	* Avoid false-sharing of memory between caches (bmaurer)
-	* BUGFIX: Fix heap sampling to use correct alloc size (bmauer)
-	* BUGFIX: Avoid gcc 4.0.x bug by making hook-clearing atomic (csilvers)
-	* BUGFIX: Avoid gcc 4.5.x optimization bug (csilvers)
-	* BUGFIX: Work around deps-determining bug in libtool 1.5.26 (csilvers)
-	* BUGFIX: Fixed test to use HAVE_PTHREAD, not HAVE_PTHREADS (csilvers)
-	* BUGFIX: Fix tls callback behavior on windows when using wpo (wtc)
-	* BUGFIX: properly align allocation sizes on Windows (antonm)
-	* BUGFIX: Fix prototypes for tcmalloc/debugalloc wrt throw() (csilvers)
-	* DOC: Updated heap-checker doc to match reality better (fischman)
-	* DOC: Document ProfilerFlush, ProfilerStartWithOptions (csilvers)
-	* DOC: Update docs for heap-profiler functions (csilvers)
-	* DOC: Clean up documentation around tcmalloc.slack_bytes (fikes)
-	* DOC: Renamed README.windows to README_windows.txt (csilvers)
-	* DOC: Update the NEWS file to be non-empty (csilvers)
-	* PORTING: Fix windows addr2line and nm with proper rc code (csilvers)
-	* PORTING: Add CycleClock and atomicops support for arm 5 (sanek)
-	* PORTING: Improve PC finding on cygwin and redhat 7 (csilvers)
-	* PORTING: speed up function-patching under windows (csilvers)
-
-Tue Jan 19 14:46:12 2010  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.5 release
-	* Add tc_set_new_mode (willchan)
-	* Make memalign functions + realloc respect tc_set_new_mode (willchan)
-	* Add ReleaseToSystem(num_bytes) (kash)
-	* Handle zero-length symbols a bit better in pprof (csilvers)
-	* Prefer __environ to /proc/self/environ in cpu profiler (csilvers)
-	* Add HEAP_CHECK_MAX_LEAKS flag to control #leaks to report (glider)
-	* Add two new numeric pageheap properties to MallocExtension (fikes)
-	* Print alloc size when mmap fails (hakon)
-	* Add ITIMER_REAL support to cpu profiler (csilvers, nabeelmian)
-	* Speed up symbolizer in heap-checker reporting (glider)
-	* Speed up futexes with FUTEX_PRIVATE_FLAG (m3b)
-	* Speed up tcmalloc but doing better span coalescing (sanjay)
-	* Better support for different wget's and addr2maps in pprof (csilvres)
-	* Implement a nothrow version of delete and delete[] (csilvers)
-	* BUGFIX: fix a race on module_libcs[i] in windows patching (csilvers)
-	* BUGFIX: Fix debugallocation to call cpp_alloc for new (willchan)
-	* BUGFIX: A simple bugfix for --raw mode (mrabkin)
-	* BUGFIX: Fix C shims to actually be valid C (csilvers)
-	* BUGFIX: Fix recursively-unmapped-region accounting (ppluzhnikov)
-	* BUGFIX: better distinguish real and fake vdso (ppluzhnikov)
-	* WINDOWS: replace debugmodule with more reliable psai (andrey)
-	* PORTING: Add .bundle as another shared library extension (csilvers)
-	* PORTING: Fixed a typo bug in the ocnfigure PRIxx m4 macro (csilvers)
-	* PORTING: Augment sysinfo to work on 64-bit OS X (csilvers)
-	* PORTING: Use sys/ucontext.h to fix compiing on OS X 10.6 (csilvers)
-	* PORTING: Fix sysinfo libname reporting for solaris x86 (jeffrey)
-	* PORTING: Use libunwind for i386 when using --omitfp (ppluzhnikov)
-	
-Thu Sep 10 13:51:15 2009  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.4 release
-	* Add debugallocation library, to catch memory leaks, stomping, etc
-	* Add --raw mode to allow for delayed processing of pprof files
-	* Use less memory when reading CPU profiles
-	* New environment variables to control kernel-allocs (sbrk, memfs, etc)
-	* Add MarkThreadBusy(): performance improvement
-	* Remove static thread-cache-size code; all is dynamic now
-	* Add new HiddenPointer class to heap checker
-	* BUGFIX: pvalloc(0) allocates now (found by new debugalloc library)
-	* BUGFIX: valloc test (not implementation) no longer overruns memory
-	* BUGFIX: GetHeapProfile no longer deadlocks
-	* BUGFIX: Support unmapping memory regions before main
-	* BUGFIX: Fix some malloc-stats formatting
-	* BUGFIX: Don't crash as often when freeing libc-allocated memory
-	* BUGFIX: Deal better with incorrect PPROF_PATH when symbolizing
-	* BUGFIX: weaken new/delete/etc in addition to malloc/free/etc
-	* BUGFIX: Fix return value of GetAllocatedSize
-	* PORTING: Fix mmap-#define problem on some 64-bit systems
-	* PORTING: Call ranlib again (some OS X versions need it)
-	* PORTING: Fix a leak when building with LLVM
-	* PORTING: Remove some unneeded bash-ishs from testing scripts
-	* WINDOWS: Support library unloading as well as loading
-	* WINDOWS/BUGFIX: Set page to 'xrw' instead of 'rw' when patching
-	
-Tue Jun  9 18:19:06 2009  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.3 release
-	* Provide our own name for memory functions: tc_malloc, etc (csilvers)
-	* Weaken memory-alloc functions so user can override them (csilvers)
-	* Remove meaningless delete(nothrow) and delete[](nothrow) (csilvers)
-	* BUILD: replace clever libtcmalloc/profiler.a with a new .a (csilvers)
-	* PORTING: improve windows port  by using google spinlocks (csilvers)
-	* PORTING: Fix RedHat 9 memory allocation in heapchecker (csilvers)
-	* PORTING: Rename OS_WINDOWS macro to PLATFORM_WINDOWS (mbelshe)
-	* PORTING/BUGFIX: Make sure we don't clobber GetLastError (mbelshe)
-	* BUGFIX: get rid of useless data for callgrind (weidenrinde)
-	* BUGFIX: Modify windows patching to deadlock sometimes (csilvers)
-	* BUGFIX: an improved fix for hook handling during fork (csilvers)
-	* BUGFIX: revamp profiler_unittest.sh, which was very broken (csilvers)
-	
-Fri Apr 17 16:40:48 2009  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.2 release
-	* Allow large_alloc_threshold=0 to turn it off entirely (csilvers)
-	* Die more helpfully when out of memory for internal data (csilvers)
-	* Refactor profile-data gathering, add a new unittest (cgd, nabeelmian)
-	* BUGFIX: fix rounding errors with static thread-size caches (addi)
-	* BUGFIX: disable hooks better when forking in leak-checker (csilvers)
-	* BUGFIX: fix realloc of crt pointers on windows (csilvers)
-	* BUGFIX: do a better job of finding binaries in .sh tests (csilvers)
-	* WINDOWS: allow overriding malloc/etc instead of patching (mbelshe)
-	* PORTING: fix compilation error in a ppc-specific file (csilvers)
-	* PORTING: deal with quirks in cygwin's /proc/self/maps (csilvers)
-	* PORTING: use 'A' version of functions for ascii input (mbelshe)
-	* PORTING: generate .so's on cygwin and mingw (ajenjo)
-	* PORTING: disable profiler methods on cygwin (jperkins)
-	* Updated autoconf version to 2.61 and libtool version to 1.5.26
-
-Wed Mar 11 11:25:34 2009  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.1 release
-	* Dynamically resize thread caches -- nice perf. improvement (kash)
-	* Add VDSO support to give better stacktraces in linux (ppluzhnikov)
-	* Improve heap-profiling sampling algorithm (ford)
-	* Rewrite leak-checking code: should be faster and more robust (sanjay)
-	* Use ps2 instead of ps for dot: better page cropping for gv (csilvers)
-	* Disable malloc-failure warning messages by default (csilvers)
-	* Update config/Makefile to disable tests on a per-OS basis (csilvers)
-	* PORTING: Get perftools compiling under MSVC 7.1 again (csilvers)
-	* PORTING: Get perftools compiling under cygwin again (csilvers)
-	* PORTING: automatically set library flags for solaris x86 (csilvers)
-	* Add TCMALLOC_SKIP_SBRK to mirror TCMALLOC_SKIP_MMAP (csilvers)
-	* Add --enable flags to allow selective building (csilvers)
-	* Put addr2line-pdb and nm-pdb in proper output directory (csilvers)
-	* Remove deprecated DisableChecksIn (sanjay)
-	* DOCUMENTATION: Document most MallocExtension routines (csilvers)
-	
-Tue Jan  6 13:58:56 2009  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.0 release
-	* Exactly the same as 1.0rc2
-
-Sun Dec 14 17:10:35 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.0rc2 release
-	* Fix compile error on 64-bit systems (casting ptr to int) (csilvers)
-
-Thu Dec 11 16:01:32 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 1.0rc1 release
-	* Replace API for selectively disabling heap-checker in code (sanjay)
-	* Add a pre-mmap hook (daven, adlr)
-	* Add MallocExtension interface to set memory-releasing rate (fikes)
-	* Augment pprof to allow any string ending in /pprof/profile (csilvers)
-	* PORTING: Rewrite -- and fix --  malloc patching for windows (dvitek)
-	* PORTING: Add nm-pdb and addr2line-pdb for use by pprof (dvitek)
-	* PORTING: Improve cygwin and mingw support (jperkins, csilvers)
-	* PORTING: Fix pprof for mac os x, other pprof improvements (csilvers)
-	* PORTING: Fix some PPC bugs in our locking code (anton.blanchard)
-	* A new unittest, smapling_test, to verify tcmalloc-profiles (csilvers)
-	* Turn off TLS for gcc < 4.1.2, due to a TLS + -fPIC bug (csilvers)
-	* Prefer __builtin_frame_address to assembly for stacktraces (nlewycky)
-	* Separate tcmalloc.cc out into multiple files -- finally! (kash)
-	* Make our locking code work with -fPIC on 32-bit x86 (aruns)
-	* Fix an initialization-ordering bug for tcmalloc/profiling (csilvers)
-	* Use "initial exec" model of TLS to speed up tcmalloc (csilvers)
-	* Enforce 16-byte alignment for tcmalloc, for SSE (sanjay)
-	
-Tue Sep 23 08:56:31 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.99.2 release
-	* COMPILE FIX: add #include needed for FreeBSD and OS X (csilvers)
-
-Sat Sep 20 09:37:18 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.99.1 release
-	* BUG FIX: look for nm, etc in /usr/bin, not /usr/crosstool (csilvers)
-
-Thu Sep 18 16:00:27 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.99 release
-	* Add IsHeapProfileRunning (csilvers)
-	* Add C shims for some of the C++ header files (csilvers)
-	* Fix heap profile file clean-up logic (maxim)
-	* Rename linuxthreads.c to .cc for better compiler support (csilvers)
-	* Add source info to disassembly in pprof (sanjay)
-	* Use open instead of fopen to avoid memory alloc (csilvers)
-	* Disable malloc extensions when running under valgrind (kcc)
-	* BUG FIX: Fix out-of-bound error by reordering a check (larryz)
-	* Add Options struct to ProfileData (cgd)
-	* Correct PC-handling of --base in pprof (csilvers)
-	* Handle 1 function occurring twice in an image (sanjay)
-	* Improve stack-data cleaning (maxim)
-	* Use 'struct Foo' to make header C compatible (csilvers)
-	* Add 'total' line to pprof --text (csilvers)
-	* Pre-allocate buffer for heap-profiler to avoid OOM errors (csilvers)
-	* Allow a few more env-settings to control tcmalloc (csilvers)
-	* Document some of the issues involving thread-local storage (csilvers)
-	* BUG FIX: Define strtoll and friends for windows (csilvers)
-
-Mon Jun  9 16:47:03 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.98 release
-	* Add ProfilerStartWithOptions() (cgd)
-	* Change tcmalloc_minimal to not do any stack-tracing at all (csilvers)
-	* Prefer mmap to sbrk for 64-buit debug mode (sanjay)
-	* Fix accounting for some tcmalloc stats (sanjay)
-	* Use setrlimit() to keep unittests from killing the machine (odo)
-	* Fix a bug when sbrk-ing near address 4G (csilvers)
-	* Make MallocHook thread-safe (jyasskin)
-	* Fix windows build for MemoryBarrier (jyasskin)
-	* Fix CPU-profiler docs to mention correct libs (csilvers)
-	* Fix for GetHeapProfile() when heap-profiling is off (maxim)
-	* Avoid realloc resizing ping-pongs using hysteresis (csilvers)
-	* Add --callgrind output support to pprof (klimek)
-	* Fix profiler.h and heap-profiler.h to be C-compatible (csilvers)
-	* Break malloc_hook.h into two parts to reduce dependencies (csilvers)
-	* Better handle systems that don't implement mmap (csilvers)
-	* PORTING: disable system_alloc_unittest for msvc (csilvers)
-	* PORTING: Makefile tweaks to build better on cygwin (csilvers)
-	
-Mon Apr 21 15:20:52 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.97 release
-	* Refactor GetHeapProfile to avoid using malloc (maxim)
-	* Fix heap-checker and heap-profiler hook interactions (maxim)
-	* Fix a data race in MemoryRegionMap::Lock (jyasskin)
-	* Improve thread-safety of leak checker (maxim)
-	* Fix mmap profile to no longer deadlock (maxim)
-	* Fix rpm to have devel package depend on non-devel (csilvers)
-	* PORTING: Fix clock-speed detection for Mac OS X (csilvers)
-
-Tue Mar 18 14:30:44 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.96 release
-	* major atomicops rewrite; fixed atomic ops code for linux/ppc (vchen)
-	* nix the stacktrace library; now build structure is simpler (csilvers)
-	* Speed up heap-checker, and reduce extraneous logging (maxim)
-	* Improve itimer code for NPTL case (cgd)
-	* Add source code annotations for use by valgrind, etc (kcc)
-	* PORTING: Fix high resolution timers for Mac OS X (adlr)
-
-Tue Feb 19 12:01:31 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.95.1 release  (bugfix release)
-	* x86_64 compile-fix: nix pread64 and pwrite64 (csilvers)
-	* more heap-checker debug logging (maxim)
-	* minor improvement to x86_64 CycleClock (gpike)
-
-Tue Feb 12 12:28:32 2008  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.95 release
-	* Better -- not perfect -- support for linux-ppc (csilvers)
-	* Fix race condition in libunwind stacktrace (aruns)
-	* Speed up x86 spinlock locking (m3b)
-	* Improve heap-checker performance (maxim)
-	* Heap checker traverses more ptrs inside heap-alloced objects (maxim)
-	* Remove deprecated ProfilerThreadState function (cgd)
-	* Update libunwind documentation for statically linked binaries (aruns)
-
-Mon Dec  3 23:51:54 2007  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.94.1 release  (bugfix release)
-	* Fix missing #includes for x86_64 compile using libunwind (csilvers)
-
-Thu Nov 29 07:59:43 2007  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.94 release
-	* PORTING: MinGW/Msys support -- runs same code as MSVC does (csilvers)
-	* PORTING: Add NumCPUs support for Mac OS X (csilvers)
-	* Work around a sscanf bug in glibc(?) (waldemar)
-	* Fix Windows MSVC bug triggered by thread deletion (csilvers)
-	* Fix bug that triggers in MSVC /O2: missing volatile (gpike)
-	* March-of-time support: quiet warnings/errors for gcc 4.2, OS X 10.5
-	* Modify pprof so it works without nm: useful for windows (csilvers)
-	* pprof: Support filtering for CPU profiles (cgd)
-	* Bugfix: have realloc report to hooks in all situations (maxim)
-	* Speed improvement: replace slow memcpy with std::copy (soren)
-	* Speed: better iterator efficiency in RecordRegionRemoval (soren)
-	* Speed: minor speed improvements via better bitfield alignment (gpike)
-	* Documentation: add documentation of binary profile output (cgd)
-	
-Fri Aug 17 12:32:56 2007  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.93 release
-	* PORTING: everything compiles on Solaris, OS X, FreeBSD (see INSTALL)
-	* PORTING: cpu-profiler works on most platforms (much better GetPC())
-	* PORTING: heap-profiler works on most platforms
-	* PORTING: improved windows support, including release builds
-	* No longer build or run ptmalloc tests by default
-	* Add support for using memfs filesystem to allocate memory in linux
-	* WINDOWS: give debug library and release library different names
-	
-Tue Jul 17 22:26:27 2007  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.92 release
-	* PERFORMANCE: use a packed cache to speed up tcmalloc
-	* PORTING: preliminary windows support! (see README.windows)
-	* PORTING: better support for solaris, OS X, FreeBSD (see INSTALL)
-	* Envvar support for running the heap-checker under gdb
-	* Add weak declarations to maybe_threads to fix no-pthreads compile bugs
-	* Some 64bit fixes, especially with pprof
-	* Better heap-checker support for some low-level allocations
-	* Fix bug where heap-profiles would sometimes get truncated
-	* New documentation about how to handle common heap leak situations
-	* Use computed includes for hash_map/set: easier config
-	* Added all used .m4 templates to the distribution
-
-Wed Apr 18 16:43:55 2007  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.91 release
-	* Brown-paper-bag bugfix: compilation error on some x86-64 machines
-
-Fri Apr 13 14:50:51 2007  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.90 release
-	* (As the version-number jump hints, this is a major new release:
-	  almost every piece of functionality was rewritten.  I can't do
-	  justice to all the changes, but will concentrate on highlights.)
-	*** USER-VISIBLE CHANGES:
-	* Ability to "release" unused memory added to tcmalloc
-	* Exposed more tweaking knobs via environment variables (see docs)
-	* pprof tries harder to map addresses to functions
-	* tcmalloc_minimal compiles and runs on FreeBSD 6.0 and Solaris 10
-	*** INTERNAL CHANGES:
-	* Much better 64-bit support
-	* Better multiple-processor support (e.g. multicore contention tweaks)
-	* Support for recent kernel ABI changes (e.g. new arg to mremap)
-	* Addition of spinlocks to tcmalloc to reduce contention cost
-	* Speed up tcmalloc by using __thread on systems that support TLS
-	* Total redesign of heap-checker to improve liveness checking
-	* More portable stack-frame analysis -- no more hard-coded constants!
-	* Disentangled heap-profiler code and heap-checker code
-	* Several new unittests to test, e.g., thread-contention costs
-	* Lots of small (but important!) bug fixes: e.g., fixing GetPC on amd64
-	*** KNOWN PROBLEMS:
-	* CPU-profiling may crash on x86_64 (64-bit) systems.  See the README
-	* Profiling/heap-checking may deadlock on x86_64 systems.  See README
-
-Wed Jun 14 15:11:14 2006  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.8 release
-	* Experimental support for remote profiling added to pprof (many)
-	* Fixed race condition in ProfileData::FlushTable (etune)
-	* Better support for weird /proc maps (maxim, mec)
-	* Fix heap-checker interaction with gdb (markus)
-	* Better 64-bit support in pprof (aruns)
-	* Reduce scavenging cost in tcmalloc by capping NumMoveSize (sanjay)
-	* Cast syscall(SYS_mmap); works on more 64-bit systems now (menage)
-	* Document the text output of pprof! (csilvers)
-	* Better compiler support for no-THREADS and for old compilers (csilvers)
-	* Make libunwind the default stack unwinder for x86-64 (aruns)
-	* Somehow the COPYING file got erased.  Regenerate it (csilvers)
-
-Thu Apr 13 20:59:09 2006  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.7 release
-	* Major rewrite of thread introspection for new kernels (markus)
-	* Major rewrite of heap-checker to use new thread tools (maxim)
-	* Add proper support for following data in thread registers (maxim)
-	* Syscall support for older kernels, including _syscall6 (markus)
-	* Support PIC mode (markus, mbland, iant)
-	* Better support for running in non-threaded contexts (csilvers)
-
-Fri Jan 27 14:04:27 2006  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.6 release
-	* More sophisticated stacktrace usage, possibly using libunwind (aruns)
-	* Update pprof to handle 64-bit profiles (dehnert)
-	* Fix GetStackTrace to correctly return top stackframe (sanjay)
-	* Add ANSI compliance for new and new[], including new_handler (jkearney)
-	* More accuracy by reading ELF files directly rather than objdump (mec)
-	* Add readline support for pprof (addi)
-	* Add #includes for PPC (csilvers)
-	* New PC-detection routine for ibook powerpc (asbestoshead)
-	* Vastly improved tcmalloc unittest (csilvers)
-	* Move documentation from /usr/doc to /usr/share/doc
-
-Mon Nov 14 17:28:59 2005  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.5 release
-	* Add va_start/va_end calls around vsnprintf() (csilvers)
-	* Write our own __syscall_return(), since it's not defined
-	  consistently on all 64-bit linux distros (markus)
-
-Wed Oct 26 15:19:16 2005  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.4 release
-	* Decrease fragmentation in tcmalloc (lefevere)
-	* Support for ARM in some of the thread-specific code (markus)
-	* Turn off heap-checker for statically-linked binaries, which
-	  cause error leak reports now (etune)
-	* Many pprof improvements, including a command-line interface (jeff)
-	* CPU profiling now automatically affects all threads in linux 2.6.
-	  (Kernel bugs break CPU profiling and threads in linux 2.4 a bit.)
-	  ProfilerEnable() and ProfilerDisable() are deprecated.  (sanjay)
-	* tcmalloc now correctly intercepts memalign (m3b, maxim)
-	* Syntax fix: added missing va_end()s.  Helps non-gcc compiling (etune)
-	* Fixed a few coredumper bugs: race condition after PTRACE_DETACH,
-	  ignore non-aligned stackframe pointers (markus, menage)
-	* 64-bit cleanup, especially for spinlock code (etune) and mmap (sanjay)
-	* Better support for finding threads in linux (markus)
-	* tcmalloc now tracks those stack traces that allocate memory (sanjay)
-	* Work around a weird setspecific problem (sanjay)
-	* Fix tcmalloc overflow problems when an alloc is close to 2G/4G (sanjay)
-
-Fri Jun 24 18:02:26 2005  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.3 release
-	* Add missing errno include for one of the unittests (csilvers)
-	* Reduce tcmalloc startup memory from 5M to 256K (sanjay)
-	* Add support for mallopt() and mallinfo (sanjay)
-	* Improve stacktrace's performance on some 64-bit systems (etune)
-	* Improve the stacktrace unittest (etune)
-
-Tue May 31 08:14:38 2005  Google Inc. <opensource@google.com>
-
-	* google-perftools: version 0.2 release
-	* Use mmap2() instead of mmap(), to map more memory (menage)
-	* Do correct pthread-local checking in heap-checker! (maxim)
-	* Avoid overflow on 64-bit machines in pprof (sanjay)
-	* Add a few more GetPC() functions, including for AMD (csilvers)
-	* Better method for overriding pthread functions (menage)
-	* (Hacky) fix to avoid overwriting profile files after fork() (csilvers)
-	* Crashing bugfix involving dumping heaps on small-stack threads (tudor)
-	* Allow library versions with letters at the end (csilvers)
-	* Config fixes for systems that don't define PATH_MAX (csilvers)
-	* Confix fixes so we no longer need config.h after install (csilvers)
-	* Fix to pprof to correctly read very big cpu profiles (csilvers)
-	* Fix to pprof to deal with new commandline flags in modern gv's
-	* Better error reporting when we can't access /proc/maps (etune)
-	* Get rid of the libc-preallocate code (which could crash on some
-	  systems); no longer needed with local-threads fix (csilvers)
-
-Tue Feb 8 09:57:17 2005  Google Inc. <opensource@google.com>
-
-	* google-perftools: initial release:
-	  The google-perftools package contains some utilities to improve
-	  and analyze the performance of C++ programs.  This includes an
-	  optimized thread-caching malloc() and cpu and heap profiling
-	  utilities.
diff --git a/third_party/tcmalloc/vendor/INSTALL b/third_party/tcmalloc/vendor/INSTALL
deleted file mode 100644
index f9a6a117..0000000
--- a/third_party/tcmalloc/vendor/INSTALL
+++ /dev/null
@@ -1,563 +0,0 @@
-Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
-Foundation, Inc.
-
-   This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-
-Perftools-Specific Install Notes
-================================
-
-*** Building from source repository
-
-As of 2.1 gperftools does not have configure and other autotools
-products checked into it's source repository. This is common practice
-for projects using autotools.
-
-NOTE: Source releases (.tar.gz that you download from
-code.google.com/p/gperftools) still have all required files just as
-before. Nothing has changed w.r.t. building from .tar.gz releases.
-
-But, in order to build gperftools checked out from subversion
-repository you need to have autoconf, automake and libtool
-installed. And before running ./configure you have to generate it (and
-a bunch of other files) by running ./autogen.sh script. That script
-will take care of calling correct autotools programs in correct order.
-
-If you're maintainer then it's business as usual too. Just run make
-dist (or, preferably, make distcheck) and it'll produce .tar.gz or
-.tar.bz2 with all autotools magic already included. So that users can
-build our software without having autotools.
-
-
-*** NOTE FOR 64-BIT LINUX SYSTEMS
-
-The glibc built-in stack-unwinder on 64-bit systems has some problems
-with the perftools libraries.  (In particular, the cpu/heap profiler
-may be in the middle of malloc, holding some malloc-related locks when
-they invoke the stack unwinder.  The built-in stack unwinder may call
-malloc recursively, which may require the thread to acquire a lock it
-already holds: deadlock.)
-
-For that reason, if you use a 64-bit system, we strongly recommend you
-install libunwind before trying to configure or install gperftools.
-libunwind can be found at
-
-   http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-beta.tar.gz
-
-Even if you already have libunwind installed, you should check the
-version.  Versions older than this will not work properly; too-new
-versions introduce new code that does not work well with perftools
-(because libunwind can call malloc, which will lead to deadlock).
-
-There have been reports of crashes with libunwind 0.99 (see
-http://code.google.com/p/gperftools/issues/detail?id=374).
-Alternately, you can use a more recent libunwind (e.g. 1.0.1) at the
-cost of adding a bit of boilerplate to your code.  For details, see
-http://groups.google.com/group/google-perftools/msg/2686d9f24ac4365f
-
-   CAUTION: if you install libunwind from the url above, be aware that
-   you may have trouble if you try to statically link your binary with
-   perftools: that is, if you link with 'gcc -static -lgcc_eh ...'.
-   This is because both libunwind and libgcc implement the same C++
-   exception handling APIs, but they implement them differently on
-   some platforms.  This is not likely to be a problem on ia64, but
-   may be on x86-64.
-
-   Also, if you link binaries statically, make sure that you add
-   -Wl,--eh-frame-hdr to your linker options. This is required so that
-   libunwind can find the information generated by the compiler
-   required for stack unwinding.
-
-   Using -static is rare, though, so unless you know this will affect
-   you it probably won't.
-
-If you cannot or do not wish to install libunwind, you can still try
-to use the built-in stack unwinder.  The built-in stack unwinder
-requires that your application, the tcmalloc library, and system
-libraries like libc, all be compiled with a frame pointer.  This is
-*not* the default for x86-64.
-
-If you are on x86-64 system, know that you have a set of system
-libraries with frame-pointers enabled, and compile all your
-applications with -fno-omit-frame-pointer, then you can enable the
-built-in perftools stack unwinder by passing the
---enable-frame-pointers flag to configure.
-
-Even with the use of libunwind, there are still known problems with
-stack unwinding on 64-bit systems, particularly x86-64.  See the
-"64-BIT ISSUES" section in README.
-
-If you encounter problems, try compiling perftools with './configure
---enable-frame-pointers'.  Note you will need to compile your
-application with frame pointers (via 'gcc -fno-omit-frame-pointer
-...') in this case.
-
-
-*** TCMALLOC LARGE PAGES: TRADING TIME FOR SPACE
-
-You can set a compiler directive that makes tcmalloc faster, at the
-cost of using more space (due to internal fragmentation).
-
-Internally, tcmalloc divides its memory into "pages."  The default
-page size is chosen to minimize memory use by reducing fragmentation.
-The cost is that keeping track of these pages can cost tcmalloc time.
-We've added a new flag to tcmalloc that enables a larger page size.
-In general, this will increase the memory needs of applications using
-tcmalloc.  However, in many cases it will speed up the applications
-as well, particularly if they allocate and free a lot of memory. We've
-seen average speedups of 3-5% on Google applications.
-
-To build libtcmalloc with large pages you need to use the
---with-tcmalloc-pagesize=ARG configure flag, e.g.:
-
-   ./configure <other flags> --with-tcmalloc-pagesize=32
-
-The ARG argument can be 8, 32 or 64 which sets the internal page size to
-8K, 32K and 64K repectively. The default is 8K.
-
-
-*** SMALL TCMALLOC CACHES: TRADING SPACE FOR TIME
-
-You can set a compiler directive that makes tcmalloc use less memory
-for overhead, at the cost of some time.
-
-Internally, tcmalloc keeps information about some of its internal data
-structures in a cache.  This speeds memory operations that need to
-access this internal data.  We've added a new, experimental flag to
-tcmalloc that reduces the size of this cache, decresaing the memory
-needs of applications using tcmalloc.
-
-This feature is still very experimental; it's not even a configure
-flag yet.  To build libtcmalloc with smaller internal caches, run
-
-   ./configure <normal flags> CXXFLAGS=-DTCMALLOC_SMALL_BUT_SLOW
-
-(or add -DTCMALLOC_SMALL_BUT_SLOW to your existing CXXFLAGS argument).
-
-
-*** NOTE FOR ___tls_get_addr ERROR
-
-When compiling perftools on some old systems, like RedHat 8, you may
-get an error like this:
-    ___tls_get_addr: symbol not found
-
-This means that you have a system where some parts are updated enough
-to support Thread Local Storage, but others are not.  The perftools
-configure script can't always detect this kind of case, leading to
-that error.  To fix it, just comment out the line
-   #define HAVE_TLS 1
-in your config.h file before building.
-
-
-*** TCMALLOC AND DLOPEN
-
-To improve performance, we use the "initial exec" model of Thread
-Local Storage in tcmalloc.  The price for this is the library will not
-work correctly if it is loaded via dlopen().  This should not be a
-problem, since loading a malloc-replacement library via dlopen is
-asking for trouble in any case: some data will be allocated with one
-malloc, some with another.  If, for some reason, you *do* need to use
-dlopen on tcmalloc, the easiest way is to use a version of tcmalloc
-with TLS turned off; see the ___tls_get_addr note above.
-
-
-*** COMPILING ON NON-LINUX SYSTEMS
-
-Perftools has been tested on the following systems:
-   FreeBSD 6.0 (x86)
-   FreeBSD 8.1 (x86_64)
-   Linux CentOS 5.5 (x86_64)
-   Linux Debian 4.0 (PPC)
-   Linux Debian 5.0 (x86)
-   Linux Fedora Core 3 (x86)
-   Linux Fedora Core 4 (x86)
-   Linux Fedora Core 5 (x86)
-   Linux Fedora Core 6 (x86)
-   Linux Fedora Core 13 (x86_64)
-   Linux Fedora Core 14 (x86_64)
-   Linux RedHat 9 (x86)
-   Linux Slackware 13 (x86_64)
-   Linux Ubuntu 6.06.1 (x86)
-   Linux Ubuntu 6.06.1 (x86_64)
-   Linux Ubuntu 10.04 (x86)
-   Linux Ubuntu 10.10 (x86_64)
-   Mac OS X 10.3.9 (Panther) (PowerPC)
-   Mac OS X 10.4.8 (Tiger) (PowerPC)
-   Mac OS X 10.4.8 (Tiger) (x86)
-   Mac OS X 10.5 (Leopard) (x86)
-   Mac OS X 10.6 (Snow Leopard) (x86)
-   Solaris 10 (x86_64)
-   Windows XP, Visual Studio 2003 (VC++ 7.1) (x86)
-   Windows XP, Visual Studio 2005 (VC++ 8) (x86)
-   Windows XP, Visual Studio 2005 (VC++ 9) (x86)
-   Windows XP, Visual Studio 2005 (VC++ 10) (x86)
-   Windows XP, MinGW 5.1.3 (x86)
-   Windows XP, Cygwin 5.1 (x86)
-
-It works in its full generality on the Linux systems
-tested (though see 64-bit notes above).  Portions of perftools work on
-the other systems.  The basic memory-allocation library,
-tcmalloc_minimal, works on all systems.  The cpu-profiler also works
-fairly widely.  However, the heap-profiler and heap-checker are not
-yet as widely supported.  In general, the 'configure' script will
-detect what OS you are building for, and only build the components
-that work on that OS.
-
-Note that tcmalloc_minimal is perfectly usable as a malloc/new
-replacement, so it is possible to use tcmalloc on all the systems
-above, by linking in libtcmalloc_minimal.
-
-** FreeBSD:
-
-   The following binaries build and run successfully (creating
-   libtcmalloc_minimal.so and libprofile.so in the process):
-      % ./configure
-      % make tcmalloc_minimal_unittest tcmalloc_minimal_large_unittest \
-             addressmap_unittest atomicops_unittest frag_unittest \
-             low_level_alloc_unittest markidle_unittest memalign_unittest \
-             packed_cache_test stacktrace_unittest system_alloc_unittest \
-             thread_dealloc_unittest profiler_unittest.sh
-      % ./tcmalloc_minimal_unittest    # to run this test
-      % [etc]                          # to run other tests
-
-   Three caveats: first, frag_unittest tries to allocate 400M of memory,
-   and if you have less virtual memory on your system, the test may
-   fail with a bad_alloc exception.
-
-   Second, profiler_unittest.sh sometimes fails in the "fork" test.
-   This is because stray SIGPROF signals from the parent process are
-   making their way into the child process.  (This may be a kernel
-   bug that only exists in older kernels.)  The profiling code itself
-   is working fine.  This only affects programs that call fork(); for
-   most programs, the cpu profiler is entirely safe to use.
-
-   Third, perftools depends on /proc to get shared library
-   information.  If you are running a FreeBSD system without proc,
-   perftools will not be able to map addresses to functions.  Some
-   unittests will fail as a result.
-
-   Finally, the new test introduced in perftools-1.2,
-   profile_handler_unittest, fails on FreeBSD.  It has something to do
-   with how the itimer works.  The cpu profiler test passes, so I
-   believe the functionality is correct and the issue is with the test
-   somehow.  If anybody is an expert on itimers and SIGPROF in
-   FreeBSD, and would like to debug this, I'd be glad to hear the
-   results!
-
-   libtcmalloc.so successfully builds, and the "advanced" tcmalloc
-   functionality all works except for the leak-checker, which has
-   Linux-specific code:
-      % make heap-profiler_unittest.sh maybe_threads_unittest.sh \
-             tcmalloc_unittest tcmalloc_both_unittest \
-             tcmalloc_large_unittest              # THESE WORK
-      % make -k heap-checker_unittest.sh \
-                heap-checker-death_unittest.sh    # THESE DO NOT
-
-   Note that unless you specify --enable-heap-checker explicitly,
-   'make' will not build the heap-checker unittests on a FreeBSD
-   system.
-
-   I have not tested other *BSD systems, but they are probably similar.
-
-** Mac OS X:
-
-   I've tested OS X 10.5 [Leopard], OS X 10.4 [Tiger] and OS X 10.3
-   [Panther] on both intel (x86) and PowerPC systems.  For Panther
-   systems, perftools does not work at all: it depends on a header
-   file, OSAtomic.h, which is new in 10.4.  (It's possible to get the
-   code working for Panther/i386 without too much work; if you're
-   interested in exploring this, drop an e-mail.)
-
-   For the other seven systems, the binaries and libraries that
-   successfully build are exactly the same as for FreeBSD.  See that
-   section for a list of binaries and instructions on building them.
-
-   In addition, it appears OS X regularly fails profiler_unittest.sh
-   in the "thread" test (in addition to occassionally failing in the
-   "fork" test).  It looks like OS X often delivers the profiling
-   signal to the main thread, even when it's sleeping, rather than
-   spawned threads that are doing actual work.  If anyone knows
-   details of how OS X handles SIGPROF (via setitimer()) events with
-   threads, and has insight into this problem, please send mail to
-   google-perftools@googlegroups.com.
-
-** Solaris 10 x86:
-
-   I've only tested using the GNU C++ compiler, not the Sun C++
-   compiler.  Using g++ requires setting the PATH appropriately when
-   configuring.
-
-   % PATH=${PATH}:/usr/sfw/bin/:/usr/ccs/bin ./configure
-   % PATH=${PATH}:/usr/sfw/bin/:/usr/ccs/bin make [...]
-
-   Again, the binaries and libraries that successfully build are
-   exactly the same as for FreeBSD.  (However, while libprofiler.so can
-   be used to generate profiles, pprof is not very successful at
-   reading them -- necessary helper programs like nm don't seem
-   to be installed by default on Solaris, or perhaps are only
-   installed as part of the Sun C++ compiler package.)  See that
-   section for a list of binaries, and instructions on building them.
-
-** Windows  (MSVC, Cygwin, and MinGW):
-
-   Work on Windows is rather preliminary: only tcmalloc_minimal is
-   supported.
-
-   We haven't found a good way to get stack traces in release mode on
-   windows (that is, when FPO is enabled), so the heap profiling may
-   not be reliable in that case.  Also, heap-checking and CPU profiling
-   do not yet work at all.  But as in other ports, the basic tcmalloc
-   library functionality, overriding malloc and new and such (and even
-   windows-specific functions like _aligned_malloc!), is working fine,
-   at least with VC++ 7.1 (Visual Studio 2003) through VC++ 10.0,
-   in both debug and release modes.  See README.windows for
-   instructions on how to install on Windows using Visual Studio.
-
-   Cygwin can compile some but not all of perftools.  Furthermore,
-   there is a problem with exception-unwinding in cygwin (it can call
-   malloc, which can call the exception-unwinding-setup code, which
-   can lead to an infinite loop).  I've comitted a workaround to the
-   exception unwinding problem, but it only works in debug mode and
-   when statically linking in tcmalloc.  I hope to have a more proper
-   fix in a later release.  To configure under cygwin, run
-
-      ./configure --disable-shared CXXFLAGS=-g && make
-
-   Most of cygwin will compile (cygwin doesn't allow weak symbols, so
-   the heap-checker and a few other pieces of functionality will not
-   compile).  'make' will compile those libraries and tests that can
-   be compiled.  You can run 'make check' to make sure the basic
-   functionality is working.  I've heard reports that some versions of
-   cygwin fail calls to pthread_join() with EINVAL, causing several
-   tests to fail.  If you have any insight into this, please mail
-   google-perftools@googlegroups.com.
-
-   This Windows functionality is also available using MinGW and Msys,
-   In this case, you can use the regular './configure && make'
-   process.  'make install' should also work.  The Makefile will limit
-   itself to those libraries and binaries that work on windows.
-
-
-Basic Installation
-==================
-
-   These are generic installation instructions.
-
-   The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation.  It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
-   It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring.  (Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.)
-
-   If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
-   The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You only need
-`configure.ac' if you want to change it or regenerate `configure' using
-a newer version of `autoconf'.
-
-The simplest way to compile this package is:
-
-  1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.  If you're
-     using `csh' on an old version of System V, you might need to type
-     `sh ./configure' instead to prevent `csh' from trying to execute
-     `configure' itself.
-
-     Running `configure' takes awhile.  While running, it prints some
-     messages telling which features it is checking for.
-
-  2. Type `make' to compile the package.
-
-  3. Optionally, type `make check' to run any self-tests that come with
-     the package.
-
-  4. Type `make install' to install the programs and any data files and
-     documentation.
-
-  5. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.  To also remove the
-     files that `configure' created (so you can compile the package for
-     a different kind of computer), type `make distclean'.  There is
-     also a `make maintainer-clean' target, but that is intended mainly
-     for the package's developers.  If you use it, you may have to get
-     all sorts of other programs in order to regenerate files that came
-     with the distribution.
-
-Compilers and Options
-=====================
-
-   Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  Run `./configure --help'
-for details on some of the pertinent environment variables.
-
-   You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment.  Here
-is an example:
-
-     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
-
-   *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-   You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'.  `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script.  `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
-   If you have to use a `make' that does not support the `VPATH'
-variable, you have to compile the package for one architecture at a
-time in the source code directory.  After you have installed the
-package for one architecture, use `make distclean' before reconfiguring
-for another architecture.
-
-Installation Names
-==================
-
-   By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc.  You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
-
-   You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files.  If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
-
-   In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
-kinds of files.  Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
-   If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
-   Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System).  The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
-   For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
-   There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on.  Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
-     CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
-     OS KERNEL-OS
-
-   See the file `config.sub' for the possible values of each field.  If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
-   If you are _building_ compiler tools for cross-compiling, you should
-use the `--target=TYPE' option to select the type of system they will
-produce code for.
-
-   If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
-   If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists.  Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-   Variables not defined in a site shell script can be set in the
-environment passed to `configure'.  However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost.  In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'.  For example:
-
-     ./configure CC=/usr/local2/bin/gcc
-
-will cause the specified gcc to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-`configure' Invocation
-======================
-
-   `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
-     Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
-
-`--cache-file=FILE'
-     Enable the cache: use and save the results of the tests in FILE,
-     traditionally `config.cache'.  FILE defaults to `/dev/null' to
-     disable caching.
-
-`--config-cache'
-`-C'
-     Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
-     Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to `/dev/null' (any error
-     messages will still be shown).
-
-`--srcdir=DIR'
-     Look for the package's source code in directory DIR.  Usually
-     `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options.  Run
-`configure --help' for more details.
diff --git a/third_party/tcmalloc/vendor/Makefile.am b/third_party/tcmalloc/vendor/Makefile.am
deleted file mode 100755
index c79227a7..0000000
--- a/third_party/tcmalloc/vendor/Makefile.am
+++ /dev/null
@@ -1,1505 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-# Note: for every library we create, we're explicit about what symbols
-# we export.  In order to avoid complications with C++ mangling, we always
-# use the regexp for of specifying symbols.
-
-# Make sure that when we re-make ./configure, we get the macros we need
-ACLOCAL_AMFLAGS = -I m4
-AUTOMAKE_OPTIONS = subdir-objects
-
-# This is so we can #include <gperftools/foo>
-AM_CPPFLAGS = -I$(top_srcdir)/src
-
-if !WITH_STACK_TRACE
-AM_CPPFLAGS += -DNO_TCMALLOC_SAMPLES
-endif !WITH_STACK_TRACE
-
-# This is mostly based on configure options
-AM_CXXFLAGS =
-
-NO_BUILTIN_CXXFLAGS =
-
-# These are good warnings to turn on by default.  We also tell gcc
-# that malloc, free, realloc, mmap, etc. are not builtins (these flags
-# are supported since gcc 3.1.1).  gcc doesn't think most of them are
-# builtins now in any case, but it's best to be explicit in case that
-# changes one day.  gcc ignores functions it doesn't understand.
-if GCC
-AM_CXXFLAGS += -Wall -Wwrite-strings -Woverloaded-virtual \
-               -Wno-sign-compare \
-               -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc \
-               -fno-builtin-calloc -fno-builtin-cfree \
-               -fno-builtin-memalign -fno-builtin-posix_memalign \
-               -fno-builtin-valloc -fno-builtin-pvalloc
-
-NO_BUILTIN_CXXFLAGS += -fno-builtin
-
-# On i386, -mmmx is needed for the mmx-based instructions in
-# atomicops-internal-x86.h. Also as of gcc 4.6, -fomit-frame-pointer
-# is the default. Since we must always have frame pointers for I386
-# in order to generate backtraces we now specify -fno-omit-frame-pointer
-# by default.
-if I386
-AM_CXXFLAGS += -mmmx
-AM_CXXFLAGS += -fno-omit-frame-pointer
-endif I386
-endif GCC
-if HAVE_W_NO_UNUSED_RESULT
-AM_CXXFLAGS += -Wno-unused-result
-endif HAVE_W_NO_UNUSED_RESULT
-if HAVE_SIZED_DEALLOCATION
-AM_CXXFLAGS += -fsized-deallocation
-endif HAVE_SIZED_DEALLOCATION
-if HAVE_F_ALIGNED_NEW
-AM_CXXFLAGS += -faligned-new
-endif HAVE_F_ALIGNED_NEW
-
-# The -no-undefined flag allows libtool to generate shared libraries for
-# Cygwin and MinGW.  LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.
-AM_LDFLAGS = -no-undefined $(LIBSTDCXX_LA_LINKER_FLAG)
-
-# These are x86-specific, having to do with frame-pointers.  In
-# particular, some x86_64 systems do not insert frame pointers by
-# default (all i386 systems that I know of, do.  I don't know about
-# non-x86 chips).  We need to tell perftools what to do about that.
-if X86_64_AND_NO_FP_BY_DEFAULT
-if ENABLE_FRAME_POINTERS
-AM_CXXFLAGS += -fno-omit-frame-pointer
-else
-  # TODO(csilvers): check if -fomit-frame-pointer might be in $(CXXFLAGS),
-  #                 before setting this.
-AM_CXXFLAGS += -DNO_FRAME_POINTER
-endif !ENABLE_FRAME_POINTERS
-endif X86_64_AND_NO_FP_BY_DEFAULT
-
-# For windows systems (at least, mingw), we need to tell all our
-# tests to link in libtcmalloc using -u.  This is because libtcmalloc
-# accomplishes its tasks via patching, leaving no work for the linker
-# to identify, so the linker will ignore libtcmalloc by default unless
-# we explicitly create a dependency via -u.
-TCMALLOC_FLAGS =
-if MINGW
-TCMALLOC_FLAGS += -Wl,-u__tcmalloc
-endif MINGW
-
-# If we have objcopy, make malloc/free/etc weak symbols.  That way folks
-# can override our malloc if they want to (they can still use tc_malloc).
-# Note: the weird-looking symbols are the c++ memory functions:
-# (in order) new, new(nothrow), new[], new[](nothrow), delete, delete[]
-# In theory this will break if mangling changes, but that seems pretty
-# unlikely at this point.  Just in case, I throw in versions with an
-# extra underscore as well, which may help on OS X.
-if HAVE_OBJCOPY_WEAKEN
-WEAKEN = $(OBJCOPY) -W malloc -W free -W realloc -W calloc -W cfree \
-         -W memalign -W posix_memalign -W valloc -W pvalloc \
-         -W aligned_alloc \
-         -W malloc_stats -W mallopt -W mallinfo -W nallocx \
-         -W _Znwm -W _ZnwmRKSt9nothrow_t -W _Znam -W _ZnamRKSt9nothrow_t \
-         -W _ZdlPv -W _ZdaPv \
-         -W __Znwm -W __ZnwmRKSt9nothrow_t -W __Znam -W __ZnamRKSt9nothrow_t \
-         -W __ZdlPv -W __ZdaPv
-else
-WEAKEN = :
-endif !HAVE_OBJCOPY_WEAKEN
-
-LIBS_TO_WEAKEN =
-
-perftoolsincludedir = $(includedir)/gperftools
-# The .h files you want to install (that is, .h files that people
-# who install this package can include in their own applications.)
-# We'll add to this later, on a library-by-library basis
-perftoolsinclude_HEADERS =
-# tcmalloc.h is a special case, because it's a .h.in file
-nodist_perftoolsinclude_HEADERS = src/gperftools/tcmalloc.h
-noinst_HEADERS = src/gperftools/tcmalloc.h.in
-
-# This is provided for backwards compatibility.  It is populated by
-# files that just forward to the canonical location in
-# perftoolsincludedir.
-googleincludedir = $(includedir)/google
-googleinclude_HEADERS =				\
-   src/google/heap-checker.h			\
-   src/google/heap-profiler.h			\
-   src/google/malloc_extension.h		\
-   src/google/malloc_extension_c.h		\
-   src/google/malloc_hook.h			\
-   src/google/malloc_hook_c.h			\
-   src/google/profiler.h			\
-   src/google/stacktrace.h			\
-   src/google/tcmalloc.h
-
-# This is for HTML and other documentation you want to install.
-# Add your documentation files (in doc/) in addition to these
-# top-level boilerplate files.  Also add a TODO file if you have one.
-# We'll add to this later, on a library-by-library basis
-dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README_windows.txt \
-                TODO ChangeLog.old
-
-# The libraries (.so's) you want to install
-# We'll add to this later, on a library-by-library basis
-lib_LTLIBRARIES =
-# This is for 'convenience libraries' -- basically just a container for sources
-noinst_LTLIBRARIES =
-## The location of the windows project file for each binary we make
-WINDOWS_PROJECTS = gperftools.sln
-
-# unittests you want to run when people type 'make check'.
-# Note: tests cannot take any arguments!
-# In theory, unittests that are scripts should be added to check_SCRIPTS
-# instead.  But check_SCRIPTS is definitely a second-class testing mechanims:
-# it don't get TESTS_ENVIRONMENT, and it doesn't get success/failure counting
-# (in fact, a script failure aborts all the rest of the tests, even with -k).
-# So, for scripts, we add the script to tests, and also put in an empty
-# rule so automake doesn't try to build the script as a C binary.
-TESTS =
-# TESTS_ENVIRONMENT sets environment variables for when you run unittest.
-# We always get "srcdir" set for free.
-# We'll add to this later, on a library-by-library basis.
-TESTS_ENVIRONMENT =
-# All script tests should be added here
-noinst_SCRIPTS =
-# If your test calls another program that, like the test itself, shouldn't
-# be installed, add it here.  (Stuff in TESTS is automatically added later).
-noinst_PROGRAMS =
-
-# Binaries we might build that should be installed
-bin_PROGRAMS =
-
-# This is my own var, used for extra libraries I make that I need installed
-EXTRA_INSTALL =
-
-## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
-
-dist_doc_DATA += docs/index.html docs/designstyle.css
-
-
-### ------- library routines, in src/base
-
-# This is a 'convenience library' -- it's not actually installed or anything
-LOGGING_INCLUDES = src/base/logging.h \
-                   src/base/commandlineflags.h \
-                   src/base/basictypes.h \
-                   src/base/dynamic_annotations.h \
-                   src/third_party/valgrind.h
-noinst_LTLIBRARIES += liblogging.la
-liblogging_la_SOURCES = src/base/logging.cc \
-                        src/base/dynamic_annotations.c \
-                        $(LOGGING_INCLUDES)
-
-SYSINFO_INCLUDES = src/base/sysinfo.h \
-                   src/getenv_safe.h \
-                   src/base/logging.h \
-                   src/base/commandlineflags.h \
-                   src/base/arm_instruction_set_select.h \
-                   src/base/basictypes.h
-noinst_LTLIBRARIES += libsysinfo.la
-libsysinfo_la_SOURCES = src/base/sysinfo.cc \
-                        $(SYSINFO_INCLUDES)
-libsysinfo_la_LIBADD = $(NANOSLEEP_LIBS)
-
-noinst_LTLIBRARIES += libmaybe_threads.la
-# .cc is conditionally added below
-libmaybe_threads_la_SOURCES = src/maybe_threads.h
-
-# For MinGW, we use also have to use libwindows Luckily, we need the
-# windows.a library in exactly the same place we need spinlock.a
-# (pretty much everywhere), so we can use the same variable name for
-# each.  We can also optimize the MinGW rule a bit by leaving out
-# files we know aren't used on windows, such as
-# atomicops-internals-x86.cc.  libwindows also obsoletes the need for
-# other files like system_alloc.cc.
-if MINGW
-WINDOWS_INCLUDES = src/windows/port.h \
-                   src/windows/mingw.h \
-                   src/windows/mini_disassembler.h \
-                   src/windows/mini_disassembler_types.h \
-                   src/windows/preamble_patcher.h
-noinst_LTLIBRARIES += libwindows.la
-libwindows_la_SOURCES = $(WINDOWS_INCLUDES) \
-                        src/windows/port.cc \
-                        src/windows/system-alloc.cc \
-                        src/windows/ia32_modrm_map.cc \
-                        src/windows/ia32_opcode_map.cc \
-                        src/windows/mini_disassembler.cc \
-                        src/windows/patch_functions.cc \
-                        src/windows/preamble_patcher.cc \
-                        src/windows/preamble_patcher_with_stub.cc
-# patch_functions.cc uses Psapi.lib.  MSVC has a #pragma for that, but not us.
-libwindows_la_LIBADD = -lpsapi
-
-SPINLOCK_INCLUDES = src/base/spinlock.h \
-                    src/base/spinlock_internal.h \
-                    src/base/spinlock_win32-inl.h \
-                    src/base/spinlock_linux-inl.h \
-                    src/base/spinlock_posix-inl.h \
-                    src/base/atomicops-internals-macosx.h \
-                    src/base/atomicops-internals-linuxppc.h \
-                    src/base/atomicops-internals-arm-generic.h \
-                    src/base/atomicops-internals-arm-v6plus.h \
-                    src/base/atomicops-internals-mips.h \
-                    src/base/atomicops-internals-windows.h \
-                    src/base/atomicops-internals-gcc.h \
-                    src/base/atomicops-internals-x86.h
-noinst_LTLIBRARIES += libspinlock.la
-libspinlock_la_SOURCES = src/base/spinlock.cc \
-                         src/base/spinlock_internal.cc \
-                         src/base/atomicops-internals-x86.cc \
-                         $(SPINLOCK_INCLUDES)
-
-LIBSPINLOCK = libwindows.la libspinlock.la libsysinfo.la liblogging.la
-
-# We also need to tell mingw that sysinfo.cc needs shlwapi.lib.
-# (We do this via a #pragma for msvc, but need to do it here for mingw).
-libsysinfo_la_LIBADD += -lshlwapi
-
-# There's a windows-specific unittest we can run.  Right now it's
-# win64-specific, and relies on masm, so we comment it out.
-## TESTS += preamble_patcher_test
-## preamble_patcher_test_SOURCES = src/windows/preamble_patcher_test.cc \
-##                                 src/windows/shortproc.asm \
-##                                 src/windows/auto_testing_hook.h \
-##                                 src/windows/preamble_patcher.h \
-##                                 src/base/basictypes.h \
-##                                 src/base/logging.h
-## preamble_patcher_test_LDFLAGS = $(TCMALLOC_FLAGS)
-## preamble_patcher_test_LDADD = $(LIBTCMALLOC_MINIMAL)
-
-# patch_functions.cc #includes tcmalloc.cc, so no need to link it in.
-TCMALLOC_CC =
-# windows has its own system for threads and system memory allocation.
-if HAVE_PTHREAD_DESPITE_ASKING_FOR
-libmaybe_threads_la_SOURCES += src/maybe_threads.cc
-endif
-SYSTEM_ALLOC_CC =
-else !MINGW
-# spinlock is the only code that uses atomicops.
-SPINLOCK_INCLUDES = src/base/spinlock.h \
-                    src/base/spinlock_internal.h \
-                    src/base/atomicops.h \
-                    src/base/atomicops-internals-macosx.h \
-                    src/base/atomicops-internals-linuxppc.h \
-                    src/base/atomicops-internals-windows.h \
-                    src/base/atomicops-internals-x86.h
-
-noinst_LTLIBRARIES += libspinlock.la
-libspinlock_la_SOURCES = src/base/spinlock.cc \
-                         src/base/spinlock_internal.cc \
-                         src/base/atomicops-internals-x86.cc \
-                         $(SPINLOCK_INCLUDES)
-libspinlock_la_LIBADD = $(NANOSLEEP_LIBS)
-# spinlock also needs NumCPUs, from libsysinfo, which in turn needs liblogging
-LIBSPINLOCK = libspinlock.la libsysinfo.la liblogging.la
-
-TCMALLOC_CC = src/tcmalloc.cc
-libmaybe_threads_la_SOURCES += src/maybe_threads.cc
-SYSTEM_ALLOC_CC = src/system-alloc.cc
-endif !MINGW
-
-# Add this whether or not we're under MinGW, to keep the tarball complete.
-WINDOWS_PROJECTS += vsprojects/preamble_patcher_test/preamble_patcher_test.vcproj
-# Because we've commented out the test, above, we have to explicitly add
-# the test files to the tarball or automake will leave them out.
-WINDOWS_PROJECTS += src/windows/preamble_patcher_test.cc \
-                    src/windows/shortproc.asm \
-                    src/windows/auto_testing_hook.h
-
-### Unittests
-TESTS += low_level_alloc_unittest
-WINDOWS_PROJECTS += vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcproj
-LOW_LEVEL_ALLOC_UNITTEST_INCLUDES = src/base/low_level_alloc.h \
-                                    src/base/basictypes.h \
-                                    src/gperftools/malloc_hook.h \
-                                    src/gperftools/malloc_hook_c.h \
-                                    src/malloc_hook-inl.h \
-                                    src/malloc_hook_mmap_linux.h \
-                                    src/malloc_hook_mmap_freebsd.h \
-                                    $(SPINLOCK_INCLUDES) \
-                                    $(LOGGING_INCLUDES)
-low_level_alloc_unittest_SOURCES = src/base/low_level_alloc.cc \
-                                   src/malloc_hook.cc \
-                                   src/tests/low_level_alloc_unittest.cc \
-                                   $(LOW_LEVEL_ALLOC_UNITTEST_INCLUDES)
-# By default, MallocHook takes stack traces for use by the heap-checker.
-# We don't need that functionality here, so we turn it off to reduce deps.
-low_level_alloc_unittest_CXXFLAGS = -DNO_TCMALLOC_SAMPLES
-low_level_alloc_unittest_LDADD = $(LIBSPINLOCK) libmaybe_threads.la
-
-TESTS += atomicops_unittest
-ATOMICOPS_UNITTEST_INCLUDES = src/base/atomicops.h \
-                              src/base/atomicops-internals-macosx.h \
-                              src/base/atomicops-internals-windows.h \
-                              src/base/atomicops-internals-x86.h \
-                              $(LOGGING_INCLUDES)
-atomicops_unittest_SOURCES = src/tests/atomicops_unittest.cc \
-                             $(ATOMICOPS_UNITTEST_INCLUDES)
-atomicops_unittest_LDADD = $(LIBSPINLOCK)
-
-
-### ------- stack trace
-
-if WITH_STACK_TRACE
-
-### The header files we use.  We divide into categories based on directory
-S_STACKTRACE_INCLUDES = src/stacktrace_impl_setup-inl.h \
-                        src/stacktrace_generic-inl.h \
-                        src/stacktrace_libgcc-inl.h \
-			src/stacktrace_libunwind-inl.h \
-			src/stacktrace_arm-inl.h \
-			src/stacktrace_powerpc-inl.h \
-			src/stacktrace_powerpc-darwin-inl.h \
-			src/stacktrace_powerpc-linux-inl.h \
-			src/stacktrace_x86-inl.h \
-			src/stacktrace_win32-inl.h \
-			src/stacktrace_instrument-inl.h \
-                        src/base/elf_mem_image.h \
-                        src/base/vdso_support.h
-
-SG_STACKTRACE_INCLUDES = src/gperftools/stacktrace.h
-STACKTRACE_INCLUDES = $(S_STACKTRACE_INCLUDES) $(SG_STACKTRACE_INCLUDES)
-perftoolsinclude_HEADERS += $(SG_STACKTRACE_INCLUDES)
-
-### Making the library
-noinst_LTLIBRARIES += libstacktrace.la
-libstacktrace_la_SOURCES = src/stacktrace.cc \
-                           src/base/elf_mem_image.cc \
-                           src/base/vdso_support.cc \
-                           $(STACKTRACE_INCLUDES)
-libstacktrace_la_LIBADD = $(UNWIND_LIBS) $(LIBSPINLOCK)
-STACKTRACE_SYMBOLS = '(GetStackTrace|GetStackFrames|GetStackTraceWithContext|GetStackFramesWithContext)'
-libstacktrace_la_LDFLAGS = -export-symbols-regex $(STACKTRACE_SYMBOLS) $(AM_LDFLAGS)
-
-noinst_LTLIBRARIES += libfake_stacktrace_scope.la
-libfake_stacktrace_scope_la_SOURCES = src/fake_stacktrace_scope.cc
-
-### Unittests
-TESTS += stacktrace_unittest
-STACKTRACE_UNITTEST_INCLUDES = src/config_for_unittests.h \
-                               src/base/commandlineflags.h \
-                               $(STACKTRACE_INCLUDES) \
-                               $(LOGGING_INCLUDES)
-stacktrace_unittest_SOURCES = src/tests/stacktrace_unittest.cc \
-                              $(STACKTRACE_UNITTEST_INCLUDES)
-stacktrace_unittest_LDADD = libstacktrace.la liblogging.la libfake_stacktrace_scope.la
-
-### Documentation
-dist_doc_DATA +=
-
-endif WITH_STACK_TRACE
-
-### ------- pprof
-
-# If we are not compiling with stacktrace support, pprof is worthless
-if WITH_STACK_TRACE
-
-bin_SCRIPTS = src/pprof
-
-### Unittests
-
-check_SCRIPTS = pprof_unittest
-pprof_unittest: $(top_srcdir)/src/pprof
-	$(top_srcdir)/src/pprof -test
-
-# Let unittests find pprof if they need to run it
-TESTS_ENVIRONMENT += PPROF_PATH=$(top_srcdir)/src/pprof
-
-### Documentation
-dist_man_MANS = docs/pprof.1
-dist_doc_DATA += docs/pprof_remote_servers.html
-
-# On MSVC, we need our own versions of addr2line and nm to work with pprof.
-WINDOWS_PROJECTS += vsprojects/nm-pdb/nm-pdb.vcproj
-WINDOWS_PROJECTS += vsprojects/addr2line-pdb/addr2line-pdb.vcproj
-# This is a slight abuse of WINDOWS_PROJECTS, but not much
-WINDOWS_PROJECTS += src/windows/nm-pdb.c \
-                    src/windows/addr2line-pdb.c
-
-endif WITH_STACK_TRACE
-
-### ------- tcmalloc_minimal (thread-caching malloc)
-
-### The header files we use.  We divide into categories based on directory
-S_TCMALLOC_MINIMAL_INCLUDES = src/common.h \
-                              src/internal_logging.h \
-                              src/system-alloc.h \
-                              src/packed-cache-inl.h \
-                              $(SPINLOCK_INCLUDES) \
-                              src/tcmalloc_guard.h \
-                              src/base/commandlineflags.h \
-                              src/base/basictypes.h \
-                              src/pagemap.h \
-                              src/sampler.h \
-                              src/central_freelist.h \
-                              src/linked_list.h \
-                              src/libc_override.h \
-                              src/libc_override_gcc_and_weak.h \
-                              src/libc_override_glibc.h \
-                              src/libc_override_osx.h \
-                              src/libc_override_redefine.h \
-                              src/page_heap.h \
-                              src/page_heap_allocator.h \
-                              src/span.h \
-                              src/static_vars.h \
-                              src/symbolize.h \
-                              src/thread_cache.h \
-                              src/stack_trace_table.h \
-                              src/base/thread_annotations.h \
-                              src/malloc_hook-inl.h \
-                              src/malloc_hook_mmap_linux.h \
-                              src/malloc_hook_mmap_freebsd.h
-SG_TCMALLOC_MINIMAL_INCLUDES = src/gperftools/malloc_hook.h \
-                               src/gperftools/malloc_hook_c.h \
-                               src/gperftools/malloc_extension.h \
-                               src/gperftools/malloc_extension_c.h \
-                               src/gperftools/nallocx.h
-TCMALLOC_MINIMAL_INCLUDES = $(S_TCMALLOC_MINIMAL_INCLUDES) $(SG_TCMALLOC_MINIMAL_INCLUDES) $(SG_STACKTRACE_INCLUDES)
-perftoolsinclude_HEADERS += $(SG_TCMALLOC_MINIMAL_INCLUDES)
-
-### Making the library
-
-noinst_LTLIBRARIES += libtcmalloc_minimal_internal.la
-libtcmalloc_minimal_internal_la_SOURCES = src/common.cc \
-                                          src/internal_logging.cc \
-                                          $(SYSTEM_ALLOC_CC) \
-                                          src/memfs_malloc.cc \
-                                          src/central_freelist.cc \
-                                          src/page_heap.cc \
-                                          src/sampler.cc \
-                                          src/span.cc \
-                                          src/stack_trace_table.cc \
-                                          src/static_vars.cc \
-                                          src/symbolize.cc \
-                                          src/thread_cache.cc \
-                                          src/malloc_hook.cc \
-                                          src/malloc_extension.cc \
-                                          $(TCMALLOC_MINIMAL_INCLUDES)
-# We #define NO_TCMALLOC_SAMPLES, since sampling is turned off for _minimal.
-libtcmalloc_minimal_internal_la_CXXFLAGS = -DNO_TCMALLOC_SAMPLES \
-                                           -DNO_HEAP_CHECK \
-                                           -DNDEBUG \
-                                           $(AM_CXXFLAGS)
-libtcmalloc_minimal_internal_la_LDFLAGS =  $(AM_LDFLAGS)
-libtcmalloc_minimal_internal_la_LIBADD =  $(LIBSPINLOCK) libmaybe_threads.la
-
-lib_LTLIBRARIES += libtcmalloc_minimal.la
-WINDOWS_PROJECTS += vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj
-libtcmalloc_minimal_la_SOURCES = $(TCMALLOC_CC) $(TCMALLOC_MINIMAL_INCLUDES)
-libtcmalloc_minimal_la_CXXFLAGS = -DNO_TCMALLOC_SAMPLES \
-                                  $(PTHREAD_CFLAGS) -DNDEBUG $(AM_CXXFLAGS)
-# -version-info gets passed to libtool
-libtcmalloc_minimal_la_LDFLAGS = -version-info @TCMALLOC_SO_VERSION@ $(AM_LDFLAGS)
-libtcmalloc_minimal_la_LIBADD = libtcmalloc_minimal_internal.la
-
-# For windows, we're playing around with trying to do some stacktrace
-# support even with libtcmalloc_minimal.  For everyone else, though,
-# we turn off all stack-trace activity for libtcmalloc_minimal.
-# TODO(csilvers): when we're done experimenting, do something principled here
-if MINGW
-LIBTCMALLOC_MINIMAL = libtcmalloc_minimal.la libstacktrace.la
-else !MINGW
-LIBTCMALLOC_MINIMAL = libtcmalloc_minimal.la
-endif !MINGW
-
-LIBS_TO_WEAKEN += libtcmalloc_minimal.la
-
-### Unittests
-
-# Commented out for the moment because malloc(very_big_num) is broken in
-# standard libc!  At least, in some situations, some of the time.
-## TESTS += malloc_unittest
-## MALLOC_UNITEST_INCLUDES = src/gperftools/malloc_extension.h \
-##                           src/gperftools/malloc_hook.h \
-##                           src/gperftools/malloc_hook_c.h \
-##                           src/malloc_hook-inl.h \
-##                           src/malloc_hook_mmap_linux.h \
-##                           src/malloc_hook_mmap_freebsd.h \
-##                           src/base/basictypes.h \
-##                           src/maybe_threads.h
-## malloc_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
-##                           src/malloc_hook.cc \
-##                           src/malloc_extension.cc \
-##                           $(MAYBE_THREADS_CC) \
-##                           $(MALLOC_UNITTEST_INCLUDES)
-## malloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-## malloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
-## malloc_unittest_LDADD = $(PTHREAD_LIBS)
-
-TESTS += tcmalloc_minimal_unittest
-WINDOWS_PROJECTS += vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcproj
-WINDOWS_PROJECTS += vsprojects/tmu-static/tmu-static.vcproj
-tcmalloc_minimal_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
-                                    src/tests/testutil.h src/tests/testutil.cc \
-                                    $(TCMALLOC_UNITTEST_INCLUDES)
-tcmalloc_minimal_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-tcmalloc_minimal_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-# We want libtcmalloc last on the link line, but due to a bug in
-# libtool involving convenience libs, they need to come last on the
-# link line in order to get dependency ordering right.  This is ok:
-# convenience libraries are .a's, so tcmalloc is still the last .so.
-# We also put pthreads after tcmalloc, because some pthread
-# implementations define their own malloc, and we need to go on the
-# first linkline to make sure our malloc 'wins'.
-tcmalloc_minimal_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) \
-                                  liblogging.la $(PTHREAD_LIBS)
-
-# lets make sure we exerice ASSERTs in at least in statically linked
-# configuration
-TESTS += tcm_min_asserts_unittest
-tcm_min_asserts_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
-                                    src/tests/testutil.h src/tests/testutil.cc \
-                                    $(libtcmalloc_minimal_internal_la_SOURCES) \
-                                    $(libtcmalloc_minimal_la_SOURCES) \
-                                    $(TCMALLOC_UNITTEST_INCLUDES)
-tcm_min_asserts_unittest_CXXFLAGS = -DNO_TCMALLOC_SAMPLES -DNO_HEAP_CHECK \
-                                    $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-tcm_min_asserts_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-tcm_min_asserts_unittest_LDADD = $(LIBSPINLOCK) libmaybe_threads.la \
-                                  liblogging.la $(PTHREAD_LIBS)
-
-TESTS += tcmalloc_minimal_large_unittest
-WINDOWS_PROJECTS += vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcproj
-tcmalloc_minimal_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
-tcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-tcmalloc_minimal_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-tcmalloc_minimal_large_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += tcmalloc_minimal_large_heap_fragmentation_unittest
-tcmalloc_minimal_large_heap_fragmentation_unittest_SOURCES = src/tests/large_heap_fragmentation_unittest.cc
-tcmalloc_minimal_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-tcmalloc_minimal_large_heap_fragmentation_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-tcmalloc_minimal_large_heap_fragmentation_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-# This tests it works to LD_PRELOAD libtcmalloc (tests maybe_threads.cc)
-# In theory this should work under mingw, but mingw has trouble running
-# shell scripts that end in .exe.  And it doesn't seem to build shared
-# libraries anyway (so can't be LD_PRELOADed) -- in fact, anybody who
-# chooses not to build shared libraries won't be able to run this test.
-# TODO(csilvers): figure out how to nix ".exe" or otherwise work under mingw
-if !MINGW
-if !ENABLE_STATIC
-TESTS += maybe_threads_unittest.sh$(EXEEXT)
-maybe_threads_unittest_sh_SOURCES = src/tests/maybe_threads_unittest.sh
-noinst_SCRIPTS += $(maybe_threads_unittest_sh_SOURCES)
-# This script preloads libtcmalloc, and calls two other binaries as well
-# TODO(csilvers): replace by 'if ! cmp $^ $@ >/dev/null 2>&; then ...; fi'
-maybe_threads_unittest.sh$(EXEEXT): $(top_srcdir)/$(maybe_threads_unittest_sh_SOURCES) \
-                           $(LIBTCMALLOC_MINIMAL) \
-                           low_level_alloc_unittest
-	rm -f $@
-	cp -p $(top_srcdir)/$(maybe_threads_unittest_sh_SOURCES) $@
-endif !ENABLE_STATIC
-endif !MINGW
-
-# These all tests components of tcmalloc_minimal
-
-TESTS += addressmap_unittest
-WINDOWS_PROJECTS += vsprojects/addressmap_unittest/addressmap_unittest.vcproj
-ADDRESSMAP_UNITTEST_INCLUDES = src/addressmap-inl.h \
-                               src/base/commandlineflags.h \
-                               $(LOGGING_INCLUDES)
-addressmap_unittest_SOURCES = src/tests/addressmap_unittest.cc \
-                              $(ADDRESSMAP_UNITTEST_INCLUDES)
-if MINGW
-addressmap_unittest_SOURCES += src/windows/port.h src/windows/port.cc
-endif MINGW
-addressmap_unittest_CXXFLAGS = -g $(AM_CXXFLAGS)
-addressmap_unittest_LDADD = liblogging.la
-
-WINDOWS_PROJECTS += vsprojects/system-alloc_unittest/system-alloc_unittest.vcproj
-if !MINGW
-TESTS += system_alloc_unittest
-system_alloc_unittest_SOURCES = src/config_for_unittests.h \
-                                src/tests/system-alloc_unittest.cc
-system_alloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-system_alloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-system_alloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-endif !MINGW
-
-TESTS += packed_cache_test
-WINDOWS_PROJECTS += vsprojects/packed-cache_test/packed-cache_test.vcproj
-packed_cache_test_SOURCES = src/tests/packed-cache_test.cc
-packed_cache_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-packed_cache_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-packed_cache_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += frag_unittest
-WINDOWS_PROJECTS += vsprojects/frag_unittest/frag_unittest.vcproj
-frag_unittest_SOURCES = src/tests/frag_unittest.cc src/config_for_unittests.h
-frag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-frag_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-frag_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += markidle_unittest
-WINDOWS_PROJECTS += vsprojects/markidle_unittest/markidle_unittest.vcproj
-markidle_unittest_SOURCES = src/tests/markidle_unittest.cc \
-                            src/config_for_unittests.h \
-                            src/tests/testutil.h src/tests/testutil.cc
-markidle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-markidle_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-markidle_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += current_allocated_bytes_test
-WINDOWS_PROJECTS += vsprojects/current_allocated_bytes_test/current_allocated_bytes_test.vcproj
-current_allocated_bytes_test_SOURCES = src/tests/current_allocated_bytes_test.cc \
-                                       src/config_for_unittests.h
-current_allocated_bytes_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-current_allocated_bytes_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-current_allocated_bytes_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += malloc_hook_test
-WINDOWS_PROJECTS += vsprojects/malloc_hook_test/malloc_hook_test.vcproj
-malloc_hook_test_SOURCES = src/tests/malloc_hook_test.cc \
-                           src/config_for_unittests.h \
-                           src/base/logging.h \
-                           src/gperftools/malloc_hook.h \
-                           src/tests/testutil.h src/tests/testutil.cc
-malloc_hook_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-malloc_hook_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-malloc_hook_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += malloc_extension_test
-WINDOWS_PROJECTS += vsprojects/malloc_extension_test/malloc_extension_test.vcproj
-malloc_extension_test_SOURCES = src/tests/malloc_extension_test.cc \
-                                src/config_for_unittests.h \
-                                src/base/logging.h \
-                                src/gperftools/malloc_extension.h \
-                                src/gperftools/malloc_extension_c.h
-malloc_extension_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-malloc_extension_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-malloc_extension_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-# This doesn't work with mingw, which links foo.a even though it
-# doesn't set ENABLE_STATIC.  TODO(csilvers): set enable_static=true
-# in configure.ac:36?
-if !MINGW
-TESTS += malloc_extension_c_test
-malloc_extension_c_test_SOURCES = src/tests/malloc_extension_c_test.c \
-                                  src/gperftools/malloc_extension.h \
-                                  src/gperftools/malloc_extension_c.h
-malloc_extension_c_test_CFLAGS = $(PTHREAD_CFLAGS) $(AM_CFLAGS)
-# -ansi here is just to help ensure the code is bog-standard C.
-if GCC
-malloc_extension_c_test_CFLAGS += -ansi
-endif GCC
-malloc_extension_c_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-malloc_extension_c_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS) -lstdc++ -lm
-endif !MINGW
-
-if !MINGW
-if !OSX
-TESTS += memalign_unittest
-memalign_unittest_SOURCES = src/tests/memalign_unittest.cc \
-                            src/tcmalloc.h \
-                            src/config_for_unittests.h \
-                            src/tests/testutil.h src/tests/testutil.cc
-memalign_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-memalign_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-memalign_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-endif !OSX
-endif !MINGW
-
-TESTS += page_heap_test
-WINDOWS_PROJECTS += vsprojects/page_heap_test/page_heap_test.vcproj
-page_heap_test_SOURCES = src/tests/page_heap_test.cc \
-                         src/config_for_unittests.h \
-                         src/base/logging.h \
-                         src/common.h \
-                         src/page_heap.h
-page_heap_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-page_heap_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-page_heap_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += pagemap_unittest
-WINDOWS_PROJECTS += vsprojects/pagemap_unittest/pagemap_unittest.vcproj
-pagemap_unittest_SOURCES = src/tests/pagemap_unittest.cc \
-                           src/config_for_unittests.h \
-                           src/base/logging.h \
-                           src/pagemap.h
-pagemap_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-pagemap_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-pagemap_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += realloc_unittest
-WINDOWS_PROJECTS += vsprojects/realloc_unittest/realloc_unittest.vcproj
-realloc_unittest_SOURCES = src/tests/realloc_unittest.cc \
-                           src/config_for_unittests.h \
-                           src/base/logging.h
-realloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-realloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-realloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += stack_trace_table_test
-WINDOWS_PROJECTS += vsprojects/stack_trace_table_test/stack_trace_table_test.vcproj
-stack_trace_table_test_SOURCES = src/tests/stack_trace_table_test.cc \
-                                 src/config_for_unittests.h
-stack_trace_table_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-stack_trace_table_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-stack_trace_table_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += thread_dealloc_unittest
-WINDOWS_PROJECTS += vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcproj
-thread_dealloc_unittest_SOURCES = src/tests/thread_dealloc_unittest.cc \
-                                  src/config_for_unittests.h \
-                                  src/tests/testutil.h src/tests/testutil.cc
-thread_dealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-thread_dealloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-thread_dealloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-### Documentation
-dist_doc_DATA += docs/tcmalloc.html \
-                 docs/overview.gif \
-                 docs/pageheap.gif \
-                 docs/spanmap.gif \
-                 docs/threadheap.gif \
-                 docs/t-test1.times.txt \
-                 docs/tcmalloc-opspercpusec.vs.threads.1024.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.128.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.131072.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.16384.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.2048.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.256.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.32768.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.4096.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.512.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.64.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.65536.bytes.png 	\
-                 docs/tcmalloc-opspercpusec.vs.threads.8192.bytes.png 	\
-                 docs/tcmalloc-opspersec.vs.size.1.threads.png 		\
-                 docs/tcmalloc-opspersec.vs.size.12.threads.png 		\
-                 docs/tcmalloc-opspersec.vs.size.16.threads.png 		\
-                 docs/tcmalloc-opspersec.vs.size.2.threads.png 		\
-                 docs/tcmalloc-opspersec.vs.size.20.threads.png 		\
-                 docs/tcmalloc-opspersec.vs.size.3.threads.png 		\
-                 docs/tcmalloc-opspersec.vs.size.4.threads.png 		\
-                 docs/tcmalloc-opspersec.vs.size.5.threads.png 		\
-                 docs/tcmalloc-opspersec.vs.size.8.threads.png
-
-# I don't know how to say "distribute the .dot files but don't install them";
-# noinst doesn't seem to work with data.  I separate them out anyway, in case
-# one day we figure it out.  Regardless, installing the dot files isn't the
-# end of the world.
-dist_doc_DATA += docs/overview.dot \
-                 docs/pageheap.dot \
-                 docs/spanmap.dot \
-                 docs/threadheap.dot
-
-
-### ------- tcmalloc_minimal_debug (thread-caching malloc with debugallocation)
-
-if WITH_DEBUGALLOC
-
-lib_LTLIBRARIES += libtcmalloc_minimal_debug.la
-libtcmalloc_minimal_debug_la_SOURCES = src/debugallocation.cc \
-                                       $(TCMALLOC_MINIMAL_INCLUDES)
-libtcmalloc_minimal_debug_la_CXXFLAGS = $(libtcmalloc_minimal_la_CXXFLAGS) \
-                                        -DTCMALLOC_FOR_DEBUGALLOCATION
-# version_info gets passed to libtool
-libtcmalloc_minimal_debug_la_LDFLAGS = $(libtcmalloc_minimal_la_LDFLAGS) \
-                                       -version-info @TCMALLOC_SO_VERSION@
-libtcmalloc_minimal_debug_la_LIBADD = $(libtcmalloc_minimal_la_LIBADD)
-
-LIBS_TO_WEAKEN += libtcmalloc_minimal_debug.la
-
-### Unittests
-
-TESTS += tcmalloc_minimal_debug_unittest
-tcmalloc_minimal_debug_unittest_SOURCES = $(tcmalloc_minimal_unittest_SOURCES)
-tcmalloc_minimal_debug_unittest_CXXFLAGS = $(tcmalloc_minimal_unittest_CXXFLAGS) \
-                                           -DDEBUGALLOCATION
-tcmalloc_minimal_debug_unittest_LDFLAGS = $(tcmalloc_minimal_unittest_LDFLAGS)
-tcmalloc_minimal_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)
-
-TESTS += malloc_extension_debug_test
-malloc_extension_debug_test_SOURCES = $(malloc_extension_test_SOURCES)
-malloc_extension_debug_test_CXXFLAGS = $(malloc_extension_test_CXXFLAGS)
-malloc_extension_debug_test_LDFLAGS = $(malloc_extension_test_LDFLAGS)
-malloc_extension_debug_test_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)
-
-if !MINGW
-if !OSX
-TESTS += memalign_debug_unittest
-memalign_debug_unittest_SOURCES = $(memalign_unittest_SOURCES)
-memalign_debug_unittest_CXXFLAGS = $(memalign_unittest_CXXFLAGS)
-memalign_debug_unittest_LDFLAGS = $(memalign_unittest_LDFLAGS)
-memalign_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)
-endif !OSX
-endif !MINGW
-
-TESTS += realloc_debug_unittest
-realloc_debug_unittest_SOURCES = $(realloc_unittest_SOURCES)
-realloc_debug_unittest_CXXFLAGS = $(realloc_unittest_CXXFLAGS)
-realloc_debug_unittest_LDFLAGS = $(realloc_unittest_LDFLAGS)
-realloc_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)
-
-# debugallocation_test checks that we print a proper stacktrace when
-# debug-allocs fail, so we can't run it if we don't have stacktrace info.
-if WITH_STACK_TRACE
-TESTS += debugallocation_test.sh$(EXEEXT)
-debugallocation_test_sh_SOURCES = src/tests/debugallocation_test.sh
-noinst_SCRIPTS += $(debugallocation_test_sh_SOURCES)
-debugallocation_test.sh$(EXEEXT): $(top_srcdir)/$(debugallocation_test_sh_SOURCES) \
-                                  debugallocation_test
-	rm -f $@
-	cp -p $(top_srcdir)/$(debugallocation_test_sh_SOURCES) $@
-
-# This is the sub-program used by debugallocation_test.sh
-noinst_PROGRAMS += debugallocation_test
-debugallocation_test_SOURCES = src/tests/debugallocation_test.cc
-debugallocation_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-debugallocation_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-debugallocation_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)
-endif WITH_STACK_TRACE
-
-endif WITH_DEBUGALLOC
-
-if !MINGW
-noinst_LTLIBRARIES += librun_benchmark.la
-librun_benchmark_la_SOURCES = \
-	benchmark/run_benchmark.c benchmark/run_benchmark.h
-
-noinst_PROGRAMS += malloc_bench malloc_bench_shared \
-	binary_trees binary_trees_shared
-
-malloc_bench_SOURCES = benchmark/malloc_bench.cc
-malloc_bench_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-malloc_bench_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-if ENABLE_STATIC
-malloc_bench_LDFLAGS += -static
-endif ENABLE_STATIC
-malloc_bench_LDADD = librun_benchmark.la libtcmalloc_minimal.la $(PTHREAD_LIBS)
-
-malloc_bench_shared_SOURCES = benchmark/malloc_bench.cc
-malloc_bench_shared_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-malloc_bench_shared_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-malloc_bench_shared_LDADD = librun_benchmark.la libtcmalloc_minimal.la $(PTHREAD_LIBS)
-
-if WITH_HEAP_PROFILER_OR_CHECKER
-
-noinst_PROGRAMS += malloc_bench_shared_full
-malloc_bench_shared_full_SOURCES = benchmark/malloc_bench.cc
-malloc_bench_shared_full_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-malloc_bench_shared_full_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-malloc_bench_shared_full_LDADD = librun_benchmark.la libtcmalloc.la $(PTHREAD_LIBS)
-
-if !OSX
-noinst_PROGRAMS += unwind_bench
-unwind_bench_SOURCES = benchmark/unwind_bench.cc benchmark/getcontext_light.cc
-unwind_bench_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-unwind_bench_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-unwind_bench_LDADD = librun_benchmark.la libtcmalloc.la $(PTHREAD_LIBS)
-endif !OSX
-
-endif WITH_HEAP_PROFILER_OR_CHECKER
-
-binary_trees_SOURCES = benchmark/binary_trees.cc
-binary_trees_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-binary_trees_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-if ENABLE_STATIC
-binary_trees_LDFLAGS += -static
-endif ENABLE_STATIC
-binary_trees_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
-
-binary_trees_shared_SOURCES = benchmark/binary_trees.cc
-binary_trees_shared_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-binary_trees_shared_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-binary_trees_shared_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
-endif !MINGW
-
-### ------- tcmalloc (thread-caching malloc + heap profiler + heap checker)
-
-if WITH_HEAP_PROFILER_OR_CHECKER
-
-### The header files we use.  We divide into categories based on directory
-S_TCMALLOC_INCLUDES = $(S_TCMALLOC_MINIMAL_INCLUDES) \
-                      $(LOGGING_INCLUDES) \
-                      src/addressmap-inl.h \
-                      src/raw_printer.h \
-                      src/base/elfcore.h \
-                      src/base/googleinit.h \
-                      src/base/linux_syscall_support.h \
-                      src/base/linuxthreads.h \
-                      src/base/stl_allocator.h \
-                      src/base/sysinfo.h \
-                      src/base/thread_lister.h \
-                      src/heap-profile-table.h \
-                      src/heap-profile-stats.h \
-                      src/maybe_emergency_malloc.h \
-                      src/emergency_malloc.h
-
-SG_TCMALLOC_INCLUDES = src/gperftools/heap-profiler.h \
-                       src/gperftools/heap-checker.h
-TCMALLOC_INCLUDES = $(S_TCMALLOC_INCLUDES) $(SG_TCMALLOC_MINIMAL_INCLUDES) \
-		    $(SG_TCMALLOC_INCLUDES) $(SG_STACKTRACE_INCLUDES)
-perftoolsinclude_HEADERS += $(SG_TCMALLOC_INCLUDES)
-
-if BUILD_EMERGENCY_MALLOC
-EMERGENCY_MALLOC_CC = src/emergency_malloc.cc src/emergency_malloc_for_stacktrace.cc
-EMERGENCY_MALLOC_DEFINE = -DENABLE_EMERGENCY_MALLOC
-else !BUILD_EMERGENCY_MALLOC
-EMERGENCY_MALLOC_CC = src/fake_stacktrace_scope.cc
-EMERGENCY_MALLOC_DEFINE =
-endif !BUILD_EMERGENCY_MALLOC
-
-### Making the library
-
-noinst_LTLIBRARIES += libtcmalloc_internal.la
-libtcmalloc_internal_la_SOURCES = $(libtcmalloc_minimal_internal_la_SOURCES) \
-                                  $(TCMALLOC_INCLUDES) \
-                                  src/base/low_level_alloc.cc \
-                                  src/heap-profile-table.cc \
-                                  src/heap-profiler.cc \
-                                  src/raw_printer.cc \
-                                  $(EMERGENCY_MALLOC_CC) \
-                                  src/memory_region_map.cc
-libtcmalloc_internal_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG \
-                                   $(AM_CXXFLAGS) $(EMERGENCY_MALLOC_DEFINE)
-libtcmalloc_internal_la_LDFLAGS = $(PTHREAD_CFLAGS)
-libtcmalloc_internal_la_LIBADD = libstacktrace.la $(PTHREAD_LIBS)
-
-lib_LTLIBRARIES += libtcmalloc.la
-libtcmalloc_la_SOURCES = $(TCMALLOC_CC) $(TCMALLOC_INCLUDES)
-libtcmalloc_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG $(AM_CXXFLAGS) $(EMERGENCY_MALLOC_DEFINE)
-libtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @TCMALLOC_SO_VERSION@
-libtcmalloc_la_LIBADD = libtcmalloc_internal.la libmaybe_threads.la $(PTHREAD_LIBS)
-
-if WITH_HEAP_CHECKER
-# heap-checker-bcad is last, in hopes its global ctor will run first.
-# (Note this is added to libtcmalloc.la, not libtcmalloc_internal.la,
-# but that's ok; the internal/external distinction is only useful for
-# cygwin, and cygwin doesn't use HEAP_CHECKER anyway.)
-HEAP_CHECKER_SOURCES = src/base/thread_lister.c \
-                       src/base/linuxthreads.cc \
-                       src/heap-checker.cc \
-                       src/heap-checker-bcad.cc
-libtcmalloc_la_SOURCES += $(HEAP_CHECKER_SOURCES)
-else !WITH_HEAP_CHECKER
-HEAP_CHECKER_SOURCES =
-libtcmalloc_internal_la_CXXFLAGS += -DNO_HEAP_CHECK
-libtcmalloc_la_CXXFLAGS += -DNO_HEAP_CHECK
-endif !WITH_HEAP_CHECKER
-
-LIBTCMALLOC = libtcmalloc.la
-
-LIBS_TO_WEAKEN += libtcmalloc.la
-
-### Unittests
-
-TESTS += tcmalloc_unittest.sh$(EXEEXT)
-tcmalloc_unittest_sh_SOURCES = src/tests/tcmalloc_unittest.sh
-noinst_SCRIPTS += $(tcmalloc_unittest_sh_SOURCES)
-tcmalloc_unittest.sh$(EXEEXT): $(top_srcdir)/$(tcmalloc_unittest_sh_SOURCES) \
-                               tcmalloc_unittest
-	rm -f $@
-	cp -p $(top_srcdir)/$(tcmalloc_unittest_sh_SOURCES) $@
-
-noinst_PROGRAMS += tcmalloc_unittest
-tcmalloc_unittest_INCLUDES = src/config_for_unittests.h \
-                             src/gperftools/malloc_extension.h
-tcmalloc_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
-                            src/tcmalloc.h \
-                            src/tests/testutil.h src/tests/testutil.cc \
-                            $(TCMALLOC_UNITTEST_INCLUDES)
-tcmalloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-tcmalloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-# We want libtcmalloc last on the link line, but due to a bug in
-# libtool involving convenience libs, they need to come last on the
-# link line in order to get dependency ordering right.  This is ok:
-# convenience libraries are .a's, so tcmalloc is still the last .so.
-# We also put pthreads after tcmalloc, because some pthread
-# implementations define their own malloc, and we need to go on the
-# first linkline to make sure our malloc 'wins'.
-tcmalloc_unittest_LDADD = $(LIBTCMALLOC) liblogging.la $(PTHREAD_LIBS)
-
-# # lets make sure we exerice ASSERTs in at least in statically linked
-# # configuration
-# TESTS += tcm_asserts_unittest
-# tcm_asserts_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
-#                                 src/tests/testutil.h src/tests/testutil.cc \
-#                                 $(libtcmalloc_internal_la_SOURCES) \
-#                                 $(libtcmalloc_la_SOURCES) \
-#                                 $(TCMALLOC_UNITTEST_INCLUDES)
-# tcm_asserts_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-# tcm_asserts_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-# tcm_asserts_unittest_LDADD = $(LIBSPINLOCK) libmaybe_threads.la libstacktrace.la \
-#                              liblogging.la $(PTHREAD_LIBS)
-
-# This makes sure it's safe to link in both tcmalloc and
-# tcmalloc_minimal.  (One would never do this on purpose, but perhaps
-# by accident...)  When we can compile libprofiler, we also link it in
-# to make sure that works too.  NOTE: On OS X, it's *not* safe to
-# link both in (we end up with two copies of every global var, and
-# the code tends to pick one arbitrarily), so don't run the test there.
-# (We define these outside the 'if' because they're reused below.)
-tcmalloc_both_unittest_srcs = src/tests/tcmalloc_unittest.cc \
-                              src/tests/testutil.h src/tests/testutil.cc \
-                              $(TCMALLOC_UNITTEST_INCLUDES)
-tcmalloc_both_unittest_cflags = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-tcmalloc_both_unittest_lflags = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-if WITH_CPU_PROFILER
-# We want libtcmalloc last on the link line, but due to a bug in
-# libtool involving convenience libs, they need to come last on the
-# link line in order to get dependency ordering right.  This is ok:
-# convenience libraries are .a's, so tcmalloc is still the last .so.
-# We also put pthreads after tcmalloc, because some pthread
-# implementations define their own malloc, and we need to go on the
-# first linkline to make sure our malloc 'wins'.
-tcmalloc_both_unittest_ladd = $(LIBTCMALLOC) $(LIBTCMALLOC_MINIMAL) \
-                              libprofiler.la liblogging.la $(PTHREAD_LIBS)
-else
-tcmalloc_both_unittest_ladd = $(LIBTCMALLOC) $(LIBTCMALLOC_MINIMAL) \
-                              liblogging.la $(PTHREAD_LIBS)
-endif !WITH_CPU_PROFILER
-if !OSX
-TESTS += tcmalloc_both_unittest
-tcmalloc_both_unittest_SOURCES = $(tcmalloc_both_unittest_srcs)
-tcmalloc_both_unittest_CXXFLAGS = $(tcmalloc_both_unittest_cflags)
-tcmalloc_both_unittest_LDFLAGS = $(tcmalloc_both_unittest_lflags)
-tcmalloc_both_unittest_LDADD = $(tcmalloc_both_unittest_ladd)
-endif !OSX
-
-TESTS += tcmalloc_large_unittest
-tcmalloc_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
-tcmalloc_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-tcmalloc_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-tcmalloc_large_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
-
-TESTS += tcmalloc_large_heap_fragmentation_unittest
-tcmalloc_large_heap_fragmentation_unittest_SOURCES = src/tests/large_heap_fragmentation_unittest.cc
-tcmalloc_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-tcmalloc_large_heap_fragmentation_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-tcmalloc_large_heap_fragmentation_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
-
-TESTS += raw_printer_test
-raw_printer_test_SOURCES = src/tests/raw_printer_test.cc
-raw_printer_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-raw_printer_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-raw_printer_test_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
-
-# sampler_test and sampling_test both require sampling to be turned
-# on, which it's not by default.  Use the "standard" value of 2^19.
-TESTS_ENVIRONMENT += TCMALLOC_SAMPLE_PARAMETER=524288
-
-TESTS += sampler_test
-WINDOWS_PROJECTS += vsprojects/sampler_test/sampler_test.vcproj
-sampler_test_SOURCES = src/tests/sampler_test.cc \
-                       src/config_for_unittests.h
-sampler_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-sampler_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-sampler_test_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS) -lm
-
-
-# These unittests often need to run binaries.  They're in the current dir
-TESTS_ENVIRONMENT += BINDIR=.
-TESTS_ENVIRONMENT += TMPDIR=/tmp/perftools
-
-TESTS += sampling_test.sh$(EXEEXT)
-sampling_test_sh_SOURCES = src/tests/sampling_test.sh
-noinst_SCRIPTS += $(sampling_test_sh_SOURCES)
-sampling_test.sh$(EXEEXT): $(top_srcdir)/$(sampling_test_sh_SOURCES) \
-                           sampling_test
-	rm -f $@
-	cp -p $(top_srcdir)/$(sampling_test_sh_SOURCES) $@
-
-# This is the sub-program used by sampling_test.sh
-# The -g is so pprof can get symbol information.
-noinst_PROGRAMS += sampling_test
-SAMPLING_TEST_INCLUDES = src/config_for_unittests.h \
-                         src/base/logging.h \
-                         src/gperftools/malloc_extension.h
-sampling_test_SOURCES = src/tests/sampling_test.cc \
-                        $(SAMPLING_TEST_INCLUDES)
-sampling_test_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-sampling_test_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-sampling_test_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
-
-endif WITH_HEAP_PROFILER_OR_CHECKER
-
-if WITH_HEAP_PROFILER
-
-TESTS += heap-profiler_unittest.sh$(EXEEXT)
-heap_profiler_unittest_sh_SOURCES = src/tests/heap-profiler_unittest.sh
-noinst_SCRIPTS += $(heap_profiler_unittest_sh_SOURCES)
-heap-profiler_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) \
-                                    heap-profiler_unittest
-	rm -f $@
-	cp -p $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) $@
-
-# These are sub-programs used by heap-profiler_unittest.sh
-noinst_PROGRAMS += heap-profiler_unittest
-HEAP_PROFILER_UNITTEST_INCLUDES = src/config_for_unittests.h \
-                                  src/gperftools/heap-profiler.h
-heap_profiler_unittest_SOURCES = src/tests/heap-profiler_unittest.cc \
-                                 $(HEAP_PROFILER_UNITTEST_INCLUDES)
-heap_profiler_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-heap_profiler_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-heap_profiler_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
-
-# Tests the compatibility include-headers in google/.  Requires a function
-# defined in the heap-profiler, which is why the test lives here.
-TESTS += simple_compat_test
-simple_compat_test_SOURCES = src/tests/simple_compat_test.cc \
-                             $(googleinclude_HEADERS)
-simple_compat_test_LDFLAGS = $(TCMALLOC_FLAGS)
-simple_compat_test_LDADD = $(LIBTCMALLOC)
-
-endif WITH_HEAP_PROFILER
-
-if WITH_HEAP_CHECKER
-
-TESTS += heap-checker_unittest.sh$(EXEEXT)
-heap_checker_unittest_sh_SOURCES = src/tests/heap-checker_unittest.sh
-noinst_SCRIPTS += $(heap_checker_unittest_sh_SOURCES)
-heap-checker_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) \
-                                   heap-checker_unittest
-	rm -f $@
-	cp -p $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) $@
-
-TESTS += heap-checker-death_unittest.sh$(EXEEXT)
-heap_checker_death_unittest_sh_SOURCES = src/tests/heap-checker-death_unittest.sh
-noinst_SCRIPTS += $(top_srcdir)/$(heap_checker_death_unittest_sh_SOURCES)
-heap-checker-death_unittest.sh$(EXEEXT): $(heap_checker_death_unittest_sh_SOURCES) \
-                                         heap-checker_unittest
-	rm -f $@
-	cp -p $(top_srcdir)/$(heap_checker_death_unittest_sh_SOURCES) $@
-
-# These are sub-programs used by heap-checker_unittest.sh
-noinst_PROGRAMS += heap-checker_unittest
-HEAP_CHECKER_UNITTEST_INCLUDES = src/config_for_unittests.h \
-                                 src/memory_region_map.h \
-                                 src/base/commandlineflags.h \
-                                 src/base/googleinit.h \
-                                 src/gperftools/heap-checker.h \
-                                 $(LOGGING_INCLUDES)
-heap_checker_unittest_SOURCES = src/tests/heap-checker_unittest.cc \
-                                $(HEAP_CHECKER_UNITTEST_INCLUDES)
-heap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
-heap_checker_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-# We want libtcmalloc last on the link line, but due to a bug in
-# libtool involving convenience libs, they need to come last on the
-# link line in order to get dependency ordering right.  This is ok:
-# convenience libraries are .a's, so tcmalloc is still the last .so.
-# We also put pthreads after tcmalloc, because some pthread
-# implementations define their own malloc, and we need to go on the
-# first linkline to make sure our malloc 'wins'.
-heap_checker_unittest_LDADD = $(LIBTCMALLOC) liblogging.la $(PTHREAD_LIBS)
-
-endif WITH_HEAP_CHECKER
-
-### Documentation (above and beyond tcmalloc_minimal documentation)
-if WITH_HEAP_PROFILER
-dist_doc_DATA += docs/heapprofile.html docs/heap-example1.png
-endif WITH_HEAP_PROFILER
-
-if WITH_HEAP_CHECKER
-dist_doc_DATA += docs/heap_checker.html
-endif WITH_HEAP_CHECKER
-
-
-### ------- tcmalloc with debugallocation
-
-if WITH_DEBUGALLOC
-if WITH_HEAP_PROFILER_OR_CHECKER
-
-lib_LTLIBRARIES += libtcmalloc_debug.la
-libtcmalloc_debug_la_SOURCES = src/debugallocation.cc $(HEAP_CHECKER_SOURCES) \
-                               $(TCMALLOC_INCLUDES)
-libtcmalloc_debug_la_CXXFLAGS = $(libtcmalloc_la_CXXFLAGS) \
-                                -DTCMALLOC_FOR_DEBUGALLOCATION
-libtcmalloc_debug_la_LDFLAGS = $(libtcmalloc_la_LDFLAGS) \
-                               -version-info @TCMALLOC_SO_VERSION@
-libtcmalloc_debug_la_LIBADD = $(libtcmalloc_la_LIBADD)
-
-LIBS_TO_WEAKEN += libtcmalloc_debug.la
-
-### Unittests
-
-TESTS += tcmalloc_debug_unittest
-tcmalloc_debug_unittest_SOURCES = $(tcmalloc_unittest_SOURCES)
-tcmalloc_debug_unittest_CXXFLAGS = $(tcmalloc_unittest_CXXFLAGS) \
-                                   -DDEBUGALLOCATION
-tcmalloc_debug_unittest_LDFLAGS = $(tcmalloc_unittest_LDFLAGS)
-tcmalloc_debug_unittest_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)
-
-TESTS += sampler_debug_test
-sampler_debug_test_SOURCES = $(sampler_test_SOURCES)
-sampler_debug_test_CXXFLAGS = $(samples_test_CXXFLAGS)
-sampler_debug_test_LDFLAGS = $(sampler_test_LDFLAGS)
-sampler_debug_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS) -lm
-
-TESTS += sampling_debug_test.sh$(EXEEXT)
-sampling_debug_test_sh_SOURCES = src/tests/sampling_test.sh
-sampling_debug_test.sh$(EXEEXT): $(top_srcdir)/$(sampling_test_sh_SOURCES) \
-                                 sampling_debug_test
-	rm -f $@
-	cp -p $(top_srcdir)/$(sampling_test_sh_SOURCES) $@
-
-# This is the sub-program using by sampling_debug_test.sh
-# The -g is so pprof can get symbol information.
-noinst_PROGRAMS += sampling_debug_test
-sampling_debug_test_SOURCES = $(sampling_test_SOURCES)
-sampling_debug_test_CXXFLAGS = $(sampling_test_CXXFLAGS)
-sampling_debug_test_LDFLAGS = $(sampling_test_LDFLAGS)
-sampling_debug_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)
-
-endif WITH_HEAP_PROFILER_OR_CHECKER
-
-if WITH_HEAP_PROFILER
-
-TESTS += heap-profiler_debug_unittest.sh$(EXEEXT)
-heap_profiler_debug_unittest_sh_SOURCES = src/tests/heap-profiler_unittest.sh
-heap-profiler_debug_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) \
-                                    heap-profiler_debug_unittest
-	rm -f $@
-	cp -p $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) $@
-
-# These are sub-programs used by heap-profiler_debug_unittest.sh
-noinst_PROGRAMS += heap-profiler_debug_unittest
-heap_profiler_debug_unittest_SOURCES = $(heap_profiler_unittest_SOURCES)
-heap_profiler_debug_unittest_CXXFLAGS = $(heap_profiler_unittest_CXXFLAGS)
-heap_profiler_debug_unittest_LDFLAGS = $(heap_profiler_unittest_LDFLAGS)
-heap_profiler_debug_unittest_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)
-
-endif WITH_HEAP_PROFILER
-
-if WITH_HEAP_CHECKER
-
-TESTS += heap-checker_debug_unittest.sh$(EXEEXT)
-heap_checker_debug_unittest_sh_SOURCES = src/tests/heap-checker_unittest.sh
-heap-checker_debug_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) \
-                                   heap-checker_debug_unittest
-	rm -f $@
-	cp -p $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) $@
-
-# These are sub-programs used by heap-checker_debug_unittest.sh
-noinst_PROGRAMS += heap-checker_debug_unittest
-heap_checker_debug_unittest_SOURCES = $(heap_checker_unittest_SOURCES)
-heap_checker_debug_unittest_CXXFLAGS = $(heap_checker_unittest_CXXFLAGS)
-heap_checker_debug_unittest_LDFLAGS = $(heap_checker_unittest_LDFLAGS)
-# We want libtcmalloc last on the link line, but due to a bug in
-# libtool involving convenience libs, they need to come last on the
-# link line in order to get dependency ordering right.  This is ok:
-# convenience libraries are .a's, so tcmalloc is still the last .so.
-heap_checker_debug_unittest_LDADD = libtcmalloc_debug.la liblogging.la \
-                                    $(PTHREAD_LIBS)
-
-endif WITH_HEAP_CHECKER
-endif WITH_DEBUGALLOC
-
-
-### ------- CPU profiler
-
-if WITH_CPU_PROFILER
-
-### The header files we use.  We divide into categories based on directory
-S_CPU_PROFILER_INCLUDES = src/profiledata.h \
-                          src/profile-handler.h \
-                          src/getpc.h \
-                          src/base/basictypes.h \
-                          src/base/commandlineflags.h \
-                          src/base/googleinit.h \
-                          src/base/logging.h \
-                          src/base/simple_mutex.h \
-                          src/base/sysinfo.h \
-                          $(SPINLOCK_INCLUDES) \
-                          $(LOGGING_INCLUDES)
-SG_CPU_PROFILER_INCLUDES = src/gperftools/profiler.h
-CPU_PROFILER_INCLUDES = $(S_CPU_PROFILER_INCLUDES) $(SG_CPU_PROFILER_INCLUDES) \
-			$(SG_STACKTRACE_INCLUDES)
-perftoolsinclude_HEADERS += $(SG_CPU_PROFILER_INCLUDES)
-
-### Making the library
-lib_LTLIBRARIES += libprofiler.la
-libprofiler_la_SOURCES = src/profiler.cc \
-                         src/profile-handler.cc \
-                         src/profiledata.cc \
-                         $(CPU_PROFILER_INCLUDES)
-libprofiler_la_LIBADD = libstacktrace.la libmaybe_threads.la libfake_stacktrace_scope.la
-# We have to include ProfileData for profiledata_unittest
-CPU_PROFILER_SYMBOLS = '(ProfilerStart|ProfilerStartWithOptions|ProfilerStop|ProfilerFlush|ProfilerEnable|ProfilerDisable|ProfilingIsEnabledForAllThreads|ProfilerRegisterThread|ProfilerGetCurrentState|ProfilerState|ProfileData|ProfileHandler)'
-libprofiler_la_LDFLAGS = -export-symbols-regex $(CPU_PROFILER_SYMBOLS) \
-                         -version-info @PROFILER_SO_VERSION@
-
-# See discussion above (under LIBTCMALLOC_MINIMAL) for why we do this.
-# Basically it's to work around systems where --rpath doesn't work right.
-LIBPROFILER = libstacktrace.la libprofiler.la
-
-### Unittests
-TESTS += getpc_test
-#WINDOWS_PROJECTS += vsprojects/getpc_test/getpc_test.vcproj
-getpc_test_SOURCES = src/tests/getpc_test.cc src/getpc.h
-
-TESTS += profiledata_unittest
-#WINDOWS_PROJECTS += vsprojects/profiledata_unittest/profiledata_unittest.vcproj
-profiledata_unittest_SOURCES = src/tests/profiledata_unittest.cc \
-                               src/profiledata.h \
-                               src/base/commandlineflags.h \
-                               src/base/logging.h \
-                               src/base/basictypes.h
-profiledata_unittest_LDADD = $(LIBPROFILER)
-
-TESTS += profile_handler_unittest
-profile_handler_unittest_SOURCES = src/tests/profile-handler_unittest.cc \
-                                   src/profile-handler.h
-profile_handler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
-profile_handler_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
-profile_handler_unittest_LDADD = $(LIBPROFILER) $(PTHREAD_LIBS)
-
-TESTS += profiler_unittest.sh$(EXEEXT)
-profiler_unittest_sh_SOURCES = src/tests/profiler_unittest.sh
-noinst_SCRIPTS += $(profiler_unittest_sh_SOURCES)
-profiler_unittest.sh$(EXEEXT): $(top_srcdir)/$(profiler_unittest_sh_SOURCES) \
-                               profiler1_unittest profiler2_unittest \
-                               profiler3_unittest profiler4_unittest
-	rm -f $@
-	cp -p $(top_srcdir)/$(profiler_unittest_sh_SOURCES) $@
-
-# These are sub-programs used by profiler_unittest.sh
-noinst_PROGRAMS += profiler1_unittest profiler2_unittest profiler3_unittest \
-                   profiler4_unittest
-PROFILER_UNITTEST_INCLUDES = src/config_for_unittests.h \
-                             src/gperftools/profiler.h
-PROFILER_UNITTEST_SRCS = src/tests/profiler_unittest.cc \
-                         src/tests/testutil.h src/tests/testutil.cc \
-                         $(PROFILER_UNITTEST_INCLUDES)
-profiler1_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)
-profiler1_unittest_CXXFLAGS = -g -DNO_THREADS $(AM_CXXFLAGS)
-profiler1_unittest_LDADD = $(LIBPROFILER)
-profiler2_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)
-profiler2_unittest_CXXFLAGS = -g -DNO_THREADS $(AM_CXXFLAGS)
-profiler2_unittest_LDADD = -lstacktrace -lprofiler
-# We depend on -lprofiler but haven't yet said how to build it.  Do so now.
-profiler2_unittest_DEPENDENCIES = $(LIBPROFILER)
-profiler3_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)
-profiler3_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-profiler3_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
-profiler3_unittest_LDADD = $(LIBPROFILER) $(PTHREAD_LIBS)
-profiler4_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)
-profiler4_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-profiler4_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
-profiler4_unittest_LDADD = -lstacktrace -lprofiler $(PTHREAD_LIBS)
-# We depend on -lprofiler but haven't yet said how to build it.  Do so now.
-profiler4_unittest_DEPENDENCIES = $(LIBPROFILER)
-
-
-### Documentation
-dist_doc_DATA += docs/cpuprofile.html \
-                 docs/cpuprofile-fileformat.html \
-                 docs/pprof-test-big.gif \
-                 docs/pprof-test.gif \
-                 docs/pprof-vsnprintf-big.gif \
-                 docs/pprof-vsnprintf.gif
-
-endif WITH_CPU_PROFILER
-
-
-### ------- CPU profiler and heap checker, in one!
-
-# Ideally, folks who wanted to use both tcmalloc and libprofiler,
-# could just link them both into their application.  But while this
-# works fine for .so files, it does not for .a files.  The easiest way
-# around this -- and I've tried a bunch of the hard ways -- is to just
-# to create another set of libraries that has both functionality in it.
-
-if WITH_HEAP_PROFILER_OR_CHECKER
-if WITH_CPU_PROFILER
-
-lib_LTLIBRARIES += libtcmalloc_and_profiler.la
-libtcmalloc_and_profiler_la_SOURCES = $(libtcmalloc_la_SOURCES) $(libprofiler_la_SOURCES)
-libtcmalloc_and_profiler_la_CXXFLAGS = $(libtcmalloc_la_CXXFLAGS) $(libprofiler_la_CXXFLAGS)
-# Since this library is meant to be used as a .a, I don't worry as much
-# about .so versioning.  I just give the libtcmalloc version number.
-# TODO(csilvers): use -export-symbols-regex?
-libtcmalloc_and_profiler_la_LDFLAGS = $(PTHREAD_CFLAGS) \
-                                      -version-info @TCMALLOC_SO_VERSION@
-# We don't include libprofiler_la_LIBADD here because all it adds is
-# libstacktrace.la, which we already get via libtcmalloc.  Trying to
-# specify it twice causes link-time duplicate-definition errors. :-(
-libtcmalloc_and_profiler_la_LIBADD = $(libtcmalloc_la_LIBADD)
-
-TESTS += tcmalloc_and_profiler_unittest
-tcmalloc_and_profiler_unittest_SOURCES = $(tcmalloc_both_unittest_srcs)
-tcmalloc_and_profiler_unittest_CXXFLAGS = $(tcmalloc_both_unittest_cflags)
-tcmalloc_and_profiler_unittest_LDFLAGS = $(tcmalloc_both_unittest_lflags)
-tcmalloc_and_profiler_unittest_LDADD = libtcmalloc_and_profiler.la
-
-LIBS_TO_WEAKEN += libtcmalloc_and_profiler.la
-
-endif WITH_CPU_PROFILER
-endif WITH_HEAP_PROFILER_OR_CHECKER
-
-## ^^^^ END OF RULES TO MAKE YOUR LIBRARIES, BINARIES, AND UNITTESTS
-
-
-# Do the weakening on some exported libtcmalloc symbols.
-install-exec-local: all-local
-all-local: $(LIBS_TO_WEAKEN)
-	for la in $(LIBS_TO_WEAKEN); do lib=".libs/`basename $$la .la`.a"; [ ! -f "$$lib" ] || $(WEAKEN) "$$lib"; done
-
-
-# This should always include $(TESTS), but may also include other
-# binaries that you compile but don't want automatically installed.
-# We'll add to this later, on a library-by-library basis
-noinst_PROGRAMS += $(TESTS)
-
-rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
-	@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
-
-deb: dist-gzip packages/deb.sh packages/deb/*
-	@cd packages && ./deb.sh ${PACKAGE} ${VERSION}
-
-# http://linux.die.net/man/1/pkg-config, http://pkg-config.freedesktop.org/wiki
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libtcmalloc.pc libtcmalloc_minimal.pc \
-                 libtcmalloc_debug.pc libtcmalloc_minimal_debug.pc \
-                 libprofiler.pc
-CLEANFILES = $(pkgconfig_DATA)
-
-# I get the description and URL lines from the rpm spec. I use sed to
-# try to rewrite exec_prefix, libdir, and includedir in terms of
-# prefix, if possible.
-libtcmalloc.pc: Makefile packages/rpm/rpm.spec
-	echo 'prefix=$(prefix)' > "$@".tmp
-	echo 'exec_prefix='`echo '$(exec_prefix)' | sed 's@^$(prefix)@$${prefix}@'` >> "$@".tmp
-	echo 'libdir='`echo '$(libdir)' | sed 's@^$(exec_prefix)@$${exec_prefix}@'` >> "$@".tmp
-	echo 'includedir='`echo '$(includedir)' | sed 's@^$(prefix)@$${prefix}@'` >> "$@".tmp
-	echo '' >> "$@".tmp
-	echo 'Name: $(PACKAGE)' >> "$@".tmp
-	echo 'Version: $(VERSION)' >> "$@".tmp
-	-grep '^Summary:' $(top_srcdir)/packages/rpm/rpm.spec | sed s/^Summary:/Description:/ | head -n1 >> "$@".tmp
-	-grep '^URL: ' $(top_srcdir)/packages/rpm/rpm.spec >> "$@".tmp
-	echo 'Requires:' >> "$@".tmp
-	echo 'Libs: -L$${libdir} -ltcmalloc' >> "$@".tmp
-	echo 'Libs.private: $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)' >> "$@".tmp
-	echo 'Cflags: -I$${includedir}' >> "$@".tmp
-	mv -f "$@".tmp "$@"
-
-# The other versions are mostly the same.
-libtcmalloc_minimal.pc: libtcmalloc.pc
-	cat libtcmalloc.pc | sed s/-ltcmalloc/-ltcmalloc_minimal/ > "$@"
-
-libtcmalloc_debug.pc: libtcmalloc.pc
-	cat libtcmalloc.pc | sed s/-ltcmalloc/-ltcmalloc_debug/ > "$@"
-
-libtcmalloc_minimal_debug.pc: libtcmalloc.pc
-	cat libtcmalloc.pc | sed s/-ltcmalloc/-ltcmalloc_minimal_debug/ > "$@"
-
-libprofiler.pc: libtcmalloc.pc
-	cat libtcmalloc.pc | sed s/-ltcmalloc/-lprofiler/ > "$@"
-
-libtool: $(LIBTOOL_DEPS)
-	$(SHELL) ./config.status --recheck
-
-@GENERATE_CHANGELOG_RULES@
-
-# Windows wants write permission to .vcproj files and maybe even sln files.
-dist-hook: dist-ChangeLog
-	test -e "$(distdir)/vsprojects" \
-	   && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/
-
-EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
-             $(SCRIPTS) libtool \
-             src/windows/get_mangled_names.cc src/windows/override_functions.cc \
-             src/windows/config.h src/windows/gperftools/tcmalloc.h \
-             docs/pprof.see_also src/windows/TODO \
-             $(WINDOWS_PROJECTS) \
-             src/solaris/libstdc++.la
diff --git a/third_party/tcmalloc/vendor/NEWS b/third_party/tcmalloc/vendor/NEWS
deleted file mode 100644
index 9938f0a..0000000
--- a/third_party/tcmalloc/vendor/NEWS
+++ /dev/null
@@ -1,1003 +0,0 @@
-== 29 Apr 2018 ==
-gperftools 2.7 is out!
-
-Few people contributed minor, but important fixes since rc.
-
-Changes:
-
-* bug in span stats printing introduced by new scalable page heap
-  change was fixed.
-
-* Christoph Müllner has contributed couple warnings fixes and initial
-  support for aarch64_ilp32 architecture.
-
-* Ben Dang contributed documentation fix for heap checker.
-
-* Fabrice Fontaine contributed fixed for linking benchmarks with
-  --disable-static.
-
-* Holy Wu has added sized deallocation unit tests.
-
-* Holy Wu has enabled support of sized deallocation (c++14) on recent
-  MSVC.
-
-* Holy Wu has fixed MSVC build in WIN32_OVERRIDE_ALLOCATORS mode. This
-  closed issue #716.
-
-* Holy Wu has contributed cleanup of config.h used on windows.
-
-* Mao Huang has contributed couple simple tcmalloc changes from
-  chromium code base. Making our tcmalloc forks a tiny bit closer.
-
-* issue #946 that caused compilation failures on some Linux clang
-  installations has been fixed. Much thanks to github user htuch for
-  helping to diagnose issue and proposing a fix.
-
-* Tulio Magno Quites Machado Filho has contributed build-time fix for
-  PPC (for problem introduced in one of commits since RC).
-
-== 18 Mar 2018 ==
-gperftools 2.7rc is out!
-
-Changes:
-
-* Most notable change in this release is that very large allocations
-  (>1MiB) are now handled be O(log n) implementation. This is
-  contributed by Todd Lipcon based on earlier work by Aliaksei
-  Kandratsenka and James Golick. Special thanks to Alexey Serbin for
-  contributing OSX fix for that commit.
-
-* detection of sized deallocation support is improved. Which should
-  fix another set of issues building on OSX. Much thanks to Alexey
-  Serbin for reporting the issue, suggesting a fix and verifying it.
-
-* Todd Lipcon made a change to extend page heaps freelists to 1 MiB
-  (up from 1MiB - 8KiB). This may help a little for some workloads.
-
-* Ishan Arora contributed typo fix to docs
-
-== 9 Dec 2017 ==
-gperftools 2.6.3 is out!
-
-Just two fixes were made in this release:
-
-* Stephan Zuercher has contributed a build fix for some recent XCode
-  versions. See issue #942 for more details.
-
-* assertion failure on some windows builds introduced by 2.6.2 was
-  fixed. Thanks to github user nkeemik for reporting it and testing
-  fix. See issue #944 for more details.
-
-== 30 Nov 2017 ==
-gperftools 2.6.2 is out!
-
-Most notable change is recently added support for C++17 over-aligned
-allocation operators contributed by Andrey Semashev. I've extended his
-implemention to have roughly same performance as malloc/new. This
-release also has native support for C11 aligned_alloc.
-
-Rest is mostly bug fixes:
-
-* Jianbo Yang has contributed a fix for potentially severe data race
-  introduced by malloc fast-path work in gperftools 2.6. This race
-  could cause occasional violation of total thread cache size
-  constraint. See issue #929 for more details.
-
-* Correct behavior in out-of-memory condition in fast-path cases was
-  restored. This was another bug introduced by fast-path optimization
-  in gperftools 2.6 which caused operator new to silently return NULL
-  instead of doing correct C++ OOM handling (calling new_handler and
-  throwing bad_alloc).
-
-* Khem Raj has contributed couple build fixes for newer glibcs (ucontext_t vs
-  struct ucontext and loff_t definition)
-
-* Piotr Sikora has contributed build fix for OSX (not building unwind
-  benchmark). This was issue #910 (thanks to Yuriy Solovyov for
-  reporting it).
-
-* Dorin Lazăr has contributed fix for compiler warning
-
-* issue #912 (occasional deadlocking calling getenv too early on
-  windows) was fixed. Thanks to github user shangcangriluo for
-  reporting it.
-
-* Couple earlier lsan-related commits still causing occasional issues
-  linking on OSX has been reverted. See issue #901.
-
-* Volodimir Krylov has contributed GetProgramInvocationName for FreeBSD
-
-* changsu lee has contributed couple minor correctness fixes (missing
-  va_end() and missing free() call in rarely executed Symbolize path)
-
-* Andrew C. Morrow has contributed some more page heap stats. See issue
-  #935.
-
-* some cases of built-time warnings from various gcc/clang versions
-  about throw() declarations have been fixes.
-
-== 9 July 2017 ==
-
-gperftools 2.6.1 is out! This is mostly bug-fixes release.
-
-* issue #901: build issue on OSX introduced in last-time commit in 2.6
-  was fixed (contributed by Francis Ricci)
-
-* tcmalloc_minimal now works on 32-bit ABI of mips64. This is issue
-  #845. Much thanks to Adhemerval Zanella and github user mtone.
-
-* Romain Geissler contributed build fix for -std=c++17. This is pull
-  request #897.
-
-* As part of fixing issue #904, tcmalloc atfork handler is now
-  installed early. This should fix slight chance of hitting deadlocks
-  at fork in some cases.
-
-== 4 July 2017 ==
-
-gperftools 2.6 is out!
-
-* Kim Gräsman contributed documentation update for HEAPPROFILESIGNAL
-  environment variable
-
-* KernelMaker contributed fix for population of min_object_size field
-  returned by MallocExtension::GetFreeListSizes
-
-* commit 8c3dc52fcfe0 "issue-654: [pprof] handle split text segments"
-  was reverted. Some OSX users reported issues with this commit. Given
-  our pprof implementation is strongly deprecated it is best to drop
-  recently introduced features rather than breaking it badly.
-
-* Francis Ricci contributed improvement for interaction with leak
-  sanitizer.
-
-== 22 May 2017 ==
-
-gperftools 2.6rc4 is out!
-
-Dynamic sized delete is disabled by default again. There is no hope of
-it working with eager dynamic symbols resolution (-z now linker
-flag). More details in
-https://bugzilla.redhat.com/show_bug.cgi?id=1452813
-
-== 21 May 2017 ==
-
-gperftools 2.6rc3 is out!
-
-gperftools compilation on older systems (e.g. rhel 5) was fixed. This
-was originally reported in github issue #888.
-
-== 14 May 2017 ==
-
-gperftools 2.6rc2 is out!
-
-Just 2 small fixes on top of 2.6rc. Particularly, Rajalakshmi
-Srinivasaraghavan contributed build fix for ppc32.
-
-== 14 May 2017 ==
-
-gperftools 2.6rc is out!
-
-Highlights of this release are performance work on malloc fast-path
-and support for more modern visual studio runtimes, and deprecation of
-bundled pprof. Another significant performance-affecting changes are
-reverting central free list transfer batch size back to 32 and
-disabling of aggressive decommit mode by default.
-
-Note, while we still ship perl implementation of pprof, everyone is
-strongly advised to use golang reimplementation of pprof from
-https://github.com/google/pprof.
-
-Here are notable changes in more details (and see ChangeLog for full
-details):
-
-* a bunch of performance tweaks to tcmalloc fast-path were
-  merged. This speeds up critical path of tcmalloc by few tens of
-  %. Well tuned and allocation-heavy programs should see substantial
-  performance boost (should apply to all modern elf platforms). This
-  is based on Google-internal tcmalloc changes for fast-path (with
-  obvious exception of lacking per-cpu mode, of course). Original
-  changes were made by Aliaksei Kandratsenka. And Andrew Hunter,
-  Dmitry Vyukov and Sanjay Ghemawat contributed with reviews and
-  discussions.
-
-* Architectures with 48 bits address space (x86-64 and aarch64) now
-  use faster 2 level page map. This was ported from Google-internal
-  change by Sanjay Ghemawat.
-
-* Default value of TCMALLOC_TRANSFER_NUM_OBJ was returned back to
-  32. Larger values have been found to hurt certain programs (but help
-  some other benchmarks). Value can still be tweaked at run time via
-  environment variable.
-
-* tcmalloc aggressive decommit mode is now disabled by default
-  again. It was found to degrade performance of certain tensorflow
-  benchmarks. Users who prefer smaller heap over small performance win
-  can still set environment variable TCMALLOC_AGGRESSIVE_DECOMMIT=t.
-
-* runtime switchable sized delete support has be fixed and re-enabled
-  (on GNU/Linux). Programs that use C++ 14 or later that use sized
-  delete can again be sped up by setting environment variable
-  TCMALLOC_ENABLE_SIZED_DELETE=t. Support for enabling sized
-  deallication support at compile-time is still present, of course.
-
-* tcmalloc now explicitly avoids use of MADV_FREE on Linux, unless
-  TCMALLOC_USE_MADV_FREE is defined at compile time. This is because
-  performance impact of MADV_FREE is not well known. Original issue
-  #780 raised by Mathias Stearn.
-
-* issue #786 with occasional deadlocks in stack trace capturing via
-  libunwind was fixed. It was originally reported as Ceph issue:
-  http://tracker.ceph.com/issues/13522
-
-* ChangeLog is now automatically generated from git log. Old ChangeLog
-  is now ChangeLog.old.
-
-* tcmalloc now provides implementation of nallocx. Function was
-  originally introduced by jemalloc and can be used to return real
-  allocation size given allocation request size. This is ported from
-  Google-internal tcmalloc change contributed by Dmitry Vyukov.
-
-* issue #843 which made tcmalloc crash when used with erlang runtime
-  was fixed.
-
-* issue #839 which caused tcmalloc's aggressive decommit mode to
-  degrade performance in some corner cases was fixed.
-
-* Bryan Chan contributed support for 31-bit s390.
-
-* Brian Silverman contributed compilation fix for 32-bit ARMs
-
-* Issue #817 that was causing tcmalloc to fail on windows 10 and
-  later, as well as on recent msvc was fixed. We now patch _free_base
-  as well.
-
-* a bunch of minor documentaion/typos fixes by: Mike Gaffney
-  <mike@uberu.com>, iivlev <iivlev@productengine.com>, savefromgoogle
-  <savefromgoogle@users.noreply.github.com>, John McDole
-  <jtmcdole@gmail.com>, zmertens <zmertens@asu.edu>, Kirill Müller
-  <krlmlr@mailbox.org>, Eugene <n.eugene536@gmail.com>, Ola Olsson
-  <ola1olsson@gmail.com>, Mostyn Bramley-Moore <mostynb@opera.com>
-
-* Tulio Magno Quites Machado Filho has contributed removal of
-  deprecated glibc malloc hooks.
-
-* Issue #827 that caused intercepting malloc on osx 10.12 to fail was
-  fixed, by copying fix made by Mike Hommey to jemalloc. Much thanks
-  to Koichi Shiraishi and David Ribeiro Alves for reporting it and
-  testing fix.
-
-* Aman Gupta and Kenton Varda contributed minor fixes to pprof (but
-  note again that pprof is deprecated)
-
-* Ryan Macnak contributed compilation fix for aarch64
-
-* Francis Ricci has fixed unaligned memory access in debug allocator
-
-* TCMALLOC_PAGE_FENCE_NEVER_RECLAIM now actually works thanks to
-  contribution by Andrew Morrow.
-
-== 12 Mar 2016 ==
-
-gperftools 2.5 is out!
-
-Just single bugfix was merged after rc2. Which was fix for issue #777.
-
-== 5 Mar 2016 ==
-
-gperftools 2.5rc2 is out!
-
-New release contains just few commits on top of first release
-candidate. One of them is build fix for Visual Studio. Another
-significant change is that dynamic sized delete is now disabled by
-default. It turned out that IFUNC relocations are not supporting our
-advanced use case on all platforms and in all cases.
-
-== 21 Feb 2016 ==
-
-gperftools 2.5rc is out!
-
-Here are major changes since 2.4:
-
-* we've moved to github!
-
-* Bryan Chan has contributed s390x support
-
-* stacktrace capturing via libgcc's _Unwind_Backtrace was implemented
-  (for architectures with missing or broken libunwind).
-
-* "emergency malloc" was implemented. Which unbreaks recursive calls
-  to malloc/free from stacktrace capturing functions (such us glib'c
-  backtrace() or libunwind on arm). It is enabled by
-  --enable-emergency-malloc configure flag or by default on arm when
-  --enable-stacktrace-via-backtrace is given. It is another fix for a
-  number common issues people had on platforms with missing or broken
-  libunwind.
-
-* C++14 sized-deallocation is now supported (on gcc 5 and recent
-  clangs). It is off by default and can be enabled at configure time
-  via --enable-sized-delete. On GNU/Linux it can also be enabled at
-  run-time by either TCMALLOC_ENABLE_SIZED_DELETE environment variable
-  or by defining tcmalloc_sized_delete_enabled function which should
-  return 1 to enable it.
-
-* we've lowered default value of transfer batch size to 512. Previous
-  value (bumped up in 2.1) was too high and caused performance
-  regression for some users. 512 should still give us performance
-  boost for workloads that need higher transfer batch size while not
-  penalizing other workloads too much.
-
-* Brian Silverman's patch finally stopped arming profiling timer
-  unless profiling is started.
-
-* Andrew Morrow has contributed support for obtaining cache size of the
-  current thread and softer idling (for use in MongoDB).
-
-* we've implemented few minor performance improvements, particularly
-  on malloc fast-path.
-
-A number of smaller fixes were made. Many of them were contributed:
-
-* issue that caused spurious profiler_unittest.sh failures was fixed.
-
-* Jonathan Lambrechts contributed improved callgrind format support to
-  pprof.
-
-* Matt Cross contributed better support for debug symbols in separate
-  files to pprof.
-
-* Matt Cross contributed support for printing collapsed stack frame
-  from pprof aimed at producing flame graphs.
-
-* Angus Gratton has contributed documentation fix mentioning that on
-  windows only tcmalloc_minimal is supported.
-
-* Anton Samokhvalov has made tcmalloc use mi_force_{un,}lock on OSX
-  instead of pthread_atfork. Which apparently fixes forking
-  issues tcmalloc had on OSX.
-
-* Milton Chiang has contributed support for building 32-bit gperftools
-  on arm8.
-
-* Patrick LoPresti has contributed support for specifying alternative
-  profiling signal via CPUPROFILE_TIMER_SIGNAL environment variable.
-
-* Paolo Bonzini has contributed support configuring filename for
-  sending malloc tracing output via TCMALLOC_TRACE_FILE environment
-  variable.
-
-* user spotrh has enabled use of futex on arm.
-
-* user mitchblank has contributed better declaration for arg-less
-  profiler functions.
-
-* Tom Conerly contributed proper freeing of memory allocated in
-  HeapProfileTable::FillOrderedProfile on error paths.
-
-* user fdeweerdt has contributed curl arguments handling fix in pprof
-
-* Frederik Mellbin fixed tcmalloc's idea of mangled new and delete
-  symbols on windows x64
-
-* Dair Grant has contributed cacheline alignment for ThreadCache
-  objects
-
-* Fredrik Mellbin has contributed updated windows/config.h for Visual
-  Studio 2015 and other windows fixes.
-
-* we're not linking libpthread to libtcmalloc_minimal anymore. Instead
-  libtcmalloc_minimal links to pthread symbols weakly. As a result
-  single-threaded programs remain single-threaded when linking to or
-  preloading libtcmalloc_minimal.so.
-
-* Boris Sazonov has contributed mips compilation fix and printf misue
-  in pprof.
-
-* Adhemerval Zanella has contributed alignment fixes for statically
-  allocated variables.
-
-* Jens Rosenboom has contributed fixes for heap-profiler_unittest.sh
-
-* gshirishfree has contributed better description for GetStats method.
-
-* cyshi has contributed spinlock pause fix.
-
-* Chris Mayo has contributed --docdir argument support for configure.
-
-* Duncan Sands has contributed fix for function aliases.
-
-* Simon Que contributed better include for malloc_hook_c.h
-
-* user wmamrak contributed struct timespec fix for Visual Studio 2015.
-
-* user ssubotin contributed typo in PrintAvailability code.
-
-
-== 10 Jan 2015 ==
-
-gperftools 2.4 is out! The code is exactly same as 2.4rc.
-
-== 28 Dec 2014 ==
-
-gperftools 2.4rc is out!
-
-Here are changes since 2.3:
-
-* enabled aggressive decommit option by default. It was found to
-  significantly improve memory fragmentation with negligible impact on
-  performance. (Thanks to investigation work performed by Adhemerval
-  Zanella)
-
-* added ./configure flags for tcmalloc pagesize and tcmalloc
-  allocation alignment. Larger page sizes have been reported to
-  improve performance occasionally. (Patch by Raphael Moreira Zinsly)
-
-* sped-up hot-path of malloc/free. By about 5% on static library and
-  about 10% on shared library. Mainly due to more efficient checking
-  of malloc hooks.
-
-* improved stacktrace capturing in cpu profiler (due to issue found by
-  Arun Sharma). As part of that issue pprof's handling of cpu profiles
-  was also improved.
-
-== 7 Dec 2014 ==
-
-gperftools 2.3 is out!
-
-Here are changes since 2.3rc:
-
-* (issue 658) correctly close socketpair fds on failure (patch by glider)
-
-* libunwind integration can be disabled at configure time (patch by
-  Raphael Moreira Zinsly)
-
-* libunwind integration is disabled by default for ppc64 (patch by
-  Raphael Moreira Zinsly)
-
-* libunwind integration is force-disabled for OSX. It was not used by
-  default anyways. Fixes compilation issue I saw.
-
-== 2 Nov 2014 ==
-
-gperftools 2.3rc is out!
-
-Most small improvements in this release were made to pprof tool.
-
-New experimental Linux-only (for now) cpu profiling mode is a notable
-big improvement.
-
-Here are notable changes since 2.2.1:
-
-* (issue-631) fixed debugallocation miscompilation on mmap-less
-  platforms (courtesy of user iamxujian)
-
-* (issue-630) reference to wrong PROFILE (vs. correct CPUPROFILE)
-  environment variable was fixed (courtesy of WenSheng He)
-
-* pprof now has option to display stack traces in output for heap
-  checker (courtesy of Michael Pasieka)
-
-* (issue-636) pprof web command now works on mingw
-
-* (issue-635) pprof now handles library paths that contain spaces
-  (courtesy of user mich...@sebesbefut.com)
-
-* (issue-637) pprof now has an option to not strip template arguments
-  (patch by jiakai)
-
-* (issue-644) possible out-of-bounds access in GetenvBeforeMain was
-  fixed (thanks to user abyss.7)
-
-* (issue-641) pprof now has an option --show_addresses (thanks to user
-  yurivict). New option prints instruction address in addition to
-  function name in stack traces
-
-* (issue-646) pprof now works around some issues of addr2line
-  reportedly when DWARF v4 format is used (patch by Adam McNeeney)
-
-* (issue-645) heap profiler exit message now includes remaining memory
-  allocated info (patch by user yurivict)
-
-* pprof code that finds location of /proc/<pid>/maps in cpu profile
-  files is now fixed (patch by Ricardo M. Correia)
-
-* (issue-654) pprof now handles "split text segments" feature of
-  Chromium for Android. (patch by simonb)
-
-* (issue-655) potential deadlock on windows caused by early call to
-  getenv in malloc initialization code was fixed (bug reported and fix
-  proposed by user zndmitry)
-
-* incorrect detection of arm 6zk instruction set support
-  (-mcpu=arm1176jzf-s) was fixed. (Reported by pedronavf on old
-  issue-493)
-
-* new cpu profiling mode on Linux is now implemented. It sets up
-  separate profiling timers for separate threads. Which improves
-  accuracy of profiling on Linux a lot. It is off by default. And is
-  enabled if both librt.f is loaded and CPUPROFILE_PER_THREAD_TIMERS
-  environment variable is set. But note that all threads need to be
-  registered via ProfilerRegisterThread.
-
-== 21 Jun 2014 ==
-
-gperftools 2.2.1 is out!
-
-Here's list of fixes:
-
-* issue-626 was closed. Which fixes initialization statically linked
-  tcmalloc.
-
-* issue 628 was closed. It adds missing header file into source
-  tarball. This fixes for compilation on PPC Linux.
-
-== 3 May 2014 ==
-
-gperftools 2.2 is out!
-
-Here are notable changes since 2.2rc:
-
-* issue 620 (crash on windows when c runtime dll is reloaded) was
-  fixed
-
-== 19 Apr 2014 ==
-
-gperftools 2.2rc is out!
-
-Here are notable changes since 2.1:
-
-* a number of fixes for a number compilers and platforms. Notably
-  Visual Studio 2013, recent mingw with c++ threads and some OSX
-  fixes.
-
-* we now have mips and mips64 support! (courtesy of Jovan Zelincevic,
-  Jean Lee, user xiaoyur347 and others)
-
-* we now have aarch64 (aka arm64) support! (contributed by Riku
-  Voipio)
-
-* there's now support for ppc64-le (by Raphael Moreira Zinsly and
-  Adhemerval Zanella)
-
-* there's now some support of uclibc (contributed by user xiaoyur347)
-
-* google/ headers will now give you deprecation warning. They are
-  deprecated since 2.0
-
-* there's now new api: tc_malloc_skip_new_handler (ported from chromium
-  fork)
-
-* issue-557: added support for dumping heap profile via signal (by
-  Jean Lee)
-
-* issue-567: Petr Hosek contributed SysAllocator support for windows
-
-* Joonsoo Kim contributed several speedups for central freelist code
-
-* TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES environment variable now works
-
-* configure scripts are now using AM_MAINTAINER_MODE. It'll only
-  affect folks who modify source from .tar.gz and want automake to
-  automatically rebuild Makefile-s. See automake documentation for
-  that.
-
-* issue-586: detect main executable even if PIE is active (based on
-  patch by user themastermind1). Notably, it fixes profiler use with
-  ruby.
-
-* there is now support for switching backtrace capturing method at
-  runtime (via TCMALLOC_STACKTRACE_METHOD and
-  TCMALLOC_STACKTRACE_METHOD_VERBOSE environment variables)
-
-* there is new backtrace capturing method using -finstrument-functions
-  prologues contributed by user xiaoyur347
-
-* few cases of crashes/deadlocks in profiler were addressed. See
-  (famous) issue-66, issue-547 and issue-579.
-
-* issue-464 (memory corruption in debugalloc's realloc after
-  memallign) is now fixed
-
-* tcmalloc is now able to release memory back to OS on windows
-  (issue-489). The code was ported from chromium fork (by a number of
-  authors).
-
-* Together with issue-489 we ported chromium's "aggressive decommit"
-  mode. In this mode (settable via malloc extension and via
-  environment variable TCMALLOC_AGGRESSIVE_DECOMMIT), free pages are
-  returned back to OS immediately.
-
-* MallocExtension::instance() is now faster (based on patch by
-  Adhemerval Zanella)
-
-* issue-610 (hangs on windows in multibyte locales) is now fixed
-
-The following people helped with ideas or patches (based on git log,
-some contributions purely in bugtracker might be missing): Andrew
-C. Morrow, yurivict, Wang YanQing, Thomas Klausner,
-davide.italiano@10gen.com, Dai MIKURUBE, Joon-Sung Um, Jovan
-Zelincevic, Jean Lee, Petr Hosek, Ben Avison, drussel, Joonsoo Kim,
-Hannes Weisbach, xiaoyur347, Riku Voipio, Adhemerval Zanella, Raphael
-Moreira Zinsly
-
-== 30 July 2013 ==
-
-gperftools 2.1 is out!
-
-Just few fixes where merged after rc. Most notably:
-
-* Some fixes for debug allocation on POWER/Linux
-
-== 20 July 2013 ==
-
-gperftools 2.1rc is out!
-
-As a result of more than a year of contributions we're ready for 2.1
-release.
-
-But before making that step I'd like to create RC and make sure people
-have chance to test it.
-
-Here are notable changes since 2.0:
-
-* fixes for building on newer platforms. Notably, there's now initial
-  support for x32 ABI (--enable-minimal only at this time))
-
-* new getNumericProperty stats for cache sizes
-
-* added HEAP_PROFILER_TIME_INTERVAL variable (see documentation)
-
-* added environment variable to control heap size (TCMALLOC_HEAP_LIMIT_MB)
-
-* added environment variable to disable release of memory back to OS
-  (TCMALLOC_DISABLE_MEMORY_RELEASE)
-
-* cpu profiler can now be switched on and off by sending it a signal
-  (specified in CPUPROFILESIGNAL)
-
-* (issue 491) fixed race-ful spinlock wake-ups
-
-* (issue 496) added some support for fork-ing of process that is using
-  tcmalloc
-
-* (issue 368) improved memory fragmentation when large chunks of
-  memory are allocated/freed
-
-== 03 February 2012 ==
-
-I've just released gperftools 2.0
-
-The `google-perftools` project has been renamed to `gperftools`.  I
-(csilvers) am stepping down as maintainer, to be replaced by
-David Chappelle.  Welcome to the team, David!  David has been an
-an active contributor to perftools in the past -- in fact, he's the
-only person other than me that already has commit status.  I am
-pleased to have him take over as maintainer.
-
-I have both renamed the project (the Google Code site renamed a few
-weeks ago), and bumped the major version number up to 2, to reflect
-the new community ownership of the project.  Almost all the
-[http://gperftools.googlecode.com/svn/tags/gperftools-2.0/ChangeLog changes]
-are related to the renaming.
-
-The main functional change from google-perftools 1.10 is that
-I've renamed the `google/` include-directory to be `gperftools/`
-instead.  New code should `#include <gperftools/tcmalloc.h>`/etc.
-(Most users of perftools don't need any perftools-specific includes at
-all, so this is mostly directed to "power users.")  I've kept the old
-names around as forwarding headers to the new, so `#include
-<google/tcmalloc.h>` will continue to work.
-
-(The other functional change which I snuck in is getting rid of some
-bash-isms in one of the unittest driver scripts, so it could run on
-Solaris.)
-
-Note that some internal names still contain the text `google`, such as
-the `google_malloc` internal linker section.  I think that's a
-trickier transition, and can happen in a future release (if at all).
-
-
-=== 31 January 2012 ===
-
-I've just released perftools 1.10
-
-There is an API-incompatible change: several of the methods in the
-`MallocExtension` class have changed from taking a `void*` to taking a
-`const void*`.  You should not be affected by this API change
-unless you've written your own custom malloc extension that derives
-from `MallocExtension`, but since it is a user-visible change, I have
-upped the `.so` version number for this release.
-
-This release focuses on improvements to linux-syscall-support.h,
-including ARM and PPC fixups and general cleanups.  I hope this will
-magically fix an array of bugs people have been seeing.
-
-There is also exciting news on the porting front, with support for
-patching win64 assembly contributed by IBM Canada!  This is an
-important step -- perhaps the most difficult -- to getting perftools
-to work on 64-bit windows using the patching technique (it doesn't
-affect the libc-modification technique).  `premable_patcher_test` has
-been added to help test these changes; it is meant to compile under
-x86_64, and won't work under win32.
-
-For the full list of changes, including improved `HEAP_PROFILE_MMAP`
-support, see the
-[http://gperftools.googlecode.com/svn/tags/google-perftools-1.10/ChangeLog ChangeLog].
-
-
-=== 24 January 2011 ===
-
-The `google-perftools` Google Code page has been renamed to
-`gperftools`, in preparation for the project being renamed to
-`gperftools`.  In the coming weeks, I'll be stepping down as
-maintainer for the perftools project, and as part of that Google is
-relinquishing ownership of the project; it will now be entirely
-community run.  The name change reflects that shift.  The 'g' in
-'gperftools' stands for 'great'. :-)
-
-=== 23 December 2011 ===
-
-I've just released perftools 1.9.1
-
-I missed including a file in the tarball, that is needed to compile on
-ARM.  If you are not compiling on ARM, or have successfully compiled
-perftools 1.9, there is no need to upgrade.
-
-
-=== 22 December 2011 ===
-
-I've just released perftools 1.9
-
-This change has a slew of improvements, from better ARM and freebsd
-support, to improved performance by moving some code outside of locks,
-to better pprof reporting of code with overloaded functions.
-
-The full list of changes is in the
-[http://google-perftools.googlecode.com/svn/tags/google-perftools-1.9/ChangeLog ChangeLog].
-
-
-=== 26 August 2011 ===
-
-I've just released perftools 1.8.3
-
-The star-crossed 1.8 series continues; in 1.8.1, I had accidentally
-removed some code that was needed for FreeBSD.  (Without this code
-many apps would crash at startup.)  This release re-adds that code.
-If you are not on FreeBSD, or are using FreeBSD with perftools 1.8 or
-earlier, there is no need to upgrade.
-
-=== 11 August 2011 ===
-
-I've just released perftools 1.8.2
-
-I was incorrectly calculating the patch-level in the configuration
-step, meaning the TC_VERSION_PATCH #define in tcmalloc.h was wrong.
-Since the testing framework checks for this, it was failing.  Now it
-should work again.  This time, I was careful to re-run my tests after
-upping the version number. :-)
-
-If you don't care about the TC_VERSION_PATCH #define, there's no
-reason to upgrae.
-
-=== 26 July 2011 ===
-
-I've just released perftools 1.8.1
-
-I was missing an #include that caused the build to break under some
-compilers, especially newer gcc's, that wanted it.  This only affects
-people who build from source, so only the .tar.gz file is updated from
-perftools 1.8.  If you didn't have any problems compiling perftools
-1.8, there's no reason to upgrade.
-
-=== 15 July 2011 ===
-
-I've just released perftools 1.8
-
-Of the many changes in this release, a good number pertain to porting.
-I've revamped OS X support to use the malloc-zone framework; it should
-now Just Work to link in tcmalloc, without needing
-`DYLD_FORCE_FLAT_NAMESPACE` or the like.  (This is a pretty major
-change, so please feel free to report feedback at
-google-perftools@googlegroups.com.)  64-bit Windows support is also
-improved, as is ARM support, and the hooks are in place to improve
-FreeBSD support as well.
-
-On the other hand, I'm seeing hanging tests on Cygwin.  I see the same
-hanging even with (the old) perftools 1.7, so I'm guessing this is
-either a problem specific to my Cygwin installation, or nobody is
-trying to use perftools under Cygwin.  If you can reproduce the
-problem, and even better have a solution, you can report it at
-google-perftools@googlegroups.com.
-
-Internal changes include several performance and space-saving tweaks.
-One is user-visible (but in "stealth mode", and otherwise
-undocumented): you can compile with `-DTCMALLOC_SMALL_BUT_SLOW`.  In
-this mode, tcmalloc will use less memory overhead, at the cost of
-running (likely not noticeably) slower.
-
-There are many other changes as well, too numerous to recount here,
-but present in the
-[http://google-perftools.googlecode.com/svn/tags/google-perftools-1.8/ChangeLog ChangeLog].
-
-
-=== 7 February 2011 ===
-
-Thanks to endlessr..., who
-[http://code.google.com/p/google-perftools/issues/detail?id=307 identified]
-why some tests were failing under MSVC 10 in release mode.  It does not look
-like these failures point toward any problem with tcmalloc itself; rather, the
-problem is with the test, which made some assumptions that broke under the
-some aggressive optimizations used in MSVC 10.  I'll fix the test, but in
-the meantime, feel free to use perftools even when compiled under MSVC
-10.
-
-=== 4 February 2011 ===
-
-I've just released perftools 1.7
-
-I apologize for the delay since the last release; so many great new
-patches and bugfixes kept coming in (and are still coming in; I also
-apologize to those folks who have to slip until the next release).  I
-picked this arbitrary time to make a cut.
-
-Among the many new features in this release is a multi-megabyte
-reduction in the amount of tcmalloc overhead uder x86_64, improved
-performance in the case of contention, and many many bugfixes,
-especially architecture-specific bugfixes.  See the
-[http://google-perftools.googlecode.com/svn/tags/google-perftools-1.7/ChangeLog ChangeLog]
-for full details.
-
-One architecture-specific change of note is added comments in the
-[http://google-perftools.googlecode.com/svn/tags/perftools-1.7/README README]
-for using tcmalloc under OS X.  I'm trying to get my head around the
-exact behavior of the OS X linker, and hope to have more improvements
-for the next release, but I hope these notes help folks who have been
-having trouble with tcmalloc on OS X.
-
-*Windows users*: I've heard reports that some unittests fail on
-Windows when compiled with MSVC 10 in Release mode.  All tests pass in
-Debug mode.  I've not heard of any problems with earlier versions of
-MSVC.  I don't know if this is a problem with the runtime patching (so
-the static patching discussed in README_windows.txt will still work),
-a problem with perftools more generally, or a bug in MSVC 10.  Anyone
-with windows expertise that can debug this, I'd be glad to hear from!
-
-
-=== 5 August 2010 ===
-
-I've just released perftools 1.6
-
-This version also has a large number of minor changes, including
-support for `malloc_usable_size()` as a glibc-compatible alias to
-`malloc_size()`, the addition of SVG-based output to `pprof`, and
-experimental support for tcmalloc large pages, which may speed up
-tcmalloc at the cost of greater memory use.  To use tcmalloc large
-pages, see the
-[http://google-perftools.googlecode.com/svn/tags/perftools-1.6/INSTALL
-INSTALL file]; for all changes, see the
-[http://google-perftools.googlecode.com/svn/tags/perftools-1.6/ChangeLog
-ChangeLog].
-
-OS X NOTE: improvements in the profiler unittest have turned up an OS
-X issue: in multithreaded programs, it seems that OS X often delivers
-the profiling signal (from sigitimer()) to the main thread, even when
-it's sleeping, rather than spawned threads that are doing actual work.
-If anyone knows details of how OS X handles SIGPROF events (from
-setitimer) in threaded programs, and has insight into this problem,
-please send mail to google-perftools@googlegroups.com.
-
-To see if you're affected by this, look for profiling time that pprof
-attributes to `___semwait_signal`.  This is work being done in other
-threads, that is being attributed to sleeping-time in the main thread.
-
-
-=== 20 January 2010 ===
-
-I've just released perftools 1.5
-
-This version has a slew of changes, leading to somewhat faster
-performance and improvements in portability.  It adds features like
-`ITIMER_REAL` support to the cpu profiler, and `tc_set_new_mode` to
-mimic the windows function of the same name.  Full details are in the
-[http://google-perftools.googlecode.com/svn/tags/perftools-1.5/ChangeLog
-ChangeLog].
-
-
-=== 11 September 2009 ===
-
-I've just released perftools 1.4
-
-The major change this release is the addition of a debugging malloc
-library!  If you link with `libtcmalloc_debug.so` instead of
-`libtcmalloc.so` (and likewise for the `minimal` variants) you'll get
-a debugging malloc, which will catch double-frees, writes to freed
-data, `free`/`delete` and `delete`/`delete[]` mismatches, and even
-(optionally) writes past the end of an allocated block.
-
-We plan to do more with this library in the future, including
-supporting it on Windows, and adding the ability to use the debugging
-library with your default malloc in addition to using it with
-tcmalloc.
-
-There are also the usual complement of bug fixes, documented in the
-ChangeLog, and a few minor user-tunable knobs added to components like
-the system allocator.
-
-
-=== 9 June 2009 ===
-
-I've just released perftools 1.3
-
-Like 1.2, this has a variety of bug fixes, especially related to the
-Windows build.  One of my bugfixes is to undo the weird `ld -r` fix to
-`.a` files that I introduced in perftools 1.2: it caused problems on
-too many platforms.  I've reverted back to normal `.a` files.  To work
-around the original problem that prompted the `ld -r` fix, I now
-provide `libtcmalloc_and_profiler.a`, for folks who want to link in
-both.
-
-The most interesting API change is that I now not only override
-`malloc`/`free`/etc, I also expose them via a unique set of symbols:
-`tc_malloc`/`tc_free`/etc.  This enables clients to write their own
-memory wrappers that use tcmalloc:
-{{{
-   void* malloc(size_t size) { void* r = tc_malloc(size); Log(r); return r; }
-}}}
-
-
-=== 17 April 2009 ===
-
-I've just released perftools 1.2.
-
-This is mostly a bugfix release.  The major change is internal: I have
-a new system for creating packages, which allows me to create 64-bit
-packages.  (I still don't do that for perftools, because there is
-still no great 64-bit solution, with libunwind still giving problems
-and --disable-frame-pointers not practical in every environment.)
-
-Another interesting change involves Windows: a
-[http://code.google.com/p/google-perftools/issues/detail?id=126 new
-patch] allows users to choose to override malloc/free/etc on Windows
-rather than patching, as is done now.  This can be used to create
-custom CRTs.
-
-My fix for this
-[http://groups.google.com/group/google-perftools/browse_thread/thread/1ff9b50043090d9d/a59210c4206f2060?lnk=gst&q=dynamic#a59210c4206f2060
-bug involving static linking] ended up being to make libtcmalloc.a and
-libperftools.a a big .o file, rather than a true `ar` archive.  This
-should not yield any problems in practice -- in fact, it should be
-better, since the heap profiler, leak checker, and cpu profiler will
-now all work even with the static libraries -- but if you find it
-does, please file a bug report.
-
-Finally, the profile_handler_unittest provided in the perftools
-testsuite (new in this release) is failing on FreeBSD.  The end-to-end
-test that uses the profile-handler is passing, so I suspect the
-problem may be with the test, not the perftools code itself.  However,
-I do not know enough about how itimers work on FreeBSD to be able to
-debug it.  If you can figure it out, please let me know!
-
-=== 11 March 2009 ===
-
-I've just released perftools 1.1!
-
-It has many changes since perftools 1.0 including
-
-  * Faster performance due to dynamically sized thread caches
-  * Better heap-sampling for more realistic profiles
-  * Improved support on Windows (MSVC 7.1 and cygwin)
-  * Better stacktraces in linux (using VDSO)
-  * Many bug fixes and feature requests
-
-Note: if you use the CPU-profiler with applications that fork without
-doing an exec right afterwards, please see the README.  Recent testing
-has shown that profiles are unreliable in that case.  The problem has
-existed since the first release of perftools.  We expect to have a fix
-for perftools 1.2.  For more details, see
-[http://code.google.com/p/google-perftools/issues/detail?id=105 issue 105].
-
-Everyone who uses perftools 1.0 is encouraged to upgrade to perftools
-1.1.  If you see any problems with the new release, please file a bug
-report at http://code.google.com/p/google-perftools/issues/list.
-
-Enjoy!
diff --git a/third_party/tcmalloc/vendor/README b/third_party/tcmalloc/vendor/README
deleted file mode 100644
index 8f61410..0000000
--- a/third_party/tcmalloc/vendor/README
+++ /dev/null
@@ -1,284 +0,0 @@
-gperftools
-----------
-(originally Google Performance Tools)
-
-The fastest malloc we’ve seen; works particularly well with threads
-and STL. Also: thread-friendly heap-checker, heap-profiler, and
-cpu-profiler.
-
-
-OVERVIEW
----------
-
-gperftools is a collection of a high-performance multi-threaded
-malloc() implementation, plus some pretty nifty performance analysis
-tools.
-
-gperftools is distributed under the terms of the BSD License. Join our
-mailing list at gperftools@googlegroups.com for updates:
-https://groups.google.com/forum/#!forum/gperftools
-
-gperftools was original home for pprof program. But do note that
-original pprof (which is still included with gperftools) is now
-deprecated in favor of golang version at https://github.com/google/pprof
-
-
-TCMALLOC
---------
-Just link in -ltcmalloc or -ltcmalloc_minimal to get the advantages of
-tcmalloc -- a replacement for malloc and new.  See below for some
-environment variables you can use with tcmalloc, as well.
-
-tcmalloc functionality is available on all systems we've tested; see
-INSTALL for more details.  See README_windows.txt for instructions on
-using tcmalloc on Windows.
-
-NOTE: When compiling with programs with gcc, that you plan to link
-with libtcmalloc, it's safest to pass in the flags
-
- -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free
-
-when compiling.  gcc makes some optimizations assuming it is using its
-own, built-in malloc; that assumption obviously isn't true with
-tcmalloc.  In practice, we haven't seen any problems with this, but
-the expected risk is highest for users who register their own malloc
-hooks with tcmalloc (using gperftools/malloc_hook.h).  The risk is
-lowest for folks who use tcmalloc_minimal (or, of course, who pass in
-the above flags :-) ).
-
-
-HEAP PROFILER
--------------
-See docs/heapprofile.html for information about how to use tcmalloc's
-heap profiler and analyze its output.
-
-As a quick-start, do the following after installing this package:
-
-1) Link your executable with -ltcmalloc
-2) Run your executable with the HEAPPROFILE environment var set:
-     $ HEAPPROFILE=/tmp/heapprof <path/to/binary> [binary args]
-3) Run pprof to analyze the heap usage
-     $ pprof <path/to/binary> /tmp/heapprof.0045.heap  # run 'ls' to see options
-     $ pprof --gv <path/to/binary> /tmp/heapprof.0045.heap
-
-You can also use LD_PRELOAD to heap-profile an executable that you
-didn't compile.
-
-There are other environment variables, besides HEAPPROFILE, you can
-set to adjust the heap-profiler behavior; c.f. "ENVIRONMENT VARIABLES"
-below.
-
-The heap profiler is available on all unix-based systems we've tested;
-see INSTALL for more details.  It is not currently available on Windows.
-
-
-HEAP CHECKER
-------------
-See docs/heap_checker.html for information about how to use tcmalloc's
-heap checker.
-
-In order to catch all heap leaks, tcmalloc must be linked *last* into
-your executable.  The heap checker may mischaracterize some memory
-accesses in libraries listed after it on the link line.  For instance,
-it may report these libraries as leaking memory when they're not.
-(See the source code for more details.)
-
-Here's a quick-start for how to use:
-
-As a quick-start, do the following after installing this package:
-
-1) Link your executable with -ltcmalloc
-2) Run your executable with the HEAPCHECK environment var set:
-     $ HEAPCHECK=1 <path/to/binary> [binary args]
-
-Other values for HEAPCHECK: normal (equivalent to "1"), strict, draconian
-
-You can also use LD_PRELOAD to heap-check an executable that you
-didn't compile.
-
-The heap checker is only available on Linux at this time; see INSTALL
-for more details.
-
-
-CPU PROFILER
-------------
-See docs/cpuprofile.html for information about how to use the CPU
-profiler and analyze its output.
-
-As a quick-start, do the following after installing this package:
-
-1) Link your executable with -lprofiler
-2) Run your executable with the CPUPROFILE environment var set:
-     $ CPUPROFILE=/tmp/prof.out <path/to/binary> [binary args]
-3) Run pprof to analyze the CPU usage
-     $ pprof <path/to/binary> /tmp/prof.out      # -pg-like text output
-     $ pprof --gv <path/to/binary> /tmp/prof.out # really cool graphical output
-
-There are other environment variables, besides CPUPROFILE, you can set
-to adjust the cpu-profiler behavior; cf "ENVIRONMENT VARIABLES" below.
-
-The CPU profiler is available on all unix-based systems we've tested;
-see INSTALL for more details.  It is not currently available on Windows.
-
-NOTE: CPU profiling doesn't work after fork (unless you immediately
-      do an exec()-like call afterwards).  Furthermore, if you do
-      fork, and the child calls exit(), it may corrupt the profile
-      data.  You can use _exit() to work around this.  We hope to have
-      a fix for both problems in the next release of perftools
-      (hopefully perftools 1.2).
-
-
-EVERYTHING IN ONE
------------------
-If you want the CPU profiler, heap profiler, and heap leak-checker to
-all be available for your application, you can do:
-   gcc -o myapp ... -lprofiler -ltcmalloc
-
-However, if you have a reason to use the static versions of the
-library, this two-library linking won't work:
-   gcc -o myapp ... /usr/lib/libprofiler.a /usr/lib/libtcmalloc.a  # errors!
-
-Instead, use the special libtcmalloc_and_profiler library, which we
-make for just this purpose:
-   gcc -o myapp ... /usr/lib/libtcmalloc_and_profiler.a
-
-
-CONFIGURATION OPTIONS
----------------------
-For advanced users, there are several flags you can pass to
-'./configure' that tweak tcmalloc performace.  (These are in addition
-to the environment variables you can set at runtime to affect
-tcmalloc, described below.)  See the INSTALL file for details.
-
-
-ENVIRONMENT VARIABLES
----------------------
-The cpu profiler, heap checker, and heap profiler will lie dormant,
-using no memory or CPU, until you turn them on.  (Thus, there's no
-harm in linking -lprofiler into every application, and also -ltcmalloc
-assuming you're ok using the non-libc malloc library.)
-
-The easiest way to turn them on is by setting the appropriate
-environment variables.  We have several variables that let you
-enable/disable features as well as tweak parameters.
-
-Here are some of the most important variables:
-
-HEAPPROFILE=<pre> -- turns on heap profiling and dumps data using this prefix
-HEAPCHECK=<type>  -- turns on heap checking with strictness 'type'
-CPUPROFILE=<file> -- turns on cpu profiling and dumps data to this file.
-PROFILESELECTED=1 -- if set, cpu-profiler will only profile regions of code
-                     surrounded with ProfilerEnable()/ProfilerDisable().
-CPUPROFILE_FREQUENCY=x-- how many interrupts/second the cpu-profiler samples.
-
-PERFTOOLS_VERBOSE=<level> -- the higher level, the more messages malloc emits
-MALLOCSTATS=<level>    -- prints memory-use stats at program-exit
-
-For a full list of variables, see the documentation pages:
-   docs/cpuprofile.html
-   docs/heapprofile.html
-   docs/heap_checker.html
-
-
-COMPILING ON NON-LINUX SYSTEMS
-------------------------------
-
-Perftools was developed and tested on x86 Linux systems, and it works
-in its full generality only on those systems.  However, we've
-successfully ported much of the tcmalloc library to FreeBSD, Solaris
-x86, and Darwin (Mac OS X) x86 and ppc; and we've ported the basic
-functionality in tcmalloc_minimal to Windows.  See INSTALL for details.
-See README_windows.txt for details on the Windows port.
-
-
-PERFORMANCE
------------
-
-If you're interested in some third-party comparisons of tcmalloc to
-other malloc libraries, here are a few web pages that have been
-brought to our attention.  The first discusses the effect of using
-various malloc libraries on OpenLDAP.  The second compares tcmalloc to
-win32's malloc.
-  http://www.highlandsun.com/hyc/malloc/
-  http://gaiacrtn.free.fr/articles/win32perftools.html
-
-It's possible to build tcmalloc in a way that trades off faster
-performance (particularly for deletes) at the cost of more memory
-fragmentation (that is, more unusable memory on your system).  See the
-INSTALL file for details.
-
-
-OLD SYSTEM ISSUES
------------------
-
-When compiling perftools on some old systems, like RedHat 8, you may
-get an error like this:
-    ___tls_get_addr: symbol not found
-
-This means that you have a system where some parts are updated enough
-to support Thread Local Storage, but others are not.  The perftools
-configure script can't always detect this kind of case, leading to
-that error.  To fix it, just comment out (or delete) the line
-   #define HAVE_TLS 1
-in your config.h file before building.
-
-
-64-BIT ISSUES
--------------
-
-There are two issues that can cause program hangs or crashes on x86_64
-64-bit systems, which use the libunwind library to get stack-traces.
-Neither issue should affect the core tcmalloc library; they both
-affect the perftools tools such as cpu-profiler, heap-checker, and
-heap-profiler.
-
-1) Some libc's -- at least glibc 2.4 on x86_64 -- have a bug where the
-libc function dl_iterate_phdr() acquires its locks in the wrong
-order.  This bug should not affect tcmalloc, but may cause occasional
-deadlock with the cpu-profiler, heap-profiler, and heap-checker.
-Its likeliness increases the more dlopen() commands an executable has.
-Most executables don't have any, though several library routines like
-getgrgid() call dlopen() behind the scenes.
-
-2) On x86-64 64-bit systems, while tcmalloc itself works fine, the
-cpu-profiler tool is unreliable: it will sometimes work, but sometimes
-cause a segfault.  I'll explain the problem first, and then some
-workarounds.
-
-Note that this only affects the cpu-profiler, which is a
-gperftools feature you must turn on manually by setting the
-CPUPROFILE environment variable.  If you do not turn on cpu-profiling,
-you shouldn't see any crashes due to perftools.
-
-The gory details: The underlying problem is in the backtrace()
-function, which is a built-in function in libc.
-Backtracing is fairly straightforward in the normal case, but can run
-into problems when having to backtrace across a signal frame.
-Unfortunately, the cpu-profiler uses signals in order to register a
-profiling event, so every backtrace that the profiler does crosses a
-signal frame.
-
-In our experience, the only time there is trouble is when the signal
-fires in the middle of pthread_mutex_lock.  pthread_mutex_lock is
-called quite a bit from system libraries, particularly at program
-startup and when creating a new thread.
-
-The solution: The dwarf debugging format has support for 'cfi
-annotations', which make it easy to recognize a signal frame.  Some OS
-distributions, such as Fedora and gentoo 2007.0, already have added
-cfi annotations to their libc.  A future version of libunwind should
-recognize these annotations; these systems should not see any
-crashses.
-
-Workarounds: If you see problems with crashes when running the
-cpu-profiler, consider inserting ProfilerStart()/ProfilerStop() into
-your code, rather than setting CPUPROFILE.  This will profile only
-those sections of the codebase.  Though we haven't done much testing,
-in theory this should reduce the chance of crashes by limiting the
-signal generation to only a small part of the codebase.  Ideally, you
-would not use ProfilerStart()/ProfilerStop() around code that spawns
-new threads, or is otherwise likely to cause a call to
-pthread_mutex_lock!
-
----
-17 May 2011
diff --git a/third_party/tcmalloc/vendor/README_windows.txt b/third_party/tcmalloc/vendor/README_windows.txt
deleted file mode 100644
index 406bd01..0000000
--- a/third_party/tcmalloc/vendor/README_windows.txt
+++ /dev/null
@@ -1,120 +0,0 @@
---- COMPILING
-
-This project has begun being ported to Windows, only tcmalloc_minimal
-is supported at this time.  A working solution file exists in this
-directory:
-    gperftools.sln
-
-You can load this solution file into VC++ 7.1 (Visual Studio 2003) or
-later -- in the latter case, it will automatically convert the files
-to the latest format for you.
-
-When you build the solution, it will create a number of unittests,
-which you can run by hand (or, more easily, under the Visual Studio
-debugger) to make sure everything is working properly on your system.
-The binaries will end up in a directory called "debug" or "release" in
-the top-level directory (next to the .sln file).  It will also create
-two binaries, nm-pdb and addr2line-pdb, which you should install in
-the same directory you install the 'pprof' perl script.
-
-I don't know very much about how to install DLLs on Windows, so you'll
-have to figure out that part for yourself.  If you choose to just
-re-use the existing .sln, make sure you set the IncludeDir's
-appropriately!  Look at the properties for libtcmalloc_minimal.dll.
-
-Note that these systems are set to build in Debug mode by default.
-You may want to change them to Release mode.
-
-To use tcmalloc_minimal in your own projects, you should only need to
-build the dll and install it someplace, so you can link it into
-further binaries.  To use the dll, you need to add the following to
-the linker line of your executable:
-   "libtcmalloc_minimal.lib" /INCLUDE:"__tcmalloc" 
-
-Here is how to accomplish this in Visual Studio 2005 (VC8):
-
-1) Have your executable depend on the tcmalloc library by selecting
-   "Project Dependencies..." from the "Project" menu.  Your executable
-   should depend on "libtcmalloc_minimal".
-
-2) Have your executable depend on a tcmalloc symbol -- this is
-   necessary so the linker doesn't "optimize out" the libtcmalloc
-   dependency -- by right-clicking on your executable's project (in
-   the solution explorer), selecting Properties from the pull-down
-   menu, then selecting "Configuration Properties" -> "Linker" ->
-   "Input".  Then, in the "Force Symbol References" field, enter the
-   text "__tcmalloc" (without the quotes).  Be sure to do this for both
-   debug and release modes!
-
-You can also link tcmalloc code in statically -- see the example
-project tcmalloc_minimal_unittest-static, which does this.  For this
-to work, you'll need to add "/D PERFTOOLS_DLL_DECL=" to the compile
-line of every perftools .cc file.  You do not need to depend on the
-tcmalloc symbol in this case (that is, you don't need to do either
-step 1 or step 2 from above).
-
-An alternative to all the above is to statically link your application
-with libc, and then replace its malloc with tcmalloc.  This allows you
-to just build and link your program normally; the tcmalloc support
-comes in a post-processing step.  This is more reliable than the above
-technique (which depends on run-time patching, which is inherently
-fragile), though more work to set up.  For details, see
-   https://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b
-
-
---- THE HEAP-PROFILER
-
-The heap-profiler has had a preliminary port to Windows but does not
-build on Windows by default.  It has not been well tested, and
-probably does not work at all when Frame Pointer Optimization (FPO) is
-enabled -- that is, in release mode.  The other features of perftools,
-such as the cpu-profiler and leak-checker, have not yet been ported to
-Windows at all.
-
-
---- WIN64
-
-The function-patcher has to disassemble code, and is very
-x86-specific.  However, the rest of perftools should work fine for
-both x86 and x64.  In particular, if you use the 'statically link with
-libc, and replace its malloc with tcmalloc' approach, mentioned above,
-it should be possible to use tcmalloc with 64-bit windows.
-
-As of perftools 1.10, there is some support for disassembling x86_64
-instructions, for work with win64.  This work is preliminary, but the
-test file preamble_patcher_test.cc is provided to play around with
-that a bit.  preamble_patcher_test will not compile on win32.
-
-
---- ISSUES
-
-NOTE FOR WIN2K USERS: According to reports
-(http://code.google.com/p/gperftools/issues/detail?id=127)
-the stack-tracing necessary for the heap-profiler does not work on
-Win2K.  The best workaround is, if you are building on a Win2k system
-is to add "/D NO_TCMALLOC_SAMPLES=" to your build, to turn off the
-stack-tracing.  You will not be able to use the heap-profiler if you
-do this.
-
-NOTE ON _MSIZE and _RECALLOC: The tcmalloc version of _msize returns
-the size of the region tcmalloc allocated for you -- which is at least
-as many bytes you asked for, but may be more.  (btw, these *are* bytes
-you own, even if you didn't ask for all of them, so it's correct code
-to access all of them if you want.)  Unfortunately, the Windows CRT
-_recalloc() routine assumes that _msize returns exactly as many bytes
-as were requested.  As a result, _recalloc() may not zero out new
-bytes correctly.  IT'S SAFEST NOT TO USE _RECALLOC WITH TCMALLOC.
-_recalloc() is a tricky routine to use in any case (it's not safe to
-use with realloc, for instance).
-
-
-I have little experience with Windows programming, so there may be
-better ways to set this up than I've done!  If you run across any
-problems, please post to the google-perftools Google Group, or report
-them on the gperftools Google Code site:
-   http://groups.google.com/group/google-perftools
-   http://code.google.com/p/gperftools/issues/list
-
--- craig
-
-Last modified: 2 February 2012
diff --git a/third_party/tcmalloc/vendor/TODO b/third_party/tcmalloc/vendor/TODO
deleted file mode 100644
index 550f7e09..0000000
--- a/third_party/tcmalloc/vendor/TODO
+++ /dev/null
@@ -1,47 +0,0 @@
-HEAP PROFILER
-
-1) Fix heap profiling under all STLs
-   * Find out how to force non-glibc STL libraries to call new() and
-     delete() for every allocation / deallocation.
-   * Make heap profiler ignore STL-internal allocations for those
-     libraries under which we cannot profile accurately, so we only
-     see object-level leaks.
-2) Remove dependency on tcmalloc?
-3) Port to non-linux O/Ses (right now code uses /proc for library info)
-4) Port to non-x86 architectures (locking code in spinlock is x86-specific)
-5) Port to C?
-6) Figure out how to get setenv() to work properly before main() in
-   shared libaries, and get rid of the profile-naming hack once we
-   do.  (See HeapProfiler::Init().)
-
-
-HEAP CHECKER
-
-1) Remove requirement that the heap-checker must be linked last into
-   an application (hard! -- it needs its global constructor to run
-   first)
-
-TCMALLOC
-
-1) Implement mallinfo/mallopt
-2) Have tcmalloc work correctly when libpthread is not linked in
-   (currently working for glibc, could use other libc's too)
-3) Return memory to the system when requirements drop
-4) Explore coloring allocated objects to avoid cache conflicts
-5) Explore biasing reclamation to larger addresses
-6) Add contention stats to a synchronization.cc (can do spinlocks,
-   but threads? -- may have to provide our own thread implementation)
-
-CPU PROFILER
-
-1) Figure out how to get setenv() to work properly before main() in
-   shared libaries(), and get rid of the profile-naming hack once we
-   do.  (See Profiler::GetUniquePathFromEnv().)
-2) Resolve crashing problems on x86_64 (see README)
-
-STACKTRACE
-
-1) Remove dependency on linux/x86
-
----
-11 March 2008
diff --git a/third_party/tcmalloc/vendor/autogen.sh b/third_party/tcmalloc/vendor/autogen.sh
deleted file mode 100755
index 7c590a31..0000000
--- a/third_party/tcmalloc/vendor/autogen.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-autoreconf -i
diff --git a/third_party/tcmalloc/vendor/benchmark/binary_trees.cc b/third_party/tcmalloc/vendor/benchmark/binary_trees.cc
deleted file mode 100644
index 4c895b2e..0000000
--- a/third_party/tcmalloc/vendor/benchmark/binary_trees.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-//
-// Copied from
-// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&lang=gpp&id=2
-// and slightly modified (particularly by adding multi-threaded
-// operation to hit malloc harder).
-//
-// This version of binary trees is mostly new/delete benchmark
-//
-// NOTE: copyright of this code is unclear, but we only distribute
-// source.
-
-/* The Computer Language Benchmarks Game
- * http://benchmarksgame.alioth.debian.org/
- *
- * Contributed by Jon Harrop
- * Modified by Alex Mizrahi
- * Adapted for gperftools and added threads by Aliaksei Kandratsenka
- */
-
-#include <algorithm>
-#include <errno.h>
-#include <iostream>
-#include <pthread.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <vector>
-
-struct Node {
-  Node *l, *r;
-  int i;
-  Node(int i2) : l(0), r(0), i(i2) {}
-  Node(Node *l2, int i2, Node *r2) : l(l2), r(r2), i(i2) {}
-  ~Node() { delete l; delete r; }
-  int check() const {
-    if (l) {
-      return l->check() + i - r->check();
-    } else {
-      return i;
-    }
-  }
-};
-
-Node *make(int i, int d) {
-  if (d == 0) return new Node(i);
-  return new Node(make(2*i-1, d-1), i, make(2*i, d-1));
-}
-
-void run(int given_depth) {
-  int min_depth = 4,
-    max_depth = std::max(min_depth+2,
-			 given_depth),
-    stretch_depth = max_depth+1;
-
-  {
-    Node *c = make(0, stretch_depth);
-    std::cout << "stretch tree of depth " << stretch_depth << "\t "
-      << "check: " << c->check() << std::endl;
-    delete c;
-  }
-
-  Node *long_lived_tree=make(0, max_depth);
-
-  for (int d=min_depth; d<=max_depth; d+=2) {
-    int iterations = 1 << (max_depth - d + min_depth), c=0;
-    for (int i=1; i<=iterations; ++i) {
-      Node *a = make(i, d), *b = make(-i, d);
-      c += a->check() + b->check();
-      delete a;
-      delete b;
-    }
-    std::cout << (2*iterations) << "\t trees of depth " << d << "\t "
-	      << "check: " << c << std::endl;
-  }
-
-  std::cout << "long lived tree of depth " << max_depth << "\t "
-	    << "check: " << (long_lived_tree->check()) << "\n";
-
-  delete long_lived_tree;
-}
-
-static void *run_tramp(void *_a) {
-  intptr_t a = reinterpret_cast<intptr_t>(_a);
-  run(a);
-  return 0;
-}
-
-int main(int argc, char *argv[]) {
-  int given_depth = argc >= 2 ? atoi(argv[1]) : 20;
-  int thread_count = std::max(1, argc >= 3 ? atoi(argv[2]) : 1) - 1;
-  std::vector<pthread_t> threads(thread_count);
-
-  for (int i = 0; i < thread_count; i++) {
-    int rv = pthread_create(&threads[i], NULL,
-                            run_tramp,
-                            reinterpret_cast<void *>(given_depth));
-    if (rv) {
-      errno = rv;
-      perror("pthread_create");
-    }
-  }
-  run_tramp(reinterpret_cast<void *>(given_depth));
-  for (int i = 0; i < thread_count; i++) {
-    pthread_join(threads[i], NULL);
-  }
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/benchmark/getcontext_light.cc b/third_party/tcmalloc/vendor/benchmark/getcontext_light.cc
deleted file mode 100644
index e8ff8b3e..0000000
--- a/third_party/tcmalloc/vendor/benchmark/getcontext_light.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <ucontext.h>
-#include <stddef.h>
-
-extern "C" void getcontext_light(ucontext_t *ctx);
-
-// clang's built-in asm cannot handle .set directives
-#if defined(__GNUC__) && !defined(__llvm__) && defined(__x86_64) && defined(_LP64)
-
-#define R(r) offsetof(ucontext_t, uc_mcontext.gregs[r])
-
-static __attribute__((used))
-void getcontext_tramp(ucontext_t *ctx) {
-	__asm__ __volatile__(".set oRBX, %c0\n"
-			     ".set oRBP, %c1\n"
-			     ".set oR12, %c2\n"
-			     ".set oR13, %c3\n"
-			     ".set oR14, %c4\n"
-			     ".set oR15, %c5\n"
-			     ".set oRIP, %c6\n"
-			     ".set oRSP, %c7\n"
-			     : :
-			       "p" (R(REG_RBX)),
-			       "p" (R(REG_RBP)),
-			       "p" (R(REG_R12)),
-			       "p" (R(REG_R13)),
-			       "p" (R(REG_R14)),
-			       "p" (R(REG_R15)),
-			       "p" (R(REG_RIP)),
-			       "p" (R(REG_RSP)));
-	getcontext_light(ctx);
-}
-
-__asm__(".pushsection .text; .globl getcontext_light\n"
-	".type getcontext_light, @function\n"
-"getcontext_light:\n"
-	"\t.cfi_startproc\n"
-	"\tmovq     %rbx, oRBX(%rdi)\n"
-	"\tmovq     %rbp, oRBP(%rdi)\n"
-	"\tmovq     %r12, oR12(%rdi)\n"
-	"\tmovq     %r13, oR13(%rdi)\n"
-	"\tmovq     %r14, oR14(%rdi)\n"
-	"\tmovq     %r15, oR14(%rdi)\n"
-
-	"\tmovq     (%rsp), %rcx\n"
-	"\tmovq     %rcx, oRIP(%rdi)\n"
-	"\tleaq     8(%rsp), %rcx\n"                /* Exclude the return address.  */
-	"\tmovq     %rcx, oRSP(%rdi)\n"
-	"\tret\n"
-	".cfi_endproc\n"
-	".size getcontext_light, .-getcontext_light\n"
-	".popsection\n"
-	);
-
-#else
-
-extern "C" void getcontext_light(ucontext_t *ctx) {
-	getcontext(ctx);
-}
-
-#endif
diff --git a/third_party/tcmalloc/vendor/benchmark/malloc_bench.cc b/third_party/tcmalloc/vendor/benchmark/malloc_bench.cc
deleted file mode 100644
index 371b8c61a..0000000
--- a/third_party/tcmalloc/vendor/benchmark/malloc_bench.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-
-#include <algorithm>
-
-#include "run_benchmark.h"
-
-static void bench_fastpath_throughput(long iterations,
-                                      uintptr_t param)
-{
-  size_t sz = 32;
-  for (; iterations>0; iterations--) {
-    void *p = malloc(sz);
-    if (!p) {
-      abort();
-    }
-    free(p);
-    // this makes next iteration use different free list. So
-    // subsequent iterations may actually overlap in time.
-    sz = ((sz * 8191) & 511) + 16;
-  }
-}
-
-static void bench_fastpath_dependent(long iterations,
-                                     uintptr_t param)
-{
-  size_t sz = 32;
-  for (; iterations>0; iterations--) {
-    void *p = malloc(sz);
-    if (!p) {
-      abort();
-    }
-    free(p);
-    // this makes next iteration depend on current iteration. But this
-    // iteration's free may still overlap with next iteration's malloc
-    sz = ((sz | reinterpret_cast<size_t>(p)) & 511) + 16;
-  }
-}
-
-static void bench_fastpath_simple(long iterations,
-                                  uintptr_t param)
-{
-  size_t sz = static_cast<size_t>(param);
-  for (; iterations>0; iterations--) {
-    void *p = malloc(sz);
-    if (!p) {
-      abort();
-    }
-    free(p);
-    // next iteration will use same free list as this iteration. So it
-    // should be prevent next iterations malloc to go too far before
-    // free done. But using same size will make free "too fast" since
-    // we'll hit size class cache.
-  }
-}
-
-#ifdef __GNUC__
-#define HAVE_SIZED_FREE_OPTION
-
-extern "C" void tc_free_sized(void *ptr, size_t size) __attribute__((weak));
-extern "C" void *tc_memalign(size_t align, size_t size) __attribute__((weak));
-
-static bool is_sized_free_available(void)
-{
-  return tc_free_sized != NULL;
-}
-
-static bool is_memalign_available(void)
-{
-  return tc_memalign != NULL;
-}
-
-static void bench_fastpath_simple_sized(long iterations,
-                                        uintptr_t param)
-{
-  size_t sz = static_cast<size_t>(param);
-  for (; iterations>0; iterations--) {
-    void *p = malloc(sz);
-    if (!p) {
-      abort();
-    }
-    tc_free_sized(p, sz);
-    // next iteration will use same free list as this iteration. So it
-    // should be prevent next iterations malloc to go too far before
-    // free done. But using same size will make free "too fast" since
-    // we'll hit size class cache.
-  }
-}
-
-static void bench_fastpath_memalign(long iterations,
-                                    uintptr_t param)
-{
-  size_t sz = static_cast<size_t>(param);
-  for (; iterations>0; iterations--) {
-    void *p = tc_memalign(32, sz);
-    if (!p) {
-      abort();
-    }
-    free(p);
-    // next iteration will use same free list as this iteration. So it
-    // should be prevent next iterations malloc to go too far before
-    // free done. But using same size will make free "too fast" since
-    // we'll hit size class cache.
-  }
-}
-
-#endif // __GNUC__
-
-#define STACKSZ (1 << 16)
-
-static void bench_fastpath_stack(long iterations,
-                                 uintptr_t _param)
-{
-
-  void *stack[STACKSZ];
-  size_t sz = 64;
-  long param = static_cast<long>(_param);
-  param &= STACKSZ - 1;
-  param = param ? param : 1;
-  for (; iterations>0; iterations -= param) {
-    for (long k = param-1; k >= 0; k--) {
-      void *p = malloc(sz);
-      if (!p) {
-        abort();
-      }
-      stack[k] = p;
-      // this makes next iteration depend on result of this iteration
-      sz = ((sz | reinterpret_cast<size_t>(p)) & 511) + 16;
-    }
-    for (long k = 0; k < param; k++) {
-      free(stack[k]);
-    }
-  }
-}
-
-static void bench_fastpath_stack_simple(long iterations,
-                                        uintptr_t _param)
-{
-
-  void *stack[STACKSZ];
-  size_t sz = 128;
-  long param = static_cast<long>(_param);
-  param &= STACKSZ - 1;
-  param = param ? param : 1;
-  for (; iterations>0; iterations -= param) {
-    for (long k = param-1; k >= 0; k--) {
-      void *p = malloc(sz);
-      if (!p) {
-        abort();
-      }
-      stack[k] = p;
-    }
-    for (long k = 0; k < param; k++) {
-      free(stack[k]);
-    }
-  }
-}
-
-static void bench_fastpath_rnd_dependent(long iterations,
-                                         uintptr_t _param)
-{
-  static const uintptr_t rnd_c = 1013904223;
-  static const uintptr_t rnd_a = 1664525;
-
-  void *ptrs[STACKSZ];
-  size_t sz = 128;
-  if ((_param & (_param - 1))) {
-    abort();
-  }
-  if (_param > STACKSZ) {
-    abort();
-  }
-  int param = static_cast<int>(_param);
-
-  for (; iterations>0; iterations -= param) {
-    for (int k = param-1; k >= 0; k--) {
-      void *p = malloc(sz);
-      if (!p) {
-        abort();
-      }
-      ptrs[k] = p;
-      sz = ((sz | reinterpret_cast<size_t>(p)) & 511) + 16;
-    }
-
-    // this will iterate through all objects in order that is
-    // unpredictable to processor's prefetchers
-    uint32_t rnd = 0;
-    uint32_t free_idx = 0;
-    do {
-      free(ptrs[free_idx]);
-      rnd = rnd * rnd_a + rnd_c;
-      free_idx = rnd & (param - 1);
-    } while (free_idx != 0);
-  }
-}
-
-static void *randomize_buffer[13<<20];
-
-
-void randomize_one_size_class(size_t size) {
-  int count = (100<<20) / size;
-  if (count * sizeof(randomize_buffer[0]) > sizeof(randomize_buffer)) {
-    abort();
-  }
-  for (int i = 0; i < count; i++) {
-    randomize_buffer[i] = malloc(size);
-  }
-  std::random_shuffle(randomize_buffer, randomize_buffer + count);
-  for (int i = 0; i < count; i++) {
-    free(randomize_buffer[i]);
-  }
-}
-
-void randomize_size_classes() {
-  randomize_one_size_class(8);
-  int i;
-  for (i = 16; i < 256; i += 16) {
-    randomize_one_size_class(i);
-  }
-  for (; i < 512; i += 32) {
-    randomize_one_size_class(i);
-  }
-  for (; i < 1024; i += 64) {
-    randomize_one_size_class(i);
-  }
-  for (; i < (4 << 10); i += 128) {
-    randomize_one_size_class(i);
-  }
-  for (; i < (32 << 10); i += 1024) {
-    randomize_one_size_class(i);
-  }
-}
-
-int main(void)
-{
-  randomize_size_classes();
-
-  report_benchmark("bench_fastpath_throughput", bench_fastpath_throughput, 0);
-  report_benchmark("bench_fastpath_dependent", bench_fastpath_dependent, 0);
-  report_benchmark("bench_fastpath_simple", bench_fastpath_simple, 64);
-  report_benchmark("bench_fastpath_simple", bench_fastpath_simple, 2048);
-  report_benchmark("bench_fastpath_simple", bench_fastpath_simple, 16384);
-
-#ifdef HAVE_SIZED_FREE_OPTION
-  if (is_sized_free_available()) {
-    report_benchmark("bench_fastpath_simple_sized", bench_fastpath_simple_sized, 64);
-    report_benchmark("bench_fastpath_simple_sized", bench_fastpath_simple_sized, 2048);
-  }
-
-  if (is_memalign_available()) {
-    report_benchmark("bench_fastpath_memalign", bench_fastpath_memalign, 64);
-    report_benchmark("bench_fastpath_memalign", bench_fastpath_memalign, 2048);
-  }
-
-#endif
-
-  for (int i = 8; i <= 512; i <<= 1) {
-    report_benchmark("bench_fastpath_stack", bench_fastpath_stack, i);
-  }
-  report_benchmark("bench_fastpath_stack_simple", bench_fastpath_stack_simple, 32);
-  report_benchmark("bench_fastpath_stack_simple", bench_fastpath_stack_simple, 8192);
-  report_benchmark("bench_fastpath_rnd_dependent", bench_fastpath_rnd_dependent, 32);
-  report_benchmark("bench_fastpath_rnd_dependent", bench_fastpath_rnd_dependent, 8192);
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/benchmark/run_benchmark.c b/third_party/tcmalloc/vendor/benchmark/run_benchmark.c
deleted file mode 100644
index 9bf04f4..0000000
--- a/third_party/tcmalloc/vendor/benchmark/run_benchmark.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "run_benchmark.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-
-struct internal_bench {
-  bench_body body;
-  uintptr_t param;
-};
-
-static void run_body(struct internal_bench *b, long iterations)
-{
-  b->body(iterations, b->param);
-}
-
-static double measure_once(struct internal_bench *b, long iterations)
-{
-  struct timeval tv_before, tv_after;
-  int rv;
-  double time;
-
-  rv = gettimeofday(&tv_before, NULL);
-  if (rv) {
-    perror("gettimeofday");
-    abort();
-  }
-
-  run_body(b, iterations);
-
-  rv = gettimeofday(&tv_after, NULL);
-  if (rv) {
-    perror("gettimeofday");
-    abort();
-  }
-  tv_after.tv_sec -= tv_before.tv_sec;
-  time = tv_after.tv_sec * 1E6 + tv_after.tv_usec;
-  time -= tv_before.tv_usec;
-  time *= 1000;
-  return time;
-}
-
-#define TRIAL_NSEC 0.3E9
-#define TARGET_NSEC 3E9
-
-static double run_benchmark(struct internal_bench *b)
-{
-  long iterations = 128;
-  double nsec;
-  while (1) {
-    nsec = measure_once(b, iterations);
-    if (nsec > TRIAL_NSEC) {
-      break;
-    }
-    iterations <<= 1;
-  }
-  while (nsec < TARGET_NSEC) {
-    iterations = (long)(iterations * TARGET_NSEC * 1.1 / nsec);
-    nsec = measure_once(b, iterations);
-  }
-  return nsec / iterations;
-}
-
-void report_benchmark(const char *name, bench_body body, uintptr_t param)
-{
-  int i;
-  struct internal_bench b = {.body = body, .param = param};
-  for (i = 0; i < 3; i++) {
-    double nsec = run_benchmark(&b);
-    int slen;
-    int padding_size;
-
-    slen = printf("Benchmark: %s", name);
-    if (param && name[strlen(name)-1] != ')') {
-      slen += printf("(%lld)", (long long)param);
-    }
-    padding_size = 60 - slen;
-    if (padding_size < 1) {
-      padding_size = 1;
-    }
-    printf("%*c%f nsec\n", padding_size, ' ', nsec);
-    fflush(stdout);
-  }
-}
diff --git a/third_party/tcmalloc/vendor/benchmark/run_benchmark.h b/third_party/tcmalloc/vendor/benchmark/run_benchmark.h
deleted file mode 100644
index e030d1e..0000000
--- a/third_party/tcmalloc/vendor/benchmark/run_benchmark.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef _RUN_BENCHMARK_H_
-#define _RUN_BENCHMARK_H_
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void (*bench_body)(long iterations, uintptr_t param);
-
-void report_benchmark(const char *name, bench_body body, uintptr_t param);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // _RUN_BENCHMARK_H_
diff --git a/third_party/tcmalloc/vendor/benchmark/unwind_bench.cc b/third_party/tcmalloc/vendor/benchmark/unwind_bench.cc
deleted file mode 100644
index 9c4e2f80..0000000
--- a/third_party/tcmalloc/vendor/benchmark/unwind_bench.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-#include "config.h"
-
-#include "base/basictypes.h"
-#include "gperftools/stacktrace.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/ucontext.h>
-#if HAVE_LIBUNWIND_H
-#include <libunwind.h>
-#endif
-
-#include "run_benchmark.h"
-
-extern "C" void getcontext_light(ucontext_t *ctx);
-
-#define MAX_FRAMES 1024
-static void *frames[MAX_FRAMES];
-
-enum measure_mode {
-  MODE_NOOP,
-  MODE_WITH_CONTEXT,
-  MODE_WITHOUT_CONTEXT
-};
-
-static int ATTRIBUTE_NOINLINE measure_unwind(int maxlevel, int mode) {
-  int n;
-
-  if (mode == MODE_NOOP)
-    return 0;
-
-  if (mode == MODE_WITH_CONTEXT) {
-    ucontext_t uc;
-    getcontext_light(&uc);
-    n = GetStackTraceWithContext(frames, MAX_FRAMES, 0, &uc);
-  } else {
-    n = GetStackTrace(frames, MAX_FRAMES, 0);
-  }
-  if (n < maxlevel) {
-    fprintf(stderr, "Expected at least %d frames, got %d\n", maxlevel, n);
-    abort();
-  }
-  return 0;
-}
-
-static int ATTRIBUTE_NOINLINE frame_forcer(int rv) {
-  return rv;
-}
-
-static int ATTRIBUTE_NOINLINE f1(int level, int maxlevel, int mode) {
-  if (level == maxlevel)
-    return frame_forcer(measure_unwind(maxlevel, mode));
-  return frame_forcer(f1(level + 1, maxlevel, mode));
-}
-
-static void bench_unwind_no_op(long iterations, uintptr_t param) {
-  do {
-    f1(0, param, MODE_NOOP);
-    iterations -= param;
-  } while (iterations > 0);
-}
-
-static void bench_unwind_context(long iterations, uintptr_t param) {
-  do {
-    f1(0, param, MODE_WITH_CONTEXT);
-    iterations -= param;
-  } while (iterations > 0);
-}
-
-static void bench_unwind_no_context(long iterations, uintptr_t param) {
-  do {
-    f1(0, param, MODE_WITHOUT_CONTEXT);
-    iterations -= param;
-  } while (iterations > 0);
-}
-
-int main(void) {
-  report_benchmark("unwind_no_op", bench_unwind_no_op, 100);
-  report_benchmark("unwind_context", bench_unwind_context, 100);
-  report_benchmark("unwind_no_context", bench_unwind_no_context, 100);
-
-//// TODO: somehow this fails at linking step. Figure out why this is missing
-// #if HAVE_LIBUNWIND_H
-//   unw_set_caching_policy(unw_local_addr_space, UNW_CACHE_PER_THREAD);
-// #endif
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/configure.ac b/third_party/tcmalloc/vendor/configure.ac
deleted file mode 100644
index 497103ec..0000000
--- a/third_party/tcmalloc/vendor/configure.ac
+++ /dev/null
@@ -1,666 +0,0 @@
-## Process this file with autoconf to produce configure.
-## In general, the safest way to proceed is to run ./autogen.sh
-
-# make sure we're interpreted by some minimal autoconf
-AC_PREREQ([2.59])
-
-AC_INIT([gperftools],[2.7],[gperftools@googlegroups.com])
-# Update this value for every release!  (A:B:C will map to foo.so.(A-C).C.B)
-# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-TCMALLOC_SO_VERSION=9:3:5
-PROFILER_SO_VERSION=4:18:4
-
-AC_SUBST(TCMALLOC_SO_VERSION)
-AC_SUBST(PROFILER_SO_VERSION)
-
-# The argument here is just something that should be in the current directory
-# (for sanity checking)
-AC_CONFIG_SRCDIR(README)
-AC_CONFIG_MACRO_DIR([m4])
-AC_CANONICAL_HOST
-AM_INIT_AUTOMAKE([dist-zip])
-AC_CONFIG_HEADERS([src/config.h])
-
-AM_MAINTAINER_MODE()
-# Export the version information (for tc_version and friends)
-TC_VERSION_MAJOR=`expr "$PACKAGE_VERSION" : '\([[0-9]]*\)'`
-TC_VERSION_MINOR=`expr "$PACKAGE_VERSION" : '[[0-9]]*\.\([[0-9]]*\)'`
-TC_VERSION_PATCH=`expr "$PACKAGE_VERSION" : '[[0-9]]*\.[[0-9]]*\(.*\)$'`
-AC_SUBST(TC_VERSION_MAJOR)
-AC_SUBST(TC_VERSION_MINOR)
-AC_SUBST(TC_VERSION_PATCH)
-AC_SUBST(PACKAGE_STRING)
-
-AX_GENERATE_CHANGELOG
-
-# The user can choose not to compile in the heap-profiler, the
-# heap-checker, or the cpu-profiler.  There's also the possibility
-# for a 'fully minimal' compile, which leaves out the stacktrace
-# code as well.  By default, we include all of these that the
-# target system supports.
-default_enable_cpu_profiler=yes
-default_enable_heap_profiler=yes
-default_enable_heap_checker=yes
-default_enable_debugalloc=yes
-default_enable_minimal=no
-default_tcmalloc_alignment=16
-need_nanosleep=yes   # Used later, to decide if to run ACX_NANOSLEEP
-case "$host" in
-   *-mingw*) default_enable_minimal=yes; default_enable_debugalloc=no;
-             need_nanosleep=no;;
-   *-cygwin*) default_enable_heap_checker=no; default_enable_cpu_profiler=no;;
-   *-freebsd*) default_enable_heap_checker=no;;
-   *-darwin*) default_enable_heap_checker=no;;
-esac
-
-# Currently only backtrace works on s390.
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __s390__])],
-                  [default_enable_libunwind=no
-                   default_enable_backtrace=yes],
-                  [default_enable_libunwind=yes
-                   default_enable_backtrace=no])
-
-# Disable libunwind linking on ppc64 by default.
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __PPC64__])],
-                  [default_enable_libunwind=no
-                   default_tcmalloc_pagesize=64],
-                  [default_enable_libunwind=yes
-                   default_tcmalloc_pagesize=8])
-
-AC_ARG_ENABLE([cpu-profiler],
-              [AS_HELP_STRING([--disable-cpu-profiler],
-                              [do not build the cpu profiler])],
-              [],
-              [enable_cpu_profiler="$default_enable_cpu_profiler"])
-AC_ARG_ENABLE([heap-profiler],
-              [AS_HELP_STRING([--disable-heap-profiler],
-                              [do not build the heap profiler])],
-              [],
-              [enable_heap_profiler="$default_enable_heap_profiler"])
-AC_ARG_ENABLE([heap-checker],
-              [AS_HELP_STRING([--disable-heap-checker],
-                              [do not build the heap checker])],
-              [],
-              [enable_heap_checker="$default_enable_heap_checker"])
-AC_ARG_ENABLE([debugalloc],
-              [AS_HELP_STRING([--disable-debugalloc],
-                              [do not build versions of libs with debugalloc])],
-              [],
-              [enable_debugalloc="$default_enable_debugalloc"])
-AC_ARG_ENABLE([minimal],
-              [AS_HELP_STRING([--enable-minimal],
-                              [build only tcmalloc-minimal (and maybe tcmalloc-minimal-debug)])],
-              [],
-              [enable_minimal="$default_enable_minimal"])
-if test "$enable_minimal" = yes; then
-  enable_cpu_profiler=no
-  enable_heap_profiler=no
-  enable_heap_checker=no
-fi
-AC_ARG_ENABLE([stacktrace-via-backtrace],
-              [AS_HELP_STRING([--enable-stacktrace-via-backtrace],
-                              [enable use of backtrace() for stacktrace capturing (may deadlock)])],
-              [enable_backtrace=yes],
-              [enable_backtrace="$default_enable_backtrace"])
-AC_ARG_ENABLE([libunwind],
-              [AS_HELP_STRING([--enable-libunwind],
-                              [enable libunwind linking])],
-              [],
-              [enable_libunwind="$default_enable_libunwind"])
-AC_ARG_WITH([tcmalloc-pagesize],
-            [AS_HELP_STRING([--with-tcmalloc-pagesize],
-                            [Set the tcmalloc internal page size to 8K, 32K or 64K])],
-            [],
-            [with_tcmalloc_pagesize=$default_tcmalloc_pagesize])
-AC_ARG_WITH([tcmalloc-alignment],
-            [AS_HELP_STRING([--with-tcmalloc-alignment],
-                            [Set the tcmalloc allocation alignment to 8 or 16 bytes])],
-            [],
-            [with_tcmalloc_alignment=$default_tcmalloc_alignment])
-
-case "$with_tcmalloc_pagesize" in
-  8)
-       #Default tcmalloc page size.
-       ;;
-  32)
-       AC_DEFINE(TCMALLOC_32K_PAGES, 1,
-                 [Define 32K of internal pages size for tcmalloc]);;
-  64)
-       AC_DEFINE(TCMALLOC_64K_PAGES, 1,
-                 [Define 64K of internal pages size for tcmalloc]);;
-  *)
-       AC_MSG_WARN([${with_tcmalloc_pagesize}K size not supported, using default tcmalloc page size.])
-esac
-case "$with_tcmalloc_alignment" in
-  8)
-       AC_DEFINE(TCMALLOC_ALIGN_8BYTES, 1,
-                 [Define 8 bytes of allocation alignment for tcmalloc]);;
-  16)
-       #Default tcmalloc allocation alignment.
-       ;;
-  *)
-       AC_MSG_WARN([${with_tcmalloc_alignment} bytes not supported, using default tcmalloc allocation alignment.])
-esac
-
-# Checks for programs.
-AC_PROG_CXX
-AC_PROG_CC
-AC_PROG_CPP
-AM_CONDITIONAL(GCC, test "$GCC" = yes)   # let the Makefile know if we're gcc
-AM_PROG_CC_C_O      # shrug: autogen.sh suddenly needs this for some reason
-
-# Check if we have an objcopy installed that supports -W
-AC_CHECK_TOOL([OBJCOPY], [objcopy], [])
-AS_IF([test -n "$OBJCOPY"], [dnl
-  AC_CACHE_CHECK([if $OBJCOPY supports -W], gpt_cv_objcopy_weaken, [dnl
-    AC_LINK_IFELSE([AC_LANG_PROGRAM([void foo() {} int main() {return 0;}])], [dnl
-      AS_IF(["$OBJCOPY" -W foo conftest$ac_exeext /dev/null],
-      	    [gpt_cv_objcopy_weaken=yes], [gpt_cv_objcopy_weaken=no])],
-    [gpt_cv_objcopy_weaken=no])])],
-  [gpt_cv_objcopy_weaken=no])
-AM_CONDITIONAL(HAVE_OBJCOPY_WEAKEN, test $gpt_cv_objcopy_weaken = yes)
-
-AC_PROG_LIBTOOL
-
-AC_C_INLINE
-AX_C___ATTRIBUTE__
-
-AC_MSG_CHECKING(for __attribute__((aligned(N))) on functions)
-AC_CACHE_VAL(ac_cv___attribute__aligned_fn, [
-  AC_TRY_COMPILE(
-    [#include <stdlib.h>
-     void foo(void) __attribute__((aligned(128)));
-     void foo(void) { exit(1); }],
-    [],
-    ac_cv___attribute__aligned_fn=yes,
-    ac_cv___attribute__aligned_fn=no
-  )])
-if test "$ac_cv___attribute__aligned_fn" = "yes"; then
-  AC_DEFINE(HAVE___ATTRIBUTE__ALIGNED_FN, 1, [define if your compiler supports alignment of functions])
-fi
-AC_MSG_RESULT($ac_cv___attribute__aligned_fn)
-
-
-# Check whether some low-level functions/files are available
-AC_HEADER_STDC
-
-# TODO(csilvers): we could remove a lot when WITH_CPU_PROFILER etc is "no".
-AC_CHECK_TYPES([__int64])       # defined in some windows platforms
-AC_CHECK_TYPES([struct mallinfo],,, [#include <malloc.h>])
-AC_CHECK_TYPES([Elf32_Versym],,, [#include <elf.h>])   # for vdso_support.h
-AC_CHECK_FUNCS(sbrk)            # for tcmalloc to get memory
-AC_CHECK_FUNCS(geteuid)         # for turning off services when run as root
-AC_CHECK_FUNCS(fork)            # for the pthread_atfork setup
-AC_CHECK_HEADERS(features.h)    # for vdso_support.h
-AC_CHECK_HEADERS(malloc.h)      # some systems define stuff there, others not
-AC_CHECK_HEADERS(glob.h)        # for heap-profile-table (cleaning up profiles)
-AC_CHECK_HEADERS(execinfo.h)    # for stacktrace? and heapchecker_unittest
-AC_CHECK_HEADERS(unwind.h)      # for stacktrace
-AC_CHECK_HEADERS(sched.h)       # for being nice in our spinlock code
-AC_CHECK_HEADERS(conflict-signal.h)      # defined on some windows platforms?
-AC_CHECK_HEADERS(sys/prctl.h)   # for thread_lister (needed by leak-checker)
-AC_CHECK_HEADERS(linux/ptrace.h)# also needed by leak-checker
-AC_CHECK_HEADERS(sys/syscall.h)
-AC_CHECK_HEADERS(sys/socket.h)  # optional; for forking out to symbolizer
-AC_CHECK_HEADERS(sys/wait.h)    # optional; for forking out to symbolizer
-AC_CHECK_HEADERS(poll.h)        # optional; for forking out to symbolizer
-AC_CHECK_HEADERS(fcntl.h)       # for tcmalloc_unittest
-AC_CHECK_HEADERS(grp.h)         # for heapchecker_unittest
-AC_CHECK_HEADERS(pwd.h)         # for heapchecker_unittest
-AC_CHECK_HEADERS(sys/resource.h)         # for memalign_unittest.cc
-AC_CHECK_HEADERS(valgrind.h)    # we have a local copy if this isn't found
-AC_CHECK_HEADERS(sys/cdefs.h)   # Where glibc defines __THROW
-AC_CHECK_HEADERS(features.h)    # Where __GLIBC__ is defined
-# We also need <ucontext.h>/<sys/ucontext.h>, but we get those from
-# AC_PC_FROM_UCONTEXT, below.
-
-# We override a lot of memory allocation routines, not all of which are
-# standard.  For those the system doesn't declare, we'll declare ourselves.
-AC_CHECK_DECLS([cfree,
-                posix_memalign,
-                memalign,
-                valloc,
-                pvalloc],,,
-               [#define _XOPEN_SOURCE 600
-                #include <stdlib.h>
-                #include <malloc.h>])
-
-if test "$ac_cv_type_struct_mallinfo" = yes; then
-  AC_SUBST(ac_cv_have_struct_mallinfo, 1)   # gperftools/tcmalloc.h needs this
-else
-  AC_SUBST(ac_cv_have_struct_mallinfo, 0)
-fi
-
-# We need to check for mmap.  cygwin supports mmap, but the autoconf
-# test doesn't work on cygwin:
-#    http://www.cygwin.com/ml/cygwin/2002-04/msg00412.html
-# This workaround comes from
-#    http://cygwin.com/ml/cygwin/2004-11/msg00138.html
-case "$host" in
-  *-*-mingw*)
-               dnl mingw doesn't have mmap, not worth
-               dnl checking. Especially given that mingw can be a
-               dnl cross-compiler
-               ;;
-  *-*-cygwin*)
-	       ac_cv_func_mmap_fixed_mapped=yes
-               AC_DEFINE(HAVE_MMAP, 1,
-                         [Define to 1 if you have a working `mmap' system call.])
-               ;;
-            *) if test "$cross_compiling" = yes; then
-                 ac_cv_func_mmap_fixed_mapped=yes
-                 AC_DEFINE(HAVE_MMAP, 1,
-                           [Define to 1 if you have a working `mmap' system call.])
-               else
-                 AC_FUNC_MMAP
-               fi
-               ;;
-esac
-
-# If AtomicWord != Atomic32, we need to define two versions of all the
-# atomicops functions.  If they're the same, we want to define only one.
-AC_MSG_CHECKING([if int32_t is the same type as intptr_t])
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdint.h>]], [[int32_t v1 = 0; intptr_t v2 = 0; return (&v1 - &v2)]])],[AC_DEFINE(INT32_EQUALS_INTPTR, 1,
-                          Define to 1 if int32_t is equivalent to intptr_t)
-                AC_MSG_RESULT([yes])],[AC_MSG_RESULT([no])])
-
-# We want to access the "PC" (Program Counter) register from a struct
-# ucontext.  Every system has its own way of doing that.  We try all the
-# possibilities we know about.  Note REG_PC should come first (REG_RIP
-# is also defined on solaris, but does the wrong thing).  But don't
-# bother if we're not doing cpu-profiling.
-# [*] means that we've not actually tested one of these systems
-if test "$enable_cpu_profiler" = yes; then
-  AC_PC_FROM_UCONTEXT(AC_MSG_WARN(Could not find the PC.  Will not try to compile libprofiler...);
-                      enable_cpu_profiler=no)
-fi
-
-# Some tests test the behavior of .so files, and only make sense for dynamic.
-AM_CONDITIONAL(ENABLE_STATIC, test "$enable_static" = yes)
-
-# We want to link in libunwind if it is enabled and exists.
-UNWIND_LIBS=
-if test "$enable_libunwind" = yes; then
-  AC_CHECK_HEADERS([libunwind.h],
-                   [AC_CHECK_LIB(unwind, backtrace, UNWIND_LIBS=-lunwind)
-                    will_use_libunwind=yes])
-fi
-AC_SUBST(UNWIND_LIBS)
-
-# On x86_64, instead of libunwind, we can choose to compile with frame-pointers.
-AC_ARG_ENABLE(frame_pointers,
-              AS_HELP_STRING([--enable-frame-pointers],
-                             [On x86_64 systems, compile with -fno-omit-frame-pointer (see INSTALL)]),
-	      , enable_frame_pointers=no)
-AM_CONDITIONAL(ENABLE_FRAME_POINTERS, test "$enable_frame_pointers" = yes)
-
-AC_MSG_CHECKING([for x86 without frame pointers])
-# Some x86_64 systems do not insert frame pointers by default.
-# We want to see if the current system is one of those.
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __x86_64__ == 1 ? 0 : 1])],
-                  [is_x86_64=yes], [is_x86_64=no])
-OLD_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -S -O2 -o fp.s"
-# This test will always fail because we don't name our output file properly.
-# We do our own determination of success/failure in the grep, below.
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int f(int x) {return x;}], [return f(0);])],
-                  [:], [:])
-x86_no_fp_by_default=no
-AS_IF([test "$is_x86_64" = yes && ! grep 'mov.*rsp.*rbp' fp.s >/dev/null 2>&1], [x86_no_fp_by_default=yes])
-AM_CONDITIONAL(X86_64_AND_NO_FP_BY_DEFAULT,
-               test "$x86_no_fp_by_default" = yes)
-rm fp.s
-CFLAGS="$OLD_CFLAGS"
-AC_MSG_RESULT([$x86_no_fp_by_default])
-
-
-# We need to know if we're i386 so we can turn on -mmms, which is not
-# on by default for i386 (it is for x86_64).
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __i386__ == 1 ? 0 : 1])],
-                  [is_i386=yes], [is_i386=no])
-AM_CONDITIONAL(I386, test "$is_i386" = yes)
-
-# See if the compiler supports -Wno-unused-result.
-# Newer ubuntu's turn on -D_FORTIFY_SOURCE=2, enabling
-# __attribute__((warn_unused_result)) for things like write(),
-# which we don't care about.
-AC_CACHE_CHECK([if the compiler supports -Wno-unused-result],
-               perftools_cv_w_no_unused_result,
-	       [OLD_CFLAGS="$CFLAGS"
-	        CFLAGS="$CFLAGS -Wno-error -Wunused-result"
-		# gcc doesn't warn about unknown flags unless it's
-		# also warning for some other purpose, hence the
-		# divide-by-0.  (We use -Wno-error to make sure the
-		# divide-by-0 doesn't cause this test to fail!)
-                #
-                # Also gcc is giving only warning for unknown flags of
-                # -Wno-XXX form. So in order to detect support we're
-                # using -Wunused-result which will cause gcc to give
-                # error which we can detect.
-	        AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, return 1/0)],
-	                          perftools_cv_w_no_unused_result=yes,
-                                  perftools_cv_w_no_unused_result=no)
-	        CFLAGS="$OLD_CFLAGS"])
-AM_CONDITIONAL(HAVE_W_NO_UNUSED_RESULT,
-	       test "$perftools_cv_w_no_unused_result" = yes)
-
-AC_ARG_ENABLE([dynamic-sized-delete-support],
-              [AS_HELP_STRING([--enable-dynamic-sized-delete-support],
-                [try to build run-time switch for sized delete operator])],
-              [enable_dyn_sized_delete="$enableval"],
-              [enable_dyn_sized_delete=no])
-
-AS_IF([test "x$enable_dyn_sized_delete" = xyes],
-      [AC_DEFINE([ENABLE_DYNAMIC_SIZED_DELETE], 1,
-                 [Build runtime detection for sized delete])])
-
-AC_ARG_ENABLE([sized-delete],
-              [AS_HELP_STRING([--enable-sized-delete],
-                              [build sized delete operator])],
-              [enable_sized_delete="$enableval"],
-              [enable_sized_delete="no"])
-AS_IF([test "x$enable_sized_delete" = xyes],
-        [AC_DEFINE([ENABLE_SIZED_DELETE], 1, [Build sized deletion operators])
-         AC_MSG_NOTICE([Will build sized deallocation operators])],
-      [AS_IF([test "x$enable_dyn_sized_delete" = xyes],
-             [AC_MSG_NOTICE([Will build dynamically detected sized deallocation operators])],
-             [AC_MSG_NOTICE([Will build sized deallocation operators that ignore size])])])
-
-AC_CACHE_CHECK([if C++ compiler supports -fsized-deallocation],
-               [perftools_cv_sized_deallocation_result],
-               [AC_LANG_PUSH(C++)
-                OLD_CXXFLAGS="$CXXFLAGS"
-                CXXFLAGS="$CXXFLAGS -fsized-deallocation"
-                AC_LINK_IFELSE([AC_LANG_PROGRAM(
-                    [[#include <new>
-#include <stddef.h>]],
-                    [[static void (* volatile ptr)(void *, size_t) = ::operator delete; (*ptr)(0, 256);]])],
-                 perftools_cv_sized_deallocation_result=yes,
-                 perftools_cv_sized_deallocation_result=no)
-                CXXFLAGS="$OLD_CXXFLAGS"
-                AC_LANG_POP(C++)])
-
-AM_CONDITIONAL(HAVE_SIZED_DEALLOCATION,
-               test "$perftools_cv_sized_deallocation_result" = yes)
-
-AC_CACHE_CHECK([if C++ compiler supports std::align_val_t without options],
-               [perftools_cv_have_align_val_t],
-               [AC_LANG_PUSH(C++)
-                AC_LINK_IFELSE([AC_LANG_PROGRAM(
-                    [[#include <new>]],
-                    [[(::operator delete)((::operator new)(256, std::align_val_t(16)), std::align_val_t(16))]])],
-                 perftools_cv_have_align_val_t=yes,
-                 perftools_cv_have_align_val_t=no)
-                AC_LANG_POP(C++)])
-
-AC_CACHE_CHECK([if C++ compiler supports -faligned-new],
-               [perftools_cv_have_f_aligned_new],
-               [AC_LANG_PUSH(C++)
-                OLD_CXXFLAGS="$CXXFLAGS"
-                CXXFLAGS="$CXXFLAGS -faligned-new"
-                AC_LINK_IFELSE([AC_LANG_PROGRAM(
-                    [[#include <new>]],
-                    [[(::operator delete)((::operator new)(256, std::align_val_t(16)), std::align_val_t(16))]])],
-                 perftools_cv_have_f_aligned_new=yes,
-                 perftools_cv_have_f_aligned_new=no)
-                CXXFLAGS="$OLD_CXXFLAGS"
-                AC_LANG_POP(C++)])
-
-AM_CONDITIONAL(HAVE_F_ALIGNED_NEW,
-               test "$perftools_cv_have_f_aligned_new" = yes)
-
-AS_IF([test "$perftools_cv_have_align_val_t" = yes || test "$perftools_cv_have_f_aligned_new" = yes],
-        [AC_DEFINE([ENABLE_ALIGNED_NEW_DELETE], 1, [Build new/delete operators for overaligned types])
-         AC_MSG_NOTICE([Will build new/delete operators for overaligned types])],
-         AC_MSG_NOTICE([Will not build new/delete operators for overaligned types]))
-
-if test "$perftools_cv_have_align_val_t" = yes || test "$perftools_cv_have_f_aligned_new" = yes; then
-  AC_SUBST(ac_cv_have_std_align_val_t, 1)   # gperftools/tcmalloc.h and windows/gperftools/tcmalloc.h need this
-else
-  AC_SUBST(ac_cv_have_std_align_val_t, 0)
-fi
-
-
-AC_CACHE_CHECK([if target has _Unwind_Backtrace],
-               [perftools_cv_have_unwind_backtrace],
-               [AC_LANG_PUSH(C++)
-                AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-                    [[#include <unwind.h>]],
-                    [[&_Unwind_Backtrace]])],
-                 [perftools_cv_have_unwind_backtrace=yes],
-                 [perftools_cv_have_unwind_backtrace=no])
-                AC_LANG_POP(C++)])
-AS_IF([test "x$perftools_cv_have_unwind_backtrace" = xyes],
-      [AC_DEFINE(HAVE_UNWIND_BACKTRACE, 1, [Whether <unwind.h> contains _Unwind_Backtrace])])
-
-AS_IF([test "x$enable_backtrace" = xyes],
-      [default_emergency_malloc=yes],
-      [default_emergency_malloc=no])
-
-AS_IF([test "x$will_use_libunwind" = xyes],
-      [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __arm__])],
-                         [default_emergency_malloc=yes])])
-
-AC_ARG_ENABLE([emergency-malloc],
-              [AS_HELP_STRING([--enable-emergency-malloc],
-                              [build emergency malloc feature])],
-              [enable_emergency_malloc="$enableval"],
-              [enable_emergency_malloc="$default_emergency_malloc"])
-
-AM_CONDITIONAL(BUILD_EMERGENCY_MALLOC, [test "x$enable_emergency_malloc" = xyes])
-
-# Defines PRIuS
-AC_COMPILER_CHARACTERISTICS
-
-# Also make sure we get standard PRI... definitions, even with glibc.
-# We have to use AH_VERBATIM because we need the #ifdef guard (gcc buglet)
-AH_VERBATIM([__STDC_FORMAT_MACROS],
-            [/* C99 says: define this to get the PRI... macros from stdint.h */
-#ifndef __STDC_FORMAT_MACROS
-# define __STDC_FORMAT_MACROS 1
-#endif])
-
-# Check if __builtin_stack_pointer() is available (for elfcore.h)
-AC_MSG_CHECKING([for __builtin_stack_pointer()])
-AC_LINK_IFELSE([AC_LANG_PROGRAM(, [void *sp = __builtin_stack_pointer()])],
-               [AC_DEFINE(HAVE_BUILTIN_STACK_POINTER, 1,
-                      Define to 1 if compiler supports __builtin_stack_pointer)
-                AC_MSG_RESULT([yes])],
-               [AC_MSG_RESULT([no])])
-
-# Check for __builtin_expect()
-AC_MSG_CHECKING([for __builtin_expect()])
-AC_LINK_IFELSE([AC_LANG_PROGRAM(, return __builtin_expect(main != 0, 1))],
-               [AC_DEFINE(HAVE_BUILTIN_EXPECT, 1,
-                          Define to 1 if compiler supports __builtin_expect)
-                AC_MSG_RESULT([yes])],
-               [AC_MSG_RESULT([no])])
-
-# Check if __environ is available (for GetenvBeforeMain)
-AC_MSG_CHECKING([for __environ])
-AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <unistd.h>],
-                                [char **env = __environ])],
-               [AC_DEFINE(HAVE___ENVIRON, 1,
-                          [Define to 1 if compiler supports __environ])
-                AC_MSG_RESULT([yes])],
-               [AC_MSG_RESULT([no])])
-
-# If we support __thread, that can speed up tcmalloc a bit.
-# Note, however, that our code tickles a bug in gcc < 4.1.2
-# involving TLS and -fPIC (which our libraries will use) on x86:
-#   http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html
-#
-# And mingw also does compile __thread but resultant code actually
-# fails to work correctly at least in some not so ancient version:
-# http://mingw-users.1079350.n2.nabble.com/gcc-4-4-multi-threaded-exception-handling-amp-thread-specifier-not-working-td3440749.html
-#
-# Also it was reported that earlier gcc versions for mips compile
-# __thread but it doesn't really work
-AC_MSG_CHECKING([for __thread])
-AC_LINK_IFELSE([AC_LANG_PROGRAM([#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ < 2))
-#error gcc has this bug: http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html
-#elif defined(__MINGW32__)
-#error mingw doesnt really support tls
-#elif defined(__APPLE__)
-#error OSX __thread support is known to call malloc which makes it unsafe to use from malloc replacement
-#endif
-], [static __thread int p = 0])],
-               [AC_DEFINE(HAVE_TLS, 1,
-                          Define to 1 if compiler supports __thread)
-                AC_MSG_RESULT([yes])],
-               [AC_MSG_RESULT([no])])
-
-# Nanosleep requires extra libraries on some architectures (solaris).
-# This sets NANOSLEEP_LIBS.  nanosleep doesn't exist on mingw, which
-# is fine for us because we don't compile libspinlock, which uses it.
-if test "$need_nanosleep" = yes; then
-  ACX_NANOSLEEP
-  AC_SUBST(NANOSLEEP_LIBS)
-fi
-
-# Solaris 10 6/06 has a bug where /usr/sfw/lib/libstdc++.la is empty.
-# If so, we replace it with our own version.
-LIBSTDCXX_LA_LINKER_FLAG=
-if test -f /usr/sfw/lib/libstdc++.la && ! test -s /usr/sfw/lib/libstdc++.la
-then
-  LIBSTDCXX_LA_LINKER_FLAG='-L$(top_srcdir)/src/solaris'
-fi
-AC_SUBST(LIBSTDCXX_LA_LINKER_FLAG)
-
-# We also need to check if the kernel supports __thread, which requires uname()
-AC_CHECK_DECLS(uname,,, [#include <sys/utsname.h>])
-
-# In fact, a lot of the code in this directory depends on pthreads
-ACX_PTHREAD
-
-AC_LANG_SAVE
-AC_LANG_CPLUSPLUS
-AC_MSG_CHECKING([whether pthread symbols are available in C++ without including pthread.h])
-acx_pthread_despite_asking_for=no
-AC_LINK_IFELSE(
-  [AC_LANG_PROGRAM([
-      #include <string>
-      #include <vector>
-  ],[
-      pthread_t th; pthread_join(th, 0);
-  ])],[
-    acx_pthread_despite_asking_for=yes
-    AC_DEFINE(HAVE_PTHREAD_DESPITE_ASKING_FOR, 1, [defined to 1 if pthread symbols are exposed even without include pthread.h])
-    AC_DEFINE(HAVE_PTHREAD, 1, [])
-  ])
-AC_MSG_RESULT([$acx_pthread_despite_asking_for])
-AC_LANG_RESTORE
-
-AM_CONDITIONAL(HAVE_PTHREAD_DESPITE_ASKING_FOR, test x"$acx_pthread_despite_asking_for" = xyes)
-
-# Find out what namespace 'normal' STL code lives in
-AC_CXX_STL_NAMESPACE
-
-# Figure out where libc has program_invocation_name
-AC_PROGRAM_INVOCATION_NAME
-
-# Make the install prefix available, to figure out where to look for pprof
-AC_INSTALL_PREFIX
-
-dnl only very recent mingw has sleep and nanosleep
-case "$host" in
-   *-mingw*)
-     AC_CHECK_DECLS([sleep], [], [], [#include <unistd.h>])
-     AC_CHECK_DECLS([nanosleep], [], [], [#include <time.h>])
-   ;;
-esac
-
-if test "x$enable_backtrace" = xyes; then
-  AC_CHECK_DECLS([backtrace], [], [], [#include <execinfo.h>])
-  save_LIBS=$LIBS
-  LIBS=$UNWIND_LIBS
-  AC_SEARCH_LIBS([backtrace], [execinfo])
-  UNWIND_LIBS=$LIBS
-  LIBS=$save_LIBS
-fi
-
-# For windows, this has a non-trivial value (__declspec(export)), but any
-# system that uses configure wants this to be the empty string.
-AC_DEFINE(PERFTOOLS_DLL_DECL,,
-          [Always the empty-string on non-windows systems.
-           On windows, should be "__declspec(dllexport)".
-	   This way, when we compile the dll, we export our functions/classes.
-	   It's safe to define this here because config.h is only used
-	   internally, to compile the DLL, and every DLL source file
-	   #includes "config.h" before anything else.])
-
-# In theory, config.h files shouldn't need a header guard, but we do,
-# because we (maybe) #include windows/mingw.h from within config.h,
-# and it #includes other .h files.  These all have header guards, so
-# the end result is if config.h is #included twice, its #undefs get
-# evaluated twice, but all the ones in mingw.h/etc only get evaluated
-# once, potentially causing trouble.  c.f.
-#   http://code.google.com/p/gperftools/issues/detail?id=246
-AH_TOP([
-#ifndef GPERFTOOLS_CONFIG_H_
-#define GPERFTOOLS_CONFIG_H_
-])
-
-AH_VERBATIM([PTHREADS_CRASHES_IF_RUN_TOO_EARLY],
-	    [/* Mark the systems where we know it's bad if pthreads runs too
-   early before main (before threads are initialized, presumably).  */
-#ifdef __FreeBSD__
-#define PTHREADS_CRASHES_IF_RUN_TOO_EARLY 1
-#endif])
-
-# MinGW uses autoconf, but also needs the windows shim routines
-# (since it doesn't have its own support for, say, pthreads).
-# This requires us to #include a special header file, and also to
-# link in some windows versions of .o's instead of the unix versions.
-#
-# Also, manually mark systems where we have to be careful how early
-# we run pthreads.  TODO(csilvers): turn this into an autoconf check.
-AH_BOTTOM([
-#ifdef __MINGW32__
-#include "windows/mingw.h"
-#endif
-
-#endif  /* #ifndef GPERFTOOLS_CONFIG_H_ */
-])
-AM_CONDITIONAL(MINGW, expr $host : '.*-mingw' >/dev/null 2>&1)
-AM_CONDITIONAL(OSX, expr $host : '.*-apple-darwin.*' >/dev/null 2>&1)
-
-# Export the --enable flags we set above.  We do this at the end so
-# other configure rules can enable or disable targets based on what
-# they find.
-AM_CONDITIONAL(WITH_CPU_PROFILER, test "$enable_cpu_profiler" = yes)
-AM_CONDITIONAL(WITH_HEAP_PROFILER, test "$enable_heap_profiler" = yes)
-AM_CONDITIONAL(WITH_HEAP_CHECKER, test "$enable_heap_checker" = yes)
-AM_CONDITIONAL(WITH_DEBUGALLOC, test "$enable_debugalloc" = yes)
-# We make tcmalloc.so if either heap-profiler or heap-checker is asked for.
-AM_CONDITIONAL(WITH_HEAP_PROFILER_OR_CHECKER,
-               test "$enable_heap_profiler" = yes -o \
-                    "$enable_heap_checker" = yes)
-# If we don't use any profilers, we don't need stack traces (or pprof)
-AM_CONDITIONAL(WITH_STACK_TRACE, test "$enable_cpu_profiler" = yes -o \
-                                      "$enable_heap_profiler" = yes -o \
-                                      "$enable_heap_checker" = yes)
-
-have_linux_sigev_thread_id=no
-AC_MSG_CHECKING([for Linux SIGEV_THREAD_ID])
-AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM([[#include <signal.h>
-                           #include <time.h>]],
-                         [[return SIGEV_THREAD_ID || CLOCK_THREAD_CPUTIME_ID || __linux;]])],
-        [AC_DEFINE(HAVE_LINUX_SIGEV_THREAD_ID, 1,
-                  [Define if this is Linux that has SIGEV_THREAD_ID])
-         have_linux_sigev_thread_id=yes
-         AC_MSG_RESULT([yes])],
-        [AC_MSG_RESULT([no])])
-
-# Write generated configuration file
-AC_CONFIG_FILES([Makefile
-                 src/gperftools/tcmalloc.h src/windows/gperftools/tcmalloc.h])
-AC_OUTPUT
-
-AS_IF([test "$x86_no_fp_by_default" = yes && test "x$enable_frame_pointers" != xyes && test "x$UNWIND_LIBS" = x && test "x$enable_minimal" != xyes],
-  [AS_IF([test "x$perftools_cv_have_unwind_backtrace" = xyes],
-    [AC_MSG_WARN([No frame pointers and no libunwind. Using experimental backtrace capturing via libgcc. Expect crashy cpu profiler.])],
-    [AS_IF([test "x$enable_backtrace" = xyes],
-      [AC_MSG_WARN([No frame pointers and no libunwind.  Using experimental backtrace(). Expect crashy cpu profiler.])],
-      [AC_MSG_FAILURE([No frame pointers and no libunwind. The compilation will fail])])])])
diff --git a/third_party/tcmalloc/vendor/docs/cpuprofile-fileformat.html b/third_party/tcmalloc/vendor/docs/cpuprofile-fileformat.html
deleted file mode 100644
index 3f90e6bc..0000000
--- a/third_party/tcmalloc/vendor/docs/cpuprofile-fileformat.html
+++ /dev/null
@@ -1,264 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<HTML>
-
-<HEAD>
-  <link rel="stylesheet" href="designstyle.css">
-  <title>Google CPU Profiler Binary Data File Format</title>
-</HEAD>
-
-<BODY>
-
-<h1>Google CPU Profiler Binary Data File Format</h1>
-
-<p align=right>
-  <i>Last modified
-    <script type=text/javascript>
-    var lm = new Date(document.lastModified);
-    document.write(lm.toDateString());
-  </script></i>
-</p>
-
-<p>This file documents the binary data file format produced by the
-Google CPU Profiler.  For information about using the CPU Profiler,
-see <a href="cpuprofile.html">its user guide</a>.
-
-<p>The profiler source code, which generates files using this format, is at
-<code>src/profiler.cc</code></a>.
-
-
-<h2>CPU Profile Data File Structure</h2>
-
-<p>CPU profile data files each consist of four parts, in order:
-
-<ul>
-  <li> Binary header
-  <li> Binary profile records
-  <li> Binary trailer
-  <li> Text list of mapped objects
-</ul>
-
-<p>The binary data is expressed in terms of "slots."  These are words
-large enough to hold the program's pointer type, i.e., for 32-bit
-programs they are 4 bytes in size, and for 64-bit programs they are 8
-bytes.  They are stored in the profile data file in the native byte
-order (i.e., little-endian for x86 and x86_64).
-
-
-<h2>Binary Header</h2>
-
-<p>The binary header format is show below.  Values written by the
-profiler, along with requirements currently enforced by the analysis
-tools, are shown in parentheses.
-
-<p>
-<table summary="Header Format"
-       frame="box" rules="sides" cellpadding="5" width="50%">
-  <tr>
-    <th width="30%">slot</th>
-    <th width="70%">data</th>
-  </tr>
-
-  <tr>
-    <td>0</td>
-    <td>header count (0; must be 0)</td>
-  </tr>
-
-  <tr>
-    <td>1</td>
-    <td>header slots after this one (3; must be &gt;= 3)</td>
-  </tr>
-
-  <tr>
-    <td>2</td>
-    <td>format version (0; must be 0)</td>
-  </tr>
-
-  <tr>
-    <td>3</td>
-    <td>sampling period, in microseconds</td>
-  </tr>
-
-  <tr>
-    <td>4</td>
-    <td>padding (0)</td>
-  </tr>
-</table>
-
-<p>The headers currently generated for 32-bit and 64-bit little-endian
-(x86 and x86_64) profiles are shown below, for comparison.
-
-<p>
-<table summary="Header Example" frame="box" rules="sides" cellpadding="5">
-  <tr>
-    <th></th>
-    <th>hdr count</th>
-    <th>hdr words</th>
-    <th>version</th>
-    <th>sampling period</th>
-    <th>pad</th>
-  </tr>
-  <tr>
-    <td>32-bit or 64-bit (slots)</td>
-    <td>0</td>
-    <td>3</td>
-    <td>0</td>
-    <td>10000</td>
-    <td>0</td>
-  </tr>
-  <tr>
-    <td>32-bit (4-byte words in file)</td>
-    <td><tt>0x00000</tt></td>
-    <td><tt>0x00003</tt></td>
-    <td><tt>0x00000</tt></td>
-    <td><tt>0x02710</tt></td>
-    <td><tt>0x00000</tt></td>
-  </tr>
-  <tr>
-    <td>64-bit LE (4-byte words in file)</td>
-    <td><tt>0x00000&nbsp;0x00000</tt></td>
-    <td><tt>0x00003&nbsp;0x00000</tt></td>
-    <td><tt>0x00000&nbsp;0x00000</tt></td>
-    <td><tt>0x02710&nbsp;0x00000</tt></td>
-    <td><tt>0x00000&nbsp;0x00000</tt></td>
-  </tr>
-</table>
-
-<p>The contents are shown in terms of slots, and in terms of 4-byte
-words in the profile data file.  The slot contents for 32-bit and
-64-bit headers are identical.  For 32-bit profiles, the 4-byte word
-view matches the slot view.  For 64-bit profiles, each (8-byte) slot
-is shown as two 4-byte words, ordered as they would appear in the
-file.
-
-<p>The profiling tools examine the contents of the file and use the
-expected locations and values of the header words field to detect
-whether the file is 32-bit or 64-bit.
-
-
-<h2>Binary Profile Records</h2>
-
-<p>The binary profile record format is shown below.
-
-<p>
-<table summary="Profile Record Format"
-       frame="box" rules="sides" cellpadding="5" width="50%">
-  <tr>
-    <th width="30%">slot</th>
-    <th width="70%">data</th>
-  </tr>
-
-  <tr>
-    <td>0</td>
-    <td>sample count, must be &gt;= 1</td>
-  </tr>
-
-  <tr>
-    <td>1</td>
-    <td>number of call chain PCs (num_pcs), must be &gt;= 1</td>
-  </tr>
-
-  <tr>
-    <td>2 .. (num_pcs + 1)</td>
-    <td>call chain PCs, most-recently-called function first.
-  </tr>
-</table>
-
-<p>The total length of a given record is 2 + num_pcs.
-
-<p>Note that multiple profile records can be emitted by the profiler
-having an identical call chain.  In that case, analysis tools should
-sum the counts of all records having identical call chains.
-
-<p><b>Note:</b> Some profile analysis tools terminate if they see
-<em>any</em> profile record with a call chain with its first entry
-having the address 0.  (This is similar to the binary trailer.)
-
-<h3>Example</h3>
-
-This example shows the slots contained in a sample profile record.
-
-<p>
-<table summary="Profile Record Example"
-       frame="box" rules="sides" cellpadding="5">
-  <tr>
-    <td>5</td>
-    <td>3</td>
-    <td>0xa0000</td>
-    <td>0xc0000</td>
-    <td>0xe0000</td>
-  </tr>
-</table>
-
-<p>In this example, 5 ticks were received at PC 0xa0000, whose
-function had been called by the function containing 0xc0000, which had
-been called from the function containing 0xe0000.
-
-
-<h2>Binary Trailer</h2>
-
-<p>The binary trailer consists of three slots of data with fixed
-values, shown below.
-
-<p>
-<table summary="Trailer Format"
-       frame="box" rules="sides" cellpadding="5" width="50%">
-  <tr>
-    <th width="30%">slot</th>
-    <th width="70%">value</th>
-  </tr>
-
-  <tr>
-    <td>0</td>
-    <td>0</td>
-  </tr>
-
-  <tr>
-    <td>1</td>
-    <td>1</td>
-  </tr>
-
-  <tr>
-    <td>2</td>
-    <td>0</td>
-  </tr>
-</table>
-
-<p>Note that this is the same data that would contained in a profile
-record with sample count = 0, num_pcs = 1, and a one-element call
-chain containing the address 0.
-
-
-<h2>Text List of Mapped Objects</h2>
-
-<p>The binary data in the file is followed immediately by a list of
-mapped objects.  This list consists of lines of text separated by
-newline characters.
-
-<p>Each line is one of the following types:
-
-<ul>
-  <li>Build specifier, starting with "<tt>build=</tt>".  For example:
-    <pre>  build=/path/to/binary</pre>
-    Leading spaces on the line are ignored.
-
-  <li>Mapping line from ProcMapsIterator::FormatLine.  For example:
-    <pre>  40000000-40015000 r-xp 00000000 03:01 12845071   /lib/ld-2.3.2.so</pre>
-    The first address must start at the beginning of the line.
-</ul>
-
-<p>Unrecognized lines should be ignored by analysis tools.
-
-<p>When processing the paths see in mapping lines, occurrences of
-<tt>$build</tt> followed by a non-word character (i.e., characters
-other than underscore or alphanumeric characters), should be replaced
-by the path given on the last build specifier line.
-
-<hr>
-<address>Chris Demetriou<br>
-<!-- Created: Mon Aug 27 12:18:26 PDT 2007 -->
-<!-- hhmts start -->
-Last modified: Mon Aug 27 12:18:26 PDT 2007  (cgd)
-<!-- hhmts end -->
-</address>
-</BODY>
-</HTML>
diff --git a/third_party/tcmalloc/vendor/docs/cpuprofile.html b/third_party/tcmalloc/vendor/docs/cpuprofile.html
deleted file mode 100644
index c81feb6..0000000
--- a/third_party/tcmalloc/vendor/docs/cpuprofile.html
+++ /dev/null
@@ -1,536 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<HTML>
-
-<HEAD>
-  <link rel="stylesheet" href="designstyle.css">
-  <title>Gperftools CPU Profiler</title>
-</HEAD>
-
-<BODY>
-
-<p align=right>
-  <i>Last modified
-  <script type=text/javascript>
-    var lm = new Date(document.lastModified);
-    document.write(lm.toDateString());
-  </script></i>
-</p>
-
-<p>This is the CPU profiler we use at Google.  There are three parts
-to using it: linking the library into an application, running the
-code, and analyzing the output.</p>
-
-<p>On the off-chance that you should need to understand it, the CPU
-profiler data file format is documented separately,
-<a href="cpuprofile-fileformat.html">here</a>.
-
-
-<H1>Linking in the Library</H1>
-
-<p>To install the CPU profiler into your executable, add
-<code>-lprofiler</code> to the link-time step for your executable.
-(It's also probably possible to add in the profiler at run-time using
-<code>LD_PRELOAD</code>, e.g.
-<code>% env LD_PRELOAD="/usr/lib/libprofiler.so" &lt;binary&gt;</code>,
-but this isn't necessarily recommended.)</p>
-
-<p>This does <i>not</i> turn on CPU profiling; it just inserts the
-code.  For that reason, it's practical to just always link
-<code>-lprofiler</code> into a binary while developing; that's what we
-do at Google.  (However, since any user can turn on the profiler by
-setting an environment variable, it's not necessarily recommended to
-install profiler-linked binaries into a production, running
-system.)</p>
-
-
-<H1>Running the Code</H1>
-
-<p>There are several alternatives to actually turn on CPU profiling
-for a given run of an executable:</p>
-
-<ol>
-  <li> <p>Define the environment variable CPUPROFILE to the filename
-       to dump the profile to.  For instance, if you had a version of
-       <code>/bin/ls</code> that had been linked against libprofiler,
-       you could run:</p>
-       <pre>% env CPUPROFILE=ls.prof /bin/ls</pre>
-  </li>
-  <li> <p>In addition to defining the environment variable CPUPROFILE
-       you can also define CPUPROFILESIGNAL.  This allows profiling to be
-       controlled via the signal number that you specify.  The signal number
-       must be unused by the program under normal operation. Internally it
-       acts as a switch, triggered by the signal, which is off by default.
-       For instance, if you had a copy of <code>/bin/chrome</code> that had been
-       been linked against libprofiler, you could run:</p>
-       <pre>% env CPUPROFILE=chrome.prof CPUPROFILESIGNAL=12 /bin/chrome &</pre>
-       <p>You can then trigger profiling to start:</p>
-       <pre>% killall -12 chrome</pre>
-	   <p>Then after a period of time you can tell it to stop which will
-       generate the profile:</p>
-       <pre>% killall -12 chrome</pre>
-  </li>
-  <li> <p>In your code, bracket the code you want profiled in calls to
-       <code>ProfilerStart()</code> and <code>ProfilerStop()</code>.
-       (These functions are declared in <code>&lt;gperftools/profiler.h&gt;</code>.)
-       <code>ProfilerStart()</code> will take
-       the profile-filename as an argument.</p>
-  </li>
-</ol>
-
-<p>In Linux 2.6 and above, profiling works correctly with threads,
-automatically profiling all threads.  In Linux 2.4, profiling only
-profiles the main thread (due to a kernel bug involving itimers and
-threads).  Profiling works correctly with sub-processes: each child
-process gets its own profile with its own name (generated by combining
-CPUPROFILE with the child's process id).</p>
-
-<p>For security reasons, CPU profiling will not write to a file -- and
-is thus not usable -- for setuid programs.</p>
-
-<p>See the include-file <code>gperftools/profiler.h</code> for
-advanced-use functions, including <code>ProfilerFlush()</code> and
-<code>ProfilerStartWithOptions()</code>.</p>
-
-
-<H2>Modifying Runtime Behavior</H2>
-
-<p>You can more finely control the behavior of the CPU profiler via
-environment variables.</p>
-
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
-  <td><code>CPUPROFILE_FREQUENCY=<i>x</i></code></td>
-  <td>default: 100</td>
-  <td>
-    How many interrupts/second the cpu-profiler samples.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>CPUPROFILE_REALTIME=1</code></td>
-  <td>default: [not set]</td>
-  <td>
-    If set to any value (including 0 or the empty string), use
-    ITIMER_REAL instead of ITIMER_PROF to gather profiles.  In
-    general, ITIMER_REAL is not as accurate as ITIMER_PROF, and also
-    interacts badly with use of alarm(), so prefer ITIMER_PROF unless
-    you have a reason prefer ITIMER_REAL.
-  </td>
-</tr>
-
-</table>
-
-
-<h1><a name="pprof">Analyzing the Output</a></h1>
-
-<p><code>pprof</code> is the script used to analyze a profile.  It has
-many output modes, both textual and graphical.  Some give just raw
-numbers, much like the <code>-pg</code> output of <code>gcc</code>,
-and others show the data in the form of a dependency graph.</p>
-
-<p>pprof <b>requires</b> <code>perl5</code> to be installed to run.
-It also requires <code>dot</code> to be installed for any of the
-graphical output routines, and <code>gv</code> to be installed for
-<code>--gv</code> mode (described below).
-</p>
-
-<p>Here are some ways to call pprof.  These are described in more
-detail below.</p>
-
-<pre>
-% pprof /bin/ls ls.prof
-                       Enters "interactive" mode
-% pprof --text /bin/ls ls.prof
-                       Outputs one line per procedure
-% pprof --gv /bin/ls ls.prof
-                       Displays annotated call-graph via 'gv'
-% pprof --gv --focus=Mutex /bin/ls ls.prof
-                       Restricts to code paths including a .*Mutex.* entry
-% pprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof
-                       Code paths including Mutex but not string
-% pprof --list=getdir /bin/ls ls.prof
-                       (Per-line) annotated source listing for getdir()
-% pprof --disasm=getdir /bin/ls ls.prof
-                       (Per-PC) annotated disassembly for getdir()
-% pprof --text localhost:1234
-                       Outputs one line per procedure for localhost:1234
-% pprof --callgrind /bin/ls ls.prof
-                       Outputs the call information in callgrind format
-</pre>
-
-
-<h3>Analyzing Text Output</h3>
-
-<p>Text mode has lines of output that look like this:</p>
-<pre>
-       14   2.1%  17.2%       58   8.7% std::_Rb_tree::find
-</pre>
-
-<p>Here is how to interpret the columns:</p>
-<ol>
-  <li> Number of profiling samples in this function
-  <li> Percentage of profiling samples in this function
-  <li> Percentage of profiling samples in the functions printed so far
-  <li> Number of profiling samples in this function and its callees
-  <li> Percentage of profiling samples in this function and its callees
-  <li> Function name
-</ol>
-
-<h3>Analyzing Callgrind Output</h3>
-
-<p>Use <a href="http://kcachegrind.sourceforge.net">kcachegrind</a> to 
-analyze your callgrind output:</p>
-<pre>
-% pprof --callgrind /bin/ls ls.prof > ls.callgrind
-% kcachegrind ls.callgrind
-</pre>
-
-<p>The cost is specified in 'hits', i.e. how many times a function
-appears in the recorded call stack information. The 'calls' from
-function a to b record how many times function b was found in the
-stack traces directly below function a.</p>
-
-<p>Tip: if you use a debug build the output will include file and line
-number information and kcachegrind will show an annotated source
-code view.</p>
-
-<h3>Node Information</h3>
-
-<p>In the various graphical modes of pprof, the output is a call graph
-annotated with timing information, like so:</p>
-
-<A HREF="pprof-test-big.gif">
-<center><table><tr><td>
-   <img src="pprof-test.gif">
-</td></tr></table></center>
-</A>
-
-<p>Each node represents a procedure.  The directed edges indicate
-caller to callee relations.  Each node is formatted as follows:</p>
-
-<center><pre>
-Class Name
-Method Name
-local (percentage)
-<b>of</b> cumulative (percentage)
-</pre></center>
-
-<p>The last one or two lines contains the timing information.  (The
-profiling is done via a sampling method, where by default we take 100
-samples a second.  Therefor one unit of time in the output corresponds
-to about 10 milliseconds of execution time.) The "local" time is the
-time spent executing the instructions directly contained in the
-procedure (and in any other procedures that were inlined into the
-procedure).  The "cumulative" time is the sum of the "local" time and
-the time spent in any callees.  If the cumulative time is the same as
-the local time, it is not printed.</p>
-
-<p>For instance, the timing information for test_main_thread()
-indicates that 155 units (about 1.55 seconds) were spent executing the
-code in <code>test_main_thread()</code> and 200 units were spent while
-executing <code>test_main_thread()</code> and its callees such as
-<code>snprintf()</code>.</p>
-
-<p>The size of the node is proportional to the local count.  The
-percentage displayed in the node corresponds to the count divided by
-the total run time of the program (that is, the cumulative count for
-<code>main()</code>).</p>
-
-<h3>Edge Information</h3>
-
-<p>An edge from one node to another indicates a caller to callee
-relationship.  Each edge is labelled with the time spent by the callee
-on behalf of the caller.  E.g, the edge from
-<code>test_main_thread()</code> to <code>snprintf()</code> indicates
-that of the 200 samples in <code>test_main_thread()</code>, 37 are
-because of calls to <code>snprintf()</code>.</p>
-
-<p>Note that <code>test_main_thread()</code> has an edge to
-<code>vsnprintf()</code>, even though <code>test_main_thread()</code>
-doesn't call that function directly.  This is because the code was
-compiled with <code>-O2</code>; the profile reflects the optimized
-control flow.</p>
-
-<h3>Meta Information</h3>
-
-<p>The top of the display should contain some meta information
-like:</p>
-<pre>
-      /tmp/profiler2_unittest
-      Total samples: 202
-      Focusing on: 202
-      Dropped nodes with &lt;= 1 abs(samples)
-      Dropped edges with &lt;= 0 samples
-</pre>
-
-<p>This section contains the name of the program, and the total
-samples collected during the profiling run.  If the
-<code>--focus</code> option is on (see the <a href="#focus">Focus</a>
-section below), the legend also contains the number of samples being
-shown in the focused display.  Furthermore, some unimportant nodes and
-edges are dropped to reduce clutter.  The characteristics of the
-dropped nodes and edges are also displayed in the legend.</p>
-
-<h3><a name=focus>Focus and Ignore</a></h3>
-
-<p>You can ask pprof to generate a display focused on a particular
-piece of the program.  You specify a regular expression.  Any portion
-of the call-graph that is on a path which contains at least one node
-matching the regular expression is preserved.  The rest of the
-call-graph is dropped on the floor.  For example, you can focus on the
-<code>vsnprintf()</code> libc call in <code>profiler2_unittest</code>
-as follows:</p>
-
-<pre>
-% pprof --gv --focus=vsnprintf /tmp/profiler2_unittest test.prof
-</pre>
-<A HREF="pprof-vsnprintf-big.gif">
-<center><table><tr><td>
-   <img src="pprof-vsnprintf.gif">
-</td></tr></table></center>
-</A>
-
-<p>Similarly, you can supply the <code>--ignore</code> option to
-ignore samples that match a specified regular expression.  E.g., if
-you are interested in everything except calls to
-<code>snprintf()</code>, you can say:</p>
-<pre>
-% pprof --gv --ignore=snprintf /tmp/profiler2_unittest test.prof
-</pre>
-
-
-<h3>Interactive mode</a></h3>
-
-<p>By default -- if you don't specify any flags to the contrary --
-pprof runs in interactive mode.  At the <code>(pprof)</code> prompt,
-you can run many of the commands described above.  You can type
-<code>help</code> for a list of what commands are available in
-interactive mode.</p>
-
-<h3><a name=options>pprof Options</a></h3>
-
-For a complete list of pprof options, you can run <code>pprof
---help</code>.
-
-<h4>Output Type</h4>
-
-<p>
-<center>
-<table frame=box rules=sides cellpadding=5 width=100%>
-<tr valign=top>
-  <td><code>--text</code></td>
-  <td>
-    Produces a textual listing.  (Note: If you have an X display, and
-    <code>dot</code> and <code>gv</code> installed, you will probably
-    be happier with the <code>--gv</code> output.)
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--gv</code></td>
-  <td>
-    Generates annotated call-graph, converts to postscript, and
-    displays via gv (requres <code>dot</code> and <code>gv</code> be
-    installed).
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--dot</code></td>
-  <td>
-    Generates the annotated call-graph in dot format and
-    emits to stdout (requres <code>dot</code> be installed).
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--ps</code></td>
-  <td>
-    Generates the annotated call-graph in Postscript format and
-    emits to stdout (requres <code>dot</code> be installed).
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--pdf</code></td>
-  <td>
-    Generates the annotated call-graph in PDF format and emits to
-    stdout (requires <code>dot</code> and <code>ps2pdf</code> be
-    installed).
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--gif</code></td>
-  <td>
-    Generates the annotated call-graph in GIF format and
-    emits to stdout (requres <code>dot</code> be installed).
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--list=&lt;<i>regexp</i>&gt;</code></td>
-  <td>
-    <p>Outputs source-code listing of routines whose
-    name matches &lt;regexp&gt;.  Each line
-    in the listing is annotated with flat and cumulative
-    sample counts.</p>
-
-    <p>In the presence of inlined calls, the samples
-    associated with inlined code tend to get assigned
-    to a line that follows the location of the 
-    inlined call.  A more precise accounting can be
-    obtained by disassembling the routine using the
-    --disasm flag.</p>
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--disasm=&lt;<i>regexp</i>&gt;</code></td>
-  <td>
-    Generates disassembly of routines that match
-    &lt;regexp&gt;, annotated with flat and
-    cumulative sample counts and emits to stdout.
-  </td>
-</tr>
-</table>
-</center>
-
-<h4>Reporting Granularity</h4>
-
-<p>By default, pprof produces one entry per procedure.  However you can
-use one of the following options to change the granularity of the
-output.  The <code>--files</code> option seems to be particularly
-useless, and may be removed eventually.</p>
-
-<center>
-<table frame=box rules=sides cellpadding=5 width=100%>
-<tr valign=top>
-  <td><code>--addresses</code></td>
-  <td>
-     Produce one node per program address.
-  </td>
-</tr>
-  <td><code>--lines</code></td>
-  <td>
-     Produce one node per source line.
-  </td>
-</tr>
-  <td><code>--functions</code></td>
-  <td>
-     Produce one node per function (this is the default).
-  </td>
-</tr>
-  <td><code>--files</code></td>
-  <td>
-     Produce one node per source file.
-  </td>
-</tr>
-</table>
-</center>
-
-<h4>Controlling the Call Graph Display</h4>
-
-<p>Some nodes and edges are dropped to reduce clutter in the output
-display.  The following options control this effect:</p>
-
-<center>
-<table frame=box rules=sides cellpadding=5 width=100%>
-<tr valign=top>
-  <td><code>--nodecount=&lt;n&gt;</code></td>
-  <td>
-    This option controls the number of displayed nodes.  The nodes
-    are first sorted by decreasing cumulative count, and then only
-    the top N nodes are kept.  The default value is 80.
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--nodefraction=&lt;f&gt;</code></td>
-  <td>
-    This option provides another mechanism for discarding nodes
-    from the display.  If the cumulative count for a node is
-    less than this option's value multiplied by the total count
-    for the profile, the node is dropped.  The default value
-    is 0.005; i.e. nodes that account for less than
-    half a percent of the total time are dropped.  A node
-    is dropped if either this condition is satisfied, or the
-    --nodecount condition is satisfied.
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--edgefraction=&lt;f&gt;</code></td>
-  <td>
-    This option controls the number of displayed edges.  First of all,
-    an edge is dropped if either its source or destination node is
-    dropped.  Otherwise, the edge is dropped if the sample
-    count along the edge is less than this option's value multiplied
-    by the total count for the profile.  The default value is
-    0.001; i.e., edges that account for less than
-    0.1% of the total time are dropped.
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--focus=&lt;re&gt;</code></td>
-  <td>
-    This option controls what region of the graph is displayed
-    based on the regular expression supplied with the option.
-    For any path in the callgraph, we check all nodes in the path
-    against the supplied regular expression.  If none of the nodes
-    match, the path is dropped from the output.
-  </td>
-</tr>
-<tr valign=top>
-  <td><code>--ignore=&lt;re&gt;</code></td>
-  <td>
-    This option controls what region of the graph is displayed
-    based on the regular expression supplied with the option.
-    For any path in the callgraph, we check all nodes in the path
-    against the supplied regular expression.  If any of the nodes
-    match, the path is dropped from the output.
-  </td>
-</tr>
-</table>
-</center>
-
-<p>The dropped edges and nodes account for some count mismatches in
-the display.  For example, the cumulative count for
-<code>snprintf()</code> in the first diagram above was 41.  However
-the local count (1) and the count along the outgoing edges (12+1+20+6)
-add up to only 40.</p>
-
-
-<h1>Caveats</h1>
-
-<ul>
-  <li> If the program exits because of a signal, the generated profile
-       will be <font color=red>incomplete, and may perhaps be
-       completely empty</font>.
-  <li> The displayed graph may have disconnected regions because
-       of the edge-dropping heuristics described above.
-  <li> If the program linked in a library that was not compiled
-       with enough symbolic information, all samples associated
-       with the library may be charged to the last symbol found
-       in the program before the library.  This will artificially
-       inflate the count for that symbol.
-  <li> If you run the program on one machine, and profile it on
-       another, and the shared libraries are different on the two
-       machines, the profiling output may be confusing: samples that
-       fall within  shared libaries may be assigned to arbitrary
-       procedures.
-  <li> If your program forks, the children will also be profiled
-       (since they inherit the same CPUPROFILE setting).  Each process
-       is profiled separately; to distinguish the child profiles from
-       the parent profile and from each other, all children will have
-       their process-id appended to the CPUPROFILE name.
-  <li> Due to a hack we make to work around a possible gcc bug, your
-       profiles may end up named strangely if the first character of
-       your CPUPROFILE variable has ascii value greater than 127.
-       This should be exceedingly rare, but if you need to use such a
-       name, just set prepend <code>./</code> to your filename:
-       <code>CPUPROFILE=./&Auml;gypten</code>.
-</ul>
-
-
-<hr>
-<address>Sanjay Ghemawat<br>
-<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->
-<!-- hhmts start -->
-Last modified: Fri May  9 14:41:29 PDT 2008
-<!-- hhmts end -->
-</address>
-</BODY>
-</HTML>
diff --git a/third_party/tcmalloc/vendor/docs/designstyle.css b/third_party/tcmalloc/vendor/docs/designstyle.css
deleted file mode 100644
index 29299af..0000000
--- a/third_party/tcmalloc/vendor/docs/designstyle.css
+++ /dev/null
@@ -1,109 +0,0 @@
-body {
-  background-color: #ffffff;
-  color: black;
-  margin-right: 1in;
-  margin-left: 1in;
-}
-
-
-h1, h2, h3, h4, h5, h6 {
-  color: #3366ff;
-  font-family: sans-serif;
-}
-@media print {
-  /* Darker version for printing */
-  h1, h2, h3, h4, h5, h6 {
-    color: #000080;
-    font-family: helvetica, sans-serif;
-  }
-}
-
-h1 { 
-  text-align: center;
-  font-size: 18pt;
-}
-h2 {
-  margin-left: -0.5in;
-}
-h3 {
-  margin-left: -0.25in;
-}
-h4 {
-  margin-left: -0.125in;
-}
-hr {
-  margin-left: -1in;
-}
-
-/* Definition lists: definition term bold */
-dt {
-  font-weight: bold;
-}
-
-address {
-  text-align: right;
-}
-/* Use the <code> tag for bits of code and <var> for variables and objects. */
-code,pre,samp,var {
-  color: #006000;
-}
-/* Use the <file> tag for file and directory paths and names. */
-file {
-  color: #905050;
-  font-family: monospace;
-}
-/* Use the <kbd> tag for stuff the user should type. */
-kbd {
-  color: #600000;
-}
-div.note p {
-  float: right;
-  width: 3in;
-  margin-right: 0%;
-  padding: 1px;
-  border: 2px solid #6060a0;
-  background-color: #fffff0;
-}
-
-UL.nobullets {
-  list-style-type: none;
-  list-style-image: none;
-  margin-left: -1em;
-}
-
-/* pretty printing styles.  See prettify.js */
-.str { color: #080; }
-.kwd { color: #008; }
-.com { color: #800; }
-.typ { color: #606; }
-.lit { color: #066; }
-.pun { color: #660; }
-.pln { color: #000; }
-.tag { color: #008; }
-.atn { color: #606; }
-.atv { color: #080; }
-pre.prettyprint { padding: 2px; border: 1px solid #888; }
-
-.embsrc { background: #eee; }
-
-@media print {
-  .str { color: #060; }
-  .kwd { color: #006; font-weight: bold; }
-  .com { color: #600; font-style: italic; }
-  .typ { color: #404; font-weight: bold; }
-  .lit { color: #044; }
-  .pun { color: #440; }
-  .pln { color: #000; }
-  .tag { color: #006; font-weight: bold; }
-  .atn { color: #404; }
-  .atv { color: #060; }
-}
-
-/* Table Column Headers */
-.hdr { 
-  color: #006; 
-  font-weight: bold; 
-  background-color: #dddddd; }
-.hdr2 { 
-  color: #006; 
-  background-color: #eeeeee; }
\ No newline at end of file
diff --git a/third_party/tcmalloc/vendor/docs/heap-example1.png b/third_party/tcmalloc/vendor/docs/heap-example1.png
deleted file mode 100644
index 9a14b6fb..0000000
--- a/third_party/tcmalloc/vendor/docs/heap-example1.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/heap_checker.html b/third_party/tcmalloc/vendor/docs/heap_checker.html
deleted file mode 100644
index ca05b50..0000000
--- a/third_party/tcmalloc/vendor/docs/heap_checker.html
+++ /dev/null
@@ -1,534 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<HTML>
-
-<HEAD>
-  <link rel="stylesheet" href="designstyle.css">
-  <title>Gperftools Heap Leak Checker</title>
-</HEAD>
-
-<BODY>
-
-<p align=right>
-  <i>Last modified
-  <script type=text/javascript>
-    var lm = new Date(document.lastModified);
-    document.write(lm.toDateString());
-  </script></i>
-</p>
-
-<p>This is the heap checker we use at Google to detect memory leaks in
-C++ programs.  There are three parts to using it: linking the library
-into an application, running the code, and analyzing the output.</p>
-
-
-<H1>Linking in the Library</H1>
-
-<p>The heap-checker is part of tcmalloc, so to install the heap
-checker into your executable, add <code>-ltcmalloc</code> to the
-link-time step for your executable.  Also, while we don't necessarily
-recommend this form of usage, it's possible to add in the profiler at
-run-time using <code>LD_PRELOAD</code>:</p>
-<pre>% env LD_PRELOAD="/usr/lib/libtcmalloc.so" <binary></pre>
-
-<p>This does <i>not</i> turn on heap checking; it just inserts the
-code.  For that reason, it's practical to just always link
-<code>-ltcmalloc</code> into a binary while developing; that's what we
-do at Google.  (However, since any user can turn on the profiler by
-setting an environment variable, it's not necessarily recommended to
-install heapchecker-linked binaries into a production, running
-system.)  Note that if you wish to use the heap checker, you must
-also use the tcmalloc memory-allocation library.  There is no way
-currently to use the heap checker separate from tcmalloc.</p>
-
-
-<h1>Running the Code</h1>
-
-<p>Note: For security reasons, heap profiling will not write to a file
--- and is thus not usable -- for setuid programs.</p>
-
-<h2><a name="whole_program">Whole-program Heap Leak Checking</a></h2>
-
-<p>The recommended way to use the heap checker is in "whole program"
-mode.  In this case, the heap-checker starts tracking memory
-allocations before the start of <code>main()</code>, and checks again
-at program-exit.  If it finds any memory leaks -- that is, any memory
-not pointed to by objects that are still "live" at program-exit -- it
-aborts the program (via <code>exit(1)</code>) and prints a message
-describing how to track down the memory leak (using <A
-HREF="heapprofile.html#pprof">pprof</A>).</p>
-
-<p>The heap-checker records the stack trace for each allocation while
-it is active. This causes a significant increase in memory usage, in
-addition to slowing your program down.</p>
-
-<p>Here's how to run a program with whole-program heap checking:</p>
-
-<ol>
-  <li> <p>Define the environment variable HEAPCHECK to the <A
-       HREF="#types">type of heap-checking</A> to do.  For instance,
-       to heap-check
-       <code>/usr/local/bin/my_binary_compiled_with_tcmalloc</code>:</p>
-       <pre>% env HEAPCHECK=normal /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>
-</ol>
-
-<p>No other action is required.</p>
-
-<p>Note that since the heap-checker uses the heap-profiling framework
-internally, it is not possible to run both the heap-checker and <A
-HREF="heapprofile.html">heap profiler</A> at the same time.</p>
-
-
-<h3><a name="types">Flavors of Heap Checking</a></h3>
-
-<p>These are the legal values when running a whole-program heap
-check:</p>
-<ol>
-  <li> <code>minimal</code>
-  <li> <code>normal</code>
-  <li> <code>strict</code>
-  <li> <code>draconian</code>
-</ol>
-
-<p>"Minimal" heap-checking starts as late as possible in a
-initialization, meaning you can leak some memory in your
-initialization routines (that run before <code>main()</code>, say),
-and not trigger a leak message.  If you frequently (and purposefully)
-leak data in one-time global initializers, "minimal" mode is useful
-for you.  Otherwise, you should avoid it for stricter modes.</p>
-
-<p>"Normal" heap-checking tracks <A HREF="#live">live objects</A> and
-reports a leak for any data that is not reachable via a live object
-when the program exits.</p>
-
-<p>"Strict" heap-checking is much like "normal" but has a few extra
-checks that memory isn't lost in global destructors.  In particular,
-if you have a global variable that allocates memory during program
-execution, and then "forgets" about the memory in the global
-destructor (say, by setting the pointer to it to NULL) without freeing
-it, that will prompt a leak message in "strict" mode, though not in
-"normal" mode.</p>
-
-<p>"Draconian" heap-checking is appropriate for those who like to be
-very precise about their memory management, and want the heap-checker
-to help them enforce it.  In "draconian" mode, the heap-checker does
-not do "live object" checking at all, so it reports a leak unless
-<i>all</i> allocated memory is freed before program exit. (However,
-you can use <A HREF="#disable">IgnoreObject()</A> to re-enable
-liveness-checking on an object-by-object basis.)</p>
-
-<p>"Normal" mode, as the name implies, is the one used most often at
-Google.  It's appropriate for everyday heap-checking use.</p>
-
-<p>In addition, there are two other possible modes:</p>
-<ul>
-  <li> <code>as-is</code>
-  <li> <code>local</code>
-</ul>
-<p><code>as-is</code> is the most flexible mode; it allows you to
-specify the various <A HREF="#options">knobs</A> of the heap checker
-explicitly.  <code>local</code> activates the <A
-HREF="#explicit">explicit heap-check instrumentation</A>, but does not
-turn on any whole-program leak checking.</p>
-
-
-<h3><A NAME="tweaking">Tweaking whole-program checking</A></h3>
-
-<p>In some cases you want to check the whole program for memory leaks,
-but waiting for after <code>main()</code> exits to do the first
-whole-program leak check is waiting too long: e.g. in a long-running
-server one might wish to simply periodically check for leaks while the
-server is running.  In this case, you can call the static method
-<code>HeapLeakChecker::NoGlobalLeaks()</code>, to verify no global leaks have happened
-as of that point in the program.</p>
-
-<p>Alternately, doing the check after <code>main()</code> exits might
-be too late.  Perhaps you have some objects that are known not to
-clean up properly at exit.  You'd like to do the "at exit" check
-before those objects are destroyed (since while they're live, any
-memory they point to will not be considered a leak).  In that case,
-you can call <code>HeapLeakChecker::NoGlobalLeaks()</code> manually, near the end of
-<code>main()</code>, and then call <code>HeapLeakChecker::CancelGlobalCheck()</code> to
-turn off the automatic post-<code>main()</code> check.</p>
-
-<p>Finally, there's a helper macro for "strict" and "draconian" modes,
-which require all global memory to be freed before program exit.  This
-freeing can be time-consuming and is often unnecessary, since libc
-cleans up all memory at program-exit for you.  If you want the
-benefits of "strict"/"draconian" modes without the cost of all that
-freeing, look at <code>REGISTER_HEAPCHECK_CLEANUP</code> (in
-<code>heap-checker.h</code>).  This macro allows you to mark specific
-cleanup code as active only when the heap-checker is turned on.</p>
-
-
-<h2><a name="explicit">Explicit (Partial-program) Heap Leak Checking</h2>
-
-<p>Instead of whole-program checking, you can check certain parts of your
-code to verify they do not have memory leaks.  This check verifies that
-between two parts of a program, no memory is allocated without being freed.</p>
-<p>To use this kind of checking code, bracket the code you want
-checked by creating a <code>HeapLeakChecker</code> object at the
-beginning of the code segment, and call
-<code>NoLeaks()</code> at the end.  These functions, and all others
-referred to in this file, are declared in
-<code>&lt;gperftools/heap-checker.h&gt;</code>.
-</p>
-
-<p>Here's an example:</p>
-<pre>
-  HeapLeakChecker heap_checker("test_foo");
-  {
-    code that exercises some foo functionality;
-    this code should not leak memory;
-  }
-  if (!heap_checker.NoLeaks()) assert(NULL == "heap memory leak");
-</pre>
-
-<p>Note that adding in the <code>HeapLeakChecker</code> object merely
-instruments the code for leak-checking.  To actually turn on this
-leak-checking on a particular run of the executable, you must still
-run with the heap-checker turned on:</p>
-<pre>% env HEAPCHECK=local /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>
-<p>If you want to do whole-program leak checking in addition to this
-manual leak checking, you can run in <code>normal</code> or some other
-mode instead: they'll run the "local" checks in addition to the
-whole-program check.</p>
-
-
-<h2><a name="disable">Disabling Heap-checking of Known Leaks</a></h2>
-
-<p>Sometimes your code has leaks that you know about and are willing
-to accept.  You would like the heap checker to ignore them when
-checking your program.  You can do this by bracketing the code in
-question with an appropriate heap-checking construct:</p>
-<pre>
-   ...
-   {
-     HeapLeakChecker::Disabler disabler;
-     &lt;leaky code&gt;
-   }
-   ...
-</pre>
-Any objects allocated by <code>leaky code</code> (including inside any
-routines called by <code>leaky code</code>) and any objects reachable
-from such objects are not reported as leaks.
-
-<p>Alternately, you can use <code>IgnoreObject()</code>, which takes a
-pointer to an object to ignore.  That memory, and everything reachable
-from it (by following pointers), is ignored for the purposes of leak
-checking.  You can call <code>UnIgnoreObject()</code> to undo the
-effects of <code>IgnoreObject()</code>.</p>
-
-
-<h2><a name="options">Tuning the Heap Checker</h2>
-
-<p>The heap leak checker has many options, some that trade off running
-time and accuracy, and others that increase the sensitivity at the
-risk of returning false positives.  For most uses, the range covered
-by the <A HREF="#types">heap-check flavors</A> is enough, but in
-specialized cases more control can be helpful.</p>
-
-<p>
-These options are specified via environment varaiables.
-</p>
-
-<p>This first set of options controls sensitivity and accuracy.  These
-options are ignored unless you run the heap checker in <A
-HREF="#types">as-is</A> mode.
-
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
-  <td><code>HEAP_CHECK_AFTER_DESTRUCTORS</code></td>
-  <td>Default: false</td>
-  <td>
-    When true, do the final leak check after all other global
-    destructors have run.  When false, do it after all
-    <code>REGISTER_HEAPCHECK_CLEANUP</code>, typically much earlier in
-    the global-destructor process.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_CHECK_IGNORE_THREAD_LIVE</code></td>
-  <td>Default: true</td>
-  <td>
-    If true, ignore objects reachable from thread stacks and registers
-    (that is, do not report them as leaks).
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_CHECK_IGNORE_GLOBAL_LIVE</code></td>
-  <td>Default: true</td>
-  <td>
-    If true, ignore objects reachable from global variables and data
-    (that is, do not report them as leaks).
-  </td>
-</tr>
-
-</table>
-
-<p>These options modify the behavior of whole-program leak
-checking.</p>
-
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
-  <td><code>HEAP_CHECK_MAX_LEAKS</code></td>
-  <td>Default: 20</td>
-  <td>
-    The maximum number of leaks to be printed to stderr (all leaks are still
-    emitted to file output for pprof to visualize). If negative or zero,
-    print all the leaks found.
-  </td>
-</tr>
-
-
-</table>
-
-<p>These options apply to all types of leak checking.</p>
-
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
-  <td><code>HEAP_CHECK_IDENTIFY_LEAKS</code></td>
-  <td>Default: false</td>
-  <td>
-    If true, generate the addresses of the leaked objects in the
-    generated memory leak profile files.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_CHECK_TEST_POINTER_ALIGNMENT</code></td>
-  <td>Default: false</td>
-  <td>
-    If true, check all leaks to see if they might be due to the use
-    of unaligned pointers.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_CHECK_POINTER_SOURCE_ALIGNMENT</code></td>
-  <td>Default: sizeof(void*)</td>
-  <td>
-    Alignment at which all pointers in memory are supposed to be located.
-    Use 1 if any alignment is ok.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>PPROF_PATH</code></td>
-  <td>Default: pprof</td>
-<td>
-    The location of the <code>pprof</code> executable.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_CHECK_DUMP_DIRECTORY</code></td>
-  <td>Default: /tmp</td>
-  <td>
-    Where the heap-profile files are kept while the program is running.
-  </td>
-</tr>
-
-</table>
-
-
-<h2>Tips for Handling Detected Leaks</h2>
-
-<p>What do you do when the heap leak checker detects a memory leak?
-First, you should run the reported <code>pprof</code> command;
-hopefully, that is enough to track down the location where the leak
-occurs.</p>
-
-<p>If the leak is a real leak, you should fix it!</p>
-
-<p>If you are sure that the reported leaks are not dangerous and there
-is no good way to fix them, then you can use
-<code>HeapLeakChecker::Disabler</code> and/or
-<code>HeapLeakChecker::IgnoreObject()</code> to disable heap-checking
-for certain parts of the codebase.</p>
-
-<p>In "strict" or "draconian" mode, leaks may be due to incomplete
-cleanup in the destructors of global variables.  If you don't wish to
-augment the cleanup routines, but still want to run in "strict" or
-"draconian" mode, consider using <A
-HREF="#tweaking"><code>REGISTER_HEAPCHECK_CLEANUP</code></A>.</p>
-
-<h2>Hints for Debugging Detected Leaks</h2>
-
-<p>Sometimes it can be useful to not only know the exact code that
-allocates the leaked objects, but also the addresses of the leaked objects.
-Combining this e.g. with additional logging in the program
-one can then track which subset of the allocations
-made at a certain spot in the code are leaked.
-<br/>
-To get the addresses of all leaked objects
-  define the environment variable <code>HEAP_CHECK_IDENTIFY_LEAKS</code>
-  to be <code>1</code>.
-The object addresses will be reported in the form of addresses
-of fake immediate callers of the memory allocation routines.
-Note that the performance of doing leak-checking in this mode
-can be noticeably worse than the default mode.
-</p>
-
-<p>One relatively common class of leaks that don't look real
-is the case of multiple initialization.
-In such cases the reported leaks are typically things that are
-linked from some global objects,
-which are initialized and say never modified again.
-The non-obvious cause of the leak is frequently the fact that
-the initialization code for these objects executes more than once.
-<br/>
-E.g. if the code of some <code>.cc</code> file is made to be included twice
-into the binary, then the constructors for global objects defined in that file
-will execute twice thus leaking the things allocated on the first run.
-<br/>
-Similar problems can occur if object initialization is done more explicitly
-e.g. on demand by a slightly buggy code
-that does not always ensure only-once initialization.
-</p>
-
-<p>
-A more rare but even more puzzling problem can be use of not properly
-aligned pointers (maybe inside of not properly aligned objects).
-Normally such pointers are not followed by the leak checker,
-hence the objects reachable only via such pointers are reported as leaks.
-If you suspect this case
-  define the environment variable <code>HEAP_CHECK_TEST_POINTER_ALIGNMENT</code>
-  to be <code>1</code>
-and then look closely at the generated leak report messages.
-</p>
-
-<h1>How It Works</h1>
-
-<p>When a <code>HeapLeakChecker</code> object is constructed, it dumps
-a memory-usage profile named
-<code>&lt;prefix&gt;.&lt;name&gt;-beg.heap</code> to a temporary
-directory.  When <code>NoLeaks()</code>
-is called (for whole-program checking, this happens automatically at
-program-exit), it dumps another profile, named
-<code>&lt;prefix&gt;.&lt;name&gt;-end.heap</code>.
-(<code>&lt;prefix&gt;</code> is typically determined automatically,
-and <code>&lt;name&gt;</code> is typically <code>argv[0]</code>.)  It
-then compares the two profiles.  If the second profile shows
-more memory use than the first, the
-<code>NoLeaks()</code> function will
-return false.  For "whole program" profiling, this will cause the
-executable to abort (via <code>exit(1)</code>).  In all cases, it will
-print a message on how to process the dumped profiles to locate
-leaks.</p>
-
-<h3><A name=live>Detecting Live Objects</A></h3>
-
-<p>At any point during a program's execution, all memory that is
-accessible at that time is considered "live."  This includes global
-variables, and also any memory that is reachable by following pointers
-from a global variable.  It also includes all memory reachable from
-the current stack frame and from current CPU registers (this captures
-local variables).  Finally, it includes the thread equivalents of
-these: thread-local storage and thread heaps, memory reachable from
-thread-local storage and thread heaps, and memory reachable from
-thread CPU registers.</p>
-
-<p>In all modes except "draconian," live memory is not
-considered to be a leak.  We detect this by doing a liveness flood,
-traversing pointers to heap objects starting from some initial memory
-regions we know to potentially contain live pointer data.  Note that
-this flood might potentially not find some (global) live data region
-to start the flood from.  If you find such, please file a bug.</p>
-
-<p>The liveness flood attempts to treat any properly aligned byte
-sequences as pointers to heap objects and thinks that it found a good
-pointer whenever the current heap memory map contains an object with
-the address whose byte representation we found.  Some pointers into
-not-at-start of object will also work here.</p>
-
-<p>As a result of this simple approach, it's possible (though
-unlikely) for the flood to be inexact and occasionally result in
-leaked objects being erroneously determined to be live.  For instance,
-random bit patterns can happen to look like pointers to leaked heap
-objects.  More likely, stale pointer data not corresponding to any
-live program variables can be still present in memory regions,
-especially in thread stacks.  For instance, depending on how the local
-<code>malloc</code> is implemented, it may reuse a heap object
-address:</p>
-<pre>
-    char* p = new char[1];   // new might return 0x80000000, say.
-    delete p;
-    new char[1];             // new might return 0x80000000 again
-    // This last new is a leak, but doesn't seem it: p looks like it points to it
-</pre>
-
-<p>In other words, imprecisions in the liveness flood mean that for
-any heap leak check we might miss some memory leaks.  This means that
-for local leak checks, we might report a memory leak in the local
-area, even though the leak actually happened before the
-<code>HeapLeakChecker</code> object was constructed.  Note that for
-whole-program checks, a leak report <i>does</i> always correspond to a
-real leak (since there's no "before" to have created a false-live
-object).</p>
-
-<p>While this liveness flood approach is not very portable and not
-100% accurate, it works in most cases and saves us from writing a lot
-of explicit clean up code and other hassles when dealing with thread
-data.</p>
-
-
-<h3>Visualizing Leak with <code>pprof</code></h3>
-
-<p>
-The heap checker automatically prints basic leak info with stack traces of
-leaked objects' allocation sites, as well as a pprof command line that can be
-used to visualize the call-graph involved in these allocations.
-The latter can be much more useful for a human
-to see where/why the leaks happened, especially if the leaks are numerous.
-</p>
-
-<h3>Leak-checking and Threads</h3>
-
-<p>At the time of HeapLeakChecker's construction and during
-<code>NoLeaks()</code> calls, we grab a lock
-and then pause all other threads so other threads do not interfere
-with recording or analyzing the state of the heap.</p>
-
-<p>In general, leak checking works correctly in the presence of
-threads.  However, thread stack data liveness determination (via
-<code>base/thread_lister.h</code>) does not work when the program is
-running under GDB, because the ptrace functionality needed for finding
-threads is already hooked to by GDB.  Conversely, leak checker's
-ptrace attempts might also interfere with GDB.  As a result, GDB can
-result in potentially false leak reports.  For this reason, the
-heap-checker turns itself off when running under GDB.</p>
-
-<p>Also, <code>thread_lister</code> only works for Linux pthreads;
-leak checking is unlikely to handle other thread implementations
-correctly.</p>
-
-<p>As mentioned in the discussion of liveness flooding, thread-stack
-liveness determination might mis-classify as reachable objects that
-very recently became unreachable (leaked).  This can happen when the
-pointers to now-logically-unreachable objects are present in the
-active thread stack frame.  In other words, trivial code like the
-following might not produce the expected leak checking outcome
-depending on how the compiled code works with the stack:</p>
-<pre>
-  int* foo = new int [20];
-  HeapLeakChecker check("a_check");
-  foo = NULL;
-  // May fail to trigger.
-  if (!heap_checker.NoLeaks()) assert(NULL == "heap memory leak");
-</pre>
-
-
-<hr>
-<address>Maxim Lifantsev<br>
-<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->
-<!-- hhmts start -->
-Last modified: Fri Jul 13 13:14:33 PDT 2007
-<!-- hhmts end -->
-</address>
-</body>
-</html>
diff --git a/third_party/tcmalloc/vendor/docs/heapprofile.html b/third_party/tcmalloc/vendor/docs/heapprofile.html
deleted file mode 100644
index 6f50869..0000000
--- a/third_party/tcmalloc/vendor/docs/heapprofile.html
+++ /dev/null
@@ -1,391 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<HTML>
-
-<HEAD>
-  <link rel="stylesheet" href="designstyle.css">
-  <title>Gperftools Heap Profiler</title>
-</HEAD>
-
-<BODY>
-
-<p align=right>
-  <i>Last modified
-  <script type=text/javascript>
-    var lm = new Date(document.lastModified);
-    document.write(lm.toDateString());
-  </script></i>
-</p>
-
-<p>This is the heap profiler we use at Google, to explore how C++
-programs manage memory.  This facility can be useful for</p>
-<ul>
-  <li> Figuring out what is in the program heap at any given time
-  <li> Locating memory leaks
-  <li> Finding places that do a lot of allocation
-</ul>
-
-<p>The profiling system instruments all allocations and frees.  It
-keeps track of various pieces of information per allocation site.  An
-allocation site is defined as the active stack trace at the call to
-<code>malloc</code>, <code>calloc</code>, <code>realloc</code>, or,
-<code>new</code>.</p>
-
-<p>There are three parts to using it: linking the library into an
-application, running the code, and analyzing the output.</p>
-
-
-<h1>Linking in the Library</h1>
-
-<p>To install the heap profiler into your executable, add
-<code>-ltcmalloc</code> to the link-time step for your executable.
-Also, while we don't necessarily recommend this form of usage, it's
-possible to add in the profiler at run-time using
-<code>LD_PRELOAD</code>:
-<pre>% env LD_PRELOAD="/usr/lib/libtcmalloc.so" &lt;binary&gt;</pre>
-
-<p>This does <i>not</i> turn on heap profiling; it just inserts the
-code.  For that reason, it's practical to just always link
-<code>-ltcmalloc</code> into a binary while developing; that's what we
-do at Google.  (However, since any user can turn on the profiler by
-setting an environment variable, it's not necessarily recommended to
-install profiler-linked binaries into a production, running
-system.)  Note that if you wish to use the heap profiler, you must
-also use the tcmalloc memory-allocation library.  There is no way
-currently to use the heap profiler separate from tcmalloc.</p>
-
-
-<h1>Running the Code</h1>
-
-<p>There are several alternatives to actually turn on heap profiling
-for a given run of an executable:</p>
-
-<ol>
-  <li> <p>Define the environment variable HEAPPROFILE to the filename
-       to dump the profile to.  For instance, to profile
-       <code>/usr/local/bin/my_binary_compiled_with_tcmalloc</code>:</p>
-       <pre>% env HEAPPROFILE=/tmp/mybin.hprof /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>
-  <li> <p>In your code, bracket the code you want profiled in calls to
-       <code>HeapProfilerStart()</code> and <code>HeapProfilerStop()</code>.
-       (These functions are declared in <code>&lt;gperftools/heap-profiler.h&gt;</code>.)
-       <code>HeapProfilerStart()</code> will take the
-       profile-filename-prefix as an argument.  Then, as often as
-       you'd like before calling <code>HeapProfilerStop()</code>, you
-       can use <code>HeapProfilerDump()</code> or
-       <code>GetHeapProfile()</code> to examine the profile.  In case
-       it's useful, <code>IsHeapProfilerRunning()</code> will tell you
-       whether you've already called HeapProfilerStart() or not.</p>
-</ol>
-
-
-<p>For security reasons, heap profiling will not write to a file --
-and is thus not usable -- for setuid programs.</p>
-
-<H2>Modifying Runtime Behavior</H2>
-
-<p>You can more finely control the behavior of the heap profiler via
-environment variables.</p>
-
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
-  <td><code>HEAP_PROFILE_ALLOCATION_INTERVAL</code></td>
-  <td>default: 1073741824 (1 Gb)</td>
-  <td>
-    Dump heap profiling information each time the specified number of
-    bytes has been allocated by the program.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_PROFILE_INUSE_INTERVAL</code></td>
-  <td>default: 104857600 (100 Mb)</td>
-  <td>
-    Dump heap profiling information whenever the high-water memory
-    usage mark increases by the specified number of bytes.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_PROFILE_TIME_INTERVAL</code></td>
-  <td>default: 0</td>
-  <td>
-    Dump heap profiling information each time the specified
-    number of seconds has elapsed.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAPPROFILESIGNAL</code></td>
-  <td>default: disabled</td>
-  <td>
-    Dump heap profiling information whenever the specified signal is sent to the
-    process.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_PROFILE_MMAP</code></td>
-  <td>default: false</td>
-  <td>
-    Profile <code>mmap</code>, <code>mremap</code> and <code>sbrk</code>
-    calls in addition
-    to <code>malloc</code>, <code>calloc</code>, <code>realloc</code>,
-    and <code>new</code>.  <b>NOTE:</b> this causes the profiler to
-    profile calls internal to tcmalloc, since tcmalloc and friends use
-    mmap and sbrk internally for allocations.  One partial solution is
-    to filter these allocations out when running <code>pprof</code>,
-    with something like
-    <code>pprof --ignore='DoAllocWithArena|SbrkSysAllocator::Alloc|MmapSysAllocator::Alloc</code>.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_PROFILE_ONLY_MMAP</code></td>
-  <td>default: false</td>
-  <td>
-    Only profile <code>mmap</code>, <code>mremap</code>, and <code>sbrk</code>
-    calls; do not profile
-    <code>malloc</code>, <code>calloc</code>, <code>realloc</code>,
-    or <code>new</code>.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>HEAP_PROFILE_MMAP_LOG</code></td>
-  <td>default: false</td>
-  <td>
-    Log <code>mmap</code>/<code>munmap</code> calls.
-  </td>
-</tr>
-
-</table>
-
-<H2>Checking for Leaks</H2>
-
-<p>You can use the heap profiler to manually check for leaks, for
-instance by reading the profiler output and looking for large
-allocations.  However, for that task, it's easier to use the <A
-HREF="heap_checker.html">automatic heap-checking facility</A> built
-into tcmalloc.</p>
-
-
-<h1><a name="pprof">Analyzing the Output</a></h1>
-
-<p>If heap-profiling is turned on in a program, the program will
-periodically write profiles to the filesystem.  The sequence of
-profiles will be named:</p>
-<pre>
-           &lt;prefix&gt;.0000.heap
-           &lt;prefix&gt;.0001.heap
-           &lt;prefix&gt;.0002.heap
-           ...
-</pre>
-<p>where <code>&lt;prefix&gt;</code> is the filename-prefix supplied
-when running the code (e.g. via the <code>HEAPPROFILE</code>
-environment variable).  Note that if the supplied prefix
-does not start with a <code>/</code>, the profile files will be
-written to the program's working directory.</p>
-
-<p>The profile output can be viewed by passing it to the
-<code>pprof</code> tool -- the same tool that's used to analyze <A
-HREF="cpuprofile.html">CPU profiles</A>.
-
-<p>Here are some examples.  These examples assume the binary is named
-<code>gfs_master</code>, and a sequence of heap profile files can be
-found in files named:</p>
-<pre>
-  /tmp/profile.0001.heap
-  /tmp/profile.0002.heap
-  ...
-  /tmp/profile.0100.heap
-</pre>
-
-<h3>Why is a process so big</h3>
-
-<pre>
-    % pprof --gv gfs_master /tmp/profile.0100.heap
-</pre>
-
-<p>This command will pop-up a <code>gv</code> window that displays
-the profile information as a directed graph.  Here is a portion
-of the resulting output:</p>
-
-<p><center>
-<img src="heap-example1.png">
-</center></p>
-
-A few explanations:
-<ul>
-<li> <code>GFS_MasterChunk::AddServer</code> accounts for 255.6 MB
-     of the live memory, which is 25% of the total live memory.
-<li> <code>GFS_MasterChunkTable::UpdateState</code> is directly
-     accountable for 176.2 MB of the live memory (i.e., it directly
-     allocated 176.2 MB that has not been freed yet).  Furthermore,
-     it and its callees are responsible for 729.9 MB.  The
-     labels on the outgoing edges give a good indication of the
-     amount allocated by each callee.
-</ul>
-
-<h3>Comparing Profiles</h3>
-
-<p>You often want to skip allocations during the initialization phase
-of a program so you can find gradual memory leaks.  One simple way to
-do this is to compare two profiles -- both collected after the program
-has been running for a while.  Specify the name of the first profile
-using the <code>--base</code> option.  For example:</p>
-<pre>
-   % pprof --base=/tmp/profile.0004.heap gfs_master /tmp/profile.0100.heap
-</pre>
-
-<p>The memory-usage in <code>/tmp/profile.0004.heap</code> will be
-subtracted from the memory-usage in
-<code>/tmp/profile.0100.heap</code> and the result will be
-displayed.</p>
-
-<h3>Text display</h3>
-
-<pre>
-% pprof --text gfs_master /tmp/profile.0100.heap
-   255.6  24.7%  24.7%    255.6  24.7% GFS_MasterChunk::AddServer
-   184.6  17.8%  42.5%    298.8  28.8% GFS_MasterChunkTable::Create
-   176.2  17.0%  59.5%    729.9  70.5% GFS_MasterChunkTable::UpdateState
-   169.8  16.4%  75.9%    169.8  16.4% PendingClone::PendingClone
-    76.3   7.4%  83.3%     76.3   7.4% __default_alloc_template::_S_chunk_alloc
-    49.5   4.8%  88.0%     49.5   4.8% hashtable::resize
-   ...
-</pre>
-
-<p>
-<ul>
-  <li> The first column contains the direct memory use in MB.
-  <li> The fourth column contains memory use by the procedure
-       and all of its callees.
-  <li> The second and fifth columns are just percentage
-       representations of the numbers in the first and fourth columns.
-  <li> The third column is a cumulative sum of the second column
-       (i.e., the <code>k</code>th entry in the third column is the
-       sum of the first <code>k</code> entries in the second column.)
-</ul>
-
-<h3>Ignoring or focusing on specific regions</h3>
-
-<p>The following command will give a graphical display of a subset of
-the call-graph.  Only paths in the call-graph that match the regular
-expression <code>DataBuffer</code> are included:</p>
-<pre>
-% pprof --gv --focus=DataBuffer gfs_master /tmp/profile.0100.heap
-</pre>
-
-<p>Similarly, the following command will omit all paths subset of the
-call-graph.  All paths in the call-graph that match the regular
-expression <code>DataBuffer</code> are discarded:</p>
-<pre>
-% pprof --gv --ignore=DataBuffer gfs_master /tmp/profile.0100.heap
-</pre>
-
-<h3>Total allocations + object-level information</h3>
-
-<p>All of the previous examples have displayed the amount of in-use
-space.  I.e., the number of bytes that have been allocated but not
-freed.  You can also get other types of information by supplying a
-flag to <code>pprof</code>:</p>
-
-<center>
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
-  <td><code>--inuse_space</code></td>
-  <td>
-     Display the number of in-use megabytes (i.e. space that has
-     been allocated but not freed).  This is the default.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>--inuse_objects</code></td>
-  <td>
-     Display the number of in-use objects (i.e. number of
-     objects that have been allocated but not freed).
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>--alloc_space</code></td>
-  <td>
-     Display the number of allocated megabytes.  This includes
-     the space that has since been de-allocated.  Use this
-     if you want to find the main allocation sites in the
-     program.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>--alloc_objects</code></td>
-  <td>
-     Display the number of allocated objects.  This includes
-     the objects that have since been de-allocated.  Use this
-     if you want to find the main allocation sites in the
-     program.
-  </td>
-
-</table>
-</center>
-
-
-<h3>Interactive mode</a></h3>
-
-<p>By default -- if you don't specify any flags to the contrary --
-pprof runs in interactive mode.  At the <code>(pprof)</code> prompt,
-you can run many of the commands described above.  You can type
-<code>help</code> for a list of what commands are available in
-interactive mode.</p>
-
-
-<h1>Caveats</h1>
-
-<ul>
-  <li> Heap profiling requires the use of libtcmalloc.  This
-       requirement may be removed in a future version of the heap
-       profiler, and the heap profiler separated out into its own
-       library.
-     
-  <li> If the program linked in a library that was not compiled
-       with enough symbolic information, all samples associated
-       with the library may be charged to the last symbol found
-       in the program before the library.  This will artificially
-       inflate the count for that symbol.
-
-  <li> If you run the program on one machine, and profile it on
-       another, and the shared libraries are different on the two
-       machines, the profiling output may be confusing: samples that
-       fall within the shared libaries may be assigned to arbitrary
-       procedures.
-
-  <li> Several libraries, such as some STL implementations, do their
-       own memory management.  This may cause strange profiling
-       results.  We have code in libtcmalloc to cause STL to use
-       tcmalloc for memory management (which in our tests is better
-       than STL's internal management), though it only works for some
-       STL implementations.
-
-  <li> If your program forks, the children will also be profiled
-       (since they inherit the same HEAPPROFILE setting).  Each
-       process is profiled separately; to distinguish the child
-       profiles from the parent profile and from each other, all
-       children will have their process-id attached to the HEAPPROFILE
-       name.
-     
-  <li> Due to a hack we make to work around a possible gcc bug, your
-       profiles may end up named strangely if the first character of
-       your HEAPPROFILE variable has ascii value greater than 127.
-       This should be exceedingly rare, but if you need to use such a
-       name, just set prepend <code>./</code> to your filename:
-       <code>HEAPPROFILE=./&Auml;gypten</code>.
-</ul>
-
-<hr>
-<address>Sanjay Ghemawat
-<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->
-</address>
-</body>
-</html>
diff --git a/third_party/tcmalloc/vendor/docs/index.html b/third_party/tcmalloc/vendor/docs/index.html
deleted file mode 100644
index 7b93ed396..0000000
--- a/third_party/tcmalloc/vendor/docs/index.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<HTML>
-
-<HEAD>
-<title>Gperftools</title>
-</HEAD>
-
-<BODY>
-<ul>
-  <li> <A HREF="tcmalloc.html">thread-caching malloc</A>
-  <li> <A HREF="heap_checker.html">heap-checking using tcmalloc</A>
-  <li> <A HREF="heapprofile.html">heap-profiling using tcmalloc</A>
-  <li> <A HREF="cpuprofile.html">CPU profiler</A>
-</ul>
-
-<hr>
-Last modified: Thu Feb  2 14:40:47 PST 2012
-
-</BODY>
-
-</HTML>
diff --git a/third_party/tcmalloc/vendor/docs/overview.dot b/third_party/tcmalloc/vendor/docs/overview.dot
deleted file mode 100644
index 9966f56..0000000
--- a/third_party/tcmalloc/vendor/docs/overview.dot
+++ /dev/null
@@ -1,15 +0,0 @@
-digraph Overview {
-node [shape = box]
-
-{rank=same
-T1 [label="Thread Cache"]
-Tsep [label="...", shape=plaintext]
-Tn [label="Thread Cache"]
-T1 -> Tsep -> Tn [style=invis]
-}
-
-C [label="Central\nHeap"]
-T1 -> C [dir=both]
-Tn -> C [dir=both]
-
-}
diff --git a/third_party/tcmalloc/vendor/docs/overview.gif b/third_party/tcmalloc/vendor/docs/overview.gif
deleted file mode 100644
index 43828dadec..0000000
--- a/third_party/tcmalloc/vendor/docs/overview.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/pageheap.dot b/third_party/tcmalloc/vendor/docs/pageheap.dot
deleted file mode 100644
index 5e9aec8..0000000
--- a/third_party/tcmalloc/vendor/docs/pageheap.dot
+++ /dev/null
@@ -1,25 +0,0 @@
-digraph PageHeap {
-rankdir=LR
-node [shape=box, width=0.3, height=0.3]
-nodesep=.05
-
-heap [shape=record, height=3, label="<f0>1 page|<f1>2 pages|<f2>3 pages|...|<f128>128 pages"]
-O0 [shape=record, label=""]
-O1 [shape=record, label=""]
-O2 [shape=record, label="{|}"]
-O3 [shape=record, label="{|}"]
-O4 [shape=record, label="{||}"]
-O5 [shape=record, label="{||}"]
-O6 [shape=record, label="{|...|}"]
-O7 [shape=record, label="{|...|}"]
-sep1 [shape=plaintext, label="..."]
-sep2 [shape=plaintext, label="..."]
-sep3 [shape=plaintext, label="..."]
-sep4 [shape=plaintext, label="..."]
-
-heap:f0 -> O0 -> O1 -> sep1
-heap:f1 -> O2 -> O3 -> sep2
-heap:f2 -> O4 -> O5 -> sep3
-heap:f128 -> O6 -> O7 -> sep4
-
-}
diff --git a/third_party/tcmalloc/vendor/docs/pageheap.gif b/third_party/tcmalloc/vendor/docs/pageheap.gif
deleted file mode 100644
index 5cf00bd..0000000
--- a/third_party/tcmalloc/vendor/docs/pageheap.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/pprof-test-big.gif b/third_party/tcmalloc/vendor/docs/pprof-test-big.gif
deleted file mode 100644
index 67a1240..0000000
--- a/third_party/tcmalloc/vendor/docs/pprof-test-big.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/pprof-test.gif b/third_party/tcmalloc/vendor/docs/pprof-test.gif
deleted file mode 100644
index 9eeab8a..0000000
--- a/third_party/tcmalloc/vendor/docs/pprof-test.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/pprof-vsnprintf-big.gif b/third_party/tcmalloc/vendor/docs/pprof-vsnprintf-big.gif
deleted file mode 100644
index 2ab292a..0000000
--- a/third_party/tcmalloc/vendor/docs/pprof-vsnprintf-big.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/pprof-vsnprintf.gif b/third_party/tcmalloc/vendor/docs/pprof-vsnprintf.gif
deleted file mode 100644
index 42a8547..0000000
--- a/third_party/tcmalloc/vendor/docs/pprof-vsnprintf.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/pprof.1 b/third_party/tcmalloc/vendor/docs/pprof.1
deleted file mode 100644
index f0f6caf..0000000
--- a/third_party/tcmalloc/vendor/docs/pprof.1
+++ /dev/null
@@ -1,131 +0,0 @@
-.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
-.TH PPROF "1" "February 2005" "pprof (part of gperftools)" Google
-.SH NAME
-pprof \- manual page for pprof (part of gperftools)
-.SH SYNOPSIS
-.B pprof
-[\fIoptions\fR] \fI<program> <profile>\fR
-.SH DESCRIPTION
-.IP
-Prints specified cpu- or heap-profile
-.SH OPTIONS
-.TP
-\fB\-\-cum\fR
-Sort by cumulative data
-.TP
-\fB\-\-base=\fR<base>
-Subtract <base> from <profile> before display
-.SS "Reporting Granularity:"
-.TP
-\fB\-\-addresses\fR
-Report at address level
-.TP
-\fB\-\-lines\fR
-Report at source line level
-.TP
-\fB\-\-functions\fR
-Report at function level [default]
-.TP
-\fB\-\-files\fR
-Report at source file level
-.SS "Output type:"
-.TP
-\fB\-\-text\fR
-Generate text report [default]
-.TP
-\fB\-\-gv\fR
-Generate Postscript and display
-.TP
-\fB\-\-list=\fR<regexp>
-Generate source listing of matching routines
-.TP
-\fB\-\-disasm=\fR<regexp>
-Generate disassembly of matching routines
-.TP
-\fB\-\-dot\fR
-Generate DOT file to stdout
-.TP
-\fB\-\-ps\fR
-Generate Postscript to stdout
-.TP
-\fB\-\-pdf\fR
-Generate PDF to stdout
-.TP
-\fB\-\-gif\fR
-Generate GIF to stdout
-.SS "Heap-Profile Options:"
-.TP
-\fB\-\-inuse_space\fR
-Display in-use (mega)bytes [default]
-.TP
-\fB\-\-inuse_objects\fR
-Display in-use objects
-.TP
-\fB\-\-alloc_space\fR
-Display allocated (mega)bytes
-.TP
-\fB\-\-alloc_objects\fR
-Display allocated objects
-.TP
-\fB\-\-show_bytes\fR
-Display space in bytes
-.TP
-\fB\-\-drop_negative\fR
-Ignore negaive differences
-.SS "Call-graph Options:"
-.TP
-\fB\-\-nodecount=\fR<n>
-Show at most so many nodes [default=80]
-.TP
-\fB\-\-nodefraction=\fR<f>
-Hide nodes below <f>*total [default=.005]
-.TP
-\fB\-\-edgefraction=\fR<f>
-Hide edges below <f>*total [default=.001]
-.TP
-\fB\-\-focus=\fR<regexp>
-Focus on nodes matching <regexp>
-.TP
-\fB\-\-ignore=\fR<regexp>
-Ignore nodes matching <regexp>
-.TP
-\fB\-\-scale=\fR<n>
-Set GV scaling [default=0]
-.SH EXAMPLES
-
-pprof /bin/ls ls.prof
-.IP
-Outputs one line per procedure
-.PP
-pprof \fB\-\-gv\fR /bin/ls ls.prof
-.IP
-Displays annotated call-graph via 'gv'
-.PP
-pprof \fB\-\-gv\fR \fB\-\-focus\fR=\fIMutex\fR /bin/ls ls.prof
-.IP
-Restricts to code paths including a .*Mutex.* entry
-.PP
-pprof \fB\-\-gv\fR \fB\-\-focus\fR=\fIMutex\fR \fB\-\-ignore\fR=\fIstring\fR /bin/ls ls.prof
-.IP
-Code paths including Mutex but not string
-.PP
-pprof \fB\-\-list\fR=\fIgetdir\fR /bin/ls ls.prof
-.IP
-Dissassembly (with per-line annotations) for getdir()
-.PP
-pprof \fB\-\-disasm\fR=\fIgetdir\fR /bin/ls ls.prof
-.IP
-Dissassembly (with per-PC annotations) for getdir()
-.SH COPYRIGHT
-Copyright \(co 2005 Google Inc.
-.SH "SEE ALSO"
-Further documentation for
-.B pprof
-is maintained as a web page called
-.B cpu_profiler.html
-and is likely installed at one of the following locations:
-.IP
-.B /usr/share/gperftools/cpu_profiler.html
-.br
-.B /usr/local/share/gperftools/cpu_profiler.html
-.PP
diff --git a/third_party/tcmalloc/vendor/docs/pprof.see_also b/third_party/tcmalloc/vendor/docs/pprof.see_also
deleted file mode 100644
index f2caf52..0000000
--- a/third_party/tcmalloc/vendor/docs/pprof.see_also
+++ /dev/null
@@ -1,11 +0,0 @@
-[see also]
-Further documentation for
-.B pprof
-is maintained as a web page called
-.B cpu_profiler.html
-and is likely installed at one of the following locations:
-.IP
-.B /usr/share/gperftools/cpu_profiler.html
-.br
-.B /usr/local/share/gperftools/cpu_profiler.html
-.PP
diff --git a/third_party/tcmalloc/vendor/docs/pprof_remote_servers.html b/third_party/tcmalloc/vendor/docs/pprof_remote_servers.html
deleted file mode 100644
index e30e612..0000000
--- a/third_party/tcmalloc/vendor/docs/pprof_remote_servers.html
+++ /dev/null
@@ -1,260 +0,0 @@
-<HTML>
-
-<HEAD>
-<title>pprof and Remote Servers</title>
-</HEAD>
-
-<BODY>
-
-<h1><code>pprof</code> and Remote Servers</h1>
-
-<p>In mid-2006, we added an experimental facility to <A
-HREF="cpu_profiler.html">pprof</A>, the tool that analyzes CPU and
-heap profiles.  This facility allows you to collect profile
-information from running applications.  It makes it easy to collect
-profile information without having to stop the program first, and
-without having to log into the machine where the application is
-running.  This is meant to be used on webservers, but will work on any
-application that can be modified to accept TCP connections on a port
-of its choosing, and to respond to HTTP requests on that port.</p>
-
-<p>We do not currently have infrastructure, such as apache modules,
-that you can pop into a webserver or other application to get the
-necessary functionality "for free."  However, it's easy to generate
-the necessary data, which should allow the interested developer to add
-the necessary support into his or her applications.</p>
-
-<p>To use <code>pprof</code> in this experimental "server" mode, you
-give the script a host and port it should query, replacing the normal
-commandline arguments of application + profile file:</p>
-<pre>
-   % pprof internalweb.mycompany.com:80
-</pre>
-
-<p>The host must be listening on that port, and be able to accept HTTP/1.0
-requests -- sent via <code>wget</code> and <code>curl</code> -- for
-several urls.  The following sections list the urls that
-<code>pprof</code> can send, and the responses it expects in
-return.</p>
-
-<p>Here are examples that pprof will recognize, when you give them
-on the commandline, are urls.  In general, you
-specify the host and a port (the port-number is required), and put
-the service-name at the end of the url.:</p>
-<blockquote><pre>
-http://myhost:80/pprof/heap            # retrieves a heap profile
-http://myhost:8008/pprof/profile       # retrieves a CPU profile
-http://myhost:80                       # retrieves a CPU profile (the default)
-http://myhost:8080/                    # retrieves a CPU profile (the default)
-myhost:8088/pprof/growth               # "http://" is optional, but port is not
-http://myhost:80/myservice/pprof/heap  # /pprof/heap just has to come at the end
-http://myhost:80/pprof/pmuprofile      # CPU profile using performance counters
-</pre></blockquote>
-
-<h2> <code><b>/pprof/heap</b></code> </h2>
-
-<p><code>pprof</code> asks for the url <code>/pprof/heap</code> to
-get heap information.  The actual url is controlled via the variable
-<code>HEAP_PAGE</code> in the <code>pprof</code> script, so you
-can change it if you'd like.</p>
-
-<p>There are two ways to get this data.  The first is to call</p>
-<pre>
-    MallocExtension::instance()->GetHeapSample(&output);
-</pre>
-<p>and have the server send <code>output</code> back as an HTTP
-response to <code>pprof</code>.  <code>MallocExtension</code> is
-defined in the header file <code>gperftools/malloc_extension.h</code>.</p>
-
-<p>Note this will only only work if the binary is being run with
-sampling turned on (which is not the default).  To do this, set the
-environment variable <code>TCMALLOC_SAMPLE_PARAMETER</code> to a
-positive value, such as 524288, before running.</p>
-
-<p>The other way is to call <code>HeapProfileStart(filename)</code>
-(from <code>heap-profiler.h</code>), continue to do work, and then,
-some number of seconds later, call <code>GetHeapProfile()</code>
-(followed by <code>HeapProfilerStop()</code>).  The server can send
-the output of <code>GetHeapProfile</code> back as the HTTP response to
-pprof.  (Note you must <code>free()</code> this data after using it.)
-This is similar to how <A HREF="#profile">profile requests</A> are
-handled, below.  This technique does not require the application to
-run with sampling turned on.</p>
-
-<p>Here's an example of what the output should look like:</p>
-<pre>
-heap profile:   1923: 127923432 [  1923: 127923432] @ heap_v2/524288
-     1:      312 [     1:      312] @ 0x2aaaabaf5ccc 0x2aaaaba4cd2c 0x2aaaac08c09a
-   928: 122586016 [   928: 122586016] @ 0x2aaaabaf682c 0x400680 0x400bdd 0x2aaaab1c368a 0x2aaaab1c8f77 0x2aaaab1c0396 0x2aaaab1c86ed 0x4007ff 0x2aaaaca62afa
-     1:       16 [     1:       16] @ 0x2aaaabaf5ccc 0x2aaaabb04bac 0x2aaaabc1b262 0x2aaaabc21496 0x2aaaabc214bb
-[...]
-</pre>
-
-
-<p> Older code may produce "version 1" heap profiles which look like this:<p/>
-<pre>
-heap profile:  14933: 791700132 [ 14933: 791700132] @ heap
-     1:   848688 [     1:   848688] @ 0xa4b142 0x7f5bfc 0x87065e 0x4056e9 0x4125f8 0x42b4f1 0x45b1ba 0x463248 0x460871 0x45cb7c 0x5f1744 0x607cee 0x5f4a5e 0x40080f 0x2aaaabad7afa
-     1:  1048576 [     1:  1048576] @ 0xa4a9b2 0x7fd025 0x4ca6d8 0x4ca814 0x4caa88 0x2aaaab104cf0 0x404e20 0x4125f8 0x42b4f1 0x45b1ba 0x463248 0x460871 0x45cb7c 0x5f1744 0x607cee 0x5f4a5e 0x40080f 0x2aaaabad7afa
-  2942: 388629374 [  2942: 388629374] @ 0xa4b142 0x4006a0 0x400bed 0x5f0cfa 0x5f1744 0x607cee 0x5f4a5e 0x40080f 0x2aaaabad7afa
-[...]
-</pre>
-<p>pprof accepts both old and new heap profiles and automatically
-detects which one you are using.</p>
-
-<h2> <code><b>/pprof/growth</b></code> </h2>
-
-<p><code>pprof</code> asks for the url <code>/pprof/growth</code> to
-get heap-profiling delta (growth) information.  The actual url is
-controlled via the variable <code>GROWTH_PAGE</code> in the
-<code>pprof</code> script, so you can change it if you'd like.</p>
-
-<p>The server should respond by calling</p>
-<pre>
-    MallocExtension::instance()->GetHeapGrowthStacks(&output);
-</pre>
-<p>and sending <code>output</code> back as an HTTP response to
-<code>pprof</code>.  <code>MallocExtension</code> is defined in the
-header file <code>gperftools/malloc_extension.h</code>.</p>
-
-<p>Here's an example, from an actual Google webserver, of what the
-output should look like:</p>
-<pre>
-heap profile:    741: 812122112 [   741: 812122112] @ growth
-     1:  1572864 [     1:  1572864] @ 0x87da564 0x87db8a3 0x84787a4 0x846e851 0x836d12f 0x834cd1c 0x8349ba5 0x10a3177 0x8349961
-     1:  1048576 [     1:  1048576] @ 0x87d92e8 0x87d9213 0x87d9178 0x87d94d3 0x87da9da 0x8a364ff 0x8a437e7 0x8ab7d23 0x8ab7da9 0x8ac7454 0x8348465 0x10a3161 0x8349961
-[...]
-</pre>
-
-
-<h2> <A NAME="profile"><code><b>/pprof/profile</b></code></A> </h2>
-
-<p><code>pprof</code> asks for the url
-<code>/pprof/profile?seconds=XX</code> to get cpu-profiling
-information.  The actual url is controlled via the variable
-<code>PROFILE_PAGE</code> in the <code>pprof</code> script, so you can
-change it if you'd like.</p>
-
-<p>The server should respond by calling
-<code>ProfilerStart(filename)</code>, continuing to do its work, and
-then, XX seconds later, calling <code>ProfilerStop()</code>.  (These
-functions are declared in <code>gperftools/profiler.h</code>.)  The
-application is responsible for picking a unique filename for
-<code>ProfilerStart()</code>.  After calling
-<code>ProfilerStop()</code>, the server should read the contents of
-<code>filename</code> and send them back as an HTTP response to
-<code>pprof</code>.</p>
-
-<p>Obviously, to get useful profile information the application must
-continue to run in the XX seconds that the profiler is running.  Thus,
-the profile start-stop calls should be done in a separate thread, or
-be otherwise non-blocking.</p>
-
-<p>The profiler output file is binary, but near the end of it, it
-should have lines of text somewhat like this:</p>
-<pre>
-01016000-01017000 rw-p 00015000 03:01 59314      /lib/ld-2.2.2.so
-</pre>
-
-<h2> <code><b>/pprof/pmuprofile</b></code> </h2>
-
-<code>pprof</code> asks for a url of the form
-<code>/pprof/pmuprofile?event=hw_event:unit_mask&period=nnn&seconds=xxx</code> 
-to get cpu-profiling information.  The actual url is controlled via the variable
-<code>PMUPROFILE_PAGE</code> in the <code>pprof</code> script, so you can
-change it if you'd like.</p> 
-
-<p>
-This is similar to pprof, but is meant to be used with your CPU's hardware 
-performance counters. The server could be implemented on top of a library 
-such as <a href="http://perfmon2.sourceforge.net/">
-<code>libpfm</code></a>. It should collect a sample every nnn occurrences 
-of the event and stop the sampling after xxx seconds. Much of the code 
-for <code>/pprof/profile</code> can be reused for this purpose.
-</p>
-
-<p>The server side routines (the equivalent of
-ProfilerStart/ProfilerStart) are not available as part of perftools,
-so this URL is unlikely to be that useful.</p>
-
-<h2> <code><b>/pprof/contention</b></code> </h2>
-
-<p>This is intended to be able to profile (thread) lock contention in
-addition to CPU and memory use.  It's not yet usable.</p>
-
-
-<h2> <code><b>/pprof/cmdline</b></code> </h2>
-
-<p><code>pprof</code> asks for the url <code>/pprof/cmdline</code> to
-figure out what application it's profiling.  The actual url is
-controlled via the variable <code>PROGRAM_NAME_PAGE</code> in the
-<code>pprof</code> script, so you can change it if you'd like.</p>
-
-<p>The server should respond by reading the contents of
-<code>/proc/self/cmdline</code>, converting all internal NUL (\0)
-characters to newlines, and sending the result back as an HTTP
-response to <code>pprof</code>.</p>
-
-<p>Here's an example return value:<p>
-<pre>
-/root/server/custom_webserver
-80
---configfile=/root/server/ws.config
-</pre>
-
-
-<h2> <code><b>/pprof/symbol</b></code> </h2>
-
-<p><code>pprof</code> asks for the url <code>/pprof/symbol</code> to
-map from hex addresses to variable names.  The actual url is
-controlled via the variable <code>SYMBOL_PAGE</code> in the
-<code>pprof</code> script, so you can change it if you'd like.</p>
-
-<p>When the server receives a GET request for
-<code>/pprof/symbol</code>, it should return a line formatted like
-so:</p>
-<pre>
-   num_symbols: ###
-</pre>
-<p>where <code>###</code> is the number of symbols found in the
-binary.  (For now, the only important distinction is whether the value
-is 0, which it is for executables that lack debug information, or
-not-0).</p>
-
-<p>This is perhaps the hardest request to write code for, because in
-addition to the GET request for this url, the server must accept POST
-requests.  This means that after the HTTP headers, pprof will pass in
-a list of hex addresses connected by <code>+</code>, like so:</p>
-<pre>
-   curl -d '0x0824d061+0x0824d1cf' http://remote_host:80/pprof/symbol
-</pre>
-
-<p>The server should read the POST data, which will be in one line,
-and for each hex value, should write one line of output to the output
-stream, like so:</p>
-<pre>
-&lt;hex address&gt;&lt;tab&gt;&lt;function name&gt;
-</pre>
-<p>For instance:</p>
-<pre>
-0x08b2dabd    _Update
-</pre>
-
-<p>The other reason this is the most difficult request to implement,
-is that the application will have to figure out for itself how to map
-from address to function name.  One possibility is to run <code>nm -C
--n &lt;program name&gt;</code> to get the mappings at
-program-compile-time.  Another, at least on Linux, is to call out to
-addr2line for every <code>pprof/symbol</code> call, for instance
-<code>addr2line -Cfse /proc/<getpid>/exe 0x12345678 0x876543210</code>
-(presumably with some caching!)</p>
-
-<p><code>pprof</code> itself does just this for local profiles (not
-ones that talk to remote servers); look at the subroutine
-<code>GetProcedureBoundaries</code>.</p>
-
-
-<hr>
-Last modified: Mon Jun 12 21:30:14 PDT 2006
-</body>
-</html>
diff --git a/third_party/tcmalloc/vendor/docs/spanmap.dot b/third_party/tcmalloc/vendor/docs/spanmap.dot
deleted file mode 100644
index 3cb42abe..0000000
--- a/third_party/tcmalloc/vendor/docs/spanmap.dot
+++ /dev/null
@@ -1,22 +0,0 @@
-digraph SpanMap {
-node [shape=box, width=0.3, height=0.3]
-nodesep=.05
-
-map [shape=record, width=6, label="<f0>|<f1>|<f2>|<f3>|<f4>|<f5>|<f6>|<f7>|<f8>|<f9>|<f10>"]
-S0 [label="a"]
-S1 [label="b"]
-S2 [label="c"]
-S3 [label="d"]
-map:f0 -> S0
-map:f1 -> S0
-map:f2 -> S1
-map:f3 -> S2
-map:f4 -> S2
-map:f5 -> S2
-map:f6 -> S2
-map:f7 -> S2
-map:f8 -> S3
-map:f9 -> S3
-map:f10 -> S3
-
-}
diff --git a/third_party/tcmalloc/vendor/docs/spanmap.gif b/third_party/tcmalloc/vendor/docs/spanmap.gif
deleted file mode 100644
index a0627f6..0000000
--- a/third_party/tcmalloc/vendor/docs/spanmap.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/t-test1.times.txt b/third_party/tcmalloc/vendor/docs/t-test1.times.txt
deleted file mode 100644
index 0163693..0000000
--- a/third_party/tcmalloc/vendor/docs/t-test1.times.txt
+++ /dev/null
@@ -1,480 +0,0 @@
-time.1.ptmalloc.64:0.56 user 0.02 system 0.57 elapsed 100% CPU
-time.1.tcmalloc.64:0.38 user 0.02 system 0.40 elapsed 98% CPU
-time.1.ptmalloc.128:0.61 user 0.01 system 0.61 elapsed 101% CPU
-time.1.tcmalloc.128:0.35 user 0.00 system 0.35 elapsed 99% CPU
-time.1.ptmalloc.256:0.59 user 0.01 system 0.60 elapsed 100% CPU
-time.1.tcmalloc.256:0.27 user 0.02 system 0.28 elapsed 102% CPU
-time.1.ptmalloc.512:0.57 user 0.00 system 0.57 elapsed 100% CPU
-time.1.tcmalloc.512:0.25 user 0.01 system 0.25 elapsed 101% CPU
-time.1.ptmalloc.1024:0.52 user 0.00 system 0.52 elapsed 99% CPU
-time.1.tcmalloc.1024:0.22 user 0.02 system 0.24 elapsed 97% CPU
-time.1.ptmalloc.2048:0.47 user 0.00 system 0.47 elapsed 99% CPU
-time.1.tcmalloc.2048:0.22 user 0.02 system 0.25 elapsed 95% CPU
-time.1.ptmalloc.4096:0.48 user 0.01 system 0.48 elapsed 100% CPU
-time.1.tcmalloc.4096:0.25 user 0.01 system 0.25 elapsed 100% CPU
-time.1.ptmalloc.8192:0.49 user 0.02 system 0.49 elapsed 102% CPU
-time.1.tcmalloc.8192:0.27 user 0.02 system 0.28 elapsed 101% CPU
-time.1.ptmalloc.16384:0.51 user 0.04 system 0.55 elapsed 99% CPU
-time.1.tcmalloc.16384:0.35 user 0.02 system 0.37 elapsed 100% CPU
-time.1.ptmalloc.32768:0.53 user 0.14 system 0.66 elapsed 100% CPU
-time.1.tcmalloc.32768:0.67 user 0.02 system 0.69 elapsed 99% CPU
-time.1.ptmalloc.65536:0.68 user 0.31 system 0.98 elapsed 100% CPU
-time.1.tcmalloc.65536:0.71 user 0.01 system 0.72 elapsed 99% CPU
-time.1.ptmalloc.131072:0.90 user 0.72 system 1.62 elapsed 99% CPU
-time.1.tcmalloc.131072:0.94 user 0.03 system 0.97 elapsed 99% CPU
-time.2.ptmalloc.64:1.05 user 0.00 system 0.53 elapsed 196% CPU
-time.2.tcmalloc.64:0.66 user 0.03 system 0.37 elapsed 185% CPU
-time.2.ptmalloc.128:1.77 user 0.01 system 0.89 elapsed 198% CPU
-time.2.tcmalloc.128:0.53 user 0.01 system 0.29 elapsed 184% CPU
-time.2.ptmalloc.256:1.14 user 0.01 system 0.62 elapsed 182% CPU
-time.2.tcmalloc.256:0.45 user 0.02 system 0.26 elapsed 180% CPU
-time.2.ptmalloc.512:1.26 user 0.40 system 1.79 elapsed 92% CPU
-time.2.tcmalloc.512:0.43 user 0.02 system 0.27 elapsed 166% CPU
-time.2.ptmalloc.1024:0.98 user 0.03 system 0.56 elapsed 179% CPU
-time.2.tcmalloc.1024:0.44 user 0.02 system 0.34 elapsed 134% CPU
-time.2.ptmalloc.2048:0.87 user 0.02 system 0.44 elapsed 199% CPU
-time.2.tcmalloc.2048:0.49 user 0.02 system 0.34 elapsed 148% CPU
-time.2.ptmalloc.4096:0.92 user 0.03 system 0.48 elapsed 196% CPU
-time.2.tcmalloc.4096:0.50 user 0.02 system 0.49 elapsed 105% CPU
-time.2.ptmalloc.8192:1.05 user 0.04 system 0.55 elapsed 196% CPU
-time.2.tcmalloc.8192:0.59 user 0.01 system 0.51 elapsed 116% CPU
-time.2.ptmalloc.16384:1.30 user 0.14 system 0.72 elapsed 198% CPU
-time.2.tcmalloc.16384:0.63 user 0.03 system 0.68 elapsed 96% CPU
-time.2.ptmalloc.32768:1.33 user 0.56 system 1.00 elapsed 189% CPU
-time.2.tcmalloc.32768:1.16 user 0.01 system 1.17 elapsed 99% CPU
-time.2.ptmalloc.65536:1.86 user 1.79 system 2.01 elapsed 181% CPU
-time.2.tcmalloc.65536:1.35 user 0.01 system 1.35 elapsed 100% CPU
-time.2.ptmalloc.131072:2.61 user 5.19 system 4.81 elapsed 162% CPU
-time.2.tcmalloc.131072:1.86 user 0.04 system 1.90 elapsed 100% CPU
-time.3.ptmalloc.64:1.79 user 0.03 system 0.67 elapsed 268% CPU
-time.3.tcmalloc.64:1.58 user 0.04 system 0.62 elapsed 260% CPU
-time.3.ptmalloc.128:2.77 user 1.34 system 3.07 elapsed 133% CPU
-time.3.tcmalloc.128:1.19 user 0.01 system 0.50 elapsed 236% CPU
-time.3.ptmalloc.256:2.14 user 0.02 system 0.85 elapsed 252% CPU
-time.3.tcmalloc.256:0.96 user 0.01 system 0.41 elapsed 236% CPU
-time.3.ptmalloc.512:3.37 user 1.31 system 3.33 elapsed 140% CPU
-time.3.tcmalloc.512:0.93 user 0.04 system 0.39 elapsed 243% CPU
-time.3.ptmalloc.1024:1.66 user 0.01 system 0.64 elapsed 260% CPU
-time.3.tcmalloc.1024:0.81 user 0.02 system 0.44 elapsed 187% CPU
-time.3.ptmalloc.2048:2.07 user 0.01 system 0.82 elapsed 252% CPU
-time.3.tcmalloc.2048:1.10 user 0.04 system 0.59 elapsed 191% CPU
-time.3.ptmalloc.4096:2.01 user 0.03 system 0.79 elapsed 258% CPU
-time.3.tcmalloc.4096:0.87 user 0.03 system 0.65 elapsed 137% CPU
-time.3.ptmalloc.8192:2.22 user 0.11 system 0.83 elapsed 280% CPU
-time.3.tcmalloc.8192:0.96 user 0.06 system 0.75 elapsed 135% CPU
-time.3.ptmalloc.16384:2.56 user 0.47 system 1.02 elapsed 295% CPU
-time.3.tcmalloc.16384:0.99 user 0.04 system 1.03 elapsed 99% CPU
-time.3.ptmalloc.32768:3.29 user 1.75 system 1.96 elapsed 256% CPU
-time.3.tcmalloc.32768:1.67 user 0.02 system 1.69 elapsed 99% CPU
-time.3.ptmalloc.65536:4.04 user 6.62 system 4.92 elapsed 216% CPU
-time.3.tcmalloc.65536:1.91 user 0.02 system 1.98 elapsed 97% CPU
-time.3.ptmalloc.131072:5.55 user 17.86 system 12.44 elapsed 188% CPU
-time.3.tcmalloc.131072:2.78 user 0.02 system 2.82 elapsed 99% CPU
-time.4.ptmalloc.64:3.42 user 1.36 system 3.20 elapsed 149% CPU
-time.4.tcmalloc.64:2.42 user 0.02 system 0.71 elapsed 341% CPU
-time.4.ptmalloc.128:3.98 user 1.79 system 3.89 elapsed 148% CPU
-time.4.tcmalloc.128:1.87 user 0.02 system 0.58 elapsed 325% CPU
-time.4.ptmalloc.256:4.06 user 2.14 system 4.12 elapsed 150% CPU
-time.4.tcmalloc.256:1.69 user 0.02 system 0.51 elapsed 331% CPU
-time.4.ptmalloc.512:4.48 user 2.15 system 4.39 elapsed 150% CPU
-time.4.tcmalloc.512:1.62 user 0.03 system 0.52 elapsed 314% CPU
-time.4.ptmalloc.1024:3.18 user 0.03 system 0.84 elapsed 381% CPU
-time.4.tcmalloc.1024:1.53 user 0.02 system 0.56 elapsed 274% CPU
-time.4.ptmalloc.2048:3.24 user 0.02 system 0.84 elapsed 384% CPU
-time.4.tcmalloc.2048:1.44 user 0.04 system 0.66 elapsed 221% CPU
-time.4.ptmalloc.4096:3.50 user 0.04 system 0.91 elapsed 389% CPU
-time.4.tcmalloc.4096:1.31 user 0.01 system 0.89 elapsed 148% CPU
-time.4.ptmalloc.8192:6.77 user 3.85 system 4.14 elapsed 256% CPU
-time.4.tcmalloc.8192:1.20 user 0.05 system 0.97 elapsed 127% CPU
-time.4.ptmalloc.16384:7.08 user 5.06 system 4.63 elapsed 262% CPU
-time.4.tcmalloc.16384:1.27 user 0.03 system 1.25 elapsed 103% CPU
-time.4.ptmalloc.32768:5.57 user 4.22 system 3.31 elapsed 295% CPU
-time.4.tcmalloc.32768:2.17 user 0.03 system 2.25 elapsed 97% CPU
-time.4.ptmalloc.65536:6.11 user 15.05 system 9.19 elapsed 230% CPU
-time.4.tcmalloc.65536:2.51 user 0.02 system 2.57 elapsed 98% CPU
-time.4.ptmalloc.131072:7.58 user 33.15 system 21.28 elapsed 191% CPU
-time.4.tcmalloc.131072:3.57 user 0.07 system 3.66 elapsed 99% CPU
-time.5.ptmalloc.64:4.44 user 2.08 system 4.37 elapsed 148% CPU
-time.5.tcmalloc.64:2.87 user 0.02 system 0.79 elapsed 361% CPU
-time.5.ptmalloc.128:4.77 user 2.77 system 5.14 elapsed 146% CPU
-time.5.tcmalloc.128:2.65 user 0.03 system 0.72 elapsed 367% CPU
-time.5.ptmalloc.256:5.82 user 2.88 system 5.49 elapsed 158% CPU
-time.5.tcmalloc.256:2.33 user 0.01 system 0.66 elapsed 352% CPU
-time.5.ptmalloc.512:6.27 user 3.11 system 5.34 elapsed 175% CPU
-time.5.tcmalloc.512:2.14 user 0.03 system 0.70 elapsed 307% CPU
-time.5.ptmalloc.1024:6.82 user 3.18 system 5.23 elapsed 191% CPU
-time.5.tcmalloc.1024:2.20 user 0.02 system 0.70 elapsed 313% CPU
-time.5.ptmalloc.2048:6.57 user 3.46 system 5.22 elapsed 192% CPU
-time.5.tcmalloc.2048:2.15 user 0.03 system 0.82 elapsed 264% CPU
-time.5.ptmalloc.4096:8.75 user 5.09 system 5.26 elapsed 263% CPU
-time.5.tcmalloc.4096:1.68 user 0.03 system 1.08 elapsed 158% CPU
-time.5.ptmalloc.8192:4.48 user 0.61 system 1.51 elapsed 335% CPU
-time.5.tcmalloc.8192:1.47 user 0.07 system 1.18 elapsed 129% CPU
-time.5.ptmalloc.16384:5.71 user 1.98 system 2.14 elapsed 358% CPU
-time.5.tcmalloc.16384:1.58 user 0.03 system 1.52 elapsed 105% CPU
-time.5.ptmalloc.32768:7.19 user 7.81 system 5.53 elapsed 270% CPU
-time.5.tcmalloc.32768:2.63 user 0.05 system 2.72 elapsed 98% CPU
-time.5.ptmalloc.65536:8.45 user 23.51 system 14.30 elapsed 223% CPU
-time.5.tcmalloc.65536:3.12 user 0.05 system 3.21 elapsed 98% CPU
-time.5.ptmalloc.131072:10.22 user 43.63 system 27.84 elapsed 193% CPU
-time.5.tcmalloc.131072:4.42 user 0.07 system 4.51 elapsed 99% CPU
-time.6.ptmalloc.64:5.57 user 2.56 system 5.08 elapsed 159% CPU
-time.6.tcmalloc.64:3.20 user 0.01 system 0.89 elapsed 360% CPU
-time.6.ptmalloc.128:5.98 user 3.52 system 5.71 elapsed 166% CPU
-time.6.tcmalloc.128:2.76 user 0.02 system 0.78 elapsed 355% CPU
-time.6.ptmalloc.256:4.61 user 0.02 system 1.19 elapsed 389% CPU
-time.6.tcmalloc.256:2.65 user 0.02 system 0.74 elapsed 356% CPU
-time.6.ptmalloc.512:8.28 user 3.88 system 6.61 elapsed 183% CPU
-time.6.tcmalloc.512:2.60 user 0.02 system 0.72 elapsed 362% CPU
-time.6.ptmalloc.1024:4.75 user 0.00 system 1.22 elapsed 387% CPU
-time.6.tcmalloc.1024:2.56 user 0.02 system 0.79 elapsed 325% CPU
-time.6.ptmalloc.2048:8.90 user 4.59 system 6.15 elapsed 219% CPU
-time.6.tcmalloc.2048:2.37 user 0.06 system 0.96 elapsed 250% CPU
-time.6.ptmalloc.4096:11.41 user 7.02 system 6.31 elapsed 291% CPU
-time.6.tcmalloc.4096:1.82 user 0.03 system 1.19 elapsed 154% CPU
-time.6.ptmalloc.8192:11.64 user 8.25 system 5.97 elapsed 332% CPU
-time.6.tcmalloc.8192:1.83 user 0.07 system 1.38 elapsed 136% CPU
-time.6.ptmalloc.16384:7.44 user 2.98 system 3.01 elapsed 345% CPU
-time.6.tcmalloc.16384:1.83 user 0.08 system 1.80 elapsed 105% CPU
-time.6.ptmalloc.32768:8.69 user 12.35 system 8.04 elapsed 261% CPU
-time.6.tcmalloc.32768:3.14 user 0.06 system 3.24 elapsed 98% CPU
-time.6.ptmalloc.65536:10.52 user 35.43 system 20.75 elapsed 221% CPU
-time.6.tcmalloc.65536:3.62 user 0.03 system 3.72 elapsed 98% CPU
-time.6.ptmalloc.131072:11.74 user 59.00 system 36.93 elapsed 191% CPU
-time.6.tcmalloc.131072:5.33 user 0.04 system 5.42 elapsed 98% CPU
-time.7.ptmalloc.64:6.60 user 3.45 system 6.01 elapsed 167% CPU
-time.7.tcmalloc.64:3.50 user 0.04 system 0.94 elapsed 376% CPU
-time.7.ptmalloc.128:7.09 user 4.25 system 6.69 elapsed 169% CPU
-time.7.tcmalloc.128:3.13 user 0.03 system 0.84 elapsed 374% CPU
-time.7.ptmalloc.256:9.28 user 4.85 system 7.20 elapsed 196% CPU
-time.7.tcmalloc.256:3.06 user 0.02 system 0.82 elapsed 375% CPU
-time.7.ptmalloc.512:9.13 user 4.78 system 6.79 elapsed 204% CPU
-time.7.tcmalloc.512:2.99 user 0.03 system 0.83 elapsed 359% CPU
-time.7.ptmalloc.1024:10.85 user 6.41 system 7.52 elapsed 229% CPU
-time.7.tcmalloc.1024:3.05 user 0.04 system 0.89 elapsed 345% CPU
-time.7.ptmalloc.2048:5.65 user 0.08 system 1.47 elapsed 388% CPU
-time.7.tcmalloc.2048:3.01 user 0.01 system 0.98 elapsed 306% CPU
-time.7.ptmalloc.4096:6.09 user 0.08 system 1.58 elapsed 389% CPU
-time.7.tcmalloc.4096:2.25 user 0.03 system 1.32 elapsed 171% CPU
-time.7.ptmalloc.8192:6.73 user 0.85 system 1.99 elapsed 379% CPU
-time.7.tcmalloc.8192:2.22 user 0.08 system 1.61 elapsed 142% CPU
-time.7.ptmalloc.16384:8.87 user 4.66 system 4.04 elapsed 334% CPU
-time.7.tcmalloc.16384:2.07 user 0.07 system 2.07 elapsed 103% CPU
-time.7.ptmalloc.32768:10.61 user 17.85 system 11.22 elapsed 253% CPU
-time.7.tcmalloc.32768:3.68 user 0.06 system 3.79 elapsed 98% CPU
-time.7.ptmalloc.65536:13.05 user 45.97 system 27.28 elapsed 216% CPU
-time.7.tcmalloc.65536:4.16 user 0.07 system 4.31 elapsed 98% CPU
-time.7.ptmalloc.131072:13.22 user 62.67 system 41.33 elapsed 183% CPU
-time.7.tcmalloc.131072:6.10 user 0.06 system 6.25 elapsed 98% CPU
-time.8.ptmalloc.64:7.31 user 3.92 system 6.39 elapsed 175% CPU
-time.8.tcmalloc.64:4.00 user 0.01 system 1.04 elapsed 383% CPU
-time.8.ptmalloc.128:9.40 user 5.41 system 7.67 elapsed 192% CPU
-time.8.tcmalloc.128:3.61 user 0.02 system 0.94 elapsed 386% CPU
-time.8.ptmalloc.256:10.61 user 6.35 system 7.96 elapsed 212% CPU
-time.8.tcmalloc.256:3.30 user 0.02 system 0.99 elapsed 335% CPU
-time.8.ptmalloc.512:12.42 user 7.10 system 8.79 elapsed 221% CPU
-time.8.tcmalloc.512:3.35 user 0.04 system 0.94 elapsed 358% CPU
-time.8.ptmalloc.1024:13.63 user 8.54 system 8.95 elapsed 247% CPU
-time.8.tcmalloc.1024:3.44 user 0.02 system 0.96 elapsed 359% CPU
-time.8.ptmalloc.2048:6.45 user 0.03 system 1.67 elapsed 386% CPU
-time.8.tcmalloc.2048:3.55 user 0.05 system 1.09 elapsed 328% CPU
-time.8.ptmalloc.4096:6.83 user 0.26 system 1.80 elapsed 393% CPU
-time.8.tcmalloc.4096:2.78 user 0.06 system 1.53 elapsed 185% CPU
-time.8.ptmalloc.8192:7.59 user 1.29 system 2.36 elapsed 376% CPU
-time.8.tcmalloc.8192:2.57 user 0.07 system 1.84 elapsed 142% CPU
-time.8.ptmalloc.16384:10.15 user 6.20 system 5.20 elapsed 314% CPU
-time.8.tcmalloc.16384:2.40 user 0.05 system 2.42 elapsed 101% CPU
-time.8.ptmalloc.32768:11.82 user 24.48 system 14.60 elapsed 248% CPU
-time.8.tcmalloc.32768:4.37 user 0.05 system 4.47 elapsed 98% CPU
-time.8.ptmalloc.65536:15.41 user 58.94 system 34.42 elapsed 215% CPU
-time.8.tcmalloc.65536:4.90 user 0.04 system 4.96 elapsed 99% CPU
-time.8.ptmalloc.131072:16.07 user 82.93 system 52.51 elapsed 188% CPU
-time.8.tcmalloc.131072:7.13 user 0.04 system 7.19 elapsed 99% CPU
-time.9.ptmalloc.64:8.44 user 4.59 system 6.92 elapsed 188% CPU
-time.9.tcmalloc.64:4.00 user 0.02 system 1.05 elapsed 382% CPU
-time.9.ptmalloc.128:10.92 user 6.14 system 8.31 elapsed 205% CPU
-time.9.tcmalloc.128:3.88 user 0.02 system 1.01 elapsed 382% CPU
-time.9.ptmalloc.256:13.01 user 7.75 system 9.12 elapsed 227% CPU
-time.9.tcmalloc.256:3.89 user 0.01 system 1.00 elapsed 386% CPU
-time.9.ptmalloc.512:14.96 user 8.89 system 9.73 elapsed 244% CPU
-time.9.tcmalloc.512:3.80 user 0.03 system 1.01 elapsed 377% CPU
-time.9.ptmalloc.1024:15.42 user 10.20 system 9.80 elapsed 261% CPU
-time.9.tcmalloc.1024:3.86 user 0.03 system 1.19 elapsed 325% CPU
-time.9.ptmalloc.2048:7.24 user 0.02 system 1.87 elapsed 388% CPU
-time.9.tcmalloc.2048:3.98 user 0.05 system 1.26 elapsed 319% CPU
-time.9.ptmalloc.4096:7.96 user 0.18 system 2.06 elapsed 394% CPU
-time.9.tcmalloc.4096:3.27 user 0.04 system 1.69 elapsed 195% CPU
-time.9.ptmalloc.8192:9.00 user 1.63 system 2.79 elapsed 380% CPU
-time.9.tcmalloc.8192:3.00 user 0.06 system 2.05 elapsed 148% CPU
-time.9.ptmalloc.16384:12.07 user 8.13 system 6.55 elapsed 308% CPU
-time.9.tcmalloc.16384:2.85 user 0.05 system 2.75 elapsed 105% CPU
-time.9.ptmalloc.32768:13.99 user 29.65 system 18.02 elapsed 242% CPU
-time.9.tcmalloc.32768:4.98 user 0.06 system 5.13 elapsed 98% CPU
-time.9.ptmalloc.65536:16.89 user 70.42 system 42.11 elapsed 207% CPU
-time.9.tcmalloc.65536:5.55 user 0.04 system 5.65 elapsed 98% CPU
-time.9.ptmalloc.131072:18.53 user 94.11 system 61.17 elapsed 184% CPU
-time.9.tcmalloc.131072:8.06 user 0.04 system 8.16 elapsed 99% CPU
-time.10.ptmalloc.64:9.81 user 5.70 system 7.42 elapsed 208% CPU
-time.10.tcmalloc.64:4.43 user 0.03 system 1.20 elapsed 370% CPU
-time.10.ptmalloc.128:12.69 user 7.81 system 9.02 elapsed 227% CPU
-time.10.tcmalloc.128:4.27 user 0.02 system 1.13 elapsed 378% CPU
-time.10.ptmalloc.256:15.04 user 9.53 system 9.92 elapsed 247% CPU
-time.10.tcmalloc.256:4.23 user 0.02 system 1.09 elapsed 388% CPU
-time.10.ptmalloc.512:17.30 user 10.46 system 10.61 elapsed 261% CPU
-time.10.tcmalloc.512:4.14 user 0.05 system 1.10 elapsed 379% CPU
-time.10.ptmalloc.1024:16.96 user 9.38 system 9.30 elapsed 283% CPU
-time.10.tcmalloc.1024:4.27 user 0.06 system 1.18 elapsed 366% CPU
-time.10.ptmalloc.2048:8.07 user 0.03 system 2.06 elapsed 393% CPU
-time.10.tcmalloc.2048:4.49 user 0.07 system 1.33 elapsed 342% CPU
-time.10.ptmalloc.4096:8.66 user 0.25 system 2.25 elapsed 394% CPU
-time.10.tcmalloc.4096:3.61 user 0.05 system 1.78 elapsed 205% CPU
-time.10.ptmalloc.8192:21.52 user 17.43 system 10.41 elapsed 374% CPU
-time.10.tcmalloc.8192:3.59 user 0.10 system 2.33 elapsed 158% CPU
-time.10.ptmalloc.16384:20.55 user 24.85 system 12.55 elapsed 361% CPU
-time.10.tcmalloc.16384:3.29 user 0.04 system 3.22 elapsed 103% CPU
-time.10.ptmalloc.32768:15.23 user 38.13 system 22.49 elapsed 237% CPU
-time.10.tcmalloc.32768:5.62 user 0.05 system 5.72 elapsed 99% CPU
-time.10.ptmalloc.65536:19.80 user 85.42 system 49.98 elapsed 210% CPU
-time.10.tcmalloc.65536:6.23 user 0.09 system 6.36 elapsed 99% CPU
-time.10.ptmalloc.131072:20.91 user 106.97 system 69.08 elapsed 185% CPU
-time.10.tcmalloc.131072:8.94 user 0.09 system 9.09 elapsed 99% CPU
-time.11.ptmalloc.64:10.82 user 6.34 system 7.92 elapsed 216% CPU
-time.11.tcmalloc.64:4.80 user 0.03 system 1.24 elapsed 387% CPU
-time.11.ptmalloc.128:14.58 user 8.61 system 9.81 elapsed 236% CPU
-time.11.tcmalloc.128:4.65 user 0.03 system 1.21 elapsed 384% CPU
-time.11.ptmalloc.256:17.38 user 10.98 system 10.75 elapsed 263% CPU
-time.11.tcmalloc.256:4.51 user 0.03 system 1.18 elapsed 384% CPU
-time.11.ptmalloc.512:19.18 user 11.71 system 10.95 elapsed 282% CPU
-time.11.tcmalloc.512:4.57 user 0.02 system 1.19 elapsed 384% CPU
-time.11.ptmalloc.1024:19.94 user 12.41 system 10.48 elapsed 308% CPU
-time.11.tcmalloc.1024:4.71 user 0.05 system 1.29 elapsed 367% CPU
-time.11.ptmalloc.2048:8.70 user 0.04 system 2.35 elapsed 371% CPU
-time.11.tcmalloc.2048:4.97 user 0.07 system 1.43 elapsed 350% CPU
-time.11.ptmalloc.4096:22.47 user 18.43 system 10.82 elapsed 377% CPU
-time.11.tcmalloc.4096:4.22 user 0.03 system 1.91 elapsed 221% CPU
-time.11.ptmalloc.8192:11.61 user 2.38 system 3.73 elapsed 374% CPU
-time.11.tcmalloc.8192:3.74 user 0.09 system 2.46 elapsed 155% CPU
-time.11.ptmalloc.16384:14.13 user 13.38 system 9.60 elapsed 286% CPU
-time.11.tcmalloc.16384:3.61 user 0.03 system 3.63 elapsed 100% CPU
-time.11.ptmalloc.32768:17.92 user 43.84 system 26.74 elapsed 230% CPU
-time.11.tcmalloc.32768:6.31 user 0.03 system 6.45 elapsed 98% CPU
-time.11.ptmalloc.65536:22.40 user 96.38 system 58.30 elapsed 203% CPU
-time.11.tcmalloc.65536:6.92 user 0.12 system 6.98 elapsed 100% CPU
-time.11.ptmalloc.131072:21.03 user 108.04 system 72.78 elapsed 177% CPU
-time.11.tcmalloc.131072:9.79 user 0.08 system 9.94 elapsed 99% CPU
-time.12.ptmalloc.64:12.23 user 7.16 system 8.38 elapsed 231% CPU
-time.12.tcmalloc.64:5.21 user 0.05 system 1.41 elapsed 371% CPU
-time.12.ptmalloc.128:16.97 user 10.19 system 10.47 elapsed 259% CPU
-time.12.tcmalloc.128:5.10 user 0.02 system 1.31 elapsed 390% CPU
-time.12.ptmalloc.256:19.99 user 12.10 system 11.57 elapsed 277% CPU
-time.12.tcmalloc.256:5.01 user 0.03 system 1.29 elapsed 390% CPU
-time.12.ptmalloc.512:21.85 user 12.66 system 11.46 elapsed 300% CPU
-time.12.tcmalloc.512:5.05 user 0.00 system 1.32 elapsed 379% CPU
-time.12.ptmalloc.1024:9.40 user 0.04 system 2.40 elapsed 393% CPU
-time.12.tcmalloc.1024:5.14 user 0.02 system 1.39 elapsed 369% CPU
-time.12.ptmalloc.2048:9.72 user 0.04 system 2.49 elapsed 391% CPU
-time.12.tcmalloc.2048:5.74 user 0.05 system 1.62 elapsed 355% CPU
-time.12.ptmalloc.4096:10.64 user 0.20 system 2.75 elapsed 393% CPU
-time.12.tcmalloc.4096:4.45 user 0.03 system 2.04 elapsed 218% CPU
-time.12.ptmalloc.8192:12.66 user 3.30 system 4.30 elapsed 371% CPU
-time.12.tcmalloc.8192:4.21 user 0.13 system 2.65 elapsed 163% CPU
-time.12.ptmalloc.16384:15.73 user 15.68 system 11.14 elapsed 281% CPU
-time.12.tcmalloc.16384:4.17 user 0.06 system 4.10 elapsed 102% CPU
-time.12.ptmalloc.32768:19.45 user 56.00 system 32.74 elapsed 230% CPU
-time.12.tcmalloc.32768:6.96 user 0.08 system 7.14 elapsed 98% CPU
-time.12.ptmalloc.65536:23.33 user 110.45 system 65.06 elapsed 205% CPU
-time.12.tcmalloc.65536:7.77 user 0.15 system 7.72 elapsed 102% CPU
-time.12.ptmalloc.131072:24.03 user 124.74 system 82.94 elapsed 179% CPU
-time.12.tcmalloc.131072:10.81 user 0.06 system 10.94 elapsed 99% CPU
-time.13.ptmalloc.64:14.08 user 7.60 system 8.85 elapsed 244% CPU
-time.13.tcmalloc.64:5.51 user 0.01 system 1.47 elapsed 375% CPU
-time.13.ptmalloc.128:18.20 user 10.98 system 10.99 elapsed 265% CPU
-time.13.tcmalloc.128:5.34 user 0.01 system 1.39 elapsed 382% CPU
-time.13.ptmalloc.256:21.48 user 13.94 system 12.25 elapsed 289% CPU
-time.13.tcmalloc.256:5.33 user 0.01 system 1.39 elapsed 381% CPU
-time.13.ptmalloc.512:24.22 user 14.84 system 12.97 elapsed 301% CPU
-time.13.tcmalloc.512:5.49 user 0.02 system 1.41 elapsed 389% CPU
-time.13.ptmalloc.1024:25.26 user 17.03 system 12.85 elapsed 328% CPU
-time.13.tcmalloc.1024:5.65 user 0.04 system 1.50 elapsed 378% CPU
-time.13.ptmalloc.2048:10.41 user 0.03 system 2.69 elapsed 387% CPU
-time.13.tcmalloc.2048:5.93 user 0.10 system 1.77 elapsed 339% CPU
-time.13.ptmalloc.4096:11.37 user 0.52 system 3.04 elapsed 391% CPU
-time.13.tcmalloc.4096:5.08 user 0.11 system 2.22 elapsed 233% CPU
-time.13.ptmalloc.8192:21.76 user 18.54 system 10.58 elapsed 380% CPU
-time.13.tcmalloc.8192:5.04 user 0.16 system 2.93 elapsed 177% CPU
-time.13.ptmalloc.16384:26.35 user 34.47 system 17.01 elapsed 357% CPU
-time.13.tcmalloc.16384:4.66 user 0.04 system 4.66 elapsed 100% CPU
-time.13.ptmalloc.32768:21.41 user 63.59 system 38.14 elapsed 222% CPU
-time.13.tcmalloc.32768:7.71 user 0.03 system 7.83 elapsed 98% CPU
-time.13.ptmalloc.65536:24.99 user 120.80 system 71.59 elapsed 203% CPU
-time.13.tcmalloc.65536:8.87 user 0.64 system 8.37 elapsed 113% CPU
-time.13.ptmalloc.131072:25.97 user 142.27 system 96.00 elapsed 175% CPU
-time.13.tcmalloc.131072:11.48 user 0.06 system 11.67 elapsed 98% CPU
-time.14.ptmalloc.64:15.01 user 9.11 system 9.41 elapsed 256% CPU
-time.14.tcmalloc.64:5.98 user 0.02 system 1.58 elapsed 378% CPU
-time.14.ptmalloc.128:20.34 user 12.72 system 11.62 elapsed 284% CPU
-time.14.tcmalloc.128:5.88 user 0.04 system 1.51 elapsed 392% CPU
-time.14.ptmalloc.256:24.26 user 14.95 system 12.92 elapsed 303% CPU
-time.14.tcmalloc.256:5.72 user 0.02 system 1.50 elapsed 381% CPU
-time.14.ptmalloc.512:27.28 user 16.45 system 13.89 elapsed 314% CPU
-time.14.tcmalloc.512:5.99 user 0.02 system 1.54 elapsed 388% CPU
-time.14.ptmalloc.1024:25.84 user 16.99 system 12.61 elapsed 339% CPU
-time.14.tcmalloc.1024:5.94 user 0.06 system 1.59 elapsed 375% CPU
-time.14.ptmalloc.2048:11.96 user 0.01 system 3.12 elapsed 382% CPU
-time.14.tcmalloc.2048:6.39 user 0.07 system 1.79 elapsed 359% CPU
-time.14.ptmalloc.4096:20.19 user 11.77 system 8.26 elapsed 386% CPU
-time.14.tcmalloc.4096:5.65 user 0.05 system 2.32 elapsed 244% CPU
-time.14.ptmalloc.8192:22.01 user 16.39 system 9.89 elapsed 387% CPU
-time.14.tcmalloc.8192:5.44 user 0.11 system 3.07 elapsed 180% CPU
-time.14.ptmalloc.16384:18.15 user 22.40 system 15.02 elapsed 269% CPU
-time.14.tcmalloc.16384:5.29 user 0.08 system 5.34 elapsed 100% CPU
-time.14.ptmalloc.32768:24.29 user 72.07 system 42.63 elapsed 225% CPU
-time.14.tcmalloc.32768:8.47 user 0.02 system 8.62 elapsed 98% CPU
-time.14.ptmalloc.65536:27.63 user 130.56 system 78.64 elapsed 201% CPU
-time.14.tcmalloc.65536:9.85 user 1.61 system 9.04 elapsed 126% CPU
-time.14.ptmalloc.131072:28.87 user 146.38 system 100.54 elapsed 174% CPU
-time.14.tcmalloc.131072:12.46 user 0.11 system 12.71 elapsed 98% CPU
-time.15.ptmalloc.64:16.25 user 10.05 system 9.82 elapsed 267% CPU
-time.15.tcmalloc.64:6.30 user 0.02 system 1.64 elapsed 385% CPU
-time.15.ptmalloc.128:22.33 user 13.23 system 12.24 elapsed 290% CPU
-time.15.tcmalloc.128:6.08 user 0.03 system 1.59 elapsed 384% CPU
-time.15.ptmalloc.256:26.56 user 16.57 system 13.70 elapsed 314% CPU
-time.15.tcmalloc.256:6.14 user 0.03 system 1.61 elapsed 382% CPU
-time.15.ptmalloc.512:29.68 user 18.08 system 14.56 elapsed 327% CPU
-time.15.tcmalloc.512:6.12 user 0.04 system 1.68 elapsed 364% CPU
-time.15.ptmalloc.1024:17.07 user 6.22 system 6.26 elapsed 371% CPU
-time.15.tcmalloc.1024:6.38 user 0.02 system 1.75 elapsed 364% CPU
-time.15.ptmalloc.2048:26.64 user 17.25 system 11.51 elapsed 381% CPU
-time.15.tcmalloc.2048:6.77 user 0.18 system 1.92 elapsed 361% CPU
-time.15.ptmalloc.4096:13.21 user 0.74 system 3.57 elapsed 390% CPU
-time.15.tcmalloc.4096:6.03 user 0.09 system 2.36 elapsed 258% CPU
-time.15.ptmalloc.8192:22.92 user 17.51 system 10.50 elapsed 385% CPU
-time.15.tcmalloc.8192:5.96 user 0.12 system 3.36 elapsed 180% CPU
-time.15.ptmalloc.16384:19.37 user 24.87 system 16.69 elapsed 264% CPU
-time.15.tcmalloc.16384:5.88 user 0.07 system 5.84 elapsed 101% CPU
-time.15.ptmalloc.32768:25.43 user 82.30 system 48.98 elapsed 219% CPU
-time.15.tcmalloc.32768:9.11 user 0.05 system 9.30 elapsed 98% CPU
-time.15.ptmalloc.65536:29.31 user 140.07 system 83.78 elapsed 202% CPU
-time.15.tcmalloc.65536:8.51 user 1.59 system 9.75 elapsed 103% CPU
-time.15.ptmalloc.131072:30.22 user 163.15 system 109.50 elapsed 176% CPU
-time.15.tcmalloc.131072:13.35 user 0.10 system 13.54 elapsed 99% CPU
-time.16.ptmalloc.64:17.69 user 10.11 system 10.11 elapsed 274% CPU
-time.16.tcmalloc.64:6.63 user 0.04 system 1.72 elapsed 387% CPU
-time.16.ptmalloc.128:23.05 user 14.37 system 12.75 elapsed 293% CPU
-time.16.tcmalloc.128:6.61 user 0.02 system 1.71 elapsed 387% CPU
-time.16.ptmalloc.256:29.11 user 19.35 system 14.57 elapsed 332% CPU
-time.16.tcmalloc.256:6.62 user 0.03 system 1.73 elapsed 382% CPU
-time.16.ptmalloc.512:31.65 user 18.71 system 14.71 elapsed 342% CPU
-time.16.tcmalloc.512:6.63 user 0.04 system 1.73 elapsed 383% CPU
-time.16.ptmalloc.1024:31.99 user 21.22 system 14.87 elapsed 357% CPU
-time.16.tcmalloc.1024:6.81 user 0.04 system 1.79 elapsed 382% CPU
-time.16.ptmalloc.2048:30.35 user 21.36 system 13.30 elapsed 388% CPU
-time.16.tcmalloc.2048:6.91 user 0.50 system 2.01 elapsed 367% CPU
-time.16.ptmalloc.4096:18.85 user 7.18 system 6.61 elapsed 393% CPU
-time.16.tcmalloc.4096:6.70 user 0.10 system 2.62 elapsed 259% CPU
-time.16.ptmalloc.8192:22.19 user 14.30 system 9.37 elapsed 389% CPU
-time.16.tcmalloc.8192:6.18 user 0.19 system 3.58 elapsed 177% CPU
-time.16.ptmalloc.16384:31.22 user 46.78 system 22.92 elapsed 340% CPU
-time.16.tcmalloc.16384:6.79 user 0.07 system 6.86 elapsed 99% CPU
-time.16.ptmalloc.32768:27.31 user 87.32 system 52.00 elapsed 220% CPU
-time.16.tcmalloc.32768:9.85 user 0.06 system 10.07 elapsed 98% CPU
-time.16.ptmalloc.65536:32.83 user 160.62 system 95.67 elapsed 202% CPU
-time.16.tcmalloc.65536:10.18 user 0.09 system 10.41 elapsed 98% CPU
-time.16.ptmalloc.131072:31.99 user 173.41 system 115.98 elapsed 177% CPU
-time.16.tcmalloc.131072:14.52 user 0.05 system 14.67 elapsed 99% CPU
-time.17.ptmalloc.64:19.38 user 11.61 system 10.61 elapsed 291% CPU
-time.17.tcmalloc.64:7.11 user 0.02 system 1.84 elapsed 386% CPU
-time.17.ptmalloc.128:26.25 user 16.15 system 13.53 elapsed 313% CPU
-time.17.tcmalloc.128:6.97 user 0.02 system 1.78 elapsed 390% CPU
-time.17.ptmalloc.256:30.66 user 18.36 system 14.97 elapsed 327% CPU
-time.17.tcmalloc.256:6.94 user 0.04 system 1.80 elapsed 387% CPU
-time.17.ptmalloc.512:33.71 user 22.79 system 15.95 elapsed 354% CPU
-time.17.tcmalloc.512:7.00 user 0.02 system 1.83 elapsed 381% CPU
-time.17.ptmalloc.1024:33.49 user 22.47 system 15.00 elapsed 373% CPU
-time.17.tcmalloc.1024:7.20 user 0.03 system 1.90 elapsed 380% CPU
-time.17.ptmalloc.2048:23.87 user 11.92 system 9.26 elapsed 386% CPU
-time.17.tcmalloc.2048:6.01 user 1.83 system 2.15 elapsed 363% CPU
-time.17.ptmalloc.4096:14.69 user 0.95 system 3.98 elapsed 392% CPU
-time.17.tcmalloc.4096:7.25 user 0.10 system 2.62 elapsed 279% CPU
-time.17.ptmalloc.8192:22.44 user 13.52 system 9.39 elapsed 382% CPU
-time.17.tcmalloc.8192:7.21 user 0.24 system 3.95 elapsed 188% CPU
-time.17.ptmalloc.16384:23.33 user 33.67 system 21.89 elapsed 260% CPU
-time.17.tcmalloc.16384:7.28 user 0.06 system 7.10 elapsed 103% CPU
-time.17.ptmalloc.32768:29.35 user 103.11 system 60.36 elapsed 219% CPU
-time.17.tcmalloc.32768:10.53 user 0.07 system 10.71 elapsed 98% CPU
-time.17.ptmalloc.65536:33.21 user 170.89 system 100.84 elapsed 202% CPU
-time.17.tcmalloc.65536:10.85 user 0.05 system 11.04 elapsed 98% CPU
-time.17.ptmalloc.131072:34.98 user 182.87 system 122.05 elapsed 178% CPU
-time.17.tcmalloc.131072:15.27 user 0.09 system 15.49 elapsed 99% CPU
-time.18.ptmalloc.64:21.08 user 12.15 system 11.43 elapsed 290% CPU
-time.18.tcmalloc.64:7.45 user 0.03 system 1.95 elapsed 383% CPU
-time.18.ptmalloc.128:27.65 user 17.26 system 14.03 elapsed 320% CPU
-time.18.tcmalloc.128:7.46 user 0.03 system 1.92 elapsed 389% CPU
-time.18.ptmalloc.256:32.78 user 20.55 system 15.70 elapsed 339% CPU
-time.18.tcmalloc.256:7.31 user 0.02 system 1.88 elapsed 389% CPU
-time.18.ptmalloc.512:33.31 user 20.06 system 15.05 elapsed 354% CPU
-time.18.tcmalloc.512:7.33 user 0.02 system 1.91 elapsed 383% CPU
-time.18.ptmalloc.1024:35.46 user 24.83 system 16.30 elapsed 369% CPU
-time.18.tcmalloc.1024:7.60 user 0.06 system 2.05 elapsed 373% CPU
-time.18.ptmalloc.2048:19.98 user 6.80 system 6.76 elapsed 395% CPU
-time.18.tcmalloc.2048:6.89 user 1.29 system 2.28 elapsed 357% CPU
-time.18.ptmalloc.4096:15.99 user 0.93 system 4.32 elapsed 391% CPU
-time.18.tcmalloc.4096:7.70 user 0.10 system 2.77 elapsed 280% CPU
-time.18.ptmalloc.8192:23.51 user 14.84 system 9.97 elapsed 384% CPU
-time.18.tcmalloc.8192:8.16 user 0.27 system 4.25 elapsed 197% CPU
-time.18.ptmalloc.16384:35.79 user 52.41 system 26.47 elapsed 333% CPU
-time.18.tcmalloc.16384:7.81 user 0.07 system 7.61 elapsed 103% CPU
-time.18.ptmalloc.32768:33.17 user 116.07 system 68.64 elapsed 217% CPU
-time.18.tcmalloc.32768:11.34 user 0.13 system 11.57 elapsed 99% CPU
-time.18.ptmalloc.65536:35.91 user 177.82 system 106.75 elapsed 200% CPU
-time.18.tcmalloc.65536:11.54 user 0.06 system 11.74 elapsed 98% CPU
-time.18.ptmalloc.131072:36.38 user 187.18 system 126.91 elapsed 176% CPU
-time.18.tcmalloc.131072:16.34 user 0.05 system 16.43 elapsed 99% CPU
-time.19.ptmalloc.64:22.90 user 13.23 system 11.82 elapsed 305% CPU
-time.19.tcmalloc.64:7.81 user 0.02 system 2.01 elapsed 388% CPU
-time.19.ptmalloc.128:30.13 user 18.58 system 14.77 elapsed 329% CPU
-time.19.tcmalloc.128:7.74 user 0.02 system 2.01 elapsed 386% CPU
-time.19.ptmalloc.256:35.33 user 21.41 system 16.35 elapsed 347% CPU
-time.19.tcmalloc.256:7.79 user 0.04 system 2.04 elapsed 382% CPU
-time.19.ptmalloc.512:39.30 user 26.22 system 17.84 elapsed 367% CPU
-time.19.tcmalloc.512:7.80 user 0.06 system 2.05 elapsed 381% CPU
-time.19.ptmalloc.1024:35.70 user 23.90 system 15.66 elapsed 380% CPU
-time.19.tcmalloc.1024:8.08 user 0.06 system 2.16 elapsed 376% CPU
-time.19.ptmalloc.2048:18.33 user 3.28 system 5.47 elapsed 394% CPU
-time.19.tcmalloc.2048:8.71 user 0.05 system 2.40 elapsed 363% CPU
-time.19.ptmalloc.4096:16.94 user 0.89 system 4.64 elapsed 383% CPU
-time.19.tcmalloc.4096:8.21 user 0.07 system 2.85 elapsed 289% CPU
-time.19.ptmalloc.8192:25.61 user 17.15 system 11.33 elapsed 377% CPU
-time.19.tcmalloc.8192:8.79 user 0.30 system 4.58 elapsed 198% CPU
-time.19.ptmalloc.16384:27.11 user 46.66 system 29.67 elapsed 248% CPU
-time.19.tcmalloc.16384:8.64 user 0.05 system 8.58 elapsed 101% CPU
-time.19.ptmalloc.32768:33.80 user 117.69 system 70.65 elapsed 214% CPU
-time.19.tcmalloc.32768:11.88 user 0.07 system 12.04 elapsed 99% CPU
-time.19.ptmalloc.65536:36.90 user 180.21 system 109.01 elapsed 199% CPU
-time.19.tcmalloc.65536:12.17 user 0.07 system 12.40 elapsed 98% CPU
-time.19.ptmalloc.131072:38.50 user 195.15 system 132.81 elapsed 175% CPU
-time.19.tcmalloc.131072:17.44 user 0.10 system 17.65 elapsed 99% CPU
-time.20.ptmalloc.64:23.37 user 13.74 system 11.86 elapsed 312% CPU
-time.20.tcmalloc.64:8.18 user 0.02 system 2.10 elapsed 389% CPU
-time.20.ptmalloc.128:31.29 user 19.97 system 15.53 elapsed 329% CPU
-time.20.tcmalloc.128:8.03 user 0.02 system 2.12 elapsed 378% CPU
-time.20.ptmalloc.256:38.40 user 25.65 system 18.25 elapsed 350% CPU
-time.20.tcmalloc.256:8.05 user 0.05 system 2.12 elapsed 380% CPU
-time.20.ptmalloc.512:40.60 user 27.70 system 18.46 elapsed 369% CPU
-time.20.tcmalloc.512:8.22 user 0.08 system 2.20 elapsed 375% CPU
-time.20.ptmalloc.1024:40.02 user 28.52 system 17.56 elapsed 390% CPU
-time.20.tcmalloc.1024:8.50 user 0.07 system 2.19 elapsed 391% CPU
-time.20.ptmalloc.2048:16.13 user 0.23 system 4.23 elapsed 386% CPU
-time.20.tcmalloc.2048:8.98 user 0.03 system 2.45 elapsed 367% CPU
-time.20.ptmalloc.4096:17.14 user 0.87 system 4.60 elapsed 391% CPU
-time.20.tcmalloc.4096:8.93 user 0.20 system 2.97 elapsed 306% CPU
-time.20.ptmalloc.8192:25.24 user 17.16 system 11.14 elapsed 380% CPU
-time.20.tcmalloc.8192:9.78 user 0.30 system 5.14 elapsed 195% CPU
-time.20.ptmalloc.16384:39.93 user 60.36 system 30.24 elapsed 331% CPU
-time.20.tcmalloc.16384:9.57 user 0.09 system 9.43 elapsed 102% CPU
-time.20.ptmalloc.32768:36.44 user 130.23 system 76.79 elapsed 217% CPU
-time.20.tcmalloc.32768:12.71 user 0.09 system 12.97 elapsed 98% CPU
-time.20.ptmalloc.65536:39.79 user 202.09 system 120.34 elapsed 200% CPU
-time.20.tcmalloc.65536:12.93 user 0.06 system 13.15 elapsed 98% CPU
-time.20.ptmalloc.131072:41.91 user 202.76 system 138.51 elapsed 176% CPU
-time.20.tcmalloc.131072:18.23 user 0.07 system 18.42 elapsed 99% CPU
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.1024.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.1024.bytes.png
deleted file mode 100644
index 8c0ae6b5..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.1024.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.128.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.128.bytes.png
deleted file mode 100644
index 24b2a274..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.128.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.131072.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.131072.bytes.png
deleted file mode 100644
index 183a77b..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.131072.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.16384.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.16384.bytes.png
deleted file mode 100644
index db59d61..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.16384.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.2048.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.2048.bytes.png
deleted file mode 100644
index 169546f..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.2048.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.256.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.256.bytes.png
deleted file mode 100644
index 6213021..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.256.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.32768.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.32768.bytes.png
deleted file mode 100644
index 18715e3a..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.32768.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.4096.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.4096.bytes.png
deleted file mode 100644
index 642e245..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.4096.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.512.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.512.bytes.png
deleted file mode 100644
index aea1d67..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.512.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.64.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.64.bytes.png
deleted file mode 100644
index 3a080de7..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.64.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.65536.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.65536.bytes.png
deleted file mode 100644
index 48ebdb63..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.65536.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.8192.bytes.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.8192.bytes.png
deleted file mode 100644
index 3a99cbc..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspercpusec.vs.threads.8192.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.1.threads.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.1.threads.png
deleted file mode 100644
index 37d406d..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.1.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.12.threads.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.12.threads.png
deleted file mode 100644
index d45458ac..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.12.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.16.threads.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.16.threads.png
deleted file mode 100644
index e8a3c9f..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.16.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.2.threads.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.2.threads.png
deleted file mode 100644
index 52d7aee..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.2.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.20.threads.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.20.threads.png
deleted file mode 100644
index da0328a..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.20.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.3.threads.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.3.threads.png
deleted file mode 100644
index 1093e81..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.3.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.4.threads.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.4.threads.png
deleted file mode 100644
index d7c79ef..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.4.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.5.threads.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.5.threads.png
deleted file mode 100644
index 779eec6..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.5.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.8.threads.png b/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.8.threads.png
deleted file mode 100644
index 76c125a..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc-opspersec.vs.size.8.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/docs/tcmalloc.html b/third_party/tcmalloc/vendor/docs/tcmalloc.html
deleted file mode 100644
index 33b8cc5..0000000
--- a/third_party/tcmalloc/vendor/docs/tcmalloc.html
+++ /dev/null
@@ -1,778 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.01 transitional//en">
-<!-- $Id: $ -->
-<html>
-<head>
-<title>TCMalloc : Thread-Caching Malloc</title>
-<link rel="stylesheet" href="designstyle.css">
-<style type="text/css">
-  em {
-    color: red;
-    font-style: normal;
-  }
-</style>
-</head>
-<body>
-
-<h1>TCMalloc : Thread-Caching Malloc</h1>
-
-<address>Sanjay Ghemawat</address>
-
-<h2><A name=motivation>Motivation</A></h2>
-
-<p>TCMalloc is faster than the glibc 2.3 malloc (available as a
-separate library called ptmalloc2) and other mallocs that I have
-tested.  ptmalloc2 takes approximately 300 nanoseconds to execute a
-malloc/free pair on a 2.8 GHz P4 (for small objects).  The TCMalloc
-implementation takes approximately 50 nanoseconds for the same
-operation pair.  Speed is important for a malloc implementation
-because if malloc is not fast enough, application writers are inclined
-to write their own custom free lists on top of malloc.  This can lead
-to extra complexity, and more memory usage unless the application
-writer is very careful to appropriately size the free lists and
-scavenge idle objects out of the free list.</p>
-
-<p>TCMalloc also reduces lock contention for multi-threaded programs.
-For small objects, there is virtually zero contention.  For large
-objects, TCMalloc tries to use fine grained and efficient spinlocks.
-ptmalloc2 also reduces lock contention by using per-thread arenas but
-there is a big problem with ptmalloc2's use of per-thread arenas.  In
-ptmalloc2 memory can never move from one arena to another.  This can
-lead to huge amounts of wasted space.  For example, in one Google
-application, the first phase would allocate approximately 300MB of
-memory for its URL canonicalization data structures.  When the first
-phase finished, a second phase would be started in the same address
-space.  If this second phase was assigned a different arena than the
-one used by the first phase, this phase would not reuse any of the
-memory left after the first phase and would add another 300MB to the
-address space.  Similar memory blowup problems were also noticed in
-other applications.</p>
-
-<p>Another benefit of TCMalloc is space-efficient representation of
-small objects.  For example, N 8-byte objects can be allocated while
-using space approximately <code>8N * 1.01</code> bytes.  I.e., a
-one-percent space overhead.  ptmalloc2 uses a four-byte header for
-each object and (I think) rounds up the size to a multiple of 8 bytes
-and ends up using <code>16N</code> bytes.</p>
-
-
-<h2><A NAME="Usage">Usage</A></h2>
-
-<p>To use TCMalloc, just link TCMalloc into your application via the
-"-ltcmalloc" linker flag.</p>
-
-<p>You can use TCMalloc in applications you didn't compile yourself,
-by using LD_PRELOAD:</p>
-<pre>
-   $ LD_PRELOAD="/usr/lib/libtcmalloc.so" <binary>
-</pre>
-<p>LD_PRELOAD is tricky, and we don't necessarily recommend this mode
-of usage.</p>
-
-<p>TCMalloc includes a <A HREF="heap_checker.html">heap checker</A>
-and <A HREF="heapprofile.html">heap profiler</A> as well.</p>
-
-<p>If you'd rather link in a version of TCMalloc that does not include
-the heap profiler and checker (perhaps to reduce binary size for a
-static binary), you can link in <code>libtcmalloc_minimal</code>
-instead.</p>
-
-
-<h2><A NAME="Overview">Overview</A></h2>
-
-<p>TCMalloc assigns each thread a thread-local cache.  Small
-allocations are satisfied from the thread-local cache.  Objects are
-moved from central data structures into a thread-local cache as
-needed, and periodic garbage collections are used to migrate memory
-back from a thread-local cache into the central data structures.</p>
-<center><img src="overview.gif"></center>
-
-<p>TCMalloc treats objects with size &lt;= 256K ("small" objects)
-differently from larger objects.  Large objects are allocated directly
-from the central heap using a page-level allocator (a page is a 8K
-aligned region of memory).  I.e., a large object is always
-page-aligned and occupies an integral number of pages.</p>
-
-<p>A run of pages can be carved up into a sequence of small objects,
-each equally sized.  For example a run of one page (4K) can be carved
-up into 32 objects of size 128 bytes each.</p>
-
-
-<h2><A NAME="Small_Object_Allocation">Small Object Allocation</A></h2>
-
-<p>Each small object size maps to one of approximately 88 allocatable
-size-classes.  For example, all allocations in the range 961 to 1024
-bytes are rounded up to 1024.  The size-classes are spaced so that
-small sizes are separated by 8 bytes, larger sizes by 16 bytes, even
-larger sizes by 32 bytes, and so forth.  The maximal spacing is
-controlled so that not too much space is wasted when an allocation
-request falls just past the end of a size class and has to be rounded
-up to the next class.</p>
-
-<p>A thread cache contains a singly linked list of free objects per
-size-class.</p>
-<center><img src="threadheap.gif"></center>
-
-<p>When allocating a small object: (1) We map its size to the
-corresponding size-class.  (2) Look in the corresponding free list in
-the thread cache for the current thread.  (3) If the free list is not
-empty, we remove the first object from the list and return it.  When
-following this fast path, TCMalloc acquires no locks at all.  This
-helps speed-up allocation significantly because a lock/unlock pair
-takes approximately 100 nanoseconds on a 2.8 GHz Xeon.</p>
-
-<p>If the free list is empty: (1) We fetch a bunch of objects from a
-central free list for this size-class (the central free list is shared
-by all threads).  (2) Place them in the thread-local free list.  (3)
-Return one of the newly fetched objects to the applications.</p>
-
-<p>If the central free list is also empty: (1) We allocate a run of
-pages from the central page allocator.  (2) Split the run into a set
-of objects of this size-class.  (3) Place the new objects on the
-central free list.  (4) As before, move some of these objects to the
-thread-local free list.</p>
-
-<h3><A NAME="Sizing_Thread_Cache_Free_Lists">
-  Sizing Thread Cache Free Lists</A></h3>
-
-<p>It is important to size the thread cache free lists correctly.  If
-the free list is too small, we'll need to go to the central free list
-too often.  If the free list is too big, we'll waste memory as objects
-sit idle in the free list.</p>
-
-<p>Note that the thread caches are just as important for deallocation
-as they are for allocation.  Without a cache, each deallocation would
-require moving the memory to the central free list.  Also, some threads
-have asymmetric alloc/free behavior (e.g. producer and consumer threads),
-so sizing the free list correctly gets trickier.</p>
-
-<p>To size the free lists appropriately, we use a slow-start algorithm
-to determine the maximum length of each individual free list.  As the
-free list is used more frequently, its maximum length grows.  However,
-if a free list is used more for deallocation than allocation, its
-maximum length will grow only up to a point where the whole list can
-be efficiently moved to the central free list at once.</p>
-
-<p>The psuedo-code below illustrates this slow-start algorithm.  Note
-that <code>num_objects_to_move</code> is specific to each size class.
-By moving a list of objects with a well-known length, the central
-cache can efficiently pass these lists between thread caches.  If
-a thread cache wants fewer than <code>num_objects_to_move</code>,
-the operation on the central free list has linear time complexity.
-The downside of always using <code>num_objects_to_move</code> as
-the number of objects to transfer to and from the central cache is
-that it wastes memory in threads that don't need all of those objects.
-
-<pre>
-Start each freelist max_length at 1.
-
-Allocation
-  if freelist empty {
-    fetch min(max_length, num_objects_to_move) from central list;
-    if max_length < num_objects_to_move {  // slow-start
-      max_length++;
-    } else {
-      max_length += num_objects_to_move;
-    }
-  }
-
-Deallocation
-  if length > max_length {
-    // Don't try to release num_objects_to_move if we don't have that many.
-    release min(max_length, num_objects_to_move) objects to central list
-    if max_length < num_objects_to_move {
-      // Slow-start up to num_objects_to_move.
-      max_length++;
-    } else if max_length > num_objects_to_move {
-      // If we consistently go over max_length, shrink max_length.
-      overages++;
-      if overages > kMaxOverages {
-        max_length -= num_objects_to_move;
-        overages = 0;
-      }
-    }
-  }
-</pre>
-
-See also the section on <a href="#Garbage_Collection">Garbage Collection</a>
-to see how it affects the <code>max_length</code>.
-
-<h2><A NAME="Medium_Object_Allocation">Medium Object Allocation</A></h2>
-
-<p>A medium object size (256K &le; size &le; 1MB) is rounded up to a page
-size (8K) and is handled by a central page heap. The central page heap
-includes an array of 128 free lists.  The <code>k</code>th entry is a
-free list of runs that consist of <code>k + 1</code> pages:</p>
-<center><img src="pageheap.gif"></center>
-
-<p>An allocation for <code>k</code> pages is satisfied by looking in
-the <code>k</code>th free list.  If that free list is empty, we look
-in the next free list, and so forth.  If no medium-object free list
-can satisfy the allocation, the allocation is treated as a large object.
-
-
-<h2><A NAME="Large_Object_Allocation">Large Object Allocation</A></h2>
-
-Allocations of 1MB or more are considered large allocations. Spans
-of free memory which can satisfy these allocations are tracked in
-a red-black tree sorted by size. Allocations follow the <em>best-fit</em>
-algorithm: the tree is searched to find the smallest span of free
-space which is larger than the requested allocation. The allocation
-is carved out of that span, and the remaining space is reinserted
-either into the large object tree or possibly into one of the smaller
-free-lists as appropriate.
-
-If no span of free memory is located that can fit the requested
-allocation, we fetch memory from the system (using <code>sbrk</code>,
-<code>mmap</code>, or by mapping in portions of
-<code>/dev/mem</code>).</p>
-
-<p>If an allocation for <code>k</code> pages is satisfied by a run
-of pages of length &gt; <code>k</code>, the remainder of the
-run is re-inserted back into the appropriate free list in the
-page heap.</p>
-
-
-<h2><A NAME="Spans">Spans</A></h2>
-
-<p>The heap managed by TCMalloc consists of a set of pages.  A run of
-contiguous pages is represented by a <code>Span</code> object.  A span
-can either be <em>allocated</em>, or <em>free</em>.  If free, the span
-is one of the entries in a page heap linked-list.  If allocated, it is
-either a large object that has been handed off to the application, or
-a run of pages that have been split up into a sequence of small
-objects.  If split into small objects, the size-class of the objects
-is recorded in the span.</p>
-
-<p>A central array indexed by page number can be used to find the span to
-which a page belongs.  For example, span <em>a</em> below occupies 2
-pages, span <em>b</em> occupies 1 page, span <em>c</em> occupies 5
-pages and span <em>d</em> occupies 3 pages.</p>
-<center><img src="spanmap.gif"></center>
-
-<p>In a 32-bit address space, the central array is represented by a a
-2-level radix tree where the root contains 32 entries and each leaf
-contains 2^14 entries (a 32-bit address space has 2^19 8K pages, and
-the first level of tree divides the 2^19 pages by 2^5).  This leads to
-a starting memory usage of 64KB of space (2^14*4 bytes) for the
-central array, which seems acceptable.</p>
-
-<p>On 64-bit machines, we use a 3-level radix tree.</p>
-
-
-<h2><A NAME="Deallocation">Deallocation</A></h2>
-
-<p>When an object is deallocated, we compute its page number and look
-it up in the central array to find the corresponding span object.  The
-span tells us whether or not the object is small, and its size-class
-if it is small.  If the object is small, we insert it into the
-appropriate free list in the current thread's thread cache.  If the
-thread cache now exceeds a predetermined size (2MB by default), we run
-a garbage collector that moves unused objects from the thread cache
-into central free lists.</p>
-
-<p>If the object is large, the span tells us the range of pages covered
-by the object.  Suppose this range is <code>[p,q]</code>.  We also
-lookup the spans for pages <code>p-1</code> and <code>q+1</code>.  If
-either of these neighboring spans are free, we coalesce them with the
-<code>[p,q]</code> span.  The resulting span is inserted into the
-appropriate free list in the page heap.</p>
-
-
-<h2>Central Free Lists for Small Objects</h2>
-
-<p>As mentioned before, we keep a central free list for each
-size-class.  Each central free list is organized as a two-level data
-structure: a set of spans, and a linked list of free objects per
-span.</p>
-
-<p>An object is allocated from a central free list by removing the
-first entry from the linked list of some span.  (If all spans have
-empty linked lists, a suitably sized span is first allocated from the
-central page heap.)</p>
-
-<p>An object is returned to a central free list by adding it to the
-linked list of its containing span.  If the linked list length now
-equals the total number of small objects in the span, this span is now
-completely free and is returned to the page heap.</p>
-
-
-<h2><A NAME="Garbage_Collection">Garbage Collection of Thread Caches</A></h2>
-
-<p>Garbage collecting objects from a thread cache keeps the size of
-the cache under control and returns unused objects to the central free
-lists.  Some threads need large caches to perform well while others
-can get by with little or no cache at all.  When a thread cache goes
-over its <code>max_size</code>, garbage collection kicks in and then the
-thread competes with the other threads for a larger cache.</p>
-
-<p>Garbage collection is run only during a deallocation.  We walk over
-all free lists in the cache and move some number of objects from the
-free list to the corresponding central list.</p>
-
-<p>The number of objects to be moved from a free list is determined
-using a per-list low-water-mark <code>L</code>.  <code>L</code>
-records the minimum length of the list since the last garbage
-collection.  Note that we could have shortened the list by
-<code>L</code> objects at the last garbage collection without
-requiring any extra accesses to the central list.  We use this past
-history as a predictor of future accesses and move <code>L/2</code>
-objects from the thread cache free list to the corresponding central
-free list.  This algorithm has the nice property that if a thread
-stops using a particular size, all objects of that size will quickly
-move from the thread cache to the central free list where they can be
-used by other threads.</p>
-
-<p>If a thread consistently deallocates more objects of a certain size
-than it allocates, this <code>L/2</code> behavior will cause at least
-<code>L/2</code> objects to always sit in the free list.  To avoid
-wasting memory this way, we shrink the maximum length of the freelist
-to converge on <code>num_objects_to_move</code> (see also
-<a href="#Sizing_Thread_Cache_Free_Lists">Sizing Thread Cache Free Lists</a>).
-
-<pre>
-Garbage Collection
-  if (L != 0 && max_length > num_objects_to_move) {
-    max_length = max(max_length - num_objects_to_move, num_objects_to_move)
-  }
-</pre>
-
-<p>The fact that the thread cache went over its <code>max_size</code> is
-an indication that the thread would benefit from a larger cache.  Simply
-increasing <code>max_size</code> would use an inordinate amount of memory
-in programs that have lots of active threads.  Developers can bound the
-memory used with the flag --tcmalloc_max_total_thread_cache_bytes.</p>
-
-<p>Each thread cache starts with a small <code>max_size</code>
-(e.g. 64KB) so that idle threads won't pre-allocate memory they don't
-need.  Each time the cache runs a garbage collection, it will also try
-to grow its <code>max_size</code>.  If the sum of the thread cache
-sizes is less than --tcmalloc_max_total_thread_cache_bytes,
-<code>max_size</code> grows easily.  If not, thread cache 1 will try
-to steal from thread cache 2 (picked round-robin) by decreasing thread
-cache 2's <code>max_size</code>.  In this way, threads that are more
-active will steal memory from other threads more often than they are
-have memory stolen from themselves.  Mostly idle threads end up with
-small caches and active threads end up with big caches.  Note that
-this stealing can cause the sum of the thread cache sizes to be
-greater than --tcmalloc_max_total_thread_cache_bytes until thread
-cache 2 deallocates some memory to trigger a garbage collection.</p>
-
-<h2><A NAME="performance">Performance Notes</A></h2>
-
-<h3>PTMalloc2 unittest</h3>
-
-<p>The PTMalloc2 package (now part of glibc) contains a unittest
-program <code>t-test1.c</code>. This forks a number of threads and
-performs a series of allocations and deallocations in each thread; the
-threads do not communicate other than by synchronization in the memory
-allocator.</p>
-
-<p><code>t-test1</code> (included in
-<code>tests/tcmalloc/</code>, and compiled as
-<code>ptmalloc_unittest1</code>) was run with a varying numbers of
-threads (1-20) and maximum allocation sizes (64 bytes -
-32Kbytes). These tests were run on a 2.4GHz dual Xeon system with
-hyper-threading enabled, using Linux glibc-2.3.2 from RedHat 9, with
-one million operations per thread in each test. In each case, the test
-was run once normally, and once with
-<code>LD_PRELOAD=libtcmalloc.so</code>.
-
-<p>The graphs below show the performance of TCMalloc vs PTMalloc2 for
-several different metrics. Firstly, total operations (millions) per
-elapsed second vs max allocation size, for varying numbers of
-threads. The raw data used to generate these graphs (the output of the
-<code>time</code> utility) is available in
-<code>t-test1.times.txt</code>.</p>
-
-<table>
-<tr>
-  <td><img src="tcmalloc-opspersec.vs.size.1.threads.png"></td>
-  <td><img src="tcmalloc-opspersec.vs.size.2.threads.png"></td>
-  <td><img src="tcmalloc-opspersec.vs.size.3.threads.png"></td>
-</tr>
-<tr>
-  <td><img src="tcmalloc-opspersec.vs.size.4.threads.png"></td>
-  <td><img src="tcmalloc-opspersec.vs.size.5.threads.png"></td>
-  <td><img src="tcmalloc-opspersec.vs.size.8.threads.png"></td>
-</tr>
-<tr>
-  <td><img src="tcmalloc-opspersec.vs.size.12.threads.png"></td>
-  <td><img src="tcmalloc-opspersec.vs.size.16.threads.png"></td>
-  <td><img src="tcmalloc-opspersec.vs.size.20.threads.png"></td>
-</tr>
-</table>
-
-
-<ul> 
-  <li> TCMalloc is much more consistently scalable than PTMalloc2 - for
-       all thread counts &gt;1 it achieves ~7-9 million ops/sec for small
-       allocations, falling to ~2 million ops/sec for larger
-       allocations. The single-thread case is an obvious outlier,
-       since it is only able to keep a single processor busy and hence
-       can achieve fewer ops/sec. PTMalloc2 has a much higher variance
-       on operations/sec - peaking somewhere around 4 million ops/sec
-       for small allocations and falling to &lt;1 million ops/sec for
-       larger allocations.
-
-  <li> TCMalloc is faster than PTMalloc2 in the vast majority of
-       cases, and particularly for small allocations. Contention
-       between threads is less of a problem in TCMalloc.
-
-  <li> TCMalloc's performance drops off as the allocation size
-       increases. This is because the per-thread cache is
-       garbage-collected when it hits a threshold (defaulting to
-       2MB). With larger allocation sizes, fewer objects can be stored
-       in the cache before it is garbage-collected.
-
-  <li> There is a noticeable drop in TCMalloc's performance at ~32K
-       maximum allocation size; at larger sizes performance drops less
-       quickly. This is due to the 32K maximum size of objects in the
-       per-thread caches; for objects larger than this TCMalloc
-       allocates from the central page heap.
-</ul>
-
-<p>Next, operations (millions) per second of CPU time vs number of
-threads, for max allocation size 64 bytes - 128 Kbytes.</p>
-
-<table>
-<tr>
-  <td><img src="tcmalloc-opspercpusec.vs.threads.64.bytes.png"></td>
-  <td><img src="tcmalloc-opspercpusec.vs.threads.256.bytes.png"></td>
-  <td><img src="tcmalloc-opspercpusec.vs.threads.1024.bytes.png"></td>
-</tr>
-<tr>
-  <td><img src="tcmalloc-opspercpusec.vs.threads.4096.bytes.png"></td>
-  <td><img src="tcmalloc-opspercpusec.vs.threads.8192.bytes.png"></td>
-  <td><img src="tcmalloc-opspercpusec.vs.threads.16384.bytes.png"></td>
-</tr>
-<tr>
-  <td><img src="tcmalloc-opspercpusec.vs.threads.32768.bytes.png"></td>
-  <td><img src="tcmalloc-opspercpusec.vs.threads.65536.bytes.png"></td>
-  <td><img src="tcmalloc-opspercpusec.vs.threads.131072.bytes.png"></td>
-</tr>
-</table>
-
-<p>Here we see again that TCMalloc is both more consistent and more
-efficient than PTMalloc2. For max allocation sizes &lt;32K, TCMalloc
-typically achieves ~2-2.5 million ops per second of CPU time with a
-large number of threads, whereas PTMalloc achieves generally 0.5-1
-million ops per second of CPU time, with a lot of cases achieving much
-less than this figure. Above 32K max allocation size, TCMalloc drops
-to 1-1.5 million ops per second of CPU time, and PTMalloc drops almost
-to zero for large numbers of threads (i.e. with PTMalloc, lots of CPU
-time is being burned spinning waiting for locks in the heavily
-multi-threaded case).</p>
-
-
-<H2><A NAME="runtime">Modifying Runtime Behavior</A></H2>
-
-<p>You can more finely control the behavior of the tcmalloc via
-environment variables.</p>
-
-<p>Generally useful flags:</p>
-
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
-  <td><code>TCMALLOC_SAMPLE_PARAMETER</code></td>
-  <td>default: 0</td>
-  <td>
-    The approximate gap between sampling actions.  That is, we
-    take one sample approximately once every
-    <code>tcmalloc_sample_parmeter</code> bytes of allocation.
-    This sampled heap information is available via
-    <code>MallocExtension::GetHeapSample()</code> or
-    <code>MallocExtension::ReadStackTraces()</code>.  A reasonable
-    value is 524288.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_RELEASE_RATE</code></td>
-  <td>default: 1.0</td>
-  <td>
-    Rate at which we release unused memory to the system, via
-    <code>madvise(MADV_DONTNEED)</code>, on systems that support
-    it.  Zero means we never release memory back to the system.
-    Increase this flag to return memory faster; decrease it
-    to return memory slower.  Reasonable rates are in the
-    range [0,10].
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD</code></td>
-  <td>default: 1073741824</td>
-  <td>
-    Allocations larger than this value cause a stack trace to be
-    dumped to stderr.  The threshold for dumping stack traces is
-    increased by a factor of 1.125 every time we print a message so
-    that the threshold automatically goes up by a factor of ~1000
-    every 60 messages.  This bounds the amount of extra logging
-    generated by this flag.  Default value of this flag is very large
-    and therefore you should see no extra logging unless the flag is
-    overridden.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES</code></td>
-  <td>default: 16777216</td>
-  <td>
-    Bound on the total amount of bytes allocated to thread caches.  This
-    bound is not strict, so it is possible for the cache to go over this
-    bound in certain circumstances.  This value defaults to 16MB.  For
-    applications with many threads, this may not be a large enough cache,
-    which can affect performance.  If you suspect your application is not
-    scaling to many threads due to lock contention in TCMalloc, you can
-    try increasing this value.  This may improve performance, at a cost
-    of extra memory use by TCMalloc.  See <a href="#Garbage_Collection">
-    Garbage Collection</a> for more details.
-  </td>
-</tr>
-
-</table>
-
-<p>Advanced "tweaking" flags, that control more precisely how tcmalloc
-tries to allocate memory from the kernel.</p>
-
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
-  <td><code>TCMALLOC_SKIP_MMAP</code></td>
-  <td>default: false</td>
-  <td>
-     If true, do not try to use <code>mmap</code> to obtain memory
-     from the kernel.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_SKIP_SBRK</code></td>
-  <td>default: false</td>
-  <td>
-     If true, do not try to use <code>sbrk</code> to obtain memory
-     from the kernel.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_DEVMEM_START</code></td>
-  <td>default: 0</td>
-  <td>
-    Physical memory starting location in MB for <code>/dev/mem</code>
-    allocation.  Setting this to 0 disables <code>/dev/mem</code>
-    allocation.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_DEVMEM_LIMIT</code></td>
-  <td>default: 0</td>
-  <td>
-     Physical memory limit location in MB for <code>/dev/mem</code>
-     allocation.  Setting this to 0 means no limit.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_DEVMEM_DEVICE</code></td>
-  <td>default: /dev/mem</td>
-  <td>
-     Device to use for allocating unmanaged memory.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_MEMFS_MALLOC_PATH</code></td>
-  <td>default: ""</td>
-  <td>
-     If set, specify a path where hugetlbfs or tmpfs is mounted.
-     This may allow for speedier allocations.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_MEMFS_LIMIT_MB</code></td>
-  <td>default: 0</td>
-  <td>
-     Limit total memfs allocation size to specified number of MB.
-     0 means "no limit".
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_MEMFS_ABORT_ON_FAIL</code></td>
-  <td>default: false</td>
-  <td>
-     If true, abort() whenever memfs_malloc fails to satisfy an allocation.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_MEMFS_IGNORE_MMAP_FAIL</code></td>
-  <td>default: false</td>
-  <td>
-     If true, ignore failures from mmap.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>TCMALLOC_MEMFS_MAP_PRIVATE</code></td>
-  <td>default: false</td>
-  <td>
-     If true, use MAP_PRIVATE when mapping via memfs, not MAP_SHARED.
-  </td>
-</tr>
-
-</table>
-
-
-<H2><A NAME="compiletime">Modifying Behavior In Code</A></H2>
-
-<p>The <code>MallocExtension</code> class, in
-<code>malloc_extension.h</code>, provides a few knobs that you can
-tweak in your program, to affect tcmalloc's behavior.</p>
-
-<h3>Releasing Memory Back to the System</h3>
-
-<p>By default, tcmalloc will release no-longer-used memory back to the
-kernel gradually, over time.  The <a
-href="#runtime">tcmalloc_release_rate</a> flag controls how quickly
-this happens.  You can also force a release at a given point in the
-progam execution like so:</p>
-<pre>
-   MallocExtension::instance()->ReleaseFreeMemory();
-</pre>
-
-<p>You can also call <code>SetMemoryReleaseRate()</code> to change the
-<code>tcmalloc_release_rate</code> value at runtime, or
-<code>GetMemoryReleaseRate</code> to see what the current release rate
-is.</p>
-
-<h3>Memory Introspection</h3>
-
-<p>There are several routines for getting a human-readable form of the
-current memory usage:</p>
-<pre>
-   MallocExtension::instance()->GetStats(buffer, buffer_length);
-   MallocExtension::instance()->GetHeapSample(&string);
-   MallocExtension::instance()->GetHeapGrowthStacks(&string);
-</pre>
-
-<p>The last two create files in the same format as the heap-profiler,
-and can be passed as data files to pprof.  The first is human-readable
-and is meant for debugging.</p>
-
-<h3>Generic Tcmalloc Status</h3>
-
-<p>TCMalloc has support for setting and retrieving arbitrary
-'properties':</p>
-<pre>
-   MallocExtension::instance()->SetNumericProperty(property_name, value);
-   MallocExtension::instance()->GetNumericProperty(property_name, &value);
-</pre>
-
-<p>It is possible for an application to set and get these properties,
-but the most useful is when a library sets the properties so the
-application can read them.  Here are the properties TCMalloc defines;
-you can access them with a call like
-<code>MallocExtension::instance()->GetNumericProperty("generic.heap_size",
-&value);</code>:</p>
-
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
-  <td><code>generic.current_allocated_bytes</code></td>
-  <td>
-    Number of bytes used by the application.  This will not typically
-    match the memory use reported by the OS, because it does not
-    include TCMalloc overhead or memory fragmentation.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>generic.heap_size</code></td>
-  <td>
-    Bytes of system memory reserved by TCMalloc.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>tcmalloc.pageheap_free_bytes</code></td>
-  <td>
-    Number of bytes in free, mapped pages in page heap.  These bytes
-    can be used to fulfill allocation requests.  They always count
-    towards virtual memory usage, and unless the underlying memory is
-    swapped out by the OS, they also count towards physical memory
-    usage.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>tcmalloc.pageheap_unmapped_bytes</code></td>
-  <td>
-    Number of bytes in free, unmapped pages in page heap.  These are
-    bytes that have been released back to the OS, possibly by one of
-    the MallocExtension "Release" calls.  They can be used to fulfill
-    allocation requests, but typically incur a page fault.  They
-    always count towards virtual memory usage, and depending on the
-    OS, typically do not count towards physical memory usage.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>tcmalloc.slack_bytes</code></td>
-  <td>
-    Sum of pageheap_free_bytes and pageheap_unmapped_bytes.  Provided
-    for backwards compatibility only.  Do not use.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>tcmalloc.max_total_thread_cache_bytes</code></td>
-  <td>
-    A limit to how much memory TCMalloc dedicates for small objects.
-    Higher numbers trade off more memory use for -- in some situations
-    -- improved efficiency.
-  </td>
-</tr>
-
-<tr valign=top>
-  <td><code>tcmalloc.current_total_thread_cache_bytes</code></td>
-  <td>
-    A measure of some of the memory TCMalloc is using (for
-    small objects).
-  </td>
-</tr>
-
-</table>
-
-<h2><A NAME="caveats">Caveats</A></h2>
-
-<p>For some systems, TCMalloc may not work correctly with
-applications that aren't linked against <code>libpthread.so</code> (or
-the equivalent on your OS). It should work on Linux using glibc 2.3,
-but other OS/libc combinations have not been tested.</p>
-
-<p>TCMalloc may be somewhat more memory hungry than other mallocs,
-(but tends not to have the huge blowups that can happen with other
-mallocs).  In particular, at startup TCMalloc allocates approximately
-240KB of internal memory.</p>
-
-<p>Don't try to load TCMalloc into a running binary (e.g., using JNI
-in Java programs).  The binary will have allocated some objects using
-the system malloc, and may try to pass them to TCMalloc for
-deallocation.  TCMalloc will not be able to handle such objects.</p>
-
-<hr>
-
-<address>Sanjay Ghemawat, Paul Menage<br>
-<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->
-<!-- hhmts start -->
-Last modified: Sat Feb 24 13:11:38 PST 2007  (csilvers)
-<!-- hhmts end -->
-</address>
-
-</body>
-</html>
diff --git a/third_party/tcmalloc/vendor/docs/threadheap.dot b/third_party/tcmalloc/vendor/docs/threadheap.dot
deleted file mode 100644
index b2dba72..0000000
--- a/third_party/tcmalloc/vendor/docs/threadheap.dot
+++ /dev/null
@@ -1,21 +0,0 @@
-digraph ThreadHeap {
-rankdir=LR
-node [shape=box, width=0.3, height=0.3]
-nodesep=.05
-
-heap [shape=record, height=2, label="<f0>class 0|<f1>class 1|<f2>class 2|..."]
-O0 [label=""]
-O1 [label=""]
-O2 [label=""]
-O3 [label=""]
-O4 [label=""]
-O5 [label=""]
-sep1 [shape=plaintext, label="..."]
-sep2 [shape=plaintext, label="..."]
-sep3 [shape=plaintext, label="..."]
-
-heap:f0 -> O0 -> O1 -> sep1
-heap:f1 -> O2 -> O3 -> sep2
-heap:f2 -> O4 -> O5 -> sep3
-
-}
diff --git a/third_party/tcmalloc/vendor/docs/threadheap.gif b/third_party/tcmalloc/vendor/docs/threadheap.gif
deleted file mode 100644
index c43d0a3..0000000
--- a/third_party/tcmalloc/vendor/docs/threadheap.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/tcmalloc/vendor/m4/ac_have_attribute.m4 b/third_party/tcmalloc/vendor/m4/ac_have_attribute.m4
deleted file mode 100644
index 19f4021..0000000
--- a/third_party/tcmalloc/vendor/m4/ac_have_attribute.m4
+++ /dev/null
@@ -1,16 +0,0 @@
-AC_DEFUN([AX_C___ATTRIBUTE__], [
-  AC_MSG_CHECKING(for __attribute__)
-  AC_CACHE_VAL(ac_cv___attribute__, [
-    AC_TRY_COMPILE(
-      [#include <stdlib.h>
-       static void foo(void) __attribute__ ((unused));
-       void foo(void) { exit(1); }],
-      [],
-      ac_cv___attribute__=yes,
-      ac_cv___attribute__=no
-    )])
-  if test "$ac_cv___attribute__" = "yes"; then
-    AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
-  fi
-  AC_MSG_RESULT($ac_cv___attribute__)
-])
diff --git a/third_party/tcmalloc/vendor/m4/acx_nanosleep.m4 b/third_party/tcmalloc/vendor/m4/acx_nanosleep.m4
deleted file mode 100644
index 1d44392..0000000
--- a/third_party/tcmalloc/vendor/m4/acx_nanosleep.m4
+++ /dev/null
@@ -1,35 +0,0 @@
-# Check for support for nanosleep.  It's defined in <time.h>, but on
-# some systems, such as solaris, you need to link in a library to use it.
-# We set acx_nanosleep_ok if nanosleep is supported; in that case,
-# NANOSLEEP_LIBS is set to whatever libraries are needed to support
-# nanosleep.
-
-AC_DEFUN([ACX_NANOSLEEP],
-[AC_MSG_CHECKING(if nanosleep requires any libraries)
- AC_LANG_SAVE
- AC_LANG_C
- acx_nanosleep_ok="no"
- NANOSLEEP_LIBS=
- # For most folks, this should just work
- AC_TRY_LINK([#include <time.h>],
-             [static struct timespec ts; nanosleep(&ts, NULL);],
-             [acx_nanosleep_ok=yes])
- # For solaris, we may  need -lrt
- if test "x$acx_nanosleep_ok" != "xyes"; then
-   OLD_LIBS="$LIBS"
-   LIBS="-lrt $LIBS"
-   AC_TRY_LINK([#include <time.h>],
-               [static struct timespec ts; nanosleep(&ts, NULL);],
-               [acx_nanosleep_ok=yes])
-   if test "x$acx_nanosleep_ok" = "xyes"; then
-     NANOSLEEP_LIBS="-lrt"
-   fi
-   LIBS="$OLD_LIBS"
- fi
- if test "x$acx_nanosleep_ok" != "xyes"; then
-   AC_MSG_ERROR([cannot find the nanosleep function])
- else
-   AC_MSG_RESULT(${NANOSLEEP_LIBS:-no})
- fi
- AC_LANG_RESTORE
-])
diff --git a/third_party/tcmalloc/vendor/m4/acx_pthread.m4 b/third_party/tcmalloc/vendor/m4/acx_pthread.m4
deleted file mode 100644
index 89d42c74..0000000
--- a/third_party/tcmalloc/vendor/m4/acx_pthread.m4
+++ /dev/null
@@ -1,397 +0,0 @@
-# This was retrieved from
-#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
-# See also (perhaps for new versions?)
-#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
-#
-# We've rewritten the inconsistency check code (from avahi), to work
-# more broadly.  In particular, it no longer assumes ld accepts -zdefs.
-# This caused a restructing of the code, but the functionality has only
-# changed a little.
-
-dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-dnl
-dnl @summary figure out how to build C programs using POSIX threads
-dnl
-dnl This macro figures out how to build C programs using POSIX threads.
-dnl It sets the PTHREAD_LIBS output variable to the threads library and
-dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
-dnl C compiler flags that are needed. (The user can also force certain
-dnl compiler flags/libs to be tested by setting these environment
-dnl variables.)
-dnl
-dnl Also sets PTHREAD_CC to any special C compiler that is needed for
-dnl multi-threaded programs (defaults to the value of CC otherwise).
-dnl (This is necessary on AIX to use the special cc_r compiler alias.)
-dnl
-dnl NOTE: You are assumed to not only compile your program with these
-dnl flags, but also link it with them as well. e.g. you should link
-dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
-dnl $LIBS
-dnl
-dnl If you are only building threads programs, you may wish to use
-dnl these variables in your default LIBS, CFLAGS, and CC:
-dnl
-dnl        LIBS="$PTHREAD_LIBS $LIBS"
-dnl        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-dnl        CC="$PTHREAD_CC"
-dnl
-dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
-dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
-dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
-dnl
-dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
-dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
-dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
-dnl default action will define HAVE_PTHREAD.
-dnl
-dnl Please let the authors know if this macro fails on any platform, or
-dnl if you have any other suggestions or comments. This macro was based
-dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
-dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
-dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
-dnl We are also grateful for the helpful feedback of numerous users.
-dnl
-dnl @category InstalledPackages
-dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
-dnl @version 2006-05-29
-dnl @license GPLWithACException
-dnl 
-dnl Checks for GCC shared/pthread inconsistency based on work by
-dnl Marcin Owsiany <marcin@owsiany.pl>
-
-
-AC_DEFUN([ACX_PTHREAD], [
-AC_REQUIRE([AC_CANONICAL_HOST])
-AC_LANG_SAVE
-AC_LANG_C
-acx_pthread_ok=no
-
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
-
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
-        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
-        AC_MSG_RESULT($acx_pthread_ok)
-        if test x"$acx_pthread_ok" = xno; then
-                PTHREAD_LIBS=""
-                PTHREAD_CFLAGS=""
-        fi
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-fi
-
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try.  Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important.  Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-#       other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-#      doesn't hurt to check since this sometimes defines pthreads too;
-#      also defines -D_REENTRANT)
-#      ... -mt is also the pthreads flag for HP/aCC
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case "${host_cpu}-${host_os}" in
-        *solaris*)
-
-        # On Solaris (at least, for some versions), libc contains stubbed
-        # (non-functional) versions of the pthreads routines, so link-based
-        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
-        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
-        # a function called by this macro, so we could check for that, but
-        # who knows whether they'll stub that too in a future libc.)  So,
-        # we'll just look for -pthreads and -lpthread first:
-
-        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
-        ;;
-esac
-
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
-
-        case $flag in
-                none)
-                AC_MSG_CHECKING([whether pthreads work without any flags])
-                ;;
-
-                -*)
-                AC_MSG_CHECKING([whether pthreads work with $flag])
-                PTHREAD_CFLAGS="$flag"
-                ;;
-
-		pthread-config)
-		AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
-		if test x"$acx_pthread_config" = xno; then continue; fi
-		PTHREAD_CFLAGS="`pthread-config --cflags`"
-		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
-		;;
-
-                *)
-                AC_MSG_CHECKING([for the pthreads library -l$flag])
-                PTHREAD_LIBS="-l$flag"
-                ;;
-        esac
-
-        save_LIBS="$LIBS"
-        save_CFLAGS="$CFLAGS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Check for various functions.  We must include pthread.h,
-        # since some functions may be macros.  (On the Sequent, we
-        # need a special flag -Kthread to make this header compile.)
-        # We check for pthread_join because it is in -lpthread on IRIX
-        # while pthread_create is in libc.  We check for pthread_attr_init
-        # due to DEC craziness with -lpthreads.  We check for
-        # pthread_cleanup_push because it is one of the few pthread
-        # functions on Solaris that doesn't have a non-functional libc stub.
-        # We try pthread_create on general principles.
-        AC_TRY_LINK([#include <pthread.h>],
-                    [pthread_t th; pthread_join(th, 0);
-                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
-                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-                    [acx_pthread_ok=yes])
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        AC_MSG_RESULT($acx_pthread_ok)
-        if test "x$acx_pthread_ok" = xyes; then
-                break;
-        fi
-
-        PTHREAD_LIBS=""
-        PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-	AC_MSG_CHECKING([for joinable pthread attribute])
-	attr_name=unknown
-	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-	    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
-                        [attr_name=$attr; break])
-	done
-        AC_MSG_RESULT($attr_name)
-        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
-                               [Define to necessary symbol if this constant
-                                uses a non-standard name on your system.])
-        fi
-
-        AC_MSG_CHECKING([if more special flags are required for pthreads])
-        flag=no
-        case "${host_cpu}-${host_os}" in
-            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
-            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
-        esac
-        AC_MSG_RESULT(${flag})
-        if test "x$flag" != xno; then
-            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
-        fi
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-        # More AIX lossage: must compile with xlc_r or cc_r
-	if test x"$GCC" != xyes; then
-          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
-        else
-          PTHREAD_CC=$CC
-	fi
-
-	# The next part tries to detect GCC inconsistency with -shared on some
-	# architectures and systems. The problem is that in certain
-	# configurations, when -shared is specified, GCC "forgets" to
-	# internally use various flags which are still necessary.
-	
-	#
-	# Prepare the flags
-	#
-	save_CFLAGS="$CFLAGS"
-	save_LIBS="$LIBS"
-	save_CC="$CC"
-	
-	# Try with the flags determined by the earlier checks.
-	#
-	# -Wl,-z,defs forces link-time symbol resolution, so that the
-	# linking checks with -shared actually have any value
-	#
-	# FIXME: -fPIC is required for -shared on many architectures,
-	# so we specify it here, but the right way would probably be to
-	# properly detect whether it is actually required.
-	CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
-	LIBS="$PTHREAD_LIBS $LIBS"
-	CC="$PTHREAD_CC"
-	
-	# In order not to create several levels of indentation, we test
-	# the value of "$done" until we find the cure or run out of ideas.
-	done="no"
-	
-	# First, make sure the CFLAGS we added are actually accepted by our
-	# compiler.  If not (and OS X's ld, for instance, does not accept -z),
-	# then we can't do this test.
-	if test x"$done" = xno; then
-	   AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
-	   AC_TRY_LINK(,, , [done=yes])
-	
-	   if test "x$done" = xyes ; then
-	      AC_MSG_RESULT([no])
-	   else
-	      AC_MSG_RESULT([yes])
-	   fi
-	fi
-	
-	if test x"$done" = xno; then
-	   AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
-	   AC_TRY_LINK([#include <pthread.h>],
-	      [pthread_t th; pthread_join(th, 0);
-	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
-	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-	      [done=yes])
-	   
-	   if test "x$done" = xyes; then
-	      AC_MSG_RESULT([yes])
-	   else
-	      AC_MSG_RESULT([no])
-	   fi
-	fi
-	
-	#
-	# Linux gcc on some architectures such as mips/mipsel forgets
-	# about -lpthread
-	#
-	if test x"$done" = xno; then
-	   AC_MSG_CHECKING([whether -lpthread fixes that])
-	   LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
-	   AC_TRY_LINK([#include <pthread.h>],
-	      [pthread_t th; pthread_join(th, 0);
-	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
-	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-	      [done=yes])
-	
-	   if test "x$done" = xyes; then
-	      AC_MSG_RESULT([yes])
-	      PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
-	   else
-	      AC_MSG_RESULT([no])
-	   fi
-	fi
-	#
-	# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
-	#
-	if test x"$done" = xno; then
-	   AC_MSG_CHECKING([whether -lc_r fixes that])
-	   LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
-	   AC_TRY_LINK([#include <pthread.h>],
-	       [pthread_t th; pthread_join(th, 0);
-	        pthread_attr_init(0); pthread_cleanup_push(0, 0);
-	        pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-	       [done=yes])
-	
-	   if test "x$done" = xyes; then
-	      AC_MSG_RESULT([yes])
-	      PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
-	   else
-	      AC_MSG_RESULT([no])
-	   fi
-	fi
-	if test x"$done" = xno; then
-	   # OK, we have run out of ideas
-	   AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
-	
-	   # so it's not safe to assume that we may use pthreads
-	   acx_pthread_ok=no
-	fi
-	
-	AC_MSG_CHECKING([whether what we have so far is sufficient with -nostdlib])
-	CFLAGS="-nostdlib $CFLAGS"
-	# we need c with nostdlib
-	LIBS="$LIBS -lc"
-	AC_TRY_LINK([#include <pthread.h>],
-	      [pthread_t th; pthread_join(th, 0);
-	       pthread_attr_init(0); pthread_cleanup_push(0, 0);
-	       pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-	      [done=yes],[done=no])
-
-	if test "x$done" = xyes; then
-	   AC_MSG_RESULT([yes])
-	else
-	   AC_MSG_RESULT([no])
-	fi
-	
-	if test x"$done" = xno; then
-	   AC_MSG_CHECKING([whether -lpthread saves the day])
-	   LIBS="-lpthread $LIBS"
-	   AC_TRY_LINK([#include <pthread.h>],
-	      [pthread_t th; pthread_join(th, 0);
-	       pthread_attr_init(0); pthread_cleanup_push(0, 0);
-	       pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-	      [done=yes],[done=no])
-
-	   if test "x$done" = xyes; then
-	      AC_MSG_RESULT([yes])
-	      PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
-	   else
-	      AC_MSG_RESULT([no])
-	      AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries and -nostdlib])
-	   fi
-	fi
-
-	CFLAGS="$save_CFLAGS"
-	LIBS="$save_LIBS"
-	CC="$save_CC"
-else
-        PTHREAD_CC="$CC"
-fi
-
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_CC)
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
-        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
-        :
-else
-        acx_pthread_ok=no
-        $2
-fi
-AC_LANG_RESTORE
-])dnl ACX_PTHREAD
diff --git a/third_party/tcmalloc/vendor/m4/ax_generate_changelog.m4 b/third_party/tcmalloc/vendor/m4/ax_generate_changelog.m4
deleted file mode 100644
index d9d5cd1..0000000
--- a/third_party/tcmalloc/vendor/m4/ax_generate_changelog.m4
+++ /dev/null
@@ -1,99 +0,0 @@
-# ===========================================================================
-#   http://www.gnu.org/software/autoconf-archive/ax_generate_changelog.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-#   AX_GENERATE_CHANGELOG()
-#
-# DESCRIPTION
-#
-#   Builds a rule for generating a ChangeLog file from version control
-#   system commit messages.  Currently, the only supported VCS is git, but
-#   support for others could be added in future.
-#
-#   Defines GENERATE_CHANGELOG_RULES which should be substituted in your
-#   Makefile.
-#
-#   Usage example:
-#
-#   configure.ac:
-#
-#     AX_GENERATE_CHANGELOG
-#
-#   Makefile.am:
-#
-#     @GENERATE_CHANGELOG_RULES@
-#     CHANGELOG_START = 0.2.3^
-#     dist-hook: dist-ChangeLog
-#
-#   ChangeLog (stub committed to VCS):
-#
-#     The ChangeLog is auto-generated when releasing.
-#     If you are seeing this, use 'git log' for a detailed list of changes.
-#
-#   This results in a "dist-ChangeLog" rule being added to the Makefile.
-#   When run, "dist-ChangeLog" will generate a ChangeLog in the
-#   $(top_distdir), using $(CHANGELOG_GIT_FLAGS) to format the output from
-#   "git log" being run in $(CHANGELOG_GIT_DIR).
-#
-#   Unless Automake is initialised with the 'foreign' option, a dummy
-#   ChangeLog file must be committed to VCS in $(top_srcdir), containing the
-#   text above (for example).  It will be substituted by the automatically
-#   generated ChangeLog during "make dist".
-#
-# LICENSE
-#
-#   Copyright (c) 2015 David King <amigadave@amigadave.com>
-#   Copyright (c) 2015 Philip Withnall <philip.withnall@collabora.co.uk>
-#
-#   Copying and distribution of this file, with or without modification, are
-#   permitted in any medium without royalty provided the copyright notice
-#   and this notice are preserved.  This file is offered as-is, without any
-#   warranty.
-
-#serial 1
-
-AC_DEFUN([AX_GENERATE_CHANGELOG],[
-	# Find git, defaulting to the 'missing' script so the user gets a nice
-	# message if git is missing, rather than a plain 'command not found'.
-	AC_PATH_PROG([GIT],[git],[${am_missing_run}git])
-	AC_SUBST([GIT])
-
-	# Build the ChangeLog rules.
-	m4_pattern_allow([AM_V_GEN])
-GENERATE_CHANGELOG_RULES='
-# Generate ChangeLog
-#
-# Optional:
-#  - CHANGELOG_START: git commit ID or tag name to output changelogs from
-#    (exclusive). (Default: include all commits)
-#  - CHANGELOG_GIT_FLAGS: General flags to pass to git-log when generating the
-#    ChangeLog. (Default: various)
-#  - CHANGELOG_GIT_DIR: .git directory to use. (Default: $(top_srcdir)/.git)
-
-# git-specific
-CHANGELOG_GIT_FLAGS ?= --stat -M -C --name-status --no-color
-CHANGELOG_GIT_DIR ?= $(top_srcdir)/.git
-
-ifeq ($(CHANGELOG_START),)
-CHANGELOG_GIT_RANGE =
-else
-CHANGELOG_GIT_RANGE = $(CHANGELOG_START)..
-endif
-
-# Generate a ChangeLog in $(top_distdir)
-dist-ChangeLog:
-	$(AM_V_GEN)if $(GIT) \
-		--git-dir=$(CHANGELOG_GIT_DIR) --work-tree=$(top_srcdir) log \
-		$(CHANGELOG_GIT_FLAGS) $(CHANGELOG_GIT_RANGE) \
-		| fmt --split-only >.ChangeLog.tmp; \
-	then mv -f .ChangeLog.tmp "$(top_distdir)/ChangeLog"; \
-	else rm -f .ChangeLog.tmp; exit 1; fi
-
-.PHONY: dist-ChangeLog
-'
-
-	AC_SUBST([GENERATE_CHANGELOG_RULES])
-	m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([GENERATE_CHANGELOG_RULES])])
-])
diff --git a/third_party/tcmalloc/vendor/m4/compiler_characteristics.m4 b/third_party/tcmalloc/vendor/m4/compiler_characteristics.m4
deleted file mode 100644
index 2b628930..0000000
--- a/third_party/tcmalloc/vendor/m4/compiler_characteristics.m4
+++ /dev/null
@@ -1,24 +0,0 @@
-# Check compiler characteristics (e.g. type sizes, PRIxx macros, ...)
-
-# If types $1 and $2 are compatible, perform action $3
-AC_DEFUN([AC_TYPES_COMPATIBLE],
-  [AC_TRY_COMPILE([#include <stddef.h>], [$1 v1 = 0; $2 v2 = 0; return (&v1 - &v2)], $3)])
-
-define(AC_PRIUS_COMMENT, [printf format code for printing a size_t and ssize_t])
-
-AC_DEFUN([AC_COMPILER_CHARACTERISTICS],
-  [AC_CACHE_CHECK(AC_PRIUS_COMMENT, ac_cv_formatting_prius_prefix,
-    [AC_TYPES_COMPATIBLE(unsigned int, size_t, 
-	                 ac_cv_formatting_prius_prefix=; ac_cv_prius_defined=1)
-     AC_TYPES_COMPATIBLE(unsigned long, size_t,
-	                 ac_cv_formatting_prius_prefix=l; ac_cv_prius_defined=1)
-     AC_TYPES_COMPATIBLE(unsigned long long, size_t,
-                         ac_cv_formatting_prius_prefix=ll; ac_cv_prius_defined=1
-     )])
-   if test -z "$ac_cv_prius_defined"; then 
-      ac_cv_formatting_prius_prefix=z;
-   fi
-   AC_DEFINE_UNQUOTED(PRIuS, "${ac_cv_formatting_prius_prefix}u", AC_PRIUS_COMMENT)
-   AC_DEFINE_UNQUOTED(PRIxS, "${ac_cv_formatting_prius_prefix}x", AC_PRIUS_COMMENT)
-   AC_DEFINE_UNQUOTED(PRIdS, "${ac_cv_formatting_prius_prefix}d", AC_PRIUS_COMMENT)
-])
diff --git a/third_party/tcmalloc/vendor/m4/install_prefix.m4 b/third_party/tcmalloc/vendor/m4/install_prefix.m4
deleted file mode 100644
index ef33f42e..0000000
--- a/third_party/tcmalloc/vendor/m4/install_prefix.m4
+++ /dev/null
@@ -1,8 +0,0 @@
-AC_DEFUN([AC_INSTALL_PREFIX],
-  [ac_cv_install_prefix="$prefix";
-   if test x"$ac_cv_install_prefix" = x"NONE" ; then
-     ac_cv_install_prefix="$ac_default_prefix";
-   fi
-   AC_DEFINE_UNQUOTED(INSTALL_PREFIX, "$ac_cv_install_prefix",
-     [prefix where we look for installed files])
-   ])
diff --git a/third_party/tcmalloc/vendor/m4/namespaces.m4 b/third_party/tcmalloc/vendor/m4/namespaces.m4
deleted file mode 100644
index d78dbe4..0000000
--- a/third_party/tcmalloc/vendor/m4/namespaces.m4
+++ /dev/null
@@ -1,15 +0,0 @@
-# Checks whether the compiler implements namespaces
-AC_DEFUN([AC_CXX_NAMESPACES],
- [AC_CACHE_CHECK(whether the compiler implements namespaces,
-                 ac_cv_cxx_namespaces,
-                 [AC_LANG_SAVE
-                  AC_LANG_CPLUSPLUS
-                  AC_TRY_COMPILE([namespace Outer {
-                                    namespace Inner { int i = 0; }}],
-                                 [using namespace Outer::Inner; return i;],
-                                 ac_cv_cxx_namespaces=yes,
-                                 ac_cv_cxx_namespaces=no)
-                  AC_LANG_RESTORE])
-  if test "$ac_cv_cxx_namespaces" = yes; then
-    AC_DEFINE(HAVE_NAMESPACES, 1, [define if the compiler implements namespaces])
-  fi])
diff --git a/third_party/tcmalloc/vendor/m4/pc_from_ucontext.m4 b/third_party/tcmalloc/vendor/m4/pc_from_ucontext.m4
deleted file mode 100644
index c9224bc64..0000000
--- a/third_party/tcmalloc/vendor/m4/pc_from_ucontext.m4
+++ /dev/null
@@ -1,98 +0,0 @@
-# We want to access the "PC" (Program Counter) register from a struct
-# ucontext.  Every system has its own way of doing that.  We try all the
-# possibilities we know about.  Note REG_PC should come first (REG_RIP
-# is also defined on solaris, but does the wrong thing).
-
-# OpenBSD doesn't have ucontext.h, but we can get PC from ucontext_t
-# by using signal.h.
-
-# The first argument of AC_PC_FROM_UCONTEXT will be invoked when we
-# cannot find a way to obtain PC from ucontext.
-
-AC_DEFUN([AC_PC_FROM_UCONTEXT],
-  [AC_CHECK_HEADERS(ucontext.h)
-   # Redhat 7 has <sys/ucontext.h>, but it barfs if we #include it directly
-   # (this was fixed in later redhats).  <ucontext.h> works fine, so use that.
-   if grep "Red Hat Linux release 7" /etc/redhat-release >/dev/null 2>&1; then
-     AC_DEFINE(HAVE_SYS_UCONTEXT_H, 0, [<sys/ucontext.h> is broken on redhat 7])
-     ac_cv_header_sys_ucontext_h=no
-   else
-     AC_CHECK_HEADERS(sys/ucontext.h)       # ucontext on OS X 10.6 (at least)
-   fi
-   AC_CHECK_HEADERS(cygwin/signal.h)        # ucontext on cywgin
-   AC_MSG_CHECKING([how to access the program counter from a struct ucontext])
-   pc_fields="           uc_mcontext.gregs[[REG_PC]]"  # Solaris x86 (32 + 64 bit)
-   pc_fields="$pc_fields uc_mcontext.gregs[[REG_EIP]]" # Linux (i386)
-   pc_fields="$pc_fields uc_mcontext.gregs[[REG_RIP]]" # Linux (x86_64)
-   pc_fields="$pc_fields uc_mcontext.sc_ip"            # Linux (ia64)
-   pc_fields="$pc_fields uc_mcontext.pc"               # Linux (mips)
-   pc_fields="$pc_fields uc_mcontext.uc_regs->gregs[[PT_NIP]]" # Linux (ppc)
-   pc_fields="$pc_fields uc_mcontext.psw.addr"         # Linux (s390)
-   pc_fields="$pc_fields uc_mcontext.gregs[[R15]]"     # Linux (arm old [untested])
-   pc_fields="$pc_fields uc_mcontext.arm_pc"           # Linux (arm arch 5)
-   pc_fields="$pc_fields uc_mcontext.gp_regs[[PT_NIP]]"  # Suse SLES 11 (ppc64)
-   pc_fields="$pc_fields uc_mcontext.mc_eip"           # FreeBSD (i386)
-   pc_fields="$pc_fields uc_mcontext.mc_rip"           # FreeBSD (x86_64 [untested])
-   pc_fields="$pc_fields uc_mcontext.__gregs[[_REG_EIP]]"  # NetBSD (i386)
-   pc_fields="$pc_fields uc_mcontext.__gregs[[_REG_RIP]]"  # NetBSD (x86_64)
-   pc_fields="$pc_fields uc_mcontext->ss.eip"          # OS X (i386, <=10.4)
-   pc_fields="$pc_fields uc_mcontext->__ss.__eip"      # OS X (i386, >=10.5)
-   pc_fields="$pc_fields uc_mcontext->ss.rip"          # OS X (x86_64)
-   pc_fields="$pc_fields uc_mcontext->__ss.__rip"      # OS X (>=10.5 [untested])
-   pc_fields="$pc_fields uc_mcontext->ss.srr0"         # OS X (ppc, ppc64 [untested])
-   pc_fields="$pc_fields uc_mcontext->__ss.__srr0"     # OS X (>=10.5 [untested])
-   pc_field_found=false
-   for pc_field in $pc_fields; do
-     if ! $pc_field_found; then
-       # Prefer sys/ucontext.h to ucontext.h, for OS X's sake.
-       if test "x$ac_cv_header_cygwin_signal_h" = xyes; then
-         AC_TRY_COMPILE([#define _GNU_SOURCE 1
-                         #include <cygwin/signal.h>],
-                        [ucontext_t u; return u.$pc_field == 0;],
-                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
-                                           How to access the PC from a struct ucontext)
-                        AC_MSG_RESULT([$pc_field])
-                        pc_field_found=true)
-       elif test "x$ac_cv_header_sys_ucontext_h" = xyes; then
-         AC_TRY_COMPILE([#define _GNU_SOURCE 1
-                         #include <sys/ucontext.h>],
-                        [ucontext_t u; return u.$pc_field == 0;],
-                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
-                                           How to access the PC from a struct ucontext)
-                        AC_MSG_RESULT([$pc_field])
-                        pc_field_found=true)
-       elif test "x$ac_cv_header_ucontext_h" = xyes; then
-         AC_TRY_COMPILE([#define _GNU_SOURCE 1
-                         #include <ucontext.h>],
-                        [ucontext_t u; return u.$pc_field == 0;],
-                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
-                                           How to access the PC from a struct ucontext)
-                        AC_MSG_RESULT([$pc_field])
-                        pc_field_found=true)
-       else     # hope some standard header gives it to us
-         AC_TRY_COMPILE([],
-                        [ucontext_t u; return u.$pc_field == 0;],
-                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
-                                           How to access the PC from a struct ucontext)
-                        AC_MSG_RESULT([$pc_field])
-                        pc_field_found=true)
-       fi
-     fi
-   done
-   if ! $pc_field_found; then
-     pc_fields="           sc_eip"  # OpenBSD (i386)
-     pc_fields="$pc_fields sc_rip"  # OpenBSD (x86_64)
-     for pc_field in $pc_fields; do
-       if ! $pc_field_found; then
-         AC_TRY_COMPILE([#include <signal.h>],
-                        [ucontext_t u; return u.$pc_field == 0;],
-                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
-                                           How to access the PC from a struct ucontext)
-                        AC_MSG_RESULT([$pc_field])
-                        pc_field_found=true)
-       fi
-     done
-   fi
-   if ! $pc_field_found; then
-     [$1]
-   fi])
diff --git a/third_party/tcmalloc/vendor/m4/program_invocation_name.m4 b/third_party/tcmalloc/vendor/m4/program_invocation_name.m4
deleted file mode 100644
index 6161f66..0000000
--- a/third_party/tcmalloc/vendor/m4/program_invocation_name.m4
+++ /dev/null
@@ -1,19 +0,0 @@
-# We need to be careful to avoid having the reference to
-# program_invocation_name optimized out.  We do that by
-# returning the value.
-
-AC_DEFUN([AC_PROGRAM_INVOCATION_NAME],
-  [AC_CACHE_CHECK(
-    for program_invocation_name,
-    ac_cv_have_program_invocation_name,
-    AC_TRY_LINK([extern char* program_invocation_name;],
-	        [return *program_invocation_name;],
-	        [ac_cv_have_program_invocation_name=yes],
-		[ac_cv_have_program_invocation_name=no])
-   )
-   if test "$ac_cv_have_program_invocation_name" = "yes"; then
-     AC_DEFINE(HAVE_PROGRAM_INVOCATION_NAME, 1,
-               [define if libc has program_invocation_name])
-   fi
-   ])
-   
diff --git a/third_party/tcmalloc/vendor/m4/stl_namespace.m4 b/third_party/tcmalloc/vendor/m4/stl_namespace.m4
deleted file mode 100644
index 989ad806..0000000
--- a/third_party/tcmalloc/vendor/m4/stl_namespace.m4
+++ /dev/null
@@ -1,25 +0,0 @@
-# We check what namespace stl code like vector expects to be executed in
-
-AC_DEFUN([AC_CXX_STL_NAMESPACE],
-  [AC_CACHE_CHECK(
-      what namespace STL code is in,
-      ac_cv_cxx_stl_namespace,
-      [AC_REQUIRE([AC_CXX_NAMESPACES])
-      AC_LANG_SAVE
-      AC_LANG_CPLUSPLUS
-      AC_TRY_COMPILE([#include <vector>],
-                     [vector<int> t; return 0;],
-                     ac_cv_cxx_stl_namespace=none)
-      AC_TRY_COMPILE([#include <vector>],
-                     [std::vector<int> t; return 0;],
-                     ac_cv_cxx_stl_namespace=std)
-      AC_LANG_RESTORE])
-   if test "$ac_cv_cxx_stl_namespace" = none; then
-      AC_DEFINE(STL_NAMESPACE,,
-                [the namespace where STL code like vector<> is defined])
-   fi
-   if test "$ac_cv_cxx_stl_namespace" = std; then
-      AC_DEFINE(STL_NAMESPACE,std,
-                [the namespace where STL code like vector<> is defined])
-   fi
-])
diff --git a/third_party/tcmalloc/vendor/packages/deb.sh b/third_party/tcmalloc/vendor/packages/deb.sh
deleted file mode 100755
index 31b423c1..0000000
--- a/third_party/tcmalloc/vendor/packages/deb.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/bash -e
-
-# This takes one commandline argument, the name of the package.  If no
-# name is given, then we'll end up just using the name associated with
-# an arbitrary .tar.gz file in the rootdir.  That's fine: there's probably
-# only one.
-#
-# Run this from the 'packages' directory, just under rootdir
-
-## Set LIB to lib if exporting a library, empty-string else
-LIB=
-#LIB=lib
-
-PACKAGE="$1"
-VERSION="$2"
-
-# We can only build Debian packages, if the Debian build tools are installed
-if [ \! -x /usr/bin/debuild ]; then
-  echo "Cannot find /usr/bin/debuild. Not building Debian packages." 1>&2
-  exit 0
-fi
-
-# Double-check we're in the packages directory, just under rootdir
-if [ \! -r ../Makefile -a \! -r ../INSTALL ]; then
-  echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
-  echo "Also, you must run \"make dist\" before running this script." 1>&2
-  exit 0
-fi
-
-# Find the top directory for this package
-topdir="${PWD%/*}"
-
-# Find the tar archive built by "make dist"
-archive="${PACKAGE}-${VERSION}"
-archive_with_underscore="${PACKAGE}_${VERSION}"
-if [ -z "${archive}" ]; then
-  echo "Cannot find ../$PACKAGE*.tar.gz. Run \"make dist\" first." 1>&2
-  exit 0
-fi
-
-# Create a pristine directory for building the Debian package files
-trap 'rm -rf '`pwd`/tmp'; exit $?' EXIT SIGHUP SIGINT SIGTERM
-
-rm -rf tmp
-mkdir -p tmp
-cd tmp
-
-# Debian has very specific requirements about the naming of build
-# directories, and tar archives. It also wants to write all generated
-# packages to the parent of the source directory. We accommodate these
-# requirements by building directly from the tar file.
-ln -s "${topdir}/${archive}.tar.gz" "${LIB}${archive}.orig.tar.gz"
-# Some version of debuilder want foo.orig.tar.gz with _ between versions.
-ln -s "${topdir}/${archive}.tar.gz" "${LIB}${archive_with_underscore}.orig.tar.gz"
-tar zfx "${LIB}${archive}.orig.tar.gz"
-[ -n "${LIB}" ] && mv "${archive}" "${LIB}${archive}"
-cd "${LIB}${archive}"
-# This is one of those 'specific requirements': where the deb control files live
-cp -a "packages/deb" "debian"
-
-# Now, we can call Debian's standard build tool
-debuild -uc -us
-cd ../..                            # get back to the original top-level dir
-
-# We'll put the result in a subdirectory that's named after the OS version
-# we've made this .deb file for.
-destdir="debian-$(cat /etc/debian_version 2>/dev/null || echo UNKNOWN)"
-
-rm -rf "$destdir"
-mkdir -p "$destdir"
-mv $(find tmp -mindepth 1 -maxdepth 1 -type f) "$destdir"
-
-echo
-echo "The Debian package files are located in $PWD/$destdir"
diff --git a/third_party/tcmalloc/vendor/packages/deb/README b/third_party/tcmalloc/vendor/packages/deb/README
deleted file mode 100644
index 57becfd..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/README
+++ /dev/null
@@ -1,7 +0,0 @@
-The list of files here isn't complete.  For a step-by-step guide on
-how to set this package up correctly, check out
-    http://www.debian.org/doc/maint-guide/
-
-Most of the files that are in this directory are boilerplate.
-However, you may need to change the list of binary-arch dependencies
-in 'rules'.
diff --git a/third_party/tcmalloc/vendor/packages/deb/changelog b/third_party/tcmalloc/vendor/packages/deb/changelog
deleted file mode 100644
index d67df6113..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/changelog
+++ /dev/null
@@ -1,208 +0,0 @@
-gperftools (2.1-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- gperftools Contributors <google-perftools@googlegroups.com>  Tue, 30 Jul 2013 11:51:13 +0300
-
-gperftools (2.0.99-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- gperftools Contributors <google-perftools@googlegroups.com>  Sat, 20 Jul 2013 14:21:10 -0700
-
-gperftools (2.0-1) unstable; urgency=low
-
-  * New upstream release.
-  * Package renamed from google-perftools to gperftools.
-
- -- Google Inc. and others <google-perftools@googlegroups.com>  Fri, 03 Feb 2012 15:40:45 -0800
-
-google-perftools (1.10-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Tue, 31 Jan 2012 10:43:50 -0800
-
-google-perftools (1.9-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Thu, 22 Dec 2011 16:22:45 -0800
-
-google-perftools (1.8-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Fri, 15 Jul 2011 16:10:51 -0700
-
-google-perftools (1.7-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Fri, 04 Feb 2011 15:54:31 -0800
-
-google-perftools (1.6-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Thu, 05 Aug 2010 12:48:03 -0700
-
-google-perftools (1.5-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Tue, 19 Jan 2010 14:46:12 -0800
-
-google-perftools (1.4-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Thu, 10 Sep 2009 13:51:15 -0700
-
-google-perftools (1.3-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Tue, 09 Jun 2009 18:19:06 -0700
-
-google-perftools (1.2-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Fri, 17 Apr 2009 16:40:48 -0700
-
-google-perftools (1.1-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Wed, 11 Mar 2009 11:25:34 -0700
-
-google-perftools (1.0-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Tue, 06 Jan 2009 13:58:56 -0800
-	
-google-perftools (1.0rc1-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Thu, 11 Dec 2008 16:01:32 -0800
-	
-google-perftools (0.99.1-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Sat, 20 Sep 2008 09:37:18 -0700
-	
-google-perftools (0.99-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Thu, 18 Sep 2008 16:00:27 -0700
-	
-google-perftools (0.98-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Mon, 09 Jun 2008 16:47:03 -0700
-	
-google-perftools (0.97-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Mon, 21 Apr 2008 15:20:52 -0700
-	
-google-perftools (0.96-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Tue, 18 Mar 2008 14:30:44 -0700
-	
-google-perftools (0.95-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Tue, 12 Feb 2008 12:28:32 -0800
-
-google-perftools (0.94-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Thu, 29 Nov 2007 07:59:43 -0800
-
-google-perftools (0.93-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Fri, 17 Aug 2007 12:32:56 -0700
-
-google-perftools (0.92-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Tue, 17 Jul 2007 22:26:27 -0700
-
-google-perftools (0.91-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Wed, 18 Apr 2007 16:43:55 -0700
-
-google-perftools (0.90-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Fri, 13 Apr 2007 14:50:51 -0700
-
-google-perftools (0.8-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Wed, 14 Jun 2006 15:11:14 -0700
-
-google-perftools (0.7-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Thu, 13 Apr 2006 20:59:09 -0700
-
-google-perftools (0.6-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Fri, 27 Jan 2006 14:04:27 -0800
-
-google-perftools (0.5-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Mon, Nov 14 17:28:59 2005 -0800
-
-google-perftools (0.4-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Wed, 26 Oct 2005 15:19:16 -0700
-
-google-perftools (0.3-1) unstable; urgency=low
-
-  * New upstream release.
-  
- -- Google Inc. <opensource@google.com>  Fri, 24 Jun 2005 18:02:26 -0700
-
-google-perftools (0.2-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Google Inc. <opensource@google.com>  Tue, 31 May 2005 08:14:38 -0700
-
-google-perftools (0.1-1) unstable; urgency=low
-
-  * Initial release.
-    The google-perftools package contains some utilities to improve
-    and analyze the performance of C++ programs.  This includes an
-    optimized thread-caching malloc() and cpu and heap profiling
-    utilities.
-
- -- Google Inc. <opensource@google.com>  Fri, 11 Mar 2005 08:07:33 -0800
diff --git a/third_party/tcmalloc/vendor/packages/deb/compat b/third_party/tcmalloc/vendor/packages/deb/compat
deleted file mode 100644
index b8626c4c..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/compat
+++ /dev/null
@@ -1 +0,0 @@
-4
diff --git a/third_party/tcmalloc/vendor/packages/deb/control b/third_party/tcmalloc/vendor/packages/deb/control
deleted file mode 100644
index 37c34a5..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/control
+++ /dev/null
@@ -1,25 +0,0 @@
-Source: gperftools
-Priority: optional
-Maintainer: gperftools Contributors <google-perftools@googlegroups.com>
-Build-Depends: debhelper (>= 4.0.0), binutils
-Standards-Version: 3.6.1
-
-Package: libgperftools-dev
-Section: libdevel
-Architecture: any
-Depends: libgperftools0 (= ${Source-Version})
-Description: libraries for CPU and heap analysis, plus an efficient thread-caching malloc
- The gperftools package contains some utilities to improve and
- analyze the performance of C++ programs.  This includes an optimized
- thread-caching malloc() and cpu and heap profiling utilities.  The
- devel package contains static and debug libraries and header files
- for developing applications that use the gperftools package.
-
-Package: libgperftools0
-Section: libs
-Architecture: any
-Depends: ${shlibs:Depends}
-Description: libraries for CPU and heap analysis, plus an efficient thread-caching malloc
- The gperftools package contains some utilities to improve and
- analyze the performance of C++ programs.  This includes an optimized
- thread-caching malloc() and cpu and heap profiling utilities.
diff --git a/third_party/tcmalloc/vendor/packages/deb/copyright b/third_party/tcmalloc/vendor/packages/deb/copyright
deleted file mode 100644
index db7c78e3..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/copyright
+++ /dev/null
@@ -1,38 +0,0 @@
-This package was debianized by gperftools Contributors <google-perftools@googlegroups.com>
-on Sat, 20 Jul 2013 14:21:10 -0700.
-
-It was downloaded from http://code.google.com/p/gperftools/downloads/list
-
-Upstream Author: google-perftools@googlegroups.com
-
-Copyright (c) 2005, Google Inc.
-All rights reserved.
-
-Copyright (c) 2013, gperftools Contributors
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/tcmalloc/vendor/packages/deb/docs b/third_party/tcmalloc/vendor/packages/deb/docs
deleted file mode 100644
index fc4806f2..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/docs
+++ /dev/null
@@ -1,47 +0,0 @@
-AUTHORS
-COPYING
-ChangeLog
-INSTALL
-NEWS
-README
-TODO
-docs/cpuprofile.html
-docs/cpuprofile-fileformat.html
-docs/designstyle.css
-docs/heap-example1.png
-docs/heap_checker.html
-docs/heapprofile.html
-docs/index.html
-docs/overview.gif
-docs/pageheap.gif
-docs/pprof-test-big.gif
-docs/pprof-test.gif
-docs/pprof-vsnprintf-big.gif
-docs/pprof-vsnprintf.gif
-docs/pprof.1
-docs/pprof_remote_servers.html
-docs/spanmap.gif
-docs/t-test1.times.txt
-docs/tcmalloc-opspercpusec.vs.threads.1024.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.128.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.131072.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.16384.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.2048.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.256.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.32768.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.4096.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.512.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.64.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.65536.bytes.png
-docs/tcmalloc-opspercpusec.vs.threads.8192.bytes.png
-docs/tcmalloc-opspersec.vs.size.1.threads.png
-docs/tcmalloc-opspersec.vs.size.12.threads.png
-docs/tcmalloc-opspersec.vs.size.16.threads.png
-docs/tcmalloc-opspersec.vs.size.2.threads.png
-docs/tcmalloc-opspersec.vs.size.20.threads.png
-docs/tcmalloc-opspersec.vs.size.3.threads.png
-docs/tcmalloc-opspersec.vs.size.4.threads.png
-docs/tcmalloc-opspersec.vs.size.5.threads.png
-docs/tcmalloc-opspersec.vs.size.8.threads.png
-docs/tcmalloc.html
-docs/threadheap.gif
diff --git a/third_party/tcmalloc/vendor/packages/deb/libgperftools-dev.dirs b/third_party/tcmalloc/vendor/packages/deb/libgperftools-dev.dirs
deleted file mode 100644
index 8f88347..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/libgperftools-dev.dirs
+++ /dev/null
@@ -1,5 +0,0 @@
-usr/lib
-usr/lib/pkgconfig
-usr/include
-usr/include/google
-usr/include/gperftools
diff --git a/third_party/tcmalloc/vendor/packages/deb/libgperftools-dev.install b/third_party/tcmalloc/vendor/packages/deb/libgperftools-dev.install
deleted file mode 100644
index e863529f..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/libgperftools-dev.install
+++ /dev/null
@@ -1,12 +0,0 @@
-usr/include/google/*
-usr/include/gperftools/*
-usr/lib/lib*.so
-usr/lib/lib*.a
-usr/lib/*.la
-usr/lib/pkgconfig/*.pc
-debian/tmp/usr/include/google/*
-debian/tmp/usr/include/gperftools/*
-debian/tmp/usr/lib/lib*.so
-debian/tmp/usr/lib/lib*.a
-debian/tmp/usr/lib/*.la
-debian/tmp/usr/lib/pkgconfig/*.pc
diff --git a/third_party/tcmalloc/vendor/packages/deb/libgperftools0.dirs b/third_party/tcmalloc/vendor/packages/deb/libgperftools0.dirs
deleted file mode 100644
index 14f5b95..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/libgperftools0.dirs
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/lib
-usr/bin
diff --git a/third_party/tcmalloc/vendor/packages/deb/libgperftools0.install b/third_party/tcmalloc/vendor/packages/deb/libgperftools0.install
deleted file mode 100644
index 047eed5..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/libgperftools0.install
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/lib/lib*.so.*
-usr/bin/pprof*
-debian/tmp/usr/lib/lib*.so.*
-debian/tmp/usr/bin/pprof*
diff --git a/third_party/tcmalloc/vendor/packages/deb/libgperftools0.manpages b/third_party/tcmalloc/vendor/packages/deb/libgperftools0.manpages
deleted file mode 100644
index 8ecbfc4a..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/libgperftools0.manpages
+++ /dev/null
@@ -1 +0,0 @@
-docs/pprof.1
diff --git a/third_party/tcmalloc/vendor/packages/deb/rules b/third_party/tcmalloc/vendor/packages/deb/rules
deleted file mode 100755
index f520bef..0000000
--- a/third_party/tcmalloc/vendor/packages/deb/rules
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-# Sample debian/rules that uses debhelper.
-# This file was originally written by Joey Hess and Craig Small.
-# As a special exception, when this file is copied by dh-make into a
-# dh-make output file, you may use that output file without restriction.
-# This special exception was added by Craig Small in version 0.37 of dh-make.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-
-# These are used for cross-compiling and for saving the configure script
-# from having to guess our platform (since we know it already)
-DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
-DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-
-
-CFLAGS = -Wall -g
-
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
-	CFLAGS += -O0
-else
-	CFLAGS += -O2
-endif
-ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
-	INSTALL_PROGRAM += -s
-endif
-
-# shared library versions, option 1
-#version=2.0.5
-#major=2
-# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
-version=`ls src/.libs/lib*.so.* | \
- awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
-major=`ls src/.libs/lib*.so.* | \
- awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
-
-config.status: configure
-	dh_testdir
-	# Add here commands to configure the package.
-	CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
-
-
-build: build-stamp
-build-stamp:  config.status
-	dh_testdir
-
-	# Add here commands to compile the package.
-	$(MAKE)
-
-	touch build-stamp
-
-clean:
-	dh_testdir
-	dh_testroot
-	rm -f build-stamp 
-
-	# Add here commands to clean up after the build process.
-	-$(MAKE) distclean
-ifneq "$(wildcard /usr/share/misc/config.sub)" ""
-	cp -f /usr/share/misc/config.sub config.sub
-endif
-ifneq "$(wildcard /usr/share/misc/config.guess)" ""
-	cp -f /usr/share/misc/config.guess config.guess
-endif
-
-
-	dh_clean 
-
-install: build
-	dh_testdir
-	dh_testroot
-	dh_clean -k 
-	dh_installdirs
-
-	# Add here commands to install the package into debian/tmp
-	$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
-
-
-# Build architecture-independent files here.
-binary-indep: build install
-# We have nothing to do by default.
-
-# Build architecture-dependent files here.
-binary-arch: build install
-	dh_testdir
-	dh_testroot
-	dh_installchangelogs ChangeLog
-	dh_installdocs
-	dh_installexamples
-	dh_install --sourcedir=debian/tmp
-#	dh_installmenu
-#	dh_installdebconf	
-#	dh_installlogrotate
-#	dh_installemacsen
-#	dh_installpam
-#	dh_installmime
-#	dh_installinit
-#	dh_installcron
-#	dh_installinfo
-	dh_installman
-	dh_link
-	dh_strip
-	dh_compress
-	dh_fixperms
-#	dh_perl
-#	dh_python
-	dh_makeshlibs
-	dh_installdeb
-	dh_shlibdeps
-	dh_gencontrol
-	dh_md5sums
-	dh_builddeb
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install 
diff --git a/third_party/tcmalloc/vendor/packages/rpm.sh b/third_party/tcmalloc/vendor/packages/rpm.sh
deleted file mode 100755
index 448a032..0000000
--- a/third_party/tcmalloc/vendor/packages/rpm.sh
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/bin/sh -e
-
-# Run this from the 'packages' directory, just under rootdir
-
-# We can only build rpm packages, if the rpm build tools are installed
-if [ \! -x /usr/bin/rpmbuild ]
-then
-  echo "Cannot find /usr/bin/rpmbuild. Not building an rpm." 1>&2
-  exit 0
-fi
-
-# Check the commandline flags
-PACKAGE="$1"
-VERSION="$2"
-fullname="${PACKAGE}-${VERSION}"
-archive=../$fullname.tar.gz
-
-if [ -z "$1" -o -z "$2" ]
-then
-  echo "Usage: $0 <package name> <package version>" 1>&2
-  exit 0
-fi
-
-# Double-check we're in the packages directory, just under rootdir
-if [ \! -r ../Makefile -a \! -r ../INSTALL ]
-then
-  echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
-  echo "Also, you must run \"make dist\" before running this script." 1>&2
-  exit 0
-fi
-
-if [ \! -r "$archive" ]
-then
-  echo "Cannot find $archive. Run \"make dist\" first." 1>&2
-  exit 0
-fi
-
-# Create the directory where the input lives, and where the output should live
-RPM_SOURCE_DIR="/tmp/rpmsource-$fullname"
-RPM_BUILD_DIR="/tmp/rpmbuild-$fullname"
-
-trap 'rm -rf $RPM_SOURCE_DIR $RPM_BUILD_DIR; exit $?' EXIT SIGHUP SIGINT SIGTERM
-
-rm -rf "$RPM_SOURCE_DIR" "$RPM_BUILD_DIR"
-mkdir "$RPM_SOURCE_DIR"
-mkdir "$RPM_BUILD_DIR"
-
-cp "$archive" "$RPM_SOURCE_DIR"
-
-# rpmbuild -- as far as I can tell -- asks the OS what CPU it has.
-# This may differ from what kind of binaries gcc produces.  dpkg
-# does a better job of this, so if we can run 'dpkg --print-architecture'
-# to get the build CPU, we use that in preference of the rpmbuild
-# default.
-target=`dpkg --print-architecture 2>/dev/null || echo ""`
-if [ -n "$target" ]
-then
-   target=" --target $target"
-fi
-
-rpmbuild -bb rpm/rpm.spec $target \
-  --define "NAME $PACKAGE" \
-  --define "VERSION $VERSION" \
-  --define "_sourcedir $RPM_SOURCE_DIR" \
-  --define "_builddir $RPM_BUILD_DIR" \
-  --define "_rpmdir $RPM_SOURCE_DIR"
-
-# We put the output in a directory based on what system we've built for
-destdir=rpm-unknown
-if [ -r /etc/issue ]
-then
-   grep "Red Hat.*release 7" /etc/issue >/dev/null 2>&1 && destdir=rh7
-   grep "Red Hat.*release 8" /etc/issue >/dev/null 2>&1 && destdir=rh8
-   grep "Red Hat.*release 9" /etc/issue >/dev/null 2>&1 && destdir=rh9
-   grep "Fedora Core.*release 1" /etc/issue >/dev/null 2>&1 && destdir=fc1
-   grep "Fedora Core.*release 2" /etc/issue >/dev/null 2>&1 && destdir=fc2
-   grep "Fedora Core.*release 3" /etc/issue >/dev/null 2>&1 && destdir=fc3
-fi
-
-rm -rf "$destdir"
-mkdir -p "$destdir"
-# We want to get not only the main package but devel etc, hence the middle *
-mv "$RPM_SOURCE_DIR"/*/"${PACKAGE}"-*"${VERSION}"*.rpm "$destdir"
-
-echo
-echo "The rpm package file(s) are located in $PWD/$destdir"
diff --git a/third_party/tcmalloc/vendor/packages/rpm/rpm.spec b/third_party/tcmalloc/vendor/packages/rpm/rpm.spec
deleted file mode 100644
index 0690e4f6..0000000
--- a/third_party/tcmalloc/vendor/packages/rpm/rpm.spec
+++ /dev/null
@@ -1,77 +0,0 @@
-%define	RELEASE	1
-%define rel     %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
-%define	prefix	/usr
-
-Name: %NAME
-Summary: Performance tools for C++
-Version: %VERSION
-Release: %rel
-Group: Development/Libraries
-URL: http://code.google.com/p/gperftools/
-License: BSD
-Vendor: gperftools Contributors
-Packager: gperftools Contributors <google-perftools@googlegroups.com>
-Source: http://%{NAME}.googlecode.com/files/%{NAME}-%{VERSION}.tar.gz
-Distribution: Redhat 7 and above.
-Buildroot: %{_tmppath}/%{name}-root
-Prefix: %prefix
-
-%description
-The %name packages contains some utilities to improve and analyze the
-performance of C++ programs.  This includes an optimized thread-caching
-malloc() and cpu and heap profiling utilities.
-
-%package devel
-Summary: Performance tools for C++
-Group: Development/Libraries
-Requires: %{NAME} = %{VERSION}
-
-%description devel
-The %name-devel package contains static and debug libraries and header
-files for developing applications that use the %name package.
-
-%changelog
-	* Mon Apr 20 2009  <opensource@google.com>
-	- Change build rule to use a configure line more like '%configure'
-	- Change install to use DESTDIR instead of prefix for configure
-	- Use wildcards for doc/ and lib/ directories
-
-	* Fri Mar 11 2005  <opensource@google.com>
-	- First draft
-
-%prep
-%setup
-
-%build
-# I can't use '% configure', because it defines -m32 which breaks some
-# of the low-level atomicops files in this package.  But I do take
-# as much from % configure (in /usr/lib/rpm/macros) as I can.
-./configure --prefix=%{_prefix} --exec-prefix=%{_exec_prefix} --bindir=%{_bindir} --sbindir=%{_sbindir} --sysconfdir=%{_sysconfdir} --datadir=%{_datadir} --includedir=%{_includedir} --libdir=%{_libdir} --libexecdir=%{_libexecdir} --localstatedir=%{_localstatedir} --sharedstatedir=%{_sharedstatedir} --mandir=%{_mandir} --infodir=%{_infodir}
-make
-
-%install
-rm -rf $RPM_BUILD_ROOT
-make DESTDIR=$RPM_BUILD_ROOT install
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root)
-
-%docdir %{prefix}/share/doc/%{NAME}-%{VERSION}
-%{prefix}/share/doc/%{NAME}-%{VERSION}/*
-
-%{_libdir}/*.so.*
-%{_bindir}/pprof
-%{_mandir}/man1/pprof.1*
-
-%files devel
-%defattr(-,root,root)
-
-%{_includedir}/google
-%{_includedir}/gperftools
-%{_libdir}/*.a
-%{_libdir}/*.la
-%{_libdir}/*.so
-%{_libdir}/pkgconfig/*.pc
diff --git a/third_party/tcmalloc/vendor/src/addressmap-inl.h b/third_party/tcmalloc/vendor/src/addressmap-inl.h
deleted file mode 100644
index fd1dc5b..0000000
--- a/third_party/tcmalloc/vendor/src/addressmap-inl.h
+++ /dev/null
@@ -1,422 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// A fast map from addresses to values.  Assumes that addresses are
-// clustered.  The main use is intended to be for heap-profiling.
-// May be too memory-hungry for other uses.
-//
-// We use a user-defined allocator/de-allocator so that we can use
-// this data structure during heap-profiling.
-//
-// IMPLEMENTATION DETAIL:
-//
-// Some default definitions/parameters:
-//  * Block      -- aligned 128-byte region of the address space
-//  * Cluster    -- aligned 1-MB region of the address space
-//  * Block-ID   -- block-number within a cluster
-//  * Cluster-ID -- Starting address of cluster divided by cluster size
-//
-// We use a three-level map to represent the state:
-//  1. A hash-table maps from a cluster-ID to the data for that cluster.
-//  2. For each non-empty cluster we keep an array indexed by
-//     block-ID tht points to the first entry in the linked-list
-//     for the block.
-//  3. At the bottom, we keep a singly-linked list of all
-//     entries in a block (for non-empty blocks).
-//
-//    hash table
-//  +-------------+
-//  | id->cluster |---> ...
-//  |     ...     |
-//  | id->cluster |--->  Cluster
-//  +-------------+     +-------+    Data for one block
-//                      |  nil  |   +------------------------------------+
-//                      |   ----+---|->[addr/value]-->[addr/value]-->... |
-//                      |  nil  |   +------------------------------------+
-//                      |   ----+--> ...
-//                      |  nil  |
-//                      |  ...  |
-//                      +-------+
-//
-// Note that we require zero-bytes of overhead for completely empty
-// clusters.  The minimum space requirement for a cluster is the size
-// of the hash-table entry plus a pointer value for each block in
-// the cluster.  Empty blocks impose no extra space requirement.
-//
-// The cost of a lookup is:
-//      a. A hash-table lookup to find the cluster
-//      b. An array access in the cluster structure
-//      c. A traversal over the linked-list for a block
-
-#ifndef BASE_ADDRESSMAP_INL_H_
-#define BASE_ADDRESSMAP_INL_H_
-
-#include "config.h"
-#include <stddef.h>
-#include <string.h>
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uint16_t (ISO naming madness)
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uint16_t might be defined
-#else
-#include <sys/types.h>          // our last best hope
-#endif
-
-// This class is thread-unsafe -- that is, instances of this class can
-// not be accessed concurrently by multiple threads -- because the
-// callback function for Iterate() may mutate contained values. If the
-// callback functions you pass do not mutate their Value* argument,
-// AddressMap can be treated as thread-compatible -- that is, it's
-// safe for multiple threads to call "const" methods on this class,
-// but not safe for one thread to call const methods on this class
-// while another thread is calling non-const methods on the class.
-template <class Value>
-class AddressMap {
- public:
-  typedef void* (*Allocator)(size_t size);
-  typedef void  (*DeAllocator)(void* ptr);
-  typedef const void* Key;
-
-  // Create an AddressMap that uses the specified allocator/deallocator.
-  // The allocator/deallocator should behave like malloc/free.
-  // For instance, the allocator does not need to return initialized memory.
-  AddressMap(Allocator alloc, DeAllocator dealloc);
-  ~AddressMap();
-
-  // If the map contains an entry for "key", return it. Else return NULL.
-  inline const Value* Find(Key key) const;
-  inline Value* FindMutable(Key key);
-
-  // Insert <key,value> into the map.  Any old value associated
-  // with key is forgotten.
-  void Insert(Key key, Value value);
-
-  // Remove any entry for key in the map.  If an entry was found
-  // and removed, stores the associated value in "*removed_value"
-  // and returns true.  Else returns false.
-  bool FindAndRemove(Key key, Value* removed_value);
-
-  // Similar to Find but we assume that keys are addresses of non-overlapping
-  // memory ranges whose sizes are given by size_func.
-  // If the map contains a range into which "key" points
-  // (at its start or inside of it, but not at the end),
-  // return the address of the associated value
-  // and store its key in "*res_key".
-  // Else return NULL.
-  // max_size specifies largest range size possibly in existence now.
-  typedef size_t (*ValueSizeFunc)(const Value& v);
-  const Value* FindInside(ValueSizeFunc size_func, size_t max_size,
-                          Key key, Key* res_key);
-
-  // Iterate over the address map calling 'callback'
-  // for all stored key-value pairs and passing 'arg' to it.
-  // We don't use full Closure/Callback machinery not to add
-  // unnecessary dependencies to this class with low-level uses.
-  template<class Type>
-  inline void Iterate(void (*callback)(Key, Value*, Type), Type arg) const;
-
- private:
-  typedef uintptr_t Number;
-
-  // The implementation assumes that addresses inserted into the map
-  // will be clustered.  We take advantage of this fact by splitting
-  // up the address-space into blocks and using a linked-list entry
-  // for each block.
-
-  // Size of each block.  There is one linked-list for each block, so
-  // do not make the block-size too big.  Oterwise, a lot of time
-  // will be spent traversing linked lists.
-  static const int kBlockBits = 7;
-  static const int kBlockSize = 1 << kBlockBits;
-
-  // Entry kept in per-block linked-list
-  struct Entry {
-    Entry* next;
-    Key    key;
-    Value  value;
-  };
-
-  // We further group a sequence of consecutive blocks into a cluster.
-  // The data for a cluster is represented as a dense array of
-  // linked-lists, one list per contained block.
-  static const int kClusterBits = 13;
-  static const Number kClusterSize = 1 << (kBlockBits + kClusterBits);
-  static const int kClusterBlocks = 1 << kClusterBits;
-
-  // We use a simple chaining hash-table to represent the clusters.
-  struct Cluster {
-    Cluster* next;                      // Next cluster in hash table chain
-    Number   id;                        // Cluster ID
-    Entry*   blocks[kClusterBlocks];    // Per-block linked-lists
-  };
-
-  // Number of hash-table entries.  With the block-size/cluster-size
-  // defined above, each cluster covers 1 MB, so an 4K entry
-  // hash-table will give an average hash-chain length of 1 for 4GB of
-  // in-use memory.
-  static const int kHashBits = 12;
-  static const int kHashSize = 1 << 12;
-
-  // Number of entry objects allocated at a time
-  static const int ALLOC_COUNT = 64;
-
-  Cluster**     hashtable_;              // The hash-table
-  Entry*        free_;                   // Free list of unused Entry objects
-
-  // Multiplicative hash function:
-  // The value "kHashMultiplier" is the bottom 32 bits of
-  //    int((sqrt(5)-1)/2 * 2^32)
-  // This is a good multiplier as suggested in CLR, Knuth.  The hash
-  // value is taken to be the top "k" bits of the bottom 32 bits
-  // of the muliplied value.
-  static const uint32_t kHashMultiplier = 2654435769u;
-  static int HashInt(Number x) {
-    // Multiply by a constant and take the top bits of the result.
-    const uint32_t m = static_cast<uint32_t>(x) * kHashMultiplier;
-    return static_cast<int>(m >> (32 - kHashBits));
-  }
-
-  // Find cluster object for specified address.  If not found
-  // and "create" is true, create the object.  If not found
-  // and "create" is false, return NULL.
-  //
-  // This method is bitwise-const if create is false.
-  Cluster* FindCluster(Number address, bool create) {
-    // Look in hashtable
-    const Number cluster_id = address >> (kBlockBits + kClusterBits);
-    const int h = HashInt(cluster_id);
-    for (Cluster* c = hashtable_[h]; c != NULL; c = c->next) {
-      if (c->id == cluster_id) {
-        return c;
-      }
-    }
-
-    // Create cluster if necessary
-    if (create) {
-      Cluster* c = New<Cluster>(1);
-      c->id = cluster_id;
-      c->next = hashtable_[h];
-      hashtable_[h] = c;
-      return c;
-    }
-    return NULL;
-  }
-
-  // Return the block ID for an address within its cluster
-  static int BlockID(Number address) {
-    return (address >> kBlockBits) & (kClusterBlocks - 1);
-  }
-
-  //--------------------------------------------------------------
-  // Memory management -- we keep all objects we allocate linked
-  // together in a singly linked list so we can get rid of them
-  // when we are all done.  Furthermore, we allow the client to
-  // pass in custom memory allocator/deallocator routines.
-  //--------------------------------------------------------------
-  struct Object {
-    Object* next;
-    // The real data starts here
-  };
-
-  Allocator     alloc_;                 // The allocator
-  DeAllocator   dealloc_;               // The deallocator
-  Object*       allocated_;             // List of allocated objects
-
-  // Allocates a zeroed array of T with length "num".  Also inserts
-  // the allocated block into a linked list so it can be deallocated
-  // when we are all done.
-  template <class T> T* New(int num) {
-    void* ptr = (*alloc_)(sizeof(Object) + num*sizeof(T));
-    memset(ptr, 0, sizeof(Object) + num*sizeof(T));
-    Object* obj = reinterpret_cast<Object*>(ptr);
-    obj->next = allocated_;
-    allocated_ = obj;
-    return reinterpret_cast<T*>(reinterpret_cast<Object*>(ptr) + 1);
-  }
-};
-
-// More implementation details follow:
-
-template <class Value>
-AddressMap<Value>::AddressMap(Allocator alloc, DeAllocator dealloc)
-  : free_(NULL),
-    alloc_(alloc),
-    dealloc_(dealloc),
-    allocated_(NULL) {
-  hashtable_ = New<Cluster*>(kHashSize);
-}
-
-template <class Value>
-AddressMap<Value>::~AddressMap() {
-  // De-allocate all of the objects we allocated
-  for (Object* obj = allocated_; obj != NULL; /**/) {
-    Object* next = obj->next;
-    (*dealloc_)(obj);
-    obj = next;
-  }
-}
-
-template <class Value>
-inline const Value* AddressMap<Value>::Find(Key key) const {
-  return const_cast<AddressMap*>(this)->FindMutable(key);
-}
-
-template <class Value>
-inline Value* AddressMap<Value>::FindMutable(Key key) {
-  const Number num = reinterpret_cast<Number>(key);
-  const Cluster* const c = FindCluster(num, false/*do not create*/);
-  if (c != NULL) {
-    for (Entry* e = c->blocks[BlockID(num)]; e != NULL; e = e->next) {
-      if (e->key == key) {
-        return &e->value;
-      }
-    }
-  }
-  return NULL;
-}
-
-template <class Value>
-void AddressMap<Value>::Insert(Key key, Value value) {
-  const Number num = reinterpret_cast<Number>(key);
-  Cluster* const c = FindCluster(num, true/*create*/);
-
-  // Look in linked-list for this block
-  const int block = BlockID(num);
-  for (Entry* e = c->blocks[block]; e != NULL; e = e->next) {
-    if (e->key == key) {
-      e->value = value;
-      return;
-    }
-  }
-
-  // Create entry
-  if (free_ == NULL) {
-    // Allocate a new batch of entries and add to free-list
-    Entry* array = New<Entry>(ALLOC_COUNT);
-    for (int i = 0; i < ALLOC_COUNT-1; i++) {
-      array[i].next = &array[i+1];
-    }
-    array[ALLOC_COUNT-1].next = free_;
-    free_ = &array[0];
-  }
-  Entry* e = free_;
-  free_ = e->next;
-  e->key = key;
-  e->value = value;
-  e->next = c->blocks[block];
-  c->blocks[block] = e;
-}
-
-template <class Value>
-bool AddressMap<Value>::FindAndRemove(Key key, Value* removed_value) {
-  const Number num = reinterpret_cast<Number>(key);
-  Cluster* const c = FindCluster(num, false/*do not create*/);
-  if (c != NULL) {
-    for (Entry** p = &c->blocks[BlockID(num)]; *p != NULL; p = &(*p)->next) {
-      Entry* e = *p;
-      if (e->key == key) {
-        *removed_value = e->value;
-        *p = e->next;         // Remove e from linked-list
-        e->next = free_;      // Add e to free-list
-        free_ = e;
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-template <class Value>
-const Value* AddressMap<Value>::FindInside(ValueSizeFunc size_func,
-                                           size_t max_size,
-                                           Key key,
-                                           Key* res_key) {
-  const Number key_num = reinterpret_cast<Number>(key);
-  Number num = key_num;  // we'll move this to move back through the clusters
-  while (1) {
-    const Cluster* c = FindCluster(num, false/*do not create*/);
-    if (c != NULL) {
-      while (1) {
-        const int block = BlockID(num);
-        bool had_smaller_key = false;
-        for (const Entry* e = c->blocks[block]; e != NULL; e = e->next) {
-          const Number e_num = reinterpret_cast<Number>(e->key);
-          if (e_num <= key_num) {
-            if (e_num == key_num  ||  // to handle 0-sized ranges
-                key_num < e_num + (*size_func)(e->value)) {
-              *res_key = e->key;
-              return &e->value;
-            }
-            had_smaller_key = true;
-          }
-        }
-        if (had_smaller_key) return NULL;  // got a range before 'key'
-                                           // and it did not contain 'key'
-        if (block == 0) break;
-        // try address-wise previous block
-        num |= kBlockSize - 1;  // start at the last addr of prev block
-        num -= kBlockSize;
-        if (key_num - num > max_size) return NULL;
-      }
-    }
-    if (num < kClusterSize) return NULL;  // first cluster
-    // go to address-wise previous cluster to try
-    num |= kClusterSize - 1;  // start at the last block of previous cluster
-    num -= kClusterSize;
-    if (key_num - num > max_size) return NULL;
-      // Having max_size to limit the search is crucial: else
-      // we have to traverse a lot of empty clusters (or blocks).
-      // We can avoid needing max_size if we put clusters into
-      // a search tree, but performance suffers considerably
-      // if we use this approach by using stl::set.
-  }
-}
-
-template <class Value>
-template <class Type>
-inline void AddressMap<Value>::Iterate(void (*callback)(Key, Value*, Type),
-                                       Type arg) const {
-  // We could optimize this by traversing only non-empty clusters and/or blocks
-  // but it does not speed up heap-checker noticeably.
-  for (int h = 0; h < kHashSize; ++h) {
-    for (const Cluster* c = hashtable_[h]; c != NULL; c = c->next) {
-      for (int b = 0; b < kClusterBlocks; ++b) {
-        for (Entry* e = c->blocks[b]; e != NULL; e = e->next) {
-          callback(e->key, &e->value, arg);
-        }
-      }
-    }
-  }
-}
-
-#endif  // BASE_ADDRESSMAP_INL_H_
diff --git a/third_party/tcmalloc/vendor/src/base/arm_instruction_set_select.h b/third_party/tcmalloc/vendor/src/base/arm_instruction_set_select.h
deleted file mode 100644
index 6fde685..0000000
--- a/third_party/tcmalloc/vendor/src/base/arm_instruction_set_select.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Alexander Levitskiy
-//
-// Generalizes the plethora of ARM flavors available to an easier to manage set
-// Defs reference is at https://wiki.edubuntu.org/ARM/Thumb2PortingHowto
-
-#ifndef ARM_INSTRUCTION_SET_SELECT_H_
-#define ARM_INSTRUCTION_SET_SELECT_H_
-
-#if defined(__ARM_ARCH_8A__)
-# define ARMV8 1
-#endif
-
-#if defined(ARMV8) || \
-    defined(__ARM_ARCH_7__) || \
-    defined(__ARM_ARCH_7R__) || \
-    defined(__ARM_ARCH_7A__)
-# define ARMV7 1
-#endif
-
-#if defined(ARMV7) || \
-    defined(__ARM_ARCH_6__) || \
-    defined(__ARM_ARCH_6J__) || \
-    defined(__ARM_ARCH_6K__) || \
-    defined(__ARM_ARCH_6Z__) || \
-    defined(__ARM_ARCH_6T2__) || \
-    defined(__ARM_ARCH_6ZK__)
-# define ARMV6 1
-#endif
-
-#if defined(ARMV6) || \
-    defined(__ARM_ARCH_5T__) || \
-    defined(__ARM_ARCH_5E__) || \
-    defined(__ARM_ARCH_5TE__) || \
-    defined(__ARM_ARCH_5TEJ__)
-# define ARMV5 1
-#endif
-
-#if defined(ARMV5) || \
-    defined(__ARM_ARCH_4__) || \
-    defined(__ARM_ARCH_4T__)
-# define ARMV4 1
-#endif
-
-#if defined(ARMV4) || \
-    defined(__ARM_ARCH_3__) || \
-    defined(__ARM_ARCH_3M__)
-# define ARMV3 1
-#endif
-
-#if defined(ARMV3) || \
-    defined(__ARM_ARCH_2__)
-# define ARMV2 1
-#endif
-
-#endif  // ARM_INSTRUCTION_SET_SELECT_H_
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops-internals-arm-generic.h b/third_party/tcmalloc/vendor/src/base/atomicops-internals-arm-generic.h
deleted file mode 100644
index d0f9413..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops-internals-arm-generic.h
+++ /dev/null
@@ -1,228 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2003, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// ---
-//
-// Author: Lei Zhang, Sasha Levitskiy
-//
-// This file is an internal atomic implementation, use base/atomicops.h instead.
-//
-// LinuxKernelCmpxchg is from Google Gears.
-
-#ifndef BASE_ATOMICOPS_INTERNALS_ARM_GENERIC_H_
-#define BASE_ATOMICOPS_INTERNALS_ARM_GENERIC_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "base/basictypes.h"
-
-typedef int32_t Atomic32;
-
-namespace base {
-namespace subtle {
-
-typedef int64_t Atomic64;
-
-// 0xffff0fc0 is the hard coded address of a function provided by
-// the kernel which implements an atomic compare-exchange. On older
-// ARM architecture revisions (pre-v6) this may be implemented using
-// a syscall. This address is stable, and in active use (hard coded)
-// by at least glibc-2.7 and the Android C library.
-// pLinuxKernelCmpxchg has both acquire and release barrier sematincs.
-typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,
-                                           Atomic32 new_value,
-                                           volatile Atomic32* ptr);
-LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg ATTRIBUTE_WEAK =
-    (LinuxKernelCmpxchgFunc) 0xffff0fc0;
-
-typedef void (*LinuxKernelMemoryBarrierFunc)(void);
-LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier ATTRIBUTE_WEAK =
-    (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
-
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev_value = *ptr;
-  do {
-    if (!pLinuxKernelCmpxchg(old_value, new_value,
-                             const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (pLinuxKernelCmpxchg(old_value, new_value,
-                               const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // pLinuxKernelCmpxchg already has acquire and release barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // pLinuxKernelCmpxchg already has acquire and release barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void MemoryBarrier() {
-  pLinuxKernelMemoryBarrier();
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-
-// 64-bit versions are not implemented yet.
-
-inline void NotImplementedFatalError(const char *function_name) {
-  fprintf(stderr, "64-bit %s() not implemented on this platform\n",
-          function_name);
-  abort();
-}
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  NotImplementedFatalError("NoBarrier_CompareAndSwap");
-  return 0;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  NotImplementedFatalError("NoBarrier_AtomicExchange");
-  return 0;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // pLinuxKernelCmpxchg already has acquire and release barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // pLinuxKernelCmpxchg already has acquire and release barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NotImplementedFatalError("NoBarrier_Store");
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NotImplementedFatalError("Acquire_Store64");
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NotImplementedFatalError("Release_Store");
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  NotImplementedFatalError("NoBarrier_Load");
-  return 0;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  NotImplementedFatalError("Atomic64 Acquire_Load");
-  return 0;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
-  NotImplementedFatalError("Atomic64 Release_Load");
-  return 0;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  NotImplementedFatalError("Atomic64 Acquire_CompareAndSwap");
-  return 0;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  NotImplementedFatalError("Atomic64 Release_CompareAndSwap");
-  return 0;
-}
-
-}  // namespace base::subtle
-}  // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_ARM_GENERIC_H_
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops-internals-arm-v6plus.h b/third_party/tcmalloc/vendor/src/base/atomicops-internals-arm-v6plus.h
deleted file mode 100644
index 35f1048..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops-internals-arm-v6plus.h
+++ /dev/null
@@ -1,330 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// ---
-//
-// Author: Sasha Levitskiy
-// based on atomicops-internals by Sanjay Ghemawat
-//
-// This file is an internal atomic implementation, use base/atomicops.h instead.
-//
-// This code implements ARM atomics for architectures V6 and  newer.
-
-#ifndef BASE_ATOMICOPS_INTERNALS_ARM_V6PLUS_H_
-#define BASE_ATOMICOPS_INTERNALS_ARM_V6PLUS_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "base/basictypes.h"  // For COMPILE_ASSERT
-
-// The LDREXD and STREXD instructions in ARM all v7 variants or above.  In v6,
-// only some variants support it.  For simplicity, we only use exclusive
-// 64-bit load/store in V7 or above.
-#if defined(ARMV7)
-# define BASE_ATOMICOPS_HAS_LDREXD_AND_STREXD
-#endif
-
-typedef int32_t Atomic32;
-
-namespace base {
-namespace subtle {
-
-typedef int64_t Atomic64;
-
-// 32-bit low-level ops
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 oldval, res;
-  do {
-    __asm__ __volatile__(
-    "ldrex   %1, [%3]\n"
-    "mov     %0, #0\n"
-    "teq     %1, %4\n"
-    // The following IT (if-then) instruction is needed for the subsequent
-    // conditional instruction STREXEQ when compiling in THUMB mode.
-    // In ARM mode, the compiler/assembler will not generate any code for it.
-    "it      eq\n"
-    "strexeq %0, %5, [%3]\n"
-        : "=&r" (res), "=&r" (oldval), "+Qo" (*ptr)
-        : "r" (ptr), "Ir" (old_value), "r" (new_value)
-        : "cc");
-  } while (res);
-  return oldval;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  Atomic32 tmp, old;
-  __asm__ __volatile__(
-      "1:\n"
-      "ldrex  %1, [%2]\n"
-      "strex  %0, %3, [%2]\n"
-      "teq    %0, #0\n"
-      "bne    1b"
-      : "=&r" (tmp), "=&r" (old)
-      : "r" (ptr), "r" (new_value)
-      : "cc", "memory");
-  return old;
-}
-
-inline void MemoryBarrier() {
-#if !defined(ARMV7)
-  uint32_t dest = 0;
-  __asm__ __volatile__("mcr p15,0,%0,c7,c10,5" :"=&r"(dest) : : "memory");
-#else
-  __asm__ __volatile__("dmb" : : : "memory");
-#endif
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_value = NoBarrier_AtomicExchange(ptr, new_value);
-  MemoryBarrier();
-  return old_value;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  MemoryBarrier();
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 value = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  MemoryBarrier();
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-// 64-bit versions are only available if LDREXD and STREXD instructions
-// are available.
-#ifdef BASE_ATOMICOPS_HAS_LDREXD_AND_STREXD
-
-#define BASE_HAS_ATOMIC64 1
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 oldval, res;
-  do {
-    __asm__ __volatile__(
-    "ldrexd   %1, [%3]\n"
-    "mov      %0, #0\n"
-    "teq      %Q1, %Q4\n"
-    // The following IT (if-then) instructions are needed for the subsequent
-    // conditional instructions when compiling in THUMB mode.
-    // In ARM mode, the compiler/assembler will not generate any code for it.
-    "it       eq\n"
-    "teqeq    %R1, %R4\n"
-    "it       eq\n"
-    "strexdeq %0, %5, [%3]\n"
-        : "=&r" (res), "=&r" (oldval), "+Q" (*ptr)
-        : "r" (ptr), "Ir" (old_value), "r" (new_value)
-        : "cc");
-  } while (res);
-  return oldval;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  int store_failed;
-  Atomic64 old;
-  __asm__ __volatile__(
-      "1:\n"
-      "ldrexd  %1, [%2]\n"
-      "strexd  %0, %3, [%2]\n"
-      "teq     %0, #0\n"
-      "bne     1b"
-      : "=&r" (store_failed), "=&r" (old)
-      : "r" (ptr), "r" (new_value)
-      : "cc", "memory");
-  return old;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_value = NoBarrier_AtomicExchange(ptr, new_value);
-  MemoryBarrier();
-  return old_value;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  MemoryBarrier();
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  int store_failed;
-  Atomic64 dummy;
-  __asm__ __volatile__(
-      "1:\n"
-      // Dummy load to lock cache line.
-      "ldrexd  %1, [%3]\n"
-      "strexd  %0, %2, [%3]\n"
-      "teq     %0, #0\n"
-      "bne     1b"
-      : "=&r" (store_failed), "=&r"(dummy)
-      : "r"(value), "r" (ptr)
-      : "cc", "memory");
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  Atomic64 res;
-  __asm__ __volatile__(
-  "ldrexd   %0, [%1]\n"
-  "clrex\n"
-      : "=r" (res)
-      : "r"(ptr), "Q"(*ptr));
-  return res;
-}
-
-#else // BASE_ATOMICOPS_HAS_LDREXD_AND_STREXD
-
-inline void NotImplementedFatalError(const char *function_name) {
-  fprintf(stderr, "64-bit %s() not implemented on this platform\n",
-          function_name);
-  abort();
-}
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  NotImplementedFatalError("NoBarrier_CompareAndSwap");
-  return 0;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  NotImplementedFatalError("NoBarrier_AtomicExchange");
-  return 0;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  NotImplementedFatalError("Acquire_AtomicExchange");
-  return 0;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  NotImplementedFatalError("Release_AtomicExchange");
-  return 0;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NotImplementedFatalError("NoBarrier_Store");
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  NotImplementedFatalError("NoBarrier_Load");
-  return 0;
-}
-
-#endif // BASE_ATOMICOPS_HAS_LDREXD_AND_STREXD
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NoBarrier_Store(ptr, value);
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  MemoryBarrier();
-  NoBarrier_Store(ptr, value);
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = NoBarrier_Load(ptr);
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
-  MemoryBarrier();
-  return NoBarrier_Load(ptr);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 value = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  MemoryBarrier();
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-}  // namespace subtle ends
-}  // namespace base ends
-
-#endif  // BASE_ATOMICOPS_INTERNALS_ARM_V6PLUS_H_
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops-internals-gcc.h b/third_party/tcmalloc/vendor/src/base/atomicops-internals-gcc.h
deleted file mode 100644
index f8d27863..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops-internals-gcc.h
+++ /dev/null
@@ -1,203 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, Linaro
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// ---
-//
-// Author: Riku Voipio, riku.voipio@linaro.org
-//
-// atomic primitives implemented with gcc atomic intrinsics:
-// http://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
-//
-
-#ifndef BASE_ATOMICOPS_INTERNALS_GCC_GENERIC_H_
-#define BASE_ATOMICOPS_INTERNALS_GCC_GENERIC_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "base/basictypes.h"
-
-typedef int32_t Atomic32;
-
-namespace base {
-namespace subtle {
-
-typedef int64_t Atomic64;
-
-inline void MemoryBarrier() {
-    __sync_synchronize();
-}
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic32*>(ptr), new_value, __ATOMIC_RELAXED);
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic32*>(ptr), new_value,  __ATOMIC_ACQUIRE);
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic32*>(ptr), new_value, __ATOMIC_RELEASE);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-// 64-bit versions
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic64*>(ptr), new_value, __ATOMIC_RELAXED);
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic64*>(ptr), new_value,  __ATOMIC_ACQUIRE);
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  return __atomic_exchange_n(const_cast<Atomic64*>(ptr), new_value, __ATOMIC_RELEASE);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value = old_value;
-  __atomic_compare_exchange_n(ptr, &prev_value, new_value, 
-          0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
-  return prev_value;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-}  // namespace base::subtle
-}  // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_GCC_GENERIC_H_
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops-internals-linuxppc.h b/third_party/tcmalloc/vendor/src/base/atomicops-internals-linuxppc.h
deleted file mode 100644
index b52fdf0d..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops-internals-linuxppc.h
+++ /dev/null
@@ -1,437 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- */
-
-// Implementation of atomic operations for ppc-linux.  This file should not
-// be included directly.  Clients should instead include
-// "base/atomicops.h".
-
-#ifndef BASE_ATOMICOPS_INTERNALS_LINUXPPC_H_
-#define BASE_ATOMICOPS_INTERNALS_LINUXPPC_H_
-
-typedef int32_t Atomic32;
-
-#ifdef __PPC64__
-#define BASE_HAS_ATOMIC64 1
-#endif
-
-namespace base {
-namespace subtle {
-
-static inline void _sync(void) {
-  __asm__ __volatile__("sync": : : "memory");
-}
-
-static inline void _lwsync(void) {
-  // gcc defines __NO_LWSYNC__ when appropriate; see
-  //    http://gcc.gnu.org/ml/gcc-patches/2006-11/msg01238.html
-#ifdef __NO_LWSYNC__
-  __asm__ __volatile__("msync": : : "memory");
-#else
-  __asm__ __volatile__("lwsync": : : "memory");
-#endif
-}
-
-static inline void _isync(void) {
-  __asm__ __volatile__("isync": : : "memory");
-}
-
-static inline Atomic32 OSAtomicAdd32(Atomic32 amount, Atomic32 *value) {
-  Atomic32 t;
-  __asm__ __volatile__(
-"1:		lwarx   %0,0,%3\n\
-		add     %0,%2,%0\n\
-		stwcx.  %0,0,%3 \n\
-		bne-    1b"
-		: "=&r" (t), "+m" (*value)
-		: "r" (amount), "r" (value)
-                : "cc");
-  return t;
-}
-
-static inline Atomic32 OSAtomicAdd32Barrier(Atomic32 amount, Atomic32 *value) {
-  Atomic32 t;
-  _lwsync();
-  t = OSAtomicAdd32(amount, value);
-  // This is based on the code snippet in the architecture manual (Vol
-  // 2, Appendix B).  It's a little tricky: correctness depends on the
-  // fact that the code right before this (in OSAtomicAdd32) has a
-  // conditional branch with a data dependency on the update.
-  // Otherwise, we'd have to use sync.
-  _isync();
-  return t;
-}
-
-static inline bool OSAtomicCompareAndSwap32(Atomic32 old_value,
-                                            Atomic32 new_value,
-                                            Atomic32 *value) {
-  Atomic32 prev;
-  __asm__ __volatile__(
-"1:		lwarx   %0,0,%2\n\
-		cmpw    0,%0,%3\n\
-		bne-    2f\n\
-		stwcx.  %4,0,%2\n\
-		bne-    1b\n\
-2:"
-                : "=&r" (prev), "+m" (*value)
-                : "r" (value), "r" (old_value), "r" (new_value)
-                : "cc");
-  return prev == old_value;
-}
-
-static inline Atomic32 OSAtomicCompareAndSwap32Acquire(Atomic32 old_value,
-                                                       Atomic32 new_value,
-                                                       Atomic32 *value) {
-  Atomic32 t;
-  t = OSAtomicCompareAndSwap32(old_value, new_value, value);
-  // This is based on the code snippet in the architecture manual (Vol
-  // 2, Appendix B).  It's a little tricky: correctness depends on the
-  // fact that the code right before this (in
-  // OSAtomicCompareAndSwap32) has a conditional branch with a data
-  // dependency on the update.  Otherwise, we'd have to use sync.
-  _isync();
-  return t;
-}
-
-static inline Atomic32 OSAtomicCompareAndSwap32Release(Atomic32 old_value,
-                                                       Atomic32 new_value,
-                                                       Atomic32 *value) {
-  _lwsync();
-  return OSAtomicCompareAndSwap32(old_value, new_value, value);
-}
-
-typedef int64_t Atomic64;
-
-inline void MemoryBarrier() {
-  // This can't be _lwsync(); we need to order the immediately
-  // preceding stores against any load that may follow, but lwsync
-  // doesn't guarantee that.
-  _sync();
-}
-
-// 32-bit Versions.
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32(old_value, new_value,
-                                 const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
-                                         Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32(old_value, new_value,
-                                     const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32Acquire(old_value, new_value,
-                                            const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32Release(old_value, new_value,
-                                            const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32Acquire(old_value, new_value,
-                                        const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32Release(old_value, new_value,
-                                        const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-#ifdef __PPC64__
-
-// 64-bit Versions.
-
-static inline Atomic64 OSAtomicAdd64(Atomic64 amount, Atomic64 *value) {
-  Atomic64 t;
-  __asm__ __volatile__(
-"1:		ldarx   %0,0,%3\n\
-		add     %0,%2,%0\n\
-		stdcx.  %0,0,%3 \n\
-		bne-    1b"
-		: "=&r" (t), "+m" (*value)
-		: "r" (amount), "r" (value)
-                : "cc");
-  return t;
-}
-
-static inline Atomic64 OSAtomicAdd64Barrier(Atomic64 amount, Atomic64 *value) {
-  Atomic64 t;
-  _lwsync();
-  t = OSAtomicAdd64(amount, value);
-  // This is based on the code snippet in the architecture manual (Vol
-  // 2, Appendix B).  It's a little tricky: correctness depends on the
-  // fact that the code right before this (in OSAtomicAdd64) has a
-  // conditional branch with a data dependency on the update.
-  // Otherwise, we'd have to use sync.
-  _isync();
-  return t;
-}
-
-static inline bool OSAtomicCompareAndSwap64(Atomic64 old_value,
-                                            Atomic64 new_value,
-                                            Atomic64 *value) {
-  Atomic64 prev;
-  __asm__ __volatile__(
-"1:		ldarx   %0,0,%2\n\
-		cmpd    0,%0,%3\n\
-		bne-    2f\n\
-		stdcx.  %4,0,%2\n\
-		bne-    1b\n\
-2:"
-                : "=&r" (prev), "+m" (*value)
-                : "r" (value), "r" (old_value), "r" (new_value)
-                : "cc");
-  return prev == old_value;
-}
-
-static inline Atomic64 OSAtomicCompareAndSwap64Acquire(Atomic64 old_value,
-                                                       Atomic64 new_value,
-                                                       Atomic64 *value) {
-  Atomic64 t;
-  t = OSAtomicCompareAndSwap64(old_value, new_value, value);
-  // This is based on the code snippet in the architecture manual (Vol
-  // 2, Appendix B).  It's a little tricky: correctness depends on the
-  // fact that the code right before this (in
-  // OSAtomicCompareAndSwap64) has a conditional branch with a data
-  // dependency on the update.  Otherwise, we'd have to use sync.
-  _isync();
-  return t;
-}
-
-static inline Atomic64 OSAtomicCompareAndSwap64Release(Atomic64 old_value,
-                                                       Atomic64 new_value,
-                                                       Atomic64 *value) {
-  _lwsync();
-  return OSAtomicCompareAndSwap64(old_value, new_value, value);
-}
-
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64(old_value, new_value,
-                                 const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
-                                         Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64(old_value, new_value,
-                                     const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64Acquire(old_value, new_value,
-                                            const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64Release(old_value, new_value,
-                                            const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64Acquire(old_value, new_value,
-                                        const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64Release(old_value, new_value,
-                                        const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-#endif
-
-inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
-  *ptr = value;
-  // This can't be _lwsync(); we need to order the immediately
-  // preceding stores against any load that may follow, but lwsync
-  // doesn't guarantee that.
-  _sync();
-}
-
-inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
-  _lwsync();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
-  Atomic32 value = *ptr;
-  _lwsync();
-  return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
-  // This can't be _lwsync(); we need to order the immediately
-  // preceding stores against any load that may follow, but lwsync
-  // doesn't guarantee that.
-  _sync();
-  return *ptr;
-}
-
-#ifdef __PPC64__
-
-// 64-bit Versions.
-
-inline void NoBarrier_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  *ptr = value;
-  // This can't be _lwsync(); we need to order the immediately
-  // preceding stores against any load that may follow, but lwsync
-  // doesn't guarantee that.
-  _sync();
-}
-
-inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  _lwsync();
-  *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64 *ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
-  Atomic64 value = *ptr;
-  _lwsync();
-  return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
-  // This can't be _lwsync(); we need to order the immediately
-  // preceding stores against any load that may follow, but lwsync
-  // doesn't guarantee that.
-  _sync();
-  return *ptr;
-}
-
-#endif
-
-}   // namespace base::subtle
-}   // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_LINUXPPC_H_
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops-internals-macosx.h b/third_party/tcmalloc/vendor/src/base/atomicops-internals-macosx.h
deleted file mode 100644
index b5130d4..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops-internals-macosx.h
+++ /dev/null
@@ -1,370 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Implementation of atomic operations for Mac OS X.  This file should not
-// be included directly.  Clients should instead include
-// "base/atomicops.h".
-
-#ifndef BASE_ATOMICOPS_INTERNALS_MACOSX_H_
-#define BASE_ATOMICOPS_INTERNALS_MACOSX_H_
-
-typedef int32_t Atomic32;
-
-// MacOS uses long for intptr_t, AtomicWord and Atomic32 are always different
-// on the Mac, even when they are the same size.  Similarly, on __ppc64__,
-// AtomicWord and Atomic64 are always different.  Thus, we need explicit
-// casting.
-#ifdef __LP64__
-#define AtomicWordCastType base::subtle::Atomic64
-#else
-#define AtomicWordCastType Atomic32
-#endif
-
-#if defined(__LP64__) || defined(__i386__)
-#define BASE_HAS_ATOMIC64 1  // Use only in tests and base/atomic*
-#endif
-
-#include <libkern/OSAtomic.h>
-
-namespace base {
-namespace subtle {
-
-#if !defined(__LP64__) && defined(__ppc__)
-
-// The Mac 64-bit OSAtomic implementations are not available for 32-bit PowerPC,
-// while the underlying assembly instructions are available only some
-// implementations of PowerPC.
-
-// The following inline functions will fail with the error message at compile
-// time ONLY IF they are called.  So it is safe to use this header if user
-// code only calls AtomicWord and Atomic32 operations.
-//
-// NOTE(vchen): Implementation notes to implement the atomic ops below may
-// be found in "PowerPC Virtual Environment Architecture, Book II,
-// Version 2.02", January 28, 2005, Appendix B, page 46.  Unfortunately,
-// extra care must be taken to ensure data are properly 8-byte aligned, and
-// that data are returned correctly according to Mac OS X ABI specs.
-
-inline int64_t OSAtomicCompareAndSwap64(
-    int64_t oldValue, int64_t newValue, int64_t *theValue) {
-  __asm__ __volatile__(
-      "_OSAtomicCompareAndSwap64_not_supported_for_32_bit_ppc\n\t");
-  return 0;
-}
-
-inline int64_t OSAtomicAdd64(int64_t theAmount, int64_t *theValue) {
-  __asm__ __volatile__(
-      "_OSAtomicAdd64_not_supported_for_32_bit_ppc\n\t");
-  return 0;
-}
-
-inline int64_t OSAtomicCompareAndSwap64Barrier(
-    int64_t oldValue, int64_t newValue, int64_t *theValue) {
-  int64_t prev = OSAtomicCompareAndSwap64(oldValue, newValue, theValue);
-  OSMemoryBarrier();
-  return prev;
-}
-
-inline int64_t OSAtomicAdd64Barrier(
-    int64_t theAmount, int64_t *theValue) {
-  int64_t new_val = OSAtomicAdd64(theAmount, theValue);
-  OSMemoryBarrier();
-  return new_val;
-}
-#endif
-
-typedef int64_t Atomic64;
-
-inline void MemoryBarrier() {
-  OSMemoryBarrier();
-}
-
-// 32-bit Versions.
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32(old_value, new_value,
-                                 const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
-                                         Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32(old_value, new_value,
-                                     const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap32Barrier(old_value, new_value,
-                                            const_cast<Atomic32*>(ptr)));
-  return old_value;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr,
-                                       Atomic32 new_value) {
-  return Acquire_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
-                                        const_cast<Atomic32*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
-  *ptr = value;
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
-  Atomic32 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-// 64-bit version
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64(old_value, new_value,
-                                 const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
-                                         Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64(old_value, new_value,
-                                     const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_value;
-  do {
-    old_value = *ptr;
-  } while (!OSAtomicCompareAndSwap64Barrier(old_value, new_value,
-                                            const_cast<Atomic64*>(ptr)));
-  return old_value;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr,
-                                       Atomic64 new_value) {
-  return Acquire_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 prev_value;
-  do {
-    if (OSAtomicCompareAndSwap64Barrier(old_value, new_value,
-                                        const_cast<Atomic64*>(ptr))) {
-      return old_value;
-    }
-    prev_value = *ptr;
-  } while (prev_value == old_value);
-  return prev_value;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  // The lib kern interface does not distinguish between
-  // Acquire and Release memory barriers; they are equivalent.
-  return Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-
-#ifdef __LP64__
-
-// 64-bit implementation on 64-bit platform
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  *ptr = value;
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  MemoryBarrier();
-  *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
-  Atomic64 value = *ptr;
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-#else
-
-// 64-bit implementation on 32-bit platform
-
-#if defined(__ppc__)
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-   __asm__ __volatile__(
-       "_NoBarrier_Store_not_supported_for_32_bit_ppc\n\t");
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-   __asm__ __volatile__(
-       "_NoBarrier_Load_not_supported_for_32_bit_ppc\n\t");
-   return 0;
-}
-
-#elif defined(__i386__)
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  __asm__ __volatile__("movq %1, %%mm0\n\t"    // Use mmx reg for 64-bit atomic
-                       "movq %%mm0, %0\n\t"  // moves (ptr could be read-only)
-                       "emms\n\t"              // Reset FP registers
-                       : "=m" (*ptr)
-                       : "m" (value)
-                       : // mark the FP stack and mmx registers as clobbered
-                         "st", "st(1)", "st(2)", "st(3)", "st(4)",
-                         "st(5)", "st(6)", "st(7)", "mm0", "mm1",
-                         "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
-
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  Atomic64 value;
-  __asm__ __volatile__("movq %1, %%mm0\n\t"  // Use mmx reg for 64-bit atomic
-                       "movq %%mm0, %0\n\t"  // moves (ptr could be read-only)
-                       "emms\n\t"            // Reset FP registers
-                       : "=m" (value)
-                       : "m" (*ptr)
-                       : // mark the FP stack and mmx registers as clobbered
-                         "st", "st(1)", "st(2)", "st(3)", "st(4)",
-                         "st(5)", "st(6)", "st(7)", "mm0", "mm1",
-                         "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
-
-  return value;
-}
-#endif
-
-
-inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  NoBarrier_Store(ptr, value);
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
-  MemoryBarrier();
-  NoBarrier_Store(ptr, value);
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
-  Atomic64 value = NoBarrier_Load(ptr);
-  MemoryBarrier();
-  return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
-  MemoryBarrier();
-  return NoBarrier_Load(ptr);
-}
-#endif  // __LP64__
-
-}   // namespace base::subtle
-}   // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_MACOSX_H_
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops-internals-mips.h b/third_party/tcmalloc/vendor/src/base/atomicops-internals-mips.h
deleted file mode 100644
index 4bfd7f6..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops-internals-mips.h
+++ /dev/null
@@ -1,323 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2013, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Author: Jovan Zelincevic <jovan.zelincevic@imgtec.com>
-// based on atomicops-internals by Sanjay Ghemawat
-
-// This file is an internal atomic implementation, use base/atomicops.h instead.
-//
-// This code implements MIPS atomics.
-
-#ifndef BASE_ATOMICOPS_INTERNALS_MIPS_H_
-#define BASE_ATOMICOPS_INTERNALS_MIPS_H_
-
-#if (_MIPS_ISA == _MIPS_ISA_MIPS64)
-#define BASE_HAS_ATOMIC64 1
-#endif
-
-typedef int32_t Atomic32;
-
-namespace base {
-namespace subtle {
-
-// Atomically execute:
-// result = *ptr;
-// if (*ptr == old_value)
-// *ptr = new_value;
-// return result;
-//
-// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
-// Always return the old value of "*ptr"
-//
-// This routine implies no memory barriers.
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value)
-{
-    Atomic32 prev, tmp;
-    __asm__ volatile(
-        ".set   push                \n"
-        ".set   noreorder           \n"
-
-    "1:                             \n"
-        "ll     %0,     %5          \n" // prev = *ptr
-        "bne    %0,     %3,     2f  \n" // if (prev != old_value) goto 2
-        " move  %2,     %4          \n" // tmp = new_value
-        "sc     %2,     %1          \n" // *ptr = tmp (with atomic check)
-        "beqz   %2,     1b          \n" // start again on atomic error
-        " nop                       \n" // delay slot nop
-    "2:                             \n"
-
-        ".set   pop                 \n"
-        : "=&r" (prev), "=m" (*ptr),
-          "=&r" (tmp)
-        : "Ir" (old_value), "r" (new_value),
-          "m" (*ptr)
-        : "memory"
-    );
-    return prev;
-}
-
-// Atomically store new_value into *ptr, returning the previous value held in
-// *ptr. This routine implies no memory barriers.
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value)
-{
-    Atomic32 temp, old;
-    __asm__ volatile(
-        ".set   push                \n"
-        ".set   noreorder           \n"
-
-    "1:                             \n"
-        "ll     %1,     %2          \n" // old = *ptr
-        "move   %0,     %3          \n" // temp = new_value
-        "sc     %0,     %2          \n" // *ptr = temp (with atomic check)
-        "beqz   %0,     1b          \n" // start again on atomic error
-        " nop                       \n" // delay slot nop
-
-        ".set   pop                 \n"
-        : "=&r" (temp), "=&r" (old),
-          "=m" (*ptr)
-        : "r" (new_value), "m" (*ptr)
-        : "memory"
-    );
-    return old;
-}
-
-inline void MemoryBarrier()
-{
-    __asm__ volatile("sync" : : : "memory");
-}
-
-// "Acquire" operations
-// ensure that no later memory access can be reordered ahead of the operation.
-// "Release" operations ensure that no previous memory access can be reordered
-// after the operation. "Barrier" operations have both "Acquire" and "Release"
-// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory
-// access.
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value)
-{
-    Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-    MemoryBarrier();
-    return res;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value)
-{
-    MemoryBarrier();
-    Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-    return res;
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value)
-{
-    *ptr = value;
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value)
-{
-    Atomic32 old_value = NoBarrier_AtomicExchange(ptr, new_value);
-    MemoryBarrier();
-    return old_value;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value)
-{
-    MemoryBarrier();
-    return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value)
-{
-    *ptr = value;
-    MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value)
-{
-    MemoryBarrier();
-    *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr)
-{
-    return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr)
-{
-    Atomic32 value = *ptr;
-    MemoryBarrier();
-    return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr)
-{
-    MemoryBarrier();
-    return *ptr;
-}
-
-#if (_MIPS_ISA == _MIPS_ISA_MIPS64) || (_MIPS_SIM == _MIPS_SIM_ABI64)
-
-typedef int64_t Atomic64;
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value)
-{
-    Atomic64 prev, tmp;
-    __asm__ volatile(
-        ".set   push                \n"
-        ".set   noreorder           \n"
-
-    "1:                             \n"
-        "lld    %0,     %5          \n" // prev = *ptr
-        "bne    %0,     %3,     2f  \n" // if (prev != old_value) goto 2
-        " move  %2,     %4          \n" // tmp = new_value
-        "scd    %2,     %1          \n" // *ptr = tmp (with atomic check)
-        "beqz   %2,     1b          \n" // start again on atomic error
-        " nop                       \n" // delay slot nop
-    "2:                             \n"
-
-        ".set   pop                 \n"
-        : "=&r" (prev), "=m" (*ptr),
-          "=&r" (tmp)
-        : "Ir" (old_value), "r" (new_value),
-          "m" (*ptr)
-        : "memory"
-    );
-    return prev;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value)
-{
-    Atomic64 temp, old;
-    __asm__ volatile(
-        ".set   push                \n"
-        ".set   noreorder           \n"
-
-    "1:                             \n"
-        "lld    %1,     %2          \n" // old = *ptr
-        "move   %0,     %3          \n" // temp = new_value
-        "scd    %0,     %2          \n" // *ptr = temp (with atomic check)
-        "beqz   %0,     1b          \n" // start again on atomic error
-        " nop                       \n" // delay slot nop
-
-        ".set   pop                 \n"
-        : "=&r" (temp), "=&r" (old),
-          "=m" (*ptr)
-        : "r" (new_value), "m" (*ptr)
-        : "memory"
-    );
-    return old;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value)
-{
-    Atomic64 old_value = NoBarrier_AtomicExchange(ptr, new_value);
-    MemoryBarrier();
-    return old_value;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value)
-{
-    Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-    MemoryBarrier();
-    return res;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value)
-{
-    MemoryBarrier();
-    Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-    return res;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value)
-{
-    *ptr = value;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value)
-{
-    MemoryBarrier();
-    return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value)
-{
-    *ptr = value;
-    MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value)
-{
-    MemoryBarrier();
-    *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr)
-{
-    return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr)
-{
-    Atomic64 value = *ptr;
-    MemoryBarrier();
-    return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr)
-{
-    MemoryBarrier();
-    return *ptr;
-}
-
-#endif
-
-}   // namespace base::subtle
-}   // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_MIPS_H_
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops-internals-windows.h b/third_party/tcmalloc/vendor/src/base/atomicops-internals-windows.h
deleted file mode 100644
index 93ced87..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops-internals-windows.h
+++ /dev/null
@@ -1,457 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-// Implementation of atomic operations using Windows API
-// functions.  This file should not be included directly.  Clients
-// should instead include "base/atomicops.h".
-
-#ifndef BASE_ATOMICOPS_INTERNALS_WINDOWS_H_
-#define BASE_ATOMICOPS_INTERNALS_WINDOWS_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "base/basictypes.h"  // For COMPILE_ASSERT
-
-typedef int32 Atomic32;
-
-#if defined(_WIN64)
-#define BASE_HAS_ATOMIC64 1  // Use only in tests and base/atomic*
-#endif
-
-namespace base {
-namespace subtle {
-
-typedef int64 Atomic64;
-
-// 32-bit low-level operations on any platform
-
-extern "C" {
-// We use windows intrinsics when we can (they seem to be supported
-// well on MSVC 8.0 and above).  Unfortunately, in some
-// environments, <windows.h> and <intrin.h> have conflicting
-// declarations of some other intrinsics, breaking compilation:
-//   http://connect.microsoft.com/VisualStudio/feedback/details/262047
-// Therefore, we simply declare the relevant intrinsics ourself.
-
-// MinGW has a bug in the header files where it doesn't indicate the
-// first argument is volatile -- they're not up to date.  See
-//   http://readlist.com/lists/lists.sourceforge.net/mingw-users/0/3861.html
-// We have to const_cast away the volatile to avoid compiler warnings.
-// TODO(csilvers): remove this once MinGW has updated MinGW/include/winbase.h
-#if defined(__MINGW32__)
-inline LONG FastInterlockedCompareExchange(volatile LONG* ptr,
-                                           LONG newval, LONG oldval) {
-  return ::InterlockedCompareExchange(const_cast<LONG*>(ptr), newval, oldval);
-}
-inline LONG FastInterlockedExchange(volatile LONG* ptr, LONG newval) {
-  return ::InterlockedExchange(const_cast<LONG*>(ptr), newval);
-}
-inline LONG FastInterlockedExchangeAdd(volatile LONG* ptr, LONG increment) {
-  return ::InterlockedExchangeAdd(const_cast<LONG*>(ptr), increment);
-}
-
-#elif _MSC_VER >= 1400   // intrinsics didn't work so well before MSVC 8.0
-// Unfortunately, in some environments, <windows.h> and <intrin.h>
-// have conflicting declarations of some intrinsics, breaking
-// compilation.  So we declare the intrinsics we need ourselves.  See
-//   http://connect.microsoft.com/VisualStudio/feedback/details/262047
-LONG _InterlockedCompareExchange(volatile LONG* ptr, LONG newval, LONG oldval);
-#pragma intrinsic(_InterlockedCompareExchange)
-inline LONG FastInterlockedCompareExchange(volatile LONG* ptr,
-                                           LONG newval, LONG oldval) {
-  return _InterlockedCompareExchange(ptr, newval, oldval);
-}
-
-LONG _InterlockedExchange(volatile LONG* ptr, LONG newval);
-#pragma intrinsic(_InterlockedExchange)
-inline LONG FastInterlockedExchange(volatile LONG* ptr, LONG newval) {
-  return _InterlockedExchange(ptr, newval);
-}
-
-LONG _InterlockedExchangeAdd(volatile LONG* ptr, LONG increment);
-#pragma intrinsic(_InterlockedExchangeAdd)
-inline LONG FastInterlockedExchangeAdd(volatile LONG* ptr, LONG increment) {
-  return _InterlockedExchangeAdd(ptr, increment);
-}
-
-#else
-inline LONG FastInterlockedCompareExchange(volatile LONG* ptr,
-                                           LONG newval, LONG oldval) {
-  return ::InterlockedCompareExchange(ptr, newval, oldval);
-}
-inline LONG FastInterlockedExchange(volatile LONG* ptr, LONG newval) {
-  return ::InterlockedExchange(ptr, newval);
-}
-inline LONG FastInterlockedExchangeAdd(volatile LONG* ptr, LONG increment) {
-  return ::InterlockedExchangeAdd(ptr, increment);
-}
-
-#endif  // ifdef __MINGW32__
-}  // extern "C"
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  LONG result = FastInterlockedCompareExchange(
-      reinterpret_cast<volatile LONG*>(ptr),
-      static_cast<LONG>(new_value),
-      static_cast<LONG>(old_value));
-  return static_cast<Atomic32>(result);
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  LONG result = FastInterlockedExchange(
-      reinterpret_cast<volatile LONG*>(ptr),
-      static_cast<LONG>(new_value));
-  return static_cast<Atomic32>(result);
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // FastInterlockedExchange has both acquire and release memory barriers.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // FastInterlockedExchange has both acquire and release memory barriers.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-}  // namespace base::subtle
-}  // namespace base
-
-
-// In msvc8/vs2005, winnt.h already contains a definition for
-// MemoryBarrier in the global namespace.  Add it there for earlier
-// versions and forward to it from within the namespace.
-#if !(defined(_MSC_VER) && _MSC_VER >= 1400)
-inline void MemoryBarrier() {
-  Atomic32 value = 0;
-  base::subtle::NoBarrier_AtomicExchange(&value, 0);
-                        // actually acts as a barrier in thisd implementation
-}
-#endif
-
-namespace base {
-namespace subtle {
-
-inline void MemoryBarrier() {
-  ::MemoryBarrier();
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
-  Acquire_AtomicExchange(ptr, value);
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value; // works w/o barrier for current Intel chips as of June 2005
-  // See comments in Atomic64 version of Release_Store() below.
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr;
-  return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-// 64-bit operations
-
-#if defined(_WIN64) || defined(__MINGW64__)
-
-// 64-bit low-level operations on 64-bit platform.
-
-COMPILE_ASSERT(sizeof(Atomic64) == sizeof(PVOID), atomic_word_is_atomic);
-
-// These are the intrinsics needed for 64-bit operations.  Similar to the
-// 32-bit case above.
-
-extern "C" {
-#if defined(__MINGW64__)
-inline PVOID FastInterlockedCompareExchangePointer(volatile PVOID* ptr,
-                                                   PVOID newval, PVOID oldval) {
-  return ::InterlockedCompareExchangePointer(const_cast<PVOID*>(ptr),
-                                             newval, oldval);
-}
-inline PVOID FastInterlockedExchangePointer(volatile PVOID* ptr, PVOID newval) {
-  return ::InterlockedExchangePointer(const_cast<PVOID*>(ptr), newval);
-}
-inline LONGLONG FastInterlockedExchangeAdd64(volatile LONGLONG* ptr,
-                                             LONGLONG increment) {
-  return ::InterlockedExchangeAdd64(const_cast<LONGLONG*>(ptr), increment);
-}
-
-#elif _MSC_VER >= 1400   // intrinsics didn't work so well before MSVC 8.0
-// Like above, we need to declare the intrinsics ourselves.
-PVOID _InterlockedCompareExchangePointer(volatile PVOID* ptr,
-                                         PVOID newval, PVOID oldval);
-#pragma intrinsic(_InterlockedCompareExchangePointer)
-inline PVOID FastInterlockedCompareExchangePointer(volatile PVOID* ptr,
-                                                   PVOID newval, PVOID oldval) {
-  return _InterlockedCompareExchangePointer(const_cast<PVOID*>(ptr),
-                                            newval, oldval);
-}
-
-PVOID _InterlockedExchangePointer(volatile PVOID* ptr, PVOID newval);
-#pragma intrinsic(_InterlockedExchangePointer)
-inline PVOID FastInterlockedExchangePointer(volatile PVOID* ptr, PVOID newval) {
-  return _InterlockedExchangePointer(const_cast<PVOID*>(ptr), newval);
-}
-
-LONGLONG _InterlockedExchangeAdd64(volatile LONGLONG* ptr, LONGLONG increment);
-#pragma intrinsic(_InterlockedExchangeAdd64)
-inline LONGLONG FastInterlockedExchangeAdd64(volatile LONGLONG* ptr,
-                                             LONGLONG increment) {
-  return _InterlockedExchangeAdd64(const_cast<LONGLONG*>(ptr), increment);
-}
-
-#else
-inline PVOID FastInterlockedCompareExchangePointer(volatile PVOID* ptr,
-                                                   PVOID newval, PVOID oldval) {
-  return ::InterlockedCompareExchangePointer(ptr, newval, oldval);
-}
-inline PVOID FastInterlockedExchangePointer(volatile PVOID* ptr, PVOID newval) {
-  return ::InterlockedExchangePointer(ptr, newval);
-}
-inline LONGLONG FastInterlockedExchangeAdd64(volatile LONGLONG* ptr,
-                                         LONGLONG increment) {
-  return ::InterlockedExchangeAdd64(ptr, increment);
-}
-
-#endif  // ifdef __MINGW64__
-}  // extern "C"
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  PVOID result = FastInterlockedCompareExchangePointer(
-    reinterpret_cast<volatile PVOID*>(ptr),
-    reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
-  return reinterpret_cast<Atomic64>(result);
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  PVOID result = FastInterlockedExchangePointer(
-    reinterpret_cast<volatile PVOID*>(ptr),
-    reinterpret_cast<PVOID>(new_value));
-  return reinterpret_cast<Atomic64>(result);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NoBarrier_AtomicExchange(ptr, value);
-              // acts as a barrier in this implementation
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value; // works w/o barrier for current Intel chips as of June 2005
-
-  // When new chips come out, check:
-  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:
-  //  System Programming Guide, Chatper 7: Multiple-processor management,
-  //  Section 7.2, Memory Ordering.
-  // Last seen at:
-  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = *ptr;
-  return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-#else  // defined(_WIN64) || defined(__MINGW64__)
-
-// 64-bit low-level operations on 32-bit platform
-
-// TODO(vchen): The GNU assembly below must be converted to MSVC inline
-// assembly.  Then the file should be renamed to ...-x86-msvc.h, probably.
-
-inline void NotImplementedFatalError(const char *function_name) {
-  fprintf(stderr, "64-bit %s() not implemented on this platform\n",
-          function_name);
-  abort();
-}
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-#if 0 // Not implemented
-  Atomic64 prev;
-  __asm__ __volatile__("movl (%3), %%ebx\n\t"    // Move 64-bit new_value into
-                       "movl 4(%3), %%ecx\n\t"   // ecx:ebx
-                       "lock; cmpxchg8b %1\n\t"  // If edx:eax (old_value) same
-                       : "=A" (prev)             // as contents of ptr:
-                       : "m" (*ptr),             //   ecx:ebx => ptr
-                         "0" (old_value),        // else:
-                         "r" (&new_value)        //   old *ptr => edx:eax
-                       : "memory", "%ebx", "%ecx");
-  return prev;
-#else
-  NotImplementedFatalError("NoBarrier_CompareAndSwap");
-  return 0;
-#endif
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-#if 0 // Not implemented
-  __asm__ __volatile__(
-                       "movl (%2), %%ebx\n\t"    // Move 64-bit new_value into
-                       "movl 4(%2), %%ecx\n\t"   // ecx:ebx
-                       "0:\n\t"
-                       "movl %1, %%eax\n\t"      // Read contents of ptr into
-                       "movl 4%1, %%edx\n\t"     // edx:eax
-                       "lock; cmpxchg8b %1\n\t"  // Attempt cmpxchg; if *ptr
-                       "jnz 0b\n\t"              // is no longer edx:eax, loop
-                       : "=A" (new_value)
-                       : "m" (*ptr),
-                         "r" (&new_value)
-                       : "memory", "%ebx", "%ecx");
-  return new_value;  // Now it's the previous value.
-#else
-  NotImplementedFatalError("NoBarrier_AtomicExchange");
-  return 0;
-#endif
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptrValue, Atomic64 value)
-{
- 	__asm {
-    	movq mm0, value;  // Use mmx reg for 64-bit atomic moves
-    	mov eax, ptrValue;
-    	movq [eax], mm0;
-    	emms;            // Empty mmx state to enable FP registers
-  	}
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NoBarrier_AtomicExchange(ptr, value);
-              // acts as a barrier in this implementation
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NoBarrier_Store(ptr, value);
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptrValue)
-{
-  	Atomic64 value;
-  	__asm {
-    	mov eax, ptrValue;
-    	movq mm0, [eax]; // Use mmx reg for 64-bit atomic moves
-    	movq value, mm0;
-    	emms; // Empty mmx state to enable FP registers
-  }
-  return value;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = NoBarrier_Load(ptr);
-  return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
-  MemoryBarrier();
-  return NoBarrier_Load(ptr);
-}
-
-#endif  // defined(_WIN64) || defined(__MINGW64__)
-
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // FastInterlockedExchange has both acquire and release memory barriers.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // FastInterlockedExchange has both acquire and release memory barriers.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-}  // namespace base::subtle
-}  // namespace base
-
-#endif  // BASE_ATOMICOPS_INTERNALS_WINDOWS_H_
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops-internals-x86.cc b/third_party/tcmalloc/vendor/src/base/atomicops-internals-x86.cc
deleted file mode 100644
index c3391e7..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops-internals-x86.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This module gets enough CPU information to optimize the
- * atomicops module on x86.
- */
-
-#include "base/atomicops.h"
-#include "base/basictypes.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include <string.h>
-
-// This file only makes sense with atomicops-internals-x86.h -- it
-// depends on structs that are defined in that file.  If atomicops.h
-// doesn't sub-include that file, then we aren't needed, and shouldn't
-// try to do anything.
-#ifdef BASE_ATOMICOPS_INTERNALS_X86_H_
-
-// Inline cpuid instruction.  In PIC compilations, %ebx contains the address
-// of the global offset table.  To avoid breaking such executables, this code
-// must preserve that register's value across cpuid instructions.
-#if defined(__i386__)
-#define cpuid(a, b, c, d, inp) \
-  asm ("mov %%ebx, %%edi\n"    \
-       "cpuid\n"               \
-       "xchg %%edi, %%ebx\n"   \
-       : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
-#elif defined (__x86_64__)
-#define cpuid(a, b, c, d, inp) \
-  asm ("mov %%rbx, %%rdi\n"    \
-       "cpuid\n"               \
-       "xchg %%rdi, %%rbx\n"   \
-       : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
-#endif
-
-#if defined(cpuid)        // initialize the struct only on x86
-
-// Set the flags so that code will run correctly and conservatively
-// until InitGoogle() is called.
-struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
-  false,          // no SSE2
-  false           // no cmpxchg16b
-};
-
-// Initialize the AtomicOps_Internalx86CPUFeatures struct.
-static void AtomicOps_Internalx86CPUFeaturesInit() {
-  uint32 eax;
-  uint32 ebx;
-  uint32 ecx;
-  uint32 edx;
-
-  // Get vendor string (issue CPUID with eax = 0)
-  cpuid(eax, ebx, ecx, edx, 0);
-  char vendor[13];
-  memcpy(vendor, &ebx, 4);
-  memcpy(vendor + 4, &edx, 4);
-  memcpy(vendor + 8, &ecx, 4);
-  vendor[12] = 0;
-
-  // get feature flags in ecx/edx, and family/model in eax
-  cpuid(eax, ebx, ecx, edx, 1);
-
-  int family = (eax >> 8) & 0xf;        // family and model fields
-  int model = (eax >> 4) & 0xf;
-  if (family == 0xf) {                  // use extended family and model fields
-    family += (eax >> 20) & 0xff;
-    model += ((eax >> 16) & 0xf) << 4;
-  }
-
-  // edx bit 26 is SSE2 which we use to tell use whether we can use mfence
-  AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);
-
-  // ecx bit 13 indicates whether the cmpxchg16b instruction is supported
-  AtomicOps_Internalx86CPUFeatures.has_cmpxchg16b = ((ecx >> 13) & 1);
-}
-
-REGISTER_MODULE_INITIALIZER(atomicops_x86, {
-  AtomicOps_Internalx86CPUFeaturesInit();
-});
-
-#endif
-
-#endif  /* ifdef BASE_ATOMICOPS_INTERNALS_X86_H_ */
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops-internals-x86.h b/third_party/tcmalloc/vendor/src/base/atomicops-internals-x86.h
deleted file mode 100644
index e441ac7..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops-internals-x86.h
+++ /dev/null
@@ -1,391 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-// Implementation of atomic operations for x86.  This file should not
-// be included directly.  Clients should instead include
-// "base/atomicops.h".
-
-#ifndef BASE_ATOMICOPS_INTERNALS_X86_H_
-#define BASE_ATOMICOPS_INTERNALS_X86_H_
-#include "base/basictypes.h"
-
-typedef int32_t Atomic32;
-#define BASE_HAS_ATOMIC64 1  // Use only in tests and base/atomic*
-
-
-// NOTE(vchen): x86 does not need to define AtomicWordCastType, because it
-// already matches Atomic32 or Atomic64, depending on the platform.
-
-
-// This struct is not part of the public API of this module; clients may not
-// use it.
-// Features of this x86.  Values may not be correct before main() is run,
-// but are set conservatively.
-struct AtomicOps_x86CPUFeatureStruct {
-  bool has_sse2;            // Processor has SSE2.
-  bool has_cmpxchg16b;      // Processor supports cmpxchg16b instruction.
-};
-
-ATTRIBUTE_VISIBILITY_HIDDEN
-extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;
-
-
-#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
-
-
-namespace base {
-namespace subtle {
-
-typedef int64_t Atomic64;
-
-// 32-bit low-level operations on any platform.
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                         Atomic32 old_value,
-                                         Atomic32 new_value) {
-  Atomic32 prev;
-  __asm__ __volatile__("lock; cmpxchgl %1,%2"
-                       : "=a" (prev)
-                       : "q" (new_value), "m" (*ptr), "0" (old_value)
-                       : "memory");
-  return prev;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
-                                         Atomic32 new_value) {
-  __asm__ __volatile__("xchgl %1,%0"  // The lock prefix is implicit for xchg.
-                       : "=r" (new_value)
-                       : "m" (*ptr), "0" (new_value)
-                       : "memory");
-  return new_value;  // Now it's the previous value.
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  Atomic32 old_val = NoBarrier_AtomicExchange(ptr, new_value);
-  return old_val;
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
-                                       Atomic32 new_value) {
-  // xchgl already has release memory barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-  return x;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-}
-
-#if defined(__x86_64__)
-
-// 64-bit implementations of memory barrier can be simpler, because it
-// "mfence" is guaranteed to exist.
-inline void MemoryBarrier() {
-  __asm__ __volatile__("mfence" : : : "memory");
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
-  *ptr = value;
-  MemoryBarrier();
-}
-
-#else
-
-inline void MemoryBarrier() {
-  if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
-    __asm__ __volatile__("mfence" : : : "memory");
-  } else { // mfence is faster but not present on PIII
-    Atomic32 x = 0;
-    Acquire_AtomicExchange(&x, 0);
-  }
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
-  if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
-    *ptr = value;
-    __asm__ __volatile__("mfence" : : : "memory");
-  } else {
-    Acquire_AtomicExchange(ptr, value);
-  }
-}
-#endif
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  ATOMICOPS_COMPILER_BARRIER();
-  *ptr = value; // An x86 store acts as a release barrier.
-  // See comments in Atomic64 version of Release_Store(), below.
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
-  return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr; // An x86 load acts as a acquire barrier.
-  // See comments in Atomic64 version of Release_Store(), below.
-  ATOMICOPS_COMPILER_BARRIER();
-  return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-#if defined(__x86_64__)
-
-// 64-bit low-level operations on 64-bit platform.
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_value,
-                                         Atomic64 new_value) {
-  Atomic64 prev;
-  __asm__ __volatile__("lock; cmpxchgq %1,%2"
-                       : "=a" (prev)
-                       : "q" (new_value), "m" (*ptr), "0" (old_value)
-                       : "memory");
-  return prev;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_value) {
-  __asm__ __volatile__("xchgq %1,%0"  // The lock prefix is implicit for xchg.
-                       : "=r" (new_value)
-                       : "m" (*ptr), "0" (new_value)
-                       : "memory");
-  return new_value;  // Now it's the previous value.
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  Atomic64 old_val = NoBarrier_AtomicExchange(ptr, new_value);
-  return old_val;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_value) {
-  // xchgq already has release memory barrier semantics.
-  return NoBarrier_AtomicExchange(ptr, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
-  *ptr = value;
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  ATOMICOPS_COMPILER_BARRIER();
-
-  *ptr = value; // An x86 store acts as a release barrier
-                // for current AMD/Intel chips as of Jan 2008.
-                // See also Acquire_Load(), below.
-
-  // When new chips come out, check:
-  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:
-  //  System Programming Guide, Chatper 7: Multiple-processor management,
-  //  Section 7.2, Memory Ordering.
-  // Last seen at:
-  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm
-  //
-  // x86 stores/loads fail to act as barriers for a few instructions (clflush
-  // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
-  // not generated by the compiler, and are rare.  Users of these instructions
-  // need to know about cache behaviour in any case since all of these involve
-  // either flushing cache lines or non-temporal cache hints.
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = *ptr; // An x86 load acts as a acquire barrier,
-                         // for current AMD/Intel chips as of Jan 2008.
-                         // See also Release_Store(), above.
-  ATOMICOPS_COMPILER_BARRIER();
-  return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
-  MemoryBarrier();
-  return *ptr;
-}
-
-#else // defined(__x86_64__)
-
-// 64-bit low-level operations on 32-bit platform.
-
-#if !((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
-// For compilers older than gcc 4.1, we use inline asm.
-//
-// Potential pitfalls:
-//
-// 1. %ebx points to Global offset table (GOT) with -fPIC.
-//    We need to preserve this register.
-// 2. When explicit registers are used in inline asm, the
-//    compiler may not be aware of it and might try to reuse
-//    the same register for another argument which has constraints
-//    that allow it ("r" for example).
-
-inline Atomic64 __sync_val_compare_and_swap(volatile Atomic64* ptr,
-                                            Atomic64 old_value,
-                                            Atomic64 new_value) {
-  Atomic64 prev;
-  __asm__ __volatile__("push %%ebx\n\t"
-                       "movl (%3), %%ebx\n\t"    // Move 64-bit new_value into
-                       "movl 4(%3), %%ecx\n\t"   // ecx:ebx
-                       "lock; cmpxchg8b (%1)\n\t"// If edx:eax (old_value) same
-                       "pop %%ebx\n\t"
-                       : "=A" (prev)             // as contents of ptr:
-                       : "D" (ptr),              //   ecx:ebx => ptr
-                         "0" (old_value),        // else:
-                         "S" (&new_value)        //   old *ptr => edx:eax
-                       : "memory", "%ecx");
-  return prev;
-}
-#endif  // Compiler < gcc-4.1
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                         Atomic64 old_val,
-                                         Atomic64 new_val) {
-  return __sync_val_compare_and_swap(ptr, old_val, new_val);
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
-                                         Atomic64 new_val) {
-  Atomic64 old_val;
-
-  do {
-    old_val = *ptr;
-  } while (__sync_val_compare_and_swap(ptr, old_val, new_val) != old_val);
-
-  return old_val;
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_val) {
-  Atomic64 old_val = NoBarrier_AtomicExchange(ptr, new_val);
-  return old_val;
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
-                                       Atomic64 new_val) {
- return NoBarrier_AtomicExchange(ptr, new_val);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
-  __asm__ __volatile__("movq %1, %%mm0\n\t"  // Use mmx reg for 64-bit atomic
-                       "movq %%mm0, %0\n\t"  // moves (ptr could be read-only)
-                       "emms\n\t"            // Empty mmx state/Reset FP regs
-                       : "=m" (*ptr)
-                       : "m" (value)
-                       : // mark the FP stack and mmx registers as clobbered
-			 "st", "st(1)", "st(2)", "st(3)", "st(4)",
-                         "st(5)", "st(6)", "st(7)", "mm0", "mm1",
-                         "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
-  NoBarrier_Store(ptr, value);
-  MemoryBarrier();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  ATOMICOPS_COMPILER_BARRIER();
-  NoBarrier_Store(ptr, value);
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
-  Atomic64 value;
-  __asm__ __volatile__("movq %1, %%mm0\n\t"  // Use mmx reg for 64-bit atomic
-                       "movq %%mm0, %0\n\t"  // moves (ptr could be read-only)
-                       "emms\n\t"            // Empty mmx state/Reset FP regs
-                       : "=m" (value)
-                       : "m" (*ptr)
-                       : // mark the FP stack and mmx registers as clobbered
-                         "st", "st(1)", "st(2)", "st(3)", "st(4)",
-                         "st(5)", "st(6)", "st(7)", "mm0", "mm1",
-                         "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
-  return value;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = NoBarrier_Load(ptr);
-  ATOMICOPS_COMPILER_BARRIER();
-  return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
-  MemoryBarrier();
-  return NoBarrier_Load(ptr);
-}
-
-#endif // defined(__x86_64__)
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-  return x;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                       Atomic64 old_value,
-                                       Atomic64 new_value) {
-  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-} // namespace base::subtle
-} // namespace base
-
-#undef ATOMICOPS_COMPILER_BARRIER
-
-#endif  // BASE_ATOMICOPS_INTERNALS_X86_H_
diff --git a/third_party/tcmalloc/vendor/src/base/atomicops.h b/third_party/tcmalloc/vendor/src/base/atomicops.h
deleted file mode 100644
index dac95be8..0000000
--- a/third_party/tcmalloc/vendor/src/base/atomicops.h
+++ /dev/null
@@ -1,399 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-// For atomic operations on statistics counters, see atomic_stats_counter.h.
-// For atomic operations on sequence numbers, see atomic_sequence_num.h.
-// For atomic operations on reference counts, see atomic_refcount.h.
-
-// Some fast atomic operations -- typically with machine-dependent
-// implementations.  This file may need editing as Google code is
-// ported to different architectures.
-
-// The routines exported by this module are subtle.  If you use them, even if
-// you get the code right, it will depend on careful reasoning about atomicity
-// and memory ordering; it will be less readable, and harder to maintain.  If
-// you plan to use these routines, you should have a good reason, such as solid
-// evidence that performance would otherwise suffer, or there being no
-// alternative.  You should assume only properties explicitly guaranteed by the
-// specifications in this file.  You are almost certainly _not_ writing code
-// just for the x86; if you assume x86 semantics, x86 hardware bugs and
-// implementations on other archtectures will cause your code to break.  If you
-// do not know what you are doing, avoid these routines, and use a Mutex.
-//
-// These following lower-level operations are typically useful only to people
-// implementing higher-level synchronization operations like spinlocks,
-// mutexes, and condition-variables.  They combine CompareAndSwap(), a load, or
-// a store with appropriate memory-ordering instructions.  "Acquire" operations
-// ensure that no later memory access can be reordered ahead of the operation.
-// "Release" operations ensure that no previous memory access can be reordered
-// after the operation.  "Barrier" operations have both "Acquire" and "Release"
-// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
-// access.
-//
-// It is incorrect to make direct assignments to/from an atomic variable.
-// You should use one of the Load or Store routines.  The NoBarrier
-// versions are provided when no barriers are needed:
-//   NoBarrier_Store()
-//   NoBarrier_Load()
-// Although there are currently no compiler enforcement, you are encouraged
-// to use these.  Moreover, if you choose to use base::subtle::Atomic64 type,
-// you MUST use one of the Load or Store routines to get correct behavior
-// on 32-bit platforms.
-//
-// The intent is eventually to put all of these routines in namespace
-// base::subtle
-
-#ifndef THREAD_ATOMICOPS_H_
-#define THREAD_ATOMICOPS_H_
-
-#include <config.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-// ------------------------------------------------------------------------
-// Include the platform specific implementations of the types
-// and operations listed below.  Implementations are to provide Atomic32
-// and Atomic64 operations. If there is a mismatch between intptr_t and
-// the Atomic32 or Atomic64 types for a platform, the platform-specific header
-// should define the macro, AtomicWordCastType in a clause similar to the
-// following:
-// #if ...pointers are 64 bits...
-// # define AtomicWordCastType base::subtle::Atomic64
-// #else
-// # define AtomicWordCastType Atomic32
-// #endif
-// TODO(csilvers): figure out ARCH_PIII/ARCH_K8 (perhaps via ./configure?)
-// ------------------------------------------------------------------------
-
-#include "base/arm_instruction_set_select.h"
-#define GCC_VERSION (__GNUC__ * 10000                 \
-                     + __GNUC_MINOR__ * 100           \
-                     + __GNUC_PATCHLEVEL__)
-
-#define CLANG_VERSION (__clang_major__ * 10000         \
-                       + __clang_minor__ * 100         \
-                       + __clang_patchlevel__)
-
-#if defined(TCMALLOC_PREFER_GCC_ATOMICS) && defined(__GNUC__) && GCC_VERSION >= 40700
-#include "base/atomicops-internals-gcc.h"
-#elif defined(TCMALLOC_PREFER_GCC_ATOMICS) && defined(__clang__) && CLANG_VERSION >= 30400
-#include "base/atomicops-internals-gcc.h"
-#elif defined(__MACH__) && defined(__APPLE__)
-#include "base/atomicops-internals-macosx.h"
-#elif defined(__GNUC__) && defined(ARMV6)
-#include "base/atomicops-internals-arm-v6plus.h"
-#elif defined(ARMV3)
-#include "base/atomicops-internals-arm-generic.h"
-#elif defined(__GNUC__) && (defined(__i386) || defined(__x86_64__))
-#include "base/atomicops-internals-x86.h"
-#elif defined(_WIN32)
-#include "base/atomicops-internals-windows.h"
-#elif defined(__linux__) && defined(__PPC__)
-#include "base/atomicops-internals-linuxppc.h"
-#elif defined(__GNUC__) && defined(__mips__)
-#include "base/atomicops-internals-mips.h"
-#elif defined(__GNUC__) && GCC_VERSION >= 40700
-#include "base/atomicops-internals-gcc.h"
-#elif defined(__clang__) && CLANG_VERSION >= 30400
-#include "base/atomicops-internals-gcc.h"
-#else
-#error You need to implement atomic operations for this architecture
-#endif
-
-// Signed type that can hold a pointer and supports the atomic ops below, as
-// well as atomic loads and stores.  Instances must be naturally-aligned.
-typedef intptr_t AtomicWord;
-
-#ifdef AtomicWordCastType
-// ------------------------------------------------------------------------
-// This section is needed only when explicit type casting is required to
-// cast AtomicWord to one of the basic atomic types (Atomic64 or Atomic32).
-// It also serves to document the AtomicWord interface.
-// ------------------------------------------------------------------------
-
-namespace base {
-namespace subtle {
-
-// Atomically execute:
-//      result = *ptr;
-//      if (*ptr == old_value)
-//        *ptr = new_value;
-//      return result;
-//
-// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
-// Always return the old value of "*ptr"
-//
-// This routine implies no memory barriers.
-inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
-                                           AtomicWord old_value,
-                                           AtomicWord new_value) {
-  return NoBarrier_CompareAndSwap(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr),
-      old_value, new_value);
-}
-
-// Atomically store new_value into *ptr, returning the previous value held in
-// *ptr.  This routine implies no memory barriers.
-inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
-                                           AtomicWord new_value) {
-  return NoBarrier_AtomicExchange(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), new_value);
-}
-
-inline AtomicWord Acquire_AtomicExchange(volatile AtomicWord* ptr,
-                                         AtomicWord new_value) {
-  return Acquire_AtomicExchange(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), new_value);
-}
-
-inline AtomicWord Release_AtomicExchange(volatile AtomicWord* ptr,
-                                         AtomicWord new_value) {
-  return Release_AtomicExchange(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), new_value);
-}
-
-inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
-                                         AtomicWord old_value,
-                                         AtomicWord new_value) {
-  return base::subtle::Acquire_CompareAndSwap(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr),
-      old_value, new_value);
-}
-
-inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
-                                         AtomicWord old_value,
-                                         AtomicWord new_value) {
-  return base::subtle::Release_CompareAndSwap(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr),
-      old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
-  NoBarrier_Store(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
-}
-
-inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
-  return base::subtle::Acquire_Store(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
-}
-
-inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
-  return base::subtle::Release_Store(
-      reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
-}
-
-inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
-  return NoBarrier_Load(
-      reinterpret_cast<volatile const AtomicWordCastType*>(ptr));
-}
-
-inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
-  return base::subtle::Acquire_Load(
-      reinterpret_cast<volatile const AtomicWordCastType*>(ptr));
-}
-
-inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
-  return base::subtle::Release_Load(
-      reinterpret_cast<volatile const AtomicWordCastType*>(ptr));
-}
-
-}  // namespace base::subtle
-}  // namespace base
-#endif  // AtomicWordCastType
-
-// ------------------------------------------------------------------------
-// Commented out type definitions and method declarations for documentation
-// of the interface provided by this module.
-// ------------------------------------------------------------------------
-
-#if 0
-
-// Signed 32-bit type that supports the atomic ops below, as well as atomic
-// loads and stores.  Instances must be naturally aligned.  This type differs
-// from AtomicWord in 64-bit binaries where AtomicWord is 64-bits.
-typedef int32_t Atomic32;
-
-// Corresponding operations on Atomic32
-namespace base {
-namespace subtle {
-
-// Signed 64-bit type that supports the atomic ops below, as well as atomic
-// loads and stores.  Instances must be naturally aligned.  This type differs
-// from AtomicWord in 32-bit binaries where AtomicWord is 32-bits.
-typedef int64_t Atomic64;
-
-Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
-                                  Atomic32 old_value,
-                                  Atomic32 new_value);
-Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
-Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
-Atomic32 Release_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
-Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                Atomic32 old_value,
-                                Atomic32 new_value);
-Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                Atomic32 old_value,
-                                Atomic32 new_value);
-void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
-void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
-void Release_Store(volatile Atomic32* ptr, Atomic32 value);
-Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
-Atomic32 Acquire_Load(volatile const Atomic32* ptr);
-Atomic32 Release_Load(volatile const Atomic32* ptr);
-
-// Corresponding operations on Atomic64
-Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
-                                  Atomic64 old_value,
-                                  Atomic64 new_value);
-Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
-Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
-Atomic64 Release_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
-
-Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
-                                Atomic64 old_value,
-                                Atomic64 new_value);
-Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
-                                Atomic64 old_value,
-                                Atomic64 new_value);
-void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);
-void Acquire_Store(volatile Atomic64* ptr, Atomic64 value);
-void Release_Store(volatile Atomic64* ptr, Atomic64 value);
-Atomic64 NoBarrier_Load(volatile const Atomic64* ptr);
-Atomic64 Acquire_Load(volatile const Atomic64* ptr);
-Atomic64 Release_Load(volatile const Atomic64* ptr);
-}  // namespace base::subtle
-}  // namespace base
-
-void MemoryBarrier();
-
-#endif  // 0
-
-
-// ------------------------------------------------------------------------
-// The following are to be deprecated when all uses have been changed to
-// use the base::subtle namespace.
-// ------------------------------------------------------------------------
-
-#ifdef AtomicWordCastType
-// AtomicWord versions to be deprecated
-inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
-                                         AtomicWord old_value,
-                                         AtomicWord new_value) {
-  return base::subtle::Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
-                                         AtomicWord old_value,
-                                         AtomicWord new_value) {
-  return base::subtle::Release_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
-  return base::subtle::Acquire_Store(ptr, value);
-}
-
-inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
-  return base::subtle::Release_Store(ptr, value);
-}
-
-inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
-  return base::subtle::Acquire_Load(ptr);
-}
-
-inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
-  return base::subtle::Release_Load(ptr);
-}
-#endif  // AtomicWordCastType
-
-// 32-bit Acquire/Release operations to be deprecated.
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return base::subtle::Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
-                                       Atomic32 old_value,
-                                       Atomic32 new_value) {
-  return base::subtle::Release_CompareAndSwap(ptr, old_value, new_value);
-}
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
-  base::subtle::Acquire_Store(ptr, value);
-}
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  return base::subtle::Release_Store(ptr, value);
-}
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  return base::subtle::Acquire_Load(ptr);
-}
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
-  return base::subtle::Release_Load(ptr);
-}
-
-#ifdef BASE_HAS_ATOMIC64
-
-// 64-bit Acquire/Release operations to be deprecated.
-
-inline base::subtle::Atomic64 Acquire_CompareAndSwap(
-    volatile base::subtle::Atomic64* ptr,
-    base::subtle::Atomic64 old_value, base::subtle::Atomic64 new_value) {
-  return base::subtle::Acquire_CompareAndSwap(ptr, old_value, new_value);
-}
-inline base::subtle::Atomic64 Release_CompareAndSwap(
-    volatile base::subtle::Atomic64* ptr,
-    base::subtle::Atomic64 old_value, base::subtle::Atomic64 new_value) {
-  return base::subtle::Release_CompareAndSwap(ptr, old_value, new_value);
-}
-inline void Acquire_Store(
-    volatile base::subtle::Atomic64* ptr, base::subtle::Atomic64 value) {
-  base::subtle::Acquire_Store(ptr, value);
-}
-inline void Release_Store(
-    volatile base::subtle::Atomic64* ptr, base::subtle::Atomic64 value) {
-  return base::subtle::Release_Store(ptr, value);
-}
-inline base::subtle::Atomic64 Acquire_Load(
-    volatile const base::subtle::Atomic64* ptr) {
-  return base::subtle::Acquire_Load(ptr);
-}
-inline base::subtle::Atomic64 Release_Load(
-    volatile const base::subtle::Atomic64* ptr) {
-  return base::subtle::Release_Load(ptr);
-}
-
-#endif  // BASE_HAS_ATOMIC64
-
-#endif  // THREAD_ATOMICOPS_H_
diff --git a/third_party/tcmalloc/vendor/src/base/basictypes.h b/third_party/tcmalloc/vendor/src/base/basictypes.h
deleted file mode 100644
index 42dbe5c..0000000
--- a/third_party/tcmalloc/vendor/src/base/basictypes.h
+++ /dev/null
@@ -1,436 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef _BASICTYPES_H_
-#define _BASICTYPES_H_
-
-#include <config.h>
-#include <string.h>       // for memcpy()
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>     // gets us PRId64, etc
-#endif
-
-// To use this in an autoconf setting, make sure you run the following
-// autoconf macros:
-//    AC_HEADER_STDC              /* for stdint_h and inttypes_h */
-//    AC_CHECK_TYPES([__int64])   /* defined in some windows platforms */
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>           // uint16_t might be here; PRId64 too.
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>             // to get uint16_t (ISO naming madness)
-#endif
-#include <sys/types.h>          // our last best hope for uint16_t
-
-// Standard typedefs
-// All Google code is compiled with -funsigned-char to make "char"
-// unsigned.  Google code therefore doesn't need a "uchar" type.
-// TODO(csilvers): how do we make sure unsigned-char works on non-gcc systems?
-typedef signed char         schar;
-typedef int8_t              int8;
-typedef int16_t             int16;
-typedef int32_t             int32;
-typedef int64_t             int64;
-
-// NOTE: unsigned types are DANGEROUS in loops and other arithmetical
-// places.  Use the signed types unless your variable represents a bit
-// pattern (eg a hash value) or you really need the extra bit.  Do NOT
-// use 'unsigned' to express "this value should always be positive";
-// use assertions for this.
-
-typedef uint8_t            uint8;
-typedef uint16_t           uint16;
-typedef uint32_t           uint32;
-typedef uint64_t           uint64;
-
-const uint16 kuint16max = (   (uint16) 0xFFFF);
-const uint32 kuint32max = (   (uint32) 0xFFFFFFFF);
-const uint64 kuint64max = ( (((uint64) kuint32max) << 32) | kuint32max );
-
-const  int8  kint8max   = (   (  int8) 0x7F);
-const  int16 kint16max  = (   ( int16) 0x7FFF);
-const  int32 kint32max  = (   ( int32) 0x7FFFFFFF);
-const  int64 kint64max =  ( ((( int64) kint32max) << 32) | kuint32max );
-
-const  int8  kint8min   = (   (  int8) 0x80);
-const  int16 kint16min  = (   ( int16) 0x8000);
-const  int32 kint32min  = (   ( int32) 0x80000000);
-const  int64 kint64min =  ( (((uint64) kint32min) << 32) | 0 );
-
-// Define the "portable" printf and scanf macros, if they're not
-// already there (via the inttypes.h we #included above, hopefully).
-// Mostly it's old systems that don't support inttypes.h, so we assume
-// they're 32 bit.
-#ifndef PRIx64
-#define PRIx64 "llx"
-#endif
-#ifndef SCNx64
-#define SCNx64 "llx"
-#endif
-#ifndef PRId64
-#define PRId64 "lld"
-#endif
-#ifndef SCNd64
-#define SCNd64 "lld"
-#endif
-#ifndef PRIu64
-#define PRIu64 "llu"
-#endif
-#ifndef PRIxPTR
-#define PRIxPTR "lx"
-#endif
-
-// Also allow for printing of a pthread_t.
-#define GPRIuPTHREAD "lu"
-#define GPRIxPTHREAD "lx"
-#if defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__APPLE__) || defined(__FreeBSD__)
-#define PRINTABLE_PTHREAD(pthreadt) reinterpret_cast<uintptr_t>(pthreadt)
-#else
-#define PRINTABLE_PTHREAD(pthreadt) pthreadt
-#endif
-
-#ifdef HAVE_BUILTIN_EXPECT
-#define PREDICT_TRUE(x) __builtin_expect(!!(x), 1)
-#define PREDICT_FALSE(x) __builtin_expect(!!(x), 0)
-#else
-#define PREDICT_TRUE(x) (x)
-#define PREDICT_FALSE(x) (x)
-#endif
-
-// A macro to disallow the evil copy constructor and operator= functions
-// This should be used in the private: declarations for a class
-#define DISALLOW_EVIL_CONSTRUCTORS(TypeName)    \
-  TypeName(const TypeName&);                    \
-  void operator=(const TypeName&)
-
-// An alternate name that leaves out the moral judgment... :-)
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) DISALLOW_EVIL_CONSTRUCTORS(TypeName)
-
-// The COMPILE_ASSERT macro can be used to verify that a compile time
-// expression is true. For example, you could use it to verify the
-// size of a static array:
-//
-//   COMPILE_ASSERT(sizeof(num_content_type_names) == sizeof(int),
-//                  content_type_names_incorrect_size);
-//
-// or to make sure a struct is smaller than a certain size:
-//
-//   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
-//
-// The second argument to the macro is the name of the variable. If
-// the expression is false, most compilers will issue a warning/error
-// containing the name of the variable.
-//
-// Implementation details of COMPILE_ASSERT:
-//
-// - COMPILE_ASSERT works by defining an array type that has -1
-//   elements (and thus is invalid) when the expression is false.
-//
-// - The simpler definition
-//
-//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
-//
-//   does not work, as gcc supports variable-length arrays whose sizes
-//   are determined at run-time (this is gcc's extension and not part
-//   of the C++ standard).  As a result, gcc fails to reject the
-//   following code with the simple definition:
-//
-//     int foo;
-//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
-//                               // not a compile-time constant.
-//
-// - By using the type CompileAssert<(bool(expr))>, we ensures that
-//   expr is a compile-time constant.  (Template arguments must be
-//   determined at compile-time.)
-//
-// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
-//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
-//
-//     CompileAssert<bool(expr)>
-//
-//   instead, these compilers will refuse to compile
-//
-//     COMPILE_ASSERT(5 > 0, some_message);
-//
-//   (They seem to think the ">" in "5 > 0" marks the end of the
-//   template argument list.)
-//
-// - The array size is (bool(expr) ? 1 : -1), instead of simply
-//
-//     ((expr) ? 1 : -1).
-//
-//   This is to avoid running into a bug in MS VC 7.1, which
-//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
-
-template <bool>
-struct CompileAssert {
-};
-
-#ifdef HAVE___ATTRIBUTE__
-# define ATTRIBUTE_UNUSED __attribute__((unused))
-#else
-# define ATTRIBUTE_UNUSED
-#endif
-
-#if defined(HAVE___ATTRIBUTE__) && defined(HAVE_TLS)
-#define ATTR_INITIAL_EXEC __attribute__ ((tls_model ("initial-exec")))
-#else
-#define ATTR_INITIAL_EXEC
-#endif
-
-#define COMPILE_ASSERT(expr, msg)                               \
-  typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] ATTRIBUTE_UNUSED
-
-#define arraysize(a)  (sizeof(a) / sizeof(*(a)))
-
-#define OFFSETOF_MEMBER(strct, field)                                   \
-   (reinterpret_cast<char*>(&reinterpret_cast<strct*>(16)->field) -     \
-    reinterpret_cast<char*>(16))
-
-// bit_cast<Dest,Source> implements the equivalent of
-// "*reinterpret_cast<Dest*>(&source)".
-//
-// The reinterpret_cast method would produce undefined behavior
-// according to ISO C++ specification section 3.10 -15 -.
-// bit_cast<> calls memcpy() which is blessed by the standard,
-// especially by the example in section 3.9.
-//
-// Fortunately memcpy() is very fast.  In optimized mode, with a
-// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
-// code with the minimal amount of data movement.  On a 32-bit system,
-// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
-// compiles to two loads and two stores.
-
-template <class Dest, class Source>
-inline Dest bit_cast(const Source& source) {
-  COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), bitcasting_unequal_sizes);
-  Dest dest;
-  memcpy(&dest, &source, sizeof(dest));
-  return dest;
-}
-
-// bit_store<Dest,Source> implements the equivalent of
-// "dest = *reinterpret_cast<Dest*>(&source)".
-//
-// This prevents undefined behavior when the dest pointer is unaligned.
-template <class Dest, class Source>
-inline void bit_store(Dest *dest, const Source *source) {
-  COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), bitcasting_unequal_sizes);
-  memcpy(dest, source, sizeof(Dest));
-}
-
-#ifdef HAVE___ATTRIBUTE__
-# define ATTRIBUTE_WEAK      __attribute__((weak))
-# define ATTRIBUTE_NOINLINE  __attribute__((noinline))
-#else
-# define ATTRIBUTE_WEAK
-# define ATTRIBUTE_NOINLINE
-#endif
-
-#if defined(HAVE___ATTRIBUTE__) && defined(__ELF__)
-# define ATTRIBUTE_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
-#else
-# define ATTRIBUTE_VISIBILITY_HIDDEN
-#endif
-
-// Section attributes are supported for both ELF and Mach-O, but in
-// very different ways.  Here's the API we provide:
-// 1) ATTRIBUTE_SECTION: put this with the declaration of all functions
-//    you want to be in the same linker section
-// 2) DEFINE_ATTRIBUTE_SECTION_VARS: must be called once per unique
-//    name.  You want to make sure this is executed before any
-//    DECLARE_ATTRIBUTE_SECTION_VARS; the easiest way is to put them
-//    in the same .cc file.  Put this call at the global level.
-// 3) INIT_ATTRIBUTE_SECTION_VARS: you can scatter calls to this in
-//    multiple places to help ensure execution before any
-//    DECLARE_ATTRIBUTE_SECTION_VARS.  You must have at least one
-//    DEFINE, but you can have many INITs.  Put each in its own scope.
-// 4) DECLARE_ATTRIBUTE_SECTION_VARS: must be called before using
-//    ATTRIBUTE_SECTION_START or ATTRIBUTE_SECTION_STOP on a name.
-//    Put this call at the global level.
-// 5) ATTRIBUTE_SECTION_START/ATTRIBUTE_SECTION_STOP: call this to say
-//    where in memory a given section is.  All functions declared with
-//    ATTRIBUTE_SECTION are guaranteed to be between START and STOP.
-
-#if defined(HAVE___ATTRIBUTE__) && defined(__ELF__)
-# define ATTRIBUTE_SECTION(name) __attribute__ ((section (#name))) __attribute__((noinline))
-
-  // Weak section declaration to be used as a global declaration
-  // for ATTRIBUTE_SECTION_START|STOP(name) to compile and link
-  // even without functions with ATTRIBUTE_SECTION(name).
-# define DECLARE_ATTRIBUTE_SECTION_VARS(name) \
-    extern char __start_##name[] ATTRIBUTE_WEAK; \
-    extern char __stop_##name[] ATTRIBUTE_WEAK
-# define INIT_ATTRIBUTE_SECTION_VARS(name)     // no-op for ELF
-# define DEFINE_ATTRIBUTE_SECTION_VARS(name)   // no-op for ELF
-
-  // Return void* pointers to start/end of a section of code with functions
-  // having ATTRIBUTE_SECTION(name), or 0 if no such function exists.
-  // One must DECLARE_ATTRIBUTE_SECTION(name) for this to compile and link.
-# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))
-# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))
-# define HAVE_ATTRIBUTE_SECTION_START 1
-
-#elif defined(HAVE___ATTRIBUTE__) && defined(__MACH__)
-# define ATTRIBUTE_SECTION(name) __attribute__ ((section ("__TEXT, " #name)))
-
-#include <mach-o/getsect.h>
-#include <mach-o/dyld.h>
-class AssignAttributeStartEnd {
- public:
-  AssignAttributeStartEnd(const char* name, char** pstart, char** pend) {
-    // Find out what dynamic library name is defined in
-    if (_dyld_present()) {
-      for (int i = _dyld_image_count() - 1; i >= 0; --i) {
-        const mach_header* hdr = _dyld_get_image_header(i);
-#ifdef MH_MAGIC_64
-        if (hdr->magic == MH_MAGIC_64) {
-          uint64_t len;
-          *pstart = getsectdatafromheader_64((mach_header_64*)hdr,
-                                             "__TEXT", name, &len);
-          if (*pstart) {   // NULL if not defined in this dynamic library
-            *pstart += _dyld_get_image_vmaddr_slide(i);   // correct for reloc
-            *pend = *pstart + len;
-            return;
-          }
-        }
-#endif
-        if (hdr->magic == MH_MAGIC) {
-          uint32_t len;
-          *pstart = getsectdatafromheader(hdr, "__TEXT", name, &len);
-          if (*pstart) {   // NULL if not defined in this dynamic library
-            *pstart += _dyld_get_image_vmaddr_slide(i);   // correct for reloc
-            *pend = *pstart + len;
-            return;
-          }
-        }
-      }
-    }
-    // If we get here, not defined in a dll at all.  See if defined statically.
-    unsigned long len;    // don't ask me why this type isn't uint32_t too...
-    *pstart = getsectdata("__TEXT", name, &len);
-    *pend = *pstart + len;
-  }
-};
-
-#define DECLARE_ATTRIBUTE_SECTION_VARS(name)    \
-  extern char* __start_##name;                  \
-  extern char* __stop_##name
-
-#define INIT_ATTRIBUTE_SECTION_VARS(name)               \
-  DECLARE_ATTRIBUTE_SECTION_VARS(name);                 \
-  static const AssignAttributeStartEnd __assign_##name( \
-    #name, &__start_##name, &__stop_##name)
-
-#define DEFINE_ATTRIBUTE_SECTION_VARS(name)     \
-  char* __start_##name, *__stop_##name;         \
-  INIT_ATTRIBUTE_SECTION_VARS(name)
-
-# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))
-# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))
-# define HAVE_ATTRIBUTE_SECTION_START 1
-
-#else  // not HAVE___ATTRIBUTE__ && __ELF__, nor HAVE___ATTRIBUTE__ && __MACH__
-# define ATTRIBUTE_SECTION(name)
-# define DECLARE_ATTRIBUTE_SECTION_VARS(name)
-# define INIT_ATTRIBUTE_SECTION_VARS(name)
-# define DEFINE_ATTRIBUTE_SECTION_VARS(name)
-# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(0))
-# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(0))
-
-#endif  // HAVE___ATTRIBUTE__ and __ELF__ or __MACH__
-
-#if defined(HAVE___ATTRIBUTE__)
-# if (defined(__i386__) || defined(__x86_64__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(64)))
-# elif (defined(__PPC__) || defined(__PPC64__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(16)))
-# elif (defined(__arm__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(64)))
-    // some ARMs have shorter cache lines (ARM1176JZF-S is 32 bytes for example) but obviously 64-byte aligned implies 32-byte aligned
-# elif (defined(__mips__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(128)))
-# elif (defined(__aarch64__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(64)))
-    // implementation specific, Cortex-A53 and 57 should have 64 bytes
-# elif (defined(__s390__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(256)))
-# else
-#   error Could not determine cache line length - unknown architecture
-# endif
-#else
-# define CACHELINE_ALIGNED
-#endif  // defined(HAVE___ATTRIBUTE__)
-
-#if defined(HAVE___ATTRIBUTE__ALIGNED_FN)
-#  define CACHELINE_ALIGNED_FN CACHELINE_ALIGNED
-#else
-#  define CACHELINE_ALIGNED_FN
-#endif
-
-// Structure for discovering alignment
-union MemoryAligner {
-  void*  p;
-  double d;
-  size_t s;
-} CACHELINE_ALIGNED;
-
-#if defined(HAVE___ATTRIBUTE__) && defined(__ELF__)
-#define ATTRIBUTE_HIDDEN __attribute__((visibility("hidden")))
-#else
-#define ATTRIBUTE_HIDDEN
-#endif
-
-#if defined(__GNUC__)
-#define ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
-#elif defined(_MSC_VER)
-#define ATTRIBUTE_ALWAYS_INLINE __forceinline
-#else
-#define ATTRIBUTE_ALWAYS_INLINE
-#endif
-
-// The following enum should be used only as a constructor argument to indicate
-// that the variable has static storage class, and that the constructor should
-// do nothing to its state.  It indicates to the reader that it is legal to
-// declare a static nistance of the class, provided the constructor is given
-// the base::LINKER_INITIALIZED argument.  Normally, it is unsafe to declare a
-// static variable that has a constructor or a destructor because invocation
-// order is undefined.  However, IF the type can be initialized by filling with
-// zeroes (which the loader does for static variables), AND the destructor also
-// does nothing to the storage, then a constructor declared as
-//       explicit MyClass(base::LinkerInitialized x) {}
-// and invoked as
-//       static MyClass my_variable_name(base::LINKER_INITIALIZED);
-namespace base {
-enum LinkerInitialized { LINKER_INITIALIZED };
-}
-
-#endif  // _BASICTYPES_H_
diff --git a/third_party/tcmalloc/vendor/src/base/commandlineflags.h b/third_party/tcmalloc/vendor/src/base/commandlineflags.h
deleted file mode 100644
index 49c904f8..0000000
--- a/third_party/tcmalloc/vendor/src/base/commandlineflags.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// This file is a compatibility layer that defines Google's version of
-// command line flags that are used for configuration.
-//
-// We put flags into their own namespace.  It is purposefully
-// named in an opaque way that people should have trouble typing
-// directly.  The idea is that DEFINE puts the flag in the weird
-// namespace, and DECLARE imports the flag from there into the
-// current namespace.  The net result is to force people to use
-// DECLARE to get access to a flag, rather than saying
-//   extern bool FLAGS_logtostderr;
-// or some such instead.  We want this so we can put extra
-// functionality (like sanity-checking) in DECLARE if we want,
-// and make sure it is picked up everywhere.
-//
-// We also put the type of the variable in the namespace, so that
-// people can't DECLARE_int32 something that they DEFINE_bool'd
-// elsewhere.
-#ifndef BASE_COMMANDLINEFLAGS_H_
-#define BASE_COMMANDLINEFLAGS_H_
-
-#include <config.h>
-#include <string>
-#include <string.h>               // for memchr
-#include <stdlib.h>               // for getenv
-#include "base/basictypes.h"
-
-#define DECLARE_VARIABLE(type, name)                                          \
-  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead {  \
-  extern PERFTOOLS_DLL_DECL type FLAGS_##name;                                \
-  }                                                                           \
-  using FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead::FLAGS_##name
-
-#define DEFINE_VARIABLE(type, name, value, meaning) \
-  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead {  \
-  PERFTOOLS_DLL_DECL type FLAGS_##name(value);                                \
-  char FLAGS_no##name;                                                        \
-  }                                                                           \
-  using FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead::FLAGS_##name
-
-// bool specialization
-#define DECLARE_bool(name) \
-  DECLARE_VARIABLE(bool, name)
-#define DEFINE_bool(name, value, meaning) \
-  DEFINE_VARIABLE(bool, name, value, meaning)
-
-// int32 specialization
-#define DECLARE_int32(name) \
-  DECLARE_VARIABLE(int32, name)
-#define DEFINE_int32(name, value, meaning) \
-  DEFINE_VARIABLE(int32, name, value, meaning)
-
-// int64 specialization
-#define DECLARE_int64(name) \
-  DECLARE_VARIABLE(int64, name)
-#define DEFINE_int64(name, value, meaning) \
-  DEFINE_VARIABLE(int64, name, value, meaning)
-
-#define DECLARE_uint64(name) \
-  DECLARE_VARIABLE(uint64, name)
-#define DEFINE_uint64(name, value, meaning) \
-  DEFINE_VARIABLE(uint64, name, value, meaning)
-
-// double specialization
-#define DECLARE_double(name) \
-  DECLARE_VARIABLE(double, name)
-#define DEFINE_double(name, value, meaning) \
-  DEFINE_VARIABLE(double, name, value, meaning)
-
-// Special case for string, because we have to specify the namespace
-// std::string, which doesn't play nicely with our FLAG__namespace hackery.
-#define DECLARE_string(name)                                          \
-  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead {  \
-  extern std::string FLAGS_##name;                                                   \
-  }                                                                           \
-  using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
-#define DEFINE_string(name, value, meaning) \
-  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead {  \
-  std::string FLAGS_##name(value);                                                   \
-  char FLAGS_no##name;                                                        \
-  }                                                                           \
-  using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
-
-// implemented in sysinfo.cc
-namespace tcmalloc {
-  namespace commandlineflags {
-
-    inline bool StringToBool(const char *value, bool def) {
-      if (!value) {
-        return def;
-      }
-      switch (value[0]) {
-      case 't':
-      case 'T':
-      case 'y':
-      case 'Y':
-      case '1':
-      case '\0':
-        return true;
-      }
-      return false;
-    }
-
-    inline int StringToInt(const char *value, int def) {
-      if (!value) {
-        return def;
-      }
-      return strtol(value, NULL, 10);
-    }
-
-    inline long long StringToLongLong(const char *value, long long def) {
-      if (!value) {
-        return def;
-      }
-      return strtoll(value, NULL, 10);
-    }
-
-    inline double StringToDouble(const char *value, double def) {
-      if (!value) {
-        return def;
-      }
-      return strtod(value, NULL);
-    }
-  }
-}
-
-// These macros (could be functions, but I don't want to bother with a .cc
-// file), make it easier to initialize flags from the environment.
-
-#define EnvToString(envname, dflt)   \
-  (!getenv(envname) ? (dflt) : getenv(envname))
-
-#define EnvToBool(envname, dflt)   \
-  tcmalloc::commandlineflags::StringToBool(getenv(envname), dflt)
-
-#define EnvToInt(envname, dflt)  \
-  tcmalloc::commandlineflags::StringToInt(getenv(envname), dflt)
-
-#define EnvToInt64(envname, dflt)  \
-  tcmalloc::commandlineflags::StringToLongLong(getenv(envname), dflt)
-
-#define EnvToDouble(envname, dflt)  \
-  tcmalloc::commandlineflags::StringToDouble(getenv(envname), dflt)
-
-#endif  // BASE_COMMANDLINEFLAGS_H_
diff --git a/third_party/tcmalloc/vendor/src/base/dynamic_annotations.c b/third_party/tcmalloc/vendor/src/base/dynamic_annotations.c
deleted file mode 100644
index 87bd2ec..0000000
--- a/third_party/tcmalloc/vendor/src/base/dynamic_annotations.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* Copyright (c) 2008-2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Kostya Serebryany
- */
-
-#ifdef __cplusplus
-# error "This file should be built as pure C to avoid name mangling"
-#endif
-
-#include "config.h"
-#include <stdlib.h>
-#include <string.h>
-
-#include "base/dynamic_annotations.h"
-#include "getenv_safe.h" // for TCMallocGetenvSafe
-
-#ifdef __GNUC__
-/* valgrind.h uses gcc extensions so it won't build with other compilers */
-# ifdef HAVE_VALGRIND_H    /* prefer the user's copy if they have it */
-#  include <valgrind.h>
-# else                     /* otherwise just use the copy that we have */
-#  include "third_party/valgrind.h"
-# endif
-#endif
-
-/* Compiler-based ThreadSanitizer defines
-   DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL = 1
-   and provides its own definitions of the functions. */
-
-#ifndef DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL
-# define DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL 0
-#endif
-
-/* Each function is empty and called (via a macro) only in debug mode.
-   The arguments are captured by dynamic tools at runtime. */
-
-#if DYNAMIC_ANNOTATIONS_ENABLED == 1 \
-    && DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0
-
-void AnnotateRWLockCreate(const char *file, int line,
-                          const volatile void *lock){}
-void AnnotateRWLockDestroy(const char *file, int line,
-                           const volatile void *lock){}
-void AnnotateRWLockAcquired(const char *file, int line,
-                            const volatile void *lock, long is_w){}
-void AnnotateRWLockReleased(const char *file, int line,
-                            const volatile void *lock, long is_w){}
-void AnnotateBarrierInit(const char *file, int line,
-                         const volatile void *barrier, long count,
-                         long reinitialization_allowed) {}
-void AnnotateBarrierWaitBefore(const char *file, int line,
-                               const volatile void *barrier) {}
-void AnnotateBarrierWaitAfter(const char *file, int line,
-                              const volatile void *barrier) {}
-void AnnotateBarrierDestroy(const char *file, int line,
-                            const volatile void *barrier) {}
-
-void AnnotateCondVarWait(const char *file, int line,
-                         const volatile void *cv,
-                         const volatile void *lock){}
-void AnnotateCondVarSignal(const char *file, int line,
-                           const volatile void *cv){}
-void AnnotateCondVarSignalAll(const char *file, int line,
-                              const volatile void *cv){}
-void AnnotatePublishMemoryRange(const char *file, int line,
-                                const volatile void *address,
-                                long size){}
-void AnnotateUnpublishMemoryRange(const char *file, int line,
-                                  const volatile void *address,
-                                  long size){}
-void AnnotatePCQCreate(const char *file, int line,
-                       const volatile void *pcq){}
-void AnnotatePCQDestroy(const char *file, int line,
-                        const volatile void *pcq){}
-void AnnotatePCQPut(const char *file, int line,
-                    const volatile void *pcq){}
-void AnnotatePCQGet(const char *file, int line,
-                    const volatile void *pcq){}
-void AnnotateNewMemory(const char *file, int line,
-                       const volatile void *mem,
-                       long size){}
-void AnnotateExpectRace(const char *file, int line,
-                        const volatile void *mem,
-                        const char *description){}
-void AnnotateBenignRace(const char *file, int line,
-                        const volatile void *mem,
-                        const char *description){}
-void AnnotateBenignRaceSized(const char *file, int line,
-                             const volatile void *mem,
-                             long size,
-                             const char *description) {}
-void AnnotateMutexIsUsedAsCondVar(const char *file, int line,
-                                  const volatile void *mu){}
-void AnnotateTraceMemory(const char *file, int line,
-                         const volatile void *arg){}
-void AnnotateThreadName(const char *file, int line,
-                        const char *name){}
-void AnnotateIgnoreReadsBegin(const char *file, int line){}
-void AnnotateIgnoreReadsEnd(const char *file, int line){}
-void AnnotateIgnoreWritesBegin(const char *file, int line){}
-void AnnotateIgnoreWritesEnd(const char *file, int line){}
-void AnnotateEnableRaceDetection(const char *file, int line, int enable){}
-void AnnotateNoOp(const char *file, int line,
-                  const volatile void *arg){}
-void AnnotateFlushState(const char *file, int line){}
-
-#endif  /* DYNAMIC_ANNOTATIONS_ENABLED == 1
-    && DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */
-
-#if DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0
-
-static int GetRunningOnValgrind(void) {
-#ifdef RUNNING_ON_VALGRIND
-  if (RUNNING_ON_VALGRIND) return 1;
-#endif
-  const char *running_on_valgrind_str = TCMallocGetenvSafe("RUNNING_ON_VALGRIND");
-  if (running_on_valgrind_str) {
-    return strcmp(running_on_valgrind_str, "0") != 0;
-  }
-  return 0;
-}
-
-/* See the comments in dynamic_annotations.h */
-int RunningOnValgrind(void) {
-  static volatile int running_on_valgrind = -1;
-  int local_running_on_valgrind = running_on_valgrind;
-  /* C doesn't have thread-safe initialization of statics, and we
-     don't want to depend on pthread_once here, so hack it. */
-  ANNOTATE_BENIGN_RACE(&running_on_valgrind, "safe hack");
-  if (local_running_on_valgrind == -1)
-    running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind();
-  return local_running_on_valgrind;
-}
-
-#endif  /* DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */
-
-/* See the comments in dynamic_annotations.h */
-double ValgrindSlowdown(void) {
-  /* Same initialization hack as in RunningOnValgrind(). */
-  static volatile double slowdown = 0.0;
-  double local_slowdown = slowdown;
-  ANNOTATE_BENIGN_RACE(&slowdown, "safe hack");
-  if (RunningOnValgrind() == 0) {
-    return 1.0;
-  }
-  if (local_slowdown == 0.0) {
-    char *env = getenv("VALGRIND_SLOWDOWN");
-    slowdown = local_slowdown = env ? atof(env) : 50.0;
-  }
-  return local_slowdown;
-}
diff --git a/third_party/tcmalloc/vendor/src/base/dynamic_annotations.h b/third_party/tcmalloc/vendor/src/base/dynamic_annotations.h
deleted file mode 100644
index 4669315..0000000
--- a/third_party/tcmalloc/vendor/src/base/dynamic_annotations.h
+++ /dev/null
@@ -1,627 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Kostya Serebryany
- */
-
-/* This file defines dynamic annotations for use with dynamic analysis
-   tool such as valgrind, PIN, etc.
-
-   Dynamic annotation is a source code annotation that affects
-   the generated code (that is, the annotation is not a comment).
-   Each such annotation is attached to a particular
-   instruction and/or to a particular object (address) in the program.
-
-   The annotations that should be used by users are macros in all upper-case
-   (e.g., ANNOTATE_NEW_MEMORY).
-
-   Actual implementation of these macros may differ depending on the
-   dynamic analysis tool being used.
-
-   See http://code.google.com/p/data-race-test/  for more information.
-
-   This file supports the following dynamic analysis tools:
-   - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero).
-      Macros are defined empty.
-   - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1).
-      Macros are defined as calls to non-inlinable empty functions
-      that are intercepted by Valgrind. */
-
-#ifndef BASE_DYNAMIC_ANNOTATIONS_H_
-#define BASE_DYNAMIC_ANNOTATIONS_H_
-
-#ifndef DYNAMIC_ANNOTATIONS_ENABLED
-# define DYNAMIC_ANNOTATIONS_ENABLED 0
-#endif
-
-#if DYNAMIC_ANNOTATIONS_ENABLED != 0
-
-  /* -------------------------------------------------------------
-     Annotations useful when implementing condition variables such as CondVar,
-     using conditional critical sections (Await/LockWhen) and when constructing
-     user-defined synchronization mechanisms.
-
-     The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can
-     be used to define happens-before arcs in user-defined synchronization
-     mechanisms:  the race detector will infer an arc from the former to the
-     latter when they share the same argument pointer.
-
-     Example 1 (reference counting):
-
-     void Unref() {
-       ANNOTATE_HAPPENS_BEFORE(&refcount_);
-       if (AtomicDecrementByOne(&refcount_) == 0) {
-         ANNOTATE_HAPPENS_AFTER(&refcount_);
-         delete this;
-       }
-     }
-
-     Example 2 (message queue):
-
-     void MyQueue::Put(Type *e) {
-       MutexLock lock(&mu_);
-       ANNOTATE_HAPPENS_BEFORE(e);
-       PutElementIntoMyQueue(e);
-     }
-
-     Type *MyQueue::Get() {
-       MutexLock lock(&mu_);
-       Type *e = GetElementFromMyQueue();
-       ANNOTATE_HAPPENS_AFTER(e);
-       return e;
-     }
-
-     Note: when possible, please use the existing reference counting and message
-     queue implementations instead of inventing new ones. */
-
-  /* Report that wait on the condition variable at address "cv" has succeeded
-     and the lock at address "lock" is held. */
-  #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \
-    AnnotateCondVarWait(__FILE__, __LINE__, cv, lock)
-
-  /* Report that wait on the condition variable at "cv" has succeeded.  Variant
-     w/o lock. */
-  #define ANNOTATE_CONDVAR_WAIT(cv) \
-    AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL)
-
-  /* Report that we are about to signal on the condition variable at address
-     "cv". */
-  #define ANNOTATE_CONDVAR_SIGNAL(cv) \
-    AnnotateCondVarSignal(__FILE__, __LINE__, cv)
-
-  /* Report that we are about to signal_all on the condition variable at "cv". */
-  #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \
-    AnnotateCondVarSignalAll(__FILE__, __LINE__, cv)
-
-  /* Annotations for user-defined synchronization mechanisms. */
-  #define ANNOTATE_HAPPENS_BEFORE(obj) ANNOTATE_CONDVAR_SIGNAL(obj)
-  #define ANNOTATE_HAPPENS_AFTER(obj)  ANNOTATE_CONDVAR_WAIT(obj)
-
-  /* Report that the bytes in the range [pointer, pointer+size) are about
-     to be published safely. The race checker will create a happens-before
-     arc from the call ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to
-     subsequent accesses to this memory.
-     Note: this annotation may not work properly if the race detector uses
-     sampling, i.e. does not observe all memory accesses.
-     */
-  #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \
-    AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size)
-
-  /* DEPRECATED. Don't use it. */
-  #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) \
-    AnnotateUnpublishMemoryRange(__FILE__, __LINE__, pointer, size)
-
-  /* DEPRECATED. Don't use it. */
-  #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size)   \
-    do {                                              \
-      ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size); \
-      ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size);   \
-    } while (0)
-
-  /* Instruct the tool to create a happens-before arc between mu->Unlock() and
-     mu->Lock(). This annotation may slow down the race detector and hide real
-     races. Normally it is used only when it would be difficult to annotate each
-     of the mutex's critical sections individually using the annotations above.
-     This annotation makes sense only for hybrid race detectors. For pure
-     happens-before detectors this is a no-op. For more details see
-     http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */
-  #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \
-    AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu)
-
-  /* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */
-  #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \
-    AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu)
-
-  /* -------------------------------------------------------------
-     Annotations useful when defining memory allocators, or when memory that
-     was protected in one way starts to be protected in another. */
-
-  /* Report that a new memory at "address" of size "size" has been allocated.
-     This might be used when the memory has been retrieved from a free list and
-     is about to be reused, or when a the locking discipline for a variable
-     changes. */
-  #define ANNOTATE_NEW_MEMORY(address, size) \
-    AnnotateNewMemory(__FILE__, __LINE__, address, size)
-
-  /* -------------------------------------------------------------
-     Annotations useful when defining FIFO queues that transfer data between
-     threads. */
-
-  /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at
-     address "pcq" has been created.  The ANNOTATE_PCQ_* annotations
-     should be used only for FIFO queues.  For non-FIFO queues use
-     ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). */
-  #define ANNOTATE_PCQ_CREATE(pcq) \
-    AnnotatePCQCreate(__FILE__, __LINE__, pcq)
-
-  /* Report that the queue at address "pcq" is about to be destroyed. */
-  #define ANNOTATE_PCQ_DESTROY(pcq) \
-    AnnotatePCQDestroy(__FILE__, __LINE__, pcq)
-
-  /* Report that we are about to put an element into a FIFO queue at address
-     "pcq". */
-  #define ANNOTATE_PCQ_PUT(pcq) \
-    AnnotatePCQPut(__FILE__, __LINE__, pcq)
-
-  /* Report that we've just got an element from a FIFO queue at address "pcq". */
-  #define ANNOTATE_PCQ_GET(pcq) \
-    AnnotatePCQGet(__FILE__, __LINE__, pcq)
-
-  /* -------------------------------------------------------------
-     Annotations that suppress errors.  It is usually better to express the
-     program's synchronization using the other annotations, but these can
-     be used when all else fails. */
-
-  /* Report that we may have a benign race at "pointer", with size
-     "sizeof(*(pointer))". "pointer" must be a non-void* pointer.  Insert at the
-     point where "pointer" has been allocated, preferably close to the point
-     where the race happens.  See also ANNOTATE_BENIGN_RACE_STATIC. */
-  #define ANNOTATE_BENIGN_RACE(pointer, description) \
-    AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \
-                            sizeof(*(pointer)), description)
-
-  /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to
-     the memory range [address, address+size). */
-  #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
-    AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description)
-
-  /* Request the analysis tool to ignore all reads in the current thread
-     until ANNOTATE_IGNORE_READS_END is called.
-     Useful to ignore intentional racey reads, while still checking
-     other reads and all writes.
-     See also ANNOTATE_UNPROTECTED_READ. */
-  #define ANNOTATE_IGNORE_READS_BEGIN() \
-    AnnotateIgnoreReadsBegin(__FILE__, __LINE__)
-
-  /* Stop ignoring reads. */
-  #define ANNOTATE_IGNORE_READS_END() \
-    AnnotateIgnoreReadsEnd(__FILE__, __LINE__)
-
-  /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */
-  #define ANNOTATE_IGNORE_WRITES_BEGIN() \
-    AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
-
-  /* Stop ignoring writes. */
-  #define ANNOTATE_IGNORE_WRITES_END() \
-    AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
-
-  /* Start ignoring all memory accesses (reads and writes). */
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
-    do {\
-      ANNOTATE_IGNORE_READS_BEGIN();\
-      ANNOTATE_IGNORE_WRITES_BEGIN();\
-    }while(0)\
-
-  /* Stop ignoring all memory accesses. */
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
-    do {\
-      ANNOTATE_IGNORE_WRITES_END();\
-      ANNOTATE_IGNORE_READS_END();\
-    }while(0)\
-
-  /* Enable (enable!=0) or disable (enable==0) race detection for all threads.
-     This annotation could be useful if you want to skip expensive race analysis
-     during some period of program execution, e.g. during initialization. */
-  #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \
-    AnnotateEnableRaceDetection(__FILE__, __LINE__, enable)
-
-  /* -------------------------------------------------------------
-     Annotations useful for debugging. */
-
-  /* Request to trace every access to "address". */
-  #define ANNOTATE_TRACE_MEMORY(address) \
-    AnnotateTraceMemory(__FILE__, __LINE__, address)
-
-  /* Report the current thread name to a race detector. */
-  #define ANNOTATE_THREAD_NAME(name) \
-    AnnotateThreadName(__FILE__, __LINE__, name)
-
-  /* -------------------------------------------------------------
-     Annotations useful when implementing locks.  They are not
-     normally needed by modules that merely use locks.
-     The "lock" argument is a pointer to the lock object. */
-
-  /* Report that a lock has been created at address "lock". */
-  #define ANNOTATE_RWLOCK_CREATE(lock) \
-    AnnotateRWLockCreate(__FILE__, __LINE__, lock)
-
-  /* Report that the lock at address "lock" is about to be destroyed. */
-  #define ANNOTATE_RWLOCK_DESTROY(lock) \
-    AnnotateRWLockDestroy(__FILE__, __LINE__, lock)
-
-  /* Report that the lock at address "lock" has been acquired.
-     is_w=1 for writer lock, is_w=0 for reader lock. */
-  #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \
-    AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w)
-
-  /* Report that the lock at address "lock" is about to be released. */
-  #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \
-    AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w)
-
-  /* -------------------------------------------------------------
-     Annotations useful when implementing barriers.  They are not
-     normally needed by modules that merely use barriers.
-     The "barrier" argument is a pointer to the barrier object. */
-
-  /* Report that the "barrier" has been initialized with initial "count".
-   If 'reinitialization_allowed' is true, initialization is allowed to happen
-   multiple times w/o calling barrier_destroy() */
-  #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
-    AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \
-                        reinitialization_allowed)
-
-  /* Report that we are about to enter barrier_wait("barrier"). */
-  #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \
-    AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier)
-
-  /* Report that we just exited barrier_wait("barrier"). */
-  #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \
-    AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier)
-
-  /* Report that the "barrier" has been destroyed. */
-  #define ANNOTATE_BARRIER_DESTROY(barrier) \
-    AnnotateBarrierDestroy(__FILE__, __LINE__, barrier)
-
-  /* -------------------------------------------------------------
-     Annotations useful for testing race detectors. */
-
-  /* Report that we expect a race on the variable at "address".
-     Use only in unit tests for a race detector. */
-  #define ANNOTATE_EXPECT_RACE(address, description) \
-    AnnotateExpectRace(__FILE__, __LINE__, address, description)
-
-  /* A no-op. Insert where you like to test the interceptors. */
-  #define ANNOTATE_NO_OP(arg) \
-    AnnotateNoOp(__FILE__, __LINE__, arg)
-
-  /* Force the race detector to flush its state. The actual effect depends on
-   * the implementation of the detector. */
-  #define ANNOTATE_FLUSH_STATE() \
-    AnnotateFlushState(__FILE__, __LINE__)
-
-
-#else  /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
-
-  #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */
-  #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */
-  #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */
-  #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */
-  #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */
-  #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */
-  #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */
-  #define ANNOTATE_BARRIER_DESTROY(barrier) /* empty */
-  #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */
-  #define ANNOTATE_CONDVAR_WAIT(cv) /* empty */
-  #define ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */
-  #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */
-  #define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */
-  #define ANNOTATE_HAPPENS_AFTER(obj) /* empty */
-  #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */
-  #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size)  /* empty */
-  #define ANNOTATE_SWAP_MEMORY_RANGE(address, size)  /* empty */
-  #define ANNOTATE_PCQ_CREATE(pcq) /* empty */
-  #define ANNOTATE_PCQ_DESTROY(pcq) /* empty */
-  #define ANNOTATE_PCQ_PUT(pcq) /* empty */
-  #define ANNOTATE_PCQ_GET(pcq) /* empty */
-  #define ANNOTATE_NEW_MEMORY(address, size) /* empty */
-  #define ANNOTATE_EXPECT_RACE(address, description) /* empty */
-  #define ANNOTATE_BENIGN_RACE(address, description) /* empty */
-  #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */
-  #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */
-  #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */
-  #define ANNOTATE_TRACE_MEMORY(arg) /* empty */
-  #define ANNOTATE_THREAD_NAME(name) /* empty */
-  #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */
-  #define ANNOTATE_IGNORE_READS_END() /* empty */
-  #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */
-  #define ANNOTATE_IGNORE_WRITES_END() /* empty */
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */
-  #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */
-  #define ANNOTATE_NO_OP(arg) /* empty */
-  #define ANNOTATE_FLUSH_STATE() /* empty */
-
-#endif  /* DYNAMIC_ANNOTATIONS_ENABLED */
-
-/* Macro definitions for GCC attributes that allow static thread safety
-   analysis to recognize and use some of the dynamic annotations as
-   escape hatches.
-   TODO(lcwu): remove the check for __SUPPORT_DYN_ANNOTATION__ once the
-   default crosstool/GCC supports these GCC attributes.  */
-
-#define ANNOTALYSIS_STATIC_INLINE
-#define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ;
-#define ANNOTALYSIS_IGNORE_READS_BEGIN
-#define ANNOTALYSIS_IGNORE_READS_END
-#define ANNOTALYSIS_IGNORE_WRITES_BEGIN
-#define ANNOTALYSIS_IGNORE_WRITES_END
-#define ANNOTALYSIS_UNPROTECTED_READ
-
-#if defined(__GNUC__) && (!defined(SWIG)) && (!defined(__clang__)) && \
-    defined(__SUPPORT_TS_ANNOTATION__) && defined(__SUPPORT_DYN_ANNOTATION__)
-
-#if DYNAMIC_ANNOTATIONS_ENABLED == 0
-#define ANNOTALYSIS_ONLY 1
-#undef ANNOTALYSIS_STATIC_INLINE
-#define ANNOTALYSIS_STATIC_INLINE static inline
-#undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-#define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY { (void)file; (void)line; }
-#endif
-
-/* Only emit attributes when annotalysis is enabled. */
-#if defined(__SUPPORT_TS_ANNOTATION__) && defined(__SUPPORT_DYN_ANNOTATION__)
-#undef  ANNOTALYSIS_IGNORE_READS_BEGIN
-#define ANNOTALYSIS_IGNORE_READS_BEGIN  __attribute__ ((ignore_reads_begin))
-#undef  ANNOTALYSIS_IGNORE_READS_END
-#define ANNOTALYSIS_IGNORE_READS_END    __attribute__ ((ignore_reads_end))
-#undef  ANNOTALYSIS_IGNORE_WRITES_BEGIN
-#define ANNOTALYSIS_IGNORE_WRITES_BEGIN __attribute__ ((ignore_writes_begin))
-#undef  ANNOTALYSIS_IGNORE_WRITES_END
-#define ANNOTALYSIS_IGNORE_WRITES_END   __attribute__ ((ignore_writes_end))
-#undef  ANNOTALYSIS_UNPROTECTED_READ
-#define ANNOTALYSIS_UNPROTECTED_READ    __attribute__ ((unprotected_read))
-#endif
-
-#endif // defined(__GNUC__) && (!defined(SWIG)) && (!defined(__clang__))
-
-/* Use the macros above rather than using these functions directly. */
-#ifdef __cplusplus
-extern "C" {
-#endif
-void AnnotateRWLockCreate(const char *file, int line,
-                          const volatile void *lock);
-void AnnotateRWLockDestroy(const char *file, int line,
-                           const volatile void *lock);
-void AnnotateRWLockAcquired(const char *file, int line,
-                            const volatile void *lock, long is_w);
-void AnnotateRWLockReleased(const char *file, int line,
-                            const volatile void *lock, long is_w);
-void AnnotateBarrierInit(const char *file, int line,
-                         const volatile void *barrier, long count,
-                         long reinitialization_allowed);
-void AnnotateBarrierWaitBefore(const char *file, int line,
-                               const volatile void *barrier);
-void AnnotateBarrierWaitAfter(const char *file, int line,
-                              const volatile void *barrier);
-void AnnotateBarrierDestroy(const char *file, int line,
-                            const volatile void *barrier);
-void AnnotateCondVarWait(const char *file, int line,
-                         const volatile void *cv,
-                         const volatile void *lock);
-void AnnotateCondVarSignal(const char *file, int line,
-                           const volatile void *cv);
-void AnnotateCondVarSignalAll(const char *file, int line,
-                              const volatile void *cv);
-void AnnotatePublishMemoryRange(const char *file, int line,
-                                const volatile void *address,
-                                long size);
-void AnnotateUnpublishMemoryRange(const char *file, int line,
-                                  const volatile void *address,
-                                  long size);
-void AnnotatePCQCreate(const char *file, int line,
-                       const volatile void *pcq);
-void AnnotatePCQDestroy(const char *file, int line,
-                        const volatile void *pcq);
-void AnnotatePCQPut(const char *file, int line,
-                    const volatile void *pcq);
-void AnnotatePCQGet(const char *file, int line,
-                    const volatile void *pcq);
-void AnnotateNewMemory(const char *file, int line,
-                       const volatile void *address,
-                       long size);
-void AnnotateExpectRace(const char *file, int line,
-                        const volatile void *address,
-                        const char *description);
-void AnnotateBenignRace(const char *file, int line,
-                        const volatile void *address,
-                        const char *description);
-void AnnotateBenignRaceSized(const char *file, int line,
-                        const volatile void *address,
-                        long size,
-                        const char *description);
-void AnnotateMutexIsUsedAsCondVar(const char *file, int line,
-                                  const volatile void *mu);
-void AnnotateTraceMemory(const char *file, int line,
-                         const volatile void *arg);
-void AnnotateThreadName(const char *file, int line,
-                        const char *name);
-ANNOTALYSIS_STATIC_INLINE
-void AnnotateIgnoreReadsBegin(const char *file, int line)
-    ANNOTALYSIS_IGNORE_READS_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-ANNOTALYSIS_STATIC_INLINE
-void AnnotateIgnoreReadsEnd(const char *file, int line)
-    ANNOTALYSIS_IGNORE_READS_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-ANNOTALYSIS_STATIC_INLINE
-void AnnotateIgnoreWritesBegin(const char *file, int line)
-    ANNOTALYSIS_IGNORE_WRITES_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-ANNOTALYSIS_STATIC_INLINE
-void AnnotateIgnoreWritesEnd(const char *file, int line)
-    ANNOTALYSIS_IGNORE_WRITES_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-void AnnotateEnableRaceDetection(const char *file, int line, int enable);
-void AnnotateNoOp(const char *file, int line,
-                  const volatile void *arg);
-void AnnotateFlushState(const char *file, int line);
-
-/* Return non-zero value if running under valgrind.
-
-  If "valgrind.h" is included into dynamic_annotations.c,
-  the regular valgrind mechanism will be used.
-  See http://valgrind.org/docs/manual/manual-core-adv.html about
-  RUNNING_ON_VALGRIND and other valgrind "client requests".
-  The file "valgrind.h" may be obtained by doing
-     svn co svn://svn.valgrind.org/valgrind/trunk/include
-
-  If for some reason you can't use "valgrind.h" or want to fake valgrind,
-  there are two ways to make this function return non-zero:
-    - Use environment variable: export RUNNING_ON_VALGRIND=1
-    - Make your tool intercept the function RunningOnValgrind() and
-      change its return value.
- */
-int RunningOnValgrind(void);
-
-/* ValgrindSlowdown returns:
-    * 1.0, if (RunningOnValgrind() == 0)
-    * 50.0, if (RunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL)
-    * atof(getenv("VALGRIND_SLOWDOWN")) otherwise
-   This function can be used to scale timeout values:
-   EXAMPLE:
-   for (;;) {
-     DoExpensiveBackgroundTask();
-     SleepForSeconds(5 * ValgrindSlowdown());
-   }
- */
-double ValgrindSlowdown(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus)
-
-  /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
-
-     Instead of doing
-        ANNOTATE_IGNORE_READS_BEGIN();
-        ... = x;
-        ANNOTATE_IGNORE_READS_END();
-     one can use
-        ... = ANNOTATE_UNPROTECTED_READ(x); */
-  template <class T>
-  inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x)
-      ANNOTALYSIS_UNPROTECTED_READ {
-    ANNOTATE_IGNORE_READS_BEGIN();
-    T res = x;
-    ANNOTATE_IGNORE_READS_END();
-    return res;
-  }
-  /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
-  #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)        \
-    namespace {                                                       \
-      class static_var ## _annotator {                                \
-       public:                                                        \
-        static_var ## _annotator() {                                  \
-          ANNOTATE_BENIGN_RACE_SIZED(&static_var,                     \
-                                      sizeof(static_var),             \
-            # static_var ": " description);                           \
-        }                                                             \
-      };                                                              \
-      static static_var ## _annotator the ## static_var ## _annotator;\
-    }
-#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
-
-  #define ANNOTATE_UNPROTECTED_READ(x) (x)
-  #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)  /* empty */
-
-#endif /* DYNAMIC_ANNOTATIONS_ENABLED */
-
-/* Annotalysis, a GCC based static analyzer, is able to understand and use
-   some of the dynamic annotations defined in this file. However, dynamic
-   annotations are usually disabled in the opt mode (to avoid additional
-   runtime overheads) while Annotalysis only works in the opt mode.
-   In order for Annotalysis to use these dynamic annotations when they
-   are disabled, we re-define these annotations here. Note that unlike the
-   original macro definitions above, these macros are expanded to calls to
-   static inline functions so that the compiler will be able to remove the
-   calls after the analysis. */
-
-#ifdef ANNOTALYSIS_ONLY
-
-  #undef ANNOTALYSIS_ONLY
-
-  /* Undefine and re-define the macros that the static analyzer understands. */
-  #undef ANNOTATE_IGNORE_READS_BEGIN
-  #define ANNOTATE_IGNORE_READS_BEGIN()           \
-    AnnotateIgnoreReadsBegin(__FILE__, __LINE__)
-
-  #undef ANNOTATE_IGNORE_READS_END
-  #define ANNOTATE_IGNORE_READS_END()             \
-    AnnotateIgnoreReadsEnd(__FILE__, __LINE__)
-
-  #undef ANNOTATE_IGNORE_WRITES_BEGIN
-  #define ANNOTATE_IGNORE_WRITES_BEGIN()          \
-    AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
-
-  #undef ANNOTATE_IGNORE_WRITES_END
-  #define ANNOTATE_IGNORE_WRITES_END()            \
-    AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
-
-  #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN()       \
-    do {                                                 \
-      ANNOTATE_IGNORE_READS_BEGIN();                     \
-      ANNOTATE_IGNORE_WRITES_BEGIN();                    \
-    }while(0)                                            \
-
-  #undef ANNOTATE_IGNORE_READS_AND_WRITES_END
-  #define ANNOTATE_IGNORE_READS_AND_WRITES_END()  \
-    do {                                          \
-      ANNOTATE_IGNORE_WRITES_END();               \
-      ANNOTATE_IGNORE_READS_END();                \
-    }while(0)                                     \
-
-  #if defined(__cplusplus)
-    #undef ANNOTATE_UNPROTECTED_READ
-    template <class T>
-    inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x)
-         ANNOTALYSIS_UNPROTECTED_READ {
-      ANNOTATE_IGNORE_READS_BEGIN();
-      T res = x;
-      ANNOTATE_IGNORE_READS_END();
-      return res;
-    }
-  #endif /* __cplusplus */
-
-#endif /* ANNOTALYSIS_ONLY */
-
-/* Undefine the macros intended only in this file. */
-#undef ANNOTALYSIS_STATIC_INLINE
-#undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY
-
-#endif  /* BASE_DYNAMIC_ANNOTATIONS_H_ */
diff --git a/third_party/tcmalloc/vendor/src/base/elf_mem_image.cc b/third_party/tcmalloc/vendor/src/base/elf_mem_image.cc
deleted file mode 100644
index d2ca1a5..0000000
--- a/third_party/tcmalloc/vendor/src/base/elf_mem_image.cc
+++ /dev/null
@@ -1,434 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Pluzhnikov
-//
-// Allow dynamic symbol lookup in an in-memory Elf image.
-//
-
-#include "base/elf_mem_image.h"
-
-#ifdef HAVE_ELF_MEM_IMAGE  // defined in elf_mem_image.h
-
-#include <stddef.h>   // for size_t, ptrdiff_t
-#include "base/logging.h"
-
-// From binutils/include/elf/common.h (this doesn't appear to be documented
-// anywhere else).
-//
-//   /* This flag appears in a Versym structure.  It means that the symbol
-//      is hidden, and is only visible with an explicit version number.
-//      This is a GNU extension.  */
-//   #define VERSYM_HIDDEN           0x8000
-//
-//   /* This is the mask for the rest of the Versym information.  */
-//   #define VERSYM_VERSION          0x7fff
-
-#define VERSYM_VERSION 0x7fff
-
-namespace base {
-
-namespace {
-template <int N> class ElfClass {
- public:
-  static const int kElfClass = -1;
-  static int ElfBind(const ElfW(Sym) *) {
-    CHECK(false); // << "Unexpected word size";
-    return 0;
-  }
-  static int ElfType(const ElfW(Sym) *) {
-    CHECK(false); // << "Unexpected word size";
-    return 0;
-  }
-};
-
-template <> class ElfClass<32> {
- public:
-  static const int kElfClass = ELFCLASS32;
-  static int ElfBind(const ElfW(Sym) *symbol) {
-    return ELF32_ST_BIND(symbol->st_info);
-  }
-  static int ElfType(const ElfW(Sym) *symbol) {
-    return ELF32_ST_TYPE(symbol->st_info);
-  }
-};
-
-template <> class ElfClass<64> {
- public:
-  static const int kElfClass = ELFCLASS64;
-  static int ElfBind(const ElfW(Sym) *symbol) {
-    return ELF64_ST_BIND(symbol->st_info);
-  }
-  static int ElfType(const ElfW(Sym) *symbol) {
-    return ELF64_ST_TYPE(symbol->st_info);
-  }
-};
-
-typedef ElfClass<__WORDSIZE> CurrentElfClass;
-
-// Extract an element from one of the ELF tables, cast it to desired type.
-// This is just a simple arithmetic and a glorified cast.
-// Callers are responsible for bounds checking.
-template <class T>
-const T* GetTableElement(const ElfW(Ehdr) *ehdr,
-                         ElfW(Off) table_offset,
-                         ElfW(Word) element_size,
-                         size_t index) {
-  return reinterpret_cast<const T*>(reinterpret_cast<const char *>(ehdr)
-                                    + table_offset
-                                    + index * element_size);
-}
-}  // namespace
-
-const void *const ElfMemImage::kInvalidBase =
-    reinterpret_cast<const void *>(~0L);
-
-ElfMemImage::ElfMemImage(const void *base) {
-  CHECK(base != kInvalidBase);
-  Init(base);
-}
-
-int ElfMemImage::GetNumSymbols() const {
-  if (!hash_) {
-    return 0;
-  }
-  // See http://www.caldera.com/developers/gabi/latest/ch5.dynamic.html#hash
-  return hash_[1];
-}
-
-const ElfW(Sym) *ElfMemImage::GetDynsym(int index) const {
-  CHECK_LT(index, GetNumSymbols());
-  return dynsym_ + index;
-}
-
-const ElfW(Versym) *ElfMemImage::GetVersym(int index) const {
-  CHECK_LT(index, GetNumSymbols());
-  return versym_ + index;
-}
-
-const ElfW(Phdr) *ElfMemImage::GetPhdr(int index) const {
-  CHECK_LT(index, ehdr_->e_phnum);
-  return GetTableElement<ElfW(Phdr)>(ehdr_,
-                                     ehdr_->e_phoff,
-                                     ehdr_->e_phentsize,
-                                     index);
-}
-
-const char *ElfMemImage::GetDynstr(ElfW(Word) offset) const {
-  CHECK_LT(offset, strsize_);
-  return dynstr_ + offset;
-}
-
-const void *ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const {
-  if (sym->st_shndx == SHN_UNDEF || sym->st_shndx >= SHN_LORESERVE) {
-    // Symbol corresponds to "special" (e.g. SHN_ABS) section.
-    return reinterpret_cast<const void *>(sym->st_value);
-  }
-  CHECK_LT(link_base_, sym->st_value);
-  return GetTableElement<char>(ehdr_, 0, 1, sym->st_value) - link_base_;
-}
-
-const ElfW(Verdef) *ElfMemImage::GetVerdef(int index) const {
-  CHECK_LE(index, verdefnum_);
-  const ElfW(Verdef) *version_definition = verdef_;
-  while (version_definition->vd_ndx < index && version_definition->vd_next) {
-    const char *const version_definition_as_char =
-        reinterpret_cast<const char *>(version_definition);
-    version_definition =
-        reinterpret_cast<const ElfW(Verdef) *>(version_definition_as_char +
-                                               version_definition->vd_next);
-  }
-  return version_definition->vd_ndx == index ? version_definition : NULL;
-}
-
-const ElfW(Verdaux) *ElfMemImage::GetVerdefAux(
-    const ElfW(Verdef) *verdef) const {
-  return reinterpret_cast<const ElfW(Verdaux) *>(verdef+1);
-}
-
-const char *ElfMemImage::GetVerstr(ElfW(Word) offset) const {
-  CHECK_LT(offset, strsize_);
-  return dynstr_ + offset;
-}
-
-void ElfMemImage::Init(const void *base) {
-  ehdr_      = NULL;
-  dynsym_    = NULL;
-  dynstr_    = NULL;
-  versym_    = NULL;
-  verdef_    = NULL;
-  hash_      = NULL;
-  strsize_   = 0;
-  verdefnum_ = 0;
-  link_base_ = ~0L;  // Sentinel: PT_LOAD .p_vaddr can't possibly be this.
-  if (!base) {
-    return;
-  }
-  const intptr_t base_as_uintptr_t = reinterpret_cast<uintptr_t>(base);
-  // Fake VDSO has low bit set.
-  const bool fake_vdso = ((base_as_uintptr_t & 1) != 0);
-  base = reinterpret_cast<const void *>(base_as_uintptr_t & ~1);
-  const char *const base_as_char = reinterpret_cast<const char *>(base);
-  if (base_as_char[EI_MAG0] != ELFMAG0 || base_as_char[EI_MAG1] != ELFMAG1 ||
-      base_as_char[EI_MAG2] != ELFMAG2 || base_as_char[EI_MAG3] != ELFMAG3) {
-    RAW_DCHECK(false, "no ELF magic"); // at %p", base);
-    return;
-  }
-  int elf_class = base_as_char[EI_CLASS];
-  if (elf_class != CurrentElfClass::kElfClass) {
-    DCHECK_EQ(elf_class, CurrentElfClass::kElfClass);
-    return;
-  }
-  switch (base_as_char[EI_DATA]) {
-    case ELFDATA2LSB: {
-      if (__LITTLE_ENDIAN != __BYTE_ORDER) {
-        DCHECK_EQ(__LITTLE_ENDIAN, __BYTE_ORDER); // << ": wrong byte order";
-        return;
-      }
-      break;
-    }
-    case ELFDATA2MSB: {
-      if (__BIG_ENDIAN != __BYTE_ORDER) {
-        DCHECK_EQ(__BIG_ENDIAN, __BYTE_ORDER); // << ": wrong byte order";
-        return;
-      }
-      break;
-    }
-    default: {
-      RAW_DCHECK(false, "unexpected data encoding"); // << base_as_char[EI_DATA];
-      return;
-    }
-  }
-
-  ehdr_ = reinterpret_cast<const ElfW(Ehdr) *>(base);
-  const ElfW(Phdr) *dynamic_program_header = NULL;
-  for (int i = 0; i < ehdr_->e_phnum; ++i) {
-    const ElfW(Phdr) *const program_header = GetPhdr(i);
-    switch (program_header->p_type) {
-      case PT_LOAD:
-        if (link_base_ == ~0L) {
-          link_base_ = program_header->p_vaddr;
-        }
-        break;
-      case PT_DYNAMIC:
-        dynamic_program_header = program_header;
-        break;
-    }
-  }
-  if (link_base_ == ~0L || !dynamic_program_header) {
-    RAW_DCHECK(~0L != link_base_, "no PT_LOADs in VDSO");
-    RAW_DCHECK(dynamic_program_header, "no PT_DYNAMIC in VDSO");
-    // Mark this image as not present. Can not recur infinitely.
-    Init(0);
-    return;
-  }
-  ptrdiff_t relocation =
-      base_as_char - reinterpret_cast<const char *>(link_base_);
-  ElfW(Dyn) *dynamic_entry =
-      reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr +
-                                    relocation);
-  for (; dynamic_entry->d_tag != DT_NULL; ++dynamic_entry) {
-    ElfW(Xword) value = dynamic_entry->d_un.d_val;
-    if (fake_vdso) {
-      // A complication: in the real VDSO, dynamic entries are not relocated
-      // (it wasn't loaded by a dynamic loader). But when testing with a
-      // "fake" dlopen()ed vdso library, the loader relocates some (but
-      // not all!) of them before we get here.
-      if (dynamic_entry->d_tag == DT_VERDEF) {
-        // The only dynamic entry (of the ones we care about) libc-2.3.6
-        // loader doesn't relocate.
-        value += relocation;
-      }
-    } else {
-      // Real VDSO. Everything needs to be relocated.
-      value += relocation;
-    }
-    switch (dynamic_entry->d_tag) {
-      case DT_HASH:
-        hash_ = reinterpret_cast<ElfW(Word) *>(value);
-        break;
-      case DT_SYMTAB:
-        dynsym_ = reinterpret_cast<ElfW(Sym) *>(value);
-        break;
-      case DT_STRTAB:
-        dynstr_ = reinterpret_cast<const char *>(value);
-        break;
-      case DT_VERSYM:
-        versym_ = reinterpret_cast<ElfW(Versym) *>(value);
-        break;
-      case DT_VERDEF:
-        verdef_ = reinterpret_cast<ElfW(Verdef) *>(value);
-        break;
-      case DT_VERDEFNUM:
-        verdefnum_ = dynamic_entry->d_un.d_val;
-        break;
-      case DT_STRSZ:
-        strsize_ = dynamic_entry->d_un.d_val;
-        break;
-      default:
-        // Unrecognized entries explicitly ignored.
-        break;
-    }
-  }
-  if (!hash_ || !dynsym_ || !dynstr_ || !versym_ ||
-      !verdef_ || !verdefnum_ || !strsize_) {
-    RAW_DCHECK(hash_, "invalid VDSO (no DT_HASH)");
-    RAW_DCHECK(dynsym_, "invalid VDSO (no DT_SYMTAB)");
-    RAW_DCHECK(dynstr_, "invalid VDSO (no DT_STRTAB)");
-    RAW_DCHECK(versym_, "invalid VDSO (no DT_VERSYM)");
-    RAW_DCHECK(verdef_, "invalid VDSO (no DT_VERDEF)");
-    RAW_DCHECK(verdefnum_, "invalid VDSO (no DT_VERDEFNUM)");
-    RAW_DCHECK(strsize_, "invalid VDSO (no DT_STRSZ)");
-    // Mark this image as not present. Can not recur infinitely.
-    Init(0);
-    return;
-  }
-}
-
-bool ElfMemImage::LookupSymbol(const char *name,
-                               const char *version,
-                               int type,
-                               SymbolInfo *info) const {
-  for (SymbolIterator it = begin(); it != end(); ++it) {
-    if (strcmp(it->name, name) == 0 && strcmp(it->version, version) == 0 &&
-        CurrentElfClass::ElfType(it->symbol) == type) {
-      if (info) {
-        *info = *it;
-      }
-      return true;
-    }
-  }
-  return false;
-}
-
-bool ElfMemImage::LookupSymbolByAddress(const void *address,
-                                        SymbolInfo *info_out) const {
-  for (SymbolIterator it = begin(); it != end(); ++it) {
-    const char *const symbol_start =
-        reinterpret_cast<const char *>(it->address);
-    const char *const symbol_end = symbol_start + it->symbol->st_size;
-    if (symbol_start <= address && address < symbol_end) {
-      if (info_out) {
-        // Client wants to know details for that symbol (the usual case).
-        if (CurrentElfClass::ElfBind(it->symbol) == STB_GLOBAL) {
-          // Strong symbol; just return it.
-          *info_out = *it;
-          return true;
-        } else {
-          // Weak or local. Record it, but keep looking for a strong one.
-          *info_out = *it;
-        }
-      } else {
-        // Client only cares if there is an overlapping symbol.
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-ElfMemImage::SymbolIterator::SymbolIterator(const void *const image, int index)
-    : index_(index), image_(image) {
-}
-
-const ElfMemImage::SymbolInfo *ElfMemImage::SymbolIterator::operator->() const {
-  return &info_;
-}
-
-const ElfMemImage::SymbolInfo& ElfMemImage::SymbolIterator::operator*() const {
-  return info_;
-}
-
-bool ElfMemImage::SymbolIterator::operator==(const SymbolIterator &rhs) const {
-  return this->image_ == rhs.image_ && this->index_ == rhs.index_;
-}
-
-bool ElfMemImage::SymbolIterator::operator!=(const SymbolIterator &rhs) const {
-  return !(*this == rhs);
-}
-
-ElfMemImage::SymbolIterator &ElfMemImage::SymbolIterator::operator++() {
-  this->Update(1);
-  return *this;
-}
-
-ElfMemImage::SymbolIterator ElfMemImage::begin() const {
-  SymbolIterator it(this, 0);
-  it.Update(0);
-  return it;
-}
-
-ElfMemImage::SymbolIterator ElfMemImage::end() const {
-  return SymbolIterator(this, GetNumSymbols());
-}
-
-void ElfMemImage::SymbolIterator::Update(int increment) {
-  const ElfMemImage *image = reinterpret_cast<const ElfMemImage *>(image_);
-  CHECK(image->IsPresent() || increment == 0);
-  if (!image->IsPresent()) {
-    return;
-  }
-  index_ += increment;
-  if (index_ >= image->GetNumSymbols()) {
-    index_ = image->GetNumSymbols();
-    return;
-  }
-  const ElfW(Sym)    *symbol = image->GetDynsym(index_);
-  const ElfW(Versym) *version_symbol = image->GetVersym(index_);
-  CHECK(symbol && version_symbol);
-  const char *const symbol_name = image->GetDynstr(symbol->st_name);
-  const ElfW(Versym) version_index = version_symbol[0] & VERSYM_VERSION;
-  const ElfW(Verdef) *version_definition = NULL;
-  const char *version_name = "";
-  if (symbol->st_shndx == SHN_UNDEF) {
-    // Undefined symbols reference DT_VERNEED, not DT_VERDEF, and
-    // version_index could well be greater than verdefnum_, so calling
-    // GetVerdef(version_index) may trigger assertion.
-  } else {
-    version_definition = image->GetVerdef(version_index);
-  }
-  if (version_definition) {
-    // I am expecting 1 or 2 auxiliary entries: 1 for the version itself,
-    // optional 2nd if the version has a parent.
-    CHECK_LE(1, version_definition->vd_cnt);
-    CHECK_LE(version_definition->vd_cnt, 2);
-    const ElfW(Verdaux) *version_aux = image->GetVerdefAux(version_definition);
-    version_name = image->GetVerstr(version_aux->vda_name);
-  }
-  info_.name    = symbol_name;
-  info_.version = version_name;
-  info_.address = image->GetSymAddr(symbol);
-  info_.symbol  = symbol;
-}
-
-}  // namespace base
-
-#endif  // HAVE_ELF_MEM_IMAGE
diff --git a/third_party/tcmalloc/vendor/src/base/elf_mem_image.h b/third_party/tcmalloc/vendor/src/base/elf_mem_image.h
deleted file mode 100644
index 5fb00ff..0000000
--- a/third_party/tcmalloc/vendor/src/base/elf_mem_image.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Pluzhnikov
-//
-// Allow dynamic symbol lookup for in-memory Elf images.
-
-#ifndef BASE_ELF_MEM_IMAGE_H_
-#define BASE_ELF_MEM_IMAGE_H_
-
-#include <config.h>
-#ifdef HAVE_FEATURES_H
-#include <features.h>   // for __GLIBC__
-#endif
-
-// Maybe one day we can rewrite this file not to require the elf
-// symbol extensions in glibc, but for right now we need them.
-#if defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__)
-
-#define HAVE_ELF_MEM_IMAGE 1
-
-#include <stdlib.h>
-#include <link.h>  // for ElfW
-
-namespace base {
-
-// An in-memory ELF image (may not exist on disk).
-class ElfMemImage {
- public:
-  // Sentinel: there could never be an elf image at this address.
-  static const void *const kInvalidBase;
-
-  // Information about a single vdso symbol.
-  // All pointers are into .dynsym, .dynstr, or .text of the VDSO.
-  // Do not free() them or modify through them.
-  struct SymbolInfo {
-    const char      *name;      // E.g. "__vdso_getcpu"
-    const char      *version;   // E.g. "LINUX_2.6", could be ""
-                                // for unversioned symbol.
-    const void      *address;   // Relocated symbol address.
-    const ElfW(Sym) *symbol;    // Symbol in the dynamic symbol table.
-  };
-
-  // Supports iteration over all dynamic symbols.
-  class SymbolIterator {
-   public:
-    friend class ElfMemImage;
-    const SymbolInfo *operator->() const;
-    const SymbolInfo &operator*() const;
-    SymbolIterator& operator++();
-    bool operator!=(const SymbolIterator &rhs) const;
-    bool operator==(const SymbolIterator &rhs) const;
-   private:
-    SymbolIterator(const void *const image, int index);
-    void Update(int incr);
-    SymbolInfo info_;
-    int index_;
-    const void *const image_;
-  };
-
-
-  explicit ElfMemImage(const void *base);
-  void                 Init(const void *base);
-  bool                 IsPresent() const { return ehdr_ != NULL; }
-  const ElfW(Phdr)*    GetPhdr(int index) const;
-  const ElfW(Sym)*     GetDynsym(int index) const;
-  const ElfW(Versym)*  GetVersym(int index) const;
-  const ElfW(Verdef)*  GetVerdef(int index) const;
-  const ElfW(Verdaux)* GetVerdefAux(const ElfW(Verdef) *verdef) const;
-  const char*          GetDynstr(ElfW(Word) offset) const;
-  const void*          GetSymAddr(const ElfW(Sym) *sym) const;
-  const char*          GetVerstr(ElfW(Word) offset) const;
-  int                  GetNumSymbols() const;
-
-  SymbolIterator begin() const;
-  SymbolIterator end() const;
-
-  // Look up versioned dynamic symbol in the image.
-  // Returns false if image is not present, or doesn't contain given
-  // symbol/version/type combination.
-  // If info_out != NULL, additional details are filled in.
-  bool LookupSymbol(const char *name, const char *version,
-                    int symbol_type, SymbolInfo *info_out) const;
-
-  // Find info about symbol (if any) which overlaps given address.
-  // Returns true if symbol was found; false if image isn't present
-  // or doesn't have a symbol overlapping given address.
-  // If info_out != NULL, additional details are filled in.
-  bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const;
-
- private:
-  const ElfW(Ehdr) *ehdr_;
-  const ElfW(Sym) *dynsym_;
-  const ElfW(Versym) *versym_;
-  const ElfW(Verdef) *verdef_;
-  const ElfW(Word) *hash_;
-  const char *dynstr_;
-  size_t strsize_;
-  size_t verdefnum_;
-  ElfW(Addr) link_base_;     // Link-time base (p_vaddr of first PT_LOAD).
-};
-
-}  // namespace base
-
-#endif  // __ELF__ and __GLIBC__ and !__native_client__
-
-#endif  // BASE_ELF_MEM_IMAGE_H_
diff --git a/third_party/tcmalloc/vendor/src/base/elfcore.h b/third_party/tcmalloc/vendor/src/base/elfcore.h
deleted file mode 100644
index 8193d422..0000000
--- a/third_party/tcmalloc/vendor/src/base/elfcore.h
+++ /dev/null
@@ -1,401 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005-2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke, Carl Crous
- */
-
-#ifndef _ELFCORE_H
-#define _ELFCORE_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* We currently only support x86-32, x86-64, ARM, MIPS, PPC on Linux.
- * Porting to other related platforms should not be difficult.
- */
-#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
-     defined(__mips__) || defined(__PPC__)) && defined(__linux)
-
-#include <stdarg.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <config.h>
-
-
-/* Define the DUMPER symbol to make sure that there is exactly one
- * core dumper built into the library.
- */
-#define DUMPER "ELF"
-
-/* By the time that we get a chance to read CPU registers in the
- * calling thread, they are already in a not particularly useful
- * state. Besides, there will be multiple frames on the stack that are
- * just making the core file confusing. To fix this problem, we take a
- * snapshot of the frame pointer, stack pointer, and instruction
- * pointer at an earlier time, and then insert these values into the
- * core file.
- */
-
-#if defined(__i386__) || defined(__x86_64__)
-  typedef struct i386_regs {    /* Normal (non-FPU) CPU registers            */
-  #ifdef __x86_64__
-    #define BP rbp
-    #define SP rsp
-    #define IP rip
-    uint64_t  r15,r14,r13,r12,rbp,rbx,r11,r10;
-    uint64_t  r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax;
-    uint64_t  rip,cs,eflags;
-    uint64_t  rsp,ss;
-    uint64_t  fs_base, gs_base;
-    uint64_t  ds,es,fs,gs;
-  #else
-    #define BP ebp
-    #define SP esp
-    #define IP eip
-    uint32_t  ebx, ecx, edx, esi, edi, ebp, eax;
-    uint16_t  ds, __ds, es, __es;
-    uint16_t  fs, __fs, gs, __gs;
-    uint32_t  orig_eax, eip;
-    uint16_t  cs, __cs;
-    uint32_t  eflags, esp;
-    uint16_t  ss, __ss;
-  #endif
-  } i386_regs;
-#elif defined(__arm__)
-  typedef struct arm_regs {     /* General purpose registers                 */
-    #define BP uregs[11]        /* Frame pointer                             */
-    #define SP uregs[13]        /* Stack pointer                             */
-    #define IP uregs[15]        /* Program counter                           */
-    #define LR uregs[14]        /* Link register                             */
-    long uregs[18];
-  } arm_regs;
-#elif defined(__mips__)
-  typedef struct mips_regs {
-    unsigned long pad[6];       /* Unused padding to match kernel structures */
-    unsigned long uregs[32];    /* General purpose registers.                */
-    unsigned long hi;           /* Used for multiplication and division.     */
-    unsigned long lo;
-    unsigned long cp0_epc;      /* Program counter.                          */
-    unsigned long cp0_badvaddr;
-    unsigned long cp0_status;
-    unsigned long cp0_cause;
-    unsigned long unused;
-  } mips_regs;
-#elif defined (__PPC__)
-  typedef struct ppc_regs {
-    #define SP uregs[1]         /* Stack pointer                             */
-    #define IP rip              /* Program counter                           */
-    #define LR lr               /* Link register                             */
-    unsigned long uregs[32];	/* General Purpose Registers - r0-r31.       */
-    double        fpr[32];	/* Floating-Point Registers - f0-f31.        */
-    unsigned long rip;		/* Program counter.                          */
-    unsigned long msr;
-    unsigned long ccr;
-    unsigned long lr;
-    unsigned long ctr;
-    unsigned long xeq;
-    unsigned long mq;
-  } ppc_regs;
-#endif
-
-#if defined(__i386__) && defined(__GNUC__)
-  /* On x86 we provide an optimized version of the FRAME() macro, if the
-   * compiler supports a GCC-style asm() directive. This results in somewhat
-   * more accurate values for CPU registers.
-   */
-  typedef struct Frame {
-    struct i386_regs uregs;
-    int              errno_;
-    pid_t            tid;
-  } Frame;
-  #define FRAME(f) Frame f;                                           \
-                   do {                                               \
-                     f.errno_ = errno;                                \
-                     f.tid    = sys_gettid();                         \
-                     __asm__ volatile (                               \
-                       "push %%ebp\n"                                 \
-                       "push %%ebx\n"                                 \
-                       "mov  %%ebx,0(%%eax)\n"                        \
-                       "mov  %%ecx,4(%%eax)\n"                        \
-                       "mov  %%edx,8(%%eax)\n"                        \
-                       "mov  %%esi,12(%%eax)\n"                       \
-                       "mov  %%edi,16(%%eax)\n"                       \
-                       "mov  %%ebp,20(%%eax)\n"                       \
-                       "mov  %%eax,24(%%eax)\n"                       \
-                       "mov  %%ds,%%ebx\n"                            \
-                       "mov  %%ebx,28(%%eax)\n"                       \
-                       "mov  %%es,%%ebx\n"                            \
-                       "mov  %%ebx,32(%%eax)\n"                       \
-                       "mov  %%fs,%%ebx\n"                            \
-                       "mov  %%ebx,36(%%eax)\n"                       \
-                       "mov  %%gs,%%ebx\n"                            \
-                       "mov  %%ebx, 40(%%eax)\n"                      \
-                       "call 0f\n"                                    \
-                     "0:pop %%ebx\n"                                  \
-                       "add  $1f-0b,%%ebx\n"                          \
-                       "mov  %%ebx,48(%%eax)\n"                       \
-                       "mov  %%cs,%%ebx\n"                            \
-                       "mov  %%ebx,52(%%eax)\n"                       \
-                       "pushf\n"                                      \
-                       "pop  %%ebx\n"                                 \
-                       "mov  %%ebx,56(%%eax)\n"                       \
-                       "mov  %%esp,%%ebx\n"                           \
-                       "add  $8,%%ebx\n"                              \
-                       "mov  %%ebx,60(%%eax)\n"                       \
-                       "mov  %%ss,%%ebx\n"                            \
-                       "mov  %%ebx,64(%%eax)\n"                       \
-                       "pop  %%ebx\n"                                 \
-                       "pop  %%ebp\n"                                 \
-                     "1:"                                             \
-                       : : "a" (&f) : "memory");                      \
-                     } while (0)
-  #define SET_FRAME(f,r)                                              \
-                     do {                                             \
-                       errno = (f).errno_;                            \
-                       (r)   = (f).uregs;                             \
-                     } while (0)
-#elif defined(__x86_64__) && defined(__GNUC__)
-  /* The FRAME and SET_FRAME macros for x86_64.  */
-  typedef struct Frame {
-    struct i386_regs uregs;
-    int              errno_;
-    pid_t            tid;
-  } Frame;
-  #define FRAME(f) Frame f;                                           \
-                   do {                                               \
-                     f.errno_ = errno;                                \
-                     f.tid    = sys_gettid();                         \
-                     __asm__ volatile (                               \
-                       "push %%rbp\n"                                 \
-                       "push %%rbx\n"                                 \
-                       "mov  %%r15,0(%%rax)\n"                        \
-                       "mov  %%r14,8(%%rax)\n"                        \
-                       "mov  %%r13,16(%%rax)\n"                       \
-                       "mov  %%r12,24(%%rax)\n"                       \
-                       "mov  %%rbp,32(%%rax)\n"                       \
-                       "mov  %%rbx,40(%%rax)\n"                       \
-                       "mov  %%r11,48(%%rax)\n"                       \
-                       "mov  %%r10,56(%%rax)\n"                       \
-                       "mov  %%r9,64(%%rax)\n"                        \
-                       "mov  %%r8,72(%%rax)\n"                        \
-                       "mov  %%rax,80(%%rax)\n"                       \
-                       "mov  %%rcx,88(%%rax)\n"                       \
-                       "mov  %%rdx,96(%%rax)\n"                       \
-                       "mov  %%rsi,104(%%rax)\n"                      \
-                       "mov  %%rdi,112(%%rax)\n"                      \
-                       "mov  %%ds,%%rbx\n"                            \
-                       "mov  %%rbx,184(%%rax)\n"                      \
-                       "mov  %%es,%%rbx\n"                            \
-                       "mov  %%rbx,192(%%rax)\n"                      \
-                       "mov  %%fs,%%rbx\n"                            \
-                       "mov  %%rbx,200(%%rax)\n"                      \
-                       "mov  %%gs,%%rbx\n"                            \
-                       "mov  %%rbx,208(%%rax)\n"                      \
-                       "call 0f\n"                                    \
-                     "0:pop %%rbx\n"                                  \
-                       "add  $1f-0b,%%rbx\n"                          \
-                       "mov  %%rbx,128(%%rax)\n"                      \
-                       "mov  %%cs,%%rbx\n"                            \
-                       "mov  %%rbx,136(%%rax)\n"                      \
-                       "pushf\n"                                      \
-                       "pop  %%rbx\n"                                 \
-                       "mov  %%rbx,144(%%rax)\n"                      \
-                       "mov  %%rsp,%%rbx\n"                           \
-                       "add  $16,%%ebx\n"                             \
-                       "mov  %%rbx,152(%%rax)\n"                      \
-                       "mov  %%ss,%%rbx\n"                            \
-                       "mov  %%rbx,160(%%rax)\n"                      \
-                       "pop  %%rbx\n"                                 \
-                       "pop  %%rbp\n"                                 \
-                     "1:"                                             \
-                       : : "a" (&f) : "memory");                      \
-                     } while (0)
-  #define SET_FRAME(f,r)                                              \
-                     do {                                             \
-                       errno = (f).errno_;                            \
-                       (f).uregs.fs_base = (r).fs_base;               \
-                       (f).uregs.gs_base = (r).gs_base;               \
-                       (r)   = (f).uregs;                             \
-                     } while (0)
-#elif defined(__arm__) && defined(__GNUC__)
-  /* ARM calling conventions are a little more tricky. A little assembly
-   * helps in obtaining an accurate snapshot of all registers.
-   */
-  typedef struct Frame {
-    struct arm_regs arm;
-    int             errno_;
-    pid_t           tid;
-  } Frame;
-  #define FRAME(f) Frame f;                                           \
-                   do {                                               \
-                     long cpsr;                                       \
-                     f.errno_ = errno;                                \
-                     f.tid    = sys_gettid();                         \
-                     __asm__ volatile(                                \
-                       "stmia %0, {r0-r15}\n" /* All integer regs   */\
-                       : : "r"(&f.arm) : "memory");                   \
-                     f.arm.uregs[16] = 0;                             \
-                     __asm__ volatile(                                \
-                       "mrs %0, cpsr\n"       /* Condition code reg */\
-                       : "=r"(cpsr));                                 \
-                     f.arm.uregs[17] = cpsr;                          \
-                   } while (0)
-  #define SET_FRAME(f,r)                                              \
-                     do {                                             \
-                       /* Don't override the FPU status register.   */\
-                       /* Use the value obtained from ptrace(). This*/\
-                       /* works, because our code does not perform  */\
-                       /* any FPU operations, itself.               */\
-                       long fps      = (f).arm.uregs[16];             \
-                       errno         = (f).errno_;                    \
-                       (r)           = (f).arm;                       \
-                       (r).uregs[16] = fps;                           \
-                     } while (0)
-#elif defined(__mips__) && defined(__GNUC__)
-  typedef struct Frame {
-    struct mips_regs mips_regs;
-    int              errno_;
-    pid_t            tid;
-  } Frame;
-  #define MIPSREG(n) ({ register unsigned long r __asm__("$"#n); r; })
-  #define FRAME(f) Frame f = { 0 };                                   \
-                   do {                                               \
-                     unsigned long hi, lo;                            \
-                     register unsigned long pc __asm__("$31");        \
-                     f.mips_regs.uregs[ 0] = MIPSREG( 0);             \
-                     f.mips_regs.uregs[ 1] = MIPSREG( 1);             \
-                     f.mips_regs.uregs[ 2] = MIPSREG( 2);             \
-                     f.mips_regs.uregs[ 3] = MIPSREG( 3);             \
-                     f.mips_regs.uregs[ 4] = MIPSREG( 4);             \
-                     f.mips_regs.uregs[ 5] = MIPSREG( 5);             \
-                     f.mips_regs.uregs[ 6] = MIPSREG( 6);             \
-                     f.mips_regs.uregs[ 7] = MIPSREG( 7);             \
-                     f.mips_regs.uregs[ 8] = MIPSREG( 8);             \
-                     f.mips_regs.uregs[ 9] = MIPSREG( 9);             \
-                     f.mips_regs.uregs[10] = MIPSREG(10);             \
-                     f.mips_regs.uregs[11] = MIPSREG(11);             \
-                     f.mips_regs.uregs[12] = MIPSREG(12);             \
-                     f.mips_regs.uregs[13] = MIPSREG(13);             \
-                     f.mips_regs.uregs[14] = MIPSREG(14);             \
-                     f.mips_regs.uregs[15] = MIPSREG(15);             \
-                     f.mips_regs.uregs[16] = MIPSREG(16);             \
-                     f.mips_regs.uregs[17] = MIPSREG(17);             \
-                     f.mips_regs.uregs[18] = MIPSREG(18);             \
-                     f.mips_regs.uregs[19] = MIPSREG(19);             \
-                     f.mips_regs.uregs[20] = MIPSREG(20);             \
-                     f.mips_regs.uregs[21] = MIPSREG(21);             \
-                     f.mips_regs.uregs[22] = MIPSREG(22);             \
-                     f.mips_regs.uregs[23] = MIPSREG(23);             \
-                     f.mips_regs.uregs[24] = MIPSREG(24);             \
-                     f.mips_regs.uregs[25] = MIPSREG(25);             \
-                     f.mips_regs.uregs[26] = MIPSREG(26);             \
-                     f.mips_regs.uregs[27] = MIPSREG(27);             \
-                     f.mips_regs.uregs[28] = MIPSREG(28);             \
-                     f.mips_regs.uregs[29] = MIPSREG(29);             \
-                     f.mips_regs.uregs[30] = MIPSREG(30);             \
-                     f.mips_regs.uregs[31] = MIPSREG(31);             \
-                     __asm__ volatile ("mfhi %0" : "=r"(hi));         \
-                     __asm__ volatile ("mflo %0" : "=r"(lo));         \
-                     __asm__ volatile ("jal 1f; 1:nop" : "=r"(pc));   \
-                     f.mips_regs.hi       = hi;                       \
-                     f.mips_regs.lo       = lo;                       \
-                     f.mips_regs.cp0_epc  = pc;                       \
-                     f.errno_             = errno;                    \
-                     f.tid                = sys_gettid();             \
-                   } while (0)
-  #define SET_FRAME(f,r)                                              \
-                   do {                                               \
-                     errno       = (f).errno_;                        \
-                     memcpy((r).uregs, (f).mips_regs.uregs,           \
-                            32*sizeof(unsigned long));                \
-                     (r).hi      = (f).mips_regs.hi;                  \
-                     (r).lo      = (f).mips_regs.lo;                  \
-                     (r).cp0_epc = (f).mips_regs.cp0_epc;             \
-                   } while (0)
-#else
-  /* If we do not have a hand-optimized assembly version of the FRAME()
-   * macro, we cannot reliably unroll the stack. So, we show a few additional
-   * stack frames for the coredumper.
-   */
-  typedef struct Frame {
-    pid_t tid;
-  } Frame;
-  #define FRAME(f) Frame f; do { f.tid = sys_gettid(); } while (0)
-  #define SET_FRAME(f,r) do { } while (0)
-#endif
-
-
-/* Internal function for generating a core file. This API can change without
- * notice and is only supposed to be used internally by the core dumper.
- *
- * This function works for both single- and multi-threaded core
- * dumps. If called as
- *
- *   FRAME(frame);
- *   InternalGetCoreDump(&frame, 0, NULL, ap);
- *
- * it creates a core file that only contains information about the
- * calling thread.
- *
- * Optionally, the caller can provide information about other threads
- * by passing their process ids in "thread_pids". The process id of
- * the caller should not be included in this array. All of the threads
- * must have been attached to with ptrace(), prior to calling this
- * function. They will be detached when "InternalGetCoreDump()" returns.
- *
- * This function either returns a file handle that can be read for obtaining
- * a core dump, or "-1" in case of an error. In the latter case, "errno"
- * will be set appropriately.
- *
- * While "InternalGetCoreDump()" is not technically async signal safe, you
- * might be tempted to invoke it from a signal handler. The code goes to
- * great lengths to make a best effort that this will actually work. But in
- * any case, you must make sure that you preserve the value of "errno"
- * yourself. It is guaranteed to be clobbered otherwise.
- *
- * Also, "InternalGetCoreDump" is not strictly speaking re-entrant. Again,
- * it makes a best effort to behave reasonably when called in a multi-
- * threaded environment, but it is ultimately the caller's responsibility
- * to provide locking.
- */
-int InternalGetCoreDump(void *frame, int num_threads, pid_t *thread_pids,
-                        va_list ap
-                     /* const struct CoreDumpParameters *params,
-                        const char *file_name,
-                        const char *PATH
-                      */);
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _ELFCORE_H */
diff --git a/third_party/tcmalloc/vendor/src/base/googleinit.h b/third_party/tcmalloc/vendor/src/base/googleinit.h
deleted file mode 100644
index 3ea411a3..0000000
--- a/third_party/tcmalloc/vendor/src/base/googleinit.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Jacob Hoffman-Andrews
-
-#ifndef _GOOGLEINIT_H
-#define _GOOGLEINIT_H
-
-#include "base/logging.h"
-
-class GoogleInitializer {
- public:
-  typedef void (*VoidFunction)(void);
-  GoogleInitializer(const char* name, VoidFunction ctor, VoidFunction dtor)
-      : name_(name), destructor_(dtor) {
-    RAW_VLOG(10, "<GoogleModuleObject> constructing: %s\n", name_);
-    if (ctor)
-      ctor();
-  }
-  ~GoogleInitializer() {
-    RAW_VLOG(10, "<GoogleModuleObject> destroying: %s\n", name_);
-    if (destructor_)
-      destructor_();
-  }
-
- private:
-  const char* const name_;
-  const VoidFunction destructor_;
-};
-
-#define REGISTER_MODULE_INITIALIZER(name, body)                 \
-  namespace {                                                   \
-    static void google_init_module_##name () { body; }          \
-    GoogleInitializer google_initializer_module_##name(#name,   \
-            google_init_module_##name, NULL);                   \
-  }
-
-#define REGISTER_MODULE_DESTRUCTOR(name, body)                  \
-  namespace {                                                   \
-    static void google_destruct_module_##name () { body; }      \
-    GoogleInitializer google_destructor_module_##name(#name,    \
-            NULL, google_destruct_module_##name);               \
-  }
-
-
-#endif /* _GOOGLEINIT_H */
diff --git a/third_party/tcmalloc/vendor/src/base/linux_syscall_support.h b/third_party/tcmalloc/vendor/src/base/linux_syscall_support.h
deleted file mode 100644
index 13aa415e..0000000
--- a/third_party/tcmalloc/vendor/src/base/linux_syscall_support.h
+++ /dev/null
@@ -1,2913 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005-2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-/* This file includes Linux-specific support functions common to the
- * coredumper and the thread lister; primarily, this is a collection
- * of direct system calls, and a couple of symbols missing from
- * standard header files.
- * There are a few options that the including file can set to control
- * the behavior of this file:
- *
- * SYS_CPLUSPLUS:
- *   The entire header file will normally be wrapped in 'extern "C" { }",
- *   making it suitable for compilation as both C and C++ source. If you
- *   do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit
- *   the wrapping. N.B. doing so will suppress inclusion of all prerequisite
- *   system header files, too. It is the caller's responsibility to provide
- *   the necessary definitions.
- *
- * SYS_ERRNO:
- *   All system calls will update "errno" unless overriden by setting the
- *   SYS_ERRNO macro prior to including this file. SYS_ERRNO should be
- *   an l-value.
- *
- * SYS_INLINE:
- *   New symbols will be defined "static inline", unless overridden by
- *   the SYS_INLINE macro.
- *
- * SYS_LINUX_SYSCALL_SUPPORT_H
- *   This macro is used to avoid multiple inclusions of this header file.
- *   If you need to include this file more than once, make sure to
- *   unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.
- *
- * SYS_PREFIX:
- *   New system calls will have a prefix of "sys_" unless overridden by
- *   the SYS_PREFIX macro. Valid values for this macro are [0..9] which
- *   results in prefixes "sys[0..9]_". It is also possible to set this
- *   macro to -1, which avoids all prefixes.
- *
- * This file defines a few internal symbols that all start with "LSS_".
- * Do not access these symbols from outside this file. They are not part
- * of the supported API.
- *
- * NOTE: This is a stripped down version of the official opensource
- * version of linux_syscall_support.h, which lives at
- *    http://code.google.com/p/linux-syscall-support/
- * It includes only the syscalls that are used in perftools, plus a
- * few extra.  Here's the breakdown:
- * 1) Perftools uses these: grep -rho 'sys_[a-z0-9_A-Z]* *(' src | sort -u
- *      sys__exit(
- *      sys_clone(
- *      sys_close(
- *      sys_fcntl(
- *      sys_fstat(
- *      sys_futex(
- *      sys_getcpu(
- *      sys_getdents64(
- *      sys_getppid(
- *      sys_gettid(
- *      sys_lseek(
- *      sys_mmap(
- *      sys_mremap(
- *      sys_munmap(
- *      sys_open(
- *      sys_pipe(
- *      sys_prctl(
- *      sys_ptrace(
- *      sys_ptrace_detach(
- *      sys_read(
- *      sys_sched_yield(
- *      sys_sigaction(
- *      sys_sigaltstack(
- *      sys_sigdelset(
- *      sys_sigfillset(
- *      sys_sigprocmask(
- *      sys_socket(
- *      sys_stat(
- *      sys_waitpid(
- * 2) These are used as subroutines of the above:
- *      sys_getpid       -- gettid
- *      sys_kill         -- ptrace_detach
- *      sys_restore      -- sigaction
- *      sys_restore_rt   -- sigaction
- *      sys_socketcall   -- socket
- *      sys_wait4        -- waitpid
- * 3) I left these in even though they're not used.  They either
- * complement the above (write vs read) or are variants (rt_sigaction):
- *      sys_fstat64
- *      sys_llseek
- *      sys_mmap2
- *      sys_openat
- *      sys_getdents
- *      sys_rt_sigaction
- *      sys_rt_sigprocmask
- *      sys_sigaddset
- *      sys_sigemptyset
- *      sys_stat64
- *      sys_write
- */
-#ifndef SYS_LINUX_SYSCALL_SUPPORT_H
-#define SYS_LINUX_SYSCALL_SUPPORT_H
-
-/* We currently only support x86-32, x86-64, ARM, MIPS, PPC/PPC64, Aarch64, s390 and s390x
- * on Linux.
- * Porting to other related platforms should not be difficult.
- */
-#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
-     defined(__mips__) || defined(__PPC__) || \
-     defined(__aarch64__) || defined(__s390__)) \
-  && (defined(__linux))
-
-#ifndef SYS_CPLUSPLUS
-#ifdef __cplusplus
-/* Some system header files in older versions of gcc neglect to properly
- * handle being included from C++. As it appears to be harmless to have
- * multiple nested 'extern "C"' blocks, just add another one here.
- */
-extern "C" {
-#endif
-
-#include <errno.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <syscall.h>
-#include <unistd.h>
-#include <linux/unistd.h>
-#include <endian.h>
-#include <fcntl.h>
-
-#ifdef __mips__
-/* Include definitions of the ABI currently in use.                          */
-#include <sgidefs.h>
-#endif
-
-#endif
-
-/* As glibc often provides subtly incompatible data structures (and implicit
- * wrapper functions that convert them), we provide our own kernel data
- * structures for use by the system calls.
- * These structures have been developed by using Linux 2.6.23 headers for
- * reference. Note though, we do not care about exact API compatibility
- * with the kernel, and in fact the kernel often does not have a single
- * API that works across architectures. Instead, we try to mimic the glibc
- * API where reasonable, and only guarantee ABI compatibility with the
- * kernel headers.
- * Most notably, here are a few changes that were made to the structures
- * defined by kernel headers:
- *
- * - we only define structures, but not symbolic names for kernel data
- *   types. For the latter, we directly use the native C datatype
- *   (i.e. "unsigned" instead of "mode_t").
- * - in a few cases, it is possible to define identical structures for
- *   both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
- *   standardizing on the 64bit version of the data types. In particular,
- *   this means that we use "unsigned" where the 32bit headers say
- *   "unsigned long".
- * - overall, we try to minimize the number of cases where we need to
- *   conditionally define different structures.
- * - the "struct kernel_sigaction" class of structures have been
- *   modified to more closely mimic glibc's API by introducing an
- *   anonymous union for the function pointer.
- * - a small number of field names had to have an underscore appended to
- *   them, because glibc defines a global macro by the same name.
- */
-
-/* include/linux/dirent.h                                                    */
-struct kernel_dirent64 {
-  unsigned long long d_ino;
-  long long          d_off;
-  unsigned short     d_reclen;
-  unsigned char      d_type;
-  char               d_name[256];
-};
-
-/* include/linux/dirent.h                                                    */
-struct kernel_dirent {
-  long               d_ino;
-  long               d_off;
-  unsigned short     d_reclen;
-  char               d_name[256];
-};
-
-/* include/linux/time.h                                                      */
-struct kernel_timespec {
-  long               tv_sec;
-  long               tv_nsec;
-};
-
-/* include/linux/time.h                                                      */
-struct kernel_timeval {
-  long               tv_sec;
-  long               tv_usec;
-};
-
-/* include/linux/resource.h                                                  */
-struct kernel_rusage {
-  struct kernel_timeval ru_utime;
-  struct kernel_timeval ru_stime;
-  long               ru_maxrss;
-  long               ru_ixrss;
-  long               ru_idrss;
-  long               ru_isrss;
-  long               ru_minflt;
-  long               ru_majflt;
-  long               ru_nswap;
-  long               ru_inblock;
-  long               ru_oublock;
-  long               ru_msgsnd;
-  long               ru_msgrcv;
-  long               ru_nsignals;
-  long               ru_nvcsw;
-  long               ru_nivcsw;
-};
-
-#if defined(__i386__) || defined(__arm__) \
-  || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__))
-
-/* include/asm-{arm,i386,mips,ppc}/signal.h                                  */
-struct kernel_old_sigaction {
-  union {
-    void             (*sa_handler_)(int);
-    void             (*sa_sigaction_)(int, siginfo_t *, void *);
-  };
-  unsigned long      sa_mask;
-  unsigned long      sa_flags;
-  void               (*sa_restorer)(void);
-} __attribute__((packed,aligned(4)));
-#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
-  #define kernel_old_sigaction kernel_sigaction
-#elif defined(__aarch64__)
-  // No kernel_old_sigaction defined for arm64.
-#endif
-
-/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
- * exactly match the size of the signal set, even though the API was
- * intended to be extensible. We define our own KERNEL_NSIG to deal with
- * this.
- * Please note that glibc provides signals [1.._NSIG-1], whereas the
- * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
- * actual number of signals is obviously the same, but the constants
- * differ by one.
- */
-#ifdef __mips__
-#define KERNEL_NSIG 128
-#else
-#define KERNEL_NSIG  64
-#endif
-
-/* include/asm-{arm,i386,mips,x86_64}/signal.h                               */
-struct kernel_sigset_t {
-  unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
-                    (8*sizeof(unsigned long))];
-};
-
-/* include/asm-{arm,generic,i386,mips,x86_64,ppc}/signal.h                   */
-struct kernel_sigaction {
-#ifdef __mips__
-  unsigned long      sa_flags;
-  union {
-    void             (*sa_handler_)(int);
-    void             (*sa_sigaction_)(int, siginfo_t *, void *);
-  };
-  struct kernel_sigset_t sa_mask;
-#else
-  union {
-    void             (*sa_handler_)(int);
-    void             (*sa_sigaction_)(int, siginfo_t *, void *);
-  };
-  unsigned long      sa_flags;
-  void               (*sa_restorer)(void);
-  struct kernel_sigset_t sa_mask;
-#endif
-};
-
-/* include/asm-{arm,i386,mips,ppc,s390}/stat.h                               */
-#ifdef __mips__
-#if (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
-struct kernel_stat {
-#else
-struct kernel_stat64 {
-#endif
-  unsigned           st_dev;
-  unsigned           __pad0[3];
-  unsigned long long st_ino;
-  unsigned           st_mode;
-  unsigned           st_nlink;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  unsigned           st_rdev;
-  unsigned           __pad1[3];
-  long long          st_size;
-  unsigned           st_atime_;
-  unsigned           st_atime_nsec_;
-  unsigned           st_mtime_;
-  unsigned           st_mtime_nsec_;
-  unsigned           st_ctime_;
-  unsigned           st_ctime_nsec_;
-  unsigned           st_blksize;
-  unsigned           __pad2;
-  unsigned long long st_blocks;
-};
-#elif defined __PPC__
-struct kernel_stat64 {
-  unsigned long long st_dev;
-  unsigned long long st_ino;
-  unsigned           st_nlink;
-  unsigned           st_mode;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  int                __pad2;
-  unsigned long long st_rdev;
-  long long          st_size;
-  long long          st_blksize;
-  long long          st_blocks;
-  kernel_timespec    st_atim;
-  kernel_timespec    st_mtim;
-  kernel_timespec    st_ctim;
-  unsigned long      __unused4;
-  unsigned long      __unused5;
-  unsigned long      __unused6;
-};
-#else
-struct kernel_stat64 {
-  unsigned long long st_dev;
-  unsigned char      __pad0[4];
-  unsigned           __st_ino;
-  unsigned           st_mode;
-  unsigned           st_nlink;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  unsigned long long st_rdev;
-  unsigned char      __pad3[4];
-  long long          st_size;
-  unsigned           st_blksize;
-  unsigned long long st_blocks;
-  unsigned           st_atime_;
-  unsigned           st_atime_nsec_;
-  unsigned           st_mtime_;
-  unsigned           st_mtime_nsec_;
-  unsigned           st_ctime_;
-  unsigned           st_ctime_nsec_;
-  unsigned long long st_ino;
-};
-#endif
-
-/* include/asm-{arm,generic,i386,mips,x86_64,ppc,s390}/stat.h                     */
-#if defined(__i386__) || defined(__arm__)
-struct kernel_stat {
-  /* The kernel headers suggest that st_dev and st_rdev should be 32bit
-   * quantities encoding 12bit major and 20bit minor numbers in an interleaved
-   * format. In reality, we do not see useful data in the top bits. So,
-   * we'll leave the padding in here, until we find a better solution.
-   */
-  unsigned short     st_dev;
-  short              pad1;
-  unsigned           st_ino;
-  unsigned short     st_mode;
-  unsigned short     st_nlink;
-  unsigned short     st_uid;
-  unsigned short     st_gid;
-  unsigned short     st_rdev;
-  short              pad2;
-  unsigned           st_size;
-  unsigned           st_blksize;
-  unsigned           st_blocks;
-  unsigned           st_atime_;
-  unsigned           st_atime_nsec_;
-  unsigned           st_mtime_;
-  unsigned           st_mtime_nsec_;
-  unsigned           st_ctime_;
-  unsigned           st_ctime_nsec_;
-  unsigned           __unused4;
-  unsigned           __unused5;
-};
-#elif defined(__x86_64__)
-struct kernel_stat {
-  uint64_t           st_dev;
-  uint64_t           st_ino;
-  uint64_t           st_nlink;
-  unsigned           st_mode;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  unsigned           __pad0;
-  uint64_t           st_rdev;
-  int64_t            st_size;
-  int64_t            st_blksize;
-  int64_t            st_blocks;
-  uint64_t           st_atime_;
-  uint64_t           st_atime_nsec_;
-  uint64_t           st_mtime_;
-  uint64_t           st_mtime_nsec_;
-  uint64_t           st_ctime_;
-  uint64_t           st_ctime_nsec_;
-  int64_t            __unused[3];
-};
-#elif defined(__PPC__)
-struct kernel_stat {
-  unsigned long long st_dev;
-  unsigned long      st_ino;
-  unsigned long      st_nlink;
-  unsigned long      st_mode;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  int                __pad2;
-  unsigned long long st_rdev;
-  long               st_size;
-  unsigned long      st_blksize;
-  unsigned long      st_blocks;
-  kernel_timespec    st_atim;
-  kernel_timespec    st_mtim;
-  kernel_timespec    st_ctim;
-  unsigned long      __unused4;
-  unsigned long      __unused5;
-  unsigned long      __unused6;
-};
-#elif defined(__mips__) \
-       && !(_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
-struct kernel_stat {
-  unsigned           st_dev;
-  int                st_pad1[3];
-  unsigned           st_ino;
-  unsigned           st_mode;
-  unsigned           st_nlink;
-  unsigned           st_uid;
-  unsigned           st_gid;
-  unsigned           st_rdev;
-  int                st_pad2[2];
-  long               st_size;
-  int                st_pad3;
-  long               st_atime_;
-  long               st_atime_nsec_;
-  long               st_mtime_;
-  long               st_mtime_nsec_;
-  long               st_ctime_;
-  long               st_ctime_nsec_;
-  int                st_blksize;
-  int                st_blocks;
-  int                st_pad4[14];
-};
-#elif defined(__aarch64__)
-struct kernel_stat {
-  unsigned long      st_dev;
-  unsigned long      st_ino;
-  unsigned int       st_mode;
-  unsigned int       st_nlink;
-  unsigned int       st_uid;
-  unsigned int       st_gid;
-  unsigned long      st_rdev;
-  unsigned long      __pad1;
-  long               st_size;
-  int                st_blksize;
-  int                __pad2;
-  long               st_blocks;
-  long               st_atime_;
-  unsigned long      st_atime_nsec_;
-  long               st_mtime_;
-  unsigned long      st_mtime_nsec_;
-  long               st_ctime_;
-  unsigned long      st_ctime_nsec_;
-  unsigned int       __unused4;
-  unsigned int       __unused5;
-};
-#elif defined(__s390x__)
-struct kernel_stat {
-  unsigned long      st_dev;
-  unsigned long      st_ino;
-  unsigned long      st_nlink;
-  unsigned int       st_mode;
-  unsigned int       st_uid;
-  unsigned int       st_gid;
-  unsigned int       __pad1;
-  unsigned long      st_rdev;
-  unsigned long      st_size;
-  unsigned long      st_atime_;
-  unsigned long      st_atime_nsec_;
-  unsigned long      st_mtime_;
-  unsigned long      st_mtime_nsec_;
-  unsigned long      st_ctime_;
-  unsigned long      st_ctime_nsec_;
-  unsigned long      st_blksize;
-  long               st_blocks;
-  unsigned long      __unused[3];
-};
-#elif defined(__s390__)
-struct kernel_stat {
-  unsigned short     st_dev;
-  unsigned short     __pad1;
-  unsigned long      st_ino;
-  unsigned short     st_mode;
-  unsigned short     st_nlink;
-  unsigned short     st_uid;
-  unsigned short     st_gid;
-  unsigned short     st_rdev;
-  unsigned short     __pad2;
-  unsigned long      st_size;
-  unsigned long      st_blksize;
-  unsigned long      st_blocks;
-  unsigned long      st_atime_;
-  unsigned long      st_atime_nsec_;
-  unsigned long      st_mtime_;
-  unsigned long      st_mtime_nsec_;
-  unsigned long      st_ctime_;
-  unsigned long      st_ctime_nsec_;
-  unsigned long      __unused4;
-  unsigned long      __unused5;
-};
-#endif
-
-
-/* Definitions missing from the standard header files                        */
-#ifndef O_DIRECTORY
-#if defined(__arm__)
-#define O_DIRECTORY             0040000
-#else
-#define O_DIRECTORY             0200000
-#endif
-#endif
-#ifndef PR_GET_DUMPABLE
-#define PR_GET_DUMPABLE         3
-#endif
-#ifndef PR_SET_DUMPABLE
-#define PR_SET_DUMPABLE         4
-#endif
-#ifndef AT_FDCWD
-#define AT_FDCWD                (-100)
-#endif
-#ifndef AT_SYMLINK_NOFOLLOW
-#define AT_SYMLINK_NOFOLLOW     0x100
-#endif
-#ifndef AT_REMOVEDIR
-#define AT_REMOVEDIR            0x200
-#endif
-#ifndef MREMAP_FIXED
-#define MREMAP_FIXED            2
-#endif
-#ifndef SA_RESTORER
-#define SA_RESTORER             0x04000000
-#endif
-
-#if defined(__i386__)
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       174
-#define __NR_rt_sigprocmask     175
-#endif
-#ifndef __NR_stat64
-#define __NR_stat64             195
-#endif
-#ifndef __NR_fstat64
-#define __NR_fstat64            197
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         220
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             224
-#endif
-#ifndef __NR_futex
-#define __NR_futex              240
-#endif
-#ifndef __NR_openat
-#define __NR_openat             295
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             318
-#endif
-/* End of i386 definitions                                                   */
-#elif defined(__arm__)
-#ifndef __syscall
-#if defined(__thumb__) || defined(__ARM_EABI__)
-#define __SYS_REG(name) register long __sysreg __asm__("r6") = __NR_##name;
-#define __SYS_REG_LIST(regs...) [sysreg] "r" (__sysreg) , ##regs
-#define __syscall(name) "swi\t0"
-#define __syscall_safe(name)                     \
-  "push  {r7}\n"                                 \
-  "mov   r7,%[sysreg]\n"                         \
-  __syscall(name)"\n"                            \
-  "pop   {r7}"
-#else
-#define __SYS_REG(name)
-#define __SYS_REG_LIST(regs...) regs
-#define __syscall(name) "swi\t" __sys1(__NR_##name) ""
-#define __syscall_safe(name) __syscall(name)
-#endif
-#endif
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       (__NR_SYSCALL_BASE + 174)
-#define __NR_rt_sigprocmask     (__NR_SYSCALL_BASE + 175)
-#endif
-#ifndef __NR_stat64
-#define __NR_stat64             (__NR_SYSCALL_BASE + 195)
-#endif
-#ifndef __NR_fstat64
-#define __NR_fstat64            (__NR_SYSCALL_BASE + 197)
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         (__NR_SYSCALL_BASE + 217)
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             (__NR_SYSCALL_BASE + 224)
-#endif
-#ifndef __NR_futex
-#define __NR_futex              (__NR_SYSCALL_BASE + 240)
-#endif
-/* End of ARM definitions                                                  */
-#elif defined(__x86_64__)
-#ifndef __NR_gettid
-#define __NR_gettid             186
-#endif
-#ifndef __NR_futex
-#define __NR_futex              202
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         217
-#endif
-#ifndef __NR_openat
-#define __NR_openat             257
-#endif
-/* End of x86-64 definitions                                                 */
-#elif defined(__mips__)
-#if _MIPS_SIM == _MIPS_SIM_ABI32
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       (__NR_Linux + 194)
-#define __NR_rt_sigprocmask     (__NR_Linux + 195)
-#endif
-#ifndef __NR_stat64
-#define __NR_stat64             (__NR_Linux + 213)
-#endif
-#ifndef __NR_fstat64
-#define __NR_fstat64            (__NR_Linux + 215)
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         (__NR_Linux + 219)
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             (__NR_Linux + 222)
-#endif
-#ifndef __NR_futex
-#define __NR_futex              (__NR_Linux + 238)
-#endif
-#ifndef __NR_openat
-#define __NR_openat             (__NR_Linux + 288)
-#endif
-#ifndef __NR_fstatat
-#define __NR_fstatat            (__NR_Linux + 293)
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             (__NR_Linux + 312)
-#endif
-/* End of MIPS (old 32bit API) definitions */
-#elif (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
-#ifndef __NR_gettid
-#define __NR_gettid             (__NR_Linux + 178)
-#endif
-#ifndef __NR_futex
-#define __NR_futex              (__NR_Linux + 194)
-#endif
-#ifndef __NR_openat
-#define __NR_openat             (__NR_Linux + 247)
-#endif
-#ifndef __NR_fstatat
-#define __NR_fstatat            (__NR_Linux + 252)
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             (__NR_Linux + 271)
-#endif
-/* End of MIPS (64bit API) definitions */
-#else
-#ifndef __NR_gettid
-#define __NR_gettid             (__NR_Linux + 178)
-#endif
-#ifndef __NR_futex
-#define __NR_futex              (__NR_Linux + 194)
-#endif
-#ifndef __NR_openat
-#define __NR_openat             (__NR_Linux + 251)
-#endif
-#ifndef __NR_fstatat
-#define __NR_fstatat            (__NR_Linux + 256)
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             (__NR_Linux + 275)
-#endif
-/* End of MIPS (new 32bit API) definitions                                   */
-#endif
-/* End of MIPS definitions                                                   */
-#elif defined(__PPC__)
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       173
-#define __NR_rt_sigprocmask     174
-#endif
-#ifndef __NR_stat64
-#define __NR_stat64             195
-#endif
-#ifndef __NR_fstat64
-#define __NR_fstat64            197
-#endif
-#ifndef __NR_socket
-#define __NR_socket             198
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         202
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             207
-#endif
-#ifndef __NR_futex
-#define __NR_futex              221
-#endif
-#ifndef __NR_openat
-#define __NR_openat             286
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             302
-#endif
-/* End of powerpc defininitions                                              */
-#elif defined(__aarch64__)
-#ifndef __NR_fstatat
-#define __NR_fstatat             79
-#endif
-/* End of aarch64 defininitions                                              */
-#elif defined(__s390__)
-#ifndef __NR_quotactl
-#define __NR_quotactl           131
-#endif
-#ifndef __NR_rt_sigreturn
-#define __NR_rt_sigreturn       173
-#endif
-#ifndef __NR_rt_sigaction
-#define __NR_rt_sigaction       174
-#endif
-#ifndef __NR_rt_sigprocmask
-#define __NR_rt_sigprocmask     175
-#endif
-#ifndef __NR_rt_sigpending
-#define __NR_rt_sigpending      176
-#endif
-#ifndef __NR_rt_sigsuspend
-#define __NR_rt_sigsuspend      179
-#endif
-#ifndef __NR_pread64
-#define __NR_pread64            180
-#endif
-#ifndef __NR_pwrite64
-#define __NR_pwrite64           181
-#endif
-#ifndef __NR_getdents64
-#define __NR_getdents64         220
-#endif
-#ifndef __NR_readahead
-#define __NR_readahead          222
-#endif
-#ifndef __NR_setxattr
-#define __NR_setxattr           224
-#endif
-#ifndef __NR_lsetxattr
-#define __NR_lsetxattr          225
-#endif
-#ifndef __NR_getxattr
-#define __NR_getxattr           227
-#endif
-#ifndef __NR_lgetxattr
-#define __NR_lgetxattr          228
-#endif
-#ifndef __NR_listxattr
-#define __NR_listxattr          230
-#endif
-#ifndef __NR_llistxattr
-#define __NR_llistxattr         231
-#endif
-#ifndef __NR_gettid
-#define __NR_gettid             236
-#endif
-#ifndef __NR_tkill
-#define __NR_tkill              237
-#endif
-#ifndef __NR_futex
-#define __NR_futex              238
-#endif
-#ifndef __NR_sched_setaffinity
-#define __NR_sched_setaffinity  239
-#endif
-#ifndef __NR_sched_getaffinity
-#define __NR_sched_getaffinity  240
-#endif
-#ifndef __NR_set_tid_address
-#define __NR_set_tid_address    252
-#endif
-#ifndef __NR_clock_gettime
-#define __NR_clock_gettime      260
-#endif
-#ifndef __NR_clock_getres
-#define __NR_clock_getres       261
-#endif
-#ifndef __NR_statfs64
-#define __NR_statfs64           265
-#endif
-#ifndef __NR_fstatfs64
-#define __NR_fstatfs64          266
-#endif
-#ifndef __NR_ioprio_set
-#define __NR_ioprio_set         282
-#endif
-#ifndef __NR_ioprio_get
-#define __NR_ioprio_get         283
-#endif
-#ifndef __NR_openat
-#define __NR_openat             288
-#endif
-#ifndef __NR_unlinkat
-#define __NR_unlinkat           294
-#endif
-#ifndef __NR_move_pages
-#define __NR_move_pages         310
-#endif
-#ifndef __NR_getcpu
-#define __NR_getcpu             311
-#endif
-#ifndef __NR_fallocate
-#define __NR_fallocate          314
-#endif
-/* Some syscalls are named/numbered differently between s390 and s390x. */
-#ifdef __s390x__
-# ifndef __NR_getrlimit
-# define __NR_getrlimit          191
-# endif
-# ifndef __NR_setresuid
-# define __NR_setresuid          208
-# endif
-# ifndef __NR_getresuid
-# define __NR_getresuid          209
-# endif
-# ifndef __NR_setresgid
-# define __NR_setresgid          210
-# endif
-# ifndef __NR_getresgid
-# define __NR_getresgid          211
-# endif
-# ifndef __NR_setfsuid
-# define __NR_setfsuid           215
-# endif
-# ifndef __NR_setfsgid
-# define __NR_setfsgid           216
-# endif
-# ifndef __NR_fadvise64
-# define __NR_fadvise64          253
-# endif
-# ifndef __NR_newfstatat
-# define __NR_newfstatat         293
-# endif
-#else /* __s390x__ */
-# ifndef __NR_getrlimit
-# define __NR_getrlimit          76
-# endif
-# ifndef __NR_setfsuid
-# define __NR_setfsuid           138
-# endif
-# ifndef __NR_setfsgid
-# define __NR_setfsgid           139
-# endif
-# ifndef __NR_setresuid
-# define __NR_setresuid          164
-# endif
-# ifndef __NR_getresuid
-# define __NR_getresuid          165
-# endif
-# ifndef __NR_setresgid
-# define __NR_setresgid          170
-# endif
-# ifndef __NR_getresgid
-# define __NR_getresgid          171
-# endif
-# ifndef __NR_ugetrlimit
-# define __NR_ugetrlimit         191
-# endif
-# ifndef __NR_mmap2
-# define __NR_mmap2              192
-# endif
-# ifndef __NR_setresuid32
-# define __NR_setresuid32        208
-# endif
-# ifndef __NR_getresuid32
-# define __NR_getresuid32        209
-# endif
-# ifndef __NR_setresgid32
-# define __NR_setresgid32        210
-# endif
-# ifndef __NR_getresgid32
-# define __NR_getresgid32        211
-# endif
-# ifndef __NR_setfsuid32
-# define __NR_setfsuid32         215
-# endif
-# ifndef __NR_setfsgid32
-# define __NR_setfsgid32         216
-# endif
-# ifndef __NR_fadvise64_64
-# define __NR_fadvise64_64       264
-# endif
-# ifndef __NR_fstatat64
-# define __NR_fstatat64          293
-# endif
-#endif /* __s390__ */
-/* End of s390/s390x definitions                                             */
-#endif
-
-
-/* After forking, we must make sure to only call system calls.               */
-#if __BOUNDED_POINTERS__
-  #error "Need to port invocations of syscalls for bounded ptrs"
-#else
-  /* The core dumper and the thread lister get executed after threads
-   * have been suspended. As a consequence, we cannot call any functions
-   * that acquire locks. Unfortunately, libc wraps most system calls
-   * (e.g. in order to implement pthread_atfork, and to make calls
-   * cancellable), which means we cannot call these functions. Instead,
-   * we have to call syscall() directly.
-   */
-  #undef LSS_ERRNO
-  #ifdef SYS_ERRNO
-    /* Allow the including file to override the location of errno. This can
-     * be useful when using clone() with the CLONE_VM option.
-     */
-    #define LSS_ERRNO SYS_ERRNO
-  #else
-    #define LSS_ERRNO errno
-  #endif
-
-  #undef LSS_INLINE
-  #ifdef SYS_INLINE
-    #define LSS_INLINE SYS_INLINE
-  #else
-    #define LSS_INLINE static inline
-  #endif
-
-  /* Allow the including file to override the prefix used for all new
-   * system calls. By default, it will be set to "sys_".
-   */
-  #undef LSS_NAME
-  #ifndef SYS_PREFIX
-    #define LSS_NAME(name) sys_##name
-  #elif SYS_PREFIX < 0
-    #define LSS_NAME(name) name
-  #elif SYS_PREFIX == 0
-    #define LSS_NAME(name) sys0_##name
-  #elif SYS_PREFIX == 1
-    #define LSS_NAME(name) sys1_##name
-  #elif SYS_PREFIX == 2
-    #define LSS_NAME(name) sys2_##name
-  #elif SYS_PREFIX == 3
-    #define LSS_NAME(name) sys3_##name
-  #elif SYS_PREFIX == 4
-    #define LSS_NAME(name) sys4_##name
-  #elif SYS_PREFIX == 5
-    #define LSS_NAME(name) sys5_##name
-  #elif SYS_PREFIX == 6
-    #define LSS_NAME(name) sys6_##name
-  #elif SYS_PREFIX == 7
-    #define LSS_NAME(name) sys7_##name
-  #elif SYS_PREFIX == 8
-    #define LSS_NAME(name) sys8_##name
-  #elif SYS_PREFIX == 9
-    #define LSS_NAME(name) sys9_##name
-  #endif
-
-  #undef  LSS_RETURN
-  #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) ||        \
-       defined(__aarch64__) || defined(__s390__))
-  /* Failing system calls return a negative result in the range of
-   * -1..-4095. These are "errno" values with the sign inverted.
-   */
-  #define LSS_RETURN(type, res)                                               \
-    do {                                                                      \
-      if ((unsigned long)(res) >= (unsigned long)(-4095)) {                   \
-        LSS_ERRNO = -(res);                                                   \
-        res = -1;                                                             \
-      }                                                                       \
-      return (type) (res);                                                    \
-    } while (0)
-  #elif defined(__mips__)
-  /* On MIPS, failing system calls return -1, and set errno in a
-   * separate CPU register.
-   */
-  #define LSS_RETURN(type, res, err)                                          \
-    do {                                                                      \
-      if (err) {                                                              \
-        LSS_ERRNO = (res);                                                    \
-        res = -1;                                                             \
-      }                                                                       \
-      return (type) (res);                                                    \
-    } while (0)
-  #elif defined(__PPC__)
-  /* On PPC, failing system calls return -1, and set errno in a
-   * separate CPU register. See linux/unistd.h.
-   */
-  #define LSS_RETURN(type, res, err)                                          \
-   do {                                                                       \
-     if (err & 0x10000000 ) {                                                 \
-       LSS_ERRNO = (res);                                                     \
-       res = -1;                                                              \
-     }                                                                        \
-     return (type) (res);                                                     \
-   } while (0)
-  #endif
-  #if defined(__i386__)
-    #if defined(NO_FRAME_POINTER) && (100 * __GNUC__ + __GNUC_MINOR__ >= 404)
-      /* This only works for GCC-4.4 and above -- the first version to use
-         .cfi directives for dwarf unwind info.  */
-      #define CFI_ADJUST_CFA_OFFSET(adjust)                                   \
-                  ".cfi_adjust_cfa_offset " #adjust "\n"
-    #else
-      #define CFI_ADJUST_CFA_OFFSET(adjust) /**/
-    #endif
-
-    /* In PIC mode (e.g. when building shared libraries), gcc for i386
-     * reserves ebx. Unfortunately, most distribution ship with implementations
-     * of _syscallX() which clobber ebx.
-     * Also, most definitions of _syscallX() neglect to mark "memory" as being
-     * clobbered. This causes problems with compilers, that do a better job
-     * at optimizing across __asm__ calls.
-     * So, we just have to redefine all of the _syscallX() macros.
-     */
-    #undef  LSS_BODY
-    #define LSS_BODY(type,args...)                                            \
-      long __res;                                                             \
-      __asm__ __volatile__("push %%ebx\n"                                     \
-                           CFI_ADJUST_CFA_OFFSET(4)                           \
-                           "movl %2,%%ebx\n"                                  \
-                           "int $0x80\n"                                      \
-                           "pop %%ebx\n"                                      \
-                           CFI_ADJUST_CFA_OFFSET(-4)                          \
-                           args                                               \
-                           : "esp", "memory");                                \
-      LSS_RETURN(type,__res)
-    #undef  _syscall0
-    #define _syscall0(type,name)                                              \
-      type LSS_NAME(name)(void) {                                             \
-        long __res;                                                           \
-        __asm__ volatile("int $0x80"                                          \
-                         : "=a" (__res)                                       \
-                         : "0" (__NR_##name)                                  \
-                         : "memory");                                         \
-        LSS_RETURN(type,__res);                                               \
-      }
-    #undef  _syscall1
-    #define _syscall1(type,name,type1,arg1)                                   \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        LSS_BODY(type,                                                        \
-             : "=a" (__res)                                                   \
-             : "0" (__NR_##name), "ri" ((long)(arg1)));                       \
-      }
-    #undef  _syscall2
-    #define _syscall2(type,name,type1,arg1,type2,arg2)                        \
-      type LSS_NAME(name)(type1 arg1,type2 arg2) {                            \
-        LSS_BODY(type,                                                        \
-             : "=a" (__res)                                                   \
-             : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2)));    \
-      }
-    #undef  _syscall3
-    #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)             \
-      type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) {                 \
-        LSS_BODY(type,                                                        \
-             : "=a" (__res)                                                   \
-             : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)),    \
-               "d" ((long)(arg3)));                                           \
-      }
-    #undef  _syscall4
-    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_BODY(type,                                                        \
-             : "=a" (__res)                                                   \
-             : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)),    \
-               "d" ((long)(arg3)),"S" ((long)(arg4)));                        \
-      }
-    #undef  _syscall5
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        long __res;                                                           \
-        __asm__ __volatile__("push %%ebx\n"                                   \
-                             "movl %2,%%ebx\n"                                \
-                             "movl %1,%%eax\n"                                \
-                             "int  $0x80\n"                                   \
-                             "pop  %%ebx"                                     \
-                             : "=a" (__res)                                   \
-                             : "i" (__NR_##name), "ri" ((long)(arg1)),        \
-                               "c" ((long)(arg2)), "d" ((long)(arg3)),        \
-                               "S" ((long)(arg4)), "D" ((long)(arg5))         \
-                             : "esp", "memory");                              \
-        LSS_RETURN(type,__res);                                               \
-      }
-    #undef  _syscall6
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        long __res;                                                           \
-        struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 };   \
-        __asm__ __volatile__("push %%ebp\n"                                   \
-                             "push %%ebx\n"                                   \
-                             "movl 4(%2),%%ebp\n"                             \
-                             "movl 0(%2), %%ebx\n"                            \
-                             "movl %1,%%eax\n"                                \
-                             "int  $0x80\n"                                   \
-                             "pop  %%ebx\n"                                   \
-                             "pop  %%ebp"                                     \
-                             : "=a" (__res)                                   \
-                             : "i" (__NR_##name),  "0" ((long)(&__s)),        \
-                               "c" ((long)(arg2)), "d" ((long)(arg3)),        \
-                               "S" ((long)(arg4)), "D" ((long)(arg5))         \
-                             : "esp", "memory");                              \
-        LSS_RETURN(type,__res);                                               \
-      }
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long __res;
-      __asm__ __volatile__(/* if (fn == NULL)
-                            *   return -EINVAL;
-                            */
-                           "movl   %3,%%ecx\n"
-                           "jecxz  1f\n"
-
-                           /* if (child_stack == NULL)
-                            *   return -EINVAL;
-                            */
-                           "movl   %4,%%ecx\n"
-                           "jecxz  1f\n"
-
-                           /* Set up alignment of the child stack:
-                            * child_stack = (child_stack & ~0xF) - 20;
-                            */
-                           "andl   $-16,%%ecx\n"
-                           "subl   $20,%%ecx\n"
-
-                           /* Push "arg" and "fn" onto the stack that will be
-                            * used by the child.
-                            */
-                           "movl   %6,%%eax\n"
-                           "movl   %%eax,4(%%ecx)\n"
-                           "movl   %3,%%eax\n"
-                           "movl   %%eax,(%%ecx)\n"
-
-                           /* %eax = syscall(%eax = __NR_clone,
-                            *                %ebx = flags,
-                            *                %ecx = child_stack,
-                            *                %edx = parent_tidptr,
-                            *                %esi = newtls,
-                            *                %edi = child_tidptr)
-                            * Also, make sure that %ebx gets preserved as it is
-                            * used in PIC mode.
-                            */
-                           "movl   %8,%%esi\n"
-                           "movl   %7,%%edx\n"
-                           "movl   %5,%%eax\n"
-                           "movl   %9,%%edi\n"
-                           "pushl  %%ebx\n"
-                           "movl   %%eax,%%ebx\n"
-                           "movl   %2,%%eax\n"
-                           "int    $0x80\n"
-
-                           /* In the parent: restore %ebx
-                            * In the child:  move "fn" into %ebx
-                            */
-                           "popl   %%ebx\n"
-
-                           /* if (%eax != 0)
-                            *   return %eax;
-                            */
-                           "test   %%eax,%%eax\n"
-                           "jnz    1f\n"
-
-                           /* In the child, now. Terminate frame pointer chain.
-                            */
-                           "movl   $0,%%ebp\n"
-
-                           /* Call "fn". "arg" is already on the stack.
-                            */
-                           "call   *%%ebx\n"
-
-                           /* Call _exit(%ebx). Unfortunately older versions
-                            * of gcc restrict the number of arguments that can
-                            * be passed to asm(). So, we need to hard-code the
-                            * system call number.
-                            */
-                           "movl   %%eax,%%ebx\n"
-                           "movl   $1,%%eax\n"
-                           "int    $0x80\n"
-
-                           /* Return to parent.
-                            */
-                         "1:\n"
-                           : "=a" (__res)
-                           : "0"(-EINVAL), "i"(__NR_clone),
-                             "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
-                             "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
-                           : "esp", "memory", "ecx", "edx", "esi", "edi");
-      LSS_RETURN(int, __res);
-    }
-
-    LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
-      /* On i386, the kernel does not know how to return from a signal
-       * handler. Instead, it relies on user space to provide a
-       * restorer function that calls the {rt_,}sigreturn() system call.
-       * Unfortunately, we cannot just reference the glibc version of this
-       * function, as glibc goes out of its way to make it inaccessible.
-       */
-      void (*res)(void);
-      __asm__ __volatile__("call   2f\n"
-                         "0:.align 16\n"
-                         "1:movl   %1,%%eax\n"
-                           "int    $0x80\n"
-                         "2:popl   %0\n"
-                           "addl   $(1b-0b),%0\n"
-                           : "=a" (res)
-                           : "i"  (__NR_rt_sigreturn));
-      return res;
-    }
-    LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
-      /* On i386, the kernel does not know how to return from a signal
-       * handler. Instead, it relies on user space to provide a
-       * restorer function that calls the {rt_,}sigreturn() system call.
-       * Unfortunately, we cannot just reference the glibc version of this
-       * function, as glibc goes out of its way to make it inaccessible.
-       */
-      void (*res)(void);
-      __asm__ __volatile__("call   2f\n"
-                         "0:.align 16\n"
-                         "1:pop    %%eax\n"
-                           "movl   %1,%%eax\n"
-                           "int    $0x80\n"
-                         "2:popl   %0\n"
-                           "addl   $(1b-0b),%0\n"
-                           : "=a" (res)
-                           : "i"  (__NR_sigreturn));
-      return res;
-    }
-  #elif defined(__x86_64__)
-    /* There are no known problems with any of the _syscallX() macros
-     * currently shipping for x86_64, but we still need to be able to define
-     * our own version so that we can override the location of the errno
-     * location (e.g. when using the clone() system call with the CLONE_VM
-     * option).
-     */
-    #undef  LSS_ENTRYPOINT
-    #define LSS_ENTRYPOINT "syscall\n"
-
-    /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
-     * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
-     * sign extension.  We can't cast pointers directly because those are
-     * 32 bits, and gcc will dump ugly warnings about casting from a pointer
-     * to an integer of a different size.
-     */
-    #undef  LSS_SYSCALL_ARG
-    #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
-    #undef  _LSS_RETURN
-    #define _LSS_RETURN(type, res, cast)                                      \
-      do {                                                                    \
-        if ((uint64_t)(res) >= (uint64_t)(-4095)) {                           \
-          LSS_ERRNO = -(res);                                                 \
-          res = -1;                                                           \
-        }                                                                     \
-        return (type)(cast)(res);                                             \
-      } while (0)
-    #undef  LSS_RETURN
-    #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
-
-    #undef  _LSS_BODY
-    #define _LSS_BODY(nr, type, name, cast, ...)                              \
-          long long __res;                                                    \
-          __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT                \
-            : "=a" (__res)                                                    \
-            : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__)                 \
-            : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory");                   \
-          _LSS_RETURN(type, __res, cast)
-    #undef  LSS_BODY
-    #define LSS_BODY(nr, type, name, args...) \
-      _LSS_BODY(nr, type, name, uintptr_t, ## args)
-
-    #undef  LSS_BODY_ASM0
-    #undef  LSS_BODY_ASM1
-    #undef  LSS_BODY_ASM2
-    #undef  LSS_BODY_ASM3
-    #undef  LSS_BODY_ASM4
-    #undef  LSS_BODY_ASM5
-    #undef  LSS_BODY_ASM6
-    #define LSS_BODY_ASM0
-    #define LSS_BODY_ASM1 LSS_BODY_ASM0
-    #define LSS_BODY_ASM2 LSS_BODY_ASM1
-    #define LSS_BODY_ASM3 LSS_BODY_ASM2
-    #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
-    #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
-    #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
-
-    #undef  LSS_BODY_CLOBBER0
-    #undef  LSS_BODY_CLOBBER1
-    #undef  LSS_BODY_CLOBBER2
-    #undef  LSS_BODY_CLOBBER3
-    #undef  LSS_BODY_CLOBBER4
-    #undef  LSS_BODY_CLOBBER5
-    #undef  LSS_BODY_CLOBBER6
-    #define LSS_BODY_CLOBBER0
-    #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
-    #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
-    #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
-    #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
-    #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
-    #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
-
-    #undef  LSS_BODY_ARG0
-    #undef  LSS_BODY_ARG1
-    #undef  LSS_BODY_ARG2
-    #undef  LSS_BODY_ARG3
-    #undef  LSS_BODY_ARG4
-    #undef  LSS_BODY_ARG5
-    #undef  LSS_BODY_ARG6
-    #define LSS_BODY_ARG0()
-    #define LSS_BODY_ARG1(arg1) \
-      LSS_BODY_ARG0(), "D" (arg1)
-    #define LSS_BODY_ARG2(arg1, arg2) \
-      LSS_BODY_ARG1(arg1), "S" (arg2)
-    #define LSS_BODY_ARG3(arg1, arg2, arg3) \
-      LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
-    #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
-      LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
-    #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
-      LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
-    #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
-      LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
-
-    #undef _syscall0
-    #define _syscall0(type,name)                                              \
-      type LSS_NAME(name)() {                                                 \
-        LSS_BODY(0, type, name);                                              \
-      }
-    #undef _syscall1
-    #define _syscall1(type,name,type1,arg1)                                   \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1));                       \
-      }
-    #undef _syscall2
-    #define _syscall2(type,name,type1,arg1,type2,arg2)                        \
-      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \
-        LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
-      }
-    #undef _syscall3
-    #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \
-        LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
-                                LSS_SYSCALL_ARG(arg3));                       \
-      }
-    #undef _syscall4
-    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
-                                LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
-      }
-    #undef _syscall5
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
-                                LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
-                                LSS_SYSCALL_ARG(arg5));                       \
-      }
-    #undef _syscall6
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
-                                LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
-                                LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
-      }
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long long __res;
-      {
-        __asm__ __volatile__(/* if (fn == NULL)
-                              *   return -EINVAL;
-                              */
-                             "testq  %4,%4\n"
-                             "jz     1f\n"
-
-                             /* if (child_stack == NULL)
-                              *   return -EINVAL;
-                              */
-                             "testq  %5,%5\n"
-                             "jz     1f\n"
-
-                             /* Set up alignment of the child stack:
-                              * child_stack = (child_stack & ~0xF) - 16;
-                              */
-                             "andq   $-16,%5\n"
-                             "subq   $16,%5\n"
-
-                             /* Push "arg" and "fn" onto the stack that will be
-                              * used by the child.
-                              */
-                             "movq   %7,8(%5)\n"
-                             "movq   %4,0(%5)\n"
-
-                             /* %rax = syscall(%rax = __NR_clone,
-                              *                %rdi = flags,
-                              *                %rsi = child_stack,
-                              *                %rdx = parent_tidptr,
-                              *                %r8  = new_tls,
-                              *                %r10 = child_tidptr)
-                              */
-                             "movq   %2,%%rax\n"
-                             "movq   %9,%%r8\n"
-                             "movq   %10,%%r10\n"
-                             "syscall\n"
-
-                             /* if (%rax != 0)
-                              *   return;
-                              */
-                             "testq  %%rax,%%rax\n"
-                             "jnz    1f\n"
-
-                             /* In the child. Terminate frame pointer chain.
-                              */
-                             "xorq   %%rbp,%%rbp\n"
-
-                             /* Call "fn(arg)".
-                              */
-                             "popq   %%rax\n"
-                             "popq   %%rdi\n"
-                             "call   *%%rax\n"
-
-                             /* Call _exit(%ebx).
-                              */
-                             "movq   %%rax,%%rdi\n"
-                             "movq   %3,%%rax\n"
-                             "syscall\n"
-
-                             /* Return to parent.
-                              */
-                           "1:\n"
-                             : "=a" (__res)
-                             : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
-                               "r"(LSS_SYSCALL_ARG(fn)),
-                               "S"(LSS_SYSCALL_ARG(child_stack)),
-                               "D"(LSS_SYSCALL_ARG(flags)),
-                               "r"(LSS_SYSCALL_ARG(arg)),
-                               "d"(LSS_SYSCALL_ARG(parent_tidptr)),
-                               "r"(LSS_SYSCALL_ARG(newtls)),
-                               "r"(LSS_SYSCALL_ARG(child_tidptr))
-                             : "rsp", "memory", "r8", "r10", "r11", "rcx");
-      }
-      LSS_RETURN(int, __res);
-    }
-
-    LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
-      /* On x86-64, the kernel does not know how to return from
-       * a signal handler. Instead, it relies on user space to provide a
-       * restorer function that calls the rt_sigreturn() system call.
-       * Unfortunately, we cannot just reference the glibc version of this
-       * function, as glibc goes out of its way to make it inaccessible.
-       */
-      long long res;
-      __asm__ __volatile__("call   2f\n"
-                         "0:.align 16\n"
-                         "1:movq   %1,%%rax\n"
-                           "syscall\n"
-                         "2:popq   %0\n"
-                           "addq   $(1b-0b),%0\n"
-                           : "=a" (res)
-                           : "i"  (__NR_rt_sigreturn));
-      return (void (*)(void))(uintptr_t)res;
-    }
-  #elif defined(__arm__)
-    /* Most definitions of _syscallX() neglect to mark "memory" as being
-     * clobbered. This causes problems with compilers, that do a better job
-     * at optimizing across __asm__ calls.
-     * So, we just have to redefine all fo the _syscallX() macros.
-     */
-    #undef LSS_REG
-    #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
-
-    /* r0..r3 are scratch registers and not preserved across function
-     * calls.  We need to first evaluate the first 4 syscall arguments
-     * and store them on stack.  They must be loaded into r0..r3 after
-     * all function calls to avoid r0..r3 being clobbered.
-     */
-    #undef LSS_SAVE_ARG
-    #define LSS_SAVE_ARG(r,a) long __tmp##r = (long)a
-    #undef LSS_LOAD_ARG
-    #define LSS_LOAD_ARG(r) register long __r##r __asm__("r"#r) = __tmp##r
-
-    #undef  LSS_BODY
-    #define LSS_BODY(type, name, args...)                                     \
-          register long __res_r0 __asm__("r0");                               \
-          long __res;                                                         \
-          __SYS_REG(name)                                                     \
-          __asm__ __volatile__ (__syscall_safe(name)                          \
-                                : "=r"(__res_r0)                              \
-                                : __SYS_REG_LIST(args)                        \
-                                : "lr", "memory");                            \
-          __res = __res_r0;                                                   \
-          LSS_RETURN(type, __res)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-      type LSS_NAME(name)() {                                                 \
-        LSS_BODY(type, name);                                                 \
-      }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        /* There is no need for using a volatile temp.  */                    \
-        LSS_REG(0, arg1);                                                     \
-        LSS_BODY(type, name, "r"(__r0));                                      \
-      }
-    #undef _syscall2
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1));                           \
-      }
-    #undef _syscall3
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_SAVE_ARG(2, arg3);                                                \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_LOAD_ARG(2);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2));                \
-      }
-    #undef _syscall4
-    #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                      type4, arg4)                                            \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_SAVE_ARG(2, arg3);                                                \
-        LSS_SAVE_ARG(3, arg4);                                                \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_LOAD_ARG(2);                                                      \
-        LSS_LOAD_ARG(3);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3));     \
-      }
-    #undef _syscall5
-    #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                      type4, arg4, type5, arg5)                               \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_SAVE_ARG(2, arg3);                                                \
-        LSS_SAVE_ARG(3, arg4);                                                \
-        LSS_REG(4, arg5);                                                     \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_LOAD_ARG(2);                                                      \
-        LSS_LOAD_ARG(3);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),      \
-                             "r"(__r4));                                      \
-      }
-    #undef _syscall6
-    #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                      type4, arg4, type5, arg5, type6, arg6)                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        LSS_SAVE_ARG(0, arg1);                                                \
-        LSS_SAVE_ARG(1, arg2);                                                \
-        LSS_SAVE_ARG(2, arg3);                                                \
-        LSS_SAVE_ARG(3, arg4);                                                \
-        LSS_REG(4, arg5);                                                     \
-        LSS_REG(5, arg6);                                                     \
-        LSS_LOAD_ARG(0);                                                      \
-        LSS_LOAD_ARG(1);                                                      \
-        LSS_LOAD_ARG(2);                                                      \
-        LSS_LOAD_ARG(3);                                                      \
-        LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),      \
-                             "r"(__r4), "r"(__r5));                           \
-      }
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      register long __res __asm__("r5");
-      {
-        if (fn == NULL || child_stack == NULL) {
-            __res = -EINVAL;
-            goto clone_exit;
-        }
-
-        /* stash first 4 arguments on stack first because we can only load
-         * them after all function calls.
-         */
-        int    tmp_flags = flags;
-        int  * tmp_stack = (int*) child_stack;
-        void * tmp_ptid  = parent_tidptr;
-        void * tmp_tls   = newtls;
-
-        register int  *__ctid  __asm__("r4") = child_tidptr;
-
-        /* Push "arg" and "fn" onto the stack that will be
-         * used by the child.
-         */
-        *(--tmp_stack) = (int) arg;
-        *(--tmp_stack) = (int) fn;
-
-        /* We must load r0..r3 last after all possible function calls.  */
-        register int   __flags __asm__("r0") = tmp_flags;
-        register void *__stack __asm__("r1") = tmp_stack;
-        register void *__ptid  __asm__("r2") = tmp_ptid;
-        register void *__tls   __asm__("r3") = tmp_tls;
-
-        /* %r0 = syscall(%r0 = flags,
-         *               %r1 = child_stack,
-         *               %r2 = parent_tidptr,
-         *               %r3 = newtls,
-         *               %r4 = child_tidptr)
-         */
-        __SYS_REG(clone)
-        __asm__ __volatile__(/* %r0 = syscall(%r0 = flags,
-                              *               %r1 = child_stack,
-                              *               %r2 = parent_tidptr,
-                              *               %r3 = newtls,
-                              *               %r4 = child_tidptr)
-                              */
-                             "push  {r7}\n"
-                             "mov   r7,%1\n"
-                             __syscall(clone)"\n"
-
-                             /* if (%r0 != 0)
-                              *   return %r0;
-                              */
-                             "movs  %0,r0\n"
-                             "bne   1f\n"
-
-                             /* In the child, now. Call "fn(arg)".
-                              */
-                             "ldr   r0,[sp, #4]\n"
-                             "mov   lr,pc\n"
-                             "ldr   pc,[sp]\n"
-
-                             /* Call _exit(%r0), which never returns.  We only
-                              * need to set r7 for EABI syscall ABI but we do
-                              * this always to simplify code sharing between
-                              * old and new syscall ABIs.
-                              */
-                             "mov   r7,%2\n"
-                             __syscall(exit)"\n"
-
-                             /* Pop r7 from the stack only in the parent.
-                              */
-                           "1: pop {r7}\n"
-                             : "=r" (__res)
-                             : "r"(__sysreg),
-                               "i"(__NR_exit), "r"(__stack), "r"(__flags),
-                               "r"(__ptid), "r"(__tls), "r"(__ctid)
-                             : "cc", "lr", "memory");
-      }
-      clone_exit:
-      LSS_RETURN(int, __res);
-    }
-  #elif defined(__mips__)
-    #undef LSS_REG
-    #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) =       \
-                                 (unsigned long)(a)
-
-    #if _MIPS_SIM == _MIPS_SIM_ABI32
-    // See http://sources.redhat.com/ml/libc-alpha/2004-10/msg00050.html
-    // or http://www.linux-mips.org/archives/linux-mips/2004-10/msg00142.html
-    #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12",\
-                                "$13", "$14", "$15", "$24", "$25", "memory"
-    #else
-    #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13",     \
-                                "$14", "$15", "$24", "$25", "memory"
-    #endif
-
-    #undef  LSS_BODY
-    #define LSS_BODY(type,name,r7,...)                                        \
-          register unsigned long __v0 __asm__("$2") = __NR_##name;            \
-          __asm__ __volatile__ ("syscall\n"                                   \
-                                : "=&r"(__v0), r7 (__r7)                      \
-                                : "0"(__v0), ##__VA_ARGS__                    \
-                                : MIPS_SYSCALL_CLOBBERS);                     \
-          LSS_RETURN(type, __v0, __r7)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-      type LSS_NAME(name)() {                                                 \
-        register unsigned long __r7 __asm__("$7");                            \
-        LSS_BODY(type, name, "=r");                                           \
-      }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        register unsigned long __r7 __asm__("$7");                            \
-        LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4));              \
-      }
-    #undef _syscall2
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \
-        register unsigned long __r7 __asm__("$7");                            \
-        LSS_REG(4, arg1); LSS_REG(5, arg2);                                   \
-        LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5));                     \
-      }
-    #undef _syscall3
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \
-        register unsigned long __r7 __asm__("$7");                            \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6));          \
-      }
-    #undef _syscall4
-    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4);                                                     \
-        LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6));          \
-      }
-    #undef _syscall5
-    #if _MIPS_SIM == _MIPS_SIM_ABI32
-    /* The old 32bit MIPS system call API passes the fifth and sixth argument
-     * on the stack, whereas the new APIs use registers "r8" and "r9".
-     */
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4);                                                     \
-        register unsigned long __v0 __asm__("$2");                            \
-        __asm__ __volatile__ (".set noreorder\n"                              \
-                              "lw    $2, %6\n"                                \
-                              "subu  $29, 32\n"                               \
-                              "sw    $2, 16($29)\n"                           \
-                              "li    $2, %2\n"                                \
-                              "syscall\n"                                     \
-                              "addiu $29, 32\n"                               \
-                              ".set reorder\n"                                \
-                              : "=&r"(__v0), "+r" (__r7)                      \
-                              : "i" (__NR_##name), "r"(__r4), "r"(__r5),      \
-                                "r"(__r6), "m" ((unsigned long)arg5)          \
-                              : MIPS_SYSCALL_CLOBBERS);                       \
-        LSS_RETURN(type, __v0, __r7);                                         \
-      }
-    #else
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4); LSS_REG(8, arg5);                                   \
-        LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6),           \
-                 "r"(__r8));                                                  \
-      }
-    #endif
-    #undef _syscall6
-    #if _MIPS_SIM == _MIPS_SIM_ABI32
-    /* The old 32bit MIPS system call API passes the fifth and sixth argument
-     * on the stack, whereas the new APIs use registers "r8" and "r9".
-     */
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4);                                                     \
-        register unsigned long __v0 __asm__("$2");                            \
-        __asm__ __volatile__ (".set noreorder\n"                              \
-                              "lw    $2, %6\n"                                \
-                              "lw    $8, %7\n"                                \
-                              "subu  $29, 32\n"                               \
-                              "sw    $2, 16($29)\n"                           \
-                              "sw    $8, 20($29)\n"                           \
-                              "li    $2, %2\n"                                \
-                              "syscall\n"                                     \
-                              "addiu $29, 32\n"                               \
-                              ".set reorder\n"                                \
-                              : "=&r"(__v0), "+r" (__r7)                      \
-                              : "i" (__NR_##name), "r"(__r4), "r"(__r5),      \
-                                "r"(__r6), "m" ((unsigned long)arg5),         \
-                                "m" ((unsigned long)arg6)                     \
-                              : MIPS_SYSCALL_CLOBBERS);                       \
-        LSS_RETURN(type, __v0, __r7);                                         \
-      }
-    #else
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5,type6 arg6) {                            \
-        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \
-        LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6);                 \
-        LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6),           \
-                 "r"(__r8), "r"(__r9));                                       \
-      }
-    #endif
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      register unsigned long __v0 __asm__("$2");
-      register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
-      {
-        register int   __flags __asm__("$4") = flags;
-        register void *__stack __asm__("$5") = child_stack;
-        register void *__ptid  __asm__("$6") = parent_tidptr;
-        register int  *__ctid  __asm__("$8") = child_tidptr;
-        __asm__ __volatile__(
-          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
-                             "subu  $29,24\n"
-          #elif _MIPS_SIM == _MIPS_SIM_NABI32
-                             "sub   $29,16\n"
-          #else
-                             "dsubu $29,16\n"
-          #endif
-
-                             /* if (fn == NULL || child_stack == NULL)
-                              *   return -EINVAL;
-                              */
-                             "li    %0,%2\n"
-                             "beqz  %5,1f\n"
-                             "beqz  %6,1f\n"
-
-                             /* Push "arg" and "fn" onto the stack that will be
-                              * used by the child.
-                              */
-          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
-                             "subu  %6,32\n"
-                             "sw    %5,0(%6)\n"
-                             "sw    %8,4(%6)\n"
-          #elif _MIPS_SIM == _MIPS_SIM_NABI32
-                             "sub   %6,32\n"
-                             "sw    %5,0(%6)\n"
-                             "sw    %8,8(%6)\n"
-          #else
-                             "dsubu %6,32\n"
-                             "sd    %5,0(%6)\n"
-                             "sd    %8,8(%6)\n"
-          #endif
-
-                             /* $7 = syscall($4 = flags,
-                              *              $5 = child_stack,
-                              *              $6 = parent_tidptr,
-                              *              $7 = newtls,
-                              *              $8 = child_tidptr)
-                              */
-                             "li    $2,%3\n"
-                             "syscall\n"
-
-                             /* if ($7 != 0)
-                              *   return $2;
-                              */
-                             "bnez  $7,1f\n"
-                             "bnez  $2,1f\n"
-
-                             /* In the child, now. Call "fn(arg)".
-                              */
-          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
-                            "lw    $25,0($29)\n"
-                            "lw    $4,4($29)\n"
-          #elif _MIPS_SIM == _MIPS_SIM_NABI32
-                            "lw    $25,0($29)\n"
-                            "lw    $4,8($29)\n"
-          #else
-                            "ld    $25,0($29)\n"
-                            "ld    $4,8($29)\n"
-          #endif
-                            "jalr  $25\n"
-
-                             /* Call _exit($2)
-                              */
-                            "move  $4,$2\n"
-                            "li    $2,%4\n"
-                            "syscall\n"
-
-                           "1:\n"
-          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
-                             "addu  $29, 24\n"
-          #elif _MIPS_SIM == _MIPS_SIM_NABI32
-                             "add   $29, 16\n"
-          #else
-                             "daddu $29,16\n"
-          #endif
-                             : "=&r" (__v0), "=r" (__r7)
-                             : "i"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
-                               "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
-                               "r"(__ptid), "r"(__r7), "r"(__ctid)
-                             : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
-                               "$24", "memory");
-      }
-      LSS_RETURN(int, __v0, __r7);
-    }
-  #elif defined (__PPC__)
-    #undef  LSS_LOADARGS_0
-    #define LSS_LOADARGS_0(name, dummy...)                                    \
-        __sc_0 = __NR_##name
-    #undef  LSS_LOADARGS_1
-    #define LSS_LOADARGS_1(name, arg1)                                        \
-            LSS_LOADARGS_0(name);                                             \
-            __sc_3 = (unsigned long) (arg1)
-    #undef  LSS_LOADARGS_2
-    #define LSS_LOADARGS_2(name, arg1, arg2)                                  \
-            LSS_LOADARGS_1(name, arg1);                                       \
-            __sc_4 = (unsigned long) (arg2)
-    #undef  LSS_LOADARGS_3
-    #define LSS_LOADARGS_3(name, arg1, arg2, arg3)                            \
-            LSS_LOADARGS_2(name, arg1, arg2);                                 \
-            __sc_5 = (unsigned long) (arg3)
-    #undef  LSS_LOADARGS_4
-    #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4)                      \
-            LSS_LOADARGS_3(name, arg1, arg2, arg3);                           \
-            __sc_6 = (unsigned long) (arg4)
-    #undef  LSS_LOADARGS_5
-    #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5)                \
-            LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4);                     \
-            __sc_7 = (unsigned long) (arg5)
-    #undef  LSS_LOADARGS_6
-    #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6)          \
-            LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5);               \
-            __sc_8 = (unsigned long) (arg6)
-    #undef  LSS_ASMINPUT_0
-    #define LSS_ASMINPUT_0 "0" (__sc_0)
-    #undef  LSS_ASMINPUT_1
-    #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
-    #undef  LSS_ASMINPUT_2
-    #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
-    #undef  LSS_ASMINPUT_3
-    #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
-    #undef  LSS_ASMINPUT_4
-    #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
-    #undef  LSS_ASMINPUT_5
-    #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
-    #undef  LSS_ASMINPUT_6
-    #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
-    #undef  LSS_BODY
-    #define LSS_BODY(nr, type, name, args...)                                 \
-        long __sc_ret, __sc_err;                                              \
-        {                                                                     \
-            register unsigned long __sc_0 __asm__ ("r0");                     \
-            register unsigned long __sc_3 __asm__ ("r3");                     \
-            register unsigned long __sc_4 __asm__ ("r4");                     \
-            register unsigned long __sc_5 __asm__ ("r5");                     \
-            register unsigned long __sc_6 __asm__ ("r6");                     \
-            register unsigned long __sc_7 __asm__ ("r7");                     \
-            register unsigned long __sc_8 __asm__ ("r8");                     \
-                                                                              \
-            LSS_LOADARGS_##nr(name, args);                                    \
-            __asm__ __volatile__                                              \
-                ("sc\n\t"                                                     \
-                 "mfcr %0"                                                    \
-                 : "=&r" (__sc_0),                                            \
-                   "=&r" (__sc_3), "=&r" (__sc_4),                            \
-                   "=&r" (__sc_5), "=&r" (__sc_6),                            \
-                   "=&r" (__sc_7), "=&r" (__sc_8)                             \
-                 : LSS_ASMINPUT_##nr                                          \
-                 : "cr0", "ctr", "memory",                                    \
-                   "r9", "r10", "r11", "r12");                                \
-            __sc_ret = __sc_3;                                                \
-            __sc_err = __sc_0;                                                \
-        }                                                                     \
-        LSS_RETURN(type, __sc_ret, __sc_err)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-       type LSS_NAME(name)(void) {                                            \
-          LSS_BODY(0, type, name);                                            \
-       }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-       type LSS_NAME(name)(type1 arg1) {                                      \
-          LSS_BODY(1, type, name, arg1);                                      \
-       }
-    #undef _syscall2
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-       type LSS_NAME(name)(type1 arg1, type2 arg2) {                          \
-          LSS_BODY(2, type, name, arg1, arg2);                                \
-       }
-    #undef _syscall3
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {              \
-          LSS_BODY(3, type, name, arg1, arg2, arg3);                          \
-       }
-    #undef _syscall4
-    #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4)                                \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {  \
-          LSS_BODY(4, type, name, arg1, arg2, arg3, arg4);                    \
-       }
-    #undef _syscall5
-    #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4, type5, arg5)                   \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,    \
-                                               type5 arg5) {                  \
-          LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5);              \
-       }
-    #undef _syscall6
-    #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4, type5, arg5, type6, arg6)      \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,    \
-                                               type5 arg5, type6 arg6) {      \
-          LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6);        \
-       }
-    /* clone function adapted from glibc 2.18 clone.S                       */
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long __ret, __err;
-      {
-#if defined(__PPC64__)
-
-/* Stack frame offsets.  */
-#if _CALL_ELF != 2
-#define FRAME_MIN_SIZE         112
-#define FRAME_TOC_SAVE         40
-#else
-#define FRAME_MIN_SIZE         32
-#define FRAME_TOC_SAVE         24
-#endif
-
-
-        register int (*__fn)(void *) __asm__ ("r3") = fn;
-        register void *__cstack      __asm__ ("r4") = child_stack;
-        register int __flags         __asm__ ("r5") = flags;
-        register void * __arg        __asm__ ("r6") = arg;
-        register int * __ptidptr     __asm__ ("r7") = parent_tidptr;
-        register void * __newtls     __asm__ ("r8") = newtls;
-        register int * __ctidptr     __asm__ ("r9") = child_tidptr;
-        __asm__ __volatile__(
-            /* check for fn == NULL
-             * and child_stack == NULL
-             */
-            "cmpdi cr0, %6, 0\n\t"
-            "cmpdi cr1, %7, 0\n\t"
-            "cror  cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
-            "beq-  cr0, 1f\n\t"
-
-            /* set up stack frame for child                                  */
-            "clrrdi %7, %7, 4\n\t"
-            "li     0, 0\n\t"
-            "stdu   0, -%13(%7)\n\t"
-
-            /* fn, arg, child_stack are saved acrVoss the syscall             */
-            "mr 28, %6\n\t"
-            "mr 29, %7\n\t"
-            "mr 27, %9\n\t"
-
-            /* syscall
-               r3 == flags
-               r4 == child_stack
-               r5 == parent_tidptr
-               r6 == newtls
-               r7 == child_tidptr                                            */
-            "mr 3, %8\n\t"
-            "mr 5, %10\n\t"
-            "mr 6, %11\n\t"
-            "mr 7, %12\n\t"
-	    "li	0, %4\n\t"
-            "sc\n\t"
-
-            /* Test if syscall was successful                                */
-            "cmpdi  cr1, 3, 0\n\t"
-            "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
-            "bne-   cr1, 1f\n\t"
-
-            /* Do the function call                                          */
-            "std   2, %14(1)\n\t"
-#if _CALL_ELF != 2
-	    "ld    0, 0(28)\n\t"
-	    "ld    2, 8(28)\n\t"
-            "mtctr 0\n\t"
-#else
-            "mr    12, 28\n\t"
-            "mtctr 12\n\t"
-#endif
-            "mr    3, 27\n\t"
-            "bctrl\n\t"
-	    "ld    2, %14(1)\n\t"
-
-            /* Call _exit(r3)                                                */
-            "li 0, %5\n\t"
-            "sc\n\t"
-
-            /* Return to parent                                              */
-	    "1:\n\t"
-            "mr %0, 3\n\t"
-              : "=r" (__ret), "=r" (__err)
-              : "0" (-1), "i" (EINVAL),
-                "i" (__NR_clone), "i" (__NR_exit),
-                "r" (__fn), "r" (__cstack), "r" (__flags),
-                "r" (__arg), "r" (__ptidptr), "r" (__newtls),
-                "r" (__ctidptr), "i" (FRAME_MIN_SIZE), "i" (FRAME_TOC_SAVE)
-              : "cr0", "cr1", "memory", "ctr",
-                "r0", "r29", "r27", "r28");
-#else
-        register int (*__fn)(void *)    __asm__ ("r8")  = fn;
-        register void *__cstack                 __asm__ ("r4")  = child_stack;
-        register int __flags                    __asm__ ("r3")  = flags;
-        register void * __arg                   __asm__ ("r9")  = arg;
-        register int * __ptidptr                __asm__ ("r5")  = parent_tidptr;
-        register void * __newtls                __asm__ ("r6")  = newtls;
-        register int * __ctidptr                __asm__ ("r7")  = child_tidptr;
-        __asm__ __volatile__(
-            /* check for fn == NULL
-             * and child_stack == NULL
-             */
-            "cmpwi cr0, %6, 0\n\t"
-            "cmpwi cr1, %7, 0\n\t"
-            "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
-            "beq- cr0, 1f\n\t"
-
-            /* set up stack frame for child                                  */
-            "clrrwi %7, %7, 4\n\t"
-            "li 0, 0\n\t"
-            "stwu 0, -16(%7)\n\t"
-
-            /* fn, arg, child_stack are saved across the syscall: r28-30     */
-            "mr 28, %6\n\t"
-            "mr 29, %7\n\t"
-            "mr 27, %9\n\t"
-
-            /* syscall                                                       */
-            "li 0, %4\n\t"
-            /* flags already in r3
-             * child_stack already in r4
-             * ptidptr already in r5
-             * newtls already in r6
-             * ctidptr already in r7
-             */
-            "sc\n\t"
-
-            /* Test if syscall was successful                                */
-            "cmpwi cr1, 3, 0\n\t"
-            "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
-            "bne- cr1, 1f\n\t"
-
-            /* Do the function call                                          */
-            "mtctr 28\n\t"
-            "mr 3, 27\n\t"
-            "bctrl\n\t"
-
-            /* Call _exit(r3)                                                */
-            "li 0, %5\n\t"
-            "sc\n\t"
-
-            /* Return to parent                                              */
-            "1:\n"
-            "mfcr %1\n\t"
-            "mr %0, 3\n\t"
-              : "=r" (__ret), "=r" (__err)
-              : "0" (-1), "1" (EINVAL),
-                "i" (__NR_clone), "i" (__NR_exit),
-                "r" (__fn), "r" (__cstack), "r" (__flags),
-                "r" (__arg), "r" (__ptidptr), "r" (__newtls),
-                "r" (__ctidptr)
-              : "cr0", "cr1", "memory", "ctr",
-                "r0", "r29", "r27", "r28");
-
-#endif
-      }
-      LSS_RETURN(int, __ret, __err);
-    }
-  #elif defined(__aarch64__)
-    #undef LSS_REG
-    #define LSS_REG(r,a) register long __x##r __asm__("x"#r) = (long)a
-    #undef  LSS_BODY
-    #define LSS_BODY(type,name,args...)                                       \
-          register long __res_x0 __asm__("x0");                               \
-          long __res;                                                         \
-          __asm__ __volatile__ ("mov x8, %1\n"                                \
-                                "svc 0x0\n"                                   \
-                                : "=r"(__res_x0)                              \
-                                : "i"(__NR_##name) , ## args                  \
-                                : "memory");                                  \
-          __res = __res_x0;                                                   \
-          LSS_RETURN(type, __res)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-      type LSS_NAME(name)(void) {                                             \
-        LSS_BODY(type, name);                                                 \
-      }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-      type LSS_NAME(name)(type1 arg1) {                                       \
-        LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__x0));                    \
-      }
-    #undef _syscall2
-    #define _syscall2_long(type, name, svc, type1, arg1, type2, arg2)         \
-      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \
-        LSS_REG(0, arg1); LSS_REG(1, arg2);                                   \
-        LSS_BODY(type, svc, "r"(__x0), "r"(__x1));                            \
-      }
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-            _syscall2_long(type, name, name, type1, arg1, type2, arg2)
-    #undef _syscall3
-    #define _syscall3_long(type, name, svc, type1, arg1, type2, arg2,         \
-                           type3, arg3)                                       \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \
-        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \
-        LSS_BODY(type, svc, "r"(__x0), "r"(__x1), "r"(__x2));                 \
-      }
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-            _syscall3_long(type, name, name, type1, arg1, type2, arg2,        \
-                           type3, arg3)
-    #undef _syscall4
-    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \
-        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \
-        LSS_REG(3, arg4);                                                     \
-        LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2), "r"(__x3));     \
-      }
-    #undef _syscall5
-    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5)                                             \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5) {                                       \
-        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \
-        LSS_REG(3, arg4); LSS_REG(4, arg5);                                   \
-        LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2), "r"(__x3),      \
-                             "r"(__x4));                                      \
-      }
-    #undef _syscall6
-    #define _syscall6_long(type,name,svc,type1,arg1,type2,arg2,type3,arg3,    \
-                           type4,arg4,type5,arg5,type6,arg6)                  \
-      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \
-                          type5 arg5, type6 arg6) {                           \
-        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \
-        LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6);                 \
-        LSS_BODY(type, svc, "r"(__x0), "r"(__x1), "x"(__x2), "r"(__x3),       \
-                             "r"(__x4), "r"(__x5));                           \
-      }
-    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \
-                      type5,arg5,type6,arg6)                                  \
-            _syscall6_long(type,name,name,type1,arg1,type2,arg2,type3,arg3,   \
-                           type4,arg4,type5,arg5,type6,arg6)
-    /* clone function adapted from glibc 2.18 clone.S                       */
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long __res;
-      {
-        register int (*__fn)(void *)  __asm__("x0") = fn;
-        register void *__stack __asm__("x1") = child_stack;
-        register int   __flags __asm__("x2") = flags;
-        register void *__arg   __asm__("x3") = arg;
-        register int  *__ptid  __asm__("x4") = parent_tidptr;
-        register void *__tls   __asm__("x5") = newtls;
-        register int  *__ctid  __asm__("x6") = child_tidptr;
-        __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
-                              *   return -EINVAL;
-                              */
-                             "cbz     x0,1f\n"
-                             "cbz     x1,1f\n"
-
-                             /* Push "arg" and "fn" onto the stack that will be
-                              * used by the child.
-                              */
-                             "stp x0,x3, [x1, #-16]!\n"
-
-                             "mov x0,x2\n" /* flags  */
-                             "mov x2,x4\n" /* ptid  */
-                             "mov x3,x5\n" /* tls */
-                             "mov x4,x6\n" /* ctid */
-                             "mov x8,%9\n" /* clone */
-
-                             "svc 0x0\n"
-
-                             /* if (%r0 != 0)
-                              *   return %r0;
-                              */
-                             "cmp x0, #0\n"
-                             "bne 2f\n"
-
-                             /* In the child, now. Call "fn(arg)".
-                              */
-                             "ldp x1, x0, [sp], #16\n"
-                             "blr x1\n"
-
-                             /* Call _exit(%r0).
-                              */
-                             "mov x8, %10\n"
-                             "svc 0x0\n"
-                           "1:\n"
-                             "mov x8, %1\n"
-                           "2:\n"
-                             : "=r" (__res)
-                             : "i"(-EINVAL),
-                               "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
-                               "r"(__ptid), "r"(__tls), "r"(__ctid),
-                               "i"(__NR_clone), "i"(__NR_exit)
-                             : "x30", "memory");
-      }
-      LSS_RETURN(int, __res);
-    }
-  #elif defined(__s390__)
-    #undef  LSS_REG
-    #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
-    #undef  LSS_BODY
-    #define LSS_BODY(type, name, args...)                                     \
-        register unsigned long __nr __asm__("r1")                             \
-            = (unsigned long)(__NR_##name);                                   \
-        register long __res_r2 __asm__("r2");                                 \
-        long __res;                                                           \
-        __asm__ __volatile__                                                  \
-            ("svc 0\n\t"                                                      \
-             : "=d"(__res_r2)                                                 \
-             : "d"(__nr), ## args                                             \
-             : "memory");                                                     \
-        __res = __res_r2;                                                     \
-        LSS_RETURN(type, __res)
-    #undef _syscall0
-    #define _syscall0(type, name)                                             \
-       type LSS_NAME(name)(void) {                                            \
-          LSS_BODY(type, name);                                               \
-       }
-    #undef _syscall1
-    #define _syscall1(type, name, type1, arg1)                                \
-       type LSS_NAME(name)(type1 arg1) {                                      \
-          LSS_REG(2, arg1);                                                   \
-          LSS_BODY(type, name, "0"(__r2));                                    \
-       }
-    #undef _syscall2
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-       type LSS_NAME(name)(type1 arg1, type2 arg2) {                          \
-          LSS_REG(2, arg1); LSS_REG(3, arg2);                                 \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3));                         \
-       }
-    #undef _syscall3
-    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {              \
-          LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4));              \
-       }
-    #undef _syscall4
-    #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4)                                \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3,                \
-                           type4 arg4) {                                      \
-          LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
-          LSS_REG(5, arg4);                                                   \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4),               \
-                               "d"(__r5));                                    \
-       }
-    #undef _syscall5
-    #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4, type5, arg5)                   \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3,                \
-                           type4 arg4, type5 arg5) {                          \
-          LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
-          LSS_REG(5, arg4); LSS_REG(6, arg5);                                 \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4),               \
-                               "d"(__r5), "d"(__r6));                         \
-       }
-    #undef _syscall6
-    #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3,      \
-                                  type4, arg4, type5, arg5, type6, arg6)      \
-       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3,                \
-                           type4 arg4, type5 arg5, type6 arg6) {              \
-          LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
-          LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6);               \
-          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4),               \
-                               "d"(__r5), "d"(__r6), "d"(__r7));              \
-       }
-    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
-                                   int flags, void *arg, int *parent_tidptr,
-                                   void *newtls, int *child_tidptr) {
-      long __ret;
-      {
-        register int  (*__fn)(void *)    __asm__ ("r1")  = fn;
-        register void  *__cstack         __asm__ ("r2")  = child_stack;
-        register int    __flags          __asm__ ("r3")  = flags;
-        register void  *__arg            __asm__ ("r0")  = arg;
-        register int   *__ptidptr        __asm__ ("r4")  = parent_tidptr;
-        register void  *__newtls         __asm__ ("r6")  = newtls;
-        register int   *__ctidptr        __asm__ ("r5")  = child_tidptr;
-        __asm__ __volatile__ (
-    #ifndef __s390x__
-                                  /* arg already in r0 */
-          "ltr %4, %4\n\t"        /* check fn, which is already in r1 */
-          "jz 1f\n\t"             /* NULL function pointer, return -EINVAL */
-          "ltr %5, %5\n\t"        /* check child_stack, which is already in r2 */
-          "jz 1f\n\t"             /* NULL stack pointer, return -EINVAL */
-                                  /* flags already in r3 */
-                                  /* parent_tidptr already in r4 */
-                                  /* child_tidptr already in r5 */
-                                  /* newtls already in r6 */
-          "svc %2\n\t"            /* invoke clone syscall */
-          "ltr %0,%%r2\n\t"       /* load return code into __ret and test */
-          "jnz 1f\n\t"            /* return to parent if non-zero */
-                                  /* start child thread */
-          "lr %%r2, %7\n\t"       /* set first parameter to void *arg */
-          "ahi %%r15, -96\n\t"    /* make room on the stack for the save area */
-          "xc 0(4,%%r15), 0(%%r15)\n\t"
-          "basr %%r14, %4\n\t"    /* jump to fn */
-          "svc %3\n"              /* invoke exit syscall */
-          "1:\n"
-    #else
-                                  /* arg already in r0 */
-          "ltgr %4, %4\n\t"       /* check fn, which is already in r1 */
-          "jz 1f\n\t"             /* NULL function pointer, return -EINVAL */
-          "ltgr %5, %5\n\t"       /* check child_stack, which is already in r2 */
-          "jz 1f\n\t"             /* NULL stack pointer, return -EINVAL */
-                                  /* flags already in r3 */
-                                  /* parent_tidptr already in r4 */
-                                  /* child_tidptr already in r5 */
-                                  /* newtls already in r6 */
-          "svc %2\n\t"            /* invoke clone syscall */
-          "ltgr %0, %%r2\n\t"     /* load return code into __ret and test */
-          "jnz 1f\n\t"            /* return to parent if non-zero */
-                                  /* start child thread */
-          "lgr %%r2, %7\n\t"      /* set first parameter to void *arg */
-          "aghi %%r15, -160\n\t"  /* make room on the stack for the save area */
-          "xc 0(8,%%r15), 0(%%r15)\n\t"
-          "basr %%r14, %4\n\t"    /* jump to fn */
-          "svc %3\n"              /* invoke exit syscall */
-          "1:\n"
-    #endif
-          : "=r" (__ret)
-          : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
-            "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
-            "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
-          : "cc", "r14", "memory"
-        );
-      }
-      LSS_RETURN(int, __ret);
-    }
-  #endif
-  #define __NR__exit   __NR_exit
-  #define __NR__gettid __NR_gettid
-  #define __NR__mremap __NR_mremap
-  LSS_INLINE _syscall1(int,     close,           int,         f)
-  LSS_INLINE _syscall1(int,     _exit,           int,         e)
-#if defined(__aarch64__) && defined (__ILP32__)
-  /* aarch64_ilp32 uses fcntl64 for sys_fcntl() */
-  LSS_INLINE _syscall3_long(int,     fcntl,      fcntl64,     int,         f,
-                       int,            c, long,   a)
-#else
-  LSS_INLINE _syscall3(int,     fcntl,           int,         f,
-                       int,            c, long,   a)
-#endif
-#if defined(__aarch64__) && defined (__ILP32__)
-  /* aarch64_ilp32 uses fstat64 for sys_fstat() */
-  LSS_INLINE _syscall2_long(int,     fstat,       fstat64,    int,         f,
-                      struct kernel_stat*,   b)
-#else
-  LSS_INLINE _syscall2(int,     fstat,           int,         f,
-                      struct kernel_stat*,   b)
-#endif
-  LSS_INLINE _syscall6(int,     futex,           int*,        a,
-                       int,            o, int,    v,
-                      struct kernel_timespec*, t,
-                       int*, a2,
-                       int, v3)
-#ifdef __NR_getdents64
-    LSS_INLINE _syscall3(int,     getdents64,      int,         f,
-                         struct kernel_dirent64*, d, int,    c)
-#define KERNEL_DIRENT kernel_dirent64
-#define GETDENTS sys_getdents64
-#else
-    LSS_INLINE _syscall3(int,     getdents,        int,         f,
-                         struct kernel_dirent*, d, int,    c)
-#define KERNEL_DIRENT kernel_dirent
-#define GETDENTS sys_getdents
-#endif
-  LSS_INLINE _syscall0(pid_t,   getpid)
-  LSS_INLINE _syscall0(pid_t,   getppid)
-  LSS_INLINE _syscall0(pid_t,   _gettid)
-  LSS_INLINE _syscall2(int,     kill,            pid_t,       p,
-                       int,            s)
-  #if defined(__x86_64__)
-    /* Need to make sure off_t isn't truncated to 32-bits under x32.  */
-    LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
-      _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
-                                        LSS_SYSCALL_ARG(w));
-    }
-  #elif defined(__aarch64__) && defined (__ILP32__)
-    /* aarch64_ilp32 uses llseek for sys_lseek() */
-    LSS_INLINE _syscall3_long(off_t,   lseek,       llseek,    int,         f,
-                         off_t,          o, int,    w)
-  #else
-    LSS_INLINE _syscall3(off_t,   lseek,           int,         f,
-                         off_t,          o, int,    w)
-  #endif
-  LSS_INLINE _syscall2(int,     munmap,          void*,       s,
-                       size_t,         l)
-  LSS_INLINE _syscall5(void*,   _mremap,         void*,       o,
-                       size_t,         os,       size_t,      ns,
-                       unsigned long,  f, void *, a)
-  LSS_INLINE _syscall2(int,     prctl,           int,         o,
-                       long,           a)
-  LSS_INLINE _syscall4(long,    ptrace,          int,         r,
-                       pid_t,          p, void *, a, void *, d)
-  LSS_INLINE _syscall3(ssize_t, read,            int,         f,
-                       void *,         b, size_t, c)
-  LSS_INLINE _syscall4(int,     rt_sigaction,    int,         s,
-                       const struct kernel_sigaction*, a,
-                       struct kernel_sigaction*, o, size_t,   c)
-  LSS_INLINE _syscall4(int, rt_sigprocmask,      int,         h,
-                       const struct kernel_sigset_t*,  s,
-                       struct kernel_sigset_t*,        o, size_t, c);
-  LSS_INLINE _syscall0(int,     sched_yield)
-  LSS_INLINE _syscall2(int,     sigaltstack,     const stack_t*, s,
-                       const stack_t*, o)
-  #if defined(__NR_fstatat)
-    LSS_INLINE _syscall4(int, fstatat, int, d, const char *, p,
-                         struct kernel_stat*,   b, int, flags)
-    LSS_INLINE int LSS_NAME(stat)(const char* p, struct kernel_stat* b) {
-      return LSS_NAME(fstatat)(AT_FDCWD,p,b,0);
-  }
-  #else
-    LSS_INLINE _syscall2(int,     stat,            const char*, f,
-                         struct kernel_stat*,   b)
-  #endif
-  LSS_INLINE _syscall3(ssize_t, write,            int,        f,
-                       const void *,   b, size_t, c)
-  #if defined(__NR_getcpu)
-    LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
-                         unsigned *, node, void *, unused);
-  #endif
-  #if defined(__x86_64__) || defined(__aarch64__) || \
-     (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
-    LSS_INLINE _syscall3(int, socket,             int,   d,
-                         int,                     t, int,       p)
-  #endif
-  #if defined(__x86_64__) || defined(__s390x__)
-    LSS_INLINE int LSS_NAME(sigaction)(int signum,
-                                       const struct kernel_sigaction *act,
-                                       struct kernel_sigaction *oldact) {
-      #if defined(__x86_64__)
-      /* On x86_64, the kernel requires us to always set our own
-       * SA_RESTORER in order to be able to return from a signal handler.
-       * This function must have a "magic" signature that the "gdb"
-       * (and maybe the kernel?) can recognize.
-       */
-      if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
-        struct kernel_sigaction a = *act;
-        a.sa_flags   |= SA_RESTORER;
-        a.sa_restorer = LSS_NAME(restore_rt)();
-        return LSS_NAME(rt_sigaction)(signum, &a, oldact,
-                                      (KERNEL_NSIG+7)/8);
-      } else
-      #endif
-        return LSS_NAME(rt_sigaction)(signum, act, oldact,
-                                      (KERNEL_NSIG+7)/8);
-    }
-
-    LSS_INLINE int LSS_NAME(sigprocmask)(int how,
-                                         const struct kernel_sigset_t *set,
-                                         struct kernel_sigset_t *oldset) {
-      return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
-    }
-  #endif
-  #if (defined(__aarch64__)) || \
-      (defined(__mips__) \
-       && (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32))
-    LSS_INLINE int LSS_NAME(sigaction)(int signum,
-                                       const struct kernel_sigaction *act,
-                                       struct kernel_sigaction *oldact) {
-        return LSS_NAME(rt_sigaction)(signum, act, oldact, (KERNEL_NSIG+7)/8);
-
-    }
-    LSS_INLINE int LSS_NAME(sigprocmask)(int how,
-                                         const struct kernel_sigset_t *set,
-                                         struct kernel_sigset_t *oldset) {
-      return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
-    }
-  #endif
-  #ifdef __NR_wait4
-    LSS_INLINE _syscall4(pid_t, wait4,            pid_t, p,
-                         int*,                    s, int,       o,
-                         struct kernel_rusage*,   r)
-    LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){
-      return LSS_NAME(wait4)(pid, status, options, 0);
-    }
-  #else
-    LSS_INLINE _syscall3(pid_t, waitpid,          pid_t, p,
-                         int*,              s,    int,   o)
-  #endif
-  #ifdef __NR_openat
-    LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
-    LSS_INLINE int LSS_NAME(open)(const char* p, int f, int m) {
-      return LSS_NAME(openat)(AT_FDCWD,p,f,m );
-    }
-  #else
-  LSS_INLINE _syscall3(int,     open,            const char*, p,
-                       int,            f, int,    m)
-  #endif
-  LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
-    memset(&set->sig, 0, sizeof(set->sig));
-    return 0;
-  }
-
-  LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
-    memset(&set->sig, -1, sizeof(set->sig));
-    return 0;
-  }
-
-  LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
-                                     int signum) {
-    if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
-      LSS_ERRNO = EINVAL;
-      return -1;
-    } else {
-      set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
-          |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0])));
-      return 0;
-    }
-  }
-
-  LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
-                                        int signum) {
-    if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
-      LSS_ERRNO = EINVAL;
-      return -1;
-    } else {
-      set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
-          &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0]))));
-      return 0;
-    }
-  }
-
-  #if defined(__i386__) ||                                                    \
-      defined(__arm__) ||                                                     \
-     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) ||                   \
-      defined(__PPC__) ||                                                     \
-     (defined(__s390__) && !defined(__s390x__))
-    #define __NR__sigaction   __NR_sigaction
-    #define __NR__sigprocmask __NR_sigprocmask
-    LSS_INLINE _syscall2(int, fstat64,             int, f,
-                         struct kernel_stat64 *, b)
-    LSS_INLINE _syscall5(int, _llseek,     uint, fd, ulong, hi, ulong, lo,
-                         loff_t *, res, uint, wh)
-#if defined(__s390__) && !defined(__s390x__)
-    /* On s390, mmap2() arguments are passed in memory. */
-    LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
-                                      off_t o) {
-      unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
-                               (unsigned long) p, (unsigned long) f,
-                               (unsigned long) d, (unsigned long) o };
-      LSS_REG(2, buf);
-      LSS_BODY(void*, mmap2, "0"(__r2));
-    }
-#elif !defined(__PPC64__)
-    #define __NR__mmap2 __NR_mmap2
-    LSS_INLINE _syscall6(void*, _mmap2,            void*, s,
-                         size_t,                   l, int,               p,
-                         int,                      f, int,               d,
-                         off_t,                    o)
-#endif
-    LSS_INLINE _syscall3(int,   _sigaction,        int,   s,
-                         const struct kernel_old_sigaction*,  a,
-                         struct kernel_old_sigaction*,        o)
-    LSS_INLINE _syscall3(int,   _sigprocmask,      int,   h,
-                         const unsigned long*,     s,
-                         unsigned long*,           o)
-    LSS_INLINE _syscall2(int, stat64,              const char *, p,
-                         struct kernel_stat64 *, b)
-
-    LSS_INLINE int LSS_NAME(sigaction)(int signum,
-                                       const struct kernel_sigaction *act,
-                                       struct kernel_sigaction *oldact) {
-      int old_errno = LSS_ERRNO;
-      int rc;
-      struct kernel_sigaction a;
-      if (act != NULL) {
-        a             = *act;
-        #ifdef __i386__
-        /* On i386, the kernel requires us to always set our own
-         * SA_RESTORER when using realtime signals. Otherwise, it does not
-         * know how to return from a signal handler. This function must have
-         * a "magic" signature that the "gdb" (and maybe the kernel?) can
-         * recognize.
-         * Apparently, a SA_RESTORER is implicitly set by the kernel, when
-         * using non-realtime signals.
-         *
-         * TODO: Test whether ARM needs a restorer
-         */
-        if (!(a.sa_flags & SA_RESTORER)) {
-          a.sa_flags   |= SA_RESTORER;
-          a.sa_restorer = (a.sa_flags & SA_SIGINFO)
-                          ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
-        }
-        #endif
-      }
-      rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
-                                  (KERNEL_NSIG+7)/8);
-      if (rc < 0 && LSS_ERRNO == ENOSYS) {
-        struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
-        if (!act) {
-          ptr_a            = NULL;
-        } else {
-          oa.sa_handler_   = act->sa_handler_;
-          memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
-          #ifndef __mips__
-          oa.sa_restorer   = act->sa_restorer;
-          #endif
-          oa.sa_flags      = act->sa_flags;
-        }
-        if (!oldact) {
-          ptr_oa           = NULL;
-        }
-        LSS_ERRNO = old_errno;
-        rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
-        if (rc == 0 && oldact) {
-          if (act) {
-            memcpy(oldact, act, sizeof(*act));
-          } else {
-            memset(oldact, 0, sizeof(*oldact));
-          }
-          oldact->sa_handler_    = ptr_oa->sa_handler_;
-          oldact->sa_flags       = ptr_oa->sa_flags;
-          memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
-          #ifndef __mips__
-          oldact->sa_restorer    = ptr_oa->sa_restorer;
-          #endif
-        }
-      }
-      return rc;
-    }
-
-    LSS_INLINE int LSS_NAME(sigprocmask)(int how,
-                                         const struct kernel_sigset_t *set,
-                                         struct kernel_sigset_t *oldset) {
-      int olderrno = LSS_ERRNO;
-      int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
-      if (rc < 0 && LSS_ERRNO == ENOSYS) {
-        LSS_ERRNO = olderrno;
-        if (oldset) {
-          LSS_NAME(sigemptyset)(oldset);
-        }
-        rc = LSS_NAME(_sigprocmask)(how,
-                                    set ? &set->sig[0] : NULL,
-                                    oldset ? &oldset->sig[0] : NULL);
-      }
-      return rc;
-    }
-  #endif
-  #if defined(__i386__) ||                                                    \
-      defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) ||                     \
-     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) ||                   \
-     (defined(__PPC__) && !defined(__PPC64__)) ||                             \
-     (defined(__s390__) && !defined(__s390x__))
-    /* On these architectures, implement mmap() with mmap2(). */
-    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
-                                    int64_t o) {
-      if (o % 4096) {
-        LSS_ERRNO = EINVAL;
-        return (void *) -1;
-      }
-      return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
-    }
-  #elif defined(__s390x__)
-    /* On s390x, mmap() arguments are passed in memory. */
-    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
-                                    int64_t o) {
-      unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
-                               (unsigned long) p, (unsigned long) f,
-                               (unsigned long) d, (unsigned long) o };
-      LSS_REG(2, buf);
-      LSS_BODY(void*, mmap, "0"(__r2));
-    }
-  #elif defined(__x86_64__)
-    /* Need to make sure __off64_t isn't truncated to 32-bits under x32.  */
-    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
-                                    int64_t o) {
-      LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
-                               LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
-                               LSS_SYSCALL_ARG(d), (uint64_t)(o));
-    }
-  #elif defined(__aarch64__) && defined (__ILP32__)
-    /* aarch64_ilp32 uses mmap2 for sys_mmap() */
-    LSS_INLINE _syscall6_long(void*, mmap, mmap2, void*, addr, size_t, length,
-                              int, prot, int, flags, int, fd, int64_t, offset)
-  #else
-    /* Remaining 64-bit architectures. */
-    LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
-                         int, flags, int, fd, int64_t, offset)
-  #endif
-  #if defined(__i386__) || \
-      defined(__PPC__) || \
-      (defined(__arm__) && !defined(__ARM_EABI__)) || \
-      (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
-      defined(__s390__)
-
-    /* See sys_socketcall in net/socket.c in kernel source.
-     * It de-multiplexes on its first arg and unpacks the arglist
-     * array in its second arg.
-     */
-    LSS_INLINE _syscall2(int, socketcall, int, c, unsigned long*, a)
-
-    LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
-      unsigned long args[3] = {
-        (unsigned long) domain,
-        (unsigned long) type,
-        (unsigned long) protocol
-      };
-      return LSS_NAME(socketcall)(1, args);
-    }
-  #elif defined(__ARM_EABI__)
-    LSS_INLINE _syscall3(int, socket,             int,   d,
-                         int,                     t, int,       p)
-  #endif
-  #if defined(__mips__)
-    /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
-     * both file handles through CPU registers.
-     */
-    LSS_INLINE int LSS_NAME(pipe)(int *p) {
-      register unsigned long __v0 __asm__("$2") = __NR_pipe;
-      register unsigned long __v1 __asm__("$3");
-      register unsigned long __r7 __asm__("$7");
-      __asm__ __volatile__ ("syscall\n"
-                            : "=&r"(__v0), "=&r"(__v1), "+r" (__r7)
-                            : "0"(__v0)
-                            : "$8", "$9", "$10", "$11", "$12",
-                              "$13", "$14", "$15", "$24", "memory");
-      if (__r7) {
-        LSS_ERRNO = __v0;
-        return -1;
-      } else {
-        p[0] = __v0;
-        p[1] = __v1;
-        return 0;
-      }
-    }
-  #elif defined(__NR_pipe2)
-    LSS_INLINE _syscall2(int,     pipe2,          int *, p,
-                         int,     f                        )
-    LSS_INLINE int LSS_NAME(pipe)( int * p) {
-        return LSS_NAME(pipe2)(p, 0);
-    }
-  #else
-    LSS_INLINE _syscall1(int,     pipe,           int *, p)
-  #endif
-
-  LSS_INLINE pid_t LSS_NAME(gettid)() {
-    pid_t tid = LSS_NAME(_gettid)();
-    if (tid != -1) {
-      return tid;
-    }
-    return LSS_NAME(getpid)();
-  }
-
-  LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
-                                    size_t new_size, int flags, ...) {
-    va_list ap;
-    void *new_address, *rc;
-    va_start(ap, flags);
-    new_address = va_arg(ap, void *);
-    rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
-                           flags, new_address);
-    va_end(ap);
-    return rc;
-  }
-
-  LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {
-    /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
-     * then sends job control signals to the real parent, rather than to
-     * the tracer. We reduce the risk of this happening by starting a
-     * whole new time slice, and then quickly sending a SIGCONT signal
-     * right after detaching from the tracee.
-     */
-    int rc, err;
-    LSS_NAME(sched_yield)();
-    rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
-    err = LSS_ERRNO;
-    LSS_NAME(kill)(pid, SIGCONT);
-    LSS_ERRNO = err;
-    return rc;
-  }
-#endif
-
-#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
-}
-#endif
-
-#endif
-#endif
diff --git a/third_party/tcmalloc/vendor/src/base/linuxthreads.cc b/third_party/tcmalloc/vendor/src/base/linuxthreads.cc
deleted file mode 100644
index 891e70c8..0000000
--- a/third_party/tcmalloc/vendor/src/base/linuxthreads.cc
+++ /dev/null
@@ -1,707 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005-2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-#include "base/linuxthreads.h"
-
-#ifdef THREADS
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sched.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <sys/prctl.h>
-#include <semaphore.h>
-
-#include "base/linux_syscall_support.h"
-#include "base/thread_lister.h"
-
-#ifndef CLONE_UNTRACED
-#define CLONE_UNTRACED 0x00800000
-#endif
-
-
-/* Synchronous signals that should not be blocked while in the lister thread.
- */
-static const int sync_signals[]  = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, SIGBUS,
-                                     SIGXCPU, SIGXFSZ };
-
-/* itoa() is not a standard function, and we cannot safely call printf()
- * after suspending threads. So, we just implement our own copy. A
- * recursive approach is the easiest here.
- */
-static char *local_itoa(char *buf, int i) {
-  if (i < 0) {
-    *buf++ = '-';
-    return local_itoa(buf, -i);
-  } else {
-    if (i >= 10)
-      buf = local_itoa(buf, i/10);
-    *buf++ = (i%10) + '0';
-    *buf   = '\000';
-    return buf;
-  }
-}
-
-
-/* Wrapper around clone() that runs "fn" on the same stack as the
- * caller! Unlike fork(), the cloned thread shares the same address space.
- * The caller must be careful to use only minimal amounts of stack until
- * the cloned thread has returned.
- * There is a good chance that the cloned thread and the caller will share
- * the same copy of errno!
- */
-#ifdef __GNUC__
-#if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3
-/* Try to force this function into a separate stack frame, and make sure
- * that arguments are passed on the stack.
- */
-static int local_clone (int (*fn)(void *), void *arg, ...)
-  __attribute__ ((noinline));
-#endif
-#endif
-
-/* To avoid the gap cross page boundaries, increase by the large parge
- * size mostly PowerPC system uses.  */
-#ifdef __PPC64__
-#define CLONE_STACK_SIZE 65536
-#else
-#define CLONE_STACK_SIZE 4096
-#endif
-
-static int local_clone (int (*fn)(void *), void *arg, ...) {
-  /* Leave 4kB of gap between the callers stack and the new clone. This
-   * should be more than sufficient for the caller to call waitpid() until
-   * the cloned thread terminates.
-   *
-   * It is important that we set the CLONE_UNTRACED flag, because newer
-   * versions of "gdb" otherwise attempt to attach to our thread, and will
-   * attempt to reap its status codes. This subsequently results in the
-   * caller hanging indefinitely in waitpid(), waiting for a change in
-   * status that will never happen. By setting the CLONE_UNTRACED flag, we
-   * prevent "gdb" from stealing events, but we still expect the thread
-   * lister to fail, because it cannot PTRACE_ATTACH to the process that
-   * is being debugged. This is OK and the error code will be reported
-   * correctly.
-   */
-  return sys_clone(fn, (char *)&arg - CLONE_STACK_SIZE,
-                   CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED, arg, 0, 0, 0);
-}
-
-
-/* Local substitute for the atoi() function, which is not necessarily safe
- * to call once threads are suspended (depending on whether libc looks up
- * locale information,  when executing atoi()).
- */
-static int local_atoi(const char *s) {
-  int n   = 0;
-  int neg = *s == '-';
-  if (neg)
-    s++;
-  while (*s >= '0' && *s <= '9')
-    n = 10*n + (*s++ - '0');
-  return neg ? -n : n;
-}
-
-
-/* Re-runs fn until it doesn't cause EINTR
- */
-#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
-
-
-/* Wrap a class around system calls, in order to give us access to
- * a private copy of errno. This only works in C++, but it has the
- * advantage of not needing nested functions, which are a non-standard
- * language extension.
- */
-#ifdef __cplusplus
-namespace {
-  class SysCalls {
-   public:
-    #define SYS_CPLUSPLUS
-    #define SYS_ERRNO     my_errno
-    #define SYS_INLINE    inline
-    #define SYS_PREFIX    -1
-    #undef  SYS_LINUX_SYSCALL_SUPPORT_H
-    #include "linux_syscall_support.h"
-    SysCalls() : my_errno(0) { }
-    int my_errno;
-  };
-}
-#define ERRNO sys.my_errno
-#else
-#define ERRNO my_errno
-#endif
-
-
-/* Wrapper for open() which is guaranteed to never return EINTR.
- */
-static int c_open(const char *fname, int flags, int mode) {
-  ssize_t rc;
-  NO_INTR(rc = sys_open(fname, flags, mode));
-  return rc;
-}
-
-
-/* abort() is not safely reentrant, and changes it's behavior each time
- * it is called. This means, if the main application ever called abort()
- * we cannot safely call it again. This would happen if we were called
- * from a SIGABRT signal handler in the main application. So, document
- * that calling SIGABRT from the thread lister makes it not signal safe
- * (and vice-versa).
- * Also, since we share address space with the main application, we
- * cannot call abort() from the callback and expect the main application
- * to behave correctly afterwards. In fact, the only thing we can do, is
- * to terminate the main application with extreme prejudice (aka
- * PTRACE_KILL).
- * We set up our own SIGABRT handler to do this.
- * In order to find the main application from the signal handler, we
- * need to store information about it in global variables. This is
- * safe, because the main application should be suspended at this
- * time. If the callback ever called TCMalloc_ResumeAllProcessThreads(), then
- * we are running a higher risk, though. So, try to avoid calling
- * abort() after calling TCMalloc_ResumeAllProcessThreads.
- */
-static volatile int *sig_pids, sig_num_threads, sig_proc, sig_marker;
-
-
-/* Signal handler to help us recover from dying while we are attached to
- * other threads.
- */
-static void SignalHandler(int signum, siginfo_t *si, void *data) {
-  if (sig_pids != NULL) {
-    if (signum == SIGABRT) {
-      while (sig_num_threads-- > 0) {
-        /* Not sure if sched_yield is really necessary here, but it does not */
-        /* hurt, and it might be necessary for the same reasons that we have */
-        /* to do so in sys_ptrace_detach().                                  */
-        sys_sched_yield();
-        sys_ptrace(PTRACE_KILL, sig_pids[sig_num_threads], 0, 0);
-      }
-    } else if (sig_num_threads > 0) {
-      TCMalloc_ResumeAllProcessThreads(sig_num_threads, (int *)sig_pids);
-    }
-  }
-  sig_pids = NULL;
-  if (sig_marker >= 0)
-    NO_INTR(sys_close(sig_marker));
-  sig_marker = -1;
-  if (sig_proc >= 0)
-    NO_INTR(sys_close(sig_proc));
-  sig_proc = -1;
-
-  sys__exit(signum == SIGABRT ? 1 : 2);
-}
-
-
-/* Try to dirty the stack, and hope that the compiler is not smart enough
- * to optimize this function away. Or worse, the compiler could inline the
- * function and permanently allocate the data on the stack.
- */
-static void DirtyStack(size_t amount) {
-  char buf[amount];
-  memset(buf, 0, amount);
-  sys_read(-1, buf, amount);
-}
-
-
-/* Data structure for passing arguments to the lister thread.
- */
-#define ALT_STACKSIZE (MINSIGSTKSZ + 4096)
-
-struct ListerParams {
-  int         result, err;
-  char        *altstack_mem;
-  ListAllProcessThreadsCallBack callback;
-  void        *parameter;
-  va_list     ap;
-  sem_t       *lock;
-};
-
-
-static void ListerThread(struct ListerParams *args) {
-  int                found_parent = 0;
-  pid_t              clone_pid  = sys_gettid(), ppid = sys_getppid();
-  char               proc_self_task[80], marker_name[48], *marker_path;
-  const char         *proc_paths[3];
-  const char *const  *proc_path = proc_paths;
-  int                proc = -1, marker = -1, num_threads = 0;
-  int                max_threads = 0, sig;
-  struct kernel_stat marker_sb, proc_sb;
-  stack_t            altstack;
-
-  /* Wait for parent thread to set appropriate permissions
-   * to allow ptrace activity
-   */
-  if (sem_wait(args->lock) < 0) {
-    goto failure;
-  }
-
-  /* Create "marker" that we can use to detect threads sharing the same
-   * address space and the same file handles. By setting the FD_CLOEXEC flag
-   * we minimize the risk of misidentifying child processes as threads;
-   * and since there is still a race condition,  we will filter those out
-   * later, anyway.
-   */
-  if ((marker = sys_socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0 ||
-      sys_fcntl(marker, F_SETFD, FD_CLOEXEC) < 0) {
-  failure:
-    args->result = -1;
-    args->err    = errno;
-    if (marker >= 0)
-      NO_INTR(sys_close(marker));
-    sig_marker = marker = -1;
-    if (proc >= 0)
-      NO_INTR(sys_close(proc));
-    sig_proc = proc = -1;
-    sys__exit(1);
-  }
-
-  /* Compute search paths for finding thread directories in /proc            */
-  local_itoa(strrchr(strcpy(proc_self_task, "/proc/"), '\000'), ppid);
-  strcpy(marker_name, proc_self_task);
-  marker_path = marker_name + strlen(marker_name);
-  strcat(proc_self_task, "/task/");
-  proc_paths[0] = proc_self_task; /* /proc/$$/task/                          */
-  proc_paths[1] = "/proc/";       /* /proc/                                  */
-  proc_paths[2] = NULL;
-
-  /* Compute path for marker socket in /proc                                 */
-  local_itoa(strcpy(marker_path, "/fd/") + 4, marker);
-  if (sys_stat(marker_name, &marker_sb) < 0) {
-    goto failure;
-  }
-
-  /* Catch signals on an alternate pre-allocated stack. This way, we can
-   * safely execute the signal handler even if we ran out of memory.
-   */
-  memset(&altstack, 0, sizeof(altstack));
-  altstack.ss_sp    = args->altstack_mem;
-  altstack.ss_flags = 0;
-  altstack.ss_size  = ALT_STACKSIZE;
-  sys_sigaltstack(&altstack, (const stack_t *)NULL);
-
-  /* Some kernels forget to wake up traced processes, when the
-   * tracer dies.  So, intercept synchronous signals and make sure
-   * that we wake up our tracees before dying. It is the caller's
-   * responsibility to ensure that asynchronous signals do not
-   * interfere with this function.
-   */
-  sig_marker = marker;
-  sig_proc   = -1;
-  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
-    struct kernel_sigaction sa;
-    memset(&sa, 0, sizeof(sa));
-    sa.sa_sigaction_ = SignalHandler;
-    sys_sigfillset(&sa.sa_mask);
-    sa.sa_flags      = SA_ONSTACK|SA_SIGINFO|SA_RESETHAND;
-    sys_sigaction(sync_signals[sig], &sa, (struct kernel_sigaction *)NULL);
-  }
-  
-  /* Read process directories in /proc/...                                   */
-  for (;;) {
-    /* Some kernels know about threads, and hide them in "/proc"
-     * (although they are still there, if you know the process
-     * id). Threads are moved into a separate "task" directory. We
-     * check there first, and then fall back on the older naming
-     * convention if necessary.
-     */
-    if ((sig_proc = proc = c_open(*proc_path, O_RDONLY|O_DIRECTORY, 0)) < 0) {
-      if (*++proc_path != NULL)
-        continue;
-      goto failure;
-    }
-    if (sys_fstat(proc, &proc_sb) < 0)
-      goto failure;
-    
-    /* Since we are suspending threads, we cannot call any libc
-     * functions that might acquire locks. Most notably, we cannot
-     * call malloc(). So, we have to allocate memory on the stack,
-     * instead. Since we do not know how much memory we need, we
-     * make a best guess. And if we guessed incorrectly we retry on
-     * a second iteration (by jumping to "detach_threads").
-     *
-     * Unless the number of threads is increasing very rapidly, we
-     * should never need to do so, though, as our guestimate is very
-     * conservative.
-     */
-    if (max_threads < proc_sb.st_nlink + 100)
-      max_threads = proc_sb.st_nlink + 100;
-    
-    /* scope */ {
-      pid_t pids[max_threads];
-      int   added_entries = 0;
-      sig_num_threads     = num_threads;
-      sig_pids            = pids;
-      for (;;) {
-        struct KERNEL_DIRENT *entry;
-        char buf[4096];
-        ssize_t nbytes = GETDENTS(proc, (struct KERNEL_DIRENT *)buf,
-                                         sizeof(buf));
-        if (nbytes < 0)
-          goto failure;
-        else if (nbytes == 0) {
-          if (added_entries) {
-            /* Need to keep iterating over "/proc" in multiple
-             * passes until we no longer find any more threads. This
-             * algorithm eventually completes, when all threads have
-             * been suspended.
-             */
-            added_entries = 0;
-            sys_lseek(proc, 0, SEEK_SET);
-            continue;
-          }
-          break;
-        }
-        for (entry = (struct KERNEL_DIRENT *)buf;
-             entry < (struct KERNEL_DIRENT *)&buf[nbytes];
-             entry = (struct KERNEL_DIRENT *)((char *)entry+entry->d_reclen)) {
-          if (entry->d_ino != 0) {
-            const char *ptr = entry->d_name;
-            pid_t pid;
-            
-            /* Some kernels hide threads by preceding the pid with a '.'     */
-            if (*ptr == '.')
-              ptr++;
-            
-            /* If the directory is not numeric, it cannot be a
-             * process/thread
-             */
-            if (*ptr < '0' || *ptr > '9')
-              continue;
-            pid = local_atoi(ptr);
-
-            /* Attach (and suspend) all threads                              */
-            if (pid && pid != clone_pid) {
-              struct kernel_stat tmp_sb;
-              char fname[entry->d_reclen + 48];
-              strcat(strcat(strcpy(fname, "/proc/"),
-                            entry->d_name), marker_path);
-              
-              /* Check if the marker is identical to the one we created      */
-              if (sys_stat(fname, &tmp_sb) >= 0 &&
-                  marker_sb.st_ino == tmp_sb.st_ino) {
-                long i, j;
-
-                /* Found one of our threads, make sure it is no duplicate    */
-                for (i = 0; i < num_threads; i++) {
-                  /* Linear search is slow, but should not matter much for
-                   * the typically small number of threads.
-                   */
-                  if (pids[i] == pid) {
-                    /* Found a duplicate; most likely on second pass         */
-                    goto next_entry;
-                  }
-                }
-                
-                /* Check whether data structure needs growing                */
-                if (num_threads >= max_threads) {
-                  /* Back to square one, this time with more memory          */
-                  NO_INTR(sys_close(proc));
-                  goto detach_threads;
-                }
-
-                /* Attaching to thread suspends it                           */
-                pids[num_threads++] = pid;
-                sig_num_threads     = num_threads;
-                if (sys_ptrace(PTRACE_ATTACH, pid, (void *)0,
-                               (void *)0) < 0) {
-                  /* If operation failed, ignore thread. Maybe it
-                   * just died?  There might also be a race
-                   * condition with a concurrent core dumper or
-                   * with a debugger. In that case, we will just
-                   * make a best effort, rather than failing
-                   * entirely.
-                   */
-                  num_threads--;
-                  sig_num_threads = num_threads;
-                  goto next_entry;
-                }
-                while (sys_waitpid(pid, (int *)0, __WALL) < 0) {
-                  if (errno != EINTR) {
-                    sys_ptrace_detach(pid);
-                    num_threads--;
-                    sig_num_threads = num_threads;
-                    goto next_entry;
-                  }
-                }
-
-                if (sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i++ != j ||
-                    sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i   != j) {
-                  /* Address spaces are distinct, even though both
-                   * processes show the "marker". This is probably
-                   * a forked child process rather than a thread.
-                   */
-                  sys_ptrace_detach(pid);
-                  num_threads--;
-                  sig_num_threads = num_threads;
-                } else {
-                  found_parent |= pid == ppid;
-                  added_entries++;
-                }
-              }
-            }
-          }
-        next_entry:;
-        }
-      }
-      NO_INTR(sys_close(proc));
-      sig_proc = proc = -1;
-
-      /* If we failed to find any threads, try looking somewhere else in
-       * /proc. Maybe, threads are reported differently on this system.
-       */
-      if (num_threads > 1 || !*++proc_path) {
-        NO_INTR(sys_close(marker));
-        sig_marker = marker = -1;
-
-        /* If we never found the parent process, something is very wrong.
-         * Most likely, we are running in debugger. Any attempt to operate
-         * on the threads would be very incomplete. Let's just report an
-         * error to the caller.
-         */
-        if (!found_parent) {
-          TCMalloc_ResumeAllProcessThreads(num_threads, pids);
-          sys__exit(3);
-        }
-
-        /* Now we are ready to call the callback,
-         * which takes care of resuming the threads for us.
-         */
-        args->result = args->callback(args->parameter, num_threads,
-                                      pids, args->ap);
-        args->err = errno;
-
-        /* Callback should have resumed threads, but better safe than sorry  */
-        if (TCMalloc_ResumeAllProcessThreads(num_threads, pids)) {
-          /* Callback forgot to resume at least one thread, report error     */
-          args->err    = EINVAL;
-          args->result = -1;
-        }
-
-        sys__exit(0);
-      }
-    detach_threads:
-      /* Resume all threads prior to retrying the operation                  */
-      TCMalloc_ResumeAllProcessThreads(num_threads, pids);
-      sig_pids = NULL;
-      num_threads = 0;
-      sig_num_threads = num_threads;
-      max_threads += 100;
-    }
-  }
-}
-
-
-/* This function gets the list of all linux threads of the current process
- * passes them to the 'callback' along with the 'parameter' pointer; at the
- * call back call time all the threads are paused via
- * PTRACE_ATTACH.
- * The callback is executed from a separate thread which shares only the
- * address space, the filesystem, and the filehandles with the caller. Most
- * notably, it does not share the same pid and ppid; and if it terminates,
- * the rest of the application is still there. 'callback' is supposed to do
- * or arrange for TCMalloc_ResumeAllProcessThreads. This happens automatically, if
- * the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous
- * signals are blocked. If the 'callback' decides to unblock them, it must
- * ensure that they cannot terminate the application, or that
- * TCMalloc_ResumeAllProcessThreads will get called.
- * It is an error for the 'callback' to make any library calls that could
- * acquire locks. Most notably, this means that most system calls have to
- * avoid going through libc. Also, this means that it is not legal to call
- * exit() or abort().
- * We return -1 on error and the return value of 'callback' on success.
- */
-int TCMalloc_ListAllProcessThreads(void *parameter,
-                                   ListAllProcessThreadsCallBack callback, ...) {
-  char                   altstack_mem[ALT_STACKSIZE];
-  struct ListerParams    args;
-  pid_t                  clone_pid;
-  int                    dumpable = 1, sig;
-  struct kernel_sigset_t sig_blocked, sig_old;
-  sem_t                  lock;
-
-  va_start(args.ap, callback);
-
-  /* If we are short on virtual memory, initializing the alternate stack
-   * might trigger a SIGSEGV. Let's do this early, before it could get us
-   * into more trouble (i.e. before signal handlers try to use the alternate
-   * stack, and before we attach to other threads).
-   */
-  memset(altstack_mem, 0, sizeof(altstack_mem));
-
-  /* Some of our cleanup functions could conceivable use more stack space.
-   * Try to touch the stack right now. This could be defeated by the compiler
-   * being too smart for it's own good, so try really hard.
-   */
-  DirtyStack(32768);
-
-  /* Make this process "dumpable". This is necessary in order to ptrace()
-   * after having called setuid().
-   */
-  dumpable = sys_prctl(PR_GET_DUMPABLE, 0);
-  if (!dumpable)
-    sys_prctl(PR_SET_DUMPABLE, 1);
-
-  /* Fill in argument block for dumper thread                                */
-  args.result       = -1;
-  args.err          = 0;
-  args.altstack_mem = altstack_mem;
-  args.parameter    = parameter;
-  args.callback     = callback;
-  args.lock         = &lock;
-
-  /* Before cloning the thread lister, block all asynchronous signals, as we */
-  /* are not prepared to handle them.                                        */
-  sys_sigfillset(&sig_blocked);
-  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
-    sys_sigdelset(&sig_blocked, sync_signals[sig]);
-  }
-  if (sys_sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old)) {
-    args.err = errno;
-    args.result = -1;
-    goto failed;
-  }
-
-  /* scope */ {
-    /* After cloning, both the parent and the child share the same instance
-     * of errno. We must make sure that at least one of these processes
-     * (in our case, the parent) uses modified syscall macros that update
-     * a local copy of errno, instead.
-     */
-    #ifdef __cplusplus
-      #define sys0_sigprocmask sys.sigprocmask
-      #define sys0_waitpid     sys.waitpid
-      SysCalls sys;
-    #else
-      int my_errno;
-      #define SYS_ERRNO        my_errno
-      #define SYS_INLINE       inline
-      #define SYS_PREFIX       0
-      #undef  SYS_LINUX_SYSCALL_SUPPORT_H
-      #include "linux_syscall_support.h"
-    #endif
-
-    /* Lock before clone so that parent can set
-	 * ptrace permissions (if necessary) prior
-     * to ListerThread actually executing
-     */
-    if (sem_init(&lock, 0, 0) == 0) {
-
-      int clone_errno;
-      clone_pid = local_clone((int (*)(void *))ListerThread, &args);
-      clone_errno = errno;
-
-      sys_sigprocmask(SIG_SETMASK, &sig_old, &sig_old);
-
-      if (clone_pid >= 0) {
-#ifdef PR_SET_PTRACER
-        /* In newer versions of glibc permission must explicitly
-         * be given to allow for ptrace.
-         */
-        prctl(PR_SET_PTRACER, clone_pid, 0, 0, 0);
-#endif
-        /* Releasing the lock here allows the
-         * ListerThread to execute and ptrace us.
-		 */
-        sem_post(&lock);
-        int status, rc;
-        while ((rc = sys0_waitpid(clone_pid, &status, __WALL)) < 0 &&
-               ERRNO == EINTR) {
-                /* Keep waiting                                                 */
-        }
-        if (rc < 0) {
-          args.err = ERRNO;
-          args.result = -1;
-        } else if (WIFEXITED(status)) {
-          switch (WEXITSTATUS(status)) {
-            case 0: break;             /* Normal process termination           */
-            case 2: args.err = EFAULT; /* Some fault (e.g. SIGSEGV) detected   */
-                    args.result = -1;
-                    break;
-            case 3: args.err = EPERM;  /* Process is already being traced      */
-                    args.result = -1;
-                    break;
-            default:args.err = ECHILD; /* Child died unexpectedly              */
-                    args.result = -1;
-                    break;
-          }
-        } else if (!WIFEXITED(status)) {
-          args.err    = EFAULT;        /* Terminated due to an unhandled signal*/
-          args.result = -1;
-        }
-        sem_destroy(&lock);
-      } else {
-        args.result = -1;
-        args.err    = clone_errno;
-      }
-    } else {
-      args.result = -1;
-      args.err    = errno;
-    }
-  }
-
-  /* Restore the "dumpable" state of the process                             */
-failed:
-  if (!dumpable)
-    sys_prctl(PR_SET_DUMPABLE, dumpable);
-
-  va_end(args.ap);
-
-  errno = args.err;
-  return args.result;
-}
-
-/* This function resumes the list of all linux threads that
- * TCMalloc_ListAllProcessThreads pauses before giving to its callback.
- * The function returns non-zero if at least one thread was
- * suspended and has now been resumed.
- */
-int TCMalloc_ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
-  int detached_at_least_one = 0;
-  while (num_threads-- > 0) {
-    detached_at_least_one |= sys_ptrace_detach(thread_pids[num_threads]) >= 0;
-  }
-  return detached_at_least_one;
-}
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/third_party/tcmalloc/vendor/src/base/linuxthreads.h b/third_party/tcmalloc/vendor/src/base/linuxthreads.h
deleted file mode 100644
index 09ce45fc..0000000
--- a/third_party/tcmalloc/vendor/src/base/linuxthreads.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (c) 2005-2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-#ifndef _LINUXTHREADS_H
-#define _LINUXTHREADS_H
-
-/* Include thread_lister.h to get the interface that we implement for linux.
- */
-
-/* We currently only support certain platforms on Linux. Porting to other
- * related platforms should not be difficult.
- */
-#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
-     defined(__mips__) || defined(__PPC__) || defined(__aarch64__) ||       \
-     defined(__s390__)) && defined(__linux)
-
-/* Define the THREADS symbol to make sure that there is exactly one core dumper
- * built into the library.
- */
-#define THREADS "Linux /proc"
-
-#endif
-
-#endif  /* _LINUXTHREADS_H */
diff --git a/third_party/tcmalloc/vendor/src/base/logging.cc b/third_party/tcmalloc/vendor/src/base/logging.cc
deleted file mode 100644
index 761c2fd5..0000000
--- a/third_party/tcmalloc/vendor/src/base/logging.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// This file just provides storage for FLAGS_verbose.
-
-#include <config.h>
-#include "base/logging.h"
-#include "base/commandlineflags.h"
-
-DEFINE_int32(verbose, EnvToInt("PERFTOOLS_VERBOSE", 0),
-             "Set to numbers >0 for more verbose output, or <0 for less.  "
-             "--verbose == -4 means we log fatal errors only.");
-
-
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-
-// While windows does have a POSIX-compatible API
-// (_open/_write/_close), it acquires memory.  Using this lower-level
-// windows API is the closest we can get to being "raw".
-RawFD RawOpenForWriting(const char* filename) {
-  // CreateFile allocates memory if file_name isn't absolute, so if
-  // that ever becomes a problem then we ought to compute the absolute
-  // path on its behalf (perhaps the ntdll/kernel function isn't aware
-  // of the working directory?)
-  RawFD fd = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
-                         CREATE_ALWAYS, 0, NULL);
-  if (fd != kIllegalRawFD && GetLastError() == ERROR_ALREADY_EXISTS)
-    SetEndOfFile(fd);    // truncate the existing file
-  return fd;
-}
-
-void RawWrite(RawFD handle, const char* buf, size_t len) {
-  while (len > 0) {
-    DWORD wrote;
-    BOOL ok = WriteFile(handle, buf, len, &wrote, NULL);
-    // We do not use an asynchronous file handle, so ok==false means an error
-    if (!ok) break;
-    buf += wrote;
-    len -= wrote;
-  }
-}
-
-void RawClose(RawFD handle) {
-  CloseHandle(handle);
-}
-
-#else  // _WIN32 || __CYGWIN__ || __CYGWIN32__
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-// Re-run fn until it doesn't cause EINTR.
-#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)
-
-RawFD RawOpenForWriting(const char* filename) {
-  return open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0664);
-}
-
-void RawWrite(RawFD fd, const char* buf, size_t len) {
-  while (len > 0) {
-    ssize_t r;
-    NO_INTR(r = write(fd, buf, len));
-    if (r <= 0) break;
-    buf += r;
-    len -= r;
-  }
-}
-
-void RawClose(RawFD fd) {
-  NO_INTR(close(fd));
-}
-
-#endif  // _WIN32 || __CYGWIN__ || __CYGWIN32__
diff --git a/third_party/tcmalloc/vendor/src/base/logging.h b/third_party/tcmalloc/vendor/src/base/logging.h
deleted file mode 100644
index a1afe4d..0000000
--- a/third_party/tcmalloc/vendor/src/base/logging.h
+++ /dev/null
@@ -1,259 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// This file contains #include information about logging-related stuff.
-// Pretty much everybody needs to #include this file so that they can
-// log various happenings.
-//
-#ifndef _LOGGING_H_
-#define _LOGGING_H_
-
-#include <config.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for write()
-#endif
-#include <string.h>    // for strlen(), strcmp()
-#include <assert.h>
-#include <errno.h>     // for errno
-#include "base/commandlineflags.h"
-
-// On some systems (like freebsd), we can't call write() at all in a
-// global constructor, perhaps because errno hasn't been set up.
-// (In windows, we can't call it because it might call malloc.)
-// Calling the write syscall is safer (it doesn't set errno), so we
-// prefer that.  Note we don't care about errno for logging: we just
-// do logging on a best-effort basis.
-#if defined(_MSC_VER)
-#define WRITE_TO_STDERR(buf, len) WriteToStderr(buf, len);  // in port.cc
-#elif defined(HAVE_SYS_SYSCALL_H)
-#include <sys/syscall.h>
-#define WRITE_TO_STDERR(buf, len) syscall(SYS_write, STDERR_FILENO, buf, len)
-#else
-#define WRITE_TO_STDERR(buf, len) write(STDERR_FILENO, buf, len)
-#endif
-
-// MSVC and mingw define their own, safe version of vnsprintf (the
-// windows one in broken) in port.cc.  Everyone else can use the
-// version here.  We had to give it a unique name for windows.
-#ifndef _WIN32
-# define perftools_vsnprintf vsnprintf
-#endif
-
-
-// We log all messages at this log-level and below.
-// INFO == -1, WARNING == -2, ERROR == -3, FATAL == -4
-DECLARE_int32(verbose);
-
-// CHECK dies with a fatal error if condition is not true.  It is *not*
-// controlled by NDEBUG, so the check will be executed regardless of
-// compilation mode.  Therefore, it is safe to do things like:
-//    CHECK(fp->Write(x) == 4)
-// Note we use write instead of printf/puts to avoid the risk we'll
-// call malloc().
-#define CHECK(condition)                                                \
-  do {                                                                  \
-    if (!(condition)) {                                                 \
-      WRITE_TO_STDERR("Check failed: " #condition "\n",                 \
-                      sizeof("Check failed: " #condition "\n")-1);      \
-      abort();                                                          \
-    }                                                                   \
-  } while (0)
-
-// This takes a message to print.  The name is historical.
-#define RAW_CHECK(condition, message)                                          \
-  do {                                                                         \
-    if (!(condition)) {                                                        \
-      WRITE_TO_STDERR("Check failed: " #condition ": " message "\n",           \
-                      sizeof("Check failed: " #condition ": " message "\n")-1);\
-      abort();                                                                 \
-    }                                                                          \
-  } while (0)
-
-// This is like RAW_CHECK, but only in debug-mode
-#ifdef NDEBUG
-enum { DEBUG_MODE = 0 };
-#define RAW_DCHECK(condition, message)
-#else
-enum { DEBUG_MODE = 1 };
-#define RAW_DCHECK(condition, message)  RAW_CHECK(condition, message)
-#endif
-
-// This prints errno as well.  Note we use write instead of printf/puts to
-// avoid the risk we'll call malloc().
-#define PCHECK(condition)                                               \
-  do {                                                                  \
-    if (!(condition)) {                                                 \
-      const int err_no = errno;                                         \
-      WRITE_TO_STDERR("Check failed: " #condition ": ",                 \
-                      sizeof("Check failed: " #condition ": ")-1);      \
-      WRITE_TO_STDERR(strerror(err_no), strlen(strerror(err_no)));      \
-      WRITE_TO_STDERR("\n", sizeof("\n")-1);                            \
-      abort();                                                          \
-    }                                                                   \
-  } while (0)
-
-// Helper macro for binary operators; prints the two values on error
-// Don't use this macro directly in your code, use CHECK_EQ et al below
-
-// WARNING: These don't compile correctly if one of the arguments is a pointer
-// and the other is NULL. To work around this, simply static_cast NULL to the
-// type of the desired pointer.
-
-// TODO(jandrews): Also print the values in case of failure.  Requires some
-// sort of type-sensitive ToString() function.
-#define CHECK_OP(op, val1, val2)                                        \
-  do {                                                                  \
-    if (!((val1) op (val2))) {                                          \
-      fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
-      abort();                                                          \
-    }                                                                   \
-  } while (0)
-
-#define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
-#define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)
-#define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)
-#define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)
-#define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
-#define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
-
-// Synonyms for CHECK_* that are used in some unittests.
-#define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)
-#define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)
-#define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)
-#define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)
-#define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)
-#define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)
-#define ASSERT_EQ(val1, val2) EXPECT_EQ(val1, val2)
-#define ASSERT_NE(val1, val2) EXPECT_NE(val1, val2)
-#define ASSERT_LE(val1, val2) EXPECT_LE(val1, val2)
-#define ASSERT_LT(val1, val2) EXPECT_LT(val1, val2)
-#define ASSERT_GE(val1, val2) EXPECT_GE(val1, val2)
-#define ASSERT_GT(val1, val2) EXPECT_GT(val1, val2)
-// As are these variants.
-#define EXPECT_TRUE(cond)     CHECK(cond)
-#define EXPECT_FALSE(cond)    CHECK(!(cond))
-#define EXPECT_STREQ(a, b)    CHECK(strcmp(a, b) == 0)
-#define ASSERT_TRUE(cond)     EXPECT_TRUE(cond)
-#define ASSERT_FALSE(cond)    EXPECT_FALSE(cond)
-#define ASSERT_STREQ(a, b)    EXPECT_STREQ(a, b)
-
-// Used for (libc) functions that return -1 and set errno
-#define CHECK_ERR(invocation)  PCHECK((invocation) != -1)
-
-// A few more checks that only happen in debug mode
-#ifdef NDEBUG
-#define DCHECK_EQ(val1, val2)
-#define DCHECK_NE(val1, val2)
-#define DCHECK_LE(val1, val2)
-#define DCHECK_LT(val1, val2)
-#define DCHECK_GE(val1, val2)
-#define DCHECK_GT(val1, val2)
-#else
-#define DCHECK_EQ(val1, val2)  CHECK_EQ(val1, val2)
-#define DCHECK_NE(val1, val2)  CHECK_NE(val1, val2)
-#define DCHECK_LE(val1, val2)  CHECK_LE(val1, val2)
-#define DCHECK_LT(val1, val2)  CHECK_LT(val1, val2)
-#define DCHECK_GE(val1, val2)  CHECK_GE(val1, val2)
-#define DCHECK_GT(val1, val2)  CHECK_GT(val1, val2)
-#endif
-
-
-#ifdef ERROR
-#undef ERROR      // may conflict with ERROR macro on windows
-#endif
-enum LogSeverity {INFO = -1, WARNING = -2, ERROR = -3, FATAL = -4};
-
-// NOTE: we add a newline to the end of the output if it's not there already
-inline void LogPrintf(int severity, const char* pat, va_list ap) {
-  // We write directly to the stderr file descriptor and avoid FILE
-  // buffering because that may invoke malloc()
-  char buf[600];
-  perftools_vsnprintf(buf, sizeof(buf)-1, pat, ap);
-  if (buf[0] != '\0' && buf[strlen(buf)-1] != '\n') {
-    assert(strlen(buf)+1 < sizeof(buf));
-    strcat(buf, "\n");
-  }
-  WRITE_TO_STDERR(buf, strlen(buf));
-  if ((severity) == FATAL)
-    abort(); // LOG(FATAL) indicates a big problem, so don't run atexit() calls
-}
-
-// Note that since the order of global constructors is unspecified,
-// global code that calls RAW_LOG may execute before FLAGS_verbose is set.
-// Such code will run with verbosity == 0 no matter what.
-#define VLOG_IS_ON(severity) (FLAGS_verbose >= severity)
-
-// In a better world, we'd use __VA_ARGS__, but VC++ 7 doesn't support it.
-#define LOG_PRINTF(severity, pat) do {          \
-  if (VLOG_IS_ON(severity)) {                   \
-    va_list ap;                                 \
-    va_start(ap, pat);                          \
-    LogPrintf(severity, pat, ap);               \
-    va_end(ap);                                 \
-  }                                             \
-} while (0)
-
-// RAW_LOG is the main function; some synonyms are used in unittests.
-inline void RAW_LOG(int lvl, const char* pat, ...)  { LOG_PRINTF(lvl, pat); }
-inline void RAW_VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); }
-inline void LOG(int lvl, const char* pat, ...)      { LOG_PRINTF(lvl, pat); }
-inline void VLOG(int lvl, const char* pat, ...)     { LOG_PRINTF(lvl, pat); }
-inline void LOG_IF(int lvl, bool cond, const char* pat, ...) {
-  if (cond)  LOG_PRINTF(lvl, pat);
-}
-
-// This isn't technically logging, but it's also IO and also is an
-// attempt to be "raw" -- that is, to not use any higher-level libc
-// routines that might allocate memory or (ideally) try to allocate
-// locks.  We use an opaque file handle (not necessarily an int)
-// to allow even more low-level stuff in the future.
-// Like other "raw" routines, these functions are best effort, and
-// thus don't return error codes (except RawOpenForWriting()).
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-#ifndef NOMINMAX
-#define NOMINMAX     // @#!$& windows
-#endif
-#include <windows.h>
-typedef HANDLE RawFD;
-const RawFD kIllegalRawFD = INVALID_HANDLE_VALUE;
-#else
-typedef int RawFD;
-const RawFD kIllegalRawFD = -1;   // what open returns if it fails
-#endif  // defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-
-RawFD RawOpenForWriting(const char* filename);   // uses default permissions
-void RawWrite(RawFD fd, const char* buf, size_t len);
-void RawClose(RawFD fd);
-
-#endif // _LOGGING_H_
diff --git a/third_party/tcmalloc/vendor/src/base/low_level_alloc.cc b/third_party/tcmalloc/vendor/src/base/low_level_alloc.cc
deleted file mode 100644
index 9aa372a..0000000
--- a/third_party/tcmalloc/vendor/src/base/low_level_alloc.cc
+++ /dev/null
@@ -1,585 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// A low-level allocator that can be used by other low-level
-// modules without introducing dependency cycles.
-// This allocator is slow and wasteful of memory;
-// it should not be used when performance is key.
-
-#include "base/low_level_alloc.h"
-#include "base/dynamic_annotations.h"
-#include "base/spinlock.h"
-#include "base/logging.h"
-#include "malloc_hook-inl.h"
-#include <gperftools/malloc_hook.h>
-#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#include <new>                   // for placement-new
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-// A first-fit allocator with amortized logarithmic free() time.
-
-LowLevelAlloc::PagesAllocator::~PagesAllocator() {
-}
-
-// ---------------------------------------------------------------------------
-static const int kMaxLevel = 30;
-
-// We put this class-only struct in a namespace to avoid polluting the
-// global namespace with this struct name (thus risking an ODR violation).
-namespace low_level_alloc_internal {
-  // This struct describes one allocated block, or one free block.
-  struct AllocList {
-    struct Header {
-      intptr_t size;  // size of entire region, including this field. Must be
-                      // first.  Valid in both allocated and unallocated blocks
-      intptr_t magic; // kMagicAllocated or kMagicUnallocated xor this
-      LowLevelAlloc::Arena *arena; // pointer to parent arena
-      void *dummy_for_alignment;   // aligns regions to 0 mod 2*sizeof(void*)
-    } header;
-
-    // Next two fields: in unallocated blocks: freelist skiplist data
-    //                  in allocated blocks: overlaps with client data
-    int levels;           // levels in skiplist used
-    AllocList *next[kMaxLevel];   // actually has levels elements.
-                                  // The AllocList node may not have room for
-                                  // all kMaxLevel entries.  See max_fit in
-                                  // LLA_SkiplistLevels()
-  };
-}
-using low_level_alloc_internal::AllocList;
-
-
-// ---------------------------------------------------------------------------
-// A trivial skiplist implementation.  This is used to keep the freelist
-// in address order while taking only logarithmic time per insert and delete.
-
-// An integer approximation of log2(size/base)
-// Requires size >= base.
-static int IntLog2(size_t size, size_t base) {
-  int result = 0;
-  for (size_t i = size; i > base; i >>= 1) { // i == floor(size/2**result)
-    result++;
-  }
-  //    floor(size / 2**result) <= base < floor(size / 2**(result-1))
-  // =>     log2(size/(base+1)) <= result < 1+log2(size/base)
-  // => result ~= log2(size/base)
-  return result;
-}
-
-// Return a random integer n:  p(n)=1/(2**n) if 1 <= n; p(n)=0 if n < 1.
-static int Random() {
-  static uint32 r = 1;         // no locking---it's not critical
-  ANNOTATE_BENIGN_RACE(&r, "benign race, not critical.");
-  int result = 1;
-  while ((((r = r*1103515245 + 12345) >> 30) & 1) == 0) {
-    result++;
-  }
-  return result;
-}
-
-// Return a number of skiplist levels for a node of size bytes, where
-// base is the minimum node size.  Compute level=log2(size / base)+n
-// where n is 1 if random is false and otherwise a random number generated with
-// the standard distribution for a skiplist:  See Random() above.
-// Bigger nodes tend to have more skiplist levels due to the log2(size / base)
-// term, so first-fit searches touch fewer nodes.  "level" is clipped so
-// level<kMaxLevel and next[level-1] will fit in the node.
-// 0 < LLA_SkiplistLevels(x,y,false) <= LLA_SkiplistLevels(x,y,true) < kMaxLevel
-static int LLA_SkiplistLevels(size_t size, size_t base, bool random) {
-  // max_fit is the maximum number of levels that will fit in a node for the
-  // given size.   We can't return more than max_fit, no matter what the
-  // random number generator says.
-  int max_fit = (size-OFFSETOF_MEMBER(AllocList, next)) / sizeof (AllocList *);
-  int level = IntLog2(size, base) + (random? Random() : 1);
-  if (level > max_fit)     level = max_fit;
-  if (level > kMaxLevel-1) level = kMaxLevel - 1;
-  RAW_CHECK(level >= 1, "block not big enough for even one level");
-  return level;
-}
-
-// Return "atleast", the first element of AllocList *head s.t. *atleast >= *e.
-// For 0 <= i < head->levels, set prev[i] to "no_greater", where no_greater
-// points to the last element at level i in the AllocList less than *e, or is
-// head if no such element exists.
-static AllocList *LLA_SkiplistSearch(AllocList *head,
-                                     AllocList *e, AllocList **prev) {
-  AllocList *p = head;
-  for (int level = head->levels - 1; level >= 0; level--) {
-    for (AllocList *n; (n = p->next[level]) != 0 && n < e; p = n) {
-    }
-    prev[level] = p;
-  }
-  return (head->levels == 0) ?  0 : prev[0]->next[0];
-}
-
-// Insert element *e into AllocList *head.  Set prev[] as LLA_SkiplistSearch.
-// Requires that e->levels be previously set by the caller (using
-// LLA_SkiplistLevels())
-static void LLA_SkiplistInsert(AllocList *head, AllocList *e,
-                               AllocList **prev) {
-  LLA_SkiplistSearch(head, e, prev);
-  for (; head->levels < e->levels; head->levels++) { // extend prev pointers
-    prev[head->levels] = head;                       // to all *e's levels
-  }
-  for (int i = 0; i != e->levels; i++) { // add element to list
-    e->next[i] = prev[i]->next[i];
-    prev[i]->next[i] = e;
-  }
-}
-
-// Remove element *e from AllocList *head.  Set prev[] as LLA_SkiplistSearch().
-// Requires that e->levels be previous set by the caller (using
-// LLA_SkiplistLevels())
-static void LLA_SkiplistDelete(AllocList *head, AllocList *e,
-                               AllocList **prev) {
-  AllocList *found = LLA_SkiplistSearch(head, e, prev);
-  RAW_CHECK(e == found, "element not in freelist");
-  for (int i = 0; i != e->levels && prev[i]->next[i] == e; i++) {
-    prev[i]->next[i] = e->next[i];
-  }
-  while (head->levels > 0 && head->next[head->levels - 1] == 0) {
-    head->levels--;   // reduce head->levels if level unused
-  }
-}
-
-// ---------------------------------------------------------------------------
-// Arena implementation
-
-struct LowLevelAlloc::Arena {
-  Arena() : mu(SpinLock::LINKER_INITIALIZED) {} // does nothing; for static init
-  explicit Arena(int) : pagesize(0) {}  // set pagesize to zero explicitly
-                                        // for non-static init
-
-  SpinLock mu;            // protects freelist, allocation_count,
-                          // pagesize, roundup, min_size
-  AllocList freelist;     // head of free list; sorted by addr (under mu)
-  int32 allocation_count; // count of allocated blocks (under mu)
-  int32 flags;            // flags passed to NewArena (ro after init)
-  size_t pagesize;        // ==getpagesize()  (init under mu, then ro)
-  size_t roundup;         // lowest power of 2 >= max(16,sizeof (AllocList))
-                          // (init under mu, then ro)
-  size_t min_size;        // smallest allocation block size
-                          // (init under mu, then ro)
-  PagesAllocator *allocator;
-};
-
-// The default arena, which is used when 0 is passed instead of an Arena
-// pointer.
-static struct LowLevelAlloc::Arena default_arena;
-
-// Non-malloc-hooked arenas: used only to allocate metadata for arenas that
-// do not want malloc hook reporting, so that for them there's no malloc hook
-// reporting even during arena creation.
-static struct LowLevelAlloc::Arena unhooked_arena;
-static struct LowLevelAlloc::Arena unhooked_async_sig_safe_arena;
-
-namespace {
-
-  class DefaultPagesAllocator : public LowLevelAlloc::PagesAllocator {
-  public:
-    virtual ~DefaultPagesAllocator() {};
-    virtual void *MapPages(int32 flags, size_t size);
-    virtual void UnMapPages(int32 flags, void *addr, size_t size);
-  };
-
-}
-
-// magic numbers to identify allocated and unallocated blocks
-static const intptr_t kMagicAllocated = 0x4c833e95;
-static const intptr_t kMagicUnallocated = ~kMagicAllocated;
-
-namespace {
-  class SCOPED_LOCKABLE ArenaLock {
-   public:
-    explicit ArenaLock(LowLevelAlloc::Arena *arena)
-        EXCLUSIVE_LOCK_FUNCTION(arena->mu)
-        : left_(false), mask_valid_(false), arena_(arena) {
-      if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
-      // We've decided not to support async-signal-safe arena use until
-      // there a demonstrated need.  Here's how one could do it though
-      // (would need to be made more portable).
-#if 0
-        sigset_t all;
-        sigfillset(&all);
-        this->mask_valid_ =
-            (pthread_sigmask(SIG_BLOCK, &all, &this->mask_) == 0);
-#else
-        RAW_CHECK(false, "We do not yet support async-signal-safe arena.");
-#endif
-      }
-      this->arena_->mu.Lock();
-    }
-
-    ArenaLock(const ArenaLock&) = delete;
-    ArenaLock& operator=(const ArenaLock&) = delete;
-
-    ~ArenaLock() { RAW_CHECK(this->left_, "haven't left Arena region"); }
-    void Leave() /*UNLOCK_FUNCTION()*/ {
-      this->arena_->mu.Unlock();
-#if 0
-      if (this->mask_valid_) {
-        pthread_sigmask(SIG_SETMASK, &this->mask_, 0);
-      }
-#endif
-      this->left_ = true;
-    }
-   private:
-    bool left_;       // whether left region
-    bool mask_valid_;
-#if 0
-    sigset_t mask_;   // old mask of blocked signals
-#endif
-    LowLevelAlloc::Arena *arena_;
-  };
-} // anonymous namespace
-
-// create an appropriate magic number for an object at "ptr"
-// "magic" should be kMagicAllocated or kMagicUnallocated
-inline static intptr_t Magic(intptr_t magic, AllocList::Header *ptr) {
-  return magic ^ reinterpret_cast<intptr_t>(ptr);
-}
-
-// Initialize the fields of an Arena
-static void ArenaInit(LowLevelAlloc::Arena *arena) {
-  if (arena->pagesize == 0) {
-    arena->pagesize = getpagesize();
-    // Round up block sizes to a power of two close to the header size.
-    arena->roundup = 16;
-    while (arena->roundup < sizeof (arena->freelist.header)) {
-      arena->roundup += arena->roundup;
-    }
-    // Don't allocate blocks less than twice the roundup size to avoid tiny
-    // free blocks.
-    arena->min_size = 2 * arena->roundup;
-    arena->freelist.header.size = 0;
-    arena->freelist.header.magic =
-        Magic(kMagicUnallocated, &arena->freelist.header);
-    arena->freelist.header.arena = arena;
-    arena->freelist.levels = 0;
-    memset(arena->freelist.next, 0, sizeof (arena->freelist.next));
-    arena->allocation_count = 0;
-    if (arena == &default_arena) {
-      // Default arena should be hooked, e.g. for heap-checker to trace
-      // pointer chains through objects in the default arena.
-      arena->flags = LowLevelAlloc::kCallMallocHook;
-    } else if (arena == &unhooked_async_sig_safe_arena) {
-      arena->flags = LowLevelAlloc::kAsyncSignalSafe;
-    } else {
-      arena->flags = 0;   // other arenas' flags may be overridden by client,
-                          // but unhooked_arena will have 0 in 'flags'.
-    }
-    arena->allocator = LowLevelAlloc::GetDefaultPagesAllocator();
-  }
-}
-
-// L < meta_data_arena->mu
-LowLevelAlloc::Arena *LowLevelAlloc::NewArena(int32 flags,
-                                              Arena *meta_data_arena) {
-  return NewArenaWithCustomAlloc(flags, meta_data_arena, NULL);
-}
-
-// L < meta_data_arena->mu
-LowLevelAlloc::Arena *LowLevelAlloc::NewArenaWithCustomAlloc(int32 flags,
-                                                             Arena *meta_data_arena,
-                                                             PagesAllocator *allocator) {
-  RAW_CHECK(meta_data_arena != 0, "must pass a valid arena");
-  if (meta_data_arena == &default_arena) {
-    if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
-      meta_data_arena = &unhooked_async_sig_safe_arena;
-    } else if ((flags & LowLevelAlloc::kCallMallocHook) == 0) {
-      meta_data_arena = &unhooked_arena;
-    }
-  }
-  // Arena(0) uses the constructor for non-static contexts
-  Arena *result =
-    new (AllocWithArena(sizeof (*result), meta_data_arena)) Arena(0);
-  ArenaInit(result);
-  result->flags = flags;
-  if (allocator) {
-    result->allocator = allocator;
-  }
-  return result;
-}
-
-// L < arena->mu, L < arena->arena->mu
-bool LowLevelAlloc::DeleteArena(Arena *arena) {
-  RAW_CHECK(arena != 0 && arena != &default_arena && arena != &unhooked_arena,
-            "may not delete default arena");
-  ArenaLock section(arena);
-  bool empty = (arena->allocation_count == 0);
-  section.Leave();
-  if (empty) {
-    while (arena->freelist.next[0] != 0) {
-      AllocList *region = arena->freelist.next[0];
-      size_t size = region->header.size;
-      arena->freelist.next[0] = region->next[0];
-      RAW_CHECK(region->header.magic ==
-                Magic(kMagicUnallocated, &region->header),
-                "bad magic number in DeleteArena()");
-      RAW_CHECK(region->header.arena == arena,
-                "bad arena pointer in DeleteArena()");
-      RAW_CHECK(size % arena->pagesize == 0,
-                "empty arena has non-page-aligned block size");
-      RAW_CHECK(reinterpret_cast<intptr_t>(region) % arena->pagesize == 0,
-                "empty arena has non-page-aligned block");
-      int munmap_result;
-      if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
-        munmap_result = munmap(region, size);
-      } else {
-        munmap_result = MallocHook::UnhookedMUnmap(region, size);
-      }
-      RAW_CHECK(munmap_result == 0,
-                "LowLevelAlloc::DeleteArena:  munmap failed address");
-    }
-    Free(arena);
-  }
-  return empty;
-}
-
-// ---------------------------------------------------------------------------
-
-// Return value rounded up to next multiple of align.
-// align must be a power of two.
-static intptr_t RoundUp(intptr_t addr, intptr_t align) {
-  return (addr + align - 1) & ~(align - 1);
-}
-
-// Equivalent to "return prev->next[i]" but with sanity checking
-// that the freelist is in the correct order, that it
-// consists of regions marked "unallocated", and that no two regions
-// are adjacent in memory (they should have been coalesced).
-// L < arena->mu
-static AllocList *Next(int i, AllocList *prev, LowLevelAlloc::Arena *arena) {
-  RAW_CHECK(i < prev->levels, "too few levels in Next()");
-  AllocList *next = prev->next[i];
-  if (next != 0) {
-    RAW_CHECK(next->header.magic == Magic(kMagicUnallocated, &next->header),
-              "bad magic number in Next()");
-    RAW_CHECK(next->header.arena == arena,
-              "bad arena pointer in Next()");
-    if (prev != &arena->freelist) {
-      RAW_CHECK(prev < next, "unordered freelist");
-      RAW_CHECK(reinterpret_cast<char *>(prev) + prev->header.size <
-                reinterpret_cast<char *>(next), "malformed freelist");
-    }
-  }
-  return next;
-}
-
-// Coalesce list item "a" with its successor if they are adjacent.
-static void Coalesce(AllocList *a) {
-  AllocList *n = a->next[0];
-  if (n != 0 && reinterpret_cast<char *>(a) + a->header.size ==
-                    reinterpret_cast<char *>(n)) {
-    LowLevelAlloc::Arena *arena = a->header.arena;
-    a->header.size += n->header.size;
-    n->header.magic = 0;
-    n->header.arena = 0;
-    AllocList *prev[kMaxLevel];
-    LLA_SkiplistDelete(&arena->freelist, n, prev);
-    LLA_SkiplistDelete(&arena->freelist, a, prev);
-    a->levels = LLA_SkiplistLevels(a->header.size, arena->min_size, true);
-    LLA_SkiplistInsert(&arena->freelist, a, prev);
-  }
-}
-
-// Adds block at location "v" to the free list
-// L >= arena->mu
-static void AddToFreelist(void *v, LowLevelAlloc::Arena *arena) {
-  AllocList *f = reinterpret_cast<AllocList *>(
-                        reinterpret_cast<char *>(v) - sizeof (f->header));
-  RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
-            "bad magic number in AddToFreelist()");
-  RAW_CHECK(f->header.arena == arena,
-            "bad arena pointer in AddToFreelist()");
-  f->levels = LLA_SkiplistLevels(f->header.size, arena->min_size, true);
-  AllocList *prev[kMaxLevel];
-  LLA_SkiplistInsert(&arena->freelist, f, prev);
-  f->header.magic = Magic(kMagicUnallocated, &f->header);
-  Coalesce(f);                  // maybe coalesce with successor
-  Coalesce(prev[0]);            // maybe coalesce with predecessor
-}
-
-// Frees storage allocated by LowLevelAlloc::Alloc().
-// L < arena->mu
-void LowLevelAlloc::Free(void *v) {
-  if (v != 0) {
-    AllocList *f = reinterpret_cast<AllocList *>(
-                        reinterpret_cast<char *>(v) - sizeof (f->header));
-    RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
-              "bad magic number in Free()");
-    LowLevelAlloc::Arena *arena = f->header.arena;
-    if ((arena->flags & kCallMallocHook) != 0) {
-      MallocHook::InvokeDeleteHook(v);
-    }
-    ArenaLock section(arena);
-    AddToFreelist(v, arena);
-    RAW_CHECK(arena->allocation_count > 0, "nothing in arena to free");
-    arena->allocation_count--;
-    section.Leave();
-  }
-}
-
-// allocates and returns a block of size bytes, to be freed with Free()
-// L < arena->mu
-static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
-  void *result = 0;
-  if (request != 0) {
-    AllocList *s;       // will point to region that satisfies request
-    ArenaLock section(arena);
-    ArenaInit(arena);
-    // round up with header
-    size_t req_rnd = RoundUp(request + sizeof (s->header), arena->roundup);
-    for (;;) {      // loop until we find a suitable region
-      // find the minimum levels that a block of this size must have
-      int i = LLA_SkiplistLevels(req_rnd, arena->min_size, false) - 1;
-      if (i < arena->freelist.levels) {   // potential blocks exist
-        AllocList *before = &arena->freelist;  // predecessor of s
-        while ((s = Next(i, before, arena)) != 0 && s->header.size < req_rnd) {
-          before = s;
-        }
-        if (s != 0) {       // we found a region
-          break;
-        }
-      }
-      // we unlock before mmap() both because mmap() may call a callback hook,
-      // and because it may be slow.
-      arena->mu.Unlock();
-      // mmap generous 64K chunks to decrease
-      // the chances/impact of fragmentation:
-      size_t new_pages_size = RoundUp(req_rnd, arena->pagesize * 16);
-      void *new_pages = arena->allocator->MapPages(arena->flags, new_pages_size);
-      arena->mu.Lock();
-      s = reinterpret_cast<AllocList *>(new_pages);
-      s->header.size = new_pages_size;
-      // Pretend the block is allocated; call AddToFreelist() to free it.
-      s->header.magic = Magic(kMagicAllocated, &s->header);
-      s->header.arena = arena;
-      AddToFreelist(&s->levels, arena);  // insert new region into free list
-    }
-    AllocList *prev[kMaxLevel];
-    LLA_SkiplistDelete(&arena->freelist, s, prev);    // remove from free list
-    // s points to the first free region that's big enough
-    if (req_rnd + arena->min_size <= s->header.size) {  // big enough to split
-      AllocList *n = reinterpret_cast<AllocList *>
-                        (req_rnd + reinterpret_cast<char *>(s));
-      n->header.size = s->header.size - req_rnd;
-      n->header.magic = Magic(kMagicAllocated, &n->header);
-      n->header.arena = arena;
-      s->header.size = req_rnd;
-      AddToFreelist(&n->levels, arena);
-    }
-    s->header.magic = Magic(kMagicAllocated, &s->header);
-    RAW_CHECK(s->header.arena == arena, "");
-    arena->allocation_count++;
-    section.Leave();
-    result = &s->levels;
-  }
-  ANNOTATE_NEW_MEMORY(result, request);
-  return result;
-}
-
-void *LowLevelAlloc::Alloc(size_t request) {
-  void *result = DoAllocWithArena(request, &default_arena);
-  if ((default_arena.flags & kCallMallocHook) != 0) {
-    // this call must be directly in the user-called allocator function
-    // for MallocHook::GetCallerStackTrace to work properly
-    MallocHook::InvokeNewHook(result, request);
-  }
-  return result;
-}
-
-void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) {
-  RAW_CHECK(arena != 0, "must pass a valid arena");
-  void *result = DoAllocWithArena(request, arena);
-  if ((arena->flags & kCallMallocHook) != 0) {
-    // this call must be directly in the user-called allocator function
-    // for MallocHook::GetCallerStackTrace to work properly
-    MallocHook::InvokeNewHook(result, request);
-  }
-  return result;
-}
-
-LowLevelAlloc::Arena *LowLevelAlloc::DefaultArena() {
-  return &default_arena;
-}
-
-static DefaultPagesAllocator *default_pages_allocator;
-static union {
-  char chars[sizeof(DefaultPagesAllocator)];
-  void *ptr;
-} debug_pages_allocator_space;
-
-LowLevelAlloc::PagesAllocator *LowLevelAlloc::GetDefaultPagesAllocator(void) {
-  if (default_pages_allocator) {
-    return default_pages_allocator;
-  }
-  default_pages_allocator = new (debug_pages_allocator_space.chars) DefaultPagesAllocator();
-  return default_pages_allocator;
-}
-
-void *DefaultPagesAllocator::MapPages(int32 flags, size_t size) {
-  void *new_pages;
-  if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
-    new_pages = MallocHook::UnhookedMMap(0, size,
-                                         PROT_WRITE|PROT_READ,
-                                         MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
-  } else {
-    new_pages = mmap(0, size,
-                     PROT_WRITE|PROT_READ,
-                     MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
-  }
-  RAW_CHECK(new_pages != MAP_FAILED, "mmap error");
-
-  return new_pages;
-}
-
-void DefaultPagesAllocator::UnMapPages(int32 flags, void *region, size_t size) {
-  int munmap_result;
-  if ((flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
-    munmap_result = munmap(region, size);
-  } else {
-    munmap_result = MallocHook::UnhookedMUnmap(region, size);
-  }
-  RAW_CHECK(munmap_result == 0,
-            "LowLevelAlloc::DeleteArena: munmap failed address");
-}
diff --git a/third_party/tcmalloc/vendor/src/base/low_level_alloc.h b/third_party/tcmalloc/vendor/src/base/low_level_alloc.h
deleted file mode 100644
index d8dfc8f..0000000
--- a/third_party/tcmalloc/vendor/src/base/low_level_alloc.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if !defined(_BASE_LOW_LEVEL_ALLOC_H_)
-#define _BASE_LOW_LEVEL_ALLOC_H_
-
-// A simple thread-safe memory allocator that does not depend on
-// mutexes or thread-specific data.  It is intended to be used
-// sparingly, and only when malloc() would introduce an unwanted
-// dependency, such as inside the heap-checker.
-
-#include <config.h>
-#include <stddef.h>             // for size_t
-#include "base/basictypes.h"
-
-class LowLevelAlloc {
- public:
-  class PagesAllocator {
-  public:
-    virtual ~PagesAllocator();
-    virtual void *MapPages(int32 flags, size_t size) = 0;
-    virtual void UnMapPages(int32 flags, void *addr, size_t size) = 0;
-  };
-
-  static PagesAllocator *GetDefaultPagesAllocator(void);
-
-  struct Arena;       // an arena from which memory may be allocated
-
-  // Returns a pointer to a block of at least "request" bytes
-  // that have been newly allocated from the specific arena.
-  // for Alloc() call the DefaultArena() is used.
-  // Returns 0 if passed request==0.
-  // Does not return 0 under other circumstances; it crashes if memory
-  // is not available.
-  static void *Alloc(size_t request)
-    ATTRIBUTE_SECTION(malloc_hook);
-  static void *AllocWithArena(size_t request, Arena *arena)
-    ATTRIBUTE_SECTION(malloc_hook);
-
-  // Deallocates a region of memory that was previously allocated with
-  // Alloc().   Does nothing if passed 0.   "s" must be either 0,
-  // or must have been returned from a call to Alloc() and not yet passed to
-  // Free() since that call to Alloc().  The space is returned to the arena
-  // from which it was allocated.
-  static void Free(void *s) ATTRIBUTE_SECTION(malloc_hook);
-
-    // ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free
-    // are to put all callers of MallocHook::Invoke* in this module
-    // into special section,
-    // so that MallocHook::GetCallerStackTrace can function accurately.
-
-  // Create a new arena.
-  // The root metadata for the new arena is allocated in the
-  // meta_data_arena; the DefaultArena() can be passed for meta_data_arena.
-  // These values may be ored into flags:
-  enum {
-    // Report calls to Alloc() and Free() via the MallocHook interface.
-    // Set in the DefaultArena.
-    kCallMallocHook = 0x0001,
-
-    // Make calls to Alloc(), Free() be async-signal-safe.  Not set in
-    // DefaultArena().
-    kAsyncSignalSafe = 0x0002,
-
-    // When used with DefaultArena(), the NewArena() and DeleteArena() calls
-    // obey the flags given explicitly in the NewArena() call, even if those
-    // flags differ from the settings in DefaultArena().  So the call
-    // NewArena(kAsyncSignalSafe, DefaultArena()) is itself async-signal-safe,
-    // as well as generatating an arena that provides async-signal-safe
-    // Alloc/Free.
-  };
-  static Arena *NewArena(int32 flags, Arena *meta_data_arena);
-
-  // note: pages allocator will never be destroyed and allocated pages will never be freed
-  // When allocator is NULL, it's same as NewArena
-  static Arena *NewArenaWithCustomAlloc(int32 flags, Arena *meta_data_arena, PagesAllocator *allocator);
-
-  // Destroys an arena allocated by NewArena and returns true,
-  // provided no allocated blocks remain in the arena.
-  // If allocated blocks remain in the arena, does nothing and
-  // returns false.
-  // It is illegal to attempt to destroy the DefaultArena().
-  static bool DeleteArena(Arena *arena);
-
-  // The default arena that always exists.
-  static Arena *DefaultArena();
-
- private:
-  LowLevelAlloc();      // no instances
-};
-
-#endif
diff --git a/third_party/tcmalloc/vendor/src/base/simple_mutex.h b/third_party/tcmalloc/vendor/src/base/simple_mutex.h
deleted file mode 100644
index a1886e4..0000000
--- a/third_party/tcmalloc/vendor/src/base/simple_mutex.h
+++ /dev/null
@@ -1,332 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-// ---
-// Author: Craig Silverstein.
-//
-// A simple mutex wrapper, supporting locks and read-write locks.
-// You should assume the locks are *not* re-entrant.
-//
-// To use: you should define the following macros in your configure.ac:
-//   ACX_PTHREAD
-//   AC_RWLOCK
-// The latter is defined in ../autoconf.
-//
-// This class is meant to be internal-only and should be wrapped by an
-// internal namespace.  Before you use this module, please give the
-// name of your internal namespace for this module.  Or, if you want
-// to expose it, you'll want to move it to the Google namespace.  We
-// cannot put this class in global namespace because there can be some
-// problems when we have multiple versions of Mutex in each shared object.
-//
-// NOTE: TryLock() is broken for NO_THREADS mode, at least in NDEBUG
-//       mode.
-//
-// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy:
-//    http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html
-// Because of that, we might as well use windows locks for
-// cygwin.  They seem to be more reliable than the cygwin pthreads layer.
-//
-// TRICKY IMPLEMENTATION NOTE:
-// This class is designed to be safe to use during
-// dynamic-initialization -- that is, by global constructors that are
-// run before main() starts.  The issue in this case is that
-// dynamic-initialization happens in an unpredictable order, and it
-// could be that someone else's dynamic initializer could call a
-// function that tries to acquire this mutex -- but that all happens
-// before this mutex's constructor has run.  (This can happen even if
-// the mutex and the function that uses the mutex are in the same .cc
-// file.)  Basically, because Mutex does non-trivial work in its
-// constructor, it's not, in the naive implementation, safe to use
-// before dynamic initialization has run on it.
-//
-// The solution used here is to pair the actual mutex primitive with a
-// bool that is set to true when the mutex is dynamically initialized.
-// (Before that it's false.)  Then we modify all mutex routines to
-// look at the bool, and not try to lock/unlock until the bool makes
-// it to true (which happens after the Mutex constructor has run.)
-//
-// This works because before main() starts -- particularly, during
-// dynamic initialization -- there are no threads, so a) it's ok that
-// the mutex operations are a no-op, since we don't need locking then
-// anyway; and b) we can be quite confident our bool won't change
-// state between a call to Lock() and a call to Unlock() (that would
-// require a global constructor in one translation unit to call Lock()
-// and another global constructor in another translation unit to call
-// Unlock() later, which is pretty perverse).
-//
-// That said, it's tricky, and can conceivably fail; it's safest to
-// avoid trying to acquire a mutex in a global constructor, if you
-// can.  One way it can fail is that a really smart compiler might
-// initialize the bool to true at static-initialization time (too
-// early) rather than at dynamic-initialization time.  To discourage
-// that, we set is_safe_ to true in code (not the constructor
-// colon-initializer) and set it to true via a function that always
-// evaluates to true, but that the compiler can't know always
-// evaluates to true.  This should be good enough.
-//
-// A related issue is code that could try to access the mutex
-// after it's been destroyed in the global destructors (because
-// the Mutex global destructor runs before some other global
-// destructor, that tries to acquire the mutex).  The way we
-// deal with this is by taking a constructor arg that global
-// mutexes should pass in, that causes the destructor to do no
-// work.  We still depend on the compiler not doing anything
-// weird to a Mutex's memory after it is destroyed, but for a
-// static global variable, that's pretty safe.
-
-#ifndef GOOGLE_MUTEX_H_
-#define GOOGLE_MUTEX_H_
-
-#include <config.h>
-
-#if defined(NO_THREADS)
-  typedef int MutexType;      // to keep a lock-count
-#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-# ifndef WIN32_LEAN_AND_MEAN
-#   define WIN32_LEAN_AND_MEAN  // We only need minimal includes
-# endif
-  // We need Windows NT or later for TryEnterCriticalSection().  If you
-  // don't need that functionality, you can remove these _WIN32_WINNT
-  // lines, and change TryLock() to assert(0) or something.
-# ifndef _WIN32_WINNT
-#   define _WIN32_WINNT 0x0400
-# endif
-# include <windows.h>
-  typedef CRITICAL_SECTION MutexType;
-#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
-  // Needed for pthread_rwlock_*.  If it causes problems, you could take it
-  // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it
-  // *does* cause problems for FreeBSD, or MacOSX, but isn't needed
-  // for locking there.)
-# ifdef __linux__
-#   define _XOPEN_SOURCE 500  // may be needed to get the rwlock calls
-# endif
-# include <pthread.h>
-  typedef pthread_rwlock_t MutexType;
-#elif defined(HAVE_PTHREAD)
-# include <pthread.h>
-  typedef pthread_mutex_t MutexType;
-#else
-# error Need to implement mutex.h for your architecture, or #define NO_THREADS
-#endif
-
-#include <assert.h>
-#include <stdlib.h>      // for abort()
-
-#define MUTEX_NAMESPACE perftools_mutex_namespace
-
-namespace MUTEX_NAMESPACE {
-
-class Mutex {
- public:
-  // This is used for the single-arg constructor
-  enum LinkerInitialized { LINKER_INITIALIZED };
-
-  // Create a Mutex that is not held by anybody.  This constructor is
-  // typically used for Mutexes allocated on the heap or the stack.
-  inline Mutex();
-  // This constructor should be used for global, static Mutex objects.
-  // It inhibits work being done by the destructor, which makes it
-  // safer for code that tries to acqiure this mutex in their global
-  // destructor.
-  inline Mutex(LinkerInitialized);
-
-  // Destructor
-  inline ~Mutex();
-
-  inline void Lock();    // Block if needed until free then acquire exclusively
-  inline void Unlock();  // Release a lock acquired via Lock()
-  inline bool TryLock(); // If free, Lock() and return true, else return false
-  // Note that on systems that don't support read-write locks, these may
-  // be implemented as synonyms to Lock() and Unlock().  So you can use
-  // these for efficiency, but don't use them anyplace where being able
-  // to do shared reads is necessary to avoid deadlock.
-  inline void ReaderLock();   // Block until free or shared then acquire a share
-  inline void ReaderUnlock(); // Release a read share of this Mutex
-  inline void WriterLock() { Lock(); }     // Acquire an exclusive lock
-  inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
-
- private:
-  MutexType mutex_;
-  // We want to make sure that the compiler sets is_safe_ to true only
-  // when we tell it to, and never makes assumptions is_safe_ is
-  // always true.  volatile is the most reliable way to do that.
-  volatile bool is_safe_;
-  // This indicates which constructor was called.
-  bool destroy_;
-
-  inline void SetIsSafe() { is_safe_ = true; }
-
-  // Catch the error of writing Mutex when intending MutexLock.
-  Mutex(Mutex* /*ignored*/) {}
-  // Disallow "evil" constructors
-  Mutex(const Mutex&);
-  void operator=(const Mutex&);
-};
-
-// Now the implementation of Mutex for various systems
-#if defined(NO_THREADS)
-
-// When we don't have threads, we can be either reading or writing,
-// but not both.  We can have lots of readers at once (in no-threads
-// mode, that's most likely to happen in recursive function calls),
-// but only one writer.  We represent this by having mutex_ be -1 when
-// writing and a number > 0 when reading (and 0 when no lock is held).
-//
-// In debug mode, we assert these invariants, while in non-debug mode
-// we do nothing, for efficiency.  That's why everything is in an
-// assert.
-
-Mutex::Mutex() : mutex_(0) { }
-Mutex::Mutex(Mutex::LinkerInitialized) : mutex_(0) { }
-Mutex::~Mutex()            { assert(mutex_ == 0); }
-void Mutex::Lock()         { assert(--mutex_ == -1); }
-void Mutex::Unlock()       { assert(mutex_++ == -1); }
-bool Mutex::TryLock()      { if (mutex_) return false; Lock(); return true; }
-void Mutex::ReaderLock()   { assert(++mutex_ > 0); }
-void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
-
-#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-
-Mutex::Mutex() : destroy_(true) {
-  InitializeCriticalSection(&mutex_);
-  SetIsSafe();
-}
-Mutex::Mutex(LinkerInitialized) : destroy_(false) {
-  InitializeCriticalSection(&mutex_);
-  SetIsSafe();
-}
-Mutex::~Mutex()            { if (destroy_) DeleteCriticalSection(&mutex_); }
-void Mutex::Lock()         { if (is_safe_) EnterCriticalSection(&mutex_); }
-void Mutex::Unlock()       { if (is_safe_) LeaveCriticalSection(&mutex_); }
-bool Mutex::TryLock()      { return is_safe_ ?
-                                 TryEnterCriticalSection(&mutex_) != 0 : true; }
-void Mutex::ReaderLock()   { Lock(); }      // we don't have read-write locks
-void Mutex::ReaderUnlock() { Unlock(); }
-
-#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
-
-#define SAFE_PTHREAD(fncall)  do {   /* run fncall if is_safe_ is true */  \
-  if (is_safe_ && fncall(&mutex_) != 0) abort();                           \
-} while (0)
-
-Mutex::Mutex() : destroy_(true) {
-  SetIsSafe();
-  if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
-}
-Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
-  SetIsSafe();
-  if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
-}
-Mutex::~Mutex()       { if (destroy_) SAFE_PTHREAD(pthread_rwlock_destroy); }
-void Mutex::Lock()         { SAFE_PTHREAD(pthread_rwlock_wrlock); }
-void Mutex::Unlock()       { SAFE_PTHREAD(pthread_rwlock_unlock); }
-bool Mutex::TryLock()      { return is_safe_ ?
-                               pthread_rwlock_trywrlock(&mutex_) == 0 : true; }
-void Mutex::ReaderLock()   { SAFE_PTHREAD(pthread_rwlock_rdlock); }
-void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
-#undef SAFE_PTHREAD
-
-#elif defined(HAVE_PTHREAD)
-
-#define SAFE_PTHREAD(fncall)  do {   /* run fncall if is_safe_ is true */  \
-  if (is_safe_ && fncall(&mutex_) != 0) abort();                           \
-} while (0)
-
-Mutex::Mutex() : destroy_(true) {
-  SetIsSafe();
-  if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
-}
-Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
-  SetIsSafe();
-  if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
-}
-Mutex::~Mutex()       { if (destroy_) SAFE_PTHREAD(pthread_mutex_destroy); }
-void Mutex::Lock()         { SAFE_PTHREAD(pthread_mutex_lock); }
-void Mutex::Unlock()       { SAFE_PTHREAD(pthread_mutex_unlock); }
-bool Mutex::TryLock()      { return is_safe_ ?
-                                 pthread_mutex_trylock(&mutex_) == 0 : true; }
-void Mutex::ReaderLock()   { Lock(); }
-void Mutex::ReaderUnlock() { Unlock(); }
-#undef SAFE_PTHREAD
-
-#endif
-
-// --------------------------------------------------------------------------
-// Some helper classes
-
-// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
-class MutexLock {
- public:
-  explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
-  ~MutexLock() { mu_->Unlock(); }
- private:
-  Mutex * const mu_;
-  // Disallow "evil" constructors
-  MutexLock(const MutexLock&);
-  void operator=(const MutexLock&);
-};
-
-// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
-class ReaderMutexLock {
- public:
-  explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
-  ~ReaderMutexLock() { mu_->ReaderUnlock(); }
- private:
-  Mutex * const mu_;
-  // Disallow "evil" constructors
-  ReaderMutexLock(const ReaderMutexLock&);
-  void operator=(const ReaderMutexLock&);
-};
-
-class WriterMutexLock {
- public:
-  explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
-  ~WriterMutexLock() { mu_->WriterUnlock(); }
- private:
-  Mutex * const mu_;
-  // Disallow "evil" constructors
-  WriterMutexLock(const WriterMutexLock&);
-  void operator=(const WriterMutexLock&);
-};
-
-// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
-#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
-#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)
-#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)
-
-}  // namespace MUTEX_NAMESPACE
-
-using namespace MUTEX_NAMESPACE;
-
-#undef MUTEX_NAMESPACE
-
-#endif  /* #define GOOGLE_SIMPLE_MUTEX_H_ */
diff --git a/third_party/tcmalloc/vendor/src/base/spinlock.cc b/third_party/tcmalloc/vendor/src/base/spinlock.cc
deleted file mode 100644
index 85ff21ed..0000000
--- a/third_party/tcmalloc/vendor/src/base/spinlock.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-#include <config.h>
-#include "base/spinlock.h"
-#include "base/spinlock_internal.h"
-#include "base/sysinfo.h"   /* for GetSystemCPUsCount() */
-
-// NOTE on the Lock-state values:
-//
-// kSpinLockFree represents the unlocked state
-// kSpinLockHeld represents the locked state with no waiters
-// kSpinLockSleeper represents the locked state with waiters
-
-static int adaptive_spin_count = 0;
-
-const base::LinkerInitialized SpinLock::LINKER_INITIALIZED =
-    base::LINKER_INITIALIZED;
-
-namespace {
-struct SpinLock_InitHelper {
-  SpinLock_InitHelper() {
-    // On multi-cpu machines, spin for longer before yielding
-    // the processor or sleeping.  Reduces idle time significantly.
-    if (GetSystemCPUsCount() > 1) {
-      adaptive_spin_count = 1000;
-    }
-  }
-};
-
-// Hook into global constructor execution:
-// We do not do adaptive spinning before that,
-// but nothing lock-intensive should be going on at that time.
-static SpinLock_InitHelper init_helper;
-
-inline void SpinlockPause(void) {
-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-  __asm__ __volatile__("rep; nop" : : );
-#endif
-}
-
-}  // unnamed namespace
-
-// Monitor the lock to see if its value changes within some time
-// period (adaptive_spin_count loop iterations). The last value read
-// from the lock is returned from the method.
-Atomic32 SpinLock::SpinLoop() {
-  int c = adaptive_spin_count;
-  while (base::subtle::NoBarrier_Load(&lockword_) != kSpinLockFree && --c > 0) {
-    SpinlockPause();
-  }
-  return base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                              kSpinLockSleeper);
-}
-
-void SpinLock::SlowLock() {
-  Atomic32 lock_value = SpinLoop();
-
-  int lock_wait_call_count = 0;
-  while (lock_value != kSpinLockFree) {
-    // If the lock is currently held, but not marked as having a sleeper, mark
-    // it as having a sleeper.
-    if (lock_value == kSpinLockHeld) {
-      // Here, just "mark" that the thread is going to sleep.  Don't store the
-      // lock wait time in the lock as that will cause the current lock
-      // owner to think it experienced contention.
-      lock_value = base::subtle::Acquire_CompareAndSwap(&lockword_,
-                                                        kSpinLockHeld,
-                                                        kSpinLockSleeper);
-      if (lock_value == kSpinLockHeld) {
-        // Successfully transitioned to kSpinLockSleeper.  Pass
-        // kSpinLockSleeper to the SpinLockDelay routine to properly indicate
-        // the last lock_value observed.
-        lock_value = kSpinLockSleeper;
-      } else if (lock_value == kSpinLockFree) {
-        // Lock is free again, so try and acquire it before sleeping.  The
-        // new lock state will be the number of cycles this thread waited if
-        // this thread obtains the lock.
-        lock_value = base::subtle::Acquire_CompareAndSwap(&lockword_,
-                                                          kSpinLockFree,
-                                                          kSpinLockSleeper);
-        continue;  // skip the delay at the end of the loop
-      }
-    }
-
-    // Wait for an OS specific delay.
-    base::internal::SpinLockDelay(&lockword_, lock_value,
-                                  ++lock_wait_call_count);
-    // Spin again after returning from the wait routine to give this thread
-    // some chance of obtaining the lock.
-    lock_value = SpinLoop();
-  }
-}
-
-void SpinLock::SlowUnlock() {
-  // wake waiter if necessary
-  base::internal::SpinLockWake(&lockword_, false);
-}
diff --git a/third_party/tcmalloc/vendor/src/base/spinlock.h b/third_party/tcmalloc/vendor/src/base/spinlock.h
deleted file mode 100644
index 7243aeaa..0000000
--- a/third_party/tcmalloc/vendor/src/base/spinlock.h
+++ /dev/null
@@ -1,143 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-// SpinLock is async signal safe.
-// If used within a signal handler, all lock holders
-// should block the signal even outside the signal handler.
-
-#ifndef BASE_SPINLOCK_H_
-#define BASE_SPINLOCK_H_
-
-#include <config.h>
-#include "base/atomicops.h"
-#include "base/basictypes.h"
-#include "base/dynamic_annotations.h"
-#include "base/thread_annotations.h"
-
-class LOCKABLE SpinLock {
- public:
-  SpinLock() : lockword_(kSpinLockFree) { }
-
-  // Special constructor for use with static SpinLock objects.  E.g.,
-  //
-  //    static SpinLock lock(base::LINKER_INITIALIZED);
-  //
-  // When intialized using this constructor, we depend on the fact
-  // that the linker has already initialized the memory appropriately.
-  // A SpinLock constructed like this can be freely used from global
-  // initializers without worrying about the order in which global
-  // initializers run.
-  explicit SpinLock(base::LinkerInitialized /*x*/) {
-    // Does nothing; lockword_ is already initialized
-  }
-
-  // Acquire this SpinLock.
-  // TODO(csilvers): uncomment the annotation when we figure out how to
-  //                 support this macro with 0 args (see thread_annotations.h)
-  inline void Lock() /*EXCLUSIVE_LOCK_FUNCTION()*/ {
-    if (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                             kSpinLockHeld) != kSpinLockFree) {
-      SlowLock();
-    }
-    ANNOTATE_RWLOCK_ACQUIRED(this, 1);
-  }
-
-  // Try to acquire this SpinLock without blocking and return true if the
-  // acquisition was successful.  If the lock was not acquired, false is
-  // returned.  If this SpinLock is free at the time of the call, TryLock
-  // will return true with high probability.
-  inline bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) {
-    bool res =
-        (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                              kSpinLockHeld) == kSpinLockFree);
-    if (res) {
-      ANNOTATE_RWLOCK_ACQUIRED(this, 1);
-    }
-    return res;
-  }
-
-  // Release this SpinLock, which must be held by the calling thread.
-  // TODO(csilvers): uncomment the annotation when we figure out how to
-  //                 support this macro with 0 args (see thread_annotations.h)
-  inline void Unlock() /*UNLOCK_FUNCTION()*/ {
-    ANNOTATE_RWLOCK_RELEASED(this, 1);
-    uint64 prev_value = static_cast<uint64>(
-        base::subtle::Release_AtomicExchange(&lockword_, kSpinLockFree));
-    if (prev_value != kSpinLockHeld) {
-      // Speed the wakeup of any waiter.
-      SlowUnlock();
-    }
-  }
-
-  // Determine if the lock is held.  When the lock is held by the invoking
-  // thread, true will always be returned. Intended to be used as
-  // CHECK(lock.IsHeld()).
-  inline bool IsHeld() const {
-    return base::subtle::NoBarrier_Load(&lockword_) != kSpinLockFree;
-  }
-
-  static const base::LinkerInitialized LINKER_INITIALIZED;  // backwards compat
- private:
-  enum { kSpinLockFree = 0 };
-  enum { kSpinLockHeld = 1 };
-  enum { kSpinLockSleeper = 2 };
-
-  volatile Atomic32 lockword_;
-
-  void SlowLock();
-  void SlowUnlock();
-  Atomic32 SpinLoop();
-
-  DISALLOW_COPY_AND_ASSIGN(SpinLock);
-};
-
-// Corresponding locker object that arranges to acquire a spinlock for
-// the duration of a C++ scope.
-class SCOPED_LOCKABLE SpinLockHolder {
- private:
-  SpinLock* lock_;
- public:
-  inline explicit SpinLockHolder(SpinLock* l) EXCLUSIVE_LOCK_FUNCTION(l)
-      : lock_(l) {
-    l->Lock();
-  }
-  // TODO(csilvers): uncomment the annotation when we figure out how to
-  //                 support this macro with 0 args (see thread_annotations.h)
-  inline ~SpinLockHolder() /*UNLOCK_FUNCTION()*/ { lock_->Unlock(); }
-};
-// Catch bug where variable name is omitted, e.g. SpinLockHolder (&lock);
-#define SpinLockHolder(x) COMPILE_ASSERT(0, spin_lock_decl_missing_var_name)
-
-
-#endif  // BASE_SPINLOCK_H_
diff --git a/third_party/tcmalloc/vendor/src/base/spinlock_internal.cc b/third_party/tcmalloc/vendor/src/base/spinlock_internal.cc
deleted file mode 100644
index d962971..0000000
--- a/third_party/tcmalloc/vendor/src/base/spinlock_internal.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2010, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// The OS-specific header included below must provide two calls:
-// base::internal::SpinLockDelay() and base::internal::SpinLockWake().
-// See spinlock_internal.h for the spec of SpinLockWake().
-
-// void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop)
-// SpinLockDelay() generates an apprproate spin delay on iteration "loop" of a
-// spin loop on location *w, whose previously observed value was "value".
-// SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick,
-// or may wait for a delay that can be truncated by a call to SpinlockWake(w).
-// In all cases, it must return in bounded time even if SpinlockWake() is not
-// called.
-
-#include "base/spinlock_internal.h"
-
-// forward declaration for use by spinlock_*-inl.h
-namespace base { namespace internal { static int SuggestedDelayNS(int loop); }}
-
-#if defined(_WIN32)
-#include "base/spinlock_win32-inl.h"
-#elif defined(__linux__)
-#include "base/spinlock_linux-inl.h"
-#else
-#include "base/spinlock_posix-inl.h"
-#endif
-
-namespace base {
-namespace internal {
-
-// Return a suggested delay in nanoseconds for iteration number "loop"
-static int SuggestedDelayNS(int loop) {
-  // Weak pseudo-random number generator to get some spread between threads
-  // when many are spinning.
-#ifdef BASE_HAS_ATOMIC64
-  static base::subtle::Atomic64 rand;
-  uint64 r = base::subtle::NoBarrier_Load(&rand);
-  r = 0x5deece66dLL * r + 0xb;   // numbers from nrand48()
-  base::subtle::NoBarrier_Store(&rand, r);
-
-  r <<= 16;   // 48-bit random number now in top 48-bits.
-  if (loop < 0 || loop > 32) {   // limit loop to 0..32
-    loop = 32;
-  }
-  // loop>>3 cannot exceed 4 because loop cannot exceed 32.
-  // Select top 20..24 bits of lower 48 bits,
-  // giving approximately 0ms to 16ms.
-  // Mean is exponential in loop for first 32 iterations, then 8ms.
-  // The futex path multiplies this by 16, since we expect explicit wakeups
-  // almost always on that path.
-  return r >> (44 - (loop >> 3));
-#else
-  static Atomic32 rand;
-  uint32 r = base::subtle::NoBarrier_Load(&rand);
-  r = 0x343fd * r + 0x269ec3;   // numbers from MSVC++
-  base::subtle::NoBarrier_Store(&rand, r);
-
-  r <<= 1;   // 31-bit random number now in top 31-bits.
-  if (loop < 0 || loop > 32) {   // limit loop to 0..32
-    loop = 32;
-  }
-  // loop>>3 cannot exceed 4 because loop cannot exceed 32.
-  // Select top 20..24 bits of lower 31 bits,
-  // giving approximately 0ms to 16ms.
-  // Mean is exponential in loop for first 32 iterations, then 8ms.
-  // The futex path multiplies this by 16, since we expect explicit wakeups
-  // almost always on that path.
-  return r >> (12 - (loop >> 3));
-#endif
-}
-
-} // namespace internal
-} // namespace base
diff --git a/third_party/tcmalloc/vendor/src/base/spinlock_internal.h b/third_party/tcmalloc/vendor/src/base/spinlock_internal.h
deleted file mode 100644
index aa47e67d..0000000
--- a/third_party/tcmalloc/vendor/src/base/spinlock_internal.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2010, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This file is an internal part spinlock.cc and once.cc
- * It may not be used directly by code outside of //base.
- */
-
-#ifndef BASE_SPINLOCK_INTERNAL_H_
-#define BASE_SPINLOCK_INTERNAL_H_
-
-#include <config.h>
-#include "base/basictypes.h"
-#include "base/atomicops.h"
-
-namespace base {
-namespace internal {
-
-void SpinLockWake(volatile Atomic32 *w, bool all);
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop);
-
-} // namespace internal
-} // namespace base
-#endif
diff --git a/third_party/tcmalloc/vendor/src/base/spinlock_linux-inl.h b/third_party/tcmalloc/vendor/src/base/spinlock_linux-inl.h
deleted file mode 100644
index aadf62a..0000000
--- a/third_party/tcmalloc/vendor/src/base/spinlock_linux-inl.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This file is a Linux-specific part of spinlock_internal.cc
- */
-
-#include <errno.h>
-#include <sched.h>
-#include <time.h>
-#include <limits.h>
-#include "base/linux_syscall_support.h"
-
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-#define FUTEX_PRIVATE_FLAG 128
-
-static bool have_futex;
-static int futex_private_flag = FUTEX_PRIVATE_FLAG;
-
-namespace {
-static struct InitModule {
-  InitModule() {
-    int x = 0;
-    // futexes are ints, so we can use them only when
-    // that's the same size as the lockword_ in SpinLock.
-    have_futex = (sizeof (Atomic32) == sizeof (int) &&
-                  sys_futex(&x, FUTEX_WAKE, 1, NULL, NULL, 0) >= 0);
-    if (have_futex &&
-        sys_futex(&x, FUTEX_WAKE | futex_private_flag, 1, NULL, NULL, 0) < 0) {
-      futex_private_flag = 0;
-    }
-  }
-} init_module;
-
-}  // anonymous namespace
-
-
-namespace base {
-namespace internal {
-
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
-  if (loop != 0) {
-    int save_errno = errno;
-    struct timespec tm;
-    tm.tv_sec = 0;
-    if (have_futex) {
-      tm.tv_nsec = base::internal::SuggestedDelayNS(loop);
-    } else {
-      tm.tv_nsec = 2000001;   // above 2ms so linux 2.4 doesn't spin
-    }
-    if (have_futex) {
-      tm.tv_nsec *= 16;  // increase the delay; we expect explicit wakeups
-      sys_futex(reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
-                FUTEX_WAIT | futex_private_flag,
-                value, reinterpret_cast<struct kernel_timespec *>(&tm),
-                NULL, 0);
-    } else {
-      nanosleep(&tm, NULL);
-    }
-    errno = save_errno;
-  }
-}
-
-void SpinLockWake(volatile Atomic32 *w, bool all) {
-  if (have_futex) {
-    sys_futex(reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
-              FUTEX_WAKE | futex_private_flag, all? INT_MAX : 1,
-              NULL, NULL, 0);
-  }
-}
-
-} // namespace internal
-} // namespace base
diff --git a/third_party/tcmalloc/vendor/src/base/spinlock_posix-inl.h b/third_party/tcmalloc/vendor/src/base/spinlock_posix-inl.h
deleted file mode 100644
index e73a30fb..0000000
--- a/third_party/tcmalloc/vendor/src/base/spinlock_posix-inl.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This file is a Posix-specific part of spinlock_internal.cc
- */
-
-#include <config.h>
-#include <errno.h>
-#ifdef HAVE_SCHED_H
-#include <sched.h>      /* For sched_yield() */
-#endif
-#include <time.h>       /* For nanosleep() */
-
-namespace base {
-namespace internal {
-
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
-  int save_errno = errno;
-  if (loop == 0) {
-  } else if (loop == 1) {
-    sched_yield();
-  } else {
-    struct timespec tm;
-    tm.tv_sec = 0;
-    tm.tv_nsec = base::internal::SuggestedDelayNS(loop);
-    nanosleep(&tm, NULL);
-  }
-  errno = save_errno;
-}
-
-void SpinLockWake(volatile Atomic32 *w, bool all) {
-}
-
-} // namespace internal
-} // namespace base
diff --git a/third_party/tcmalloc/vendor/src/base/spinlock_win32-inl.h b/third_party/tcmalloc/vendor/src/base/spinlock_win32-inl.h
deleted file mode 100644
index 956b9653..0000000
--- a/third_party/tcmalloc/vendor/src/base/spinlock_win32-inl.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * This file is a Win32-specific part of spinlock_internal.cc
- */
-
-
-#include <windows.h>
-
-namespace base {
-namespace internal {
-
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
-  if (loop == 0) {
-  } else if (loop == 1) {
-    Sleep(0);
-  } else {
-    Sleep(base::internal::SuggestedDelayNS(loop) / 1000000);
-  }
-}
-
-void SpinLockWake(volatile Atomic32 *w, bool all) {
-}
-
-} // namespace internal
-} // namespace base
diff --git a/third_party/tcmalloc/vendor/src/base/stl_allocator.h b/third_party/tcmalloc/vendor/src/base/stl_allocator.h
deleted file mode 100644
index 2345f46..0000000
--- a/third_party/tcmalloc/vendor/src/base/stl_allocator.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Maxim Lifantsev
- */
-
-
-#ifndef BASE_STL_ALLOCATOR_H_
-#define BASE_STL_ALLOCATOR_H_
-
-#include <config.h>
-
-#include <stddef.h>   // for ptrdiff_t
-#include <limits>
-
-#include "base/logging.h"
-
-// Generic allocator class for STL objects
-// that uses a given type-less allocator Alloc, which must provide:
-//   static void* Alloc::Allocate(size_t size);
-//   static void Alloc::Free(void* ptr, size_t size);
-//
-// STL_Allocator<T, MyAlloc> provides the same thread-safety
-// guarantees as MyAlloc.
-//
-// Usage example:
-//   set<T, less<T>, STL_Allocator<T, MyAlloc> > my_set;
-// CAVEAT: Parts of the code below are probably specific
-//         to the STL version(s) we are using.
-//         The code is simply lifted from what std::allocator<> provides.
-template <typename T, class Alloc>
-class STL_Allocator {
- public:
-  typedef size_t     size_type;
-  typedef ptrdiff_t  difference_type;
-  typedef T*         pointer;
-  typedef const T*   const_pointer;
-  typedef T&         reference;
-  typedef const T&   const_reference;
-  typedef T          value_type;
-
-  template <class T1> struct rebind {
-    typedef STL_Allocator<T1, Alloc> other;
-  };
-
-  STL_Allocator() { }
-  STL_Allocator(const STL_Allocator&) { }
-  template <class T1> STL_Allocator(const STL_Allocator<T1, Alloc>&) { }
-  ~STL_Allocator() { }
-
-  pointer address(reference x) const { return &x; }
-  const_pointer address(const_reference x) const { return &x; }
-
-  pointer allocate(size_type n, const void* = 0) {
-    RAW_DCHECK((n * sizeof(T)) / sizeof(T) == n, "n is too big to allocate");
-    return static_cast<T*>(Alloc::Allocate(n * sizeof(T)));
-  }
-  void deallocate(pointer p, size_type n) { Alloc::Free(p, n * sizeof(T)); }
-
-  size_type max_size() const { return size_t(-1) / sizeof(T); }
-
-  void construct(pointer p, const T& val) { ::new(p) T(val); }
-  void construct(pointer p) { ::new(p) T(); }
-  void destroy(pointer p) { p->~T(); }
-
-  // There's no state, so these allocators are always equal
-  bool operator==(const STL_Allocator&) const { return true; }
-};
-
-#endif  // BASE_STL_ALLOCATOR_H_
diff --git a/third_party/tcmalloc/vendor/src/base/sysinfo.cc b/third_party/tcmalloc/vendor/src/base/sysinfo.cc
deleted file mode 100644
index 36f70679..0000000
--- a/third_party/tcmalloc/vendor/src/base/sysinfo.cc
+++ /dev/null
@@ -1,891 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <config.h>
-#if (defined(_WIN32) || defined(__MINGW32__)) && !defined(__CYGWIN__) && !defined(__CYGWIN32)
-# define PLATFORM_WINDOWS 1
-#endif
-
-#include <ctype.h>    // for isspace()
-#include <stdlib.h>   // for getenv()
-#include <stdio.h>    // for snprintf(), sscanf()
-#include <string.h>   // for memmove(), memchr(), etc.
-#include <fcntl.h>    // for open()
-#include <errno.h>    // for errno
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>   // for read()
-#endif
-#if defined __MACH__          // Mac OS X, almost certainly
-#include <mach-o/dyld.h>      // for iterating over dll's in ProcMapsIter
-#include <mach-o/loader.h>    // for iterating over dll's in ProcMapsIter
-#include <sys/types.h>
-#include <sys/sysctl.h>       // how we figure out numcpu's on OS X
-#elif defined __FreeBSD__
-#include <sys/sysctl.h>
-#elif defined __sun__         // Solaris
-#include <procfs.h>           // for, e.g., prmap_t
-#elif defined(PLATFORM_WINDOWS)
-#include <process.h>          // for getpid() (actually, _getpid())
-#include <shlwapi.h>          // for SHGetValueA()
-#include <tlhelp32.h>         // for Module32First()
-#endif
-#include "base/sysinfo.h"
-#include "base/commandlineflags.h"
-#include "base/dynamic_annotations.h"   // for RunningOnValgrind
-#include "base/logging.h"
-
-#ifdef PLATFORM_WINDOWS
-#ifdef MODULEENTRY32
-// In a change from the usual W-A pattern, there is no A variant of
-// MODULEENTRY32.  Tlhelp32.h #defines the W variant, but not the A.
-// In unicode mode, tlhelp32.h #defines MODULEENTRY32 to be
-// MODULEENTRY32W.  These #undefs are the only way I see to get back
-// access to the original, ascii struct (and related functions).
-#undef MODULEENTRY32
-#undef Module32First
-#undef Module32Next
-#undef PMODULEENTRY32
-#undef LPMODULEENTRY32
-#endif  /* MODULEENTRY32 */
-// MinGW doesn't seem to define this, perhaps some windowsen don't either.
-#ifndef TH32CS_SNAPMODULE32
-#define TH32CS_SNAPMODULE32  0
-#endif  /* TH32CS_SNAPMODULE32 */
-#endif  /* PLATFORM_WINDOWS */
-
-// Re-run fn until it doesn't cause EINTR.
-#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)
-
-// open/read/close can set errno, which may be illegal at this
-// time, so prefer making the syscalls directly if we can.
-#ifdef HAVE_SYS_SYSCALL_H
-# include <sys/syscall.h>
-#endif
-#ifdef SYS_open   // solaris 11, at least sometimes, only defines SYS_openat
-# define safeopen(filename, mode)  syscall(SYS_open, filename, mode)
-#else
-# define safeopen(filename, mode)  open(filename, mode)
-#endif
-#ifdef SYS_read
-# define saferead(fd, buffer, size)  syscall(SYS_read, fd, buffer, size)
-#else
-# define saferead(fd, buffer, size)  read(fd, buffer, size)
-#endif
-#ifdef SYS_close
-# define safeclose(fd)  syscall(SYS_close, fd)
-#else
-# define safeclose(fd)  close(fd)
-#endif
-
-// ----------------------------------------------------------------------
-// GetenvBeforeMain()
-// GetUniquePathFromEnv()
-//    Some non-trivial getenv-related functions.
-// ----------------------------------------------------------------------
-
-// we reimplement memcmp and friends to avoid depending on any glibc
-// calls too early in the process lifetime. This allows us to use
-// GetenvBeforeMain from inside ifunc handler
-static int slow_memcmp(const void *_a, const void *_b, size_t n) {
-  const uint8_t *a = reinterpret_cast<const uint8_t *>(_a);
-  const uint8_t *b = reinterpret_cast<const uint8_t *>(_b);
-  while (n-- != 0) {
-    uint8_t ac = *a++;
-    uint8_t bc = *b++;
-    if (ac != bc) {
-      if (ac < bc) {
-        return -1;
-      }
-      return 1;
-    }
-  }
-  return 0;
-}
-
-static const char *slow_memchr(const char *s, int c, size_t n) {
-  uint8_t ch = static_cast<uint8_t>(c);
-  while (n--) {
-    if (*s++ == ch) {
-      return s - 1;
-    }
-  }
-  return 0;
-}
-
-static size_t slow_strlen(const char *s) {
-  const char *s2 = slow_memchr(s, '\0', static_cast<size_t>(-1));
-  return s2 - s;
-}
-
-// It's not safe to call getenv() in the malloc hooks, because they
-// might be called extremely early, before libc is done setting up
-// correctly.  In particular, the thread library may not be done
-// setting up errno.  So instead, we use the built-in __environ array
-// if it exists, and otherwise read /proc/self/environ directly, using
-// system calls to read the file, and thus avoid setting errno.
-// /proc/self/environ has a limit of how much data it exports (around
-// 8K), so it's not an ideal solution.
-const char* GetenvBeforeMain(const char* name) {
-  const int namelen = slow_strlen(name);
-#if defined(HAVE___ENVIRON)   // if we have it, it's declared in unistd.h
-  if (__environ) {            // can exist but be NULL, if statically linked
-    for (char** p = __environ; *p; p++) {
-      if (!slow_memcmp(*p, name, namelen) && (*p)[namelen] == '=')
-        return *p + namelen+1;
-    }
-    return NULL;
-  }
-#endif
-#if defined(PLATFORM_WINDOWS)
-  // TODO(mbelshe) - repeated calls to this function will overwrite the
-  // contents of the static buffer.
-  static char envvar_buf[1024];  // enough to hold any envvar we care about
-  if (!GetEnvironmentVariableA(name, envvar_buf, sizeof(envvar_buf)-1))
-    return NULL;
-  return envvar_buf;
-#endif
-  // static is ok because this function should only be called before
-  // main(), when we're single-threaded.
-  static char envbuf[16<<10];
-  if (*envbuf == '\0') {    // haven't read the environ yet
-    int fd = safeopen("/proc/self/environ", O_RDONLY);
-    // The -2 below guarantees the last two bytes of the buffer will be \0\0
-    if (fd == -1 ||           // unable to open the file, fall back onto libc
-        saferead(fd, envbuf, sizeof(envbuf) - 2) < 0) { // error reading file
-      RAW_VLOG(1, "Unable to open /proc/self/environ, falling back "
-               "on getenv(\"%s\"), which may not work", name);
-      if (fd != -1) safeclose(fd);
-      return getenv(name);
-    }
-    safeclose(fd);
-  }
-  const char* p = envbuf;
-  while (*p != '\0') {    // will happen at the \0\0 that terminates the buffer
-    // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
-    const char* endp = (char*)slow_memchr(p, '\0',
-                                          sizeof(envbuf) - (p - envbuf));
-    if (endp == NULL)            // this entry isn't NUL terminated
-      return NULL;
-    else if (!slow_memcmp(p, name, namelen) && p[namelen] == '=')    // it's a match
-      return p + namelen+1;      // point after =
-    p = endp + 1;
-  }
-  return NULL;                   // env var never found
-}
-
-extern "C" {
-  const char* TCMallocGetenvSafe(const char* name) {
-    return GetenvBeforeMain(name);
-  }
-}
-
-// This takes as an argument an environment-variable name (like
-// CPUPROFILE) whose value is supposed to be a file-path, and sets
-// path to that path, and returns true.  If the env var doesn't exist,
-// or is the empty string, leave path unchanged and returns false.
-// The reason this is non-trivial is that this function handles munged
-// pathnames.  Here's why:
-//
-// If we're a child process of the 'main' process, we can't just use
-// getenv("CPUPROFILE") -- the parent process will be using that path.
-// Instead we append our pid to the pathname.  How do we tell if we're a
-// child process?  Ideally we'd set an environment variable that all
-// our children would inherit.  But -- and this is seemingly a bug in
-// gcc -- if you do a setenv() in a shared libarary in a global
-// constructor, the environment setting is lost by the time main() is
-// called.  The only safe thing we can do in such a situation is to
-// modify the existing envvar.  So we do a hack: in the parent, we set
-// the high bit of the 1st char of CPUPROFILE.  In the child, we
-// notice the high bit is set and append the pid().  This works
-// assuming cpuprofile filenames don't normally have the high bit set
-// in their first character!  If that assumption is violated, we'll
-// still get a profile, but one with an unexpected name.
-// TODO(csilvers): set an envvar instead when we can do it reliably.
-bool GetUniquePathFromEnv(const char* env_name, char* path) {
-  char* envval = getenv(env_name);
-  if (envval == NULL || *envval == '\0')
-    return false;
-  if (envval[0] & 128) {                  // high bit is set
-    snprintf(path, PATH_MAX, "%c%s_%u",   // add pid and clear high bit
-             envval[0] & 127, envval+1, (unsigned int)(getpid()));
-  } else {
-    snprintf(path, PATH_MAX, "%s", envval);
-    envval[0] |= 128;                     // set high bit for kids to see
-  }
-  return true;
-}
-
-void SleepForMilliseconds(int milliseconds) {
-#ifdef PLATFORM_WINDOWS
-  _sleep(milliseconds);   // Windows's _sleep takes milliseconds argument
-#else
-  // Sleep for a few milliseconds
-  struct timespec sleep_time;
-  sleep_time.tv_sec = milliseconds / 1000;
-  sleep_time.tv_nsec = (milliseconds % 1000) * 1000000;
-  while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR)
-    ;  // Ignore signals and wait for the full interval to elapse.
-#endif
-}
-
-int GetSystemCPUsCount()
-{
-#if defined(PLATFORM_WINDOWS)
-  // Get the number of processors.
-  SYSTEM_INFO info;
-  GetSystemInfo(&info);
-  return  info.dwNumberOfProcessors;
-#else
-  long rv = sysconf(_SC_NPROCESSORS_ONLN);
-  if (rv < 0) {
-    return 1;
-  }
-  return static_cast<int>(rv);
-#endif
-}
-
-// ----------------------------------------------------------------------
-
-#if defined __linux__ || defined __FreeBSD__ || defined __sun__ || defined __CYGWIN__ || defined __CYGWIN32__
-static void ConstructFilename(const char* spec, pid_t pid,
-                              char* buf, int buf_size) {
-  CHECK_LT(snprintf(buf, buf_size,
-                    spec,
-                    static_cast<int>(pid ? pid : getpid())), buf_size);
-}
-#endif
-
-// A templatized helper function instantiated for Mach (OS X) only.
-// It can handle finding info for both 32 bits and 64 bits.
-// Returns true if it successfully handled the hdr, false else.
-#ifdef __MACH__          // Mac OS X, almost certainly
-template<uint32_t kMagic, uint32_t kLCSegment,
-         typename MachHeader, typename SegmentCommand>
-static bool NextExtMachHelper(const mach_header* hdr,
-                              int current_image, int current_load_cmd,
-                              uint64 *start, uint64 *end, char **flags,
-                              uint64 *offset, int64 *inode, char **filename,
-                              uint64 *file_mapping, uint64 *file_pages,
-                              uint64 *anon_mapping, uint64 *anon_pages,
-                              dev_t *dev) {
-  static char kDefaultPerms[5] = "r-xp";
-  if (hdr->magic != kMagic)
-    return false;
-  const char* lc = (const char *)hdr + sizeof(MachHeader);
-  // TODO(csilvers): make this not-quadradic (increment and hold state)
-  for (int j = 0; j < current_load_cmd; j++)  // advance to *our* load_cmd
-    lc += ((const load_command *)lc)->cmdsize;
-  if (((const load_command *)lc)->cmd == kLCSegment) {
-    const intptr_t dlloff = _dyld_get_image_vmaddr_slide(current_image);
-    const SegmentCommand* sc = (const SegmentCommand *)lc;
-    if (start) *start = sc->vmaddr + dlloff;
-    if (end) *end = sc->vmaddr + sc->vmsize + dlloff;
-    if (flags) *flags = kDefaultPerms;  // can we do better?
-    if (offset) *offset = sc->fileoff;
-    if (inode) *inode = 0;
-    if (filename)
-      *filename = const_cast<char*>(_dyld_get_image_name(current_image));
-    if (file_mapping) *file_mapping = 0;
-    if (file_pages) *file_pages = 0;   // could we use sc->filesize?
-    if (anon_mapping) *anon_mapping = 0;
-    if (anon_pages) *anon_pages = 0;
-    if (dev) *dev = 0;
-    return true;
-  }
-
-  return false;
-}
-#endif
-
-// Finds |c| in |text|, and assign '\0' at the found position.
-// The original character at the modified position should be |c|.
-// A pointer to the modified position is stored in |endptr|.
-// |endptr| should not be NULL.
-static bool ExtractUntilChar(char *text, int c, char **endptr) {
-  CHECK_NE(text, NULL);
-  CHECK_NE(endptr, NULL);
-  char *found;
-  found = strchr(text, c);
-  if (found == NULL) {
-    *endptr = NULL;
-    return false;
-  }
-
-  *endptr = found;
-  *found = '\0';
-  return true;
-}
-
-// Increments |*text_pointer| while it points a whitespace character.
-// It is to follow sscanf's whilespace handling.
-static void SkipWhileWhitespace(char **text_pointer, int c) {
-  if (isspace(c)) {
-    while (isspace(**text_pointer) && isspace(*((*text_pointer) + 1))) {
-      ++(*text_pointer);
-    }
-  }
-}
-
-template<class T>
-static T StringToInteger(char *text, char **endptr, int base) {
-  assert(false);
-  return T();
-}
-
-template<>
-int StringToInteger<int>(char *text, char **endptr, int base) {
-  return strtol(text, endptr, base);
-}
-
-template<>
-int64 StringToInteger<int64>(char *text, char **endptr, int base) {
-  return strtoll(text, endptr, base);
-}
-
-template<>
-uint64 StringToInteger<uint64>(char *text, char **endptr, int base) {
-  return strtoull(text, endptr, base);
-}
-
-template<typename T>
-static T StringToIntegerUntilChar(
-    char *text, int base, int c, char **endptr_result) {
-  CHECK_NE(endptr_result, NULL);
-  *endptr_result = NULL;
-
-  char *endptr_extract;
-  if (!ExtractUntilChar(text, c, &endptr_extract))
-    return 0;
-
-  T result;
-  char *endptr_strto;
-  result = StringToInteger<T>(text, &endptr_strto, base);
-  *endptr_extract = c;
-
-  if (endptr_extract != endptr_strto)
-    return 0;
-
-  *endptr_result = endptr_extract;
-  SkipWhileWhitespace(endptr_result, c);
-
-  return result;
-}
-
-static char *CopyStringUntilChar(
-    char *text, unsigned out_len, int c, char *out) {
-  char *endptr;
-  if (!ExtractUntilChar(text, c, &endptr))
-    return NULL;
-
-  strncpy(out, text, out_len);
-  out[out_len-1] = '\0';
-  *endptr = c;
-
-  SkipWhileWhitespace(&endptr, c);
-  return endptr;
-}
-
-template<typename T>
-static bool StringToIntegerUntilCharWithCheck(
-    T *outptr, char *text, int base, int c, char **endptr) {
-  *outptr = StringToIntegerUntilChar<T>(*endptr, base, c, endptr);
-  if (*endptr == NULL || **endptr == '\0') return false;
-  ++(*endptr);
-  return true;
-}
-
-static bool ParseProcMapsLine(char *text, uint64 *start, uint64 *end,
-                              char *flags, uint64 *offset,
-                              int *major, int *minor, int64 *inode,
-                              unsigned *filename_offset) {
-#if defined(__linux__)
-  /*
-   * It's similar to:
-   * sscanf(text, "%"SCNx64"-%"SCNx64" %4s %"SCNx64" %x:%x %"SCNd64" %n",
-   *        start, end, flags, offset, major, minor, inode, filename_offset)
-   */
-  char *endptr = text;
-  if (endptr == NULL || *endptr == '\0')  return false;
-
-  if (!StringToIntegerUntilCharWithCheck(start, endptr, 16, '-', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(end, endptr, 16, ' ', &endptr))
-    return false;
-
-  endptr = CopyStringUntilChar(endptr, 5, ' ', flags);
-  if (endptr == NULL || *endptr == '\0')  return false;
-  ++endptr;
-
-  if (!StringToIntegerUntilCharWithCheck(offset, endptr, 16, ' ', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(major, endptr, 16, ':', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(minor, endptr, 16, ' ', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(inode, endptr, 10, ' ', &endptr))
-    return false;
-
-  *filename_offset = (endptr - text);
-  return true;
-#else
-  return false;
-#endif
-}
-
-ProcMapsIterator::ProcMapsIterator(pid_t pid) {
-  Init(pid, NULL, false);
-}
-
-ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer) {
-  Init(pid, buffer, false);
-}
-
-ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer,
-                                   bool use_maps_backing) {
-  Init(pid, buffer, use_maps_backing);
-}
-
-void ProcMapsIterator::Init(pid_t pid, Buffer *buffer,
-                            bool use_maps_backing) {
-  pid_ = pid;
-  using_maps_backing_ = use_maps_backing;
-  dynamic_buffer_ = NULL;
-  if (!buffer) {
-    // If the user didn't pass in any buffer storage, allocate it
-    // now. This is the normal case; the signal handler passes in a
-    // static buffer.
-    buffer = dynamic_buffer_ = new Buffer;
-  } else {
-    dynamic_buffer_ = NULL;
-  }
-
-  ibuf_ = buffer->buf_;
-
-  stext_ = etext_ = nextline_ = ibuf_;
-  ebuf_ = ibuf_ + Buffer::kBufSize - 1;
-  nextline_ = ibuf_;
-
-#if defined(__linux__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-  if (use_maps_backing) {  // don't bother with clever "self" stuff in this case
-    ConstructFilename("/proc/%d/maps_backing", pid, ibuf_, Buffer::kBufSize);
-  } else if (pid == 0) {
-    // We have to kludge a bit to deal with the args ConstructFilename
-    // expects.  The 1 is never used -- it's only impt. that it's not 0.
-    ConstructFilename("/proc/self/maps", 1, ibuf_, Buffer::kBufSize);
-  } else {
-    ConstructFilename("/proc/%d/maps", pid, ibuf_, Buffer::kBufSize);
-  }
-  // No error logging since this can be called from the crash dump
-  // handler at awkward moments. Users should call Valid() before
-  // using.
-  NO_INTR(fd_ = open(ibuf_, O_RDONLY));
-#elif defined(__FreeBSD__)
-  // We don't support maps_backing on freebsd
-  if (pid == 0) {
-    ConstructFilename("/proc/curproc/map", 1, ibuf_, Buffer::kBufSize);
-  } else {
-    ConstructFilename("/proc/%d/map", pid, ibuf_, Buffer::kBufSize);
-  }
-  NO_INTR(fd_ = open(ibuf_, O_RDONLY));
-#elif defined(__sun__)
-  if (pid == 0) {
-    ConstructFilename("/proc/self/map", 1, ibuf_, Buffer::kBufSize);
-  } else {
-    ConstructFilename("/proc/%d/map", pid, ibuf_, Buffer::kBufSize);
-  }
-  NO_INTR(fd_ = open(ibuf_, O_RDONLY));
-#elif defined(__MACH__)
-  current_image_ = _dyld_image_count();   // count down from the top
-  current_load_cmd_ = -1;
-#elif defined(PLATFORM_WINDOWS)
-  snapshot_ = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE |
-                                       TH32CS_SNAPMODULE32,
-                                       GetCurrentProcessId());
-  memset(&module_, 0, sizeof(module_));
-#else
-  fd_ = -1;   // so Valid() is always false
-#endif
-
-}
-
-ProcMapsIterator::~ProcMapsIterator() {
-#if defined(PLATFORM_WINDOWS)
-  if (snapshot_ != INVALID_HANDLE_VALUE) CloseHandle(snapshot_);
-#elif defined(__MACH__)
-  // no cleanup necessary!
-#else
-  if (fd_ >= 0) NO_INTR(close(fd_));
-#endif
-  delete dynamic_buffer_;
-}
-
-bool ProcMapsIterator::Valid() const {
-#if defined(PLATFORM_WINDOWS)
-  return snapshot_ != INVALID_HANDLE_VALUE;
-#elif defined(__MACH__)
-  return 1;
-#else
-  return fd_ != -1;
-#endif
-}
-
-bool ProcMapsIterator::Next(uint64 *start, uint64 *end, char **flags,
-                            uint64 *offset, int64 *inode, char **filename) {
-  return NextExt(start, end, flags, offset, inode, filename, NULL, NULL,
-                 NULL, NULL, NULL);
-}
-
-// This has too many arguments.  It should really be building
-// a map object and returning it.  The problem is that this is called
-// when the memory allocator state is undefined, hence the arguments.
-bool ProcMapsIterator::NextExt(uint64 *start, uint64 *end, char **flags,
-                               uint64 *offset, int64 *inode, char **filename,
-                               uint64 *file_mapping, uint64 *file_pages,
-                               uint64 *anon_mapping, uint64 *anon_pages,
-                               dev_t *dev) {
-
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-  do {
-    // Advance to the start of the next line
-    stext_ = nextline_;
-
-    // See if we have a complete line in the buffer already
-    nextline_ = static_cast<char *>(memchr (stext_, '\n', etext_ - stext_));
-    if (!nextline_) {
-      // Shift/fill the buffer so we do have a line
-      int count = etext_ - stext_;
-
-      // Move the current text to the start of the buffer
-      memmove(ibuf_, stext_, count);
-      stext_ = ibuf_;
-      etext_ = ibuf_ + count;
-
-      int nread = 0;            // fill up buffer with text
-      while (etext_ < ebuf_) {
-        NO_INTR(nread = read(fd_, etext_, ebuf_ - etext_));
-        if (nread > 0)
-          etext_ += nread;
-        else
-          break;
-      }
-
-      // Zero out remaining characters in buffer at EOF to avoid returning
-      // garbage from subsequent calls.
-      if (etext_ != ebuf_ && nread == 0) {
-        memset(etext_, 0, ebuf_ - etext_);
-      }
-      *etext_ = '\n';   // sentinel; safe because ibuf extends 1 char beyond ebuf
-      nextline_ = static_cast<char *>(memchr (stext_, '\n', etext_ + 1 - stext_));
-    }
-    *nextline_ = 0;                // turn newline into nul
-    nextline_ += ((nextline_ < etext_)? 1 : 0);  // skip nul if not end of text
-    // stext_ now points at a nul-terminated line
-    uint64 tmpstart, tmpend, tmpoffset;
-    int64 tmpinode;
-    int major, minor;
-    unsigned filename_offset = 0;
-#if defined(__linux__)
-    // for now, assume all linuxes have the same format
-    if (!ParseProcMapsLine(
-        stext_,
-        start ? start : &tmpstart,
-        end ? end : &tmpend,
-        flags_,
-        offset ? offset : &tmpoffset,
-        &major, &minor,
-        inode ? inode : &tmpinode, &filename_offset)) continue;
-#elif defined(__CYGWIN__) || defined(__CYGWIN32__)
-    // cygwin is like linux, except the third field is the "entry point"
-    // rather than the offset (see format_process_maps at
-    // http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/fhandler_process.cc?rev=1.89&content-type=text/x-cvsweb-markup&cvsroot=src
-    // Offset is always be 0 on cygwin: cygwin implements an mmap
-    // by loading the whole file and then calling NtMapViewOfSection.
-    // Cygwin also seems to set its flags kinda randomly; use windows default.
-    char tmpflags[5];
-    if (offset)
-      *offset = 0;
-    strcpy(flags_, "r-xp");
-    if (sscanf(stext_, "%llx-%llx %4s %llx %x:%x %lld %n",
-               start ? start : &tmpstart,
-               end ? end : &tmpend,
-               tmpflags,
-               &tmpoffset,
-               &major, &minor,
-               inode ? inode : &tmpinode, &filename_offset) != 7) continue;
-#elif defined(__FreeBSD__)
-    // For the format, see http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/fs/procfs/procfs_map.c?rev=1.31&content-type=text/x-cvsweb-markup
-    tmpstart = tmpend = tmpoffset = 0;
-    tmpinode = 0;
-    major = minor = 0;   // can't get this info in freebsd
-    if (inode)
-      *inode = 0;        // nor this
-    if (offset)
-      *offset = 0;       // seems like this should be in there, but maybe not
-    // start end resident privateresident obj(?) prot refcnt shadowcnt
-    // flags copy_on_write needs_copy type filename:
-    // 0x8048000 0x804a000 2 0 0xc104ce70 r-x 1 0 0x0 COW NC vnode /bin/cat
-    if (sscanf(stext_, "0x%" SCNx64 " 0x%" SCNx64 " %*d %*d %*p %3s %*d %*d 0x%*x %*s %*s %*s %n",
-               start ? start : &tmpstart,
-               end ? end : &tmpend,
-               flags_,
-               &filename_offset) != 3) continue;
-#endif
-
-    // Depending on the Linux kernel being used, there may or may not be a space
-    // after the inode if there is no filename.  sscanf will in such situations
-    // nondeterministically either fill in filename_offset or not (the results
-    // differ on multiple calls in the same run even with identical arguments).
-    // We don't want to wander off somewhere beyond the end of the string.
-    size_t stext_length = strlen(stext_);
-    if (filename_offset == 0 || filename_offset > stext_length)
-      filename_offset = stext_length;
-
-    // We found an entry
-    if (flags) *flags = flags_;
-    if (filename) *filename = stext_ + filename_offset;
-    if (dev) *dev = minor | (major << 8);
-
-    if (using_maps_backing_) {
-      // Extract and parse physical page backing info.
-      char *backing_ptr = stext_ + filename_offset +
-          strlen(stext_+filename_offset);
-
-      // find the second '('
-      int paren_count = 0;
-      while (--backing_ptr > stext_) {
-        if (*backing_ptr == '(') {
-          ++paren_count;
-          if (paren_count >= 2) {
-            uint64 tmp_file_mapping;
-            uint64 tmp_file_pages;
-            uint64 tmp_anon_mapping;
-            uint64 tmp_anon_pages;
-
-            sscanf(backing_ptr+1, "F %" SCNx64 " %" SCNd64 ") (A %" SCNx64 " %" SCNd64 ")",
-                   file_mapping ? file_mapping : &tmp_file_mapping,
-                   file_pages ? file_pages : &tmp_file_pages,
-                   anon_mapping ? anon_mapping : &tmp_anon_mapping,
-                   anon_pages ? anon_pages : &tmp_anon_pages);
-            // null terminate the file name (there is a space
-            // before the first (.
-            backing_ptr[-1] = 0;
-            break;
-          }
-        }
-      }
-    }
-
-    return true;
-  } while (etext_ > ibuf_);
-#elif defined(__sun__)
-  // This is based on MA_READ == 4, MA_WRITE == 2, MA_EXEC == 1
-  static char kPerms[8][4] = { "---", "--x", "-w-", "-wx",
-                               "r--", "r-x", "rw-", "rwx" };
-  COMPILE_ASSERT(MA_READ == 4, solaris_ma_read_must_equal_4);
-  COMPILE_ASSERT(MA_WRITE == 2, solaris_ma_write_must_equal_2);
-  COMPILE_ASSERT(MA_EXEC == 1, solaris_ma_exec_must_equal_1);
-  Buffer object_path;
-  int nread = 0;            // fill up buffer with text
-  NO_INTR(nread = read(fd_, ibuf_, sizeof(prmap_t)));
-  if (nread == sizeof(prmap_t)) {
-    long inode_from_mapname = 0;
-    prmap_t* mapinfo = reinterpret_cast<prmap_t*>(ibuf_);
-    // Best-effort attempt to get the inode from the filename.  I think the
-    // two middle ints are major and minor device numbers, but I'm not sure.
-    sscanf(mapinfo->pr_mapname, "ufs.%*d.%*d.%ld", &inode_from_mapname);
-
-    if (pid_ == 0) {
-      CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,
-                        "/proc/self/path/%s", mapinfo->pr_mapname),
-               Buffer::kBufSize);
-    } else {
-      CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,
-                        "/proc/%d/path/%s",
-                        static_cast<int>(pid_), mapinfo->pr_mapname),
-               Buffer::kBufSize);
-    }
-    ssize_t len = readlink(object_path.buf_, current_filename_, PATH_MAX);
-    CHECK_LT(len, PATH_MAX);
-    if (len < 0)
-      len = 0;
-    current_filename_[len] = '\0';
-
-    if (start) *start = mapinfo->pr_vaddr;
-    if (end) *end = mapinfo->pr_vaddr + mapinfo->pr_size;
-    if (flags) *flags = kPerms[mapinfo->pr_mflags & 7];
-    if (offset) *offset = mapinfo->pr_offset;
-    if (inode) *inode = inode_from_mapname;
-    if (filename) *filename = current_filename_;
-    if (file_mapping) *file_mapping = 0;
-    if (file_pages) *file_pages = 0;
-    if (anon_mapping) *anon_mapping = 0;
-    if (anon_pages) *anon_pages = 0;
-    if (dev) *dev = 0;
-    return true;
-  }
-#elif defined(__MACH__)
-  // We return a separate entry for each segment in the DLL. (TODO(csilvers):
-  // can we do better?)  A DLL ("image") has load-commands, some of which
-  // talk about segment boundaries.
-  // cf image_for_address from http://svn.digium.com/view/asterisk/team/oej/minivoicemail/dlfcn.c?revision=53912
-  for (; current_image_ >= 0; current_image_--) {
-    const mach_header* hdr = _dyld_get_image_header(current_image_);
-    if (!hdr) continue;
-    if (current_load_cmd_ < 0)   // set up for this image
-      current_load_cmd_ = hdr->ncmds;  // again, go from the top down
-
-    // We start with the next load command (we've already looked at this one).
-    for (current_load_cmd_--; current_load_cmd_ >= 0; current_load_cmd_--) {
-#ifdef MH_MAGIC_64
-      if (NextExtMachHelper<MH_MAGIC_64, LC_SEGMENT_64,
-                            struct mach_header_64, struct segment_command_64>(
-                                hdr, current_image_, current_load_cmd_,
-                                start, end, flags, offset, inode, filename,
-                                file_mapping, file_pages, anon_mapping,
-                                anon_pages, dev)) {
-        return true;
-      }
-#endif
-      if (NextExtMachHelper<MH_MAGIC, LC_SEGMENT,
-                            struct mach_header, struct segment_command>(
-                                hdr, current_image_, current_load_cmd_,
-                                start, end, flags, offset, inode, filename,
-                                file_mapping, file_pages, anon_mapping,
-                                anon_pages, dev)) {
-        return true;
-      }
-    }
-    // If we get here, no more load_cmd's in this image talk about
-    // segments.  Go on to the next image.
-  }
-#elif defined(PLATFORM_WINDOWS)
-  static char kDefaultPerms[5] = "r-xp";
-  BOOL ok;
-  if (module_.dwSize == 0) {  // only possible before first call
-    module_.dwSize = sizeof(module_);
-    ok = Module32First(snapshot_, &module_);
-  } else {
-    ok = Module32Next(snapshot_, &module_);
-  }
-  if (ok) {
-    uint64 base_addr = reinterpret_cast<DWORD_PTR>(module_.modBaseAddr);
-    if (start) *start = base_addr;
-    if (end) *end = base_addr + module_.modBaseSize;
-    if (flags) *flags = kDefaultPerms;
-    if (offset) *offset = 0;
-    if (inode) *inode = 0;
-    if (filename) *filename = module_.szExePath;
-    if (file_mapping) *file_mapping = 0;
-    if (file_pages) *file_pages = 0;
-    if (anon_mapping) *anon_mapping = 0;
-    if (anon_pages) *anon_pages = 0;
-    if (dev) *dev = 0;
-    return true;
-  }
-#endif
-
-  // We didn't find anything
-  return false;
-}
-
-int ProcMapsIterator::FormatLine(char* buffer, int bufsize,
-                                 uint64 start, uint64 end, const char *flags,
-                                 uint64 offset, int64 inode,
-                                 const char *filename, dev_t dev) {
-  // We assume 'flags' looks like 'rwxp' or 'rwx'.
-  char r = (flags && flags[0] == 'r') ? 'r' : '-';
-  char w = (flags && flags[0] && flags[1] == 'w') ? 'w' : '-';
-  char x = (flags && flags[0] && flags[1] && flags[2] == 'x') ? 'x' : '-';
-  // p always seems set on linux, so we set the default to 'p', not '-'
-  char p = (flags && flags[0] && flags[1] && flags[2] && flags[3] != 'p')
-      ? '-' : 'p';
-
-  const int rc = snprintf(buffer, bufsize,
-                          "%08" PRIx64 "-%08" PRIx64 " %c%c%c%c %08" PRIx64 " %02x:%02x %-11" PRId64 " %s\n",
-                          start, end, r,w,x,p, offset,
-                          static_cast<int>(dev/256), static_cast<int>(dev%256),
-                          inode, filename);
-  return (rc < 0 || rc >= bufsize) ? 0 : rc;
-}
-
-namespace tcmalloc {
-
-// Helper to add the list of mapped shared libraries to a profile.
-// Fill formatted "/proc/self/maps" contents into buffer 'buf' of size 'size'
-// and return the actual size occupied in 'buf'.  We fill wrote_all to true
-// if we successfully wrote all proc lines to buf, false else.
-// We do not provision for 0-terminating 'buf'.
-int FillProcSelfMaps(char buf[], int size, bool* wrote_all) {
-  ProcMapsIterator::Buffer iterbuf;
-  ProcMapsIterator it(0, &iterbuf);   // 0 means "current pid"
-
-  uint64 start, end, offset;
-  int64 inode;
-  char *flags, *filename;
-  int bytes_written = 0;
-  *wrote_all = true;
-  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
-    const int line_length = it.FormatLine(buf + bytes_written,
-                                          size - bytes_written,
-                                          start, end, flags, offset,
-                                          inode, filename, 0);
-    if (line_length == 0)
-      *wrote_all = false;     // failed to write this line out
-    else
-      bytes_written += line_length;
-
-  }
-  return bytes_written;
-}
-
-// Dump the same data as FillProcSelfMaps reads to fd.
-// It seems easier to repeat parts of FillProcSelfMaps here than to
-// reuse it via a call.
-void DumpProcSelfMaps(RawFD fd) {
-  ProcMapsIterator::Buffer iterbuf;
-  ProcMapsIterator it(0, &iterbuf);   // 0 means "current pid"
-
-  uint64 start, end, offset;
-  int64 inode;
-  char *flags, *filename;
-  ProcMapsIterator::Buffer linebuf;
-  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
-    int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_),
-                                start, end, flags, offset, inode, filename,
-                                0);
-    RawWrite(fd, linebuf.buf_, written);
-  }
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/vendor/src/base/sysinfo.h b/third_party/tcmalloc/vendor/src/base/sysinfo.h
deleted file mode 100644
index e30b0d4d..0000000
--- a/third_party/tcmalloc/vendor/src/base/sysinfo.h
+++ /dev/null
@@ -1,232 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// All functions here are thread-hostile due to file caching unless
-// commented otherwise.
-
-#ifndef _SYSINFO_H_
-#define _SYSINFO_H_
-
-#include <config.h>
-
-#include <time.h>
-#if (defined(_WIN32) || defined(__MINGW32__)) && (!defined(__CYGWIN__) && !defined(__CYGWIN32__))
-#include <windows.h>   // for DWORD
-#include <tlhelp32.h>  // for CreateToolhelp32Snapshot
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for pid_t
-#endif
-#include <stddef.h>    // for size_t
-#include <limits.h>    // for PATH_MAX
-#include "base/basictypes.h"
-#include "base/logging.h"   // for RawFD
-
-// This getenv function is safe to call before the C runtime is initialized.
-// On Windows, it utilizes GetEnvironmentVariable() and on unix it uses
-// /proc/self/environ instead calling getenv().  It's intended to be used in
-// routines that run before main(), when the state required for getenv() may
-// not be set up yet.  In particular, errno isn't set up until relatively late
-// (after the pthreads library has a chance to make it threadsafe), and
-// getenv() doesn't work until then. 
-// On some platforms, this call will utilize the same, static buffer for
-// repeated GetenvBeforeMain() calls. Callers should not expect pointers from
-// this routine to be long lived.
-// Note that on unix, /proc only has the environment at the time the
-// application was started, so this routine ignores setenv() calls/etc.  Also
-// note it only reads the first 16K of the environment.
-extern const char* GetenvBeforeMain(const char* name);
-
-// This takes as an argument an environment-variable name (like
-// CPUPROFILE) whose value is supposed to be a file-path, and sets
-// path to that path, and returns true.  Non-trivial for surprising
-// reasons, as documented in sysinfo.cc.  path must have space PATH_MAX.
-extern bool GetUniquePathFromEnv(const char* env_name, char* path);
-
-extern int GetSystemCPUsCount();
-
-void SleepForMilliseconds(int milliseconds);
-
-//  Return true if we're running POSIX (e.g., NPTL on Linux) threads,
-//  as opposed to a non-POSIX thread library.  The thing that we care
-//  about is whether a thread's pid is the same as the thread that
-//  spawned it.  If so, this function returns true.
-//  Thread-safe.
-//  Note: We consider false negatives to be OK.
-bool HasPosixThreads();
-
-#ifndef SWIG  // SWIG doesn't like struct Buffer and variable arguments.
-
-// A ProcMapsIterator abstracts access to /proc/maps for a given
-// process. Needs to be stack-allocatable and avoid using stdio/malloc
-// so it can be used in the google stack dumper, heap-profiler, etc.
-//
-// On Windows and Mac OS X, this iterator iterates *only* over DLLs
-// mapped into this process space.  For Linux, FreeBSD, and Solaris,
-// it iterates over *all* mapped memory regions, including anonymous
-// mmaps.  For other O/Ss, it is unlikely to work at all, and Valid()
-// will always return false.  Also note: this routine only works on
-// FreeBSD if procfs is mounted: make sure this is in your /etc/fstab:
-//    proc            /proc   procfs  rw 0 0
-class ProcMapsIterator {
- public:
-  struct Buffer {
-#ifdef __FreeBSD__
-    // FreeBSD requires us to read all of the maps file at once, so
-    // we have to make a buffer that's "always" big enough
-    static const size_t kBufSize = 102400;
-#else   // a one-line buffer is good enough
-    static const size_t kBufSize = PATH_MAX + 1024;
-#endif
-    char buf_[kBufSize];
-  };
-
-
-  // Create a new iterator for the specified pid.  pid can be 0 for "self".
-  explicit ProcMapsIterator(pid_t pid);
-
-  // Create an iterator with specified storage (for use in signal
-  // handler). "buffer" should point to a ProcMapsIterator::Buffer
-  // buffer can be NULL in which case a bufer will be allocated.
-  ProcMapsIterator(pid_t pid, Buffer *buffer);
-
-  // Iterate through maps_backing instead of maps if use_maps_backing
-  // is true.  Otherwise the same as above.  buffer can be NULL and
-  // it will allocate a buffer itself.
-  ProcMapsIterator(pid_t pid, Buffer *buffer,
-                   bool use_maps_backing);
-
-  // Returns true if the iterator successfully initialized;
-  bool Valid() const;
-
-  // Returns a pointer to the most recently parsed line. Only valid
-  // after Next() returns true, and until the iterator is destroyed or
-  // Next() is called again.  This may give strange results on non-Linux
-  // systems.  Prefer FormatLine() if that may be a concern.
-  const char *CurrentLine() const { return stext_; }
-
-  // Writes the "canonical" form of the /proc/xxx/maps info for a single
-  // line to the passed-in buffer. Returns the number of bytes written,
-  // or 0 if it was not able to write the complete line.  (To guarantee
-  // success, buffer should have size at least Buffer::kBufSize.)
-  // Takes as arguments values set via a call to Next().  The
-  // "canonical" form of the line (taken from linux's /proc/xxx/maps):
-  //    <start_addr(hex)>-<end_addr(hex)> <perms(rwxp)> <offset(hex)>   +
-  //    <major_dev(hex)>:<minor_dev(hex)> <inode> <filename> Note: the
-  // eg
-  //    08048000-0804c000 r-xp 00000000 03:01 3793678    /bin/cat
-  // If you don't have the dev_t (dev), feel free to pass in 0.
-  // (Next() doesn't return a dev_t, though NextExt does.)
-  //
-  // Note: if filename and flags were obtained via a call to Next(),
-  // then the output of this function is only valid if Next() returned
-  // true, and only until the iterator is destroyed or Next() is
-  // called again.  (Since filename, at least, points into CurrentLine.)
-  static int FormatLine(char* buffer, int bufsize,
-                        uint64 start, uint64 end, const char *flags,
-                        uint64 offset, int64 inode, const char *filename,
-                        dev_t dev);
-
-  // Find the next entry in /proc/maps; return true if found or false
-  // if at the end of the file.
-  //
-  // Any of the result pointers can be NULL if you're not interested
-  // in those values.
-  //
-  // If "flags" and "filename" are passed, they end up pointing to
-  // storage within the ProcMapsIterator that is valid only until the
-  // iterator is destroyed or Next() is called again. The caller may
-  // modify the contents of these strings (up as far as the first NUL,
-  // and only until the subsequent call to Next()) if desired.
-
-  // The offsets are all uint64 in order to handle the case of a
-  // 32-bit process running on a 64-bit kernel
-  //
-  // IMPORTANT NOTE: see top-of-class notes for details about what
-  // mapped regions Next() iterates over, depending on O/S.
-  // TODO(csilvers): make flags and filename const.
-  bool Next(uint64 *start, uint64 *end, char **flags,
-            uint64 *offset, int64 *inode, char **filename);
-
-  bool NextExt(uint64 *start, uint64 *end, char **flags,
-               uint64 *offset, int64 *inode, char **filename,
-               uint64 *file_mapping, uint64 *file_pages,
-               uint64 *anon_mapping, uint64 *anon_pages,
-               dev_t *dev);
-
-  ~ProcMapsIterator();
-
- private:
-  void Init(pid_t pid, Buffer *buffer, bool use_maps_backing);
-
-  char *ibuf_;        // input buffer
-  char *stext_;       // start of text
-  char *etext_;       // end of text
-  char *nextline_;    // start of next line
-  char *ebuf_;        // end of buffer (1 char for a nul)
-#if (defined(_WIN32) || defined(__MINGW32__)) && (!defined(__CYGWIN__) && !defined(__CYGWIN32__))
-  HANDLE snapshot_;   // filehandle on dll info
-  // In a change from the usual W-A pattern, there is no A variant of
-  // MODULEENTRY32.  Tlhelp32.h #defines the W variant, but not the A.
-  // We want the original A variants, and this #undef is the only
-  // way I see to get them.  Redefining it when we're done prevents us
-  // from affecting other .cc files.
-# ifdef MODULEENTRY32  // Alias of W
-#   undef MODULEENTRY32
-  MODULEENTRY32 module_;   // info about current dll (and dll iterator)
-#   define MODULEENTRY32 MODULEENTRY32W
-# else  // It's the ascii, the one we want.
-  MODULEENTRY32 module_;   // info about current dll (and dll iterator)
-# endif
-#elif defined(__MACH__)
-  int current_image_; // dll's are called "images" in macos parlance
-  int current_load_cmd_;   // the segment of this dll we're examining
-#elif defined(__sun__)     // Solaris
-  int fd_;
-  char current_filename_[PATH_MAX];
-#else
-  int fd_;            // filehandle on /proc/*/maps
-#endif
-  pid_t pid_;
-  char flags_[10];
-  Buffer* dynamic_buffer_;  // dynamically-allocated Buffer
-  bool using_maps_backing_; // true if we are looking at maps_backing instead of maps.
-};
-
-#endif  /* #ifndef SWIG */
-
-// Helper routines
-
-namespace tcmalloc {
-int FillProcSelfMaps(char buf[], int size, bool* wrote_all);
-void DumpProcSelfMaps(RawFD fd);
-}
-
-#endif   /* #ifndef _SYSINFO_H_ */
diff --git a/third_party/tcmalloc/vendor/src/base/thread_annotations.h b/third_party/tcmalloc/vendor/src/base/thread_annotations.h
deleted file mode 100644
index f57b299..0000000
--- a/third_party/tcmalloc/vendor/src/base/thread_annotations.h
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Le-Chun Wu
-//
-// This header file contains the macro definitions for thread safety
-// annotations that allow the developers to document the locking policies
-// of their multi-threaded code. The annotations can also help program
-// analysis tools to identify potential thread safety issues.
-//
-// The annotations are implemented using GCC's "attributes" extension.
-// Using the macros defined here instead of the raw GCC attributes allows
-// for portability and future compatibility.
-//
-// This functionality is not yet fully implemented in perftools,
-// but may be one day.
-
-#ifndef BASE_THREAD_ANNOTATIONS_H_
-#define BASE_THREAD_ANNOTATIONS_H_
-
-
-#if defined(__GNUC__) \
-  && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \
-  && defined(__SUPPORT_TS_ANNOTATION__) && (!defined(SWIG))
-#define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
-#else
-#define THREAD_ANNOTATION_ATTRIBUTE__(x)   // no-op
-#endif
-
-
-// Document if a shared variable/field needs to be protected by a lock.
-// GUARDED_BY allows the user to specify a particular lock that should be
-// held when accessing the annotated variable, while GUARDED_VAR only
-// indicates a shared variable should be guarded (by any lock). GUARDED_VAR
-// is primarily used when the client cannot express the name of the lock.
-#define GUARDED_BY(x)          THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
-#define GUARDED_VAR            THREAD_ANNOTATION_ATTRIBUTE__(guarded)
-
-// Document if the memory location pointed to by a pointer should be guarded
-// by a lock when dereferencing the pointer. Similar to GUARDED_VAR,
-// PT_GUARDED_VAR is primarily used when the client cannot express the name
-// of the lock. Note that a pointer variable to a shared memory location
-// could itself be a shared variable. For example, if a shared global pointer
-// q, which is guarded by mu1, points to a shared memory location that is
-// guarded by mu2, q should be annotated as follows:
-//     int *q GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
-#define PT_GUARDED_BY(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x))
-#define PT_GUARDED_VAR \
-  THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded)
-
-// Document the acquisition order between locks that can be held
-// simultaneously by a thread. For any two locks that need to be annotated
-// to establish an acquisition order, only one of them needs the annotation.
-// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER
-// and ACQUIRED_BEFORE.)
-#define ACQUIRED_AFTER(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x))
-#define ACQUIRED_BEFORE(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x))
-
-// The following three annotations document the lock requirements for
-// functions/methods.
-
-// Document if a function expects certain locks to be held before it is called
-#define EXCLUSIVE_LOCKS_REQUIRED(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x))
-
-#define SHARED_LOCKS_REQUIRED(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(x))
-
-// Document the locks acquired in the body of the function. These locks
-// cannot be held when calling this function (as google3's Mutex locks are
-// non-reentrant).
-#define LOCKS_EXCLUDED(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x))
-
-// Document the lock the annotated function returns without acquiring it.
-#define LOCK_RETURNED(x)       THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
-
-// Document if a class/type is a lockable type (such as the Mutex class).
-#define LOCKABLE               THREAD_ANNOTATION_ATTRIBUTE__(lockable)
-
-// Document if a class is a scoped lockable type (such as the MutexLock class).
-#define SCOPED_LOCKABLE        THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
-
-// The following annotations specify lock and unlock primitives.
-#define EXCLUSIVE_LOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock(x))
-
-#define SHARED_LOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(shared_lock(x))
-
-#define EXCLUSIVE_TRYLOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock(x))
-
-#define SHARED_TRYLOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock(x))
-
-#define UNLOCK_FUNCTION(x) \
-  THREAD_ANNOTATION_ATTRIBUTE__(unlock(x))
-
-// An escape hatch for thread safety analysis to ignore the annotated function.
-#define NO_THREAD_SAFETY_ANALYSIS \
-  THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
-
-#endif  // BASE_THREAD_ANNOTATIONS_H_
diff --git a/third_party/tcmalloc/vendor/src/base/thread_lister.c b/third_party/tcmalloc/vendor/src/base/thread_lister.c
deleted file mode 100644
index 9dc8d72..0000000
--- a/third_party/tcmalloc/vendor/src/base/thread_lister.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright (c) 2005-2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-#include "config.h"
-
-#include "base/thread_lister.h"
-
-#include <stdio.h>         /* needed for NULL on some powerpc platforms (?!) */
-#include <sys/types.h>
-#include <unistd.h>        /* for getpid */
-
-#ifdef HAVE_SYS_PRCTL
-# include <sys/prctl.h>
-#endif
-
-#include "base/linuxthreads.h"
-/* Include other thread listers here that define THREADS macro
- * only when they can provide a good implementation.
- */
-
-#ifndef THREADS
-
-/* Default trivial thread lister for single-threaded applications,
- * or if the multi-threading code has not been ported, yet.
- */
-
-int TCMalloc_ListAllProcessThreads(void *parameter,
-				   ListAllProcessThreadsCallBack callback, ...) {
-  int rc;
-  va_list ap;
-  pid_t pid;
-
-#ifdef HAVE_SYS_PRCTL
-  int dumpable = prctl(PR_GET_DUMPABLE, 0);
-  if (!dumpable)
-    prctl(PR_SET_DUMPABLE, 1);
-#endif
-  va_start(ap, callback);
-  pid = getpid();
-  rc = callback(parameter, 1, &pid, ap);
-  va_end(ap);
-#ifdef HAVE_SYS_PRCTL
-  if (!dumpable)
-    prctl(PR_SET_DUMPABLE, 0);
-#endif
-  return rc;
-}
-
-int TCMalloc_ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
-  return 1;
-}
-
-#endif   /* ifndef THREADS */
diff --git a/third_party/tcmalloc/vendor/src/base/thread_lister.h b/third_party/tcmalloc/vendor/src/base/thread_lister.h
deleted file mode 100644
index 6e70b89..0000000
--- a/third_party/tcmalloc/vendor/src/base/thread_lister.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode: c; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* Copyright (c) 2005-2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
-
-#ifndef _THREAD_LISTER_H
-#define _THREAD_LISTER_H
-
-#include <stdarg.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef int (*ListAllProcessThreadsCallBack)(void *parameter,
-                                             int num_threads,
-                                             pid_t *thread_pids,
-                                             va_list ap);
-
-/* This function gets the list of all linux threads of the current process
- * passes them to the 'callback' along with the 'parameter' pointer; at the
- * call back call time all the threads are paused via
- * PTRACE_ATTACH.
- * The callback is executed from a separate thread which shares only the
- * address space, the filesystem, and the filehandles with the caller. Most
- * notably, it does not share the same pid and ppid; and if it terminates,
- * the rest of the application is still there. 'callback' is supposed to do
- * or arrange for TCMalloc_ResumeAllProcessThreads. This happens automatically, if
- * the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous
- * signals are blocked. If the 'callback' decides to unblock them, it must
- * ensure that they cannot terminate the application, or that
- * TCMalloc_ResumeAllProcessThreads will get called.
- * It is an error for the 'callback' to make any library calls that could
- * acquire locks. Most notably, this means that most system calls have to
- * avoid going through libc. Also, this means that it is not legal to call
- * exit() or abort().
- * We return -1 on error and the return value of 'callback' on success.
- */
-int TCMalloc_ListAllProcessThreads(void *parameter,
-                                   ListAllProcessThreadsCallBack callback, ...);
-
-/* This function resumes the list of all linux threads that
- * TCMalloc_ListAllProcessThreads pauses before giving to its
- * callback.  The function returns non-zero if at least one thread was
- * suspended and has now been resumed.
- */
-int TCMalloc_ResumeAllProcessThreads(int num_threads, pid_t *thread_pids);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* _THREAD_LISTER_H */
diff --git a/third_party/tcmalloc/vendor/src/base/vdso_support.cc b/third_party/tcmalloc/vendor/src/base/vdso_support.cc
deleted file mode 100644
index c52fcf9..0000000
--- a/third_party/tcmalloc/vendor/src/base/vdso_support.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Pluzhnikov
-//
-// Allow dynamic symbol lookup in the kernel VDSO page.
-//
-// VDSOSupport -- a class representing kernel VDSO (if present).
-//
-
-#include "base/vdso_support.h"
-
-#ifdef HAVE_VDSO_SUPPORT     // defined in vdso_support.h
-
-#include <fcntl.h>
-#include <stddef.h>   // for ptrdiff_t
-
-#include "base/logging.h"
-#include "base/dynamic_annotations.h"
-#include "base/basictypes.h"  // for COMPILE_ASSERT
-
-#ifndef AT_SYSINFO_EHDR
-#define AT_SYSINFO_EHDR 33
-#endif
-
-namespace base {
-
-const void *VDSOSupport::vdso_base_ = ElfMemImage::kInvalidBase;
-VDSOSupport::VDSOSupport()
-    // If vdso_base_ is still set to kInvalidBase, we got here
-    // before VDSOSupport::Init has been called. Call it now.
-    : image_(vdso_base_ == ElfMemImage::kInvalidBase ? Init() : vdso_base_) {
-}
-
-// NOTE: we can't use GoogleOnceInit() below, because we can be
-// called by tcmalloc, and none of the *once* stuff may be functional yet.
-//
-// In addition, we hope that the VDSOSupportHelper constructor
-// causes this code to run before there are any threads, and before
-// InitGoogle() has executed any chroot or setuid calls.
-//
-// Finally, even if there is a race here, it is harmless, because
-// the operation should be idempotent.
-const void *VDSOSupport::Init() {
-  if (vdso_base_ == ElfMemImage::kInvalidBase) {
-    // Valgrind zaps AT_SYSINFO_EHDR and friends from the auxv[]
-    // on stack, and so glibc works as if VDSO was not present.
-    // But going directly to kernel via /proc/self/auxv below bypasses
-    // Valgrind zapping. So we check for Valgrind separately.
-    if (RunningOnValgrind()) {
-      vdso_base_ = NULL;
-      return NULL;
-    }
-    int fd = open("/proc/self/auxv", O_RDONLY);
-    if (fd == -1) {
-      // Kernel too old to have a VDSO.
-      vdso_base_ = NULL;
-      return NULL;
-    }
-    ElfW(auxv_t) aux;
-    while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) {
-      if (aux.a_type == AT_SYSINFO_EHDR) {
-        COMPILE_ASSERT(sizeof(vdso_base_) == sizeof(aux.a_un.a_val),
-                       unexpected_sizeof_pointer_NE_sizeof_a_val);
-        vdso_base_ = reinterpret_cast<void *>(aux.a_un.a_val);
-        break;
-      }
-    }
-    close(fd);
-    if (vdso_base_ == ElfMemImage::kInvalidBase) {
-      // Didn't find AT_SYSINFO_EHDR in auxv[].
-      vdso_base_ = NULL;
-    }
-  }
-  return vdso_base_;
-}
-
-const void *VDSOSupport::SetBase(const void *base) {
-  CHECK(base != ElfMemImage::kInvalidBase);
-  const void *old_base = vdso_base_;
-  vdso_base_ = base;
-  image_.Init(base);
-  return old_base;
-}
-
-bool VDSOSupport::LookupSymbol(const char *name,
-                               const char *version,
-                               int type,
-                               SymbolInfo *info) const {
-  return image_.LookupSymbol(name, version, type, info);
-}
-
-bool VDSOSupport::LookupSymbolByAddress(const void *address,
-                                        SymbolInfo *info_out) const {
-  return image_.LookupSymbolByAddress(address, info_out);
-}
-
-// We need to make sure VDSOSupport::Init() is called before
-// the main() runs, since it might do something like setuid or
-// chroot.  If VDSOSupport
-// is used in any global constructor, this will happen, since
-// VDSOSupport's constructor calls Init.  But if not, we need to
-// ensure it here, with a global constructor of our own.  This
-// is an allowed exception to the normal rule against non-trivial
-// global constructors.
-static class VDSOInitHelper {
- public:
-  VDSOInitHelper() { VDSOSupport::Init(); }
-} vdso_init_helper;
-}
-
-#endif  // HAVE_VDSO_SUPPORT
diff --git a/third_party/tcmalloc/vendor/src/base/vdso_support.h b/third_party/tcmalloc/vendor/src/base/vdso_support.h
deleted file mode 100644
index c17d2249..0000000
--- a/third_party/tcmalloc/vendor/src/base/vdso_support.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Pluzhnikov
-//
-// Allow dynamic symbol lookup in the kernel VDSO page.
-//
-// VDSO stands for "Virtual Dynamic Shared Object" -- a page of
-// executable code, which looks like a shared library, but doesn't
-// necessarily exist anywhere on disk, and which gets mmap()ed into
-// every process by kernels which support VDSO, such as 2.6.x for 32-bit
-// executables, and 2.6.24 and above for 64-bit executables.
-//
-// More details could be found here:
-// http://www.trilithium.com/johan/2005/08/linux-gate/
-//
-// VDSOSupport -- a class representing kernel VDSO (if present).
-//
-// Example usage:
-//  VDSOSupport vdso;
-//  VDSOSupport::SymbolInfo info;
-//  typedef (*FN)(unsigned *, void *, void *);
-//  FN fn = NULL;
-//  if (vdso.LookupSymbol("__vdso_getcpu", "LINUX_2.6", STT_FUNC, &info)) {
-//     fn = reinterpret_cast<FN>(info.address);
-//  }
-
-#ifndef BASE_VDSO_SUPPORT_H_
-#define BASE_VDSO_SUPPORT_H_
-
-#include <config.h>
-#include "base/basictypes.h"
-#include "base/elf_mem_image.h"
-
-#ifdef HAVE_ELF_MEM_IMAGE
-
-// Enable VDSO support only for the architectures/operating systems that
-// support it.
-#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
-#define HAVE_VDSO_SUPPORT 1
-#endif
-
-#include <stdlib.h>     // for NULL
-
-namespace base {
-
-// NOTE: this class may be used from within tcmalloc, and can not
-// use any memory allocation routines.
-class VDSOSupport {
- public:
-  VDSOSupport();
-
-  typedef ElfMemImage::SymbolInfo SymbolInfo;
-  typedef ElfMemImage::SymbolIterator SymbolIterator;
-
-  // Answers whether we have a vdso at all.
-  bool IsPresent() const { return image_.IsPresent(); }
-
-  // Allow to iterate over all VDSO symbols.
-  SymbolIterator begin() const { return image_.begin(); }
-  SymbolIterator end() const { return image_.end(); }
-
-  // Look up versioned dynamic symbol in the kernel VDSO.
-  // Returns false if VDSO is not present, or doesn't contain given
-  // symbol/version/type combination.
-  // If info_out != NULL, additional details are filled in.
-  bool LookupSymbol(const char *name, const char *version,
-                    int symbol_type, SymbolInfo *info_out) const;
-
-  // Find info about symbol (if any) which overlaps given address.
-  // Returns true if symbol was found; false if VDSO isn't present
-  // or doesn't have a symbol overlapping given address.
-  // If info_out != NULL, additional details are filled in.
-  bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const;
-
-  // Used only for testing. Replace real VDSO base with a mock.
-  // Returns previous value of vdso_base_. After you are done testing,
-  // you are expected to call SetBase() with previous value, in order to
-  // reset state to the way it was.
-  const void *SetBase(const void *s);
-
-  // Computes vdso_base_ and returns it. Should be called as early as
-  // possible; before any thread creation, chroot or setuid.
-  static const void *Init();
-
- private:
-  // image_ represents VDSO ELF image in memory.
-  // image_.ehdr_ == NULL implies there is no VDSO.
-  ElfMemImage image_;
-
-  // Cached value of auxv AT_SYSINFO_EHDR, computed once.
-  // This is a tri-state:
-  //   kInvalidBase   => value hasn't been determined yet.
-  //              0   => there is no VDSO.
-  //           else   => vma of VDSO Elf{32,64}_Ehdr.
-  //
-  // When testing with mock VDSO, low bit is set.
-  // The low bit is always available because vdso_base_ is
-  // page-aligned.
-  static const void *vdso_base_;
-
-  DISALLOW_COPY_AND_ASSIGN(VDSOSupport);
-};
-
-}  // namespace base
-
-#endif  // HAVE_ELF_MEM_IMAGE
-
-#endif  // BASE_VDSO_SUPPORT_H_
diff --git a/third_party/tcmalloc/vendor/src/central_freelist.cc b/third_party/tcmalloc/vendor/src/central_freelist.cc
deleted file mode 100644
index 01a73104..0000000
--- a/third_party/tcmalloc/vendor/src/central_freelist.cc
+++ /dev/null
@@ -1,387 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include "config.h"
-#include <algorithm>
-#include "central_freelist.h"
-#include "internal_logging.h"  // for ASSERT, MESSAGE
-#include "linked_list.h"       // for SLL_Next, SLL_Push, etc
-#include "page_heap.h"         // for PageHeap
-#include "static_vars.h"       // for Static
-
-using std::min;
-using std::max;
-
-namespace tcmalloc {
-
-void CentralFreeList::Init(size_t cl) {
-  size_class_ = cl;
-  tcmalloc::DLL_Init(&empty_);
-  tcmalloc::DLL_Init(&nonempty_);
-  num_spans_ = 0;
-  counter_ = 0;
-
-  max_cache_size_ = kMaxNumTransferEntries;
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-  // Disable the transfer cache for the small footprint case.
-  cache_size_ = 0;
-#else
-  cache_size_ = 16;
-#endif
-  if (cl > 0) {
-    // Limit the maximum size of the cache based on the size class.  If this
-    // is not done, large size class objects will consume a lot of memory if
-    // they just sit in the transfer cache.
-    int32_t bytes = Static::sizemap()->ByteSizeForClass(cl);
-    int32_t objs_to_move = Static::sizemap()->num_objects_to_move(cl);
-
-    ASSERT(objs_to_move > 0 && bytes > 0);
-    // Limit each size class cache to at most 1MB of objects or one entry,
-    // whichever is greater. Total transfer cache memory used across all
-    // size classes then can't be greater than approximately
-    // 1MB * kMaxNumTransferEntries.
-    // min and max are in parens to avoid macro-expansion on windows.
-    max_cache_size_ = (min)(max_cache_size_,
-                          (max)(1, (1024 * 1024) / (bytes * objs_to_move)));
-    cache_size_ = (min)(cache_size_, max_cache_size_);
-  }
-  used_slots_ = 0;
-  ASSERT(cache_size_ <= max_cache_size_);
-}
-
-void CentralFreeList::ReleaseListToSpans(void* start) {
-  while (start) {
-    void *next = SLL_Next(start);
-    ReleaseToSpans(start);
-    start = next;
-  }
-}
-
-// MapObjectToSpan should logically be part of ReleaseToSpans.  But
-// this triggers an optimization bug in gcc 4.5.0.  Moving to a
-// separate function, and making sure that function isn't inlined,
-// seems to fix the problem.  It also should be fixed for gcc 4.5.1.
-static
-#if __GNUC__ == 4 && __GNUC_MINOR__ == 5 && __GNUC_PATCHLEVEL__ == 0
-__attribute__ ((noinline))
-#endif
-Span* MapObjectToSpan(void* object) {
-  const PageID p = reinterpret_cast<uintptr_t>(object) >> kPageShift;
-  Span* span = Static::pageheap()->GetDescriptor(p);
-  return span;
-}
-
-void CentralFreeList::ReleaseToSpans(void* object) {
-  Span* span = MapObjectToSpan(object);
-  ASSERT(span != NULL);
-  ASSERT(span->refcount > 0);
-
-  // If span is empty, move it to non-empty list
-  if (span->objects == NULL) {
-    tcmalloc::DLL_Remove(span);
-    tcmalloc::DLL_Prepend(&nonempty_, span);
-    Event(span, 'N', 0);
-  }
-
-  // The following check is expensive, so it is disabled by default
-  if (false) {
-    // Check that object does not occur in list
-    int got = 0;
-    for (void* p = span->objects; p != NULL; p = *((void**) p)) {
-      ASSERT(p != object);
-      got++;
-    }
-    ASSERT(got + span->refcount ==
-           (span->length<<kPageShift) /
-           Static::sizemap()->ByteSizeForClass(span->sizeclass));
-  }
-
-  counter_++;
-  span->refcount--;
-  if (span->refcount == 0) {
-    Event(span, '#', 0);
-    counter_ -= ((span->length<<kPageShift) /
-                 Static::sizemap()->ByteSizeForClass(span->sizeclass));
-    tcmalloc::DLL_Remove(span);
-    --num_spans_;
-
-    // Release central list lock while operating on pageheap
-    lock_.Unlock();
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      Static::pageheap()->Delete(span);
-    }
-    lock_.Lock();
-  } else {
-    *(reinterpret_cast<void**>(object)) = span->objects;
-    span->objects = object;
-  }
-}
-
-bool CentralFreeList::EvictRandomSizeClass(
-    int locked_size_class, bool force) {
-  static int race_counter = 0;
-  int t = race_counter++;  // Updated without a lock, but who cares.
-  if (t >= Static::num_size_classes()) {
-    while (t >= Static::num_size_classes()) {
-      t -= Static::num_size_classes();
-    }
-    race_counter = t;
-  }
-  ASSERT(t >= 0);
-  ASSERT(t < Static::num_size_classes());
-  if (t == locked_size_class) return false;
-  return Static::central_cache()[t].ShrinkCache(locked_size_class, force);
-}
-
-bool CentralFreeList::MakeCacheSpace() {
-  // Is there room in the cache?
-  if (used_slots_ < cache_size_) return true;
-  // Check if we can expand this cache?
-  if (cache_size_ == max_cache_size_) return false;
-  // Ok, we'll try to grab an entry from some other size class.
-  if (EvictRandomSizeClass(size_class_, false) ||
-      EvictRandomSizeClass(size_class_, true)) {
-    // Succeeded in evicting, we're going to make our cache larger.
-    // However, we may have dropped and re-acquired the lock in
-    // EvictRandomSizeClass (via ShrinkCache and the LockInverter), so the
-    // cache_size may have changed.  Therefore, check and verify that it is
-    // still OK to increase the cache_size.
-    if (cache_size_ < max_cache_size_) {
-      cache_size_++;
-      return true;
-    }
-  }
-  return false;
-}
-
-
-namespace {
-class LockInverter {
- private:
-  SpinLock *held_, *temp_;
- public:
-  inline explicit LockInverter(SpinLock* held, SpinLock *temp)
-    : held_(held), temp_(temp) { held_->Unlock(); temp_->Lock(); }
-  inline ~LockInverter() { temp_->Unlock(); held_->Lock();  }
-};
-}
-
-// This function is marked as NO_THREAD_SAFETY_ANALYSIS because it uses
-// LockInverter to release one lock and acquire another in scoped-lock
-// style, which our current annotation/analysis does not support.
-bool CentralFreeList::ShrinkCache(int locked_size_class, bool force)
-    NO_THREAD_SAFETY_ANALYSIS {
-  // Start with a quick check without taking a lock.
-  if (cache_size_ == 0) return false;
-  // We don't evict from a full cache unless we are 'forcing'.
-  if (force == false && used_slots_ == cache_size_) return false;
-
-  // Grab lock, but first release the other lock held by this thread.  We use
-  // the lock inverter to ensure that we never hold two size class locks
-  // concurrently.  That can create a deadlock because there is no well
-  // defined nesting order.
-  LockInverter li(&Static::central_cache()[locked_size_class].lock_, &lock_);
-  ASSERT(used_slots_ <= cache_size_);
-  ASSERT(0 <= cache_size_);
-  if (cache_size_ == 0) return false;
-  if (used_slots_ == cache_size_) {
-    if (force == false) return false;
-    // ReleaseListToSpans releases the lock, so we have to make all the
-    // updates to the central list before calling it.
-    cache_size_--;
-    used_slots_--;
-    ReleaseListToSpans(tc_slots_[used_slots_].head);
-    return true;
-  }
-  cache_size_--;
-  return true;
-}
-
-void CentralFreeList::InsertRange(void *start, void *end, int N) {
-  SpinLockHolder h(&lock_);
-  if (N == Static::sizemap()->num_objects_to_move(size_class_) &&
-    MakeCacheSpace()) {
-    int slot = used_slots_++;
-    ASSERT(slot >=0);
-    ASSERT(slot < max_cache_size_);
-    TCEntry *entry = &tc_slots_[slot];
-    entry->head = start;
-    entry->tail = end;
-    return;
-  }
-  ReleaseListToSpans(start);
-}
-
-int CentralFreeList::RemoveRange(void **start, void **end, int N) {
-  ASSERT(N > 0);
-  lock_.Lock();
-  if (N == Static::sizemap()->num_objects_to_move(size_class_) &&
-      used_slots_ > 0) {
-    int slot = --used_slots_;
-    ASSERT(slot >= 0);
-    TCEntry *entry = &tc_slots_[slot];
-    *start = entry->head;
-    *end = entry->tail;
-    lock_.Unlock();
-    return N;
-  }
-
-  int result = 0;
-  *start = NULL;
-  *end = NULL;
-  // TODO: Prefetch multiple TCEntries?
-  result = FetchFromOneSpansSafe(N, start, end);
-  if (result != 0) {
-    while (result < N) {
-      int n;
-      void* head = NULL;
-      void* tail = NULL;
-      n = FetchFromOneSpans(N - result, &head, &tail);
-      if (!n) break;
-      result += n;
-      SLL_PushRange(start, head, tail);
-    }
-  }
-  lock_.Unlock();
-  return result;
-}
-
-
-int CentralFreeList::FetchFromOneSpansSafe(int N, void **start, void **end) {
-  int result = FetchFromOneSpans(N, start, end);
-  if (!result) {
-    Populate();
-    result = FetchFromOneSpans(N, start, end);
-  }
-  return result;
-}
-
-int CentralFreeList::FetchFromOneSpans(int N, void **start, void **end) {
-  if (tcmalloc::DLL_IsEmpty(&nonempty_)) return 0;
-  Span* span = nonempty_.next;
-
-  ASSERT(span->objects != NULL);
-
-  int result = 0;
-  void *prev, *curr;
-  curr = span->objects;
-  do {
-    prev = curr;
-    curr = *(reinterpret_cast<void**>(curr));
-  } while (++result < N && curr != NULL);
-
-  if (curr == NULL) {
-    // Move to empty list
-    tcmalloc::DLL_Remove(span);
-    tcmalloc::DLL_Prepend(&empty_, span);
-    Event(span, 'E', 0);
-  }
-
-  *start = span->objects;
-  *end = prev;
-  span->objects = curr;
-  SLL_SetNext(*end, NULL);
-  span->refcount += result;
-  counter_ -= result;
-  return result;
-}
-
-// Fetch memory from the system and add to the central cache freelist.
-void CentralFreeList::Populate() {
-  // Release central list lock while operating on pageheap
-  lock_.Unlock();
-  const size_t npages = Static::sizemap()->class_to_pages(size_class_);
-
-  Span* span;
-  {
-    SpinLockHolder h(Static::pageheap_lock());
-    span = Static::pageheap()->New(npages);
-    if (span) Static::pageheap()->RegisterSizeClass(span, size_class_);
-  }
-  if (span == NULL) {
-    Log(kLog, __FILE__, __LINE__,
-        "tcmalloc: allocation failed", npages << kPageShift);
-    lock_.Lock();
-    return;
-  }
-  ASSERT(span->length == npages);
-  // Cache sizeclass info eagerly.  Locking is not necessary.
-  // (Instead of being eager, we could just replace any stale info
-  // about this span, but that seems to be no better in practice.)
-  for (int i = 0; i < npages; i++) {
-    Static::pageheap()->SetCachedSizeClass(span->start + i, size_class_);
-  }
-
-  // Split the block into pieces and add to the free-list
-  // TODO: coloring of objects to avoid cache conflicts?
-  void** tail = &span->objects;
-  char* ptr = reinterpret_cast<char*>(span->start << kPageShift);
-  char* limit = ptr + (npages << kPageShift);
-  const size_t size = Static::sizemap()->ByteSizeForClass(size_class_);
-  int num = 0;
-  while (ptr + size <= limit) {
-    *tail = ptr;
-    tail = reinterpret_cast<void**>(ptr);
-    ptr += size;
-    num++;
-  }
-  ASSERT(ptr <= limit);
-  *tail = NULL;
-  span->refcount = 0; // No sub-object in use yet
-
-  // Add span to list of non-empty spans
-  lock_.Lock();
-  tcmalloc::DLL_Prepend(&nonempty_, span);
-  ++num_spans_;
-  counter_ += num;
-}
-
-int CentralFreeList::tc_length() {
-  SpinLockHolder h(&lock_);
-  return used_slots_ * Static::sizemap()->num_objects_to_move(size_class_);
-}
-
-size_t CentralFreeList::OverheadBytes() {
-  SpinLockHolder h(&lock_);
-  if (size_class_ == 0) {  // 0 holds the 0-sized allocations
-    return 0;
-  }
-  const size_t pages_per_span = Static::sizemap()->class_to_pages(size_class_);
-  const size_t object_size = Static::sizemap()->class_to_size(size_class_);
-  ASSERT(object_size > 0);
-  const size_t overhead_per_span = (pages_per_span * kPageSize) % object_size;
-  return num_spans_ * overhead_per_span;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/vendor/src/central_freelist.h b/third_party/tcmalloc/vendor/src/central_freelist.h
deleted file mode 100644
index 4148680d..0000000
--- a/third_party/tcmalloc/vendor/src/central_freelist.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#ifndef TCMALLOC_CENTRAL_FREELIST_H_
-#define TCMALLOC_CENTRAL_FREELIST_H_
-
-#include "config.h"
-#include <stddef.h>                     // for size_t
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for int32_t
-#endif
-#include "base/spinlock.h"
-#include "base/thread_annotations.h"
-#include "common.h"
-#include "span.h"
-
-namespace tcmalloc {
-
-// Data kept per size-class in central cache.
-class CentralFreeList {
- public:
-  // A CentralFreeList may be used before its constructor runs.
-  // So we prevent lock_'s constructor from doing anything to the
-  // lock_ state.
-  CentralFreeList() : lock_(base::LINKER_INITIALIZED) { }
-
-  void Init(size_t cl);
-
-  // These methods all do internal locking.
-
-  // Insert the specified range into the central freelist.  N is the number of
-  // elements in the range.  RemoveRange() is the opposite operation.
-  void InsertRange(void *start, void *end, int N);
-
-  // Returns the actual number of fetched elements and sets *start and *end.
-  int RemoveRange(void **start, void **end, int N);
-
-  // Returns the number of free objects in cache.
-  int length() {
-    SpinLockHolder h(&lock_);
-    return counter_;
-  }
-
-  // Returns the number of free objects in the transfer cache.
-  int tc_length();
-
-  // Returns the memory overhead (internal fragmentation) attributable
-  // to the freelist.  This is memory lost when the size of elements
-  // in a freelist doesn't exactly divide the page-size (an 8192-byte
-  // page full of 5-byte objects would have 2 bytes memory overhead).
-  size_t OverheadBytes();
-
-  // Lock/Unlock the internal SpinLock. Used on the pthread_atfork call
-  // to set the lock in a consistent state before the fork.
-  void Lock() {
-    lock_.Lock();
-  }
-
-  void Unlock() {
-    lock_.Unlock();
-  }
-
- private:
-  // TransferCache is used to cache transfers of
-  // sizemap.num_objects_to_move(size_class) back and forth between
-  // thread caches and the central cache for a given size class.
-  struct TCEntry {
-    void *head;  // Head of chain of objects.
-    void *tail;  // Tail of chain of objects.
-  };
-
-  // A central cache freelist can have anywhere from 0 to kMaxNumTransferEntries
-  // slots to put link list chains into.
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-  // For the small memory model, the transfer cache is not used.
-  static const int kMaxNumTransferEntries = 0;
-#else
-  // Starting point for the the maximum number of entries in the transfer cache.
-  // This actual maximum for a given size class may be lower than this
-  // maximum value.
-  static const int kMaxNumTransferEntries = 64;
-#endif
-
-  // REQUIRES: lock_ is held
-  // Remove object from cache and return.
-  // Return NULL if no free entries in cache.
-  int FetchFromOneSpans(int N, void **start, void **end) EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ is held
-  // Remove object from cache and return.  Fetches
-  // from pageheap if cache is empty.  Only returns
-  // NULL on allocation failure.
-  int FetchFromOneSpansSafe(int N, void **start, void **end) EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ is held
-  // Release a linked list of objects to spans.
-  // May temporarily release lock_.
-  void ReleaseListToSpans(void *start) EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ is held
-  // Release an object to spans.
-  // May temporarily release lock_.
-  void ReleaseToSpans(void* object) EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ is held
-  // Populate cache by fetching from the page heap.
-  // May temporarily release lock_.
-  void Populate() EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock is held.
-  // Tries to make room for a TCEntry.  If the cache is full it will try to
-  // expand it at the cost of some other cache size.  Return false if there is
-  // no space.
-  bool MakeCacheSpace() EXCLUSIVE_LOCKS_REQUIRED(lock_);
-
-  // REQUIRES: lock_ for locked_size_class is held.
-  // Picks a "random" size class to steal TCEntry slot from.  In reality it
-  // just iterates over the sizeclasses but does so without taking a lock.
-  // Returns true on success.
-  // May temporarily lock a "random" size class.
-  static bool EvictRandomSizeClass(int locked_size_class, bool force);
-
-  // REQUIRES: lock_ is *not* held.
-  // Tries to shrink the Cache.  If force is true it will relase objects to
-  // spans if it allows it to shrink the cache.  Return false if it failed to
-  // shrink the cache.  Decrements cache_size_ on succeess.
-  // May temporarily take lock_.  If it takes lock_, the locked_size_class
-  // lock is released to keep the thread from holding two size class locks
-  // concurrently which could lead to a deadlock.
-  bool ShrinkCache(int locked_size_class, bool force) LOCKS_EXCLUDED(lock_);
-
-  // This lock protects all the data members.  cached_entries and cache_size_
-  // may be looked at without holding the lock.
-  SpinLock lock_;
-
-  // We keep linked lists of empty and non-empty spans.
-  size_t   size_class_;     // My size class
-  Span     empty_;          // Dummy header for list of empty spans
-  Span     nonempty_;       // Dummy header for list of non-empty spans
-  size_t   num_spans_;      // Number of spans in empty_ plus nonempty_
-  size_t   counter_;        // Number of free objects in cache entry
-
-  // Here we reserve space for TCEntry cache slots.  Space is preallocated
-  // for the largest possible number of entries than any one size class may
-  // accumulate.  Not all size classes are allowed to accumulate
-  // kMaxNumTransferEntries, so there is some wasted space for those size
-  // classes.
-  TCEntry tc_slots_[kMaxNumTransferEntries];
-
-  // Number of currently used cached entries in tc_slots_.  This variable is
-  // updated under a lock but can be read without one.
-  int32_t used_slots_;
-  // The current number of slots for this size class.  This is an
-  // adaptive value that is increased if there is lots of traffic
-  // on a given size class.
-  int32_t cache_size_;
-  // Maximum size of the cache for a given size class.
-  int32_t max_cache_size_;
-};
-
-// Pads each CentralCache object to multiple of 64 bytes.  Since some
-// compilers (such as MSVC) don't like it when the padding is 0, I use
-// template specialization to remove the padding entirely when
-// sizeof(CentralFreeList) is a multiple of 64.
-template<int kFreeListSizeMod64>
-class CentralFreeListPaddedTo : public CentralFreeList {
- private:
-  char pad_[64 - kFreeListSizeMod64];
-};
-
-template<>
-class CentralFreeListPaddedTo<0> : public CentralFreeList {
-};
-
-class CentralFreeListPadded : public CentralFreeListPaddedTo<
-  sizeof(CentralFreeList) % 64> {
-};
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_CENTRAL_FREELIST_H_
diff --git a/third_party/tcmalloc/vendor/src/common.cc b/third_party/tcmalloc/vendor/src/common.cc
deleted file mode 100644
index 203afdf9..0000000
--- a/third_party/tcmalloc/vendor/src/common.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <stdlib.h> // for getenv and strtol
-#include "config.h"
-#include "common.h"
-#include "system-alloc.h"
-#include "base/spinlock.h"
-#include "getenv_safe.h" // TCMallocGetenvSafe
-
-namespace tcmalloc {
-
-// Define the maximum number of object per classe type to transfer between
-// thread and central caches.
-static int32 FLAGS_tcmalloc_transfer_num_objects;
-
-static const int32 kDefaultTransferNumObjecs = 32;
-
-// The init function is provided to explicit initialize the variable value
-// from the env. var to avoid C++ global construction that might defer its
-// initialization after a malloc/new call.
-static inline void InitTCMallocTransferNumObjects()
-{
-  if (FLAGS_tcmalloc_transfer_num_objects == 0) {
-    const char *envval = TCMallocGetenvSafe("TCMALLOC_TRANSFER_NUM_OBJ");
-    FLAGS_tcmalloc_transfer_num_objects = !envval ? kDefaultTransferNumObjecs :
-      strtol(envval, NULL, 10);
-  }
-}
-
-// Note: the following only works for "n"s that fit in 32-bits, but
-// that is fine since we only use it for small sizes.
-static inline int LgFloor(size_t n) {
-  int log = 0;
-  for (int i = 4; i >= 0; --i) {
-    int shift = (1 << i);
-    size_t x = n >> shift;
-    if (x != 0) {
-      n = x;
-      log += shift;
-    }
-  }
-  ASSERT(n == 1);
-  return log;
-}
-
-int AlignmentForSize(size_t size) {
-  int alignment = kAlignment;
-  if (size > kMaxSize) {
-    // Cap alignment at kPageSize for large sizes.
-    alignment = kPageSize;
-  } else if (size >= 128) {
-    // Space wasted due to alignment is at most 1/8, i.e., 12.5%.
-    alignment = (1 << LgFloor(size)) / 8;
-  } else if (size >= kMinAlign) {
-    // We need an alignment of at least 16 bytes to satisfy
-    // requirements for some SSE types.
-    alignment = kMinAlign;
-  }
-  // Maximum alignment allowed is page size alignment.
-  if (alignment > kPageSize) {
-    alignment = kPageSize;
-  }
-  CHECK_CONDITION(size < kMinAlign || alignment >= kMinAlign);
-  CHECK_CONDITION((alignment & (alignment - 1)) == 0);
-  return alignment;
-}
-
-int SizeMap::NumMoveSize(size_t size) {
-  if (size == 0) return 0;
-  // Use approx 64k transfers between thread and central caches.
-  int num = static_cast<int>(64.0 * 1024.0 / size);
-  if (num < 2) num = 2;
-
-  // Avoid bringing too many objects into small object free lists.
-  // If this value is too large:
-  // - We waste memory with extra objects sitting in the thread caches.
-  // - The central freelist holds its lock for too long while
-  //   building a linked list of objects, slowing down the allocations
-  //   of other threads.
-  // If this value is too small:
-  // - We go to the central freelist too often and we have to acquire
-  //   its lock each time.
-  // This value strikes a balance between the constraints above.
-  if (num > FLAGS_tcmalloc_transfer_num_objects)
-    num = FLAGS_tcmalloc_transfer_num_objects;
-
-  return num;
-}
-
-// Initialize the mapping arrays
-void SizeMap::Init() {
-  InitTCMallocTransferNumObjects();
-
-  // Do some sanity checking on add_amount[]/shift_amount[]/class_array[]
-  if (ClassIndex(0) != 0) {
-    Log(kCrash, __FILE__, __LINE__,
-        "Invalid class index for size 0", ClassIndex(0));
-  }
-  if (ClassIndex(kMaxSize) >= sizeof(class_array_)) {
-    Log(kCrash, __FILE__, __LINE__,
-        "Invalid class index for kMaxSize", ClassIndex(kMaxSize));
-  }
-
-  // Compute the size classes we want to use
-  int sc = 1;   // Next size class to assign
-  int alignment = kAlignment;
-  CHECK_CONDITION(kAlignment <= kMinAlign);
-  for (size_t size = kAlignment; size <= kMaxSize; size += alignment) {
-    alignment = AlignmentForSize(size);
-    CHECK_CONDITION((size % alignment) == 0);
-
-    int blocks_to_move = NumMoveSize(size) / 4;
-    size_t psize = 0;
-    do {
-      psize += kPageSize;
-      // Allocate enough pages so leftover is less than 1/8 of total.
-      // This bounds wasted space to at most 12.5%.
-      while ((psize % size) > (psize >> 3)) {
-        psize += kPageSize;
-      }
-      // Continue to add pages until there are at least as many objects in
-      // the span as are needed when moving objects from the central
-      // freelists and spans to the thread caches.
-    } while ((psize / size) < (blocks_to_move));
-    const size_t my_pages = psize >> kPageShift;
-
-    if (sc > 1 && my_pages == class_to_pages_[sc-1]) {
-      // See if we can merge this into the previous class without
-      // increasing the fragmentation of the previous class.
-      const size_t my_objects = (my_pages << kPageShift) / size;
-      const size_t prev_objects = (class_to_pages_[sc-1] << kPageShift)
-                                  / class_to_size_[sc-1];
-      if (my_objects == prev_objects) {
-        // Adjust last class to include this size
-        class_to_size_[sc-1] = size;
-        continue;
-      }
-    }
-
-    // Add new class
-    class_to_pages_[sc] = my_pages;
-    class_to_size_[sc] = size;
-    sc++;
-  }
-  num_size_classes = sc;
-  if (sc > kClassSizesMax) {
-    Log(kCrash, __FILE__, __LINE__,
-        "too many size classes: (found vs. max)", sc, kClassSizesMax);
-  }
-
-  // Initialize the mapping arrays
-  int next_size = 0;
-  for (int c = 1; c < num_size_classes; c++) {
-    const int max_size_in_class = class_to_size_[c];
-    for (int s = next_size; s <= max_size_in_class; s += kAlignment) {
-      class_array_[ClassIndex(s)] = c;
-    }
-    next_size = max_size_in_class + kAlignment;
-  }
-
-  // Double-check sizes just to be safe
-  for (size_t size = 0; size <= kMaxSize;) {
-    const int sc = SizeClass(size);
-    if (sc <= 0 || sc >= num_size_classes) {
-      Log(kCrash, __FILE__, __LINE__,
-          "Bad size class (class, size)", sc, size);
-    }
-    if (sc > 1 && size <= class_to_size_[sc-1]) {
-      Log(kCrash, __FILE__, __LINE__,
-          "Allocating unnecessarily large class (class, size)", sc, size);
-    }
-    const size_t s = class_to_size_[sc];
-    if (size > s || s == 0) {
-      Log(kCrash, __FILE__, __LINE__,
-          "Bad (class, size, requested)", sc, s, size);
-    }
-    if (size <= kMaxSmallSize) {
-      size += 8;
-    } else {
-      size += 128;
-    }
-  }
-
-  // Our fast-path aligned allocation functions rely on 'naturally
-  // aligned' sizes to produce aligned addresses. Lets check if that
-  // holds for size classes that we produced.
-  //
-  // I.e. we're checking that
-  //
-  // align = (1 << shift), malloc(i * align) % align == 0,
-  //
-  // for all align values up to kPageSize.
-  for (size_t align = kMinAlign; align <= kPageSize; align <<= 1) {
-    for (size_t size = align; size < kPageSize; size += align) {
-      CHECK_CONDITION(class_to_size_[SizeClass(size)] % align == 0);
-    }
-  }
-
-  // Initialize the num_objects_to_move array.
-  for (size_t cl = 1; cl  < num_size_classes; ++cl) {
-    num_objects_to_move_[cl] = NumMoveSize(ByteSizeForClass(cl));
-  }
-}
-
-// Metadata allocator -- keeps stats about how many bytes allocated.
-static uint64_t metadata_system_bytes_ = 0;
-static const size_t kMetadataAllocChunkSize = 8*1024*1024;
-// As ThreadCache objects are allocated with MetaDataAlloc, and also
-// CACHELINE_ALIGNED, we must use the same alignment as TCMalloc_SystemAlloc.
-static const size_t kMetadataAllignment = sizeof(MemoryAligner);
-
-static char *metadata_chunk_alloc_;
-static size_t metadata_chunk_avail_;
-
-static SpinLock metadata_alloc_lock(SpinLock::LINKER_INITIALIZED);
-
-void* MetaDataAlloc(size_t bytes) {
-  if (bytes >= kMetadataAllocChunkSize) {
-    void *rv = TCMalloc_SystemAlloc(bytes,
-                                    NULL, kMetadataAllignment);
-    if (rv != NULL) {
-      metadata_system_bytes_ += bytes;
-    }
-    return rv;
-  }
-
-  SpinLockHolder h(&metadata_alloc_lock);
-
-  // the following works by essentially turning address to integer of
-  // log_2 kMetadataAllignment size and negating it. I.e. negated
-  // value + original value gets 0 and that's what we want modulo
-  // kMetadataAllignment. Note, we negate before masking higher bits
-  // off, otherwise we'd have to mask them off after negation anyways.
-  intptr_t alignment = -reinterpret_cast<intptr_t>(metadata_chunk_alloc_) & (kMetadataAllignment-1);
-
-  if (metadata_chunk_avail_ < bytes + alignment) {
-    size_t real_size;
-    void *ptr = TCMalloc_SystemAlloc(kMetadataAllocChunkSize,
-                                     &real_size, kMetadataAllignment);
-    if (ptr == NULL) {
-      return NULL;
-    }
-
-    metadata_chunk_alloc_ = static_cast<char *>(ptr);
-    metadata_chunk_avail_ = real_size;
-
-    alignment = 0;
-  }
-
-  void *rv = static_cast<void *>(metadata_chunk_alloc_ + alignment);
-  bytes += alignment;
-  metadata_chunk_alloc_ += bytes;
-  metadata_chunk_avail_ -= bytes;
-  metadata_system_bytes_ += bytes;
-  return rv;
-}
-
-uint64_t metadata_system_bytes() { return metadata_system_bytes_; }
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/vendor/src/common.h b/third_party/tcmalloc/vendor/src/common.h
deleted file mode 100644
index cb45315..0000000
--- a/third_party/tcmalloc/vendor/src/common.h
+++ /dev/null
@@ -1,311 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// Common definitions for tcmalloc code.
-
-#ifndef TCMALLOC_COMMON_H_
-#define TCMALLOC_COMMON_H_
-
-#include "config.h"
-#include <stddef.h>                     // for size_t
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uintptr_t, uint64_t
-#endif
-#include "internal_logging.h"  // for ASSERT, etc
-#include "base/basictypes.h"   // for LIKELY, etc
-
-// Type that can hold a page number
-typedef uintptr_t PageID;
-
-// Type that can hold the length of a run of pages
-typedef uintptr_t Length;
-
-//-------------------------------------------------------------------
-// Configuration
-//-------------------------------------------------------------------
-
-#if defined(TCMALLOC_ALIGN_8BYTES)
-// Unless we force to use 8 bytes alignment we use an alignment of
-// at least 16 bytes to statisfy requirements for some SSE types.
-// Keep in mind when using the 16 bytes alignment you can have a space
-// waste due alignment of 25%. (eg malloc of 24 bytes will get 32 bytes)
-static const size_t kMinAlign   = 8;
-#else
-static const size_t kMinAlign   = 16;
-#endif
-
-// Using large pages speeds up the execution at a cost of larger memory use.
-// Deallocation may speed up by a factor as the page map gets 8x smaller, so
-// lookups in the page map result in fewer L2 cache misses, which translates to
-// speedup for application/platform combinations with high L2 cache pressure.
-// As the number of size classes increases with large pages, we increase
-// the thread cache allowance to avoid passing more free ranges to and from
-// central lists.  Also, larger pages are less likely to get freed.
-// These two factors cause a bounded increase in memory use.
-#if defined(TCMALLOC_32K_PAGES)
-static const size_t kPageShift  = 15;
-#elif defined(TCMALLOC_64K_PAGES)
-static const size_t kPageShift  = 16;
-#else
-static const size_t kPageShift  = 13;
-#endif
-
-static const size_t kClassSizesMax = 96;
-
-static const size_t kMaxThreadCacheSize = 4 << 20;
-
-static const size_t kPageSize   = 1 << kPageShift;
-static const size_t kMaxSize    = 256 * 1024;
-static const size_t kAlignment  = 8;
-// For all span-lengths <= kMaxPages we keep an exact-size list in PageHeap.
-static const size_t kMaxPages = 1 << (20 - kPageShift);
-
-// Default bound on the total amount of thread caches.
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-// Make the overall thread cache no bigger than that of a single thread
-// for the small memory footprint case.
-static const size_t kDefaultOverallThreadCacheSize = kMaxThreadCacheSize;
-#else
-static const size_t kDefaultOverallThreadCacheSize = 8u * kMaxThreadCacheSize;
-#endif
-
-// Lower bound on the per-thread cache sizes
-static const size_t kMinThreadCacheSize = kMaxSize * 2;
-
-// The number of bytes one ThreadCache will steal from another when
-// the first ThreadCache is forced to Scavenge(), delaying the
-// next call to Scavenge for this thread.
-static const size_t kStealAmount = 1 << 16;
-
-// The number of times that a deallocation can cause a freelist to
-// go over its max_length() before shrinking max_length().
-static const int kMaxOverages = 3;
-
-// Maximum length we allow a per-thread free-list to have before we
-// move objects from it into the corresponding central free-list.  We
-// want this big to avoid locking the central free-list too often.  It
-// should not hurt to make this list somewhat big because the
-// scavenging code will shrink it down when its contents are not in use.
-static const int kMaxDynamicFreeListLength = 8192;
-
-static const Length kMaxValidPages = (~static_cast<Length>(0)) >> kPageShift;
-
-#if __aarch64__ || __x86_64__ || _M_AMD64 || _M_ARM64
-// All current x86_64 processors only look at the lower 48 bits in
-// virtual to physical address translation. The top 16 are all same as
-// bit 47. And bit 47 value 1 reserved for kernel-space addresses in
-// practice. So it is actually 47 usable bits from malloc
-// perspective. This lets us use faster two level page maps on this
-// architecture.
-//
-// There is very similar story on 64-bit arms except it has full 48
-// bits for user-space. Because of that, and because in principle OSes
-// can start giving some of highest-bit-set addresses to user-space,
-// we don't bother to limit x86 to 47 bits.
-//
-// As of now there are published plans to add more bits to x86-64
-// virtual address space, but since 48 bits has been norm for long
-// time and lots of software is relying on it, it will be opt-in from
-// OS perspective. So we can keep doing "48 bits" at least for now.
-static const int kAddressBits = (sizeof(void*) < 8 ? (8 * sizeof(void*)) : 48);
-#else
-// mipsen and ppcs have more general hardware so we have to support
-// full 64-bits of addresses.
-static const int kAddressBits = 8 * sizeof(void*);
-#endif
-
-namespace tcmalloc {
-
-// Convert byte size into pages.  This won't overflow, but may return
-// an unreasonably large value if bytes is huge enough.
-inline Length pages(size_t bytes) {
-  return (bytes >> kPageShift) +
-      ((bytes & (kPageSize - 1)) > 0 ? 1 : 0);
-}
-
-// For larger allocation sizes, we use larger memory alignments to
-// reduce the number of size classes.
-int AlignmentForSize(size_t size);
-
-// Size-class information + mapping
-class SizeMap {
- private:
-  //-------------------------------------------------------------------
-  // Mapping from size to size_class and vice versa
-  //-------------------------------------------------------------------
-
-  // Sizes <= 1024 have an alignment >= 8.  So for such sizes we have an
-  // array indexed by ceil(size/8).  Sizes > 1024 have an alignment >= 128.
-  // So for these larger sizes we have an array indexed by ceil(size/128).
-  //
-  // We flatten both logical arrays into one physical array and use
-  // arithmetic to compute an appropriate index.  The constants used by
-  // ClassIndex() were selected to make the flattening work.
-  //
-  // Examples:
-  //   Size       Expression                      Index
-  //   -------------------------------------------------------
-  //   0          (0 + 7) / 8                     0
-  //   1          (1 + 7) / 8                     1
-  //   ...
-  //   1024       (1024 + 7) / 8                  128
-  //   1025       (1025 + 127 + (120<<7)) / 128   129
-  //   ...
-  //   32768      (32768 + 127 + (120<<7)) / 128  376
-  static const int kMaxSmallSize = 1024;
-  static const size_t kClassArraySize =
-      ((kMaxSize + 127 + (120 << 7)) >> 7) + 1;
-  unsigned char class_array_[kClassArraySize];
-
-  static inline size_t SmallSizeClass(size_t s) {
-    return (static_cast<uint32_t>(s) + 7) >> 3;
-  }
-
-  static inline size_t LargeSizeClass(size_t s) {
-    return (static_cast<uint32_t>(s) + 127 + (120 << 7)) >> 7;
-  }
-
-  // If size is no more than kMaxSize, compute index of the
-  // class_array[] entry for it, putting the class index in output
-  // parameter idx and returning true. Otherwise return false.
-  static inline bool ATTRIBUTE_ALWAYS_INLINE ClassIndexMaybe(size_t s,
-                                                             uint32* idx) {
-    if (PREDICT_TRUE(s <= kMaxSmallSize)) {
-      *idx = (static_cast<uint32>(s) + 7) >> 3;
-      return true;
-    } else if (s <= kMaxSize) {
-      *idx = (static_cast<uint32>(s) + 127 + (120 << 7)) >> 7;
-      return true;
-    }
-    return false;
-  }
-
-  // Compute index of the class_array[] entry for a given size
-  static inline size_t ClassIndex(size_t s) {
-    // Use unsigned arithmetic to avoid unnecessary sign extensions.
-    ASSERT(0 <= s);
-    ASSERT(s <= kMaxSize);
-    if (PREDICT_TRUE(s <= kMaxSmallSize)) {
-      return SmallSizeClass(s);
-    } else {
-      return LargeSizeClass(s);
-    }
-  }
-
-  // Number of objects to move between a per-thread list and a central
-  // list in one shot.  We want this to be not too small so we can
-  // amortize the lock overhead for accessing the central list.  Making
-  // it too big may temporarily cause unnecessary memory wastage in the
-  // per-thread free list until the scavenger cleans up the list.
-  int num_objects_to_move_[kClassSizesMax];
-
-  int NumMoveSize(size_t size);
-
-  // Mapping from size class to max size storable in that class
-  int32 class_to_size_[kClassSizesMax];
-
-  // Mapping from size class to number of pages to allocate at a time
-  size_t class_to_pages_[kClassSizesMax];
-
- public:
-  size_t num_size_classes;
-
-  // Constructor should do nothing since we rely on explicit Init()
-  // call, which may or may not be called before the constructor runs.
-  SizeMap() { }
-
-  // Initialize the mapping arrays
-  void Init();
-
-  inline int SizeClass(size_t size) {
-    return class_array_[ClassIndex(size)];
-  }
-
-  // Check if size is small enough to be representable by a size
-  // class, and if it is, put matching size class into *cl. Returns
-  // true iff matching size class was found.
-  inline bool ATTRIBUTE_ALWAYS_INLINE GetSizeClass(size_t size, uint32* cl) {
-    uint32 idx;
-    if (!ClassIndexMaybe(size, &idx)) {
-      return false;
-    }
-    *cl = class_array_[idx];
-    return true;
-  }
-
-  // Get the byte-size for a specified class
-  inline int32 ATTRIBUTE_ALWAYS_INLINE ByteSizeForClass(uint32 cl) {
-    return class_to_size_[cl];
-  }
-
-  // Mapping from size class to max size storable in that class
-  inline int32 class_to_size(uint32 cl) {
-    return class_to_size_[cl];
-  }
-
-  // Mapping from size class to number of pages to allocate at a time
-  inline size_t class_to_pages(uint32 cl) {
-    return class_to_pages_[cl];
-  }
-
-  // Number of objects to move between a per-thread list and a central
-  // list in one shot.  We want this to be not too small so we can
-  // amortize the lock overhead for accessing the central list.  Making
-  // it too big may temporarily cause unnecessary memory wastage in the
-  // per-thread free list until the scavenger cleans up the list.
-  inline int num_objects_to_move(uint32 cl) {
-    return num_objects_to_move_[cl];
-  }
-};
-
-// Allocates "bytes" worth of memory and returns it.  Increments
-// metadata_system_bytes appropriately.  May return NULL if allocation
-// fails.  Requires pageheap_lock is held.
-void* MetaDataAlloc(size_t bytes);
-
-// Returns the total number of bytes allocated from the system.
-// Requires pageheap_lock is held.
-uint64_t metadata_system_bytes();
-
-// size/depth are made the same size as a pointer so that some generic
-// code below can conveniently cast them back and forth to void*.
-static const int kMaxStackDepth = 31;
-struct StackTrace {
-  uintptr_t size;          // Size of object
-  uintptr_t depth;         // Number of PC values stored in array below
-  void*     stack[kMaxStackDepth];
-};
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_COMMON_H_
diff --git a/third_party/tcmalloc/vendor/src/config_for_unittests.h b/third_party/tcmalloc/vendor/src/config_for_unittests.h
deleted file mode 100644
index 66592a7..0000000
--- a/third_party/tcmalloc/vendor/src/config_for_unittests.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Craig Silverstein
-//
-// This file is needed for windows -- unittests are not part of the
-// perftools dll, but still want to include config.h just like the
-// dll does, so they can use internal tools and APIs for testing.
-//
-// The problem is that config.h declares PERFTOOLS_DLL_DECL to be
-// for exporting symbols, but the unittest needs to *import* symbols
-// (since it's not the dll).
-//
-// The solution is to have this file, which is just like config.h but
-// sets PERFTOOLS_DLL_DECL to do a dllimport instead of a dllexport.
-//
-// The reason we need this extra PERFTOOLS_DLL_DECL_FOR_UNITTESTS
-// variable is in case people want to set PERFTOOLS_DLL_DECL explicitly
-// to something other than __declspec(dllexport).  In that case, they
-// may want to use something other than __declspec(dllimport) for the
-// unittest case.  For that, we allow folks to define both
-// PERFTOOLS_DLL_DECL and PERFTOOLS_DLL_DECL_FOR_UNITTESTS explicitly.
-//
-// NOTE: This file is equivalent to config.h on non-windows systems,
-// which never defined PERFTOOLS_DLL_DECL_FOR_UNITTESTS and always
-// define PERFTOOLS_DLL_DECL to the empty string.
-
-#include "config.h"
-
-#undef PERFTOOLS_DLL_DECL
-#ifdef PERFTOOLS_DLL_DECL_FOR_UNITTESTS
-# define PERFTOOLS_DLL_DECL  PERFTOOLS_DLL_DECL_FOR_UNITTESTS
-#else
-# define PERFTOOLS_DLL_DECL  // if DLL_DECL_FOR_UNITTESTS isn't defined, use ""
-#endif
diff --git a/third_party/tcmalloc/vendor/src/debugallocation.cc b/third_party/tcmalloc/vendor/src/debugallocation.cc
deleted file mode 100644
index 7c438f2..0000000
--- a/third_party/tcmalloc/vendor/src/debugallocation.cc
+++ /dev/null
@@ -1,1583 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2000, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Urs Holzle <opensource@google.com>
-
-#include "config.h"
-#include <errno.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-// We only need malloc.h for struct mallinfo.
-#ifdef HAVE_STRUCT_MALLINFO
-// Malloc can be in several places on older versions of OS X.
-# if defined(HAVE_MALLOC_H)
-# include <malloc.h>
-# elif defined(HAVE_MALLOC_MALLOC_H)
-# include <malloc/malloc.h>
-# elif defined(HAVE_SYS_MALLOC_H)
-# include <sys/malloc.h>
-# endif
-#endif
-#ifdef HAVE_PTHREAD
-#include <pthread.h>
-#endif
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <gperftools/malloc_extension.h>
-#include <gperftools/malloc_hook.h>
-#include <gperftools/stacktrace.h>
-#include "addressmap-inl.h"
-#include "base/commandlineflags.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "malloc_hook-inl.h"
-#include "symbolize.h"
-
-// NOTE: due to #define below, tcmalloc.cc will omit tc_XXX
-// definitions. So that debug implementations can be defined
-// instead. We're going to use do_malloc, do_free and other do_XXX
-// functions that are defined in tcmalloc.cc for actual memory
-// management
-#define TCMALLOC_USING_DEBUGALLOCATION
-#include "tcmalloc.cc"
-
-// __THROW is defined in glibc systems.  It means, counter-intuitively,
-// "This function will never throw an exception."  It's an optional
-// optimization tool, but we may need to use it to match glibc prototypes.
-#ifndef __THROW    // I guess we're not on a glibc system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-// ========================================================================= //
-
-DEFINE_bool(malloctrace,
-            EnvToBool("TCMALLOC_TRACE", false),
-            "Enables memory (de)allocation tracing to /tmp/google.alloc.");
-#ifdef HAVE_MMAP
-DEFINE_bool(malloc_page_fence,
-            EnvToBool("TCMALLOC_PAGE_FENCE", false),
-            "Enables putting of memory allocations at page boundaries "
-            "with a guard page following the allocation (to catch buffer "
-            "overruns right when they happen).");
-DEFINE_bool(malloc_page_fence_never_reclaim,
-            EnvToBool("TCMALLOC_PAGE_FENCE_NEVER_RECLAIM", false),
-            "Enables making the virtual address space inaccessible "
-            "upon a deallocation instead of returning it and reusing later.");
-#else
-DEFINE_bool(malloc_page_fence, false, "Not usable (requires mmap)");
-DEFINE_bool(malloc_page_fence_never_reclaim, false, "Not usable (required mmap)");
-#endif
-DEFINE_bool(malloc_reclaim_memory,
-            EnvToBool("TCMALLOC_RECLAIM_MEMORY", true),
-            "If set to false, we never return memory to malloc "
-            "when an object is deallocated. This ensures that all "
-            "heap object addresses are unique.");
-DEFINE_int32(max_free_queue_size,
-             EnvToInt("TCMALLOC_MAX_FREE_QUEUE_SIZE", 10*1024*1024),
-             "If greater than 0, keep freed blocks in a queue instead of "
-             "releasing them to the allocator immediately.  Release them when "
-             "the total size of all blocks in the queue would otherwise exceed "
-             "this limit.");
-
-DEFINE_bool(symbolize_stacktrace,
-            EnvToBool("TCMALLOC_SYMBOLIZE_STACKTRACE", true),
-            "Symbolize the stack trace when provided (on some error exits)");
-
-// If we are LD_PRELOAD-ed against a non-pthreads app, then
-// pthread_once won't be defined.  We declare it here, for that
-// case (with weak linkage) which will cause the non-definition to
-// resolve to NULL.  We can then check for NULL or not in Instance.
-extern "C" int pthread_once(pthread_once_t *, void (*)(void))
-    ATTRIBUTE_WEAK;
-
-// ========================================================================= //
-
-// A safe version of printf() that does not do any allocation and
-// uses very little stack space.
-static void TracePrintf(int fd, const char *fmt, ...)
-  __attribute__ ((__format__ (__printf__, 2, 3)));
-
-// Round "value" up to next "alignment" boundary.
-// Requires that "alignment" be a power of two.
-static intptr_t RoundUp(intptr_t value, intptr_t alignment) {
-  return (value + alignment - 1) & ~(alignment - 1);
-}
-
-// ========================================================================= //
-
-class MallocBlock;
-
-// A circular buffer to hold freed blocks of memory.  MallocBlock::Deallocate
-// (below) pushes blocks into this queue instead of returning them to the
-// underlying allocator immediately.  See MallocBlock::Deallocate for more
-// information.
-//
-// We can't use an STL class for this because we need to be careful not to
-// perform any heap de-allocations in any of the code in this class, since the
-// code in MallocBlock::Deallocate is not re-entrant.
-template <typename QueueEntry>
-class FreeQueue {
- public:
-  FreeQueue() : q_front_(0), q_back_(0) {}
-
-  bool Full() {
-    return (q_front_ + 1) % kFreeQueueSize == q_back_;
-  }
-
-  void Push(const QueueEntry& block) {
-    q_[q_front_] = block;
-    q_front_ = (q_front_ + 1) % kFreeQueueSize;
-  }
-
-  QueueEntry Pop() {
-    RAW_CHECK(q_back_ != q_front_, "Queue is empty");
-    const QueueEntry& ret = q_[q_back_];
-    q_back_ = (q_back_ + 1) % kFreeQueueSize;
-    return ret;
-  }
-
-  size_t size() const {
-    return (q_front_ - q_back_ + kFreeQueueSize) % kFreeQueueSize;
-  }
-
- private:
-  // Maximum number of blocks kept in the free queue before being freed.
-  static const int kFreeQueueSize = 1024;
-
-  QueueEntry q_[kFreeQueueSize];
-  int q_front_;
-  int q_back_;
-};
-
-struct MallocBlockQueueEntry {
-  MallocBlockQueueEntry() : block(NULL), size(0),
-                            num_deleter_pcs(0), deleter_threadid(0) {}
-  MallocBlockQueueEntry(MallocBlock* b, size_t s) : block(b), size(s) {
-    if (FLAGS_max_free_queue_size != 0 && b != NULL) {
-      // Adjust the number of frames to skip (4) if you change the
-      // location of this call.
-      num_deleter_pcs =
-        MallocHook::GetCallerStackTrace(
-          deleter_pcs,
-          sizeof(deleter_pcs) / sizeof(deleter_pcs[0]),
-          4);
-      deleter_threadid = pthread_self();
-    } else {
-      num_deleter_pcs = 0;
-      // Zero is an illegal pthread id by my reading of the pthread
-      // implementation:
-      deleter_threadid = 0;
-    }
-  }
-
-  MallocBlock* block;
-  size_t size;
-
-  // When deleted and put in the free queue, we (flag-controlled)
-  // record the stack so that if corruption is later found, we can
-  // print the deleter's stack.  (These three vars add 144 bytes of
-  // overhead under the LP64 data model.)
-  void* deleter_pcs[16];
-  int num_deleter_pcs;
-  pthread_t deleter_threadid;
-};
-
-class MallocBlock {
- public:  // allocation type constants
-
-  // Different allocation types we distinguish.
-  // Note: The lower 4 bits are not random: we index kAllocName array
-  // by these values masked with kAllocTypeMask;
-  // the rest are "random" magic bits to help catch memory corruption.
-  static const int kMallocType = 0xEFCDAB90;
-  static const int kNewType = 0xFEBADC81;
-  static const int kArrayNewType = 0xBCEADF72;
-
- private:  // constants
-
-  // A mask used on alloc types above to get to 0, 1, 2
-  static const int kAllocTypeMask = 0x3;
-  // An additional bit to set in AllocType constants
-  // to mark now deallocated regions.
-  static const int kDeallocatedTypeBit = 0x4;
-
-  // For better memory debugging, we initialize all storage to known
-  // values, and overwrite the storage when it's deallocated:
-  // Byte that fills uninitialized storage.
-  static const int kMagicUninitializedByte = 0xAB;
-  // Byte that fills deallocated storage.
-  // NOTE: tcmalloc.cc depends on the value of kMagicDeletedByte
-  //       to work around a bug in the pthread library.
-  static const int kMagicDeletedByte = 0xCD;
-  // A size_t (type of alloc_type_ below) in a deallocated storage
-  // filled with kMagicDeletedByte.
-  static const size_t kMagicDeletedSizeT =
-      0xCDCDCDCD | (((size_t)0xCDCDCDCD << 16) << 16);
-    // Initializer works for 32 and 64 bit size_ts;
-    // "<< 16 << 16" is to fool gcc from issuing a warning
-    // when size_ts are 32 bits.
-
-  // NOTE: on Linux, you can enable malloc debugging support in libc by
-  // setting the environment variable MALLOC_CHECK_ to 1 before you
-  // start the program (see man malloc).
-
-  // We use either do_malloc or mmap to make the actual allocation. In
-  // order to remember which one of the two was used for any block, we store an
-  // appropriate magic word next to the block.
-  static const size_t kMagicMalloc = 0xDEADBEEF;
-  static const size_t kMagicMMap = 0xABCDEFAB;
-
-  // This array will be filled with 0xCD, for use with memcmp.
-  static unsigned char kMagicDeletedBuffer[1024];
-  static pthread_once_t deleted_buffer_initialized_;
-  static bool deleted_buffer_initialized_no_pthreads_;
-
- private:  // data layout
-
-                    // The four fields size1_,offset_,magic1_,alloc_type_
-                    // should together occupy a multiple of 16 bytes. (At the
-                    // moment, sizeof(size_t) == 4 or 8 depending on piii vs
-                    // k8, and 4 of those sum to 16 or 32 bytes).
-                    // This, combined with do_malloc's alignment guarantees,
-                    // ensures that SSE types can be stored into the returned
-                    // block, at &size2_.
-  size_t size1_;
-  size_t offset_;   // normally 0 unless memaligned memory
-                    // see comments in memalign() and FromRawPointer().
-  size_t magic1_;
-  size_t alloc_type_;
-  // here comes the actual data (variable length)
-  // ...
-  // then come the size2_ and magic2_, or a full page of mprotect-ed memory
-  // if the malloc_page_fence feature is enabled.
-  size_t size2_;
-  size_t magic2_;
-
- private:  // static data and helpers
-
-  // Allocation map: stores the allocation type for each allocated object,
-  // or the type or'ed with kDeallocatedTypeBit
-  // for each formerly allocated object.
-  typedef AddressMap<int> AllocMap;
-  static AllocMap* alloc_map_;
-  // This protects alloc_map_ and consistent state of metadata
-  // for each still-allocated object in it.
-  // We use spin locks instead of pthread_mutex_t locks
-  // to prevent crashes via calls to pthread_mutex_(un)lock
-  // for the (de)allocations coming from pthreads initialization itself.
-  static SpinLock alloc_map_lock_;
-
-  // A queue of freed blocks.  Instead of releasing blocks to the allocator
-  // immediately, we put them in a queue, freeing them only when necessary
-  // to keep the total size of all the freed blocks below the limit set by
-  // FLAGS_max_free_queue_size.
-  static FreeQueue<MallocBlockQueueEntry>* free_queue_;
-
-  static size_t free_queue_size_;  // total size of blocks in free_queue_
-  // protects free_queue_ and free_queue_size_
-  static SpinLock free_queue_lock_;
-
-  // Names of allocation types (kMallocType, kNewType, kArrayNewType)
-  static const char* const kAllocName[];
-  // Names of corresponding deallocation types
-  static const char* const kDeallocName[];
-
-  static const char* AllocName(int type) {
-    return kAllocName[type & kAllocTypeMask];
-  }
-
-  static const char* DeallocName(int type) {
-    return kDeallocName[type & kAllocTypeMask];
-  }
-
- private:  // helper accessors
-
-  bool IsMMapped() const { return kMagicMMap == magic1_; }
-
-  bool IsValidMagicValue(size_t value) const {
-    return kMagicMMap == value  ||  kMagicMalloc == value;
-  }
-
-  static size_t real_malloced_size(size_t size) {
-    return size + sizeof(MallocBlock);
-  }
-
-  /*
-   * Here we assume size of page is kMinAlign aligned,
-   * so if size is MALLOC_ALIGNMENT aligned too, then we could
-   * guarantee return address is also kMinAlign aligned, because
-   * mmap return address at nearby page boundary on Linux.
-   */
-  static size_t real_mmapped_size(size_t size) {
-    size_t tmp = size + MallocBlock::data_offset();
-    tmp = RoundUp(tmp, kMinAlign);
-    return tmp;
-  }
-
-  size_t real_size() {
-    return IsMMapped() ? real_mmapped_size(size1_) : real_malloced_size(size1_);
-  }
-
-  // NOTE: if the block is mmapped (that is, we're using the
-  // malloc_page_fence option) then there's no size2 or magic2
-  // (instead, the guard page begins where size2 would be).
-
-  size_t* size2_addr() { return (size_t*)((char*)&size2_ + size1_); }
-  const size_t* size2_addr() const {
-    return (const size_t*)((char*)&size2_ + size1_);
-  }
-
-  size_t* magic2_addr() { return (size_t*)(size2_addr() + 1); }
-  const size_t* magic2_addr() const { return (const size_t*)(size2_addr() + 1); }
-
- private:  // other helpers
-
-  void Initialize(size_t size, int type) {
-    RAW_CHECK(IsValidMagicValue(magic1_), "");
-    // record us as allocated in the map
-    alloc_map_lock_.Lock();
-    if (!alloc_map_) {
-      void* p = do_malloc(sizeof(AllocMap));
-      alloc_map_ = new(p) AllocMap(do_malloc, do_free);
-    }
-    alloc_map_->Insert(data_addr(), type);
-    // initialize us
-    size1_ = size;
-    offset_ = 0;
-    alloc_type_ = type;
-    if (!IsMMapped()) {
-      bit_store(magic2_addr(), &magic1_);
-      bit_store(size2_addr(), &size);
-    }
-    alloc_map_lock_.Unlock();
-    memset(data_addr(), kMagicUninitializedByte, size);
-    if (!IsMMapped()) {
-      RAW_CHECK(memcmp(&size1_, size2_addr(), sizeof(size1_)) == 0, "should hold");
-      RAW_CHECK(memcmp(&magic1_, magic2_addr(), sizeof(magic1_)) == 0, "should hold");
-    }
-  }
-
-  size_t CheckAndClear(int type, size_t given_size) {
-    alloc_map_lock_.Lock();
-    CheckLocked(type);
-    if (!IsMMapped()) {
-      RAW_CHECK(memcmp(&size1_, size2_addr(), sizeof(size1_)) == 0, "should hold");
-    }
-    // record us as deallocated in the map
-    alloc_map_->Insert(data_addr(), type | kDeallocatedTypeBit);
-    alloc_map_lock_.Unlock();
-    // clear us
-    const size_t size = real_size();
-    RAW_CHECK(!given_size || given_size == size1_,
-              "right size must be passed to sized delete");
-    memset(this, kMagicDeletedByte, size);
-    return size;
-  }
-
-  void CheckLocked(int type) const {
-    int map_type = 0;
-    const int* found_type =
-      alloc_map_ != NULL ? alloc_map_->Find(data_addr()) : NULL;
-    if (found_type == NULL) {
-      RAW_LOG(FATAL, "memory allocation bug: object at %p "
-                     "has never been allocated", data_addr());
-    } else {
-      map_type = *found_type;
-    }
-    if ((map_type & kDeallocatedTypeBit) != 0) {
-      RAW_LOG(FATAL, "memory allocation bug: object at %p "
-                     "has been already deallocated (it was allocated with %s)",
-                     data_addr(), AllocName(map_type & ~kDeallocatedTypeBit));
-    }
-    if (alloc_type_ == kMagicDeletedSizeT) {
-      RAW_LOG(FATAL, "memory stomping bug: a word before object at %p "
-                     "has been corrupted; or else the object has been already "
-                     "deallocated and our memory map has been corrupted",
-                     data_addr());
-    }
-    if (!IsValidMagicValue(magic1_)) {
-      RAW_LOG(FATAL, "memory stomping bug: a word before object at %p "
-                     "has been corrupted; "
-                     "or else our memory map has been corrupted and this is a "
-                     "deallocation for not (currently) heap-allocated object",
-                     data_addr());
-    }
-    if (!IsMMapped()) {
-      if (memcmp(&size1_, size2_addr(), sizeof(size1_))) {
-        RAW_LOG(FATAL, "memory stomping bug: a word after object at %p "
-                       "has been corrupted", data_addr());
-      }
-      size_t addr;
-      bit_store(&addr, magic2_addr());
-      if (!IsValidMagicValue(addr)) {
-        RAW_LOG(FATAL, "memory stomping bug: a word after object at %p "
-                "has been corrupted", data_addr());
-      }
-    }
-    if (alloc_type_ != type) {
-      if ((alloc_type_ != MallocBlock::kMallocType) &&
-          (alloc_type_ != MallocBlock::kNewType)    &&
-          (alloc_type_ != MallocBlock::kArrayNewType)) {
-        RAW_LOG(FATAL, "memory stomping bug: a word before object at %p "
-                       "has been corrupted", data_addr());
-      }
-      RAW_LOG(FATAL, "memory allocation/deallocation mismatch at %p: "
-                     "allocated with %s being deallocated with %s",
-                     data_addr(), AllocName(alloc_type_), DeallocName(type));
-    }
-    if (alloc_type_ != map_type) {
-      RAW_LOG(FATAL, "memory stomping bug: our memory map has been corrupted : "
-                     "allocation at %p made with %s "
-                     "is recorded in the map to be made with %s",
-                     data_addr(), AllocName(alloc_type_),  AllocName(map_type));
-    }
-  }
-
- public:  // public accessors
-
-  void* data_addr() { return (void*)&size2_; }
-  const void* data_addr() const { return (const void*)&size2_; }
-
-  static size_t data_offset() { return OFFSETOF_MEMBER(MallocBlock, size2_); }
-
-  size_t data_size() const { return size1_; }
-
-  void set_offset(int offset) { this->offset_ = offset; }
-
- public:  // our main interface
-
-  static MallocBlock* Allocate(size_t size, int type) {
-    // Prevent an integer overflow / crash with large allocation sizes.
-    // TODO - Note that for a e.g. 64-bit size_t, max_size_t may not actually
-    // be the maximum value, depending on how the compiler treats ~0. The worst
-    // practical effect is that allocations are limited to 4Gb or so, even if
-    // the address space could take more.
-    static size_t max_size_t = ~0;
-    if (size > max_size_t - sizeof(MallocBlock)) {
-      RAW_LOG(ERROR, "Massive size passed to malloc: %" PRIuS "", size);
-      return NULL;
-    }
-    MallocBlock* b = NULL;
-    const bool use_malloc_page_fence = FLAGS_malloc_page_fence;
-#ifdef HAVE_MMAP
-    if (use_malloc_page_fence) {
-      // Put the block towards the end of the page and make the next page
-      // inaccessible. This will catch buffer overrun right when it happens.
-      size_t sz = real_mmapped_size(size);
-      int pagesize = getpagesize();
-      int num_pages = (sz + pagesize - 1) / pagesize + 1;
-      char* p = (char*) mmap(NULL, num_pages * pagesize, PROT_READ|PROT_WRITE,
-                             MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-      if (p == MAP_FAILED) {
-        // If the allocation fails, abort rather than returning NULL to
-        // malloc. This is because in most cases, the program will run out
-        // of memory in this mode due to tremendous amount of wastage. There
-        // is no point in propagating the error elsewhere.
-        RAW_LOG(FATAL, "Out of memory: possibly due to page fence overhead: %s",
-                strerror(errno));
-      }
-      // Mark the page after the block inaccessible
-      if (mprotect(p + (num_pages - 1) * pagesize, pagesize, PROT_NONE)) {
-        RAW_LOG(FATAL, "Guard page setup failed: %s", strerror(errno));
-      }
-      b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz);
-    } else {
-      b = (MallocBlock*) do_malloc(real_malloced_size(size));
-    }
-#else
-    b = (MallocBlock*) do_malloc(real_malloced_size(size));
-#endif
-
-    // It would be nice to output a diagnostic on allocation failure
-    // here, but logging (other than FATAL) requires allocating
-    // memory, which could trigger a nasty recursion. Instead, preserve
-    // malloc semantics and return NULL on failure.
-    if (b != NULL) {
-      b->magic1_ = use_malloc_page_fence ? kMagicMMap : kMagicMalloc;
-      b->Initialize(size, type);
-    }
-    return b;
-  }
-
-  void Deallocate(int type, size_t given_size) {
-    if (IsMMapped()) {  // have to do this before CheckAndClear
-#ifdef HAVE_MMAP
-      int size = CheckAndClear(type, given_size);
-      int pagesize = getpagesize();
-      int num_pages = (size + pagesize - 1) / pagesize + 1;
-      char* p = (char*) this;
-      if (FLAGS_malloc_page_fence_never_reclaim  ||
-          !FLAGS_malloc_reclaim_memory) {
-        mprotect(p - (num_pages - 1) * pagesize + size,
-                 num_pages * pagesize, PROT_NONE);
-      } else {
-        munmap(p - (num_pages - 1) * pagesize + size, num_pages * pagesize);
-      }
-#endif
-    } else {
-      const size_t size = CheckAndClear(type, given_size);
-      if (FLAGS_malloc_reclaim_memory) {
-        // Instead of freeing the block immediately, push it onto a queue of
-        // recently freed blocks.  Free only enough blocks to keep from
-        // exceeding the capacity of the queue or causing the total amount of
-        // un-released memory in the queue from exceeding
-        // FLAGS_max_free_queue_size.
-        ProcessFreeQueue(this, size, FLAGS_max_free_queue_size);
-      }
-    }
-  }
-
-  static size_t FreeQueueSize() {
-    SpinLockHolder l(&free_queue_lock_);
-    return free_queue_size_;
-  }
-
-  static void ProcessFreeQueue(MallocBlock* b, size_t size,
-                               int max_free_queue_size) {
-    // MallocBlockQueueEntry are about 144 in size, so we can only
-    // use a small array of them on the stack.
-    MallocBlockQueueEntry entries[4];
-    int num_entries = 0;
-    MallocBlockQueueEntry new_entry(b, size);
-    free_queue_lock_.Lock();
-    if (free_queue_ == NULL)
-      free_queue_ = new FreeQueue<MallocBlockQueueEntry>;
-    RAW_CHECK(!free_queue_->Full(), "Free queue mustn't be full!");
-
-    if (b != NULL) {
-      free_queue_size_ += size + sizeof(MallocBlockQueueEntry);
-      free_queue_->Push(new_entry);
-    }
-
-    // Free blocks until the total size of unfreed blocks no longer exceeds
-    // max_free_queue_size, and the free queue has at least one free
-    // space in it.
-    while (free_queue_size_ > max_free_queue_size || free_queue_->Full()) {
-      RAW_CHECK(num_entries < arraysize(entries), "entries array overflow");
-      entries[num_entries] = free_queue_->Pop();
-      free_queue_size_ -=
-          entries[num_entries].size + sizeof(MallocBlockQueueEntry);
-      num_entries++;
-      if (num_entries == arraysize(entries)) {
-        // The queue will not be full at this point, so it is ok to
-        // release the lock.  The queue may still contain more than
-        // max_free_queue_size, but this is not a strict invariant.
-        free_queue_lock_.Unlock();
-        for (int i = 0; i < num_entries; i++) {
-          CheckForDanglingWrites(entries[i]);
-          do_free(entries[i].block);
-        }
-        num_entries = 0;
-        free_queue_lock_.Lock();
-      }
-    }
-    free_queue_lock_.Unlock();
-    for (int i = 0; i < num_entries; i++) {
-      CheckForDanglingWrites(entries[i]);
-      do_free(entries[i].block);
-    }
-  }
-
-  static void InitDeletedBuffer() {
-    memset(kMagicDeletedBuffer, kMagicDeletedByte, sizeof(kMagicDeletedBuffer));
-    deleted_buffer_initialized_no_pthreads_ = true;
-  }
-
-  static void CheckForDanglingWrites(const MallocBlockQueueEntry& queue_entry) {
-    // Initialize the buffer if necessary.
-    if (pthread_once)
-      pthread_once(&deleted_buffer_initialized_, &InitDeletedBuffer);
-    if (!deleted_buffer_initialized_no_pthreads_) {
-      // This will be the case on systems that don't link in pthreads,
-      // including on FreeBSD where pthread_once has a non-zero address
-      // (but doesn't do anything) even when pthreads isn't linked in.
-      InitDeletedBuffer();
-    }
-
-    const unsigned char* p =
-        reinterpret_cast<unsigned char*>(queue_entry.block);
-
-    static const size_t size_of_buffer = sizeof(kMagicDeletedBuffer);
-    const size_t size = queue_entry.size;
-    const size_t buffers = size / size_of_buffer;
-    const size_t remainder = size % size_of_buffer;
-    size_t buffer_idx;
-    for (buffer_idx = 0; buffer_idx < buffers; ++buffer_idx) {
-      CheckForCorruptedBuffer(queue_entry, buffer_idx, p, size_of_buffer);
-      p += size_of_buffer;
-    }
-    CheckForCorruptedBuffer(queue_entry, buffer_idx, p, remainder);
-  }
-
-  static void CheckForCorruptedBuffer(const MallocBlockQueueEntry& queue_entry,
-                                      size_t buffer_idx,
-                                      const unsigned char* buffer,
-                                      size_t size_of_buffer) {
-    if (memcmp(buffer, kMagicDeletedBuffer, size_of_buffer) == 0) {
-      return;
-    }
-
-    RAW_LOG(ERROR,
-            "Found a corrupted memory buffer in MallocBlock (may be offset "
-            "from user ptr): buffer index: %zd, buffer ptr: %p, size of "
-            "buffer: %zd", buffer_idx, buffer, size_of_buffer);
-
-    // The magic deleted buffer should only be 1024 bytes, but in case
-    // this changes, let's put an upper limit on the number of debug
-    // lines we'll output:
-    if (size_of_buffer <= 1024) {
-      for (int i = 0; i < size_of_buffer; ++i) {
-        if (buffer[i] != kMagicDeletedByte) {
-          RAW_LOG(ERROR, "Buffer byte %d is 0x%02x (should be 0x%02x).",
-                  i, buffer[i], kMagicDeletedByte);
-        }
-      }
-    } else {
-      RAW_LOG(ERROR, "Buffer too large to print corruption.");
-    }
-
-    const MallocBlock* b = queue_entry.block;
-    const size_t size = queue_entry.size;
-    if (queue_entry.num_deleter_pcs > 0) {
-      TracePrintf(STDERR_FILENO, "Deleted by thread %p\n",
-                  reinterpret_cast<void*>(
-                      PRINTABLE_PTHREAD(queue_entry.deleter_threadid)));
-
-      // We don't want to allocate or deallocate memory here, so we use
-      // placement-new.  It's ok that we don't destroy this, since we're
-      // just going to error-exit below anyway.  Union is for alignment.
-      union { void* alignment; char buf[sizeof(SymbolTable)]; } tablebuf;
-      SymbolTable* symbolization_table = new (tablebuf.buf) SymbolTable;
-      for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {
-        // Symbolizes the previous address of pc because pc may be in the
-        // next function.  This may happen when the function ends with
-        // a call to a function annotated noreturn (e.g. CHECK).
-        char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);
-        symbolization_table->Add(pc - 1);
-      }
-      if (FLAGS_symbolize_stacktrace)
-        symbolization_table->Symbolize();
-      for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {
-        char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);
-        TracePrintf(STDERR_FILENO, "    @ %p %s\n",
-                    pc, symbolization_table->GetSymbol(pc - 1));
-      }
-    } else {
-      RAW_LOG(ERROR,
-              "Skipping the printing of the deleter's stack!  Its stack was "
-              "not found; either the corruption occurred too early in "
-              "execution to obtain a stack trace or --max_free_queue_size was "
-              "set to 0.");
-    }
-
-    RAW_LOG(FATAL,
-            "Memory was written to after being freed.  MallocBlock: %p, user "
-            "ptr: %p, size: %zd.  If you can't find the source of the error, "
-            "try using ASan (http://code.google.com/p/address-sanitizer/), "
-            "Valgrind, or Purify, or study the "
-            "output of the deleter's stack printed above.",
-            b, b->data_addr(), size);
-  }
-
-  static MallocBlock* FromRawPointer(void* p) {
-    const size_t data_offset = MallocBlock::data_offset();
-    // Find the header just before client's memory.
-    MallocBlock *mb = reinterpret_cast<MallocBlock *>(
-                reinterpret_cast<char *>(p) - data_offset);
-    // If mb->alloc_type_ is kMagicDeletedSizeT, we're not an ok pointer.
-    if (mb->alloc_type_ == kMagicDeletedSizeT) {
-      RAW_LOG(FATAL, "memory allocation bug: object at %p has been already"
-                     " deallocated; or else a word before the object has been"
-                     " corrupted (memory stomping bug)", p);
-    }
-    // If mb->offset_ is zero (common case), mb is the real header.
-    // If mb->offset_ is non-zero, this block was allocated by debug
-    // memallign implementation, and mb->offset_ is the distance
-    // backwards to the real header from mb, which is a fake header.
-    if (mb->offset_ == 0) {
-      return mb;
-    }
-
-    MallocBlock *main_block = reinterpret_cast<MallocBlock *>(
-      reinterpret_cast<char *>(mb) - mb->offset_);
-
-    if (main_block->offset_ != 0) {
-      RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted."
-              " Need 0 but got %x",
-              (unsigned)(main_block->offset_));
-    }
-    if (main_block >= p) {
-      RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted."
-              " Detected main_block address overflow: %x",
-              (unsigned)(mb->offset_));
-    }
-    if (main_block->size2_addr() < p) {
-      RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted."
-              " It points below it's own main_block: %x",
-              (unsigned)(mb->offset_));
-    }
-
-    return main_block;
-  }
-
-  static const MallocBlock* FromRawPointer(const void* p) {
-    // const-safe version: we just cast about
-    return FromRawPointer(const_cast<void*>(p));
-  }
-
-  void Check(int type) const {
-    alloc_map_lock_.Lock();
-    CheckLocked(type);
-    alloc_map_lock_.Unlock();
-  }
-
-  static bool CheckEverything() {
-    alloc_map_lock_.Lock();
-    if (alloc_map_ != NULL)  alloc_map_->Iterate(CheckCallback, 0);
-    alloc_map_lock_.Unlock();
-    return true;  // if we get here, we're okay
-  }
-
-  static bool MemoryStats(int* blocks, size_t* total,
-                          int histogram[kMallocHistogramSize]) {
-    memset(histogram, 0, kMallocHistogramSize * sizeof(int));
-    alloc_map_lock_.Lock();
-    stats_blocks_ = 0;
-    stats_total_ = 0;
-    stats_histogram_ = histogram;
-    if (alloc_map_ != NULL) alloc_map_->Iterate(StatsCallback, 0);
-    *blocks = stats_blocks_;
-    *total = stats_total_;
-    alloc_map_lock_.Unlock();
-    return true;
-  }
-
- private:  // helpers for CheckEverything and MemoryStats
-
-  static void CheckCallback(const void* ptr, int* type, int dummy) {
-    if ((*type & kDeallocatedTypeBit) == 0) {
-      FromRawPointer(ptr)->CheckLocked(*type);
-    }
-  }
-
-  // Accumulation variables for StatsCallback protected by alloc_map_lock_
-  static int stats_blocks_;
-  static size_t stats_total_;
-  static int* stats_histogram_;
-
-  static void StatsCallback(const void* ptr, int* type, int dummy) {
-    if ((*type & kDeallocatedTypeBit) == 0) {
-      const MallocBlock* b = FromRawPointer(ptr);
-      b->CheckLocked(*type);
-      ++stats_blocks_;
-      size_t mysize = b->size1_;
-      int entry = 0;
-      stats_total_ += mysize;
-      while (mysize) {
-        ++entry;
-        mysize >>= 1;
-      }
-      RAW_CHECK(entry < kMallocHistogramSize,
-                "kMallocHistogramSize should be at least as large as log2 "
-                "of the maximum process memory size");
-      stats_histogram_[entry] += 1;
-    }
-  }
-};
-
-void DanglingWriteChecker() {
-  // Clear out the remaining free queue to check for dangling writes.
-  MallocBlock::ProcessFreeQueue(NULL, 0, 0);
-}
-
-// ========================================================================= //
-
-const size_t MallocBlock::kMagicMalloc;
-const size_t MallocBlock::kMagicMMap;
-
-MallocBlock::AllocMap* MallocBlock::alloc_map_ = NULL;
-SpinLock MallocBlock::alloc_map_lock_(SpinLock::LINKER_INITIALIZED);
-
-FreeQueue<MallocBlockQueueEntry>* MallocBlock::free_queue_ = NULL;
-size_t MallocBlock::free_queue_size_ = 0;
-SpinLock MallocBlock::free_queue_lock_(SpinLock::LINKER_INITIALIZED);
-
-unsigned char MallocBlock::kMagicDeletedBuffer[1024];
-pthread_once_t MallocBlock::deleted_buffer_initialized_ = PTHREAD_ONCE_INIT;
-bool MallocBlock::deleted_buffer_initialized_no_pthreads_ = false;
-
-const char* const MallocBlock::kAllocName[] = {
-  "malloc",
-  "new",
-  "new []",
-  NULL,
-};
-
-const char* const MallocBlock::kDeallocName[] = {
-  "free",
-  "delete",
-  "delete []",
-  NULL,
-};
-
-int MallocBlock::stats_blocks_;
-size_t MallocBlock::stats_total_;
-int* MallocBlock::stats_histogram_;
-
-// ========================================================================= //
-
-// The following cut-down version of printf() avoids
-// using stdio or ostreams.
-// This is to guarantee no recursive calls into
-// the allocator and to bound the stack space consumed.  (The pthread
-// manager thread in linuxthreads has a very small stack,
-// so fprintf can't be called.)
-static void TracePrintf(int fd, const char *fmt, ...) {
-  char buf[64];
-  int i = 0;
-  va_list ap;
-  va_start(ap, fmt);
-  const char *p = fmt;
-  char numbuf[25];
-  if (fd < 0) {
-    va_end(ap);
-    return;
-  }
-  numbuf[sizeof(numbuf)-1] = 0;
-  while (*p != '\0') {              // until end of format string
-    char *s = &numbuf[sizeof(numbuf)-1];
-    if (p[0] == '%' && p[1] != 0) {  // handle % formats
-      int64 l = 0;
-      unsigned long base = 0;
-      if (*++p == 's') {                            // %s
-        s = va_arg(ap, char *);
-      } else if (*p == 'l' && p[1] == 'd') {        // %ld
-        l = va_arg(ap, long);
-        base = 10;
-        p++;
-      } else if (*p == 'l' && p[1] == 'u') {        // %lu
-        l = va_arg(ap, unsigned long);
-        base = 10;
-        p++;
-      } else if (*p == 'z' && p[1] == 'u') {        // %zu
-        l = va_arg(ap, size_t);
-        base = 10;
-        p++;
-      } else if (*p == 'u') {                       // %u
-        l = va_arg(ap, unsigned int);
-        base = 10;
-      } else if (*p == 'd') {                       // %d
-        l = va_arg(ap, int);
-        base = 10;
-      } else if (*p == 'p') {                       // %p
-        l = va_arg(ap, intptr_t);
-        base = 16;
-      } else {
-        write(STDERR_FILENO, "Unimplemented TracePrintf format\n", 33);
-        write(STDERR_FILENO, p, 2);
-        write(STDERR_FILENO, "\n", 1);
-        abort();
-      }
-      p++;
-      if (base != 0) {
-        bool minus = (l < 0 && base == 10);
-        uint64 ul = minus? -l : l;
-        do {
-          *--s = "0123456789abcdef"[ul % base];
-          ul /= base;
-        } while (ul != 0);
-        if (base == 16) {
-          *--s = 'x';
-          *--s = '0';
-        } else if (minus) {
-          *--s = '-';
-        }
-      }
-    } else {                        // handle normal characters
-      *--s = *p++;
-    }
-    while (*s != 0) {
-      if (i == sizeof(buf)) {
-        write(fd, buf, i);
-        i = 0;
-      }
-      buf[i++] = *s++;
-    }
-  }
-  if (i != 0) {
-    write(fd, buf, i);
-  }
-  va_end(ap);
-}
-
-// Return the file descriptor we're writing a log to
-static int TraceFd() {
-  static int trace_fd = -1;
-  if (trace_fd == -1) {            // Open the trace file on the first call
-    const char *val = getenv("TCMALLOC_TRACE_FILE");
-    bool fallback_to_stderr = false;
-    if (!val) {
-      val = "/tmp/google.alloc";
-      fallback_to_stderr = true;
-    }
-    trace_fd = open(val, O_CREAT|O_TRUNC|O_WRONLY, 0666);
-    if (trace_fd == -1) {
-      if (fallback_to_stderr) {
-        trace_fd = 2;
-        TracePrintf(trace_fd, "Can't open %s.  Logging to stderr.\n", val);
-      } else {
-        TracePrintf(2, "Can't open %s.  Logging disabled.\n", val);
-      }
-    }
-    // Add a header to the log.
-    TracePrintf(trace_fd, "Trace started: %lu\n",
-                static_cast<unsigned long>(time(NULL)));
-    TracePrintf(trace_fd,
-                "func\tsize\tptr\tthread_id\tstack pcs for tools/symbolize\n");
-  }
-  return trace_fd;
-}
-
-// Print the hex stack dump on a single line.   PCs are separated by tabs.
-static void TraceStack(void) {
-  void *pcs[16];
-  int n = GetStackTrace(pcs, sizeof(pcs)/sizeof(pcs[0]), 0);
-  for (int i = 0; i != n; i++) {
-    TracePrintf(TraceFd(), "\t%p", pcs[i]);
-  }
-}
-
-// This protects MALLOC_TRACE, to make sure its info is atomically written.
-static SpinLock malloc_trace_lock(SpinLock::LINKER_INITIALIZED);
-
-#define MALLOC_TRACE(name, size, addr)                                  \
-  do {                                                                  \
-    if (FLAGS_malloctrace) {                                            \
-      SpinLockHolder l(&malloc_trace_lock);                             \
-      TracePrintf(TraceFd(), "%s\t%" PRIuS "\t%p\t%" GPRIuPTHREAD,      \
-                  name, size, addr, PRINTABLE_PTHREAD(pthread_self())); \
-      TraceStack();                                                     \
-      TracePrintf(TraceFd(), "\n");                                     \
-    }                                                                   \
-  } while (0)
-
-// ========================================================================= //
-
-// Write the characters buf[0, ..., size-1] to
-// the malloc trace buffer.
-// This function is intended for debugging,
-// and is not declared in any header file.
-// You must insert a declaration of it by hand when you need
-// to use it.
-void __malloctrace_write(const char *buf, size_t size) {
-  if (FLAGS_malloctrace) {
-    write(TraceFd(), buf, size);
-  }
-}
-
-// ========================================================================= //
-
-// General debug allocation/deallocation
-
-static inline void* DebugAllocate(size_t size, int type) {
-  MallocBlock* ptr = MallocBlock::Allocate(size, type);
-  if (ptr == NULL)  return NULL;
-  MALLOC_TRACE("malloc", size, ptr->data_addr());
-  return ptr->data_addr();
-}
-
-static inline void DebugDeallocate(void* ptr, int type, size_t given_size) {
-  MALLOC_TRACE("free",
-               (ptr != 0 ? MallocBlock::FromRawPointer(ptr)->data_size() : 0),
-               ptr);
-  if (ptr)  MallocBlock::FromRawPointer(ptr)->Deallocate(type, given_size);
-}
-
-// ========================================================================= //
-
-// The following functions may be called via MallocExtension::instance()
-// for memory verification and statistics.
-class DebugMallocImplementation : public TCMallocImplementation {
- public:
-  virtual bool GetNumericProperty(const char* name, size_t* value) {
-    bool result = TCMallocImplementation::GetNumericProperty(name, value);
-    if (result && (strcmp(name, "generic.current_allocated_bytes") == 0)) {
-      // Subtract bytes kept in the free queue
-      size_t qsize = MallocBlock::FreeQueueSize();
-      if (*value >= qsize) {
-        *value -= qsize;
-      }
-    }
-    return result;
-  }
-
-  virtual bool VerifyNewMemory(const void* p) {
-    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kNewType);
-    return true;
-  }
-
-  virtual bool VerifyArrayNewMemory(const void* p) {
-    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kArrayNewType);
-    return true;
-  }
-
-  virtual bool VerifyMallocMemory(const void* p) {
-    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kMallocType);
-    return true;
-  }
-
-  virtual bool VerifyAllMemory() {
-    return MallocBlock::CheckEverything();
-  }
-
-  virtual bool MallocMemoryStats(int* blocks, size_t* total,
-                                 int histogram[kMallocHistogramSize]) {
-    return MallocBlock::MemoryStats(blocks, total, histogram);
-  }
-
-  virtual size_t GetEstimatedAllocatedSize(size_t size) {
-    return size;
-  }
-
-  virtual size_t GetAllocatedSize(const void* p) {
-    if (p) {
-      RAW_CHECK(GetOwnership(p) != MallocExtension::kNotOwned,
-                "ptr not allocated by tcmalloc");
-      return MallocBlock::FromRawPointer(p)->data_size();
-    }
-    return 0;
-  }
-
-  virtual MallocExtension::Ownership GetOwnership(const void* p) {
-    if (!p) {
-      // nobody owns NULL
-      return MallocExtension::kNotOwned;
-    }
-
-    // FIXME: note that correct GetOwnership should not touch memory
-    // that is not owned by tcmalloc. Main implementation is using
-    // pagemap to discover if page in question is owned by us or
-    // not. But pagemap only has marks for first and last page of
-    // spans.  Note that if p was returned out of our memalign with
-    // big alignment, then it will point outside of marked pages. Also
-    // note that FromRawPointer call below requires touching memory
-    // before pointer in order to handle memalign-ed chunks
-    // (offset_). This leaves us with two options:
-    //
-    // * do FromRawPointer first and have possibility of crashing if
-    //   we're given not owned pointer
-    //
-    // * return incorrect ownership for those large memalign chunks
-    //
-    // I've decided to choose later, which appears to happen rarer and
-    // therefore is arguably a lesser evil
-
-    MallocExtension::Ownership rv = TCMallocImplementation::GetOwnership(p);
-    if (rv != MallocExtension::kOwned) {
-      return rv;
-    }
-
-    const MallocBlock* mb = MallocBlock::FromRawPointer(p);
-    return TCMallocImplementation::GetOwnership(mb);
-  }
-
-  virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {
-    static const char* kDebugFreeQueue = "debug.free_queue";
-
-    TCMallocImplementation::GetFreeListSizes(v);
-
-    MallocExtension::FreeListInfo i;
-    i.type = kDebugFreeQueue;
-    i.min_object_size = 0;
-    i.max_object_size = numeric_limits<size_t>::max();
-    i.total_bytes_free = MallocBlock::FreeQueueSize();
-    v->push_back(i);
-  }
-
- };
-
-static union {
-  char chars[sizeof(DebugMallocImplementation)];
-  void *ptr;
-} debug_malloc_implementation_space;
-
-REGISTER_MODULE_INITIALIZER(debugallocation, {
-#if (__cplusplus >= 201103L)
-    COMPILE_ASSERT(alignof(debug_malloc_implementation_space) >= alignof(DebugMallocImplementation),
-                   debug_malloc_implementation_space_is_not_properly_aligned);
-#endif
-  // Either we or valgrind will control memory management.  We
-  // register our extension if we're the winner. Otherwise let
-  // Valgrind use its own malloc (so don't register our extension).
-  if (!RunningOnValgrind()) {
-    DebugMallocImplementation *impl = new (debug_malloc_implementation_space.chars) DebugMallocImplementation();
-    MallocExtension::Register(impl);
-  }
-});
-
-REGISTER_MODULE_DESTRUCTOR(debugallocation, {
-  if (!RunningOnValgrind()) {
-    // When the program exits, check all blocks still in the free
-    // queue for corruption.
-    DanglingWriteChecker();
-  }
-});
-
-// ========================================================================= //
-
-struct debug_alloc_retry_data {
-  size_t size;
-  int new_type;
-};
-
-static void *retry_debug_allocate(void *arg) {
-  debug_alloc_retry_data *data = static_cast<debug_alloc_retry_data *>(arg);
-  return DebugAllocate(data->size, data->new_type);
-}
-
-// This is mostly the same a cpp_alloc in tcmalloc.cc.
-// TODO(csilvers): change Allocate() above to call cpp_alloc, so we
-// don't have to reproduce the logic here.  To make tc_new_mode work
-// properly, I think we'll need to separate out the logic of throwing
-// from the logic of calling the new-handler.
-inline void* debug_cpp_alloc(size_t size, int new_type, bool nothrow) {
-  void* p = DebugAllocate(size, new_type);
-  if (p != NULL) {
-    return p;
-  }
-  struct debug_alloc_retry_data data;
-  data.size = size;
-  data.new_type = new_type;
-  return handle_oom(retry_debug_allocate, &data,
-                    true, nothrow);
-}
-
-inline void* do_debug_malloc_or_debug_cpp_alloc(size_t size) {
-  void* p = DebugAllocate(size, MallocBlock::kMallocType);
-  if (p != NULL) {
-    return p;
-  }
-  struct debug_alloc_retry_data data;
-  data.size = size;
-  data.new_type = MallocBlock::kMallocType;
-  return handle_oom(retry_debug_allocate, &data,
-                    false, true);
-}
-
-// Exported routines
-
-// frame forcer and force_frame exist only to prevent tail calls to
-// DebugDeallocate to be actually implemented as tail calls. This is
-// important because stack trace capturing in MallocBlockQueueEntry
-// relies on google_malloc section being on stack and tc_XXX functions
-// are in that section. So they must not jump to DebugDeallocate but
-// have to do call. frame_forcer call at the end of such functions
-// prevents tail calls to DebugDeallocate.
-static int frame_forcer;
-static void force_frame() {
-  int dummy = *(int volatile *)&frame_forcer;
-  (void)dummy;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW {
-  if (ThreadCache::IsUseEmergencyMalloc()) {
-    return tcmalloc::EmergencyMalloc(size);
-  }
-  void* ptr = do_debug_malloc_or_debug_cpp_alloc(size);
-  MallocHook::InvokeNewHook(ptr, size);
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW {
-  if (tcmalloc::IsEmergencyPtr(ptr)) {
-    return tcmalloc::EmergencyFree(ptr);
-  }
-  MallocHook::InvokeDeleteHook(ptr);
-  DebugDeallocate(ptr, MallocBlock::kMallocType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(ptr);
-  DebugDeallocate(ptr, MallocBlock::kMallocType, size);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_calloc(size_t count, size_t size) PERFTOOLS_NOTHROW {
-  if (ThreadCache::IsUseEmergencyMalloc()) {
-    return tcmalloc::EmergencyCalloc(count, size);
-  }
-  // Overflow check
-  const size_t total_size = count * size;
-  if (size != 0 && total_size / size != count) return NULL;
-
-  void* block = do_debug_malloc_or_debug_cpp_alloc(total_size);
-  MallocHook::InvokeNewHook(block, total_size);
-  if (block)  memset(block, 0, total_size);
-  return block;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW {
-  if (tcmalloc::IsEmergencyPtr(ptr)) {
-    return tcmalloc::EmergencyFree(ptr);
-  }
-  MallocHook::InvokeDeleteHook(ptr);
-  DebugDeallocate(ptr, MallocBlock::kMallocType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW {
-  if (tcmalloc::IsEmergencyPtr(ptr)) {
-    return tcmalloc::EmergencyRealloc(ptr, size);
-  }
-  if (ptr == NULL) {
-    ptr = do_debug_malloc_or_debug_cpp_alloc(size);
-    MallocHook::InvokeNewHook(ptr, size);
-    return ptr;
-  }
-  if (size == 0) {
-    MallocHook::InvokeDeleteHook(ptr);
-    DebugDeallocate(ptr, MallocBlock::kMallocType, 0);
-    return NULL;
-  }
-  MallocBlock* old = MallocBlock::FromRawPointer(ptr);
-  old->Check(MallocBlock::kMallocType);
-  MallocBlock* p = MallocBlock::Allocate(size, MallocBlock::kMallocType);
-
-  // If realloc fails we are to leave the old block untouched and
-  // return null
-  if (p == NULL)  return NULL;
-
-  // if ptr was allocated via memalign, then old->data_size() is not
-  // start of user data. So we must be careful to copy only user-data
-  char *old_begin = (char *)old->data_addr();
-  char *old_end = old_begin + old->data_size();
-
-  ssize_t old_ssize = old_end - (char *)ptr;
-  CHECK_CONDITION(old_ssize >= 0);
-
-  size_t old_size = (size_t)old_ssize;
-  CHECK_CONDITION(old_size <= old->data_size());
-
-  memcpy(p->data_addr(), ptr, (old_size < size) ? old_size : size);
-  MallocHook::InvokeDeleteHook(ptr);
-  MallocHook::InvokeNewHook(p->data_addr(), size);
-  DebugDeallocate(ptr, MallocBlock::kMallocType, 0);
-  MALLOC_TRACE("realloc", p->data_size(), p->data_addr());
-  return p->data_addr();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new(size_t size) {
-  void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, false);
-  MallocHook::InvokeNewHook(ptr, size);
-  if (ptr == NULL) {
-    RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new failed.", size);
-  }
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, true);
-  MallocHook::InvokeNewHook(ptr, size);
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kNewType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kNewType, size);
-  force_frame();
-}
-
-// Some STL implementations explicitly invoke this.
-// It is completely equivalent to a normal delete (delete never throws).
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kNewType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size) {
-  void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, false);
-  MallocHook::InvokeNewHook(ptr, size);
-  if (ptr == NULL) {
-    RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new[] failed.", size);
-  }
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::nothrow_t&)
-    PERFTOOLS_NOTHROW {
-  void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, true);
-  MallocHook::InvokeNewHook(ptr, size);
-  return ptr;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kArrayNewType, 0);
-  force_frame();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kArrayNewType, size);
-  force_frame();
-}
-
-// Some STL implementations explicitly invoke this.
-// It is completely equivalent to a normal delete (delete never throws).
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  MallocHook::InvokeDeleteHook(p);
-  DebugDeallocate(p, MallocBlock::kArrayNewType, 0);
-  force_frame();
-}
-
-// This is mostly the same as do_memalign in tcmalloc.cc.
-static void *do_debug_memalign(size_t alignment, size_t size, int type) {
-  // Allocate >= size bytes aligned on "alignment" boundary
-  // "alignment" is a power of two.
-  void *p = 0;
-  RAW_CHECK((alignment & (alignment-1)) == 0, "must be power of two");
-  const size_t data_offset = MallocBlock::data_offset();
-  // Allocate "alignment-1" extra bytes to ensure alignment is possible, and
-  // a further data_offset bytes for an additional fake header.
-  size_t extra_bytes = data_offset + alignment - 1;
-  if (size + extra_bytes < size) return NULL;         // Overflow
-  p = DebugAllocate(size + extra_bytes, type);
-  if (p != 0) {
-    intptr_t orig_p = reinterpret_cast<intptr_t>(p);
-    // Leave data_offset bytes for fake header, and round up to meet
-    // alignment.
-    p = reinterpret_cast<void *>(RoundUp(orig_p + data_offset, alignment));
-    // Create a fake header block with an offset_ that points back to the
-    // real header.  FromRawPointer uses this value.
-    MallocBlock *fake_hdr = reinterpret_cast<MallocBlock *>(
-                reinterpret_cast<char *>(p) - data_offset);
-    // offset_ is distance between real and fake headers.
-    // p is now end of fake header (beginning of client area),
-    // and orig_p is the end of the real header, so offset_
-    // is their difference.
-    //
-    // Note that other fields of fake_hdr are initialized with
-    // kMagicUninitializedByte
-    fake_hdr->set_offset(reinterpret_cast<intptr_t>(p) - orig_p);
-  }
-  return p;
-}
-
-struct memalign_retry_data {
-  size_t align;
-  size_t size;
-  int type;
-};
-
-static void *retry_debug_memalign(void *arg) {
-  memalign_retry_data *data = static_cast<memalign_retry_data *>(arg);
-  return do_debug_memalign(data->align, data->size, data->type);
-}
-
-ATTRIBUTE_ALWAYS_INLINE
-inline void* do_debug_memalign_or_debug_cpp_memalign(size_t align,
-                                                     size_t size,
-                                                     int type,
-                                                     bool from_operator,
-                                                     bool nothrow) {
-  void* p = do_debug_memalign(align, size, type);
-  if (p != NULL) {
-    return p;
-  }
-
-  struct memalign_retry_data data;
-  data.align = align;
-  data.size = size;
-  data.type = type;
-  return handle_oom(retry_debug_memalign, &data,
-                    from_operator, nothrow);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_memalign(size_t align, size_t size) PERFTOOLS_NOTHROW {
-  void *p = do_debug_memalign_or_debug_cpp_memalign(align, size, MallocBlock::kMallocType, false, true);
-  MallocHook::InvokeNewHook(p, size);
-  return p;
-}
-
-// Implementation taken from tcmalloc/tcmalloc.cc
-extern "C" PERFTOOLS_DLL_DECL int tc_posix_memalign(void** result_ptr, size_t align, size_t size)
-    PERFTOOLS_NOTHROW {
-  if (((align % sizeof(void*)) != 0) ||
-      ((align & (align - 1)) != 0) ||
-      (align == 0)) {
-    return EINVAL;
-  }
-
-  void* result = do_debug_memalign_or_debug_cpp_memalign(align, size, MallocBlock::kMallocType, false, true);
-  MallocHook::InvokeNewHook(result, size);
-  if (result == NULL) {
-    return ENOMEM;
-  } else {
-    *result_ptr = result;
-    return 0;
-  }
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_valloc(size_t size) PERFTOOLS_NOTHROW {
-  // Allocate >= size bytes starting on a page boundary
-  void *p = do_debug_memalign_or_debug_cpp_memalign(getpagesize(), size, MallocBlock::kMallocType, false, true);
-  MallocHook::InvokeNewHook(p, size);
-  return p;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t size) PERFTOOLS_NOTHROW {
-  // Round size up to a multiple of pages
-  // then allocate memory on a page boundary
-  int pagesize = getpagesize();
-  size = RoundUp(size, pagesize);
-  if (size == 0) {     // pvalloc(0) should allocate one page, according to
-    size = pagesize;   // http://man.free4web.biz/man3/libmpatrol.3.html
-  }
-  void *p = do_debug_memalign_or_debug_cpp_memalign(pagesize, size, MallocBlock::kMallocType, false, true);
-  MallocHook::InvokeNewHook(p, size);
-  return p;
-}
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t align) {
-  void* result = do_debug_memalign_or_debug_cpp_memalign(static_cast<size_t>(align), size, MallocBlock::kNewType, true, false);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t align, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  void* result = do_debug_memalign_or_debug_cpp_memalign(static_cast<size_t>(align), size, MallocBlock::kNewType, true, true);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t) PERFTOOLS_NOTHROW {
-  tc_delete(p);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t align) PERFTOOLS_NOTHROW {
-  // Reproduce actual size calculation done by do_debug_memalign
-  const size_t alignment = static_cast<size_t>(align);
-  const size_t data_offset = MallocBlock::data_offset();
-  const size_t extra_bytes = data_offset + alignment - 1;
-
-  tc_delete_sized(p, size + extra_bytes);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  tc_delete(p);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t align) {
-  void* result = do_debug_memalign_or_debug_cpp_memalign(static_cast<size_t>(align), size, MallocBlock::kArrayNewType, true, false);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t align, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
-  void* result = do_debug_memalign_or_debug_cpp_memalign(static_cast<size_t>(align), size, MallocBlock::kArrayNewType, true, true);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t) PERFTOOLS_NOTHROW {
-  tc_deletearray(p);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t align) PERFTOOLS_NOTHROW {
-  // Reproduce actual size calculation done by do_debug_memalign
-  const size_t alignment = static_cast<size_t>(align);
-  const size_t data_offset = MallocBlock::data_offset();
-  const size_t extra_bytes = data_offset + alignment - 1;
-
-  tc_deletearray_sized(p, size + extra_bytes);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  tc_deletearray(p);
-}
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-// malloc_stats just falls through to the base implementation.
-extern "C" PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW {
-  do_malloc_stats();
-}
-
-extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW {
-  return do_mallopt(cmd, value);
-}
-
-#ifdef HAVE_STRUCT_MALLINFO
-extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW {
-  return do_mallinfo();
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW {
-  return MallocExtension::instance()->GetAllocatedSize(ptr);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW {
-  void* result = DebugAllocate(size, MallocBlock::kMallocType);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
diff --git a/third_party/tcmalloc/vendor/src/emergency_malloc.cc b/third_party/tcmalloc/vendor/src/emergency_malloc.cc
deleted file mode 100644
index 81c5554..0000000
--- a/third_party/tcmalloc/vendor/src/emergency_malloc.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "config.h"
-
-#include "emergency_malloc.h"
-
-#include <errno.h>                      // for ENOMEM, errno
-#include <string.h>                     // for memset
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/low_level_alloc.h"
-#include "base/spinlock.h"
-#include "internal_logging.h"
-
-
-namespace tcmalloc {
-  __attribute__ ((visibility("internal"))) char *emergency_arena_start;
-  __attribute__ ((visibility("internal"))) uintptr_t emergency_arena_start_shifted;
-
-  static CACHELINE_ALIGNED SpinLock emergency_malloc_lock(base::LINKER_INITIALIZED);
-  static char *emergency_arena_end;
-  static LowLevelAlloc::Arena *emergency_arena;
-
-  class EmergencyArenaPagesAllocator : public LowLevelAlloc::PagesAllocator {
-    ~EmergencyArenaPagesAllocator() {}
-    void *MapPages(int32 flags, size_t size) {
-      char *new_end = emergency_arena_end + size;
-      if (new_end > emergency_arena_start + kEmergencyArenaSize) {
-        RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes in emergency zone.", size);
-      }
-      char *rv = emergency_arena_end;
-      emergency_arena_end = new_end;
-      return static_cast<void *>(rv);
-    }
-    void UnMapPages(int32 flags, void *addr, size_t size) {
-      RAW_LOG(FATAL, "UnMapPages is not implemented for emergency arena");
-    }
-  };
-
-  static union {
-    char bytes[sizeof(EmergencyArenaPagesAllocator)];
-    void *ptr;
-  } pages_allocator_place;
-
-  static void InitEmergencyMalloc(void) {
-    const int32 flags = LowLevelAlloc::kAsyncSignalSafe;
-
-    void *arena = LowLevelAlloc::GetDefaultPagesAllocator()->MapPages(flags, kEmergencyArenaSize * 2);
-
-    uintptr_t arena_ptr = reinterpret_cast<uintptr_t>(arena);
-    uintptr_t ptr = (arena_ptr + kEmergencyArenaSize - 1) & ~(kEmergencyArenaSize-1);
-
-    emergency_arena_end = emergency_arena_start = reinterpret_cast<char *>(ptr);
-    EmergencyArenaPagesAllocator *allocator = new (pages_allocator_place.bytes) EmergencyArenaPagesAllocator();
-    emergency_arena = LowLevelAlloc::NewArenaWithCustomAlloc(0, LowLevelAlloc::DefaultArena(), allocator);
-
-    emergency_arena_start_shifted = reinterpret_cast<uintptr_t>(emergency_arena_start) >> kEmergencyArenaShift;
-
-    uintptr_t head_unmap_size = ptr - arena_ptr;
-    CHECK_CONDITION(head_unmap_size < kEmergencyArenaSize);
-    if (head_unmap_size != 0) {
-      LowLevelAlloc::GetDefaultPagesAllocator()->UnMapPages(flags, arena, ptr - arena_ptr);
-    }
-
-    uintptr_t tail_unmap_size = kEmergencyArenaSize - head_unmap_size;
-    void *tail_start = reinterpret_cast<void *>(arena_ptr + head_unmap_size + kEmergencyArenaSize);
-    LowLevelAlloc::GetDefaultPagesAllocator()->UnMapPages(flags, tail_start, tail_unmap_size);
-  }
-
-  PERFTOOLS_DLL_DECL void *EmergencyMalloc(size_t size) {
-    SpinLockHolder l(&emergency_malloc_lock);
-
-    if (emergency_arena_start == NULL) {
-      InitEmergencyMalloc();
-      CHECK_CONDITION(emergency_arena_start != NULL);
-    }
-
-    void *rv = LowLevelAlloc::AllocWithArena(size, emergency_arena);
-    if (rv == NULL) {
-      errno = ENOMEM;
-    }
-    return rv;
-  }
-
-  PERFTOOLS_DLL_DECL void EmergencyFree(void *p) {
-    SpinLockHolder l(&emergency_malloc_lock);
-    if (emergency_arena_start == NULL) {
-      InitEmergencyMalloc();
-      CHECK_CONDITION(emergency_arena_start != NULL);
-      free(p);
-      return;
-    }
-    CHECK_CONDITION(emergency_arena_start);
-    LowLevelAlloc::Free(p);
-  }
-
-  PERFTOOLS_DLL_DECL void *EmergencyRealloc(void *_old_ptr, size_t new_size) {
-    if (_old_ptr == NULL) {
-      return EmergencyMalloc(new_size);
-    }
-    if (new_size == 0) {
-      EmergencyFree(_old_ptr);
-      return NULL;
-    }
-    SpinLockHolder l(&emergency_malloc_lock);
-    CHECK_CONDITION(emergency_arena_start);
-
-    char *old_ptr = static_cast<char *>(_old_ptr);
-    CHECK_CONDITION(old_ptr <= emergency_arena_end);
-    CHECK_CONDITION(emergency_arena_start <= old_ptr);
-
-    // NOTE: we don't know previous size of old_ptr chunk. So instead
-    // of trying to figure out right size of copied memory, we just
-    // copy largest possible size. We don't care about being slow.
-    size_t old_ptr_size = emergency_arena_end - old_ptr;
-    size_t copy_size = (new_size < old_ptr_size) ? new_size : old_ptr_size;
-
-    void *new_ptr = LowLevelAlloc::AllocWithArena(new_size, emergency_arena);
-    if (new_ptr == NULL) {
-      errno = ENOMEM;
-      return NULL;
-    }
-    memcpy(new_ptr, old_ptr, copy_size);
-
-    LowLevelAlloc::Free(old_ptr);
-    return new_ptr;
-  }
-
-  PERFTOOLS_DLL_DECL void *EmergencyCalloc(size_t n, size_t elem_size) {
-    // Overflow check
-    const size_t size = n * elem_size;
-    if (elem_size != 0 && size / elem_size != n) return NULL;
-    void *rv = EmergencyMalloc(size);
-    if (rv != NULL) {
-      memset(rv, 0, size);
-    }
-    return rv;
-  }
-};
diff --git a/third_party/tcmalloc/vendor/src/emergency_malloc.h b/third_party/tcmalloc/vendor/src/emergency_malloc.h
deleted file mode 100644
index 8a82cfc..0000000
--- a/third_party/tcmalloc/vendor/src/emergency_malloc.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef EMERGENCY_MALLOC_H
-#define EMERGENCY_MALLOC_H
-#include "config.h"
-
-#include <stddef.h>
-
-#include "base/basictypes.h"
-#include "common.h"
-
-namespace tcmalloc {
-  static const uintptr_t kEmergencyArenaShift = 20+4; // 16 megs
-  static const uintptr_t kEmergencyArenaSize = 1 << kEmergencyArenaShift;
-
-  extern __attribute__ ((visibility("internal"))) char *emergency_arena_start;
-  extern __attribute__ ((visibility("internal"))) uintptr_t emergency_arena_start_shifted;;
-
-  PERFTOOLS_DLL_DECL void *EmergencyMalloc(size_t size);
-  PERFTOOLS_DLL_DECL void EmergencyFree(void *p);
-  PERFTOOLS_DLL_DECL void *EmergencyCalloc(size_t n, size_t elem_size);
-  PERFTOOLS_DLL_DECL void *EmergencyRealloc(void *old_ptr, size_t new_size);
-
-  static inline bool IsEmergencyPtr(const void *_ptr) {
-    uintptr_t ptr = reinterpret_cast<uintptr_t>(_ptr);
-    return PREDICT_FALSE((ptr >> kEmergencyArenaShift) == emergency_arena_start_shifted)
-      && emergency_arena_start_shifted;
-  }
-
-} // namespace tcmalloc
-
-#endif
diff --git a/third_party/tcmalloc/vendor/src/emergency_malloc_for_stacktrace.cc b/third_party/tcmalloc/vendor/src/emergency_malloc_for_stacktrace.cc
deleted file mode 100644
index f1dc35e7..0000000
--- a/third_party/tcmalloc/vendor/src/emergency_malloc_for_stacktrace.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "emergency_malloc.h"
-#include "thread_cache.h"
-
-namespace tcmalloc {
-  bool EnterStacktraceScope(void);
-  void LeaveStacktraceScope(void);
-}
-
-bool tcmalloc::EnterStacktraceScope(void) {
-  if (ThreadCache::IsUseEmergencyMalloc()) {
-    return false;
-  }
-  ThreadCache::SetUseEmergencyMalloc();
-  return true;
-}
-
-void tcmalloc::LeaveStacktraceScope(void) {
-  ThreadCache::ResetUseEmergencyMalloc();
-}
diff --git a/third_party/tcmalloc/vendor/src/fake_stacktrace_scope.cc b/third_party/tcmalloc/vendor/src/fake_stacktrace_scope.cc
deleted file mode 100644
index ee35a04..0000000
--- a/third_party/tcmalloc/vendor/src/fake_stacktrace_scope.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "base/basictypes.h"
-
-namespace tcmalloc {
-  ATTRIBUTE_WEAK bool EnterStacktraceScope(void) {
-    return true;
-  }
-  ATTRIBUTE_WEAK void LeaveStacktraceScope(void) {
-  }
-}
diff --git a/third_party/tcmalloc/vendor/src/getenv_safe.h b/third_party/tcmalloc/vendor/src/getenv_safe.h
deleted file mode 100644
index 3b9f4dbb..0000000
--- a/third_party/tcmalloc/vendor/src/getenv_safe.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
- * Copyright (c) 2014, gperftools Contributors
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef GETENV_SAFE_H
-#define GETENV_SAFE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* 
- * This getenv function is safe to call before the C runtime is initialized.
- * On Windows, it utilizes GetEnvironmentVariable() and on unix it uses
- * /proc/self/environ instead calling getenv().  It's intended to be used in
- * routines that run before main(), when the state required for getenv() may
- * not be set up yet.  In particular, errno isn't set up until relatively late
- * (after the pthreads library has a chance to make it threadsafe), and
- * getenv() doesn't work until then.
- * On some platforms, this call will utilize the same, static buffer for
- * repeated GetenvBeforeMain() calls. Callers should not expect pointers from
- * this routine to be long lived.
- * Note that on unix, /proc only has the environment at the time the
- * application was started, so this routine ignores setenv() calls/etc.  Also
- * note it only reads the first 16K of the environment.
- * 
- * NOTE: this is version of GetenvBeforeMain that's usable from
- * C. Implementation is in sysinfo.cc
- */
-const char* TCMallocGetenvSafe(const char* name);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/third_party/tcmalloc/vendor/src/getpc.h b/third_party/tcmalloc/vendor/src/getpc.h
deleted file mode 100644
index 163873e..0000000
--- a/third_party/tcmalloc/vendor/src/getpc.h
+++ /dev/null
@@ -1,192 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This is an internal header file used by profiler.cc.  It defines
-// the single (inline) function GetPC.  GetPC is used in a signal
-// handler to figure out the instruction that was being executed when
-// the signal-handler was triggered.
-//
-// To get this, we use the ucontext_t argument to the signal-handler
-// callback, which holds the full context of what was going on when
-// the signal triggered.  How to get from a ucontext_t to a Program
-// Counter is OS-dependent.
-
-#ifndef BASE_GETPC_H_
-#define BASE_GETPC_H_
-
-#include "config.h"
-
-// On many linux systems, we may need _GNU_SOURCE to get access to
-// the defined constants that define the register we want to see (eg
-// REG_EIP).  Note this #define must come first!
-#define _GNU_SOURCE 1
-// If #define _GNU_SOURCE causes problems, this might work instead.
-// It will cause problems for FreeBSD though!, because it turns off
-// the needed __BSD_VISIBLE.
-//#define _XOPEN_SOURCE 500
-
-#include <string.h>         // for memcmp
-#if defined(HAVE_SYS_UCONTEXT_H)
-#include <sys/ucontext.h>
-#elif defined(HAVE_UCONTEXT_H)
-#include <ucontext.h>       // for ucontext_t (and also mcontext_t)
-#elif defined(HAVE_CYGWIN_SIGNAL_H)
-#include <cygwin/signal.h>
-typedef ucontext ucontext_t;
-#endif
-
-
-// Take the example where function Foo() calls function Bar().  For
-// many architectures, Bar() is responsible for setting up and tearing
-// down its own stack frame.  In that case, it's possible for the
-// interrupt to happen when execution is in Bar(), but the stack frame
-// is not properly set up (either before it's done being set up, or
-// after it's been torn down but before Bar() returns).  In those
-// cases, the stack trace cannot see the caller function anymore.
-//
-// GetPC can try to identify this situation, on architectures where it
-// might occur, and unwind the current function call in that case to
-// avoid false edges in the profile graph (that is, edges that appear
-// to show a call skipping over a function).  To do this, we hard-code
-// in the asm instructions we might see when setting up or tearing
-// down a stack frame.
-//
-// This is difficult to get right: the instructions depend on the
-// processor, the compiler ABI, and even the optimization level.  This
-// is a best effort patch -- if we fail to detect such a situation, or
-// mess up the PC, nothing happens; the returned PC is not used for
-// any further processing.
-struct CallUnrollInfo {
-  // Offset from (e)ip register where this instruction sequence
-  // should be matched. Interpreted as bytes. Offset 0 is the next
-  // instruction to execute. Be extra careful with negative offsets in
-  // architectures of variable instruction length (like x86) - it is
-  // not that easy as taking an offset to step one instruction back!
-  int pc_offset;
-  // The actual instruction bytes. Feel free to make it larger if you
-  // need a longer sequence.
-  unsigned char ins[16];
-  // How many bytes to match from ins array?
-  int ins_size;
-  // The offset from the stack pointer (e)sp where to look for the
-  // call return address. Interpreted as bytes.
-  int return_sp_offset;
-};
-
-
-// The dereferences needed to get the PC from a struct ucontext were
-// determined at configure time, and stored in the macro
-// PC_FROM_UCONTEXT in config.h.  The only thing we need to do here,
-// then, is to do the magic call-unrolling for systems that support it.
-
-// -- Special case 1: linux x86, for which we have CallUnrollInfo
-#if defined(__linux) && defined(__i386) && defined(__GNUC__)
-static const CallUnrollInfo callunrollinfo[] = {
-  // Entry to a function:  push %ebp;  mov  %esp,%ebp
-  // Top-of-stack contains the caller IP.
-  { 0,
-    {0x55, 0x89, 0xe5}, 3,
-    0
-  },
-  // Entry to a function, second instruction:  push %ebp;  mov  %esp,%ebp
-  // Top-of-stack contains the old frame, caller IP is +4.
-  { -1,
-    {0x55, 0x89, 0xe5}, 3,
-    4
-  },
-  // Return from a function: RET.
-  // Top-of-stack contains the caller IP.
-  { 0,
-    {0xc3}, 1,
-    0
-  }
-};
-
-inline void* GetPC(const ucontext_t& signal_ucontext) {
-  // See comment above struct CallUnrollInfo.  Only try instruction
-  // flow matching if both eip and esp looks reasonable.
-  const int eip = signal_ucontext.uc_mcontext.gregs[REG_EIP];
-  const int esp = signal_ucontext.uc_mcontext.gregs[REG_ESP];
-  if ((eip & 0xffff0000) != 0 && (~eip & 0xffff0000) != 0 &&
-      (esp & 0xffff0000) != 0) {
-    char* eip_char = reinterpret_cast<char*>(eip);
-    for (int i = 0; i < sizeof(callunrollinfo)/sizeof(*callunrollinfo); ++i) {
-      if (!memcmp(eip_char + callunrollinfo[i].pc_offset,
-                  callunrollinfo[i].ins, callunrollinfo[i].ins_size)) {
-        // We have a match.
-        void **retaddr = (void**)(esp + callunrollinfo[i].return_sp_offset);
-        return *retaddr;
-      }
-    }
-  }
-  return (void*)eip;
-}
-
-// Special case #2: Windows, which has to do something totally different.
-#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
-// If this is ever implemented, probably the way to do it is to have
-// profiler.cc use a high-precision timer via timeSetEvent:
-//    http://msdn2.microsoft.com/en-us/library/ms712713.aspx
-// We'd use it in mode TIME_CALLBACK_FUNCTION/TIME_PERIODIC.
-// The callback function would be something like prof_handler, but
-// alas the arguments are different: no ucontext_t!  I don't know
-// how we'd get the PC (using StackWalk64?)
-//    http://msdn2.microsoft.com/en-us/library/ms680650.aspx
-
-#include "base/logging.h"   // for RAW_LOG
-#ifndef HAVE_CYGWIN_SIGNAL_H
-typedef int ucontext_t;
-#endif
-
-inline void* GetPC(const struct ucontext_t& signal_ucontext) {
-  RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n");
-  return NULL;
-}
-
-// Normal cases.  If this doesn't compile, it's probably because
-// PC_FROM_UCONTEXT is the empty string.  You need to figure out
-// the right value for your system, and add it to the list in
-// configure.ac (or set it manually in your config.h).
-#else
-inline void* GetPC(const ucontext_t& signal_ucontext) {
-#if defined(__s390__) && !defined(__s390x__)
-  // Mask out the AMODE31 bit from the PC recorded in the context.
-  return (void*)((unsigned long)signal_ucontext.PC_FROM_UCONTEXT & 0x7fffffffUL);
-#else
-  return (void*)signal_ucontext.PC_FROM_UCONTEXT;   // defined in config.h
-#endif
-}
-
-#endif
-
-#endif  // BASE_GETPC_H_
diff --git a/third_party/tcmalloc/vendor/src/google/heap-checker.h b/third_party/tcmalloc/vendor/src/google/heap-checker.h
deleted file mode 100644
index 6b9ffe5..0000000
--- a/third_party/tcmalloc/vendor/src/google/heap-checker.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/heap-checker.h is deprecated. Use gperftools/heap-checker.h instead"
-#endif
-#include <gperftools/heap-checker.h>
diff --git a/third_party/tcmalloc/vendor/src/google/heap-profiler.h b/third_party/tcmalloc/vendor/src/google/heap-profiler.h
deleted file mode 100644
index 6155484..0000000
--- a/third_party/tcmalloc/vendor/src/google/heap-profiler.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2005, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/heap-profiler.h is deprecated. Use gperftools/heap-profiler.h instead"
-#endif
-#include <gperftools/heap-profiler.h>
diff --git a/third_party/tcmalloc/vendor/src/google/malloc_extension.h b/third_party/tcmalloc/vendor/src/google/malloc_extension.h
deleted file mode 100644
index fdad25a3..0000000
--- a/third_party/tcmalloc/vendor/src/google/malloc_extension.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/malloc_extension.h is deprecated. Use gperftools/malloc_extension.h instead"
-#endif
-#include <gperftools/malloc_extension.h>
diff --git a/third_party/tcmalloc/vendor/src/google/malloc_extension_c.h b/third_party/tcmalloc/vendor/src/google/malloc_extension_c.h
deleted file mode 100644
index 3c5cd38..0000000
--- a/third_party/tcmalloc/vendor/src/google/malloc_extension_c.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/malloc_extension_c.h is deprecated. Use gperftools/malloc_extension_c.h instead"
-#endif
-#include <gperftools/malloc_extension_c.h>
diff --git a/third_party/tcmalloc/vendor/src/google/malloc_hook.h b/third_party/tcmalloc/vendor/src/google/malloc_hook.h
deleted file mode 100644
index 7ec0002..0000000
--- a/third_party/tcmalloc/vendor/src/google/malloc_hook.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/malloc_hook.h is deprecated. Use gperftools/malloc_hook.h instead"
-#endif
-#include <gperftools/malloc_hook.h>
diff --git a/third_party/tcmalloc/vendor/src/google/malloc_hook_c.h b/third_party/tcmalloc/vendor/src/google/malloc_hook_c.h
deleted file mode 100644
index eb21aaf..0000000
--- a/third_party/tcmalloc/vendor/src/google/malloc_hook_c.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/malloc_hook_c.h is deprecated. Use gperftools/malloc_hook_c.h instead"
-#endif
-#include <gperftools/malloc_hook_c.h>
diff --git a/third_party/tcmalloc/vendor/src/google/profiler.h b/third_party/tcmalloc/vendor/src/google/profiler.h
deleted file mode 100644
index 293d605..0000000
--- a/third_party/tcmalloc/vendor/src/google/profiler.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2005, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/profiler.h is deprecated. Use gperftools/profiler.h instead"
-#endif
-#include <gperftools/profiler.h>
diff --git a/third_party/tcmalloc/vendor/src/google/stacktrace.h b/third_party/tcmalloc/vendor/src/google/stacktrace.h
deleted file mode 100644
index 55f12d2..0000000
--- a/third_party/tcmalloc/vendor/src/google/stacktrace.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/stacktrace.h is deprecated. Use gperftools/stacktrace.h instead"
-#endif
-#include <gperftools/stacktrace.h>
diff --git a/third_party/tcmalloc/vendor/src/google/tcmalloc.h b/third_party/tcmalloc/vendor/src/google/tcmalloc.h
deleted file mode 100644
index 1addeb61..0000000
--- a/third_party/tcmalloc/vendor/src/google/tcmalloc.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#if defined(__GNUC__) && !defined(GPERFTOOLS_SUPPRESS_LEGACY_WARNING)
-#warning "google/tcmalloc.h is deprecated. Use gperftools/tcmalloc.h instead"
-#endif
-#include <gperftools/tcmalloc.h>
diff --git a/third_party/tcmalloc/vendor/src/gperftools/heap-checker.h b/third_party/tcmalloc/vendor/src/gperftools/heap-checker.h
deleted file mode 100644
index edd6cc7..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/heap-checker.h
+++ /dev/null
@@ -1,422 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Maxim Lifantsev (with design ideas by Sanjay Ghemawat)
-//
-//
-// Module for detecing heap (memory) leaks.
-//
-// For full(er) information, see docs/heap_checker.html
-//
-// This module can be linked into programs with
-// no slowdown caused by this unless you activate the leak-checker:
-//
-//    1. Set the environment variable HEAPCHEK to _type_ before
-//       running the program.
-//
-// _type_ is usually "normal" but can also be "minimal", "strict", or
-// "draconian".  (See the html file for other options, like 'local'.)
-//
-// After that, just run your binary.  If the heap-checker detects
-// a memory leak at program-exit, it will print instructions on how
-// to track down the leak.
-
-#ifndef BASE_HEAP_CHECKER_H_
-#define BASE_HEAP_CHECKER_H_
-
-#include <sys/types.h>  // for size_t
-// I can't #include config.h in this public API file, but I should
-// really use configure (and make malloc_extension.h a .in file) to
-// figure out if the system has stdint.h or not.  But I'm lazy, so
-// for now I'm assuming it's a problem only with MSVC.
-#ifndef _MSC_VER
-#include <stdint.h>     // for uintptr_t
-#endif
-#include <stdarg.h>     // for va_list
-#include <vector>
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-
-// The class is thread-safe with respect to all the provided static methods,
-// as well as HeapLeakChecker objects: they can be accessed by multiple threads.
-class PERFTOOLS_DLL_DECL HeapLeakChecker {
- public:
-
-  // ----------------------------------------------------------------------- //
-  // Static functions for working with (whole-program) leak checking.
-
-  // If heap leak checking is currently active in some mode
-  // e.g. if leak checking was started (and is still active now)
-  // due to HEAPCHECK=... defined in the environment.
-  // The return value reflects iff HeapLeakChecker objects manually
-  // constructed right now will be doing leak checking or nothing.
-  // Note that we can go from active to inactive state during InitGoogle()
-  // if FLAGS_heap_check gets set to "" by some code before/during InitGoogle().
-  static bool IsActive();
-
-  // Return pointer to the whole-program checker if it has been created
-  // and NULL otherwise.
-  // Once GlobalChecker() returns non-NULL that object will not disappear and
-  // will be returned by all later GlobalChecker calls.
-  // This is mainly to access BytesLeaked() and ObjectsLeaked() (see below)
-  // for the whole-program checker after one calls NoGlobalLeaks()
-  // or similar and gets false.
-  static HeapLeakChecker* GlobalChecker();
-
-  // Do whole-program leak check now (if it was activated for this binary);
-  // return false only if it was activated and has failed.
-  // The mode of the check is controlled by the command-line flags.
-  // This method can be called repeatedly.
-  // Things like GlobalChecker()->SameHeap() can also be called explicitly
-  // to do the desired flavor of the check.
-  static bool NoGlobalLeaks();
-
-  // If whole-program checker if active,
-  // cancel its automatic execution after main() exits.
-  // This requires that some leak check (e.g. NoGlobalLeaks())
-  // has been called at least once on the whole-program checker.
-  static void CancelGlobalCheck();
-
-  // ----------------------------------------------------------------------- //
-  // Non-static functions for starting and doing leak checking.
-
-  // Start checking and name the leak check performed.
-  // The name is used in naming dumped profiles
-  // and needs to be unique only within your binary.
-  // It must also be a string that can be a part of a file name,
-  // in particular not contain path expressions.
-  explicit HeapLeakChecker(const char *name);
-
-  // Destructor (verifies that some *NoLeaks or *SameHeap method
-  // has been called at least once).
-  ~HeapLeakChecker();
-
-  // These used to be different but are all the same now: they return
-  // true iff all memory allocated since this HeapLeakChecker object
-  // was constructor is still reachable from global state.
-  //
-  // Because we fork to convert addresses to symbol-names, and forking
-  // is not thread-safe, and we may be called in a threaded context,
-  // we do not try to symbolize addresses when called manually.
-  bool NoLeaks() { return DoNoLeaks(DO_NOT_SYMBOLIZE); }
-
-  // These forms are obsolete; use NoLeaks() instead.
-  // TODO(csilvers): mark as DEPRECATED.
-  bool QuickNoLeaks()  { return NoLeaks(); }
-  bool BriefNoLeaks()  { return NoLeaks(); }
-  bool SameHeap()      { return NoLeaks(); }
-  bool QuickSameHeap() { return NoLeaks(); }
-  bool BriefSameHeap() { return NoLeaks(); }
-
-  // Detailed information about the number of leaked bytes and objects
-  // (both of these can be negative as well).
-  // These are available only after a *SameHeap or *NoLeaks
-  // method has been called.
-  // Note that it's possible for both of these to be zero
-  // while SameHeap() or NoLeaks() returned false in case
-  // of a heap state change that is significant
-  // but preserves the byte and object counts.
-  ssize_t BytesLeaked() const;
-  ssize_t ObjectsLeaked() const;
-
-  // ----------------------------------------------------------------------- //
-  // Static helpers to make us ignore certain leaks.
-
-  // Scoped helper class.  Should be allocated on the stack inside a
-  // block of code.  Any heap allocations done in the code block
-  // covered by the scoped object (including in nested function calls
-  // done by the code block) will not be reported as leaks.  This is
-  // the recommended replacement for the GetDisableChecksStart() and
-  // DisableChecksToHereFrom() routines below.
-  //
-  // Example:
-  //   void Foo() {
-  //     HeapLeakChecker::Disabler disabler;
-  //     ... code that allocates objects whose leaks should be ignored ...
-  //   }
-  //
-  // REQUIRES: Destructor runs in same thread as constructor
-  class Disabler {
-   public:
-    Disabler();
-    ~Disabler();
-   private:
-    Disabler(const Disabler&);        // disallow copy
-    void operator=(const Disabler&);  // and assign
-  };
-
-  // Ignore an object located at 'ptr' (can go at the start or into the object)
-  // as well as all heap objects (transitively) referenced from it for the
-  // purposes of heap leak checking. Returns 'ptr' so that one can write
-  //   static T* obj = IgnoreObject(new T(...));
-  //
-  // If 'ptr' does not point to an active allocated object at the time of this
-  // call, it is ignored; but if it does, the object must not get deleted from
-  // the heap later on.
-  //
-  // See also HiddenPointer, below, if you need to prevent a pointer from
-  // being traversed by the heap checker but do not wish to transitively
-  // whitelist objects referenced through it.
-  template <typename T>
-  static T* IgnoreObject(T* ptr) {
-    DoIgnoreObject(static_cast<const void*>(const_cast<const T*>(ptr)));
-    return ptr;
-  }
-
-  // Undo what an earlier IgnoreObject() call promised and asked to do.
-  // At the time of this call 'ptr' must point at or inside of an active
-  // allocated object which was previously registered with IgnoreObject().
-  static void UnIgnoreObject(const void* ptr);
-
-  // ----------------------------------------------------------------------- //
-  // Internal types defined in .cc
-
-  class Allocator;
-  struct RangeValue;
-
- private:
-
-  // ----------------------------------------------------------------------- //
-  // Various helpers
-
-  // Create the name of the heap profile file.
-  // Should be deleted via Allocator::Free().
-  char* MakeProfileNameLocked();
-
-  // Helper for constructors
-  void Create(const char *name, bool make_start_snapshot);
-
-  enum ShouldSymbolize { SYMBOLIZE, DO_NOT_SYMBOLIZE };
-
-  // Helper for *NoLeaks and *SameHeap
-  bool DoNoLeaks(ShouldSymbolize should_symbolize);
-
-  // Helper for NoGlobalLeaks, also called by the global destructor.
-  static bool NoGlobalLeaksMaybeSymbolize(ShouldSymbolize should_symbolize);
-
-  // These used to be public, but they are now deprecated.
-  // Will remove entirely when all internal uses are fixed.
-  // In the meantime, use friendship so the unittest can still test them.
-  static void* GetDisableChecksStart();
-  static void DisableChecksToHereFrom(const void* start_address);
-  static void DisableChecksIn(const char* pattern);
-  friend void RangeDisabledLeaks();
-  friend void NamedTwoDisabledLeaks();
-  friend void* RunNamedDisabledLeaks(void*);
-  friend void TestHeapLeakCheckerNamedDisabling();
-
-  // Actually implements IgnoreObject().
-  static void DoIgnoreObject(const void* ptr);
-
-  // Disable checks based on stack trace entry at a depth <=
-  // max_depth.  Used to hide allocations done inside some special
-  // libraries.
-  static void DisableChecksFromToLocked(const void* start_address,
-                                        const void* end_address,
-                                        int max_depth);
-
-  // Helper for DoNoLeaks to ignore all objects reachable from all live data
-  static void IgnoreAllLiveObjectsLocked(const void* self_stack_top);
-
-  // Callback we pass to TCMalloc_ListAllProcessThreads (see thread_lister.h)
-  // that is invoked when all threads of our process are found and stopped.
-  // The call back does the things needed to ignore live data reachable from
-  // thread stacks and registers for all our threads
-  // as well as do other global-live-data ignoring
-  // (via IgnoreNonThreadLiveObjectsLocked)
-  // during the quiet state of all threads being stopped.
-  // For the argument meaning see the comment by TCMalloc_ListAllProcessThreads.
-  // Here we only use num_threads and thread_pids, that TCMalloc_ListAllProcessThreads
-  // fills for us with the number and pids of all the threads of our process
-  // it found and attached to.
-  static int IgnoreLiveThreadsLocked(void* parameter,
-                                     int num_threads,
-                                     pid_t* thread_pids,
-                                     va_list ap);
-
-  // Helper for IgnoreAllLiveObjectsLocked and IgnoreLiveThreadsLocked
-  // that we prefer to execute from IgnoreLiveThreadsLocked
-  // while all threads are stopped.
-  // This helper does live object discovery and ignoring
-  // for all objects that are reachable from everything
-  // not related to thread stacks and registers.
-  static void IgnoreNonThreadLiveObjectsLocked();
-
-  // Helper for IgnoreNonThreadLiveObjectsLocked and IgnoreLiveThreadsLocked
-  // to discover and ignore all heap objects
-  // reachable from currently considered live objects
-  // (live_objects static global variable in out .cc file).
-  // "name", "name2" are two strings that we print one after another
-  // in a debug message to describe what kind of live object sources
-  // are being used.
-  static void IgnoreLiveObjectsLocked(const char* name, const char* name2);
-
-  // Do the overall whole-program heap leak check if needed;
-  // returns true when did the leak check.
-  static bool DoMainHeapCheck();
-
-  // Type of task for UseProcMapsLocked
-  enum ProcMapsTask {
-    RECORD_GLOBAL_DATA,
-    DISABLE_LIBRARY_ALLOCS
-  };
-
-  // Success/Error Return codes for UseProcMapsLocked.
-  enum ProcMapsResult {
-    PROC_MAPS_USED,
-    CANT_OPEN_PROC_MAPS,
-    NO_SHARED_LIBS_IN_PROC_MAPS
-  };
-
-  // Read /proc/self/maps, parse it, and do the 'proc_maps_task' for each line.
-  static ProcMapsResult UseProcMapsLocked(ProcMapsTask proc_maps_task);
-
-  // A ProcMapsTask to disable allocations from 'library'
-  // that is mapped to [start_address..end_address)
-  // (only if library is a certain system library).
-  static void DisableLibraryAllocsLocked(const char* library,
-                                         uintptr_t start_address,
-                                         uintptr_t end_address);
-
-  // Return true iff "*ptr" points to a heap object
-  // ("*ptr" can point at the start or inside of a heap object
-  //  so that this works e.g. for pointers to C++ arrays, C++ strings,
-  //  multiple-inherited objects, or pointers to members).
-  // We also fill *object_size for this object then
-  // and we move "*ptr" to point to the very start of the heap object.
-  static inline bool HaveOnHeapLocked(const void** ptr, size_t* object_size);
-
-  // Helper to shutdown heap leak checker when it's not needed
-  // or can't function properly.
-  static void TurnItselfOffLocked();
-
-  // Internally-used c-tor to start whole-executable checking.
-  HeapLeakChecker();
-
-  // ----------------------------------------------------------------------- //
-  // Friends and externally accessed helpers.
-
-  // Helper for VerifyHeapProfileTableStackGet in the unittest
-  // to get the recorded allocation caller for ptr,
-  // which must be a heap object.
-  static const void* GetAllocCaller(void* ptr);
-  friend void VerifyHeapProfileTableStackGet();
-
-  // This gets to execute before constructors for all global objects
-  static void BeforeConstructorsLocked();
-  friend void HeapLeakChecker_BeforeConstructors();
-
-  // This gets to execute after destructors for all global objects
-  friend void HeapLeakChecker_AfterDestructors();
-
-  // Full starting of recommended whole-program checking.
-  friend void HeapLeakChecker_InternalInitStart();
-
-  // Runs REGISTER_HEAPCHECK_CLEANUP cleanups and potentially
-  // calls DoMainHeapCheck
-  friend void HeapLeakChecker_RunHeapCleanups();
-
-  // ----------------------------------------------------------------------- //
-  // Member data.
-
-  class SpinLock* lock_;  // to make HeapLeakChecker objects thread-safe
-  const char* name_;  // our remembered name (we own it)
-                      // NULL means this leak checker is a noop
-
-  // Snapshot taken when the checker was created.  May be NULL
-  // for the global heap checker object.  We use void* instead of
-  // HeapProfileTable::Snapshot* to avoid including heap-profile-table.h.
-  void* start_snapshot_;
-
-  bool has_checked_;  // if we have done the leak check, so these are ready:
-  ssize_t inuse_bytes_increase_;  // bytes-in-use increase for this checker
-  ssize_t inuse_allocs_increase_;  // allocations-in-use increase
-                                   // for this checker
-  bool keep_profiles_;  // iff we should keep the heap profiles we've made
-
-  // ----------------------------------------------------------------------- //
-
-  // Disallow "evil" constructors.
-  HeapLeakChecker(const HeapLeakChecker&);
-  void operator=(const HeapLeakChecker&);
-};
-
-
-// Holds a pointer that will not be traversed by the heap checker.
-// Contrast with HeapLeakChecker::IgnoreObject(o), in which o and
-// all objects reachable from o are ignored by the heap checker.
-template <class T>
-class HiddenPointer {
- public:
-  explicit HiddenPointer(T* t)
-      : masked_t_(reinterpret_cast<uintptr_t>(t) ^ kHideMask) {
-  }
-  // Returns unhidden pointer.  Be careful where you save the result.
-  T* get() const { return reinterpret_cast<T*>(masked_t_ ^ kHideMask); }
-
- private:
-  // Arbitrary value, but not such that xor'ing with it is likely
-  // to map one valid pointer to another valid pointer:
-  static const uintptr_t kHideMask =
-      static_cast<uintptr_t>(0xF03A5F7BF03A5F7Bll);
-  uintptr_t masked_t_;
-};
-
-// A class that exists solely to run its destructor.  This class should not be
-// used directly, but instead by the REGISTER_HEAPCHECK_CLEANUP macro below.
-class PERFTOOLS_DLL_DECL HeapCleaner {
- public:
-  typedef void (*void_function)(void);
-  HeapCleaner(void_function f);
-  static void RunHeapCleanups();
- private:
-  static std::vector<void_function>* heap_cleanups_;
-};
-
-// A macro to declare module heap check cleanup tasks
-// (they run only if we are doing heap leak checking.)
-// 'body' should be the cleanup code to run.  'name' doesn't matter,
-// but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls.
-#define REGISTER_HEAPCHECK_CLEANUP(name, body)  \
-  namespace { \
-  void heapcheck_cleanup_##name() { body; } \
-  static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \
-  }
-
-#endif  // BASE_HEAP_CHECKER_H_
diff --git a/third_party/tcmalloc/vendor/src/gperftools/heap-profiler.h b/third_party/tcmalloc/vendor/src/gperftools/heap-profiler.h
deleted file mode 100644
index 38c6afe..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/heap-profiler.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- *
- * Module for heap-profiling.
- *
- * For full(er) information, see docs/heapprofile.html
- *
- * This module can be linked into your program with
- * no slowdown caused by this unless you activate the profiler
- * using one of the following methods:
- *
- *    1. Before starting the program, set the environment variable
- *       "HEAPPROFILE" to be the name of the file to which the profile
- *       data should be written.
- *
- *    2. Programmatically, start and stop the profiler using the
- *       routines "HeapProfilerStart(filename)" and "HeapProfilerStop()".
- *
- */
-
-#ifndef BASE_HEAP_PROFILER_H_
-#define BASE_HEAP_PROFILER_H_
-
-#include <stddef.h>
-
-/* Annoying stuff for windows; makes sure clients can import these functions */
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-/* All this code should be usable from within C apps. */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Start profiling and arrange to write profile data to file names
- * of the form: "prefix.0000", "prefix.0001", ...
- */
-PERFTOOLS_DLL_DECL void HeapProfilerStart(const char* prefix);
-
-/* Returns non-zero if we are currently profiling the heap.  (Returns
- * an int rather than a bool so it's usable from C.)  This is true
- * between calls to HeapProfilerStart() and HeapProfilerStop(), and
- * also if the program has been run with HEAPPROFILER, or some other
- * way to turn on whole-program profiling.
- */
-int IsHeapProfilerRunning();
-
-/* Stop heap profiling.  Can be restarted again with HeapProfilerStart(),
- * but the currently accumulated profiling information will be cleared.
- */
-PERFTOOLS_DLL_DECL void HeapProfilerStop();
-
-/* Dump a profile now - can be used for dumping at a hopefully
- * quiescent state in your program, in order to more easily track down
- * memory leaks. Will include the reason in the logged message
- */
-PERFTOOLS_DLL_DECL void HeapProfilerDump(const char *reason);
-
-/* Generate current heap profiling information.
- * Returns an empty string when heap profiling is not active.
- * The returned pointer is a '\0'-terminated string allocated using malloc()
- * and should be free()-ed as soon as the caller does not need it anymore.
- */
-PERFTOOLS_DLL_DECL char* GetHeapProfile();
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  /* BASE_HEAP_PROFILER_H_ */
diff --git a/third_party/tcmalloc/vendor/src/gperftools/malloc_extension.h b/third_party/tcmalloc/vendor/src/gperftools/malloc_extension.h
deleted file mode 100644
index 689b5f1..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/malloc_extension.h
+++ /dev/null
@@ -1,434 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// Extra extensions exported by some malloc implementations.  These
-// extensions are accessed through a virtual base class so an
-// application can link against a malloc that does not implement these
-// extensions, and it will get default versions that do nothing.
-//
-// NOTE FOR C USERS: If you wish to use this functionality from within
-// a C program, see malloc_extension_c.h.
-
-#ifndef BASE_MALLOC_EXTENSION_H_
-#define BASE_MALLOC_EXTENSION_H_
-
-#include <stddef.h>
-// I can't #include config.h in this public API file, but I should
-// really use configure (and make malloc_extension.h a .in file) to
-// figure out if the system has stdint.h or not.  But I'm lazy, so
-// for now I'm assuming it's a problem only with MSVC.
-#ifndef _MSC_VER
-#include <stdint.h>
-#endif
-#include <string>
-#include <vector>
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-static const int kMallocHistogramSize = 64;
-
-// One day, we could support other types of writers (perhaps for C?)
-typedef std::string MallocExtensionWriter;
-
-namespace base {
-struct MallocRange;
-}
-
-// Interface to a pluggable system allocator.
-class PERFTOOLS_DLL_DECL SysAllocator {
- public:
-  SysAllocator() {
-  }
-  virtual ~SysAllocator();
-
-  // Allocates "size"-byte of memory from system aligned with "alignment".
-  // Returns NULL if failed. Otherwise, the returned pointer p up to and
-  // including (p + actual_size -1) have been allocated.
-  virtual void* Alloc(size_t size, size_t *actual_size, size_t alignment) = 0;
-};
-
-// The default implementations of the following routines do nothing.
-// All implementations should be thread-safe; the current one
-// (TCMallocImplementation) is.
-class PERFTOOLS_DLL_DECL MallocExtension {
- public:
-  virtual ~MallocExtension();
-
-  // Call this very early in the program execution -- say, in a global
-  // constructor -- to set up parameters and state needed by all
-  // instrumented malloc implemenatations.  One example: this routine
-  // sets environemnt variables to tell STL to use libc's malloc()
-  // instead of doing its own memory management.  This is safe to call
-  // multiple times, as long as each time is before threads start up.
-  static void Initialize();
-
-  // See "verify_memory.h" to see what these routines do
-  virtual bool VerifyAllMemory();
-  virtual bool VerifyNewMemory(const void* p);
-  virtual bool VerifyArrayNewMemory(const void* p);
-  virtual bool VerifyMallocMemory(const void* p);
-  virtual bool MallocMemoryStats(int* blocks, size_t* total,
-                                 int histogram[kMallocHistogramSize]);
-
-  // Get a human readable description of the following malloc data structures.
-  // - Total inuse memory by application.
-  // - Free memory(thread, central and page heap),
-  // - Freelist of central cache, each class.
-  // - Page heap freelist.
-  // The state is stored as a null-terminated string
-  // in a prefix of "buffer[0,buffer_length-1]".
-  // REQUIRES: buffer_length > 0.
-  virtual void GetStats(char* buffer, int buffer_length);
-
-  // Outputs to "writer" a sample of live objects and the stack traces
-  // that allocated these objects.  The format of the returned output
-  // is equivalent to the output of the heap profiler and can
-  // therefore be passed to "pprof". This function is equivalent to
-  // ReadStackTraces. The main difference is that this function returns
-  // serialized data appropriately formatted for use by the pprof tool.
-  // NOTE: by default, tcmalloc does not do any heap sampling, and this
-  //       function will always return an empty sample.  To get useful
-  //       data from GetHeapSample, you must also set the environment
-  //       variable TCMALLOC_SAMPLE_PARAMETER to a value such as 524288.
-  virtual void GetHeapSample(MallocExtensionWriter* writer);
-
-  // Outputs to "writer" the stack traces that caused growth in the
-  // address space size.  The format of the returned output is
-  // equivalent to the output of the heap profiler and can therefore
-  // be passed to "pprof". This function is equivalent to
-  // ReadHeapGrowthStackTraces. The main difference is that this function
-  // returns serialized data appropriately formatted for use by the
-  // pprof tool.  (This does not depend on, or require,
-  // TCMALLOC_SAMPLE_PARAMETER.)
-  virtual void GetHeapGrowthStacks(MallocExtensionWriter* writer);
-
-  // Invokes func(arg, range) for every controlled memory
-  // range.  *range is filled in with information about the range.
-  //
-  // This is a best-effort interface useful only for performance
-  // analysis.  The implementation may not call func at all.
-  typedef void (RangeFunction)(void*, const base::MallocRange*);
-  virtual void Ranges(void* arg, RangeFunction func);
-
-  // -------------------------------------------------------------------
-  // Control operations for getting and setting malloc implementation
-  // specific parameters.  Some currently useful properties:
-  //
-  // generic
-  // -------
-  // "generic.current_allocated_bytes"
-  //      Number of bytes currently allocated by application
-  //      This property is not writable.
-  //
-  // "generic.heap_size"
-  //      Number of bytes in the heap ==
-  //            current_allocated_bytes +
-  //            fragmentation +
-  //            freed memory regions
-  //      This property is not writable.
-  //
-  // tcmalloc
-  // --------
-  // "tcmalloc.max_total_thread_cache_bytes"
-  //      Upper limit on total number of bytes stored across all
-  //      per-thread caches.  Default: 16MB.
-  //
-  // "tcmalloc.current_total_thread_cache_bytes"
-  //      Number of bytes used across all thread caches.
-  //      This property is not writable.
-  //
-  // "tcmalloc.central_cache_free_bytes"
-  //      Number of free bytes in the central cache that have been
-  //      assigned to size classes. They always count towards virtual
-  //      memory usage, and unless the underlying memory is swapped out
-  //      by the OS, they also count towards physical memory usage.
-  //      This property is not writable.
-  //
-  // "tcmalloc.transfer_cache_free_bytes"
-  //      Number of free bytes that are waiting to be transfered between
-  //      the central cache and a thread cache. They always count
-  //      towards virtual memory usage, and unless the underlying memory
-  //      is swapped out by the OS, they also count towards physical
-  //      memory usage. This property is not writable.
-  //
-  // "tcmalloc.thread_cache_free_bytes"
-  //      Number of free bytes in thread caches. They always count
-  //      towards virtual memory usage, and unless the underlying memory
-  //      is swapped out by the OS, they also count towards physical
-  //      memory usage. This property is not writable.
-  //
-  // "tcmalloc.pageheap_free_bytes"
-  //      Number of bytes in free, mapped pages in page heap.  These
-  //      bytes can be used to fulfill allocation requests.  They
-  //      always count towards virtual memory usage, and unless the
-  //      underlying memory is swapped out by the OS, they also count
-  //      towards physical memory usage.  This property is not writable.
-  //
-  // "tcmalloc.pageheap_unmapped_bytes"
-  //        Number of bytes in free, unmapped pages in page heap.
-  //        These are bytes that have been released back to the OS,
-  //        possibly by one of the MallocExtension "Release" calls.
-  //        They can be used to fulfill allocation requests, but
-  //        typically incur a page fault.  They always count towards
-  //        virtual memory usage, and depending on the OS, typically
-  //        do not count towards physical memory usage.  This property
-  //        is not writable.
-  // -------------------------------------------------------------------
-
-  // Get the named "property"'s value.  Returns true if the property
-  // is known.  Returns false if the property is not a valid property
-  // name for the current malloc implementation.
-  // REQUIRES: property != NULL; value != NULL
-  virtual bool GetNumericProperty(const char* property, size_t* value);
-
-  // Set the named "property"'s value.  Returns true if the property
-  // is known and writable.  Returns false if the property is not a
-  // valid property name for the current malloc implementation, or
-  // is not writable.
-  // REQUIRES: property != NULL
-  virtual bool SetNumericProperty(const char* property, size_t value);
-
-  // Mark the current thread as "idle".  This routine may optionally
-  // be called by threads as a hint to the malloc implementation that
-  // any thread-specific resources should be released.  Note: this may
-  // be an expensive routine, so it should not be called too often.
-  //
-  // Also, if the code that calls this routine will go to sleep for
-  // a while, it should take care to not allocate anything between
-  // the call to this routine and the beginning of the sleep.
-  //
-  // Most malloc implementations ignore this routine.
-  virtual void MarkThreadIdle();
-
-  // Mark the current thread as "busy".  This routine should be
-  // called after MarkThreadIdle() if the thread will now do more
-  // work.  If this method is not called, performance may suffer.
-  //
-  // Most malloc implementations ignore this routine.
-  virtual void MarkThreadBusy();
-
-  // Gets the system allocator used by the malloc extension instance. Returns
-  // NULL for malloc implementations that do not support pluggable system
-  // allocators.
-  virtual SysAllocator* GetSystemAllocator();
-
-  // Sets the system allocator to the specified.
-  //
-  // Users could register their own system allocators for malloc implementation
-  // that supports pluggable system allocators, such as TCMalloc, by doing:
-  //   alloc = new MyOwnSysAllocator();
-  //   MallocExtension::instance()->SetSystemAllocator(alloc);
-  // It's up to users whether to fall back (recommended) to the default
-  // system allocator (use GetSystemAllocator() above) or not. The caller is
-  // responsible to any necessary locking.
-  // See tcmalloc/system-alloc.h for the interface and
-  //     tcmalloc/memfs_malloc.cc for the examples.
-  //
-  // It's a no-op for malloc implementations that do not support pluggable
-  // system allocators.
-  virtual void SetSystemAllocator(SysAllocator *a);
-
-  // Try to release num_bytes of free memory back to the operating
-  // system for reuse.  Use this extension with caution -- to get this
-  // memory back may require faulting pages back in by the OS, and
-  // that may be slow.  (Currently only implemented in tcmalloc.)
-  virtual void ReleaseToSystem(size_t num_bytes);
-
-  // Same as ReleaseToSystem() but release as much memory as possible.
-  virtual void ReleaseFreeMemory();
-
-  // Sets the rate at which we release unused memory to the system.
-  // Zero means we never release memory back to the system.  Increase
-  // this flag to return memory faster; decrease it to return memory
-  // slower.  Reasonable rates are in the range [0,10].  (Currently
-  // only implemented in tcmalloc).
-  virtual void SetMemoryReleaseRate(double rate);
-
-  // Gets the release rate.  Returns a value < 0 if unknown.
-  virtual double GetMemoryReleaseRate();
-
-  // Returns the estimated number of bytes that will be allocated for
-  // a request of "size" bytes.  This is an estimate: an allocation of
-  // SIZE bytes may reserve more bytes, but will never reserve less.
-  // (Currently only implemented in tcmalloc, other implementations
-  // always return SIZE.)
-  // This is equivalent to malloc_good_size() in OS X.
-  virtual size_t GetEstimatedAllocatedSize(size_t size);
-
-  // Returns the actual number N of bytes reserved by tcmalloc for the
-  // pointer p.  The client is allowed to use the range of bytes
-  // [p, p+N) in any way it wishes (i.e. N is the "usable size" of this
-  // allocation).  This number may be equal to or greater than the number
-  // of bytes requested when p was allocated.
-  // p must have been allocated by this malloc implementation,
-  // must not be an interior pointer -- that is, must be exactly
-  // the pointer returned to by malloc() et al., not some offset
-  // from that -- and should not have been freed yet.  p may be NULL.
-  // (Currently only implemented in tcmalloc; other implementations
-  // will return 0.)
-  // This is equivalent to malloc_size() in OS X, malloc_usable_size()
-  // in glibc, and _msize() for windows.
-  virtual size_t GetAllocatedSize(const void* p);
-
-  // Returns kOwned if this malloc implementation allocated the memory
-  // pointed to by p, or kNotOwned if some other malloc implementation
-  // allocated it or p is NULL.  May also return kUnknownOwnership if
-  // the malloc implementation does not keep track of ownership.
-  // REQUIRES: p must be a value returned from a previous call to
-  // malloc(), calloc(), realloc(), memalign(), posix_memalign(),
-  // valloc(), pvalloc(), new, or new[], and must refer to memory that
-  // is currently allocated (so, for instance, you should not pass in
-  // a pointer after having called free() on it).
-  enum Ownership {
-    // NOTE: Enum values MUST be kept in sync with the version in
-    // malloc_extension_c.h
-    kUnknownOwnership = 0,
-    kOwned,
-    kNotOwned
-  };
-  virtual Ownership GetOwnership(const void* p);
-
-  // The current malloc implementation.  Always non-NULL.
-  static MallocExtension* instance();
-
-  // Change the malloc implementation.  Typically called by the
-  // malloc implementation during initialization.
-  static void Register(MallocExtension* implementation);
-
-  // Returns detailed information about malloc's freelists. For each list,
-  // return a FreeListInfo:
-  struct FreeListInfo {
-    size_t min_object_size;
-    size_t max_object_size;
-    size_t total_bytes_free;
-    const char* type;
-  };
-  // Each item in the vector refers to a different freelist. The lists
-  // are identified by the range of allocations that objects in the
-  // list can satisfy ([min_object_size, max_object_size]) and the
-  // type of freelist (see below). The current size of the list is
-  // returned in total_bytes_free (which count against a processes
-  // resident and virtual size).
-  //
-  // Currently supported types are:
-  //
-  // "tcmalloc.page{_unmapped}" - tcmalloc's page heap. An entry for each size
-  //          class in the page heap is returned. Bytes in "page_unmapped"
-  //          are no longer backed by physical memory and do not count against
-  //          the resident size of a process.
-  //
-  // "tcmalloc.large{_unmapped}" - tcmalloc's list of objects larger
-  //          than the largest page heap size class. Only one "large"
-  //          entry is returned. There is no upper-bound on the size
-  //          of objects in the large free list; this call returns
-  //          kint64max for max_object_size.  Bytes in
-  //          "large_unmapped" are no longer backed by physical memory
-  //          and do not count against the resident size of a process.
-  //
-  // "tcmalloc.central" - tcmalloc's central free-list. One entry per
-  //          size-class is returned. Never unmapped.
-  //
-  // "debug.free_queue" - free objects queued by the debug allocator
-  //                      and not returned to tcmalloc.
-  //
-  // "tcmalloc.thread" - tcmalloc's per-thread caches. Never unmapped.
-  virtual void GetFreeListSizes(std::vector<FreeListInfo>* v);
-
-  // Get a list of stack traces of sampled allocation points.  Returns
-  // a pointer to a "new[]-ed" result array, and stores the sample
-  // period in "sample_period".
-  //
-  // The state is stored as a sequence of adjacent entries
-  // in the returned array.  Each entry has the following form:
-  //    uintptr_t count;        // Number of objects with following trace
-  //    uintptr_t size;         // Total size of objects with following trace
-  //    uintptr_t depth;        // Number of PC values in stack trace
-  //    void*     stack[depth]; // PC values that form the stack trace
-  //
-  // The list of entries is terminated by a "count" of 0.
-  //
-  // It is the responsibility of the caller to "delete[]" the returned array.
-  //
-  // May return NULL to indicate no results.
-  //
-  // This is an internal extension.  Callers should use the more
-  // convenient "GetHeapSample(string*)" method defined above.
-  virtual void** ReadStackTraces(int* sample_period);
-
-  // Like ReadStackTraces(), but returns stack traces that caused growth
-  // in the address space size.
-  virtual void** ReadHeapGrowthStackTraces();
-
-  // Returns the size in bytes of the calling threads cache.
-  virtual size_t GetThreadCacheSize();
-
-  // Like MarkThreadIdle, but does not destroy the internal data
-  // structures of the thread cache. When the thread resumes, it wil
-  // have an empty cache but will not need to pay to reconstruct the
-  // cache data structures.
-  virtual void MarkThreadTemporarilyIdle();
-};
-
-namespace base {
-
-// Information passed per range.  More fields may be added later.
-struct MallocRange {
-  enum Type {
-    INUSE,                // Application is using this range
-    FREE,                 // Range is currently free
-    UNMAPPED,             // Backing physical memory has been returned to the OS
-    UNKNOWN
-    // More enum values may be added in the future
-  };
-
-  uintptr_t address;    // Address of range
-  size_t length;        // Byte length of range
-  Type type;            // Type of this range
-  double fraction;      // Fraction of range that is being used (0 if !INUSE)
-
-  // Perhaps add the following:
-  // - stack trace if this range was sampled
-  // - heap growth stack trace if applicable to this range
-  // - age when allocated (for inuse) or freed (if not in use)
-};
-
-} // namespace base
-
-#endif  // BASE_MALLOC_EXTENSION_H_
diff --git a/third_party/tcmalloc/vendor/src/gperftools/malloc_extension_c.h b/third_party/tcmalloc/vendor/src/gperftools/malloc_extension_c.h
deleted file mode 100644
index 70ff686..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/malloc_extension_c.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * --
- * Author: Craig Silverstein
- *
- * C shims for the C++ malloc_extension.h.  See malloc_extension.h for
- * details.  Note these C shims always work on
- * MallocExtension::instance(); it is not possible to have more than
- * one MallocExtension object in C applications.
- */
-
-#ifndef _MALLOC_EXTENSION_C_H_
-#define _MALLOC_EXTENSION_C_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-
-/* Annoying stuff for windows -- makes sure clients can import these fns */
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define kMallocExtensionHistogramSize 64
-
-PERFTOOLS_DLL_DECL int MallocExtension_VerifyAllMemory(void);
-PERFTOOLS_DLL_DECL int MallocExtension_VerifyNewMemory(const void* p);
-PERFTOOLS_DLL_DECL int MallocExtension_VerifyArrayNewMemory(const void* p);
-PERFTOOLS_DLL_DECL int MallocExtension_VerifyMallocMemory(const void* p);
-PERFTOOLS_DLL_DECL int MallocExtension_MallocMemoryStats(int* blocks, size_t* total,
-                                      int histogram[kMallocExtensionHistogramSize]);
-PERFTOOLS_DLL_DECL void MallocExtension_GetStats(char* buffer, int buffer_length);
-
-/* TODO(csilvers): write a C version of these routines, that perhaps
- * takes a function ptr and a void *.
- */
-/* void MallocExtension_GetHeapSample(string* result); */
-/* void MallocExtension_GetHeapGrowthStacks(string* result); */
-
-PERFTOOLS_DLL_DECL int MallocExtension_GetNumericProperty(const char* property, size_t* value);
-PERFTOOLS_DLL_DECL int MallocExtension_SetNumericProperty(const char* property, size_t value);
-PERFTOOLS_DLL_DECL void MallocExtension_MarkThreadIdle(void);
-PERFTOOLS_DLL_DECL void MallocExtension_MarkThreadBusy(void);
-PERFTOOLS_DLL_DECL void MallocExtension_ReleaseToSystem(size_t num_bytes);
-PERFTOOLS_DLL_DECL void MallocExtension_ReleaseFreeMemory(void);
-PERFTOOLS_DLL_DECL size_t MallocExtension_GetEstimatedAllocatedSize(size_t size);
-PERFTOOLS_DLL_DECL size_t MallocExtension_GetAllocatedSize(const void* p);
-PERFTOOLS_DLL_DECL size_t MallocExtension_GetThreadCacheSize(void);
-PERFTOOLS_DLL_DECL void MallocExtension_MarkThreadTemporarilyIdle(void);
-
-/*
- * NOTE: These enum values MUST be kept in sync with the version in
- *       malloc_extension.h
- */
-typedef enum {
-  MallocExtension_kUnknownOwnership = 0,
-  MallocExtension_kOwned,
-  MallocExtension_kNotOwned
-} MallocExtension_Ownership;
-
-PERFTOOLS_DLL_DECL MallocExtension_Ownership MallocExtension_GetOwnership(const void* p);
-
-#ifdef __cplusplus
-}   /* extern "C" */
-#endif
-
-#endif /* _MALLOC_EXTENSION_C_H_ */
diff --git a/third_party/tcmalloc/vendor/src/gperftools/malloc_hook.h b/third_party/tcmalloc/vendor/src/gperftools/malloc_hook.h
deleted file mode 100644
index b76411f..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/malloc_hook.h
+++ /dev/null
@@ -1,359 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Some of our malloc implementations can invoke the following hooks whenever
-// memory is allocated or deallocated.  MallocHook is thread-safe, and things
-// you do before calling AddFooHook(MyHook) are visible to any resulting calls
-// to MyHook.  Hooks must be thread-safe.  If you write:
-//
-//   CHECK(MallocHook::AddNewHook(&MyNewHook));
-//
-// MyNewHook will be invoked in subsequent calls in the current thread, but
-// there are no guarantees on when it might be invoked in other threads.
-//
-// There are a limited number of slots available for each hook type.  Add*Hook
-// will return false if there are no slots available.  Remove*Hook will return
-// false if the given hook was not already installed.
-//
-// The order in which individual hooks are called in Invoke*Hook is undefined.
-//
-// It is safe for a hook to remove itself within Invoke*Hook and add other
-// hooks.  Any hooks added inside a hook invocation (for the same hook type)
-// will not be invoked for the current invocation.
-//
-// One important user of these hooks is the heap profiler.
-//
-// CAVEAT: If you add new MallocHook::Invoke* calls then those calls must be
-// directly in the code of the (de)allocation function that is provided to the
-// user and that function must have an ATTRIBUTE_SECTION(malloc_hook) attribute.
-//
-// Note: the Invoke*Hook() functions are defined in malloc_hook-inl.h.  If you
-// need to invoke a hook (which you shouldn't unless you're part of tcmalloc),
-// be sure to #include malloc_hook-inl.h in addition to malloc_hook.h.
-//
-// NOTE FOR C USERS: If you want to use malloc_hook functionality from
-// a C program, #include malloc_hook_c.h instead of this file.
-
-#ifndef _MALLOC_HOOK_H_
-#define _MALLOC_HOOK_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-extern "C" {
-#include "malloc_hook_c.h"  // a C version of the malloc_hook interface
-}
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-// The C++ methods below call the C version (MallocHook_*), and thus
-// convert between an int and a bool.  Windows complains about this
-// (a "performance warning") which we don't care about, so we suppress.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4800)
-#endif
-
-// Note: malloc_hook_c.h defines MallocHook_*Hook and
-// MallocHook_{Add,Remove}*Hook.  The version of these inside the MallocHook
-// class are defined in terms of the malloc_hook_c version.  See malloc_hook_c.h
-// for details of these types/functions.
-
-class PERFTOOLS_DLL_DECL MallocHook {
- public:
-  // The NewHook is invoked whenever an object is allocated.
-  // It may be passed NULL if the allocator returned NULL.
-  typedef MallocHook_NewHook NewHook;
-  inline static bool AddNewHook(NewHook hook) {
-    return MallocHook_AddNewHook(hook);
-  }
-  inline static bool RemoveNewHook(NewHook hook) {
-    return MallocHook_RemoveNewHook(hook);
-  }
-  inline static void InvokeNewHook(const void* p, size_t s);
-
-  // The DeleteHook is invoked whenever an object is deallocated.
-  // It may be passed NULL if the caller is trying to delete NULL.
-  typedef MallocHook_DeleteHook DeleteHook;
-  inline static bool AddDeleteHook(DeleteHook hook) {
-    return MallocHook_AddDeleteHook(hook);
-  }
-  inline static bool RemoveDeleteHook(DeleteHook hook) {
-    return MallocHook_RemoveDeleteHook(hook);
-  }
-  inline static void InvokeDeleteHook(const void* p);
-
-  // The PreMmapHook is invoked with mmap or mmap64 arguments just
-  // before the call is actually made.  Such a hook may be useful
-  // in memory limited contexts, to catch allocations that will exceed
-  // a memory limit, and take outside actions to increase that limit.
-  typedef MallocHook_PreMmapHook PreMmapHook;
-  inline static bool AddPreMmapHook(PreMmapHook hook) {
-    return MallocHook_AddPreMmapHook(hook);
-  }
-  inline static bool RemovePreMmapHook(PreMmapHook hook) {
-    return MallocHook_RemovePreMmapHook(hook);
-  }
-  inline static void InvokePreMmapHook(const void* start,
-                                       size_t size,
-                                       int protection,
-                                       int flags,
-                                       int fd,
-                                       off_t offset);
-
-  // The MmapReplacement is invoked after the PreMmapHook but before
-  // the call is actually made. The MmapReplacement should return true
-  // if it handled the call, or false if it is still necessary to
-  // call mmap/mmap64.
-  // This should be used only by experts, and users must be be
-  // extremely careful to avoid recursive calls to mmap. The replacement
-  // should be async signal safe.
-  // Only one MmapReplacement is supported. After setting an MmapReplacement
-  // you must call RemoveMmapReplacement before calling SetMmapReplacement
-  // again.
-  typedef MallocHook_MmapReplacement MmapReplacement;
-  inline static bool SetMmapReplacement(MmapReplacement hook) {
-    return MallocHook_SetMmapReplacement(hook);
-  }
-  inline static bool RemoveMmapReplacement(MmapReplacement hook) {
-    return MallocHook_RemoveMmapReplacement(hook);
-  }
-  inline static bool InvokeMmapReplacement(const void* start,
-                                           size_t size,
-                                           int protection,
-                                           int flags,
-                                           int fd,
-                                           off_t offset,
-                                           void** result);
-
-
-  // The MmapHook is invoked whenever a region of memory is mapped.
-  // It may be passed MAP_FAILED if the mmap failed.
-  typedef MallocHook_MmapHook MmapHook;
-  inline static bool AddMmapHook(MmapHook hook) {
-    return MallocHook_AddMmapHook(hook);
-  }
-  inline static bool RemoveMmapHook(MmapHook hook) {
-    return MallocHook_RemoveMmapHook(hook);
-  }
-  inline static void InvokeMmapHook(const void* result,
-                                    const void* start,
-                                    size_t size,
-                                    int protection,
-                                    int flags,
-                                    int fd,
-                                    off_t offset);
-
-  // The MunmapReplacement is invoked with munmap arguments just before
-  // the call is actually made. The MunmapReplacement should return true
-  // if it handled the call, or false if it is still necessary to
-  // call munmap.
-  // This should be used only by experts. The replacement should be
-  // async signal safe.
-  // Only one MunmapReplacement is supported. After setting an
-  // MunmapReplacement you must call RemoveMunmapReplacement before
-  // calling SetMunmapReplacement again.
-  typedef MallocHook_MunmapReplacement MunmapReplacement;
-  inline static bool SetMunmapReplacement(MunmapReplacement hook) {
-    return MallocHook_SetMunmapReplacement(hook);
-  }
-  inline static bool RemoveMunmapReplacement(MunmapReplacement hook) {
-    return MallocHook_RemoveMunmapReplacement(hook);
-  }
-  inline static bool InvokeMunmapReplacement(const void* p,
-                                             size_t size,
-                                             int* result);
-
-  // The MunmapHook is invoked whenever a region of memory is unmapped.
-  typedef MallocHook_MunmapHook MunmapHook;
-  inline static bool AddMunmapHook(MunmapHook hook) {
-    return MallocHook_AddMunmapHook(hook);
-  }
-  inline static bool RemoveMunmapHook(MunmapHook hook) {
-    return MallocHook_RemoveMunmapHook(hook);
-  }
-  inline static void InvokeMunmapHook(const void* p, size_t size);
-
-  // The MremapHook is invoked whenever a region of memory is remapped.
-  typedef MallocHook_MremapHook MremapHook;
-  inline static bool AddMremapHook(MremapHook hook) {
-    return MallocHook_AddMremapHook(hook);
-  }
-  inline static bool RemoveMremapHook(MremapHook hook) {
-    return MallocHook_RemoveMremapHook(hook);
-  }
-  inline static void InvokeMremapHook(const void* result,
-                                      const void* old_addr,
-                                      size_t old_size,
-                                      size_t new_size,
-                                      int flags,
-                                      const void* new_addr);
-
-  // The PreSbrkHook is invoked just before sbrk is called -- except when
-  // the increment is 0.  This is because sbrk(0) is often called
-  // to get the top of the memory stack, and is not actually a
-  // memory-allocation call.  It may be useful in memory-limited contexts,
-  // to catch allocations that will exceed the limit and take outside
-  // actions to increase such a limit.
-  typedef MallocHook_PreSbrkHook PreSbrkHook;
-  inline static bool AddPreSbrkHook(PreSbrkHook hook) {
-    return MallocHook_AddPreSbrkHook(hook);
-  }
-  inline static bool RemovePreSbrkHook(PreSbrkHook hook) {
-    return MallocHook_RemovePreSbrkHook(hook);
-  }
-  inline static void InvokePreSbrkHook(ptrdiff_t increment);
-
-  // The SbrkHook is invoked whenever sbrk is called -- except when
-  // the increment is 0.  This is because sbrk(0) is often called
-  // to get the top of the memory stack, and is not actually a
-  // memory-allocation call.
-  typedef MallocHook_SbrkHook SbrkHook;
-  inline static bool AddSbrkHook(SbrkHook hook) {
-    return MallocHook_AddSbrkHook(hook);
-  }
-  inline static bool RemoveSbrkHook(SbrkHook hook) {
-    return MallocHook_RemoveSbrkHook(hook);
-  }
-  inline static void InvokeSbrkHook(const void* result, ptrdiff_t increment);
-
-  // Get the current stack trace.  Try to skip all routines up to and
-  // and including the caller of MallocHook::Invoke*.
-  // Use "skip_count" (similarly to GetStackTrace from stacktrace.h)
-  // as a hint about how many routines to skip if better information
-  // is not available.
-  inline static int GetCallerStackTrace(void** result, int max_depth,
-                                        int skip_count) {
-    return MallocHook_GetCallerStackTrace(result, max_depth, skip_count);
-  }
-
-  // Unhooked versions of mmap() and munmap().   These should be used
-  // only by experts, since they bypass heapchecking, etc.
-  // Note: These do not run hooks, but they still use the MmapReplacement
-  // and MunmapReplacement.
-  static void* UnhookedMMap(void *start, size_t length, int prot, int flags,
-                            int fd, off_t offset);
-  static int UnhookedMUnmap(void *start, size_t length);
-
-  // The following are DEPRECATED.
-  inline static NewHook GetNewHook();
-  inline static NewHook SetNewHook(NewHook hook) {
-    return MallocHook_SetNewHook(hook);
-  }
-
-  inline static DeleteHook GetDeleteHook();
-  inline static DeleteHook SetDeleteHook(DeleteHook hook) {
-    return MallocHook_SetDeleteHook(hook);
-  }
-
-  inline static PreMmapHook GetPreMmapHook();
-  inline static PreMmapHook SetPreMmapHook(PreMmapHook hook) {
-    return MallocHook_SetPreMmapHook(hook);
-  }
-
-  inline static MmapHook GetMmapHook();
-  inline static MmapHook SetMmapHook(MmapHook hook) {
-    return MallocHook_SetMmapHook(hook);
-  }
-
-  inline static MunmapHook GetMunmapHook();
-  inline static MunmapHook SetMunmapHook(MunmapHook hook) {
-    return MallocHook_SetMunmapHook(hook);
-  }
-
-  inline static MremapHook GetMremapHook();
-  inline static MremapHook SetMremapHook(MremapHook hook) {
-    return MallocHook_SetMremapHook(hook);
-  }
-
-  inline static PreSbrkHook GetPreSbrkHook();
-  inline static PreSbrkHook SetPreSbrkHook(PreSbrkHook hook) {
-    return MallocHook_SetPreSbrkHook(hook);
-  }
-
-  inline static SbrkHook GetSbrkHook();
-  inline static SbrkHook SetSbrkHook(SbrkHook hook) {
-    return MallocHook_SetSbrkHook(hook);
-  }
-  // End of DEPRECATED methods.
-
- private:
-  // Slow path versions of Invoke*Hook.
-  static void InvokeNewHookSlow(const void* p, size_t s);
-  static void InvokeDeleteHookSlow(const void* p);
-  static void InvokePreMmapHookSlow(const void* start,
-                                    size_t size,
-                                    int protection,
-                                    int flags,
-                                    int fd,
-                                    off_t offset);
-  static void InvokeMmapHookSlow(const void* result,
-                                 const void* start,
-                                 size_t size,
-                                 int protection,
-                                 int flags,
-                                 int fd,
-                                 off_t offset);
-  static bool InvokeMmapReplacementSlow(const void* start,
-                                        size_t size,
-                                        int protection,
-                                        int flags,
-                                        int fd,
-                                        off_t offset,
-                                        void** result);
-  static void InvokeMunmapHookSlow(const void* p, size_t size);
-  static bool InvokeMunmapReplacementSlow(const void* p,
-                                          size_t size,
-                                          int* result);
-  static void InvokeMremapHookSlow(const void* result,
-                                   const void* old_addr,
-                                   size_t old_size,
-                                   size_t new_size,
-                                   int flags,
-                                   const void* new_addr);
-  static void InvokePreSbrkHookSlow(ptrdiff_t increment);
-  static void InvokeSbrkHookSlow(const void* result, ptrdiff_t increment);
-};
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-
-#endif /* _MALLOC_HOOK_H_ */
diff --git a/third_party/tcmalloc/vendor/src/gperftools/malloc_hook_c.h b/third_party/tcmalloc/vendor/src/gperftools/malloc_hook_c.h
deleted file mode 100644
index 56337e15..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/malloc_hook_c.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * --
- * Author: Craig Silverstein
- *
- * C shims for the C++ malloc_hook.h.  See malloc_hook.h for details
- * on how to use these.
- */
-
-#ifndef _MALLOC_HOOK_C_H_
-#define _MALLOC_HOOK_C_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-
-/* Annoying stuff for windows; makes sure clients can import these functions */
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Get the current stack trace.  Try to skip all routines up to and
- * and including the caller of MallocHook::Invoke*.
- * Use "skip_count" (similarly to GetStackTrace from stacktrace.h)
- * as a hint about how many routines to skip if better information
- * is not available.
- */
-PERFTOOLS_DLL_DECL
-int MallocHook_GetCallerStackTrace(void** result, int max_depth,
-                                   int skip_count);
-
-/* The MallocHook_{Add,Remove}*Hook functions return 1 on success and 0 on
- * failure.
- */
-
-typedef void (*MallocHook_NewHook)(const void* ptr, size_t size);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddNewHook(MallocHook_NewHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveNewHook(MallocHook_NewHook hook);
-
-typedef void (*MallocHook_DeleteHook)(const void* ptr);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddDeleteHook(MallocHook_DeleteHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveDeleteHook(MallocHook_DeleteHook hook);
-
-typedef void (*MallocHook_PreMmapHook)(const void *start,
-                                       size_t size,
-                                       int protection,
-                                       int flags,
-                                       int fd,
-                                       off_t offset);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddPreMmapHook(MallocHook_PreMmapHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemovePreMmapHook(MallocHook_PreMmapHook hook);
-
-typedef void (*MallocHook_MmapHook)(const void* result,
-                                    const void* start,
-                                    size_t size,
-                                    int protection,
-                                    int flags,
-                                    int fd,
-                                    off_t offset);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddMmapHook(MallocHook_MmapHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveMmapHook(MallocHook_MmapHook hook);
-
-typedef int (*MallocHook_MmapReplacement)(const void* start,
-                                          size_t size,
-                                          int protection,
-                                          int flags,
-                                          int fd,
-                                          off_t offset,
-                                          void** result);
-int MallocHook_SetMmapReplacement(MallocHook_MmapReplacement hook);
-int MallocHook_RemoveMmapReplacement(MallocHook_MmapReplacement hook);
-
-typedef void (*MallocHook_MunmapHook)(const void* ptr, size_t size);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddMunmapHook(MallocHook_MunmapHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveMunmapHook(MallocHook_MunmapHook hook);
-
-typedef int (*MallocHook_MunmapReplacement)(const void* ptr,
-                                            size_t size,
-                                            int* result);
-int MallocHook_SetMunmapReplacement(MallocHook_MunmapReplacement hook);
-int MallocHook_RemoveMunmapReplacement(MallocHook_MunmapReplacement hook);
-
-typedef void (*MallocHook_MremapHook)(const void* result,
-                                      const void* old_addr,
-                                      size_t old_size,
-                                      size_t new_size,
-                                      int flags,
-                                      const void* new_addr);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddMremapHook(MallocHook_MremapHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveMremapHook(MallocHook_MremapHook hook);
-
-typedef void (*MallocHook_PreSbrkHook)(ptrdiff_t increment);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddPreSbrkHook(MallocHook_PreSbrkHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemovePreSbrkHook(MallocHook_PreSbrkHook hook);
-
-typedef void (*MallocHook_SbrkHook)(const void* result, ptrdiff_t increment);
-PERFTOOLS_DLL_DECL
-int MallocHook_AddSbrkHook(MallocHook_SbrkHook hook);
-PERFTOOLS_DLL_DECL
-int MallocHook_RemoveSbrkHook(MallocHook_SbrkHook hook);
-
-/* The following are DEPRECATED. */
-PERFTOOLS_DLL_DECL
-MallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_PreMmapHook MallocHook_SetPreMmapHook(MallocHook_PreMmapHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_MmapHook MallocHook_SetMmapHook(MallocHook_MmapHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_MunmapHook MallocHook_SetMunmapHook(MallocHook_MunmapHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_MremapHook MallocHook_SetMremapHook(MallocHook_MremapHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_PreSbrkHook MallocHook_SetPreSbrkHook(MallocHook_PreSbrkHook hook);
-PERFTOOLS_DLL_DECL
-MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook);
-/* End of DEPRECATED functions. */
-
-#ifdef __cplusplus
-}   // extern "C"
-#endif
-
-#endif /* _MALLOC_HOOK_C_H_ */
diff --git a/third_party/tcmalloc/vendor/src/gperftools/nallocx.h b/third_party/tcmalloc/vendor/src/gperftools/nallocx.h
deleted file mode 100644
index 01f874ca..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/nallocx.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _NALLOCX_H_
-#define _NALLOCX_H_
-#include <stddef.h>
-
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#  define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#  define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MALLOCX_LG_ALIGN(la) ((int)(la))
-
-/*
- * The nallocx function allocates no memory, but it performs the same size
- * computation as the malloc function, and returns the real size of the
- * allocation that would result from the equivalent malloc function call.
- * nallocx is a malloc extension originally implemented by jemalloc:
- * http://www.unix.com/man-page/freebsd/3/nallocx/
- *
- * Note, we only support MALLOCX_LG_ALIGN flag and nothing else.
- */
-PERFTOOLS_DLL_DECL size_t nallocx(size_t size, int flags);
-
-/* same as above but never weak */
-PERFTOOLS_DLL_DECL size_t tc_nallocx(size_t size, int flags);
-
-#ifdef __cplusplus
-}   /* extern "C" */
-#endif
-
-#endif /* _NALLOCX_H_ */
diff --git a/third_party/tcmalloc/vendor/src/gperftools/profiler.h b/third_party/tcmalloc/vendor/src/gperftools/profiler.h
deleted file mode 100644
index 1e7eb12..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/profiler.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2005, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- *
- * Module for CPU profiling based on periodic pc-sampling.
- *
- * For full(er) information, see docs/cpuprofile.html
- *
- * This module is linked into your program with
- * no slowdown caused by this unless you activate the profiler
- * using one of the following methods:
- *
- *    1. Before starting the program, set the environment variable
- *       "CPUPROFILE" to be the name of the file to which the profile
- *       data should be written.
- *
- *    2. Programmatically, start and stop the profiler using the
- *       routines "ProfilerStart(filename)" and "ProfilerStop()".
- *
- *
- * (Note: if using linux 2.4 or earlier, only the main thread may be
- * profiled.)
- *
- * Use pprof to view the resulting profile output.
- *    % pprof <path_to_executable> <profile_file_name>
- *    % pprof --gv  <path_to_executable> <profile_file_name>
- *
- * These functions are thread-safe.
- */
-
-#ifndef BASE_PROFILER_H_
-#define BASE_PROFILER_H_
-
-#include <time.h>       /* For time_t */
-
-/* Annoying stuff for windows; makes sure clients can import these functions */
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-/* All this code should be usable from within C apps. */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Profiler options, for use with ProfilerStartWithOptions.  To use:
- *
- *   struct ProfilerOptions options;
- *   memset(&options, 0, sizeof options);
- *
- * then fill in fields as needed.
- *
- * This structure is intended to be usable from C code, so no constructor
- * is provided to initialize it.  (Use memset as described above).
- */
-struct ProfilerOptions {
-  /* Filter function and argument.
-   *
-   * If filter_in_thread is not NULL, when a profiling tick is delivered
-   * the profiler will call:
-   *
-   *   (*filter_in_thread)(filter_in_thread_arg)
-   *
-   * If it returns nonzero, the sample will be included in the profile.
-   * Note that filter_in_thread runs in a signal handler, so must be
-   * async-signal-safe.
-   *
-   * A typical use would be to set up filter results for each thread
-   * in the system before starting the profiler, then to make
-   * filter_in_thread be a very simple function which retrieves those
-   * results in an async-signal-safe way.  Retrieval could be done
-   * using thread-specific data, or using a shared data structure that
-   * supports async-signal-safe lookups.
-   */
-  int (*filter_in_thread)(void *arg);
-  void *filter_in_thread_arg;
-};
-
-/* Start profiling and write profile info into fname, discarding any
- * existing profiling data in that file.
- *
- * This is equivalent to calling ProfilerStartWithOptions(fname, NULL).
- */
-PERFTOOLS_DLL_DECL int ProfilerStart(const char* fname);
-
-/* Start profiling and write profile into fname, discarding any
- * existing profiling data in that file.
- *
- * The profiler is configured using the options given by 'options'.
- * Options which are not specified are given default values.
- *
- * 'options' may be NULL, in which case all are given default values.
- *
- * Returns nonzero if profiling was started successfully, or zero else.
- */
-PERFTOOLS_DLL_DECL int ProfilerStartWithOptions(
-    const char *fname, const struct ProfilerOptions *options);
-
-/* Stop profiling. Can be started again with ProfilerStart(), but
- * the currently accumulated profiling data will be cleared.
- */
-PERFTOOLS_DLL_DECL void ProfilerStop(void);
-
-/* Flush any currently buffered profiling state to the profile file.
- * Has no effect if the profiler has not been started.
- */
-PERFTOOLS_DLL_DECL void ProfilerFlush(void);
-
-
-/* DEPRECATED: these functions were used to enable/disable profiling
- * in the current thread, but no longer do anything.
- */
-PERFTOOLS_DLL_DECL void ProfilerEnable(void);
-PERFTOOLS_DLL_DECL void ProfilerDisable(void);
-
-/* Returns nonzero if profile is currently enabled, zero if it's not. */
-PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads(void);
-
-/* Routine for registering new threads with the profiler.
- */
-PERFTOOLS_DLL_DECL void ProfilerRegisterThread(void);
-
-/* Stores state about profiler's current status into "*state". */
-struct ProfilerState {
-  int    enabled;             /* Is profiling currently enabled? */
-  time_t start_time;          /* If enabled, when was profiling started? */
-  char   profile_name[1024];  /* Name of profile file being written, or '\0' */
-  int    samples_gathered;    /* Number of samples gathered so far (or 0) */
-};
-PERFTOOLS_DLL_DECL void ProfilerGetCurrentState(struct ProfilerState* state);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  /* BASE_PROFILER_H_ */
diff --git a/third_party/tcmalloc/vendor/src/gperftools/stacktrace.h b/third_party/tcmalloc/vendor/src/gperftools/stacktrace.h
deleted file mode 100644
index 2b9c5a13..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/stacktrace.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Routines to extract the current stack trace.  These functions are
-// thread-safe.
-
-#ifndef GOOGLE_STACKTRACE_H_
-#define GOOGLE_STACKTRACE_H_
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-
-// Skips the most recent "skip_count" stack frames (also skips the
-// frame generated for the "GetStackFrames" routine itself), and then
-// records the pc values for up to the next "max_depth" frames in
-// "result", and the corresponding stack frame sizes in "sizes".
-// Returns the number of values recorded in "result"/"sizes".
-//
-// Example:
-//      main() { foo(); }
-//      foo() { bar(); }
-//      bar() {
-//        void* result[10];
-//        int sizes[10];
-//        int depth = GetStackFrames(result, sizes, 10, 1);
-//      }
-//
-// The GetStackFrames call will skip the frame for "bar".  It will
-// return 2 and will produce pc values that map to the following
-// procedures:
-//      result[0]       foo
-//      result[1]       main
-// (Actually, there may be a few more entries after "main" to account for
-// startup procedures.)
-// And corresponding stack frame sizes will also be recorded:
-//    sizes[0]       16
-//    sizes[1]       16
-// (Stack frame sizes of 16 above are just for illustration purposes.)
-// Stack frame sizes of 0 or less indicate that those frame sizes couldn't
-// be identified.
-//
-// This routine may return fewer stack frame entries than are
-// available. Also note that "result" and "sizes" must both be non-NULL.
-extern PERFTOOLS_DLL_DECL int GetStackFrames(void** result, int* sizes, int max_depth,
-                          int skip_count);
-
-// Same as above, but to be used from a signal handler. The "uc" parameter
-// should be the pointer to ucontext_t which was passed as the 3rd parameter
-// to sa_sigaction signal handler. It may help the unwinder to get a
-// better stack trace under certain conditions. The "uc" may safely be NULL.
-extern PERFTOOLS_DLL_DECL int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
-                                     int skip_count, const void *uc);
-
-// This is similar to the GetStackFrames routine, except that it returns
-// the stack trace only, and not the stack frame sizes as well.
-// Example:
-//      main() { foo(); }
-//      foo() { bar(); }
-//      bar() {
-//        void* result[10];
-//        int depth = GetStackTrace(result, 10, 1);
-//      }
-//
-// This produces:
-//      result[0]       foo
-//      result[1]       main
-//           ....       ...
-//
-// "result" must not be NULL.
-extern PERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,
-                                            int skip_count);
-
-// Same as above, but to be used from a signal handler. The "uc" parameter
-// should be the pointer to ucontext_t which was passed as the 3rd parameter
-// to sa_sigaction signal handler. It may help the unwinder to get a
-// better stack trace under certain conditions. The "uc" may safely be NULL.
-extern PERFTOOLS_DLL_DECL int GetStackTraceWithContext(void** result, int max_depth,
-                                    int skip_count, const void *uc);
-
-#endif /* GOOGLE_STACKTRACE_H_ */
diff --git a/third_party/tcmalloc/vendor/src/gperftools/tcmalloc.h.in b/third_party/tcmalloc/vendor/src/gperftools/tcmalloc.h.in
deleted file mode 100644
index 84ac8fa5..0000000
--- a/third_party/tcmalloc/vendor/src/gperftools/tcmalloc.h.in
+++ /dev/null
@@ -1,163 +0,0 @@
-// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat <opensource@google.com>
- *         .h file by Craig Silverstein <opensource@google.com>
- */
-
-#ifndef TCMALLOC_TCMALLOC_H_
-#define TCMALLOC_TCMALLOC_H_
-
-#include <stddef.h>                     /* for size_t */
-#ifdef __cplusplus
-#include <new>                          /* for std::nothrow_t, std::align_val_t */
-#endif
-
-/* Define the version number so folks can check against it */
-#define TC_VERSION_MAJOR  @TC_VERSION_MAJOR@
-#define TC_VERSION_MINOR  @TC_VERSION_MINOR@
-#define TC_VERSION_PATCH  "@TC_VERSION_PATCH@"
-#define TC_VERSION_STRING "gperftools @TC_VERSION_MAJOR@.@TC_VERSION_MINOR@@TC_VERSION_PATCH@"
-
-/* For struct mallinfo, if it's defined. */
-#if @ac_cv_have_struct_mallinfo@
-# include <malloc.h>
-#endif
-
-#ifndef PERFTOOLS_NOTHROW
-
-#if __cplusplus >= 201103L
-#define PERFTOOLS_NOTHROW noexcept
-#elif defined(__cplusplus)
-#define PERFTOOLS_NOTHROW throw()
-#else
-# ifdef __GNUC__
-#  define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
-# else
-#  define PERFTOOLS_NOTHROW
-# endif
-#endif
-
-#endif
-
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-  /*
-   * Returns a human-readable version string.  If major, minor,
-   * and/or patch are not NULL, they are set to the major version,
-   * minor version, and patch-code (a string, usually "").
-   */
-  PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
-                                            const char** patch) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
-                                       size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
-                                           size_t align, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
-#if @ac_cv_have_struct_mallinfo@
-  PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW;
-#endif
-
-  /*
-   * This is an alias for MallocExtension::instance()->GetAllocatedSize().
-   * It is equivalent to
-   *    OS X: malloc_size()
-   *    glibc: malloc_usable_size()
-   *    Windows: _msize()
-   */
-  PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
-
-#ifdef __cplusplus
-  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_new(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-
-#if @ac_cv_have_std_align_val_t@ && __cplusplus >= 201703L
-  PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t al,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t al,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t al,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-#endif
-}
-#endif
-
-/* We're only un-defining for public */
-#if !defined(GPERFTOOLS_CONFIG_H_)
-
-#undef PERFTOOLS_NOTHROW
-
-#endif /* GPERFTOOLS_CONFIG_H_ */
-
-#endif  /* #ifndef TCMALLOC_TCMALLOC_H_ */
diff --git a/third_party/tcmalloc/vendor/src/heap-checker-bcad.cc b/third_party/tcmalloc/vendor/src/heap-checker-bcad.cc
deleted file mode 100644
index 00efdb7..0000000
--- a/third_party/tcmalloc/vendor/src/heap-checker-bcad.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Maxim Lifantsev
-//
-// A file to ensure that components of heap leak checker run before
-// all global object constructors and after all global object
-// destructors.
-//
-// This file must be the last library any binary links against.
-// Otherwise, the heap checker may not be able to run early enough to
-// catalog all the global objects in your program.  If this happens,
-// and later in the program you allocate memory and have one of these
-// "uncataloged" global objects point to it, the heap checker will
-// consider that allocation to be a leak, even though it's not (since
-// the allocated object is reachable from global data and hence "live").
-
-#include <stdlib.h>      // for abort()
-#include <gperftools/malloc_extension.h>
-
-// A dummy variable to refer from heap-checker.cc.  This is to make
-// sure this file is not optimized out by the linker.
-bool heap_leak_checker_bcad_variable;
-
-extern void HeapLeakChecker_AfterDestructors();  // in heap-checker.cc
-
-// A helper class to ensure that some components of heap leak checking
-// can happen before construction and after destruction
-// of all global/static objects.
-class HeapLeakCheckerGlobalPrePost {
- public:
-  HeapLeakCheckerGlobalPrePost() {
-    if (count_ == 0) {
-      // The 'new int' will ensure that we have run an initial malloc
-      // hook, which will set up the heap checker via
-      // MallocHook_InitAtFirstAllocation_HeapLeakChecker.  See malloc_hook.cc.
-      // This is done in this roundabout fashion in order to avoid self-deadlock
-      // if we directly called HeapLeakChecker_BeforeConstructors here.
-      delete new int;
-      // This needs to be called before the first allocation of an STL
-      // object, but after libc is done setting up threads (because it
-      // calls setenv, which requires a thread-aware errno).  By
-      // putting it here, we hope it's the first bit of code executed
-      // after the libc global-constructor code.
-      MallocExtension::Initialize();
-    }
-    ++count_;
-  }
-  ~HeapLeakCheckerGlobalPrePost() {
-    if (count_ <= 0)  abort();
-    --count_;
-    if (count_ == 0)  HeapLeakChecker_AfterDestructors();
-  }
- private:
-  // Counter of constructions/destructions of objects of this class
-  // (just in case there are more than one of them).
-  static int count_;
-};
-
-int HeapLeakCheckerGlobalPrePost::count_ = 0;
-
-// The early-construction/late-destruction global object.
-static const HeapLeakCheckerGlobalPrePost heap_leak_checker_global_pre_post;
diff --git a/third_party/tcmalloc/vendor/src/heap-checker.cc b/third_party/tcmalloc/vendor/src/heap-checker.cc
deleted file mode 100755
index 8e71f582..0000000
--- a/third_party/tcmalloc/vendor/src/heap-checker.cc
+++ /dev/null
@@ -1,2388 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Maxim Lifantsev
-//
-
-#include "config.h"
-
-#include <fcntl.h>    // for O_RDONLY (we use syscall to do actual reads)
-#include <string.h>
-#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#ifdef HAVE_PTHREAD
-#include <pthread.h>
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <assert.h>
-
-#if defined(HAVE_LINUX_PTRACE_H)
-#include <linux/ptrace.h>
-#endif
-#ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#endif
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
-#include <wtypes.h>
-#include <winbase.h>
-#undef ERROR     // windows defines these as macros, which can cause trouble
-#undef max
-#undef min
-#endif
-
-#include <string>
-#include <vector>
-#include <map>
-#include <set>
-#include <algorithm>
-#include <functional>
-
-#include <gperftools/heap-checker.h>
-
-#include "base/basictypes.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include <gperftools/stacktrace.h>
-#include "base/commandlineflags.h"
-#include "base/elfcore.h"              // for i386_regs
-#include "base/thread_lister.h"
-#include "heap-profile-table.h"
-#include "base/low_level_alloc.h"
-#include "malloc_hook-inl.h"
-#include <gperftools/malloc_hook.h>
-#include <gperftools/malloc_extension.h>
-#include "maybe_threads.h"
-#include "memory_region_map.h"
-#include "base/spinlock.h"
-#include "base/sysinfo.h"
-#include "base/stl_allocator.h"
-
-using std::string;
-using std::basic_string;
-using std::pair;
-using std::map;
-using std::set;
-using std::vector;
-using std::swap;
-using std::make_pair;
-using std::min;
-using std::max;
-using std::less;
-using std::char_traits;
-
-// If current process is being ptrace()d, 'TracerPid' in /proc/self/status
-// will be non-zero.
-static bool IsDebuggerAttached(void) {    // only works under linux, probably
-  char buf[256];   // TracerPid comes relatively earlier in status output
-  int fd = open("/proc/self/status", O_RDONLY);
-  if (fd == -1) {
-    return false;  // Can't tell for sure.
-  }
-  const int len = read(fd, buf, sizeof(buf));
-  bool rc = false;
-  if (len > 0) {
-    const char *const kTracerPid = "TracerPid:\t";
-    buf[len - 1] = '\0';
-    const char *p = strstr(buf, kTracerPid);
-    if (p != NULL) {
-      rc = (strncmp(p + strlen(kTracerPid), "0\n", 2) != 0);
-    }
-  }
-  close(fd);
-  return rc;
-}
-
-// This is the default if you don't link in -lprofiler
-extern "C" {
-ATTRIBUTE_WEAK PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads();
-int ProfilingIsEnabledForAllThreads() { return false; }
-}
-
-//----------------------------------------------------------------------
-// Flags that control heap-checking
-//----------------------------------------------------------------------
-
-DEFINE_string(heap_check,
-              EnvToString("HEAPCHECK", ""),
-              "The heap leak checking to be done over the whole executable: "
-              "\"minimal\", \"normal\", \"strict\", "
-              "\"draconian\", \"as-is\", and \"local\" "
-              " or the empty string are the supported choices. "
-              "(See HeapLeakChecker_InternalInitStart for details.)");
-
-DEFINE_bool(heap_check_report, true, "Obsolete");
-
-DEFINE_bool(heap_check_before_constructors,
-            true,
-            "deprecated; pretty much always true now");
-
-DEFINE_bool(heap_check_after_destructors,
-            EnvToBool("HEAP_CHECK_AFTER_DESTRUCTORS", false),
-            "If overall heap check is to end after global destructors "
-            "or right after all REGISTER_HEAPCHECK_CLEANUP's");
-
-DEFINE_bool(heap_check_strict_check, true, "Obsolete");
-
-DEFINE_bool(heap_check_ignore_global_live,
-            EnvToBool("HEAP_CHECK_IGNORE_GLOBAL_LIVE", true),
-            "If overall heap check is to ignore heap objects reachable "
-            "from the global data");
-
-DEFINE_bool(heap_check_identify_leaks,
-            EnvToBool("HEAP_CHECK_IDENTIFY_LEAKS", false),
-            "If heap check should generate the addresses of the leaked "
-            "objects in the memory leak profiles.  This may be useful "
-            "in tracking down leaks where only a small fraction of "
-            "objects allocated at the same stack trace are leaked.");
-
-DEFINE_bool(heap_check_ignore_thread_live,
-            EnvToBool("HEAP_CHECK_IGNORE_THREAD_LIVE", true),
-            "If set to true, objects reachable from thread stacks "
-            "and registers are not reported as leaks");
-
-DEFINE_bool(heap_check_test_pointer_alignment,
-            EnvToBool("HEAP_CHECK_TEST_POINTER_ALIGNMENT", false),
-            "Set to true to check if the found leak can be due to "
-            "use of unaligned pointers");
-
-// Alignment at which all pointers in memory are supposed to be located;
-// use 1 if any alignment is ok.
-// heap_check_test_pointer_alignment flag guides if we try the value of 1.
-// The larger it can be, the lesser is the chance of missing real leaks.
-static const size_t kPointerSourceAlignment = sizeof(void*);
-DEFINE_int32(heap_check_pointer_source_alignment,
-	     EnvToInt("HEAP_CHECK_POINTER_SOURCE_ALIGNMENT",
-                      kPointerSourceAlignment),
-             "Alignment at which all pointers in memory are supposed to be "
-             "located.  Use 1 if any alignment is ok.");
-
-// A reasonable default to handle pointers inside of typical class objects:
-// Too low and we won't be able to traverse pointers to normally-used
-// nested objects and base parts of multiple-inherited objects.
-// Too high and it will both slow down leak checking (FindInsideAlloc
-// in HaveOnHeapLocked will get slower when there are large on-heap objects)
-// and make it probabilistically more likely to miss leaks
-// of large-sized objects.
-static const int64 kHeapCheckMaxPointerOffset = 1024;
-DEFINE_int64(heap_check_max_pointer_offset,
-	     EnvToInt("HEAP_CHECK_MAX_POINTER_OFFSET",
-                      kHeapCheckMaxPointerOffset),
-             "Largest pointer offset for which we traverse "
-             "pointers going inside of heap allocated objects. "
-             "Set to -1 to use the actual largest heap object size.");
-
-DEFINE_bool(heap_check_run_under_gdb,
-            EnvToBool("HEAP_CHECK_RUN_UNDER_GDB", false),
-            "If false, turns off heap-checking library when running under gdb "
-            "(normally, set to 'true' only when debugging the heap-checker)");
-
-DEFINE_int32(heap_check_delay_seconds, 0,
-             "Number of seconds to delay on-exit heap checking."
-             " If you set this flag,"
-             " you may also want to set exit_timeout_seconds in order to"
-             " avoid exit timeouts.\n"
-             "NOTE: This flag is to be used only to help diagnose issues"
-             " where it is suspected that the heap checker is reporting"
-             " false leaks that will disappear if the heap checker delays"
-             " its checks. Report any such issues to the heap-checker"
-             " maintainer(s).");
-
-//----------------------------------------------------------------------
-
-DEFINE_string(heap_profile_pprof,
-              EnvToString("PPROF_PATH", "pprof"),
-              "OBSOLETE; not used");
-
-DEFINE_string(heap_check_dump_directory,
-              EnvToString("HEAP_CHECK_DUMP_DIRECTORY", "/tmp"),
-              "Directory to put heap-checker leak dump information");
-
-
-//----------------------------------------------------------------------
-// HeapLeakChecker global data
-//----------------------------------------------------------------------
-
-// Global lock for all the global data of this module.
-static SpinLock heap_checker_lock(SpinLock::LINKER_INITIALIZED);
-
-//----------------------------------------------------------------------
-
-// Heap profile prefix for leak checking profiles.
-// Gets assigned once when leak checking is turned on, then never modified.
-static const string* profile_name_prefix = NULL;
-
-// Whole-program heap leak checker.
-// Gets assigned once when leak checking is turned on,
-// then main_heap_checker is never deleted.
-static HeapLeakChecker* main_heap_checker = NULL;
-
-// Whether we will use main_heap_checker to do a check at program exit
-// automatically. In any case user can ask for more checks on main_heap_checker
-// via GlobalChecker().
-static bool do_main_heap_check = false;
-
-// The heap profile we use to collect info about the heap.
-// This is created in HeapLeakChecker::BeforeConstructorsLocked
-// together with setting heap_checker_on (below) to true
-// and registering our new/delete malloc hooks;
-// similarly all are unset in HeapLeakChecker::TurnItselfOffLocked.
-static HeapProfileTable* heap_profile = NULL;
-
-// If we are doing (or going to do) any kind of heap-checking.
-static bool heap_checker_on = false;
-
-// pid of the process that does whole-program heap leak checking
-static pid_t heap_checker_pid = 0;
-
-// If we did heap profiling during global constructors execution
-static bool constructor_heap_profiling = false;
-
-// RAW_VLOG level we dump key INFO messages at.  If you want to turn
-// off these messages, set the environment variable PERFTOOLS_VERBOSE=-1.
-static const int heap_checker_info_level = 0;
-
-//----------------------------------------------------------------------
-// HeapLeakChecker's own memory allocator that is
-// independent of the normal program allocator.
-//----------------------------------------------------------------------
-
-// Wrapper of LowLevelAlloc for STL_Allocator and direct use.
-// We always access this class under held heap_checker_lock,
-// this allows us to in particular protect the period when threads are stopped
-// at random spots with TCMalloc_ListAllProcessThreads by heap_checker_lock,
-// w/o worrying about the lock in LowLevelAlloc::Arena.
-// We rely on the fact that we use an own arena with an own lock here.
-class HeapLeakChecker::Allocator {
- public:
-  static void Init() {
-    RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-    RAW_DCHECK(arena_ == NULL, "");
-    arena_ = LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
-  }
-  static void Shutdown() {
-    RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-    if (!LowLevelAlloc::DeleteArena(arena_)  ||  alloc_count_ != 0) {
-      RAW_LOG(FATAL, "Internal heap checker leak of %d objects", alloc_count_);
-    }
-  }
-  static int alloc_count() {
-    RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-    return alloc_count_;
-  }
-  static void* Allocate(size_t n) {
-    RAW_DCHECK(arena_  &&  heap_checker_lock.IsHeld(), "");
-    void* p = LowLevelAlloc::AllocWithArena(n, arena_);
-    if (p) alloc_count_ += 1;
-    return p;
-  }
-  static void Free(void* p) {
-    RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-    if (p) alloc_count_ -= 1;
-    LowLevelAlloc::Free(p);
-  }
-  static void Free(void* p, size_t /* n */) {
-    Free(p);
-  }
-  // destruct, free, and make *p to be NULL
-  template<typename T> static void DeleteAndNull(T** p) {
-    (*p)->~T();
-    Free(*p);
-    *p = NULL;
-  }
-  template<typename T> static void DeleteAndNullIfNot(T** p) {
-    if (*p != NULL) DeleteAndNull(p);
-  }
- private:
-  static LowLevelAlloc::Arena* arena_;
-  static int alloc_count_;
-};
-
-LowLevelAlloc::Arena* HeapLeakChecker::Allocator::arena_ = NULL;
-int HeapLeakChecker::Allocator::alloc_count_ = 0;
-
-//----------------------------------------------------------------------
-// HeapLeakChecker live object tracking components
-//----------------------------------------------------------------------
-
-// Cases of live object placement we distinguish
-enum ObjectPlacement {
-  MUST_BE_ON_HEAP,   // Must point to a live object of the matching size in the
-                     // heap_profile map of the heap when we get to it
-  IGNORED_ON_HEAP,   // Is a live (ignored) object on heap
-  MAYBE_LIVE,        // Is a piece of writable memory from /proc/self/maps
-  IN_GLOBAL_DATA,    // Is part of global data region of the executable
-  THREAD_DATA,       // Part of a thread stack and a thread descriptor with TLS
-  THREAD_REGISTERS,  // Values in registers of some thread
-};
-
-// Information about an allocated object
-struct AllocObject {
-  const void* ptr;        // the object
-  uintptr_t size;         // its size
-  ObjectPlacement place;  // where ptr points to
-
-  AllocObject(const void* p, size_t s, ObjectPlacement l)
-    : ptr(p), size(s), place(l) { }
-};
-
-// All objects (memory ranges) ignored via HeapLeakChecker::IgnoreObject
-// Key is the object's address; value is its size.
-typedef map<uintptr_t, size_t, less<uintptr_t>,
-            STL_Allocator<pair<const uintptr_t, size_t>,
-                          HeapLeakChecker::Allocator>
-           > IgnoredObjectsMap;
-static IgnoredObjectsMap* ignored_objects = NULL;
-
-// All objects (memory ranges) that we consider to be the sources of pointers
-// to live (not leaked) objects.
-// At different times this holds (what can be reached from) global data regions
-// and the objects we've been told to ignore.
-// For any AllocObject::ptr "live_objects" is supposed to contain at most one
-// record at any time. We maintain this by checking with the heap_profile map
-// of the heap and removing the live heap objects we've handled from it.
-// This vector is maintained as a stack and the frontier of reachable
-// live heap objects in our flood traversal of them.
-typedef vector<AllocObject,
-               STL_Allocator<AllocObject, HeapLeakChecker::Allocator>
-              > LiveObjectsStack;
-static LiveObjectsStack* live_objects = NULL;
-
-// A special string type that uses my allocator
-typedef basic_string<char, char_traits<char>,
-                     STL_Allocator<char, HeapLeakChecker::Allocator>
-                    > HCL_string;
-
-// A placeholder to fill-in the starting values for live_objects
-// for each library so we can keep the library-name association for logging.
-typedef map<HCL_string, LiveObjectsStack, less<HCL_string>,
-            STL_Allocator<pair<const HCL_string, LiveObjectsStack>,
-                          HeapLeakChecker::Allocator>
-           > LibraryLiveObjectsStacks;
-static LibraryLiveObjectsStacks* library_live_objects = NULL;
-
-// Value stored in the map of disabled address ranges;
-// its key is the end of the address range.
-// We'll ignore allocations with a return address in a disabled range
-// if the address occurs at 'max_depth' or less in the stack trace.
-struct HeapLeakChecker::RangeValue {
-  uintptr_t start_address;  // the start of the range
-  int       max_depth;      // the maximal stack depth to disable at
-};
-typedef map<uintptr_t, HeapLeakChecker::RangeValue, less<uintptr_t>,
-            STL_Allocator<pair<const uintptr_t, HeapLeakChecker::RangeValue>,
-                          HeapLeakChecker::Allocator>
-           > DisabledRangeMap;
-// The disabled program counter address ranges for profile dumping
-// that are registered with HeapLeakChecker::DisableChecksFromToLocked.
-static DisabledRangeMap* disabled_ranges = NULL;
-
-// Set of stack tops.
-// These are used to consider live only appropriate chunks of the memory areas
-// that are used for stacks (and maybe thread-specific data as well)
-// so that we do not treat pointers from outdated stack frames as live.
-typedef set<uintptr_t, less<uintptr_t>,
-            STL_Allocator<uintptr_t, HeapLeakChecker::Allocator>
-           > StackTopSet;
-static StackTopSet* stack_tops = NULL;
-
-// A map of ranges of code addresses for the system libraries
-// that can mmap/mremap/sbrk-allocate memory regions for stacks
-// and thread-local storage that we want to consider as live global data.
-// Maps from the end address to the start address.
-typedef map<uintptr_t, uintptr_t, less<uintptr_t>,
-            STL_Allocator<pair<const uintptr_t, uintptr_t>,
-                          HeapLeakChecker::Allocator>
-           > GlobalRegionCallerRangeMap;
-static GlobalRegionCallerRangeMap* global_region_caller_ranges = NULL;
-
-// TODO(maxim): make our big data structs into own modules
-
-// Disabler is implemented by keeping track of a per-thread count
-// of active Disabler objects.  Any objects allocated while the
-// count > 0 are not reported.
-
-#ifdef HAVE_TLS
-
-static __thread int thread_disable_counter
-// The "inital exec" model is faster than the default TLS model, at
-// the cost you can't dlopen this library.  But dlopen on heap-checker
-// doesn't work anyway -- it must run before main -- so this is a good
-// trade-off.
-# ifdef HAVE___ATTRIBUTE__
-   __attribute__ ((tls_model ("initial-exec")))
-# endif
-    ;
-inline int get_thread_disable_counter() {
-  return thread_disable_counter;
-}
-inline void set_thread_disable_counter(int value) {
-  thread_disable_counter = value;
-}
-
-#else  // #ifdef HAVE_TLS
-
-static pthread_key_t thread_disable_counter_key;
-static int main_thread_counter;   // storage for use before main()
-static bool use_main_thread_counter = true;
-
-// TODO(csilvers): this is called from NewHook, in the middle of malloc().
-// If perftools_pthread_getspecific calls malloc, that will lead to an
-// infinite loop.  I don't know how to fix that, so I hope it never happens!
-inline int get_thread_disable_counter() {
-  if (use_main_thread_counter)  // means we're running really early
-    return main_thread_counter;
-  void* p = perftools_pthread_getspecific(thread_disable_counter_key);
-  return (intptr_t)p;   // kinda evil: store the counter directly in the void*
-}
-
-inline void set_thread_disable_counter(int value) {
-  if (use_main_thread_counter) {   // means we're running really early
-    main_thread_counter = value;
-    return;
-  }
-  intptr_t pointer_sized_value = value;
-  // kinda evil: store the counter directly in the void*
-  void* p = (void*)pointer_sized_value;
-  // NOTE: this may call malloc, which will call NewHook which will call
-  // get_thread_disable_counter() which will call pthread_getspecific().  I
-  // don't know if anything bad can happen if we call getspecific() in the
-  // middle of a setspecific() call.  It seems to work ok in practice...
-  perftools_pthread_setspecific(thread_disable_counter_key, p);
-}
-
-// The idea here is that this initializer will run pretty late: after
-// pthreads have been totally set up.  At this point we can call
-// pthreads routines, so we set those up.
-class InitThreadDisableCounter {
- public:
-  InitThreadDisableCounter() {
-    perftools_pthread_key_create(&thread_disable_counter_key, NULL);
-    // Set up the main thread's value, which we have a special variable for.
-    void* p = (void*)(intptr_t)main_thread_counter;   // store the counter directly
-    perftools_pthread_setspecific(thread_disable_counter_key, p);
-    use_main_thread_counter = false;
-  }
-};
-InitThreadDisableCounter init_thread_disable_counter;
-
-#endif  // #ifdef HAVE_TLS
-
-HeapLeakChecker::Disabler::Disabler() {
-  // It is faster to unconditionally increment the thread-local
-  // counter than to check whether or not heap-checking is on
-  // in a thread-safe manner.
-  int counter = get_thread_disable_counter();
-  set_thread_disable_counter(counter + 1);
-  RAW_VLOG(10, "Increasing thread disable counter to %d", counter + 1);
-}
-
-HeapLeakChecker::Disabler::~Disabler() {
-  int counter = get_thread_disable_counter();
-  RAW_DCHECK(counter > 0, "");
-  if (counter > 0) {
-    set_thread_disable_counter(counter - 1);
-    RAW_VLOG(10, "Decreasing thread disable counter to %d", counter);
-  } else {
-    RAW_VLOG(0, "Thread disable counter underflow : %d", counter);
-  }
-}
-
-//----------------------------------------------------------------------
-
-// The size of the largest heap object allocated so far.
-static size_t max_heap_object_size = 0;
-// The possible range of addresses that can point
-// into one of the elements of heap_objects.
-static uintptr_t min_heap_address = uintptr_t(-1LL);
-static uintptr_t max_heap_address = 0;
-
-//----------------------------------------------------------------------
-
-// Simple casting helpers for uintptr_t and void*:
-template<typename T>
-inline static const void* AsPtr(T addr) {
-  return reinterpret_cast<void*>(addr);
-}
-inline static uintptr_t AsInt(const void* ptr) {
-  return reinterpret_cast<uintptr_t>(ptr);
-}
-
-//----------------------------------------------------------------------
-
-// We've seen reports that strstr causes heap-checker crashes in some
-// libc's (?):
-//    http://code.google.com/p/gperftools/issues/detail?id=263
-// It's simple enough to use our own.  This is not in time-critical code.
-static const char* hc_strstr(const char* s1, const char* s2) {
-  const size_t len = strlen(s2);
-  RAW_CHECK(len > 0, "Unexpected empty string passed to strstr()");
-  for (const char* p = strchr(s1, *s2); p != NULL; p = strchr(p+1, *s2)) {
-    if (strncmp(p, s2, len) == 0) {
-      return p;
-    }
-  }
-  return NULL;
-}
-
-//----------------------------------------------------------------------
-
-// Our hooks for MallocHook
-static void NewHook(const void* ptr, size_t size) {
-  if (ptr != NULL) {
-    const int counter = get_thread_disable_counter();
-    const bool ignore = (counter > 0);
-    RAW_VLOG(16, "Recording Alloc: %p of %" PRIuS "; %d", ptr, size,
-             int(counter));
-
-    // Fetch the caller's stack trace before acquiring heap_checker_lock.
-    void* stack[HeapProfileTable::kMaxStackDepth];
-    int depth = HeapProfileTable::GetCallerStackTrace(0, stack);
-
-    { SpinLockHolder l(&heap_checker_lock);
-      if (size > max_heap_object_size) max_heap_object_size = size;
-      uintptr_t addr = AsInt(ptr);
-      if (addr < min_heap_address) min_heap_address = addr;
-      addr += size;
-      if (addr > max_heap_address) max_heap_address = addr;
-      if (heap_checker_on) {
-        heap_profile->RecordAlloc(ptr, size, depth, stack);
-        if (ignore) {
-          heap_profile->MarkAsIgnored(ptr);
-        }
-      }
-    }
-    RAW_VLOG(17, "Alloc Recorded: %p of %" PRIuS "", ptr, size);
-  }
-}
-
-static void DeleteHook(const void* ptr) {
-  if (ptr != NULL) {
-    RAW_VLOG(16, "Recording Free %p", ptr);
-    { SpinLockHolder l(&heap_checker_lock);
-      if (heap_checker_on) heap_profile->RecordFree(ptr);
-    }
-    RAW_VLOG(17, "Free Recorded: %p", ptr);
-  }
-}
-
-//----------------------------------------------------------------------
-
-enum StackDirection {
-  GROWS_TOWARDS_HIGH_ADDRESSES,
-  GROWS_TOWARDS_LOW_ADDRESSES,
-  UNKNOWN_DIRECTION
-};
-
-// Determine which way the stack grows:
-
-static StackDirection ATTRIBUTE_NOINLINE GetStackDirection(
-    const uintptr_t *const ptr) {
-  uintptr_t x;
-  if (&x < ptr)
-    return GROWS_TOWARDS_LOW_ADDRESSES;
-  if (ptr < &x)
-    return GROWS_TOWARDS_HIGH_ADDRESSES;
-
-  RAW_CHECK(0, "");  // Couldn't determine the stack direction.
-
-  return UNKNOWN_DIRECTION;
-}
-
-// Direction of stack growth (will initialize via GetStackDirection())
-static StackDirection stack_direction = UNKNOWN_DIRECTION;
-
-// This routine is called for every thread stack we know about to register it.
-static void RegisterStackLocked(const void* top_ptr) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_DCHECK(MemoryRegionMap::LockIsHeld(), "");
-  RAW_VLOG(10, "Thread stack at %p", top_ptr);
-  uintptr_t top = AsInt(top_ptr);
-  stack_tops->insert(top);  // add for later use
-
-  // make sure stack_direction is initialized
-  if (stack_direction == UNKNOWN_DIRECTION) {
-    stack_direction = GetStackDirection(&top);
-  }
-
-  // Find memory region with this stack
-  MemoryRegionMap::Region region;
-  if (MemoryRegionMap::FindAndMarkStackRegion(top, &region)) {
-    // Make the proper portion of the stack live:
-    if (stack_direction == GROWS_TOWARDS_LOW_ADDRESSES) {
-      RAW_VLOG(11, "Live stack at %p of %" PRIuPTR " bytes",
-                  top_ptr, region.end_addr - top);
-      live_objects->push_back(AllocObject(top_ptr, region.end_addr - top,
-                                          THREAD_DATA));
-    } else {  // GROWS_TOWARDS_HIGH_ADDRESSES
-      RAW_VLOG(11, "Live stack at %p of %" PRIuPTR " bytes",
-                  AsPtr(region.start_addr),
-                  top - region.start_addr);
-      live_objects->push_back(AllocObject(AsPtr(region.start_addr),
-                                          top - region.start_addr,
-                                          THREAD_DATA));
-    }
-  // not in MemoryRegionMap, look in library_live_objects:
-  } else if (FLAGS_heap_check_ignore_global_live) {
-    for (LibraryLiveObjectsStacks::iterator lib = library_live_objects->begin();
-         lib != library_live_objects->end(); ++lib) {
-      for (LiveObjectsStack::iterator span = lib->second.begin();
-           span != lib->second.end(); ++span) {
-        uintptr_t start = AsInt(span->ptr);
-        uintptr_t end = start + span->size;
-        if (start <= top  &&  top < end) {
-          RAW_VLOG(11, "Stack at %p is inside /proc/self/maps chunk %p..%p",
-                      top_ptr, AsPtr(start), AsPtr(end));
-          // Shrink start..end region by chopping away the memory regions in
-          // MemoryRegionMap that land in it to undo merging of regions
-          // in /proc/self/maps, so that we correctly identify what portion
-          // of start..end is actually the stack region.
-          uintptr_t stack_start = start;
-          uintptr_t stack_end = end;
-          // can optimize-away this loop, but it does not run often
-          RAW_DCHECK(MemoryRegionMap::LockIsHeld(), "");
-          for (MemoryRegionMap::RegionIterator r =
-                 MemoryRegionMap::BeginRegionLocked();
-               r != MemoryRegionMap::EndRegionLocked(); ++r) {
-            if (top < r->start_addr  &&  r->start_addr < stack_end) {
-              stack_end = r->start_addr;
-            }
-            if (stack_start < r->end_addr  &&  r->end_addr <= top) {
-              stack_start = r->end_addr;
-            }
-          }
-          if (stack_start != start  ||  stack_end != end) {
-            RAW_VLOG(11, "Stack at %p is actually inside memory chunk %p..%p",
-                        top_ptr, AsPtr(stack_start), AsPtr(stack_end));
-          }
-          // Make the proper portion of the stack live:
-          if (stack_direction == GROWS_TOWARDS_LOW_ADDRESSES) {
-            RAW_VLOG(11, "Live stack at %p of %" PRIuPTR " bytes",
-                        top_ptr, stack_end - top);
-            live_objects->push_back(
-              AllocObject(top_ptr, stack_end - top, THREAD_DATA));
-          } else {  // GROWS_TOWARDS_HIGH_ADDRESSES
-            RAW_VLOG(11, "Live stack at %p of %" PRIuPTR " bytes",
-                        AsPtr(stack_start), top - stack_start);
-            live_objects->push_back(
-              AllocObject(AsPtr(stack_start), top - stack_start, THREAD_DATA));
-          }
-          lib->second.erase(span);  // kill the rest of the region
-          // Put the non-stack part(s) of the region back:
-          if (stack_start != start) {
-            lib->second.push_back(AllocObject(AsPtr(start), stack_start - start,
-                                  MAYBE_LIVE));
-          }
-          if (stack_end != end) {
-            lib->second.push_back(AllocObject(AsPtr(stack_end), end - stack_end,
-                                  MAYBE_LIVE));
-          }
-          return;
-        }
-      }
-    }
-    RAW_LOG(ERROR, "Memory region for stack at %p not found. "
-                   "Will likely report false leak positives.", top_ptr);
-  }
-}
-
-// Iterator for heap allocation map data to make ignored objects "live"
-// (i.e., treated as roots for the mark-and-sweep phase)
-static void MakeIgnoredObjectsLiveCallbackLocked(
-    const void* ptr, const HeapProfileTable::AllocInfo& info) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  if (info.ignored) {
-    live_objects->push_back(AllocObject(ptr, info.object_size,
-                                        MUST_BE_ON_HEAP));
-  }
-}
-
-// Iterator for heap allocation map data to make objects allocated from
-// disabled regions of code to be live.
-static void MakeDisabledLiveCallbackLocked(
-    const void* ptr, const HeapProfileTable::AllocInfo& info) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  bool stack_disable = false;
-  bool range_disable = false;
-  for (int depth = 0; depth < info.stack_depth; depth++) {
-    uintptr_t addr = AsInt(info.call_stack[depth]);
-    if (disabled_ranges) {
-      DisabledRangeMap::const_iterator iter
-        = disabled_ranges->upper_bound(addr);
-      if (iter != disabled_ranges->end()) {
-        RAW_DCHECK(iter->first > addr, "");
-        if (iter->second.start_address < addr  &&
-            iter->second.max_depth > depth) {
-          range_disable = true;  // in range; dropping
-          break;
-        }
-      }
-    }
-  }
-  if (stack_disable || range_disable) {
-    uintptr_t start_address = AsInt(ptr);
-    uintptr_t end_address = start_address + info.object_size;
-    StackTopSet::const_iterator iter
-      = stack_tops->lower_bound(start_address);
-    if (iter != stack_tops->end()) {
-      RAW_DCHECK(*iter >= start_address, "");
-      if (*iter < end_address) {
-        // We do not disable (treat as live) whole allocated regions
-        // if they are used to hold thread call stacks
-        // (i.e. when we find a stack inside).
-        // The reason is that we'll treat as live the currently used
-        // stack portions anyway (see RegisterStackLocked),
-        // and the rest of the region where the stack lives can well
-        // contain outdated stack variables which are not live anymore,
-        // hence should not be treated as such.
-        RAW_VLOG(11, "Not %s-disabling %" PRIuS " bytes at %p"
-                    ": have stack inside: %p",
-                    (stack_disable ? "stack" : "range"),
-                    info.object_size, ptr, AsPtr(*iter));
-        return;
-      }
-    }
-    RAW_VLOG(11, "%s-disabling %" PRIuS " bytes at %p",
-                (stack_disable ? "Stack" : "Range"), info.object_size, ptr);
-    live_objects->push_back(AllocObject(ptr, info.object_size,
-                                        MUST_BE_ON_HEAP));
-  }
-}
-
-static const char kUnnamedProcSelfMapEntry[] = "UNNAMED";
-
-// This function takes some fields from a /proc/self/maps line:
-//
-//   start_address  start address of a memory region.
-//   end_address    end address of a memory region
-//   permissions    rwx + private/shared bit
-//   filename       filename of the mapped file
-//
-// If the region is not writeable, then it cannot have any heap
-// pointers in it, otherwise we record it as a candidate live region
-// to get filtered later.
-static void RecordGlobalDataLocked(uintptr_t start_address,
-                                   uintptr_t end_address,
-                                   const char* permissions,
-                                   const char* filename) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  // Ignore non-writeable regions.
-  if (strchr(permissions, 'w') == NULL) return;
-  if (filename == NULL  ||  *filename == '\0') {
-    filename = kUnnamedProcSelfMapEntry;
-  }
-  RAW_VLOG(11, "Looking into %s: 0x%" PRIxPTR "..0x%" PRIxPTR,
-              filename, start_address, end_address);
-  (*library_live_objects)[filename].
-    push_back(AllocObject(AsPtr(start_address),
-                          end_address - start_address,
-                          MAYBE_LIVE));
-}
-
-// See if 'library' from /proc/self/maps has base name 'library_base'
-// i.e. contains it and has '.' or '-' after it.
-static bool IsLibraryNamed(const char* library, const char* library_base) {
-  const char* p = hc_strstr(library, library_base);
-  size_t sz = strlen(library_base);
-  return p != NULL  &&  (p[sz] == '.'  ||  p[sz] == '-');
-}
-
-// static
-void HeapLeakChecker::DisableLibraryAllocsLocked(const char* library,
-                                                 uintptr_t start_address,
-                                                 uintptr_t end_address) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  int depth = 0;
-  // TODO(maxim): maybe this should be extended to also use objdump
-  //              and pick the text portion of the library more precisely.
-  if (IsLibraryNamed(library, "/libpthread")  ||
-        // libpthread has a lot of small "system" leaks we don't care about.
-        // In particular it allocates memory to store data supplied via
-        // pthread_setspecific (which can be the only pointer to a heap object).
-      IsLibraryNamed(library, "/libdl")  ||
-        // library loaders leak some "system" heap that we don't care about
-      IsLibraryNamed(library, "/libcrypto")  ||
-        // Sometimes libcrypto of OpenSSH is compiled with -fomit-frame-pointer
-        // (any library can be, of course, but this one often is because speed
-        // is so important for making crypto usable).  We ignore all its
-        // allocations because we can't see the call stacks.  We'd prefer
-        // to ignore allocations done in files/symbols that match
-        // "default_malloc_ex|default_realloc_ex"
-        // but that doesn't work when the end-result binary is stripped.
-      IsLibraryNamed(library, "/libjvm")  ||
-        // JVM has a lot of leaks we don't care about.
-      IsLibraryNamed(library, "/libzip")
-        // The JVM leaks java.util.zip.Inflater after loading classes.
-     ) {
-    depth = 1;  // only disable allocation calls directly from the library code
-  } else if (IsLibraryNamed(library, "/ld")
-               // library loader leaks some "system" heap
-               // (e.g. thread-local storage) that we don't care about
-            ) {
-    depth = 2;  // disable allocation calls directly from the library code
-                // and at depth 2 from it.
-    // We need depth 2 here solely because of a libc bug that
-    // forces us to jump through __memalign_hook and MemalignOverride hoops
-    // in tcmalloc.cc.
-    // Those buggy __libc_memalign() calls are in ld-linux.so and happen for
-    // thread-local storage allocations that we want to ignore here.
-    // We go with the depth-2 hack as a workaround for this libc bug:
-    // otherwise we'd need to extend MallocHook interface
-    // so that correct stack depth adjustment can be propagated from
-    // the exceptional case of MemalignOverride.
-    // Using depth 2 here should not mask real leaks because ld-linux.so
-    // does not call user code.
-  }
-  if (depth) {
-    RAW_VLOG(10, "Disabling allocations from %s at depth %d:", library, depth);
-    DisableChecksFromToLocked(AsPtr(start_address), AsPtr(end_address), depth);
-    if (IsLibraryNamed(library, "/libpthread")  ||
-        IsLibraryNamed(library, "/libdl")  ||
-        IsLibraryNamed(library, "/ld")) {
-      RAW_VLOG(10, "Global memory regions made by %s will be live data",
-                  library);
-      if (global_region_caller_ranges == NULL) {
-        global_region_caller_ranges =
-          new(Allocator::Allocate(sizeof(GlobalRegionCallerRangeMap)))
-            GlobalRegionCallerRangeMap;
-      }
-      global_region_caller_ranges
-        ->insert(make_pair(end_address, start_address));
-    }
-  }
-}
-
-// static
-HeapLeakChecker::ProcMapsResult HeapLeakChecker::UseProcMapsLocked(
-                                  ProcMapsTask proc_maps_task) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  // Need to provide own scratch memory to ProcMapsIterator:
-  ProcMapsIterator::Buffer buffer;
-  ProcMapsIterator it(0, &buffer);
-  if (!it.Valid()) {
-    int errsv = errno;
-    RAW_LOG(ERROR, "Could not open /proc/self/maps: errno=%d. "
-                   "Libraries will not be handled correctly.", errsv);
-    return CANT_OPEN_PROC_MAPS;
-  }
-  uint64 start_address, end_address, file_offset;
-  int64 inode;
-  char *permissions, *filename;
-  bool saw_shared_lib = false;
-  bool saw_nonzero_inode = false;
-  bool saw_shared_lib_with_nonzero_inode = false;
-  while (it.Next(&start_address, &end_address, &permissions,
-                 &file_offset, &inode, &filename)) {
-    if (start_address >= end_address) {
-      // Warn if a line we can be interested in is ill-formed:
-      if (inode != 0) {
-        RAW_LOG(ERROR, "Errors reading /proc/self/maps. "
-                       "Some global memory regions will not "
-                       "be handled correctly.");
-      }
-      // Silently skip other ill-formed lines: some are possible
-      // probably due to the interplay of how /proc/self/maps is updated
-      // while we read it in chunks in ProcMapsIterator and
-      // do things in this loop.
-      continue;
-    }
-    // Determine if any shared libraries are present (this is the same
-    // list of extensions as is found in pprof).  We want to ignore
-    // 'fake' libraries with inode 0 when determining.  However, some
-    // systems don't share inodes via /proc, so we turn off this check
-    // if we don't see any evidence that we're getting inode info.
-    if (inode != 0) {
-      saw_nonzero_inode = true;
-    }
-    if ((hc_strstr(filename, "lib") && hc_strstr(filename, ".so")) ||
-        hc_strstr(filename, ".dll") ||
-        // not all .dylib filenames start with lib. .dylib is big enough
-        // that we are unlikely to get false matches just checking that.
-        hc_strstr(filename, ".dylib") || hc_strstr(filename, ".bundle")) {
-      saw_shared_lib = true;
-      if (inode != 0) {
-        saw_shared_lib_with_nonzero_inode = true;
-      }
-    }
-
-    switch (proc_maps_task) {
-      case DISABLE_LIBRARY_ALLOCS:
-        // All lines starting like
-        // "401dc000-4030f000 r??p 00132000 03:01 13991972  lib/bin"
-        // identify a data and code sections of a shared library or our binary
-        if (inode != 0 && strncmp(permissions, "r-xp", 4) == 0) {
-          DisableLibraryAllocsLocked(filename, start_address, end_address);
-        }
-        break;
-      case RECORD_GLOBAL_DATA:
-        RecordGlobalDataLocked(start_address, end_address,
-                               permissions, filename);
-        break;
-      default:
-        RAW_CHECK(0, "");
-    }
-  }
-  // If /proc/self/maps is reporting inodes properly (we saw a
-  // non-zero inode), then we only say we saw a shared lib if we saw a
-  // 'real' one, with a non-zero inode.
-  if (saw_nonzero_inode) {
-    saw_shared_lib = saw_shared_lib_with_nonzero_inode;
-  }
-  if (!saw_shared_lib) {
-    RAW_LOG(ERROR, "No shared libs detected. Will likely report false leak "
-                   "positives for statically linked executables.");
-    return NO_SHARED_LIBS_IN_PROC_MAPS;
-  }
-  return PROC_MAPS_USED;
-}
-
-// Total number and size of live objects dropped from the profile;
-// (re)initialized in IgnoreAllLiveObjectsLocked.
-static int64 live_objects_total;
-static int64 live_bytes_total;
-
-// pid of the thread that is doing the current leak check
-// (protected by our lock; IgnoreAllLiveObjectsLocked sets it)
-static pid_t self_thread_pid = 0;
-
-// Status of our thread listing callback execution
-// (protected by our lock; used from within IgnoreAllLiveObjectsLocked)
-static enum {
-  CALLBACK_NOT_STARTED,
-  CALLBACK_STARTED,
-  CALLBACK_COMPLETED,
-} thread_listing_status = CALLBACK_NOT_STARTED;
-
-// Ideally to avoid deadlocks this function should not result in any libc
-// or other function calls that might need to lock a mutex:
-// It is called when all threads of a process are stopped
-// at arbitrary points thus potentially holding those locks.
-//
-// In practice we are calling some simple i/o and sprintf-type library functions
-// for logging messages, but use only our own LowLevelAlloc::Arena allocator.
-//
-// This is known to be buggy: the library i/o function calls are able to cause
-// deadlocks when they request a lock that a stopped thread happens to hold.
-// This issue as far as we know have so far not resulted in any deadlocks
-// in practice, so for now we are taking our chance that the deadlocks
-// have insignificant frequency.
-//
-// If such deadlocks become a problem we should make the i/o calls
-// into appropriately direct system calls (or eliminate them),
-// in particular write() is not safe and vsnprintf() is potentially dangerous
-// due to reliance on locale functions (these are called through RAW_LOG
-// and in other ways).
-//
-
-#if defined(HAVE_LINUX_PTRACE_H) && defined(HAVE_SYS_SYSCALL_H) && defined(DUMPER)
-# if (defined(__i386__) || defined(__x86_64))
-#  define THREAD_REGS i386_regs
-# elif defined(__PPC__)
-#  define THREAD_REGS ppc_regs
-# endif
-#endif
-
-/*static*/ int HeapLeakChecker::IgnoreLiveThreadsLocked(void* parameter,
-                                                        int num_threads,
-                                                        pid_t* thread_pids,
-                                                        va_list /*ap*/) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  thread_listing_status = CALLBACK_STARTED;
-  RAW_VLOG(11, "Found %d threads (from pid %d)", num_threads, getpid());
-
-  if (FLAGS_heap_check_ignore_global_live) {
-    UseProcMapsLocked(RECORD_GLOBAL_DATA);
-  }
-
-  // We put the registers from other threads here
-  // to make pointers stored in them live.
-  vector<void*, STL_Allocator<void*, Allocator> > thread_registers;
-
-  int failures = 0;
-  for (int i = 0; i < num_threads; ++i) {
-    // the leak checking thread itself is handled
-    // specially via self_thread_stack, not here:
-    if (thread_pids[i] == self_thread_pid) continue;
-    RAW_VLOG(11, "Handling thread with pid %d", thread_pids[i]);
-#ifdef THREAD_REGS
-    THREAD_REGS thread_regs;
-#define sys_ptrace(r, p, a, d)  syscall(SYS_ptrace, (r), (p), (a), (d))
-    // We use sys_ptrace to avoid thread locking
-    // because this is called from TCMalloc_ListAllProcessThreads
-    // when all but this thread are suspended.
-    if (sys_ptrace(PTRACE_GETREGS, thread_pids[i], NULL, &thread_regs) == 0) {
-      // Need to use SP to get all the data from the very last stack frame:
-      COMPILE_ASSERT(sizeof(thread_regs.SP) == sizeof(void*),
-                     SP_register_does_not_look_like_a_pointer);
-      RegisterStackLocked(reinterpret_cast<void*>(thread_regs.SP));
-      // Make registers live (just in case PTRACE_ATTACH resulted in some
-      // register pointers still being in the registers and not on the stack):
-      for (void** p = reinterpret_cast<void**>(&thread_regs);
-           p < reinterpret_cast<void**>(&thread_regs + 1); ++p) {
-        RAW_VLOG(12, "Thread register %p", *p);
-        thread_registers.push_back(*p);
-      }
-    } else {
-      failures += 1;
-    }
-#else
-    failures += 1;
-#endif
-  }
-  // Use all the collected thread (stack) liveness sources:
-  IgnoreLiveObjectsLocked("threads stack data", "");
-  if (thread_registers.size()) {
-    // Make thread registers be live heap data sources.
-    // we rely here on the fact that vector is in one memory chunk:
-    RAW_VLOG(11, "Live registers at %p of %" PRIuS " bytes",
-                &thread_registers[0], thread_registers.size() * sizeof(void*));
-    live_objects->push_back(AllocObject(&thread_registers[0],
-                                        thread_registers.size() * sizeof(void*),
-                                        THREAD_REGISTERS));
-    IgnoreLiveObjectsLocked("threads register data", "");
-  }
-  // Do all other liveness walking while all threads are stopped:
-  IgnoreNonThreadLiveObjectsLocked();
-  // Can now resume the threads:
-  TCMalloc_ResumeAllProcessThreads(num_threads, thread_pids);
-  thread_listing_status = CALLBACK_COMPLETED;
-  return failures;
-}
-
-// Stack top of the thread that is doing the current leak check
-// (protected by our lock; IgnoreAllLiveObjectsLocked sets it)
-static const void* self_thread_stack_top;
-
-// static
-void HeapLeakChecker::IgnoreNonThreadLiveObjectsLocked() {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_DCHECK(MemoryRegionMap::LockIsHeld(), "");
-  RAW_VLOG(11, "Handling self thread with pid %d", self_thread_pid);
-  // Register our own stack:
-
-  // Important that all stack ranges (including the one here)
-  // are known before we start looking at them
-  // in MakeDisabledLiveCallbackLocked:
-  RegisterStackLocked(self_thread_stack_top);
-  IgnoreLiveObjectsLocked("stack data", "");
-
-  // Make objects we were told to ignore live:
-  if (ignored_objects) {
-    for (IgnoredObjectsMap::const_iterator object = ignored_objects->begin();
-         object != ignored_objects->end(); ++object) {
-      const void* ptr = AsPtr(object->first);
-      RAW_VLOG(11, "Ignored live object at %p of %" PRIuS " bytes",
-                  ptr, object->second);
-      live_objects->
-        push_back(AllocObject(ptr, object->second, MUST_BE_ON_HEAP));
-      // we do this liveness check for ignored_objects before doing any
-      // live heap walking to make sure it does not fail needlessly:
-      size_t object_size;
-      if (!(heap_profile->FindAlloc(ptr, &object_size)  &&
-            object->second == object_size)) {
-        RAW_LOG(FATAL, "Object at %p of %" PRIuS " bytes from an"
-                       " IgnoreObject() has disappeared", ptr, object->second);
-      }
-    }
-    IgnoreLiveObjectsLocked("ignored objects", "");
-  }
-
-  // Treat objects that were allocated when a Disabler was live as
-  // roots.  I.e., if X was allocated while a Disabler was active,
-  // and Y is reachable from X, arrange that neither X nor Y are
-  // treated as leaks.
-  heap_profile->IterateAllocs(MakeIgnoredObjectsLiveCallbackLocked);
-  IgnoreLiveObjectsLocked("disabled objects", "");
-
-  // Make code-address-disabled objects live and ignored:
-  // This in particular makes all thread-specific data live
-  // because the basic data structure to hold pointers to thread-specific data
-  // is allocated from libpthreads and we have range-disabled that
-  // library code with UseProcMapsLocked(DISABLE_LIBRARY_ALLOCS);
-  // so now we declare all thread-specific data reachable from there as live.
-  heap_profile->IterateAllocs(MakeDisabledLiveCallbackLocked);
-  IgnoreLiveObjectsLocked("disabled code", "");
-
-  // Actually make global data live:
-  if (FLAGS_heap_check_ignore_global_live) {
-    bool have_null_region_callers = false;
-    for (LibraryLiveObjectsStacks::iterator l = library_live_objects->begin();
-         l != library_live_objects->end(); ++l) {
-      RAW_CHECK(live_objects->empty(), "");
-      // Process library_live_objects in l->second
-      // filtering them by MemoryRegionMap:
-      // It's safe to iterate over MemoryRegionMap
-      // w/o locks here as we are inside MemoryRegionMap::Lock():
-      RAW_DCHECK(MemoryRegionMap::LockIsHeld(), "");
-      // The only change to MemoryRegionMap possible in this loop
-      // is region addition as a result of allocating more memory
-      // for live_objects. This won't invalidate the RegionIterator
-      // or the intent of the loop.
-      // --see the comment by MemoryRegionMap::BeginRegionLocked().
-      for (MemoryRegionMap::RegionIterator region =
-             MemoryRegionMap::BeginRegionLocked();
-           region != MemoryRegionMap::EndRegionLocked(); ++region) {
-        // "region" from MemoryRegionMap is to be subtracted from
-        // (tentatively live) regions in l->second
-        // if it has a stack inside or it was allocated by
-        // a non-special caller (not one covered by a range
-        // in global_region_caller_ranges).
-        // This will in particular exclude all memory chunks used
-        // by the heap itself as well as what's been allocated with
-        // any allocator on top of mmap.
-        bool subtract = true;
-        if (!region->is_stack  &&  global_region_caller_ranges) {
-          if (region->caller() == static_cast<uintptr_t>(NULL)) {
-            have_null_region_callers = true;
-          } else {
-            GlobalRegionCallerRangeMap::const_iterator iter
-              = global_region_caller_ranges->upper_bound(region->caller());
-            if (iter != global_region_caller_ranges->end()) {
-              RAW_DCHECK(iter->first > region->caller(), "");
-              if (iter->second < region->caller()) {  // in special region
-                subtract = false;
-              }
-            }
-          }
-        }
-        if (subtract) {
-          // The loop puts the result of filtering l->second into live_objects:
-          for (LiveObjectsStack::const_iterator i = l->second.begin();
-               i != l->second.end(); ++i) {
-            // subtract *region from *i
-            uintptr_t start = AsInt(i->ptr);
-            uintptr_t end = start + i->size;
-            if (region->start_addr <= start  &&  end <= region->end_addr) {
-              // full deletion due to subsumption
-            } else if (start < region->start_addr  &&
-                       region->end_addr < end) {  // cutting-out split
-              live_objects->push_back(AllocObject(i->ptr,
-                                                  region->start_addr - start,
-                                                  IN_GLOBAL_DATA));
-              live_objects->push_back(AllocObject(AsPtr(region->end_addr),
-                                                  end - region->end_addr,
-                                                  IN_GLOBAL_DATA));
-            } else if (region->end_addr > start  &&
-                       region->start_addr <= start) {  // cut from start
-              live_objects->push_back(AllocObject(AsPtr(region->end_addr),
-                                                  end - region->end_addr,
-                                                  IN_GLOBAL_DATA));
-            } else if (region->start_addr > start  &&
-                       region->start_addr < end) {  // cut from end
-              live_objects->push_back(AllocObject(i->ptr,
-                                                  region->start_addr - start,
-                                                  IN_GLOBAL_DATA));
-            } else {  // pass: no intersection
-              live_objects->push_back(AllocObject(i->ptr, i->size,
-                                                  IN_GLOBAL_DATA));
-            }
-          }
-          // Move live_objects back into l->second
-          // for filtering by the next region.
-          live_objects->swap(l->second);
-          live_objects->clear();
-        }
-      }
-      // Now get and use live_objects from the final version of l->second:
-      if (VLOG_IS_ON(11)) {
-        for (LiveObjectsStack::const_iterator i = l->second.begin();
-             i != l->second.end(); ++i) {
-          RAW_VLOG(11, "Library live region at %p of %" PRIuPTR " bytes",
-                      i->ptr, i->size);
-        }
-      }
-      live_objects->swap(l->second);
-      IgnoreLiveObjectsLocked("in globals of\n  ", l->first.c_str());
-    }
-    if (have_null_region_callers) {
-      RAW_LOG(ERROR, "Have memory regions w/o callers: "
-                     "might report false leaks");
-    }
-    Allocator::DeleteAndNull(&library_live_objects);
-  }
-}
-
-// Callback for TCMalloc_ListAllProcessThreads in IgnoreAllLiveObjectsLocked below
-// to test/verify that we have just the one main thread, in which case
-// we can do everything in that main thread,
-// so that CPU profiler can collect all its samples.
-// Returns the number of threads in the process.
-static int IsOneThread(void* parameter, int num_threads,
-                       pid_t* thread_pids, va_list ap) {
-  if (num_threads != 1) {
-    RAW_LOG(WARNING, "Have threads: Won't CPU-profile the bulk of leak "
-                     "checking work happening in IgnoreLiveThreadsLocked!");
-  }
-  TCMalloc_ResumeAllProcessThreads(num_threads, thread_pids);
-  return num_threads;
-}
-
-// Dummy for IgnoreAllLiveObjectsLocked below.
-// Making it global helps with compiler warnings.
-static va_list dummy_ap;
-
-// static
-void HeapLeakChecker::IgnoreAllLiveObjectsLocked(const void* self_stack_top) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_CHECK(live_objects == NULL, "");
-  live_objects = new(Allocator::Allocate(sizeof(LiveObjectsStack)))
-                   LiveObjectsStack;
-  stack_tops = new(Allocator::Allocate(sizeof(StackTopSet))) StackTopSet;
-  // reset the counts
-  live_objects_total = 0;
-  live_bytes_total = 0;
-  // Reduce max_heap_object_size to FLAGS_heap_check_max_pointer_offset
-  // for the time of leak check.
-  // FLAGS_heap_check_max_pointer_offset caps max_heap_object_size
-  // to manage reasonably low chances of random bytes
-  // appearing to be pointing into large actually leaked heap objects.
-  const size_t old_max_heap_object_size = max_heap_object_size;
-  max_heap_object_size = (
-    FLAGS_heap_check_max_pointer_offset != -1
-    ? min(size_t(FLAGS_heap_check_max_pointer_offset), max_heap_object_size)
-    : max_heap_object_size);
-  // Record global data as live:
-  if (FLAGS_heap_check_ignore_global_live) {
-    library_live_objects =
-      new(Allocator::Allocate(sizeof(LibraryLiveObjectsStacks)))
-        LibraryLiveObjectsStacks;
-  }
-  // Ignore all thread stacks:
-  thread_listing_status = CALLBACK_NOT_STARTED;
-  bool need_to_ignore_non_thread_objects = true;
-  self_thread_pid = getpid();
-  self_thread_stack_top = self_stack_top;
-  if (FLAGS_heap_check_ignore_thread_live) {
-    // In case we are doing CPU profiling we'd like to do all the work
-    // in the main thread, not in the special thread created by
-    // TCMalloc_ListAllProcessThreads, so that CPU profiler can
-    // collect all its samples.  The machinery of
-    // TCMalloc_ListAllProcessThreads conflicts with the CPU profiler
-    // by also relying on signals and ::sigaction.  We can do this
-    // (run everything in the main thread) safely only if there's just
-    // the main thread itself in our process.  This variable reflects
-    // these two conditions:
-    bool want_and_can_run_in_main_thread =
-      ProfilingIsEnabledForAllThreads()  &&
-      TCMalloc_ListAllProcessThreads(NULL, IsOneThread) == 1;
-    // When the normal path of TCMalloc_ListAllProcessThreads below is taken,
-    // we fully suspend the threads right here before any liveness checking
-    // and keep them suspended for the whole time of liveness checking
-    // inside of the IgnoreLiveThreadsLocked callback.
-    // (The threads can't (de)allocate due to lock on the delete hook but
-    //  if not suspended they could still mess with the pointer
-    //  graph while we walk it).
-    int r = want_and_can_run_in_main_thread
-            ? IgnoreLiveThreadsLocked(NULL, 1, &self_thread_pid, dummy_ap)
-            : TCMalloc_ListAllProcessThreads(NULL, IgnoreLiveThreadsLocked);
-    need_to_ignore_non_thread_objects = r < 0;
-    if (r < 0) {
-      RAW_LOG(WARNING, "Thread finding failed with %d errno=%d", r, errno);
-      if (thread_listing_status == CALLBACK_COMPLETED) {
-        RAW_LOG(INFO, "Thread finding callback "
-                      "finished ok; hopefully everything is fine");
-        need_to_ignore_non_thread_objects = false;
-      } else if (thread_listing_status == CALLBACK_STARTED) {
-        RAW_LOG(FATAL, "Thread finding callback was "
-                       "interrupted or crashed; can't fix this");
-      } else {  // CALLBACK_NOT_STARTED
-        RAW_LOG(ERROR, "Could not find thread stacks. "
-                       "Will likely report false leak positives.");
-      }
-    } else if (r != 0) {
-      RAW_LOG(ERROR, "Thread stacks not found for %d threads. "
-                     "Will likely report false leak positives.", r);
-    } else {
-      RAW_VLOG(11, "Thread stacks appear to be found for all threads");
-    }
-  } else {
-    RAW_LOG(WARNING, "Not looking for thread stacks; "
-                     "objects reachable only from there "
-                     "will be reported as leaks");
-  }
-  // Do all other live data ignoring here if we did not do it
-  // within thread listing callback with all threads stopped.
-  if (need_to_ignore_non_thread_objects) {
-    if (FLAGS_heap_check_ignore_global_live) {
-      UseProcMapsLocked(RECORD_GLOBAL_DATA);
-    }
-    IgnoreNonThreadLiveObjectsLocked();
-  }
-  if (live_objects_total) {
-    RAW_VLOG(10, "Ignoring %" PRId64 " reachable objects of %" PRId64 " bytes",
-                live_objects_total, live_bytes_total);
-  }
-  // Free these: we made them here and heap_profile never saw them
-  Allocator::DeleteAndNull(&live_objects);
-  Allocator::DeleteAndNull(&stack_tops);
-  max_heap_object_size = old_max_heap_object_size;  // reset this var
-}
-
-// Alignment at which we should consider pointer positions
-// in IgnoreLiveObjectsLocked. Will normally use the value of
-// FLAGS_heap_check_pointer_source_alignment.
-static size_t pointer_source_alignment = kPointerSourceAlignment;
-// Global lock for HeapLeakChecker::DoNoLeaks
-// to protect pointer_source_alignment.
-static SpinLock alignment_checker_lock(SpinLock::LINKER_INITIALIZED);
-
-// This function changes the live bits in the heap_profile-table's state:
-// we only record the live objects to be skipped.
-//
-// When checking if a byte sequence points to a heap object we use
-// HeapProfileTable::FindInsideAlloc to handle both pointers to
-// the start and inside of heap-allocated objects.
-// The "inside" case needs to be checked to support
-// at least the following relatively common cases:
-// - C++ arrays allocated with new FooClass[size] for classes
-//   with destructors have their size recorded in a sizeof(int) field
-//   before the place normal pointers point to.
-// - basic_string<>-s for e.g. the C++ library of gcc 3.4
-//   have the meta-info in basic_string<...>::_Rep recorded
-//   before the place normal pointers point to.
-// - Multiple-inherited objects have their pointers when cast to
-//   different base classes pointing inside of the actually
-//   allocated object.
-// - Sometimes reachability pointers point to member objects of heap objects,
-//   and then those member objects point to the full heap object.
-// - Third party UnicodeString: it stores a 32-bit refcount
-//   (in both 32-bit and 64-bit binaries) as the first uint32
-//   in the allocated memory and a normal pointer points at
-//   the second uint32 behind the refcount.
-// By finding these additional objects here
-// we slightly increase the chance to mistake random memory bytes
-// for a pointer and miss a leak in a particular run of a binary.
-//
-/*static*/ void HeapLeakChecker::IgnoreLiveObjectsLocked(const char* name,
-                                                         const char* name2) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  int64 live_object_count = 0;
-  int64 live_byte_count = 0;
-  while (!live_objects->empty()) {
-    const char* object =
-      reinterpret_cast<const char*>(live_objects->back().ptr);
-    size_t size = live_objects->back().size;
-    const ObjectPlacement place = live_objects->back().place;
-    live_objects->pop_back();
-    if (place == MUST_BE_ON_HEAP  &&  heap_profile->MarkAsLive(object)) {
-      live_object_count += 1;
-      live_byte_count += size;
-    }
-    RAW_VLOG(13, "Looking for heap pointers in %p of %" PRIuS " bytes",
-                object, size);
-    const char* const whole_object = object;
-    size_t const whole_size = size;
-    // Try interpretting any byte sequence in object,size as a heap pointer:
-    const size_t remainder = AsInt(object) % pointer_source_alignment;
-    if (remainder) {
-      object += pointer_source_alignment - remainder;
-      if (size >= pointer_source_alignment - remainder) {
-        size -= pointer_source_alignment - remainder;
-      } else {
-        size = 0;
-      }
-    }
-    if (size < sizeof(void*)) continue;
-
-#ifdef NO_FRAME_POINTER
-    // Frame pointer omission requires us to use libunwind, which uses direct
-    // mmap and munmap system calls, and that needs special handling.
-    if (name2 == kUnnamedProcSelfMapEntry) {
-      static const uintptr_t page_mask = ~(getpagesize() - 1);
-      const uintptr_t addr = reinterpret_cast<uintptr_t>(object);
-      if ((addr & page_mask) == 0 && (size & page_mask) == 0) {
-        // This is an object we slurped from /proc/self/maps.
-        // It may or may not be readable at this point.
-        //
-        // In case all the above conditions made a mistake, and the object is
-        // not related to libunwind, we also verify that it's not readable
-        // before ignoring it.
-        if (msync(const_cast<char*>(object), size, MS_ASYNC) != 0) {
-          // Skip unreadable object, so we don't crash trying to sweep it.
-          RAW_VLOG(0, "Ignoring inaccessible object [%p, %p) "
-                   "(msync error %d (%s))",
-                   object, object + size, errno, strerror(errno));
-          continue;
-        }
-      }
-    }
-#endif
-
-    const char* const max_object = object + size - sizeof(void*);
-    while (object <= max_object) {
-      // potentially unaligned load:
-      const uintptr_t addr = *reinterpret_cast<const uintptr_t*>(object);
-      // Do fast check before the more expensive HaveOnHeapLocked lookup:
-      // this code runs for all memory words that are potentially pointers:
-      const bool can_be_on_heap =
-        // Order tests by the likelyhood of the test failing in 64/32 bit modes.
-        // Yes, this matters: we either lose 5..6% speed in 32 bit mode
-        // (which is already slower) or by a factor of 1.5..1.91 in 64 bit mode.
-        // After the alignment test got dropped the above performance figures
-        // must have changed; might need to revisit this.
-#if defined(__x86_64__)
-        addr <= max_heap_address  &&  // <= is for 0-sized object with max addr
-        min_heap_address <= addr;
-#else
-        min_heap_address <= addr  &&
-        addr <= max_heap_address;  // <= is for 0-sized object with max addr
-#endif
-      if (can_be_on_heap) {
-        const void* ptr = reinterpret_cast<const void*>(addr);
-        // Too expensive (inner loop): manually uncomment when debugging:
-        // RAW_VLOG(17, "Trying pointer to %p at %p", ptr, object);
-        size_t object_size;
-        if (HaveOnHeapLocked(&ptr, &object_size)  &&
-            heap_profile->MarkAsLive(ptr)) {
-          // We take the (hopefully low) risk here of encountering by accident
-          // a byte sequence in memory that matches an address of
-          // a heap object which is in fact leaked.
-          // I.e. in very rare and probably not repeatable/lasting cases
-          // we might miss some real heap memory leaks.
-          RAW_VLOG(14, "Found pointer to %p of %" PRIuS " bytes at %p "
-                      "inside %p of size %" PRIuS "",
-                      ptr, object_size, object, whole_object, whole_size);
-          if (VLOG_IS_ON(15)) {
-            // log call stacks to help debug how come something is not a leak
-            HeapProfileTable::AllocInfo alloc;
-            if (!heap_profile->FindAllocDetails(ptr, &alloc)) {
-              RAW_LOG(FATAL, "FindAllocDetails failed on ptr %p", ptr);
-            }
-            RAW_LOG(INFO, "New live %p object's alloc stack:", ptr);
-            for (int i = 0; i < alloc.stack_depth; ++i) {
-              RAW_LOG(INFO, "  @ %p", alloc.call_stack[i]);
-            }
-          }
-          live_object_count += 1;
-          live_byte_count += object_size;
-          live_objects->push_back(AllocObject(ptr, object_size,
-                                              IGNORED_ON_HEAP));
-        }
-      }
-      object += pointer_source_alignment;
-    }
-  }
-  live_objects_total += live_object_count;
-  live_bytes_total += live_byte_count;
-  if (live_object_count) {
-    RAW_VLOG(10, "Removed %" PRId64 " live heap objects of %" PRId64 " bytes: %s%s",
-                live_object_count, live_byte_count, name, name2);
-  }
-}
-
-//----------------------------------------------------------------------
-// HeapLeakChecker leak check disabling components
-//----------------------------------------------------------------------
-
-// static
-void HeapLeakChecker::DisableChecksIn(const char* pattern) {
-  RAW_LOG(WARNING, "DisableChecksIn(%s) is ignored", pattern);
-}
-
-// static
-void HeapLeakChecker::DoIgnoreObject(const void* ptr) {
-  SpinLockHolder l(&heap_checker_lock);
-  if (!heap_checker_on) return;
-  size_t object_size;
-  if (!HaveOnHeapLocked(&ptr, &object_size)) {
-    RAW_LOG(ERROR, "No live heap object at %p to ignore", ptr);
-  } else {
-    RAW_VLOG(10, "Going to ignore live object at %p of %" PRIuS " bytes",
-                ptr, object_size);
-    if (ignored_objects == NULL)  {
-      ignored_objects = new(Allocator::Allocate(sizeof(IgnoredObjectsMap)))
-                          IgnoredObjectsMap;
-    }
-    if (!ignored_objects->insert(make_pair(AsInt(ptr), object_size)).second) {
-      RAW_LOG(WARNING, "Object at %p is already being ignored", ptr);
-    }
-  }
-}
-
-// static
-void HeapLeakChecker::UnIgnoreObject(const void* ptr) {
-  SpinLockHolder l(&heap_checker_lock);
-  if (!heap_checker_on) return;
-  size_t object_size;
-  if (!HaveOnHeapLocked(&ptr, &object_size)) {
-    RAW_LOG(FATAL, "No live heap object at %p to un-ignore", ptr);
-  } else {
-    bool found = false;
-    if (ignored_objects) {
-      IgnoredObjectsMap::iterator object = ignored_objects->find(AsInt(ptr));
-      if (object != ignored_objects->end()  &&  object_size == object->second) {
-        ignored_objects->erase(object);
-        found = true;
-        RAW_VLOG(10, "Now not going to ignore live object "
-                    "at %p of %" PRIuS " bytes", ptr, object_size);
-      }
-    }
-    if (!found)  RAW_LOG(FATAL, "Object at %p has not been ignored", ptr);
-  }
-}
-
-//----------------------------------------------------------------------
-// HeapLeakChecker non-static functions
-//----------------------------------------------------------------------
-
-char* HeapLeakChecker::MakeProfileNameLocked() {
-  RAW_DCHECK(lock_->IsHeld(), "");
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  const int len = profile_name_prefix->size() + strlen(name_) + 5 +
-                  strlen(HeapProfileTable::kFileExt) + 1;
-  char* file_name = reinterpret_cast<char*>(Allocator::Allocate(len));
-  snprintf(file_name, len, "%s.%s-end%s",
-           profile_name_prefix->c_str(), name_,
-           HeapProfileTable::kFileExt);
-  return file_name;
-}
-
-void HeapLeakChecker::Create(const char *name, bool make_start_snapshot) {
-  SpinLockHolder l(lock_);
-  name_ = NULL;  // checker is inactive
-  start_snapshot_ = NULL;
-  has_checked_ = false;
-  inuse_bytes_increase_ = 0;
-  inuse_allocs_increase_ = 0;
-  keep_profiles_ = false;
-  char* n = new char[strlen(name) + 1];   // do this before we lock
-  IgnoreObject(n);  // otherwise it might be treated as live due to our stack
-  { // Heap activity in other threads is paused for this whole scope.
-    SpinLockHolder al(&alignment_checker_lock);
-    SpinLockHolder hl(&heap_checker_lock);
-    MemoryRegionMap::LockHolder ml;
-    if (heap_checker_on  &&  profile_name_prefix != NULL) {
-      RAW_DCHECK(strchr(name, '/') == NULL, "must be a simple name");
-      memcpy(n, name, strlen(name) + 1);
-      name_ = n;  // checker is active
-      if (make_start_snapshot) {
-        start_snapshot_ = heap_profile->TakeSnapshot();
-      }
-
-      const HeapProfileTable::Stats& t = heap_profile->total();
-      const size_t start_inuse_bytes = t.alloc_size - t.free_size;
-      const size_t start_inuse_allocs = t.allocs - t.frees;
-      RAW_VLOG(10, "Start check \"%s\" profile: %" PRIuS " bytes "
-               "in %" PRIuS " objects",
-               name_, start_inuse_bytes, start_inuse_allocs);
-    } else {
-      RAW_LOG(WARNING, "Heap checker is not active, "
-                       "hence checker \"%s\" will do nothing!", name);
-    RAW_LOG(WARNING, "To activate set the HEAPCHECK environment variable.\n");
-    }
-  }
-  if (name_ == NULL) {
-    UnIgnoreObject(n);
-    delete[] n;  // must be done after we unlock
-  }
-}
-
-HeapLeakChecker::HeapLeakChecker(const char *name) : lock_(new SpinLock) {
-  RAW_DCHECK(strcmp(name, "_main_") != 0, "_main_ is reserved");
-  Create(name, true/*create start_snapshot_*/);
-}
-
-HeapLeakChecker::HeapLeakChecker() : lock_(new SpinLock) {
-  if (FLAGS_heap_check_before_constructors) {
-    // We want to check for leaks of objects allocated during global
-    // constructors (i.e., objects allocated already).  So we do not
-    // create a baseline snapshot and hence check for leaks of objects
-    // that may have already been created.
-    Create("_main_", false);
-  } else {
-    // We want to ignore leaks of objects allocated during global
-    // constructors (i.e., objects allocated already).  So we snapshot
-    // the current heap contents and use them as a baseline that is
-    // not reported by the leak checker.
-    Create("_main_", true);
-  }
-}
-
-ssize_t HeapLeakChecker::BytesLeaked() const {
-  SpinLockHolder l(lock_);
-  if (!has_checked_) {
-    RAW_LOG(FATAL, "*NoLeaks|SameHeap must execute before this call");
-  }
-  return inuse_bytes_increase_;
-}
-
-ssize_t HeapLeakChecker::ObjectsLeaked() const {
-  SpinLockHolder l(lock_);
-  if (!has_checked_) {
-    RAW_LOG(FATAL, "*NoLeaks|SameHeap must execute before this call");
-  }
-  return inuse_allocs_increase_;
-}
-
-// Save pid of main thread for using in naming dump files
-static int32 main_thread_pid = getpid();
-#ifdef HAVE_PROGRAM_INVOCATION_NAME
-#ifdef __UCLIBC__
-extern const char* program_invocation_name;
-extern const char* program_invocation_short_name;
-#else
-extern char* program_invocation_name;
-extern char* program_invocation_short_name;
-#endif
-static const char* invocation_name() { return program_invocation_short_name; }
-static string invocation_path() { return program_invocation_name; }
-#else
-static const char* invocation_name() { return "<your binary>"; }
-static string invocation_path() { return "<your binary>"; }
-#endif
-
-// Prints commands that users can run to get more information
-// about the reported leaks.
-static void SuggestPprofCommand(const char* pprof_file_arg) {
-  // Extra help information to print for the user when the test is
-  // being run in a way where the straightforward pprof command will
-  // not suffice.
-  string extra_help;
-
-  // Common header info to print for remote runs
-  const string remote_header =
-      "This program is being executed remotely and therefore the pprof\n"
-      "command printed above will not work.  Either run this program\n"
-      "locally, or adjust the pprof command as follows to allow it to\n"
-      "work on your local machine:\n";
-
-  // Extra command for fetching remote data
-  string fetch_cmd;
-
-  RAW_LOG(WARNING,
-          "\n\n"
-          "If the preceding stack traces are not enough to find "
-          "the leaks, try running THIS shell command:\n\n"
-          "%s%s %s \"%s\" --inuse_objects --lines --heapcheck "
-          " --edgefraction=1e-10 --nodefraction=1e-10 --gv\n"
-          "\n"
-          "%s"
-          "If you are still puzzled about why the leaks are "
-          "there, try rerunning this program with "
-          "HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with "
-          "HEAP_CHECK_MAX_POINTER_OFFSET=-1\n"
-          "If the leak report occurs in a small fraction of runs, "
-          "try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB "
-          "or with TCMALLOC_RECLAIM_MEMORY=false, "  // only works for debugalloc
-          "it might help find leaks more repeatably\n",
-          fetch_cmd.c_str(),
-          "pprof",           // works as long as pprof is on your path
-          invocation_path().c_str(),
-          pprof_file_arg,
-          extra_help.c_str()
-          );
-}
-
-bool HeapLeakChecker::DoNoLeaks(ShouldSymbolize should_symbolize) {
-  SpinLockHolder l(lock_);
-  // The locking also helps us keep the messages
-  // for the two checks close together.
-  SpinLockHolder al(&alignment_checker_lock);
-
-  // thread-safe: protected by alignment_checker_lock
-  static bool have_disabled_hooks_for_symbolize = false;
-  // Once we've checked for leaks and symbolized the results once, it's
-  // not safe to do it again.  This is because in order to symbolize
-  // safely, we had to disable all the malloc hooks here, so we no
-  // longer can be confident we've collected all the data we need.
-  if (have_disabled_hooks_for_symbolize) {
-    RAW_LOG(FATAL, "Must not call heap leak checker manually after "
-            " program-exit's automatic check.");
-  }
-
-  HeapProfileTable::Snapshot* leaks = NULL;
-  char* pprof_file = NULL;
-
-  {
-    // Heap activity in other threads is paused during this function
-    // (i.e. until we got all profile difference info).
-    SpinLockHolder hl(&heap_checker_lock);
-    if (heap_checker_on == false) {
-      if (name_ != NULL) {  // leak checking enabled when created the checker
-        RAW_LOG(WARNING, "Heap leak checker got turned off after checker "
-                "\"%s\" has been created, no leak check is being done for it!",
-                name_);
-      }
-      return true;
-    }
-
-    // Update global_region_caller_ranges. They may need to change since
-    // e.g. initialization because shared libraries might have been loaded or
-    // unloaded.
-    Allocator::DeleteAndNullIfNot(&global_region_caller_ranges);
-    ProcMapsResult pm_result = UseProcMapsLocked(DISABLE_LIBRARY_ALLOCS);
-    RAW_CHECK(pm_result == PROC_MAPS_USED, "");
-
-    // Keep track of number of internally allocated objects so we
-    // can detect leaks in the heap-leak-checket itself
-    const int initial_allocs = Allocator::alloc_count();
-
-    if (name_ == NULL) {
-      RAW_LOG(FATAL, "Heap leak checker must not be turned on "
-              "after construction of a HeapLeakChecker");
-    }
-
-    MemoryRegionMap::LockHolder ml;
-    int a_local_var;  // Use our stack ptr to make stack data live:
-
-    // Make the heap profile, other threads are locked out.
-    HeapProfileTable::Snapshot* base =
-        reinterpret_cast<HeapProfileTable::Snapshot*>(start_snapshot_);
-    RAW_DCHECK(FLAGS_heap_check_pointer_source_alignment > 0, "");
-    pointer_source_alignment = FLAGS_heap_check_pointer_source_alignment;
-    IgnoreAllLiveObjectsLocked(&a_local_var);
-    leaks = heap_profile->NonLiveSnapshot(base);
-
-    inuse_bytes_increase_ = static_cast<ssize_t>(leaks->total().alloc_size);
-    inuse_allocs_increase_ = static_cast<ssize_t>(leaks->total().allocs);
-    if (leaks->Empty()) {
-      heap_profile->ReleaseSnapshot(leaks);
-      leaks = NULL;
-
-      // We can only check for internal leaks along the no-user-leak
-      // path since in the leak path we temporarily release
-      // heap_checker_lock and another thread can come in and disturb
-      // allocation counts.
-      if (Allocator::alloc_count() != initial_allocs) {
-        RAW_LOG(FATAL, "Internal HeapChecker leak of %d objects ; %d -> %d",
-                Allocator::alloc_count() - initial_allocs,
-                initial_allocs, Allocator::alloc_count());
-      }
-    } else if (FLAGS_heap_check_test_pointer_alignment) {
-      if (pointer_source_alignment == 1) {
-        RAW_LOG(WARNING, "--heap_check_test_pointer_alignment has no effect: "
-                "--heap_check_pointer_source_alignment was already set to 1");
-      } else {
-        // Try with reduced pointer aligment
-        pointer_source_alignment = 1;
-        IgnoreAllLiveObjectsLocked(&a_local_var);
-        HeapProfileTable::Snapshot* leaks_wo_align =
-            heap_profile->NonLiveSnapshot(base);
-        pointer_source_alignment = FLAGS_heap_check_pointer_source_alignment;
-        if (leaks_wo_align->Empty()) {
-          RAW_LOG(WARNING, "Found no leaks without pointer alignment: "
-                  "something might be placing pointers at "
-                  "unaligned addresses! This needs to be fixed.");
-        } else {
-          RAW_LOG(INFO, "Found leaks without pointer alignment as well: "
-                  "unaligned pointers must not be the cause of leaks.");
-          RAW_LOG(INFO, "--heap_check_test_pointer_alignment did not help "
-                  "to diagnose the leaks.");
-        }
-        heap_profile->ReleaseSnapshot(leaks_wo_align);
-      }
-    }
-
-    if (leaks != NULL) {
-      pprof_file = MakeProfileNameLocked();
-    }
-  }
-
-  has_checked_ = true;
-  if (leaks == NULL) {
-    if (FLAGS_heap_check_max_pointer_offset == -1) {
-      RAW_LOG(WARNING,
-              "Found no leaks without max_pointer_offset restriction: "
-              "it's possible that the default value of "
-              "heap_check_max_pointer_offset flag is too low. "
-              "Do you use pointers with larger than that offsets "
-              "pointing in the middle of heap-allocated objects?");
-    }
-    const HeapProfileTable::Stats& stats = heap_profile->total();
-    RAW_VLOG(heap_checker_info_level,
-             "No leaks found for check \"%s\" "
-             "(but no 100%% guarantee that there aren't any): "
-             "found %" PRId64 " reachable heap objects of %" PRId64 " bytes",
-             name_,
-             int64(stats.allocs - stats.frees),
-             int64(stats.alloc_size - stats.free_size));
-  } else {
-    if (should_symbolize == SYMBOLIZE) {
-      // To turn addresses into symbols, we need to fork, which is a
-      // problem if both parent and child end up trying to call the
-      // same malloc-hooks we've set up, at the same time.  To avoid
-      // trouble, we turn off the hooks before symbolizing.  Note that
-      // this makes it unsafe to ever leak-report again!  Luckily, we
-      // typically only want to report once in a program's run, at the
-      // very end.
-      if (MallocHook::GetNewHook() == NewHook)
-        MallocHook::SetNewHook(NULL);
-      if (MallocHook::GetDeleteHook() == DeleteHook)
-        MallocHook::SetDeleteHook(NULL);
-      MemoryRegionMap::Shutdown();
-      // Make sure all the hooks really got unset:
-      RAW_CHECK(MallocHook::GetNewHook() == NULL, "");
-      RAW_CHECK(MallocHook::GetDeleteHook() == NULL, "");
-      RAW_CHECK(MallocHook::GetMmapHook() == NULL, "");
-      RAW_CHECK(MallocHook::GetSbrkHook() == NULL, "");
-      have_disabled_hooks_for_symbolize = true;
-      leaks->ReportLeaks(name_, pprof_file, true);  // true = should_symbolize
-    } else {
-      leaks->ReportLeaks(name_, pprof_file, false);
-    }
-    if (FLAGS_heap_check_identify_leaks) {
-      leaks->ReportIndividualObjects();
-    }
-
-    SuggestPprofCommand(pprof_file);
-
-    {
-      SpinLockHolder hl(&heap_checker_lock);
-      heap_profile->ReleaseSnapshot(leaks);
-      Allocator::Free(pprof_file);
-    }
-  }
-
-  return (leaks == NULL);
-}
-
-HeapLeakChecker::~HeapLeakChecker() {
-  if (name_ != NULL) {  // had leak checking enabled when created the checker
-    if (!has_checked_) {
-      RAW_LOG(FATAL, "Some *NoLeaks|SameHeap method"
-                     " must be called on any created HeapLeakChecker");
-    }
-
-    // Deallocate any snapshot taken at start
-    if (start_snapshot_ != NULL) {
-      SpinLockHolder l(&heap_checker_lock);
-      heap_profile->ReleaseSnapshot(
-          reinterpret_cast<HeapProfileTable::Snapshot*>(start_snapshot_));
-    }
-
-    UnIgnoreObject(name_);
-    delete[] name_;
-    name_ = NULL;
-  }
-  delete lock_;
-}
-
-//----------------------------------------------------------------------
-// HeapLeakChecker overall heap check components
-//----------------------------------------------------------------------
-
-// static
-bool HeapLeakChecker::IsActive() {
-  SpinLockHolder l(&heap_checker_lock);
-  return heap_checker_on;
-}
-
-vector<HeapCleaner::void_function>* HeapCleaner::heap_cleanups_ = NULL;
-
-// When a HeapCleaner object is intialized, add its function to the static list
-// of cleaners to be run before leaks checking.
-HeapCleaner::HeapCleaner(void_function f) {
-  if (heap_cleanups_ == NULL)
-    heap_cleanups_ = new vector<HeapCleaner::void_function>;
-  heap_cleanups_->push_back(f);
-}
-
-// Run all of the cleanup functions and delete the vector.
-void HeapCleaner::RunHeapCleanups() {
-  if (!heap_cleanups_)
-    return;
-  for (int i = 0; i < heap_cleanups_->size(); i++) {
-    void (*f)(void) = (*heap_cleanups_)[i];
-    f();
-  }
-  delete heap_cleanups_;
-  heap_cleanups_ = NULL;
-}
-
-// Program exit heap cleanup registered as a module object destructor.
-// Will not get executed when we crash on a signal.
-//
-void HeapLeakChecker_RunHeapCleanups() {
-  if (FLAGS_heap_check == "local")   // don't check heap in this mode
-    return;
-  { SpinLockHolder l(&heap_checker_lock);
-    // can get here (via forks?) with other pids
-    if (heap_checker_pid != getpid()) return;
-  }
-  HeapCleaner::RunHeapCleanups();
-  if (!FLAGS_heap_check_after_destructors) HeapLeakChecker::DoMainHeapCheck();
-}
-
-static bool internal_init_start_has_run = false;
-
-// Called exactly once, before main() (but hopefully just before).
-// This picks a good unique name for the dumped leak checking heap profiles.
-//
-// Because we crash when InternalInitStart is called more than once,
-// it's fine that we hold heap_checker_lock only around pieces of
-// this function: this is still enough for thread-safety w.r.t. other functions
-// of this module.
-// We can't hold heap_checker_lock throughout because it would deadlock
-// on a memory allocation since our new/delete hooks can be on.
-//
-void HeapLeakChecker_InternalInitStart() {
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_CHECK(!internal_init_start_has_run,
-              "Heap-check constructor called twice.  Perhaps you both linked"
-              " in the heap checker, and also used LD_PRELOAD to load it?");
-    internal_init_start_has_run = true;
-
-#ifdef ADDRESS_SANITIZER
-    // AddressSanitizer's custom malloc conflicts with HeapChecker.
-    FLAGS_heap_check = "";
-#endif
-
-    if (FLAGS_heap_check.empty()) {
-      // turns out we do not need checking in the end; can stop profiling
-      HeapLeakChecker::TurnItselfOffLocked();
-      return;
-    } else if (RunningOnValgrind()) {
-      // There is no point in trying -- we'll just fail.
-      RAW_LOG(WARNING, "Can't run under Valgrind; will turn itself off");
-      HeapLeakChecker::TurnItselfOffLocked();
-      return;
-    }
-  }
-
-  // Changing this to false can be useful when debugging heap-checker itself:
-  if (!FLAGS_heap_check_run_under_gdb && IsDebuggerAttached()) {
-    RAW_LOG(WARNING, "Someone is ptrace()ing us; will turn itself off");
-    SpinLockHolder l(&heap_checker_lock);
-    HeapLeakChecker::TurnItselfOffLocked();
-    return;
-  }
-
-  { SpinLockHolder l(&heap_checker_lock);
-    if (!constructor_heap_profiling) {
-      RAW_LOG(FATAL, "Can not start so late. You have to enable heap checking "
-	             "with HEAPCHECK=<mode>.");
-    }
-  }
-
-  // Set all flags
-  RAW_DCHECK(FLAGS_heap_check_pointer_source_alignment > 0, "");
-  if (FLAGS_heap_check == "minimal") {
-    // The least we can check.
-    FLAGS_heap_check_before_constructors = false;  // from after main
-                                                   // (ignore more)
-    FLAGS_heap_check_after_destructors = false;  // to after cleanup
-                                                 // (most data is live)
-    FLAGS_heap_check_ignore_thread_live = true;  // ignore all live
-    FLAGS_heap_check_ignore_global_live = true;  // ignore all live
-  } else if (FLAGS_heap_check == "normal") {
-    // Faster than 'minimal' and not much stricter.
-    FLAGS_heap_check_before_constructors = true;  // from no profile (fast)
-    FLAGS_heap_check_after_destructors = false;  // to after cleanup
-                                                 // (most data is live)
-    FLAGS_heap_check_ignore_thread_live = true;  // ignore all live
-    FLAGS_heap_check_ignore_global_live = true;  // ignore all live
-  } else if (FLAGS_heap_check == "strict") {
-    // A bit stricter than 'normal': global destructors must fully clean up
-    // after themselves if they are present.
-    FLAGS_heap_check_before_constructors = true;  // from no profile (fast)
-    FLAGS_heap_check_after_destructors = true;  // to after destructors
-                                                // (less data live)
-    FLAGS_heap_check_ignore_thread_live = true;  // ignore all live
-    FLAGS_heap_check_ignore_global_live = true;  // ignore all live
-  } else if (FLAGS_heap_check == "draconian") {
-    // Drop not very portable and not very exact live heap flooding.
-    FLAGS_heap_check_before_constructors = true;  // from no profile (fast)
-    FLAGS_heap_check_after_destructors = true;  // to after destructors
-                                                // (need them)
-    FLAGS_heap_check_ignore_thread_live = false;  // no live flood (stricter)
-    FLAGS_heap_check_ignore_global_live = false;  // no live flood (stricter)
-  } else if (FLAGS_heap_check == "as-is") {
-    // do nothing: use other flags as is
-  } else if (FLAGS_heap_check == "local") {
-    // do nothing
-  } else {
-    RAW_LOG(FATAL, "Unsupported heap_check flag: %s",
-                   FLAGS_heap_check.c_str());
-  }
-  // FreeBSD doesn't seem to honor atexit execution order:
-  //    http://code.google.com/p/gperftools/issues/detail?id=375
-  // Since heap-checking before destructors depends on atexit running
-  // at the right time, on FreeBSD we always check after, even in the
-  // less strict modes.  This just means FreeBSD is always a bit
-  // stricter in its checking than other OSes.
-  // This now appears to be the case in other OSes as well;
-  // so always check afterwards.
-  FLAGS_heap_check_after_destructors = true;
-
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_DCHECK(heap_checker_pid == getpid(), "");
-    heap_checker_on = true;
-    RAW_DCHECK(heap_profile, "");
-    HeapLeakChecker::ProcMapsResult pm_result = HeapLeakChecker::UseProcMapsLocked(HeapLeakChecker::DISABLE_LIBRARY_ALLOCS);
-      // might neeed to do this more than once
-      // if one later dynamically loads libraries that we want disabled
-    if (pm_result != HeapLeakChecker::PROC_MAPS_USED) {  // can't function
-      HeapLeakChecker::TurnItselfOffLocked();
-      return;
-    }
-  }
-
-  // make a good place and name for heap profile leak dumps
-  string* profile_prefix =
-    new string(FLAGS_heap_check_dump_directory + "/" + invocation_name());
-
-  // Finalize prefix for dumping leak checking profiles.
-  const int32 our_pid = getpid();   // safest to call getpid() outside lock
-  { SpinLockHolder l(&heap_checker_lock);
-    // main_thread_pid might still be 0 if this function is being called before
-    // global constructors.  In that case, our pid *is* the main pid.
-    if (main_thread_pid == 0)
-      main_thread_pid = our_pid;
-  }
-  char pid_buf[15];
-  snprintf(pid_buf, sizeof(pid_buf), ".%d", main_thread_pid);
-  *profile_prefix += pid_buf;
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_DCHECK(profile_name_prefix == NULL, "");
-    profile_name_prefix = profile_prefix;
-  }
-
-  // Make sure new/delete hooks are installed properly
-  // and heap profiler is indeed able to keep track
-  // of the objects being allocated.
-  // We test this to make sure we are indeed checking for leaks.
-  char* test_str = new char[5];
-  size_t size;
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_CHECK(heap_profile->FindAlloc(test_str, &size),
-              "our own new/delete not linked?");
-  }
-  delete[] test_str;
-  { SpinLockHolder l(&heap_checker_lock);
-    // This check can fail when it should not if another thread allocates
-    // into this same spot right this moment,
-    // which is unlikely since this code runs in InitGoogle.
-    RAW_CHECK(!heap_profile->FindAlloc(test_str, &size),
-              "our own new/delete not linked?");
-  }
-  // If we crash in the above code, it probably means that
-  // "nm <this_binary> | grep new" will show that tcmalloc's new/delete
-  // implementation did not get linked-in into this binary
-  // (i.e. nm will list __builtin_new and __builtin_vec_new as undefined).
-  // If this happens, it is a BUILD bug to be fixed.
-
-  RAW_VLOG(heap_checker_info_level,
-           "WARNING: Perftools heap leak checker is active "
-           "-- Performance may suffer");
-
-  if (FLAGS_heap_check != "local") {
-    HeapLeakChecker* main_hc = new HeapLeakChecker();
-    SpinLockHolder l(&heap_checker_lock);
-    RAW_DCHECK(main_heap_checker == NULL,
-               "Repeated creation of main_heap_checker");
-    main_heap_checker = main_hc;
-    do_main_heap_check = true;
-  }
-
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_CHECK(heap_checker_on  &&  constructor_heap_profiling,
-              "Leak checking is expected to be fully turned on now");
-  }
-
-  // For binaries built in debug mode, this will set release queue of
-  // debugallocation.cc to 100M to make it less likely for real leaks to
-  // be hidden due to reuse of heap memory object addresses.
-  // Running a test with --malloc_reclaim_memory=0 would help find leaks even
-  // better, but the test might run out of memory as a result.
-  // The scenario is that a heap object at address X is allocated and freed,
-  // but some other data-structure still retains a pointer to X.
-  // Then the same heap memory is used for another object, which is leaked,
-  // but the leak is not noticed due to the pointer to the original object at X.
-  // TODO(csilvers): support this in some manner.
-#if 0
-  SetCommandLineOptionWithMode("max_free_queue_size", "104857600",  // 100M
-                               SET_FLAG_IF_DEFAULT);
-#endif
-}
-
-// We want this to run early as well, but not so early as
-// ::BeforeConstructors (we want flag assignments to have already
-// happened, for instance).  Initializer-registration does the trick.
-REGISTER_MODULE_INITIALIZER(init_start, HeapLeakChecker_InternalInitStart());
-REGISTER_MODULE_DESTRUCTOR(init_start, HeapLeakChecker_RunHeapCleanups());
-
-// static
-bool HeapLeakChecker::NoGlobalLeaksMaybeSymbolize(
-    ShouldSymbolize should_symbolize) {
-  // we never delete or change main_heap_checker once it's set:
-  HeapLeakChecker* main_hc = GlobalChecker();
-  if (main_hc) {
-    RAW_VLOG(10, "Checking for whole-program memory leaks");
-    return main_hc->DoNoLeaks(should_symbolize);
-  }
-  return true;
-}
-
-// static
-bool HeapLeakChecker::DoMainHeapCheck() {
-  if (FLAGS_heap_check_delay_seconds > 0) {
-    sleep(FLAGS_heap_check_delay_seconds);
-  }
-  { SpinLockHolder l(&heap_checker_lock);
-    if (!do_main_heap_check) return false;
-    RAW_DCHECK(heap_checker_pid == getpid(), "");
-    do_main_heap_check = false;  // will do it now; no need to do it more
-  }
-
-  // The program is over, so it's safe to symbolize addresses (which
-  // requires a fork) because no serious work is expected to be done
-  // after this.  Symbolizing is really useful -- knowing what
-  // function has a leak is better than knowing just an address --
-  // and while we can only safely symbolize once in a program run,
-  // now is the time (after all, there's no "later" that would be better).
-  if (!NoGlobalLeaksMaybeSymbolize(SYMBOLIZE)) {
-    if (FLAGS_heap_check_identify_leaks) {
-      RAW_LOG(FATAL, "Whole-program memory leaks found.");
-    }
-    RAW_LOG(ERROR, "Exiting with error code (instead of crashing) "
-                   "because of whole-program memory leaks");
-    _exit(1);    // we don't want to call atexit() routines!
-  }
-  return true;
-}
-
-// static
-HeapLeakChecker* HeapLeakChecker::GlobalChecker() {
-  SpinLockHolder l(&heap_checker_lock);
-  return main_heap_checker;
-}
-
-// static
-bool HeapLeakChecker::NoGlobalLeaks() {
-  // symbolizing requires a fork, which isn't safe to do in general.
-  return NoGlobalLeaksMaybeSymbolize(DO_NOT_SYMBOLIZE);
-}
-
-// static
-void HeapLeakChecker::CancelGlobalCheck() {
-  SpinLockHolder l(&heap_checker_lock);
-  if (do_main_heap_check) {
-    RAW_VLOG(heap_checker_info_level,
-             "Canceling the automatic at-exit whole-program memory leak check");
-    do_main_heap_check = false;
-  }
-}
-
-// static
-void HeapLeakChecker::BeforeConstructorsLocked() {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_CHECK(!constructor_heap_profiling,
-            "BeforeConstructorsLocked called multiple times");
-#ifdef ADDRESS_SANITIZER
-  // AddressSanitizer's custom malloc conflicts with HeapChecker.
-  return;
-#endif
-  // Set hooks early to crash if 'new' gets called before we make heap_profile,
-  // and make sure no other hooks existed:
-  RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
-  RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
-  constructor_heap_profiling = true;
-  MemoryRegionMap::Init(1, /* use_buckets */ false);
-    // Set up MemoryRegionMap with (at least) one caller stack frame to record
-    // (important that it's done before HeapProfileTable creation below).
-  Allocator::Init();
-  RAW_CHECK(heap_profile == NULL, "");
-  heap_profile = new(Allocator::Allocate(sizeof(HeapProfileTable)))
-      HeapProfileTable(&Allocator::Allocate, &Allocator::Free,
-                       /* profile_mmap */ false);
-  RAW_VLOG(10, "Starting tracking the heap");
-  heap_checker_on = true;
-}
-
-// static
-void HeapLeakChecker::TurnItselfOffLocked() {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  // Set FLAGS_heap_check to "", for users who test for it
-  if (!FLAGS_heap_check.empty())  // be a noop in the common case
-    FLAGS_heap_check.clear();     // because clear() could allocate memory
-  if (constructor_heap_profiling) {
-    RAW_CHECK(heap_checker_on, "");
-    RAW_VLOG(heap_checker_info_level, "Turning perftools heap leak checking off");
-    heap_checker_on = false;
-    // Unset our hooks checking they were set:
-    RAW_CHECK(MallocHook::RemoveNewHook(&NewHook), "");
-    RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), "");
-    Allocator::DeleteAndNull(&heap_profile);
-    // free our optional global data:
-    Allocator::DeleteAndNullIfNot(&ignored_objects);
-    Allocator::DeleteAndNullIfNot(&disabled_ranges);
-    Allocator::DeleteAndNullIfNot(&global_region_caller_ranges);
-    Allocator::Shutdown();
-    MemoryRegionMap::Shutdown();
-  }
-  RAW_CHECK(!heap_checker_on, "");
-}
-
-extern bool heap_leak_checker_bcad_variable;  // in heap-checker-bcad.cc
-
-static bool has_called_before_constructors = false;
-
-// TODO(maxim): inline this function with
-// MallocHook_InitAtFirstAllocation_HeapLeakChecker, and also rename
-// HeapLeakChecker::BeforeConstructorsLocked.
-void HeapLeakChecker_BeforeConstructors() {
-  SpinLockHolder l(&heap_checker_lock);
-  // We can be called from several places: the first mmap/sbrk/alloc call
-  // or the first global c-tor from heap-checker-bcad.cc:
-  // Do not re-execute initialization:
-  if (has_called_before_constructors) return;
-  has_called_before_constructors = true;
-
-  heap_checker_pid = getpid();  // set it always
-  heap_leak_checker_bcad_variable = true;
-  // just to reference it, so that heap-checker-bcad.o is linked in
-
-  // This function can be called *very* early, before the normal
-  // global-constructor that sets FLAGS_verbose.  Set it manually now,
-  // so the RAW_LOG messages here are controllable.
-  const char* verbose_str = GetenvBeforeMain("PERFTOOLS_VERBOSE");
-  if (verbose_str && atoi(verbose_str)) {  // different than the default of 0?
-    FLAGS_verbose = atoi(verbose_str);
-  }
-
-  bool need_heap_check = true;
-  // The user indicates a desire for heap-checking via the HEAPCHECK
-  // environment variable.  If it's not set, there's no way to do
-  // heap-checking.
-  if (!GetenvBeforeMain("HEAPCHECK")) {
-    need_heap_check = false;
-  }
-#ifdef HAVE_GETEUID
-  if (need_heap_check && getuid() != geteuid()) {
-    // heap-checker writes out files.  Thus, for security reasons, we don't
-    // recognize the env. var. to turn on heap-checking if we're setuid.
-    RAW_LOG(WARNING, ("HeapChecker: ignoring HEAPCHECK because "
-                      "program seems to be setuid\n"));
-    need_heap_check = false;
-  }
-#endif
-  if (need_heap_check) {
-    HeapLeakChecker::BeforeConstructorsLocked();
-  }
-}
-
-// This function overrides the weak function defined in malloc_hook.cc and
-// called by one of the initial malloc hooks (malloc_hook.cc) when the very
-// first memory allocation or an mmap/sbrk happens.  This ensures that
-// HeapLeakChecker is initialized and installs all its hooks early enough to
-// track absolutely all memory allocations and all memory region acquisitions
-// via mmap and sbrk.
-extern "C" void MallocHook_InitAtFirstAllocation_HeapLeakChecker() {
-  HeapLeakChecker_BeforeConstructors();
-}
-
-// This function is executed after all global object destructors run.
-void HeapLeakChecker_AfterDestructors() {
-  { SpinLockHolder l(&heap_checker_lock);
-    // can get here (via forks?) with other pids
-    if (heap_checker_pid != getpid()) return;
-  }
-  if (FLAGS_heap_check_after_destructors) {
-    if (HeapLeakChecker::DoMainHeapCheck()) {
-      const struct timespec sleep_time = { 0, 500000000 };  // 500 ms
-      nanosleep(&sleep_time, NULL);
-        // Need this hack to wait for other pthreads to exit.
-        // Otherwise tcmalloc find errors
-        // on a free() call from pthreads.
-    }
-  }
-  SpinLockHolder l(&heap_checker_lock);
-  RAW_CHECK(!do_main_heap_check, "should have done it");
-}
-
-//----------------------------------------------------------------------
-// HeapLeakChecker disabling helpers
-//----------------------------------------------------------------------
-
-// These functions are at the end of the file to prevent their inlining:
-
-// static
-void HeapLeakChecker::DisableChecksFromToLocked(const void* start_address,
-                                                const void* end_address,
-                                                int max_depth) {
-  RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  RAW_DCHECK(start_address < end_address, "");
-  if (disabled_ranges == NULL) {
-    disabled_ranges = new(Allocator::Allocate(sizeof(DisabledRangeMap)))
-                        DisabledRangeMap;
-  }
-  RangeValue value;
-  value.start_address = AsInt(start_address);
-  value.max_depth = max_depth;
-  if (disabled_ranges->insert(make_pair(AsInt(end_address), value)).second) {
-    RAW_VLOG(10, "Disabling leak checking in stack traces "
-                "under frame addresses between %p..%p",
-                start_address, end_address);
-  } else {  // check that this is just a verbatim repetition
-    RangeValue const& val = disabled_ranges->find(AsInt(end_address))->second;
-    if (val.max_depth != value.max_depth  ||
-        val.start_address != value.start_address) {
-      RAW_LOG(FATAL, "Two DisableChecksToHereFrom calls conflict: "
-                     "(%p, %p, %d) vs. (%p, %p, %d)",
-                     AsPtr(val.start_address), end_address, val.max_depth,
-                     start_address, end_address, max_depth);
-    }
-  }
-}
-
-// static
-inline bool HeapLeakChecker::HaveOnHeapLocked(const void** ptr,
-                                              size_t* object_size) {
-  // Commented-out because HaveOnHeapLocked is very performance-critical:
-  // RAW_DCHECK(heap_checker_lock.IsHeld(), "");
-  const uintptr_t addr = AsInt(*ptr);
-  if (heap_profile->FindInsideAlloc(
-        *ptr, max_heap_object_size, ptr, object_size)) {
-    RAW_VLOG(16, "Got pointer into %p at +%" PRIuPTR " offset",
-             *ptr, addr - AsInt(*ptr));
-    return true;
-  }
-  return false;
-}
-
-// static
-const void* HeapLeakChecker::GetAllocCaller(void* ptr) {
-  // this is used only in the unittest, so the heavy checks are fine
-  HeapProfileTable::AllocInfo info;
-  { SpinLockHolder l(&heap_checker_lock);
-    RAW_CHECK(heap_profile->FindAllocDetails(ptr, &info), "");
-  }
-  RAW_CHECK(info.stack_depth >= 1, "");
-  return info.call_stack[0];
-}
diff --git a/third_party/tcmalloc/vendor/src/heap-profile-stats.h b/third_party/tcmalloc/vendor/src/heap-profile-stats.h
deleted file mode 100644
index ae45d588..0000000
--- a/third_party/tcmalloc/vendor/src/heap-profile-stats.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2013, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file defines structs to accumulate memory allocation and deallocation
-// counts.  These structs are commonly used for malloc (in HeapProfileTable)
-// and mmap (in MemoryRegionMap).
-
-// A bucket is data structure for heap profiling to store a pair of a stack
-// trace and counts of (de)allocation.  Buckets are stored in a hash table
-// which is declared as "HeapProfileBucket**".
-//
-// A hash value is computed from a stack trace.  Collision in the hash table
-// is resolved by separate chaining with linked lists.  The links in the list
-// are implemented with the member "HeapProfileBucket* next".
-//
-// A structure of a hash table HeapProfileBucket** bucket_table would be like:
-// bucket_table[0] => NULL
-// bucket_table[1] => HeapProfileBucket() => HeapProfileBucket() => NULL
-// ...
-// bucket_table[i] => HeapProfileBucket() => NULL
-// ...
-// bucket_table[n] => HeapProfileBucket() => NULL
-
-#ifndef HEAP_PROFILE_STATS_H_
-#define HEAP_PROFILE_STATS_H_
-
-struct HeapProfileStats {
-  // Returns true if the two HeapProfileStats are semantically equal.
-  bool Equivalent(const HeapProfileStats& other) const {
-    return allocs - frees == other.allocs - other.frees &&
-        alloc_size - free_size == other.alloc_size - other.free_size;
-  }
-
-  int32 allocs;      // Number of allocation calls.
-  int32 frees;       // Number of free calls.
-  int64 alloc_size;  // Total size of all allocated objects so far.
-  int64 free_size;   // Total size of all freed objects so far.
-};
-
-// Allocation and deallocation statistics per each stack trace.
-struct HeapProfileBucket : public HeapProfileStats {
-  // Longest stack trace we record.
-  static const int kMaxStackDepth = 32;
-
-  uintptr_t hash;           // Hash value of the stack trace.
-  int depth;                // Depth of stack trace.
-  const void** stack;       // Stack trace.
-  HeapProfileBucket* next;  // Next entry in hash-table.
-};
-
-#endif  // HEAP_PROFILE_STATS_H_
diff --git a/third_party/tcmalloc/vendor/src/heap-profile-table.cc b/third_party/tcmalloc/vendor/src/heap-profile-table.cc
deleted file mode 100644
index 7486468c..0000000
--- a/third_party/tcmalloc/vendor/src/heap-profile-table.cc
+++ /dev/null
@@ -1,631 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//         Maxim Lifantsev (refactoring)
-//
-
-#include <config.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>   // for write()
-#endif
-#include <fcntl.h>    // for open()
-#ifdef HAVE_GLOB_H
-#include <glob.h>
-#ifndef GLOB_NOMATCH  // true on some old cygwins
-# define GLOB_NOMATCH 0
-#endif
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h> // for PRIxPTR
-#endif
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif
-#include <errno.h>
-#include <stdarg.h>
-#include <string>
-#include <map>
-#include <algorithm>  // for sort(), equal(), and copy()
-
-#include "heap-profile-table.h"
-
-#include "base/logging.h"
-#include "raw_printer.h"
-#include "symbolize.h"
-#include <gperftools/stacktrace.h>
-#include <gperftools/malloc_hook.h>
-#include "memory_region_map.h"
-#include "base/commandlineflags.h"
-#include "base/logging.h"    // for the RawFD I/O commands
-#include "base/sysinfo.h"
-
-using std::sort;
-using std::equal;
-using std::copy;
-using std::string;
-using std::map;
-
-using tcmalloc::FillProcSelfMaps;   // from sysinfo.h
-using tcmalloc::DumpProcSelfMaps;   // from sysinfo.h
-
-//----------------------------------------------------------------------
-
-DEFINE_bool(cleanup_old_heap_profiles,
-            EnvToBool("HEAP_PROFILE_CLEANUP", true),
-            "At initialization time, delete old heap profiles.");
-
-DEFINE_int32(heap_check_max_leaks,
-             EnvToInt("HEAP_CHECK_MAX_LEAKS", 20),
-             "The maximum number of leak reports to print.");
-
-//----------------------------------------------------------------------
-
-// header of the dumped heap profile
-static const char kProfileHeader[] = "heap profile: ";
-static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n";
-
-//----------------------------------------------------------------------
-
-const char HeapProfileTable::kFileExt[] = ".heap";
-
-//----------------------------------------------------------------------
-
-static const int kHashTableSize = 179999;   // Size for bucket_table_.
-/*static*/ const int HeapProfileTable::kMaxStackDepth;
-
-//----------------------------------------------------------------------
-
-// We strip out different number of stack frames in debug mode
-// because less inlining happens in that case
-#ifdef NDEBUG
-static const int kStripFrames = 2;
-#else
-static const int kStripFrames = 3;
-#endif
-
-// For sorting Stats or Buckets by in-use space
-static bool ByAllocatedSpace(HeapProfileTable::Stats* a,
-                             HeapProfileTable::Stats* b) {
-  // Return true iff "a" has more allocated space than "b"
-  return (a->alloc_size - a->free_size) > (b->alloc_size - b->free_size);
-}
-
-//----------------------------------------------------------------------
-
-HeapProfileTable::HeapProfileTable(Allocator alloc,
-                                   DeAllocator dealloc,
-                                   bool profile_mmap)
-    : alloc_(alloc),
-      dealloc_(dealloc),
-      profile_mmap_(profile_mmap),
-      bucket_table_(NULL),
-      num_buckets_(0),
-      address_map_(NULL) {
-  // Make a hash table for buckets.
-  const int table_bytes = kHashTableSize * sizeof(*bucket_table_);
-  bucket_table_ = static_cast<Bucket**>(alloc_(table_bytes));
-  memset(bucket_table_, 0, table_bytes);
-
-  // Make an allocation map.
-  address_map_ =
-      new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_);
-
-  // Initialize.
-  memset(&total_, 0, sizeof(total_));
-  num_buckets_ = 0;
-}
-
-HeapProfileTable::~HeapProfileTable() {
-  // Free the allocation map.
-  address_map_->~AllocationMap();
-  dealloc_(address_map_);
-  address_map_ = NULL;
-
-  // Free the hash table.
-  for (int i = 0; i < kHashTableSize; i++) {
-    for (Bucket* curr = bucket_table_[i]; curr != 0; /**/) {
-      Bucket* bucket = curr;
-      curr = curr->next;
-      dealloc_(bucket->stack);
-      dealloc_(bucket);
-    }
-  }
-  dealloc_(bucket_table_);
-  bucket_table_ = NULL;
-}
-
-HeapProfileTable::Bucket* HeapProfileTable::GetBucket(int depth,
-                                                      const void* const key[]) {
-  // Make hash-value
-  uintptr_t h = 0;
-  for (int i = 0; i < depth; i++) {
-    h += reinterpret_cast<uintptr_t>(key[i]);
-    h += h << 10;
-    h ^= h >> 6;
-  }
-  h += h << 3;
-  h ^= h >> 11;
-
-  // Lookup stack trace in table
-  unsigned int buck = ((unsigned int) h) % kHashTableSize;
-  for (Bucket* b = bucket_table_[buck]; b != 0; b = b->next) {
-    if ((b->hash == h) &&
-        (b->depth == depth) &&
-        equal(key, key + depth, b->stack)) {
-      return b;
-    }
-  }
-
-  // Create new bucket
-  const size_t key_size = sizeof(key[0]) * depth;
-  const void** kcopy = reinterpret_cast<const void**>(alloc_(key_size));
-  copy(key, key + depth, kcopy);
-  Bucket* b = reinterpret_cast<Bucket*>(alloc_(sizeof(Bucket)));
-  memset(b, 0, sizeof(*b));
-  b->hash  = h;
-  b->depth = depth;
-  b->stack = kcopy;
-  b->next  = bucket_table_[buck];
-  bucket_table_[buck] = b;
-  num_buckets_++;
-  return b;
-}
-
-int HeapProfileTable::GetCallerStackTrace(
-    int skip_count, void* stack[kMaxStackDepth]) {
-  return MallocHook::GetCallerStackTrace(
-      stack, kMaxStackDepth, kStripFrames + skip_count + 1);
-}
-
-void HeapProfileTable::RecordAlloc(
-    const void* ptr, size_t bytes, int stack_depth,
-    const void* const call_stack[]) {
-  Bucket* b = GetBucket(stack_depth, call_stack);
-  b->allocs++;
-  b->alloc_size += bytes;
-  total_.allocs++;
-  total_.alloc_size += bytes;
-
-  AllocValue v;
-  v.set_bucket(b);  // also did set_live(false); set_ignore(false)
-  v.bytes = bytes;
-  address_map_->Insert(ptr, v);
-}
-
-void HeapProfileTable::RecordFree(const void* ptr) {
-  AllocValue v;
-  if (address_map_->FindAndRemove(ptr, &v)) {
-    Bucket* b = v.bucket();
-    b->frees++;
-    b->free_size += v.bytes;
-    total_.frees++;
-    total_.free_size += v.bytes;
-  }
-}
-
-bool HeapProfileTable::FindAlloc(const void* ptr, size_t* object_size) const {
-  const AllocValue* alloc_value = address_map_->Find(ptr);
-  if (alloc_value != NULL) *object_size = alloc_value->bytes;
-  return alloc_value != NULL;
-}
-
-bool HeapProfileTable::FindAllocDetails(const void* ptr,
-                                        AllocInfo* info) const {
-  const AllocValue* alloc_value = address_map_->Find(ptr);
-  if (alloc_value != NULL) {
-    info->object_size = alloc_value->bytes;
-    info->call_stack = alloc_value->bucket()->stack;
-    info->stack_depth = alloc_value->bucket()->depth;
-  }
-  return alloc_value != NULL;
-}
-
-bool HeapProfileTable::FindInsideAlloc(const void* ptr,
-                                       size_t max_size,
-                                       const void** object_ptr,
-                                       size_t* object_size) const {
-  const AllocValue* alloc_value =
-    address_map_->FindInside(&AllocValueSize, max_size, ptr, object_ptr);
-  if (alloc_value != NULL) *object_size = alloc_value->bytes;
-  return alloc_value != NULL;
-}
-
-bool HeapProfileTable::MarkAsLive(const void* ptr) {
-  AllocValue* alloc = address_map_->FindMutable(ptr);
-  if (alloc && !alloc->live()) {
-    alloc->set_live(true);
-    return true;
-  }
-  return false;
-}
-
-void HeapProfileTable::MarkAsIgnored(const void* ptr) {
-  AllocValue* alloc = address_map_->FindMutable(ptr);
-  if (alloc) {
-    alloc->set_ignore(true);
-  }
-}
-
-// We'd be happier using snprintfer, but we don't to reduce dependencies.
-int HeapProfileTable::UnparseBucket(const Bucket& b,
-                                    char* buf, int buflen, int bufsize,
-                                    const char* extra,
-                                    Stats* profile_stats) {
-  if (profile_stats != NULL) {
-    profile_stats->allocs += b.allocs;
-    profile_stats->alloc_size += b.alloc_size;
-    profile_stats->frees += b.frees;
-    profile_stats->free_size += b.free_size;
-  }
-  int printed =
-    snprintf(buf + buflen, bufsize - buflen, "%6d: %8" PRId64 " [%6d: %8" PRId64 "] @%s",
-             b.allocs - b.frees,
-             b.alloc_size - b.free_size,
-             b.allocs,
-             b.alloc_size,
-             extra);
-  // If it looks like the snprintf failed, ignore the fact we printed anything
-  if (printed < 0 || printed >= bufsize - buflen) return buflen;
-  buflen += printed;
-  for (int d = 0; d < b.depth; d++) {
-    printed = snprintf(buf + buflen, bufsize - buflen, " 0x%08" PRIxPTR,
-                       reinterpret_cast<uintptr_t>(b.stack[d]));
-    if (printed < 0 || printed >= bufsize - buflen) return buflen;
-    buflen += printed;
-  }
-  printed = snprintf(buf + buflen, bufsize - buflen, "\n");
-  if (printed < 0 || printed >= bufsize - buflen) return buflen;
-  buflen += printed;
-  return buflen;
-}
-
-HeapProfileTable::Bucket**
-HeapProfileTable::MakeSortedBucketList() const {
-  Bucket** list = static_cast<Bucket**>(alloc_(sizeof(Bucket) * num_buckets_));
-
-  int bucket_count = 0;
-  for (int i = 0; i < kHashTableSize; i++) {
-    for (Bucket* curr = bucket_table_[i]; curr != 0; curr = curr->next) {
-      list[bucket_count++] = curr;
-    }
-  }
-  RAW_DCHECK(bucket_count == num_buckets_, "");
-
-  sort(list, list + num_buckets_, ByAllocatedSpace);
-
-  return list;
-}
-
-void HeapProfileTable::IterateOrderedAllocContexts(
-    AllocContextIterator callback) const {
-  Bucket** list = MakeSortedBucketList();
-  AllocContextInfo info;
-  for (int i = 0; i < num_buckets_; ++i) {
-    *static_cast<Stats*>(&info) = *static_cast<Stats*>(list[i]);
-    info.stack_depth = list[i]->depth;
-    info.call_stack = list[i]->stack;
-    callback(info);
-  }
-  dealloc_(list);
-}
-
-int HeapProfileTable::FillOrderedProfile(char buf[], int size) const {
-  Bucket** list = MakeSortedBucketList();
-
-  // Our file format is "bucket, bucket, ..., bucket, proc_self_maps_info".
-  // In the cases buf is too small, we'd rather leave out the last
-  // buckets than leave out the /proc/self/maps info.  To ensure that,
-  // we actually print the /proc/self/maps info first, then move it to
-  // the end of the buffer, then write the bucket info into whatever
-  // is remaining, and then move the maps info one last time to close
-  // any gaps.  Whew!
-  int map_length = snprintf(buf, size, "%s", kProcSelfMapsHeader);
-  if (map_length < 0 || map_length >= size) {
-      dealloc_(list);
-      return 0;
-  }
-  bool dummy;   // "wrote_all" -- did /proc/self/maps fit in its entirety?
-  map_length += FillProcSelfMaps(buf + map_length, size - map_length, &dummy);
-  RAW_DCHECK(map_length <= size, "");
-  char* const map_start = buf + size - map_length;      // move to end
-  memmove(map_start, buf, map_length);
-  size -= map_length;
-
-  Stats stats;
-  memset(&stats, 0, sizeof(stats));
-  int bucket_length = snprintf(buf, size, "%s", kProfileHeader);
-  if (bucket_length < 0 || bucket_length >= size) {
-      dealloc_(list);
-      return 0;
-  }
-  bucket_length = UnparseBucket(total_, buf, bucket_length, size,
-                                " heapprofile", &stats);
-
-  // Dump the mmap list first.
-  if (profile_mmap_) {
-    BufferArgs buffer(buf, bucket_length, size);
-    MemoryRegionMap::IterateBuckets<BufferArgs*>(DumpBucketIterator, &buffer);
-    bucket_length = buffer.buflen;
-  }
-
-  for (int i = 0; i < num_buckets_; i++) {
-    bucket_length = UnparseBucket(*list[i], buf, bucket_length, size, "",
-                                  &stats);
-  }
-  RAW_DCHECK(bucket_length < size, "");
-
-  dealloc_(list);
-
-  RAW_DCHECK(buf + bucket_length <= map_start, "");
-  memmove(buf + bucket_length, map_start, map_length);  // close the gap
-
-  return bucket_length + map_length;
-}
-
-// static
-void HeapProfileTable::DumpBucketIterator(const Bucket* bucket,
-                                          BufferArgs* args) {
-  args->buflen = UnparseBucket(*bucket, args->buf, args->buflen, args->bufsize,
-                               "", NULL);
-}
-
-inline
-void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v,
-                                           const DumpArgs& args) {
-  if (v->live()) {
-    v->set_live(false);
-    return;
-  }
-  if (v->ignore()) {
-    return;
-  }
-  Bucket b;
-  memset(&b, 0, sizeof(b));
-  b.allocs = 1;
-  b.alloc_size = v->bytes;
-  b.depth = v->bucket()->depth;
-  b.stack = v->bucket()->stack;
-  char buf[1024];
-  int len = UnparseBucket(b, buf, 0, sizeof(buf), "", args.profile_stats);
-  RawWrite(args.fd, buf, len);
-}
-
-// Callback from NonLiveSnapshot; adds entry to arg->dest
-// if not the entry is not live and is not present in arg->base.
-void HeapProfileTable::AddIfNonLive(const void* ptr, AllocValue* v,
-                                    AddNonLiveArgs* arg) {
-  if (v->live()) {
-    v->set_live(false);
-  } else {
-    if (arg->base != NULL && arg->base->map_.Find(ptr) != NULL) {
-      // Present in arg->base, so do not save
-    } else {
-      arg->dest->Add(ptr, *v);
-    }
-  }
-}
-
-bool HeapProfileTable::WriteProfile(const char* file_name,
-                                    const Bucket& total,
-                                    AllocationMap* allocations) {
-  RAW_VLOG(1, "Dumping non-live heap profile to %s", file_name);
-  RawFD fd = RawOpenForWriting(file_name);
-  if (fd != kIllegalRawFD) {
-    RawWrite(fd, kProfileHeader, strlen(kProfileHeader));
-    char buf[512];
-    int len = UnparseBucket(total, buf, 0, sizeof(buf), " heapprofile",
-                            NULL);
-    RawWrite(fd, buf, len);
-    const DumpArgs args(fd, NULL);
-    allocations->Iterate<const DumpArgs&>(DumpNonLiveIterator, args);
-    RawWrite(fd, kProcSelfMapsHeader, strlen(kProcSelfMapsHeader));
-    DumpProcSelfMaps(fd);
-    RawClose(fd);
-    return true;
-  } else {
-    RAW_LOG(ERROR, "Failed dumping filtered heap profile to %s", file_name);
-    return false;
-  }
-}
-
-void HeapProfileTable::CleanupOldProfiles(const char* prefix) {
-  if (!FLAGS_cleanup_old_heap_profiles)
-    return;
-  string pattern = string(prefix) + ".*" + kFileExt;
-#if defined(HAVE_GLOB_H)
-  glob_t g;
-  const int r = glob(pattern.c_str(), GLOB_ERR, NULL, &g);
-  if (r == 0 || r == GLOB_NOMATCH) {
-    const int prefix_length = strlen(prefix);
-    for (int i = 0; i < g.gl_pathc; i++) {
-      const char* fname = g.gl_pathv[i];
-      if ((strlen(fname) >= prefix_length) &&
-          (memcmp(fname, prefix, prefix_length) == 0)) {
-        RAW_VLOG(1, "Removing old heap profile %s", fname);
-        unlink(fname);
-      }
-    }
-  }
-  globfree(&g);
-#else   /* HAVE_GLOB_H */
-  RAW_LOG(WARNING, "Unable to remove old heap profiles (can't run glob())");
-#endif
-}
-
-HeapProfileTable::Snapshot* HeapProfileTable::TakeSnapshot() {
-  Snapshot* s = new (alloc_(sizeof(Snapshot))) Snapshot(alloc_, dealloc_);
-  address_map_->Iterate(AddToSnapshot, s);
-  return s;
-}
-
-void HeapProfileTable::ReleaseSnapshot(Snapshot* s) {
-  s->~Snapshot();
-  dealloc_(s);
-}
-
-// Callback from TakeSnapshot; adds a single entry to snapshot
-void HeapProfileTable::AddToSnapshot(const void* ptr, AllocValue* v,
-                                     Snapshot* snapshot) {
-  snapshot->Add(ptr, *v);
-}
-
-HeapProfileTable::Snapshot* HeapProfileTable::NonLiveSnapshot(
-    Snapshot* base) {
-  RAW_VLOG(2, "NonLiveSnapshot input: %d %d\n",
-           int(total_.allocs - total_.frees),
-           int(total_.alloc_size - total_.free_size));
-
-  Snapshot* s = new (alloc_(sizeof(Snapshot))) Snapshot(alloc_, dealloc_);
-  AddNonLiveArgs args;
-  args.dest = s;
-  args.base = base;
-  address_map_->Iterate<AddNonLiveArgs*>(AddIfNonLive, &args);
-  RAW_VLOG(2, "NonLiveSnapshot output: %d %d\n",
-           int(s->total_.allocs - s->total_.frees),
-           int(s->total_.alloc_size - s->total_.free_size));
-  return s;
-}
-
-// Information kept per unique bucket seen
-struct HeapProfileTable::Snapshot::Entry {
-  int count;
-  int bytes;
-  Bucket* bucket;
-  Entry() : count(0), bytes(0) { }
-
-  // Order by decreasing bytes
-  bool operator<(const Entry& x) const {
-    return this->bytes > x.bytes;
-  }
-};
-
-// State used to generate leak report.  We keep a mapping from Bucket pointer
-// the collected stats for that bucket.
-struct HeapProfileTable::Snapshot::ReportState {
-  map<Bucket*, Entry> buckets_;
-};
-
-// Callback from ReportLeaks; updates ReportState.
-void HeapProfileTable::Snapshot::ReportCallback(const void* ptr,
-                                                AllocValue* v,
-                                                ReportState* state) {
-  Entry* e = &state->buckets_[v->bucket()]; // Creates empty Entry first time
-  e->bucket = v->bucket();
-  e->count++;
-  e->bytes += v->bytes;
-}
-
-void HeapProfileTable::Snapshot::ReportLeaks(const char* checker_name,
-                                             const char* filename,
-                                             bool should_symbolize) {
-  // This is only used by the heap leak checker, but is intimately
-  // tied to the allocation map that belongs in this module and is
-  // therefore placed here.
-  RAW_LOG(ERROR, "Leak check %s detected leaks of %" PRIuS " bytes "
-          "in %" PRIuS " objects",
-          checker_name,
-          size_t(total_.alloc_size),
-          size_t(total_.allocs));
-
-  // Group objects by Bucket
-  ReportState state;
-  map_.Iterate(&ReportCallback, &state);
-
-  // Sort buckets by decreasing leaked size
-  const int n = state.buckets_.size();
-  Entry* entries = new Entry[n];
-  int dst = 0;
-  for (map<Bucket*,Entry>::const_iterator iter = state.buckets_.begin();
-       iter != state.buckets_.end();
-       ++iter) {
-    entries[dst++] = iter->second;
-  }
-  sort(entries, entries + n);
-
-  // Report a bounded number of leaks to keep the leak report from
-  // growing too long.
-  const int to_report =
-      (FLAGS_heap_check_max_leaks > 0 &&
-       n > FLAGS_heap_check_max_leaks) ? FLAGS_heap_check_max_leaks : n;
-  RAW_LOG(ERROR, "The %d largest leaks:", to_report);
-
-  // Print
-  SymbolTable symbolization_table;
-  for (int i = 0; i < to_report; i++) {
-    const Entry& e = entries[i];
-    for (int j = 0; j < e.bucket->depth; j++) {
-      symbolization_table.Add(e.bucket->stack[j]);
-    }
-  }
-  static const int kBufSize = 2<<10;
-  char buffer[kBufSize];
-  if (should_symbolize)
-    symbolization_table.Symbolize();
-  for (int i = 0; i < to_report; i++) {
-    const Entry& e = entries[i];
-    base::RawPrinter printer(buffer, kBufSize);
-    printer.Printf("Leak of %d bytes in %d objects allocated from:\n",
-                   e.bytes, e.count);
-    for (int j = 0; j < e.bucket->depth; j++) {
-      const void* pc = e.bucket->stack[j];
-      printer.Printf("\t@ %" PRIxPTR " %s\n",
-          reinterpret_cast<uintptr_t>(pc), symbolization_table.GetSymbol(pc));
-    }
-    RAW_LOG(ERROR, "%s", buffer);
-  }
-
-  if (to_report < n) {
-    RAW_LOG(ERROR, "Skipping leaks numbered %d..%d",
-            to_report, n-1);
-  }
-  delete[] entries;
-
-  // TODO: Dump the sorted Entry list instead of dumping raw data?
-  // (should be much shorter)
-  if (!HeapProfileTable::WriteProfile(filename, total_, &map_)) {
-    RAW_LOG(ERROR, "Could not write pprof profile to %s", filename);
-  }
-}
-
-void HeapProfileTable::Snapshot::ReportObject(const void* ptr,
-                                              AllocValue* v,
-                                              char* unused) {
-  // Perhaps also log the allocation stack trace (unsymbolized)
-  // on this line in case somebody finds it useful.
-  RAW_LOG(ERROR, "leaked %" PRIuS " byte object %p", v->bytes, ptr);
-}
-
-void HeapProfileTable::Snapshot::ReportIndividualObjects() {
-  char unused;
-  map_.Iterate(ReportObject, &unused);
-}
diff --git a/third_party/tcmalloc/vendor/src/heap-profile-table.h b/third_party/tcmalloc/vendor/src/heap-profile-table.h
deleted file mode 100644
index 0429ec4..0000000
--- a/third_party/tcmalloc/vendor/src/heap-profile-table.h
+++ /dev/null
@@ -1,401 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//         Maxim Lifantsev (refactoring)
-//
-
-#ifndef BASE_HEAP_PROFILE_TABLE_H_
-#define BASE_HEAP_PROFILE_TABLE_H_
-
-#include "addressmap-inl.h"
-#include "base/basictypes.h"
-#include "base/logging.h"   // for RawFD
-#include "heap-profile-stats.h"
-
-// Table to maintain a heap profile data inside,
-// i.e. the set of currently active heap memory allocations.
-// thread-unsafe and non-reentrant code:
-// each instance object must be used by one thread
-// at a time w/o self-recursion.
-//
-// TODO(maxim): add a unittest for this class.
-class HeapProfileTable {
- public:
-
-  // Extension to be used for heap pforile files.
-  static const char kFileExt[];
-
-  // Longest stack trace we record.
-  static const int kMaxStackDepth = 32;
-
-  // data types ----------------------------
-
-  // Profile stats.
-  typedef HeapProfileStats Stats;
-
-  // Info we can return about an allocation.
-  struct AllocInfo {
-    size_t object_size;  // size of the allocation
-    const void* const* call_stack;  // call stack that made the allocation call
-    int stack_depth;  // depth of call_stack
-    bool live;
-    bool ignored;
-  };
-
-  // Info we return about an allocation context.
-  // An allocation context is a unique caller stack trace
-  // of an allocation operation.
-  struct AllocContextInfo : public Stats {
-    int stack_depth;                // Depth of stack trace
-    const void* const* call_stack;  // Stack trace
-  };
-
-  // Memory (de)allocator interface we'll use.
-  typedef void* (*Allocator)(size_t size);
-  typedef void  (*DeAllocator)(void* ptr);
-
-  // interface ---------------------------
-
-  HeapProfileTable(Allocator alloc, DeAllocator dealloc, bool profile_mmap);
-
-  HeapProfileTable(const HeapProfileTable&) = delete;
-  HeapProfileTable& operator=(const HeapProfileTable&) = delete;
-
-  ~HeapProfileTable();
-
-  // Collect the stack trace for the function that asked to do the
-  // allocation for passing to RecordAlloc() below.
-  //
-  // The stack trace is stored in 'stack'. The stack depth is returned.
-  //
-  // 'skip_count' gives the number of stack frames between this call
-  // and the memory allocation function.
-  static int GetCallerStackTrace(int skip_count, void* stack[kMaxStackDepth]);
-
-  // Record an allocation at 'ptr' of 'bytes' bytes.  'stack_depth'
-  // and 'call_stack' identifying the function that requested the
-  // allocation. They can be generated using GetCallerStackTrace() above.
-  void RecordAlloc(const void* ptr, size_t bytes,
-                   int stack_depth, const void* const call_stack[]);
-
-  // Record the deallocation of memory at 'ptr'.
-  void RecordFree(const void* ptr);
-
-  // Return true iff we have recorded an allocation at 'ptr'.
-  // If yes, fill *object_size with the allocation byte size.
-  bool FindAlloc(const void* ptr, size_t* object_size) const;
-  // Same as FindAlloc, but fills all of *info.
-  bool FindAllocDetails(const void* ptr, AllocInfo* info) const;
-
-  // Return true iff "ptr" points into a recorded allocation
-  // If yes, fill *object_ptr with the actual allocation address
-  // and *object_size with the allocation byte size.
-  // max_size specifies largest currently possible allocation size.
-  bool FindInsideAlloc(const void* ptr, size_t max_size,
-                       const void** object_ptr, size_t* object_size) const;
-
-  // If "ptr" points to a recorded allocation and it's not marked as live
-  // mark it as live and return true. Else return false.
-  // All allocations start as non-live.
-  bool MarkAsLive(const void* ptr);
-
-  // If "ptr" points to a recorded allocation, mark it as "ignored".
-  // Ignored objects are treated like other objects, except that they
-  // are skipped in heap checking reports.
-  void MarkAsIgnored(const void* ptr);
-
-  // Return current total (de)allocation statistics.  It doesn't contain
-  // mmap'ed regions.
-  const Stats& total() const { return total_; }
-
-  // Allocation data iteration callback: gets passed object pointer and
-  // fully-filled AllocInfo.
-  typedef void (*AllocIterator)(const void* ptr, const AllocInfo& info);
-
-  // Iterate over the allocation profile data calling "callback"
-  // for every allocation.
-  void IterateAllocs(AllocIterator callback) const {
-    address_map_->Iterate(MapArgsAllocIterator, callback);
-  }
-
-  // Allocation context profile data iteration callback
-  typedef void (*AllocContextIterator)(const AllocContextInfo& info);
-
-  // Iterate over the allocation context profile data calling "callback"
-  // for every allocation context. Allocation contexts are ordered by the
-  // size of allocated space.
-  void IterateOrderedAllocContexts(AllocContextIterator callback) const;
-
-  // Fill profile data into buffer 'buf' of size 'size'
-  // and return the actual size occupied by the dump in 'buf'.
-  // The profile buckets are dumped in the decreasing order
-  // of currently allocated bytes.
-  // We do not provision for 0-terminating 'buf'.
-  int FillOrderedProfile(char buf[], int size) const;
-
-  // Cleanup any old profile files matching prefix + ".*" + kFileExt.
-  static void CleanupOldProfiles(const char* prefix);
-
-  // Return a snapshot of the current contents of *this.
-  // Caller must call ReleaseSnapshot() on result when no longer needed.
-  // The result is only valid while this exists and until
-  // the snapshot is discarded by calling ReleaseSnapshot().
-  class Snapshot;
-  Snapshot* TakeSnapshot();
-
-  // Release a previously taken snapshot.  snapshot must not
-  // be used after this call.
-  void ReleaseSnapshot(Snapshot* snapshot);
-
-  // Return a snapshot of every non-live, non-ignored object in *this.
-  // If "base" is non-NULL, skip any objects present in "base".
-  // As a side-effect, clears the "live" bit on every live object in *this.
-  // Caller must call ReleaseSnapshot() on result when no longer needed.
-  Snapshot* NonLiveSnapshot(Snapshot* base);
-
- private:
-
-  // data types ----------------------------
-
-  // Hash table bucket to hold (de)allocation stats
-  // for a given allocation call stack trace.
-  typedef HeapProfileBucket Bucket;
-
-  // Info stored in the address map
-  struct AllocValue {
-    // Access to the stack-trace bucket
-    Bucket* bucket() const {
-      return reinterpret_cast<Bucket*>(bucket_rep & ~uintptr_t(kMask));
-    }
-    // This also does set_live(false).
-    void set_bucket(Bucket* b) { bucket_rep = reinterpret_cast<uintptr_t>(b); }
-    size_t  bytes;   // Number of bytes in this allocation
-
-    // Access to the allocation liveness flag (for leak checking)
-    bool live() const { return bucket_rep & kLive; }
-    void set_live(bool l) {
-      bucket_rep = (bucket_rep & ~uintptr_t(kLive)) | (l ? kLive : 0);
-    }
-
-    // Should this allocation be ignored if it looks like a leak?
-    bool ignore() const { return bucket_rep & kIgnore; }
-    void set_ignore(bool r) {
-      bucket_rep = (bucket_rep & ~uintptr_t(kIgnore)) | (r ? kIgnore : 0);
-    }
-
-   private:
-    // We store a few bits in the bottom bits of bucket_rep.
-    // (Alignment is at least four, so we have at least two bits.)
-    static const int kLive = 1;
-    static const int kIgnore = 2;
-    static const int kMask = kLive | kIgnore;
-
-    uintptr_t bucket_rep;
-  };
-
-  // helper for FindInsideAlloc
-  static size_t AllocValueSize(const AllocValue& v) { return v.bytes; }
-
-  typedef AddressMap<AllocValue> AllocationMap;
-
-  // Arguments that need to be passed DumpBucketIterator callback below.
-  struct BufferArgs {
-    BufferArgs(char* buf_arg, int buflen_arg, int bufsize_arg)
-        : buf(buf_arg),
-          buflen(buflen_arg),
-          bufsize(bufsize_arg) {
-    }
-
-    char* buf;
-    int buflen;
-    int bufsize;
-
-    DISALLOW_COPY_AND_ASSIGN(BufferArgs);
-  };
-
-  // Arguments that need to be passed DumpNonLiveIterator callback below.
-  struct DumpArgs {
-    DumpArgs(RawFD fd_arg, Stats* profile_stats_arg)
-        : fd(fd_arg),
-          profile_stats(profile_stats_arg) {
-    }
-
-    RawFD fd;  // file to write to
-    Stats* profile_stats;  // stats to update (may be NULL)
-  };
-
-  // helpers ----------------------------
-
-  // Unparse bucket b and print its portion of profile dump into buf.
-  // We return the amount of space in buf that we use.  We start printing
-  // at buf + buflen, and promise not to go beyond buf + bufsize.
-  // We do not provision for 0-terminating 'buf'.
-  //
-  // If profile_stats is non-NULL, we update *profile_stats by
-  // counting bucket b.
-  //
-  // "extra" is appended to the unparsed bucket.  Typically it is empty,
-  // but may be set to something like " heapprofile" for the total
-  // bucket to indicate the type of the profile.
-  static int UnparseBucket(const Bucket& b,
-                           char* buf, int buflen, int bufsize,
-                           const char* extra,
-                           Stats* profile_stats);
-
-  // Get the bucket for the caller stack trace 'key' of depth 'depth'
-  // creating the bucket if needed.
-  Bucket* GetBucket(int depth, const void* const key[]);
-
-  // Helper for IterateAllocs to do callback signature conversion
-  // from AllocationMap::Iterate to AllocIterator.
-  static void MapArgsAllocIterator(const void* ptr, AllocValue* v,
-                                   AllocIterator callback) {
-    AllocInfo info;
-    info.object_size = v->bytes;
-    info.call_stack = v->bucket()->stack;
-    info.stack_depth = v->bucket()->depth;
-    info.live = v->live();
-    info.ignored = v->ignore();
-    callback(ptr, info);
-  }
-
-  // Helper to dump a bucket.
-  inline static void DumpBucketIterator(const Bucket* bucket,
-                                        BufferArgs* args);
-
-  // Helper for DumpNonLiveProfile to do object-granularity
-  // heap profile dumping. It gets passed to AllocationMap::Iterate.
-  inline static void DumpNonLiveIterator(const void* ptr, AllocValue* v,
-                                         const DumpArgs& args);
-
-  // Helper for IterateOrderedAllocContexts and FillOrderedProfile.
-  // Creates a sorted list of Buckets whose length is num_buckets_.
-  // The caller is responsible for deallocating the returned list.
-  Bucket** MakeSortedBucketList() const;
-
-  // Helper for TakeSnapshot.  Saves object to snapshot.
-  static void AddToSnapshot(const void* ptr, AllocValue* v, Snapshot* s);
-
-  // Arguments passed to AddIfNonLive
-  struct AddNonLiveArgs {
-    Snapshot* dest;
-    Snapshot* base;
-  };
-
-  // Helper for NonLiveSnapshot.  Adds the object to the destination
-  // snapshot if it is non-live.
-  static void AddIfNonLive(const void* ptr, AllocValue* v,
-                           AddNonLiveArgs* arg);
-
-  // Write contents of "*allocations" as a heap profile to
-  // "file_name".  "total" must contain the total of all entries in
-  // "*allocations".
-  static bool WriteProfile(const char* file_name,
-                           const Bucket& total,
-                           AllocationMap* allocations);
-
-  // data ----------------------------
-
-  // Memory (de)allocator that we use.
-  Allocator alloc_;
-  DeAllocator dealloc_;
-
-  // Overall profile stats; we use only the Stats part,
-  // but make it a Bucket to pass to UnparseBucket.
-  Bucket total_;
-
-  bool profile_mmap_;
-
-  // Bucket hash table for malloc.
-  // We hand-craft one instead of using one of the pre-written
-  // ones because we do not want to use malloc when operating on the table.
-  // It is only few lines of code, so no big deal.
-  Bucket** bucket_table_;
-  int num_buckets_;
-
-  // Map of all currently allocated objects and mapped regions we know about.
-  AllocationMap* address_map_;
-};
-
-class HeapProfileTable::Snapshot {
- public:
-  const Stats& total() const { return total_; }
-
-  // Report anything in this snapshot as a leak.
-  // May use new/delete for temporary storage.
-  // If should_symbolize is true, will fork (which is not threadsafe)
-  // to turn addresses into symbol names.  Set to false for maximum safety.
-  // Also writes a heap profile to "filename" that contains
-  // all of the objects in this snapshot.
-  void ReportLeaks(const char* checker_name, const char* filename,
-                   bool should_symbolize);
-
-  // Report the addresses of all leaked objects.
-  // May use new/delete for temporary storage.
-  void ReportIndividualObjects();
-
-  bool Empty() const {
-    return (total_.allocs == 0) && (total_.alloc_size == 0);
-  }
-
- private:
-  friend class HeapProfileTable;
-
-  // Total count/size are stored in a Bucket so we can reuse UnparseBucket
-  Bucket total_;
-
-  // We share the Buckets managed by the parent table, but have our
-  // own object->bucket map.
-  AllocationMap map_;
-
-  Snapshot(Allocator alloc, DeAllocator dealloc) : map_(alloc, dealloc) {
-    memset(&total_, 0, sizeof(total_));
-  }
-
-  // Callback used to populate a Snapshot object with entries found
-  // in another allocation map.
-  inline void Add(const void* ptr, const AllocValue& v) {
-    map_.Insert(ptr, v);
-    total_.allocs++;
-    total_.alloc_size += v.bytes;
-  }
-
-  // Helpers for sorting and generating leak reports
-  struct Entry;
-  struct ReportState;
-  static void ReportCallback(const void* ptr, AllocValue* v, ReportState*);
-  static void ReportObject(const void* ptr, AllocValue* v, char*);
-
-  DISALLOW_COPY_AND_ASSIGN(Snapshot);
-};
-
-#endif  // BASE_HEAP_PROFILE_TABLE_H_
diff --git a/third_party/tcmalloc/vendor/src/heap-profiler.cc b/third_party/tcmalloc/vendor/src/heap-profiler.cc
deleted file mode 100755
index 33a25ac..0000000
--- a/third_party/tcmalloc/vendor/src/heap-profiler.cc
+++ /dev/null
@@ -1,622 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// TODO: Log large allocations
-
-#include <config.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>    // for open()
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <signal.h>
-
-#include <algorithm>
-#include <string>
-
-#include <gperftools/heap-profiler.h>
-
-#include "base/logging.h"
-#include "base/basictypes.h"   // for PRId64, among other things
-#include "base/googleinit.h"
-#include "base/commandlineflags.h"
-#include "malloc_hook-inl.h"
-#include "tcmalloc_guard.h"
-#include <gperftools/malloc_hook.h>
-#include <gperftools/malloc_extension.h>
-#include "base/spinlock.h"
-#include "base/low_level_alloc.h"
-#include "base/sysinfo.h"      // for GetUniquePathFromEnv()
-#include "heap-profile-table.h"
-#include "memory_region_map.h"
-
-
-#ifndef	PATH_MAX
-#ifdef MAXPATHLEN
-#define	PATH_MAX	MAXPATHLEN
-#else
-#define	PATH_MAX	4096         // seems conservative for max filename len!
-#endif
-#endif
-
-using STL_NAMESPACE::string;
-using STL_NAMESPACE::sort;
-
-//----------------------------------------------------------------------
-// Flags that control heap-profiling
-//
-// The thread-safety of the profiler depends on these being immutable
-// after main starts, so don't change them.
-//----------------------------------------------------------------------
-
-DEFINE_int64(heap_profile_allocation_interval,
-             EnvToInt64("HEAP_PROFILE_ALLOCATION_INTERVAL", 1 << 30 /*1GB*/),
-             "If non-zero, dump heap profiling information once every "
-             "specified number of bytes allocated by the program since "
-             "the last dump.");
-DEFINE_int64(heap_profile_deallocation_interval,
-             EnvToInt64("HEAP_PROFILE_DEALLOCATION_INTERVAL", 0),
-             "If non-zero, dump heap profiling information once every "
-             "specified number of bytes deallocated by the program "
-             "since the last dump.");
-// We could also add flags that report whenever inuse_bytes changes by
-// X or -X, but there hasn't been a need for that yet, so we haven't.
-DEFINE_int64(heap_profile_inuse_interval,
-             EnvToInt64("HEAP_PROFILE_INUSE_INTERVAL", 100 << 20 /*100MB*/),
-             "If non-zero, dump heap profiling information whenever "
-             "the high-water memory usage mark increases by the specified "
-             "number of bytes.");
-DEFINE_int64(heap_profile_time_interval,
-             EnvToInt64("HEAP_PROFILE_TIME_INTERVAL", 0),
-             "If non-zero, dump heap profiling information once every "
-             "specified number of seconds since the last dump.");
-DEFINE_bool(mmap_log,
-            EnvToBool("HEAP_PROFILE_MMAP_LOG", false),
-            "Should mmap/munmap calls be logged?");
-DEFINE_bool(mmap_profile,
-            EnvToBool("HEAP_PROFILE_MMAP", false),
-            "If heap-profiling is on, also profile mmap, mremap, and sbrk)");
-DEFINE_bool(only_mmap_profile,
-            EnvToBool("HEAP_PROFILE_ONLY_MMAP", false),
-            "If heap-profiling is on, only profile mmap, mremap, and sbrk; "
-            "do not profile malloc/new/etc");
-
-
-//----------------------------------------------------------------------
-// Locking
-//----------------------------------------------------------------------
-
-// A pthread_mutex has way too much lock contention to be used here.
-//
-// I would like to use Mutex, but it can call malloc(),
-// which can cause us to fall into an infinite recursion.
-//
-// So we use a simple spinlock.
-static SpinLock heap_lock(SpinLock::LINKER_INITIALIZED);
-
-//----------------------------------------------------------------------
-// Simple allocator for heap profiler's internal memory
-//----------------------------------------------------------------------
-
-static LowLevelAlloc::Arena *heap_profiler_memory;
-
-static void* ProfilerMalloc(size_t bytes) {
-  return LowLevelAlloc::AllocWithArena(bytes, heap_profiler_memory);
-}
-static void ProfilerFree(void* p) {
-  LowLevelAlloc::Free(p);
-}
-
-// We use buffers of this size in DoGetHeapProfile.
-static const int kProfileBufferSize = 1 << 20;
-
-// This is a last-ditch buffer we use in DumpProfileLocked in case we
-// can't allocate more memory from ProfilerMalloc.  We expect this
-// will be used by HeapProfileEndWriter when the application has to
-// exit due to out-of-memory.  This buffer is allocated in
-// HeapProfilerStart.  Access to this must be protected by heap_lock.
-static char* global_profiler_buffer = NULL;
-
-
-//----------------------------------------------------------------------
-// Profiling control/state data
-//----------------------------------------------------------------------
-
-// Access to all of these is protected by heap_lock.
-static bool  is_on = false;           // If are on as a subsytem.
-static bool  dumping = false;         // Dumping status to prevent recursion
-static char* filename_prefix = NULL;  // Prefix used for profile file names
-                                      // (NULL if no need for dumping yet)
-static int   dump_count = 0;          // How many dumps so far
-static int64 last_dump_alloc = 0;     // alloc_size when did we last dump
-static int64 last_dump_free = 0;      // free_size when did we last dump
-static int64 high_water_mark = 0;     // In-use-bytes at last high-water dump
-static int64 last_dump_time = 0;      // The time of the last dump
-
-static HeapProfileTable* heap_profile = NULL;  // the heap profile table
-
-//----------------------------------------------------------------------
-// Profile generation
-//----------------------------------------------------------------------
-
-// Input must be a buffer of size at least 1MB.
-static char* DoGetHeapProfileLocked(char* buf, int buflen) {
-  // We used to be smarter about estimating the required memory and
-  // then capping it to 1MB and generating the profile into that.
-  if (buf == NULL || buflen < 1)
-    return NULL;
-
-  RAW_DCHECK(heap_lock.IsHeld(), "");
-  int bytes_written = 0;
-  if (is_on) {
-    HeapProfileTable::Stats const stats = heap_profile->total();
-    (void)stats;   // avoid an unused-variable warning in non-debug mode.
-    bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
-    // FillOrderedProfile should not reduce the set of active mmap-ed regions,
-    // hence MemoryRegionMap will let us remove everything we've added above:
-    RAW_DCHECK(stats.Equivalent(heap_profile->total()), "");
-    // if this fails, we somehow removed by FillOrderedProfile
-    // more than we have added.
-  }
-  buf[bytes_written] = '\0';
-  RAW_DCHECK(bytes_written == strlen(buf), "");
-
-  return buf;
-}
-
-extern "C" char* GetHeapProfile() {
-  // Use normal malloc: we return the profile to the user to free it:
-  char* buffer = reinterpret_cast<char*>(malloc(kProfileBufferSize));
-  SpinLockHolder l(&heap_lock);
-  return DoGetHeapProfileLocked(buffer, kProfileBufferSize);
-}
-
-// defined below
-static void NewHook(const void* ptr, size_t size);
-static void DeleteHook(const void* ptr);
-
-// Helper for HeapProfilerDump.
-static void DumpProfileLocked(const char* reason) {
-  RAW_DCHECK(heap_lock.IsHeld(), "");
-  RAW_DCHECK(is_on, "");
-  RAW_DCHECK(!dumping, "");
-
-  if (filename_prefix == NULL) return;  // we do not yet need dumping
-
-  dumping = true;
-
-  // Make file name
-  char file_name[1000];
-  dump_count++;
-  snprintf(file_name, sizeof(file_name), "%s.%04d%s",
-           filename_prefix, dump_count, HeapProfileTable::kFileExt);
-
-  // Dump the profile
-  RAW_VLOG(0, "Dumping heap profile to %s (%s)", file_name, reason);
-  // We must use file routines that don't access memory, since we hold
-  // a memory lock now.
-  RawFD fd = RawOpenForWriting(file_name);
-  if (fd == kIllegalRawFD) {
-    RAW_LOG(ERROR, "Failed dumping heap profile to %s", file_name);
-    dumping = false;
-    return;
-  }
-
-  // This case may be impossible, but it's best to be safe.
-  // It's safe to use the global buffer: we're protected by heap_lock.
-  if (global_profiler_buffer == NULL) {
-    global_profiler_buffer =
-        reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
-  }
-
-  char* profile = DoGetHeapProfileLocked(global_profiler_buffer,
-                                         kProfileBufferSize);
-  RawWrite(fd, profile, strlen(profile));
-  RawClose(fd);
-
-  dumping = false;
-}
-
-//----------------------------------------------------------------------
-// Profile collection
-//----------------------------------------------------------------------
-
-// Dump a profile after either an allocation or deallocation, if
-// the memory use has changed enough since the last dump.
-static void MaybeDumpProfileLocked() {
-  if (!dumping) {
-    const HeapProfileTable::Stats& total = heap_profile->total();
-    const int64 inuse_bytes = total.alloc_size - total.free_size;
-    bool need_to_dump = false;
-    char buf[128];
-
-    if (FLAGS_heap_profile_allocation_interval > 0 &&
-        total.alloc_size >=
-        last_dump_alloc + FLAGS_heap_profile_allocation_interval) {
-      snprintf(buf, sizeof(buf), ("%" PRId64 " MB allocated cumulatively, "
-                                  "%" PRId64 " MB currently in use"),
-               total.alloc_size >> 20, inuse_bytes >> 20);
-      need_to_dump = true;
-    } else if (FLAGS_heap_profile_deallocation_interval > 0 &&
-               total.free_size >=
-               last_dump_free + FLAGS_heap_profile_deallocation_interval) {
-      snprintf(buf, sizeof(buf), ("%" PRId64 " MB freed cumulatively, "
-                                  "%" PRId64 " MB currently in use"),
-               total.free_size >> 20, inuse_bytes >> 20);
-      need_to_dump = true;
-    } else if (FLAGS_heap_profile_inuse_interval > 0 &&
-               inuse_bytes >
-               high_water_mark + FLAGS_heap_profile_inuse_interval) {
-      snprintf(buf, sizeof(buf), "%" PRId64 " MB currently in use",
-               inuse_bytes >> 20);
-      need_to_dump = true;
-    } else if (FLAGS_heap_profile_time_interval > 0 ) {
-      int64 current_time = time(NULL);
-      if (current_time - last_dump_time >=
-          FLAGS_heap_profile_time_interval) {
-        snprintf(buf, sizeof(buf), "%" PRId64 " sec since the last dump",
-                 current_time - last_dump_time);
-        need_to_dump = true;
-        last_dump_time = current_time;
-      }
-    }
-    if (need_to_dump) {
-      DumpProfileLocked(buf);
-
-      last_dump_alloc = total.alloc_size;
-      last_dump_free = total.free_size;
-      if (inuse_bytes > high_water_mark)
-        high_water_mark = inuse_bytes;
-    }
-  }
-}
-
-// Record an allocation in the profile.
-static void RecordAlloc(const void* ptr, size_t bytes, int skip_count) {
-  // Take the stack trace outside the critical section.
-  void* stack[HeapProfileTable::kMaxStackDepth];
-  int depth = HeapProfileTable::GetCallerStackTrace(skip_count + 1, stack);
-  SpinLockHolder l(&heap_lock);
-  if (is_on) {
-    heap_profile->RecordAlloc(ptr, bytes, depth, stack);
-    MaybeDumpProfileLocked();
-  }
-}
-
-// Record a deallocation in the profile.
-static void RecordFree(const void* ptr) {
-  SpinLockHolder l(&heap_lock);
-  if (is_on) {
-    heap_profile->RecordFree(ptr);
-    MaybeDumpProfileLocked();
-  }
-}
-
-//----------------------------------------------------------------------
-// Allocation/deallocation hooks for MallocHook
-//----------------------------------------------------------------------
-
-// static
-void NewHook(const void* ptr, size_t size) {
-  if (ptr != NULL) RecordAlloc(ptr, size, 0);
-}
-
-// static
-void DeleteHook(const void* ptr) {
-  if (ptr != NULL) RecordFree(ptr);
-}
-
-// TODO(jandrews): Re-enable stack tracing
-#ifdef TODO_REENABLE_STACK_TRACING
-static void RawInfoStackDumper(const char* message, void*) {
-  RAW_LOG(INFO, "%.*s", static_cast<int>(strlen(message) - 1), message);
-  // -1 is to chop the \n which will be added by RAW_LOG
-}
-#endif
-
-static void MmapHook(const void* result, const void* start, size_t size,
-                     int prot, int flags, int fd, off_t offset) {
-  if (FLAGS_mmap_log) {  // log it
-    // We use PRIxS not just '%p' to avoid deadlocks
-    // in pretty-printing of NULL as "nil".
-    // TODO(maxim): instead should use a safe snprintf reimplementation
-    RAW_LOG(INFO,
-            "mmap(start=0x%" PRIxPTR ", len=%" PRIuS ", prot=0x%x, flags=0x%x, "
-            "fd=%d, offset=0x%x) = 0x%" PRIxPTR "",
-            (uintptr_t) start, size, prot, flags, fd, (unsigned int) offset,
-            (uintptr_t) result);
-#ifdef TODO_REENABLE_STACK_TRACING
-    DumpStackTrace(1, RawInfoStackDumper, NULL);
-#endif
-  }
-}
-
-static void MremapHook(const void* result, const void* old_addr,
-                       size_t old_size, size_t new_size,
-                       int flags, const void* new_addr) {
-  if (FLAGS_mmap_log) {  // log it
-    // We use PRIxS not just '%p' to avoid deadlocks
-    // in pretty-printing of NULL as "nil".
-    // TODO(maxim): instead should use a safe snprintf reimplementation
-    RAW_LOG(INFO,
-            "mremap(old_addr=0x%" PRIxPTR ", old_size=%" PRIuS ", "
-            "new_size=%" PRIuS ", flags=0x%x, new_addr=0x%" PRIxPTR ") = "
-            "0x%" PRIxPTR "",
-            (uintptr_t) old_addr, old_size, new_size, flags,
-            (uintptr_t) new_addr, (uintptr_t) result);
-#ifdef TODO_REENABLE_STACK_TRACING
-    DumpStackTrace(1, RawInfoStackDumper, NULL);
-#endif
-  }
-}
-
-static void MunmapHook(const void* ptr, size_t size) {
-  if (FLAGS_mmap_log) {  // log it
-    // We use PRIxS not just '%p' to avoid deadlocks
-    // in pretty-printing of NULL as "nil".
-    // TODO(maxim): instead should use a safe snprintf reimplementation
-    RAW_LOG(INFO, "munmap(start=0x%" PRIxPTR ", len=%" PRIuS ")",
-                  (uintptr_t) ptr, size);
-#ifdef TODO_REENABLE_STACK_TRACING
-    DumpStackTrace(1, RawInfoStackDumper, NULL);
-#endif
-  }
-}
-
-static void SbrkHook(const void* result, ptrdiff_t increment) {
-  if (FLAGS_mmap_log) {  // log it
-    RAW_LOG(INFO, "sbrk(inc=%" PRIdS ") = 0x%" PRIxPTR "",
-                  increment, (uintptr_t) result);
-#ifdef TODO_REENABLE_STACK_TRACING
-    DumpStackTrace(1, RawInfoStackDumper, NULL);
-#endif
-  }
-}
-
-//----------------------------------------------------------------------
-// Starting/stopping/dumping
-//----------------------------------------------------------------------
-
-extern "C" void HeapProfilerStart(const char* prefix) {
-  SpinLockHolder l(&heap_lock);
-
-  if (is_on) return;
-
-  is_on = true;
-
-  RAW_VLOG(0, "Starting tracking the heap");
-
-  // This should be done before the hooks are set up, since it should
-  // call new, and we want that to be accounted for correctly.
-  MallocExtension::Initialize();
-
-  if (FLAGS_only_mmap_profile) {
-    FLAGS_mmap_profile = true;
-  }
-
-  if (FLAGS_mmap_profile) {
-    // Ask MemoryRegionMap to record all mmap, mremap, and sbrk
-    // call stack traces of at least size kMaxStackDepth:
-    MemoryRegionMap::Init(HeapProfileTable::kMaxStackDepth,
-                          /* use_buckets */ true);
-  }
-
-  if (FLAGS_mmap_log) {
-    // Install our hooks to do the logging:
-    RAW_CHECK(MallocHook::AddMmapHook(&MmapHook), "");
-    RAW_CHECK(MallocHook::AddMremapHook(&MremapHook), "");
-    RAW_CHECK(MallocHook::AddMunmapHook(&MunmapHook), "");
-    RAW_CHECK(MallocHook::AddSbrkHook(&SbrkHook), "");
-  }
-
-  heap_profiler_memory =
-    LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
-
-  // Reserve space now for the heap profiler, so we can still write a
-  // heap profile even if the application runs out of memory.
-  global_profiler_buffer =
-      reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
-
-  heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable)))
-      HeapProfileTable(ProfilerMalloc, ProfilerFree, FLAGS_mmap_profile);
-
-  last_dump_alloc = 0;
-  last_dump_free = 0;
-  high_water_mark = 0;
-  last_dump_time = 0;
-
-  // We do not reset dump_count so if the user does a sequence of
-  // HeapProfilerStart/HeapProfileStop, we will get a continuous
-  // sequence of profiles.
-
-  if (FLAGS_only_mmap_profile == false) {
-    // Now set the hooks that capture new/delete and malloc/free.
-    RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
-    RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
-  }
-
-  // Copy filename prefix
-  RAW_DCHECK(filename_prefix == NULL, "");
-  const int prefix_length = strlen(prefix);
-  filename_prefix = reinterpret_cast<char*>(ProfilerMalloc(prefix_length + 1));
-  memcpy(filename_prefix, prefix, prefix_length);
-  filename_prefix[prefix_length] = '\0';
-}
-
-extern "C" int IsHeapProfilerRunning() {
-  SpinLockHolder l(&heap_lock);
-  return is_on ? 1 : 0;   // return an int, because C code doesn't have bool
-}
-
-extern "C" void HeapProfilerStop() {
-  SpinLockHolder l(&heap_lock);
-
-  if (!is_on) return;
-
-  if (FLAGS_only_mmap_profile == false) {
-    // Unset our new/delete hooks, checking they were set:
-    RAW_CHECK(MallocHook::RemoveNewHook(&NewHook), "");
-    RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), "");
-  }
-  if (FLAGS_mmap_log) {
-    // Restore mmap/sbrk hooks, checking that our hooks were set:
-    RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), "");
-    RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), "");
-    RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), "");
-    RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
-  }
-
-  // free profile
-  heap_profile->~HeapProfileTable();
-  ProfilerFree(heap_profile);
-  heap_profile = NULL;
-
-  // free output-buffer memory
-  ProfilerFree(global_profiler_buffer);
-
-  // free prefix
-  ProfilerFree(filename_prefix);
-  filename_prefix = NULL;
-
-  if (!LowLevelAlloc::DeleteArena(heap_profiler_memory)) {
-    RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
-  }
-
-  if (FLAGS_mmap_profile) {
-    MemoryRegionMap::Shutdown();
-  }
-
-  is_on = false;
-}
-
-extern "C" void HeapProfilerDump(const char *reason) {
-  SpinLockHolder l(&heap_lock);
-  if (is_on && !dumping) {
-    DumpProfileLocked(reason);
-  }
-}
-
-// Signal handler that is registered when a user selectable signal
-// number is defined in the environment variable HEAPPROFILESIGNAL.
-static void HeapProfilerDumpSignal(int signal_number) {
-  (void)signal_number;
-  if (!heap_lock.TryLock()) {
-    return;
-  }
-  if (is_on && !dumping) {
-    DumpProfileLocked("signal");
-  }
-  heap_lock.Unlock();
-}
-
-
-//----------------------------------------------------------------------
-// Initialization/finalization code
-//----------------------------------------------------------------------
-
-// Initialization code
-static void HeapProfilerInit() {
-  // Everything after this point is for setting up the profiler based on envvar
-  char fname[PATH_MAX];
-  if (!GetUniquePathFromEnv("HEAPPROFILE", fname)) {
-    return;
-  }
-  // We do a uid check so we don't write out files in a setuid executable.
-#ifdef HAVE_GETEUID
-  if (getuid() != geteuid()) {
-    RAW_LOG(WARNING, ("HeapProfiler: ignoring HEAPPROFILE because "
-                      "program seems to be setuid\n"));
-    return;
-  }
-#endif
-
-  char *signal_number_str = getenv("HEAPPROFILESIGNAL");
-  if (signal_number_str != NULL) {
-    long int signal_number = strtol(signal_number_str, NULL, 10);
-    intptr_t old_signal_handler = reinterpret_cast<intptr_t>(signal(signal_number, HeapProfilerDumpSignal));
-    if (old_signal_handler == reinterpret_cast<intptr_t>(SIG_ERR)) {
-      RAW_LOG(FATAL, "Failed to set signal. Perhaps signal number %s is invalid\n", signal_number_str);
-    } else if (old_signal_handler == 0) {
-      RAW_LOG(INFO,"Using signal %d as heap profiling switch", signal_number);
-    } else {
-      RAW_LOG(FATAL, "Signal %d already in use\n", signal_number);
-    }
-  }
-
-  HeapProfileTable::CleanupOldProfiles(fname);
-
-  HeapProfilerStart(fname);
-}
-
-// class used for finalization -- dumps the heap-profile at program exit
-struct HeapProfileEndWriter {
-  ~HeapProfileEndWriter() {
-    char buf[128];
-    if (heap_profile) {
-      const HeapProfileTable::Stats& total = heap_profile->total();
-      const int64 inuse_bytes = total.alloc_size - total.free_size;
-
-      if ((inuse_bytes >> 20) > 0) {
-        snprintf(buf, sizeof(buf), ("Exiting, %" PRId64 " MB in use"),
-                 inuse_bytes >> 20);
-      } else if ((inuse_bytes >> 10) > 0) {
-        snprintf(buf, sizeof(buf), ("Exiting, %" PRId64 " kB in use"),
-                 inuse_bytes >> 10);
-      } else {
-        snprintf(buf, sizeof(buf), ("Exiting, %" PRId64 " bytes in use"),
-                 inuse_bytes);
-      }
-    } else {
-      snprintf(buf, sizeof(buf), ("Exiting"));
-    }
-    HeapProfilerDump(buf);
-  }
-};
-
-// We want to make sure tcmalloc is up and running before starting the profiler
-static const TCMallocGuard tcmalloc_initializer;
-REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
-static HeapProfileEndWriter heap_profile_end_writer;
diff --git a/third_party/tcmalloc/vendor/src/internal_logging.cc b/third_party/tcmalloc/vendor/src/internal_logging.cc
deleted file mode 100644
index 708fa650..0000000
--- a/third_party/tcmalloc/vendor/src/internal_logging.cc
+++ /dev/null
@@ -1,192 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-#include "internal_logging.h"
-#include <stdarg.h>                     // for va_end, va_start
-#include <stdio.h>                      // for vsnprintf, va_list, etc
-#include <stdlib.h>                     // for abort
-#include <string.h>                     // for strlen, memcpy
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for write()
-#endif
-
-#include <gperftools/malloc_extension.h>
-#include "base/logging.h"   // for perftools_vsnprintf
-#include "base/spinlock.h"              // for SpinLockHolder, SpinLock
-
-// Variables for storing crash output.  Allocated statically since we
-// may not be able to heap-allocate while crashing.
-static SpinLock crash_lock(base::LINKER_INITIALIZED);
-static bool crashed = false;
-static const int kStatsBufferSize = 16 << 10;
-static char stats_buffer[kStatsBufferSize] = { 0 };
-
-namespace tcmalloc {
-
-static void WriteMessage(const char* msg, int length) {
-  write(STDERR_FILENO, msg, length);
-}
-
-void (*log_message_writer)(const char* msg, int length) = WriteMessage;
-
-
-class Logger {
- public:
-  bool Add(const LogItem& item);
-  bool AddStr(const char* str, int n);
-  bool AddNum(uint64_t num, int base);  // base must be 10 or 16.
-
-  static const int kBufSize = 200;
-  char* p_;
-  char* end_;
-  char buf_[kBufSize];
-};
-
-void Log(LogMode mode, const char* filename, int line,
-         LogItem a, LogItem b, LogItem c, LogItem d) {
-  Logger state;
-  state.p_ = state.buf_;
-  state.end_ = state.buf_ + sizeof(state.buf_);
-  state.AddStr(filename, strlen(filename))
-      && state.AddStr(":", 1)
-      && state.AddNum(line, 10)
-      && state.AddStr("]", 1)
-      && state.Add(a)
-      && state.Add(b)
-      && state.Add(c)
-      && state.Add(d);
-
-  // Teminate with newline
-  if (state.p_ >= state.end_) {
-    state.p_ = state.end_ - 1;
-  }
-  *state.p_ = '\n';
-  state.p_++;
-
-  int msglen = state.p_ - state.buf_;
-  if (mode == kLog) {
-    (*log_message_writer)(state.buf_, msglen);
-    return;
-  }
-
-  bool first_crash = false;
-  {
-    SpinLockHolder l(&crash_lock);
-    if (!crashed) {
-      crashed = true;
-      first_crash = true;
-    }
-  }
-
-  (*log_message_writer)(state.buf_, msglen);
-  if (first_crash && mode == kCrashWithStats) {
-    MallocExtension::instance()->GetStats(stats_buffer, kStatsBufferSize);
-    (*log_message_writer)(stats_buffer, strlen(stats_buffer));
-  }
-
-  abort();
-}
-
-bool Logger::Add(const LogItem& item) {
-  // Separate items with spaces
-  if (p_ < end_) {
-    *p_ = ' ';
-    p_++;
-  }
-
-  switch (item.tag_) {
-    case LogItem::kStr:
-      return AddStr(item.u_.str, strlen(item.u_.str));
-    case LogItem::kUnsigned:
-      return AddNum(item.u_.unum, 10);
-    case LogItem::kSigned:
-      if (item.u_.snum < 0) {
-        // The cast to uint64_t is intentionally before the negation
-        // so that we do not attempt to negate -2^63.
-        return AddStr("-", 1)
-            && AddNum(- static_cast<uint64_t>(item.u_.snum), 10);
-      } else {
-        return AddNum(static_cast<uint64_t>(item.u_.snum), 10);
-      }
-    case LogItem::kPtr:
-      return AddStr("0x", 2)
-          && AddNum(reinterpret_cast<uintptr_t>(item.u_.ptr), 16);
-    default:
-      return false;
-  }
-}
-
-bool Logger::AddStr(const char* str, int n) {
-  if (end_ - p_ < n) {
-    return false;
-  } else {
-    memcpy(p_, str, n);
-    p_ += n;
-    return true;
-  }
-}
-
-bool Logger::AddNum(uint64_t num, int base) {
-  static const char kDigits[] = "0123456789abcdef";
-  char space[22];  // more than enough for 2^64 in smallest supported base (10)
-  char* end = space + sizeof(space);
-  char* pos = end;
-  do {
-    pos--;
-    *pos = kDigits[num % base];
-    num /= base;
-  } while (num > 0 && pos > space);
-  return AddStr(pos, end - pos);
-}
-
-}  // end tcmalloc namespace
-
-void TCMalloc_Printer::printf(const char* format, ...) {
-  if (left_ > 0) {
-    va_list ap;
-    va_start(ap, format);
-    const int r = perftools_vsnprintf(buf_, left_, format, ap);
-    va_end(ap);
-    if (r < 0) {
-      // Perhaps an old glibc that returns -1 on truncation?
-      left_ = 0;
-    } else if (r > left_) {
-      // Truncation
-      left_ = 0;
-    } else {
-      left_ -= r;
-      buf_ += r;
-    }
-  }
-}
diff --git a/third_party/tcmalloc/vendor/src/internal_logging.h b/third_party/tcmalloc/vendor/src/internal_logging.h
deleted file mode 100644
index 0c300c3..0000000
--- a/third_party/tcmalloc/vendor/src/internal_logging.h
+++ /dev/null
@@ -1,144 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// Internal logging and related utility routines.
-
-#ifndef TCMALLOC_INTERNAL_LOGGING_H_
-#define TCMALLOC_INTERNAL_LOGGING_H_
-
-#include <config.h>
-#include <stddef.h>                     // for size_t
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-
-//-------------------------------------------------------------------
-// Utility routines
-//-------------------------------------------------------------------
-
-// Safe logging helper: we write directly to the stderr file
-// descriptor and avoid FILE buffering because that may invoke
-// malloc().
-//
-// Example:
-//   Log(kLog, __FILE__, __LINE__, "error", bytes);
-
-namespace tcmalloc {
-enum LogMode {
-  kLog,                       // Just print the message
-  kCrash,                     // Print the message and crash
-  kCrashWithStats             // Print the message, some stats, and crash
-};
-
-class Logger;
-
-// A LogItem holds any of the argument types that can be passed to Log()
-class LogItem {
- public:
-  LogItem()                     : tag_(kEnd)      { }
-  LogItem(const char* v)        : tag_(kStr)      { u_.str = v; }
-  LogItem(int v)                : tag_(kSigned)   { u_.snum = v; }
-  LogItem(long v)               : tag_(kSigned)   { u_.snum = v; }
-  LogItem(long long v)          : tag_(kSigned)   { u_.snum = v; }
-  LogItem(unsigned int v)       : tag_(kUnsigned) { u_.unum = v; }
-  LogItem(unsigned long v)      : tag_(kUnsigned) { u_.unum = v; }
-  LogItem(unsigned long long v) : tag_(kUnsigned) { u_.unum = v; }
-  LogItem(const void* v)        : tag_(kPtr)      { u_.ptr = v; }
- private:
-  friend class Logger;
-  enum Tag {
-    kStr,
-    kSigned,
-    kUnsigned,
-    kPtr,
-    kEnd
-  };
-  Tag tag_;
-  union {
-    const char* str;
-    const void* ptr;
-    int64_t snum;
-    uint64_t unum;
-  } u_;
-};
-
-extern PERFTOOLS_DLL_DECL void Log(LogMode mode, const char* filename, int line,
-                LogItem a, LogItem b = LogItem(),
-                LogItem c = LogItem(), LogItem d = LogItem());
-
-// Tests can override this function to collect logging messages.
-extern PERFTOOLS_DLL_DECL void (*log_message_writer)(const char* msg, int length);
-
-}  // end tcmalloc namespace
-
-// Like assert(), but executed even in NDEBUG mode
-#undef CHECK_CONDITION
-#define CHECK_CONDITION(cond)                                            \
-do {                                                                     \
-  if (!(cond)) {                                                         \
-    ::tcmalloc::Log(::tcmalloc::kCrash, __FILE__, __LINE__, #cond);      \
-  }                                                                      \
-} while (0)
-
-// Our own version of assert() so we can avoid hanging by trying to do
-// all kinds of goofy printing while holding the malloc lock.
-#ifndef NDEBUG
-#define ASSERT(cond) CHECK_CONDITION(cond)
-#else
-#define ASSERT(cond) ((void) 0)
-#endif
-
-// Print into buffer
-class TCMalloc_Printer {
- private:
-  char* buf_;           // Where should we write next
-  int   left_;          // Space left in buffer (including space for \0)
-
- public:
-  // REQUIRES: "length > 0"
-  TCMalloc_Printer(char* buf, int length) : buf_(buf), left_(length) {
-    buf[0] = '\0';
-  }
-
-  void printf(const char* format, ...)
-#ifdef HAVE___ATTRIBUTE__
-    __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
-;
-};
-
-#endif  // TCMALLOC_INTERNAL_LOGGING_H_
diff --git a/third_party/tcmalloc/vendor/src/libc_override.h b/third_party/tcmalloc/vendor/src/libc_override.h
deleted file mode 100644
index c981c3d..0000000
--- a/third_party/tcmalloc/vendor/src/libc_override.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// This .h file imports the code that causes tcmalloc to override libc
-// versions of malloc/free/new/delete/etc.  That is, it provides the
-// logic that makes it so calls to malloc(10) go through tcmalloc,
-// rather than the default (libc) malloc.
-//
-// This file also provides a method: ReplaceSystemAlloc(), that every
-// libc_override_*.h file it #includes is required to provide.  This
-// is called when first setting up tcmalloc -- that is, when a global
-// constructor in tcmalloc.cc is executed -- to do any initialization
-// work that may be required for this OS.  (Note we cannot entirely
-// control when tcmalloc is initialized, and the system may do some
-// mallocs and frees before this routine is called.)  It may be a
-// noop.
-//
-// Every libc has its own way of doing this, and sometimes the compiler
-// matters too, so we have a different file for each libc, and often
-// for different compilers and OS's.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_INL_H_
-#define TCMALLOC_LIBC_OVERRIDE_INL_H_
-
-#include <config.h>
-#ifdef HAVE_FEATURES_H
-#include <features.h>   // for __GLIBC__
-#endif
-#include <gperftools/tcmalloc.h>
-
-#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
-#define CPP_NOTHROW noexcept
-#define CPP_BADALLOC
-#else
-#define CPP_NOTHROW throw()
-#define CPP_BADALLOC throw(std::bad_alloc)
-#endif
-
-static void ReplaceSystemAlloc();  // defined in the .h files below
-
-// For windows, there are two ways to get tcmalloc.  If we're
-// patching, then src/windows/patch_function.cc will do the necessary
-// overriding here.  Otherwise, we doing the 'redefine' trick, where
-// we remove malloc/new/etc from mscvcrt.dll, and just need to define
-// them now.
-#if defined(_WIN32) && defined(WIN32_DO_PATCHING)
-void PatchWindowsFunctions();   // in src/windows/patch_function.cc
-static void ReplaceSystemAlloc() { PatchWindowsFunctions(); }
-
-#elif defined(_WIN32) && !defined(WIN32_DO_PATCHING)
-#include "libc_override_redefine.h"
-
-#elif defined(__APPLE__)
-#include "libc_override_osx.h"
-
-#elif defined(__GLIBC__)
-#include "libc_override_glibc.h"
-
-// Not all gcc systems necessarily support weak symbols, but all the
-// ones I know of do, so for now just assume they all do.
-#elif defined(__GNUC__)
-#include "libc_override_gcc_and_weak.h"
-
-#else
-#error Need to add support for your libc/OS here
-
-#endif
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_INL_H_
diff --git a/third_party/tcmalloc/vendor/src/libc_override_gcc_and_weak.h b/third_party/tcmalloc/vendor/src/libc_override_gcc_and_weak.h
deleted file mode 100644
index 6875164..0000000
--- a/third_party/tcmalloc/vendor/src/libc_override_gcc_and_weak.h
+++ /dev/null
@@ -1,244 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Used to override malloc routines on systems that define the
-// memory allocation routines to be weak symbols in their libc
-// (almost all unix-based systems are like this), on gcc, which
-// suppports the 'alias' attribute.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_GCC_AND_WEAK_INL_H_
-#define TCMALLOC_LIBC_OVERRIDE_GCC_AND_WEAK_INL_H_
-
-#ifdef HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>    // for __THROW
-#endif
-#include <gperftools/tcmalloc.h>
-
-#include "getenv_safe.h" // TCMallocGetenvSafe
-#include "base/commandlineflags.h"
-
-#ifndef __THROW    // I guess we're not on a glibc-like system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-#ifndef __GNUC__
-# error libc_override_gcc_and_weak.h is for gcc distributions only.
-#endif
-
-#define ALIAS(tc_fn)   __attribute__ ((alias (#tc_fn), used))
-
-void* operator new(size_t size) CPP_BADALLOC  ALIAS(tc_new);
-void operator delete(void* p) CPP_NOTHROW     ALIAS(tc_delete);
-void* operator new[](size_t size) CPP_BADALLOC ALIAS(tc_newarray);
-void operator delete[](void* p) CPP_NOTHROW   ALIAS(tc_deletearray);
-void* operator new(size_t size, const std::nothrow_t& nt) CPP_NOTHROW
-                                              ALIAS(tc_new_nothrow);
-void* operator new[](size_t size, const std::nothrow_t& nt) CPP_NOTHROW
-                                              ALIAS(tc_newarray_nothrow);
-void operator delete(void* p, const std::nothrow_t& nt) CPP_NOTHROW
-                                              ALIAS(tc_delete_nothrow);
-void operator delete[](void* p, const std::nothrow_t& nt) CPP_NOTHROW
-                                              ALIAS(tc_deletearray_nothrow);
-
-#if defined(ENABLE_SIZED_DELETE)
-
-void operator delete(void *p, size_t size) CPP_NOTHROW
-    ALIAS(tc_delete_sized);
-void operator delete[](void *p, size_t size) CPP_NOTHROW
-    ALIAS(tc_deletearray_sized);
-
-#elif defined(ENABLE_DYNAMIC_SIZED_DELETE) && \
-  (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
-
-static void delegate_sized_delete(void *p, size_t s) {
-  (operator delete)(p);
-}
-
-static void delegate_sized_deletearray(void *p, size_t s) {
-  (operator delete[])(p);
-}
-
-extern "C" __attribute__((weak))
-int tcmalloc_sized_delete_enabled(void);
-
-static bool sized_delete_enabled(void) {
-  if (tcmalloc_sized_delete_enabled != 0) {
-    return !!tcmalloc_sized_delete_enabled();
-  }
-
-  const char *flag = TCMallocGetenvSafe("TCMALLOC_ENABLE_SIZED_DELETE");
-  return tcmalloc::commandlineflags::StringToBool(flag, false);
-}
-
-extern "C" {
-
-static void *resolve_delete_sized(void) {
-  if (sized_delete_enabled()) {
-    return reinterpret_cast<void *>(tc_delete_sized);
-  }
-  return reinterpret_cast<void *>(delegate_sized_delete);
-}
-
-static void *resolve_deletearray_sized(void) {
-  if (sized_delete_enabled()) {
-    return reinterpret_cast<void *>(tc_deletearray_sized);
-  }
-  return reinterpret_cast<void *>(delegate_sized_deletearray);
-}
-
-}
-
-void operator delete(void *p, size_t size) CPP_NOTHROW
-  __attribute__((ifunc("resolve_delete_sized")));
-void operator delete[](void *p, size_t size) CPP_NOTHROW
-  __attribute__((ifunc("resolve_deletearray_sized")));
-
-#else /* !ENABLE_SIZED_DELETE && !ENABLE_DYN_SIZED_DELETE */
-
-void operator delete(void *p, size_t size) CPP_NOTHROW
-  ALIAS(tc_delete);
-void operator delete[](void *p, size_t size) CPP_NOTHROW
-  ALIAS(tc_deletearray);
-
-#endif /* !ENABLE_SIZED_DELETE && !ENABLE_DYN_SIZED_DELETE */
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-void* operator new(size_t size, std::align_val_t al)
-    ALIAS(tc_new_aligned);
-void operator delete(void* p, std::align_val_t al) CPP_NOTHROW
-    ALIAS(tc_delete_aligned);
-void* operator new[](size_t size, std::align_val_t al)
-    ALIAS(tc_newarray_aligned);
-void operator delete[](void* p, std::align_val_t al) CPP_NOTHROW
-    ALIAS(tc_deletearray_aligned);
-void* operator new(size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
-    ALIAS(tc_new_aligned_nothrow);
-void* operator new[](size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
-    ALIAS(tc_newarray_aligned_nothrow);
-void operator delete(void* p, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
-    ALIAS(tc_delete_aligned_nothrow);
-void operator delete[](void* p, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
-    ALIAS(tc_deletearray_aligned_nothrow);
-
-#if defined(ENABLE_SIZED_DELETE)
-
-void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-    ALIAS(tc_delete_sized_aligned);
-void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-    ALIAS(tc_deletearray_sized_aligned);
-
-#else /* defined(ENABLE_SIZED_DELETE) */
-
-#if defined(ENABLE_DYNAMIC_SIZED_DELETE) && \
-  (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
-
-static void delegate_sized_aligned_delete(void *p, size_t s, std::align_val_t al) {
-  (operator delete)(p, al);
-}
-
-static void delegate_sized_aligned_deletearray(void *p, size_t s, std::align_val_t al) {
-  (operator delete[])(p, al);
-}
-
-extern "C" {
-
-static void *resolve_delete_sized_aligned(void) {
-  if (sized_delete_enabled()) {
-    return reinterpret_cast<void *>(tc_delete_sized_aligned);
-  }
-  return reinterpret_cast<void *>(delegate_sized_aligned_delete);
-}
-
-static void *resolve_deletearray_sized_aligned(void) {
-  if (sized_delete_enabled()) {
-    return reinterpret_cast<void *>(tc_deletearray_sized_aligned);
-  }
-  return reinterpret_cast<void *>(delegate_sized_aligned_deletearray);
-}
-
-}
-
-void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-  __attribute__((ifunc("resolve_delete_sized_aligned")));
-void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-  __attribute__((ifunc("resolve_deletearray_sized_aligned")));
-
-#else /* defined(ENABLE_DYN_SIZED_DELETE) */
-
-void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-  ALIAS(tc_delete);
-void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-  ALIAS(tc_deletearray);
-
-#endif /* defined(ENABLE_DYN_SIZED_DELETE) */
-
-#endif /* defined(ENABLE_SIZED_DELETE) */
-
-#endif /* defined(ENABLE_ALIGNED_NEW_DELETE) */
-
-extern "C" {
-  void* malloc(size_t size) __THROW               ALIAS(tc_malloc);
-  void free(void* ptr) __THROW                    ALIAS(tc_free);
-  void* realloc(void* ptr, size_t size) __THROW   ALIAS(tc_realloc);
-  void* calloc(size_t n, size_t size) __THROW     ALIAS(tc_calloc);
-  void cfree(void* ptr) __THROW                   ALIAS(tc_cfree);
-  void* memalign(size_t align, size_t s) __THROW  ALIAS(tc_memalign);
-  void* aligned_alloc(size_t align, size_t s) __THROW ALIAS(tc_memalign);
-  void* valloc(size_t size) __THROW               ALIAS(tc_valloc);
-  void* pvalloc(size_t size) __THROW              ALIAS(tc_pvalloc);
-  int posix_memalign(void** r, size_t a, size_t s) __THROW
-      ALIAS(tc_posix_memalign);
-#ifndef __UCLIBC__
-  void malloc_stats(void) __THROW                 ALIAS(tc_malloc_stats);
-#endif
-  int mallopt(int cmd, int value) __THROW         ALIAS(tc_mallopt);
-#ifdef HAVE_STRUCT_MALLINFO
-  struct mallinfo mallinfo(void) __THROW          ALIAS(tc_mallinfo);
-#endif
-  size_t malloc_size(void* p) __THROW             ALIAS(tc_malloc_size);
-#if defined(__ANDROID__)
-  size_t malloc_usable_size(const void* p) __THROW
-         ALIAS(tc_malloc_size);
-#else
-  size_t malloc_usable_size(void* p) __THROW      ALIAS(tc_malloc_size);
-#endif
-}   // extern "C"
-
-#undef ALIAS
-
-// No need to do anything at tcmalloc-registration time: we do it all
-// via overriding weak symbols (at link time).
-static void ReplaceSystemAlloc() { }
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_GCC_AND_WEAK_INL_H_
diff --git a/third_party/tcmalloc/vendor/src/libc_override_glibc.h b/third_party/tcmalloc/vendor/src/libc_override_glibc.h
deleted file mode 100644
index 3269213..0000000
--- a/third_party/tcmalloc/vendor/src/libc_override_glibc.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Used to override malloc routines on systems that are using glibc.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_GLIBC_INL_H_
-#define TCMALLOC_LIBC_OVERRIDE_GLIBC_INL_H_
-
-#include <config.h>
-#include <features.h>     // for __GLIBC__
-#include <gperftools/tcmalloc.h>
-
-#ifndef __GLIBC__
-# error libc_override_glibc.h is for glibc distributions only.
-#endif
-
-// In glibc, the memory-allocation methods are weak symbols, so we can
-// just override them with our own.  If we're using gcc, we can use
-// __attribute__((alias)) to do the overriding easily (exception:
-// Mach-O, which doesn't support aliases).  Otherwise we have to use a
-// function call.
-#if !defined(__GNUC__) || defined(__MACH__)
-
-// This also defines ReplaceSystemAlloc().
-# include "libc_override_redefine.h"  // defines functions malloc()/etc
-
-#else  // #if !defined(__GNUC__) || defined(__MACH__)
-
-// If we get here, we're a gcc system, so do all the overriding we do
-// with gcc.  This does the overriding of all the 'normal' memory
-// allocation.  This also defines ReplaceSystemAlloc().
-# include "libc_override_gcc_and_weak.h"
-
-// We also have to do some glibc-specific overriding.  Some library
-// routines on RedHat 9 allocate memory using malloc() and free it
-// using __libc_free() (or vice-versa).  Since we provide our own
-// implementations of malloc/free, we need to make sure that the
-// __libc_XXX variants (defined as part of glibc) also point to the
-// same implementations.  Since it only matters for redhat, we
-// do it inside the gcc #ifdef, since redhat uses gcc.
-// TODO(csilvers): only do this if we detect we're an old enough glibc?
-
-#define ALIAS(tc_fn)   __attribute__ ((alias (#tc_fn)))
-extern "C" {
-  void* __libc_malloc(size_t size)                ALIAS(tc_malloc);
-  void __libc_free(void* ptr)                     ALIAS(tc_free);
-  void* __libc_realloc(void* ptr, size_t size)    ALIAS(tc_realloc);
-  void* __libc_calloc(size_t n, size_t size)      ALIAS(tc_calloc);
-  void __libc_cfree(void* ptr)                    ALIAS(tc_cfree);
-  void* __libc_memalign(size_t align, size_t s)   ALIAS(tc_memalign);
-  void* __libc_valloc(size_t size)                ALIAS(tc_valloc);
-  void* __libc_pvalloc(size_t size)               ALIAS(tc_pvalloc);
-  int __posix_memalign(void** r, size_t a, size_t s)  ALIAS(tc_posix_memalign);
-}   // extern "C"
-#undef ALIAS
-
-#endif  // #if defined(__GNUC__) && !defined(__MACH__)
-
-// No need to write ReplaceSystemAlloc(); one of the #includes above
-// did it for us.
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_GLIBC_INL_H_
diff --git a/third_party/tcmalloc/vendor/src/libc_override_osx.h b/third_party/tcmalloc/vendor/src/libc_override_osx.h
deleted file mode 100644
index 9d5d6115..0000000
--- a/third_party/tcmalloc/vendor/src/libc_override_osx.h
+++ /dev/null
@@ -1,308 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Used to override malloc routines on OS X systems.  We use the
-// malloc-zone functionality built into OS X to register our malloc
-// routine.
-//
-// 1) We used to use the normal 'override weak libc malloc/etc'
-// technique for OS X.  This is not optimal because mach does not
-// support the 'alias' attribute, so we had to have forwarding
-// functions.  It also does not work very well with OS X shared
-// libraries (dylibs) -- in general, the shared libs don't use
-// tcmalloc unless run with the DYLD_FORCE_FLAT_NAMESPACE envvar.
-//
-// 2) Another approach would be to use an interposition array:
-//      static const interpose_t interposers[] __attribute__((section("__DATA, __interpose"))) = {
-//        { (void *)tc_malloc, (void *)malloc },
-//        { (void *)tc_free, (void *)free },
-//      };
-// This requires the user to set the DYLD_INSERT_LIBRARIES envvar, so
-// is not much better.
-//
-// 3) Registering a new malloc zone avoids all these issues:
-//  http://www.opensource.apple.com/source/Libc/Libc-583/include/malloc/malloc.h
-//  http://www.opensource.apple.com/source/Libc/Libc-583/gen/malloc.c
-// If we make tcmalloc the default malloc zone (undocumented but
-// possible) then all new allocs use it, even those in shared
-// libraries.  Allocs done before tcmalloc was installed, or in libs
-// that aren't using tcmalloc for some reason, will correctly go
-// through the malloc-zone interface when free-ing, and will pick up
-// the libc free rather than tcmalloc free.  So it should "never"
-// cause a crash (famous last words).
-//
-// 4) The routines one must define for one's own malloc have changed
-// between OS X versions.  This requires some hoops on our part, but
-// is only really annoying when it comes to posix_memalign.  The right
-// behavior there depends on what OS version tcmalloc was compiled on,
-// but also what OS version the program is running on.  For now, we
-// punt and don't implement our own posix_memalign.  Apps that really
-// care can use tc_posix_memalign directly.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_OSX_INL_H_
-#define TCMALLOC_LIBC_OVERRIDE_OSX_INL_H_
-
-#include <config.h>
-#ifdef HAVE_FEATURES_H
-#include <features.h>
-#endif
-#include <gperftools/tcmalloc.h>
-
-#if !defined(__APPLE__)
-# error libc_override_glibc-osx.h is for OS X distributions only.
-#endif
-
-#include <AvailabilityMacros.h>
-#include <malloc/malloc.h>
-
-namespace tcmalloc {
-  void CentralCacheLockAll();
-  void CentralCacheUnlockAll();
-}
-
-// from AvailabilityMacros.h
-#if defined(MAC_OS_X_VERSION_10_6) && \
-    MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
-extern "C" {
-  // This function is only available on 10.6 (and later) but the
-  // LibSystem headers do not use AvailabilityMacros.h to handle weak
-  // importing automatically.  This prototype is a copy of the one in
-  // <malloc/malloc.h> with the WEAK_IMPORT_ATTRBIUTE added.
-  extern malloc_zone_t *malloc_default_purgeable_zone(void)
-      WEAK_IMPORT_ATTRIBUTE;
-}
-#endif
-
-// We need to provide wrappers around all the libc functions.
-namespace {
-size_t mz_size(malloc_zone_t* zone, const void* ptr) {
-  if (MallocExtension::instance()->GetOwnership(ptr) != MallocExtension::kOwned)
-    return 0;  // malloc_zone semantics: return 0 if we don't own the memory
-
-  // TODO(csilvers): change this method to take a const void*, one day.
-  return MallocExtension::instance()->GetAllocatedSize(const_cast<void*>(ptr));
-}
-
-void* mz_malloc(malloc_zone_t* zone, size_t size) {
-  return tc_malloc(size);
-}
-
-void* mz_calloc(malloc_zone_t* zone, size_t num_items, size_t size) {
-  return tc_calloc(num_items, size);
-}
-
-void* mz_valloc(malloc_zone_t* zone, size_t size) {
-  return tc_valloc(size);
-}
-
-void mz_free(malloc_zone_t* zone, void* ptr) {
-  return tc_free(ptr);
-}
-
-void* mz_realloc(malloc_zone_t* zone, void* ptr, size_t size) {
-  return tc_realloc(ptr, size);
-}
-
-void* mz_memalign(malloc_zone_t* zone, size_t align, size_t size) {
-  return tc_memalign(align, size);
-}
-
-void mz_destroy(malloc_zone_t* zone) {
-  // A no-op -- we will not be destroyed!
-}
-
-// malloc_introspection callbacks.  I'm not clear on what all of these do.
-kern_return_t mi_enumerator(task_t task, void *,
-                            unsigned type_mask, vm_address_t zone_address,
-                            memory_reader_t reader,
-                            vm_range_recorder_t recorder) {
-  // Should enumerate all the pointers we have.  Seems like a lot of work.
-  return KERN_FAILURE;
-}
-
-size_t mi_good_size(malloc_zone_t *zone, size_t size) {
-  // I think it's always safe to return size, but we maybe could do better.
-  return size;
-}
-
-boolean_t mi_check(malloc_zone_t *zone) {
-  return MallocExtension::instance()->VerifyAllMemory();
-}
-
-void mi_print(malloc_zone_t *zone, boolean_t verbose) {
-  int bufsize = 8192;
-  if (verbose)
-    bufsize = 102400;   // I picked this size arbitrarily
-  char* buffer = new char[bufsize];
-  MallocExtension::instance()->GetStats(buffer, bufsize);
-  fprintf(stdout, "%s", buffer);
-  delete[] buffer;
-}
-
-void mi_log(malloc_zone_t *zone, void *address) {
-  // I don't think we support anything like this
-}
-
-void mi_force_lock(malloc_zone_t *zone) {
-  tcmalloc::CentralCacheLockAll();
-}
-
-void mi_force_unlock(malloc_zone_t *zone) {
-  tcmalloc::CentralCacheUnlockAll();
-}
-
-void mi_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) {
-  // TODO(csilvers): figure out how to fill these out
-  stats->blocks_in_use = 0;
-  stats->size_in_use = 0;
-  stats->max_size_in_use = 0;
-  stats->size_allocated = 0;
-}
-
-boolean_t mi_zone_locked(malloc_zone_t *zone) {
-  return false;  // Hopefully unneeded by us!
-}
-
-}  // unnamed namespace
-
-// OS X doesn't have pvalloc, cfree, malloc_statc, etc, so we can just
-// define our own. :-)  OS X supplies posix_memalign in some versions
-// but not others, either strongly or weakly linked, in a way that's
-// difficult enough to code to correctly, that I just don't try to
-// support either memalign() or posix_memalign().  If you need them
-// and are willing to code to tcmalloc, you can use tc_posix_memalign().
-extern "C" {
-  void  cfree(void* p)                   { tc_cfree(p);               }
-  void* pvalloc(size_t s)                { return tc_pvalloc(s);      }
-  void malloc_stats(void)                { tc_malloc_stats();         }
-  int mallopt(int cmd, int v)            { return tc_mallopt(cmd, v); }
-  // No struct mallinfo on OS X, so don't define mallinfo().
-  // An alias for malloc_size(), which OS X defines.
-  size_t malloc_usable_size(void* p)     { return tc_malloc_size(p); }
-}  // extern "C"
-
-static malloc_zone_t *get_default_zone() {
-   malloc_zone_t **zones = NULL;
-   unsigned int num_zones = 0;
-
-   /*
-    * On OSX 10.12, malloc_default_zone returns a special zone that is not
-    * present in the list of registered zones. That zone uses a "lite zone"
-    * if one is present (apparently enabled when malloc stack logging is
-    * enabled), or the first registered zone otherwise. In practice this
-    * means unless malloc stack logging is enabled, the first registered
-    * zone is the default.
-    * So get the list of zones to get the first one, instead of relying on
-    * malloc_default_zone.
-    */
-   if (KERN_SUCCESS != malloc_get_all_zones(0, NULL, (vm_address_t**) &zones,
-                                            &num_zones)) {
-       /* Reset the value in case the failure happened after it was set. */
-       num_zones = 0;
-   }
-
-   if (num_zones)
-     return zones[0];
-
-   return malloc_default_zone();
-}
-
-
-static void ReplaceSystemAlloc() {
-  static malloc_introspection_t tcmalloc_introspection;
-  memset(&tcmalloc_introspection, 0, sizeof(tcmalloc_introspection));
-
-  tcmalloc_introspection.enumerator = &mi_enumerator;
-  tcmalloc_introspection.good_size = &mi_good_size;
-  tcmalloc_introspection.check = &mi_check;
-  tcmalloc_introspection.print = &mi_print;
-  tcmalloc_introspection.log = &mi_log;
-  tcmalloc_introspection.force_lock = &mi_force_lock;
-  tcmalloc_introspection.force_unlock = &mi_force_unlock;
-
-  static malloc_zone_t tcmalloc_zone;
-  memset(&tcmalloc_zone, 0, sizeof(malloc_zone_t));
-
-  // Start with a version 4 zone which is used for OS X 10.4 and 10.5.
-  tcmalloc_zone.version = 4;
-  tcmalloc_zone.zone_name = "tcmalloc";
-  tcmalloc_zone.size = &mz_size;
-  tcmalloc_zone.malloc = &mz_malloc;
-  tcmalloc_zone.calloc = &mz_calloc;
-  tcmalloc_zone.valloc = &mz_valloc;
-  tcmalloc_zone.free = &mz_free;
-  tcmalloc_zone.realloc = &mz_realloc;
-  tcmalloc_zone.destroy = &mz_destroy;
-  tcmalloc_zone.batch_malloc = NULL;
-  tcmalloc_zone.batch_free = NULL;
-  tcmalloc_zone.introspect = &tcmalloc_introspection;
-
-  // from AvailabilityMacros.h
-#if defined(MAC_OS_X_VERSION_10_6) && \
-    MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
-  // Switch to version 6 on OSX 10.6 to support memalign.
-  tcmalloc_zone.version = 6;
-  tcmalloc_zone.free_definite_size = NULL;
-  tcmalloc_zone.memalign = &mz_memalign;
-  tcmalloc_introspection.zone_locked = &mi_zone_locked;
-
-  // Request the default purgable zone to force its creation. The
-  // current default zone is registered with the purgable zone for
-  // doing tiny and small allocs.  Sadly, it assumes that the default
-  // zone is the szone implementation from OS X and will crash if it
-  // isn't.  By creating the zone now, this will be true and changing
-  // the default zone won't cause a problem.  This only needs to
-  // happen when actually running on OS X 10.6 and higher (note the
-  // ifdef above only checks if we were *compiled* with 10.6 or
-  // higher; at runtime we have to check if this symbol is defined.)
-  if (malloc_default_purgeable_zone) {
-    malloc_default_purgeable_zone();
-  }
-#endif
-
-  // Register the tcmalloc zone. At this point, it will not be the
-  // default zone.
-  malloc_zone_register(&tcmalloc_zone);
-
-  // Unregister and reregister the default zone.  Unregistering swaps
-  // the specified zone with the last one registered which for the
-  // default zone makes the more recently registered zone the default
-  // zone.  The default zone is then re-registered to ensure that
-  // allocations made from it earlier will be handled correctly.
-  // Things are not guaranteed to work that way, but it's how they work now.
-  malloc_zone_t *default_zone = get_default_zone();
-  malloc_zone_unregister(default_zone);
-  malloc_zone_register(default_zone);
-}
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_OSX_INL_H_
diff --git a/third_party/tcmalloc/vendor/src/libc_override_redefine.h b/third_party/tcmalloc/vendor/src/libc_override_redefine.h
deleted file mode 100644
index 4d61b25..0000000
--- a/third_party/tcmalloc/vendor/src/libc_override_redefine.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Used on systems that don't have their own definition of
-// malloc/new/etc.  (Typically this will be a windows msvcrt.dll that
-// has been edited to remove the definitions.)  We can just define our
-// own as normal functions.
-//
-// This should also work on systems were all the malloc routines are
-// defined as weak symbols, and there's no support for aliasing.
-
-#ifndef TCMALLOC_LIBC_OVERRIDE_REDEFINE_H_
-#define TCMALLOC_LIBC_OVERRIDE_REDEFINE_H_
-
-void* operator new(size_t size)                  { return tc_new(size);       }
-void operator delete(void* p) CPP_NOTHROW        { tc_delete(p);              }
-void* operator new[](size_t size)                { return tc_newarray(size);  }
-void operator delete[](void* p) CPP_NOTHROW      { tc_deletearray(p);         }
-void* operator new(size_t size, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_new_nothrow(size, nt);
-}
-void* operator new[](size_t size, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_newarray_nothrow(size, nt);
-}
-void operator delete(void* ptr, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_delete_nothrow(ptr, nt);
-}
-void operator delete[](void* ptr, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_deletearray_nothrow(ptr, nt);
-}
-
-#ifdef ENABLE_SIZED_DELETE
-void operator delete(void* p, size_t s) CPP_NOTHROW  { tc_delete_sized(p, s);     }
-void operator delete[](void* p, size_t s) CPP_NOTHROW{ tc_deletearray_sized(p, s);}
-#endif
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-void* operator new(size_t size, std::align_val_t al) {
-  return tc_new_aligned(size, al);
-}
-void operator delete(void* p, std::align_val_t al) CPP_NOTHROW {
-  tc_delete_aligned(p, al);
-}
-void* operator new[](size_t size, std::align_val_t al) {
-  return tc_newarray_aligned(size, al);
-}
-void operator delete[](void* p, std::align_val_t al) CPP_NOTHROW {
-  tc_deletearray_aligned(p, al);
-}
-void* operator new(size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_new_aligned_nothrow(size, al, nt);
-}
-void* operator new[](size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_newarray_aligned_nothrow(size, al, nt);
-}
-void operator delete(void* ptr, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_delete_aligned_nothrow(ptr, al, nt);
-}
-void operator delete[](void* ptr, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
-  return tc_deletearray_aligned_nothrow(ptr, al, nt);
-}
-
-#ifdef ENABLE_SIZED_DELETE
-void operator delete(void* p, size_t s, std::align_val_t al) CPP_NOTHROW {
-  tc_delete_sized_aligned(p, s, al);
-}
-void operator delete[](void* p, size_t s, std::align_val_t al) CPP_NOTHROW {
-  tc_deletearray_sized_aligned(p, s, al);
-}
-#endif
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-extern "C" {
-  void* malloc(size_t s)                         { return tc_malloc(s);       }
-  void  free(void* p)                            { tc_free(p);                }
-  void* realloc(void* p, size_t s)               { return tc_realloc(p, s);   }
-  void* calloc(size_t n, size_t s)               { return tc_calloc(n, s);    }
-  void  cfree(void* p)                           { tc_cfree(p);               }
-  void* memalign(size_t a, size_t s)             { return tc_memalign(a, s);  }
-  void* aligned_alloc(size_t a, size_t s)        { return tc_memalign(a, s);  }
-  void* valloc(size_t s)                         { return tc_valloc(s);       }
-  void* pvalloc(size_t s)                        { return tc_pvalloc(s);      }
-  int posix_memalign(void** r, size_t a, size_t s)         {
-    return tc_posix_memalign(r, a, s);
-  }
-  void malloc_stats(void)                        { tc_malloc_stats();         }
-  int mallopt(int cmd, int v)                    { return tc_mallopt(cmd, v); }
-#ifdef HAVE_STRUCT_MALLINFO
-  struct mallinfo mallinfo(void)                 { return tc_mallinfo();      }
-#endif
-  size_t malloc_size(void* p)                    { return tc_malloc_size(p); }
-  size_t malloc_usable_size(void* p)             { return tc_malloc_size(p); }
-}  // extern "C"
-
-// No need to do anything at tcmalloc-registration time: we do it all
-// via overriding weak symbols (at link time).
-static void ReplaceSystemAlloc() { }
-
-#endif  // TCMALLOC_LIBC_OVERRIDE_REDEFINE_H_
diff --git a/third_party/tcmalloc/vendor/src/linked_list.h b/third_party/tcmalloc/vendor/src/linked_list.h
deleted file mode 100644
index f25b6f89..0000000
--- a/third_party/tcmalloc/vendor/src/linked_list.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// Some very basic linked list functions for dealing with using void * as
-// storage.
-
-#ifndef TCMALLOC_LINKED_LIST_H_
-#define TCMALLOC_LINKED_LIST_H_
-
-#include <stddef.h>
-
-namespace tcmalloc {
-
-inline void *SLL_Next(void *t) {
-  return *(reinterpret_cast<void**>(t));
-}
-
-inline void SLL_SetNext(void *t, void *n) {
-  *(reinterpret_cast<void**>(t)) = n;
-}
-
-inline void SLL_Push(void **list, void *element) {
-  void *next = *list;
-  *list = element;
-  SLL_SetNext(element, next);
-}
-
-inline void *SLL_Pop(void **list) {
-  void *result = *list;
-  *list = SLL_Next(*list);
-  return result;
-}
-
-inline bool SLL_TryPop(void **list, void **rv) {
-  void *result = *list;
-  if (!result) {
-    return false;
-  }
-  void *next = SLL_Next(*list);
-  *list = next;
-  *rv = result;
-  return true;
-}
-
-// Remove N elements from a linked list to which head points.  head will be
-// modified to point to the new head.  start and end will point to the first
-// and last nodes of the range.  Note that end will point to NULL after this
-// function is called.
-inline void SLL_PopRange(void **head, int N, void **start, void **end) {
-  if (N == 0) {
-    *start = NULL;
-    *end = NULL;
-    return;
-  }
-
-  void *tmp = *head;
-  for (int i = 1; i < N; ++i) {
-    tmp = SLL_Next(tmp);
-  }
-
-  *start = *head;
-  *end = tmp;
-  *head = SLL_Next(tmp);
-  // Unlink range from list.
-  SLL_SetNext(tmp, NULL);
-}
-
-inline void SLL_PushRange(void **head, void *start, void *end) {
-  if (!start) return;
-  SLL_SetNext(end, *head);
-  *head = start;
-}
-
-inline size_t SLL_Size(void *head) {
-  int count = 0;
-  while (head) {
-    count++;
-    head = SLL_Next(head);
-  }
-  return count;
-}
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_LINKED_LIST_H_
diff --git a/third_party/tcmalloc/vendor/src/malloc_extension.cc b/third_party/tcmalloc/vendor/src/malloc_extension.cc
deleted file mode 100644
index 6e695523..0000000
--- a/third_party/tcmalloc/vendor/src/malloc_extension.cc
+++ /dev/null
@@ -1,388 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-#include <string>
-#include "base/dynamic_annotations.h"
-#include "base/sysinfo.h"    // for FillProcSelfMaps
-#ifndef NO_HEAP_CHECK
-#include "gperftools/heap-checker.h"
-#endif
-#include "gperftools/malloc_extension.h"
-#include "gperftools/malloc_extension_c.h"
-#include "maybe_threads.h"
-#include "base/googleinit.h"
-
-using STL_NAMESPACE::string;
-using STL_NAMESPACE::vector;
-
-static void DumpAddressMap(string* result) {
-  *result += "\nMAPPED_LIBRARIES:\n";
-  // We keep doubling until we get a fit
-  const size_t old_resultlen = result->size();
-  for (int amap_size = 10240; amap_size < 10000000; amap_size *= 2) {
-    result->resize(old_resultlen + amap_size);
-    bool wrote_all = false;
-    const int bytes_written =
-        tcmalloc::FillProcSelfMaps(&((*result)[old_resultlen]), amap_size,
-                                   &wrote_all);
-    if (wrote_all) {   // we fit!
-      (*result)[old_resultlen + bytes_written] = '\0';
-      result->resize(old_resultlen + bytes_written);
-      return;
-    }
-  }
-  result->reserve(old_resultlen);   // just don't print anything
-}
-
-// Note: this routine is meant to be called before threads are spawned.
-void MallocExtension::Initialize() {
-  static bool initialize_called = false;
-
-  if (initialize_called) return;
-  initialize_called = true;
-
-#ifdef __GLIBC__
-  // GNU libc++ versions 3.3 and 3.4 obey the environment variables
-  // GLIBCPP_FORCE_NEW and GLIBCXX_FORCE_NEW respectively.  Setting
-  // one of these variables forces the STL default allocator to call
-  // new() or delete() for each allocation or deletion.  Otherwise
-  // the STL allocator tries to avoid the high cost of doing
-  // allocations by pooling memory internally.  However, tcmalloc
-  // does allocations really fast, especially for the types of small
-  // items one sees in STL, so it's better off just using us.
-  // TODO: control whether we do this via an environment variable?
-  setenv("GLIBCPP_FORCE_NEW", "1", false /* no overwrite*/);
-  setenv("GLIBCXX_FORCE_NEW", "1", false /* no overwrite*/);
-
-  // Now we need to make the setenv 'stick', which it may not do since
-  // the env is flakey before main() is called.  But luckily stl only
-  // looks at this env var the first time it tries to do an alloc, and
-  // caches what it finds.  So we just cause an stl alloc here.
-  string dummy("I need to be allocated");
-  dummy += "!";         // so the definition of dummy isn't optimized out
-#endif  /* __GLIBC__ */
-}
-
-// SysAllocator implementation
-SysAllocator::~SysAllocator() {}
-
-// Default implementation -- does nothing
-MallocExtension::~MallocExtension() { }
-bool MallocExtension::VerifyAllMemory() { return true; }
-bool MallocExtension::VerifyNewMemory(const void* p) { return true; }
-bool MallocExtension::VerifyArrayNewMemory(const void* p) { return true; }
-bool MallocExtension::VerifyMallocMemory(const void* p) { return true; }
-
-bool MallocExtension::GetNumericProperty(const char* property, size_t* value) {
-  return false;
-}
-
-bool MallocExtension::SetNumericProperty(const char* property, size_t value) {
-  return false;
-}
-
-void MallocExtension::GetStats(char* buffer, int length) {
-  assert(length > 0);
-  buffer[0] = '\0';
-}
-
-bool MallocExtension::MallocMemoryStats(int* blocks, size_t* total,
-                                       int histogram[kMallocHistogramSize]) {
-  *blocks = 0;
-  *total = 0;
-  memset(histogram, 0, sizeof(*histogram) * kMallocHistogramSize);
-  return true;
-}
-
-void** MallocExtension::ReadStackTraces(int* sample_period) {
-  return NULL;
-}
-
-void** MallocExtension::ReadHeapGrowthStackTraces() {
-  return NULL;
-}
-
-void MallocExtension::MarkThreadIdle() {
-  // Default implementation does nothing
-}
-
-void MallocExtension::MarkThreadBusy() {
-  // Default implementation does nothing
-}
-
-SysAllocator* MallocExtension::GetSystemAllocator() {
-  return NULL;
-}
-
-void MallocExtension::SetSystemAllocator(SysAllocator *a) {
-  // Default implementation does nothing
-}
-
-void MallocExtension::ReleaseToSystem(size_t num_bytes) {
-  // Default implementation does nothing
-}
-
-void MallocExtension::ReleaseFreeMemory() {
-  ReleaseToSystem(static_cast<size_t>(-1));   // SIZE_T_MAX
-}
-
-void MallocExtension::SetMemoryReleaseRate(double rate) {
-  // Default implementation does nothing
-}
-
-double MallocExtension::GetMemoryReleaseRate() {
-  return -1.0;
-}
-
-size_t MallocExtension::GetEstimatedAllocatedSize(size_t size) {
-  return size;
-}
-
-size_t MallocExtension::GetAllocatedSize(const void* p) {
-  assert(GetOwnership(p) != kNotOwned);
-  return 0;
-}
-
-MallocExtension::Ownership MallocExtension::GetOwnership(const void* p) {
-  return kUnknownOwnership;
-}
-
-void MallocExtension::GetFreeListSizes(
-    vector<MallocExtension::FreeListInfo>* v) {
-  v->clear();
-}
-
-size_t MallocExtension::GetThreadCacheSize() {
-  return 0;
-}
-
-void MallocExtension::MarkThreadTemporarilyIdle() {
-  // Default implementation does nothing
-}
-
-// The current malloc extension object.
-
-static MallocExtension* current_instance;
-
-static void InitModule() {
-  if (current_instance != NULL) {
-    return;
-  }
-  current_instance = new MallocExtension;
-#ifndef NO_HEAP_CHECK
-  HeapLeakChecker::IgnoreObject(current_instance);
-#endif
-}
-
-REGISTER_MODULE_INITIALIZER(malloc_extension_init, InitModule())
-
-MallocExtension* MallocExtension::instance() {
-  InitModule();
-  return current_instance;
-}
-
-void MallocExtension::Register(MallocExtension* implementation) {
-  InitModule();
-  // When running under valgrind, our custom malloc is replaced with
-  // valgrind's one and malloc extensions will not work.  (Note:
-  // callers should be responsible for checking that they are the
-  // malloc that is really being run, before calling Register.  This
-  // is just here as an extra sanity check.)
-  if (!RunningOnValgrind()) {
-    current_instance = implementation;
-  }
-}
-
-// -----------------------------------------------------------------------
-// Heap sampling support
-// -----------------------------------------------------------------------
-
-namespace {
-
-// Accessors
-uintptr_t Count(void** entry) {
-  return reinterpret_cast<uintptr_t>(entry[0]);
-}
-uintptr_t Size(void** entry) {
-  return reinterpret_cast<uintptr_t>(entry[1]);
-}
-uintptr_t Depth(void** entry) {
-  return reinterpret_cast<uintptr_t>(entry[2]);
-}
-void* PC(void** entry, int i) {
-  return entry[3+i];
-}
-
-void PrintCountAndSize(MallocExtensionWriter* writer,
-                       uintptr_t count, uintptr_t size) {
-  char buf[100];
-  snprintf(buf, sizeof(buf),
-           "%6" PRIu64 ": %8" PRIu64 " [%6" PRIu64 ": %8" PRIu64 "] @",
-           static_cast<uint64>(count),
-           static_cast<uint64>(size),
-           static_cast<uint64>(count),
-           static_cast<uint64>(size));
-  writer->append(buf, strlen(buf));
-}
-
-void PrintHeader(MallocExtensionWriter* writer,
-                 const char* label, void** entries) {
-  // Compute the total count and total size
-  uintptr_t total_count = 0;
-  uintptr_t total_size = 0;
-  for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
-    total_count += Count(entry);
-    total_size += Size(entry);
-  }
-
-  const char* const kTitle = "heap profile: ";
-  writer->append(kTitle, strlen(kTitle));
-  PrintCountAndSize(writer, total_count, total_size);
-  writer->append(" ", 1);
-  writer->append(label, strlen(label));
-  writer->append("\n", 1);
-}
-
-void PrintStackEntry(MallocExtensionWriter* writer, void** entry) {
-  PrintCountAndSize(writer, Count(entry), Size(entry));
-
-  for (int i = 0; i < Depth(entry); i++) {
-    char buf[32];
-    snprintf(buf, sizeof(buf), " %p", PC(entry, i));
-    writer->append(buf, strlen(buf));
-  }
-  writer->append("\n", 1);
-}
-
-}
-
-void MallocExtension::GetHeapSample(MallocExtensionWriter* writer) {
-  int sample_period = 0;
-  void** entries = ReadStackTraces(&sample_period);
-  if (entries == NULL) {
-    const char* const kErrorMsg =
-        "This malloc implementation does not support sampling.\n"
-        "As of 2005/01/26, only tcmalloc supports sampling, and\n"
-        "you are probably running a binary that does not use\n"
-        "tcmalloc.\n";
-    writer->append(kErrorMsg, strlen(kErrorMsg));
-    return;
-  }
-
-  char label[32];
-  sprintf(label, "heap_v2/%d", sample_period);
-  PrintHeader(writer, label, entries);
-  for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
-    PrintStackEntry(writer, entry);
-  }
-  delete[] entries;
-
-  DumpAddressMap(writer);
-}
-
-void MallocExtension::GetHeapGrowthStacks(MallocExtensionWriter* writer) {
-  void** entries = ReadHeapGrowthStackTraces();
-  if (entries == NULL) {
-    const char* const kErrorMsg =
-        "This malloc implementation does not support "
-        "ReadHeapGrowthStackTraces().\n"
-        "As of 2005/09/27, only tcmalloc supports this, and you\n"
-        "are probably running a binary that does not use tcmalloc.\n";
-    writer->append(kErrorMsg, strlen(kErrorMsg));
-    return;
-  }
-
-  // Do not canonicalize the stack entries, so that we get a
-  // time-ordered list of stack traces, which may be useful if the
-  // client wants to focus on the latest stack traces.
-  PrintHeader(writer, "growth", entries);
-  for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
-    PrintStackEntry(writer, entry);
-  }
-  delete[] entries;
-
-  DumpAddressMap(writer);
-}
-
-void MallocExtension::Ranges(void* arg, RangeFunction func) {
-  // No callbacks by default
-}
-
-// These are C shims that work on the current instance.
-
-#define C_SHIM(fn, retval, paramlist, arglist)          \
-  extern "C" PERFTOOLS_DLL_DECL retval MallocExtension_##fn paramlist {    \
-    return MallocExtension::instance()->fn arglist;     \
-  }
-
-C_SHIM(VerifyAllMemory, int, (void), ());
-C_SHIM(VerifyNewMemory, int, (const void* p), (p));
-C_SHIM(VerifyArrayNewMemory, int, (const void* p), (p));
-C_SHIM(VerifyMallocMemory, int, (const void* p), (p));
-C_SHIM(MallocMemoryStats, int,
-       (int* blocks, size_t* total, int histogram[kMallocHistogramSize]),
-       (blocks, total, histogram));
-
-C_SHIM(GetStats, void,
-       (char* buffer, int buffer_length), (buffer, buffer_length));
-C_SHIM(GetNumericProperty, int,
-       (const char* property, size_t* value), (property, value));
-C_SHIM(SetNumericProperty, int,
-       (const char* property, size_t value), (property, value));
-
-C_SHIM(MarkThreadIdle, void, (void), ());
-C_SHIM(MarkThreadBusy, void, (void), ());
-C_SHIM(ReleaseFreeMemory, void, (void), ());
-C_SHIM(ReleaseToSystem, void, (size_t num_bytes), (num_bytes));
-C_SHIM(GetEstimatedAllocatedSize, size_t, (size_t size), (size));
-C_SHIM(GetAllocatedSize, size_t, (const void* p), (p));
-C_SHIM(GetThreadCacheSize, size_t, (void), ());
-C_SHIM(MarkThreadTemporarilyIdle, void, (void), ());
-
-// Can't use the shim here because of the need to translate the enums.
-extern "C"
-MallocExtension_Ownership MallocExtension_GetOwnership(const void* p) {
-  return static_cast<MallocExtension_Ownership>(
-      MallocExtension::instance()->GetOwnership(p));
-}
diff --git a/third_party/tcmalloc/vendor/src/malloc_hook-inl.h b/third_party/tcmalloc/vendor/src/malloc_hook-inl.h
deleted file mode 100644
index 30375d6..0000000
--- a/third_party/tcmalloc/vendor/src/malloc_hook-inl.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// This has the implementation details of malloc_hook that are needed
-// to use malloc-hook inside the tcmalloc system.  It does not hold
-// any of the client-facing calls that are used to add new hooks.
-
-#ifndef _MALLOC_HOOK_INL_H_
-#define _MALLOC_HOOK_INL_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-#include "base/atomicops.h"
-#include "base/basictypes.h"
-#include <gperftools/malloc_hook.h>
-
-#include "common.h" // for UNLIKELY
-
-namespace base { namespace internal {
-
-// Capacity of 8 means that HookList is 9 words.
-static const int kHookListCapacity = 8;
-// last entry is reserved for deprecated "singular" hooks. So we have
-// 7 "normal" hooks per list
-static const int kHookListMaxValues = 7;
-static const int kHookListSingularIdx = 7;
-
-// HookList: a class that provides synchronized insertions and removals and
-// lockless traversal.  Most of the implementation is in malloc_hook.cc.
-template <typename T>
-struct PERFTOOLS_DLL_DECL HookList {
-  COMPILE_ASSERT(sizeof(T) <= sizeof(AtomicWord), T_should_fit_in_AtomicWord);
-
-  // Adds value to the list.  Note that duplicates are allowed.  Thread-safe and
-  // blocking (acquires hooklist_spinlock).  Returns true on success; false
-  // otherwise (failures include invalid value and no space left).
-  bool Add(T value);
-
-  void FixupPrivEndLocked();
-
-  // Removes the first entry matching value from the list.  Thread-safe and
-  // blocking (acquires hooklist_spinlock).  Returns true on success; false
-  // otherwise (failures include invalid value and no value found).
-  bool Remove(T value);
-
-  // Store up to n values of the list in output_array, and return the number of
-  // elements stored.  Thread-safe and non-blocking.  This is fast (one memory
-  // access) if the list is empty.
-  int Traverse(T* output_array, int n) const;
-
-  // Fast inline implementation for fast path of Invoke*Hook.
-  bool empty() const {
-    return base::subtle::NoBarrier_Load(&priv_end) == 0;
-  }
-
-  // Used purely to handle deprecated singular hooks
-  T GetSingular() const {
-    const AtomicWord *place = &priv_data[kHookListSingularIdx];
-    return bit_cast<T>(base::subtle::NoBarrier_Load(place));
-  }
-
-  T ExchangeSingular(T new_val);
-
-  // This internal data is not private so that the class is an aggregate and can
-  // be initialized by the linker.  Don't access this directly.  Use the
-  // INIT_HOOK_LIST macro in malloc_hook.cc.
-
-  // One more than the index of the last valid element in priv_data.  During
-  // 'Remove' this may be past the last valid element in priv_data, but
-  // subsequent values will be 0.
-  //
-  // Index kHookListCapacity-1 is reserved as 'deprecated' single hook pointer
-  AtomicWord priv_end;
-  AtomicWord priv_data[kHookListCapacity];
-};
-
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::NewHook> new_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::DeleteHook> delete_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::PreMmapHook> premmap_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MmapHook> mmap_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MmapReplacement> mmap_replacement_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MunmapHook> munmap_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MunmapReplacement> munmap_replacement_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::MremapHook> mremap_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::PreSbrkHook> presbrk_hooks_;
-ATTRIBUTE_VISIBILITY_HIDDEN extern HookList<MallocHook::SbrkHook> sbrk_hooks_;
-
-} }  // namespace base::internal
-
-// The following method is DEPRECATED
-inline MallocHook::NewHook MallocHook::GetNewHook() {
-  return base::internal::new_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeNewHook(const void* p, size_t s) {
-  if (PREDICT_FALSE(!base::internal::new_hooks_.empty())) {
-    InvokeNewHookSlow(p, s);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::DeleteHook MallocHook::GetDeleteHook() {
-  return base::internal::delete_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeDeleteHook(const void* p) {
-  if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
-    InvokeDeleteHookSlow(p);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::PreMmapHook MallocHook::GetPreMmapHook() {
-  return base::internal::premmap_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokePreMmapHook(const void* start,
-                                          size_t size,
-                                          int protection,
-                                          int flags,
-                                          int fd,
-                                          off_t offset) {
-  if (!base::internal::premmap_hooks_.empty()) {
-    InvokePreMmapHookSlow(start, size, protection, flags, fd, offset);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::MmapHook MallocHook::GetMmapHook() {
-  return base::internal::mmap_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeMmapHook(const void* result,
-                                       const void* start,
-                                       size_t size,
-                                       int protection,
-                                       int flags,
-                                       int fd,
-                                       off_t offset) {
-  if (!base::internal::mmap_hooks_.empty()) {
-    InvokeMmapHookSlow(result, start, size, protection, flags, fd, offset);
-  }
-}
-
-inline bool MallocHook::InvokeMmapReplacement(const void* start,
-                                              size_t size,
-                                              int protection,
-                                              int flags,
-                                              int fd,
-                                              off_t offset,
-                                              void** result) {
-  if (!base::internal::mmap_replacement_.empty()) {
-    return InvokeMmapReplacementSlow(start, size,
-                                     protection, flags,
-                                     fd, offset,
-                                     result);
-  }
-  return false;
-}
-
-// The following method is DEPRECATED
-inline MallocHook::MunmapHook MallocHook::GetMunmapHook() {
-  return base::internal::munmap_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeMunmapHook(const void* p, size_t size) {
-  if (!base::internal::munmap_hooks_.empty()) {
-    InvokeMunmapHookSlow(p, size);
-  }
-}
-
-inline bool MallocHook::InvokeMunmapReplacement(
-    const void* p, size_t size, int* result) {
-  if (!base::internal::mmap_replacement_.empty()) {
-    return InvokeMunmapReplacementSlow(p, size, result);
-  }
-  return false;
-}
-
-// The following method is DEPRECATED
-inline MallocHook::MremapHook MallocHook::GetMremapHook() {
-  return base::internal::mremap_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeMremapHook(const void* result,
-                                         const void* old_addr,
-                                         size_t old_size,
-                                         size_t new_size,
-                                         int flags,
-                                         const void* new_addr) {
-  if (!base::internal::mremap_hooks_.empty()) {
-    InvokeMremapHookSlow(result, old_addr, old_size, new_size, flags, new_addr);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::PreSbrkHook MallocHook::GetPreSbrkHook() {
-  return base::internal::presbrk_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokePreSbrkHook(ptrdiff_t increment) {
-  if (!base::internal::presbrk_hooks_.empty() && increment != 0) {
-    InvokePreSbrkHookSlow(increment);
-  }
-}
-
-// The following method is DEPRECATED
-inline MallocHook::SbrkHook MallocHook::GetSbrkHook() {
-  return base::internal::sbrk_hooks_.GetSingular();
-}
-
-inline void MallocHook::InvokeSbrkHook(const void* result,
-                                       ptrdiff_t increment) {
-  if (!base::internal::sbrk_hooks_.empty() && increment != 0) {
-    InvokeSbrkHookSlow(result, increment);
-  }
-}
-
-#endif /* _MALLOC_HOOK_INL_H_ */
diff --git a/third_party/tcmalloc/vendor/src/malloc_hook.cc b/third_party/tcmalloc/vendor/src/malloc_hook.cc
deleted file mode 100644
index 64c2165..0000000
--- a/third_party/tcmalloc/vendor/src/malloc_hook.cc
+++ /dev/null
@@ -1,711 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-
-// Disable the glibc prototype of mremap(), as older versions of the
-// system headers define this function with only four arguments,
-// whereas newer versions allow an optional fifth argument:
-#ifdef HAVE_MMAP
-# define mremap glibc_mremap
-# include <sys/mman.h>
-# undef mremap
-#endif
-
-#include <stddef.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <algorithm>
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "maybe_emergency_malloc.h"
-#include "maybe_threads.h"
-#include "malloc_hook-inl.h"
-#include <gperftools/malloc_hook.h>
-
-// This #ifdef should almost never be set.  Set NO_TCMALLOC_SAMPLES if
-// you're porting to a system where you really can't get a stacktrace.
-#ifdef NO_TCMALLOC_SAMPLES
-  // We use #define so code compiles even if you #include stacktrace.h somehow.
-# define GetStackTrace(stack, depth, skip)  (0)
-#else
-# include <gperftools/stacktrace.h>
-#endif
-
-// __THROW is defined in glibc systems.  It means, counter-intuitively,
-// "This function will never throw an exception."  It's an optional
-// optimization tool, but we may need to use it to match glibc prototypes.
-#ifndef __THROW    // I guess we're not on a glibc system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-using std::copy;
-
-
-// Declaration of default weak initialization function, that can be overridden
-// by linking-in a strong definition (as heap-checker.cc does).  This is
-// extern "C" so that it doesn't trigger gold's --detect-odr-violations warning,
-// which only looks at C++ symbols.
-//
-// This function is declared here as weak, and defined later, rather than a more
-// straightforward simple weak definition, as a workround for an icc compiler
-// issue ((Intel reference 290819).  This issue causes icc to resolve weak
-// symbols too early, at compile rather than link time.  By declaring it (weak)
-// here, then defining it below after its use, we can avoid the problem.
-extern "C" {
-ATTRIBUTE_WEAK void MallocHook_InitAtFirstAllocation_HeapLeakChecker();
-}
-
-namespace {
-
-void RemoveInitialHooksAndCallInitializers();  // below.
-
-pthread_once_t once = PTHREAD_ONCE_INIT;
-
-// These hooks are installed in MallocHook as the only initial hooks.  The first
-// hook that is called will run RemoveInitialHooksAndCallInitializers (see the
-// definition below) and then redispatch to any malloc hooks installed by
-// RemoveInitialHooksAndCallInitializers.
-//
-// Note(llib): there is a possibility of a race in the event that there are
-// multiple threads running before the first allocation.  This is pretty
-// difficult to achieve, but if it is then multiple threads may concurrently do
-// allocations.  The first caller will call
-// RemoveInitialHooksAndCallInitializers via one of the initial hooks.  A
-// concurrent allocation may, depending on timing either:
-// * still have its initial malloc hook installed, run that and block on waiting
-//   for the first caller to finish its call to
-//   RemoveInitialHooksAndCallInitializers, and proceed normally.
-// * occur some time during the RemoveInitialHooksAndCallInitializers call, at
-//   which point there could be no initial hooks and the subsequent hooks that
-//   are about to be set up by RemoveInitialHooksAndCallInitializers haven't
-//   been installed yet.  I think the worst we can get is that some allocations
-//   will not get reported to some hooks set by the initializers called from
-//   RemoveInitialHooksAndCallInitializers.
-
-void InitialNewHook(const void* ptr, size_t size) {
-  perftools_pthread_once(&once, &RemoveInitialHooksAndCallInitializers);
-  MallocHook::InvokeNewHook(ptr, size);
-}
-
-void InitialPreMMapHook(const void* start,
-                               size_t size,
-                               int protection,
-                               int flags,
-                               int fd,
-                               off_t offset) {
-  perftools_pthread_once(&once, &RemoveInitialHooksAndCallInitializers);
-  MallocHook::InvokePreMmapHook(start, size, protection, flags, fd, offset);
-}
-
-void InitialPreSbrkHook(ptrdiff_t increment) {
-  perftools_pthread_once(&once, &RemoveInitialHooksAndCallInitializers);
-  MallocHook::InvokePreSbrkHook(increment);
-}
-
-// This function is called at most once by one of the above initial malloc
-// hooks.  It removes all initial hooks and initializes all other clients that
-// want to get control at the very first memory allocation.  The initializers
-// may assume that the initial malloc hooks have been removed.  The initializers
-// may set up malloc hooks and allocate memory.
-void RemoveInitialHooksAndCallInitializers() {
-  RAW_CHECK(MallocHook::RemoveNewHook(&InitialNewHook), "");
-  RAW_CHECK(MallocHook::RemovePreMmapHook(&InitialPreMMapHook), "");
-  RAW_CHECK(MallocHook::RemovePreSbrkHook(&InitialPreSbrkHook), "");
-
-  // HeapLeakChecker is currently the only module that needs to get control on
-  // the first memory allocation, but one can add other modules by following the
-  // same weak/strong function pattern.
-  MallocHook_InitAtFirstAllocation_HeapLeakChecker();
-}
-
-}  // namespace
-
-// Weak default initialization function that must go after its use.
-extern "C" void MallocHook_InitAtFirstAllocation_HeapLeakChecker() {
-  // Do nothing.
-}
-
-namespace base { namespace internal {
-
-// This lock is shared between all implementations of HookList::Add & Remove.
-// The potential for contention is very small.  This needs to be a SpinLock and
-// not a Mutex since it's possible for Mutex locking to allocate memory (e.g.,
-// per-thread allocation in debug builds), which could cause infinite recursion.
-static SpinLock hooklist_spinlock(base::LINKER_INITIALIZED);
-
-template <typename T>
-bool HookList<T>::Add(T value_as_t) {
-  AtomicWord value = bit_cast<AtomicWord>(value_as_t);
-  if (value == 0) {
-    return false;
-  }
-  SpinLockHolder l(&hooklist_spinlock);
-  // Find the first slot in data that is 0.
-  int index = 0;
-  while ((index < kHookListMaxValues) &&
-         (base::subtle::NoBarrier_Load(&priv_data[index]) != 0)) {
-    ++index;
-  }
-  if (index == kHookListMaxValues) {
-    return false;
-  }
-  AtomicWord prev_num_hooks = base::subtle::Acquire_Load(&priv_end);
-  base::subtle::NoBarrier_Store(&priv_data[index], value);
-  if (prev_num_hooks <= index) {
-    base::subtle::NoBarrier_Store(&priv_end, index + 1);
-  }
-  return true;
-}
-
-template <typename T>
-void HookList<T>::FixupPrivEndLocked() {
-  AtomicWord hooks_end = base::subtle::NoBarrier_Load(&priv_end);
-  while ((hooks_end > 0) &&
-         (base::subtle::NoBarrier_Load(&priv_data[hooks_end - 1]) == 0)) {
-    --hooks_end;
-  }
-  base::subtle::NoBarrier_Store(&priv_end, hooks_end);
-}
-
-template <typename T>
-bool HookList<T>::Remove(T value_as_t) {
-  if (value_as_t == 0) {
-    return false;
-  }
-  SpinLockHolder l(&hooklist_spinlock);
-  AtomicWord hooks_end = base::subtle::NoBarrier_Load(&priv_end);
-  int index = 0;
-  while (index < hooks_end && value_as_t != bit_cast<T>(
-             base::subtle::NoBarrier_Load(&priv_data[index]))) {
-    ++index;
-  }
-  if (index == hooks_end) {
-    return false;
-  }
-  base::subtle::NoBarrier_Store(&priv_data[index], 0);
-  FixupPrivEndLocked();
-  return true;
-}
-
-template <typename T>
-int HookList<T>::Traverse(T* output_array, int n) const {
-  AtomicWord hooks_end = base::subtle::Acquire_Load(&priv_end);
-  int actual_hooks_end = 0;
-  for (int i = 0; i < hooks_end && n > 0; ++i) {
-    AtomicWord data = base::subtle::Acquire_Load(&priv_data[i]);
-    if (data != 0) {
-      *output_array++ = bit_cast<T>(data);
-      ++actual_hooks_end;
-      --n;
-    }
-  }
-  return actual_hooks_end;
-}
-
-template <typename T>
-T HookList<T>::ExchangeSingular(T value_as_t) {
-  AtomicWord value = bit_cast<AtomicWord>(value_as_t);
-  AtomicWord old_value;
-  SpinLockHolder l(&hooklist_spinlock);
-  old_value = base::subtle::NoBarrier_Load(&priv_data[kHookListSingularIdx]);
-  base::subtle::NoBarrier_Store(&priv_data[kHookListSingularIdx], value);
-  if (value != 0) {
-    base::subtle::NoBarrier_Store(&priv_end, kHookListSingularIdx + 1);
-  } else {
-    FixupPrivEndLocked();
-  }
-  return bit_cast<T>(old_value);
-}
-
-// Initialize a HookList (optionally with the given initial_value in index 0).
-#define INIT_HOOK_LIST { 0 }
-#define INIT_HOOK_LIST_WITH_VALUE(initial_value)                \
-  { 1, { reinterpret_cast<AtomicWord>(initial_value) } }
-
-// Explicit instantiation for malloc_hook_test.cc.  This ensures all the methods
-// are instantiated.
-template struct HookList<MallocHook::NewHook>;
-
-HookList<MallocHook::NewHook> new_hooks_ =
-    INIT_HOOK_LIST_WITH_VALUE(&InitialNewHook);
-HookList<MallocHook::DeleteHook> delete_hooks_ = INIT_HOOK_LIST;
-HookList<MallocHook::PreMmapHook> premmap_hooks_ =
-    INIT_HOOK_LIST_WITH_VALUE(&InitialPreMMapHook);
-HookList<MallocHook::MmapHook> mmap_hooks_ = INIT_HOOK_LIST;
-HookList<MallocHook::MunmapHook> munmap_hooks_ = INIT_HOOK_LIST;
-HookList<MallocHook::MremapHook> mremap_hooks_ = INIT_HOOK_LIST;
-HookList<MallocHook::PreSbrkHook> presbrk_hooks_ =
-    INIT_HOOK_LIST_WITH_VALUE(InitialPreSbrkHook);
-HookList<MallocHook::SbrkHook> sbrk_hooks_ = INIT_HOOK_LIST;
-
-// These lists contain either 0 or 1 hooks.
-HookList<MallocHook::MmapReplacement> mmap_replacement_ = { 0 };
-HookList<MallocHook::MunmapReplacement> munmap_replacement_ = { 0 };
-
-#undef INIT_HOOK_LIST_WITH_VALUE
-#undef INIT_HOOK_LIST
-
-} }  // namespace base::internal
-
-using base::internal::kHookListMaxValues;
-using base::internal::new_hooks_;
-using base::internal::delete_hooks_;
-using base::internal::premmap_hooks_;
-using base::internal::mmap_hooks_;
-using base::internal::mmap_replacement_;
-using base::internal::munmap_hooks_;
-using base::internal::munmap_replacement_;
-using base::internal::mremap_hooks_;
-using base::internal::presbrk_hooks_;
-using base::internal::sbrk_hooks_;
-
-// These are available as C bindings as well as C++, hence their
-// definition outside the MallocHook class.
-extern "C"
-int MallocHook_AddNewHook(MallocHook_NewHook hook) {
-  RAW_VLOG(10, "AddNewHook(%p)", hook);
-  return new_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveNewHook(MallocHook_NewHook hook) {
-  RAW_VLOG(10, "RemoveNewHook(%p)", hook);
-  return new_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddDeleteHook(MallocHook_DeleteHook hook) {
-  RAW_VLOG(10, "AddDeleteHook(%p)", hook);
-  return delete_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveDeleteHook(MallocHook_DeleteHook hook) {
-  RAW_VLOG(10, "RemoveDeleteHook(%p)", hook);
-  return delete_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddPreMmapHook(MallocHook_PreMmapHook hook) {
-  RAW_VLOG(10, "AddPreMmapHook(%p)", hook);
-  return premmap_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemovePreMmapHook(MallocHook_PreMmapHook hook) {
-  RAW_VLOG(10, "RemovePreMmapHook(%p)", hook);
-  return premmap_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_SetMmapReplacement(MallocHook_MmapReplacement hook) {
-  RAW_VLOG(10, "SetMmapReplacement(%p)", hook);
-  // NOTE this is a best effort CHECK. Concurrent sets could succeed since
-  // this test is outside of the Add spin lock.
-  RAW_CHECK(mmap_replacement_.empty(), "Only one MMapReplacement is allowed.");
-  return mmap_replacement_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMmapReplacement(MallocHook_MmapReplacement hook) {
-  RAW_VLOG(10, "RemoveMmapReplacement(%p)", hook);
-  return mmap_replacement_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddMmapHook(MallocHook_MmapHook hook) {
-  RAW_VLOG(10, "AddMmapHook(%p)", hook);
-  return mmap_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMmapHook(MallocHook_MmapHook hook) {
-  RAW_VLOG(10, "RemoveMmapHook(%p)", hook);
-  return mmap_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddMunmapHook(MallocHook_MunmapHook hook) {
-  RAW_VLOG(10, "AddMunmapHook(%p)", hook);
-  return munmap_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMunmapHook(MallocHook_MunmapHook hook) {
-  RAW_VLOG(10, "RemoveMunmapHook(%p)", hook);
-  return munmap_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_SetMunmapReplacement(MallocHook_MunmapReplacement hook) {
-  RAW_VLOG(10, "SetMunmapReplacement(%p)", hook);
-  // NOTE this is a best effort CHECK. Concurrent sets could succeed since
-  // this test is outside of the Add spin lock.
-  RAW_CHECK(munmap_replacement_.empty(),
-            "Only one MunmapReplacement is allowed.");
-  return munmap_replacement_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMunmapReplacement(MallocHook_MunmapReplacement hook) {
-  RAW_VLOG(10, "RemoveMunmapReplacement(%p)", hook);
-  return munmap_replacement_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddMremapHook(MallocHook_MremapHook hook) {
-  RAW_VLOG(10, "AddMremapHook(%p)", hook);
-  return mremap_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveMremapHook(MallocHook_MremapHook hook) {
-  RAW_VLOG(10, "RemoveMremapHook(%p)", hook);
-  return mremap_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddPreSbrkHook(MallocHook_PreSbrkHook hook) {
-  RAW_VLOG(10, "AddPreSbrkHook(%p)", hook);
-  return presbrk_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemovePreSbrkHook(MallocHook_PreSbrkHook hook) {
-  RAW_VLOG(10, "RemovePreSbrkHook(%p)", hook);
-  return presbrk_hooks_.Remove(hook);
-}
-
-extern "C"
-int MallocHook_AddSbrkHook(MallocHook_SbrkHook hook) {
-  RAW_VLOG(10, "AddSbrkHook(%p)", hook);
-  return sbrk_hooks_.Add(hook);
-}
-
-extern "C"
-int MallocHook_RemoveSbrkHook(MallocHook_SbrkHook hook) {
-  RAW_VLOG(10, "RemoveSbrkHook(%p)", hook);
-  return sbrk_hooks_.Remove(hook);
-}
-
-// The code below is DEPRECATED.
-extern "C"
-MallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook) {
-  RAW_VLOG(10, "SetNewHook(%p)", hook);
-  return new_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook) {
-  RAW_VLOG(10, "SetDeleteHook(%p)", hook);
-  return delete_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_PreMmapHook MallocHook_SetPreMmapHook(MallocHook_PreMmapHook hook) {
-  RAW_VLOG(10, "SetPreMmapHook(%p)", hook);
-  return premmap_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_MmapHook MallocHook_SetMmapHook(MallocHook_MmapHook hook) {
-  RAW_VLOG(10, "SetMmapHook(%p)", hook);
-  return mmap_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_MunmapHook MallocHook_SetMunmapHook(MallocHook_MunmapHook hook) {
-  RAW_VLOG(10, "SetMunmapHook(%p)", hook);
-  return munmap_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_MremapHook MallocHook_SetMremapHook(MallocHook_MremapHook hook) {
-  RAW_VLOG(10, "SetMremapHook(%p)", hook);
-  return mremap_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_PreSbrkHook MallocHook_SetPreSbrkHook(MallocHook_PreSbrkHook hook) {
-  RAW_VLOG(10, "SetPreSbrkHook(%p)", hook);
-  return presbrk_hooks_.ExchangeSingular(hook);
-}
-
-extern "C"
-MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook) {
-  RAW_VLOG(10, "SetSbrkHook(%p)", hook);
-  return sbrk_hooks_.ExchangeSingular(hook);
-}
-// End of DEPRECATED code section.
-
-// Note: embedding the function calls inside the traversal of HookList would be
-// very confusing, as it is legal for a hook to remove itself and add other
-// hooks.  Doing traversal first, and then calling the hooks ensures we only
-// call the hooks registered at the start.
-#define INVOKE_HOOKS(HookType, hook_list, args) do {                    \
-    HookType hooks[kHookListMaxValues];                                 \
-    int num_hooks = hook_list.Traverse(hooks, kHookListMaxValues);      \
-    for (int i = 0; i < num_hooks; ++i) {                               \
-      (*hooks[i])args;                                                  \
-    }                                                                   \
-  } while (0)
-
-// There should only be one replacement. Return the result of the first
-// one, or false if there is none.
-#define INVOKE_REPLACEMENT(HookType, hook_list, args) do {              \
-    HookType hooks[kHookListMaxValues];                                 \
-    int num_hooks = hook_list.Traverse(hooks, kHookListMaxValues);      \
-    return (num_hooks > 0 && (*hooks[0])args);                          \
-  } while (0)
-
-
-void MallocHook::InvokeNewHookSlow(const void* p, size_t s) {
-  if (tcmalloc::IsEmergencyPtr(p)) {
-    return;
-  }
-  INVOKE_HOOKS(NewHook, new_hooks_, (p, s));
-}
-
-void MallocHook::InvokeDeleteHookSlow(const void* p) {
-  if (tcmalloc::IsEmergencyPtr(p)) {
-    return;
-  }
-  INVOKE_HOOKS(DeleteHook, delete_hooks_, (p));
-}
-
-void MallocHook::InvokePreMmapHookSlow(const void* start,
-                                       size_t size,
-                                       int protection,
-                                       int flags,
-                                       int fd,
-                                       off_t offset) {
-  INVOKE_HOOKS(PreMmapHook, premmap_hooks_, (start, size, protection, flags, fd,
-                                            offset));
-}
-
-void MallocHook::InvokeMmapHookSlow(const void* result,
-                                    const void* start,
-                                    size_t size,
-                                    int protection,
-                                    int flags,
-                                    int fd,
-                                    off_t offset) {
-  INVOKE_HOOKS(MmapHook, mmap_hooks_, (result, start, size, protection, flags,
-                                       fd, offset));
-}
-
-bool MallocHook::InvokeMmapReplacementSlow(const void* start,
-                                           size_t size,
-                                           int protection,
-                                           int flags,
-                                           int fd,
-                                           off_t offset,
-                                           void** result) {
-  INVOKE_REPLACEMENT(MmapReplacement, mmap_replacement_,
-                      (start, size, protection, flags, fd, offset, result));
-}
-
-void MallocHook::InvokeMunmapHookSlow(const void* p, size_t s) {
-  INVOKE_HOOKS(MunmapHook, munmap_hooks_, (p, s));
-}
-
-bool MallocHook::InvokeMunmapReplacementSlow(const void* p,
-                                             size_t s,
-                                             int* result) {
-  INVOKE_REPLACEMENT(MunmapReplacement, munmap_replacement_, (p, s, result));
-}
-
-void MallocHook::InvokeMremapHookSlow(const void* result,
-                                      const void* old_addr,
-                                      size_t old_size,
-                                      size_t new_size,
-                                      int flags,
-                                      const void* new_addr) {
-  INVOKE_HOOKS(MremapHook, mremap_hooks_, (result, old_addr, old_size, new_size,
-                                           flags, new_addr));
-}
-
-void MallocHook::InvokePreSbrkHookSlow(ptrdiff_t increment) {
-  INVOKE_HOOKS(PreSbrkHook, presbrk_hooks_, (increment));
-}
-
-void MallocHook::InvokeSbrkHookSlow(const void* result, ptrdiff_t increment) {
-  INVOKE_HOOKS(SbrkHook, sbrk_hooks_, (result, increment));
-}
-
-#undef INVOKE_HOOKS
-
-#ifndef NO_TCMALLOC_SAMPLES
-
-DEFINE_ATTRIBUTE_SECTION_VARS(google_malloc);
-DECLARE_ATTRIBUTE_SECTION_VARS(google_malloc);
-  // actual functions are in debugallocation.cc or tcmalloc.cc
-DEFINE_ATTRIBUTE_SECTION_VARS(malloc_hook);
-DECLARE_ATTRIBUTE_SECTION_VARS(malloc_hook);
-  // actual functions are in this file, malloc_hook.cc, and low_level_alloc.cc
-
-#define ADDR_IN_ATTRIBUTE_SECTION(addr, name) \
-  (reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_START(name)) <= \
-     reinterpret_cast<uintptr_t>(addr) && \
-   reinterpret_cast<uintptr_t>(addr) < \
-     reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_STOP(name)))
-
-// Return true iff 'caller' is a return address within a function
-// that calls one of our hooks via MallocHook:Invoke*.
-// A helper for GetCallerStackTrace.
-static inline bool InHookCaller(const void* caller) {
-  return ADDR_IN_ATTRIBUTE_SECTION(caller, google_malloc) ||
-         ADDR_IN_ATTRIBUTE_SECTION(caller, malloc_hook);
-  // We can use one section for everything except tcmalloc_or_debug
-  // due to its special linkage mode, which prevents merging of the sections.
-}
-
-#undef ADDR_IN_ATTRIBUTE_SECTION
-
-static bool checked_sections = false;
-
-static inline void CheckInHookCaller() {
-  if (!checked_sections) {
-    INIT_ATTRIBUTE_SECTION_VARS(google_malloc);
-    if (ATTRIBUTE_SECTION_START(google_malloc) ==
-        ATTRIBUTE_SECTION_STOP(google_malloc)) {
-      RAW_LOG(ERROR, "google_malloc section is missing, "
-                     "thus InHookCaller is broken!");
-    }
-    INIT_ATTRIBUTE_SECTION_VARS(malloc_hook);
-    if (ATTRIBUTE_SECTION_START(malloc_hook) ==
-        ATTRIBUTE_SECTION_STOP(malloc_hook)) {
-      RAW_LOG(ERROR, "malloc_hook section is missing, "
-                     "thus InHookCaller is broken!");
-    }
-    checked_sections = true;
-  }
-}
-
-#endif // !NO_TCMALLOC_SAMPLES
-
-// We can improve behavior/compactness of this function
-// if we pass a generic test function (with a generic arg)
-// into the implementations for GetStackTrace instead of the skip_count.
-extern "C" int MallocHook_GetCallerStackTrace(void** result, int max_depth,
-                                              int skip_count) {
-#if defined(NO_TCMALLOC_SAMPLES)
-  return 0;
-#elif !defined(HAVE_ATTRIBUTE_SECTION_START)
-  // Fall back to GetStackTrace and good old but fragile frame skip counts.
-  // Note: this path is inaccurate when a hook is not called directly by an
-  // allocation function but is daisy-chained through another hook,
-  // search for MallocHook::(Get|Set|Invoke)* to find such cases.
-  return GetStackTrace(result, max_depth, skip_count + int(DEBUG_MODE));
-  // due to -foptimize-sibling-calls in opt mode
-  // there's no need for extra frame skip here then
-#else
-  CheckInHookCaller();
-  // MallocHook caller determination via InHookCaller works, use it:
-  static const int kMaxSkip = 32 + 6 + 3;
-    // Constant tuned to do just one GetStackTrace call below in practice
-    // and not get many frames that we don't actually need:
-    // currently max passsed max_depth is 32,
-    // max passed/needed skip_count is 6
-    // and 3 is to account for some hook daisy chaining.
-  static const int kStackSize = kMaxSkip + 1;
-  void* stack[kStackSize];
-  int depth = GetStackTrace(stack, kStackSize, 1);  // skip this function frame
-  if (depth == 0)   // silenty propagate cases when GetStackTrace does not work
-    return 0;
-  for (int i = 0; i < depth; ++i) {  // stack[0] is our immediate caller
-    if (InHookCaller(stack[i])) {
-      // fast-path to slow-path calls may be implemented by compiler
-      // as non-tail calls. Causing two functions on stack trace to be
-      // inside google_malloc. In such case we're skipping to
-      // outermost such frame since this is where malloc stack frames
-      // really start.
-      while (i + 1 < depth && InHookCaller(stack[i+1])) {
-        i++;
-      }
-      RAW_VLOG(10, "Found hooked allocator at %d: %p <- %p",
-                   i, stack[i], stack[i+1]);
-      i += 1;  // skip hook caller frame
-      depth -= i;  // correct depth
-      if (depth > max_depth) depth = max_depth;
-      copy(stack + i, stack + i + depth, result);
-      if (depth < max_depth  &&  depth + i == kStackSize) {
-        // get frames for the missing depth
-        depth +=
-          GetStackTrace(result + depth, max_depth - depth, 1 + kStackSize);
-      }
-      return depth;
-    }
-  }
-  RAW_LOG(WARNING, "Hooked allocator frame not found, returning empty trace");
-    // If this happens try increasing kMaxSkip
-    // or else something must be wrong with InHookCaller,
-    // e.g. for every section used in InHookCaller
-    // all functions in that section must be inside the same library.
-  return 0;
-#endif
-}
-
-// On systems where we know how, we override mmap/munmap/mremap/sbrk
-// to provide support for calling the related hooks (in addition,
-// of course, to doing what these functions normally do).
-
-#if defined(__linux)
-# include "malloc_hook_mmap_linux.h"
-
-#elif defined(__FreeBSD__)
-# include "malloc_hook_mmap_freebsd.h"
-
-#else
-
-/*static*/void* MallocHook::UnhookedMMap(void *start, size_t length, int prot,
-                                         int flags, int fd, off_t offset) {
-  void* result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = mmap(start, length, prot, flags, fd, offset);
-  }
-  return result;
-}
-
-/*static*/int MallocHook::UnhookedMUnmap(void *start, size_t length) {
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    result = munmap(start, length);
-  }
-  return result;
-}
-
-#endif
diff --git a/third_party/tcmalloc/vendor/src/malloc_hook_mmap_freebsd.h b/third_party/tcmalloc/vendor/src/malloc_hook_mmap_freebsd.h
deleted file mode 100644
index 8575dcc7..0000000
--- a/third_party/tcmalloc/vendor/src/malloc_hook_mmap_freebsd.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Override mmap/munmap/mremap/sbrk to provide support for calling the
-// related hooks (in addition, of course, to doing what these
-// functions normally do).
-
-#ifndef __FreeBSD__
-# error Should only be including malloc_hook_mmap_freebsd.h on FreeBSD systems.
-#endif
-
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <dlfcn.h>
-
-// Make sure mmap doesn't get #define'd away by <sys/mman.h>
-#undef mmap
-
-// According to the FreeBSD documentation, use syscall if you do not
-// need 64-bit alignment otherwise use __syscall. Indeed, syscall
-// doesn't work correctly in most situations on 64-bit. It's return
-// type is 'int' so for things like SYS_mmap, it actually truncates
-// the returned address to 32-bits.
-#if defined(__amd64__) || defined(__x86_64__)
-# define MALLOC_HOOK_SYSCALL __syscall
-#else
-# define MALLOC_HOOK_SYSCALL syscall
-#endif
-
-
-extern "C" {
-  void* mmap(void *start, size_t length,int prot, int flags,
-             int fd, off_t offset) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  int munmap(void* start, size_t length) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  void* sbrk(intptr_t increment) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-}
-
-static inline void* do_mmap(void *start, size_t length,
-                            int prot, int flags,
-                            int fd, off_t offset) __THROW {
-  return (void *)MALLOC_HOOK_SYSCALL(SYS_mmap,
-                                     start, length, prot, flags, fd, offset);
-}
-
-static inline void* do_sbrk(intptr_t increment) {
-  static void *(*libc_sbrk)(intptr_t);
-  if (libc_sbrk == NULL)
-    libc_sbrk = (void *(*)(intptr_t))dlsym(RTLD_NEXT, "sbrk");
-
-  return libc_sbrk(increment);
-}
-
-
-extern "C" void* mmap(void *start, size_t length, int prot, int flags,
-                      int fd, off_t offset) __THROW {
-  MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset);
-  void *result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap(start, length, prot, flags, fd,
-                       static_cast<size_t>(offset)); // avoid sign extension
-  }
-  MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);
-  return result;
-}
-
-extern "C" int munmap(void* start, size_t length) __THROW {
-  MallocHook::InvokeMunmapHook(start, length);
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    result = MALLOC_HOOK_SYSCALL(SYS_munmap, start, length);
-  }
-
-  return result;
-}
-
-extern "C" void* sbrk(intptr_t increment) __THROW {
-  MallocHook::InvokePreSbrkHook(increment);
-  void *result = do_sbrk(increment);
-  MallocHook::InvokeSbrkHook(result, increment);
-  return result;
-}
-
-/*static*/void* MallocHook::UnhookedMMap(void *start, size_t length, int prot,
-                                         int flags, int fd, off_t offset) {
-  void* result;
-  if (!MallocHook::InvokeMmapReplacement(
-	  start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap(start, length, prot, flags, fd, offset);
-  }
-
-  return result;
-}
-
-/*static*/int MallocHook::UnhookedMUnmap(void *start, size_t length) {
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    result = MALLOC_HOOK_SYSCALL(SYS_munmap, start, length);
-  }
-  return result;
-}
-
-#undef MALLOC_HOOK_SYSCALL
diff --git a/third_party/tcmalloc/vendor/src/malloc_hook_mmap_linux.h b/third_party/tcmalloc/vendor/src/malloc_hook_mmap_linux.h
deleted file mode 100755
index 2f6116f..0000000
--- a/third_party/tcmalloc/vendor/src/malloc_hook_mmap_linux.h
+++ /dev/null
@@ -1,242 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-// We define mmap() and mmap64(), which somewhat reimplements libc's mmap
-// syscall stubs.  Unfortunately libc only exports the stubs via weak symbols
-// (which we're overriding with our mmap64() and mmap() wrappers) so we can't
-// just call through to them.
-
-#ifndef __linux
-# error Should only be including malloc_hook_mmap_linux.h on linux systems.
-#endif
-
-#include <unistd.h>
-#include <syscall.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include "base/linux_syscall_support.h"
-
-// The x86-32 case and the x86-64 case differ:
-// 32b has a mmap2() syscall, 64b does not.
-// 64b and 32b have different calling conventions for mmap().
-
-// I test for 64-bit first so I don't have to do things like
-// '#if (defined(__mips__) && !defined(__MIPS64__))' as a mips32 check.
-#if defined(__x86_64__) \
-    || defined(__PPC64__) \
-    || defined(__aarch64__) \
-    || (defined(_MIPS_SIM) && (_MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32)) \
-    || defined(__s390__)
-
-static inline void* do_mmap64(void *start, size_t length,
-                              int prot, int flags,
-                              int fd, __off64_t offset) __THROW {
-  return sys_mmap(start, length, prot, flags, fd, offset);
-}
-
-#define MALLOC_HOOK_HAVE_DO_MMAP64 1
-
-#elif defined(__i386__) || defined(__PPC__) || defined(__mips__) || \
-      defined(__arm__)
-
-static inline void* do_mmap64(void *start, size_t length,
-                              int prot, int flags,
-                              int fd, __off64_t offset) __THROW {
-  void *result;
-
-  // Try mmap2() unless it's not supported
-  static bool have_mmap2 = true;
-  if (have_mmap2) {
-    static int pagesize = 0;
-    if (!pagesize) pagesize = getpagesize();
-
-    // Check that the offset is page aligned
-    if (offset & (pagesize - 1)) {
-      result = MAP_FAILED;
-      errno = EINVAL;
-      goto out;
-    }
-
-    result = (void *)syscall(SYS_mmap2,
-                             start, length, prot, flags, fd,
-                             (off_t) (offset / pagesize));
-    if (result != MAP_FAILED || errno != ENOSYS)  goto out;
-
-    // We don't have mmap2() after all - don't bother trying it in future
-    have_mmap2 = false;
-  }
-
-  if (((off_t)offset) != offset) {
-    // If we're trying to map a 64-bit offset, fail now since we don't
-    // have 64-bit mmap() support.
-    result = MAP_FAILED;
-    errno = EINVAL;
-    goto out;
-  }
-
-#ifdef __NR_mmap
-  {
-    // Fall back to old 32-bit offset mmap() call
-    // Old syscall interface cannot handle six args, so pass in an array
-    int32 args[6] = { (int32) start, (int32) length, prot, flags, fd,
-                      (int32)(off_t) offset };
-    result = (void *)syscall(SYS_mmap, args);
-  }
-#else
-  // Some Linux ports like ARM EABI Linux has no mmap, just mmap2.
-  result = MAP_FAILED;
-#endif
-
- out:
-  return result;
-}
-
-#define MALLOC_HOOK_HAVE_DO_MMAP64 1
-
-#endif  // #if defined(__x86_64__)
-
-
-#ifdef MALLOC_HOOK_HAVE_DO_MMAP64
-
-// We use do_mmap64 abstraction to put MallocHook::InvokeMmapHook
-// calls right into mmap and mmap64, so that the stack frames in the caller's
-// stack are at the same offsets for all the calls of memory allocating
-// functions.
-
-// Put all callers of MallocHook::Invoke* in this module into
-// malloc_hook section,
-// so that MallocHook::GetCallerStackTrace can function accurately:
-
-// Make sure mmap doesn't get #define'd away by <sys/mman.h>
-# undef mmap
-
-extern "C" {
-  void* mmap64(void *start, size_t length, int prot, int flags,
-               int fd, __off64_t offset  ) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  void* mmap(void *start, size_t length,int prot, int flags,
-             int fd, off_t offset) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  int munmap(void* start, size_t length) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  void* mremap(void* old_addr, size_t old_size, size_t new_size,
-               int flags, ...) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-  void* sbrk(intptr_t increment) __THROW
-    ATTRIBUTE_SECTION(malloc_hook);
-}
-
-extern "C" void* mmap64(void *start, size_t length, int prot, int flags,
-                        int fd, __off64_t offset) __THROW {
-  MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset);
-  void *result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap64(start, length, prot, flags, fd, offset);
-  }
-  MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);
-  return result;
-}
-
-# if !defined(__USE_FILE_OFFSET64) || !defined(__REDIRECT_NTH)
-
-extern "C" void* mmap(void *start, size_t length, int prot, int flags,
-                      int fd, off_t offset) __THROW {
-  MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset);
-  void *result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap64(start, length, prot, flags, fd,
-                       static_cast<size_t>(offset)); // avoid sign extension
-  }
-  MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);
-  return result;
-}
-
-# endif  // !defined(__USE_FILE_OFFSET64) || !defined(__REDIRECT_NTH)
-
-extern "C" int munmap(void* start, size_t length) __THROW {
-  MallocHook::InvokeMunmapHook(start, length);
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    result = sys_munmap(start, length);
-  }
-  return result;
-}
-
-extern "C" void* mremap(void* old_addr, size_t old_size, size_t new_size,
-                        int flags, ...) __THROW {
-  va_list ap;
-  va_start(ap, flags);
-  void *new_address = va_arg(ap, void *);
-  va_end(ap);
-  void* result = sys_mremap(old_addr, old_size, new_size, flags, new_address);
-  MallocHook::InvokeMremapHook(result, old_addr, old_size, new_size, flags,
-                               new_address);
-  return result;
-}
-
-#ifndef __UCLIBC__
-// libc's version:
-extern "C" void* __sbrk(intptr_t increment);
-
-extern "C" void* sbrk(intptr_t increment) __THROW {
-  MallocHook::InvokePreSbrkHook(increment);
-  void *result = __sbrk(increment);
-  MallocHook::InvokeSbrkHook(result, increment);
-  return result;
-}
-
-#endif
-
-/*static*/void* MallocHook::UnhookedMMap(void *start, size_t length, int prot,
-                                         int flags, int fd, off_t offset) {
-  void* result;
-  if (!MallocHook::InvokeMmapReplacement(
-          start, length, prot, flags, fd, offset, &result)) {
-    result = do_mmap64(start, length, prot, flags, fd, offset);
-  }
-  return result;
-}
-
-/*static*/int MallocHook::UnhookedMUnmap(void *start, size_t length) {
-  int result;
-  if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) {
-    result = syscall(SYS_munmap, start, length);
-  }
-  return result;
-}
-
-#undef MALLOC_HOOK_HAVE_DO_MMAP64
-
-#endif  // #ifdef MALLOC_HOOK_HAVE_DO_MMAP64
diff --git a/third_party/tcmalloc/vendor/src/maybe_emergency_malloc.h b/third_party/tcmalloc/vendor/src/maybe_emergency_malloc.h
deleted file mode 100644
index 250ecf0..0000000
--- a/third_party/tcmalloc/vendor/src/maybe_emergency_malloc.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2014, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef MAYBE_EMERGENCY_MALLOC_H
-#define MAYBE_EMERGENCY_MALLOC_H
-
-#include "config.h"
-
-#ifdef ENABLE_EMERGENCY_MALLOC
-
-#include "emergency_malloc.h"
-
-#else
-
-namespace tcmalloc {
-  static inline void *EmergencyMalloc(size_t size) {return NULL;}
-  static inline void EmergencyFree(void *p) {}
-  static inline void *EmergencyCalloc(size_t n, size_t elem_size) {return NULL;}
-  static inline void *EmergencyRealloc(void *old_ptr, size_t new_size) {return NULL;}
-
-  static inline bool IsEmergencyPtr(const void *_ptr) {
-    return false;
-  }
-}
-
-#endif // ENABLE_EMERGENCY_MALLOC
-
-#endif
diff --git a/third_party/tcmalloc/vendor/src/maybe_threads.cc b/third_party/tcmalloc/vendor/src/maybe_threads.cc
deleted file mode 100644
index ef7e582..0000000
--- a/third_party/tcmalloc/vendor/src/maybe_threads.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Menage <opensource@google.com>
-//
-// Some wrappers for pthread functions so that we can be LD_PRELOADed
-// against non-pthreads apps.
-//
-// This module will behave very strangely if some pthreads functions
-// exist and others don't.
-
-#include "config.h"
-#include <assert.h>
-#include <string.h>    // for memcmp
-#include <stdio.h>     // for __isthreaded on FreeBSD
-// We don't actually need strings. But including this header seems to
-// stop the compiler trying to short-circuit our pthreads existence
-// tests and claiming that the address of a function is always
-// non-zero. I have no idea why ...
-#include <string>
-#include "maybe_threads.h"
-#include "base/basictypes.h"
-#include "base/logging.h"
-
-// __THROW is defined in glibc systems.  It means, counter-intuitively,
-// "This function will never throw an exception."  It's an optional
-// optimization tool, but we may need to use it to match glibc prototypes.
-#ifndef __THROW    // I guess we're not on a glibc system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-// These are the methods we're going to conditionally include.
-extern "C" {
-  int pthread_key_create (pthread_key_t*, void (*)(void*))
-      __THROW ATTRIBUTE_WEAK;
-  int pthread_key_delete (pthread_key_t)
-      __THROW ATTRIBUTE_WEAK;
-  void *pthread_getspecific(pthread_key_t)
-      __THROW ATTRIBUTE_WEAK;
-  int pthread_setspecific(pthread_key_t, const void*)
-      __THROW ATTRIBUTE_WEAK;
-  int pthread_once(pthread_once_t *, void (*)(void))
-      ATTRIBUTE_WEAK;
-#ifdef HAVE_FORK
-  int pthread_atfork(void (*__prepare) (void),
-                     void (*__parent) (void),
-                     void (*__child) (void))
-    __THROW ATTRIBUTE_WEAK;
-#endif
-}
-
-#define MAX_PERTHREAD_VALS 16
-static void *perftools_pthread_specific_vals[MAX_PERTHREAD_VALS];
-static int next_key;
-
-// NOTE: it's similar to bitcast defined in basic_types.h with
-// exception of ignoring sizes mismatch
-template <typename T1, typename T2>
-static T2 memcpy_cast(const T1 &input) {
-  T2 output;
-  size_t s = sizeof(input);
-  if (sizeof(output) < s) {
-    s = sizeof(output);
-  }
-  memcpy(&output, &input, s);
-  return output;
-}
-
-int perftools_pthread_key_create(pthread_key_t *key,
-                                 void (*destr_function) (void *)) {
-  if (pthread_key_create) {
-    return pthread_key_create(key, destr_function);
-  } else {
-    assert(next_key < MAX_PERTHREAD_VALS);
-    *key = memcpy_cast<int, pthread_key_t>(next_key++);
-    return 0;
-  }
-}
-
-int perftools_pthread_key_delete(pthread_key_t key) {
-  if (pthread_key_delete) {
-    return pthread_key_delete(key);
-  } else {
-    return 0;
-  }
-}
-
-void *perftools_pthread_getspecific(pthread_key_t key) {
-  if (pthread_getspecific) {
-    return pthread_getspecific(key);
-  } else {
-    return perftools_pthread_specific_vals[memcpy_cast<pthread_key_t, int>(key)];
-  }
-}
-
-int perftools_pthread_setspecific(pthread_key_t key, void *val) {
-  if (pthread_setspecific) {
-    return pthread_setspecific(key, val);
-  } else {
-    perftools_pthread_specific_vals[memcpy_cast<pthread_key_t, int>(key)] = val;
-    return 0;
-  }
-}
-
-
-static pthread_once_t pthread_once_init = PTHREAD_ONCE_INIT;
-int perftools_pthread_once(pthread_once_t *ctl,
-                           void  (*init_routine) (void)) {
-#ifdef __FreeBSD__
-  // On __FreeBSD__, calling pthread_once on a system that is not
-  // linked with -pthread is silently a noop. :-( Luckily, we have a
-  // workaround: FreeBSD exposes __isthreaded in <stdio.h>, which is
-  // set to 1 when the first thread is spawned.  So on those systems,
-  // we can use our own separate pthreads-once mechanism, which is
-  // used until __isthreaded is 1 (which will never be true if the app
-  // is not linked with -pthread).
-  static bool pthread_once_ran_before_threads = false;
-  if (pthread_once_ran_before_threads) {
-    return 0;
-  }
-  if (!__isthreaded) {
-    init_routine();
-    pthread_once_ran_before_threads = true;
-    return 0;
-  }
-#endif
-  if (pthread_once) {
-    return pthread_once(ctl, init_routine);
-  } else {
-    if (memcmp(ctl, &pthread_once_init, sizeof(*ctl)) == 0) {
-      init_routine();
-      ++*(char*)(ctl);        // make it so it's no longer equal to init
-    }
-    return 0;
-  }
-}
-
-#ifdef HAVE_FORK
-
-void perftools_pthread_atfork(void (*before)(),
-                              void (*parent_after)(),
-                              void (*child_after)()) {
-  if (pthread_atfork) {
-    int rv = pthread_atfork(before, parent_after, child_after);
-    CHECK(rv == 0);
-  }
-}
-
-#endif
diff --git a/third_party/tcmalloc/vendor/src/maybe_threads.h b/third_party/tcmalloc/vendor/src/maybe_threads.h
deleted file mode 100644
index c6cfdf7..0000000
--- a/third_party/tcmalloc/vendor/src/maybe_threads.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Paul Menage <opensource@google.com>
-
-//-------------------------------------------------------------------
-// Some wrappers for pthread functions so that we can be LD_PRELOADed
-// against non-pthreads apps.
-//-------------------------------------------------------------------
-
-#ifndef GOOGLE_MAYBE_THREADS_H_
-#define GOOGLE_MAYBE_THREADS_H_
-
-#ifdef HAVE_PTHREAD
-#include <pthread.h>
-#endif
-
-int perftools_pthread_key_create(pthread_key_t *key,
-                                 void (*destr_function) (void *));
-int perftools_pthread_key_delete(pthread_key_t key);
-void *perftools_pthread_getspecific(pthread_key_t key);
-int perftools_pthread_setspecific(pthread_key_t key, void *val);
-int perftools_pthread_once(pthread_once_t *ctl,
-                           void  (*init_routine) (void));
-
-// Our wrapper for pthread_atfork. Does _nothing_ when there are no
-// threads. See static_vars.cc:SetupAtForkLocksHandler for only user
-// of this.
-void perftools_pthread_atfork(void (*before)(),
-                              void (*parent_after)(),
-                              void (*child_after)());
-
-#endif  /* GOOGLE_MAYBE_THREADS_H_ */
diff --git a/third_party/tcmalloc/vendor/src/memfs_malloc.cc b/third_party/tcmalloc/vendor/src/memfs_malloc.cc
deleted file mode 100644
index fd26daff..0000000
--- a/third_party/tcmalloc/vendor/src/memfs_malloc.cc
+++ /dev/null
@@ -1,272 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Arun Sharma
-//
-// A tcmalloc system allocator that uses a memory based filesystem such as
-// tmpfs or hugetlbfs
-//
-// Since these only exist on linux, we only register this allocator there.
-
-#ifdef __linux
-
-#include <config.h>
-#include <errno.h>                      // for errno, EINVAL
-#include <inttypes.h>                   // for PRId64
-#include <limits.h>                     // for PATH_MAX
-#include <stddef.h>                     // for size_t, NULL
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for int64_t, uintptr_t
-#endif
-#include <stdio.h>                      // for snprintf
-#include <stdlib.h>                     // for mkstemp
-#include <string.h>                     // for strerror
-#include <sys/mman.h>                   // for mmap, MAP_FAILED, etc
-#include <sys/statfs.h>                 // for fstatfs, statfs
-#include <unistd.h>                     // for ftruncate, off_t, unlink
-#include <new>                          // for operator new
-#include <string>
-
-#include <gperftools/malloc_extension.h>
-#include "base/basictypes.h"
-#include "base/googleinit.h"
-#include "base/sysinfo.h"
-#include "internal_logging.h"
-
-// TODO(sanjay): Move the code below into the tcmalloc namespace
-using tcmalloc::kLog;
-using tcmalloc::kCrash;
-using tcmalloc::Log;
-using std::string;
-
-DEFINE_string(memfs_malloc_path, EnvToString("TCMALLOC_MEMFS_MALLOC_PATH", ""),
-              "Path where hugetlbfs or tmpfs is mounted. The caller is "
-              "responsible for ensuring that the path is unique and does "
-              "not conflict with another process");
-DEFINE_int64(memfs_malloc_limit_mb,
-             EnvToInt("TCMALLOC_MEMFS_LIMIT_MB", 0),
-             "Limit total allocation size to the "
-             "specified number of MiB.  0 == no limit.");
-DEFINE_bool(memfs_malloc_abort_on_fail,
-            EnvToBool("TCMALLOC_MEMFS_ABORT_ON_FAIL", false),
-            "abort() whenever memfs_malloc fails to satisfy an allocation "
-            "for any reason.");
-DEFINE_bool(memfs_malloc_ignore_mmap_fail,
-            EnvToBool("TCMALLOC_MEMFS_IGNORE_MMAP_FAIL", false),
-            "Ignore failures from mmap");
-DEFINE_bool(memfs_malloc_map_private,
-            EnvToBool("TCMALLOC_MEMFS_MAP_PRIVATE", false),
-	    "Use MAP_PRIVATE with mmap");
-
-// Hugetlbfs based allocator for tcmalloc
-class HugetlbSysAllocator: public SysAllocator {
-public:
-  explicit HugetlbSysAllocator(SysAllocator* fallback)
-    : failed_(true),  // To disable allocator until Initialize() is called.
-      big_page_size_(0),
-      hugetlb_fd_(-1),
-      hugetlb_base_(0),
-      fallback_(fallback) {
-  }
-
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-  bool Initialize();
-
-  bool failed_;          // Whether failed to allocate memory.
-
-private:
-  void* AllocInternal(size_t size, size_t *actual_size, size_t alignment);
-
-  int64 big_page_size_;
-  int hugetlb_fd_;       // file descriptor for hugetlb
-  off_t hugetlb_base_;
-
-  SysAllocator* fallback_;  // Default system allocator to fall back to.
-};
-static union {
-  char buf[sizeof(HugetlbSysAllocator)];
-  void *ptr;
-} hugetlb_space;
-
-// No locking needed here since we assume that tcmalloc calls
-// us with an internal lock held (see tcmalloc/system-alloc.cc).
-void* HugetlbSysAllocator::Alloc(size_t size, size_t *actual_size,
-                                 size_t alignment) {
-  if (failed_) {
-    return fallback_->Alloc(size, actual_size, alignment);
-  }
-
-  // We don't respond to allocation requests smaller than big_page_size_ unless
-  // the caller is ok to take more than they asked for. Used by MetaDataAlloc.
-  if (actual_size == NULL && size < big_page_size_) {
-    return fallback_->Alloc(size, actual_size, alignment);
-  }
-
-  // Enforce huge page alignment.  Be careful to deal with overflow.
-  size_t new_alignment = alignment;
-  if (new_alignment < big_page_size_) new_alignment = big_page_size_;
-  size_t aligned_size = ((size + new_alignment - 1) /
-                         new_alignment) * new_alignment;
-  if (aligned_size < size) {
-    return fallback_->Alloc(size, actual_size, alignment);
-  }
-
-  void* result = AllocInternal(aligned_size, actual_size, new_alignment);
-  if (result != NULL) {
-    return result;
-  }
-  Log(kLog, __FILE__, __LINE__,
-      "HugetlbSysAllocator: (failed, allocated)", failed_, hugetlb_base_);
-  if (FLAGS_memfs_malloc_abort_on_fail) {
-    Log(kCrash, __FILE__, __LINE__,
-        "memfs_malloc_abort_on_fail is set");
-  }
-  return fallback_->Alloc(size, actual_size, alignment);
-}
-
-void* HugetlbSysAllocator::AllocInternal(size_t size, size_t* actual_size,
-                                         size_t alignment) {
-  // Ask for extra memory if alignment > pagesize
-  size_t extra = 0;
-  if (alignment > big_page_size_) {
-    extra = alignment - big_page_size_;
-  }
-
-  // Test if this allocation would put us over the limit.
-  off_t limit = FLAGS_memfs_malloc_limit_mb*1024*1024;
-  if (limit > 0 && hugetlb_base_ + size + extra > limit) {
-    // Disable the allocator when there's less than one page left.
-    if (limit - hugetlb_base_ < big_page_size_) {
-      Log(kLog, __FILE__, __LINE__, "reached memfs_malloc_limit_mb");
-      failed_ = true;
-    }
-    else {
-      Log(kLog, __FILE__, __LINE__,
-          "alloc too large (size, bytes left)", size, limit-hugetlb_base_);
-    }
-    return NULL;
-  }
-
-  // This is not needed for hugetlbfs, but needed for tmpfs.  Annoyingly
-  // hugetlbfs returns EINVAL for ftruncate.
-  int ret = ftruncate(hugetlb_fd_, hugetlb_base_ + size + extra);
-  if (ret != 0 && errno != EINVAL) {
-    Log(kLog, __FILE__, __LINE__,
-        "ftruncate failed", strerror(errno));
-    failed_ = true;
-    return NULL;
-  }
-
-  // Note: size + extra does not overflow since:
-  //            size + alignment < (1<<NBITS).
-  // and        extra <= alignment
-  // therefore  size + extra < (1<<NBITS)
-  void *result;
-  result = mmap(0, size + extra, PROT_WRITE|PROT_READ,
-                FLAGS_memfs_malloc_map_private ? MAP_PRIVATE : MAP_SHARED,
-                hugetlb_fd_, hugetlb_base_);
-  if (result == reinterpret_cast<void*>(MAP_FAILED)) {
-    if (!FLAGS_memfs_malloc_ignore_mmap_fail) {
-      Log(kLog, __FILE__, __LINE__,
-          "mmap failed (size, error)", size + extra, strerror(errno));
-      failed_ = true;
-    }
-    return NULL;
-  }
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-
-  // Adjust the return memory so it is aligned
-  size_t adjust = 0;
-  if ((ptr & (alignment - 1)) != 0) {
-    adjust = alignment - (ptr & (alignment - 1));
-  }
-  ptr += adjust;
-  hugetlb_base_ += (size + extra);
-
-  if (actual_size) {
-    *actual_size = size + extra - adjust;
-  }
-
-  return reinterpret_cast<void*>(ptr);
-}
-
-bool HugetlbSysAllocator::Initialize() {
-  char path[PATH_MAX];
-  const int pathlen = FLAGS_memfs_malloc_path.size();
-  if (pathlen + 8 > sizeof(path)) {
-    Log(kCrash, __FILE__, __LINE__, "XX fatal: memfs_malloc_path too long");
-    return false;
-  }
-  memcpy(path, FLAGS_memfs_malloc_path.data(), pathlen);
-  memcpy(path + pathlen, ".XXXXXX", 8);  // Also copies terminating \0
-
-  int hugetlb_fd = mkstemp(path);
-  if (hugetlb_fd == -1) {
-    Log(kLog, __FILE__, __LINE__,
-        "warning: unable to create memfs_malloc_path",
-        path, strerror(errno));
-    return false;
-  }
-
-  // Cleanup memory on process exit
-  if (unlink(path) == -1) {
-    Log(kCrash, __FILE__, __LINE__,
-        "fatal: error unlinking memfs_malloc_path", path, strerror(errno));
-    return false;
-  }
-
-  // Use fstatfs to figure out the default page size for memfs
-  struct statfs sfs;
-  if (fstatfs(hugetlb_fd, &sfs) == -1) {
-    Log(kCrash, __FILE__, __LINE__,
-        "fatal: error fstatfs of memfs_malloc_path", strerror(errno));
-    return false;
-  }
-  int64 page_size = sfs.f_bsize;
-
-  hugetlb_fd_ = hugetlb_fd;
-  big_page_size_ = page_size;
-  failed_ = false;
-  return true;
-}
-
-REGISTER_MODULE_INITIALIZER(memfs_malloc, {
-  if (FLAGS_memfs_malloc_path.length()) {
-    SysAllocator* alloc = MallocExtension::instance()->GetSystemAllocator();
-    HugetlbSysAllocator* hp =
-      new (hugetlb_space.buf) HugetlbSysAllocator(alloc);
-    if (hp->Initialize()) {
-      MallocExtension::instance()->SetSystemAllocator(hp);
-    }
-  }
-});
-
-#endif   /* ifdef __linux */
diff --git a/third_party/tcmalloc/vendor/src/memory_region_map.cc b/third_party/tcmalloc/vendor/src/memory_region_map.cc
deleted file mode 100755
index 841d6f3c..0000000
--- a/third_party/tcmalloc/vendor/src/memory_region_map.cc
+++ /dev/null
@@ -1,831 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Maxim Lifantsev
- */
-
-//
-// Background and key design points of MemoryRegionMap.
-//
-// MemoryRegionMap is a low-level module with quite atypical requirements that
-// result in some degree of non-triviality of the implementation and design.
-//
-// MemoryRegionMap collects info about *all* memory regions created with
-// mmap, munmap, mremap, sbrk.
-// They key word above is 'all': all that are happening in a process
-// during its lifetime frequently starting even before global object
-// constructor execution.
-//
-// This is needed by the primary client of MemoryRegionMap:
-// HeapLeakChecker uses the regions and the associated stack traces
-// to figure out what part of the memory is the heap:
-// if MemoryRegionMap were to miss some (early) regions, leak checking would
-// stop working correctly.
-//
-// To accomplish the goal of functioning before/during global object
-// constructor execution MemoryRegionMap is done as a singleton service
-// that relies on own on-demand initialized static constructor-less data,
-// and only relies on other low-level modules that can also function properly
-// even before global object constructors run.
-//
-// Accomplishing the goal of collecting data about all mmap, munmap, mremap,
-// sbrk occurrences is a more involved: conceptually to do this one needs to
-// record some bits of data in particular about any mmap or sbrk call,
-// but to do that one needs to allocate memory for that data at some point,
-// but all memory allocations in the end themselves come from an mmap
-// or sbrk call (that's how the address space of the process grows).
-//
-// Also note that we need to do all the above recording from
-// within an mmap/sbrk hook which is sometimes/frequently is made by a memory
-// allocator, including the allocator MemoryRegionMap itself must rely on.
-// In the case of heap-checker usage this includes even the very first
-// mmap/sbrk call happening in the program: heap-checker gets activated due to
-// a link-time installed mmap/sbrk hook and it initializes MemoryRegionMap
-// and asks it to record info about this very first call right from that
-// very first hook invocation.
-//
-// MemoryRegionMap is doing its memory allocations via LowLevelAlloc:
-// unlike more complex standard memory allocator, LowLevelAlloc cooperates with
-// MemoryRegionMap by not holding any of its own locks while it calls mmap
-// to get memory, thus we are able to call LowLevelAlloc from
-// our mmap/sbrk hooks without causing a deadlock in it.
-// For the same reason of deadlock prevention the locking in MemoryRegionMap
-// itself is write-recursive which is an exception to Google's mutex usage.
-//
-// We still need to break the infinite cycle of mmap calling our hook,
-// which asks LowLevelAlloc for memory to record this mmap,
-// which (sometimes) causes mmap, which calls our hook, and so on.
-// We do this as follows: on a recursive call of MemoryRegionMap's
-// mmap/sbrk/mremap hook we record the data about the allocation in a
-// static fixed-sized stack (saved_regions and saved_buckets), when the
-// recursion unwinds but before returning from the outer hook call we unwind
-// this stack and move the data from saved_regions and saved_buckets to its
-// permanent place in the RegionSet and "bucket_table" respectively,
-// which can cause more allocations and mmap-s and recursion and unwinding,
-// but the whole process ends eventually due to the fact that for the small
-// allocations we are doing LowLevelAlloc reuses one mmap call and parcels out
-// the memory it created to satisfy several of our allocation requests.
-//
-
-// ========================================================================= //
-
-#include <config.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#elif !defined(MAP_FAILED)
-#define MAP_FAILED -1  // the only thing we need from mman.h
-#endif
-#ifdef HAVE_PTHREAD
-#include <pthread.h>   // for pthread_t, pthread_self()
-#endif
-#include <stddef.h>
-
-#include <algorithm>
-#include <set>
-
-#include "memory_region_map.h"
-
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include "base/low_level_alloc.h"
-#include "malloc_hook-inl.h"
-
-#include <gperftools/stacktrace.h>
-#include <gperftools/malloc_hook.h>
-
-// MREMAP_FIXED is a linux extension.  How it's used in this file,
-// setting it to 0 is equivalent to saying, "This feature isn't
-// supported", which is right.
-#ifndef MREMAP_FIXED
-# define MREMAP_FIXED  0
-#endif
-
-using std::max;
-
-// ========================================================================= //
-
-int MemoryRegionMap::client_count_ = 0;
-int MemoryRegionMap::max_stack_depth_ = 0;
-MemoryRegionMap::RegionSet* MemoryRegionMap::regions_ = NULL;
-LowLevelAlloc::Arena* MemoryRegionMap::arena_ = NULL;
-SpinLock MemoryRegionMap::lock_(SpinLock::LINKER_INITIALIZED);
-SpinLock MemoryRegionMap::owner_lock_(  // ACQUIRED_AFTER(lock_)
-    SpinLock::LINKER_INITIALIZED);
-int MemoryRegionMap::recursion_count_ = 0;  // GUARDED_BY(owner_lock_)
-pthread_t MemoryRegionMap::lock_owner_tid_;  // GUARDED_BY(owner_lock_)
-int64 MemoryRegionMap::map_size_ = 0;
-int64 MemoryRegionMap::unmap_size_ = 0;
-HeapProfileBucket** MemoryRegionMap::bucket_table_ = NULL;  // GUARDED_BY(lock_)
-int MemoryRegionMap::num_buckets_ = 0;  // GUARDED_BY(lock_)
-int MemoryRegionMap::saved_buckets_count_ = 0;  // GUARDED_BY(lock_)
-HeapProfileBucket MemoryRegionMap::saved_buckets_[20];  // GUARDED_BY(lock_)
-
-// GUARDED_BY(lock_)
-const void* MemoryRegionMap::saved_buckets_keys_[20][kMaxStackDepth];
-
-// ========================================================================= //
-
-// Simple hook into execution of global object constructors,
-// so that we do not call pthread_self() when it does not yet work.
-static bool libpthread_initialized = false;
-REGISTER_MODULE_INITIALIZER(libpthread_initialized_setter,
-                            libpthread_initialized = true);
-
-static inline bool current_thread_is(pthread_t should_be) {
-  // Before main() runs, there's only one thread, so we're always that thread
-  if (!libpthread_initialized) return true;
-  // this starts working only sometime well into global constructor execution:
-  return pthread_equal(pthread_self(), should_be);
-}
-
-// ========================================================================= //
-
-// Constructor-less place-holder to store a RegionSet in.
-union MemoryRegionMap::RegionSetRep {
-  char rep[sizeof(RegionSet)];
-  void* align_it;  // do not need a better alignment for 'rep' than this
-  RegionSet* region_set() { return reinterpret_cast<RegionSet*>(rep); }
-};
-
-// The bytes where MemoryRegionMap::regions_ will point to.
-// We use RegionSetRep with noop c-tor so that global construction
-// does not interfere.
-static MemoryRegionMap::RegionSetRep regions_rep;
-
-// ========================================================================= //
-
-// Has InsertRegionLocked been called recursively
-// (or rather should we *not* use regions_ to record a hooked mmap).
-static bool recursive_insert = false;
-
-void MemoryRegionMap::Init(int max_stack_depth, bool use_buckets) {
-  RAW_VLOG(10, "MemoryRegionMap Init");
-  RAW_CHECK(max_stack_depth >= 0, "");
-  // Make sure we don't overflow the memory in region stacks:
-  RAW_CHECK(max_stack_depth <= kMaxStackDepth,
-            "need to increase kMaxStackDepth?");
-  Lock();
-  client_count_ += 1;
-  max_stack_depth_ = max(max_stack_depth_, max_stack_depth);
-  if (client_count_ > 1) {
-    // not first client: already did initialization-proper
-    Unlock();
-    RAW_VLOG(10, "MemoryRegionMap Init increment done");
-    return;
-  }
-  // Set our hooks and make sure they were installed:
-  RAW_CHECK(MallocHook::AddMmapHook(&MmapHook), "");
-  RAW_CHECK(MallocHook::AddMremapHook(&MremapHook), "");
-  RAW_CHECK(MallocHook::AddSbrkHook(&SbrkHook), "");
-  RAW_CHECK(MallocHook::AddMunmapHook(&MunmapHook), "");
-  // We need to set recursive_insert since the NewArena call itself
-  // will already do some allocations with mmap which our hooks will catch
-  // recursive_insert allows us to buffer info about these mmap calls.
-  // Note that Init() can be (and is) sometimes called
-  // already from within an mmap/sbrk hook.
-  recursive_insert = true;
-  arena_ = LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
-  recursive_insert = false;
-  HandleSavedRegionsLocked(&InsertRegionLocked);  // flush the buffered ones
-    // Can't instead use HandleSavedRegionsLocked(&DoInsertRegionLocked) before
-    // recursive_insert = false; as InsertRegionLocked will also construct
-    // regions_ on demand for us.
-  if (use_buckets) {
-    const int table_bytes = kHashTableSize * sizeof(*bucket_table_);
-    recursive_insert = true;
-    bucket_table_ = static_cast<HeapProfileBucket**>(
-        MyAllocator::Allocate(table_bytes));
-    recursive_insert = false;
-    memset(bucket_table_, 0, table_bytes);
-    num_buckets_ = 0;
-  }
-  Unlock();
-  RAW_VLOG(10, "MemoryRegionMap Init done");
-}
-
-bool MemoryRegionMap::Shutdown() {
-  RAW_VLOG(10, "MemoryRegionMap Shutdown");
-  Lock();
-  RAW_CHECK(client_count_ > 0, "");
-  client_count_ -= 1;
-  if (client_count_ != 0) {  // not last client; need not really shutdown
-    Unlock();
-    RAW_VLOG(10, "MemoryRegionMap Shutdown decrement done");
-    return true;
-  }
-  if (bucket_table_ != NULL) {
-    for (int i = 0; i < kHashTableSize; i++) {
-      for (HeapProfileBucket* curr = bucket_table_[i]; curr != 0; /**/) {
-        HeapProfileBucket* bucket = curr;
-        curr = curr->next;
-        MyAllocator::Free(bucket->stack, 0);
-        MyAllocator::Free(bucket, 0);
-      }
-    }
-    MyAllocator::Free(bucket_table_, 0);
-    num_buckets_ = 0;
-    bucket_table_ = NULL;
-  }
-  RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), "");
-  RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), "");
-  RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), "");
-  RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
-  if (regions_) regions_->~RegionSet();
-  regions_ = NULL;
-  bool deleted_arena = LowLevelAlloc::DeleteArena(arena_);
-  if (deleted_arena) {
-    arena_ = 0;
-  } else {
-    RAW_LOG(WARNING, "Can't delete LowLevelAlloc arena: it's being used");
-  }
-  Unlock();
-  RAW_VLOG(10, "MemoryRegionMap Shutdown done");
-  return deleted_arena;
-}
-
-bool MemoryRegionMap::IsRecordingLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  return client_count_ > 0;
-}
-
-// Invariants (once libpthread_initialized is true):
-//   * While lock_ is not held, recursion_count_ is 0 (and
-//     lock_owner_tid_ is the previous owner, but we don't rely on
-//     that).
-//   * recursion_count_ and lock_owner_tid_ are only written while
-//     both lock_ and owner_lock_ are held. They may be read under
-//     just owner_lock_.
-//   * At entry and exit of Lock() and Unlock(), the current thread
-//     owns lock_ iff pthread_equal(lock_owner_tid_, pthread_self())
-//     && recursion_count_ > 0.
-void MemoryRegionMap::Lock() {
-  {
-    SpinLockHolder l(&owner_lock_);
-    if (recursion_count_ > 0 && current_thread_is(lock_owner_tid_)) {
-      RAW_CHECK(lock_.IsHeld(), "Invariants violated");
-      recursion_count_++;
-      RAW_CHECK(recursion_count_ <= 5,
-                "recursive lock nesting unexpectedly deep");
-      return;
-    }
-  }
-  lock_.Lock();
-  {
-    SpinLockHolder l(&owner_lock_);
-    RAW_CHECK(recursion_count_ == 0,
-              "Last Unlock didn't reset recursion_count_");
-    if (libpthread_initialized)
-      lock_owner_tid_ = pthread_self();
-    recursion_count_ = 1;
-  }
-}
-
-void MemoryRegionMap::Unlock() {
-  SpinLockHolder l(&owner_lock_);
-  RAW_CHECK(recursion_count_ >  0, "unlock when not held");
-  RAW_CHECK(lock_.IsHeld(),
-            "unlock when not held, and recursion_count_ is wrong");
-  RAW_CHECK(current_thread_is(lock_owner_tid_), "unlock by non-holder");
-  recursion_count_--;
-  if (recursion_count_ == 0) {
-    lock_.Unlock();
-  }
-}
-
-bool MemoryRegionMap::LockIsHeld() {
-  SpinLockHolder l(&owner_lock_);
-  return lock_.IsHeld()  &&  current_thread_is(lock_owner_tid_);
-}
-
-const MemoryRegionMap::Region*
-MemoryRegionMap::DoFindRegionLocked(uintptr_t addr) {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  if (regions_ != NULL) {
-    Region sample;
-    sample.SetRegionSetKey(addr);
-    RegionSet::iterator region = regions_->lower_bound(sample);
-    if (region != regions_->end()) {
-      RAW_CHECK(addr <= region->end_addr, "");
-      if (region->start_addr <= addr  &&  addr < region->end_addr) {
-        return &(*region);
-      }
-    }
-  }
-  return NULL;
-}
-
-bool MemoryRegionMap::FindRegion(uintptr_t addr, Region* result) {
-  Lock();
-  const Region* region = DoFindRegionLocked(addr);
-  if (region != NULL) *result = *region;  // create it as an independent copy
-  Unlock();
-  return region != NULL;
-}
-
-bool MemoryRegionMap::FindAndMarkStackRegion(uintptr_t stack_top,
-                                             Region* result) {
-  Lock();
-  const Region* region = DoFindRegionLocked(stack_top);
-  if (region != NULL) {
-    RAW_VLOG(10, "Stack at %p is inside region %p..%p",
-                reinterpret_cast<void*>(stack_top),
-                reinterpret_cast<void*>(region->start_addr),
-                reinterpret_cast<void*>(region->end_addr));
-    const_cast<Region*>(region)->set_is_stack();  // now we know
-      // cast is safe (set_is_stack does not change the set ordering key)
-    *result = *region;  // create *result as an independent copy
-  }
-  Unlock();
-  return region != NULL;
-}
-
-HeapProfileBucket* MemoryRegionMap::GetBucket(int depth,
-                                              const void* const key[]) {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  // Make hash-value
-  uintptr_t hash = 0;
-  for (int i = 0; i < depth; i++) {
-    hash += reinterpret_cast<uintptr_t>(key[i]);
-    hash += hash << 10;
-    hash ^= hash >> 6;
-  }
-  hash += hash << 3;
-  hash ^= hash >> 11;
-
-  // Lookup stack trace in table
-  unsigned int hash_index = (static_cast<unsigned int>(hash)) % kHashTableSize;
-  for (HeapProfileBucket* bucket = bucket_table_[hash_index];
-       bucket != 0;
-       bucket = bucket->next) {
-    if ((bucket->hash == hash) && (bucket->depth == depth) &&
-        std::equal(key, key + depth, bucket->stack)) {
-      return bucket;
-    }
-  }
-
-  // Create new bucket
-  const size_t key_size = sizeof(key[0]) * depth;
-  HeapProfileBucket* bucket;
-  if (recursive_insert) {  // recursion: save in saved_buckets_
-    const void** key_copy = saved_buckets_keys_[saved_buckets_count_];
-    std::copy(key, key + depth, key_copy);
-    bucket = &saved_buckets_[saved_buckets_count_];
-    memset(bucket, 0, sizeof(*bucket));
-    ++saved_buckets_count_;
-    bucket->stack = key_copy;
-    bucket->next  = NULL;
-  } else {
-    recursive_insert = true;
-    const void** key_copy = static_cast<const void**>(
-        MyAllocator::Allocate(key_size));
-    recursive_insert = false;
-    std::copy(key, key + depth, key_copy);
-    recursive_insert = true;
-    bucket = static_cast<HeapProfileBucket*>(
-        MyAllocator::Allocate(sizeof(HeapProfileBucket)));
-    recursive_insert = false;
-    memset(bucket, 0, sizeof(*bucket));
-    bucket->stack = key_copy;
-    bucket->next  = bucket_table_[hash_index];
-  }
-  bucket->hash = hash;
-  bucket->depth = depth;
-  bucket_table_[hash_index] = bucket;
-  ++num_buckets_;
-  return bucket;
-}
-
-MemoryRegionMap::RegionIterator MemoryRegionMap::BeginRegionLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  RAW_CHECK(regions_ != NULL, "");
-  return regions_->begin();
-}
-
-MemoryRegionMap::RegionIterator MemoryRegionMap::EndRegionLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  RAW_CHECK(regions_ != NULL, "");
-  return regions_->end();
-}
-
-inline void MemoryRegionMap::DoInsertRegionLocked(const Region& region) {
-  RAW_VLOG(12, "Inserting region %p..%p from %p",
-              reinterpret_cast<void*>(region.start_addr),
-              reinterpret_cast<void*>(region.end_addr),
-              reinterpret_cast<void*>(region.caller()));
-  RegionSet::const_iterator i = regions_->lower_bound(region);
-  if (i != regions_->end() && i->start_addr <= region.start_addr) {
-    RAW_DCHECK(region.end_addr <= i->end_addr, "");  // lower_bound ensures this
-    return;  // 'region' is a subset of an already recorded region; do nothing
-    // We can be stricter and allow this only when *i has been created via
-    // an mmap with MAP_NORESERVE flag set.
-  }
-  if (DEBUG_MODE) {
-    RAW_CHECK(i == regions_->end()  ||  !region.Overlaps(*i),
-              "Wow, overlapping memory regions");
-    Region sample;
-    sample.SetRegionSetKey(region.start_addr);
-    i = regions_->lower_bound(sample);
-    RAW_CHECK(i == regions_->end()  ||  !region.Overlaps(*i),
-              "Wow, overlapping memory regions");
-  }
-  region.AssertIsConsistent();  // just making sure
-  // This inserts and allocates permanent storage for region
-  // and its call stack data: it's safe to do it now:
-  regions_->insert(region);
-  RAW_VLOG(12, "Inserted region %p..%p :",
-              reinterpret_cast<void*>(region.start_addr),
-              reinterpret_cast<void*>(region.end_addr));
-  if (VLOG_IS_ON(12))  LogAllLocked();
-}
-
-// These variables are local to MemoryRegionMap::InsertRegionLocked()
-// and MemoryRegionMap::HandleSavedRegionsLocked()
-// and are file-level to ensure that they are initialized at load time.
-
-// Number of unprocessed region inserts.
-static int saved_regions_count = 0;
-
-// Unprocessed inserts (must be big enough to hold all allocations that can
-// be caused by a InsertRegionLocked call).
-// Region has no constructor, so that c-tor execution does not interfere
-// with the any-time use of the static memory behind saved_regions.
-static MemoryRegionMap::Region saved_regions[20];
-
-inline void MemoryRegionMap::HandleSavedRegionsLocked(
-              void (*insert_func)(const Region& region)) {
-  while (saved_regions_count > 0) {
-    // Making a local-var copy of the region argument to insert_func
-    // including its stack (w/o doing any memory allocations) is important:
-    // in many cases the memory in saved_regions
-    // will get written-to during the (*insert_func)(r) call below.
-    Region r = saved_regions[--saved_regions_count];
-    (*insert_func)(r);
-  }
-}
-
-void MemoryRegionMap::RestoreSavedBucketsLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  while (saved_buckets_count_ > 0) {
-    HeapProfileBucket bucket = saved_buckets_[--saved_buckets_count_];
-    unsigned int hash_index =
-        static_cast<unsigned int>(bucket.hash) % kHashTableSize;
-    bool is_found = false;
-    for (HeapProfileBucket* curr = bucket_table_[hash_index];
-         curr != 0;
-         curr = curr->next) {
-      if ((curr->hash == bucket.hash) && (curr->depth == bucket.depth) &&
-          std::equal(bucket.stack, bucket.stack + bucket.depth, curr->stack)) {
-        curr->allocs += bucket.allocs;
-        curr->alloc_size += bucket.alloc_size;
-        curr->frees += bucket.frees;
-        curr->free_size += bucket.free_size;
-        is_found = true;
-        break;
-      }
-    }
-    if (is_found) continue;
-
-    const size_t key_size = sizeof(bucket.stack[0]) * bucket.depth;
-    const void** key_copy = static_cast<const void**>(
-        MyAllocator::Allocate(key_size));
-    std::copy(bucket.stack, bucket.stack + bucket.depth, key_copy);
-    HeapProfileBucket* new_bucket = static_cast<HeapProfileBucket*>(
-        MyAllocator::Allocate(sizeof(HeapProfileBucket)));
-    memset(new_bucket, 0, sizeof(*new_bucket));
-    new_bucket->hash = bucket.hash;
-    new_bucket->depth = bucket.depth;
-    new_bucket->stack = key_copy;
-    new_bucket->next = bucket_table_[hash_index];
-    bucket_table_[hash_index] = new_bucket;
-    ++num_buckets_;
-  }
-}
-
-inline void MemoryRegionMap::InsertRegionLocked(const Region& region) {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  // We can be called recursively, because RegionSet constructor
-  // and DoInsertRegionLocked() (called below) can call the allocator.
-  // recursive_insert tells us if that's the case. When this happens,
-  // region insertion information is recorded in saved_regions[],
-  // and taken into account when the recursion unwinds.
-  // Do the insert:
-  if (recursive_insert) {  // recursion: save in saved_regions
-    RAW_VLOG(12, "Saving recursive insert of region %p..%p from %p",
-                reinterpret_cast<void*>(region.start_addr),
-                reinterpret_cast<void*>(region.end_addr),
-                reinterpret_cast<void*>(region.caller()));
-    RAW_CHECK(saved_regions_count < arraysize(saved_regions), "");
-    // Copy 'region' to saved_regions[saved_regions_count]
-    // together with the contents of its call_stack,
-    // then increment saved_regions_count.
-    saved_regions[saved_regions_count++] = region;
-  } else {  // not a recusrive call
-    if (regions_ == NULL) {  // init regions_
-      RAW_VLOG(12, "Initializing region set");
-      regions_ = regions_rep.region_set();
-      recursive_insert = true;
-      new(regions_) RegionSet();
-      HandleSavedRegionsLocked(&DoInsertRegionLocked);
-      recursive_insert = false;
-    }
-    recursive_insert = true;
-    // Do the actual insertion work to put new regions into regions_:
-    DoInsertRegionLocked(region);
-    HandleSavedRegionsLocked(&DoInsertRegionLocked);
-    recursive_insert = false;
-  }
-}
-
-// We strip out different number of stack frames in debug mode
-// because less inlining happens in that case
-#ifdef NDEBUG
-static const int kStripFrames = 1;
-#else
-static const int kStripFrames = 3;
-#endif
-
-void MemoryRegionMap::RecordRegionAddition(const void* start, size_t size) {
-  // Record start/end info about this memory acquisition call in a new region:
-  Region region;
-  region.Create(start, size);
-  // First get the call stack info into the local varible 'region':
-  int depth = 0;
-  // NOTE: libunwind also does mmap and very much likely while holding
-  // it's own lock(s). So some threads may first take libunwind lock,
-  // and then take region map lock (necessary to record mmap done from
-  // inside libunwind). On the other hand other thread(s) may do
-  // normal mmap. Which would call this method to record it. Which
-  // would then proceed with installing that record to region map
-  // while holding region map lock. That may cause mmap from our own
-  // internal allocators, so attempt to unwind in this case may cause
-  // reverse order of taking libuwind and region map locks. Which is
-  // obvious deadlock.
-  //
-  // Thankfully, we can easily detect if we're holding region map lock
-  // and avoid recording backtrace in this (rare and largely
-  // irrelevant) case. By doing this we "declare" that thread needing
-  // both locks must take region map lock last. In other words we do
-  // not allow taking libuwind lock when we already have region map
-  // lock. Note, this is generally impossible when somebody tries to
-  // mix cpu profiling and heap checking/profiling, because cpu
-  // profiler grabs backtraces at arbitrary places. But at least such
-  // combination is rarer and less relevant.
-  if (max_stack_depth_ > 0 && !LockIsHeld()) {
-    depth = MallocHook::GetCallerStackTrace(const_cast<void**>(region.call_stack),
-                                            max_stack_depth_, kStripFrames + 1);
-  }
-  region.set_call_stack_depth(depth);  // record stack info fully
-  RAW_VLOG(10, "New global region %p..%p from %p",
-              reinterpret_cast<void*>(region.start_addr),
-              reinterpret_cast<void*>(region.end_addr),
-              reinterpret_cast<void*>(region.caller()));
-  // Note: none of the above allocates memory.
-  Lock();  // recursively lock
-  map_size_ += size;
-  InsertRegionLocked(region);
-    // This will (eventually) allocate storage for and copy over the stack data
-    // from region.call_stack_data_ that is pointed by region.call_stack().
-  if (bucket_table_ != NULL) {
-    HeapProfileBucket* b = GetBucket(depth, region.call_stack);
-    ++b->allocs;
-    b->alloc_size += size;
-    if (!recursive_insert) {
-      recursive_insert = true;
-      RestoreSavedBucketsLocked();
-      recursive_insert = false;
-    }
-  }
-  Unlock();
-}
-
-void MemoryRegionMap::RecordRegionRemoval(const void* start, size_t size) {
-  Lock();
-  if (recursive_insert) {
-    // First remove the removed region from saved_regions, if it's
-    // there, to prevent overrunning saved_regions in recursive
-    // map/unmap call sequences, and also from later inserting regions
-    // which have already been unmapped.
-    uintptr_t start_addr = reinterpret_cast<uintptr_t>(start);
-    uintptr_t end_addr = start_addr + size;
-    int put_pos = 0;
-    int old_count = saved_regions_count;
-    for (int i = 0; i < old_count; ++i, ++put_pos) {
-      Region& r = saved_regions[i];
-      if (r.start_addr == start_addr && r.end_addr == end_addr) {
-        // An exact match, so it's safe to remove.
-        RecordRegionRemovalInBucket(r.call_stack_depth, r.call_stack, size);
-        --saved_regions_count;
-        --put_pos;
-        RAW_VLOG(10, ("Insta-Removing saved region %p..%p; "
-                     "now have %d saved regions"),
-                 reinterpret_cast<void*>(start_addr),
-                 reinterpret_cast<void*>(end_addr),
-                 saved_regions_count);
-      } else {
-        if (put_pos < i) {
-          saved_regions[put_pos] = saved_regions[i];
-        }
-      }
-    }
-  }
-  if (regions_ == NULL) {  // We must have just unset the hooks,
-                           // but this thread was already inside the hook.
-    Unlock();
-    return;
-  }
-  if (!recursive_insert) {
-    HandleSavedRegionsLocked(&InsertRegionLocked);
-  }
-    // first handle adding saved regions if any
-  uintptr_t start_addr = reinterpret_cast<uintptr_t>(start);
-  uintptr_t end_addr = start_addr + size;
-  // subtract start_addr, end_addr from all the regions
-  RAW_VLOG(10, "Removing global region %p..%p; have %" PRIuS " regions",
-              reinterpret_cast<void*>(start_addr),
-              reinterpret_cast<void*>(end_addr),
-              regions_->size());
-  Region sample;
-  sample.SetRegionSetKey(start_addr);
-  // Only iterate over the regions that might overlap start_addr..end_addr:
-  for (RegionSet::iterator region = regions_->lower_bound(sample);
-       region != regions_->end()  &&  region->start_addr < end_addr;
-       /*noop*/) {
-    RAW_VLOG(13, "Looking at region %p..%p",
-                reinterpret_cast<void*>(region->start_addr),
-                reinterpret_cast<void*>(region->end_addr));
-    if (start_addr <= region->start_addr  &&
-        region->end_addr <= end_addr) {  // full deletion
-      RAW_VLOG(12, "Deleting region %p..%p",
-                  reinterpret_cast<void*>(region->start_addr),
-                  reinterpret_cast<void*>(region->end_addr));
-      RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
-                                  region->end_addr - region->start_addr);
-      RegionSet::iterator d = region;
-      ++region;
-      regions_->erase(d);
-      continue;
-    } else if (region->start_addr < start_addr  &&
-               end_addr < region->end_addr) {  // cutting-out split
-      RAW_VLOG(12, "Splitting region %p..%p in two",
-                  reinterpret_cast<void*>(region->start_addr),
-                  reinterpret_cast<void*>(region->end_addr));
-      RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
-                                  end_addr - start_addr);
-      // Make another region for the start portion:
-      // The new region has to be the start portion because we can't
-      // just modify region->end_addr as it's the sorting key.
-      Region r = *region;
-      r.set_end_addr(start_addr);
-      InsertRegionLocked(r);
-      // cut *region from start:
-      const_cast<Region&>(*region).set_start_addr(end_addr);
-    } else if (end_addr > region->start_addr  &&
-               start_addr <= region->start_addr) {  // cut from start
-      RAW_VLOG(12, "Start-chopping region %p..%p",
-                  reinterpret_cast<void*>(region->start_addr),
-                  reinterpret_cast<void*>(region->end_addr));
-      RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
-                                  end_addr - region->start_addr);
-      const_cast<Region&>(*region).set_start_addr(end_addr);
-    } else if (start_addr > region->start_addr  &&
-               start_addr < region->end_addr) {  // cut from end
-      RAW_VLOG(12, "End-chopping region %p..%p",
-                  reinterpret_cast<void*>(region->start_addr),
-                  reinterpret_cast<void*>(region->end_addr));
-      RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
-                                  region->end_addr - start_addr);
-      // Can't just modify region->end_addr (it's the sorting key):
-      Region r = *region;
-      r.set_end_addr(start_addr);
-      RegionSet::iterator d = region;
-      ++region;
-      // It's safe to erase before inserting since r is independent of *d:
-      // r contains an own copy of the call stack:
-      regions_->erase(d);
-      InsertRegionLocked(r);
-      continue;
-    }
-    ++region;
-  }
-  RAW_VLOG(12, "Removed region %p..%p; have %" PRIuS " regions",
-              reinterpret_cast<void*>(start_addr),
-              reinterpret_cast<void*>(end_addr),
-              regions_->size());
-  if (VLOG_IS_ON(12))  LogAllLocked();
-  unmap_size_ += size;
-  Unlock();
-}
-
-void MemoryRegionMap::RecordRegionRemovalInBucket(int depth,
-                                                  const void* const stack[],
-                                                  size_t size) {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  if (bucket_table_ == NULL) return;
-  HeapProfileBucket* b = GetBucket(depth, stack);
-  ++b->frees;
-  b->free_size += size;
-}
-
-void MemoryRegionMap::MmapHook(const void* result,
-                               const void* start, size_t size,
-                               int prot, int flags,
-                               int fd, off_t offset) {
-  // TODO(maxim): replace all 0x%" PRIxS " by %p when RAW_VLOG uses a safe
-  // snprintf reimplementation that does not malloc to pretty-print NULL
-  RAW_VLOG(10, "MMap = 0x%" PRIxPTR " of %" PRIuS " at %" PRIu64 " "
-              "prot %d flags %d fd %d offs %" PRId64,
-              reinterpret_cast<uintptr_t>(result), size,
-              reinterpret_cast<uint64>(start), prot, flags, fd,
-              static_cast<int64>(offset));
-  if (result != reinterpret_cast<void*>(MAP_FAILED)  &&  size != 0) {
-    RecordRegionAddition(result, size);
-  }
-}
-
-void MemoryRegionMap::MunmapHook(const void* ptr, size_t size) {
-  RAW_VLOG(10, "MUnmap of %p %" PRIuS "", ptr, size);
-  if (size != 0) {
-    RecordRegionRemoval(ptr, size);
-  }
-}
-
-void MemoryRegionMap::MremapHook(const void* result,
-                                 const void* old_addr, size_t old_size,
-                                 size_t new_size, int flags,
-                                 const void* new_addr) {
-  RAW_VLOG(10, "MRemap = 0x%" PRIxPTR " of 0x%" PRIxPTR " %" PRIuS " "
-              "to %" PRIuS " flags %d new_addr=0x%" PRIxPTR,
-              (uintptr_t)result, (uintptr_t)old_addr,
-               old_size, new_size, flags,
-               flags & MREMAP_FIXED ? (uintptr_t)new_addr : 0);
-  if (result != reinterpret_cast<void*>(-1)) {
-    RecordRegionRemoval(old_addr, old_size);
-    RecordRegionAddition(result, new_size);
-  }
-}
-
-void MemoryRegionMap::SbrkHook(const void* result, ptrdiff_t increment) {
-  RAW_VLOG(10, "Sbrk = 0x%" PRIxPTR " of %" PRIdS "", (uintptr_t)result, increment);
-  if (result != reinterpret_cast<void*>(-1)) {
-    if (increment > 0) {
-      void* new_end = sbrk(0);
-      RecordRegionAddition(result, reinterpret_cast<uintptr_t>(new_end) -
-                                   reinterpret_cast<uintptr_t>(result));
-    } else if (increment < 0) {
-      void* new_end = sbrk(0);
-      RecordRegionRemoval(new_end, reinterpret_cast<uintptr_t>(result) -
-                                   reinterpret_cast<uintptr_t>(new_end));
-    }
-  }
-}
-
-void MemoryRegionMap::LogAllLocked() {
-  RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
-  RAW_LOG(INFO, "List of regions:");
-  uintptr_t previous = 0;
-  for (RegionSet::const_iterator r = regions_->begin();
-       r != regions_->end(); ++r) {
-    RAW_LOG(INFO, "Memory region 0x%" PRIxPTR "..0x%" PRIxPTR " "
-                  "from 0x%" PRIxPTR " stack=%d",
-                  r->start_addr, r->end_addr, r->caller(), r->is_stack);
-    RAW_CHECK(previous < r->end_addr, "wow, we messed up the set order");
-      // this must be caused by uncontrolled recursive operations on regions_
-    previous = r->end_addr;
-  }
-  RAW_LOG(INFO, "End of regions list");
-}
diff --git a/third_party/tcmalloc/vendor/src/memory_region_map.h b/third_party/tcmalloc/vendor/src/memory_region_map.h
deleted file mode 100644
index b6ae95b7..0000000
--- a/third_party/tcmalloc/vendor/src/memory_region_map.h
+++ /dev/null
@@ -1,415 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Maxim Lifantsev
- */
-
-#ifndef BASE_MEMORY_REGION_MAP_H_
-#define BASE_MEMORY_REGION_MAP_H_
-
-#include <config.h>
-
-#ifdef HAVE_PTHREAD
-#include <pthread.h>
-#endif
-#include <stddef.h>
-#include <set>
-#include "base/stl_allocator.h"
-#include "base/spinlock.h"
-#include "base/thread_annotations.h"
-#include "base/low_level_alloc.h"
-#include "heap-profile-stats.h"
-
-// TODO(maxim): add a unittest:
-//  execute a bunch of mmaps and compare memory map what strace logs
-//  execute a bunch of mmap/munmup and compare memory map with
-//  own accounting of what those mmaps generated
-
-// Thread-safe class to collect and query the map of all memory regions
-// in a process that have been created with mmap, munmap, mremap, sbrk.
-// For each memory region, we keep track of (and provide to users)
-// the stack trace that allocated that memory region.
-// The recorded stack trace depth is bounded by
-// a user-supplied max_stack_depth parameter of Init().
-// After initialization with Init()
-// (which can happened even before global object constructor execution)
-// we collect the map by installing and monitoring MallocHook-s
-// to mmap, munmap, mremap, sbrk.
-// At any time one can query this map via provided interface.
-// For more details on the design of MemoryRegionMap
-// see the comment at the top of our .cc file.
-class MemoryRegionMap {
- private:
-  // Max call stack recording depth supported by Init().  Set it to be
-  // high enough for all our clients.  Note: we do not define storage
-  // for this (doing that requires special handling in windows), so
-  // don't take the address of it!
-  static const int kMaxStackDepth = 32;
-
-  // Size of the hash table of buckets.  A structure of the bucket table is
-  // described in heap-profile-stats.h.
-  static const int kHashTableSize = 179999;
-
- public:
-  // interface ================================================================
-
-  // Every client of MemoryRegionMap must call Init() before first use,
-  // and Shutdown() after last use.  This allows us to reference count
-  // this (singleton) class properly.  MemoryRegionMap assumes it's the
-  // only client of MallocHooks, so a client can only register other
-  // MallocHooks after calling Init() and must unregister them before
-  // calling Shutdown().
-
-  // Initialize this module to record memory allocation stack traces.
-  // Stack traces that have more than "max_stack_depth" frames
-  // are automatically shrunk to "max_stack_depth" when they are recorded.
-  // Init() can be called more than once w/o harm, largest max_stack_depth
-  // will be the effective one.
-  // When "use_buckets" is true, then counts of mmap and munmap sizes will be
-  // recorded with each stack trace.  If Init() is called more than once, then
-  // counting will be effective after any call contained "use_buckets" of true.
-  // It will install mmap, munmap, mremap, sbrk hooks
-  // and initialize arena_ and our hook and locks, hence one can use
-  // MemoryRegionMap::Lock()/Unlock() to manage the locks.
-  // Uses Lock/Unlock inside.
-  static void Init(int max_stack_depth, bool use_buckets);
-
-  // Try to shutdown this module undoing what Init() did.
-  // Returns true iff could do full shutdown (or it was not attempted).
-  // Full shutdown is attempted when the number of Shutdown() calls equals
-  // the number of Init() calls.
-  static bool Shutdown();
-
-  // Return true if MemoryRegionMap is initialized and recording, i.e. when
-  // then number of Init() calls are more than the number of Shutdown() calls.
-  static bool IsRecordingLocked();
-
-  // Locks to protect our internal data structures.
-  // These also protect use of arena_ if our Init() has been done.
-  // The lock is recursive.
-  static void Lock() EXCLUSIVE_LOCK_FUNCTION(lock_);
-  static void Unlock() UNLOCK_FUNCTION(lock_);
-
-  // Returns true when the lock is held by this thread (for use in RAW_CHECK-s).
-  static bool LockIsHeld();
-
-  // Locker object that acquires the MemoryRegionMap::Lock
-  // for the duration of its lifetime (a C++ scope).
-  class LockHolder {
-   public:
-    LockHolder() { Lock(); }
-
-    LockHolder(const LockHolder&) = delete;
-    LockHolder& operator=(const LockHolder&) = delete;
-
-    ~LockHolder() { Unlock(); }
-  };
-
-  // A memory region that we know about through malloc_hook-s.
-  // This is essentially an interface through which MemoryRegionMap
-  // exports the collected data to its clients.  Thread-compatible.
-  struct Region {
-    uintptr_t start_addr;  // region start address
-    uintptr_t end_addr;  // region end address
-    int call_stack_depth;  // number of caller stack frames that we saved
-    const void* call_stack[kMaxStackDepth];  // caller address stack array
-                                             // filled to call_stack_depth size
-    bool is_stack;  // does this region contain a thread's stack:
-                    // a user of MemoryRegionMap supplies this info
-
-    // Convenience accessor for call_stack[0],
-    // i.e. (the program counter of) the immediate caller
-    // of this region's allocation function,
-    // but it also returns NULL when call_stack_depth is 0,
-    // i.e whe we weren't able to get the call stack.
-    // This usually happens in recursive calls, when the stack-unwinder
-    // calls mmap() which in turn calls the stack-unwinder.
-    uintptr_t caller() const {
-      return reinterpret_cast<uintptr_t>(call_stack_depth >= 1
-                                         ? call_stack[0] : NULL);
-    }
-
-    // Return true iff this region overlaps region x.
-    bool Overlaps(const Region& x) const {
-      return start_addr < x.end_addr  &&  end_addr > x.start_addr;
-    }
-
-   private:  // helpers for MemoryRegionMap
-    friend class MemoryRegionMap;
-
-    // The ways we create Region-s:
-    void Create(const void* start, size_t size) {
-      start_addr = reinterpret_cast<uintptr_t>(start);
-      end_addr = start_addr + size;
-      is_stack = false;  // not a stack till marked such
-      call_stack_depth = 0;
-      AssertIsConsistent();
-    }
-    void set_call_stack_depth(int depth) {
-      RAW_DCHECK(call_stack_depth == 0, "");  // only one such set is allowed
-      call_stack_depth = depth;
-      AssertIsConsistent();
-    }
-
-    // The ways we modify Region-s:
-    void set_is_stack() { is_stack = true; }
-    void set_start_addr(uintptr_t addr) {
-      start_addr = addr;
-      AssertIsConsistent();
-    }
-    void set_end_addr(uintptr_t addr) {
-      end_addr = addr;
-      AssertIsConsistent();
-    }
-
-    // Verifies that *this contains consistent data, crashes if not the case.
-    void AssertIsConsistent() const {
-      RAW_DCHECK(start_addr < end_addr, "");
-      RAW_DCHECK(call_stack_depth >= 0  &&
-                 call_stack_depth <= kMaxStackDepth, "");
-    }
-
-    // Post-default construction helper to make a Region suitable
-    // for searching in RegionSet regions_.
-    void SetRegionSetKey(uintptr_t addr) {
-      // make sure *this has no usable data:
-      if (DEBUG_MODE) memset(this, 0xFF, sizeof(*this));
-      end_addr = addr;
-    }
-
-    // Note: call_stack[kMaxStackDepth] as a member lets us make Region
-    // a simple self-contained struct with correctly behaving bit-vise copying.
-    // This simplifies the code of this module but wastes some memory:
-    // in most-often use case of this module (leak checking)
-    // only one call_stack element out of kMaxStackDepth is actually needed.
-    // Making the storage for call_stack variable-sized,
-    // substantially complicates memory management for the Region-s:
-    // as they need to be created and manipulated for some time
-    // w/o any memory allocations, yet are also given out to the users.
-  };
-
-  // Find the region that covers addr and write its data into *result if found,
-  // in which case *result gets filled so that it stays fully functional
-  // even when the underlying region gets removed from MemoryRegionMap.
-  // Returns success. Uses Lock/Unlock inside.
-  static bool FindRegion(uintptr_t addr, Region* result);
-
-  // Find the region that contains stack_top, mark that region as
-  // a stack region, and write its data into *result if found,
-  // in which case *result gets filled so that it stays fully functional
-  // even when the underlying region gets removed from MemoryRegionMap.
-  // Returns success. Uses Lock/Unlock inside.
-  static bool FindAndMarkStackRegion(uintptr_t stack_top, Region* result);
-
-  // Iterate over the buckets which store mmap and munmap counts per stack
-  // trace.  It calls "callback" for each bucket, and passes "arg" to it.
-  template<class Type>
-  static void IterateBuckets(void (*callback)(const HeapProfileBucket*, Type),
-                             Type arg);
-
-  // Get the bucket whose caller stack trace is "key".  The stack trace is
-  // used to a depth of "depth" at most.  The requested bucket is created if
-  // needed.
-  // The bucket table is described in heap-profile-stats.h.
-  static HeapProfileBucket* GetBucket(int depth, const void* const key[]);
-
- private:  // our internal types ==============================================
-
-  // Region comparator for sorting with STL
-  struct RegionCmp {
-    bool operator()(const Region& x, const Region& y) const {
-      return x.end_addr < y.end_addr;
-    }
-  };
-
-  // We allocate STL objects in our own arena.
-  struct MyAllocator {
-    static void *Allocate(size_t n) {
-      return LowLevelAlloc::AllocWithArena(n, arena_);
-    }
-    static void Free(const void *p, size_t /* n */) {
-      LowLevelAlloc::Free(const_cast<void*>(p));
-    }
-  };
-
-  // Set of the memory regions
-  typedef std::set<Region, RegionCmp,
-              STL_Allocator<Region, MyAllocator> > RegionSet;
-
- public:  // more in-depth interface ==========================================
-
-  // STL iterator with values of Region
-  typedef RegionSet::const_iterator RegionIterator;
-
-  // Return the begin/end iterators to all the regions.
-  // These need Lock/Unlock protection around their whole usage (loop).
-  // Even when the same thread causes modifications during such a loop
-  // (which are permitted due to recursive locking)
-  // the loop iterator will still be valid as long as its region
-  // has not been deleted, but EndRegionLocked should be
-  // re-evaluated whenever the set of regions has changed.
-  static RegionIterator BeginRegionLocked();
-  static RegionIterator EndRegionLocked();
-
-  // Return the accumulated sizes of mapped and unmapped regions.
-  static int64 MapSize() { return map_size_; }
-  static int64 UnmapSize() { return unmap_size_; }
-
-  // Effectively private type from our .cc =================================
-  // public to let us declare global objects:
-  union RegionSetRep;
-
- private:
-  // representation ===========================================================
-
-  // Counter of clients of this module that have called Init().
-  static int client_count_;
-
-  // Maximal number of caller stack frames to save (>= 0).
-  static int max_stack_depth_;
-
-  // Arena used for our allocations in regions_.
-  static LowLevelAlloc::Arena* arena_;
-
-  // Set of the mmap/sbrk/mremap-ed memory regions
-  // To be accessed *only* when Lock() is held.
-  // Hence we protect the non-recursive lock used inside of arena_
-  // with our recursive Lock(). This lets a user prevent deadlocks
-  // when threads are stopped by TCMalloc_ListAllProcessThreads at random spots
-  // simply by acquiring our recursive Lock() before that.
-  static RegionSet* regions_;
-
-  // Lock to protect regions_ and buckets_ variables and the data behind.
-  static SpinLock lock_;
-  // Lock to protect the recursive lock itself.
-  static SpinLock owner_lock_;
-
-  // Recursion count for the recursive lock.
-  static int recursion_count_;
-  // The thread id of the thread that's inside the recursive lock.
-  static pthread_t lock_owner_tid_;
-
-  // Total size of all mapped pages so far
-  static int64 map_size_;
-  // Total size of all unmapped pages so far
-  static int64 unmap_size_;
-
-  // Bucket hash table which is described in heap-profile-stats.h.
-  static HeapProfileBucket** bucket_table_ GUARDED_BY(lock_);
-  static int num_buckets_ GUARDED_BY(lock_);
-
-  // The following members are local to MemoryRegionMap::GetBucket()
-  // and MemoryRegionMap::HandleSavedBucketsLocked()
-  // and are file-level to ensure that they are initialized at load time.
-  //
-  // These are used as temporary storage to break the infinite cycle of mmap
-  // calling our hook which (sometimes) causes mmap.  It must be a static
-  // fixed-size array.  The size 20 is just an expected value for safety.
-  // The details are described in memory_region_map.cc.
-
-  // Number of unprocessed bucket inserts.
-  static int saved_buckets_count_ GUARDED_BY(lock_);
-
-  // Unprocessed inserts (must be big enough to hold all mmaps that can be
-  // caused by a GetBucket call).
-  // Bucket has no constructor, so that c-tor execution does not interfere
-  // with the any-time use of the static memory behind saved_buckets.
-  static HeapProfileBucket saved_buckets_[20] GUARDED_BY(lock_);
-
-  static const void* saved_buckets_keys_[20][kMaxStackDepth] GUARDED_BY(lock_);
-
-  // helpers ==================================================================
-
-  // Helper for FindRegion and FindAndMarkStackRegion:
-  // returns the region covering 'addr' or NULL; assumes our lock_ is held.
-  static const Region* DoFindRegionLocked(uintptr_t addr);
-
-  // Verifying wrapper around regions_->insert(region)
-  // To be called to do InsertRegionLocked's work only!
-  inline static void DoInsertRegionLocked(const Region& region);
-  // Handle regions saved by InsertRegionLocked into a tmp static array
-  // by calling insert_func on them.
-  inline static void HandleSavedRegionsLocked(
-                       void (*insert_func)(const Region& region));
-
-  // Restore buckets saved in a tmp static array by GetBucket to the bucket
-  // table where all buckets eventually should be.
-  static void RestoreSavedBucketsLocked();
-
-  // Wrapper around DoInsertRegionLocked
-  // that handles the case of recursive allocator calls.
-  inline static void InsertRegionLocked(const Region& region);
-
-  // Record addition of a memory region at address "start" of size "size"
-  // (called from our mmap/mremap/sbrk hooks).
-  static void RecordRegionAddition(const void* start, size_t size);
-  // Record deletion of a memory region at address "start" of size "size"
-  // (called from our munmap/mremap/sbrk hooks).
-  static void RecordRegionRemoval(const void* start, size_t size);
-
-  // Record deletion of a memory region of size "size" in a bucket whose
-  // caller stack trace is "key".  The stack trace is used to a depth of
-  // "depth" at most.
-  static void RecordRegionRemovalInBucket(int depth,
-                                          const void* const key[],
-                                          size_t size);
-
-  // Hooks for MallocHook
-  static void MmapHook(const void* result,
-                       const void* start, size_t size,
-                       int prot, int flags,
-                       int fd, off_t offset);
-  static void MunmapHook(const void* ptr, size_t size);
-  static void MremapHook(const void* result, const void* old_addr,
-                         size_t old_size, size_t new_size, int flags,
-                         const void* new_addr);
-  static void SbrkHook(const void* result, ptrdiff_t increment);
-
-  // Log all memory regions; Useful for debugging only.
-  // Assumes Lock() is held
-  static void LogAllLocked();
-
-  DISALLOW_COPY_AND_ASSIGN(MemoryRegionMap);
-};
-
-template <class Type>
-void MemoryRegionMap::IterateBuckets(
-    void (*callback)(const HeapProfileBucket*, Type), Type callback_arg) {
-  for (int index = 0; index < kHashTableSize; index++) {
-    for (HeapProfileBucket* bucket = bucket_table_[index];
-         bucket != NULL;
-         bucket = bucket->next) {
-      callback(bucket, callback_arg);
-    }
-  }
-}
-
-#endif  // BASE_MEMORY_REGION_MAP_H_
diff --git a/third_party/tcmalloc/vendor/src/packed-cache-inl.h b/third_party/tcmalloc/vendor/src/packed-cache-inl.h
deleted file mode 100644
index 7c216e5..0000000
--- a/third_party/tcmalloc/vendor/src/packed-cache-inl.h
+++ /dev/null
@@ -1,216 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Geoff Pike
-//
-// This file provides a minimal cache that can hold a <key, value> pair
-// with little if any wasted space.  The types of the key and value
-// must be unsigned integral types or at least have unsigned semantics
-// for >>, casting, and similar operations.
-//
-// Synchronization is not provided.  However, the cache is implemented
-// as an array of cache entries whose type is chosen at compile time.
-// If a[i] is atomic on your hardware for the chosen array type then
-// raciness will not necessarily lead to bugginess.  The cache entries
-// must be large enough to hold a partial key and a value packed
-// together.  The partial keys are bit strings of length
-// kKeybits - kHashbits, and the values are bit strings of length kValuebits.
-//
-// In an effort to use minimal space, every cache entry represents
-// some <key, value> pair; the class provides no way to mark a cache
-// entry as empty or uninitialized.  In practice, you may want to have
-// reserved keys or values to get around this limitation.  For example, in
-// tcmalloc's PageID-to-sizeclass cache, a value of 0 is used as
-// "unknown sizeclass."
-//
-// Usage Considerations
-// --------------------
-//
-// kHashbits controls the size of the cache.  The best value for
-// kHashbits will of course depend on the application.  Perhaps try
-// tuning the value of kHashbits by measuring different values on your
-// favorite benchmark.  Also remember not to be a pig; other
-// programs that need resources may suffer if you are.
-//
-// The main uses for this class will be when performance is
-// critical and there's a convenient type to hold the cache's
-// entries.  As described above, the number of bits required
-// for a cache entry is (kKeybits - kHashbits) + kValuebits.  Suppose
-// kKeybits + kValuebits is 43.  Then it probably makes sense to
-// chose kHashbits >= 11 so that cache entries fit in a uint32.
-//
-// On the other hand, suppose kKeybits = kValuebits = 64.  Then
-// using this class may be less worthwhile.  You'll probably
-// be using 128 bits for each entry anyway, so maybe just pick
-// a hash function, H, and use an array indexed by H(key):
-//    void Put(K key, V value) { a_[H(key)] = pair<K, V>(key, value); }
-//    V GetOrDefault(K key, V default) { const pair<K, V> &p = a_[H(key)]; ... }
-//    etc.
-//
-// Further Details
-// ---------------
-//
-// For caches used only by one thread, the following is true:
-// 1. For a cache c,
-//      (c.Put(key, value), c.GetOrDefault(key, 0)) == value
-//    and
-//      (c.Put(key, value), <...>, c.GetOrDefault(key, 0)) == value
-//    if the elided code contains no c.Put calls.
-//
-// 2. Has(key) will return false if no <key, value> pair with that key
-//    has ever been Put.  However, a newly initialized cache will have
-//    some <key, value> pairs already present.  When you create a new
-//    cache, you must specify an "initial value."  The initialization
-//    procedure is equivalent to Clear(initial_value), which is
-//    equivalent to Put(k, initial_value) for all keys k from 0 to
-//    2^kHashbits - 1.
-//
-// 3. If key and key' differ then the only way Put(key, value) may
-//    cause Has(key') to change is that Has(key') may change from true to
-//    false. Furthermore, a Put() call that doesn't change Has(key')
-//    doesn't change GetOrDefault(key', ...) either.
-//
-// Implementation details:
-//
-// This is a direct-mapped cache with 2^kHashbits entries; the hash
-// function simply takes the low bits of the key.  We store whole keys
-// if a whole key plus a whole value fits in an entry.  Otherwise, an
-// entry is the high bits of a key and a value, packed together.
-// E.g., a 20 bit key and a 7 bit value only require a uint16 for each
-// entry if kHashbits >= 11.
-//
-// Alternatives to this scheme will be added as needed.
-
-#ifndef TCMALLOC_PACKED_CACHE_INL_H_
-#define TCMALLOC_PACKED_CACHE_INL_H_
-
-#include "config.h"
-#include <stddef.h>                     // for size_t
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uintptr_t
-#endif
-#include "base/basictypes.h"
-#include "common.h"
-#include "internal_logging.h"
-
-// A safe way of doing "(1 << n) - 1" -- without worrying about overflow
-// Note this will all be resolved to a constant expression at compile-time
-#define N_ONES_(IntType, N)                                     \
-  ( (N) == 0 ? 0 : ((static_cast<IntType>(1) << ((N)-1))-1 +    \
-                    (static_cast<IntType>(1) << ((N)-1))) )
-
-// The types K and V provide upper bounds on the number of valid keys
-// and values, but we explicitly require the keys to be less than
-// 2^kKeybits and the values to be less than 2^kValuebits.  The size
-// of the table is controlled by kHashbits, and the type of each entry
-// in the cache is uintptr_t (native machine word).  See also the big
-// comment at the top of the file.
-template <int kKeybits>
-class PackedCache {
- public:
-  typedef uintptr_t T;
-  typedef uintptr_t K;
-  typedef uint32 V;
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-  // Decrease the size map cache if running in the small memory mode.
-  static const int kHashbits = 12;
-#else
-  static const int kHashbits = 16;
-#endif
-  static const int kValuebits = 7;
-  // one bit after value bits
-  static const int kInvalidMask = 0x80;
-
-  explicit PackedCache() {
-    COMPILE_ASSERT(kKeybits + kValuebits + 1 <= 8 * sizeof(T), use_whole_keys);
-    COMPILE_ASSERT(kHashbits <= kKeybits, hash_function);
-    COMPILE_ASSERT(kHashbits >= kValuebits + 1, small_values_space);
-    Clear();
-  }
-
-  bool TryGet(K key, V* out) const {
-    // As with other code in this class, we touch array_ as few times
-    // as we can.  Assuming entries are read atomically then certain
-    // races are harmless.
-    ASSERT(key == (key & kKeyMask));
-    T hash = Hash(key);
-    T expected_entry = key;
-    expected_entry &= ~N_ONES_(T, kHashbits);
-    T entry = array_[hash];
-    entry ^= expected_entry;
-    if (PREDICT_FALSE(entry >= (1 << kValuebits))) {
-      return false;
-    }
-    *out = static_cast<V>(entry);
-    return true;
-  }
-
-  void Clear() {
-    // sets 'invalid' bit in every byte, include value byte
-    memset(const_cast<T* >(array_), kInvalidMask, sizeof(array_));
-  }
-
-  void Put(K key, V value) {
-    ASSERT(key == (key & kKeyMask));
-    ASSERT(value == (value & kValueMask));
-    array_[Hash(key)] = KeyToUpper(key) | value;
-  }
-
-  void Invalidate(K key) {
-    ASSERT(key == (key & kKeyMask));
-    array_[Hash(key)] = KeyToUpper(key) | kInvalidMask;
-  }
-
- private:
-  // we just wipe all hash bits out of key. I.e. clear lower
-  // kHashbits. We rely on compiler knowing value of Hash(k).
-  static T KeyToUpper(K k) {
-    return static_cast<T>(k) ^ Hash(k);
-  }
-
-  static T Hash(K key) {
-    return static_cast<T>(key) & N_ONES_(size_t, kHashbits);
-  }
-
-  // For masking a K.
-  static const K kKeyMask = N_ONES_(K, kKeybits);
-
-  // For masking a V or a T.
-  static const V kValueMask = N_ONES_(V, kValuebits);
-
-  // array_ is the cache.  Its elements are volatile because any
-  // thread can write any array element at any time.
-  volatile T array_[1 << kHashbits];
-};
-
-#undef N_ONES_
-
-#endif  // TCMALLOC_PACKED_CACHE_INL_H_
diff --git a/third_party/tcmalloc/vendor/src/page_heap.cc b/third_party/tcmalloc/vendor/src/page_heap.cc
deleted file mode 100644
index 7dd5646..0000000
--- a/third_party/tcmalloc/vendor/src/page_heap.cc
+++ /dev/null
@@ -1,726 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>                   // for PRIuPTR
-#endif
-#include <errno.h>                      // for ENOMEM, errno
-#include <gperftools/malloc_extension.h>      // for MallocRange, etc
-#include "base/basictypes.h"
-#include "base/commandlineflags.h"
-#include "internal_logging.h"  // for ASSERT, TCMalloc_Printer, etc
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "static_vars.h"       // for Static
-#include "system-alloc.h"      // for TCMalloc_SystemAlloc, etc
-
-DEFINE_double(tcmalloc_release_rate,
-              EnvToDouble("TCMALLOC_RELEASE_RATE", 1.0),
-              "Rate at which we release unused memory to the system.  "
-              "Zero means we never release memory back to the system.  "
-              "Increase this flag to return memory faster; decrease it "
-              "to return memory slower.  Reasonable rates are in the "
-              "range [0,10]");
-
-DEFINE_int64(tcmalloc_heap_limit_mb,
-              EnvToInt("TCMALLOC_HEAP_LIMIT_MB", 0),
-              "Limit total size of the process heap to the "
-              "specified number of MiB. "
-              "When we approach the limit the memory is released "
-              "to the system more aggressively (more minor page faults). "
-              "Zero means to allocate as long as system allows.");
-
-namespace tcmalloc {
-
-PageHeap::PageHeap()
-    : pagemap_(MetaDataAlloc),
-      scavenge_counter_(0),
-      // Start scavenging at kMaxPages list
-      release_index_(kMaxPages),
-      aggressive_decommit_(false) {
-  COMPILE_ASSERT(kClassSizesMax <= (1 << PageMapCache::kValuebits), valuebits);
-  for (int i = 0; i < kMaxPages; i++) {
-    DLL_Init(&free_[i].normal);
-    DLL_Init(&free_[i].returned);
-  }
-}
-
-Span* PageHeap::SearchFreeAndLargeLists(Length n) {
-  ASSERT(Check());
-  ASSERT(n > 0);
-
-  // Find first size >= n that has a non-empty list
-  for (Length s = n; s <= kMaxPages; s++) {
-    Span* ll = &free_[s - 1].normal;
-    // If we're lucky, ll is non-empty, meaning it has a suitable span.
-    if (!DLL_IsEmpty(ll)) {
-      ASSERT(ll->next->location == Span::ON_NORMAL_FREELIST);
-      return Carve(ll->next, n);
-    }
-    // Alternatively, maybe there's a usable returned span.
-    ll = &free_[s - 1].returned;
-    if (!DLL_IsEmpty(ll)) {
-      // We did not call EnsureLimit before, to avoid releasing the span
-      // that will be taken immediately back.
-      // Calling EnsureLimit here is not very expensive, as it fails only if
-      // there is no more normal spans (and it fails efficiently)
-      // or SystemRelease does not work (there is probably no returned spans).
-      if (EnsureLimit(n)) {
-        // ll may have became empty due to coalescing
-        if (!DLL_IsEmpty(ll)) {
-          ASSERT(ll->next->location == Span::ON_RETURNED_FREELIST);
-          return Carve(ll->next, n);
-        }
-      }
-    }
-  }
-  // No luck in free lists, our last chance is in a larger class.
-  return AllocLarge(n);  // May be NULL
-}
-
-static const size_t kForcedCoalesceInterval = 128*1024*1024;
-
-Span* PageHeap::New(Length n) {
-  ASSERT(Check());
-  ASSERT(n > 0);
-
-  Span* result = SearchFreeAndLargeLists(n);
-  if (result != NULL)
-    return result;
-
-  if (stats_.free_bytes != 0 && stats_.unmapped_bytes != 0
-      && stats_.free_bytes + stats_.unmapped_bytes >= stats_.system_bytes / 4
-      && (stats_.system_bytes / kForcedCoalesceInterval
-          != (stats_.system_bytes + (n << kPageShift)) / kForcedCoalesceInterval)) {
-    // We're about to grow heap, but there are lots of free pages.
-    // tcmalloc's design decision to keep unmapped and free spans
-    // separately and never coalesce them means that sometimes there
-    // can be free pages span of sufficient size, but it consists of
-    // "segments" of different type so page heap search cannot find
-    // it. In order to prevent growing heap and wasting memory in such
-    // case we're going to unmap all free pages. So that all free
-    // spans are maximally coalesced.
-    //
-    // We're also limiting 'rate' of going into this path to be at
-    // most once per 128 megs of heap growth. Otherwise programs that
-    // grow heap frequently (and that means by small amount) could be
-    // penalized with higher count of minor page faults.
-    //
-    // See also large_heap_fragmentation_unittest.cc and
-    // https://code.google.com/p/gperftools/issues/detail?id=368
-    ReleaseAtLeastNPages(static_cast<Length>(0x7fffffff));
-
-    // then try again. If we are forced to grow heap because of large
-    // spans fragmentation and not because of problem described above,
-    // then at the very least we've just unmapped free but
-    // insufficiently big large spans back to OS. So in case of really
-    // unlucky memory fragmentation we'll be consuming virtual address
-    // space, but not real memory
-    result = SearchFreeAndLargeLists(n);
-    if (result != NULL) return result;
-  }
-
-  // Grow the heap and try again.
-  if (!GrowHeap(n)) {
-    ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
-    ASSERT(Check());
-    // underlying SysAllocator likely set ENOMEM but we can get here
-    // due to EnsureLimit so we set it here too.
-    //
-    // Setting errno to ENOMEM here allows us to avoid dealing with it
-    // in fast-path.
-    errno = ENOMEM;
-    return NULL;
-  }
-  return SearchFreeAndLargeLists(n);
-}
-
-Span* PageHeap::AllocLarge(Length n) {
-  Span *best = NULL;
-  Span *best_normal = NULL;
-
-  // Create a Span to use as an upper bound.
-  Span bound;
-  bound.start = 0;
-  bound.length = n;
-
-  // First search the NORMAL spans..
-  SpanSet::iterator place = large_normal_.upper_bound(SpanPtrWithLength(&bound));
-  if (place != large_normal_.end()) {
-    best = place->span;
-    best_normal = best;
-    ASSERT(best->location == Span::ON_NORMAL_FREELIST);
-  }
-
-  // Try to find better fit from RETURNED spans.
-  place = large_returned_.upper_bound(SpanPtrWithLength(&bound));
-  if (place != large_returned_.end()) {
-    Span *c = place->span;
-    ASSERT(c->location == Span::ON_RETURNED_FREELIST);
-    if (best_normal == NULL
-        || c->length < best->length
-        || (c->length == best->length && c->start < best->start))
-      best = place->span;
-  }
-
-  if (best == best_normal) {
-    return best == NULL ? NULL : Carve(best, n);
-  }
-
-  // best comes from RETURNED set.
-
-  if (EnsureLimit(n, false)) {
-    return Carve(best, n);
-  }
-
-  if (EnsureLimit(n, true)) {
-    // best could have been destroyed by coalescing.
-    // best_normal is not a best-fit, and it could be destroyed as well.
-    // We retry, the limit is already ensured:
-    return AllocLarge(n);
-  }
-
-  // If best_normal existed, EnsureLimit would succeeded:
-  ASSERT(best_normal == NULL);
-  // We are not allowed to take best from returned list.
-  return NULL;
-}
-
-Span* PageHeap::Split(Span* span, Length n) {
-  ASSERT(0 < n);
-  ASSERT(n < span->length);
-  ASSERT(span->location == Span::IN_USE);
-  ASSERT(span->sizeclass == 0);
-  Event(span, 'T', n);
-
-  const int extra = span->length - n;
-  Span* leftover = NewSpan(span->start + n, extra);
-  ASSERT(leftover->location == Span::IN_USE);
-  Event(leftover, 'U', extra);
-  RecordSpan(leftover);
-  pagemap_.set(span->start + n - 1, span); // Update map from pageid to span
-  span->length = n;
-
-  return leftover;
-}
-
-void PageHeap::CommitSpan(Span* span) {
-  ++stats_.commit_count;
-
-  TCMalloc_SystemCommit(reinterpret_cast<void*>(span->start << kPageShift),
-                        static_cast<size_t>(span->length << kPageShift));
-  stats_.committed_bytes += span->length << kPageShift;
-  stats_.total_commit_bytes += (span->length << kPageShift);
-}
-
-bool PageHeap::DecommitSpan(Span* span) {
-  ++stats_.decommit_count;
-
-  bool rv = TCMalloc_SystemRelease(reinterpret_cast<void*>(span->start << kPageShift),
-                                   static_cast<size_t>(span->length << kPageShift));
-  if (rv) {
-    stats_.committed_bytes -= span->length << kPageShift;
-    stats_.total_decommit_bytes += (span->length << kPageShift);
-  }
-
-  return rv;
-}
-
-Span* PageHeap::Carve(Span* span, Length n) {
-  ASSERT(n > 0);
-  ASSERT(span->location != Span::IN_USE);
-  const int old_location = span->location;
-  RemoveFromFreeList(span);
-  span->location = Span::IN_USE;
-  Event(span, 'A', n);
-
-  const int extra = span->length - n;
-  ASSERT(extra >= 0);
-  if (extra > 0) {
-    Span* leftover = NewSpan(span->start + n, extra);
-    leftover->location = old_location;
-    Event(leftover, 'S', extra);
-    RecordSpan(leftover);
-
-    // The previous span of |leftover| was just splitted -- no need to
-    // coalesce them. The next span of |leftover| was not previously coalesced
-    // with |span|, i.e. is NULL or has got location other than |old_location|.
-#ifndef NDEBUG
-    const PageID p = leftover->start;
-    const Length len = leftover->length;
-    Span* next = GetDescriptor(p+len);
-    ASSERT (next == NULL ||
-            next->location == Span::IN_USE ||
-            next->location != leftover->location);
-#endif
-
-    PrependToFreeList(leftover);  // Skip coalescing - no candidates possible
-    span->length = n;
-    pagemap_.set(span->start + n - 1, span);
-  }
-  ASSERT(Check());
-  if (old_location == Span::ON_RETURNED_FREELIST) {
-    // We need to recommit this address space.
-    CommitSpan(span);
-  }
-  ASSERT(span->location == Span::IN_USE);
-  ASSERT(span->length == n);
-  ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
-  return span;
-}
-
-void PageHeap::Delete(Span* span) {
-  ASSERT(Check());
-  ASSERT(span->location == Span::IN_USE);
-  ASSERT(span->length > 0);
-  ASSERT(GetDescriptor(span->start) == span);
-  ASSERT(GetDescriptor(span->start + span->length - 1) == span);
-  const Length n = span->length;
-  span->sizeclass = 0;
-  span->sample = 0;
-  span->location = Span::ON_NORMAL_FREELIST;
-  Event(span, 'D', span->length);
-  MergeIntoFreeList(span);  // Coalesces if possible
-  IncrementalScavenge(n);
-  ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
-  ASSERT(Check());
-}
-
-// Given span we're about to free and other span (still on free list),
-// checks if 'other' span is mergable with 'span'. If it is, removes
-// other span from free list, performs aggressive decommit if
-// necessary and returns 'other' span. Otherwise 'other' span cannot
-// be merged and is left untouched. In that case NULL is returned.
-Span* PageHeap::CheckAndHandlePreMerge(Span* span, Span* other) {
-  if (other == NULL) {
-    return other;
-  }
-  // if we're in aggressive decommit mode and span is decommitted,
-  // then we try to decommit adjacent span.
-  if (aggressive_decommit_ && other->location == Span::ON_NORMAL_FREELIST
-      && span->location == Span::ON_RETURNED_FREELIST) {
-    bool worked = DecommitSpan(other);
-    if (!worked) {
-      return NULL;
-    }
-  } else if (other->location != span->location) {
-    return NULL;
-  }
-
-  RemoveFromFreeList(other);
-  return other;
-}
-
-void PageHeap::MergeIntoFreeList(Span* span) {
-  ASSERT(span->location != Span::IN_USE);
-
-  // Coalesce -- we guarantee that "p" != 0, so no bounds checking
-  // necessary.  We do not bother resetting the stale pagemap
-  // entries for the pieces we are merging together because we only
-  // care about the pagemap entries for the boundaries.
-  //
-  // Note: depending on aggressive_decommit_ mode we allow only
-  // similar spans to be coalesced.
-  //
-  // The following applies if aggressive_decommit_ is enabled:
-  //
-  // TODO(jar): "Always decommit" causes some extra calls to commit when we are
-  // called in GrowHeap() during an allocation :-/.  We need to eval the cost of
-  // that oscillation, and possibly do something to reduce it.
-
-  // TODO(jar): We need a better strategy for deciding to commit, or decommit,
-  // based on memory usage and free heap sizes.
-
-  const PageID p = span->start;
-  const Length n = span->length;
-
-  if (aggressive_decommit_ && span->location == Span::ON_NORMAL_FREELIST) {
-    if (DecommitSpan(span)) {
-      span->location = Span::ON_RETURNED_FREELIST;
-    }
-  }
-
-  Span* prev = CheckAndHandlePreMerge(span, GetDescriptor(p-1));
-  if (prev != NULL) {
-    // Merge preceding span into this span
-    ASSERT(prev->start + prev->length == p);
-    const Length len = prev->length;
-    DeleteSpan(prev);
-    span->start -= len;
-    span->length += len;
-    pagemap_.set(span->start, span);
-    Event(span, 'L', len);
-  }
-  Span* next = CheckAndHandlePreMerge(span, GetDescriptor(p+n));
-  if (next != NULL) {
-    // Merge next span into this span
-    ASSERT(next->start == p+n);
-    const Length len = next->length;
-    DeleteSpan(next);
-    span->length += len;
-    pagemap_.set(span->start + span->length - 1, span);
-    Event(span, 'R', len);
-  }
-
-  PrependToFreeList(span);
-}
-
-void PageHeap::PrependToFreeList(Span* span) {
-  ASSERT(span->location != Span::IN_USE);
-  if (span->location == Span::ON_NORMAL_FREELIST)
-    stats_.free_bytes += (span->length << kPageShift);
-  else
-    stats_.unmapped_bytes += (span->length << kPageShift);
-
-  if (span->length > kMaxPages) {
-    SpanSet *set = &large_normal_;
-    if (span->location == Span::ON_RETURNED_FREELIST)
-      set = &large_returned_;
-    std::pair<SpanSet::iterator, bool> p =
-        set->insert(SpanPtrWithLength(span));
-    ASSERT(p.second); // We never have duplicates since span->start is unique.
-    span->SetSpanSetIterator(p.first);
-    return;
-  }
-
-  SpanList* list = &free_[span->length - 1];
-  if (span->location == Span::ON_NORMAL_FREELIST) {
-    DLL_Prepend(&list->normal, span);
-  } else {
-    DLL_Prepend(&list->returned, span);
-  }
-}
-
-void PageHeap::RemoveFromFreeList(Span* span) {
-  ASSERT(span->location != Span::IN_USE);
-  if (span->location == Span::ON_NORMAL_FREELIST) {
-    stats_.free_bytes -= (span->length << kPageShift);
-  } else {
-    stats_.unmapped_bytes -= (span->length << kPageShift);
-  }
-  if (span->length > kMaxPages) {
-    SpanSet *set = &large_normal_;
-    if (span->location == Span::ON_RETURNED_FREELIST)
-      set = &large_returned_;
-    SpanSet::iterator iter = span->ExtractSpanSetIterator();
-    ASSERT(iter->span == span);
-    ASSERT(set->find(SpanPtrWithLength(span)) == iter);
-    set->erase(iter);
-  } else {
-    DLL_Remove(span);
-  }
-}
-
-void PageHeap::IncrementalScavenge(Length n) {
-  // Fast path; not yet time to release memory
-  scavenge_counter_ -= n;
-  if (scavenge_counter_ >= 0) return;  // Not yet time to scavenge
-
-  const double rate = FLAGS_tcmalloc_release_rate;
-  if (rate <= 1e-6) {
-    // Tiny release rate means that releasing is disabled.
-    scavenge_counter_ = kDefaultReleaseDelay;
-    return;
-  }
-
-  ++stats_.scavenge_count;
-
-  Length released_pages = ReleaseAtLeastNPages(1);
-
-  if (released_pages == 0) {
-    // Nothing to scavenge, delay for a while.
-    scavenge_counter_ = kDefaultReleaseDelay;
-  } else {
-    // Compute how long to wait until we return memory.
-    // FLAGS_tcmalloc_release_rate==1 means wait for 1000 pages
-    // after releasing one page.
-    const double mult = 1000.0 / rate;
-    double wait = mult * static_cast<double>(released_pages);
-    if (wait > kMaxReleaseDelay) {
-      // Avoid overflow and bound to reasonable range.
-      wait = kMaxReleaseDelay;
-    }
-    scavenge_counter_ = static_cast<int64_t>(wait);
-  }
-}
-
-Length PageHeap::ReleaseSpan(Span* s) {
-  ASSERT(s->location == Span::ON_NORMAL_FREELIST);
-
-  if (DecommitSpan(s)) {
-    RemoveFromFreeList(s);
-    const Length n = s->length;
-    s->location = Span::ON_RETURNED_FREELIST;
-    MergeIntoFreeList(s);  // Coalesces if possible.
-    return n;
-  }
-
-  return 0;
-}
-
-Length PageHeap::ReleaseAtLeastNPages(Length num_pages) {
-  Length released_pages = 0;
-
-  // Round robin through the lists of free spans, releasing a
-  // span from each list.  Stop after releasing at least num_pages
-  // or when there is nothing more to release.
-  while (released_pages < num_pages && stats_.free_bytes > 0) {
-    for (int i = 0; i < kMaxPages+1 && released_pages < num_pages;
-         i++, release_index_++) {
-      Span *s;
-      if (release_index_ > kMaxPages) release_index_ = 0;
-
-      if (release_index_ == kMaxPages) {
-        if (large_normal_.empty()) {
-          continue;
-        }
-        s = (large_normal_.begin())->span;
-      } else {
-        SpanList* slist = &free_[release_index_];
-        if (DLL_IsEmpty(&slist->normal)) {
-          continue;
-        }
-        s = slist->normal.prev;
-      }
-      // TODO(todd) if the remaining number of pages to release
-      // is significantly smaller than s->length, and s is on the
-      // large freelist, should we carve s instead of releasing?
-      // the whole thing?
-      Length released_len = ReleaseSpan(s);
-      // Some systems do not support release
-      if (released_len == 0) return released_pages;
-      released_pages += released_len;
-    }
-  }
-  return released_pages;
-}
-
-bool PageHeap::EnsureLimit(Length n, bool withRelease)
-{
-  Length limit = (FLAGS_tcmalloc_heap_limit_mb*1024*1024) >> kPageShift;
-  if (limit == 0) return true; //there is no limit
-
-  // We do not use stats_.system_bytes because it does not take
-  // MetaDataAllocs into account.
-  Length takenPages = TCMalloc_SystemTaken >> kPageShift;
-  //XXX takenPages may be slightly bigger than limit for two reasons:
-  //* MetaDataAllocs ignore the limit (it is not easy to handle
-  //  out of memory there)
-  //* sys_alloc may round allocation up to huge page size,
-  //  although smaller limit was ensured
-
-  ASSERT(takenPages >= stats_.unmapped_bytes >> kPageShift);
-  takenPages -= stats_.unmapped_bytes >> kPageShift;
-
-  if (takenPages + n > limit && withRelease) {
-    takenPages -= ReleaseAtLeastNPages(takenPages + n - limit);
-  }
-
-  return takenPages + n <= limit;
-}
-
-void PageHeap::RegisterSizeClass(Span* span, uint32 sc) {
-  // Associate span object with all interior pages as well
-  ASSERT(span->location == Span::IN_USE);
-  ASSERT(GetDescriptor(span->start) == span);
-  ASSERT(GetDescriptor(span->start+span->length-1) == span);
-  Event(span, 'C', sc);
-  span->sizeclass = sc;
-  for (Length i = 1; i < span->length-1; i++) {
-    pagemap_.set(span->start+i, span);
-  }
-}
-
-void PageHeap::GetSmallSpanStats(SmallSpanStats* result) {
-  for (int i = 0; i < kMaxPages; i++) {
-    result->normal_length[i] = DLL_Length(&free_[i].normal);
-    result->returned_length[i] = DLL_Length(&free_[i].returned);
-  }
-}
-
-void PageHeap::GetLargeSpanStats(LargeSpanStats* result) {
-  result->spans = 0;
-  result->normal_pages = 0;
-  result->returned_pages = 0;
-  for (SpanSet::iterator it = large_normal_.begin(); it != large_normal_.end(); ++it) {
-    result->normal_pages += it->length;
-    result->spans++;
-  }
-  for (SpanSet::iterator it = large_returned_.begin(); it != large_returned_.end(); ++it) {
-    result->returned_pages += it->length;
-    result->spans++;
-  }
-}
-
-bool PageHeap::GetNextRange(PageID start, base::MallocRange* r) {
-  Span* span = reinterpret_cast<Span*>(pagemap_.Next(start));
-  if (span == NULL) {
-    return false;
-  }
-  r->address = span->start << kPageShift;
-  r->length = span->length << kPageShift;
-  r->fraction = 0;
-  switch (span->location) {
-    case Span::IN_USE:
-      r->type = base::MallocRange::INUSE;
-      r->fraction = 1;
-      if (span->sizeclass > 0) {
-        // Only some of the objects in this span may be in use.
-        const size_t osize = Static::sizemap()->class_to_size(span->sizeclass);
-        r->fraction = (1.0 * osize * span->refcount) / r->length;
-      }
-      break;
-    case Span::ON_NORMAL_FREELIST:
-      r->type = base::MallocRange::FREE;
-      break;
-    case Span::ON_RETURNED_FREELIST:
-      r->type = base::MallocRange::UNMAPPED;
-      break;
-    default:
-      r->type = base::MallocRange::UNKNOWN;
-      break;
-  }
-  return true;
-}
-
-static void RecordGrowth(size_t growth) {
-  StackTrace* t = Static::stacktrace_allocator()->New();
-  t->depth = GetStackTrace(t->stack, kMaxStackDepth-1, 3);
-  t->size = growth;
-  t->stack[kMaxStackDepth-1] = reinterpret_cast<void*>(Static::growth_stacks());
-  Static::set_growth_stacks(t);
-}
-
-bool PageHeap::GrowHeap(Length n) {
-  ASSERT(kMaxPages >= kMinSystemAlloc);
-  if (n > kMaxValidPages) return false;
-  Length ask = (n>kMinSystemAlloc) ? n : static_cast<Length>(kMinSystemAlloc);
-  size_t actual_size;
-  void* ptr = NULL;
-  if (EnsureLimit(ask)) {
-      ptr = TCMalloc_SystemAlloc(ask << kPageShift, &actual_size, kPageSize);
-  }
-  if (ptr == NULL) {
-    if (n < ask) {
-      // Try growing just "n" pages
-      ask = n;
-      if (EnsureLimit(ask)) {
-        ptr = TCMalloc_SystemAlloc(ask << kPageShift, &actual_size, kPageSize);
-      }
-    }
-    if (ptr == NULL) return false;
-  }
-  ask = actual_size >> kPageShift;
-  RecordGrowth(ask << kPageShift);
-
-  ++stats_.reserve_count;
-  ++stats_.commit_count;
-
-  uint64_t old_system_bytes = stats_.system_bytes;
-  stats_.system_bytes += (ask << kPageShift);
-  stats_.committed_bytes += (ask << kPageShift);
-
-  stats_.total_commit_bytes += (ask << kPageShift);
-  stats_.total_reserve_bytes += (ask << kPageShift);
-
-  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-  ASSERT(p > 0);
-
-  // If we have already a lot of pages allocated, just pre allocate a bunch of
-  // memory for the page map. This prevents fragmentation by pagemap metadata
-  // when a program keeps allocating and freeing large blocks.
-
-  if (old_system_bytes < kPageMapBigAllocationThreshold
-      && stats_.system_bytes >= kPageMapBigAllocationThreshold) {
-    pagemap_.PreallocateMoreMemory();
-  }
-
-  // Make sure pagemap_ has entries for all of the new pages.
-  // Plus ensure one before and one after so coalescing code
-  // does not need bounds-checking.
-  if (pagemap_.Ensure(p-1, ask+2)) {
-    // Pretend the new area is allocated and then Delete() it to cause
-    // any necessary coalescing to occur.
-    Span* span = NewSpan(p, ask);
-    RecordSpan(span);
-    Delete(span);
-    ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
-    ASSERT(Check());
-    return true;
-  } else {
-    // We could not allocate memory within "pagemap_"
-    // TODO: Once we can return memory to the system, return the new span
-    return false;
-  }
-}
-
-bool PageHeap::Check() {
-  return true;
-}
-
-bool PageHeap::CheckExpensive() {
-  bool result = Check();
-  CheckSet(&large_normal_, kMaxPages + 1, Span::ON_NORMAL_FREELIST);
-  CheckSet(&large_returned_, kMaxPages + 1, Span::ON_RETURNED_FREELIST);
-  for (int s = 1; s <= kMaxPages; s++) {
-    CheckList(&free_[s - 1].normal, s, s, Span::ON_NORMAL_FREELIST);
-    CheckList(&free_[s - 1].returned, s, s, Span::ON_RETURNED_FREELIST);
-  }
-  return result;
-}
-
-bool PageHeap::CheckList(Span* list, Length min_pages, Length max_pages,
-                         int freelist) {
-  for (Span* s = list->next; s != list; s = s->next) {
-    CHECK_CONDITION(s->location == freelist);  // NORMAL or RETURNED
-    CHECK_CONDITION(s->length >= min_pages);
-    CHECK_CONDITION(s->length <= max_pages);
-    CHECK_CONDITION(GetDescriptor(s->start) == s);
-    CHECK_CONDITION(GetDescriptor(s->start+s->length-1) == s);
-  }
-  return true;
-}
-
-bool PageHeap::CheckSet(SpanSet* spanset, Length min_pages,int freelist) {
-  for (SpanSet::iterator it = spanset->begin(); it != spanset->end(); ++it) {
-    Span* s = it->span;
-    CHECK_CONDITION(s->length == it->length);
-    CHECK_CONDITION(s->location == freelist);  // NORMAL or RETURNED
-    CHECK_CONDITION(s->length >= min_pages);
-    CHECK_CONDITION(GetDescriptor(s->start) == s);
-    CHECK_CONDITION(GetDescriptor(s->start+s->length-1) == s);
-  }
-  return true;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/vendor/src/page_heap.h b/third_party/tcmalloc/vendor/src/page_heap.h
deleted file mode 100644
index bf50394..0000000
--- a/third_party/tcmalloc/vendor/src/page_heap.h
+++ /dev/null
@@ -1,358 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#ifndef TCMALLOC_PAGE_HEAP_H_
-#define TCMALLOC_PAGE_HEAP_H_
-
-#include <config.h>
-#include <stddef.h>                     // for size_t
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uint64_t, int64_t, uint16_t
-#endif
-#include <gperftools/malloc_extension.h>
-#include "base/basictypes.h"
-#include "common.h"
-#include "packed-cache-inl.h"
-#include "pagemap.h"
-#include "span.h"
-
-// We need to dllexport PageHeap just for the unittest.  MSVC complains
-// that we don't dllexport the PageHeap members, but we don't need to
-// test those, so I just suppress this warning.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4251)
-#endif
-
-// This #ifdef should almost never be set.  Set NO_TCMALLOC_SAMPLES if
-// you're porting to a system where you really can't get a stacktrace.
-// Because we control the definition of GetStackTrace, all clients of
-// GetStackTrace should #include us rather than stacktrace.h.
-#ifdef NO_TCMALLOC_SAMPLES
-  // We use #define so code compiles even if you #include stacktrace.h somehow.
-# define GetStackTrace(stack, depth, skip)  (0)
-#else
-# include <gperftools/stacktrace.h>
-#endif
-
-namespace base {
-struct MallocRange;
-}
-
-namespace tcmalloc {
-
-// -------------------------------------------------------------------------
-// Map from page-id to per-page data
-// -------------------------------------------------------------------------
-
-// We use PageMap2<> for 32-bit and PageMap3<> for 64-bit machines.
-// We also use a simple one-level cache for hot PageID-to-sizeclass mappings,
-// because sometimes the sizeclass is all the information we need.
-
-// Selector class -- general selector uses 3-level map
-template <int BITS> class MapSelector {
- public:
-  typedef TCMalloc_PageMap3<BITS-kPageShift> Type;
-};
-
-#ifndef TCMALLOC_SMALL_BUT_SLOW
-// x86-64 and arm64 are using 48 bits of address space. So we can use
-// just two level map, but since initial ram consumption of this mode
-// is a bit on the higher side, we opt-out of it in
-// TCMALLOC_SMALL_BUT_SLOW mode.
-template <> class MapSelector<48> {
- public:
-  typedef TCMalloc_PageMap2<48-kPageShift> Type;
-};
-
-#endif // TCMALLOC_SMALL_BUT_SLOW
-
-// A two-level map for 32-bit machines
-template <> class MapSelector<32> {
- public:
-  typedef TCMalloc_PageMap2<32-kPageShift> Type;
-};
-
-// -------------------------------------------------------------------------
-// Page-level allocator
-//  * Eager coalescing
-//
-// Heap for page-level allocation.  We allow allocating and freeing a
-// contiguous runs of pages (called a "span").
-// -------------------------------------------------------------------------
-
-class PERFTOOLS_DLL_DECL PageHeap {
- public:
-  PageHeap();
-
-  // Allocate a run of "n" pages.  Returns zero if out of memory.
-  // Caller should not pass "n == 0" -- instead, n should have
-  // been rounded up already.
-  Span* New(Length n);
-
-  // Delete the span "[p, p+n-1]".
-  // REQUIRES: span was returned by earlier call to New() and
-  //           has not yet been deleted.
-  void Delete(Span* span);
-
-  // Mark an allocated span as being used for small objects of the
-  // specified size-class.
-  // REQUIRES: span was returned by an earlier call to New()
-  //           and has not yet been deleted.
-  void RegisterSizeClass(Span* span, uint32 sc);
-
-  // Split an allocated span into two spans: one of length "n" pages
-  // followed by another span of length "span->length - n" pages.
-  // Modifies "*span" to point to the first span of length "n" pages.
-  // Returns a pointer to the second span.
-  //
-  // REQUIRES: "0 < n < span->length"
-  // REQUIRES: span->location == IN_USE
-  // REQUIRES: span->sizeclass == 0
-  Span* Split(Span* span, Length n);
-
-  // Return the descriptor for the specified page.  Returns NULL if
-  // this PageID was not allocated previously.
-  inline ATTRIBUTE_ALWAYS_INLINE
-  Span* GetDescriptor(PageID p) const {
-    return reinterpret_cast<Span*>(pagemap_.get(p));
-  }
-
-  // If this page heap is managing a range with starting page # >= start,
-  // store info about the range in *r and return true.  Else return false.
-  bool GetNextRange(PageID start, base::MallocRange* r);
-
-  // Page heap statistics
-  struct Stats {
-    Stats() : system_bytes(0), free_bytes(0), unmapped_bytes(0), committed_bytes(0),
-        scavenge_count(0), commit_count(0), total_commit_bytes(0),
-        decommit_count(0), total_decommit_bytes(0),
-        reserve_count(0), total_reserve_bytes(0) {}
-    uint64_t system_bytes;    // Total bytes allocated from system
-    uint64_t free_bytes;      // Total bytes on normal freelists
-    uint64_t unmapped_bytes;  // Total bytes on returned freelists
-    uint64_t committed_bytes;  // Bytes committed, always <= system_bytes_.
-
-    uint64_t scavenge_count;   // Number of times scavagened flush pages
-
-    uint64_t commit_count;          // Number of virtual memory commits
-    uint64_t total_commit_bytes;    // Bytes committed in lifetime of process
-    uint64_t decommit_count;        // Number of virtual memory decommits
-    uint64_t total_decommit_bytes;  // Bytes decommitted in lifetime of process
-
-    uint64_t reserve_count;         // Number of virtual memory reserves
-    uint64_t total_reserve_bytes;   // Bytes reserved in lifetime of process
-  };
-  inline Stats stats() const { return stats_; }
-
-  struct SmallSpanStats {
-    // For each free list of small spans, the length (in spans) of the
-    // normal and returned free lists for that size.
-    //
-    // NOTE: index 'i' accounts the number of spans of length 'i + 1'.
-    int64 normal_length[kMaxPages];
-    int64 returned_length[kMaxPages];
-  };
-  void GetSmallSpanStats(SmallSpanStats* result);
-
-  // Stats for free large spans (i.e., spans with more than kMaxPages pages).
-  struct LargeSpanStats {
-    int64 spans;           // Number of such spans
-    int64 normal_pages;    // Combined page length of normal large spans
-    int64 returned_pages;  // Combined page length of unmapped spans
-  };
-  void GetLargeSpanStats(LargeSpanStats* result);
-
-  bool Check();
-  // Like Check() but does some more comprehensive checking.
-  bool CheckExpensive();
-  bool CheckList(Span* list, Length min_pages, Length max_pages,
-                 int freelist);  // ON_NORMAL_FREELIST or ON_RETURNED_FREELIST
-  bool CheckSet(SpanSet *s, Length min_pages, int freelist);
-
-  // Try to release at least num_pages for reuse by the OS.  Returns
-  // the actual number of pages released, which may be less than
-  // num_pages if there weren't enough pages to release. The result
-  // may also be larger than num_pages since page_heap might decide to
-  // release one large range instead of fragmenting it into two
-  // smaller released and unreleased ranges.
-  Length ReleaseAtLeastNPages(Length num_pages);
-
-  // Reads and writes to pagemap_cache_ do not require locking.
-  bool TryGetSizeClass(PageID p, uint32* out) const {
-    return pagemap_cache_.TryGet(p, out);
-  }
-  void SetCachedSizeClass(PageID p, uint32 cl) {
-    ASSERT(cl != 0);
-    pagemap_cache_.Put(p, cl);
-  }
-  void InvalidateCachedSizeClass(PageID p) { pagemap_cache_.Invalidate(p); }
-  uint32 GetSizeClassOrZero(PageID p) const {
-    uint32 cached_value;
-    if (!TryGetSizeClass(p, &cached_value)) {
-      cached_value = 0;
-    }
-    return cached_value;
-  }
-
-  bool GetAggressiveDecommit(void) {return aggressive_decommit_;}
-  void SetAggressiveDecommit(bool aggressive_decommit) {
-    aggressive_decommit_ = aggressive_decommit;
-  }
-
- private:
-  // Allocates a big block of memory for the pagemap once we reach more than
-  // 128MB
-  static const size_t kPageMapBigAllocationThreshold = 128 << 20;
-
-  // Minimum number of pages to fetch from system at a time.  Must be
-  // significantly bigger than kBlockSize to amortize system-call
-  // overhead, and also to reduce external fragementation.  Also, we
-  // should keep this value big because various incarnations of Linux
-  // have small limits on the number of mmap() regions per
-  // address-space.
-  // REQUIRED: kMinSystemAlloc <= kMaxPages;
-  static const int kMinSystemAlloc = kMaxPages;
-
-  // Never delay scavenging for more than the following number of
-  // deallocated pages.  With 4K pages, this comes to 4GB of
-  // deallocation.
-  static const int kMaxReleaseDelay = 1 << 20;
-
-  // If there is nothing to release, wait for so many pages before
-  // scavenging again.  With 4K pages, this comes to 1GB of memory.
-  static const int kDefaultReleaseDelay = 1 << 18;
-
-  // Pick the appropriate map and cache types based on pointer size
-  typedef MapSelector<kAddressBits>::Type PageMap;
-  typedef PackedCache<kAddressBits - kPageShift> PageMapCache;
-  mutable PageMapCache pagemap_cache_;
-  PageMap pagemap_;
-
-  // We segregate spans of a given size into two circular linked
-  // lists: one for normal spans, and one for spans whose memory
-  // has been returned to the system.
-  struct SpanList {
-    Span        normal;
-    Span        returned;
-  };
-
-  // Sets of spans with length > kMaxPages.
-  //
-  // Rather than using a linked list, we use sets here for efficient
-  // best-fit search.
-  SpanSet large_normal_;
-  SpanSet large_returned_;
-
-  // Array mapping from span length to a doubly linked list of free spans
-  //
-  // NOTE: index 'i' stores spans of length 'i + 1'.
-  SpanList free_[kMaxPages];
-
-  // Statistics on system, free, and unmapped bytes
-  Stats stats_;
-
-  Span* SearchFreeAndLargeLists(Length n);
-
-  bool GrowHeap(Length n);
-
-  // REQUIRES: span->length >= n
-  // REQUIRES: span->location != IN_USE
-  // Remove span from its free list, and move any leftover part of
-  // span into appropriate free lists.  Also update "span" to have
-  // length exactly "n" and mark it as non-free so it can be returned
-  // to the client.  After all that, decrease free_pages_ by n and
-  // return span.
-  Span* Carve(Span* span, Length n);
-
-  void RecordSpan(Span* span) {
-    pagemap_.set(span->start, span);
-    if (span->length > 1) {
-      pagemap_.set(span->start + span->length - 1, span);
-    }
-  }
-
-  // Allocate a large span of length == n.  If successful, returns a
-  // span of exactly the specified length.  Else, returns NULL.
-  Span* AllocLarge(Length n);
-
-  // Coalesce span with neighboring spans if possible, prepend to
-  // appropriate free list, and adjust stats.
-  void MergeIntoFreeList(Span* span);
-
-  // Commit the span.
-  void CommitSpan(Span* span);
-
-  // Decommit the span.
-  bool DecommitSpan(Span* span);
-
-  // Prepends span to appropriate free list, and adjusts stats.
-  void PrependToFreeList(Span* span);
-
-  // Removes span from its free list, and adjust stats.
-  void RemoveFromFreeList(Span* span);
-
-  // Incrementally release some memory to the system.
-  // IncrementalScavenge(n) is called whenever n pages are freed.
-  void IncrementalScavenge(Length n);
-
-  // Attempts to decommit 's' and move it to the returned freelist.
-  //
-  // Returns the length of the Span or zero if release failed.
-  //
-  // REQUIRES: 's' must be on the NORMAL freelist.
-  Length ReleaseSpan(Span *s);
-
-  // Checks if we are allowed to take more memory from the system.
-  // If limit is reached and allowRelease is true, tries to release
-  // some unused spans.
-  bool EnsureLimit(Length n, bool allowRelease = true);
-
-  Span* CheckAndHandlePreMerge(Span *span, Span *other);
-
-  // Number of pages to deallocate before doing more scavenging
-  int64_t scavenge_counter_;
-
-  // Index of last free list where we released memory to the OS.
-  int release_index_;
-
-  bool aggressive_decommit_;
-};
-
-}  // namespace tcmalloc
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-#endif  // TCMALLOC_PAGE_HEAP_H_
diff --git a/third_party/tcmalloc/vendor/src/page_heap_allocator.h b/third_party/tcmalloc/vendor/src/page_heap_allocator.h
deleted file mode 100644
index 3fecabde..0000000
--- a/third_party/tcmalloc/vendor/src/page_heap_allocator.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#ifndef TCMALLOC_PAGE_HEAP_ALLOCATOR_H_
-#define TCMALLOC_PAGE_HEAP_ALLOCATOR_H_
-
-#include <stddef.h>                     // for NULL, size_t
-
-#include "common.h"            // for MetaDataAlloc
-#include "internal_logging.h"  // for ASSERT
-
-namespace tcmalloc {
-
-// Simple allocator for objects of a specified type.  External locking
-// is required before accessing one of these objects.
-template <class T>
-class PageHeapAllocator {
- public:
-  // We use an explicit Init function because these variables are statically
-  // allocated and their constructors might not have run by the time some
-  // other static variable tries to allocate memory.
-  void Init() {
-    ASSERT(sizeof(T) <= kAllocIncrement);
-    inuse_ = 0;
-    free_area_ = NULL;
-    free_avail_ = 0;
-    free_list_ = NULL;
-    // Reserve some space at the beginning to avoid fragmentation.
-    Delete(New());
-  }
-
-  T* New() {
-    // Consult free list
-    void* result;
-    if (free_list_ != NULL) {
-      result = free_list_;
-      free_list_ = *(reinterpret_cast<void**>(result));
-    } else {
-      if (free_avail_ < sizeof(T)) {
-        // Need more room. We assume that MetaDataAlloc returns
-        // suitably aligned memory.
-        free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));
-        if (free_area_ == NULL) {
-          Log(kCrash, __FILE__, __LINE__,
-              "FATAL ERROR: Out of memory trying to allocate internal "
-              "tcmalloc data (bytes, object-size)",
-              kAllocIncrement, sizeof(T));
-        }
-        free_avail_ = kAllocIncrement;
-      }
-      result = free_area_;
-      free_area_ += sizeof(T);
-      free_avail_ -= sizeof(T);
-    }
-    inuse_++;
-    return reinterpret_cast<T*>(result);
-  }
-
-  void Delete(T* p) {
-    *(reinterpret_cast<void**>(p)) = free_list_;
-    free_list_ = p;
-    inuse_--;
-  }
-
-  int inuse() const { return inuse_; }
-
- private:
-  // How much to allocate from system at a time
-  static const int kAllocIncrement = 128 << 10;
-
-  // Free area from which to carve new objects
-  char* free_area_;
-  size_t free_avail_;
-
-  // Free list of already carved objects
-  void* free_list_;
-
-  // Number of allocated but unfreed objects
-  int inuse_;
-};
-
-// STL-compatible allocator which forwards allocations to a PageHeapAllocator.
-//
-// Like PageHeapAllocator, this requires external synchronization. To avoid multiple
-// separate STLPageHeapAllocator<T> from sharing the same underlying PageHeapAllocator<T>,
-// the |LockingTag| template argument should be used. Template instantiations with
-// different locking tags can safely be used concurrently.
-template <typename T, class LockingTag>
-class STLPageHeapAllocator {
- public:
-  typedef size_t     size_type;
-  typedef ptrdiff_t  difference_type;
-  typedef T*         pointer;
-  typedef const T*   const_pointer;
-  typedef T&         reference;
-  typedef const T&   const_reference;
-  typedef T          value_type;
-
-  template <class T1> struct rebind {
-    typedef STLPageHeapAllocator<T1, LockingTag> other;
-  };
-
-  STLPageHeapAllocator() { }
-  STLPageHeapAllocator(const STLPageHeapAllocator&) { }
-  template <class T1> STLPageHeapAllocator(const STLPageHeapAllocator<T1, LockingTag>&) { }
-  ~STLPageHeapAllocator() { }
-
-  pointer address(reference x) const { return &x; }
-  const_pointer address(const_reference x) const { return &x; }
-
-  size_type max_size() const { return size_t(-1) / sizeof(T); }
-
-  void construct(pointer p, const T& val) { ::new(p) T(val); }
-  void construct(pointer p) { ::new(p) T(); }
-  void destroy(pointer p) { p->~T(); }
-
-  // There's no state, so these allocators are always equal
-  bool operator==(const STLPageHeapAllocator&) const { return true; }
-  bool operator!=(const STLPageHeapAllocator&) const { return false; }
-
-  pointer allocate(size_type n, const void* = 0) {
-    if (!underlying_.initialized) {
-      underlying_.allocator.Init();
-      underlying_.initialized = true;
-    }
-
-    CHECK_CONDITION(n == 1);
-    return underlying_.allocator.New();
-  }
-  void deallocate(pointer p, size_type n) {
-    CHECK_CONDITION(n == 1);
-    underlying_.allocator.Delete(p);
-  }
-
- private:
-  struct Storage {
-    explicit Storage(base::LinkerInitialized x) {}
-    PageHeapAllocator<T> allocator;
-    bool initialized;
-  };
-  static Storage underlying_;
-};
-
-template<typename T, class LockingTag>
-typename STLPageHeapAllocator<T, LockingTag>::Storage STLPageHeapAllocator<T, LockingTag>::underlying_(base::LINKER_INITIALIZED);
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_PAGE_HEAP_ALLOCATOR_H_
diff --git a/third_party/tcmalloc/vendor/src/pagemap.h b/third_party/tcmalloc/vendor/src/pagemap.h
deleted file mode 100644
index 68b2d24c..0000000
--- a/third_party/tcmalloc/vendor/src/pagemap.h
+++ /dev/null
@@ -1,328 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// A data structure used by the caching malloc.  It maps from page# to
-// a pointer that contains info about that page.  We use two
-// representations: one for 32-bit addresses, and another for 64 bit
-// addresses.  Both representations provide the same interface.  The
-// first representation is implemented as a flat array, the seconds as
-// a three-level radix tree that strips away approximately 1/3rd of
-// the bits every time.
-//
-// The BITS parameter should be the number of bits required to hold
-// a page number.  E.g., with 32 bit pointers and 4K pages (i.e.,
-// page offset fits in lower 12 bits), BITS == 20.
-
-#ifndef TCMALLOC_PAGEMAP_H_
-#define TCMALLOC_PAGEMAP_H_
-
-#include "config.h"
-
-#include <stddef.h>                     // for NULL, size_t
-#include <string.h>                     // for memset
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-#include "internal_logging.h"  // for ASSERT
-
-// Single-level array
-template <int BITS>
-class TCMalloc_PageMap1 {
- private:
-  static const int LENGTH = 1 << BITS;
-
-  void** array_;
-
- public:
-  typedef uintptr_t Number;
-
-  explicit TCMalloc_PageMap1(void* (*allocator)(size_t)) {
-    array_ = reinterpret_cast<void**>((*allocator)(sizeof(void*) << BITS));
-    memset(array_, 0, sizeof(void*) << BITS);
-  }
-
-  // Ensure that the map contains initialized entries "x .. x+n-1".
-  // Returns true if successful, false if we could not allocate memory.
-  bool Ensure(Number x, size_t n) {
-    // Nothing to do since flat array was allocated at start.  All
-    // that's left is to check for overflow (that is, we don't want to
-    // ensure a number y where array_[y] would be an out-of-bounds
-    // access).
-    return n <= LENGTH - x;   // an overflow-free way to do "x + n <= LENGTH"
-  }
-
-  void PreallocateMoreMemory() {}
-
-  // Return the current value for KEY.  Returns NULL if not yet set,
-  // or if k is out of range.
-  ATTRIBUTE_ALWAYS_INLINE
-  void* get(Number k) const {
-    if ((k >> BITS) > 0) {
-      return NULL;
-    }
-    return array_[k];
-  }
-
-  // REQUIRES "k" is in range "[0,2^BITS-1]".
-  // REQUIRES "k" has been ensured before.
-  //
-  // Sets the value 'v' for key 'k'.
-  void set(Number k, void* v) {
-    array_[k] = v;
-  }
-
-  // Return the first non-NULL pointer found in this map for
-  // a page number >= k.  Returns NULL if no such number is found.
-  void* Next(Number k) const {
-    while (k < (1 << BITS)) {
-      if (array_[k] != NULL) return array_[k];
-      k++;
-    }
-    return NULL;
-  }
-};
-
-// Two-level radix tree
-template <int BITS>
-class TCMalloc_PageMap2 {
- private:
-  static const int LEAF_BITS = (BITS + 1) / 2;
-  static const int LEAF_LENGTH = 1 << LEAF_BITS;
-
-  static const int ROOT_BITS = BITS - LEAF_BITS;
-  static const int ROOT_LENGTH = 1 << ROOT_BITS;
-
-  // Leaf node
-  struct Leaf {
-    void* values[LEAF_LENGTH];
-  };
-
-  Leaf* root_[ROOT_LENGTH];             // Pointers to child nodes
-  void* (*allocator_)(size_t);          // Memory allocator
-
- public:
-  typedef uintptr_t Number;
-
-  explicit TCMalloc_PageMap2(void* (*allocator)(size_t)) {
-    allocator_ = allocator;
-    memset(root_, 0, sizeof(root_));
-  }
-
-  ATTRIBUTE_ALWAYS_INLINE
-  void* get(Number k) const {
-    const Number i1 = k >> LEAF_BITS;
-    const Number i2 = k & (LEAF_LENGTH-1);
-    if ((k >> BITS) > 0 || root_[i1] == NULL) {
-      return NULL;
-    }
-    return root_[i1]->values[i2];
-  }
-
-  void set(Number k, void* v) {
-    const Number i1 = k >> LEAF_BITS;
-    const Number i2 = k & (LEAF_LENGTH-1);
-    ASSERT(i1 < ROOT_LENGTH);
-    root_[i1]->values[i2] = v;
-  }
-
-  bool Ensure(Number start, size_t n) {
-    for (Number key = start; key <= start + n - 1; ) {
-      const Number i1 = key >> LEAF_BITS;
-
-      // Check for overflow
-      if (i1 >= ROOT_LENGTH)
-        return false;
-
-      // Make 2nd level node if necessary
-      if (root_[i1] == NULL) {
-        Leaf* leaf = reinterpret_cast<Leaf*>((*allocator_)(sizeof(Leaf)));
-        if (leaf == NULL) return false;
-        memset(leaf, 0, sizeof(*leaf));
-        root_[i1] = leaf;
-      }
-
-      // Advance key past whatever is covered by this leaf node
-      key = ((key >> LEAF_BITS) + 1) << LEAF_BITS;
-    }
-    return true;
-  }
-
-  void PreallocateMoreMemory() {
-    // Allocate enough to keep track of all possible pages
-    if (BITS < 20) {
-      Ensure(0, Number(1) << BITS);
-    }
-  }
-
-  void* Next(Number k) const {
-    while (k < (Number(1) << BITS)) {
-      const Number i1 = k >> LEAF_BITS;
-      Leaf* leaf = root_[i1];
-      if (leaf != NULL) {
-        // Scan forward in leaf
-        for (Number i2 = k & (LEAF_LENGTH - 1); i2 < LEAF_LENGTH; i2++) {
-          if (leaf->values[i2] != NULL) {
-            return leaf->values[i2];
-          }
-        }
-      }
-      // Skip to next top-level entry
-      k = (i1 + 1) << LEAF_BITS;
-    }
-    return NULL;
-  }
-};
-
-// Three-level radix tree
-template <int BITS>
-class TCMalloc_PageMap3 {
- private:
-  // How many bits should we consume at each interior level
-  static const int INTERIOR_BITS = (BITS + 2) / 3; // Round-up
-  static const int INTERIOR_LENGTH = 1 << INTERIOR_BITS;
-
-  // How many bits should we consume at leaf level
-  static const int LEAF_BITS = BITS - 2*INTERIOR_BITS;
-  static const int LEAF_LENGTH = 1 << LEAF_BITS;
-
-  // Interior node
-  struct Node {
-    Node* ptrs[INTERIOR_LENGTH];
-  };
-
-  // Leaf node
-  struct Leaf {
-    void* values[LEAF_LENGTH];
-  };
-
-  Node  root_;                          // Root of radix tree
-  void* (*allocator_)(size_t);          // Memory allocator
-
-  Node* NewNode() {
-    Node* result = reinterpret_cast<Node*>((*allocator_)(sizeof(Node)));
-    if (result != NULL) {
-      memset(result, 0, sizeof(*result));
-    }
-    return result;
-  }
-
- public:
-  typedef uintptr_t Number;
-
-  explicit TCMalloc_PageMap3(void* (*allocator)(size_t)) {
-    allocator_ = allocator;
-    memset(&root_, 0, sizeof(root_));
-  }
-
-  ATTRIBUTE_ALWAYS_INLINE
-  void* get(Number k) const {
-    const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS);
-    const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1);
-    const Number i3 = k & (LEAF_LENGTH-1);
-    if ((k >> BITS) > 0 ||
-        root_.ptrs[i1] == NULL || root_.ptrs[i1]->ptrs[i2] == NULL) {
-      return NULL;
-    }
-    return reinterpret_cast<Leaf*>(root_.ptrs[i1]->ptrs[i2])->values[i3];
-  }
-
-  void set(Number k, void* v) {
-    ASSERT(k >> BITS == 0);
-    const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS);
-    const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1);
-    const Number i3 = k & (LEAF_LENGTH-1);
-    reinterpret_cast<Leaf*>(root_.ptrs[i1]->ptrs[i2])->values[i3] = v;
-  }
-
-  bool Ensure(Number start, size_t n) {
-    for (Number key = start; key <= start + n - 1; ) {
-      const Number i1 = key >> (LEAF_BITS + INTERIOR_BITS);
-      const Number i2 = (key >> LEAF_BITS) & (INTERIOR_LENGTH-1);
-
-      // Check for overflow
-      if (i1 >= INTERIOR_LENGTH || i2 >= INTERIOR_LENGTH)
-        return false;
-
-      // Make 2nd level node if necessary
-      if (root_.ptrs[i1] == NULL) {
-        Node* n = NewNode();
-        if (n == NULL) return false;
-        root_.ptrs[i1] = n;
-      }
-
-      // Make leaf node if necessary
-      if (root_.ptrs[i1]->ptrs[i2] == NULL) {
-        Leaf* leaf = reinterpret_cast<Leaf*>((*allocator_)(sizeof(Leaf)));
-        if (leaf == NULL) return false;
-        memset(leaf, 0, sizeof(*leaf));
-        root_.ptrs[i1]->ptrs[i2] = reinterpret_cast<Node*>(leaf);
-      }
-
-      // Advance key past whatever is covered by this leaf node
-      key = ((key >> LEAF_BITS) + 1) << LEAF_BITS;
-    }
-    return true;
-  }
-
-  void PreallocateMoreMemory() {
-  }
-
-  void* Next(Number k) const {
-    while (k < (Number(1) << BITS)) {
-      const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS);
-      const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1);
-      if (root_.ptrs[i1] == NULL) {
-        // Advance to next top-level entry
-        k = (i1 + 1) << (LEAF_BITS + INTERIOR_BITS);
-      } else {
-        Leaf* leaf = reinterpret_cast<Leaf*>(root_.ptrs[i1]->ptrs[i2]);
-        if (leaf != NULL) {
-          for (Number i3 = (k & (LEAF_LENGTH-1)); i3 < LEAF_LENGTH; i3++) {
-            if (leaf->values[i3] != NULL) {
-              return leaf->values[i3];
-            }
-          }
-        }
-        // Advance to next interior entry
-        k = ((k >> LEAF_BITS) + 1) << LEAF_BITS;
-      }
-    }
-    return NULL;
-  }
-};
-
-#endif  // TCMALLOC_PAGEMAP_H_
diff --git a/third_party/tcmalloc/vendor/src/pprof b/third_party/tcmalloc/vendor/src/pprof
deleted file mode 100755
index 9e18fc6..0000000
--- a/third_party/tcmalloc/vendor/src/pprof
+++ /dev/null
@@ -1,5580 +0,0 @@
-#! /usr/bin/env perl
-
-# Copyright (c) 1998-2007, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Program for printing the profile generated by common/profiler.cc,
-# or by the heap profiler (common/debugallocation.cc)
-#
-# The profile contains a sequence of entries of the form:
-#       <count> <stack trace>
-# This program parses the profile, and generates user-readable
-# output.
-#
-# Examples:
-#
-# % tools/pprof "program" "profile"
-#   Enters "interactive" mode
-#
-# % tools/pprof --text "program" "profile"
-#   Generates one line per procedure
-#
-# % tools/pprof --gv "program" "profile"
-#   Generates annotated call-graph and displays via "gv"
-#
-# % tools/pprof --gv --focus=Mutex "program" "profile"
-#   Restrict to code paths that involve an entry that matches "Mutex"
-#
-# % tools/pprof --gv --focus=Mutex --ignore=string "program" "profile"
-#   Restrict to code paths that involve an entry that matches "Mutex"
-#   and does not match "string"
-#
-# % tools/pprof --list=IBF_CheckDocid "program" "profile"
-#   Generates disassembly listing of all routines with at least one
-#   sample that match the --list=<regexp> pattern.  The listing is
-#   annotated with the flat and cumulative sample counts at each line.
-#
-# % tools/pprof --disasm=IBF_CheckDocid "program" "profile"
-#   Generates disassembly listing of all routines with at least one
-#   sample that match the --disasm=<regexp> pattern.  The listing is
-#   annotated with the flat and cumulative sample counts at each PC value.
-#
-# TODO: Use color to indicate files?
-
-use strict;
-use warnings;
-use Getopt::Long;
-use Cwd;
-use POSIX;
-
-my $PPROF_VERSION = "2.0";
-
-# These are the object tools we use which can come from a
-# user-specified location using --tools, from the PPROF_TOOLS
-# environment variable, or from the environment.
-my %obj_tool_map = (
-  "objdump" => "objdump",
-  "nm" => "nm",
-  "addr2line" => "addr2line",
-  "c++filt" => "c++filt",
-  ## ConfigureObjTools may add architecture-specific entries:
-  #"nm_pdb" => "nm-pdb",       # for reading windows (PDB-format) executables
-  #"addr2line_pdb" => "addr2line-pdb",                                # ditto
-  #"otool" => "otool",         # equivalent of objdump on OS X
-);
-# NOTE: these are lists, so you can put in commandline flags if you want.
-my @DOT = ("dot");          # leave non-absolute, since it may be in /usr/local
-my @GV = ("gv");
-my @EVINCE = ("evince");    # could also be xpdf or perhaps acroread
-my @KCACHEGRIND = ("kcachegrind");
-my @PS2PDF = ("ps2pdf");
-# These are used for dynamic profiles
-my @URL_FETCHER = ("curl", "-s");
-
-# These are the web pages that servers need to support for dynamic profiles
-my $HEAP_PAGE = "/pprof/heap";
-my $PROFILE_PAGE = "/pprof/profile";   # must support cgi-param "?seconds=#"
-my $PMUPROFILE_PAGE = "/pprof/pmuprofile(?:\\?.*)?"; # must support cgi-param
-                                                # ?seconds=#&event=x&period=n
-my $GROWTH_PAGE = "/pprof/growth";
-my $CONTENTION_PAGE = "/pprof/contention";
-my $WALL_PAGE = "/pprof/wall(?:\\?.*)?";  # accepts options like namefilter
-my $FILTEREDPROFILE_PAGE = "/pprof/filteredprofile(?:\\?.*)?";
-my $CENSUSPROFILE_PAGE = "/pprof/censusprofile(?:\\?.*)?"; # must support cgi-param
-                                                       # "?seconds=#",
-                                                       # "?tags_regexp=#" and
-                                                       # "?type=#".
-my $SYMBOL_PAGE = "/pprof/symbol";     # must support symbol lookup via POST
-my $PROGRAM_NAME_PAGE = "/pprof/cmdline";
-
-# These are the web pages that can be named on the command line.
-# All the alternatives must begin with /.
-my $PROFILES = "($HEAP_PAGE|$PROFILE_PAGE|$PMUPROFILE_PAGE|" .
-               "$GROWTH_PAGE|$CONTENTION_PAGE|$WALL_PAGE|" .
-               "$FILTEREDPROFILE_PAGE|$CENSUSPROFILE_PAGE)";
-
-# default binary name
-my $UNKNOWN_BINARY = "(unknown)";
-
-# There is a pervasive dependency on the length (in hex characters,
-# i.e., nibbles) of an address, distinguishing between 32-bit and
-# 64-bit profiles.  To err on the safe size, default to 64-bit here:
-my $address_length = 16;
-
-my $dev_null = "/dev/null";
-if (! -e $dev_null && $^O =~ /MSWin/) {    # $^O is the OS perl was built for
-  $dev_null = "nul";
-}
-
-# A list of paths to search for shared object files
-my @prefix_list = ();
-
-# Special routine name that should not have any symbols.
-# Used as separator to parse "addr2line -i" output.
-my $sep_symbol = '_fini';
-my $sep_address = undef;
-
-my @stackTraces;
-
-##### Argument parsing #####
-
-sub usage_string {
-  return <<EOF;
-Usage:
-$0 [options] <program> <profiles>
-   <profiles> is a space separated list of profile names.
-$0 [options] <symbolized-profiles>
-   <symbolized-profiles> is a list of profile files where each file contains
-   the necessary symbol mappings  as well as profile data (likely generated
-   with --raw).
-$0 [options] <profile>
-   <profile> is a remote form.  Symbols are obtained from host:port$SYMBOL_PAGE
-
-   Each name can be:
-   /path/to/profile        - a path to a profile file
-   host:port[/<service>]   - a location of a service to get profile from
-
-   The /<service> can be $HEAP_PAGE, $PROFILE_PAGE, /pprof/pmuprofile,
-                         $GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall,
-                         $CENSUSPROFILE_PAGE, or /pprof/filteredprofile.
-   For instance:
-     $0 http://myserver.com:80$HEAP_PAGE
-   If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling).
-$0 --symbols <program>
-   Maps addresses to symbol names.  In this mode, stdin should be a
-   list of library mappings, in the same format as is found in the heap-
-   and cpu-profile files (this loosely matches that of /proc/self/maps
-   on linux), followed by a list of hex addresses to map, one per line.
-
-   For more help with querying remote servers, including how to add the
-   necessary server-side support code, see this filename (or one like it):
-
-   /usr/doc/gperftools-$PPROF_VERSION/pprof_remote_servers.html
-
-Options:
-   --cum               Sort by cumulative data
-   --base=<base>       Subtract <base> from <profile> before display
-   --interactive       Run in interactive mode (interactive "help" gives help) [default]
-   --seconds=<n>       Length of time for dynamic profiles [default=30 secs]
-   --add_lib=<file>    Read additional symbols and line info from the given library
-   --lib_prefix=<dir>  Comma separated list of library path prefixes
-   --no_strip_temp     Do not strip template arguments from function names
-
-Reporting Granularity:
-   --addresses         Report at address level
-   --lines             Report at source line level
-   --functions         Report at function level [default]
-   --files             Report at source file level
-
-Output type:
-   --text              Generate text report
-   --stacks            Generate stack traces similar to the heap profiler (requires --text)
-   --callgrind         Generate callgrind format to stdout
-   --gv                Generate Postscript and display
-   --evince            Generate PDF and display
-   --web               Generate SVG and display
-   --list=<regexp>     Generate source listing of matching routines
-   --disasm=<regexp>   Generate disassembly of matching routines
-   --symbols           Print demangled symbol names found at given addresses
-   --dot               Generate DOT file to stdout
-   --ps                Generate Postscript to stdout
-   --pdf               Generate PDF to stdout
-   --svg               Generate SVG to stdout
-   --gif               Generate GIF to stdout
-   --raw               Generate symbolized pprof data (useful with remote fetch)
-   --collapsed         Generate collapsed stacks for building flame graphs
-                       (see http://www.brendangregg.com/flamegraphs.html)
-
-Heap-Profile Options:
-   --inuse_space       Display in-use (mega)bytes [default]
-   --inuse_objects     Display in-use objects
-   --alloc_space       Display allocated (mega)bytes
-   --alloc_objects     Display allocated objects
-   --show_bytes        Display space in bytes
-   --drop_negative     Ignore negative differences
-
-Contention-profile options:
-   --total_delay       Display total delay at each region [default]
-   --contentions       Display number of delays at each region
-   --mean_delay        Display mean delay at each region
-
-Call-graph Options:
-   --nodecount=<n>     Show at most so many nodes [default=80]
-   --nodefraction=<f>  Hide nodes below <f>*total [default=.005]
-   --edgefraction=<f>  Hide edges below <f>*total [default=.001]
-   --maxdegree=<n>     Max incoming/outgoing edges per node [default=8]
-   --focus=<regexp>    Focus on nodes matching <regexp>
-   --ignore=<regexp>   Ignore nodes matching <regexp>
-   --scale=<n>         Set GV scaling [default=0]
-   --heapcheck         Make nodes with non-0 object counts
-                       (i.e. direct leak generators) more visible
-
-Miscellaneous:
-   --no-auto-signal-frm Automatically drop 2nd frame that is always same (cpu-only)
-                       (assuming that it is artifact of bad stack captures
-                        which include signal handler frames)
-   --show_addresses    Always show addresses when applicable
-   --tools=<prefix or binary:fullpath>[,...]   \$PATH for object tool pathnames
-   --test              Run unit tests
-   --help              This message
-   --version           Version information
-
-Environment Variables:
-   PPROF_TMPDIR        Profiles directory. Defaults to \$HOME/pprof
-   PPROF_TOOLS         Prefix for object tools pathnames
-
-Examples:
-
-$0 /bin/ls ls.prof
-                       Enters "interactive" mode
-$0 --text /bin/ls ls.prof
-                       Outputs one line per procedure
-$0 --web /bin/ls ls.prof
-                       Displays annotated call-graph in web browser
-$0 --gv /bin/ls ls.prof
-                       Displays annotated call-graph via 'gv'
-$0 --gv --focus=Mutex /bin/ls ls.prof
-                       Restricts to code paths including a .*Mutex.* entry
-$0 --gv --focus=Mutex --ignore=string /bin/ls ls.prof
-                       Code paths including Mutex but not string
-$0 --list=getdir /bin/ls ls.prof
-                       (Per-line) annotated source listing for getdir()
-$0 --disasm=getdir /bin/ls ls.prof
-                       (Per-PC) annotated disassembly for getdir()
-
-$0 http://localhost:1234/
-                       Enters "interactive" mode
-$0 --text localhost:1234
-                       Outputs one line per procedure for localhost:1234
-$0 --raw localhost:1234 > ./local.raw
-$0 --text ./local.raw
-                       Fetches a remote profile for later analysis and then
-                       analyzes it in text mode.
-EOF
-}
-
-sub version_string {
-  return <<EOF
-pprof (part of gperftools $PPROF_VERSION)
-
-Copyright 1998-2007 Google Inc.
-
-This is BSD licensed software; see the source for copying conditions
-and license information.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE.
-EOF
-}
-
-sub usage {
-  my $msg = shift;
-  print STDERR "$msg\n\n";
-  print STDERR usage_string();
-  exit(1);
-}
-
-sub Init() {
-  # Setup tmp-file name and handler to clean it up.
-  # We do this in the very beginning so that we can use
-  # error() and cleanup() function anytime here after.
-  $main::tmpfile_sym = "/tmp/pprof$$.sym";
-  $main::tmpfile_ps = "/tmp/pprof$$";
-  $main::next_tmpfile = 0;
-  $SIG{'INT'} = \&sighandler;
-
-  # Cache from filename/linenumber to source code
-  $main::source_cache = ();
-
-  $main::opt_help = 0;
-  $main::opt_version = 0;
-  $main::opt_show_addresses = 0;
-  $main::opt_no_auto_signal_frames = 0;
-
-  $main::opt_cum = 0;
-  $main::opt_base = '';
-  $main::opt_addresses = 0;
-  $main::opt_lines = 0;
-  $main::opt_functions = 0;
-  $main::opt_files = 0;
-  $main::opt_lib_prefix = "";
-
-  $main::opt_text = 0;
-  $main::opt_stacks = 0;
-  $main::opt_callgrind = 0;
-  $main::opt_list = "";
-  $main::opt_disasm = "";
-  $main::opt_symbols = 0;
-  $main::opt_gv = 0;
-  $main::opt_evince = 0;
-  $main::opt_web = 0;
-  $main::opt_dot = 0;
-  $main::opt_ps = 0;
-  $main::opt_pdf = 0;
-  $main::opt_gif = 0;
-  $main::opt_svg = 0;
-  $main::opt_raw = 0;
-  $main::opt_collapsed = 0;
-
-  $main::opt_nodecount = 80;
-  $main::opt_nodefraction = 0.005;
-  $main::opt_edgefraction = 0.001;
-  $main::opt_maxdegree = 8;
-  $main::opt_focus = '';
-  $main::opt_ignore = '';
-  $main::opt_scale = 0;
-  $main::opt_heapcheck = 0;
-  $main::opt_seconds = 30;
-  $main::opt_lib = "";
-
-  $main::opt_inuse_space   = 0;
-  $main::opt_inuse_objects = 0;
-  $main::opt_alloc_space   = 0;
-  $main::opt_alloc_objects = 0;
-  $main::opt_show_bytes    = 0;
-  $main::opt_drop_negative = 0;
-  $main::opt_interactive   = 0;
-
-  $main::opt_total_delay = 0;
-  $main::opt_contentions = 0;
-  $main::opt_mean_delay = 0;
-
-  $main::opt_tools   = "";
-  $main::opt_debug   = 0;
-  $main::opt_test    = 0;
-
-  # Do not strip template argument in function names
-  $main::opt_no_strip_temp = 0;
-
-  # These are undocumented flags used only by unittests.
-  $main::opt_test_stride = 0;
-
-  # Are we using $SYMBOL_PAGE?
-  $main::use_symbol_page = 0;
-
-  # Files returned by TempName.
-  %main::tempnames = ();
-
-  # Type of profile we are dealing with
-  # Supported types:
-  #     cpu
-  #     heap
-  #     growth
-  #     contention
-  $main::profile_type = '';     # Empty type means "unknown"
-
-  GetOptions("help!"          => \$main::opt_help,
-             "version!"       => \$main::opt_version,
-             "show_addresses!"=> \$main::opt_show_addresses,
-             "no-auto-signal-frm!"=> \$main::opt_no_auto_signal_frames,
-             "cum!"           => \$main::opt_cum,
-             "base=s"         => \$main::opt_base,
-             "seconds=i"      => \$main::opt_seconds,
-             "add_lib=s"      => \$main::opt_lib,
-             "lib_prefix=s"   => \$main::opt_lib_prefix,
-             "functions!"     => \$main::opt_functions,
-             "lines!"         => \$main::opt_lines,
-             "addresses!"     => \$main::opt_addresses,
-             "files!"         => \$main::opt_files,
-             "text!"          => \$main::opt_text,
-             "stacks!"        => \$main::opt_stacks,
-             "callgrind!"     => \$main::opt_callgrind,
-             "list=s"         => \$main::opt_list,
-             "disasm=s"       => \$main::opt_disasm,
-             "symbols!"       => \$main::opt_symbols,
-             "gv!"            => \$main::opt_gv,
-             "evince!"        => \$main::opt_evince,
-             "web!"           => \$main::opt_web,
-             "dot!"           => \$main::opt_dot,
-             "ps!"            => \$main::opt_ps,
-             "pdf!"           => \$main::opt_pdf,
-             "svg!"           => \$main::opt_svg,
-             "gif!"           => \$main::opt_gif,
-             "raw!"           => \$main::opt_raw,
-             "collapsed!"     => \$main::opt_collapsed,
-             "interactive!"   => \$main::opt_interactive,
-             "nodecount=i"    => \$main::opt_nodecount,
-             "nodefraction=f" => \$main::opt_nodefraction,
-             "edgefraction=f" => \$main::opt_edgefraction,
-             "maxdegree=i"    => \$main::opt_maxdegree,
-             "focus=s"        => \$main::opt_focus,
-             "ignore=s"       => \$main::opt_ignore,
-             "scale=i"        => \$main::opt_scale,
-             "heapcheck"      => \$main::opt_heapcheck,
-             "inuse_space!"   => \$main::opt_inuse_space,
-             "inuse_objects!" => \$main::opt_inuse_objects,
-             "alloc_space!"   => \$main::opt_alloc_space,
-             "alloc_objects!" => \$main::opt_alloc_objects,
-             "show_bytes!"    => \$main::opt_show_bytes,
-             "drop_negative!" => \$main::opt_drop_negative,
-             "total_delay!"   => \$main::opt_total_delay,
-             "contentions!"   => \$main::opt_contentions,
-             "mean_delay!"    => \$main::opt_mean_delay,
-             "tools=s"        => \$main::opt_tools,
-             "no_strip_temp!" => \$main::opt_no_strip_temp,
-             "test!"          => \$main::opt_test,
-             "debug!"         => \$main::opt_debug,
-             # Undocumented flags used only by unittests:
-             "test_stride=i"  => \$main::opt_test_stride,
-      ) || usage("Invalid option(s)");
-
-  # Deal with the standard --help and --version
-  if ($main::opt_help) {
-    print usage_string();
-    exit(0);
-  }
-
-  if ($main::opt_version) {
-    print version_string();
-    exit(0);
-  }
-
-  # Disassembly/listing/symbols mode requires address-level info
-  if ($main::opt_disasm || $main::opt_list || $main::opt_symbols) {
-    $main::opt_functions = 0;
-    $main::opt_lines = 0;
-    $main::opt_addresses = 1;
-    $main::opt_files = 0;
-  }
-
-  # Check heap-profiling flags
-  if ($main::opt_inuse_space +
-      $main::opt_inuse_objects +
-      $main::opt_alloc_space +
-      $main::opt_alloc_objects > 1) {
-    usage("Specify at most on of --inuse/--alloc options");
-  }
-
-  # Check output granularities
-  my $grains =
-      $main::opt_functions +
-      $main::opt_lines +
-      $main::opt_addresses +
-      $main::opt_files +
-      0;
-  if ($grains > 1) {
-    usage("Only specify one output granularity option");
-  }
-  if ($grains == 0) {
-    $main::opt_functions = 1;
-  }
-
-  # Check output modes
-  my $modes =
-      $main::opt_text +
-      $main::opt_callgrind +
-      ($main::opt_list eq '' ? 0 : 1) +
-      ($main::opt_disasm eq '' ? 0 : 1) +
-      ($main::opt_symbols == 0 ? 0 : 1) +
-      $main::opt_gv +
-      $main::opt_evince +
-      $main::opt_web +
-      $main::opt_dot +
-      $main::opt_ps +
-      $main::opt_pdf +
-      $main::opt_svg +
-      $main::opt_gif +
-      $main::opt_raw +
-      $main::opt_collapsed +
-      $main::opt_interactive +
-      0;
-  if ($modes > 1) {
-    usage("Only specify one output mode");
-  }
-  if ($modes == 0) {
-    if (-t STDOUT) {  # If STDOUT is a tty, activate interactive mode
-      $main::opt_interactive = 1;
-    } else {
-      $main::opt_text = 1;
-    }
-  }
-
-  if ($main::opt_test) {
-    RunUnitTests();
-    # Should not return
-    exit(1);
-  }
-
-  # Binary name and profile arguments list
-  $main::prog = "";
-  @main::pfile_args = ();
-
-  # Remote profiling without a binary (using $SYMBOL_PAGE instead)
-  if (@ARGV > 0) {
-    if (IsProfileURL($ARGV[0])) {
-      printf STDERR "Using remote profile at $ARGV[0].\n";
-      $main::use_symbol_page = 1;
-    } elsif (IsSymbolizedProfileFile($ARGV[0])) {
-      $main::use_symbolized_profile = 1;
-      $main::prog = $UNKNOWN_BINARY;  # will be set later from the profile file
-    }
-  }
-
-  if ($main::use_symbol_page || $main::use_symbolized_profile) {
-    # We don't need a binary!
-    my %disabled = ('--lines' => $main::opt_lines,
-                    '--disasm' => $main::opt_disasm);
-    for my $option (keys %disabled) {
-      usage("$option cannot be used without a binary") if $disabled{$option};
-    }
-    # Set $main::prog later...
-    scalar(@ARGV) || usage("Did not specify profile file");
-  } elsif ($main::opt_symbols) {
-    # --symbols needs a binary-name (to run nm on, etc) but not profiles
-    $main::prog = shift(@ARGV) || usage("Did not specify program");
-  } else {
-    $main::prog = shift(@ARGV) || usage("Did not specify program");
-    scalar(@ARGV) || usage("Did not specify profile file");
-  }
-
-  # Parse profile file/location arguments
-  foreach my $farg (@ARGV) {
-    if ($farg =~ m/(.*)\@([0-9]+)(|\/.*)$/ ) {
-      my $machine = $1;
-      my $num_machines = $2;
-      my $path = $3;
-      for (my $i = 0; $i < $num_machines; $i++) {
-        unshift(@main::pfile_args, "$i.$machine$path");
-      }
-    } else {
-      unshift(@main::pfile_args, $farg);
-    }
-  }
-
-  if ($main::use_symbol_page) {
-    unless (IsProfileURL($main::pfile_args[0])) {
-      error("The first profile should be a remote form to use $SYMBOL_PAGE\n");
-    }
-    CheckSymbolPage();
-    $main::prog = FetchProgramName();
-  } elsif (!$main::use_symbolized_profile) {  # may not need objtools!
-    ConfigureObjTools($main::prog)
-  }
-
-  # Break the opt_lib_prefix into the prefix_list array
-  @prefix_list = split (',', $main::opt_lib_prefix);
-
-  # Remove trailing / from the prefixes, in the list to prevent
-  # searching things like /my/path//lib/mylib.so
-  foreach (@prefix_list) {
-    s|/+$||;
-  }
-}
-
-sub Main() {
-  Init();
-  $main::collected_profile = undef;
-  @main::profile_files = ();
-  $main::op_time = time();
-
-  # Printing symbols is special and requires a lot less info that most.
-  if ($main::opt_symbols) {
-    PrintSymbols(*STDIN);   # Get /proc/maps and symbols output from stdin
-    return;
-  }
-
-  # Fetch all profile data
-  FetchDynamicProfiles();
-
-  # this will hold symbols that we read from the profile files
-  my $symbol_map = {};
-
-  # Read one profile, pick the last item on the list
-  my $data = ReadProfile($main::prog, pop(@main::profile_files));
-  my $profile = $data->{profile};
-  my $pcs = $data->{pcs};
-  my $libs = $data->{libs};   # Info about main program and shared libraries
-  $symbol_map = MergeSymbols($symbol_map, $data->{symbols});
-
-  # Add additional profiles, if available.
-  if (scalar(@main::profile_files) > 0) {
-    foreach my $pname (@main::profile_files) {
-      my $data2 = ReadProfile($main::prog, $pname);
-      $profile = AddProfile($profile, $data2->{profile});
-      $pcs = AddPcs($pcs, $data2->{pcs});
-      $symbol_map = MergeSymbols($symbol_map, $data2->{symbols});
-    }
-  }
-
-  # Subtract base from profile, if specified
-  if ($main::opt_base ne '') {
-    my $base = ReadProfile($main::prog, $main::opt_base);
-    $profile = SubtractProfile($profile, $base->{profile});
-    $pcs = AddPcs($pcs, $base->{pcs});
-    $symbol_map = MergeSymbols($symbol_map, $base->{symbols});
-  }
-
-  # Get total data in profile
-  my $total = TotalProfile($profile);
-
-  # Collect symbols
-  my $symbols;
-  if ($main::use_symbolized_profile) {
-    $symbols = FetchSymbols($pcs, $symbol_map);
-  } elsif ($main::use_symbol_page) {
-    $symbols = FetchSymbols($pcs);
-  } else {
-    # TODO(csilvers): $libs uses the /proc/self/maps data from profile1,
-    # which may differ from the data from subsequent profiles, especially
-    # if they were run on different machines.  Use appropriate libs for
-    # each pc somehow.
-    $symbols = ExtractSymbols($libs, $pcs);
-  }
-
-  # Remove uniniteresting stack items
-  $profile = RemoveUninterestingFrames($symbols, $profile);
-
-  # Focus?
-  if ($main::opt_focus ne '') {
-    $profile = FocusProfile($symbols, $profile, $main::opt_focus);
-  }
-
-  # Ignore?
-  if ($main::opt_ignore ne '') {
-    $profile = IgnoreProfile($symbols, $profile, $main::opt_ignore);
-  }
-
-  my $calls = ExtractCalls($symbols, $profile);
-
-  # Reduce profiles to required output granularity, and also clean
-  # each stack trace so a given entry exists at most once.
-  my $reduced = ReduceProfile($symbols, $profile);
-
-  # Get derived profiles
-  my $flat = FlatProfile($reduced);
-  my $cumulative = CumulativeProfile($reduced);
-
-  # Print
-  if (!$main::opt_interactive) {
-    if ($main::opt_disasm) {
-      PrintDisassembly($libs, $flat, $cumulative, $main::opt_disasm);
-    } elsif ($main::opt_list) {
-      PrintListing($total, $libs, $flat, $cumulative, $main::opt_list, 0);
-    } elsif ($main::opt_text) {
-      # Make sure the output is empty when have nothing to report
-      # (only matters when --heapcheck is given but we must be
-      # compatible with old branches that did not pass --heapcheck always):
-      if ($total != 0) {
-        printf("Total: %s %s\n", Unparse($total), Units());
-      }
-      if ($main::opt_stacks) {
-        printf("Stacks:\n\n");
-        PrintStacksForText($symbols, $profile);
-      }
-      PrintText($symbols, $flat, $cumulative, -1);
-    } elsif ($main::opt_raw) {
-      PrintSymbolizedProfile($symbols, $profile, $main::prog);
-    } elsif ($main::opt_collapsed) {
-      PrintCollapsedStacks($symbols, $profile);
-    } elsif ($main::opt_callgrind) {
-      PrintCallgrind($calls);
-    } else {
-      if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) {
-        if ($main::opt_gv) {
-          RunGV(TempName($main::next_tmpfile, "ps"), "");
-        } elsif ($main::opt_evince) {
-          RunEvince(TempName($main::next_tmpfile, "pdf"), "");
-        } elsif ($main::opt_web) {
-          my $tmp = TempName($main::next_tmpfile, "svg");
-          RunWeb($tmp);
-          # The command we run might hand the file name off
-          # to an already running browser instance and then exit.
-          # Normally, we'd remove $tmp on exit (right now),
-          # but fork a child to remove $tmp a little later, so that the
-          # browser has time to load it first.
-          delete $main::tempnames{$tmp};
-          if (fork() == 0) {
-            sleep 5;
-            unlink($tmp);
-            exit(0);
-          }
-        }
-      } else {
-        cleanup();
-        exit(1);
-      }
-    }
-  } else {
-    InteractiveMode($profile, $symbols, $libs, $total);
-  }
-
-  cleanup();
-  exit(0);
-}
-
-##### Entry Point #####
-
-Main();
-
-# Temporary code to detect if we're running on a Goobuntu system.
-# These systems don't have the right stuff installed for the special
-# Readline libraries to work, so as a temporary workaround, we default
-# to using the normal stdio code, rather than the fancier readline-based
-# code
-sub ReadlineMightFail {
-  if (-e '/lib/libtermcap.so.2') {
-    return 0;  # libtermcap exists, so readline should be okay
-  } else {
-    return 1;
-  }
-}
-
-sub RunGV {
-  my $fname = shift;
-  my $bg = shift;       # "" or " &" if we should run in background
-  if (!system(ShellEscape(@GV, "--version") . " >$dev_null 2>&1")) {
-    # Options using double dash are supported by this gv version.
-    # Also, turn on noantialias to better handle bug in gv for
-    # postscript files with large dimensions.
-    # TODO: Maybe we should not pass the --noantialias flag
-    # if the gv version is known to work properly without the flag.
-    system(ShellEscape(@GV, "--scale=$main::opt_scale", "--noantialias", $fname)
-           . $bg);
-  } else {
-    # Old gv version - only supports options that use single dash.
-    print STDERR ShellEscape(@GV, "-scale", $main::opt_scale) . "\n";
-    system(ShellEscape(@GV, "-scale", "$main::opt_scale", $fname) . $bg);
-  }
-}
-
-sub RunEvince {
-  my $fname = shift;
-  my $bg = shift;       # "" or " &" if we should run in background
-  system(ShellEscape(@EVINCE, $fname) . $bg);
-}
-
-sub RunWeb {
-  my $fname = shift;
-  print STDERR "Loading web page file:///$fname\n";
-
-  if (`uname` =~ /Darwin/) {
-    # OS X: open will use standard preference for SVG files.
-    system("/usr/bin/open", $fname);
-    return;
-  }
-
-  if (`uname` =~ /MINGW/) {
-    # Windows(MinGW): open will use standard preference for SVG files.
-    system("cmd", "/c", "start", $fname);
-    return;
-  }
-
-  # Some kind of Unix; try generic symlinks, then specific browsers.
-  # (Stop once we find one.)
-  # Works best if the browser is already running.
-  my @alt = (
-    "/etc/alternatives/gnome-www-browser",
-    "/etc/alternatives/x-www-browser",
-    "google-chrome",
-    "firefox",
-  );
-  foreach my $b (@alt) {
-    if (system($b, $fname) == 0) {
-      return;
-    }
-  }
-
-  print STDERR "Could not load web browser.\n";
-}
-
-sub RunKcachegrind {
-  my $fname = shift;
-  my $bg = shift;       # "" or " &" if we should run in background
-  print STDERR "Starting '@KCACHEGRIND " . $fname . $bg . "'\n";
-  system(ShellEscape(@KCACHEGRIND, $fname) . $bg);
-}
-
-
-##### Interactive helper routines #####
-
-sub InteractiveMode {
-  $| = 1;  # Make output unbuffered for interactive mode
-  my ($orig_profile, $symbols, $libs, $total) = @_;
-
-  print STDERR "Welcome to pprof!  For help, type 'help'.\n";
-
-  # Use ReadLine if it's installed and input comes from a console.
-  if ( -t STDIN &&
-       !ReadlineMightFail() &&
-       defined(eval {require Term::ReadLine}) ) {
-    my $term = new Term::ReadLine 'pprof';
-    while ( defined ($_ = $term->readline('(pprof) '))) {
-      $term->addhistory($_) if /\S/;
-      if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {
-        last;    # exit when we get an interactive command to quit
-      }
-    }
-  } else {       # don't have readline
-    while (1) {
-      print STDERR "(pprof) ";
-      $_ = <STDIN>;
-      last if ! defined $_ ;
-      s/\r//g;         # turn windows-looking lines into unix-looking lines
-
-      # Save some flags that might be reset by InteractiveCommand()
-      my $save_opt_lines = $main::opt_lines;
-
-      if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {
-        last;    # exit when we get an interactive command to quit
-      }
-
-      # Restore flags
-      $main::opt_lines = $save_opt_lines;
-    }
-  }
-}
-
-# Takes two args: orig profile, and command to run.
-# Returns 1 if we should keep going, or 0 if we were asked to quit
-sub InteractiveCommand {
-  my($orig_profile, $symbols, $libs, $total, $command) = @_;
-  $_ = $command;                # just to make future m//'s easier
-  if (!defined($_)) {
-    print STDERR "\n";
-    return 0;
-  }
-  if (m/^\s*quit/) {
-    return 0;
-  }
-  if (m/^\s*help/) {
-    InteractiveHelpMessage();
-    return 1;
-  }
-  # Clear all the mode options -- mode is controlled by "$command"
-  $main::opt_text = 0;
-  $main::opt_callgrind = 0;
-  $main::opt_disasm = 0;
-  $main::opt_list = 0;
-  $main::opt_gv = 0;
-  $main::opt_evince = 0;
-  $main::opt_cum = 0;
-
-  if (m/^\s*(text|top)(\d*)\s*(.*)/) {
-    $main::opt_text = 1;
-
-    my $line_limit = ($2 ne "") ? int($2) : 10;
-
-    my $routine;
-    my $ignore;
-    ($routine, $ignore) = ParseInteractiveArgs($3);
-
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    PrintText($symbols, $flat, $cumulative, $line_limit);
-    return 1;
-  }
-  if (m/^\s*callgrind\s*([^ \n]*)/) {
-    $main::opt_callgrind = 1;
-
-    # Get derived profiles
-    my $calls = ExtractCalls($symbols, $orig_profile);
-    my $filename = $1;
-    if ( $1 eq '' ) {
-      $filename = TempName($main::next_tmpfile, "callgrind");
-    }
-    PrintCallgrind($calls, $filename);
-    if ( $1 eq '' ) {
-      RunKcachegrind($filename, " & ");
-      $main::next_tmpfile++;
-    }
-
-    return 1;
-  }
-  if (m/^\s*(web)?list\s*(.+)/) {
-    my $html = (defined($1) && ($1 eq "web"));
-    $main::opt_list = 1;
-
-    my $routine;
-    my $ignore;
-    ($routine, $ignore) = ParseInteractiveArgs($2);
-
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    PrintListing($total, $libs, $flat, $cumulative, $routine, $html);
-    return 1;
-  }
-  if (m/^\s*disasm\s*(.+)/) {
-    $main::opt_disasm = 1;
-
-    my $routine;
-    my $ignore;
-    ($routine, $ignore) = ParseInteractiveArgs($1);
-
-    # Process current profile to account for various settings
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    PrintDisassembly($libs, $flat, $cumulative, $routine);
-    return 1;
-  }
-  if (m/^\s*(gv|web|evince)\s*(.*)/) {
-    $main::opt_gv = 0;
-    $main::opt_evince = 0;
-    $main::opt_web = 0;
-    if ($1 eq "gv") {
-      $main::opt_gv = 1;
-    } elsif ($1 eq "evince") {
-      $main::opt_evince = 1;
-    } elsif ($1 eq "web") {
-      $main::opt_web = 1;
-    }
-
-    my $focus;
-    my $ignore;
-    ($focus, $ignore) = ParseInteractiveArgs($2);
-
-    # Process current profile to account for various settings
-    my $profile = ProcessProfile($total, $orig_profile, $symbols,
-                                 $focus, $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) {
-      if ($main::opt_gv) {
-        RunGV(TempName($main::next_tmpfile, "ps"), " &");
-      } elsif ($main::opt_evince) {
-        RunEvince(TempName($main::next_tmpfile, "pdf"), " &");
-      } elsif ($main::opt_web) {
-        RunWeb(TempName($main::next_tmpfile, "svg"));
-      }
-      $main::next_tmpfile++;
-    }
-    return 1;
-  }
-  if (m/^\s*$/) {
-    return 1;
-  }
-  print STDERR "Unknown command: try 'help'.\n";
-  return 1;
-}
-
-
-sub ProcessProfile {
-  my $total_count = shift;
-  my $orig_profile = shift;
-  my $symbols = shift;
-  my $focus = shift;
-  my $ignore = shift;
-
-  # Process current profile to account for various settings
-  my $profile = $orig_profile;
-  printf("Total: %s %s\n", Unparse($total_count), Units());
-  if ($focus ne '') {
-    $profile = FocusProfile($symbols, $profile, $focus);
-    my $focus_count = TotalProfile($profile);
-    printf("After focusing on '%s': %s %s of %s (%0.1f%%)\n",
-           $focus,
-           Unparse($focus_count), Units(),
-           Unparse($total_count), ($focus_count*100.0) / $total_count);
-  }
-  if ($ignore ne '') {
-    $profile = IgnoreProfile($symbols, $profile, $ignore);
-    my $ignore_count = TotalProfile($profile);
-    printf("After ignoring '%s': %s %s of %s (%0.1f%%)\n",
-           $ignore,
-           Unparse($ignore_count), Units(),
-           Unparse($total_count),
-           ($ignore_count*100.0) / $total_count);
-  }
-
-  return $profile;
-}
-
-sub InteractiveHelpMessage {
-  print STDERR <<ENDOFHELP;
-Interactive pprof mode
-
-Commands:
-  gv
-  gv [focus] [-ignore1] [-ignore2]
-      Show graphical hierarchical display of current profile.  Without
-      any arguments, shows all samples in the profile.  With the optional
-      "focus" argument, restricts the samples shown to just those where
-      the "focus" regular expression matches a routine name on the stack
-      trace.
-
-  web
-  web [focus] [-ignore1] [-ignore2]
-      Like GV, but displays profile in your web browser instead of using
-      Ghostview. Works best if your web browser is already running.
-      To change the browser that gets used:
-      On Linux, set the /etc/alternatives/gnome-www-browser symlink.
-      On OS X, change the Finder association for SVG files.
-
-  list [routine_regexp] [-ignore1] [-ignore2]
-      Show source listing of routines whose names match "routine_regexp"
-
-  weblist [routine_regexp] [-ignore1] [-ignore2]
-     Displays a source listing of routines whose names match "routine_regexp"
-     in a web browser.  You can click on source lines to view the
-     corresponding disassembly.
-
-  top [--cum] [-ignore1] [-ignore2]
-  top20 [--cum] [-ignore1] [-ignore2]
-  top37 [--cum] [-ignore1] [-ignore2]
-      Show top lines ordered by flat profile count, or cumulative count
-      if --cum is specified.  If a number is present after 'top', the
-      top K routines will be shown (defaults to showing the top 10)
-
-  disasm [routine_regexp] [-ignore1] [-ignore2]
-      Show disassembly of routines whose names match "routine_regexp",
-      annotated with sample counts.
-
-  callgrind
-  callgrind [filename]
-      Generates callgrind file. If no filename is given, kcachegrind is called.
-
-  help - This listing
-  quit or ^D - End pprof
-
-For commands that accept optional -ignore tags, samples where any routine in
-the stack trace matches the regular expression in any of the -ignore
-parameters will be ignored.
-
-Further pprof details are available at this location (or one similar):
-
- /usr/doc/gperftools-$PPROF_VERSION/cpu_profiler.html
- /usr/doc/gperftools-$PPROF_VERSION/heap_profiler.html
-
-ENDOFHELP
-}
-sub ParseInteractiveArgs {
-  my $args = shift;
-  my $focus = "";
-  my $ignore = "";
-  my @x = split(/ +/, $args);
-  foreach $a (@x) {
-    if ($a =~ m/^(--|-)lines$/) {
-      $main::opt_lines = 1;
-    } elsif ($a =~ m/^(--|-)cum$/) {
-      $main::opt_cum = 1;
-    } elsif ($a =~ m/^-(.*)/) {
-      $ignore .= (($ignore ne "") ? "|" : "" ) . $1;
-    } else {
-      $focus .= (($focus ne "") ? "|" : "" ) . $a;
-    }
-  }
-  if ($ignore ne "") {
-    print STDERR "Ignoring samples in call stacks that match '$ignore'\n";
-  }
-  return ($focus, $ignore);
-}
-
-##### Output code #####
-
-sub TempName {
-  my $fnum = shift;
-  my $ext = shift;
-  my $file = "$main::tmpfile_ps.$fnum.$ext";
-  $main::tempnames{$file} = 1;
-  return $file;
-}
-
-# Print profile data in packed binary format (64-bit) to standard out
-sub PrintProfileData {
-  my $profile = shift;
-  my $big_endian = pack("L", 1) eq pack("N", 1);
-  # print header (64-bit style)
-  # (zero) (header-size) (version) (sample-period) (zero)
-  if ($big_endian) {
-    print pack('L*', 0, 0, 0, 3, 0, 0, 0, 1, 0, 0);
-  }
-  else {
-    print pack('L*', 0, 0, 3, 0, 0, 0, 1, 0, 0, 0);
-  }
-
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    if ($#addrs >= 0) {
-      my $depth = $#addrs + 1;
-      # int(foo / 2**32) is the only reliable way to get rid of bottom
-      # 32 bits on both 32- and 64-bit systems.
-      if ($big_endian) {
-        print pack('L*', int($count / 2**32), $count & 0xFFFFFFFF);
-        print pack('L*', int($depth / 2**32), $depth & 0xFFFFFFFF);
-      }
-      else {
-        print pack('L*', $count & 0xFFFFFFFF, int($count / 2**32));
-        print pack('L*', $depth & 0xFFFFFFFF, int($depth / 2**32));
-      }
-
-      foreach my $full_addr (@addrs) {
-        my $addr = $full_addr;
-        $addr =~ s/0x0*//;  # strip off leading 0x, zeroes
-        if (length($addr) > 16) {
-          print STDERR "Invalid address in profile: $full_addr\n";
-          next;
-        }
-        my $low_addr = substr($addr, -8);       # get last 8 hex chars
-        my $high_addr = substr($addr, -16, 8);  # get up to 8 more hex chars
-        if ($big_endian) {
-          print pack('L*', hex('0x' . $high_addr), hex('0x' . $low_addr));
-        }
-        else {
-          print pack('L*', hex('0x' . $low_addr), hex('0x' . $high_addr));
-        }
-      }
-    }
-  }
-}
-
-# Print symbols and profile data
-sub PrintSymbolizedProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $prog = shift;
-
-  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $symbol_marker = $&;
-
-  print '--- ', $symbol_marker, "\n";
-  if (defined($prog)) {
-    print 'binary=', $prog, "\n";
-  }
-  while (my ($pc, $name) = each(%{$symbols})) {
-    my $sep = ' ';
-    print '0x', $pc;
-    # We have a list of function names, which include the inlined
-    # calls.  They are separated (and terminated) by --, which is
-    # illegal in function names.
-    for (my $j = 2; $j <= $#{$name}; $j += 3) {
-      print $sep, $name->[$j];
-      $sep = '--';
-    }
-    print "\n";
-  }
-  print '---', "\n";
-
-  $PROFILE_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $profile_marker = $&;
-  print '--- ', $profile_marker, "\n";
-  if (defined($main::collected_profile)) {
-    # if used with remote fetch, simply dump the collected profile to output.
-    open(SRC, "<$main::collected_profile");
-    while (<SRC>) {
-      print $_;
-    }
-    close(SRC);
-  } else {
-    # dump a cpu-format profile to standard out
-    PrintProfileData($profile);
-  }
-}
-
-# Print text output
-sub PrintText {
-  my $symbols = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $line_limit = shift;
-
-  if ($main::opt_stacks && @stackTraces) {
-      foreach (sort { (split " ", $b)[1] <=> (split " ", $a)[1]; } @stackTraces) {
-	  print "$_\n" if $main::opt_debug;
-	  my ($n1, $s1, $n2, $s2, @addrs) = split;
-	  print "Leak of $s1 bytes in $n1 objects allocated from:\n";
-	  foreach my $pcstr (@addrs) {
-	      $pcstr =~ s/^0x//;
-	      my $sym;
-	      if (! defined $symbols->{$pcstr}) {
-		  $sym = "unknown";
-	      } else {
-		  $sym = "$symbols->{$pcstr}[0] $symbols->{$pcstr}[1]";
-	      }
-	      print "\t@ $pcstr $sym\n";
-	  }
-      }
-      print "\n";
-  }
-
-  my $total = TotalProfile($flat);
-
-  # Which profile to sort by?
-  my $s = $main::opt_cum ? $cumulative : $flat;
-
-  my $running_sum = 0;
-  my $lines = 0;
-  foreach my $k (sort { GetEntry($s, $b) <=> GetEntry($s, $a) || $a cmp $b }
-                 keys(%{$cumulative})) {
-    my $f = GetEntry($flat, $k);
-    my $c = GetEntry($cumulative, $k);
-    $running_sum += $f;
-
-    my $sym = $k;
-    if (exists($symbols->{$k})) {
-      $sym = $symbols->{$k}->[0] . " " . $symbols->{$k}->[1];
-      if ($main::opt_addresses) {
-        $sym = $k . " " . $sym;
-      }
-    }
-
-    if ($f != 0 || $c != 0) {
-      printf("%8s %6s %6s %8s %6s %s\n",
-             Unparse($f),
-             Percent($f, $total),
-             Percent($running_sum, $total),
-             Unparse($c),
-             Percent($c, $total),
-             $sym);
-    }
-    $lines++;
-    last if ($line_limit >= 0 && $lines >= $line_limit);
-  }
-}
-
-# Callgrind format has a compression for repeated function and file
-# names.  You show the name the first time, and just use its number
-# subsequently.  This can cut down the file to about a third or a
-# quarter of its uncompressed size.  $key and $val are the key/value
-# pair that would normally be printed by callgrind; $map is a map from
-# value to number.
-sub CompressedCGName {
-  my($key, $val, $map) = @_;
-  my $idx = $map->{$val};
-  # For very short keys, providing an index hurts rather than helps.
-  if (length($val) <= 3) {
-    return "$key=$val\n";
-  } elsif (defined($idx)) {
-    return "$key=($idx)\n";
-  } else {
-    # scalar(keys $map) gives the number of items in the map.
-    $idx = scalar(keys(%{$map})) + 1;
-    $map->{$val} = $idx;
-    return "$key=($idx) $val\n";
-  }
-}
-
-# Print the call graph in a way that's suiteable for callgrind.
-sub PrintCallgrind {
-  my $calls = shift;
-  my $filename;
-  my %filename_to_index_map;
-  my %fnname_to_index_map;
-
-  if ($main::opt_interactive) {
-    $filename = shift;
-    print STDERR "Writing callgrind file to '$filename'.\n"
-  } else {
-    $filename = "&STDOUT";
-  }
-  open(CG, ">$filename");
-  print CG ("events: Hits\n\n");
-  foreach my $call ( map { $_->[0] }
-                     sort { $a->[1] cmp $b ->[1] ||
-                            $a->[2] <=> $b->[2] }
-                     map { /([^:]+):(\d+):([^ ]+)( -> ([^:]+):(\d+):(.+))?/;
-                           [$_, $1, $2] }
-                     keys %$calls ) {
-    my $count = int($calls->{$call});
-    $call =~ /([^:]+):(\d+):([^ ]+)( -> ([^:]+):(\d+):(.+))?/;
-    my ( $caller_file, $caller_line, $caller_function,
-         $callee_file, $callee_line, $callee_function ) =
-       ( $1, $2, $3, $5, $6, $7 );
-
-    # TODO(csilvers): for better compression, collect all the
-    # caller/callee_files and functions first, before printing
-    # anything, and only compress those referenced more than once.
-    print CG CompressedCGName("fl", $caller_file, \%filename_to_index_map);
-    print CG CompressedCGName("fn", $caller_function, \%fnname_to_index_map);
-    if (defined $6) {
-      print CG CompressedCGName("cfl", $callee_file, \%filename_to_index_map);
-      print CG CompressedCGName("cfn", $callee_function, \%fnname_to_index_map);
-      print CG ("calls=$count $callee_line\n");
-    }
-    print CG ("$caller_line $count\n\n");
-  }
-}
-
-# Print disassembly for all all routines that match $main::opt_disasm
-sub PrintDisassembly {
-  my $libs = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $disasm_opts = shift;
-
-  my $total = TotalProfile($flat);
-
-  foreach my $lib (@{$libs}) {
-    my $symbol_table = GetProcedureBoundaries($lib->[0], $disasm_opts);
-    my $offset = AddressSub($lib->[1], $lib->[3]);
-    foreach my $routine (sort ByName keys(%{$symbol_table})) {
-      my $start_addr = $symbol_table->{$routine}->[0];
-      my $end_addr = $symbol_table->{$routine}->[1];
-      # See if there are any samples in this routine
-      my $length = hex(AddressSub($end_addr, $start_addr));
-      my $addr = AddressAdd($start_addr, $offset);
-      for (my $i = 0; $i < $length; $i++) {
-        if (defined($cumulative->{$addr})) {
-          PrintDisassembledFunction($lib->[0], $offset,
-                                    $routine, $flat, $cumulative,
-                                    $start_addr, $end_addr, $total);
-          last;
-        }
-        $addr = AddressInc($addr);
-      }
-    }
-  }
-}
-
-# Return reference to array of tuples of the form:
-#       [start_address, filename, linenumber, instruction, limit_address]
-# E.g.,
-#       ["0x806c43d", "/foo/bar.cc", 131, "ret", "0x806c440"]
-sub Disassemble {
-  my $prog = shift;
-  my $offset = shift;
-  my $start_addr = shift;
-  my $end_addr = shift;
-
-  my $objdump = $obj_tool_map{"objdump"};
-  my $cmd = ShellEscape($objdump, "-C", "-d", "-l", "--no-show-raw-insn",
-                        "--start-address=0x$start_addr",
-                        "--stop-address=0x$end_addr", $prog);
-  open(OBJDUMP, "$cmd |") || error("$cmd: $!\n");
-  my @result = ();
-  my $filename = "";
-  my $linenumber = -1;
-  my $last = ["", "", "", ""];
-  while (<OBJDUMP>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    chop;
-    if (m|\s*([^:\s]+):(\d+)\s*$|) {
-      # Location line of the form:
-      #   <filename>:<linenumber>
-      $filename = $1;
-      $linenumber = $2;
-    } elsif (m/^ +([0-9a-f]+):\s*(.*)/) {
-      # Disassembly line -- zero-extend address to full length
-      my $addr = HexExtend($1);
-      my $k = AddressAdd($addr, $offset);
-      $last->[4] = $k;   # Store ending address for previous instruction
-      $last = [$k, $filename, $linenumber, $2, $end_addr];
-      push(@result, $last);
-    }
-  }
-  close(OBJDUMP);
-  return @result;
-}
-
-# The input file should contain lines of the form /proc/maps-like
-# output (same format as expected from the profiles) or that looks
-# like hex addresses (like "0xDEADBEEF").  We will parse all
-# /proc/maps output, and for all the hex addresses, we will output
-# "short" symbol names, one per line, in the same order as the input.
-sub PrintSymbols {
-  my $maps_and_symbols_file = shift;
-
-  # ParseLibraries expects pcs to be in a set.  Fine by us...
-  my @pclist = ();   # pcs in sorted order
-  my $pcs = {};
-  my $map = "";
-  foreach my $line (<$maps_and_symbols_file>) {
-    $line =~ s/\r//g;    # turn windows-looking lines into unix-looking lines
-    if ($line =~ /\b(0x[0-9a-f]+)\b/i) {
-      push(@pclist, HexExtend($1));
-      $pcs->{$pclist[-1]} = 1;
-    } else {
-      $map .= $line;
-    }
-  }
-
-  my $libs = ParseLibraries($main::prog, $map, $pcs);
-  my $symbols = ExtractSymbols($libs, $pcs);
-
-  foreach my $pc (@pclist) {
-    # ->[0] is the shortname, ->[2] is the full name
-    print(($symbols->{$pc}->[0] || "??") . "\n");
-  }
-}
-
-
-# For sorting functions by name
-sub ByName {
-  return ShortFunctionName($a) cmp ShortFunctionName($b);
-}
-
-# Print source-listing for all all routines that match $list_opts
-sub PrintListing {
-  my $total = shift;
-  my $libs = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $list_opts = shift;
-  my $html = shift;
-
-  my $output = \*STDOUT;
-  my $fname = "";
-
-  if ($html) {
-    # Arrange to write the output to a temporary file
-    $fname = TempName($main::next_tmpfile, "html");
-    $main::next_tmpfile++;
-    if (!open(TEMP, ">$fname")) {
-      print STDERR "$fname: $!\n";
-      return;
-    }
-    $output = \*TEMP;
-    print $output HtmlListingHeader();
-    printf $output ("<div class=\"legend\">%s<br>Total: %s %s</div>\n",
-                    $main::prog, Unparse($total), Units());
-  }
-
-  my $listed = 0;
-  foreach my $lib (@{$libs}) {
-    my $symbol_table = GetProcedureBoundaries($lib->[0], $list_opts);
-    my $offset = AddressSub($lib->[1], $lib->[3]);
-    foreach my $routine (sort ByName keys(%{$symbol_table})) {
-      # Print if there are any samples in this routine
-      my $start_addr = $symbol_table->{$routine}->[0];
-      my $end_addr = $symbol_table->{$routine}->[1];
-      my $length = hex(AddressSub($end_addr, $start_addr));
-      my $addr = AddressAdd($start_addr, $offset);
-      for (my $i = 0; $i < $length; $i++) {
-        if (defined($cumulative->{$addr})) {
-          $listed += PrintSource(
-            $lib->[0], $offset,
-            $routine, $flat, $cumulative,
-            $start_addr, $end_addr,
-            $html,
-            $output);
-          last;
-        }
-        $addr = AddressInc($addr);
-      }
-    }
-  }
-
-  if ($html) {
-    if ($listed > 0) {
-      print $output HtmlListingFooter();
-      close($output);
-      RunWeb($fname);
-    } else {
-      close($output);
-      unlink($fname);
-    }
-  }
-}
-
-sub HtmlListingHeader {
-  return <<'EOF';
-<DOCTYPE html>
-<html>
-<head>
-<title>Pprof listing</title>
-<style type="text/css">
-body {
-  font-family: sans-serif;
-}
-h1 {
-  font-size: 1.5em;
-  margin-bottom: 4px;
-}
-.legend {
-  font-size: 1.25em;
-}
-.line {
-  color: #aaaaaa;
-}
-.nop {
-  color: #aaaaaa;
-}
-.unimportant {
-  color: #cccccc;
-}
-.disasmloc {
-  color: #000000;
-}
-.deadsrc {
-  cursor: pointer;
-}
-.deadsrc:hover {
-  background-color: #eeeeee;
-}
-.livesrc {
-  color: #0000ff;
-  cursor: pointer;
-}
-.livesrc:hover {
-  background-color: #eeeeee;
-}
-.asm {
-  color: #008800;
-  display: none;
-}
-</style>
-<script type="text/javascript">
-function pprof_toggle_asm(e) {
-  var target;
-  if (!e) e = window.event;
-  if (e.target) target = e.target;
-  else if (e.srcElement) target = e.srcElement;
-
-  if (target) {
-    var asm = target.nextSibling;
-    if (asm && asm.className == "asm") {
-      asm.style.display = (asm.style.display == "block" ? "" : "block");
-      e.preventDefault();
-      return false;
-    }
-  }
-}
-</script>
-</head>
-<body>
-EOF
-}
-
-sub HtmlListingFooter {
-  return <<'EOF';
-</body>
-</html>
-EOF
-}
-
-sub HtmlEscape {
-  my $text = shift;
-  $text =~ s/&/&amp;/g;
-  $text =~ s/</&lt;/g;
-  $text =~ s/>/&gt;/g;
-  return $text;
-}
-
-# Returns the indentation of the line, if it has any non-whitespace
-# characters.  Otherwise, returns -1.
-sub Indentation {
-  my $line = shift;
-  if (m/^(\s*)\S/) {
-    return length($1);
-  } else {
-    return -1;
-  }
-}
-
-# If the symbol table contains inlining info, Disassemble() may tag an
-# instruction with a location inside an inlined function.  But for
-# source listings, we prefer to use the location in the function we
-# are listing.  So use MapToSymbols() to fetch full location
-# information for each instruction and then pick out the first
-# location from a location list (location list contains callers before
-# callees in case of inlining).
-#
-# After this routine has run, each entry in $instructions contains:
-#   [0] start address
-#   [1] filename for function we are listing
-#   [2] line number for function we are listing
-#   [3] disassembly
-#   [4] limit address
-#   [5] most specific filename (may be different from [1] due to inlining)
-#   [6] most specific line number (may be different from [2] due to inlining)
-sub GetTopLevelLineNumbers {
-  my ($lib, $offset, $instructions) = @_;
-  my $pcs = [];
-  for (my $i = 0; $i <= $#{$instructions}; $i++) {
-    push(@{$pcs}, $instructions->[$i]->[0]);
-  }
-  my $symbols = {};
-  MapToSymbols($lib, $offset, $pcs, $symbols);
-  for (my $i = 0; $i <= $#{$instructions}; $i++) {
-    my $e = $instructions->[$i];
-    push(@{$e}, $e->[1]);
-    push(@{$e}, $e->[2]);
-    my $addr = $e->[0];
-    my $sym = $symbols->{$addr};
-    if (defined($sym)) {
-      if ($#{$sym} >= 2 && $sym->[1] =~ m/^(.*):(\d+)$/) {
-        $e->[1] = $1;  # File name
-        $e->[2] = $2;  # Line number
-      }
-    }
-  }
-}
-
-# Print source-listing for one routine
-sub PrintSource {
-  my $prog = shift;
-  my $offset = shift;
-  my $routine = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $start_addr = shift;
-  my $end_addr = shift;
-  my $html = shift;
-  my $output = shift;
-
-  # Disassemble all instructions (just to get line numbers)
-  my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);
-  GetTopLevelLineNumbers($prog, $offset, \@instructions);
-
-  # Hack 1: assume that the first source file encountered in the
-  # disassembly contains the routine
-  my $filename = undef;
-  for (my $i = 0; $i <= $#instructions; $i++) {
-    if ($instructions[$i]->[2] >= 0) {
-      $filename = $instructions[$i]->[1];
-      last;
-    }
-  }
-  if (!defined($filename)) {
-    print STDERR "no filename found in $routine\n";
-    return 0;
-  }
-
-  # Hack 2: assume that the largest line number from $filename is the
-  # end of the procedure.  This is typically safe since if P1 contains
-  # an inlined call to P2, then P2 usually occurs earlier in the
-  # source file.  If this does not work, we might have to compute a
-  # density profile or just print all regions we find.
-  my $lastline = 0;
-  for (my $i = 0; $i <= $#instructions; $i++) {
-    my $f = $instructions[$i]->[1];
-    my $l = $instructions[$i]->[2];
-    if (($f eq $filename) && ($l > $lastline)) {
-      $lastline = $l;
-    }
-  }
-
-  # Hack 3: assume the first source location from "filename" is the start of
-  # the source code.
-  my $firstline = 1;
-  for (my $i = 0; $i <= $#instructions; $i++) {
-    if ($instructions[$i]->[1] eq $filename) {
-      $firstline = $instructions[$i]->[2];
-      last;
-    }
-  }
-
-  # Hack 4: Extend last line forward until its indentation is less than
-  # the indentation we saw on $firstline
-  my $oldlastline = $lastline;
-  {
-    if (!open(FILE, "<$filename")) {
-      print STDERR "$filename: $!\n";
-      return 0;
-    }
-    my $l = 0;
-    my $first_indentation = -1;
-    while (<FILE>) {
-      s/\r//g;         # turn windows-looking lines into unix-looking lines
-      $l++;
-      my $indent = Indentation($_);
-      if ($l >= $firstline) {
-        if ($first_indentation < 0 && $indent >= 0) {
-          $first_indentation = $indent;
-          last if ($first_indentation == 0);
-        }
-      }
-      if ($l >= $lastline && $indent >= 0) {
-        if ($indent >= $first_indentation) {
-          $lastline = $l+1;
-        } else {
-          last;
-        }
-      }
-    }
-    close(FILE);
-  }
-
-  # Assign all samples to the range $firstline,$lastline,
-  # Hack 4: If an instruction does not occur in the range, its samples
-  # are moved to the next instruction that occurs in the range.
-  my $samples1 = {};        # Map from line number to flat count
-  my $samples2 = {};        # Map from line number to cumulative count
-  my $running1 = 0;         # Unassigned flat counts
-  my $running2 = 0;         # Unassigned cumulative counts
-  my $total1 = 0;           # Total flat counts
-  my $total2 = 0;           # Total cumulative counts
-  my %disasm = ();          # Map from line number to disassembly
-  my $running_disasm = "";  # Unassigned disassembly
-  my $skip_marker = "---\n";
-  if ($html) {
-    $skip_marker = "";
-    for (my $l = $firstline; $l <= $lastline; $l++) {
-      $disasm{$l} = "";
-    }
-  }
-  my $last_dis_filename = '';
-  my $last_dis_linenum = -1;
-  my $last_touched_line = -1;  # To detect gaps in disassembly for a line
-  foreach my $e (@instructions) {
-    # Add up counts for all address that fall inside this instruction
-    my $c1 = 0;
-    my $c2 = 0;
-    for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) {
-      $c1 += GetEntry($flat, $a);
-      $c2 += GetEntry($cumulative, $a);
-    }
-
-    if ($html) {
-      my $dis = sprintf("      %6s %6s \t\t%8s: %s ",
-                        HtmlPrintNumber($c1),
-                        HtmlPrintNumber($c2),
-                        UnparseAddress($offset, $e->[0]),
-                        CleanDisassembly($e->[3]));
-      
-      # Append the most specific source line associated with this instruction
-      if (length($dis) < 80) { $dis .= (' ' x (80 - length($dis))) };
-      $dis = HtmlEscape($dis);
-      my $f = $e->[5];
-      my $l = $e->[6];
-      if ($f ne $last_dis_filename) {
-        $dis .= sprintf("<span class=disasmloc>%s:%d</span>", 
-                        HtmlEscape(CleanFileName($f)), $l);
-      } elsif ($l ne $last_dis_linenum) {
-        # De-emphasize the unchanged file name portion
-        $dis .= sprintf("<span class=unimportant>%s</span>" .
-                        "<span class=disasmloc>:%d</span>", 
-                        HtmlEscape(CleanFileName($f)), $l);
-      } else {
-        # De-emphasize the entire location
-        $dis .= sprintf("<span class=unimportant>%s:%d</span>", 
-                        HtmlEscape(CleanFileName($f)), $l);
-      }
-      $last_dis_filename = $f;
-      $last_dis_linenum = $l;
-      $running_disasm .= $dis;
-      $running_disasm .= "\n";
-    }
-
-    $running1 += $c1;
-    $running2 += $c2;
-    $total1 += $c1;
-    $total2 += $c2;
-    my $file = $e->[1];
-    my $line = $e->[2];
-    if (($file eq $filename) &&
-        ($line >= $firstline) &&
-        ($line <= $lastline)) {
-      # Assign all accumulated samples to this line
-      AddEntry($samples1, $line, $running1);
-      AddEntry($samples2, $line, $running2);
-      $running1 = 0;
-      $running2 = 0;
-      if ($html) {
-        if ($line != $last_touched_line && $disasm{$line} ne '') {
-          $disasm{$line} .= "\n";
-        }
-        $disasm{$line} .= $running_disasm;
-        $running_disasm = '';
-        $last_touched_line = $line;
-      }
-    }
-  }
-
-  # Assign any leftover samples to $lastline
-  AddEntry($samples1, $lastline, $running1);
-  AddEntry($samples2, $lastline, $running2);
-  if ($html) {
-    if ($lastline != $last_touched_line && $disasm{$lastline} ne '') {
-      $disasm{$lastline} .= "\n";
-    }
-    $disasm{$lastline} .= $running_disasm;
-  }
-
-  if ($html) {
-    printf $output (
-      "<h1>%s</h1>%s\n<pre onClick=\"pprof_toggle_asm()\">\n" .
-      "Total:%6s %6s (flat / cumulative %s)\n",
-      HtmlEscape(ShortFunctionName($routine)),
-      HtmlEscape(CleanFileName($filename)),
-      Unparse($total1),
-      Unparse($total2),
-      Units());
-  } else {
-    printf $output (
-      "ROUTINE ====================== %s in %s\n" .
-      "%6s %6s Total %s (flat / cumulative)\n",
-      ShortFunctionName($routine),
-      CleanFileName($filename),
-      Unparse($total1),
-      Unparse($total2),
-      Units());
-  }
-  if (!open(FILE, "<$filename")) {
-    print STDERR "$filename: $!\n";
-    return 0;
-  }
-  my $l = 0;
-  while (<FILE>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    $l++;
-    if ($l >= $firstline - 5 &&
-        (($l <= $oldlastline + 5) || ($l <= $lastline))) {
-      chop;
-      my $text = $_;
-      if ($l == $firstline) { print $output $skip_marker; }
-      my $n1 = GetEntry($samples1, $l);
-      my $n2 = GetEntry($samples2, $l);
-      if ($html) {
-        # Emit a span that has one of the following classes:
-        #    livesrc -- has samples
-        #    deadsrc -- has disassembly, but with no samples
-        #    nop     -- has no matching disasembly
-        # Also emit an optional span containing disassembly.
-        my $dis = $disasm{$l};
-        my $asm = "";
-        if (defined($dis) && $dis ne '') {
-          $asm = "<span class=\"asm\">" . $dis . "</span>";
-        }
-        my $source_class = (($n1 + $n2 > 0) 
-                            ? "livesrc" 
-                            : (($asm ne "") ? "deadsrc" : "nop"));
-        printf $output (
-          "<span class=\"line\">%5d</span> " .
-          "<span class=\"%s\">%6s %6s %s</span>%s\n",
-          $l, $source_class,
-          HtmlPrintNumber($n1),
-          HtmlPrintNumber($n2),
-          HtmlEscape($text),
-          $asm);
-      } else {
-        printf $output(
-          "%6s %6s %4d: %s\n",
-          UnparseAlt($n1),
-          UnparseAlt($n2),
-          $l,
-          $text);
-      }
-      if ($l == $lastline)  { print $output $skip_marker; }
-    };
-  }
-  close(FILE);
-  if ($html) {
-    print $output "</pre>\n";
-  }
-  return 1;
-}
-
-# Return the source line for the specified file/linenumber.
-# Returns undef if not found.
-sub SourceLine {
-  my $file = shift;
-  my $line = shift;
-
-  # Look in cache
-  if (!defined($main::source_cache{$file})) {
-    if (100 < scalar keys(%main::source_cache)) {
-      # Clear the cache when it gets too big
-      $main::source_cache = ();
-    }
-
-    # Read all lines from the file
-    if (!open(FILE, "<$file")) {
-      print STDERR "$file: $!\n";
-      $main::source_cache{$file} = [];  # Cache the negative result
-      return undef;
-    }
-    my $lines = [];
-    push(@{$lines}, "");        # So we can use 1-based line numbers as indices
-    while (<FILE>) {
-      push(@{$lines}, $_);
-    }
-    close(FILE);
-
-    # Save the lines in the cache
-    $main::source_cache{$file} = $lines;
-  }
-
-  my $lines = $main::source_cache{$file};
-  if (($line < 0) || ($line > $#{$lines})) {
-    return undef;
-  } else {
-    return $lines->[$line];
-  }
-}
-
-# Print disassembly for one routine with interspersed source if available
-sub PrintDisassembledFunction {
-  my $prog = shift;
-  my $offset = shift;
-  my $routine = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $start_addr = shift;
-  my $end_addr = shift;
-  my $total = shift;
-
-  # Disassemble all instructions
-  my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);
-
-  # Make array of counts per instruction
-  my @flat_count = ();
-  my @cum_count = ();
-  my $flat_total = 0;
-  my $cum_total = 0;
-  foreach my $e (@instructions) {
-    # Add up counts for all address that fall inside this instruction
-    my $c1 = 0;
-    my $c2 = 0;
-    for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) {
-      $c1 += GetEntry($flat, $a);
-      $c2 += GetEntry($cumulative, $a);
-    }
-    push(@flat_count, $c1);
-    push(@cum_count, $c2);
-    $flat_total += $c1;
-    $cum_total += $c2;
-  }
-
-  # Print header with total counts
-  printf("ROUTINE ====================== %s\n" .
-         "%6s %6s %s (flat, cumulative) %.1f%% of total\n",
-         ShortFunctionName($routine),
-         Unparse($flat_total),
-         Unparse($cum_total),
-         Units(),
-         ($cum_total * 100.0) / $total);
-
-  # Process instructions in order
-  my $current_file = "";
-  for (my $i = 0; $i <= $#instructions; ) {
-    my $e = $instructions[$i];
-
-    # Print the new file name whenever we switch files
-    if ($e->[1] ne $current_file) {
-      $current_file = $e->[1];
-      my $fname = $current_file;
-      $fname =~ s|^\./||;   # Trim leading "./"
-
-      # Shorten long file names
-      if (length($fname) >= 58) {
-        $fname = "..." . substr($fname, -55);
-      }
-      printf("-------------------- %s\n", $fname);
-    }
-
-    # TODO: Compute range of lines to print together to deal with
-    # small reorderings.
-    my $first_line = $e->[2];
-    my $last_line = $first_line;
-    my %flat_sum = ();
-    my %cum_sum = ();
-    for (my $l = $first_line; $l <= $last_line; $l++) {
-      $flat_sum{$l} = 0;
-      $cum_sum{$l} = 0;
-    }
-
-    # Find run of instructions for this range of source lines
-    my $first_inst = $i;
-    while (($i <= $#instructions) &&
-           ($instructions[$i]->[2] >= $first_line) &&
-           ($instructions[$i]->[2] <= $last_line)) {
-      $e = $instructions[$i];
-      $flat_sum{$e->[2]} += $flat_count[$i];
-      $cum_sum{$e->[2]} += $cum_count[$i];
-      $i++;
-    }
-    my $last_inst = $i - 1;
-
-    # Print source lines
-    for (my $l = $first_line; $l <= $last_line; $l++) {
-      my $line = SourceLine($current_file, $l);
-      if (!defined($line)) {
-        $line = "?\n";
-        next;
-      } else {
-        $line =~ s/^\s+//;
-      }
-      printf("%6s %6s %5d: %s",
-             UnparseAlt($flat_sum{$l}),
-             UnparseAlt($cum_sum{$l}),
-             $l,
-             $line);
-    }
-
-    # Print disassembly
-    for (my $x = $first_inst; $x <= $last_inst; $x++) {
-      my $e = $instructions[$x];
-      printf("%6s %6s    %8s: %6s\n",
-             UnparseAlt($flat_count[$x]),
-             UnparseAlt($cum_count[$x]),
-             UnparseAddress($offset, $e->[0]),
-             CleanDisassembly($e->[3]));
-    }
-  }
-}
-
-# Print DOT graph
-sub PrintDot {
-  my $prog = shift;
-  my $symbols = shift;
-  my $raw = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $overall_total = shift;
-
-  # Get total
-  my $local_total = TotalProfile($flat);
-  my $nodelimit = int($main::opt_nodefraction * $local_total);
-  my $edgelimit = int($main::opt_edgefraction * $local_total);
-  my $nodecount = $main::opt_nodecount;
-
-  # Find nodes to include
-  my @list = (sort { abs(GetEntry($cumulative, $b)) <=>
-                     abs(GetEntry($cumulative, $a))
-                     || $a cmp $b }
-              keys(%{$cumulative}));
-  my $last = $nodecount - 1;
-  if ($last > $#list) {
-    $last = $#list;
-  }
-  while (($last >= 0) &&
-         (abs(GetEntry($cumulative, $list[$last])) <= $nodelimit)) {
-    $last--;
-  }
-  if ($last < 0) {
-    print STDERR "No nodes to print\n";
-    return 0;
-  }
-
-  if ($nodelimit > 0 || $edgelimit > 0) {
-    printf STDERR ("Dropping nodes with <= %s %s; edges with <= %s abs(%s)\n",
-                   Unparse($nodelimit), Units(),
-                   Unparse($edgelimit), Units());
-  }
-
-  # Open DOT output file
-  my $output;
-  my $escaped_dot = ShellEscape(@DOT);
-  my $escaped_ps2pdf = ShellEscape(@PS2PDF);
-  if ($main::opt_gv) {
-    my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, "ps"));
-    $output = "| $escaped_dot -Tps2 >$escaped_outfile";
-  } elsif ($main::opt_evince) {
-    my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, "pdf"));
-    $output = "| $escaped_dot -Tps2 | $escaped_ps2pdf - $escaped_outfile";
-  } elsif ($main::opt_ps) {
-    $output = "| $escaped_dot -Tps2";
-  } elsif ($main::opt_pdf) {
-    $output = "| $escaped_dot -Tps2 | $escaped_ps2pdf - -";
-  } elsif ($main::opt_web || $main::opt_svg) {
-    # We need to post-process the SVG, so write to a temporary file always.
-    my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, "svg"));
-    $output = "| $escaped_dot -Tsvg >$escaped_outfile";
-  } elsif ($main::opt_gif) {
-    $output = "| $escaped_dot -Tgif";
-  } else {
-    $output = ">&STDOUT";
-  }
-  open(DOT, $output) || error("$output: $!\n");
-
-  # Title
-  printf DOT ("digraph \"%s; %s %s\" {\n",
-              $prog,
-              Unparse($overall_total),
-              Units());
-  if ($main::opt_pdf) {
-    # The output is more printable if we set the page size for dot.
-    printf DOT ("size=\"8,11\"\n");
-  }
-  printf DOT ("node [width=0.375,height=0.25];\n");
-
-  # Print legend
-  printf DOT ("Legend [shape=box,fontsize=24,shape=plaintext," .
-              "label=\"%s\\l%s\\l%s\\l%s\\l%s\\l\"];\n",
-              $prog,
-              sprintf("Total %s: %s", Units(), Unparse($overall_total)),
-              sprintf("Focusing on: %s", Unparse($local_total)),
-              sprintf("Dropped nodes with <= %s abs(%s)",
-                      Unparse($nodelimit), Units()),
-              sprintf("Dropped edges with <= %s %s",
-                      Unparse($edgelimit), Units())
-              );
-
-  # Print nodes
-  my %node = ();
-  my $nextnode = 1;
-  foreach my $a (@list[0..$last]) {
-    # Pick font size
-    my $f = GetEntry($flat, $a);
-    my $c = GetEntry($cumulative, $a);
-
-    my $fs = 8;
-    if ($local_total > 0) {
-      $fs = 8 + (50.0 * sqrt(abs($f * 1.0 / $local_total)));
-    }
-
-    $node{$a} = $nextnode++;
-    my $sym = $a;
-    $sym =~ s/\s+/\\n/g;
-    $sym =~ s/::/\\n/g;
-
-    # Extra cumulative info to print for non-leaves
-    my $extra = "";
-    if ($f != $c) {
-      $extra = sprintf("\\rof %s (%s)",
-                       Unparse($c),
-                       Percent($c, $local_total));
-    }
-    my $style = "";
-    if ($main::opt_heapcheck) {
-      if ($f > 0) {
-        # make leak-causing nodes more visible (add a background)
-        $style = ",style=filled,fillcolor=gray"
-      } elsif ($f < 0) {
-        # make anti-leak-causing nodes (which almost never occur)
-        # stand out as well (triple border)
-        $style = ",peripheries=3"
-      }
-    }
-
-    printf DOT ("N%d [label=\"%s\\n%s (%s)%s\\r" .
-                "\",shape=box,fontsize=%.1f%s];\n",
-                $node{$a},
-                $sym,
-                Unparse($f),
-                Percent($f, $local_total),
-                $extra,
-                $fs,
-                $style,
-               );
-  }
-
-  # Get edges and counts per edge
-  my %edge = ();
-  my $n;
-  my $fullname_to_shortname_map = {};
-  FillFullnameToShortnameMap($symbols, $fullname_to_shortname_map);
-  foreach my $k (keys(%{$raw})) {
-    # TODO: omit low %age edges
-    $n = $raw->{$k};
-    my @translated = TranslateStack($symbols, $fullname_to_shortname_map, $k);
-    for (my $i = 1; $i <= $#translated; $i++) {
-      my $src = $translated[$i];
-      my $dst = $translated[$i-1];
-      #next if ($src eq $dst);  # Avoid self-edges?
-      if (exists($node{$src}) && exists($node{$dst})) {
-        my $edge_label = "$src\001$dst";
-        if (!exists($edge{$edge_label})) {
-          $edge{$edge_label} = 0;
-        }
-        $edge{$edge_label} += $n;
-      }
-    }
-  }
-
-  # Print edges (process in order of decreasing counts)
-  my %indegree = ();   # Number of incoming edges added per node so far
-  my %outdegree = ();  # Number of outgoing edges added per node so far
-  foreach my $e (sort { $edge{$b} <=> $edge{$a} } keys(%edge)) {
-    my @x = split(/\001/, $e);
-    $n = $edge{$e};
-
-    # Initialize degree of kept incoming and outgoing edges if necessary
-    my $src = $x[0];
-    my $dst = $x[1];
-    if (!exists($outdegree{$src})) { $outdegree{$src} = 0; }
-    if (!exists($indegree{$dst})) { $indegree{$dst} = 0; }
-
-    my $keep;
-    if ($indegree{$dst} == 0) {
-      # Keep edge if needed for reachability
-      $keep = 1;
-    } elsif (abs($n) <= $edgelimit) {
-      # Drop if we are below --edgefraction
-      $keep = 0;
-    } elsif ($outdegree{$src} >= $main::opt_maxdegree ||
-             $indegree{$dst} >= $main::opt_maxdegree) {
-      # Keep limited number of in/out edges per node
-      $keep = 0;
-    } else {
-      $keep = 1;
-    }
-
-    if ($keep) {
-      $outdegree{$src}++;
-      $indegree{$dst}++;
-
-      # Compute line width based on edge count
-      my $fraction = abs($local_total ? (3 * ($n / $local_total)) : 0);
-      if ($fraction > 1) { $fraction = 1; }
-      my $w = $fraction * 2;
-      if ($w < 1 && ($main::opt_web || $main::opt_svg)) {
-        # SVG output treats line widths < 1 poorly.
-        $w = 1;
-      }
-
-      # Dot sometimes segfaults if given edge weights that are too large, so
-      # we cap the weights at a large value
-      my $edgeweight = abs($n) ** 0.7;
-      if ($edgeweight > 100000) { $edgeweight = 100000; }
-      $edgeweight = int($edgeweight);
-
-      my $style = sprintf("setlinewidth(%f)", $w);
-      if ($x[1] =~ m/\(inline\)/) {
-        $style .= ",dashed";
-      }
-
-      # Use a slightly squashed function of the edge count as the weight
-      printf DOT ("N%s -> N%s [label=%s, weight=%d, style=\"%s\"];\n",
-                  $node{$x[0]},
-                  $node{$x[1]},
-                  Unparse($n),
-                  $edgeweight,
-                  $style);
-    }
-  }
-
-  print DOT ("}\n");
-  close(DOT);
-
-  if ($main::opt_web || $main::opt_svg) {
-    # Rewrite SVG to be more usable inside web browser.
-    RewriteSvg(TempName($main::next_tmpfile, "svg"));
-  }
-
-  return 1;
-}
-
-sub RewriteSvg {
-  my $svgfile = shift;
-
-  open(SVG, $svgfile) || die "open temp svg: $!";
-  my @svg = <SVG>;
-  close(SVG);
-  unlink $svgfile;
-  my $svg = join('', @svg);
-
-  # Dot's SVG output is
-  #
-  #    <svg width="___" height="___"
-  #     viewBox="___" xmlns=...>
-  #    <g id="graph0" transform="...">
-  #    ...
-  #    </g>
-  #    </svg>
-  #
-  # Change it to
-  #
-  #    <svg width="100%" height="100%"
-  #     xmlns=...>
-  #    $svg_javascript
-  #    <g id="viewport" transform="translate(0,0)">
-  #    <g id="graph0" transform="...">
-  #    ...
-  #    </g>
-  #    </g>
-  #    </svg>
-
-  # Fix width, height; drop viewBox.
-  $svg =~ s/(?s)<svg width="[^"]+" height="[^"]+"(.*?)viewBox="[^"]+"/<svg width="100%" height="100%"$1/;
-
-  # Insert script, viewport <g> above first <g>
-  my $svg_javascript = SvgJavascript();
-  my $viewport = "<g id=\"viewport\" transform=\"translate(0,0)\">\n";
-  $svg =~ s/<g id="graph\d"/$svg_javascript$viewport$&/;
-
-  # Insert final </g> above </svg>.
-  $svg =~ s/(.*)(<\/svg>)/$1<\/g>$2/;
-  $svg =~ s/<g id="graph\d"(.*?)/<g id="viewport"$1/;
-
-  if ($main::opt_svg) {
-    # --svg: write to standard output.
-    print $svg;
-  } else {
-    # Write back to temporary file.
-    open(SVG, ">$svgfile") || die "open $svgfile: $!";
-    print SVG $svg;
-    close(SVG);
-  }
-}
-
-sub SvgJavascript {
-  return <<'EOF';
-<script type="text/ecmascript"><![CDATA[
-// SVGPan
-// http://www.cyberz.org/blog/2009/12/08/svgpan-a-javascript-svg-panzoomdrag-library/
-// Local modification: if(true || ...) below to force panning, never moving.
-
-/**
- *  SVGPan library 1.2
- * ====================
- *
- * Given an unique existing element with id "viewport", including the
- * the library into any SVG adds the following capabilities:
- *
- *  - Mouse panning
- *  - Mouse zooming (using the wheel)
- *  - Object dargging
- *
- * Known issues:
- *
- *  - Zooming (while panning) on Safari has still some issues
- *
- * Releases:
- *
- * 1.2, Sat Mar 20 08:42:50 GMT 2010, Zeng Xiaohui
- *	Fixed a bug with browser mouse handler interaction
- *
- * 1.1, Wed Feb  3 17:39:33 GMT 2010, Zeng Xiaohui
- *	Updated the zoom code to support the mouse wheel on Safari/Chrome
- *
- * 1.0, Andrea Leofreddi
- *	First release
- *
- * This code is licensed under the following BSD license:
- *
- * Copyright 2009-2010 Andrea Leofreddi <a.leofreddi@itcharm.com>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice, this list of
- *       conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright notice, this list
- *       of conditions and the following disclaimer in the documentation and/or other materials
- *       provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY Andrea Leofreddi ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Andrea Leofreddi OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of Andrea Leofreddi.
- */
-
-var root = document.documentElement;
-
-var state = 'none', stateTarget, stateOrigin, stateTf;
-
-setupHandlers(root);
-
-/**
- * Register handlers
- */
-function setupHandlers(root){
-	setAttributes(root, {
-		"onmouseup" : "add(evt)",
-		"onmousedown" : "handleMouseDown(evt)",
-		"onmousemove" : "handleMouseMove(evt)",
-		"onmouseup" : "handleMouseUp(evt)",
-		//"onmouseout" : "handleMouseUp(evt)", // Decomment this to stop the pan functionality when dragging out of the SVG element
-	});
-
-	if(navigator.userAgent.toLowerCase().indexOf('webkit') >= 0)
-		window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari
-	else
-		window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
-
-	var g = svgDoc.getElementById("svg");
-	g.width = "100%";
-	g.height = "100%";
-}
-
-/**
- * Instance an SVGPoint object with given event coordinates.
- */
-function getEventPoint(evt) {
-	var p = root.createSVGPoint();
-
-	p.x = evt.clientX;
-	p.y = evt.clientY;
-
-	return p;
-}
-
-/**
- * Sets the current transform matrix of an element.
- */
-function setCTM(element, matrix) {
-	var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
-
-	element.setAttribute("transform", s);
-}
-
-/**
- * Dumps a matrix to a string (useful for debug).
- */
-function dumpMatrix(matrix) {
-	var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\n  " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\n  0, 0, 1 ]";
-
-	return s;
-}
-
-/**
- * Sets attributes of an element.
- */
-function setAttributes(element, attributes){
-	for (i in attributes)
-		element.setAttributeNS(null, i, attributes[i]);
-}
-
-/**
- * Handle mouse move event.
- */
-function handleMouseWheel(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	var delta;
-
-	if(evt.wheelDelta)
-		delta = evt.wheelDelta / 3600; // Chrome/Safari
-	else
-		delta = evt.detail / -90; // Mozilla
-
-	var z = 1 + delta; // Zoom factor: 0.9/1.1
-
-	var g = svgDoc.getElementById("viewport");
-
-	var p = getEventPoint(evt);
-
-	p = p.matrixTransform(g.getCTM().inverse());
-
-	// Compute new scale matrix in current mouse position
-	var k = root.createSVGMatrix().translate(p.x, p.y).scale(z).translate(-p.x, -p.y);
-
-        setCTM(g, g.getCTM().multiply(k));
-
-	stateTf = stateTf.multiply(k.inverse());
-}
-
-/**
- * Handle mouse move event.
- */
-function handleMouseMove(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	var g = svgDoc.getElementById("viewport");
-
-	if(state == 'pan') {
-		// Pan mode
-		var p = getEventPoint(evt).matrixTransform(stateTf);
-
-		setCTM(g, stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
-	} else if(state == 'move') {
-		// Move mode
-		var p = getEventPoint(evt).matrixTransform(g.getCTM().inverse());
-
-		setCTM(stateTarget, root.createSVGMatrix().translate(p.x - stateOrigin.x, p.y - stateOrigin.y).multiply(g.getCTM().inverse()).multiply(stateTarget.getCTM()));
-
-		stateOrigin = p;
-	}
-}
-
-/**
- * Handle click event.
- */
-function handleMouseDown(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	var g = svgDoc.getElementById("viewport");
-
-	if(true || evt.target.tagName == "svg") {
-		// Pan mode
-		state = 'pan';
-
-		stateTf = g.getCTM().inverse();
-
-		stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
-	} else {
-		// Move mode
-		state = 'move';
-
-		stateTarget = evt.target;
-
-		stateTf = g.getCTM().inverse();
-
-		stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
-	}
-}
-
-/**
- * Handle mouse button release event.
- */
-function handleMouseUp(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	if(state == 'pan' || state == 'move') {
-		// Quit pan mode
-		state = '';
-	}
-}
-
-]]></script>
-EOF
-}
-
-# Provides a map from fullname to shortname for cases where the
-# shortname is ambiguous.  The symlist has both the fullname and
-# shortname for all symbols, which is usually fine, but sometimes --
-# such as overloaded functions -- two different fullnames can map to
-# the same shortname.  In that case, we use the address of the
-# function to disambiguate the two.  This function fills in a map that
-# maps fullnames to modified shortnames in such cases.  If a fullname
-# is not present in the map, the 'normal' shortname provided by the
-# symlist is the appropriate one to use.
-sub FillFullnameToShortnameMap {
-  my $symbols = shift;
-  my $fullname_to_shortname_map = shift;
-  my $shortnames_seen_once = {};
-  my $shortnames_seen_more_than_once = {};
-
-  foreach my $symlist (values(%{$symbols})) {
-    # TODO(csilvers): deal with inlined symbols too.
-    my $shortname = $symlist->[0];
-    my $fullname = $symlist->[2];
-    if ($fullname !~ /<[0-9a-fA-F]+>$/) {  # fullname doesn't end in an address
-      next;       # the only collisions we care about are when addresses differ
-    }
-    if (defined($shortnames_seen_once->{$shortname}) &&
-        $shortnames_seen_once->{$shortname} ne $fullname) {
-      $shortnames_seen_more_than_once->{$shortname} = 1;
-    } else {
-      $shortnames_seen_once->{$shortname} = $fullname;
-    }
-  }
-
-  foreach my $symlist (values(%{$symbols})) {
-    my $shortname = $symlist->[0];
-    my $fullname = $symlist->[2];
-    # TODO(csilvers): take in a list of addresses we care about, and only
-    # store in the map if $symlist->[1] is in that list.  Saves space.
-    next if defined($fullname_to_shortname_map->{$fullname});
-    if (defined($shortnames_seen_more_than_once->{$shortname})) {
-      if ($fullname =~ /<0*([^>]*)>$/) {   # fullname has address at end of it
-        $fullname_to_shortname_map->{$fullname} = "$shortname\@$1";
-      }
-    }
-  }
-}
-
-# Return a small number that identifies the argument.
-# Multiple calls with the same argument will return the same number.
-# Calls with different arguments will return different numbers.
-sub ShortIdFor {
-  my $key = shift;
-  my $id = $main::uniqueid{$key};
-  if (!defined($id)) {
-    $id = keys(%main::uniqueid) + 1;
-    $main::uniqueid{$key} = $id;
-  }
-  return $id;
-}
-
-# Translate a stack of addresses into a stack of symbols
-sub TranslateStack {
-  my $symbols = shift;
-  my $fullname_to_shortname_map = shift;
-  my $k = shift;
-
-  my @addrs = split(/\n/, $k);
-  my @result = ();
-  for (my $i = 0; $i <= $#addrs; $i++) {
-    my $a = $addrs[$i];
-
-    # Skip large addresses since they sometimes show up as fake entries on RH9
-    if (length($a) > 8 && $a gt "7fffffffffffffff") {
-      next;
-    }
-
-    if ($main::opt_disasm || $main::opt_list) {
-      # We want just the address for the key
-      push(@result, $a);
-      next;
-    }
-
-    my $symlist = $symbols->{$a};
-    if (!defined($symlist)) {
-      $symlist = [$a, "", $a];
-    }
-
-    # We can have a sequence of symbols for a particular entry
-    # (more than one symbol in the case of inlining).  Callers
-    # come before callees in symlist, so walk backwards since
-    # the translated stack should contain callees before callers.
-    for (my $j = $#{$symlist}; $j >= 2; $j -= 3) {
-      my $func = $symlist->[$j-2];
-      my $fileline = $symlist->[$j-1];
-      my $fullfunc = $symlist->[$j];
-      if (defined($fullname_to_shortname_map->{$fullfunc})) {
-        $func = $fullname_to_shortname_map->{$fullfunc};
-      }
-      if ($j > 2) {
-        $func = "$func (inline)";
-      }
-
-      # Do not merge nodes corresponding to Callback::Run since that
-      # causes confusing cycles in dot display.  Instead, we synthesize
-      # a unique name for this frame per caller.
-      if ($func =~ m/Callback.*::Run$/) {
-        my $caller = ($i > 0) ? $addrs[$i-1] : 0;
-        $func = "Run#" . ShortIdFor($caller);
-      }
-
-      if ($main::opt_addresses) {
-        push(@result, "$a $func $fileline");
-      } elsif ($main::opt_lines) {
-        if ($func eq '??' && $fileline eq '??:0') {
-          push(@result, "$a");
-        } elsif (!$main::opt_show_addresses) {
-          push(@result, "$func $fileline");
-        } else {
-          push(@result, "$func $fileline ($a)");
-        }
-      } elsif ($main::opt_functions) {
-        if ($func eq '??') {
-          push(@result, "$a");
-        } elsif (!$main::opt_show_addresses) {
-          push(@result, $func);
-        } else {
-          push(@result, "$func ($a)");
-        }
-      } elsif ($main::opt_files) {
-        if ($fileline eq '??:0' || $fileline eq '') {
-          push(@result, "$a");
-        } else {
-          my $f = $fileline;
-          $f =~ s/:\d+$//;
-          push(@result, $f);
-        }
-      } else {
-        push(@result, $a);
-        last;  # Do not print inlined info
-      }
-    }
-  }
-
-  # print join(",", @addrs), " => ", join(",", @result), "\n";
-  return @result;
-}
-
-# Generate percent string for a number and a total
-sub Percent {
-  my $num = shift;
-  my $tot = shift;
-  if ($tot != 0) {
-    return sprintf("%.1f%%", $num * 100.0 / $tot);
-  } else {
-    return ($num == 0) ? "nan" : (($num > 0) ? "+inf" : "-inf");
-  }
-}
-
-# Generate pretty-printed form of number
-sub Unparse {
-  my $num = shift;
-  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
-    if ($main::opt_inuse_objects || $main::opt_alloc_objects) {
-      return sprintf("%d", $num);
-    } else {
-      if ($main::opt_show_bytes) {
-        return sprintf("%d", $num);
-      } else {
-        return sprintf("%.1f", $num / 1048576.0);
-      }
-    }
-  } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {
-    return sprintf("%.3f", $num / 1e9); # Convert nanoseconds to seconds
-  } else {
-    return sprintf("%d", $num);
-  }
-}
-
-# Alternate pretty-printed form: 0 maps to "."
-sub UnparseAlt {
-  my $num = shift;
-  if ($num == 0) {
-    return ".";
-  } else {
-    return Unparse($num);
-  }
-}
-
-# Alternate pretty-printed form: 0 maps to ""
-sub HtmlPrintNumber {
-  my $num = shift;
-  if ($num == 0) {
-    return "";
-  } else {
-    return Unparse($num);
-  }
-}
-
-# Return output units
-sub Units {
-  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
-    if ($main::opt_inuse_objects || $main::opt_alloc_objects) {
-      return "objects";
-    } else {
-      if ($main::opt_show_bytes) {
-        return "B";
-      } else {
-        return "MB";
-      }
-    }
-  } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {
-    return "seconds";
-  } else {
-    return "samples";
-  }
-}
-
-##### Profile manipulation code #####
-
-# Generate flattened profile:
-# If count is charged to stack [a,b,c,d], in generated profile,
-# it will be charged to [a]
-sub FlatProfile {
-  my $profile = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    if ($#addrs >= 0) {
-      AddEntry($result, $addrs[0], $count);
-    }
-  }
-  return $result;
-}
-
-# Generate cumulative profile:
-# If count is charged to stack [a,b,c,d], in generated profile,
-# it will be charged to [a], [b], [c], [d]
-sub CumulativeProfile {
-  my $profile = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    foreach my $a (@addrs) {
-      AddEntry($result, $a, $count);
-    }
-  }
-  return $result;
-}
-
-# If the second-youngest PC on the stack is always the same, returns
-# that pc.  Otherwise, returns undef.
-sub IsSecondPcAlwaysTheSame {
-  my $profile = shift;
-
-  my $second_pc = undef;
-  foreach my $k (keys(%{$profile})) {
-    my @addrs = split(/\n/, $k);
-    if ($#addrs < 1) {
-      return undef;
-    }
-    if (not defined $second_pc) {
-      $second_pc = $addrs[1];
-    } else {
-      if ($second_pc ne $addrs[1]) {
-        return undef;
-      }
-    }
-  }
-  return $second_pc;
-}
-
-sub ExtractSymbolLocationInlineStack {
-  my $symbols = shift;
-  my $address = shift;
-  my $stack = shift;
-  # 'addr2line' outputs "??:0" for unknown locations; we do the
-  # same to be consistent.
-  if (exists $symbols->{$address}) {
-    my @localinlinestack = @{$symbols->{$address}};
-    for (my $i = $#localinlinestack; $i > 0; $i-=3) {
-      my $file = $localinlinestack[$i-1];
-      my $fn = $localinlinestack[$i-2];
-      if ($file eq "?" || $file eq ":0") {
-        $file = "??:0";
-      }
-      my $suffix = "[inline]";
-      if ($i == 2) {
-        $suffix = "";
-      }
-      push (@$stack, $file.":".$fn.$suffix);
-    }
-  }
-  else {
-      push (@$stack, "??:0:unknown");
-  }
-}
-
-sub ExtractSymbolNameInlineStack {
-  my $symbols = shift;
-  my $address = shift;
-
-  my @stack = ();
-
-  if (exists $symbols->{$address}) {
-    my @localinlinestack = @{$symbols->{$address}};
-    for (my $i = $#localinlinestack; $i > 0; $i-=3) {
-      my $file = $localinlinestack[$i-1];
-      my $fn = $localinlinestack[$i-0];
-
-      if ($file eq "?" || $file eq ":0") {
-        $file = "??:0";
-      }
-      if ($fn eq '??') {
-        # If we can't get the symbol name, at least use the file information.
-        $fn = $file;
-      }
-      my $suffix = "[inline]";
-      if ($i == 2) {
-        $suffix = "";
-      }
-      push (@stack, $fn.$suffix);
-    }
-  }
-  else {
-    # If we can't get a symbol name, at least fill in the address.
-    push (@stack, $address);
-  }
-
-  return @stack;
-}
-
-sub ExtractSymbolLocation {
-  my $symbols = shift;
-  my $address = shift;
-  # 'addr2line' outputs "??:0" for unknown locations; we do the
-  # same to be consistent.
-  my $location = "??:0:unknown";
-  if (exists $symbols->{$address}) {
-    my $file = $symbols->{$address}->[1];
-    if ($file eq "?" || $file eq ":0") {
-      $file = "??:0"
-    }
-    $location = $file . ":" . $symbols->{$address}->[0];
-  }
-  return $location;
-}
-
-# Extracts a graph of calls.
-sub ExtractCalls {
-  my $symbols = shift;
-  my $profile = shift;
-  my $calls = {};
-  while( my ($stack_trace, $count) = each %$profile ) {
-    my @address = split(/\n/, $stack_trace);
-    my @stack = ();
-    ExtractSymbolLocationInlineStack($symbols, $address[0], \@stack);
-    for (my $i = 1; $i <= $#address; $i++) {
-      ExtractSymbolLocationInlineStack($symbols, $address[$i], \@stack);
-    }
-    AddEntry($calls, $stack[0], $count);
-    for (my $i = 1; $i < $#address; $i++) {
-      AddEntry($calls, "$stack[$i] -> $stack[$i-1]", $count);
-    }
-  }
-  return $calls;
-}
-
-sub PrintStacksForText {
-  my $symbols = shift;
-  my $profile = shift;
-
-  while (my ($stack_trace, $count) = each %$profile) {
-    my @address = split(/\n/, $stack_trace);
-    for (my $i = 0; $i <= $#address; $i++) {
-      $address[$i] = sprintf("(%s) %s", $address[$i], ExtractSymbolLocation($symbols, $address[$i]));
-    }
-    printf("%-8d %s\n\n", $count, join("\n         ", @address));
-  }
-}
-
-sub PrintCollapsedStacks {
-  my $symbols = shift;
-  my $profile = shift;
-
-  while (my ($stack_trace, $count) = each %$profile) {
-    my @address = split(/\n/, $stack_trace);
-    my @names = reverse ( map { ExtractSymbolNameInlineStack($symbols, $_) } @address );
-    printf("%s %d\n", join(";", @names), $count);
-  }
-}
-
-sub RemoveUninterestingFrames {
-  my $symbols = shift;
-  my $profile = shift;
-
-  # List of function names to skip
-  my %skip = ();
-  my $skip_regexp = 'NOMATCH';
-  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
-    foreach my $name ('calloc',
-                      'cfree',
-                      'malloc',
-                      'free',
-                      'memalign',
-                      'posix_memalign',
-                      'pvalloc',
-                      'valloc',
-                      'realloc',
-                      'tc_calloc',
-                      'tc_cfree',
-                      'tc_malloc',
-                      'tc_free',
-                      'tc_memalign',
-                      'tc_posix_memalign',
-                      'tc_pvalloc',
-                      'tc_valloc',
-                      'tc_realloc',
-                      'tc_new',
-                      'tc_delete',
-                      'tc_newarray',
-                      'tc_deletearray',
-                      'tc_new_nothrow',
-                      'tc_newarray_nothrow',
-                      'do_malloc',
-                      '::do_malloc',   # new name -- got moved to an unnamed ns
-                      '::do_malloc_or_cpp_alloc',
-                      'DoSampledAllocation',
-                      'simple_alloc::allocate',
-                      '__malloc_alloc_template::allocate',
-                      '__builtin_delete',
-                      '__builtin_new',
-                      '__builtin_vec_delete',
-                      '__builtin_vec_new',
-                      'operator new',
-                      'operator new[]',
-                      # The entry to our memory-allocation routines on OS X
-                      'malloc_zone_malloc',
-                      'malloc_zone_calloc',
-                      'malloc_zone_valloc',
-                      'malloc_zone_realloc',
-                      'malloc_zone_memalign',
-                      'malloc_zone_free',
-                      # These mark the beginning/end of our custom sections
-                      '__start_google_malloc',
-                      '__stop_google_malloc',
-                      '__start_malloc_hook',
-                      '__stop_malloc_hook') {
-      $skip{$name} = 1;
-      $skip{"_" . $name} = 1;   # Mach (OS X) adds a _ prefix to everything
-    }
-    # TODO: Remove TCMalloc once everything has been
-    # moved into the tcmalloc:: namespace and we have flushed
-    # old code out of the system.
-    $skip_regexp = "TCMalloc|^tcmalloc::";
-  } elsif ($main::profile_type eq 'contention') {
-    foreach my $vname ('base::RecordLockProfileData',
-                       'base::SubmitMutexProfileData',
-                       'base::SubmitSpinLockProfileData',
-                       'Mutex::Unlock',
-                       'Mutex::UnlockSlow',
-                       'Mutex::ReaderUnlock',
-                       'MutexLock::~MutexLock',
-                       'SpinLock::Unlock',
-                       'SpinLock::SlowUnlock',
-                       'SpinLockHolder::~SpinLockHolder') {
-      $skip{$vname} = 1;
-    }
-  } elsif ($main::profile_type eq 'cpu' && !$main::opt_no_auto_signal_frames) {
-    # Drop signal handlers used for CPU profile collection
-    # TODO(dpeng): this should not be necessary; it's taken
-    # care of by the general 2nd-pc mechanism below.
-    foreach my $name ('ProfileData::Add',           # historical
-                      'ProfileData::prof_handler',  # historical
-                      'CpuProfiler::prof_handler',
-                      '__FRAME_END__',
-                      '__pthread_sighandler',
-                      '__restore') {
-      $skip{$name} = 1;
-    }
-  } else {
-    # Nothing skipped for unknown types
-  }
-
-  if ($main::profile_type eq 'cpu') {
-    # If all the second-youngest program counters are the same,
-    # this STRONGLY suggests that it is an artifact of measurement,
-    # i.e., stack frames pushed by the CPU profiler signal handler.
-    # Hence, we delete them.
-    # (The topmost PC is read from the signal structure, not from
-    # the stack, so it does not get involved.)
-    while (my $second_pc = IsSecondPcAlwaysTheSame($profile)) {
-      my $result = {};
-      my $func = '';
-      if (exists($symbols->{$second_pc})) {
-        $second_pc = $symbols->{$second_pc}->[0];
-      }
-      if ($main::opt_no_auto_signal_frames) {
-        print STDERR "All second stack frames are same: `$second_pc'.\nMight be stack trace capturing bug.\n";
-        last;
-      }
-      print STDERR "Removing $second_pc from all stack traces.\n";
-      foreach my $k (keys(%{$profile})) {
-        my $count = $profile->{$k};
-        my @addrs = split(/\n/, $k);
-        my $topaddr = POSIX::strtoul($addrs[0], 16);
-        splice @addrs, 1, 1;
-        if ($#addrs > 1) {
-          my $subtopaddr = POSIX::strtoul($addrs[1], 16);
-          if ($subtopaddr + 1 == $topaddr) {
-            splice @addrs, 1, 1;
-          }
-        }
-        my $reduced_path = join("\n", @addrs);
-        AddEntry($result, $reduced_path, $count);
-      }
-      $profile = $result;
-    }
-  }
-
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    my @path = ();
-    foreach my $a (@addrs) {
-      if (exists($symbols->{$a})) {
-        my $func = $symbols->{$a}->[0];
-        if ($skip{$func} || ($func =~ m/$skip_regexp/)) {
-          next;
-        }
-      }
-      push(@path, $a);
-    }
-    my $reduced_path = join("\n", @path);
-    AddEntry($result, $reduced_path, $count);
-  }
-  return $result;
-}
-
-# Reduce profile to granularity given by user
-sub ReduceProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $result = {};
-  my $fullname_to_shortname_map = {};
-  FillFullnameToShortnameMap($symbols, $fullname_to_shortname_map);
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @translated = TranslateStack($symbols, $fullname_to_shortname_map, $k);
-    my @path = ();
-    my %seen = ();
-    $seen{''} = 1;      # So that empty keys are skipped
-    foreach my $e (@translated) {
-      # To avoid double-counting due to recursion, skip a stack-trace
-      # entry if it has already been seen
-      if (!$seen{$e}) {
-        $seen{$e} = 1;
-        push(@path, $e);
-      }
-    }
-    my $reduced_path = join("\n", @path);
-    AddEntry($result, $reduced_path, $count);
-  }
-  return $result;
-}
-
-# Does the specified symbol array match the regexp?
-sub SymbolMatches {
-  my $sym = shift;
-  my $re = shift;
-  if (defined($sym)) {
-    for (my $i = 0; $i < $#{$sym}; $i += 3) {
-      if ($sym->[$i] =~ m/$re/ || $sym->[$i+1] =~ m/$re/) {
-        return 1;
-      }
-    }
-  }
-  return 0;
-}
-
-# Focus only on paths involving specified regexps
-sub FocusProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $focus = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    foreach my $a (@addrs) {
-      # Reply if it matches either the address/shortname/fileline
-      if (($a =~ m/$focus/) || SymbolMatches($symbols->{$a}, $focus)) {
-        AddEntry($result, $k, $count);
-        last;
-      }
-    }
-  }
-  return $result;
-}
-
-# Focus only on paths not involving specified regexps
-sub IgnoreProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $ignore = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    my $matched = 0;
-    foreach my $a (@addrs) {
-      # Reply if it matches either the address/shortname/fileline
-      if (($a =~ m/$ignore/) || SymbolMatches($symbols->{$a}, $ignore)) {
-        $matched = 1;
-        last;
-      }
-    }
-    if (!$matched) {
-      AddEntry($result, $k, $count);
-    }
-  }
-  return $result;
-}
-
-# Get total count in profile
-sub TotalProfile {
-  my $profile = shift;
-  my $result = 0;
-  foreach my $k (keys(%{$profile})) {
-    $result += $profile->{$k};
-  }
-  return $result;
-}
-
-# Add A to B
-sub AddProfile {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  # add all keys in A
-  foreach my $k (keys(%{$A})) {
-    my $v = $A->{$k};
-    AddEntry($R, $k, $v);
-  }
-  # add all keys in B
-  foreach my $k (keys(%{$B})) {
-    my $v = $B->{$k};
-    AddEntry($R, $k, $v);
-  }
-  return $R;
-}
-
-# Merges symbol maps
-sub MergeSymbols {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  foreach my $k (keys(%{$A})) {
-    $R->{$k} = $A->{$k};
-  }
-  if (defined($B)) {
-    foreach my $k (keys(%{$B})) {
-      $R->{$k} = $B->{$k};
-    }
-  }
-  return $R;
-}
-
-
-# Add A to B
-sub AddPcs {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  # add all keys in A
-  foreach my $k (keys(%{$A})) {
-    $R->{$k} = 1
-  }
-  # add all keys in B
-  foreach my $k (keys(%{$B})) {
-    $R->{$k} = 1
-  }
-  return $R;
-}
-
-# Subtract B from A
-sub SubtractProfile {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  foreach my $k (keys(%{$A})) {
-    my $v = $A->{$k} - GetEntry($B, $k);
-    if ($v < 0 && $main::opt_drop_negative) {
-      $v = 0;
-    }
-    AddEntry($R, $k, $v);
-  }
-  if (!$main::opt_drop_negative) {
-    # Take care of when subtracted profile has more entries
-    foreach my $k (keys(%{$B})) {
-      if (!exists($A->{$k})) {
-        AddEntry($R, $k, 0 - $B->{$k});
-      }
-    }
-  }
-  return $R;
-}
-
-# Get entry from profile; zero if not present
-sub GetEntry {
-  my $profile = shift;
-  my $k = shift;
-  if (exists($profile->{$k})) {
-    return $profile->{$k};
-  } else {
-    return 0;
-  }
-}
-
-# Add entry to specified profile
-sub AddEntry {
-  my $profile = shift;
-  my $k = shift;
-  my $n = shift;
-  if (!exists($profile->{$k})) {
-    $profile->{$k} = 0;
-  }
-  $profile->{$k} += $n;
-}
-
-# Add a stack of entries to specified profile, and add them to the $pcs
-# list.
-sub AddEntries {
-  my $profile = shift;
-  my $pcs = shift;
-  my $stack = shift;
-  my $count = shift;
-  my @k = ();
-
-  foreach my $e (split(/\s+/, $stack)) {
-    my $pc = HexExtend($e);
-    $pcs->{$pc} = 1;
-    push @k, $pc;
-  }
-  AddEntry($profile, (join "\n", @k), $count);
-}
-
-##### Code to profile a server dynamically #####
-
-sub CheckSymbolPage {
-  my $url = SymbolPageURL();
-  my $command = ShellEscape(@URL_FETCHER, $url);
-  open(SYMBOL, "$command |") or error($command);
-  my $line = <SYMBOL>;
-  $line =~ s/\r//g;         # turn windows-looking lines into unix-looking lines
-  close(SYMBOL);
-  unless (defined($line)) {
-    error("$url doesn't exist\n");
-  }
-
-  if ($line =~ /^num_symbols:\s+(\d+)$/) {
-    if ($1 == 0) {
-      error("Stripped binary. No symbols available.\n");
-    }
-  } else {
-    error("Failed to get the number of symbols from $url\n");
-  }
-}
-
-sub IsProfileURL {
-  my $profile_name = shift;
-  if (-f $profile_name) {
-    printf STDERR "Using local file $profile_name.\n";
-    return 0;
-  }
-  return 1;
-}
-
-sub ParseProfileURL {
-  my $profile_name = shift;
-
-  if (!defined($profile_name) || $profile_name eq "") {
-    return ();
-  }
-
-  # Split profile URL - matches all non-empty strings, so no test.
-  $profile_name =~ m,^(https?://)?([^/]+)(.*?)(/|$PROFILES)?$,;
-
-  my $proto = $1 || "http://";
-  my $hostport = $2;
-  my $prefix = $3;
-  my $profile = $4 || "/";
-
-  my $host = $hostport;
-  $host =~ s/:.*//;
-
-  my $baseurl = "$proto$hostport$prefix";
-  return ($host, $baseurl, $profile);
-}
-
-# We fetch symbols from the first profile argument.
-sub SymbolPageURL {
-  my ($host, $baseURL, $path) = ParseProfileURL($main::pfile_args[0]);
-  return "$baseURL$SYMBOL_PAGE";
-}
-
-sub FetchProgramName() {
-  my ($host, $baseURL, $path) = ParseProfileURL($main::pfile_args[0]);
-  my $url = "$baseURL$PROGRAM_NAME_PAGE";
-  my $command_line = ShellEscape(@URL_FETCHER, $url);
-  open(CMDLINE, "$command_line |") or error($command_line);
-  my $cmdline = <CMDLINE>;
-  $cmdline =~ s/\r//g;   # turn windows-looking lines into unix-looking lines
-  close(CMDLINE);
-  error("Failed to get program name from $url\n") unless defined($cmdline);
-  $cmdline =~ s/\x00.+//;  # Remove argv[1] and latters.
-  $cmdline =~ s!\n!!g;  # Remove LFs.
-  return $cmdline;
-}
-
-# Gee, curl's -L (--location) option isn't reliable at least
-# with its 7.12.3 version.  Curl will forget to post data if
-# there is a redirection.  This function is a workaround for
-# curl.  Redirection happens on borg hosts.
-sub ResolveRedirectionForCurl {
-  my $url = shift;
-  my $command_line = ShellEscape(@URL_FETCHER, "--head", $url);
-  open(CMDLINE, "$command_line |") or error($command_line);
-  while (<CMDLINE>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    if (/^Location: (.*)/) {
-      $url = $1;
-    }
-  }
-  close(CMDLINE);
-  return $url;
-}
-
-# Add a timeout flat to URL_FETCHER.  Returns a new list.
-sub AddFetchTimeout {
-  my $timeout = shift;
-  my @fetcher = @_;
-  if (defined($timeout)) {
-    if (join(" ", @fetcher) =~ m/\bcurl -s/) {
-      push(@fetcher, "--max-time", sprintf("%d", $timeout));
-    } elsif (join(" ", @fetcher) =~ m/\brpcget\b/) {
-      push(@fetcher, sprintf("--deadline=%d", $timeout));
-    }
-  }
-  return @fetcher;
-}
-
-# Reads a symbol map from the file handle name given as $1, returning
-# the resulting symbol map.  Also processes variables relating to symbols.
-# Currently, the only variable processed is 'binary=<value>' which updates
-# $main::prog to have the correct program name.
-sub ReadSymbols {
-  my $in = shift;
-  my $map = {};
-  while (<$in>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    # Removes all the leading zeroes from the symbols, see comment below.
-    if (m/^0x0*([0-9a-f]+)\s+(.+)/) {
-      $map->{$1} = $2;
-    } elsif (m/^---/) {
-      last;
-    } elsif (m/^([a-z][^=]*)=(.*)$/ ) {
-      my ($variable, $value) = ($1, $2);
-      for ($variable, $value) {
-        s/^\s+//;
-        s/\s+$//;
-      }
-      if ($variable eq "binary") {
-        if ($main::prog ne $UNKNOWN_BINARY && $main::prog ne $value) {
-          printf STDERR ("Warning: Mismatched binary name '%s', using '%s'.\n",
-                         $main::prog, $value);
-        }
-        $main::prog = $value;
-      } else {
-        printf STDERR ("Ignoring unknown variable in symbols list: " .
-            "'%s' = '%s'\n", $variable, $value);
-      }
-    }
-  }
-  return $map;
-}
-
-# Fetches and processes symbols to prepare them for use in the profile output
-# code.  If the optional 'symbol_map' arg is not given, fetches symbols from
-# $SYMBOL_PAGE for all PC values found in profile.  Otherwise, the raw symbols
-# are assumed to have already been fetched into 'symbol_map' and are simply
-# extracted and processed.
-sub FetchSymbols {
-  my $pcset = shift;
-  my $symbol_map = shift;
-
-  my %seen = ();
-  my @pcs = grep { !$seen{$_}++ } keys(%$pcset);  # uniq
-
-  if (!defined($symbol_map)) {
-    my $post_data = join("+", sort((map {"0x" . "$_"} @pcs)));
-
-    open(POSTFILE, ">$main::tmpfile_sym");
-    print POSTFILE $post_data;
-    close(POSTFILE);
-
-    my $url = SymbolPageURL();
-
-    my $command_line;
-    if (join(" ", @URL_FETCHER) =~ m/\bcurl -s/) {
-      $url = ResolveRedirectionForCurl($url);
-      $command_line = ShellEscape(@URL_FETCHER, "-d", "\@$main::tmpfile_sym",
-                                  $url);
-    } else {
-      $command_line = (ShellEscape(@URL_FETCHER, "--post", $url)
-                       . " < " . ShellEscape($main::tmpfile_sym));
-    }
-    # We use c++filt in case $SYMBOL_PAGE gives us mangled symbols.
-    my $escaped_cppfilt = ShellEscape($obj_tool_map{"c++filt"});
-    open(SYMBOL, "$command_line | $escaped_cppfilt |") or error($command_line);
-    $symbol_map = ReadSymbols(*SYMBOL{IO});
-    close(SYMBOL);
-  }
-
-  my $symbols = {};
-  foreach my $pc (@pcs) {
-    my $fullname;
-    # For 64 bits binaries, symbols are extracted with 8 leading zeroes.
-    # Then /symbol reads the long symbols in as uint64, and outputs
-    # the result with a "0x%08llx" format which get rid of the zeroes.
-    # By removing all the leading zeroes in both $pc and the symbols from
-    # /symbol, the symbols match and are retrievable from the map.
-    my $shortpc = $pc;
-    $shortpc =~ s/^0*//;
-    # Each line may have a list of names, which includes the function
-    # and also other functions it has inlined.  They are separated (in
-    # PrintSymbolizedProfile), by --, which is illegal in function names.
-    my $fullnames;
-    if (defined($symbol_map->{$shortpc})) {
-      $fullnames = $symbol_map->{$shortpc};
-    } else {
-      $fullnames = "0x" . $pc;  # Just use addresses
-    }
-    my $sym = [];
-    $symbols->{$pc} = $sym;
-    foreach my $fullname (split("--", $fullnames)) {
-      my $name = ShortFunctionName($fullname);
-      push(@{$sym}, $name, "?", $fullname);
-    }
-  }
-  return $symbols;
-}
-
-sub BaseName {
-  my $file_name = shift;
-  $file_name =~ s!^.*/!!;  # Remove directory name
-  return $file_name;
-}
-
-sub MakeProfileBaseName {
-  my ($binary_name, $profile_name) = @_;
-  my ($host, $baseURL, $path) = ParseProfileURL($profile_name);
-  my $binary_shortname = BaseName($binary_name);
-  return sprintf("%s.%s.%s",
-                 $binary_shortname, $main::op_time, $host);
-}
-
-sub FetchDynamicProfile {
-  my $binary_name = shift;
-  my $profile_name = shift;
-  my $fetch_name_only = shift;
-  my $encourage_patience = shift;
-
-  if (!IsProfileURL($profile_name)) {
-    return $profile_name;
-  } else {
-    my ($host, $baseURL, $path) = ParseProfileURL($profile_name);
-    if ($path eq "" || $path eq "/") {
-      # Missing type specifier defaults to cpu-profile
-      $path = $PROFILE_PAGE;
-    }
-
-    my $profile_file = MakeProfileBaseName($binary_name, $profile_name);
-
-    my $url = "$baseURL$path";
-    my $fetch_timeout = undef;
-    if ($path =~ m/$PROFILE_PAGE|$PMUPROFILE_PAGE/) {
-      if ($path =~ m/[?]/) {
-        $url .= "&";
-      } else {
-        $url .= "?";
-      }
-      $url .= sprintf("seconds=%d", $main::opt_seconds);
-      $fetch_timeout = $main::opt_seconds * 1.01 + 60;
-    } else {
-      # For non-CPU profiles, we add a type-extension to
-      # the target profile file name.
-      my $suffix = $path;
-      $suffix =~ s,/,.,g;
-      $profile_file .= $suffix;
-    }
-
-    my $profile_dir = $ENV{"PPROF_TMPDIR"} || ($ENV{HOME} . "/pprof");
-    if (! -d $profile_dir) {
-      mkdir($profile_dir)
-          || die("Unable to create profile directory $profile_dir: $!\n");
-    }
-    my $tmp_profile = "$profile_dir/.tmp.$profile_file";
-    my $real_profile = "$profile_dir/$profile_file";
-
-    if ($fetch_name_only > 0) {
-      return $real_profile;
-    }
-
-    my @fetcher = AddFetchTimeout($fetch_timeout, @URL_FETCHER);
-    my $cmd = ShellEscape(@fetcher, $url) . " > " . ShellEscape($tmp_profile);
-    if ($path =~ m/$PROFILE_PAGE|$PMUPROFILE_PAGE|$CENSUSPROFILE_PAGE/){
-      print STDERR "Gathering CPU profile from $url for $main::opt_seconds seconds to\n  ${real_profile}\n";
-      if ($encourage_patience) {
-        print STDERR "Be patient...\n";
-      }
-    } else {
-      print STDERR "Fetching $path profile from $url to\n  ${real_profile}\n";
-    }
-
-    (system($cmd) == 0) || error("Failed to get profile: $cmd: $!\n");
-    (system("mv", $tmp_profile, $real_profile) == 0) || error("Unable to rename profile\n");
-    print STDERR "Wrote profile to $real_profile\n";
-    $main::collected_profile = $real_profile;
-    return $main::collected_profile;
-  }
-}
-
-# Collect profiles in parallel
-sub FetchDynamicProfiles {
-  my $items = scalar(@main::pfile_args);
-  my $levels = log($items) / log(2);
-
-  if ($items == 1) {
-    $main::profile_files[0] = FetchDynamicProfile($main::prog, $main::pfile_args[0], 0, 1);
-  } else {
-    # math rounding issues
-    if ((2 ** $levels) < $items) {
-     $levels++;
-    }
-    my $count = scalar(@main::pfile_args);
-    for (my $i = 0; $i < $count; $i++) {
-      $main::profile_files[$i] = FetchDynamicProfile($main::prog, $main::pfile_args[$i], 1, 0);
-    }
-    print STDERR "Fetching $count profiles, Be patient...\n";
-    FetchDynamicProfilesRecurse($levels, 0, 0);
-    $main::collected_profile = join(" \\\n    ", @main::profile_files);
-  }
-}
-
-# Recursively fork a process to get enough processes
-# collecting profiles
-sub FetchDynamicProfilesRecurse {
-  my $maxlevel = shift;
-  my $level = shift;
-  my $position = shift;
-
-  if (my $pid = fork()) {
-    $position = 0 | ($position << 1);
-    TryCollectProfile($maxlevel, $level, $position);
-    wait;
-  } else {
-    $position = 1 | ($position << 1);
-    TryCollectProfile($maxlevel, $level, $position);
-    cleanup();
-    exit(0);
-  }
-}
-
-# Collect a single profile
-sub TryCollectProfile {
-  my $maxlevel = shift;
-  my $level = shift;
-  my $position = shift;
-
-  if ($level >= ($maxlevel - 1)) {
-    if ($position < scalar(@main::pfile_args)) {
-      FetchDynamicProfile($main::prog, $main::pfile_args[$position], 0, 0);
-    }
-  } else {
-    FetchDynamicProfilesRecurse($maxlevel, $level+1, $position);
-  }
-}
-
-##### Parsing code #####
-
-# Provide a small streaming-read module to handle very large
-# cpu-profile files.  Stream in chunks along a sliding window.
-# Provides an interface to get one 'slot', correctly handling
-# endian-ness differences.  A slot is one 32-bit or 64-bit word
-# (depending on the input profile).  We tell endianness and bit-size
-# for the profile by looking at the first 8 bytes: in cpu profiles,
-# the second slot is always 3 (we'll accept anything that's not 0).
-BEGIN {
-  package CpuProfileStream;
-
-  sub new {
-    my ($class, $file, $fname) = @_;
-    my $self = { file        => $file,
-                 base        => 0,
-                 stride      => 512 * 1024,   # must be a multiple of bitsize/8
-                 slots       => [],
-                 unpack_code => "",           # N for big-endian, V for little
-                 perl_is_64bit => 1,          # matters if profile is 64-bit
-    };
-    bless $self, $class;
-    # Let unittests adjust the stride
-    if ($main::opt_test_stride > 0) {
-      $self->{stride} = $main::opt_test_stride;
-    }
-    # Read the first two slots to figure out bitsize and endianness.
-    my $slots = $self->{slots};
-    my $str;
-    read($self->{file}, $str, 8);
-    # Set the global $address_length based on what we see here.
-    # 8 is 32-bit (8 hexadecimal chars); 16 is 64-bit (16 hexadecimal chars).
-    $address_length = ($str eq (chr(0)x8)) ? 16 : 8;
-    if ($address_length == 8) {
-      if (substr($str, 6, 2) eq chr(0)x2) {
-        $self->{unpack_code} = 'V';  # Little-endian.
-      } elsif (substr($str, 4, 2) eq chr(0)x2) {
-        $self->{unpack_code} = 'N';  # Big-endian
-      } else {
-        ::error("$fname: header size >= 2**16\n");
-      }
-      @$slots = unpack($self->{unpack_code} . "*", $str);
-    } else {
-      # If we're a 64-bit profile, check if we're a 64-bit-capable
-      # perl.  Otherwise, each slot will be represented as a float
-      # instead of an int64, losing precision and making all the
-      # 64-bit addresses wrong.  We won't complain yet, but will
-      # later if we ever see a value that doesn't fit in 32 bits.
-      my $has_q = 0;
-      eval { $has_q = pack("Q", "1") ? 1 : 1; };
-      if (!$has_q) {
-        $self->{perl_is_64bit} = 0;
-      }
-      read($self->{file}, $str, 8);
-      if (substr($str, 4, 4) eq chr(0)x4) {
-        # We'd love to use 'Q', but it's a) not universal, b) not endian-proof.
-        $self->{unpack_code} = 'V';  # Little-endian.
-      } elsif (substr($str, 0, 4) eq chr(0)x4) {
-        $self->{unpack_code} = 'N';  # Big-endian
-      } else {
-        ::error("$fname: header size >= 2**32\n");
-      }
-      my @pair = unpack($self->{unpack_code} . "*", $str);
-      # Since we know one of the pair is 0, it's fine to just add them.
-      @$slots = (0, $pair[0] + $pair[1]);
-    }
-    return $self;
-  }
-
-  # Load more data when we access slots->get(X) which is not yet in memory.
-  sub overflow {
-    my ($self) = @_;
-    my $slots = $self->{slots};
-    $self->{base} += $#$slots + 1;   # skip over data we're replacing
-    my $str;
-    read($self->{file}, $str, $self->{stride});
-    if ($address_length == 8) {      # the 32-bit case
-      # This is the easy case: unpack provides 32-bit unpacking primitives.
-      @$slots = unpack($self->{unpack_code} . "*", $str);
-    } else {
-      # We need to unpack 32 bits at a time and combine.
-      my @b32_values = unpack($self->{unpack_code} . "*", $str);
-      my @b64_values = ();
-      for (my $i = 0; $i < $#b32_values; $i += 2) {
-        # TODO(csilvers): if this is a 32-bit perl, the math below
-        #    could end up in a too-large int, which perl will promote
-        #    to a double, losing necessary precision.  Deal with that.
-        #    Right now, we just die.
-        my ($lo, $hi) = ($b32_values[$i], $b32_values[$i+1]);
-        if ($self->{unpack_code} eq 'N') {    # big-endian
-          ($lo, $hi) = ($hi, $lo);
-        }
-        my $value = $lo + $hi * (2**32);
-        if (!$self->{perl_is_64bit} &&   # check value is exactly represented
-            (($value % (2**32)) != $lo || int($value / (2**32)) != $hi)) {
-          ::error("Need a 64-bit perl to process this 64-bit profile.\n");
-        }
-        push(@b64_values, $value);
-      }
-      @$slots = @b64_values;
-    }
-  }
-
-  # Access the i-th long in the file (logically), or -1 at EOF.
-  sub get {
-    my ($self, $idx) = @_;
-    my $slots = $self->{slots};
-    while ($#$slots >= 0) {
-      if ($idx < $self->{base}) {
-        # The only time we expect a reference to $slots[$i - something]
-        # after referencing $slots[$i] is reading the very first header.
-        # Since $stride > |header|, that shouldn't cause any lookback
-        # errors.  And everything after the header is sequential.
-        print STDERR "Unexpected look-back reading CPU profile";
-        return -1;   # shrug, don't know what better to return
-      } elsif ($idx > $self->{base} + $#$slots) {
-        $self->overflow();
-      } else {
-        return $slots->[$idx - $self->{base}];
-      }
-    }
-    # If we get here, $slots is [], which means we've reached EOF
-    return -1;  # unique since slots is supposed to hold unsigned numbers
-  }
-}
-
-# Reads the top, 'header' section of a profile, and returns the last
-# line of the header, commonly called a 'header line'.  The header
-# section of a profile consists of zero or more 'command' lines that
-# are instructions to pprof, which pprof executes when reading the
-# header.  All 'command' lines start with a %.  After the command
-# lines is the 'header line', which is a profile-specific line that
-# indicates what type of profile it is, and perhaps other global
-# information about the profile.  For instance, here's a header line
-# for a heap profile:
-#   heap profile:     53:    38236 [  5525:  1284029] @ heapprofile
-# For historical reasons, the CPU profile does not contain a text-
-# readable header line.  If the profile looks like a CPU profile,
-# this function returns "".  If no header line could be found, this
-# function returns undef.
-#
-# The following commands are recognized:
-#   %warn -- emit the rest of this line to stderr, prefixed by 'WARNING:'
-#
-# The input file should be in binmode.
-sub ReadProfileHeader {
-  local *PROFILE = shift;
-  my $firstchar = "";
-  my $line = "";
-  read(PROFILE, $firstchar, 1);
-  seek(PROFILE, -1, 1);                    # unread the firstchar
-  if ($firstchar !~ /[[:print:]]/) {       # is not a text character
-    return "";
-  }
-  while (defined($line = <PROFILE>)) {
-    $line =~ s/\r//g;   # turn windows-looking lines into unix-looking lines
-    if ($line =~ /^%warn\s+(.*)/) {        # 'warn' command
-      # Note this matches both '%warn blah\n' and '%warn\n'.
-      print STDERR "WARNING: $1\n";        # print the rest of the line
-    } elsif ($line =~ /^%/) {
-      print STDERR "Ignoring unknown command from profile header: $line";
-    } else {
-      # End of commands, must be the header line.
-      return $line;
-    }
-  }
-  return undef;     # got to EOF without seeing a header line
-}
-
-sub IsSymbolizedProfileFile {
-  my $file_name = shift;
-  if (!(-e $file_name) || !(-r $file_name)) {
-    return 0;
-  }
-  # Check if the file contains a symbol-section marker.
-  open(TFILE, "<$file_name");
-  binmode TFILE;
-  my $firstline = ReadProfileHeader(*TFILE);
-  close(TFILE);
-  if (!$firstline) {
-    return 0;
-  }
-  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $symbol_marker = $&;
-  return $firstline =~ /^--- *$symbol_marker/;
-}
-
-# Parse profile generated by common/profiler.cc and return a reference
-# to a map:
-#      $result->{version}     Version number of profile file
-#      $result->{period}      Sampling period (in microseconds)
-#      $result->{profile}     Profile object
-#      $result->{map}         Memory map info from profile
-#      $result->{pcs}         Hash of all PC values seen, key is hex address
-sub ReadProfile {
-  my $prog = shift;
-  my $fname = shift;
-  my $result;            # return value
-
-  $CONTENTION_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $contention_marker = $&;
-  $GROWTH_PAGE  =~ m,[^/]+$,;    # matches everything after the last slash
-  my $growth_marker = $&;
-  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $symbol_marker = $&;
-  $PROFILE_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $profile_marker = $&;
-
-  # Look at first line to see if it is a heap or a CPU profile.
-  # CPU profile may start with no header at all, and just binary data
-  # (starting with \0\0\0\0) -- in that case, don't try to read the
-  # whole firstline, since it may be gigabytes(!) of data.
-  open(PROFILE, "<$fname") || error("$fname: $!\n");
-  binmode PROFILE;      # New perls do UTF-8 processing
-  my $header = ReadProfileHeader(*PROFILE);
-  if (!defined($header)) {   # means "at EOF"
-    error("Profile is empty.\n");
-  }
-
-  my $symbols;
-  if ($header =~ m/^--- *$symbol_marker/o) {
-    # Verify that the user asked for a symbolized profile
-    if (!$main::use_symbolized_profile) {
-      # we have both a binary and symbolized profiles, abort
-      error("FATAL ERROR: Symbolized profile\n   $fname\ncannot be used with " .
-            "a binary arg. Try again without passing\n   $prog\n");
-    }
-    # Read the symbol section of the symbolized profile file.
-    $symbols = ReadSymbols(*PROFILE{IO});
-    # Read the next line to get the header for the remaining profile.
-    $header = ReadProfileHeader(*PROFILE) || "";
-  }
-
-  $main::profile_type = '';
-  if ($header =~ m/^heap profile:.*$growth_marker/o) {
-    $main::profile_type = 'growth';
-    $result =  ReadHeapProfile($prog, *PROFILE, $header);
-  } elsif ($header =~ m/^heap profile:/) {
-    $main::profile_type = 'heap';
-    $result =  ReadHeapProfile($prog, *PROFILE, $header);
-  } elsif ($header =~ m/^--- *$contention_marker/o) {
-    $main::profile_type = 'contention';
-    $result = ReadSynchProfile($prog, *PROFILE);
-  } elsif ($header =~ m/^--- *Stacks:/) {
-    print STDERR
-      "Old format contention profile: mistakenly reports " .
-      "condition variable signals as lock contentions.\n";
-    $main::profile_type = 'contention';
-    $result = ReadSynchProfile($prog, *PROFILE);
-  } elsif ($header =~ m/^--- *$profile_marker/) {
-    # the binary cpu profile data starts immediately after this line
-    $main::profile_type = 'cpu';
-    $result = ReadCPUProfile($prog, $fname, *PROFILE);
-  } else {
-    if (defined($symbols)) {
-      # a symbolized profile contains a format we don't recognize, bail out
-      error("$fname: Cannot recognize profile section after symbols.\n");
-    }
-    # no ascii header present -- must be a CPU profile
-    $main::profile_type = 'cpu';
-    $result = ReadCPUProfile($prog, $fname, *PROFILE);
-  }
-
-  close(PROFILE);
-
-  # if we got symbols along with the profile, return those as well
-  if (defined($symbols)) {
-    $result->{symbols} = $symbols;
-  }
-
-  return $result;
-}
-
-# Subtract one from caller pc so we map back to call instr.
-# However, don't do this if we're reading a symbolized profile
-# file, in which case the subtract-one was done when the file
-# was written.
-#
-# We apply the same logic to all readers, though ReadCPUProfile uses an
-# independent implementation.
-sub FixCallerAddresses {
-  my $stack = shift;
-  if ($main::use_symbolized_profile) {
-    return $stack;
-  } else {
-    $stack =~ /(\s)/;
-    my $delimiter = $1;
-    my @addrs = split(' ', $stack);
-    my @fixedaddrs;
-    $#fixedaddrs = $#addrs;
-    if ($#addrs >= 0) {
-      $fixedaddrs[0] = $addrs[0];
-    }
-    for (my $i = 1; $i <= $#addrs; $i++) {
-      $fixedaddrs[$i] = AddressSub($addrs[$i], "0x1");
-    }
-    return join $delimiter, @fixedaddrs;
-  }
-}
-
-# CPU profile reader
-sub ReadCPUProfile {
-  my $prog = shift;
-  my $fname = shift;       # just used for logging
-  local *PROFILE = shift;
-  my $version;
-  my $period;
-  my $i;
-  my $profile = {};
-  my $pcs = {};
-
-  # Parse string into array of slots.
-  my $slots = CpuProfileStream->new(*PROFILE, $fname);
-
-  # Read header.  The current header version is a 5-element structure
-  # containing:
-  #   0: header count (always 0)
-  #   1: header "words" (after this one: 3)
-  #   2: format version (0)
-  #   3: sampling period (usec)
-  #   4: unused padding (always 0)
-  if ($slots->get(0) != 0 ) {
-    error("$fname: not a profile file, or old format profile file\n");
-  }
-  $i = 2 + $slots->get(1);
-  $version = $slots->get(2);
-  $period = $slots->get(3);
-  # Do some sanity checking on these header values.
-  if ($version > (2**32) || $period > (2**32) || $i > (2**32) || $i < 5) {
-    error("$fname: not a profile file, or corrupted profile file\n");
-  }
-
-  # Parse profile
-  while ($slots->get($i) != -1) {
-    my $n = $slots->get($i++);
-    my $d = $slots->get($i++);
-    if ($d > (2**16)) {  # TODO(csilvers): what's a reasonable max-stack-depth?
-      my $addr = sprintf("0%o", $i * ($address_length == 8 ? 4 : 8));
-      print STDERR "At index $i (address $addr):\n";
-      error("$fname: stack trace depth >= 2**32\n");
-    }
-    if ($slots->get($i) == 0) {
-      # End of profile data marker
-      $i += $d;
-      last;
-    }
-
-    # Make key out of the stack entries
-    my @k = ();
-    for (my $j = 0; $j < $d; $j++) {
-      my $pc = $slots->get($i+$j);
-      # Subtract one from caller pc so we map back to call instr.
-      # However, don't do this if we're reading a symbolized profile
-      # file, in which case the subtract-one was done when the file
-      # was written.
-      if ($j > 0 && !$main::use_symbolized_profile) {
-        $pc--;
-      }
-      $pc = sprintf("%0*x", $address_length, $pc);
-      $pcs->{$pc} = 1;
-      push @k, $pc;
-    }
-
-    AddEntry($profile, (join "\n", @k), $n);
-    $i += $d;
-  }
-
-  # Parse map
-  my $map = '';
-  seek(PROFILE, $i * ($address_length / 2), 0);
-  read(PROFILE, $map, (stat PROFILE)[7]);
-
-  my $r = {};
-  $r->{version} = $version;
-  $r->{period} = $period;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-
-  return $r;
-}
-
-sub ReadHeapProfile {
-  my $prog = shift;
-  local *PROFILE = shift;
-  my $header = shift;
-
-  my $index = 1;
-  if ($main::opt_inuse_space) {
-    $index = 1;
-  } elsif ($main::opt_inuse_objects) {
-    $index = 0;
-  } elsif ($main::opt_alloc_space) {
-    $index = 3;
-  } elsif ($main::opt_alloc_objects) {
-    $index = 2;
-  }
-
-  # Find the type of this profile.  The header line looks like:
-  #    heap profile:   1246:  8800744 [  1246:  8800744] @ <heap-url>/266053
-  # There are two pairs <count: size>, the first inuse objects/space, and the
-  # second allocated objects/space.  This is followed optionally by a profile
-  # type, and if that is present, optionally by a sampling frequency.
-  # For remote heap profiles (v1):
-  # The interpretation of the sampling frequency is that the profiler, for
-  # each sample, calculates a uniformly distributed random integer less than
-  # the given value, and records the next sample after that many bytes have
-  # been allocated.  Therefore, the expected sample interval is half of the
-  # given frequency.  By default, if not specified, the expected sample
-  # interval is 128KB.  Only remote-heap-page profiles are adjusted for
-  # sample size.
-  # For remote heap profiles (v2):
-  # The sampling frequency is the rate of a Poisson process. This means that
-  # the probability of sampling an allocation of size X with sampling rate Y
-  # is 1 - exp(-X/Y)
-  # For version 2, a typical header line might look like this:
-  # heap profile:   1922: 127792360 [  1922: 127792360] @ <heap-url>_v2/524288
-  # the trailing number (524288) is the sampling rate. (Version 1 showed
-  # double the 'rate' here)
-  my $sampling_algorithm = 0;
-  my $sample_adjustment = 0;
-  chomp($header);
-  my $type = "unknown";
-  if ($header =~ m"^heap profile:\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\](\s*@\s*([^/]*)(/(\d+))?)?") {
-    if (defined($6) && ($6 ne '')) {
-      $type = $6;
-      my $sample_period = $8;
-      # $type is "heapprofile" for profiles generated by the
-      # heap-profiler, and either "heap" or "heap_v2" for profiles
-      # generated by sampling directly within tcmalloc.  It can also
-      # be "growth" for heap-growth profiles.  The first is typically
-      # found for profiles generated locally, and the others for
-      # remote profiles.
-      if (($type eq "heapprofile") || ($type !~ /heap/) ) {
-        # No need to adjust for the sampling rate with heap-profiler-derived data
-        $sampling_algorithm = 0;
-      } elsif ($type =~ /_v2/) {
-        $sampling_algorithm = 2;     # version 2 sampling
-        if (defined($sample_period) && ($sample_period ne '')) {
-          $sample_adjustment = int($sample_period);
-        }
-      } else {
-        $sampling_algorithm = 1;     # version 1 sampling
-        if (defined($sample_period) && ($sample_period ne '')) {
-          $sample_adjustment = int($sample_period)/2;
-        }
-      }
-    } else {
-      # We detect whether or not this is a remote-heap profile by checking
-      # that the total-allocated stats ($n2,$s2) are exactly the
-      # same as the in-use stats ($n1,$s1).  It is remotely conceivable
-      # that a non-remote-heap profile may pass this check, but it is hard
-      # to imagine how that could happen.
-      # In this case it's so old it's guaranteed to be remote-heap version 1.
-      my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4);
-      if (($n1 == $n2) && ($s1 == $s2)) {
-        # This is likely to be a remote-heap based sample profile
-        $sampling_algorithm = 1;
-      }
-    }
-  }
-
-  if ($sampling_algorithm > 0) {
-    # For remote-heap generated profiles, adjust the counts and sizes to
-    # account for the sample rate (we sample once every 128KB by default).
-    if ($sample_adjustment == 0) {
-      # Turn on profile adjustment.
-      $sample_adjustment = 128*1024;
-      print STDERR "Adjusting heap profiles for 1-in-128KB sampling rate\n";
-    } else {
-      printf STDERR ("Adjusting heap profiles for 1-in-%d sampling rate\n",
-                     $sample_adjustment);
-    }
-    if ($sampling_algorithm > 1) {
-      # We don't bother printing anything for the original version (version 1)
-      printf STDERR "Heap version $sampling_algorithm\n";
-    }
-  }
-
-  my $profile = {};
-  my $pcs = {};
-  my $map = "";
-
-  while (<PROFILE>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    if (/^MAPPED_LIBRARIES:/) {
-      # Read the /proc/self/maps data
-      while (<PROFILE>) {
-        s/\r//g;         # turn windows-looking lines into unix-looking lines
-        $map .= $_;
-      }
-      last;
-    }
-
-    if (/^--- Memory map:/) {
-      # Read /proc/self/maps data as formatted by DumpAddressMap()
-      my $buildvar = "";
-      while (<PROFILE>) {
-        s/\r//g;         # turn windows-looking lines into unix-looking lines
-        # Parse "build=<dir>" specification if supplied
-        if (m/^\s*build=(.*)\n/) {
-          $buildvar = $1;
-        }
-
-        # Expand "$build" variable if available
-        $_ =~ s/\$build\b/$buildvar/g;
-
-        $map .= $_;
-      }
-      last;
-    }
-
-    # Read entry of the form:
-    #  <count1>: <bytes1> [<count2>: <bytes2>] @ a1 a2 a3 ... an
-    s/^\s*//;
-    s/\s*$//;
-    if (m/^\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\]\s+@\s+(.*)$/) {
-      my $stack = $5;
-      my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4);
-
-      if ($sample_adjustment) {
-        if ($sampling_algorithm == 2) {
-          # Remote-heap version 2
-          # The sampling frequency is the rate of a Poisson process.
-          # This means that the probability of sampling an allocation of
-          # size X with sampling rate Y is 1 - exp(-X/Y)
-          if ($n1 != 0) {
-            my $ratio = (($s1*1.0)/$n1)/($sample_adjustment);
-            my $scale_factor = 1/(1 - exp(-$ratio));
-            $n1 *= $scale_factor;
-            $s1 *= $scale_factor;
-          }
-          if ($n2 != 0) {
-            my $ratio = (($s2*1.0)/$n2)/($sample_adjustment);
-            my $scale_factor = 1/(1 - exp(-$ratio));
-            $n2 *= $scale_factor;
-            $s2 *= $scale_factor;
-          }
-        } else {
-          # Remote-heap version 1
-          my $ratio;
-          $ratio = (($s1*1.0)/$n1)/($sample_adjustment);
-          if ($ratio < 1) {
-            $n1 /= $ratio;
-            $s1 /= $ratio;
-          }
-          $ratio = (($s2*1.0)/$n2)/($sample_adjustment);
-          if ($ratio < 1) {
-            $n2 /= $ratio;
-            $s2 /= $ratio;
-          }
-        }
-      }
-
-      my @counts = ($n1, $s1, $n2, $s2);
-      $stack = FixCallerAddresses($stack);
-      push @stackTraces, "$n1 $s1 $n2 $s2 $stack";
-      AddEntries($profile, $pcs, $stack, $counts[$index]);
-    }
-  }
-
-  my $r = {};
-  $r->{version} = "heap";
-  $r->{period} = 1;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-  return $r;
-}
-
-sub ReadSynchProfile {
-  my $prog = shift;
-  local *PROFILE = shift;
-  my $header = shift;
-
-  my $map = '';
-  my $profile = {};
-  my $pcs = {};
-  my $sampling_period = 1;
-  my $cyclespernanosec = 2.8;   # Default assumption for old binaries
-  my $seen_clockrate = 0;
-  my $line;
-
-  my $index = 0;
-  if ($main::opt_total_delay) {
-    $index = 0;
-  } elsif ($main::opt_contentions) {
-    $index = 1;
-  } elsif ($main::opt_mean_delay) {
-    $index = 2;
-  }
-
-  while ( $line = <PROFILE> ) {
-    $line =~ s/\r//g;      # turn windows-looking lines into unix-looking lines
-    if ( $line =~ /^\s*(\d+)\s+(\d+) \@\s*(.*?)\s*$/ ) {
-      my ($cycles, $count, $stack) = ($1, $2, $3);
-
-      # Convert cycles to nanoseconds
-      $cycles /= $cyclespernanosec;
-
-      # Adjust for sampling done by application
-      $cycles *= $sampling_period;
-      $count *= $sampling_period;
-
-      my @values = ($cycles, $count, $cycles / $count);
-      AddEntries($profile, $pcs, FixCallerAddresses($stack), $values[$index]);
-
-    } elsif ( $line =~ /^(slow release).*thread \d+  \@\s*(.*?)\s*$/ ||
-              $line =~ /^\s*(\d+) \@\s*(.*?)\s*$/ ) {
-      my ($cycles, $stack) = ($1, $2);
-      if ($cycles !~ /^\d+$/) {
-        next;
-      }
-
-      # Convert cycles to nanoseconds
-      $cycles /= $cyclespernanosec;
-
-      # Adjust for sampling done by application
-      $cycles *= $sampling_period;
-
-      AddEntries($profile, $pcs, FixCallerAddresses($stack), $cycles);
-
-    } elsif ( $line =~ m/^([a-z][^=]*)=(.*)$/ ) {
-      my ($variable, $value) = ($1,$2);
-      for ($variable, $value) {
-        s/^\s+//;
-        s/\s+$//;
-      }
-      if ($variable eq "cycles/second") {
-        $cyclespernanosec = $value / 1e9;
-        $seen_clockrate = 1;
-      } elsif ($variable eq "sampling period") {
-        $sampling_period = $value;
-      } elsif ($variable eq "ms since reset") {
-        # Currently nothing is done with this value in pprof
-        # So we just silently ignore it for now
-      } elsif ($variable eq "discarded samples") {
-        # Currently nothing is done with this value in pprof
-        # So we just silently ignore it for now
-      } else {
-        printf STDERR ("Ignoring unnknown variable in /contention output: " .
-                       "'%s' = '%s'\n",$variable,$value);
-      }
-    } else {
-      # Memory map entry
-      $map .= $line;
-    }
-  }
-
-  if (!$seen_clockrate) {
-    printf STDERR ("No cycles/second entry in profile; Guessing %.1f GHz\n",
-                   $cyclespernanosec);
-  }
-
-  my $r = {};
-  $r->{version} = 0;
-  $r->{period} = $sampling_period;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-  return $r;
-}
-
-# Given a hex value in the form "0x1abcd" or "1abcd", return either
-# "0001abcd" or "000000000001abcd", depending on the current (global)
-# address length.
-sub HexExtend {
-  my $addr = shift;
-
-  $addr =~ s/^(0x)?0*//;
-  my $zeros_needed = $address_length - length($addr);
-  if ($zeros_needed < 0) {
-    printf STDERR "Warning: address $addr is longer than address length $address_length\n";
-    return $addr;
-  }
-  return ("0" x $zeros_needed) . $addr;
-}
-
-##### Symbol extraction #####
-
-# Aggressively search the lib_prefix values for the given library
-# If all else fails, just return the name of the library unmodified.
-# If the lib_prefix is "/my/path,/other/path" and $file is "/lib/dir/mylib.so"
-# it will search the following locations in this order, until it finds a file:
-#   /my/path/lib/dir/mylib.so
-#   /other/path/lib/dir/mylib.so
-#   /my/path/dir/mylib.so
-#   /other/path/dir/mylib.so
-#   /my/path/mylib.so
-#   /other/path/mylib.so
-#   /lib/dir/mylib.so              (returned as last resort)
-sub FindLibrary {
-  my $file = shift;
-  my $suffix = $file;
-
-  # Search for the library as described above
-  do {
-    foreach my $prefix (@prefix_list) {
-      my $fullpath = $prefix . $suffix;
-      if (-e $fullpath) {
-        return $fullpath;
-      }
-    }
-  } while ($suffix =~ s|^/[^/]+/|/|);
-  return $file;
-}
-
-# Return path to library with debugging symbols.
-# For libc libraries, the copy in /usr/lib/debug contains debugging symbols
-sub DebuggingLibrary {
-  my $file = shift;
-  if ($file =~ m|^/| && -f "/usr/lib/debug$file") {
-    return "/usr/lib/debug$file";
-  }
-  if ($file =~ m|^/| && -f "/usr/lib/debug$file.debug") {
-    return "/usr/lib/debug$file.debug";
-  }
-  return undef;
-}
-
-# Parse text section header of a library using objdump
-sub ParseTextSectionHeaderFromObjdump {
-  my $lib = shift;
-
-  my $size = undef;
-  my $vma;
-  my $file_offset;
-  # Get objdump output from the library file to figure out how to
-  # map between mapped addresses and addresses in the library.
-  my $cmd = ShellEscape($obj_tool_map{"objdump"}, "-h", $lib);
-  open(OBJDUMP, "$cmd |") || error("$cmd: $!\n");
-  while (<OBJDUMP>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    # Idx Name          Size      VMA       LMA       File off  Algn
-    #  10 .text         00104b2c  420156f0  420156f0  000156f0  2**4
-    # For 64-bit objects, VMA and LMA will be 16 hex digits, size and file
-    # offset may still be 8.  But AddressSub below will still handle that.
-    my @x = split;
-    if (($#x >= 6) && ($x[1] eq '.text')) {
-      $size = $x[2];
-      $vma = $x[3];
-      $file_offset = $x[5];
-      last;
-    }
-  }
-  close(OBJDUMP);
-
-  if (!defined($size)) {
-    return undef;
-  }
-
-  my $r = {};
-  $r->{size} = $size;
-  $r->{vma} = $vma;
-  $r->{file_offset} = $file_offset;
-
-  return $r;
-}
-
-# Parse text section header of a library using otool (on OS X)
-sub ParseTextSectionHeaderFromOtool {
-  my $lib = shift;
-
-  my $size = undef;
-  my $vma = undef;
-  my $file_offset = undef;
-  # Get otool output from the library file to figure out how to
-  # map between mapped addresses and addresses in the library.
-  my $command = ShellEscape($obj_tool_map{"otool"}, "-l", $lib);
-  open(OTOOL, "$command |") || error("$command: $!\n");
-  my $cmd = "";
-  my $sectname = "";
-  my $segname = "";
-  foreach my $line (<OTOOL>) {
-    $line =~ s/\r//g;      # turn windows-looking lines into unix-looking lines
-    # Load command <#>
-    #       cmd LC_SEGMENT
-    # [...]
-    # Section
-    #   sectname __text
-    #    segname __TEXT
-    #       addr 0x000009f8
-    #       size 0x00018b9e
-    #     offset 2552
-    #      align 2^2 (4)
-    # We will need to strip off the leading 0x from the hex addresses,
-    # and convert the offset into hex.
-    if ($line =~ /Load command/) {
-      $cmd = "";
-      $sectname = "";
-      $segname = "";
-    } elsif ($line =~ /Section/) {
-      $sectname = "";
-      $segname = "";
-    } elsif ($line =~ /cmd (\w+)/) {
-      $cmd = $1;
-    } elsif ($line =~ /sectname (\w+)/) {
-      $sectname = $1;
-    } elsif ($line =~ /segname (\w+)/) {
-      $segname = $1;
-    } elsif (!(($cmd eq "LC_SEGMENT" || $cmd eq "LC_SEGMENT_64") &&
-               $sectname eq "__text" &&
-               $segname eq "__TEXT")) {
-      next;
-    } elsif ($line =~ /\baddr 0x([0-9a-fA-F]+)/) {
-      $vma = $1;
-    } elsif ($line =~ /\bsize 0x([0-9a-fA-F]+)/) {
-      $size = $1;
-    } elsif ($line =~ /\boffset ([0-9]+)/) {
-      $file_offset = sprintf("%016x", $1);
-    }
-    if (defined($vma) && defined($size) && defined($file_offset)) {
-      last;
-    }
-  }
-  close(OTOOL);
-
-  if (!defined($vma) || !defined($size) || !defined($file_offset)) {
-     return undef;
-  }
-
-  my $r = {};
-  $r->{size} = $size;
-  $r->{vma} = $vma;
-  $r->{file_offset} = $file_offset;
-
-  return $r;
-}
-
-sub ParseTextSectionHeader {
-  # obj_tool_map("otool") is only defined if we're in a Mach-O environment
-  if (defined($obj_tool_map{"otool"})) {
-    my $r = ParseTextSectionHeaderFromOtool(@_);
-    if (defined($r)){
-      return $r;
-    }
-  }
-  # If otool doesn't work, or we don't have it, fall back to objdump
-  return ParseTextSectionHeaderFromObjdump(@_);
-}
-
-# Split /proc/pid/maps dump into a list of libraries
-sub ParseLibraries {
-  return if $main::use_symbol_page;  # We don't need libraries info.
-  my $prog = Cwd::abs_path(shift);
-  my $map = shift;
-  my $pcs = shift;
-
-  my $result = [];
-  my $h = "[a-f0-9]+";
-  my $zero_offset = HexExtend("0");
-
-  my $buildvar = "";
-  foreach my $l (split("\n", $map)) {
-    if ($l =~ m/^\s*build=(.*)$/) {
-      $buildvar = $1;
-    }
-
-    my $start;
-    my $finish;
-    my $offset;
-    my $lib;
-    if ($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(.+\.(so|dll|dylib|bundle|node)((\.\d+)+\w*(\.\d+){0,3})?)$/i) {
-      # Full line from /proc/self/maps.  Example:
-      #   40000000-40015000 r-xp 00000000 03:01 12845071   /lib/ld-2.3.2.so
-      $start = HexExtend($1);
-      $finish = HexExtend($2);
-      $offset = HexExtend($3);
-      $lib = $4;
-      $lib =~ s|\\|/|g;     # turn windows-style paths into unix-style paths
-    } elsif ($l =~ /^\s*($h)-($h):\s*(\S+\.so(\.\d+)*)/) {
-      # Cooked line from DumpAddressMap.  Example:
-      #   40000000-40015000: /lib/ld-2.3.2.so
-      $start = HexExtend($1);
-      $finish = HexExtend($2);
-      $offset = $zero_offset;
-      $lib = $3;
-    } elsif (($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(\S+)$/i) && ($4 eq $prog)) {
-      # PIEs and address space randomization do not play well with our
-      # default assumption that main executable is at lowest
-      # addresses. So we're detecting main executable in
-      # /proc/self/maps as well.
-      $start = HexExtend($1);
-      $finish = HexExtend($2);
-      $offset = HexExtend($3);
-      $lib = $4;
-      $lib =~ s|\\|/|g;     # turn windows-style paths into unix-style paths
-    } else {
-      next;
-    }
-
-    # Expand "$build" variable if available
-    $lib =~ s/\$build\b/$buildvar/g;
-
-    $lib = FindLibrary($lib);
-
-    # Check for pre-relocated libraries, which use pre-relocated symbol tables
-    # and thus require adjusting the offset that we'll use to translate
-    # VM addresses into symbol table addresses.
-    # Only do this if we're not going to fetch the symbol table from a
-    # debugging copy of the library.
-    if (!DebuggingLibrary($lib)) {
-      my $text = ParseTextSectionHeader($lib);
-      if (defined($text)) {
-         my $vma_offset = AddressSub($text->{vma}, $text->{file_offset});
-         $offset = AddressAdd($offset, $vma_offset);
-      }
-    }
-
-    push(@{$result}, [$lib, $start, $finish, $offset]);
-  }
-
-  # Append special entry for additional library (not relocated)
-  if ($main::opt_lib ne "") {
-    my $text = ParseTextSectionHeader($main::opt_lib);
-    if (defined($text)) {
-       my $start = $text->{vma};
-       my $finish = AddressAdd($start, $text->{size});
-
-       push(@{$result}, [$main::opt_lib, $start, $finish, $start]);
-    }
-  }
-
-  # Append special entry for the main program.  This covers
-  # 0..max_pc_value_seen, so that we assume pc values not found in one
-  # of the library ranges will be treated as coming from the main
-  # program binary.
-  my $min_pc = HexExtend("0");
-  my $max_pc = $min_pc;          # find the maximal PC value in any sample
-  foreach my $pc (keys(%{$pcs})) {
-    if (HexExtend($pc) gt $max_pc) { $max_pc = HexExtend($pc); }
-  }
-  push(@{$result}, [$prog, $min_pc, $max_pc, $zero_offset]);
-
-  return $result;
-}
-
-# Add two hex addresses of length $address_length.
-# Run pprof --test for unit test if this is changed.
-sub AddressAdd {
-  my $addr1 = shift;
-  my $addr2 = shift;
-  my $sum;
-
-  if ($address_length == 8) {
-    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:
-    $sum = (hex($addr1)+hex($addr2)) % (0x10000000 * 16);
-    return sprintf("%08x", $sum);
-
-  } else {
-    # Do the addition in 7-nibble chunks to trivialize carry handling.
-
-    if ($main::opt_debug and $main::opt_test) {
-      print STDERR "AddressAdd $addr1 + $addr2 = ";
-    }
-
-    my $a1 = substr($addr1,-7);
-    $addr1 = substr($addr1,0,-7);
-    my $a2 = substr($addr2,-7);
-    $addr2 = substr($addr2,0,-7);
-    $sum = hex($a1) + hex($a2);
-    my $c = 0;
-    if ($sum > 0xfffffff) {
-      $c = 1;
-      $sum -= 0x10000000;
-    }
-    my $r = sprintf("%07x", $sum);
-
-    $a1 = substr($addr1,-7);
-    $addr1 = substr($addr1,0,-7);
-    $a2 = substr($addr2,-7);
-    $addr2 = substr($addr2,0,-7);
-    $sum = hex($a1) + hex($a2) + $c;
-    $c = 0;
-    if ($sum > 0xfffffff) {
-      $c = 1;
-      $sum -= 0x10000000;
-    }
-    $r = sprintf("%07x", $sum) . $r;
-
-    $sum = hex($addr1) + hex($addr2) + $c;
-    if ($sum > 0xff) { $sum -= 0x100; }
-    $r = sprintf("%02x", $sum) . $r;
-
-    if ($main::opt_debug and $main::opt_test) { print STDERR "$r\n"; }
-
-    return $r;
-  }
-}
-
-
-# Subtract two hex addresses of length $address_length.
-# Run pprof --test for unit test if this is changed.
-sub AddressSub {
-  my $addr1 = shift;
-  my $addr2 = shift;
-  my $diff;
-
-  if ($address_length == 8) {
-    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:
-    $diff = (hex($addr1)-hex($addr2)) % (0x10000000 * 16);
-    return sprintf("%08x", $diff);
-
-  } else {
-    # Do the addition in 7-nibble chunks to trivialize borrow handling.
-    # if ($main::opt_debug) { print STDERR "AddressSub $addr1 - $addr2 = "; }
-
-    my $a1 = hex(substr($addr1,-7));
-    $addr1 = substr($addr1,0,-7);
-    my $a2 = hex(substr($addr2,-7));
-    $addr2 = substr($addr2,0,-7);
-    my $b = 0;
-    if ($a2 > $a1) {
-      $b = 1;
-      $a1 += 0x10000000;
-    }
-    $diff = $a1 - $a2;
-    my $r = sprintf("%07x", $diff);
-
-    $a1 = hex(substr($addr1,-7));
-    $addr1 = substr($addr1,0,-7);
-    $a2 = hex(substr($addr2,-7)) + $b;
-    $addr2 = substr($addr2,0,-7);
-    $b = 0;
-    if ($a2 > $a1) {
-      $b = 1;
-      $a1 += 0x10000000;
-    }
-    $diff = $a1 - $a2;
-    $r = sprintf("%07x", $diff) . $r;
-
-    $a1 = hex($addr1);
-    $a2 = hex($addr2) + $b;
-    if ($a2 > $a1) { $a1 += 0x100; }
-    $diff = $a1 - $a2;
-    $r = sprintf("%02x", $diff) . $r;
-
-    # if ($main::opt_debug) { print STDERR "$r\n"; }
-
-    return $r;
-  }
-}
-
-# Increment a hex addresses of length $address_length.
-# Run pprof --test for unit test if this is changed.
-sub AddressInc {
-  my $addr = shift;
-  my $sum;
-
-  if ($address_length == 8) {
-    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:
-    $sum = (hex($addr)+1) % (0x10000000 * 16);
-    return sprintf("%08x", $sum);
-
-  } else {
-    # Do the addition in 7-nibble chunks to trivialize carry handling.
-    # We are always doing this to step through the addresses in a function,
-    # and will almost never overflow the first chunk, so we check for this
-    # case and exit early.
-
-    # if ($main::opt_debug) { print STDERR "AddressInc $addr1 = "; }
-
-    my $a1 = substr($addr,-7);
-    $addr = substr($addr,0,-7);
-    $sum = hex($a1) + 1;
-    my $r = sprintf("%07x", $sum);
-    if ($sum <= 0xfffffff) {
-      $r = $addr . $r;
-      # if ($main::opt_debug) { print STDERR "$r\n"; }
-      return HexExtend($r);
-    } else {
-      $r = "0000000";
-    }
-
-    $a1 = substr($addr,-7);
-    $addr = substr($addr,0,-7);
-    $sum = hex($a1) + 1;
-    $r = sprintf("%07x", $sum) . $r;
-    if ($sum <= 0xfffffff) {
-      $r = $addr . $r;
-      # if ($main::opt_debug) { print STDERR "$r\n"; }
-      return HexExtend($r);
-    } else {
-      $r = "00000000000000";
-    }
-
-    $sum = hex($addr) + 1;
-    if ($sum > 0xff) { $sum -= 0x100; }
-    $r = sprintf("%02x", $sum) . $r;
-
-    # if ($main::opt_debug) { print STDERR "$r\n"; }
-    return $r;
-  }
-}
-
-# Extract symbols for all PC values found in profile
-sub ExtractSymbols {
-  my $libs = shift;
-  my $pcset = shift;
-
-  my $symbols = {};
-
-  # Map each PC value to the containing library.  To make this faster,
-  # we sort libraries by their starting pc value (highest first), and
-  # advance through the libraries as we advance the pc.  Sometimes the
-  # addresses of libraries may overlap with the addresses of the main
-  # binary, so to make sure the libraries 'win', we iterate over the
-  # libraries in reverse order (which assumes the binary doesn't start
-  # in the middle of a library, which seems a fair assumption).
-  my @pcs = (sort { $a cmp $b } keys(%{$pcset}));  # pcset is 0-extended strings
-  foreach my $lib (sort {$b->[1] cmp $a->[1]} @{$libs}) {
-    my $libname = $lib->[0];
-    my $start = $lib->[1];
-    my $finish = $lib->[2];
-    my $offset = $lib->[3];
-
-    # Get list of pcs that belong in this library.
-    my $contained = [];
-    my ($start_pc_index, $finish_pc_index);
-    # Find smallest finish_pc_index such that $finish < $pc[$finish_pc_index].
-    for ($finish_pc_index = $#pcs + 1; $finish_pc_index > 0;
-         $finish_pc_index--) {
-      last if $pcs[$finish_pc_index - 1] le $finish;
-    }
-    # Find smallest start_pc_index such that $start <= $pc[$start_pc_index].
-    for ($start_pc_index = $finish_pc_index; $start_pc_index > 0;
-         $start_pc_index--) {
-      last if $pcs[$start_pc_index - 1] lt $start;
-    }
-    # This keeps PC values higher than $pc[$finish_pc_index] in @pcs,
-    # in case there are overlaps in libraries and the main binary.
-    @{$contained} = splice(@pcs, $start_pc_index,
-                           $finish_pc_index - $start_pc_index);
-    # Map to symbols
-    MapToSymbols($libname, AddressSub($start, $offset), $contained, $symbols);
-  }
-
-  return $symbols;
-}
-
-# Map list of PC values to symbols for a given image
-sub MapToSymbols {
-  my $image = shift;
-  my $offset = shift;
-  my $pclist = shift;
-  my $symbols = shift;
-
-  my $debug = 0;
-
-  # For libc (and other) libraries, the copy in /usr/lib/debug contains debugging symbols
-  my $debugging = DebuggingLibrary($image);
-  if ($debugging) {
-    $image = $debugging;
-  }
-
-  # Ignore empty binaries
-  if ($#{$pclist} < 0) { return; }
-
-  # Figure out the addr2line command to use
-  my $addr2line = $obj_tool_map{"addr2line"};
-  my $cmd = ShellEscape($addr2line, "-f", "-C", "-e", $image);
-  if (exists $obj_tool_map{"addr2line_pdb"}) {
-    $addr2line = $obj_tool_map{"addr2line_pdb"};
-    $cmd = ShellEscape($addr2line, "--demangle", "-f", "-C", "-e", $image);
-  }
-
-  # If "addr2line" isn't installed on the system at all, just use
-  # nm to get what info we can (function names, but not line numbers).
-  if (system(ShellEscape($addr2line, "--help") . " >$dev_null 2>&1") != 0) {
-    MapSymbolsWithNM($image, $offset, $pclist, $symbols);
-    return;
-  }
-
-  # "addr2line -i" can produce a variable number of lines per input
-  # address, with no separator that allows us to tell when data for
-  # the next address starts.  So we find the address for a special
-  # symbol (_fini) and interleave this address between all real
-  # addresses passed to addr2line.  The name of this special symbol
-  # can then be used as a separator.
-  $sep_address = undef;  # May be filled in by MapSymbolsWithNM()
-  my $nm_symbols = {};
-  MapSymbolsWithNM($image, $offset, $pclist, $nm_symbols);
-  if (defined($sep_address)) {
-    # Only add " -i" to addr2line if the binary supports it.
-    # addr2line --help returns 0, but not if it sees an unknown flag first.
-    if (system("$cmd -i --help >$dev_null 2>&1") == 0) {
-      $cmd .= " -i";
-    } else {
-      $sep_address = undef;   # no need for sep_address if we don't support -i
-    }
-  }
-
-  # Make file with all PC values with intervening 'sep_address' so
-  # that we can reliably detect the end of inlined function list
-  open(ADDRESSES, ">$main::tmpfile_sym") || error("$main::tmpfile_sym: $!\n");
-  if ($debug) { print("---- $image ---\n"); }
-  for (my $i = 0; $i <= $#{$pclist}; $i++) {
-    # addr2line always reads hex addresses, and does not need '0x' prefix.
-    if ($debug) { printf STDERR ("%s\n", $pclist->[$i]); }
-    printf ADDRESSES ("%s\n", AddressSub($pclist->[$i], $offset));
-    if (defined($sep_address)) {
-      printf ADDRESSES ("%s\n", $sep_address);
-    }
-  }
-  close(ADDRESSES);
-  if ($debug) {
-    print("----\n");
-    system("cat", $main::tmpfile_sym);
-    print("---- $cmd ---\n");
-    system("$cmd < " . ShellEscape($main::tmpfile_sym));
-    print("----\n");
-  }
-
-  open(SYMBOLS, "$cmd <" . ShellEscape($main::tmpfile_sym) . " |")
-      || error("$cmd: $!\n");
-  my $count = 0;   # Index in pclist
-  while (<SYMBOLS>) {
-    # Read fullfunction and filelineinfo from next pair of lines
-    s/\r?\n$//g;
-    my $fullfunction = $_;
-    $_ = <SYMBOLS>;
-    s/\r?\n$//g;
-    my $filelinenum = $_;
-
-    if (defined($sep_address) && $fullfunction eq $sep_symbol) {
-      # Terminating marker for data for this address
-      $count++;
-      next;
-    }
-
-    $filelinenum =~ s|\\|/|g; # turn windows-style paths into unix-style paths
-
-    # Remove discriminator markers as this comes after the line number and
-    # confuses the rest of this script.
-    $filelinenum =~ s/ \(discriminator \d+\)$//;
-    # Convert unknown line numbers into line 0.
-    $filelinenum =~ s/:\?$/:0/;
-
-    my $pcstr = $pclist->[$count];
-    my $function = ShortFunctionName($fullfunction);
-    my $nms = $nm_symbols->{$pcstr};
-    if (defined($nms)) {
-      if ($fullfunction eq '??') {
-        # nm found a symbol for us.
-        $function = $nms->[0];
-        $fullfunction = $nms->[2];
-      } else {
-	# MapSymbolsWithNM tags each routine with its starting address,
-	# useful in case the image has multiple occurrences of this
-	# routine.  (It uses a syntax that resembles template paramters,
-	# that are automatically stripped out by ShortFunctionName().)
-	# addr2line does not provide the same information.  So we check
-	# if nm disambiguated our symbol, and if so take the annotated
-	# (nm) version of the routine-name.  TODO(csilvers): this won't
-	# catch overloaded, inlined symbols, which nm doesn't see.
-	# Better would be to do a check similar to nm's, in this fn.
-	if ($nms->[2] =~ m/^\Q$function\E/) {  # sanity check it's the right fn
-	  $function = $nms->[0];
-	  $fullfunction = $nms->[2];
-	}
-      }
-    }
-    
-    # Prepend to accumulated symbols for pcstr
-    # (so that caller comes before callee)
-    my $sym = $symbols->{$pcstr};
-    if (!defined($sym)) {
-      $sym = [];
-      $symbols->{$pcstr} = $sym;
-    }
-    unshift(@{$sym}, $function, $filelinenum, $fullfunction);
-    if ($debug) { printf STDERR ("%s => [%s]\n", $pcstr, join(" ", @{$sym})); }
-    if (!defined($sep_address)) {
-      # Inlining is off, so this entry ends immediately
-      $count++;
-    }
-  }
-  close(SYMBOLS);
-}
-
-# Use nm to map the list of referenced PCs to symbols.  Return true iff we
-# are able to read procedure information via nm.
-sub MapSymbolsWithNM {
-  my $image = shift;
-  my $offset = shift;
-  my $pclist = shift;
-  my $symbols = shift;
-
-  # Get nm output sorted by increasing address
-  my $symbol_table = GetProcedureBoundaries($image, ".");
-  if (!%{$symbol_table}) {
-    return 0;
-  }
-  # Start addresses are already the right length (8 or 16 hex digits).
-  my @names = sort { $symbol_table->{$a}->[0] cmp $symbol_table->{$b}->[0] }
-    keys(%{$symbol_table});
-
-  if ($#names < 0) {
-    # No symbols: just use addresses
-    foreach my $pc (@{$pclist}) {
-      my $pcstr = "0x" . $pc;
-      $symbols->{$pc} = [$pcstr, "?", $pcstr];
-    }
-    return 0;
-  }
-
-  # Sort addresses so we can do a join against nm output
-  my $index = 0;
-  my $fullname = $names[0];
-  my $name = ShortFunctionName($fullname);
-  foreach my $pc (sort { $a cmp $b } @{$pclist}) {
-    # Adjust for mapped offset
-    my $mpc = AddressSub($pc, $offset);
-    while (($index < $#names) && ($mpc ge $symbol_table->{$fullname}->[1])){
-      $index++;
-      $fullname = $names[$index];
-      $name = ShortFunctionName($fullname);
-    }
-    if ($mpc lt $symbol_table->{$fullname}->[1]) {
-      $symbols->{$pc} = [$name, "?", $fullname];
-    } else {
-      my $pcstr = "0x" . $pc;
-      $symbols->{$pc} = [$pcstr, "?", $pcstr];
-    }
-  }
-  return 1;
-}
-
-sub ShortFunctionName {
-  my $function = shift;
-  while ($function =~ s/\([^()]*\)(\s*const)?//g) { }   # Argument types
-  $function =~ s/<[0-9a-f]*>$//g;                # Remove Address
-  if (!$main::opt_no_strip_temp) {
-      while ($function =~ s/<[^<>]*>//g)  { }   # Remove template arguments
-  }
-  $function =~ s/^.*\s+(\w+::)/$1/;          # Remove leading type
-  return $function;
-}
-
-# Trim overly long symbols found in disassembler output
-sub CleanDisassembly {
-  my $d = shift;
-  while ($d =~ s/\([^()%]*\)(\s*const)?//g) { } # Argument types, not (%rax)
-  while ($d =~ s/(\w+)<[^<>]*>/$1/g)  { }       # Remove template arguments
-  return $d;
-}
-
-# Clean file name for display
-sub CleanFileName {
-  my ($f) = @_;
-  $f =~ s|^/proc/self/cwd/||;
-  $f =~ s|^\./||;
-  return $f;
-}
-
-# Make address relative to section and clean up for display
-sub UnparseAddress {
-  my ($offset, $address) = @_;
-  $address = AddressSub($address, $offset);
-  $address =~ s/^0x//;
-  $address =~ s/^0*//;
-  return $address;
-}
-
-##### Miscellaneous #####
-
-# Find the right versions of the above object tools to use.  The
-# argument is the program file being analyzed, and should be an ELF
-# 32-bit or ELF 64-bit executable file.  The location of the tools
-# is determined by considering the following options in this order:
-#   1) --tools option, if set
-#   2) PPROF_TOOLS environment variable, if set
-#   3) the environment
-sub ConfigureObjTools {
-  my $prog_file = shift;
-
-  # Check for the existence of $prog_file because /usr/bin/file does not
-  # predictably return error status in prod.
-  (-e $prog_file)  || error("$prog_file does not exist.\n");
-
-  my $file_type = undef;
-  if (-e "/usr/bin/file") {
-    # Follow symlinks (at least for systems where "file" supports that).
-    my $escaped_prog_file = ShellEscape($prog_file);
-    $file_type = `/usr/bin/file -L $escaped_prog_file 2>$dev_null ||
-                  /usr/bin/file $escaped_prog_file`;
-  } elsif ($^O == "MSWin32") {
-    $file_type = "MS Windows";
-  } else {
-    print STDERR "WARNING: Can't determine the file type of $prog_file";
-  }
-
-  if ($file_type =~ /64-bit/) {
-    # Change $address_length to 16 if the program file is ELF 64-bit.
-    # We can't detect this from many (most?) heap or lock contention
-    # profiles, since the actual addresses referenced are generally in low
-    # memory even for 64-bit programs.
-    $address_length = 16;
-  }
-
-  if ($file_type =~ /MS Windows/) {
-    # For windows, we provide a version of nm and addr2line as part of
-    # the opensource release, which is capable of parsing
-    # Windows-style PDB executables.  It should live in the path, or
-    # in the same directory as pprof.
-    $obj_tool_map{"nm_pdb"} = "nm-pdb";
-    $obj_tool_map{"addr2line_pdb"} = "addr2line-pdb";
-  }
-
-  if ($file_type =~ /Mach-O/) {
-    # OS X uses otool to examine Mach-O files, rather than objdump.
-    $obj_tool_map{"otool"} = "otool";
-    $obj_tool_map{"addr2line"} = "false";  # no addr2line
-    $obj_tool_map{"objdump"} = "false";  # no objdump
-  }
-
-  # Go fill in %obj_tool_map with the pathnames to use:
-  foreach my $tool (keys %obj_tool_map) {
-    $obj_tool_map{$tool} = ConfigureTool($obj_tool_map{$tool});
-  }
-}
-
-# Returns the path of a caller-specified object tool.  If --tools or
-# PPROF_TOOLS are specified, then returns the full path to the tool
-# with that prefix.  Otherwise, returns the path unmodified (which
-# means we will look for it on PATH).
-sub ConfigureTool {
-  my $tool = shift;
-  my $path;
-
-  # --tools (or $PPROF_TOOLS) is a comma separated list, where each
-  # item is either a) a pathname prefix, or b) a map of the form
-  # <tool>:<path>.  First we look for an entry of type (b) for our
-  # tool.  If one is found, we use it.  Otherwise, we consider all the
-  # pathname prefixes in turn, until one yields an existing file.  If
-  # none does, we use a default path.
-  my $tools = $main::opt_tools || $ENV{"PPROF_TOOLS"} || "";
-  if ($tools =~ m/(,|^)\Q$tool\E:([^,]*)/) {
-    $path = $2;
-    # TODO(csilvers): sanity-check that $path exists?  Hard if it's relative.
-  } elsif ($tools ne '') {
-    foreach my $prefix (split(',', $tools)) {
-      next if ($prefix =~ /:/);    # ignore "tool:fullpath" entries in the list
-      if (-x $prefix . $tool) {
-        $path = $prefix . $tool;
-        last;
-      }
-    }
-    if (!$path) {
-      error("No '$tool' found with prefix specified by " .
-            "--tools (or \$PPROF_TOOLS) '$tools'\n");
-    }
-  } else {
-    # ... otherwise use the version that exists in the same directory as
-    # pprof.  If there's nothing there, use $PATH.
-    $0 =~ m,[^/]*$,;     # this is everything after the last slash
-    my $dirname = $`;    # this is everything up to and including the last slash
-    if (-x "$dirname$tool") {
-      $path = "$dirname$tool";
-    } else { 
-      $path = $tool;
-    }
-  }
-  if ($main::opt_debug) { print STDERR "Using '$path' for '$tool'.\n"; }
-  return $path;
-}
-
-sub ShellEscape {
-  my @escaped_words = ();
-  foreach my $word (@_) {
-    my $escaped_word = $word;
-    if ($word =~ m![^a-zA-Z0-9/.,_=-]!) {  # check for anything not in whitelist
-      $escaped_word =~ s/'/'\\''/;
-      $escaped_word = "'$escaped_word'";
-    }
-    push(@escaped_words, $escaped_word);
-  }
-  return join(" ", @escaped_words);
-}
-
-sub cleanup {
-  unlink($main::tmpfile_sym);
-  unlink(keys %main::tempnames);
-
-  # We leave any collected profiles in $HOME/pprof in case the user wants
-  # to look at them later.  We print a message informing them of this.
-  if ((scalar(@main::profile_files) > 0) &&
-      defined($main::collected_profile)) {
-    if (scalar(@main::profile_files) == 1) {
-      print STDERR "Dynamically gathered profile is in $main::collected_profile\n";
-    }
-    print STDERR "If you want to investigate this profile further, you can do:\n";
-    print STDERR "\n";
-    print STDERR "  $0 \\\n";
-    print STDERR "    $main::prog \\\n";
-    print STDERR "    $main::collected_profile\n";
-    print STDERR "\n";
-  }
-}
-
-sub sighandler {
-  cleanup();
-  exit(1);
-}
-
-sub error {
-  my $msg = shift;
-  print STDERR $msg;
-  cleanup();
-  exit(1);
-}
-
-
-# Run $nm_command and get all the resulting procedure boundaries whose
-# names match "$regexp" and returns them in a hashtable mapping from
-# procedure name to a two-element vector of [start address, end address]
-sub GetProcedureBoundariesViaNm {
-  my $escaped_nm_command = shift;    # shell-escaped
-  my $regexp = shift;
-  my $image = shift;
-
-  my $symbol_table = {};
-  open(NM, "$escaped_nm_command |") || error("$escaped_nm_command: $!\n");
-  my $last_start = "0";
-  my $routine = "";
-  while (<NM>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    if (m/^\s*([0-9a-f]+) (.) (..*)/) {
-      my $start_val = $1;
-      my $type = $2;
-      my $this_routine = $3;
-
-      # It's possible for two symbols to share the same address, if
-      # one is a zero-length variable (like __start_google_malloc) or
-      # one symbol is a weak alias to another (like __libc_malloc).
-      # In such cases, we want to ignore all values except for the
-      # actual symbol, which in nm-speak has type "T".  The logic
-      # below does this, though it's a bit tricky: what happens when
-      # we have a series of lines with the same address, is the first
-      # one gets queued up to be processed.  However, it won't
-      # *actually* be processed until later, when we read a line with
-      # a different address.  That means that as long as we're reading
-      # lines with the same address, we have a chance to replace that
-      # item in the queue, which we do whenever we see a 'T' entry --
-      # that is, a line with type 'T'.  If we never see a 'T' entry,
-      # we'll just go ahead and process the first entry (which never
-      # got touched in the queue), and ignore the others.
-      if ($start_val eq $last_start && $type =~ /t/i) {
-        # We are the 'T' symbol at this address, replace previous symbol.
-        $routine = $this_routine;
-        next;
-      } elsif ($start_val eq $last_start) {
-        # We're not the 'T' symbol at this address, so ignore us.
-        next;
-      }
-
-      if ($this_routine eq $sep_symbol) {
-        $sep_address = HexExtend($start_val);
-      }
-
-      # Tag this routine with the starting address in case the image
-      # has multiple occurrences of this routine.  We use a syntax
-      # that resembles template paramters that are automatically
-      # stripped out by ShortFunctionName()
-      $this_routine .= "<$start_val>";
-
-      if (defined($routine) && $routine =~ m/$regexp/) {
-        $symbol_table->{$routine} = [HexExtend($last_start),
-                                     HexExtend($start_val)];
-      }
-      $last_start = $start_val;
-      $routine = $this_routine;
-    } elsif (m/^Loaded image name: (.+)/) {
-      # The win32 nm workalike emits information about the binary it is using.
-      if ($main::opt_debug) { print STDERR "Using Image $1\n"; }
-    } elsif (m/^PDB file name: (.+)/) {
-      # The win32 nm workalike emits information about the pdb it is using.
-      if ($main::opt_debug) { print STDERR "Using PDB $1\n"; }
-    }
-  }
-  close(NM);
-  # Handle the last line in the nm output.  Unfortunately, we don't know
-  # how big this last symbol is, because we don't know how big the file
-  # is.  For now, we just give it a size of 0.
-  # TODO(csilvers): do better here.
-  if (defined($routine) && $routine =~ m/$regexp/) {
-    $symbol_table->{$routine} = [HexExtend($last_start),
-                                 HexExtend($last_start)];
-  }
-
-  # Verify if addr2line can find the $sep_symbol.  If not, we use objdump
-  # to find the address for the $sep_symbol on code section which addr2line
-  # can find.
-  if (defined($sep_address)){
-    my $start_val = $sep_address;
-    my $addr2line = $obj_tool_map{"addr2line"};
-    my $cmd = ShellEscape($addr2line, "-f", "-C", "-e", $image, "-i");
-    open(FINI, "echo $start_val | $cmd  |")
-         || error("echo $start_val | $cmd: $!\n");
-    $_ = <FINI>;
-    s/\r?\n$//g;
-    my $fini = $_;
-    close(FINI);
-    if ($fini ne $sep_symbol){
-      my $objdump =  $obj_tool_map{"objdump"};
-      $cmd = ShellEscape($objdump, "-d", $image);
-      my $grep = ShellEscape("grep", $sep_symbol);
-      my $tail = ShellEscape("tail", "-n", "1");
-      open(FINI, "$cmd | $grep | $tail |")
-           || error("$cmd | $grep | $tail: $!\n");
-      s/\r//g; # turn windows-looking lines into unix-looking lines
-      my $data = <FINI>;
-      if (defined($data)){
-        ($start_val, $fini) = split(/ </,$data);
-      }
-      close(FINI);
-    }
-    $sep_address = HexExtend($start_val);
-  }
-
-  return $symbol_table;
-}
-
-# Gets the procedure boundaries for all routines in "$image" whose names
-# match "$regexp" and returns them in a hashtable mapping from procedure
-# name to a two-element vector of [start address, end address].
-# Will return an empty map if nm is not installed or not working properly.
-sub GetProcedureBoundaries {
-  my $image = shift;
-  my $regexp = shift;
-
-  # If $image doesn't start with /, then put ./ in front of it.  This works
-  # around an obnoxious bug in our probing of nm -f behavior.
-  # "nm -f $image" is supposed to fail on GNU nm, but if:
-  #
-  # a. $image starts with [BbSsPp] (for example, bin/foo/bar), AND
-  # b. you have a.out in your current directory (a not uncommon occurrence)
-  #
-  # then "nm -f $image" succeeds because -f only looks at the first letter of
-  # the argument, which looks valid because it's [BbSsPp], and then since
-  # there's no image provided, it looks for a.out and finds it.
-  #
-  # This regex makes sure that $image starts with . or /, forcing the -f
-  # parsing to fail since . and / are not valid formats.
-  $image =~ s#^[^/]#./$&#;
-
-  # For libc libraries, the copy in /usr/lib/debug contains debugging symbols
-  my $debugging = DebuggingLibrary($image);
-  if ($debugging) {
-    $image = $debugging;
-  }
-
-  my $nm = $obj_tool_map{"nm"};
-  my $cppfilt = $obj_tool_map{"c++filt"};
-
-  # nm can fail for two reasons: 1) $image isn't a debug library; 2) nm
-  # binary doesn't support --demangle.  In addition, for OS X we need
-  # to use the -f flag to get 'flat' nm output (otherwise we don't sort
-  # properly and get incorrect results).  Unfortunately, GNU nm uses -f
-  # in an incompatible way.  So first we test whether our nm supports
-  # --demangle and -f.
-  my $demangle_flag = "";
-  my $cppfilt_flag = "";
-  my $to_devnull = ">$dev_null 2>&1";
-  if (system(ShellEscape($nm, "--demangle", "image") . $to_devnull) == 0) {
-    # In this mode, we do "nm --demangle <foo>"
-    $demangle_flag = "--demangle";
-    $cppfilt_flag = "";
-  } elsif (system(ShellEscape($cppfilt, $image) . $to_devnull) == 0) {
-    # In this mode, we do "nm <foo> | c++filt"
-    $cppfilt_flag = " | " . ShellEscape($cppfilt);
-  };
-  my $flatten_flag = "";
-  if (system(ShellEscape($nm, "-f", $image) . $to_devnull) == 0) {
-    $flatten_flag = "-f";
-  }
-
-  # Finally, in the case $imagie isn't a debug library, we try again with
-  # -D to at least get *exported* symbols.  If we can't use --demangle,
-  # we use c++filt instead, if it exists on this system.
-  my @nm_commands = (ShellEscape($nm, "-n", $flatten_flag, $demangle_flag,
-                                 $image) . " 2>$dev_null $cppfilt_flag",
-                     ShellEscape($nm, "-D", "-n", $flatten_flag, $demangle_flag,
-                                 $image) . " 2>$dev_null $cppfilt_flag",
-                     # 6nm is for Go binaries
-                     ShellEscape("6nm", "$image") . " 2>$dev_null | sort",
-                     );
-
-  # If the executable is an MS Windows PDB-format executable, we'll
-  # have set up obj_tool_map("nm_pdb").  In this case, we actually
-  # want to use both unix nm and windows-specific nm_pdb, since
-  # PDB-format executables can apparently include dwarf .o files.
-  if (exists $obj_tool_map{"nm_pdb"}) {
-    push(@nm_commands,
-         ShellEscape($obj_tool_map{"nm_pdb"}, "--demangle", $image)
-         . " 2>$dev_null");
-  }
-
-  foreach my $nm_command (@nm_commands) {
-    my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp, $image);
-    return $symbol_table if (%{$symbol_table});
-  }
-  my $symbol_table = {};
-  return $symbol_table;
-}
-
-
-# The test vectors for AddressAdd/Sub/Inc are 8-16-nibble hex strings.
-# To make them more readable, we add underscores at interesting places.
-# This routine removes the underscores, producing the canonical representation
-# used by pprof to represent addresses, particularly in the tested routines.
-sub CanonicalHex {
-  my $arg = shift;
-  return join '', (split '_',$arg);
-}
-
-
-# Unit test for AddressAdd:
-sub AddressAddUnitTest {
-  my $test_data_8 = shift;
-  my $test_data_16 = shift;
-  my $error_count = 0;
-  my $fail_count = 0;
-  my $pass_count = 0;
-  # print STDERR "AddressAddUnitTest: ", 1+$#{$test_data_8}, " tests\n";
-
-  # First a few 8-nibble addresses.  Note that this implementation uses
-  # plain old arithmetic, so a quick sanity check along with verifying what
-  # happens to overflow (we want it to wrap):
-  $address_length = 8;
-  foreach my $row (@{$test_data_8}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressAdd ($row->[0], $row->[1]);
-    if ($sum ne $row->[2]) {
-      printf STDERR "ERROR: %s != %s + %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[2];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressAdd 32-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count = $fail_count;
-  $fail_count = 0;
-  $pass_count = 0;
-
-  # Now 16-nibble addresses.
-  $address_length = 16;
-  foreach my $row (@{$test_data_16}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressAdd (CanonicalHex($row->[0]), CanonicalHex($row->[1]));
-    my $expected = join '', (split '_',$row->[2]);
-    if ($sum ne CanonicalHex($row->[2])) {
-      printf STDERR "ERROR: %s != %s + %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[2];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressAdd 64-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count += $fail_count;
-
-  return $error_count;
-}
-
-
-# Unit test for AddressSub:
-sub AddressSubUnitTest {
-  my $test_data_8 = shift;
-  my $test_data_16 = shift;
-  my $error_count = 0;
-  my $fail_count = 0;
-  my $pass_count = 0;
-  # print STDERR "AddressSubUnitTest: ", 1+$#{$test_data_8}, " tests\n";
-
-  # First a few 8-nibble addresses.  Note that this implementation uses
-  # plain old arithmetic, so a quick sanity check along with verifying what
-  # happens to overflow (we want it to wrap):
-  $address_length = 8;
-  foreach my $row (@{$test_data_8}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressSub ($row->[0], $row->[1]);
-    if ($sum ne $row->[3]) {
-      printf STDERR "ERROR: %s != %s - %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[3];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressSub 32-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count = $fail_count;
-  $fail_count = 0;
-  $pass_count = 0;
-
-  # Now 16-nibble addresses.
-  $address_length = 16;
-  foreach my $row (@{$test_data_16}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressSub (CanonicalHex($row->[0]), CanonicalHex($row->[1]));
-    if ($sum ne CanonicalHex($row->[3])) {
-      printf STDERR "ERROR: %s != %s - %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[3];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressSub 64-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count += $fail_count;
-
-  return $error_count;
-}
-
-
-# Unit test for AddressInc:
-sub AddressIncUnitTest {
-  my $test_data_8 = shift;
-  my $test_data_16 = shift;
-  my $error_count = 0;
-  my $fail_count = 0;
-  my $pass_count = 0;
-  # print STDERR "AddressIncUnitTest: ", 1+$#{$test_data_8}, " tests\n";
-
-  # First a few 8-nibble addresses.  Note that this implementation uses
-  # plain old arithmetic, so a quick sanity check along with verifying what
-  # happens to overflow (we want it to wrap):
-  $address_length = 8;
-  foreach my $row (@{$test_data_8}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressInc ($row->[0]);
-    if ($sum ne $row->[4]) {
-      printf STDERR "ERROR: %s != %s + 1 = %s\n", $sum,
-             $row->[0], $row->[4];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressInc 32-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count = $fail_count;
-  $fail_count = 0;
-  $pass_count = 0;
-
-  # Now 16-nibble addresses.
-  $address_length = 16;
-  foreach my $row (@{$test_data_16}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressInc (CanonicalHex($row->[0]));
-    if ($sum ne CanonicalHex($row->[4])) {
-      printf STDERR "ERROR: %s != %s + 1 = %s\n", $sum,
-             $row->[0], $row->[4];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressInc 64-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count += $fail_count;
-
-  return $error_count;
-}
-
-
-# Driver for unit tests.
-# Currently just the address add/subtract/increment routines for 64-bit.
-sub RunUnitTests {
-  my $error_count = 0;
-
-  # This is a list of tuples [a, b, a+b, a-b, a+1]
-  my $unit_test_data_8 = [
-    [qw(aaaaaaaa 50505050 fafafafa 5a5a5a5a aaaaaaab)],
-    [qw(50505050 aaaaaaaa fafafafa a5a5a5a6 50505051)],
-    [qw(ffffffff aaaaaaaa aaaaaaa9 55555555 00000000)],
-    [qw(00000001 ffffffff 00000000 00000002 00000002)],
-    [qw(00000001 fffffff0 fffffff1 00000011 00000002)],
-  ];
-  my $unit_test_data_16 = [
-    # The implementation handles data in 7-nibble chunks, so those are the
-    # interesting boundaries.
-    [qw(aaaaaaaa 50505050
-        00_000000f_afafafa 00_0000005_a5a5a5a 00_000000a_aaaaaab)],
-    [qw(50505050 aaaaaaaa
-        00_000000f_afafafa ff_ffffffa_5a5a5a6 00_0000005_0505051)],
-    [qw(ffffffff aaaaaaaa
-        00_000001a_aaaaaa9 00_0000005_5555555 00_0000010_0000000)],
-    [qw(00000001 ffffffff
-        00_0000010_0000000 ff_ffffff0_0000002 00_0000000_0000002)],
-    [qw(00000001 fffffff0
-        00_000000f_ffffff1 ff_ffffff0_0000011 00_0000000_0000002)],
-
-    [qw(00_a00000a_aaaaaaa 50505050
-        00_a00000f_afafafa 00_a000005_a5a5a5a 00_a00000a_aaaaaab)],
-    [qw(0f_fff0005_0505050 aaaaaaaa
-        0f_fff000f_afafafa 0f_ffefffa_5a5a5a6 0f_fff0005_0505051)],
-    [qw(00_000000f_fffffff 01_800000a_aaaaaaa
-        01_800001a_aaaaaa9 fe_8000005_5555555 00_0000010_0000000)],
-    [qw(00_0000000_0000001 ff_fffffff_fffffff
-        00_0000000_0000000 00_0000000_0000002 00_0000000_0000002)],
-    [qw(00_0000000_0000001 ff_fffffff_ffffff0
-        ff_fffffff_ffffff1 00_0000000_0000011 00_0000000_0000002)],
-  ];
-
-  $error_count += AddressAddUnitTest($unit_test_data_8, $unit_test_data_16);
-  $error_count += AddressSubUnitTest($unit_test_data_8, $unit_test_data_16);
-  $error_count += AddressIncUnitTest($unit_test_data_8, $unit_test_data_16);
-  if ($error_count > 0) {
-    print STDERR $error_count, " errors: FAILED\n";
-  } else {
-    print STDERR "PASS\n";
-  }
-  exit ($error_count);
-}
diff --git a/third_party/tcmalloc/vendor/src/profile-handler.cc b/third_party/tcmalloc/vendor/src/profile-handler.cc
deleted file mode 100644
index 7fdcb69..0000000
--- a/third_party/tcmalloc/vendor/src/profile-handler.cc
+++ /dev/null
@@ -1,584 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//         Nabeel Mian
-//
-// Implements management of profile timers and the corresponding signal handler.
-
-#include "config.h"
-#include "profile-handler.h"
-
-#if !(defined(__CYGWIN__) || defined(__CYGWIN32__))
-
-#include <stdio.h>
-#include <errno.h>
-#include <sys/time.h>
-
-#include <list>
-#include <string>
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-// for timer_{create,settime} and associated typedefs & constants
-#include <time.h>
-// for sys_gettid
-#include "base/linux_syscall_support.h"
-// for perftools_pthread_key_create
-#include "maybe_threads.h"
-#endif
-
-#include "base/dynamic_annotations.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "maybe_threads.h"
-
-using std::list;
-using std::string;
-
-// This structure is used by ProfileHandlerRegisterCallback and
-// ProfileHandlerUnregisterCallback as a handle to a registered callback.
-struct ProfileHandlerToken {
-  // Sets the callback and associated arg.
-  ProfileHandlerToken(ProfileHandlerCallback cb, void* cb_arg)
-      : callback(cb),
-        callback_arg(cb_arg) {
-  }
-
-  // Callback function to be invoked on receiving a profile timer interrupt.
-  ProfileHandlerCallback callback;
-  // Argument for the callback function.
-  void* callback_arg;
-};
-
-// Blocks a signal from being delivered to the current thread while the object
-// is alive. Unblocks it upon destruction.
-class ScopedSignalBlocker {
- public:
-  ScopedSignalBlocker(int signo) {
-    sigemptyset(&sig_set_);
-    sigaddset(&sig_set_, signo);
-    RAW_CHECK(sigprocmask(SIG_BLOCK, &sig_set_, NULL) == 0,
-              "sigprocmask (block)");
-  }
-  ~ScopedSignalBlocker() {
-    RAW_CHECK(sigprocmask(SIG_UNBLOCK, &sig_set_, NULL) == 0,
-              "sigprocmask (unblock)");
-  }
-
- private:
-  sigset_t sig_set_;
-};
-
-// This class manages profile timers and associated signal handler. This is a
-// a singleton.
-class ProfileHandler {
- public:
-  // Registers the current thread with the profile handler.
-  void RegisterThread();
-
-  // Registers a callback routine to receive profile timer ticks. The returned
-  // token is to be used when unregistering this callback and must not be
-  // deleted by the caller.
-  ProfileHandlerToken* RegisterCallback(ProfileHandlerCallback callback,
-                                        void* callback_arg);
-
-  // Unregisters a previously registered callback. Expects the token returned
-  // by the corresponding RegisterCallback routine.
-  void UnregisterCallback(ProfileHandlerToken* token)
-      NO_THREAD_SAFETY_ANALYSIS;
-
-  // Unregisters all the callbacks and stops the timer(s).
-  void Reset();
-
-  // Gets the current state of profile handler.
-  void GetState(ProfileHandlerState* state);
-
-  // Initializes and returns the ProfileHandler singleton.
-  static ProfileHandler* Instance();
-
- private:
-  ProfileHandler();
-  ~ProfileHandler();
-
-  // Largest allowed frequency.
-  static const int32 kMaxFrequency = 4000;
-  // Default frequency.
-  static const int32 kDefaultFrequency = 100;
-
-  // ProfileHandler singleton.
-  static ProfileHandler* instance_;
-
-  // pthread_once_t for one time initialization of ProfileHandler singleton.
-  static pthread_once_t once_;
-
-  // Initializes the ProfileHandler singleton via GoogleOnceInit.
-  static void Init();
-
-  // Timer state as configured previously.
-  bool timer_running_;
-
-  // The number of profiling signal interrupts received.
-  int64 interrupts_ GUARDED_BY(signal_lock_);
-
-  // Profiling signal interrupt frequency, read-only after construction.
-  int32 frequency_;
-
-  // ITIMER_PROF (which uses SIGPROF), or ITIMER_REAL (which uses SIGALRM).
-  // Translated into an equivalent choice of clock if per_thread_timer_enabled_
-  // is true.
-  int timer_type_;
-
-  // Signal number for timer signal.
-  int signal_number_;
-
-  // Counts the number of callbacks registered.
-  int32 callback_count_ GUARDED_BY(control_lock_);
-
-  // Is profiling allowed at all?
-  bool allowed_;
-
-  // Must be false if HAVE_LINUX_SIGEV_THREAD_ID is not defined.
-  bool per_thread_timer_enabled_;
-
-#ifdef HAVE_LINUX_SIGEV_THREAD_ID
-  // this is used to destroy per-thread profiling timers on thread
-  // termination
-  pthread_key_t thread_timer_key;
-#endif
-
-  // This lock serializes the registration of threads and protects the
-  // callbacks_ list below.
-  // Locking order:
-  // In the context of a signal handler, acquire signal_lock_ to walk the
-  // callback list. Otherwise, acquire control_lock_, disable the signal
-  // handler and then acquire signal_lock_.
-  SpinLock control_lock_ ACQUIRED_BEFORE(signal_lock_);
-  SpinLock signal_lock_;
-
-  // Holds the list of registered callbacks. We expect the list to be pretty
-  // small. Currently, the cpu profiler (base/profiler) and thread module
-  // (base/thread.h) are the only two components registering callbacks.
-  // Following are the locking requirements for callbacks_:
-  // For read-write access outside the SIGPROF handler:
-  //  - Acquire control_lock_
-  //  - Disable SIGPROF handler.
-  //  - Acquire signal_lock_
-  // For read-only access in the context of SIGPROF handler
-  // (Read-write access is *not allowed* in the SIGPROF handler)
-  //  - Acquire signal_lock_
-  // For read-only access outside SIGPROF handler:
-  //  - Acquire control_lock_
-  typedef list<ProfileHandlerToken*> CallbackList;
-  typedef CallbackList::iterator CallbackIterator;
-  CallbackList callbacks_ GUARDED_BY(signal_lock_);
-
-  // Starts or stops the interval timer.
-  // Will ignore any requests to enable or disable when
-  // per_thread_timer_enabled_ is true.
-  void UpdateTimer(bool enable) EXCLUSIVE_LOCKS_REQUIRED(signal_lock_);
-
-  // Returns true if the handler is not being used by something else.
-  // This checks the kernel's signal handler table.
-  bool IsSignalHandlerAvailable();
-
-  // Signal handler. Iterates over and calls all the registered callbacks.
-  static void SignalHandler(int sig, siginfo_t* sinfo, void* ucontext);
-
-  DISALLOW_COPY_AND_ASSIGN(ProfileHandler);
-};
-
-ProfileHandler* ProfileHandler::instance_ = NULL;
-pthread_once_t ProfileHandler::once_ = PTHREAD_ONCE_INIT;
-
-const int32 ProfileHandler::kMaxFrequency;
-const int32 ProfileHandler::kDefaultFrequency;
-
-// If we are LD_PRELOAD-ed against a non-pthreads app, then these functions
-// won't be defined.  We declare them here, for that case (with weak linkage)
-// which will cause the non-definition to resolve to NULL.  We can then check
-// for NULL or not in Instance.
-extern "C" {
-int pthread_once(pthread_once_t *, void (*)(void)) ATTRIBUTE_WEAK;
-int pthread_kill(pthread_t thread_id, int signo) ATTRIBUTE_WEAK;
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-int timer_create(clockid_t clockid, struct sigevent* evp,
-                 timer_t* timerid) ATTRIBUTE_WEAK;
-int timer_delete(timer_t timerid) ATTRIBUTE_WEAK;
-int timer_settime(timer_t timerid, int flags, const struct itimerspec* value,
-                  struct itimerspec* ovalue) ATTRIBUTE_WEAK;
-#endif
-}
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-
-struct timer_id_holder {
-  timer_t timerid;
-  timer_id_holder(timer_t _timerid) : timerid(_timerid) {}
-};
-
-extern "C" {
-  static void ThreadTimerDestructor(void *arg) {
-    if (!arg) {
-      return;
-    }
-    timer_id_holder *holder = static_cast<timer_id_holder *>(arg);
-    timer_delete(holder->timerid);
-    delete holder;
-  }
-}
-
-static void CreateThreadTimerKey(pthread_key_t *pkey) {
-  int rv = perftools_pthread_key_create(pkey, ThreadTimerDestructor);
-  if (rv) {
-    RAW_LOG(FATAL, "aborting due to pthread_key_create error: %s", strerror(rv));
-  }
-}
-
-static void StartLinuxThreadTimer(int timer_type, int signal_number,
-                                  int32 frequency, pthread_key_t timer_key) {
-  int rv;
-  struct sigevent sevp;
-  timer_t timerid;
-  struct itimerspec its;
-  memset(&sevp, 0, sizeof(sevp));
-  sevp.sigev_notify = SIGEV_THREAD_ID;
-  sevp._sigev_un._tid = sys_gettid();
-  sevp.sigev_signo = signal_number;
-  clockid_t clock = CLOCK_THREAD_CPUTIME_ID;
-  if (timer_type == ITIMER_REAL) {
-    clock = CLOCK_MONOTONIC;
-  }
-  rv = timer_create(clock, &sevp, &timerid);
-  if (rv) {
-    RAW_LOG(FATAL, "aborting due to timer_create error: %s", strerror(errno));
-  }
-
-  timer_id_holder *holder = new timer_id_holder(timerid);
-  rv = perftools_pthread_setspecific(timer_key, holder);
-  if (rv) {
-    RAW_LOG(FATAL, "aborting due to pthread_setspecific error: %s", strerror(rv));
-  }
-
-  its.it_interval.tv_sec = 0;
-  its.it_interval.tv_nsec = 1000000000 / frequency;
-  its.it_value = its.it_interval;
-  rv = timer_settime(timerid, 0, &its, 0);
-  if (rv) {
-    RAW_LOG(FATAL, "aborting due to timer_settime error: %s", strerror(errno));
-  }
-}
-#endif
-
-void ProfileHandler::Init() {
-  instance_ = new ProfileHandler();
-}
-
-ProfileHandler* ProfileHandler::Instance() {
-  if (pthread_once) {
-    pthread_once(&once_, Init);
-  }
-  if (instance_ == NULL) {
-    // This will be true on systems that don't link in pthreads,
-    // including on FreeBSD where pthread_once has a non-zero address
-    // (but doesn't do anything) even when pthreads isn't linked in.
-    Init();
-    assert(instance_ != NULL);
-  }
-  return instance_;
-}
-
-ProfileHandler::ProfileHandler()
-    : timer_running_(false),
-      interrupts_(0),
-      callback_count_(0),
-      allowed_(true),
-      per_thread_timer_enabled_(false) {
-  SpinLockHolder cl(&control_lock_);
-
-  timer_type_ = (getenv("CPUPROFILE_REALTIME") ? ITIMER_REAL : ITIMER_PROF);
-  signal_number_ = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
-
-  // Get frequency of interrupts (if specified)
-  char junk;
-  const char* fr = getenv("CPUPROFILE_FREQUENCY");
-  if (fr != NULL && (sscanf(fr, "%u%c", &frequency_, &junk) == 1) &&
-      (frequency_ > 0)) {
-    // Limit to kMaxFrequency
-    frequency_ = (frequency_ > kMaxFrequency) ? kMaxFrequency : frequency_;
-  } else {
-    frequency_ = kDefaultFrequency;
-  }
-
-  if (!allowed_) {
-    return;
-  }
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-  // Do this early because we might be overriding signal number.
-
-  const char *per_thread = getenv("CPUPROFILE_PER_THREAD_TIMERS");
-  const char *signal_number = getenv("CPUPROFILE_TIMER_SIGNAL");
-
-  if (per_thread || signal_number) {
-    if (timer_create && pthread_once) {
-      CreateThreadTimerKey(&thread_timer_key);
-      per_thread_timer_enabled_ = true;
-      // Override signal number if requested.
-      if (signal_number) {
-        signal_number_ = strtol(signal_number, NULL, 0);
-      }
-    } else {
-      RAW_LOG(INFO,
-              "Ignoring CPUPROFILE_PER_THREAD_TIMERS and\n"
-              " CPUPROFILE_TIMER_SIGNAL due to lack of timer_create().\n"
-              " Preload or link to librt.so for this to work");
-    }
-  }
-#endif
-
-  // If something else is using the signal handler,
-  // assume it has priority over us and stop.
-  if (!IsSignalHandlerAvailable()) {
-    RAW_LOG(INFO, "Disabling profiler because signal %d handler is already in use.",
-            signal_number_);
-    allowed_ = false;
-    return;
-  }
-
-  // Install the signal handler.
-  struct sigaction sa;
-  sa.sa_sigaction = SignalHandler;
-  sa.sa_flags = SA_RESTART | SA_SIGINFO;
-  sigemptyset(&sa.sa_mask);
-  RAW_CHECK(sigaction(signal_number_, &sa, NULL) == 0, "sigprof (enable)");
-}
-
-ProfileHandler::~ProfileHandler() {
-  Reset();
-#ifdef HAVE_LINUX_SIGEV_THREAD_ID
-  if (per_thread_timer_enabled_) {
-    perftools_pthread_key_delete(thread_timer_key);
-  }
-#endif
-}
-
-void ProfileHandler::RegisterThread() {
-  SpinLockHolder cl(&control_lock_);
-
-  if (!allowed_) {
-    return;
-  }
-
-  // Record the thread identifier and start the timer if profiling is on.
-  ScopedSignalBlocker block(signal_number_);
-  SpinLockHolder sl(&signal_lock_);
-#if HAVE_LINUX_SIGEV_THREAD_ID
-  if (per_thread_timer_enabled_) {
-    StartLinuxThreadTimer(timer_type_, signal_number_, frequency_,
-                          thread_timer_key);
-    return;
-  }
-#endif
-  UpdateTimer(callback_count_ > 0);
-}
-
-ProfileHandlerToken* ProfileHandler::RegisterCallback(
-    ProfileHandlerCallback callback, void* callback_arg) {
-
-  ProfileHandlerToken* token = new ProfileHandlerToken(callback, callback_arg);
-
-  SpinLockHolder cl(&control_lock_);
-  {
-    ScopedSignalBlocker block(signal_number_);
-    SpinLockHolder sl(&signal_lock_);
-    callbacks_.push_back(token);
-    ++callback_count_;
-    UpdateTimer(true);
-  }
-  return token;
-}
-
-void ProfileHandler::UnregisterCallback(ProfileHandlerToken* token) {
-  SpinLockHolder cl(&control_lock_);
-  for (CallbackIterator it = callbacks_.begin(); it != callbacks_.end();
-       ++it) {
-    if ((*it) == token) {
-      RAW_CHECK(callback_count_ > 0, "Invalid callback count");
-      {
-        ScopedSignalBlocker block(signal_number_);
-        SpinLockHolder sl(&signal_lock_);
-        delete *it;
-        callbacks_.erase(it);
-        --callback_count_;
-        if (callback_count_ == 0)
-          UpdateTimer(false);
-      }
-      return;
-    }
-  }
-  // Unknown token.
-  RAW_LOG(FATAL, "Invalid token");
-}
-
-void ProfileHandler::Reset() {
-  SpinLockHolder cl(&control_lock_);
-  {
-    ScopedSignalBlocker block(signal_number_);
-    SpinLockHolder sl(&signal_lock_);
-    CallbackIterator it = callbacks_.begin();
-    while (it != callbacks_.end()) {
-      CallbackIterator tmp = it;
-      ++it;
-      delete *tmp;
-      callbacks_.erase(tmp);
-    }
-    callback_count_ = 0;
-    UpdateTimer(false);
-  }
-}
-
-void ProfileHandler::GetState(ProfileHandlerState* state) {
-  SpinLockHolder cl(&control_lock_);
-  {
-    ScopedSignalBlocker block(signal_number_);
-    SpinLockHolder sl(&signal_lock_);  // Protects interrupts_.
-    state->interrupts = interrupts_;
-  }
-  state->frequency = frequency_;
-  state->callback_count = callback_count_;
-  state->allowed = allowed_;
-}
-
-void ProfileHandler::UpdateTimer(bool enable) {
-  if (per_thread_timer_enabled_) {
-    // Ignore any attempts to disable it because that's not supported, and it's
-    // always enabled so enabling is always a NOP.
-    return;
-  }
-
-  if (enable == timer_running_) {
-    return;
-  }
-  timer_running_ = enable;
-
-  struct itimerval timer;
-  static const int kMillion = 1000000;
-  int interval_usec = enable ? kMillion / frequency_ : 0;
-  timer.it_interval.tv_sec = interval_usec / kMillion;
-  timer.it_interval.tv_usec = interval_usec % kMillion;
-  timer.it_value = timer.it_interval;
-  setitimer(timer_type_, &timer, 0);
-}
-
-bool ProfileHandler::IsSignalHandlerAvailable() {
-  struct sigaction sa;
-  RAW_CHECK(sigaction(signal_number_, NULL, &sa) == 0, "is-signal-handler avail");
-
-  // We only take over the handler if the current one is unset.
-  // It must be SIG_IGN or SIG_DFL, not some other function.
-  // SIG_IGN must be allowed because when profiling is allowed but
-  // not actively in use, this code keeps the handler set to SIG_IGN.
-  // That setting will be inherited across fork+exec.  In order for
-  // any child to be able to use profiling, SIG_IGN must be treated
-  // as available.
-  return sa.sa_handler == SIG_IGN || sa.sa_handler == SIG_DFL;
-}
-
-void ProfileHandler::SignalHandler(int sig, siginfo_t* sinfo, void* ucontext) {
-  int saved_errno = errno;
-  // At this moment, instance_ must be initialized because the handler is
-  // enabled in RegisterThread or RegisterCallback only after
-  // ProfileHandler::Instance runs.
-  ProfileHandler* instance = ANNOTATE_UNPROTECTED_READ(instance_);
-  RAW_CHECK(instance != NULL, "ProfileHandler is not initialized");
-  {
-    SpinLockHolder sl(&instance->signal_lock_);
-    ++instance->interrupts_;
-    for (CallbackIterator it = instance->callbacks_.begin();
-         it != instance->callbacks_.end();
-         ++it) {
-      (*it)->callback(sig, sinfo, ucontext, (*it)->callback_arg);
-    }
-  }
-  errno = saved_errno;
-}
-
-// This module initializer registers the main thread, so it must be
-// executed in the context of the main thread.
-REGISTER_MODULE_INITIALIZER(profile_main, ProfileHandlerRegisterThread());
-
-void ProfileHandlerRegisterThread() {
-  ProfileHandler::Instance()->RegisterThread();
-}
-
-ProfileHandlerToken* ProfileHandlerRegisterCallback(
-    ProfileHandlerCallback callback, void* callback_arg) {
-  return ProfileHandler::Instance()->RegisterCallback(callback, callback_arg);
-}
-
-void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token) {
-  ProfileHandler::Instance()->UnregisterCallback(token);
-}
-
-void ProfileHandlerReset() {
-  return ProfileHandler::Instance()->Reset();
-}
-
-void ProfileHandlerGetState(ProfileHandlerState* state) {
-  ProfileHandler::Instance()->GetState(state);
-}
-
-#else  // OS_CYGWIN
-
-// ITIMER_PROF doesn't work under cygwin.  ITIMER_REAL is available, but doesn't
-// work as well for profiling, and also interferes with alarm().  Because of
-// these issues, unless a specific need is identified, profiler support is
-// disabled under Cygwin.
-void ProfileHandlerRegisterThread() {
-}
-
-ProfileHandlerToken* ProfileHandlerRegisterCallback(
-    ProfileHandlerCallback callback, void* callback_arg) {
-  return NULL;
-}
-
-void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token) {
-}
-
-void ProfileHandlerReset() {
-}
-
-void ProfileHandlerGetState(ProfileHandlerState* state) {
-}
-
-#endif  // OS_CYGWIN
diff --git a/third_party/tcmalloc/vendor/src/profile-handler.h b/third_party/tcmalloc/vendor/src/profile-handler.h
deleted file mode 100644
index 3eae169..0000000
--- a/third_party/tcmalloc/vendor/src/profile-handler.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Nabeel Mian
- *
- * This module manages the cpu profile timers and the associated interrupt
- * handler. When enabled, all threads in the program are profiled.
- *
- * Any component interested in receiving a profile timer interrupt can do so by
- * registering a callback. All registered callbacks must be async-signal-safe.
- *
- * Note: This module requires the sole ownership of the configured timer and
- * signal. The timer defaults to ITIMER_PROF, can be changed to ITIMER_REAL by
- * the environment variable CPUPROFILE_REALTIME, or is changed to a POSIX timer
- * with CPUPROFILE_PER_THREAD_TIMERS. The signal defaults to SIGPROF/SIGALRM to
- * match the choice of timer and can be set to an arbitrary value using
- * CPUPROFILE_TIMER_SIGNAL with CPUPROFILE_PER_THREAD_TIMERS.
- */
-
-#ifndef BASE_PROFILE_HANDLER_H_
-#define BASE_PROFILE_HANDLER_H_
-
-#include "config.h"
-#include <signal.h>
-#ifdef COMPILER_MSVC
-#include "conflict-signal.h"
-#endif
-#include "base/basictypes.h"
-
-/* Forward declaration. */
-struct ProfileHandlerToken;
-
-/*
- * Callback function to be used with ProfilefHandlerRegisterCallback. This
- * function will be called in the context of SIGPROF signal handler and must
- * be async-signal-safe. The first three arguments are the values provided by
- * the SIGPROF signal handler. We use void* to avoid using ucontext_t on
- * non-POSIX systems.
- *
- * Requirements:
- * - Callback must be async-signal-safe.
- * - None of the functions in ProfileHandler are async-signal-safe. Therefore,
- *   callback function *must* not call any of the ProfileHandler functions.
- * - Callback is not required to be re-entrant. At most one instance of
- *   callback can run at a time.
- *
- * Notes:
- * - The SIGPROF signal handler saves and restores errno, so the callback
- *   doesn't need to.
- * - Callback code *must* not acquire lock(s) to serialize access to data shared
- *   with the code outside the signal handler (callback must be
- *   async-signal-safe). If such a serialization is needed, follow the model
- *   used by profiler.cc:
- *
- *   When code other than the signal handler modifies the shared data it must:
- *   - Acquire lock.
- *   - Unregister the callback with the ProfileHandler.
- *   - Modify shared data.
- *   - Re-register the callback.
- *   - Release lock.
- *   and the callback code gets a lockless, read-write access to the data.
- */
-typedef void (*ProfileHandlerCallback)(int sig, siginfo_t* sig_info,
-                                       void* ucontext, void* callback_arg);
-
-/*
- * Registers a new thread with profile handler and should be called only once
- * per thread. The main thread is registered at program startup. This routine
- * is called by the Thread module in google3/thread whenever a new thread is
- * created. This function is not async-signal-safe.
- */
-void ProfileHandlerRegisterThread();
-
-/*
- * Registers a callback routine. This callback function will be called in the
- * context of SIGPROF handler, so must be async-signal-safe. The returned token
- * is to be used when unregistering this callback via
- * ProfileHandlerUnregisterCallback. Registering the first callback enables
- * the SIGPROF signal handler. Caller must not free the returned token. This
- * function is not async-signal-safe.
- */
-ProfileHandlerToken* ProfileHandlerRegisterCallback(
-    ProfileHandlerCallback callback, void* callback_arg);
-
-/*
- * Unregisters a previously registered callback. Expects the token returned
- * by the corresponding ProfileHandlerRegisterCallback and asserts that the
- * passed token is valid. Unregistering the last callback disables the SIGPROF
- * signal handler. It waits for the currently running callback to
- * complete before returning. This function is not async-signal-safe.
- */
-void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token);
-
-/*
- * FOR TESTING ONLY
- * Unregisters all the callbacks, stops the timers (if shared) and disables the
- * SIGPROF handler. All the threads, including the main thread, need to be
- * re-registered after this call. This function is not async-signal-safe.
- */
-void ProfileHandlerReset();
-
-/*
- * Stores profile handler's current state. This function is not
- * async-signal-safe.
- */
-struct ProfileHandlerState {
-  int32 frequency;  /* Profiling frequency */
-  int32 callback_count;  /* Number of callbacks registered */
-  int64 interrupts;  /* Number of interrupts received */
-  bool allowed; /* Profiling is allowed */
-};
-void ProfileHandlerGetState(struct ProfileHandlerState* state);
-
-#endif  /* BASE_PROFILE_HANDLER_H_ */
diff --git a/third_party/tcmalloc/vendor/src/profiledata.cc b/third_party/tcmalloc/vendor/src/profiledata.cc
deleted file mode 100644
index 8b05d3a..0000000
--- a/third_party/tcmalloc/vendor/src/profiledata.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Sanjay Ghemawat
-//         Chris Demetriou (refactoring)
-//
-// Collect profiling data.
-
-#include <config.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <sys/time.h>
-#include <string.h>
-#include <fcntl.h>
-
-#include "profiledata.h"
-
-#include "base/logging.h"
-#include "base/sysinfo.h"
-
-// All of these are initialized in profiledata.h.
-const int ProfileData::kMaxStackDepth;
-const int ProfileData::kAssociativity;
-const int ProfileData::kBuckets;
-const int ProfileData::kBufferLength;
-
-ProfileData::Options::Options()
-    : frequency_(1) {
-}
-
-// This function is safe to call from asynchronous signals (but is not
-// re-entrant).  However, that's not part of its public interface.
-void ProfileData::Evict(const Entry& entry) {
-  const int d = entry.depth;
-  const int nslots = d + 2;     // Number of slots needed in eviction buffer
-  if (num_evicted_ + nslots > kBufferLength) {
-    FlushEvicted();
-    assert(num_evicted_ == 0);
-    assert(nslots <= kBufferLength);
-  }
-  evict_[num_evicted_++] = entry.count;
-  evict_[num_evicted_++] = d;
-  memcpy(&evict_[num_evicted_], entry.stack, d * sizeof(Slot));
-  num_evicted_ += d;
-}
-
-ProfileData::ProfileData()
-    : hash_(0),
-      evict_(0),
-      num_evicted_(0),
-      out_(-1),
-      count_(0),
-      evictions_(0),
-      total_bytes_(0),
-      fname_(0),
-      start_time_(0) {
-}
-
-bool ProfileData::Start(const char* fname,
-                        const ProfileData::Options& options) {
-  if (enabled()) {
-    return false;
-  }
-
-  // Open output file and initialize various data structures
-  int fd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0666);
-  if (fd < 0) {
-    // Can't open outfile for write
-    return false;
-  }
-
-  start_time_ = time(NULL);
-  fname_ = strdup(fname);
-
-  // Reset counters
-  num_evicted_ = 0;
-  count_       = 0;
-  evictions_   = 0;
-  total_bytes_ = 0;
-
-  hash_ = new Bucket[kBuckets];
-  evict_ = new Slot[kBufferLength];
-  memset(hash_, 0, sizeof(hash_[0]) * kBuckets);
-
-  // Record special entries
-  evict_[num_evicted_++] = 0;                     // count for header
-  evict_[num_evicted_++] = 3;                     // depth for header
-  evict_[num_evicted_++] = 0;                     // Version number
-  CHECK_NE(0, options.frequency());
-  int period = 1000000 / options.frequency();
-  evict_[num_evicted_++] = period;                // Period (microseconds)
-  evict_[num_evicted_++] = 0;                     // Padding
-
-  out_ = fd;
-
-  return true;
-}
-
-ProfileData::~ProfileData() {
-  Stop();
-}
-
-// Dump /proc/maps data to fd.  Copied from heap-profile-table.cc.
-#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)
-
-static void FDWrite(int fd, const char* buf, size_t len) {
-  while (len > 0) {
-    ssize_t r;
-    NO_INTR(r = write(fd, buf, len));
-    RAW_CHECK(r >= 0, "write failed");
-    buf += r;
-    len -= r;
-  }
-}
-
-static void DumpProcSelfMaps(int fd) {
-  ProcMapsIterator::Buffer iterbuf;
-  ProcMapsIterator it(0, &iterbuf);   // 0 means "current pid"
-
-  uint64 start, end, offset;
-  int64 inode;
-  char *flags, *filename;
-  ProcMapsIterator::Buffer linebuf;
-  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
-    int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_),
-                                start, end, flags, offset, inode, filename,
-                                0);
-    FDWrite(fd, linebuf.buf_, written);
-  }
-}
-
-void ProfileData::Stop() {
-  if (!enabled()) {
-    return;
-  }
-
-  // Move data from hash table to eviction buffer
-  for (int b = 0; b < kBuckets; b++) {
-    Bucket* bucket = &hash_[b];
-    for (int a = 0; a < kAssociativity; a++) {
-      if (bucket->entry[a].count > 0) {
-        Evict(bucket->entry[a]);
-      }
-    }
-  }
-
-  if (num_evicted_ + 3 > kBufferLength) {
-    // Ensure there is enough room for end of data marker
-    FlushEvicted();
-  }
-
-  // Write end of data marker
-  evict_[num_evicted_++] = 0;         // count
-  evict_[num_evicted_++] = 1;         // depth
-  evict_[num_evicted_++] = 0;         // end of data marker
-  FlushEvicted();
-
-  // Dump "/proc/self/maps" so we get list of mapped shared libraries
-  DumpProcSelfMaps(out_);
-
-  Reset();
-  fprintf(stderr, "PROFILE: interrupts/evictions/bytes = %d/%d/%" PRIuS "\n",
-          count_, evictions_, total_bytes_);
-}
-
-void ProfileData::Reset() {
-  if (!enabled()) {
-    return;
-  }
-
-  // Don't reset count_, evictions_, or total_bytes_ here.  They're used
-  // by Stop to print information about the profile after reset, and are
-  // cleared by Start when starting a new profile.
-  close(out_);
-  delete[] hash_;
-  hash_ = 0;
-  delete[] evict_;
-  evict_ = 0;
-  num_evicted_ = 0;
-  free(fname_);
-  fname_ = 0;
-  start_time_ = 0;
-
-  out_ = -1;
-}
-
-// This function is safe to call from asynchronous signals (but is not
-// re-entrant).  However, that's not part of its public interface.
-void ProfileData::GetCurrentState(State* state) const {
-  if (enabled()) {
-    state->enabled = true;
-    state->start_time = start_time_;
-    state->samples_gathered = count_;
-    int buf_size = sizeof(state->profile_name);
-    strncpy(state->profile_name, fname_, buf_size);
-    state->profile_name[buf_size-1] = '\0';
-  } else {
-    state->enabled = false;
-    state->start_time = 0;
-    state->samples_gathered = 0;
-    state->profile_name[0] = '\0';
-  }
-}
-
-// This function is safe to call from asynchronous signals (but is not
-// re-entrant).  However, that's not part of its public interface.
-void ProfileData::FlushTable() {
-  if (!enabled()) {
-    return;
-  }
-
-  // Move data from hash table to eviction buffer
-  for (int b = 0; b < kBuckets; b++) {
-    Bucket* bucket = &hash_[b];
-    for (int a = 0; a < kAssociativity; a++) {
-      if (bucket->entry[a].count > 0) {
-        Evict(bucket->entry[a]);
-        bucket->entry[a].depth = 0;
-        bucket->entry[a].count = 0;
-      }
-    }
-  }
-
-  // Write out all pending data
-  FlushEvicted();
-}
-
-void ProfileData::Add(int depth, const void* const* stack) {
-  if (!enabled()) {
-    return;
-  }
-
-  if (depth > kMaxStackDepth) depth = kMaxStackDepth;
-  RAW_CHECK(depth > 0, "ProfileData::Add depth <= 0");
-
-  // Make hash-value
-  Slot h = 0;
-  for (int i = 0; i < depth; i++) {
-    Slot slot = reinterpret_cast<Slot>(stack[i]);
-    h = (h << 8) | (h >> (8*(sizeof(h)-1)));
-    h += (slot * 31) + (slot * 7) + (slot * 3);
-  }
-
-  count_++;
-
-  // See if table already has an entry for this trace
-  bool done = false;
-  Bucket* bucket = &hash_[h % kBuckets];
-  for (int a = 0; a < kAssociativity; a++) {
-    Entry* e = &bucket->entry[a];
-    if (e->depth == depth) {
-      bool match = true;
-      for (int i = 0; i < depth; i++) {
-        if (e->stack[i] != reinterpret_cast<Slot>(stack[i])) {
-          match = false;
-          break;
-        }
-      }
-      if (match) {
-        e->count++;
-        done = true;
-        break;
-      }
-    }
-  }
-
-  if (!done) {
-    // Evict entry with smallest count
-    Entry* e = &bucket->entry[0];
-    for (int a = 1; a < kAssociativity; a++) {
-      if (bucket->entry[a].count < e->count) {
-        e = &bucket->entry[a];
-      }
-    }
-    if (e->count > 0) {
-      evictions_++;
-      Evict(*e);
-    }
-
-    // Use the newly evicted entry
-    e->depth = depth;
-    e->count = 1;
-    for (int i = 0; i < depth; i++) {
-      e->stack[i] = reinterpret_cast<Slot>(stack[i]);
-    }
-  }
-}
-
-// This function is safe to call from asynchronous signals (but is not
-// re-entrant).  However, that's not part of its public interface.
-void ProfileData::FlushEvicted() {
-  if (num_evicted_ > 0) {
-    const char* buf = reinterpret_cast<char*>(evict_);
-    size_t bytes = sizeof(evict_[0]) * num_evicted_;
-    total_bytes_ += bytes;
-    FDWrite(out_, buf, bytes);
-  }
-  num_evicted_ = 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/profiledata.h b/third_party/tcmalloc/vendor/src/profiledata.h
deleted file mode 100644
index b94b28cf..0000000
--- a/third_party/tcmalloc/vendor/src/profiledata.h
+++ /dev/null
@@ -1,184 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Sanjay Ghemawat
-//         Chris Demetriou (refactoring)
-//
-// Collect profiling data.
-//
-// The profile data file format is documented in
-// docs/cpuprofile-fileformat.html
-
-
-#ifndef BASE_PROFILEDATA_H_
-#define BASE_PROFILEDATA_H_
-
-#include <config.h>
-#include <time.h>   // for time_t
-#include <stdint.h>
-#include "base/basictypes.h"
-
-// A class that accumulates profile samples and writes them to a file.
-//
-// Each sample contains a stack trace and a count.  Memory usage is
-// reduced by combining profile samples that have the same stack trace
-// by adding up the associated counts.
-//
-// Profile data is accumulated in a bounded amount of memory, and will
-// flushed to a file as necessary to stay within the memory limit.
-//
-// Use of this class assumes external synchronization.  The exact
-// requirements of that synchronization are that:
-//
-//  - 'Add' may be called from asynchronous signals, but is not
-//    re-entrant.
-//
-//  - None of 'Start', 'Stop', 'Reset', 'Flush', and 'Add' may be
-//    called at the same time.
-//
-//  - 'Start', 'Stop', or 'Reset' should not be called while 'Enabled'
-//     or 'GetCurrent' are running, and vice versa.
-//
-// A profiler which uses asyncronous signals to add samples will
-// typically use two locks to protect this data structure:
-//
-//  - A SpinLock which is held over all calls except for the 'Add'
-//    call made from the signal handler.
-//
-//  - A SpinLock which is held over calls to 'Start', 'Stop', 'Reset',
-//    'Flush', and 'Add'.  (This SpinLock should be acquired after
-//    the first SpinLock in all cases where both are needed.)
-class ProfileData {
- public:
-  struct State {
-    bool     enabled;             // Is profiling currently enabled?
-    time_t   start_time;          // If enabled, when was profiling started?
-    char     profile_name[1024];  // Name of file being written, or '\0'
-    int      samples_gathered;    // Number of samples gathered to far (or 0)
-  };
-
-  class Options {
-   public:
-    Options();
-
-    // Get and set the sample frequency.
-    int frequency() const {
-      return frequency_;
-    }
-    void set_frequency(int frequency) {
-      frequency_ = frequency;
-    }
-
-   private:
-    int      frequency_;                  // Sample frequency.
-  };
-
-  static const int kMaxStackDepth = 64;  // Max stack depth stored in profile
-
-  ProfileData();
-  ~ProfileData();
-
-  // If data collection is not already enabled start to collect data
-  // into fname.  Parameters related to this profiling run are specified
-  // by 'options'.
-  //
-  // Returns true if data collection could be started, otherwise (if an
-  // error occurred or if data collection was already enabled) returns
-  // false.
-  bool Start(const char *fname, const Options& options);
-
-  // If data collection is enabled, stop data collection and write the
-  // data to disk.
-  void Stop();
-
-  // Stop data collection without writing anything else to disk, and
-  // discard any collected data.
-  void Reset();
-
-  // If data collection is enabled, record a sample with 'depth'
-  // entries from 'stack'.  (depth must be > 0.)  At most
-  // kMaxStackDepth stack entries will be recorded, starting with
-  // stack[0].
-  //
-  // This function is safe to call from asynchronous signals (but is
-  // not re-entrant).
-  void Add(int depth, const void* const* stack);
-
-  // If data collection is enabled, write the data to disk (and leave
-  // the collector enabled).
-  void FlushTable();
-
-  // Is data collection currently enabled?
-  bool enabled() const { return out_ >= 0; }
-
-  // Get the current state of the data collector.
-  void GetCurrentState(State* state) const;
-
- private:
-  static const int kAssociativity = 4;          // For hashtable
-  static const int kBuckets = 1 << 10;          // For hashtable
-  static const int kBufferLength = 1 << 18;     // For eviction buffer
-
-  // Type of slots: each slot can be either a count, or a PC value
-  typedef uintptr_t Slot;
-
-  // Hash-table/eviction-buffer entry (a.k.a. a sample)
-  struct Entry {
-    Slot count;                  // Number of hits
-    Slot depth;                  // Stack depth
-    Slot stack[kMaxStackDepth];  // Stack contents
-  };
-
-  // Hash table bucket
-  struct Bucket {
-    Entry entry[kAssociativity];
-  };
-
-  Bucket*       hash_;          // hash table
-  Slot*         evict_;         // evicted entries
-  int           num_evicted_;   // how many evicted entries?
-  int           out_;           // fd for output file.
-  int           count_;         // How many samples recorded
-  int           evictions_;     // How many evictions
-  size_t        total_bytes_;   // How much output
-  char*         fname_;         // Profile file name
-  time_t        start_time_;    // Start time, or 0
-
-  // Move 'entry' to the eviction buffer.
-  void Evict(const Entry& entry);
-
-  // Write contents of eviction buffer to disk.
-  void FlushEvicted();
-
-  DISALLOW_COPY_AND_ASSIGN(ProfileData);
-};
-
-#endif  // BASE_PROFILEDATA_H_
diff --git a/third_party/tcmalloc/vendor/src/profiler.cc b/third_party/tcmalloc/vendor/src/profiler.cc
deleted file mode 100644
index f4f5990..0000000
--- a/third_party/tcmalloc/vendor/src/profiler.cc
+++ /dev/null
@@ -1,431 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//         Chris Demetriou (refactoring)
-//
-// Profile current program by sampling stack-trace every so often
-
-#include "config.h"
-#include "getpc.h"      // should be first to get the _GNU_SOURCE dfn
-#include <signal.h>
-#include <assert.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>  // for getpid()
-#endif
-#if defined(HAVE_SYS_UCONTEXT_H)
-#include <sys/ucontext.h>
-#elif defined(HAVE_UCONTEXT_H)
-#include <ucontext.h>
-#elif defined(HAVE_CYGWIN_SIGNAL_H)
-#include <cygwin/signal.h>
-typedef ucontext ucontext_t;
-#else
-typedef int ucontext_t;   // just to quiet the compiler, mostly
-#endif
-#include <sys/time.h>
-#include <string>
-#include <gperftools/profiler.h>
-#include <gperftools/stacktrace.h>
-#include "base/commandlineflags.h"
-#include "base/logging.h"
-#include "base/googleinit.h"
-#include "base/spinlock.h"
-#include "base/sysinfo.h"             /* for GetUniquePathFromEnv, etc */
-#include "profiledata.h"
-#include "profile-handler.h"
-#ifdef HAVE_CONFLICT_SIGNAL_H
-#include "conflict-signal.h"          /* used on msvc machines */
-#endif
-
-using std::string;
-
-DEFINE_bool(cpu_profiler_unittest,
-            EnvToBool("PERFTOOLS_UNITTEST", true),
-            "Determines whether or not we are running under the \
-             control of a unit test. This allows us to include or \
-			 exclude certain behaviours.");
-
-// Collects up all profile data. This is a singleton, which is
-// initialized by a constructor at startup. If no cpu profiler
-// signal is specified then the profiler lifecycle is either
-// manaully controlled via the API or attached to the scope of
-// the singleton (program scope). Otherwise the cpu toggle is
-// used to allow for user selectable control via signal generation.
-// This is very useful for profiling a daemon process without
-// having to start and stop the daemon or having to modify the
-// source code to use the cpu profiler API.
-class CpuProfiler {
- public:
-  CpuProfiler();
-  ~CpuProfiler();
-
-  // Start profiler to write profile info into fname
-  bool Start(const char* fname, const ProfilerOptions* options);
-
-  // Stop profiling and write the data to disk.
-  void Stop();
-
-  // Write the data to disk (and continue profiling).
-  void FlushTable();
-
-  bool Enabled();
-
-  void GetCurrentState(ProfilerState* state);
-
-  static CpuProfiler instance_;
-
- private:
-  // This lock implements the locking requirements described in the ProfileData
-  // documentation, specifically:
-  //
-  // lock_ is held all over all collector_ method calls except for the 'Add'
-  // call made from the signal handler, to protect against concurrent use of
-  // collector_'s control routines. Code other than signal handler must
-  // unregister the signal handler before calling any collector_ method.
-  // 'Add' method in the collector is protected by a guarantee from
-  // ProfileHandle that only one instance of prof_handler can run at a time.
-  SpinLock      lock_;
-  ProfileData   collector_;
-
-  // Filter function and its argument, if any.  (NULL means include all
-  // samples).  Set at start, read-only while running.  Written while holding
-  // lock_, read and executed in the context of SIGPROF interrupt.
-  int           (*filter_)(void*);
-  void*         filter_arg_;
-
-  // Opaque token returned by the profile handler. To be used when calling
-  // ProfileHandlerUnregisterCallback.
-  ProfileHandlerToken* prof_handler_token_;
-
-  // Sets up a callback to receive SIGPROF interrupt.
-  void EnableHandler();
-
-  // Disables receiving SIGPROF interrupt.
-  void DisableHandler();
-
-  // Signal handler that records the interrupted pc in the profile data.
-  static void prof_handler(int sig, siginfo_t*, void* signal_ucontext,
-                           void* cpu_profiler);
-};
-
-// Signal handler that is registered when a user selectable signal
-// number is defined in the environment variable CPUPROFILESIGNAL.
-static void CpuProfilerSwitch(int signal_number)
-{
-    bool static started = false;
-	static unsigned profile_count = 0;
-    static char base_profile_name[1024] = "\0";
-
-	if (base_profile_name[0] == '\0') {
-    	if (!GetUniquePathFromEnv("CPUPROFILE", base_profile_name)) {
-        	RAW_LOG(FATAL,"Cpu profiler switch is registered but no CPUPROFILE is defined");
-        	return;
-    	}
-	}
-    if (!started) 
-    {
-    	char full_profile_name[1024];
-
-		snprintf(full_profile_name, sizeof(full_profile_name), "%s.%u",
-                 base_profile_name, profile_count++);
-
-        if(!ProfilerStart(full_profile_name))
-        {
-            RAW_LOG(FATAL, "Can't turn on cpu profiling for '%s': %s\n",
-                    full_profile_name, strerror(errno));
-        }
-    }
-    else    
-    {
-        ProfilerStop();
-    }
-    started = !started;
-}
-
-// Profile data structure singleton: Constructor will check to see if
-// profiling should be enabled.  Destructor will write profile data
-// out to disk.
-CpuProfiler CpuProfiler::instance_;
-
-// Initialize profiling: activated if getenv("CPUPROFILE") exists.
-CpuProfiler::CpuProfiler()
-    : prof_handler_token_(NULL) {
-  // TODO(cgd) Move this code *out* of the CpuProfile constructor into a
-  // separate object responsible for initialization. With ProfileHandler there
-  // is no need to limit the number of profilers.
-  if (getenv("CPUPROFILE") == NULL) {
-    if (!FLAGS_cpu_profiler_unittest) {
-      RAW_LOG(WARNING, "CPU profiler linked but no valid CPUPROFILE environment variable found\n");
-    }
-    return;
-  }
-
-  // We don't enable profiling if setuid -- it's a security risk
-#ifdef HAVE_GETEUID
-  if (getuid() != geteuid()) {
-    if (!FLAGS_cpu_profiler_unittest) {
-      RAW_LOG(WARNING, "Cannot perform CPU profiling when running with setuid\n");
-    }
-    return;
-  }
-#endif
-
-  char *signal_number_str = getenv("CPUPROFILESIGNAL");
-  if (signal_number_str != NULL) {
-    long int signal_number = strtol(signal_number_str, NULL, 10);
-    if (signal_number >= 1 && signal_number <= 64) {
-      intptr_t old_signal_handler = reinterpret_cast<intptr_t>(signal(signal_number, CpuProfilerSwitch));
-      if (old_signal_handler == 0) {
-        RAW_LOG(INFO,"Using signal %d as cpu profiling switch", signal_number);
-      } else {
-        RAW_LOG(FATAL, "Signal %d already in use\n", signal_number);
-      }
-    } else {
-      RAW_LOG(FATAL, "Signal number %s is invalid\n", signal_number_str);
-    }
-  } else {
-    char fname[PATH_MAX];
-    if (!GetUniquePathFromEnv("CPUPROFILE", fname)) {
-      if (!FLAGS_cpu_profiler_unittest) {
-        RAW_LOG(WARNING, "CPU profiler linked but no valid CPUPROFILE environment variable found\n");
-      }
-      return;
-	}
-
-    if (!Start(fname, NULL)) {
-      RAW_LOG(FATAL, "Can't turn on cpu profiling for '%s': %s\n",
-              fname, strerror(errno));
-    }
-  }
-}
-
-bool CpuProfiler::Start(const char* fname, const ProfilerOptions* options) {
-  SpinLockHolder cl(&lock_);
-
-  if (collector_.enabled()) {
-    return false;
-  }
-
-  ProfileHandlerState prof_handler_state;
-  ProfileHandlerGetState(&prof_handler_state);
-
-  ProfileData::Options collector_options;
-  collector_options.set_frequency(prof_handler_state.frequency);
-  if (!collector_.Start(fname, collector_options)) {
-    return false;
-  }
-
-  filter_ = NULL;
-  if (options != NULL && options->filter_in_thread != NULL) {
-    filter_ = options->filter_in_thread;
-    filter_arg_ = options->filter_in_thread_arg;
-  }
-
-  // Setup handler for SIGPROF interrupts
-  EnableHandler();
-
-  return true;
-}
-
-CpuProfiler::~CpuProfiler() {
-  Stop();
-}
-
-// Stop profiling and write out any collected profile data
-void CpuProfiler::Stop() {
-  SpinLockHolder cl(&lock_);
-
-  if (!collector_.enabled()) {
-    return;
-  }
-
-  // Unregister prof_handler to stop receiving SIGPROF interrupts before
-  // stopping the collector.
-  DisableHandler();
-
-  // DisableHandler waits for the currently running callback to complete and
-  // guarantees no future invocations. It is safe to stop the collector.
-  collector_.Stop();
-}
-
-void CpuProfiler::FlushTable() {
-  SpinLockHolder cl(&lock_);
-
-  if (!collector_.enabled()) {
-    return;
-  }
-
-  // Unregister prof_handler to stop receiving SIGPROF interrupts before
-  // flushing the profile data.
-  DisableHandler();
-
-  // DisableHandler waits for the currently running callback to complete and
-  // guarantees no future invocations. It is safe to flush the profile data.
-  collector_.FlushTable();
-
-  EnableHandler();
-}
-
-bool CpuProfiler::Enabled() {
-  SpinLockHolder cl(&lock_);
-  return collector_.enabled();
-}
-
-void CpuProfiler::GetCurrentState(ProfilerState* state) {
-  ProfileData::State collector_state;
-  {
-    SpinLockHolder cl(&lock_);
-    collector_.GetCurrentState(&collector_state);
-  }
-
-  state->enabled = collector_state.enabled;
-  state->start_time = static_cast<time_t>(collector_state.start_time);
-  state->samples_gathered = collector_state.samples_gathered;
-  int buf_size = sizeof(state->profile_name);
-  strncpy(state->profile_name, collector_state.profile_name, buf_size);
-  state->profile_name[buf_size-1] = '\0';
-}
-
-void CpuProfiler::EnableHandler() {
-  RAW_CHECK(prof_handler_token_ == NULL, "SIGPROF handler already registered");
-  prof_handler_token_ = ProfileHandlerRegisterCallback(prof_handler, this);
-  RAW_CHECK(prof_handler_token_ != NULL, "Failed to set up SIGPROF handler");
-}
-
-void CpuProfiler::DisableHandler() {
-  RAW_CHECK(prof_handler_token_ != NULL, "SIGPROF handler is not registered");
-  ProfileHandlerUnregisterCallback(prof_handler_token_);
-  prof_handler_token_ = NULL;
-}
-
-// Signal handler that records the pc in the profile-data structure. We do no
-// synchronization here.  profile-handler.cc guarantees that at most one
-// instance of prof_handler() will run at a time. All other routines that
-// access the data touched by prof_handler() disable this signal handler before
-// accessing the data and therefore cannot execute concurrently with
-// prof_handler().
-void CpuProfiler::prof_handler(int sig, siginfo_t*, void* signal_ucontext,
-                               void* cpu_profiler) {
-  CpuProfiler* instance = static_cast<CpuProfiler*>(cpu_profiler);
-
-  if (instance->filter_ == NULL ||
-      (*instance->filter_)(instance->filter_arg_)) {
-    void* stack[ProfileData::kMaxStackDepth];
-
-    // Under frame-pointer-based unwinding at least on x86, the
-    // top-most active routine doesn't show up as a normal frame, but
-    // as the "pc" value in the signal handler context.
-    stack[0] = GetPC(*reinterpret_cast<ucontext_t*>(signal_ucontext));
-
-    // We skip the top three stack trace entries (this function,
-    // SignalHandler::SignalHandler and one signal handler frame)
-    // since they are artifacts of profiling and should not be
-    // measured.  Other profiling related frames may be removed by
-    // "pprof" at analysis time.  Instead of skipping the top frames,
-    // we could skip nothing, but that would increase the profile size
-    // unnecessarily.
-    int depth = GetStackTraceWithContext(stack + 1, arraysize(stack) - 1,
-                                         3, signal_ucontext);
-
-    void **used_stack;
-    if (depth > 0 && stack[1] == stack[0]) {
-      // in case of non-frame-pointer-based unwinding we will get
-      // duplicate of PC in stack[1], which we don't want
-      used_stack = stack + 1;
-    } else {
-      used_stack = stack;
-      depth++;  // To account for pc value in stack[0];
-    }
-
-    instance->collector_.Add(depth, used_stack);
-  }
-}
-
-#if !(defined(__CYGWIN__) || defined(__CYGWIN32__))
-
-extern "C" PERFTOOLS_DLL_DECL void ProfilerRegisterThread() {
-  ProfileHandlerRegisterThread();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void ProfilerFlush() {
-  CpuProfiler::instance_.FlushTable();
-}
-
-extern "C" PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads() {
-  return CpuProfiler::instance_.Enabled();
-}
-
-extern "C" PERFTOOLS_DLL_DECL int ProfilerStart(const char* fname) {
-  return CpuProfiler::instance_.Start(fname, NULL);
-}
-
-extern "C" PERFTOOLS_DLL_DECL int ProfilerStartWithOptions(
-    const char *fname, const ProfilerOptions *options) {
-  return CpuProfiler::instance_.Start(fname, options);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void ProfilerStop() {
-  CpuProfiler::instance_.Stop();
-}
-
-extern "C" PERFTOOLS_DLL_DECL void ProfilerGetCurrentState(
-    ProfilerState* state) {
-  CpuProfiler::instance_.GetCurrentState(state);
-}
-
-#else  // OS_CYGWIN
-
-// ITIMER_PROF doesn't work under cygwin.  ITIMER_REAL is available, but doesn't
-// work as well for profiling, and also interferes with alarm().  Because of
-// these issues, unless a specific need is identified, profiler support is
-// disabled under Cygwin.
-extern "C" void ProfilerRegisterThread() { }
-extern "C" void ProfilerFlush() { }
-extern "C" int ProfilingIsEnabledForAllThreads() { return 0; }
-extern "C" int ProfilerStart(const char* fname) { return 0; }
-extern "C" int ProfilerStartWithOptions(const char *fname,
-                                        const ProfilerOptions *options) {
-  return 0;
-}
-extern "C" void ProfilerStop() { }
-extern "C" void ProfilerGetCurrentState(ProfilerState* state) {
-  memset(state, 0, sizeof(*state));
-}
-
-#endif  // OS_CYGWIN
-
-// DEPRECATED routines
-extern "C" PERFTOOLS_DLL_DECL void ProfilerEnable() { }
-extern "C" PERFTOOLS_DLL_DECL void ProfilerDisable() { }
diff --git a/third_party/tcmalloc/vendor/src/raw_printer.cc b/third_party/tcmalloc/vendor/src/raw_printer.cc
deleted file mode 100644
index 3cf028e..0000000
--- a/third_party/tcmalloc/vendor/src/raw_printer.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: sanjay@google.com (Sanjay Ghemawat)
-
-#include <config.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include "raw_printer.h"
-#include "base/logging.h"
-
-namespace base {
-
-RawPrinter::RawPrinter(char* buf, int length)
-    : base_(buf),
-      ptr_(buf),
-      limit_(buf + length - 1) {
-  RAW_DCHECK(length > 0, "");
-  *ptr_ = '\0';
-  *limit_ = '\0';
-}
-
-void RawPrinter::Printf(const char* format, ...) {
-  if (limit_ > ptr_) {
-    va_list ap;
-    va_start(ap, format);
-    int avail = limit_ - ptr_;
-    // We pass avail+1 to vsnprintf() since that routine needs room
-    // to store the trailing \0.
-    const int r = perftools_vsnprintf(ptr_, avail+1, format, ap);
-    va_end(ap);
-    if (r < 0) {
-      // Perhaps an old glibc that returns -1 on truncation?
-      ptr_ = limit_;
-    } else if (r > avail) {
-      // Truncation
-      ptr_ = limit_;
-    } else {
-      ptr_ += r;
-    }
-  }
-}
-
-}
diff --git a/third_party/tcmalloc/vendor/src/raw_printer.h b/third_party/tcmalloc/vendor/src/raw_printer.h
deleted file mode 100644
index 9288bb5..0000000
--- a/third_party/tcmalloc/vendor/src/raw_printer.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// A printf() wrapper that writes into a fixed length buffer.
-// Useful in low-level code that does not want to use allocating
-// routines like StringPrintf().
-//
-// The implementation currently uses vsnprintf().  This seems to
-// be fine for use in many low-level contexts, but we may need to
-// rethink this decision if we hit a problem with it calling
-// down into malloc() etc.
-
-#ifndef BASE_RAW_PRINTER_H_
-#define BASE_RAW_PRINTER_H_
-
-#include <config.h>
-#include "base/basictypes.h"
-
-namespace base {
-
-class RawPrinter {
- public:
-  // REQUIRES: "length > 0"
-  // Will printf any data added to this into "buf[0,length-1]" and
-  // will arrange to always keep buf[] null-terminated.
-  RawPrinter(char* buf, int length);
-
-  // Return the number of bytes that have been appended to the string
-  // so far.  Does not count any bytes that were dropped due to overflow.
-  int length() const { return (ptr_ - base_); }
-
-  // Return the number of bytes that can be added to this.
-  int space_left() const { return (limit_ - ptr_); }
-
-  // Format the supplied arguments according to the "format" string
-  // and append to this.  Will silently truncate the output if it does
-  // not fit.
-  void Printf(const char* format, ...)
-#ifdef HAVE___ATTRIBUTE__
-  __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
-;
-
- private:
-  // We can write into [ptr_ .. limit_-1].
-  // *limit_ is also writable, but reserved for a terminating \0
-  // in case we overflow.
-  //
-  // Invariants: *ptr_ == \0
-  // Invariants: *limit_ == \0
-  char* base_;          // Initial pointer
-  char* ptr_;           // Where should we write next
-  char* limit_;         // One past last non-\0 char we can write
-
-  DISALLOW_COPY_AND_ASSIGN(RawPrinter);
-};
-
-}
-
-#endif  // BASE_RAW_PRINTER_H_
diff --git a/third_party/tcmalloc/vendor/src/sampler.cc b/third_party/tcmalloc/vendor/src/sampler.cc
deleted file mode 100644
index e63d4cb..0000000
--- a/third_party/tcmalloc/vendor/src/sampler.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Daniel Ford
-
-#include "sampler.h"
-
-#include <algorithm>  // For min()
-#include <math.h>
-#include "base/commandlineflags.h"
-
-using std::min;
-
-// The approximate gap in bytes between sampling actions.
-// I.e., we take one sample approximately once every
-// tcmalloc_sample_parameter bytes of allocation
-// i.e. about once every 512KB if value is 1<<19.
-#ifdef NO_TCMALLOC_SAMPLES
-DEFINE_int64(tcmalloc_sample_parameter, 0,
-             "Unused: code is compiled with NO_TCMALLOC_SAMPLES");
-#else
-DEFINE_int64(tcmalloc_sample_parameter,
-             EnvToInt64("TCMALLOC_SAMPLE_PARAMETER", 0),
-             "The approximate gap in bytes between sampling actions. "
-             "This must be between 1 and 2^58.");
-#endif
-
-namespace tcmalloc {
-
-int Sampler::GetSamplePeriod() {
-  return FLAGS_tcmalloc_sample_parameter;
-}
-
-// Run this before using your sampler
-void Sampler::Init(uint64_t seed) {
-  ASSERT(seed != 0);
-
-  // Initialize PRNG
-  rnd_ = seed;
-  // Step it forward 20 times for good measure
-  for (int i = 0; i < 20; i++) {
-    rnd_ = NextRandom(rnd_);
-  }
-  // Initialize counter
-  bytes_until_sample_ = PickNextSamplingPoint();
-}
-
-#define MAX_SSIZE (static_cast<ssize_t>(static_cast<size_t>(static_cast<ssize_t>(-1)) >> 1))
-
-// Generates a geometric variable with the specified mean (512K by default).
-// This is done by generating a random number between 0 and 1 and applying
-// the inverse cumulative distribution function for an exponential.
-// Specifically: Let m be the inverse of the sample period, then
-// the probability distribution function is m*exp(-mx) so the CDF is
-// p = 1 - exp(-mx), so
-// q = 1 - p = exp(-mx)
-// log_e(q) = -mx
-// -log_e(q)/m = x
-// log_2(q) * (-log_e(2) * 1/m) = x
-// In the code, q is actually in the range 1 to 2**26, hence the -26 below
-ssize_t Sampler::PickNextSamplingPoint() {
-  if (FLAGS_tcmalloc_sample_parameter <= 0) {
-    // In this case, we don't want to sample ever, and the larger a
-    // value we put here, the longer until we hit the slow path
-    // again. However, we have to support the flag changing at
-    // runtime, so pick something reasonably large (to keep overhead
-    // low) but small enough that we'll eventually start to sample
-    // again.
-    return 16 << 20;
-  }
-
-  rnd_ = NextRandom(rnd_);
-  // Take the top 26 bits as the random number
-  // (This plus the 1<<58 sampling bound give a max possible step of
-  // 5194297183973780480 bytes.)
-  const uint64_t prng_mod_power = 48;  // Number of bits in prng
-  // The uint32_t cast is to prevent a (hard-to-reproduce) NAN
-  // under piii debug for some binaries.
-  double q = static_cast<uint32_t>(rnd_ >> (prng_mod_power - 26)) + 1.0;
-  // Put the computed p-value through the CDF of a geometric.
-  double interval =
-      (log2(q) - 26) * (-log(2.0) * FLAGS_tcmalloc_sample_parameter);
-
-  // Very large values of interval overflow ssize_t. If we happen to
-  // hit such improbable condition, we simply cheat and clamp interval
-  // to largest supported value.
-  return static_cast<ssize_t>(std::min<double>(interval, MAX_SSIZE));
-}
-
-bool Sampler::RecordAllocationSlow(size_t k) {
-  if (!initialized_) {
-    initialized_ = true;
-    Init(reinterpret_cast<uintptr_t>(this));
-    if (static_cast<size_t>(bytes_until_sample_) >= k) {
-      bytes_until_sample_ -= k;
-      return true;
-    }
-  }
-  bytes_until_sample_ = PickNextSamplingPoint();
-  return FLAGS_tcmalloc_sample_parameter <= 0;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/vendor/src/sampler.h b/third_party/tcmalloc/vendor/src/sampler.h
deleted file mode 100644
index 16d3b09..0000000
--- a/third_party/tcmalloc/vendor/src/sampler.h
+++ /dev/null
@@ -1,230 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Daniel Ford
-
-#ifndef TCMALLOC_SAMPLER_H_
-#define TCMALLOC_SAMPLER_H_
-
-#include "config.h"
-#include <stddef.h>                     // for size_t
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uint64_t, uint32_t, int32_t
-#endif
-#include <string.h>                     // for memcpy
-#include "base/basictypes.h"  // for ASSERT
-#include "internal_logging.h"  // for ASSERT
-#include "static_vars.h"
-
-namespace tcmalloc {
-
-//-------------------------------------------------------------------
-// Sampler to decide when to create a sample trace for an allocation
-// Not thread safe: Each thread should have it's own sampler object.
-// Caller must use external synchronization if used
-// from multiple threads.
-//
-// With 512K average sample step (the default):
-//  the probability of sampling a 4K allocation is about 0.00778
-//  the probability of sampling a 1MB allocation is about 0.865
-//  the probability of sampling a 1GB allocation is about 1.00000
-// In general, the probablity of sampling is an allocation of size X
-// given a flag value of Y (default 1M) is:
-//  1 - e^(-X/Y)
-//
-// With 128K average sample step:
-//  the probability of sampling a 1MB allocation is about 0.99966
-//  the probability of sampling a 1GB allocation is about 1.0
-//  (about 1 - 2**(-26))
-// With 1M average sample step:
-//  the probability of sampling a 4K allocation is about 0.00390
-//  the probability of sampling a 1MB allocation is about 0.632
-//  the probability of sampling a 1GB allocation is about 1.0
-//
-// The sampler works by representing memory as a long stream from
-// which allocations are taken. Some of the bytes in this stream are
-// marked and if an allocation includes a marked byte then it is
-// sampled. Bytes are marked according to a Poisson point process
-// with each byte being marked independently with probability
-// p = 1/tcmalloc_sample_parameter.  This makes the probability
-// of sampling an allocation of X bytes equal to the CDF of
-// a geometric with mean tcmalloc_sample_parameter. (ie. the
-// probability that at least one byte in the range is marked). This
-// is accurately given by the CDF of the corresponding exponential
-// distribution : 1 - e^(-X/tcmalloc_sample_parameter_)
-// Independence of the byte marking ensures independence of
-// the sampling of each allocation.
-//
-// This scheme is implemented by noting that, starting from any
-// fixed place, the number of bytes until the next marked byte
-// is geometrically distributed. This number is recorded as
-// bytes_until_sample_.  Every allocation subtracts from this
-// number until it is less than 0. When this happens the current
-// allocation is sampled.
-//
-// When an allocation occurs, bytes_until_sample_ is reset to
-// a new independtly sampled geometric number of bytes. The
-// memoryless property of the point process means that this may
-// be taken as the number of bytes after the end of the current
-// allocation until the next marked byte. This ensures that
-// very large allocations which would intersect many marked bytes
-// only result in a single call to PickNextSamplingPoint.
-//-------------------------------------------------------------------
-
-class SamplerTest;
-
-class PERFTOOLS_DLL_DECL Sampler {
- public:
-  // Initialize this sampler.
-  void Init(uint64_t seed);
-
-  // Record allocation of "k" bytes.  Return true if no further work
-  // is need, and false if allocation needed to be sampled.
-  bool RecordAllocation(size_t k);
-
-  // Same as above (but faster), except:
-  // a) REQUIRES(k < std::numeric_limits<ssize_t>::max())
-  // b) if this returns false, you must call RecordAllocation
-  //    to confirm if sampling truly needed.
-  //
-  // The point of this function is to only deal with common case of no
-  // sampling and let caller (which is in malloc fast-path) to
-  // "escalate" to fuller and slower logic only if necessary.
-  bool TryRecordAllocationFast(size_t k);
-
-  // Generate a geometric with mean 512K (or FLAG_tcmalloc_sample_parameter)
-  ssize_t PickNextSamplingPoint();
-
-  // Returns the current sample period
-  static int GetSamplePeriod();
-
-  // The following are public for the purposes of testing
-  static uint64_t NextRandom(uint64_t rnd_);  // Returns the next prng value
-
-  // C++03 requires that types stored in TLS be POD.  As a result, you must
-  // initialize these members to {0, 0, false} before using this class!
-  //
-  // TODO(ahh): C++11 support will let us make these private.
-
-  // Bytes until we sample next.
-  //
-  // More specifically when bytes_until_sample_ is X, we can allocate
-  // X bytes without triggering sampling; on the (X+1)th allocated
-  // byte, the containing allocation will be sampled.
-  //
-  // Always non-negative with only very brief exceptions (see
-  // DecrementFast{,Finish}, so casting to size_t is ok.
-  ssize_t bytes_until_sample_;
-  uint64_t rnd_;  // Cheap random number generator
-  bool initialized_;
-
- private:
-  friend class SamplerTest;
-  bool RecordAllocationSlow(size_t k);
-};
-
-inline bool Sampler::RecordAllocation(size_t k) {
-  // The first time we enter this function we expect bytes_until_sample_
-  // to be zero, and we must call SampleAllocationSlow() to ensure
-  // proper initialization of static vars.
-  ASSERT(Static::IsInited() || bytes_until_sample_ == 0);
-
-  // Note that we have to deal with arbitrarily large values of k
-  // here. Thus we're upcasting bytes_until_sample_ to unsigned rather
-  // than the other way around. And this is why this code cannot be
-  // merged with DecrementFast code below.
-  if (static_cast<size_t>(bytes_until_sample_) < k) {
-    bool result = RecordAllocationSlow(k);
-    ASSERT(Static::IsInited());
-    return result;
-  } else {
-    bytes_until_sample_ -= k;
-    ASSERT(Static::IsInited());
-    return true;
-  }
-}
-
-inline bool Sampler::TryRecordAllocationFast(size_t k) {
-  // For efficiency reason, we're testing bytes_until_sample_ after
-  // decrementing it by k. This allows compiler to do sub <reg>, <mem>
-  // followed by conditional jump on sign. But it is correct only if k
-  // is actually smaller than largest ssize_t value. Otherwise
-  // converting k to signed value overflows.
-  //
-  // It would be great for generated code to be sub <reg>, <mem>
-  // followed by conditional jump on 'carry', which would work for
-  // arbitrary values of k, but there seem to be no way to express
-  // that in C++.
-  //
-  // Our API contract explicitly states that only small values of k
-  // are permitted. And thus it makes sense to assert on that.
-  ASSERT(static_cast<ssize_t>(k) >= 0);
-
-  bytes_until_sample_ -= static_cast<ssize_t>(k);
-  if (PREDICT_FALSE(bytes_until_sample_ < 0)) {
-    // Note, we undo sampling counter update, since we're not actually
-    // handling slow path in the "needs sampling" case (calling
-    // RecordAllocationSlow to reset counter). And we do that in order
-    // to avoid non-tail calls in malloc fast-path. See also comments
-    // on declaration inside Sampler class.
-    //
-    // volatile is used here to improve compiler's choice of
-    // instuctions. We know that this path is very rare and that there
-    // is no need to keep previous value of bytes_until_sample_ in
-    // register. This helps compiler generate slightly more efficient
-    // sub <reg>, <mem> instruction for subtraction above.
-    volatile ssize_t *ptr =
-        const_cast<volatile ssize_t *>(&bytes_until_sample_);
-    *ptr += k;
-    return false;
-  }
-  return true;
-}
-
-// Inline functions which are public for testing purposes
-
-// Returns the next prng value.
-// pRNG is: aX+b mod c with a = 0x5DEECE66D, b =  0xB, c = 1<<48
-// This is the lrand64 generator.
-inline uint64_t Sampler::NextRandom(uint64_t rnd) {
-  const uint64_t prng_mult = 0x5DEECE66DULL;
-  const uint64_t prng_add = 0xB;
-  const uint64_t prng_mod_power = 48;
-  const uint64_t prng_mod_mask =
-      ~((~static_cast<uint64_t>(0)) << prng_mod_power);
-  return (prng_mult * rnd + prng_add) & prng_mod_mask;
-}
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_SAMPLER_H_
diff --git a/third_party/tcmalloc/vendor/src/span.cc b/third_party/tcmalloc/vendor/src/span.cc
deleted file mode 100644
index 4d08964..0000000
--- a/third_party/tcmalloc/vendor/src/span.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#include <config.h>
-#include "span.h"
-
-#include <string.h>                     // for NULL, memset
-
-#include "internal_logging.h"  // for ASSERT
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "static_vars.h"       // for Static
-
-namespace tcmalloc {
-
-#ifdef SPAN_HISTORY
-void Event(Span* span, char op, int v = 0) {
-  span->history[span->nexthistory] = op;
-  span->value[span->nexthistory] = v;
-  span->nexthistory++;
-  if (span->nexthistory == sizeof(span->history)) span->nexthistory = 0;
-}
-#endif
-
-Span* NewSpan(PageID p, Length len) {
-  Span* result = Static::span_allocator()->New();
-  memset(result, 0, sizeof(*result));
-  result->start = p;
-  result->length = len;
-#ifdef SPAN_HISTORY
-  result->nexthistory = 0;
-#endif
-  return result;
-}
-
-void DeleteSpan(Span* span) {
-#ifndef NDEBUG
-  // In debug mode, trash the contents of deleted Spans
-  memset(span, 0x3f, sizeof(*span));
-#endif
-  Static::span_allocator()->Delete(span);
-}
-
-void DLL_Init(Span* list) {
-  list->next = list;
-  list->prev = list;
-}
-
-void DLL_Remove(Span* span) {
-  span->prev->next = span->next;
-  span->next->prev = span->prev;
-  span->prev = NULL;
-  span->next = NULL;
-}
-
-int DLL_Length(const Span* list) {
-  int result = 0;
-  for (Span* s = list->next; s != list; s = s->next) {
-    result++;
-  }
-  return result;
-}
-
-void DLL_Prepend(Span* list, Span* span) {
-  ASSERT(span->next == NULL);
-  ASSERT(span->prev == NULL);
-  span->next = list->next;
-  span->prev = list;
-  list->next->prev = span;
-  list->next = span;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/vendor/src/span.h b/third_party/tcmalloc/vendor/src/span.h
deleted file mode 100644
index ca3f710f..0000000
--- a/third_party/tcmalloc/vendor/src/span.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// A Span is a contiguous run of pages.
-
-#ifndef TCMALLOC_SPAN_H_
-#define TCMALLOC_SPAN_H_
-
-#include <config.h>
-#include <set>
-#include "common.h"
-#include "base/logging.h"
-#include "page_heap_allocator.h"
-
-namespace tcmalloc {
-
-struct SpanBestFitLess;
-struct Span;
-
-// Store a pointer to a span along with a cached copy of its length.
-// These are used as set elements to improve the performance of
-// comparisons during tree traversal: the lengths are inline with the
-// tree nodes and thus avoid expensive cache misses to dereference
-// the actual Span objects in most cases.
-struct SpanPtrWithLength {
-  explicit SpanPtrWithLength(Span* s);
-
-  Span* span;
-  Length length;
-};
-typedef std::set<SpanPtrWithLength, SpanBestFitLess, STLPageHeapAllocator<SpanPtrWithLength, void> > SpanSet;
-
-// Comparator for best-fit search, with address order as a tie-breaker.
-struct SpanBestFitLess {
-  bool operator()(SpanPtrWithLength a, SpanPtrWithLength b) const;
-};
-
-// Information kept for a span (a contiguous run of pages).
-struct Span {
-  PageID        start;          // Starting page number
-  Length        length;         // Number of pages in span
-  Span*         next;           // Used when in link list
-  Span*         prev;           // Used when in link list
-  union {
-    void* objects;              // Linked list of free objects
-
-    // Span may contain iterator pointing back at SpanSet entry of
-    // this span into set of large spans. It is used to quickly delete
-    // spans from those sets. span_iter_space is space for such
-    // iterator which lifetime is controlled explicitly.
-    char span_iter_space[sizeof(SpanSet::iterator)];
-  };
-  unsigned int  refcount : 16;  // Number of non-free objects
-  unsigned int  sizeclass : 8;  // Size-class for small objects (or 0)
-  unsigned int  location : 2;   // Is the span on a freelist, and if so, which?
-  unsigned int  sample : 1;     // Sampled object?
-  bool          has_span_iter : 1; // Iff span_iter_space has valid
-                                   // iterator. Only for debug builds.
-
-  // Sets iterator stored in span_iter_space.
-  // Requires has_span_iter == 0.
-  void SetSpanSetIterator(const SpanSet::iterator& iter);
-  // Copies out and destroys iterator stored in span_iter_space.
-  SpanSet::iterator ExtractSpanSetIterator();
-
-#undef SPAN_HISTORY
-#ifdef SPAN_HISTORY
-  // For debugging, we can keep a log events per span
-  int nexthistory;
-  char history[64];
-  int value[64];
-#endif
-
-  // What freelist the span is on: IN_USE if on none, or normal or returned
-  enum { IN_USE, ON_NORMAL_FREELIST, ON_RETURNED_FREELIST };
-};
-
-#ifdef SPAN_HISTORY
-void Event(Span* span, char op, int v = 0);
-#else
-#define Event(s,o,v) ((void) 0)
-#endif
-
-inline SpanPtrWithLength::SpanPtrWithLength(Span* s)
-    : span(s),
-      length(s->length) {
-}
-
-inline bool SpanBestFitLess::operator()(SpanPtrWithLength a, SpanPtrWithLength b) const {
-  if (a.length < b.length)
-    return true;
-  if (a.length > b.length)
-    return false;
-  return a.span->start < b.span->start;
-}
-
-inline void Span::SetSpanSetIterator(const SpanSet::iterator& iter) {
-  ASSERT(!has_span_iter);
-  has_span_iter = 1;
-
-  new (span_iter_space) SpanSet::iterator(iter);
-}
-
-inline SpanSet::iterator Span::ExtractSpanSetIterator() {
-  typedef SpanSet::iterator iterator_type;
-
-  ASSERT(has_span_iter);
-  has_span_iter = 0;
-
-  iterator_type* this_iter =
-    reinterpret_cast<iterator_type*>(span_iter_space);
-  iterator_type retval = *this_iter;
-  this_iter->~iterator_type();
-  return retval;
-}
-
-// Allocator/deallocator for spans
-Span* NewSpan(PageID p, Length len);
-void DeleteSpan(Span* span);
-
-// -------------------------------------------------------------------------
-// Doubly linked list of spans.
-// -------------------------------------------------------------------------
-
-// Initialize *list to an empty list.
-void DLL_Init(Span* list);
-
-// Remove 'span' from the linked list in which it resides, updating the
-// pointers of adjacent Spans and setting span's next and prev to NULL.
-void DLL_Remove(Span* span);
-
-// Return true iff "list" is empty.
-inline bool DLL_IsEmpty(const Span* list) {
-  return list->next == list;
-}
-
-// Add span to the front of list.
-void DLL_Prepend(Span* list, Span* span);
-
-// Return the length of the linked list. O(n)
-int DLL_Length(const Span* list);
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_SPAN_H_
diff --git a/third_party/tcmalloc/vendor/src/stack_trace_table.cc b/third_party/tcmalloc/vendor/src/stack_trace_table.cc
deleted file mode 100644
index 1862124..0000000
--- a/third_party/tcmalloc/vendor/src/stack_trace_table.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Andrew Fikes
-
-#include <config.h>
-#include "stack_trace_table.h"
-#include <string.h>                     // for NULL, memset
-#include "base/spinlock.h"              // for SpinLockHolder
-#include "common.h"            // for StackTrace
-#include "internal_logging.h"  // for ASSERT, Log
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "static_vars.h"       // for Static
-
-namespace tcmalloc {
-
-bool StackTraceTable::Bucket::KeyEqual(uintptr_t h,
-                                       const StackTrace& t) const {
-  const bool eq = (this->hash == h && this->trace.depth == t.depth);
-  for (int i = 0; eq && i < t.depth; ++i) {
-    if (this->trace.stack[i] != t.stack[i]) {
-      return false;
-    }
-  }
-  return eq;
-}
-
-StackTraceTable::StackTraceTable()
-    : error_(false),
-      depth_total_(0),
-      bucket_total_(0),
-      table_(new Bucket*[kHashTableSize]()) {
-  memset(table_, 0, kHashTableSize * sizeof(Bucket*));
-}
-
-StackTraceTable::~StackTraceTable() {
-  delete[] table_;
-}
-
-void StackTraceTable::AddTrace(const StackTrace& t) {
-  if (error_) {
-    return;
-  }
-
-  // Hash function borrowed from base/heap-profile-table.cc
-  uintptr_t h = 0;
-  for (int i = 0; i < t.depth; ++i) {
-    h += reinterpret_cast<uintptr_t>(t.stack[i]);
-    h += h << 10;
-    h ^= h >> 6;
-  }
-  h += h << 3;
-  h ^= h >> 11;
-
-  const int idx = h % kHashTableSize;
-
-  Bucket* b = table_[idx];
-  while (b != NULL && !b->KeyEqual(h, t)) {
-    b = b->next;
-  }
-  if (b != NULL) {
-    b->count++;
-    b->trace.size += t.size;  // keep cumulative size
-  } else {
-    depth_total_ += t.depth;
-    bucket_total_++;
-    b = Static::bucket_allocator()->New();
-    if (b == NULL) {
-      Log(kLog, __FILE__, __LINE__,
-          "tcmalloc: could not allocate bucket", sizeof(*b));
-      error_ = true;
-    } else {
-      b->hash = h;
-      b->trace = t;
-      b->count = 1;
-      b->next = table_[idx];
-      table_[idx] = b;
-    }
-  }
-}
-
-void** StackTraceTable::ReadStackTracesAndClear() {
-  if (error_) {
-    return NULL;
-  }
-
-  // Allocate output array
-  const int out_len = bucket_total_ * 3 + depth_total_ + 1;
-  void** out = new void*[out_len];
-  if (out == NULL) {
-    Log(kLog, __FILE__, __LINE__,
-        "tcmalloc: allocation failed for stack traces",
-        out_len * sizeof(*out));
-    return NULL;
-  }
-
-  // Fill output array
-  int idx = 0;
-  for (int i = 0; i < kHashTableSize; ++i) {
-    Bucket* b = table_[i];
-    while (b != NULL) {
-      out[idx++] = reinterpret_cast<void*>(static_cast<uintptr_t>(b->count));
-      out[idx++] = reinterpret_cast<void*>(b->trace.size);  // cumulative size
-      out[idx++] = reinterpret_cast<void*>(b->trace.depth);
-      for (int d = 0; d < b->trace.depth; ++d) {
-        out[idx++] = b->trace.stack[d];
-      }
-      b = b->next;
-    }
-  }
-  out[idx++] = NULL;
-  ASSERT(idx == out_len);
-
-  // Clear state
-  error_ = false;
-  depth_total_ = 0;
-  bucket_total_ = 0;
-  SpinLockHolder h(Static::pageheap_lock());
-  for (int i = 0; i < kHashTableSize; ++i) {
-    Bucket* b = table_[i];
-    while (b != NULL) {
-      Bucket* next = b->next;
-      Static::bucket_allocator()->Delete(b);
-      b = next;
-    }
-    table_[i] = NULL;
-  }
-
-  return out;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/vendor/src/stack_trace_table.h b/third_party/tcmalloc/vendor/src/stack_trace_table.h
deleted file mode 100644
index e289771..0000000
--- a/third_party/tcmalloc/vendor/src/stack_trace_table.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Andrew Fikes
-//
-// Utility class for coalescing sampled stack traces.  Not thread-safe.
-
-#ifndef TCMALLOC_STACK_TRACE_TABLE_H_
-#define TCMALLOC_STACK_TRACE_TABLE_H_
-
-#include <config.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uintptr_t
-#endif
-#include "common.h"
-
-namespace tcmalloc {
-
-class PERFTOOLS_DLL_DECL StackTraceTable {
- public:
-  // REQUIRES: L < pageheap_lock
-  StackTraceTable();
-  ~StackTraceTable();
-
-  // Adds stack trace "t" to table.
-  //
-  // REQUIRES: L >= pageheap_lock
-  void AddTrace(const StackTrace& t);
-
-  // Returns stack traces formatted per MallocExtension guidelines.
-  // May return NULL on error.  Clears state before returning.
-  //
-  // REQUIRES: L < pageheap_lock
-  void** ReadStackTracesAndClear();
-
-  // Exposed for PageHeapAllocator
-  struct Bucket {
-    // Key
-    uintptr_t hash;
-    StackTrace trace;
-
-    // Payload
-    int count;
-    Bucket* next;
-
-    bool KeyEqual(uintptr_t h, const StackTrace& t) const;
-  };
-
-  // For testing
-  int depth_total() const { return depth_total_; }
-  int bucket_total() const { return bucket_total_; }
-
- private:
-  static const int kHashTableSize = 1 << 14; // => table_ is 128k
-
-  bool error_;
-  int depth_total_;
-  int bucket_total_;
-  Bucket** table_;
-};
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_STACK_TRACE_TABLE_H_
diff --git a/third_party/tcmalloc/vendor/src/stacktrace.cc b/third_party/tcmalloc/vendor/src/stacktrace.cc
deleted file mode 100644
index 7e853d8..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace.cc
+++ /dev/null
@@ -1,340 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Produce stack trace.
-//
-// There are three different ways we can try to get the stack trace:
-//
-// 1) Our hand-coded stack-unwinder.  This depends on a certain stack
-//    layout, which is used by gcc (and those systems using a
-//    gcc-compatible ABI) on x86 systems, at least since gcc 2.95.
-//    It uses the frame pointer to do its work.
-//
-// 2) The libunwind library.  This is still in development, and as a
-//    separate library adds a new dependency, abut doesn't need a frame
-//    pointer.  It also doesn't call malloc.
-//
-// 3) The gdb unwinder -- also the one used by the c++ exception code.
-//    It's obviously well-tested, but has a fatal flaw: it can call
-//    malloc() from the unwinder.  This is a problem because we're
-//    trying to use the unwinder to instrument malloc().
-//
-// Note: if you add a new implementation here, make sure it works
-// correctly when GetStackTrace() is called with max_depth == 0.
-// Some code may do that.
-
-#include <config.h>
-#include <stdlib.h> // for getenv
-#include <string.h> // for strcmp
-#include <stdio.h> // for fprintf
-#include "gperftools/stacktrace.h"
-#include "base/commandlineflags.h"
-#include "base/googleinit.h"
-#include "getenv_safe.h"
-
-
-// we're using plain struct and not class to avoid any possible issues
-// during initialization. Struct of pointers is easy to init at
-// link-time.
-struct GetStackImplementation {
-  int (*GetStackFramesPtr)(void** result, int* sizes, int max_depth,
-                           int skip_count);
-
-  int (*GetStackFramesWithContextPtr)(void** result, int* sizes, int max_depth,
-                                      int skip_count, const void *uc);
-
-  int (*GetStackTracePtr)(void** result, int max_depth,
-                          int skip_count);
-
-  int (*GetStackTraceWithContextPtr)(void** result, int max_depth,
-                                  int skip_count, const void *uc);
-
-  const char *name;
-};
-
-#if HAVE_DECL_BACKTRACE
-#define STACKTRACE_INL_HEADER "stacktrace_generic-inl.h"
-#define GST_SUFFIX generic
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_generic
-#endif
-
-#ifdef HAVE_UNWIND_BACKTRACE
-#define STACKTRACE_INL_HEADER "stacktrace_libgcc-inl.h"
-#define GST_SUFFIX libgcc
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_libgcc
-#endif
-
-// libunwind uses __thread so we check for both libunwind.h and
-// __thread support
-#if defined(HAVE_LIBUNWIND_H) && defined(HAVE_TLS)
-#define STACKTRACE_INL_HEADER "stacktrace_libunwind-inl.h"
-#define GST_SUFFIX libunwind
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_libunwind
-#endif // HAVE_LIBUNWIND_H
-
-#if defined(__i386__) || defined(__x86_64__)
-#define STACKTRACE_INL_HEADER "stacktrace_x86-inl.h"
-#define GST_SUFFIX x86
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_x86
-#endif // i386 || x86_64
-
-#if defined(__ppc__) || defined(__PPC__)
-#if defined(__linux__)
-#define STACKTRACE_INL_HEADER "stacktrace_powerpc-linux-inl.h"
-#else
-#define STACKTRACE_INL_HEADER "stacktrace_powerpc-darwin-inl.h"
-#endif
-#define GST_SUFFIX ppc
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_ppc
-#endif
-
-#if defined(__arm__)
-#define STACKTRACE_INL_HEADER "stacktrace_arm-inl.h"
-#define GST_SUFFIX arm
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_arm
-#endif
-
-#ifdef TCMALLOC_ENABLE_INSTRUMENT_STACKTRACE
-#define STACKTRACE_INL_HEADER "stacktrace_instrument-inl.h"
-#define GST_SUFFIX instrument
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_instrument
-#endif
-
-// The Windows case -- probably cygwin and mingw will use one of the
-// x86-includes above, but if not, we can fall back to windows intrinsics.
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
-#define STACKTRACE_INL_HEADER "stacktrace_win32-inl.h"
-#define GST_SUFFIX win32
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_win32
-#endif
-
-static GetStackImplementation *all_impls[] = {
-#ifdef HAVE_GST_libgcc
-  &impl__libgcc,
-#endif
-#ifdef HAVE_GST_generic
-  &impl__generic,
-#endif
-#ifdef HAVE_GST_libunwind
-  &impl__libunwind,
-#endif
-#ifdef HAVE_GST_x86
-  &impl__x86,
-#endif
-#ifdef HAVE_GST_arm
-  &impl__arm,
-#endif
-#ifdef HAVE_GST_ppc
-  &impl__ppc,
-#endif
-#ifdef HAVE_GST_instrument
-  &impl__instrument,
-#endif
-#ifdef HAVE_GST_win32
-  &impl__win32,
-#endif
-  NULL
-};
-
-// ppc and i386 implementations prefer arch-specific asm implementations.
-// arm's asm implementation is broken
-#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__PPC__)
-#if !defined(NO_FRAME_POINTER)
-#define TCMALLOC_DONT_PREFER_LIBUNWIND
-#endif
-#endif
-
-static bool get_stack_impl_inited;
-
-#if defined(HAVE_GST_instrument)
-static GetStackImplementation *get_stack_impl = &impl__instrument;
-#elif defined(HAVE_GST_win32)
-static GetStackImplementation *get_stack_impl = &impl__win32;
-#elif defined(HAVE_GST_x86) && defined(TCMALLOC_DONT_PREFER_LIBUNWIND)
-static GetStackImplementation *get_stack_impl = &impl__x86;
-#elif defined(HAVE_GST_ppc) && defined(TCMALLOC_DONT_PREFER_LIBUNWIND)
-static GetStackImplementation *get_stack_impl = &impl__ppc;
-#elif defined(HAVE_GST_libunwind)
-static GetStackImplementation *get_stack_impl = &impl__libunwind;
-#elif defined(HAVE_GST_libgcc)
-static GetStackImplementation *get_stack_impl = &impl__libgcc;
-#elif defined(HAVE_GST_generic)
-static GetStackImplementation *get_stack_impl = &impl__generic;
-#elif defined(HAVE_GST_arm)
-static GetStackImplementation *get_stack_impl = &impl__arm;
-#elif 0
-// This is for the benefit of code analysis tools that may have
-// trouble with the computed #include above.
-# include "stacktrace_x86-inl.h"
-# include "stacktrace_libunwind-inl.h"
-# include "stacktrace_generic-inl.h"
-# include "stacktrace_powerpc-inl.h"
-# include "stacktrace_win32-inl.h"
-# include "stacktrace_arm-inl.h"
-# include "stacktrace_instrument-inl.h"
-#else
-#error Cannot calculate stack trace: will need to write for your environment
-#endif
-
-static int ATTRIBUTE_NOINLINE frame_forcer(int rv) {
-  return rv;
-}
-
-static void init_default_stack_impl_inner(void);
-
-namespace tcmalloc {
-  bool EnterStacktraceScope(void);
-  void LeaveStacktraceScope(void);
-}
-
-namespace {
-  using tcmalloc::EnterStacktraceScope;
-  using tcmalloc::LeaveStacktraceScope;
-
-  class StacktraceScope {
-    bool stacktrace_allowed;
-  public:
-    StacktraceScope() {
-      stacktrace_allowed = true;
-      stacktrace_allowed = EnterStacktraceScope();
-    }
-    bool IsStacktraceAllowed() {
-      return stacktrace_allowed;
-    }
-    ~StacktraceScope() {
-      if (stacktrace_allowed) {
-        LeaveStacktraceScope();
-      }
-    }
-  };
-}
-
-PERFTOOLS_DLL_DECL int GetStackFrames(void** result, int* sizes, int max_depth,
-                                      int skip_count) {
-  StacktraceScope scope;
-  if (!scope.IsStacktraceAllowed()) {
-    return 0;
-  }
-  init_default_stack_impl_inner();
-  return frame_forcer(get_stack_impl->GetStackFramesPtr(result, sizes, max_depth, skip_count));
-}
-
-PERFTOOLS_DLL_DECL int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
-                                                 int skip_count, const void *uc) {
-  StacktraceScope scope;
-  if (!scope.IsStacktraceAllowed()) {
-    return 0;
-  }
-  init_default_stack_impl_inner();
-  return frame_forcer(get_stack_impl->GetStackFramesWithContextPtr(
-                        result, sizes, max_depth,
-                        skip_count, uc));
-}
-
-PERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,
-                                     int skip_count) {
-  StacktraceScope scope;
-  if (!scope.IsStacktraceAllowed()) {
-    return 0;
-  }
-  init_default_stack_impl_inner();
-  return frame_forcer(get_stack_impl->GetStackTracePtr(result, max_depth, skip_count));
-}
-
-PERFTOOLS_DLL_DECL int GetStackTraceWithContext(void** result, int max_depth,
-                                                int skip_count, const void *uc) {
-  StacktraceScope scope;
-  if (!scope.IsStacktraceAllowed()) {
-    return 0;
-  }
-  init_default_stack_impl_inner();
-  return frame_forcer(get_stack_impl->GetStackTraceWithContextPtr(
-                        result, max_depth, skip_count, uc));
-}
-
-static void init_default_stack_impl_inner(void) {
-  if (get_stack_impl_inited) {
-    return;
-  }
-  get_stack_impl_inited = true;
-  const char *val = TCMallocGetenvSafe("TCMALLOC_STACKTRACE_METHOD");
-  if (!val || !*val) {
-    return;
-  }
-  for (GetStackImplementation **p = all_impls; *p; p++) {
-    GetStackImplementation *c = *p;
-    if (strcmp(c->name, val) == 0) {
-      get_stack_impl = c;
-      return;
-    }
-  }
-  fprintf(stderr, "Unknown or unsupported stacktrace method requested: %s. Ignoring it\n", val);
-}
-
-static void init_default_stack_impl(void) {
-  init_default_stack_impl_inner();
-  if (EnvToBool("TCMALLOC_STACKTRACE_METHOD_VERBOSE", false)) {
-    fprintf(stderr, "Chosen stacktrace method is %s\nSupported methods:\n", get_stack_impl->name);
-    for (GetStackImplementation **p = all_impls; *p; p++) {
-      GetStackImplementation *c = *p;
-      fprintf(stderr, "* %s\n", c->name);
-    }
-    fputs("\n", stderr);
-  }
-}
-
-REGISTER_MODULE_INITIALIZER(stacktrace_init_default_stack_impl, init_default_stack_impl());
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_arm-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_arm-inl.h
deleted file mode 100644
index 1586b8f..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_arm-inl.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Doug Kwan
-// This is inspired by Craig Silverstein's PowerPC stacktrace code.
-//
-
-#ifndef BASE_STACKTRACE_ARM_INL_H_
-#define BASE_STACKTRACE_ARM_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <stdint.h>   // for uintptr_t
-#include "base/basictypes.h"  // for NULL
-#include <gperftools/stacktrace.h>
-
-// WARNING:
-// This only works if all your code is in either ARM or THUMB mode.  With
-// interworking, the frame pointer of the caller can either be in r11 (ARM
-// mode) or r7 (THUMB mode).  A callee only saves the frame pointer of its
-// mode in a fixed location on its stack frame.  If the caller is a different
-// mode, there is no easy way to find the frame pointer.  It can either be
-// still in the designated register or saved on stack along with other callee
-// saved registers.
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING>
-static void **NextStackFrame(void **old_sp) {
-  void **new_sp = (void**) old_sp[-1];
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp) return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp) return NULL;
-    // And allow frames upto about 1MB.
-    if ((new_sp > old_sp)
-        && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
-  }
-  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
-  return new_sp;
-}
-
-// This ensures that GetStackTrace stes up the Link Register properly.
-#ifdef __GNUC__
-void StacktraceArmDummyFunction() __attribute__((noinline));
-void StacktraceArmDummyFunction() { __asm__ volatile(""); }
-#else
-# error StacktraceArmDummyFunction() needs to be ported to this platform.
-#endif
-#endif  // BASE_STACKTRACE_ARM_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-#ifdef __GNUC__
-  void **sp = reinterpret_cast<void**>(__builtin_frame_address(0));
-#else
-# error reading stack point not yet supported on this platform.
-#endif
-
-  // On ARM, the return address is stored in the link register (r14).
-  // This is not saved on the stack frame of a leaf function.  To
-  // simplify code that reads return addresses, we call a dummy
-  // function so that the return address of this function is also
-  // stored in the stack frame.  This works at least for gcc.
-  StacktraceArmDummyFunction();
-
-  skip_count++; // skip parent frame due to indirection in stacktrace.cc
-
-  int n = 0;
-  while (sp && n < max_depth) {
-    // The GetStackFrames routine is called when we are in some
-    // informational context (the failure signal handler for example).
-    // Use the non-strict unwinding rules to produce a stack trace
-    // that is as complete as possible (even if it contains a few bogus
-    // entries in some rare cases).
-    void **next_sp = NextStackFrame<IS_STACK_FRAMES == 0>(sp);
-
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n] = *sp;
-
-#if IS_STACK_FRAMES
-      if (next_sp > sp) {
-        sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    sp = next_sp;
-  }
-  return n;
-}
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_generic-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_generic-inl.h
deleted file mode 100644
index 7d7c22d9..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_generic-inl.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Portable implementation - just use glibc
-//
-// Note:  The glibc implementation may cause a call to malloc.
-// This can cause a deadlock in HeapProfiler.
-
-#ifndef BASE_STACKTRACE_GENERIC_INL_H_
-#define BASE_STACKTRACE_GENERIC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <execinfo.h>
-#include <string.h>
-#include "gperftools/stacktrace.h"
-#endif  // BASE_STACKTRACE_GENERIC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  static const int kStackLength = 64;
-  void * stack[kStackLength];
-  int size;
-
-  size = backtrace(stack, kStackLength);
-  skip_count += 2;  // we want to skip the current and it's parent frame as well
-  int result_count = size - skip_count;
-  if (result_count < 0)
-    result_count = 0;
-  if (result_count > max_depth)
-    result_count = max_depth;
-  for (int i = 0; i < result_count; i++)
-    result[i] = stack[i + skip_count];
-
-#if IS_STACK_FRAMES
-  // No implementation for finding out the stack frame sizes yet.
-  memset(sizes, 0, sizeof(*sizes) * result_count);
-#endif
-
-  return result_count;
-}
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_impl_setup-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_impl_setup-inl.h
deleted file mode 100644
index 698c5b38..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_impl_setup-inl.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// NOTE: this is NOT to be #include-d normally. It's internal
-// implementation detail of stacktrace.cc
-//
-
-// Copyright (c) 2014, gperftools Contributors.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Aliaksey Kandratsenka <alk@tut.by>
-//
-//  based on stacktrace.cc and stacktrace_config.h by Sanjay Ghemawat
-//  and Paul Pluzhnikov from Google Inc
-
-#define SIS_CONCAT2(a, b) a##b
-#define SIS_CONCAT(a, b) SIS_CONCAT2(a,b)
-
-#define SIS_STRINGIFY(a) SIS_STRINGIFY2(a)
-#define SIS_STRINGIFY2(a) #a
-
-#define IS_STACK_FRAMES 0
-#define IS_WITH_CONTEXT 0
-#define GET_STACK_TRACE_OR_FRAMES \
-  SIS_CONCAT(GetStackTrace_, GST_SUFFIX)(void **result, int max_depth, int skip_count)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-#define IS_STACK_FRAMES 1
-#define IS_WITH_CONTEXT 0
-#define GET_STACK_TRACE_OR_FRAMES \
-  SIS_CONCAT(GetStackFrames_, GST_SUFFIX)(void **result, int *sizes, int max_depth, int skip_count)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-#define IS_STACK_FRAMES 0
-#define IS_WITH_CONTEXT 1
-#define GET_STACK_TRACE_OR_FRAMES \
-  SIS_CONCAT(GetStackTraceWithContext_, GST_SUFFIX)(void **result, int max_depth, \
-                                                   int skip_count, const void *ucp)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-#define IS_STACK_FRAMES 1
-#define IS_WITH_CONTEXT 1
-#define GET_STACK_TRACE_OR_FRAMES \
-  SIS_CONCAT(GetStackFramesWithContext_, GST_SUFFIX)(void **result, int *sizes, int max_depth, \
-                                                    int skip_count, const void *ucp)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-static GetStackImplementation SIS_CONCAT(impl__,GST_SUFFIX) = {
-  SIS_CONCAT(GetStackFrames_, GST_SUFFIX),
-  SIS_CONCAT(GetStackFramesWithContext_, GST_SUFFIX),
-  SIS_CONCAT(GetStackTrace_, GST_SUFFIX),
-  SIS_CONCAT(GetStackTraceWithContext_, GST_SUFFIX),
-  SIS_STRINGIFY(GST_SUFFIX)
-};
-
-#undef SIS_CONCAT2
-#undef SIS_CONCAT
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_instrument-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_instrument-inl.h
deleted file mode 100755
index c631765c..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_instrument-inl.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2013, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Jean Lee <xiaoyur347@gmail.com>
-// based on gcc Code-Gen-Options "-finstrument-functions" listed in
-// http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html .
-// Should run configure with CXXFLAGS="-finstrument-functions".
-
-// This file is a backtrace implementation for systems :
-// * The glibc implementation of backtrace() may cause a call to malloc,
-//   and cause a deadlock in HeapProfiler.
-// * The libunwind implementation prints no backtrace.
-
-// The backtrace arrays are stored in "thread_back_trace" variable.
-// Maybe to use thread local storage is better and should save memorys.
-
-#ifndef BASE_STACKTRACE_INSTRUMENT_INL_H_
-#define BASE_STACKTRACE_INSTRUMENT_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <execinfo.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include "gperftools/stacktrace.h"
-
-#define gettid() syscall(__NR_gettid)
-#ifndef __x86_64__
-#define MAX_THREAD (32768)
-#else
-#define MAX_THREAD (65536)
-#endif
-#define MAX_DEPTH  (30)
-#define ATTRIBUTE_NOINSTRUMENT __attribute__ ((no_instrument_function))
-
-typedef struct {
-  int   stack_depth;
-  void* frame[MAX_DEPTH];
-}BACK_TRACE;
-
-static BACK_TRACE thread_back_trace[MAX_THREAD];
-extern "C" {
-void __cyg_profile_func_enter(void *func_address,
-                              void *call_site) ATTRIBUTE_NOINSTRUMENT;
-void __cyg_profile_func_enter(void *func_address, void *call_site) {
-  (void)func_address;
-
-  BACK_TRACE* backtrace = thread_back_trace + gettid();
-  int stack_depth = backtrace->stack_depth;
-  backtrace->stack_depth = stack_depth + 1;
-  if ( stack_depth >= MAX_DEPTH ) {
-    return;
-  }
-  backtrace->frame[stack_depth] = call_site;
-}
-
-void __cyg_profile_func_exit(void *func_address,
-                             void *call_site) ATTRIBUTE_NOINSTRUMENT;
-void __cyg_profile_func_exit(void *func_address, void *call_site) {
-  (void)func_address;
-  (void)call_site;
-
-  BACK_TRACE* backtrace = thread_back_trace + gettid();
-  int stack_depth = backtrace->stack_depth;
-  backtrace->stack_depth = stack_depth - 1;
-  if ( stack_depth >= MAX_DEPTH ) {
-    return;
-  }
-  backtrace->frame[stack_depth] = 0;
-}
-}  // extern "C"
-
-static int cyg_backtrace(void **buffer, int size) {
-  BACK_TRACE* backtrace = thread_back_trace + gettid();
-  int stack_depth = backtrace->stack_depth;
-  if ( stack_depth >= MAX_DEPTH ) {
-    stack_depth = MAX_DEPTH;
-  }
-  int nSize = (size > stack_depth) ? stack_depth : size;
-  for (int i = 0; i < nSize; i++) {
-  buffer[i] = backtrace->frame[nSize - i - 1];
-  }
-
-  return nSize;
-}
-
-#endif  // BASE_STACKTRACE_INSTRUMENT_INL_H_
-
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  static const int kStackLength = 64;
-  void * stack[kStackLength];
-  int size;
-  memset(stack, 0, sizeof(stack));
-
-  size = cyg_backtrace(stack, kStackLength);
-  skip_count += 2;  // we want to skip the current and parent frame as well
-  int result_count = size - skip_count;
-  if (result_count < 0)
-    result_count = 0;
-  if (result_count > max_depth)
-    result_count = max_depth;
-  for (int i = 0; i < result_count; i++)
-    result[i] = stack[i + skip_count];
-
-#if IS_STACK_FRAMES
-  // No implementation for finding out the stack frame sizes yet.
-  memset(sizes, 0, sizeof(*sizes) * result_count);
-#endif
-
-  return result_count;
-}
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_libgcc-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_libgcc-inl.h
deleted file mode 100644
index ce9cf51..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_libgcc-inl.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2016, gperftools Contributors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file implements backtrace capturing via libgcc's
-// _Unwind_Backtrace. This generally works almost always. It will fail
-// sometimes when we're trying to capture backtrace from signal
-// handler (i.e. in cpu profiler) while some C++ code is throwing
-// exception.
-
-#ifndef BASE_STACKTRACE_LIBGCC_INL_H_
-#define BASE_STACKTRACE_LIBGCC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-extern "C" {
-#include <assert.h>
-#include <string.h>   // for memset()
-}
-
-#include <unwind.h>
-
-#include "gperftools/stacktrace.h"
-
-struct libgcc_backtrace_data {
-  void **array;
-  int skip;
-  int pos;
-  int limit;
-};
-
-static _Unwind_Reason_Code libgcc_backtrace_helper(struct _Unwind_Context *ctx,
-                                                   void *_data) {
-  libgcc_backtrace_data *data =
-    reinterpret_cast<libgcc_backtrace_data *>(_data);
-
-  if (data->skip > 0) {
-    data->skip--;
-    return _URC_NO_REASON;
-  }
-
-  if (data->pos < data->limit) {
-    void *ip = reinterpret_cast<void *>(_Unwind_GetIP(ctx));;
-    data->array[data->pos++] = ip;
-  }
-
-  return _URC_NO_REASON;
-}
-
-#endif  // BASE_STACKTRACE_LIBGCC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  libgcc_backtrace_data data;
-  data.array = result;
-  // we're also skipping current and parent's frame
-  data.skip = skip_count + 2;
-  data.pos = 0;
-  data.limit = max_depth;
-
-  _Unwind_Backtrace(libgcc_backtrace_helper, &data);
-
-  if (data.pos > 1 && data.array[data.pos - 1] == NULL)
-    --data.pos;
-
-#if IS_STACK_FRAMES
-  // No implementation for finding out the stack frame sizes.
-  memset(sizes, 0, sizeof(*sizes) * data.pos);
-#endif
-
-  return data.pos;
-}
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_libunwind-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_libunwind-inl.h
deleted file mode 100644
index 6f361ecd..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_libunwind-inl.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Arun Sharma
-//
-// Produce stack trace using libunwind
-
-#ifndef BASE_STACKTRACE_LIBINWIND_INL_H_
-#define BASE_STACKTRACE_LIBINWIND_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-// We only need local unwinder.
-#define UNW_LOCAL_ONLY
-
-extern "C" {
-#include <assert.h>
-#include <string.h>   // for memset()
-#include <libunwind.h>
-}
-#include "gperftools/stacktrace.h"
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-
-// Sometimes, we can try to get a stack trace from within a stack
-// trace, because libunwind can call mmap (maybe indirectly via an
-// internal mmap based memory allocator), and that mmap gets trapped
-// and causes a stack-trace request.  If were to try to honor that
-// recursive request, we'd end up with infinite recursion or deadlock.
-// Luckily, it's safe to ignore those subsequent traces.  In such
-// cases, we return 0 to indicate the situation.
-static __thread int recursive ATTR_INITIAL_EXEC;
-
-#if defined(TCMALLOC_ENABLE_UNWIND_FROM_UCONTEXT) && (defined(__i386__) || defined(__x86_64__)) && defined(__GNU_LIBRARY__)
-#define BASE_STACKTRACE_UNW_CONTEXT_IS_UCONTEXT 1
-#endif
-
-#endif  // BASE_STACKTRACE_LIBINWIND_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  void *ip;
-  int n = 0;
-  unw_cursor_t cursor;
-  unw_context_t uc;
-#if IS_STACK_FRAMES
-  unw_word_t sp = 0, next_sp = 0;
-#endif
-
-  if (recursive) {
-    return 0;
-  }
-  ++recursive;
-
-#if (IS_WITH_CONTEXT && defined(BASE_STACKTRACE_UNW_CONTEXT_IS_UCONTEXT))
-  if (ucp) {
-    uc = *(static_cast<unw_context_t *>(const_cast<void *>(ucp)));
-    /* this is a bit weird. profiler.cc calls us with signal's ucontext
-     * yet passing us 2 as skip_count and essentially assuming we won't
-     * use ucontext. */
-    /* In order to fix that I'm going to assume that if ucp is
-     * non-null we're asked to ignore skip_count in case we're
-     * able to use ucp */
-    skip_count = 0;
-  } else {
-    unw_getcontext(&uc);
-    skip_count += 2;         // Do not include current and parent frame
-  }
-#else
-  unw_getcontext(&uc);
-  skip_count += 2;         // Do not include current and parent frame
-#endif
-
-  int ret = unw_init_local(&cursor, &uc);
-  assert(ret >= 0);
-
-  while (skip_count--) {
-    if (unw_step(&cursor) <= 0) {
-      goto out;
-    }
-#if IS_STACK_FRAMES
-    if (unw_get_reg(&cursor, UNW_REG_SP, &next_sp)) {
-      goto out;
-    }
-#endif
-  }
-
-  while (n < max_depth) {
-    if (unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip) < 0) {
-      break;
-    }
-#if IS_STACK_FRAMES
-    sizes[n] = 0;
-#endif
-    result[n++] = ip;
-    if (unw_step(&cursor) <= 0) {
-      break;
-    }
-#if IS_STACK_FRAMES
-    sp = next_sp;
-    if (unw_get_reg(&cursor, UNW_REG_SP, &next_sp) , 0) {
-      break;
-    }
-    sizes[n - 1] = next_sp - sp;
-#endif
-  }
-out:
-  --recursive;
-  return n;
-}
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_powerpc-darwin-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_powerpc-darwin-inl.h
deleted file mode 100644
index c4c2edb..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_powerpc-darwin-inl.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Produce stack trace.  ABI documentation reference can be found at:
-// * PowerPC32 ABI: https://www.power.org/documentation/
-// power-architecture-32-bit-abi-supplement-1-0-embeddedlinuxunified/
-// * PowerPC64 ABI:
-// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
-
-#ifndef BASE_STACKTRACE_POWERPC_INL_H_
-#define BASE_STACKTRACE_POWERPC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <stdint.h>   // for uintptr_t
-#include <stdlib.h>   // for NULL
-#include <gperftools/stacktrace.h>
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING>
-static void **NextStackFrame(void **old_sp) {
-  void **new_sp = (void **) *old_sp;
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp) return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp) return NULL;
-    // And allow frames upto about 1MB.
-    if ((new_sp > old_sp)
-        && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
-  }
-  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
-  return new_sp;
-}
-
-// This ensures that GetStackTrace stes up the Link Register properly.
-void StacktracePowerPCDummyFunction() __attribute__((noinline));
-void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
-#endif  // BASE_STACKTRACE_POWERPC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-int GET_STACK_TRACE_OR_FRAMES {
-  void **sp;
-  // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
-  // and Darwin 8.8.1 (Tiger) use as 1.38.  This means we have to use a
-  // different asm syntax.  I don't know quite the best way to discriminate
-  // systems using the old as from the new one; I've gone with __APPLE__.
-  // TODO(csilvers): use autoconf instead, to look for 'as --version' == 1 or 2
-  __asm__ volatile ("mr %0,r1" : "=r" (sp));
-
-  // On PowerPC, the "Link Register" or "Link Record" (LR), is a stack
-  // entry that holds the return address of the subroutine call (what
-  // instruction we run after our function finishes).  This is the
-  // same as the stack-pointer of our parent routine, which is what we
-  // want here.  While the compiler will always(?) set up LR for
-  // subroutine calls, it may not for leaf functions (such as this one).
-  // This routine forces the compiler (at least gcc) to push it anyway.
-  StacktracePowerPCDummyFunction();
-
-#if IS_STACK_FRAMES
-  // Note we do *not* increment skip_count here for the SYSV ABI.  If
-  // we did, the list of stack frames wouldn't properly match up with
-  // the list of return addresses.  Note this means the top pc entry
-  // is probably bogus for linux/ppc (and other SYSV-ABI systems).
-#else
-  // The LR save area is used by the callee, so the top entry is bogus.
-  skip_count++;
-#endif
-
-  int n = 0;
-  while (sp && n < max_depth) {
-    // The GetStackFrames routine is called when we are in some
-    // informational context (the failure signal handler for example).
-    // Use the non-strict unwinding rules to produce a stack trace
-    // that is as complete as possible (even if it contains a few
-    // bogus entries in some rare cases).
-    void **next_sp = NextStackFrame<!IS_STACK_FRAMES>(sp);
-
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      // PowerPC has 3 main ABIs, which say where in the stack the
-      // Link Register is.  For DARWIN and AIX (used by apple and
-      // linux ppc64), it's in sp[2].  For SYSV (used by linux ppc),
-      // it's in sp[1].
-#if defined(__PPC64__)
-      // This check is in case the compiler doesn't define _CALL_AIX/etc.
-      result[n] = *(sp+2);
-#elif defined(__linux)
-      // This check is in case the compiler doesn't define _CALL_SYSV.
-      result[n] = *(sp+1);
-#endif
-
-#if IS_STACK_FRAMES
-      if (next_sp > sp) {
-        sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    sp = next_sp;
-  }
-  return n;
-}
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_powerpc-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_powerpc-inl.h
deleted file mode 100644
index 811d6cc9..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_powerpc-inl.h
+++ /dev/null
@@ -1,176 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// Produce stack trace.  I'm guessing (hoping!) the code is much like
-// for x86.  For apple machines, at least, it seems to be; see
-//    http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html
-//    http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
-// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882
-
-#ifndef BASE_STACKTRACE_POWERPC_INL_H_
-#define BASE_STACKTRACE_POWERPC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <stdint.h>   // for uintptr_t
-#include <stdlib.h>   // for NULL
-#include <gperftools/stacktrace.h>
-
-struct layout_ppc {
-  struct layout_ppc *next;
-#if defined(__APPLE__) || (defined(__linux) && defined(__PPC64__))
-  long condition_register;
-#endif
-  void *return_addr;
-};
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING>
-static layout_ppc *NextStackFrame(layout_ppc *current) {
-  uintptr_t old_sp = (uintptr_t)(current);
-  uintptr_t new_sp = (uintptr_t)(current->next);
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp)
-      return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if (new_sp - old_sp > 100000)
-      return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp)
-      return NULL;
-    // And allow frames upto about 1MB.
-    if ((new_sp > old_sp) && (new_sp - old_sp > 1000000))
-      return NULL;
-  }
-  if (new_sp & (sizeof(void *) - 1))
-    return NULL;
-  return current->next;
-}
-
-// This ensures that GetStackTrace stes up the Link Register properly.
-void StacktracePowerPCDummyFunction() __attribute__((noinline));
-void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
-#endif  // BASE_STACKTRACE_POWERPC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// Load instruction used on top-of-stack get.
-#if defined(__PPC64__) || defined(__LP64__)
-# define LOAD "ld"
-#else
-# define LOAD "lwz"
-#endif
-
-#if defined(__linux__) && defined(__PPC__)
-# define TOP_STACK "%0,0(1)"
-#elif defined(__MACH__) && defined(__APPLE__)
-// Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
-// and Darwin 8.8.1 (Tiger) use as 1.38.  This means we have to use a
-// different asm syntax.  I don't know quite the best way to discriminate
-// systems using the old as from the new one; I've gone with __APPLE__.
-// TODO(csilvers): use autoconf instead, to look for 'as --version' == 1 or 2
-# define TOP_STACK "%0,0(r1)"
-#endif
-
-
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  layout_ppc *current;
-  int n;
-
-  // Force GCC to spill LR.
-  asm volatile ("" : "=l"(current));
-
-  // Get the address on top-of-stack
-  asm volatile (LOAD " " TOP_STACK : "=r"(current));
-
-  StacktracePowerPCDummyFunction();
-
-  n = 0;
-  skip_count++; // skip parent's frame due to indirection in
-                // stacktrace.cc
-  while (current && n < max_depth) {
-
-    // The GetStackFrames routine is called when we are in some
-    // informational context (the failure signal handler for example).
-    // Use the non-strict unwinding rules to produce a stack trace
-    // that is as complete as possible (even if it contains a few
-    // bogus entries in some rare cases).
-    layout_ppc *next = NextStackFrame<!IS_STACK_FRAMES>(current);
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n] = current->return_addr;
-#if IS_STACK_FRAMES
-      if (next > current) {
-        sizes[n] = (uintptr_t)next - (uintptr_t)current;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    current = next;
-  }
-
-  // It's possible the second-last stack frame can't return
-  // (that is, it's __libc_start_main), in which case
-  // the CRT startup code will have set its LR to 'NULL'.
-  if (n > 0 && result[n-1] == NULL)
-    n--;
-
-  return n;
-}
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_powerpc-linux-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_powerpc-linux-inl.h
deleted file mode 100644
index a301a46..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_powerpc-linux-inl.h
+++ /dev/null
@@ -1,231 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// Produce stack trace.  ABI documentation reference can be found at:
-// * PowerPC32 ABI: https://www.power.org/documentation/
-// power-architecture-32-bit-abi-supplement-1-0-embeddedlinuxunified/
-// * PowerPC64 ABI:
-// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
-
-#ifndef BASE_STACKTRACE_POWERPC_INL_H_
-#define BASE_STACKTRACE_POWERPC_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include <stdint.h>   // for uintptr_t
-#include <stdlib.h>   // for NULL
-#include <signal.h>  // for siginfo_t
-#include <gperftools/stacktrace.h>
-#include <base/vdso_support.h>
-
-#if defined(HAVE_SYS_UCONTEXT_H)
-#include <sys/ucontext.h>
-#elif defined(HAVE_UCONTEXT_H)
-#include <ucontext.h>  // for ucontext_t
-#endif
-
-// PowerPC64 Little Endian follows BE wrt. backchain, condition register,
-// and LR save area, so no need to adjust the reading struct.
-struct layout_ppc {
-  struct layout_ppc *next;
-#ifdef __PPC64__
-  long condition_register;
-#endif
-  void *return_addr;
-};
-
-// Signal callbacks are handled by the vDSO symbol:
-//
-// * PowerPC64 Linux (arch/powerpc/kernel/vdso64/sigtramp.S):
-//   __kernel_sigtramp_rt64
-// * PowerPC32 Linux (arch/powerpc/kernel/vdso32/sigtramp.S):
-//   __kernel_sigtramp32
-//   __kernel_sigtramp_rt32
-//
-// So a backtrace may need to specially handling if the symbol readed is
-// the signal trampoline.
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING>
-static layout_ppc *NextStackFrame(layout_ppc *current) {
-  uintptr_t old_sp = (uintptr_t)(current);
-  uintptr_t new_sp = (uintptr_t)(current->next);
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp)
-      return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if (new_sp - old_sp > 100000)
-      return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp)
-      return NULL;
-    // And allow frames upto about 1MB.
-    if ((new_sp > old_sp) && (new_sp - old_sp > 1000000))
-      return NULL;
-  }
-  if (new_sp & (sizeof(void *) - 1))
-    return NULL;
-  return current->next;
-}
-
-// This ensures that GetStackTrace stes up the Link Register properly.
-void StacktracePowerPCDummyFunction() __attribute__((noinline));
-void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
-#endif  // BASE_STACKTRACE_POWERPC_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// Load instruction used on top-of-stack get.
-#if defined(__PPC64__) || defined(__LP64__)
-# define LOAD "ld"
-#else
-# define LOAD "lwz"
-#endif
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-static int GET_STACK_TRACE_OR_FRAMES {
-  layout_ppc *current;
-  int n;
-
-  // Get the address on top-of-stack
-  current = reinterpret_cast<layout_ppc*> (__builtin_frame_address (0));
-  // And ignore the current symbol
-  current = current->next;
-
-  StacktracePowerPCDummyFunction();
-
-  n = 0;
-  skip_count++; // skip parent's frame due to indirection in
-                // stacktrace.cc
-
-  base::VDSOSupport vdso;
-  base::ElfMemImage::SymbolInfo rt_sigreturn_symbol_info;
-#ifdef __PPC64__
-  const void *sigtramp64_vdso = 0;
-  if (vdso.LookupSymbol("__kernel_sigtramp_rt64", "LINUX_2.6.15", STT_NOTYPE,
-                        &rt_sigreturn_symbol_info))
-    sigtramp64_vdso = rt_sigreturn_symbol_info.address;
-#else
-  const void *sigtramp32_vdso = 0;
-  if (vdso.LookupSymbol("__kernel_sigtramp32", "LINUX_2.6.15", STT_NOTYPE,
-                        &rt_sigreturn_symbol_info))
-    sigtramp32_vdso = rt_sigreturn_symbol_info.address;
-  const void *sigtramp32_rt_vdso = 0;
-  if (vdso.LookupSymbol("__kernel_sigtramp_rt32", "LINUX_2.6.15", STT_NOTYPE,
-                        &rt_sigreturn_symbol_info))
-    sigtramp32_rt_vdso = rt_sigreturn_symbol_info.address;
-#endif
-
-  while (current && n < max_depth) {
-
-    // The GetStackFrames routine is called when we are in some
-    // informational context (the failure signal handler for example).
-    // Use the non-strict unwinding rules to produce a stack trace
-    // that is as complete as possible (even if it contains a few
-    // bogus entries in some rare cases).
-    layout_ppc *next = NextStackFrame<!IS_STACK_FRAMES>(current);
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n] = current->return_addr;
-#ifdef __PPC64__
-      if (sigtramp64_vdso && (sigtramp64_vdso == current->return_addr)) {
-        struct signal_frame_64 {
-          char dummy[128];
-          ucontext_t uc;
-        // We don't care about the rest, since the IP value is at 'uc' field.
-        } *sigframe = reinterpret_cast<signal_frame_64*>(current);
-        result[n] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP];
-      }
-#else
-      if (sigtramp32_vdso && (sigtramp32_vdso == current->return_addr)) {
-        struct signal_frame_32 {
-          char dummy[64];
-          struct sigcontext sctx;
-          mcontext_t mctx;
-          // We don't care about the rest, since IP value is at 'mctx' field.
-        } *sigframe = reinterpret_cast<signal_frame_32*>(current);
-        result[n] = (void*) sigframe->mctx.gregs[PT_NIP];
-      } else if (sigtramp32_rt_vdso && (sigtramp32_rt_vdso == current->return_addr)) {
-        struct rt_signal_frame_32 {
-          char dummy[64 + 16];
-          siginfo_t info;
-          ucontext_t uc;
-          // We don't care about the rest, since IP value is at 'uc' field.A
-        } *sigframe = reinterpret_cast<rt_signal_frame_32*>(current);
-        result[n] = (void*) sigframe->uc.uc_mcontext.uc_regs->gregs[PT_NIP];
-      }
-#endif
-
-#if IS_STACK_FRAMES
-      if (next > current) {
-        sizes[n] = (uintptr_t)next - (uintptr_t)current;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    current = next;
-  }
-
-  // It's possible the second-last stack frame can't return
-  // (that is, it's __libc_start_main), in which case
-  // the CRT startup code will have set its LR to 'NULL'.
-  if (n > 0 && result[n-1] == NULL)
-    n--;
-
-  return n;
-}
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_win32-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_win32-inl.h
deleted file mode 100644
index 663e9a5..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_win32-inl.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Produces a stack trace for Windows.  Normally, one could use
-// stacktrace_x86-inl.h or stacktrace_x86_64-inl.h -- and indeed, that
-// should work for binaries compiled using MSVC in "debug" mode.
-// However, in "release" mode, Windows uses frame-pointer
-// optimization, which makes getting a stack trace very difficult.
-//
-// There are several approaches one can take.  One is to use Windows
-// intrinsics like StackWalk64.  These can work, but have restrictions
-// on how successful they can be.  Another attempt is to write a
-// version of stacktrace_x86-inl.h that has heuristic support for
-// dealing with FPO, similar to what WinDbg does (see
-// http://www.nynaeve.net/?p=97).
-//
-// The solution we've ended up doing is to call the undocumented
-// windows function RtlCaptureStackBackTrace, which probably doesn't
-// work with FPO but at least is fast, and doesn't require a symbol
-// server.
-//
-// This code is inspired by a patch from David Vitek:
-//   http://code.google.com/p/gperftools/issues/detail?id=83
-
-#ifndef BASE_STACKTRACE_WIN32_INL_H_
-#define BASE_STACKTRACE_WIN32_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include "config.h"
-#include <windows.h>    // for GetProcAddress and GetModuleHandle
-#include <assert.h>
-
-typedef USHORT NTAPI RtlCaptureStackBackTrace_Function(
-    IN ULONG frames_to_skip,
-    IN ULONG frames_to_capture,
-    OUT PVOID *backtrace,
-    OUT PULONG backtrace_hash);
-
-// Load the function we need at static init time, where we don't have
-// to worry about someone else holding the loader's lock.
-static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =
-   (RtlCaptureStackBackTrace_Function*)
-   GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
-
-static int GetStackTrace_win32(void** result, int max_depth,
-                               int skip_count) {
-  if (!RtlCaptureStackBackTrace_fn) {
-    // TODO(csilvers): should we log an error here?
-    return 0;     // can't find a stacktrace with no function to call
-  }
-  return (int)RtlCaptureStackBackTrace_fn(skip_count + 3, max_depth,
-                                          result, 0);
-}
-
-static int not_implemented(void) {
-  assert(0 == "Not yet implemented");
-  return 0;
-}
-
-static int GetStackFrames_win32(void** /* pcs */,
-                                int* /* sizes */,
-                                int /* max_depth */,
-                                int /* skip_count */) {
-  return not_implemented();
-}
-
-static int GetStackFramesWithContext_win32(void** result, int* sizes, int max_depth,
-                                           int skip_count, const void *uc) {
-  return not_implemented();
-}
-
-static int GetStackTraceWithContext_win32(void** result, int max_depth,
-                                          int skip_count, const void *uc) {
-  return not_implemented();
-}
-
-
-#endif  // BASE_STACKTRACE_WIN32_INL_H_
diff --git a/third_party/tcmalloc/vendor/src/stacktrace_x86-inl.h b/third_party/tcmalloc/vendor/src/stacktrace_x86-inl.h
deleted file mode 100644
index 46eb5d8..0000000
--- a/third_party/tcmalloc/vendor/src/stacktrace_x86-inl.h
+++ /dev/null
@@ -1,354 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Produce stack trace
-
-#ifndef BASE_STACKTRACE_X86_INL_H_
-#define BASE_STACKTRACE_X86_INL_H_
-// Note: this file is included into stacktrace.cc more than once.
-// Anything that should only be defined once should be here:
-
-#include "config.h"
-#include <stdlib.h>   // for NULL
-#include <assert.h>
-#if defined(HAVE_SYS_UCONTEXT_H)
-#include <sys/ucontext.h>
-#elif defined(HAVE_UCONTEXT_H)
-#include <ucontext.h>  // for ucontext_t
-#elif defined(HAVE_CYGWIN_SIGNAL_H)
-// cygwin/signal.h has a buglet where it uses pthread_attr_t without
-// #including <pthread.h> itself.  So we have to do it.
-# ifdef HAVE_PTHREAD
-# include <pthread.h>
-# endif
-#include <cygwin/signal.h>
-typedef ucontext ucontext_t;
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>   // for uintptr_t
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h> // for msync
-#include "base/vdso_support.h"
-#endif
-
-#include "gperftools/stacktrace.h"
-
-#if defined(__linux__) && defined(__i386__) && defined(__ELF__) && defined(HAVE_MMAP)
-// Count "push %reg" instructions in VDSO __kernel_vsyscall(),
-// preceding "syscall" or "sysenter".
-// If __kernel_vsyscall uses frame pointer, answer 0.
-//
-// kMaxBytes tells how many instruction bytes of __kernel_vsyscall
-// to analyze before giving up. Up to kMaxBytes+1 bytes of
-// instructions could be accessed.
-//
-// Here are known __kernel_vsyscall instruction sequences:
-//
-// SYSENTER (linux-2.6.26/arch/x86/vdso/vdso32/sysenter.S).
-// Used on Intel.
-//  0xffffe400 <__kernel_vsyscall+0>:       push   %ecx
-//  0xffffe401 <__kernel_vsyscall+1>:       push   %edx
-//  0xffffe402 <__kernel_vsyscall+2>:       push   %ebp
-//  0xffffe403 <__kernel_vsyscall+3>:       mov    %esp,%ebp
-//  0xffffe405 <__kernel_vsyscall+5>:       sysenter
-//
-// SYSCALL (see linux-2.6.26/arch/x86/vdso/vdso32/syscall.S).
-// Used on AMD.
-//  0xffffe400 <__kernel_vsyscall+0>:       push   %ebp
-//  0xffffe401 <__kernel_vsyscall+1>:       mov    %ecx,%ebp
-//  0xffffe403 <__kernel_vsyscall+3>:       syscall
-//
-// i386 (see linux-2.6.26/arch/x86/vdso/vdso32/int80.S)
-//  0xffffe400 <__kernel_vsyscall+0>:       int $0x80
-//  0xffffe401 <__kernel_vsyscall+1>:       ret
-//
-static const int kMaxBytes = 10;
-
-// We use assert()s instead of DCHECK()s -- this is too low level
-// for DCHECK().
-
-static int CountPushInstructions(const unsigned char *const addr) {
-  int result = 0;
-  for (int i = 0; i < kMaxBytes; ++i) {
-    if (addr[i] == 0x89) {
-      // "mov reg,reg"
-      if (addr[i + 1] == 0xE5) {
-        // Found "mov %esp,%ebp".
-        return 0;
-      }
-      ++i;  // Skip register encoding byte.
-    } else if (addr[i] == 0x0F &&
-               (addr[i + 1] == 0x34 || addr[i + 1] == 0x05)) {
-      // Found "sysenter" or "syscall".
-      return result;
-    } else if ((addr[i] & 0xF0) == 0x50) {
-      // Found "push %reg".
-      ++result;
-    } else if (addr[i] == 0xCD && addr[i + 1] == 0x80) {
-      // Found "int $0x80"
-      assert(result == 0);
-      return 0;
-    } else {
-      // Unexpected instruction.
-      assert(0 == "unexpected instruction in __kernel_vsyscall");
-      return 0;
-    }
-  }
-  // Unexpected: didn't find SYSENTER or SYSCALL in
-  // [__kernel_vsyscall, __kernel_vsyscall + kMaxBytes) interval.
-  assert(0 == "did not find SYSENTER or SYSCALL in __kernel_vsyscall");
-  return 0;
-}
-#endif
-
-// Given a pointer to a stack frame, locate and return the calling
-// stackframe, or return NULL if no stackframe can be found. Perform sanity
-// checks (the strictness of which is controlled by the boolean parameter
-// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
-template<bool STRICT_UNWINDING, bool WITH_CONTEXT>
-static void **NextStackFrame(void **old_sp, const void *uc) {
-  void **new_sp = (void **) *old_sp;
-
-#if defined(__linux__) && defined(__i386__) && defined(HAVE_VDSO_SUPPORT)
-  if (WITH_CONTEXT && uc != NULL) {
-    // How many "push %reg" instructions are there at __kernel_vsyscall?
-    // This is constant for a given kernel and processor, so compute
-    // it only once.
-    static int num_push_instructions = -1;  // Sentinel: not computed yet.
-    // Initialize with sentinel value: __kernel_rt_sigreturn can not possibly
-    // be there.
-    static const unsigned char *kernel_rt_sigreturn_address = NULL;
-    static const unsigned char *kernel_vsyscall_address = NULL;
-    if (num_push_instructions == -1) {
-      base::VDSOSupport vdso;
-      if (vdso.IsPresent()) {
-        base::VDSOSupport::SymbolInfo rt_sigreturn_symbol_info;
-        base::VDSOSupport::SymbolInfo vsyscall_symbol_info;
-        if (!vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_2.5",
-                               STT_FUNC, &rt_sigreturn_symbol_info) ||
-            !vdso.LookupSymbol("__kernel_vsyscall", "LINUX_2.5",
-                               STT_FUNC, &vsyscall_symbol_info) ||
-            rt_sigreturn_symbol_info.address == NULL ||
-            vsyscall_symbol_info.address == NULL) {
-          // Unexpected: 32-bit VDSO is present, yet one of the expected
-          // symbols is missing or NULL.
-          assert(0 == "VDSO is present, but doesn't have expected symbols");
-          num_push_instructions = 0;
-        } else {
-          kernel_rt_sigreturn_address =
-              reinterpret_cast<const unsigned char *>(
-                  rt_sigreturn_symbol_info.address);
-          kernel_vsyscall_address =
-              reinterpret_cast<const unsigned char *>(
-                  vsyscall_symbol_info.address);
-          num_push_instructions =
-              CountPushInstructions(kernel_vsyscall_address);
-        }
-      } else {
-        num_push_instructions = 0;
-      }
-    }
-    if (num_push_instructions != 0 && kernel_rt_sigreturn_address != NULL &&
-        old_sp[1] == kernel_rt_sigreturn_address) {
-      const ucontext_t *ucv = static_cast<const ucontext_t *>(uc);
-      // This kernel does not use frame pointer in its VDSO code,
-      // and so %ebp is not suitable for unwinding.
-      void **const reg_ebp =
-          reinterpret_cast<void **>(ucv->uc_mcontext.gregs[REG_EBP]);
-      const unsigned char *const reg_eip =
-          reinterpret_cast<unsigned char *>(ucv->uc_mcontext.gregs[REG_EIP]);
-      if (new_sp == reg_ebp &&
-          kernel_vsyscall_address <= reg_eip &&
-          reg_eip - kernel_vsyscall_address < kMaxBytes) {
-        // We "stepped up" to __kernel_vsyscall, but %ebp is not usable.
-        // Restore from 'ucv' instead.
-        void **const reg_esp =
-            reinterpret_cast<void **>(ucv->uc_mcontext.gregs[REG_ESP]);
-        // Check that alleged %esp is not NULL and is reasonably aligned.
-        if (reg_esp &&
-            ((uintptr_t)reg_esp & (sizeof(reg_esp) - 1)) == 0) {
-          // Check that alleged %esp is actually readable. This is to prevent
-          // "double fault" in case we hit the first fault due to e.g. stack
-          // corruption.
-          //
-          // page_size is linker-initalized to avoid async-unsafe locking
-          // that GCC would otherwise insert (__cxa_guard_acquire etc).
-          static int page_size;
-          if (page_size == 0) {
-            // First time through.
-            page_size = getpagesize();
-          }
-          void *const reg_esp_aligned =
-              reinterpret_cast<void *>(
-                  (uintptr_t)(reg_esp + num_push_instructions - 1) &
-                  ~(page_size - 1));
-          if (msync(reg_esp_aligned, page_size, MS_ASYNC) == 0) {
-            // Alleged %esp is readable, use it for further unwinding.
-            new_sp = reinterpret_cast<void **>(
-                reg_esp[num_push_instructions - 1]);
-          }
-        }
-      }
-    }
-  }
-#endif
-
-  // Check that the transition from frame pointer old_sp to frame
-  // pointer new_sp isn't clearly bogus
-  if (STRICT_UNWINDING) {
-    // With the stack growing downwards, older stack frame must be
-    // at a greater address that the current one.
-    if (new_sp <= old_sp) return NULL;
-    // Assume stack frames larger than 100,000 bytes are bogus.
-    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
-  } else {
-    // In the non-strict mode, allow discontiguous stack frames.
-    // (alternate-signal-stacks for example).
-    if (new_sp == old_sp) return NULL;
-    if (new_sp > old_sp) {
-      // And allow frames upto about 1MB.
-      const uintptr_t delta = (uintptr_t)new_sp - (uintptr_t)old_sp;
-      const uintptr_t acceptable_delta = 1000000;
-      if (delta > acceptable_delta) {
-        return NULL;
-      }
-    }
-  }
-  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
-#ifdef __i386__
-  // On 64-bit machines, the stack pointer can be very close to
-  // 0xffffffff, so we explicitly check for a pointer into the
-  // last two pages in the address space
-  if ((uintptr_t)new_sp >= 0xffffe000) return NULL;
-#endif
-#ifdef HAVE_MMAP
-  if (!STRICT_UNWINDING) {
-    // Lax sanity checks cause a crash on AMD-based machines with
-    // VDSO-enabled kernels.
-    // Make an extra sanity check to insure new_sp is readable.
-    // Note: NextStackFrame<false>() is only called while the program
-    //       is already on its last leg, so it's ok to be slow here.
-    static int page_size = getpagesize();
-    void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1));
-    if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1)
-      return NULL;
-  }
-#endif
-  return new_sp;
-}
-
-#endif  // BASE_STACKTRACE_X86_INL_H_
-
-// Note: this part of the file is included several times.
-// Do not put globals below.
-
-// The following 4 functions are generated from the code below:
-//   GetStack{Trace,Frames}()
-//   GetStack{Trace,Frames}WithContext()
-//
-// These functions take the following args:
-//   void** result: the stack-trace, as an array
-//   int* sizes: the size of each stack frame, as an array
-//               (GetStackFrames* only)
-//   int max_depth: the size of the result (and sizes) array(s)
-//   int skip_count: how many stack pointers to skip before storing in result
-//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-
-static int GET_STACK_TRACE_OR_FRAMES {
-  void **sp;
-#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) || __llvm__
-  // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8.
-  // It's always correct on llvm, and the techniques below aren't (in
-  // particular, llvm-gcc will make a copy of pcs, so it's not in sp[2]),
-  // so we also prefer __builtin_frame_address when running under llvm.
-  sp = reinterpret_cast<void**>(__builtin_frame_address(0));
-#elif defined(__i386__)
-  // Stack frame format:
-  //    sp[0]   pointer to previous frame
-  //    sp[1]   caller address
-  //    sp[2]   first argument
-  //    ...
-  // NOTE: This will break under llvm, since result is a copy and not in sp[2]
-  sp = (void **)&result - 2;
-#elif defined(__x86_64__)
-  unsigned long rbp;
-  // Move the value of the register %rbp into the local variable rbp.
-  // We need 'volatile' to prevent this instruction from getting moved
-  // around during optimization to before function prologue is done.
-  // An alternative way to achieve this
-  // would be (before this __asm__ instruction) to call Noop() defined as
-  //   static void Noop() __attribute__ ((noinline));  // prevent inlining
-  //   static void Noop() { asm(""); }  // prevent optimizing-away
-  __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
-  // Arguments are passed in registers on x86-64, so we can't just
-  // offset from &result
-  sp = (void **) rbp;
-#else
-# error Using stacktrace_x86-inl.h on a non x86 architecture!
-#endif
-
-  skip_count++; // skip parent's frame due to indirection in stacktrace.cc
-
-  int n = 0;
-  while (sp && n < max_depth) {
-    if (*(sp+1) == reinterpret_cast<void *>(0)) {
-      // In 64-bit code, we often see a frame that
-      // points to itself and has a return address of 0.
-      break;
-    }
-#if !IS_WITH_CONTEXT
-    const void *const ucp = NULL;
-#endif
-    void **next_sp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(sp, ucp);
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n] = *(sp+1);
-#if IS_STACK_FRAMES
-      if (next_sp > sp) {
-        sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
-      } else {
-        // A frame-size of 0 is used to indicate unknown frame size.
-        sizes[n] = 0;
-      }
-#endif
-      n++;
-    }
-    sp = next_sp;
-  }
-  return n;
-}
diff --git a/third_party/tcmalloc/vendor/src/static_vars.cc b/third_party/tcmalloc/vendor/src/static_vars.cc
deleted file mode 100644
index 3743d1a3..0000000
--- a/third_party/tcmalloc/vendor/src/static_vars.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Ken Ashcraft <opensource@google.com>
-
-#include <config.h>
-#include "static_vars.h"
-#include <stddef.h>                     // for NULL
-#include <new>                          // for operator new
-#ifdef HAVE_PTHREAD
-#include <pthread.h>                    // for pthread_atfork
-#endif
-#include "internal_logging.h"  // for CHECK_CONDITION
-#include "common.h"
-#include "sampler.h"           // for Sampler
-#include "getenv_safe.h"       // TCMallocGetenvSafe
-#include "base/googleinit.h"
-#include "maybe_threads.h"
-
-namespace tcmalloc {
-
-#if defined(HAVE_FORK) && defined(HAVE_PTHREAD)
-// These following two functions are registered via pthread_atfork to make
-// sure the central_cache locks remain in a consisten state in the forked
-// version of the thread.
-
-void CentralCacheLockAll()
-{
-  Static::pageheap_lock()->Lock();
-  for (int i = 0; i < Static::num_size_classes(); ++i)
-    Static::central_cache()[i].Lock();
-}
-
-void CentralCacheUnlockAll()
-{
-  for (int i = 0; i < Static::num_size_classes(); ++i)
-    Static::central_cache()[i].Unlock();
-  Static::pageheap_lock()->Unlock();
-}
-#endif
-
-bool Static::inited_;
-SpinLock Static::pageheap_lock_(SpinLock::LINKER_INITIALIZED);
-SizeMap Static::sizemap_;
-CentralFreeListPadded Static::central_cache_[kClassSizesMax];
-PageHeapAllocator<Span> Static::span_allocator_;
-PageHeapAllocator<StackTrace> Static::stacktrace_allocator_;
-Span Static::sampled_objects_;
-PageHeapAllocator<StackTraceTable::Bucket> Static::bucket_allocator_;
-StackTrace* Static::growth_stacks_ = NULL;
-Static::PageHeapStorage Static::pageheap_;
-
-void Static::InitStaticVars() {
-  sizemap_.Init();
-  span_allocator_.Init();
-  span_allocator_.New(); // Reduce cache conflicts
-  span_allocator_.New(); // Reduce cache conflicts
-  stacktrace_allocator_.Init();
-  bucket_allocator_.Init();
-  // Do a bit of sanitizing: make sure central_cache is aligned properly
-  CHECK_CONDITION((sizeof(central_cache_[0]) % 64) == 0);
-  for (int i = 0; i < num_size_classes(); ++i) {
-    central_cache_[i].Init(i);
-  }
-
-  new (&pageheap_.memory) PageHeap;
-
-  bool aggressive_decommit =
-    tcmalloc::commandlineflags::StringToBool(
-      TCMallocGetenvSafe("TCMALLOC_AGGRESSIVE_DECOMMIT"), false);
-
-  pageheap()->SetAggressiveDecommit(aggressive_decommit);
-
-  inited_ = true;
-
-  DLL_Init(&sampled_objects_);
-}
-
-void Static::InitLateMaybeRecursive() {
-#if defined(HAVE_FORK) && defined(HAVE_PTHREAD) \
-  && !defined(__APPLE__) && !defined(TCMALLOC_NO_ATFORK)
-  // OSX has it's own way of handling atfork in malloc (see
-  // libc_override_osx.h).
-  //
-  // For other OSes we do pthread_atfork even if standard seemingly
-  // discourages pthread_atfork, asking apps to do only
-  // async-signal-safe calls between fork and exec.
-  //
-  // We're deliberately attempting to register atfork handlers as part
-  // of malloc initialization. So very early. This ensures that our
-  // handler is called last and that means fork will try to grab
-  // tcmalloc locks last avoiding possible issues with many other
-  // locks that are held around calls to malloc. I.e. if we don't do
-  // that, fork() grabbing malloc lock before such other lock would be
-  // prone to deadlock, if some other thread holds other lock and
-  // calls malloc.
-  //
-  // We still leave some way of disabling it via
-  // -DTCMALLOC_NO_ATFORK. It looks like on glibc even with fully
-  // static binaries malloc is really initialized very early. But I
-  // can see how combination of static linking and other libc-s could
-  // be less fortunate and allow some early app constructors to run
-  // before malloc is ever called.
-
-  perftools_pthread_atfork(
-    CentralCacheLockAll,    // parent calls before fork
-    CentralCacheUnlockAll,  // parent calls after fork
-    CentralCacheUnlockAll); // child calls after fork
-#endif
-
-#ifndef NDEBUG
-  // pthread_atfork above may malloc sometimes. Lets ensure we test
-  // that malloc works from here.
-  free(malloc(1));
-#endif
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/vendor/src/static_vars.h b/third_party/tcmalloc/vendor/src/static_vars.h
deleted file mode 100644
index 3eeae0f..0000000
--- a/third_party/tcmalloc/vendor/src/static_vars.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Ken Ashcraft <opensource@google.com>
-//
-// Static variables shared by multiple classes.
-
-#ifndef TCMALLOC_STATIC_VARS_H_
-#define TCMALLOC_STATIC_VARS_H_
-
-#include <config.h>
-#include "base/basictypes.h"
-#include "base/spinlock.h"
-#include "central_freelist.h"
-#include "common.h"
-#include "page_heap.h"
-#include "page_heap_allocator.h"
-#include "span.h"
-#include "stack_trace_table.h"
-
-namespace tcmalloc {
-
-class Static {
- public:
-  // Linker initialized, so this lock can be accessed at any time.
-  static SpinLock* pageheap_lock() { return &pageheap_lock_; }
-
-  // Must be called before calling any of the accessors below.
-  static void InitStaticVars();
-  static void InitLateMaybeRecursive();
-
-  // Central cache -- an array of free-lists, one per size-class.
-  // We have a separate lock per free-list to reduce contention.
-  static CentralFreeListPadded* central_cache() { return central_cache_; }
-
-  static SizeMap* sizemap() { return &sizemap_; }
-
-  static unsigned num_size_classes() { return sizemap_.num_size_classes; }
-
-  //////////////////////////////////////////////////////////////////////
-  // In addition to the explicit initialization comment, the variables below
-  // must be protected by pageheap_lock.
-
-  // Page-level allocator.
-  static PageHeap* pageheap() { return reinterpret_cast<PageHeap *>(&pageheap_.memory); }
-
-  static PageHeapAllocator<Span>* span_allocator() { return &span_allocator_; }
-
-  static PageHeapAllocator<StackTrace>* stacktrace_allocator() {
-    return &stacktrace_allocator_;
-  }
-
-  static StackTrace* growth_stacks() { return growth_stacks_; }
-  static void set_growth_stacks(StackTrace* s) { growth_stacks_ = s; }
-
-  // State kept for sampled allocations (/pprof/heap support)
-  static Span* sampled_objects() { return &sampled_objects_; }
-  static PageHeapAllocator<StackTraceTable::Bucket>* bucket_allocator() {
-    return &bucket_allocator_;
-  }
-
-  // Check if InitStaticVars() has been run.
-  static bool IsInited() { return inited_; }
-
- private:
-  // some unit tests depend on this and link to static vars
-  // imperfectly. Thus we keep those unhidden for now. Thankfully
-  // they're not performance-critical.
-  /* ATTRIBUTE_HIDDEN */ static bool inited_;
-  /* ATTRIBUTE_HIDDEN */ static SpinLock pageheap_lock_;
-
-  // These static variables require explicit initialization.  We cannot
-  // count on their constructors to do any initialization because other
-  // static variables may try to allocate memory before these variables
-  // can run their constructors.
-
-  ATTRIBUTE_HIDDEN static SizeMap sizemap_;
-  ATTRIBUTE_HIDDEN static CentralFreeListPadded central_cache_[kClassSizesMax];
-  ATTRIBUTE_HIDDEN static PageHeapAllocator<Span> span_allocator_;
-  ATTRIBUTE_HIDDEN static PageHeapAllocator<StackTrace> stacktrace_allocator_;
-  ATTRIBUTE_HIDDEN static Span sampled_objects_;
-  ATTRIBUTE_HIDDEN static PageHeapAllocator<StackTraceTable::Bucket> bucket_allocator_;
-
-  // Linked list of stack traces recorded every time we allocated memory
-  // from the system.  Useful for finding allocation sites that cause
-  // increase in the footprint of the system.  The linked list pointer
-  // is stored in trace->stack[kMaxStackDepth-1].
-  ATTRIBUTE_HIDDEN static StackTrace* growth_stacks_;
-
-  // PageHeap uses a constructor for initialization.  Like the members above,
-  // we can't depend on initialization order, so pageheap is new'd
-  // into this buffer.
-  union PageHeapStorage {
-    char memory[sizeof(PageHeap)];
-    uintptr_t extra;  // To force alignment
-  };
-  ATTRIBUTE_HIDDEN static PageHeapStorage pageheap_;
-};
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_STATIC_VARS_H_
diff --git a/third_party/tcmalloc/vendor/src/symbolize.cc b/third_party/tcmalloc/vendor/src/symbolize.cc
deleted file mode 100755
index 88609ff..0000000
--- a/third_party/tcmalloc/vendor/src/symbolize.cc
+++ /dev/null
@@ -1,296 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This forks out to pprof to do the actual symbolizing.  We might
-// be better off writing our own in C++.
-
-#include "config.h"
-#include "symbolize.h"
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>   // for write()
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>   // for socketpair() -- needed by Symbolize
-#endif
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>   // for wait() -- needed by Symbolize
-#endif
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif
-#ifdef __MACH__
-#include <mach-o/dyld.h>   // for GetProgramInvocationName()
-#include <limits.h>        // for PATH_MAX
-#endif
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-#include <io.h>            // for get_osfhandle()
-#endif
-#include <string>
-#include "base/commandlineflags.h"
-#include "base/logging.h"
-#include "base/sysinfo.h"
-#if defined(__FreeBSD__)
-#include <sys/sysctl.h>
-#endif
-
-using std::string;
-using tcmalloc::DumpProcSelfMaps;   // from sysinfo.h
-
-
-DEFINE_string(symbolize_pprof,
-              EnvToString("PPROF_PATH", "pprof"),
-              "Path to pprof to call for reporting function names.");
-
-// heap_profile_table_pprof may be referenced after destructors are
-// called (since that's when leak-checking is done), so we make
-// a more-permanent copy that won't ever get destroyed.
-static string* g_pprof_path = new string(FLAGS_symbolize_pprof);
-
-// Returns NULL if we're on an OS where we can't get the invocation name.
-// Using a static var is ok because we're not called from a thread.
-static const char* GetProgramInvocationName() {
-#if defined(HAVE_PROGRAM_INVOCATION_NAME)
-#ifdef __UCLIBC__
-  extern const char* program_invocation_name; // uclibc provides this
-#else
-  extern char* program_invocation_name;  // gcc provides this
-#endif
-  return program_invocation_name;
-#elif defined(__MACH__)
-  // We don't want to allocate memory for this since we may be
-  // calculating it when memory is corrupted.
-  static char program_invocation_name[PATH_MAX];
-  if (program_invocation_name[0] == '\0') {  // first time calculating
-    uint32_t length = sizeof(program_invocation_name);
-    if (_NSGetExecutablePath(program_invocation_name, &length))
-      return NULL;
-  }
-  return program_invocation_name;
-#elif defined(__FreeBSD__)
-  static char program_invocation_name[PATH_MAX];
-  size_t len = sizeof(program_invocation_name);
-  static const int name[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
-  if (!sysctl(name, 4, program_invocation_name, &len, NULL, 0))
-    return program_invocation_name;
-  return NULL;
-#else
-  return NULL;   // figure out a way to get argv[0]
-#endif
-}
-
-// Prints an error message when you can't run Symbolize().
-static void PrintError(const char* reason) {
-  RAW_LOG(ERROR,
-          "*** WARNING: Cannot convert addresses to symbols in output below.\n"
-          "*** Reason: %s\n"
-          "*** If you cannot fix this, try running pprof directly.\n",
-          reason);
-}
-
-void SymbolTable::Add(const void* addr) {
-  symbolization_table_[addr] = "";
-}
-
-const char* SymbolTable::GetSymbol(const void* addr) {
-  return symbolization_table_[addr];
-}
-
-// Updates symbolization_table with the pointers to symbol names corresponding
-// to its keys. The symbol names are stored in out, which is allocated and
-// freed by the caller of this routine.
-// Note that the forking/etc is not thread-safe or re-entrant.  That's
-// ok for the purpose we need -- reporting leaks detected by heap-checker
-// -- but be careful if you decide to use this routine for other purposes.
-// Returns number of symbols read on error.  If can't symbolize, returns 0
-// and emits an error message about why.
-int SymbolTable::Symbolize() {
-#if !defined(HAVE_UNISTD_H)  || !defined(HAVE_SYS_SOCKET_H) || !defined(HAVE_SYS_WAIT_H)
-  PrintError("Perftools does not know how to call a sub-process on this O/S");
-  return 0;
-#else
-  const char* argv0 = GetProgramInvocationName();
-  if (argv0 == NULL) {  // can't call symbolize if we can't figure out our name
-    PrintError("Cannot figure out the name of this executable (argv0)");
-    return 0;
-  }
-  if (access(g_pprof_path->c_str(), R_OK) != 0) {
-    PrintError("Cannot find 'pprof' (is PPROF_PATH set correctly?)");
-    return 0;
-  }
-
-  // All this work is to do two-way communication.  ugh.
-  int *child_in = NULL;   // file descriptors
-  int *child_out = NULL;  // for now, we don't worry about child_err
-  int child_fds[5][2];    // socketpair may be called up to five times below
-
-  // The client program may close its stdin and/or stdout and/or stderr
-  // thus allowing socketpair to reuse file descriptors 0, 1 or 2.
-  // In this case the communication between the forked processes may be broken
-  // if either the parent or the child tries to close or duplicate these
-  // descriptors. The loop below produces two pairs of file descriptors, each
-  // greater than 2 (stderr).
-  for (int i = 0; i < 5; i++) {
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, child_fds[i]) == -1) {
-      for (int j = 0; j < i; j++) {
-        close(child_fds[j][0]);
-        close(child_fds[j][1]);
-        PrintError("Cannot create a socket pair");
-      }
-      return 0;
-    } else {
-      if ((child_fds[i][0] > 2) && (child_fds[i][1] > 2)) {
-        if (child_in == NULL) {
-          child_in = child_fds[i];
-        } else {
-          child_out = child_fds[i];
-          for (int j = 0; j < i; j++) {
-            if (child_fds[j] == child_in) continue;
-            close(child_fds[j][0]);
-            close(child_fds[j][1]);
-          }
-          break;
-        }
-      }
-    }
-  }
-
-  switch (fork()) {
-    case -1: {  // error
-      close(child_in[0]);
-      close(child_in[1]);
-      close(child_out[0]);
-      close(child_out[1]);
-      PrintError("Unknown error calling fork()");
-      return 0;
-    }
-    case 0: {  // child
-      close(child_in[1]);   // child uses the 0's, parent uses the 1's
-      close(child_out[1]);  // child uses the 0's, parent uses the 1's
-      close(0);
-      close(1);
-      if (dup2(child_in[0], 0) == -1) _exit(1);
-      if (dup2(child_out[0], 1) == -1) _exit(2);
-      // Unset vars that might cause trouble when we fork
-      unsetenv("CPUPROFILE");
-      unsetenv("HEAPPROFILE");
-      unsetenv("HEAPCHECK");
-      unsetenv("PERFTOOLS_VERBOSE");
-      execlp(g_pprof_path->c_str(), g_pprof_path->c_str(),
-             "--symbols", argv0, NULL);
-      _exit(3);  // if execvp fails, it's bad news for us
-    }
-    default: {  // parent
-      close(child_in[0]);   // child uses the 0's, parent uses the 1's
-      close(child_out[0]);  // child uses the 0's, parent uses the 1's
-#ifdef HAVE_POLL_H
-      // Waiting for 1ms seems to give the OS time to notice any errors.
-      poll(0, 0, 1);
-      // For maximum safety, we check to make sure the execlp
-      // succeeded before trying to write.  (Otherwise we'll get a
-      // SIGPIPE.)  For systems without poll.h, we'll just skip this
-      // check, and trust that the user set PPROF_PATH correctly!
-      struct pollfd pfd = { child_in[1], POLLOUT, 0 };
-      if (!poll(&pfd, 1, 0) || !(pfd.revents & POLLOUT) ||
-          (pfd.revents & (POLLHUP|POLLERR))) {
-        PrintError("Cannot run 'pprof' (is PPROF_PATH set correctly?)");
-        return 0;
-      }
-#endif
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-      // On cygwin, DumpProcSelfMaps() takes a HANDLE, not an fd.  Convert.
-      const HANDLE symbols_handle = (HANDLE) get_osfhandle(child_in[1]);
-      DumpProcSelfMaps(symbols_handle);
-#else
-      DumpProcSelfMaps(child_in[1]);  // what pprof expects on stdin
-#endif
-
-      // Allocate 24 bytes = ("0x" + 8 bytes + "\n" + overhead) for each
-      // address to feed to pprof.
-      const int kOutBufSize = 24 * symbolization_table_.size();
-      char *pprof_buffer = new char[kOutBufSize];
-      int written = 0;
-      for (SymbolMap::const_iterator iter = symbolization_table_.begin();
-           iter != symbolization_table_.end(); ++iter) {
-        written += snprintf(pprof_buffer + written, kOutBufSize - written,
-                 // pprof expects format to be 0xXXXXXX
-                 "0x%" PRIxPTR "\n", reinterpret_cast<uintptr_t>(iter->first));
-      }
-      write(child_in[1], pprof_buffer, strlen(pprof_buffer));
-      close(child_in[1]);             // that's all we need to write
-      delete[] pprof_buffer;
-
-      const int kSymbolBufferSize = kSymbolSize * symbolization_table_.size();
-      int total_bytes_read = 0;
-      delete[] symbol_buffer_;
-      symbol_buffer_ = new char[kSymbolBufferSize];
-      memset(symbol_buffer_, '\0', kSymbolBufferSize);
-      while (1) {
-        int bytes_read = read(child_out[1], symbol_buffer_ + total_bytes_read,
-                              kSymbolBufferSize - total_bytes_read);
-        if (bytes_read < 0) {
-          close(child_out[1]);
-          PrintError("Cannot read data from pprof");
-          return 0;
-        } else if (bytes_read == 0) {
-          close(child_out[1]);
-          wait(NULL);
-          break;
-        } else {
-          total_bytes_read += bytes_read;
-        }
-      }
-      // We have successfully read the output of pprof into out.  Make sure
-      // the last symbol is full (we can tell because it ends with a \n).
-      if (total_bytes_read == 0 || symbol_buffer_[total_bytes_read - 1] != '\n')
-        return 0;
-      // make the symbolization_table_ values point to the output vector
-      SymbolMap::iterator fill = symbolization_table_.begin();
-      int num_symbols = 0;
-      const char *current_name = symbol_buffer_;
-      for (int i = 0; i < total_bytes_read; i++) {
-        if (symbol_buffer_[i] == '\n') {
-          fill->second = current_name;
-          symbol_buffer_[i] = '\0';
-          current_name = symbol_buffer_ + i + 1;
-          fill++;
-          num_symbols++;
-        }
-      }
-      return num_symbols;
-    }
-  }
-  PrintError("Unkown error (should never occur!)");
-  return 0;  // shouldn't be reachable
-#endif
-}
diff --git a/third_party/tcmalloc/vendor/src/symbolize.h b/third_party/tcmalloc/vendor/src/symbolize.h
deleted file mode 100644
index 728d073..0000000
--- a/third_party/tcmalloc/vendor/src/symbolize.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-
-#ifndef TCMALLOC_SYMBOLIZE_H_
-#define TCMALLOC_SYMBOLIZE_H_
-
-#include "config.h"
-#ifdef HAVE_STDINT_H
-#include <stdint.h>  // for uintptr_t
-#endif
-#include <stddef.h>  // for NULL
-#include <map>
-
-using std::map;
-
-// SymbolTable encapsulates the address operations necessary for stack trace
-// symbolization. A common use-case is to Add() the addresses from one or
-// several stack traces to a table, call Symbolize() once and use GetSymbol()
-// to get the symbol names for pretty-printing the stack traces.
-class SymbolTable {
- public:
-  SymbolTable()
-    : symbol_buffer_(NULL) {}
-  ~SymbolTable() {
-    delete[] symbol_buffer_;
-  }
-
-  // Adds an address to the table. This may overwrite a currently known symbol
-  // name, so Add() should not generally be called after Symbolize().
-  void Add(const void* addr);
-
-  // Returns the symbol name for addr, if the given address was added before
-  // the last successful call to Symbolize(). Otherwise may return an empty
-  // c-string.
-  const char* GetSymbol(const void* addr);
-
-  // Obtains the symbol names for the addresses stored in the table and returns
-  // the number of addresses actually symbolized.
-  int Symbolize();
-
- private:
-  typedef map<const void*, const char*> SymbolMap;
-
-  // An average size of memory allocated for a stack trace symbol.
-  static const int kSymbolSize = 1024;
-
-  // Map from addresses to symbol names.
-  SymbolMap symbolization_table_;
-
-  // Pointer to the buffer that stores the symbol names.
-  char *symbol_buffer_;
-};
-
-#endif  // TCMALLOC_SYMBOLIZE_H_
diff --git a/third_party/tcmalloc/vendor/src/system-alloc.cc b/third_party/tcmalloc/vendor/src/system-alloc.cc
deleted file mode 100755
index 292e482a..0000000
--- a/third_party/tcmalloc/vendor/src/system-alloc.cc
+++ /dev/null
@@ -1,555 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-
-#include <config.h>
-#include <errno.h>                      // for EAGAIN, errno
-#include <fcntl.h>                      // for open, O_RDWR
-#include <stddef.h>                     // for size_t, NULL, ptrdiff_t
-#if defined HAVE_STDINT_H
-#include <stdint.h>                     // for uintptr_t, intptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>                   // for munmap, mmap, MADV_DONTNEED, etc
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                     // for sbrk, getpagesize, off_t
-#endif
-#include <new>                          // for operator new
-#include <gperftools/malloc_extension.h>
-#include "base/basictypes.h"
-#include "base/commandlineflags.h"
-#include "base/spinlock.h"              // for SpinLockHolder, SpinLock, etc
-#include "common.h"
-#include "internal_logging.h"
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-// Linux added support for MADV_FREE in 4.5 but we aren't ready to use it
-// yet. Among other things, using compile-time detection leads to poor
-// results when compiling on a system with MADV_FREE and running on a
-// system without it. See https://github.com/gperftools/gperftools/issues/780.
-#if defined(__linux__) && defined(MADV_FREE) && !defined(TCMALLOC_USE_MADV_FREE)
-# undef MADV_FREE
-#endif
-
-// MADV_FREE is specifically designed for use by malloc(), but only
-// FreeBSD supports it; in linux we fall back to the somewhat inferior
-// MADV_DONTNEED.
-#if !defined(MADV_FREE) && defined(MADV_DONTNEED)
-# define MADV_FREE  MADV_DONTNEED
-#endif
-
-// Solaris has a bug where it doesn't declare madvise() for C++.
-//    http://www.opensolaris.org/jive/thread.jspa?threadID=21035&tstart=0
-#if defined(__sun) && defined(__SVR4)
-# include <sys/types.h>    // for caddr_t
-  extern "C" { extern int madvise(caddr_t, size_t, int); }
-#endif
-
-// Set kDebugMode mode so that we can have use C++ conditionals
-// instead of preprocessor conditionals.
-#ifdef NDEBUG
-static const bool kDebugMode = false;
-#else
-static const bool kDebugMode = true;
-#endif
-
-// TODO(sanjay): Move the code below into the tcmalloc namespace
-using tcmalloc::kLog;
-using tcmalloc::Log;
-
-// Check that no bit is set at position ADDRESS_BITS or higher.
-static bool CheckAddressBits(uintptr_t ptr) {
-  bool always_ok = (kAddressBits == 8 * sizeof(void*));
-  // this is a bit insane but otherwise we get compiler warning about
-  // shifting right by word size even if this code is dead :(
-  int shift_bits = always_ok ? 0 : kAddressBits;
-  return always_ok || ((ptr >> shift_bits) == 0);
-}
-
-COMPILE_ASSERT(kAddressBits <= 8 * sizeof(void*),
-               address_bits_larger_than_pointer_size);
-
-static SpinLock spinlock(SpinLock::LINKER_INITIALIZED);
-
-#if defined(HAVE_MMAP) || defined(MADV_FREE)
-// Page size is initialized on demand (only needed for mmap-based allocators)
-static size_t pagesize = 0;
-#endif
-
-// The current system allocator
-SysAllocator* tcmalloc_sys_alloc = NULL;
-
-// Number of bytes taken from system.
-size_t TCMalloc_SystemTaken = 0;
-
-// Configuration parameters.
-DEFINE_int32(malloc_devmem_start,
-             EnvToInt("TCMALLOC_DEVMEM_START", 0),
-             "Physical memory starting location in MB for /dev/mem allocation."
-             "  Setting this to 0 disables /dev/mem allocation");
-DEFINE_int32(malloc_devmem_limit,
-             EnvToInt("TCMALLOC_DEVMEM_LIMIT", 0),
-             "Physical memory limit location in MB for /dev/mem allocation."
-             "  Setting this to 0 means no limit.");
-DEFINE_bool(malloc_skip_sbrk,
-            EnvToBool("TCMALLOC_SKIP_SBRK", false),
-            "Whether sbrk can be used to obtain memory.");
-DEFINE_bool(malloc_skip_mmap,
-            EnvToBool("TCMALLOC_SKIP_MMAP", false),
-            "Whether mmap can be used to obtain memory.");
-DEFINE_bool(malloc_disable_memory_release,
-            EnvToBool("TCMALLOC_DISABLE_MEMORY_RELEASE", false),
-            "Whether MADV_FREE/MADV_DONTNEED should be used"
-            " to return unused memory to the system.");
-
-// static allocators
-class SbrkSysAllocator : public SysAllocator {
-public:
-  SbrkSysAllocator() : SysAllocator() {
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-};
-static union {
-  char buf[sizeof(SbrkSysAllocator)];
-  void *ptr;
-} sbrk_space;
-
-class MmapSysAllocator : public SysAllocator {
-public:
-  MmapSysAllocator() : SysAllocator() {
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-};
-static union {
-  char buf[sizeof(MmapSysAllocator)];
-  void *ptr;
-} mmap_space;
-
-class DevMemSysAllocator : public SysAllocator {
-public:
-  DevMemSysAllocator() : SysAllocator() {
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-};
-
-class DefaultSysAllocator : public SysAllocator {
- public:
-  DefaultSysAllocator() : SysAllocator() {
-    for (int i = 0; i < kMaxAllocators; i++) {
-      failed_[i] = true;
-      allocs_[i] = NULL;
-      names_[i] = NULL;
-    }
-  }
-  void SetChildAllocator(SysAllocator* alloc, unsigned int index,
-                         const char* name) {
-    if (index < kMaxAllocators && alloc != NULL) {
-      allocs_[index] = alloc;
-      failed_[index] = false;
-      names_[index] = name;
-    }
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-
- private:
-  static const int kMaxAllocators = 2;
-  bool failed_[kMaxAllocators];
-  SysAllocator* allocs_[kMaxAllocators];
-  const char* names_[kMaxAllocators];
-};
-static union {
-  char buf[sizeof(DefaultSysAllocator)];
-  void *ptr;
-} default_space;
-static const char sbrk_name[] = "SbrkSysAllocator";
-static const char mmap_name[] = "MmapSysAllocator";
-
-
-void* SbrkSysAllocator::Alloc(size_t size, size_t *actual_size,
-                              size_t alignment) {
-#if !defined(HAVE_SBRK) || defined(__UCLIBC__)
-  return NULL;
-#else
-  // Check if we should use sbrk allocation.
-  // FLAGS_malloc_skip_sbrk starts out as false (its uninitialized
-  // state) and eventually gets initialized to the specified value.  Note
-  // that this code runs for a while before the flags are initialized.
-  // That means that even if this flag is set to true, some (initial)
-  // memory will be allocated with sbrk before the flag takes effect.
-  if (FLAGS_malloc_skip_sbrk) {
-    return NULL;
-  }
-
-  // sbrk will release memory if passed a negative number, so we do
-  // a strict check here
-  if (static_cast<ptrdiff_t>(size + alignment) < 0) return NULL;
-
-  // This doesn't overflow because TCMalloc_SystemAlloc has already
-  // tested for overflow at the alignment boundary.
-  size = ((size + alignment - 1) / alignment) * alignment;
-
-  // "actual_size" indicates that the bytes from the returned pointer
-  // p up to and including (p + actual_size - 1) have been allocated.
-  if (actual_size) {
-    *actual_size = size;
-  }
-
-  // Check that we we're not asking for so much more memory that we'd
-  // wrap around the end of the virtual address space.  (This seems
-  // like something sbrk() should check for us, and indeed opensolaris
-  // does, but glibc does not:
-  //    http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/sys/sbrk.c?a=true
-  //    http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/libc/misc/sbrk.c?rev=1.1.2.1&content-type=text/plain&cvsroot=glibc
-  // Without this check, sbrk may succeed when it ought to fail.)
-  if (reinterpret_cast<intptr_t>(sbrk(0)) + size < size) {
-    return NULL;
-  }
-
-  void* result = sbrk(size);
-  if (result == reinterpret_cast<void*>(-1)) {
-    return NULL;
-  }
-
-  // Is it aligned?
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-  if ((ptr & (alignment-1)) == 0)  return result;
-
-  // Try to get more memory for alignment
-  size_t extra = alignment - (ptr & (alignment-1));
-  void* r2 = sbrk(extra);
-  if (reinterpret_cast<uintptr_t>(r2) == (ptr + size)) {
-    // Contiguous with previous result
-    return reinterpret_cast<void*>(ptr + extra);
-  }
-
-  // Give up and ask for "size + alignment - 1" bytes so
-  // that we can find an aligned region within it.
-  result = sbrk(size + alignment - 1);
-  if (result == reinterpret_cast<void*>(-1)) {
-    return NULL;
-  }
-  ptr = reinterpret_cast<uintptr_t>(result);
-  if ((ptr & (alignment-1)) != 0) {
-    ptr += alignment - (ptr & (alignment-1));
-  }
-  return reinterpret_cast<void*>(ptr);
-#endif  // HAVE_SBRK
-}
-
-void* MmapSysAllocator::Alloc(size_t size, size_t *actual_size,
-                              size_t alignment) {
-#ifndef HAVE_MMAP
-  return NULL;
-#else
-  // Check if we should use mmap allocation.
-  // FLAGS_malloc_skip_mmap starts out as false (its uninitialized
-  // state) and eventually gets initialized to the specified value.  Note
-  // that this code runs for a while before the flags are initialized.
-  // Chances are we never get here before the flags are initialized since
-  // sbrk is used until the heap is exhausted (before mmap is used).
-  if (FLAGS_malloc_skip_mmap) {
-    return NULL;
-  }
-
-  // Enforce page alignment
-  if (pagesize == 0) pagesize = getpagesize();
-  if (alignment < pagesize) alignment = pagesize;
-  size_t aligned_size = ((size + alignment - 1) / alignment) * alignment;
-  if (aligned_size < size) {
-    return NULL;
-  }
-  size = aligned_size;
-
-  // "actual_size" indicates that the bytes from the returned pointer
-  // p up to and including (p + actual_size - 1) have been allocated.
-  if (actual_size) {
-    *actual_size = size;
-  }
-
-  // Ask for extra memory if alignment > pagesize
-  size_t extra = 0;
-  if (alignment > pagesize) {
-    extra = alignment - pagesize;
-  }
-
-  // Note: size + extra does not overflow since:
-  //            size + alignment < (1<<NBITS).
-  // and        extra <= alignment
-  // therefore  size + extra < (1<<NBITS)
-  void* result = mmap(NULL, size + extra,
-                      PROT_READ|PROT_WRITE,
-                      MAP_PRIVATE|MAP_ANONYMOUS,
-                      -1, 0);
-  if (result == reinterpret_cast<void*>(MAP_FAILED)) {
-    return NULL;
-  }
-
-  // Adjust the return memory so it is aligned
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-  size_t adjust = 0;
-  if ((ptr & (alignment - 1)) != 0) {
-    adjust = alignment - (ptr & (alignment - 1));
-  }
-
-  // Return the unused memory to the system
-  if (adjust > 0) {
-    munmap(reinterpret_cast<void*>(ptr), adjust);
-  }
-  if (adjust < extra) {
-    munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust);
-  }
-
-  ptr += adjust;
-  return reinterpret_cast<void*>(ptr);
-#endif  // HAVE_MMAP
-}
-
-void* DevMemSysAllocator::Alloc(size_t size, size_t *actual_size,
-                                size_t alignment) {
-#ifndef HAVE_MMAP
-  return NULL;
-#else
-  static bool initialized = false;
-  static off_t physmem_base;  // next physical memory address to allocate
-  static off_t physmem_limit; // maximum physical address allowed
-  static int physmem_fd;      // file descriptor for /dev/mem
-
-  // Check if we should use /dev/mem allocation.  Note that it may take
-  // a while to get this flag initialized, so meanwhile we fall back to
-  // the next allocator.  (It looks like 7MB gets allocated before
-  // this flag gets initialized -khr.)
-  if (FLAGS_malloc_devmem_start == 0) {
-    // NOTE: not a devmem_failure - we'd like TCMalloc_SystemAlloc to
-    // try us again next time.
-    return NULL;
-  }
-
-  if (!initialized) {
-    physmem_fd = open("/dev/mem", O_RDWR);
-    if (physmem_fd < 0) {
-      return NULL;
-    }
-    physmem_base = FLAGS_malloc_devmem_start*1024LL*1024LL;
-    physmem_limit = FLAGS_malloc_devmem_limit*1024LL*1024LL;
-    initialized = true;
-  }
-
-  // Enforce page alignment
-  if (pagesize == 0) pagesize = getpagesize();
-  if (alignment < pagesize) alignment = pagesize;
-  size_t aligned_size = ((size + alignment - 1) / alignment) * alignment;
-  if (aligned_size < size) {
-    return NULL;
-  }
-  size = aligned_size;
-
-  // "actual_size" indicates that the bytes from the returned pointer
-  // p up to and including (p + actual_size - 1) have been allocated.
-  if (actual_size) {
-    *actual_size = size;
-  }
-
-  // Ask for extra memory if alignment > pagesize
-  size_t extra = 0;
-  if (alignment > pagesize) {
-    extra = alignment - pagesize;
-  }
-
-  // check to see if we have any memory left
-  if (physmem_limit != 0 &&
-      ((size + extra) > (physmem_limit - physmem_base))) {
-    return NULL;
-  }
-
-  // Note: size + extra does not overflow since:
-  //            size + alignment < (1<<NBITS).
-  // and        extra <= alignment
-  // therefore  size + extra < (1<<NBITS)
-  void *result = mmap(0, size + extra, PROT_WRITE|PROT_READ,
-                      MAP_SHARED, physmem_fd, physmem_base);
-  if (result == reinterpret_cast<void*>(MAP_FAILED)) {
-    return NULL;
-  }
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-
-  // Adjust the return memory so it is aligned
-  size_t adjust = 0;
-  if ((ptr & (alignment - 1)) != 0) {
-    adjust = alignment - (ptr & (alignment - 1));
-  }
-
-  // Return the unused virtual memory to the system
-  if (adjust > 0) {
-    munmap(reinterpret_cast<void*>(ptr), adjust);
-  }
-  if (adjust < extra) {
-    munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust);
-  }
-
-  ptr += adjust;
-  physmem_base += adjust + size;
-
-  return reinterpret_cast<void*>(ptr);
-#endif  // HAVE_MMAP
-}
-
-void* DefaultSysAllocator::Alloc(size_t size, size_t *actual_size,
-                                 size_t alignment) {
-  for (int i = 0; i < kMaxAllocators; i++) {
-    if (!failed_[i] && allocs_[i] != NULL) {
-      void* result = allocs_[i]->Alloc(size, actual_size, alignment);
-      if (result != NULL) {
-        return result;
-      }
-      failed_[i] = true;
-    }
-  }
-  // After both failed, reset "failed_" to false so that a single failed
-  // allocation won't make the allocator never work again.
-  for (int i = 0; i < kMaxAllocators; i++) {
-    failed_[i] = false;
-  }
-  return NULL;
-}
-
-ATTRIBUTE_WEAK ATTRIBUTE_NOINLINE
-SysAllocator *tc_get_sysalloc_override(SysAllocator *def)
-{
-  return def;
-}
-
-static bool system_alloc_inited = false;
-void InitSystemAllocators(void) {
-  MmapSysAllocator *mmap = new (mmap_space.buf) MmapSysAllocator();
-  SbrkSysAllocator *sbrk = new (sbrk_space.buf) SbrkSysAllocator();
-
-  // In 64-bit debug mode, place the mmap allocator first since it
-  // allocates pointers that do not fit in 32 bits and therefore gives
-  // us better testing of code's 64-bit correctness.  It also leads to
-  // less false negatives in heap-checking code.  (Numbers are less
-  // likely to look like pointers and therefore the conservative gc in
-  // the heap-checker is less likely to misinterpret a number as a
-  // pointer).
-  DefaultSysAllocator *sdef = new (default_space.buf) DefaultSysAllocator();
-  if (kDebugMode && sizeof(void*) > 4) {
-    sdef->SetChildAllocator(mmap, 0, mmap_name);
-    sdef->SetChildAllocator(sbrk, 1, sbrk_name);
-  } else {
-    sdef->SetChildAllocator(sbrk, 0, sbrk_name);
-    sdef->SetChildAllocator(mmap, 1, mmap_name);
-  }
-
-  tcmalloc_sys_alloc = tc_get_sysalloc_override(sdef);
-}
-
-void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
-                           size_t alignment) {
-  // Discard requests that overflow
-  if (size + alignment < size) return NULL;
-
-  SpinLockHolder lock_holder(&spinlock);
-
-  if (!system_alloc_inited) {
-    InitSystemAllocators();
-    system_alloc_inited = true;
-  }
-
-  // Enforce minimum alignment
-  if (alignment < sizeof(MemoryAligner)) alignment = sizeof(MemoryAligner);
-
-  size_t actual_size_storage;
-  if (actual_size == NULL) {
-    actual_size = &actual_size_storage;
-  }
-
-  void* result = tcmalloc_sys_alloc->Alloc(size, actual_size, alignment);
-  if (result != NULL) {
-    CHECK_CONDITION(
-      CheckAddressBits(reinterpret_cast<uintptr_t>(result) + *actual_size - 1));
-    TCMalloc_SystemTaken += *actual_size;
-  }
-  return result;
-}
-
-bool TCMalloc_SystemRelease(void* start, size_t length) {
-#ifdef MADV_FREE
-  if (FLAGS_malloc_devmem_start) {
-    // It's not safe to use MADV_FREE/MADV_DONTNEED if we've been
-    // mapping /dev/mem for heap memory.
-    return false;
-  }
-  if (FLAGS_malloc_disable_memory_release) return false;
-  if (pagesize == 0) pagesize = getpagesize();
-  const size_t pagemask = pagesize - 1;
-
-  size_t new_start = reinterpret_cast<size_t>(start);
-  size_t end = new_start + length;
-  size_t new_end = end;
-
-  // Round up the starting address and round down the ending address
-  // to be page aligned:
-  new_start = (new_start + pagesize - 1) & ~pagemask;
-  new_end = new_end & ~pagemask;
-
-  ASSERT((new_start & pagemask) == 0);
-  ASSERT((new_end & pagemask) == 0);
-  ASSERT(new_start >= reinterpret_cast<size_t>(start));
-  ASSERT(new_end <= end);
-
-  if (new_end > new_start) {
-    int result;
-    do {
-      result = madvise(reinterpret_cast<char*>(new_start),
-          new_end - new_start, MADV_FREE);
-    } while (result == -1 && errno == EAGAIN);
-
-    return result != -1;
-  }
-#endif
-  return false;
-}
-
-void TCMalloc_SystemCommit(void* start, size_t length) {
-  // Nothing to do here.  TCMalloc_SystemRelease does not alter pages
-  // such that they need to be re-committed before they can be used by the
-  // application.
-}
diff --git a/third_party/tcmalloc/vendor/src/system-alloc.h b/third_party/tcmalloc/vendor/src/system-alloc.h
deleted file mode 100644
index 655d470..0000000
--- a/third_party/tcmalloc/vendor/src/system-alloc.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Routine that uses sbrk/mmap to allocate memory from the system.
-// Useful for implementing malloc.
-
-#ifndef TCMALLOC_SYSTEM_ALLOC_H_
-#define TCMALLOC_SYSTEM_ALLOC_H_
-
-#include <config.h>
-#include <stddef.h>                     // for size_t
-
-class SysAllocator;
-
-// REQUIRES: "alignment" is a power of two or "0" to indicate default alignment
-//
-// Allocate and return "N" bytes of zeroed memory.
-//
-// If actual_bytes is NULL then the returned memory is exactly the
-// requested size.  If actual bytes is non-NULL then the allocator
-// may optionally return more bytes than asked for (i.e. return an
-// entire "huge" page if a huge page allocator is in use).
-//
-// The returned pointer is a multiple of "alignment" if non-zero. The
-// returned pointer will always be aligned suitably for holding a
-// void*, double, or size_t. In addition, if this platform defines
-// CACHELINE_ALIGNED, the return pointer will always be cacheline
-// aligned.
-//
-// Returns NULL when out of memory.
-extern PERFTOOLS_DLL_DECL
-void* TCMalloc_SystemAlloc(size_t bytes, size_t *actual_bytes,
-			   size_t alignment = 0);
-
-// This call is a hint to the operating system that the pages
-// contained in the specified range of memory will not be used for a
-// while, and can be released for use by other processes or the OS.
-// Pages which are released in this way may be destroyed (zeroed) by
-// the OS.  The benefit of this function is that it frees memory for
-// use by the system, the cost is that the pages are faulted back into
-// the address space next time they are touched, which can impact
-// performance.  (Only pages fully covered by the memory region will
-// be released, partial pages will not.)
-//
-// Returns false if release failed or not supported.
-extern PERFTOOLS_DLL_DECL
-bool TCMalloc_SystemRelease(void* start, size_t length);
-
-// Called to ressurect memory which has been previously released
-// to the system via TCMalloc_SystemRelease.  An attempt to
-// commit a page that is already committed does not cause this
-// function to fail.
-extern PERFTOOLS_DLL_DECL
-void TCMalloc_SystemCommit(void* start, size_t length);
-
-// The current system allocator.
-extern PERFTOOLS_DLL_DECL SysAllocator* tcmalloc_sys_alloc;
-
-// Number of bytes taken from system.
-extern PERFTOOLS_DLL_DECL size_t TCMalloc_SystemTaken;
-
-#endif /* TCMALLOC_SYSTEM_ALLOC_H_ */
diff --git a/third_party/tcmalloc/vendor/src/tcmalloc.cc b/third_party/tcmalloc/vendor/src/tcmalloc.cc
deleted file mode 100644
index 7b18ddbc..0000000
--- a/third_party/tcmalloc/vendor/src/tcmalloc.cc
+++ /dev/null
@@ -1,2198 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-//
-// A malloc that uses a per-thread cache to satisfy small malloc requests.
-// (The time for malloc/free of a small object drops from 300 ns to 50 ns.)
-//
-// See docs/tcmalloc.html for a high-level
-// description of how this malloc works.
-//
-// SYNCHRONIZATION
-//  1. The thread-specific lists are accessed without acquiring any locks.
-//     This is safe because each such list is only accessed by one thread.
-//  2. We have a lock per central free-list, and hold it while manipulating
-//     the central free list for a particular size.
-//  3. The central page allocator is protected by "pageheap_lock".
-//  4. The pagemap (which maps from page-number to descriptor),
-//     can be read without holding any locks, and written while holding
-//     the "pageheap_lock".
-//  5. To improve performance, a subset of the information one can get
-//     from the pagemap is cached in a data structure, pagemap_cache_,
-//     that atomically reads and writes its entries.  This cache can be
-//     read and written without locking.
-//
-//     This multi-threaded access to the pagemap is safe for fairly
-//     subtle reasons.  We basically assume that when an object X is
-//     allocated by thread A and deallocated by thread B, there must
-//     have been appropriate synchronization in the handoff of object
-//     X from thread A to thread B.  The same logic applies to pagemap_cache_.
-//
-// THE PAGEID-TO-SIZECLASS CACHE
-// Hot PageID-to-sizeclass mappings are held by pagemap_cache_.  If this cache
-// returns 0 for a particular PageID then that means "no information," not that
-// the sizeclass is 0.  The cache may have stale information for pages that do
-// not hold the beginning of any free()'able object.  Staleness is eliminated
-// in Populate() for pages with sizeclass > 0 objects, and in do_malloc() and
-// do_memalign() for all other relevant pages.
-//
-// PAGEMAP
-// -------
-// Page map contains a mapping from page id to Span.
-//
-// If Span s occupies pages [p..q],
-//      pagemap[p] == s
-//      pagemap[q] == s
-//      pagemap[p+1..q-1] are undefined
-//      pagemap[p-1] and pagemap[q+1] are defined:
-//         NULL if the corresponding page is not yet in the address space.
-//         Otherwise it points to a Span.  This span may be free
-//         or allocated.  If free, it is in one of pageheap's freelist.
-//
-// TODO: Bias reclamation to larger addresses
-// TODO: implement mallinfo/mallopt
-// TODO: Better testing
-//
-// 9/28/2003 (new page-level allocator replaces ptmalloc2):
-// * malloc/free of small objects goes from ~300 ns to ~50 ns.
-// * allocation of a reasonably complicated struct
-//   goes from about 1100 ns to about 300 ns.
-
-#include "config.h"
-// At least for gcc on Linux/i386 and Linux/amd64 not adding throw()
-// to tc_xxx functions actually ends up generating better code.
-#define PERFTOOLS_NOTHROW
-#include <gperftools/tcmalloc.h>
-
-#include <errno.h>                      // for ENOMEM, EINVAL, errno
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-#include <stddef.h>                     // for size_t, NULL
-#include <stdlib.h>                     // for getenv
-#include <string.h>                     // for strcmp, memset, strlen, etc
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                     // for getpagesize, write, etc
-#endif
-#include <algorithm>                    // for max, min
-#include <limits>                       // for numeric_limits
-#include <new>                          // for nothrow_t (ptr only), etc
-#include <vector>                       // for vector
-
-#include <gperftools/malloc_extension.h>
-#include <gperftools/malloc_hook.h>         // for MallocHook
-#include <gperftools/nallocx.h>
-#include "base/basictypes.h"            // for int64
-#include "base/commandlineflags.h"      // for RegisterFlagValidator, etc
-#include "base/dynamic_annotations.h"   // for RunningOnValgrind
-#include "base/spinlock.h"              // for SpinLockHolder
-#include "central_freelist.h"  // for CentralFreeListPadded
-#include "common.h"            // for StackTrace, kPageShift, etc
-#include "internal_logging.h"  // for ASSERT, TCMalloc_Printer, etc
-#include "linked_list.h"       // for SLL_SetNext
-#include "malloc_hook-inl.h"       // for MallocHook::InvokeNewHook, etc
-#include "page_heap.h"         // for PageHeap, PageHeap::Stats
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "span.h"              // for Span, DLL_Prepend, etc
-#include "stack_trace_table.h"  // for StackTraceTable
-#include "static_vars.h"       // for Static
-#include "system-alloc.h"      // for DumpSystemAllocatorStats, etc
-#include "tcmalloc_guard.h"    // for TCMallocGuard
-#include "thread_cache.h"      // for ThreadCache
-
-#include "maybe_emergency_malloc.h"
-
-#if (defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)) && !defined(WIN32_OVERRIDE_ALLOCATORS)
-# define WIN32_DO_PATCHING 1
-#endif
-
-// Some windows file somewhere (at least on cygwin) #define's small (!)
-#undef small
-
-using STL_NAMESPACE::max;
-using STL_NAMESPACE::min;
-using STL_NAMESPACE::numeric_limits;
-using STL_NAMESPACE::vector;
-
-#include "libc_override.h"
-
-using tcmalloc::AlignmentForSize;
-using tcmalloc::kLog;
-using tcmalloc::kCrash;
-using tcmalloc::kCrashWithStats;
-using tcmalloc::Log;
-using tcmalloc::PageHeap;
-using tcmalloc::PageHeapAllocator;
-using tcmalloc::SizeMap;
-using tcmalloc::Span;
-using tcmalloc::StackTrace;
-using tcmalloc::Static;
-using tcmalloc::ThreadCache;
-
-DECLARE_double(tcmalloc_release_rate);
-
-// Those common architectures are known to be safe w.r.t. aliasing function
-// with "extra" unused args to function with fewer arguments (e.g.
-// tc_delete_nothrow being aliased to tc_delete).
-//
-// Benefit of aliasing is relatively moderate. It reduces instruction
-// cache pressure a bit (not relevant for largely unused
-// tc_delete_nothrow, but is potentially relevant for
-// tc_delete_aligned (or sized)). It also used to be the case that gcc
-// 5+ optimization for merging identical functions kicked in and
-// "screwed" one of the otherwise identical functions with extra
-// jump. I am not able to reproduce that anymore.
-#if !defined(__i386__) && !defined(__x86_64__) && \
-    !defined(__ppc__) && !defined(__PPC__) && \
-    !defined(__aarch64__) && !defined(__mips__) && !defined(__arm__)
-#undef TCMALLOC_NO_ALIASES
-#define TCMALLOC_NO_ALIASES
-#endif
-
-#if defined(__GNUC__) && defined(__ELF__) && !defined(TCMALLOC_NO_ALIASES)
-#define TC_ALIAS(name) __attribute__((alias(#name)))
-#endif
-
-// For windows, the printf we use to report large allocs is
-// potentially dangerous: it could cause a malloc that would cause an
-// infinite loop.  So by default we set the threshold to a huge number
-// on windows, so this bad situation will never trigger.  You can
-// always set TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD manually if you
-// want this functionality.
-#ifdef _WIN32
-const int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 62;
-#else
-const int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 30;
-#endif
-DEFINE_int64(tcmalloc_large_alloc_report_threshold,
-             EnvToInt64("TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD",
-                        kDefaultLargeAllocReportThreshold),
-             "Allocations larger than this value cause a stack "
-             "trace to be dumped to stderr.  The threshold for "
-             "dumping stack traces is increased by a factor of 1.125 "
-             "every time we print a message so that the threshold "
-             "automatically goes up by a factor of ~1000 every 60 "
-             "messages.  This bounds the amount of extra logging "
-             "generated by this flag.  Default value of this flag "
-             "is very large and therefore you should see no extra "
-             "logging unless the flag is overridden.  Set to 0 to "
-             "disable reporting entirely.");
-
-
-// We already declared these functions in tcmalloc.h, but we have to
-// declare them again to give them an ATTRIBUTE_SECTION: we want to
-// put all callers of MallocHook::Invoke* in this module into
-// ATTRIBUTE_SECTION(google_malloc) section, so that
-// MallocHook::GetCallerStackTrace can function accurately.
-#ifndef _WIN32   // windows doesn't have attribute_section, so don't bother
-extern "C" {
-  void* tc_malloc(size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_free(void* ptr) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_free_sized(void* ptr, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_cfree(void* ptr) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-  void* tc_memalign(size_t __alignment, size_t __size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  int tc_posix_memalign(void** ptr, size_t align, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-  void tc_malloc_stats(void) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-#ifdef HAVE_STRUCT_MALLINFO
-  struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-#endif
-
-  void* tc_new(size_t size)
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete(void* p) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_newarray(size_t size)
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray(void* p) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-  // And the nothrow variants of these:
-  void* tc_new_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_newarray_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  // Surprisingly, standard C++ library implementations use a
-  // nothrow-delete internally.  See, eg:
-  // http://www.dinkumware.com/manuals/?manual=compleat&page=new.html
-  void tc_delete_nothrow(void* ptr, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_nothrow(void* ptr, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-  void* tc_new_aligned(size_t size, std::align_val_t al)
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_newarray_aligned(size_t size, std::align_val_t al)
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-  // And the nothrow variants of these:
-  void* tc_new_aligned_nothrow(size_t size, std::align_val_t al, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_delete_aligned_nothrow(void* ptr, std::align_val_t al, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-  void tc_deletearray_aligned_nothrow(void* ptr, std::align_val_t al, const std::nothrow_t&) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-  // Some non-standard extensions that we support.
-
-  // This is equivalent to
-  //    OS X: malloc_size()
-  //    glibc: malloc_usable_size()
-  //    Windows: _msize()
-  size_t tc_malloc_size(void* p) PERFTOOLS_NOTHROW
-      ATTRIBUTE_SECTION(google_malloc);
-}  // extern "C"
-#endif  // #ifndef _WIN32
-
-// ----------------------- IMPLEMENTATION -------------------------------
-
-static int tc_new_mode = 0;  // See tc_set_new_mode().
-
-// Routines such as free() and realloc() catch some erroneous pointers
-// passed to them, and invoke the below when they do.  (An erroneous pointer
-// won't be caught if it's within a valid span or a stale span for which
-// the pagemap cache has a non-zero sizeclass.) This is a cheap (source-editing
-// required) kind of exception handling for these routines.
-namespace {
-ATTRIBUTE_NOINLINE void InvalidFree(void* ptr) {
-  if (tcmalloc::IsEmergencyPtr(ptr)) {
-    tcmalloc::EmergencyFree(ptr);
-    return;
-  }
-  Log(kCrash, __FILE__, __LINE__, "Attempt to free invalid pointer", ptr);
-}
-
-size_t InvalidGetSizeForRealloc(const void* old_ptr) {
-  Log(kCrash, __FILE__, __LINE__,
-      "Attempt to realloc invalid pointer", old_ptr);
-  return 0;
-}
-
-size_t InvalidGetAllocatedSize(const void* ptr) {
-  Log(kCrash, __FILE__, __LINE__,
-      "Attempt to get the size of an invalid pointer", ptr);
-  return 0;
-}
-}  // unnamed namespace
-
-// Extract interesting stats
-struct TCMallocStats {
-  uint64_t thread_bytes;      // Bytes in thread caches
-  uint64_t central_bytes;     // Bytes in central cache
-  uint64_t transfer_bytes;    // Bytes in central transfer cache
-  uint64_t metadata_bytes;    // Bytes alloced for metadata
-  PageHeap::Stats pageheap;   // Stats from page heap
-};
-
-// Get stats into "r".  Also, if class_count != NULL, class_count[k]
-// will be set to the total number of objects of size class k in the
-// central cache, transfer cache, and per-thread caches. If small_spans
-// is non-NULL, it is filled.  Same for large_spans.
-static void ExtractStats(TCMallocStats* r, uint64_t* class_count,
-                         PageHeap::SmallSpanStats* small_spans,
-                         PageHeap::LargeSpanStats* large_spans) {
-  r->central_bytes = 0;
-  r->transfer_bytes = 0;
-  for (int cl = 0; cl < Static::num_size_classes(); ++cl) {
-    const int length = Static::central_cache()[cl].length();
-    const int tc_length = Static::central_cache()[cl].tc_length();
-    const size_t cache_overhead = Static::central_cache()[cl].OverheadBytes();
-    const size_t size = static_cast<uint64_t>(
-        Static::sizemap()->ByteSizeForClass(cl));
-    r->central_bytes += (size * length) + cache_overhead;
-    r->transfer_bytes += (size * tc_length);
-    if (class_count) {
-      // Sum the lengths of all per-class freelists, except the per-thread
-      // freelists, which get counted when we call GetThreadStats(), below.
-      class_count[cl] = length + tc_length;
-    }
-
-  }
-
-  // Add stats from per-thread heaps
-  r->thread_bytes = 0;
-  { // scope
-    SpinLockHolder h(Static::pageheap_lock());
-    ThreadCache::GetThreadStats(&r->thread_bytes, class_count);
-    r->metadata_bytes = tcmalloc::metadata_system_bytes();
-    r->pageheap = Static::pageheap()->stats();
-    if (small_spans != NULL) {
-      Static::pageheap()->GetSmallSpanStats(small_spans);
-    }
-    if (large_spans != NULL) {
-      Static::pageheap()->GetLargeSpanStats(large_spans);
-    }
-  }
-}
-
-static double PagesToMiB(uint64_t pages) {
-  return (pages << kPageShift) / 1048576.0;
-}
-
-// WRITE stats to "out"
-static void DumpStats(TCMalloc_Printer* out, int level) {
-  TCMallocStats stats;
-  uint64_t class_count[kClassSizesMax];
-  PageHeap::SmallSpanStats small;
-  PageHeap::LargeSpanStats large;
-  if (level >= 2) {
-    ExtractStats(&stats, class_count, &small, &large);
-  } else {
-    ExtractStats(&stats, NULL, NULL, NULL);
-  }
-
-  static const double MiB = 1048576.0;
-
-  const uint64_t virtual_memory_used = (stats.pageheap.system_bytes
-                                        + stats.metadata_bytes);
-  const uint64_t physical_memory_used = (virtual_memory_used
-                                         - stats.pageheap.unmapped_bytes);
-  const uint64_t bytes_in_use_by_app = (physical_memory_used
-                                        - stats.metadata_bytes
-                                        - stats.pageheap.free_bytes
-                                        - stats.central_bytes
-                                        - stats.transfer_bytes
-                                        - stats.thread_bytes);
-
-#ifdef TCMALLOC_SMALL_BUT_SLOW
-  out->printf(
-      "NOTE:  SMALL MEMORY MODEL IS IN USE, PERFORMANCE MAY SUFFER.\n");
-#endif
-  out->printf(
-      "------------------------------------------------\n"
-      "MALLOC:   %12" PRIu64 " (%7.1f MiB) Bytes in use by application\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in page heap freelist\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in central cache freelist\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in transfer cache freelist\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in thread cache freelists\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in malloc metadata\n"
-      "MALLOC:   ------------\n"
-      "MALLOC: = %12" PRIu64 " (%7.1f MiB) Actual memory used (physical + swap)\n"
-      "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes released to OS (aka unmapped)\n"
-      "MALLOC:   ------------\n"
-      "MALLOC: = %12" PRIu64 " (%7.1f MiB) Virtual address space used\n"
-      "MALLOC:\n"
-      "MALLOC:   %12" PRIu64 "              Spans in use\n"
-      "MALLOC:   %12" PRIu64 "              Thread heaps in use\n"
-      "MALLOC:   %12" PRIu64 "              Tcmalloc page size\n"
-      "------------------------------------------------\n"
-      "Call ReleaseFreeMemory() to release freelist memory to the OS"
-      " (via madvise()).\n"
-      "Bytes released to the OS take up virtual address space"
-      " but no physical memory.\n",
-      bytes_in_use_by_app, bytes_in_use_by_app / MiB,
-      stats.pageheap.free_bytes, stats.pageheap.free_bytes / MiB,
-      stats.central_bytes, stats.central_bytes / MiB,
-      stats.transfer_bytes, stats.transfer_bytes / MiB,
-      stats.thread_bytes, stats.thread_bytes / MiB,
-      stats.metadata_bytes, stats.metadata_bytes / MiB,
-      physical_memory_used, physical_memory_used / MiB,
-      stats.pageheap.unmapped_bytes, stats.pageheap.unmapped_bytes / MiB,
-      virtual_memory_used, virtual_memory_used / MiB,
-      uint64_t(Static::span_allocator()->inuse()),
-      uint64_t(ThreadCache::HeapsInUse()),
-      uint64_t(kPageSize));
-
-  if (level >= 2) {
-    out->printf("------------------------------------------------\n");
-    out->printf("Total size of freelists for per-thread caches,\n");
-    out->printf("transfer cache, and central cache, by size class\n");
-    out->printf("------------------------------------------------\n");
-    uint64_t cumulative = 0;
-    for (uint32 cl = 0; cl < Static::num_size_classes(); ++cl) {
-      if (class_count[cl] > 0) {
-        size_t cl_size = Static::sizemap()->ByteSizeForClass(cl);
-        uint64_t class_bytes = class_count[cl] * cl_size;
-        cumulative += class_bytes;
-        out->printf("class %3d [ %8" PRIuS " bytes ] : "
-                "%8" PRIu64 " objs; %5.1f MiB; %5.1f cum MiB\n",
-                cl, cl_size,
-                class_count[cl],
-                class_bytes / MiB,
-                cumulative / MiB);
-      }
-    }
-
-    // append page heap info
-    int nonempty_sizes = 0;
-    for (int s = 0; s < kMaxPages; s++) {
-      if (small.normal_length[s] + small.returned_length[s] > 0) {
-        nonempty_sizes++;
-      }
-    }
-    out->printf("------------------------------------------------\n");
-    out->printf("PageHeap: %d sizes; %6.1f MiB free; %6.1f MiB unmapped\n",
-                nonempty_sizes, stats.pageheap.free_bytes / MiB,
-                stats.pageheap.unmapped_bytes / MiB);
-    out->printf("------------------------------------------------\n");
-    uint64_t total_normal = 0;
-    uint64_t total_returned = 0;
-    for (int s = 1; s <= kMaxPages; s++) {
-      const int n_length = small.normal_length[s - 1];
-      const int r_length = small.returned_length[s - 1];
-      if (n_length + r_length > 0) {
-        uint64_t n_pages = s * n_length;
-        uint64_t r_pages = s * r_length;
-        total_normal += n_pages;
-        total_returned += r_pages;
-        out->printf("%6u pages * %6u spans ~ %6.1f MiB; %6.1f MiB cum"
-                    "; unmapped: %6.1f MiB; %6.1f MiB cum\n",
-                    s,
-                    (n_length + r_length),
-                    PagesToMiB(n_pages + r_pages),
-                    PagesToMiB(total_normal + total_returned),
-                    PagesToMiB(r_pages),
-                    PagesToMiB(total_returned));
-      }
-    }
-
-    total_normal += large.normal_pages;
-    total_returned += large.returned_pages;
-    out->printf(">%-5u large * %6u spans ~ %6.1f MiB; %6.1f MiB cum"
-                "; unmapped: %6.1f MiB; %6.1f MiB cum\n",
-                static_cast<unsigned int>(kMaxPages),
-                static_cast<unsigned int>(large.spans),
-                PagesToMiB(large.normal_pages + large.returned_pages),
-                PagesToMiB(total_normal + total_returned),
-                PagesToMiB(large.returned_pages),
-                PagesToMiB(total_returned));
-  }
-}
-
-static void PrintStats(int level) {
-  const int kBufferSize = 16 << 10;
-  char* buffer = new char[kBufferSize];
-  TCMalloc_Printer printer(buffer, kBufferSize);
-  DumpStats(&printer, level);
-  write(STDERR_FILENO, buffer, strlen(buffer));
-  delete[] buffer;
-}
-
-static void** DumpHeapGrowthStackTraces() {
-  // Count how much space we need
-  int needed_slots = 0;
-  {
-    SpinLockHolder h(Static::pageheap_lock());
-    for (StackTrace* t = Static::growth_stacks();
-         t != NULL;
-         t = reinterpret_cast<StackTrace*>(
-             t->stack[tcmalloc::kMaxStackDepth-1])) {
-      needed_slots += 3 + t->depth;
-    }
-    needed_slots += 100;            // Slop in case list grows
-    needed_slots += needed_slots/8; // An extra 12.5% slop
-  }
-
-  void** result = new void*[needed_slots];
-  if (result == NULL) {
-    Log(kLog, __FILE__, __LINE__,
-        "tcmalloc: allocation failed for stack trace slots",
-        needed_slots * sizeof(*result));
-    return NULL;
-  }
-
-  SpinLockHolder h(Static::pageheap_lock());
-  int used_slots = 0;
-  for (StackTrace* t = Static::growth_stacks();
-       t != NULL;
-       t = reinterpret_cast<StackTrace*>(
-           t->stack[tcmalloc::kMaxStackDepth-1])) {
-    ASSERT(used_slots < needed_slots);  // Need to leave room for terminator
-    if (used_slots + 3 + t->depth >= needed_slots) {
-      // No more room
-      break;
-    }
-
-    result[used_slots+0] = reinterpret_cast<void*>(static_cast<uintptr_t>(1));
-    result[used_slots+1] = reinterpret_cast<void*>(t->size);
-    result[used_slots+2] = reinterpret_cast<void*>(t->depth);
-    for (int d = 0; d < t->depth; d++) {
-      result[used_slots+3+d] = t->stack[d];
-    }
-    used_slots += 3 + t->depth;
-  }
-  result[used_slots] = reinterpret_cast<void*>(static_cast<uintptr_t>(0));
-  return result;
-}
-
-static void IterateOverRanges(void* arg, MallocExtension::RangeFunction func) {
-  PageID page = 1;  // Some code may assume that page==0 is never used
-  bool done = false;
-  while (!done) {
-    // Accumulate a small number of ranges in a local buffer
-    static const int kNumRanges = 16;
-    static base::MallocRange ranges[kNumRanges];
-    int n = 0;
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      while (n < kNumRanges) {
-        if (!Static::pageheap()->GetNextRange(page, &ranges[n])) {
-          done = true;
-          break;
-        } else {
-          uintptr_t limit = ranges[n].address + ranges[n].length;
-          page = (limit + kPageSize - 1) >> kPageShift;
-          n++;
-        }
-      }
-    }
-
-    for (int i = 0; i < n; i++) {
-      (*func)(arg, &ranges[i]);
-    }
-  }
-}
-
-// TCMalloc's support for extra malloc interfaces
-class TCMallocImplementation : public MallocExtension {
- private:
-  // ReleaseToSystem() might release more than the requested bytes because
-  // the page heap releases at the span granularity, and spans are of wildly
-  // different sizes.  This member keeps track of the extra bytes bytes
-  // released so that the app can periodically call ReleaseToSystem() to
-  // release memory at a constant rate.
-  // NOTE: Protected by Static::pageheap_lock().
-  size_t extra_bytes_released_;
-
- public:
-  TCMallocImplementation()
-      : extra_bytes_released_(0) {
-  }
-
-  virtual void GetStats(char* buffer, int buffer_length) {
-    ASSERT(buffer_length > 0);
-    TCMalloc_Printer printer(buffer, buffer_length);
-
-    // Print level one stats unless lots of space is available
-    if (buffer_length < 10000) {
-      DumpStats(&printer, 1);
-    } else {
-      DumpStats(&printer, 2);
-    }
-  }
-
-  // We may print an extra, tcmalloc-specific warning message here.
-  virtual void GetHeapSample(MallocExtensionWriter* writer) {
-    if (FLAGS_tcmalloc_sample_parameter == 0) {
-      const char* const kWarningMsg =
-          "%warn\n"
-          "%warn This heap profile does not have any data in it, because\n"
-          "%warn the application was run with heap sampling turned off.\n"
-          "%warn To get useful data from GetHeapSample(), you must\n"
-          "%warn set the environment variable TCMALLOC_SAMPLE_PARAMETER to\n"
-          "%warn a positive sampling period, such as 524288.\n"
-          "%warn\n";
-      writer->append(kWarningMsg, strlen(kWarningMsg));
-    }
-    MallocExtension::GetHeapSample(writer);
-  }
-
-  virtual void** ReadStackTraces(int* sample_period) {
-    tcmalloc::StackTraceTable table;
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      Span* sampled = Static::sampled_objects();
-      for (Span* s = sampled->next; s != sampled; s = s->next) {
-        table.AddTrace(*reinterpret_cast<StackTrace*>(s->objects));
-      }
-    }
-    *sample_period = ThreadCache::GetCache()->GetSamplePeriod();
-    return table.ReadStackTracesAndClear(); // grabs and releases pageheap_lock
-  }
-
-  virtual void** ReadHeapGrowthStackTraces() {
-    return DumpHeapGrowthStackTraces();
-  }
-
-  virtual size_t GetThreadCacheSize() {
-    ThreadCache* tc = ThreadCache::GetCacheIfPresent();
-    if (!tc)
-      return 0;
-    return tc->Size();
-  }
-
-  virtual void MarkThreadTemporarilyIdle() {
-    ThreadCache::BecomeTemporarilyIdle();
-  }
-
-  virtual void Ranges(void* arg, RangeFunction func) {
-    IterateOverRanges(arg, func);
-  }
-
-  virtual bool GetNumericProperty(const char* name, size_t* value) {
-    ASSERT(name != NULL);
-
-    if (strcmp(name, "generic.current_allocated_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.pageheap.system_bytes
-               - stats.thread_bytes
-               - stats.central_bytes
-               - stats.transfer_bytes
-               - stats.pageheap.free_bytes
-               - stats.pageheap.unmapped_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "generic.heap_size") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.pageheap.system_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.slack_bytes") == 0) {
-      // Kept for backwards compatibility.  Now defined externally as:
-      //    pageheap_free_bytes + pageheap_unmapped_bytes.
-      SpinLockHolder l(Static::pageheap_lock());
-      PageHeap::Stats stats = Static::pageheap()->stats();
-      *value = stats.free_bytes + stats.unmapped_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.central_cache_free_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.central_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.transfer_cache_free_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.transfer_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.thread_cache_free_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.thread_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_free_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().free_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_unmapped_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().unmapped_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_committed_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().committed_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_scavenge_count") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().scavenge_count;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_commit_count") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().commit_count;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_total_commit_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().total_commit_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_decommit_count") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().decommit_count;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_total_decommit_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().total_decommit_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_reserve_count") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = Static::pageheap()->stats().reserve_count;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.pageheap_total_reserve_bytes") == 0) {
-        SpinLockHolder l(Static::pageheap_lock());
-        *value = Static::pageheap()->stats().total_reserve_bytes;
-        return true;
-    }
-
-    if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = ThreadCache::overall_thread_cache_size();
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.current_total_thread_cache_bytes") == 0) {
-      TCMallocStats stats;
-      ExtractStats(&stats, NULL, NULL, NULL);
-      *value = stats.thread_bytes;
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.aggressive_memory_decommit") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = size_t(Static::pageheap()->GetAggressiveDecommit());
-      return true;
-    }
-
-    return false;
-  }
-
-  virtual bool SetNumericProperty(const char* name, size_t value) {
-    ASSERT(name != NULL);
-
-    if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      ThreadCache::set_overall_thread_cache_size(value);
-      return true;
-    }
-
-    if (strcmp(name, "tcmalloc.aggressive_memory_decommit") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      Static::pageheap()->SetAggressiveDecommit(value != 0);
-      return true;
-    }
-
-    return false;
-  }
-
-  virtual void MarkThreadIdle() {
-    ThreadCache::BecomeIdle();
-  }
-
-  virtual void MarkThreadBusy();  // Implemented below
-
-  virtual SysAllocator* GetSystemAllocator() {
-    SpinLockHolder h(Static::pageheap_lock());
-    return tcmalloc_sys_alloc;
-  }
-
-  virtual void SetSystemAllocator(SysAllocator* alloc) {
-    SpinLockHolder h(Static::pageheap_lock());
-    tcmalloc_sys_alloc = alloc;
-  }
-
-  virtual void ReleaseToSystem(size_t num_bytes) {
-    SpinLockHolder h(Static::pageheap_lock());
-    if (num_bytes <= extra_bytes_released_) {
-      // We released too much on a prior call, so don't release any
-      // more this time.
-      extra_bytes_released_ = extra_bytes_released_ - num_bytes;
-      return;
-    }
-    num_bytes = num_bytes - extra_bytes_released_;
-    // num_bytes might be less than one page.  If we pass zero to
-    // ReleaseAtLeastNPages, it won't do anything, so we release a whole
-    // page now and let extra_bytes_released_ smooth it out over time.
-    Length num_pages = max<Length>(num_bytes >> kPageShift, 1);
-    size_t bytes_released = Static::pageheap()->ReleaseAtLeastNPages(
-        num_pages) << kPageShift;
-    if (bytes_released > num_bytes) {
-      extra_bytes_released_ = bytes_released - num_bytes;
-    } else {
-      // The PageHeap wasn't able to release num_bytes.  Don't try to
-      // compensate with a big release next time.  Specifically,
-      // ReleaseFreeMemory() calls ReleaseToSystem(LONG_MAX).
-      extra_bytes_released_ = 0;
-    }
-  }
-
-  virtual void SetMemoryReleaseRate(double rate) {
-    FLAGS_tcmalloc_release_rate = rate;
-  }
-
-  virtual double GetMemoryReleaseRate() {
-    return FLAGS_tcmalloc_release_rate;
-  }
-  virtual size_t GetEstimatedAllocatedSize(size_t size);
-
-  // This just calls GetSizeWithCallback, but because that's in an
-  // unnamed namespace, we need to move the definition below it in the
-  // file.
-  virtual size_t GetAllocatedSize(const void* ptr);
-
-  // This duplicates some of the logic in GetSizeWithCallback, but is
-  // faster.  This is important on OS X, where this function is called
-  // on every allocation operation.
-  virtual Ownership GetOwnership(const void* ptr) {
-    const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-    // The rest of tcmalloc assumes that all allocated pointers use at
-    // most kAddressBits bits.  If ptr doesn't, then it definitely
-    // wasn't alloacted by tcmalloc.
-    if ((p >> (kAddressBits - kPageShift)) > 0) {
-      return kNotOwned;
-    }
-    uint32 cl;
-    if (Static::pageheap()->TryGetSizeClass(p, &cl)) {
-      return kOwned;
-    }
-    const Span *span = Static::pageheap()->GetDescriptor(p);
-    return span ? kOwned : kNotOwned;
-  }
-
-  virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {
-    static const char* kCentralCacheType = "tcmalloc.central";
-    static const char* kTransferCacheType = "tcmalloc.transfer";
-    static const char* kThreadCacheType = "tcmalloc.thread";
-    static const char* kPageHeapType = "tcmalloc.page";
-    static const char* kPageHeapUnmappedType = "tcmalloc.page_unmapped";
-    static const char* kLargeSpanType = "tcmalloc.large";
-    static const char* kLargeUnmappedSpanType = "tcmalloc.large_unmapped";
-
-    v->clear();
-
-    // central class information
-    int64 prev_class_size = 0;
-    for (int cl = 1; cl < Static::num_size_classes(); ++cl) {
-      size_t class_size = Static::sizemap()->ByteSizeForClass(cl);
-      MallocExtension::FreeListInfo i;
-      i.min_object_size = prev_class_size + 1;
-      i.max_object_size = class_size;
-      i.total_bytes_free =
-          Static::central_cache()[cl].length() * class_size;
-      i.type = kCentralCacheType;
-      v->push_back(i);
-
-      // transfer cache
-      i.total_bytes_free =
-          Static::central_cache()[cl].tc_length() * class_size;
-      i.type = kTransferCacheType;
-      v->push_back(i);
-
-      prev_class_size = Static::sizemap()->ByteSizeForClass(cl);
-    }
-
-    // Add stats from per-thread heaps
-    uint64_t class_count[kClassSizesMax];
-    memset(class_count, 0, sizeof(class_count));
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      uint64_t thread_bytes = 0;
-      ThreadCache::GetThreadStats(&thread_bytes, class_count);
-    }
-
-    prev_class_size = 0;
-    for (int cl = 1; cl < Static::num_size_classes(); ++cl) {
-      MallocExtension::FreeListInfo i;
-      i.min_object_size = prev_class_size + 1;
-      i.max_object_size = Static::sizemap()->ByteSizeForClass(cl);
-      i.total_bytes_free =
-          class_count[cl] * Static::sizemap()->ByteSizeForClass(cl);
-      i.type = kThreadCacheType;
-      v->push_back(i);
-
-      prev_class_size = Static::sizemap()->ByteSizeForClass(cl);
-    }
-
-    // append page heap info
-    PageHeap::SmallSpanStats small;
-    PageHeap::LargeSpanStats large;
-    {
-      SpinLockHolder h(Static::pageheap_lock());
-      Static::pageheap()->GetSmallSpanStats(&small);
-      Static::pageheap()->GetLargeSpanStats(&large);
-    }
-
-    // large spans: mapped
-    MallocExtension::FreeListInfo span_info;
-    span_info.type = kLargeSpanType;
-    span_info.max_object_size = (numeric_limits<size_t>::max)();
-    span_info.min_object_size = kMaxPages << kPageShift;
-    span_info.total_bytes_free = large.normal_pages << kPageShift;
-    v->push_back(span_info);
-
-    // large spans: unmapped
-    span_info.type = kLargeUnmappedSpanType;
-    span_info.total_bytes_free = large.returned_pages << kPageShift;
-    v->push_back(span_info);
-
-    // small spans
-    for (int s = 1; s <= kMaxPages; s++) {
-      MallocExtension::FreeListInfo i;
-      i.max_object_size = (s << kPageShift);
-      i.min_object_size = ((s - 1) << kPageShift);
-
-      i.type = kPageHeapType;
-      i.total_bytes_free = (s << kPageShift) * small.normal_length[s - 1];
-      v->push_back(i);
-
-      i.type = kPageHeapUnmappedType;
-      i.total_bytes_free = (s << kPageShift) * small.returned_length[s - 1];
-      v->push_back(i);
-    }
-  }
-};
-
-static inline ATTRIBUTE_ALWAYS_INLINE
-size_t align_size_up(size_t size, size_t align) {
-  ASSERT(align <= kPageSize);
-  size_t new_size = (size + align - 1) & ~(align - 1);
-  if (PREDICT_FALSE(new_size == 0)) {
-    // Note, new_size == 0 catches both integer overflow and size
-    // being 0.
-    if (size == 0) {
-      new_size = align;
-    } else {
-      new_size = size;
-    }
-  }
-  return new_size;
-}
-
-// Puts in *cl size class that is suitable for allocation of size bytes with
-// align alignment. Returns true if such size class exists and false otherwise.
-static bool size_class_with_alignment(size_t size, size_t align, uint32_t* cl) {
-  if (PREDICT_FALSE(align > kPageSize)) {
-    return false;
-  }
-  size = align_size_up(size, align);
-  if (PREDICT_FALSE(!Static::sizemap()->GetSizeClass(size, cl))) {
-    return false;
-  }
-  ASSERT((Static::sizemap()->class_to_size(*cl) & (align - 1)) == 0);
-  return true;
-}
-
-// nallocx slow path. Moved to a separate function because
-// ThreadCache::InitModule is not inlined which would cause nallocx to
-// become non-leaf function with stack frame and stack spills.
-static ATTRIBUTE_NOINLINE size_t nallocx_slow(size_t size, int flags) {
-  if (PREDICT_FALSE(!Static::IsInited())) ThreadCache::InitModule();
-
-  size_t align = static_cast<size_t>(1ull << (flags & 0x3f));
-  uint32 cl;
-  bool ok = size_class_with_alignment(size, align, &cl);
-  if (ok) {
-    return Static::sizemap()->ByteSizeForClass(cl);
-  } else {
-    return tcmalloc::pages(size) << kPageShift;
-  }
-}
-
-// The nallocx function allocates no memory, but it performs the same size
-// computation as the malloc function, and returns the real size of the
-// allocation that would result from the equivalent malloc function call.
-// nallocx is a malloc extension originally implemented by jemalloc:
-// http://www.unix.com/man-page/freebsd/3/nallocx/
-extern "C" PERFTOOLS_DLL_DECL
-size_t tc_nallocx(size_t size, int flags) {
-  if (PREDICT_FALSE(flags != 0)) {
-    return nallocx_slow(size, flags);
-  }
-  uint32 cl;
-  // size class 0 is only possible if malloc is not yet initialized
-  if (Static::sizemap()->GetSizeClass(size, &cl) && cl != 0) {
-    return Static::sizemap()->ByteSizeForClass(cl);
-  } else {
-    return nallocx_slow(size, 0);
-  }
-}
-
-extern "C" PERFTOOLS_DLL_DECL
-size_t nallocx(size_t size, int flags)
-#ifdef TC_ALIAS
-  TC_ALIAS(tc_nallocx);
-#else
-{
-  return nallocx_slow(size, flags);
-}
-#endif
-
-
-size_t TCMallocImplementation::GetEstimatedAllocatedSize(size_t size) {
-  return tc_nallocx(size, 0);
-}
-
-// The constructor allocates an object to ensure that initialization
-// runs before main(), and therefore we do not have a chance to become
-// multi-threaded before initialization.  We also create the TSD key
-// here.  Presumably by the time this constructor runs, glibc is in
-// good enough shape to handle pthread_key_create().
-//
-// The constructor also takes the opportunity to tell STL to use
-// tcmalloc.  We want to do this early, before construct time, so
-// all user STL allocations go through tcmalloc (which works really
-// well for STL).
-//
-// The destructor prints stats when the program exits.
-static int tcmallocguard_refcount = 0;  // no lock needed: runs before main()
-TCMallocGuard::TCMallocGuard() {
-  if (tcmallocguard_refcount++ == 0) {
-    ReplaceSystemAlloc();    // defined in libc_override_*.h
-    tc_free(tc_malloc(1));
-    ThreadCache::InitTSD();
-    tc_free(tc_malloc(1));
-    // Either we, or debugallocation.cc, or valgrind will control memory
-    // management.  We register our extension if we're the winner.
-#ifdef TCMALLOC_USING_DEBUGALLOCATION
-    // Let debugallocation register its extension.
-#else
-    if (RunningOnValgrind()) {
-      // Let Valgrind uses its own malloc (so don't register our extension).
-    } else {
-      MallocExtension::Register(new TCMallocImplementation);
-    }
-#endif
-  }
-}
-
-TCMallocGuard::~TCMallocGuard() {
-  if (--tcmallocguard_refcount == 0) {
-    const char* env = NULL;
-    if (!RunningOnValgrind()) {
-      // Valgrind uses it's own malloc so we cannot do MALLOCSTATS
-      env = getenv("MALLOCSTATS");
-    }
-    if (env != NULL) {
-      int level = atoi(env);
-      if (level < 1) level = 1;
-      PrintStats(level);
-    }
-  }
-}
-#ifndef WIN32_OVERRIDE_ALLOCATORS
-static TCMallocGuard module_enter_exit_hook;
-#endif
-
-//-------------------------------------------------------------------
-// Helpers for the exported routines below
-//-------------------------------------------------------------------
-
-static inline bool CheckCachedSizeClass(void *ptr) {
-  PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-  uint32 cached_value;
-  if (!Static::pageheap()->TryGetSizeClass(p, &cached_value)) {
-    return true;
-  }
-  return cached_value == Static::pageheap()->GetDescriptor(p)->sizeclass;
-}
-
-static inline ATTRIBUTE_ALWAYS_INLINE void* CheckedMallocResult(void *result) {
-  ASSERT(result == NULL || CheckCachedSizeClass(result));
-  return result;
-}
-
-static inline ATTRIBUTE_ALWAYS_INLINE void* SpanToMallocResult(Span *span) {
-  Static::pageheap()->InvalidateCachedSizeClass(span->start);
-  return
-      CheckedMallocResult(reinterpret_cast<void*>(span->start << kPageShift));
-}
-
-static void* DoSampledAllocation(size_t size) {
-#ifndef NO_TCMALLOC_SAMPLES
-  // Grab the stack trace outside the heap lock
-  StackTrace tmp;
-  tmp.depth = GetStackTrace(tmp.stack, tcmalloc::kMaxStackDepth, 1);
-  tmp.size = size;
-
-  SpinLockHolder h(Static::pageheap_lock());
-  // Allocate span
-  Span *span = Static::pageheap()->New(tcmalloc::pages(size == 0 ? 1 : size));
-  if (PREDICT_FALSE(span == NULL)) {
-    return NULL;
-  }
-
-  // Allocate stack trace
-  StackTrace *stack = Static::stacktrace_allocator()->New();
-  if (PREDICT_FALSE(stack == NULL)) {
-    // Sampling failed because of lack of memory
-    return span;
-  }
-  *stack = tmp;
-  span->sample = 1;
-  span->objects = stack;
-  tcmalloc::DLL_Prepend(Static::sampled_objects(), span);
-
-  return SpanToMallocResult(span);
-#else
-  abort();
-#endif
-}
-
-namespace {
-
-typedef void* (*malloc_fn)(void *arg);
-
-SpinLock set_new_handler_lock(SpinLock::LINKER_INITIALIZED);
-
-void* handle_oom(malloc_fn retry_fn,
-                 void* retry_arg,
-                 bool from_operator,
-                 bool nothrow) {
-  // we hit out of memory condition, usually if it happens we've
-  // called sbrk or mmap and failed, and thus errno is set. But there
-  // is support for setting up custom system allocator or setting up
-  // page heap size limit, in which cases errno may remain
-  // untouched.
-  //
-  // So we set errno here. C++ operator new doesn't require ENOMEM to
-  // be set, but doesn't forbid it too (and often C++ oom does happen
-  // with ENOMEM set).
-  errno = ENOMEM;
-  if (!from_operator && !tc_new_mode) {
-    // we're out of memory in C library function (malloc etc) and no
-    // "new mode" forced on us. Just return NULL
-    return NULL;
-  }
-  // we're OOM in operator new or "new mode" is set. We might have to
-  // call new_handle and maybe retry allocation.
-
-  for (;;) {
-    // Get the current new handler.  NB: this function is not
-    // thread-safe.  We make a feeble stab at making it so here, but
-    // this lock only protects against tcmalloc interfering with
-    // itself, not with other libraries calling set_new_handler.
-    std::new_handler nh;
-    {
-      SpinLockHolder h(&set_new_handler_lock);
-      nh = std::set_new_handler(0);
-      (void) std::set_new_handler(nh);
-    }
-#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
-    if (!nh) {
-      return NULL;
-    }
-    // Since exceptions are disabled, we don't really know if new_handler
-    // failed.  Assume it will abort if it fails.
-    (*nh)();
-#else
-    // If no new_handler is established, the allocation failed.
-    if (!nh) {
-      if (nothrow) {
-        return NULL;
-      }
-      throw std::bad_alloc();
-    }
-    // Otherwise, try the new_handler.  If it returns, retry the
-    // allocation.  If it throws std::bad_alloc, fail the allocation.
-    // if it throws something else, don't interfere.
-    try {
-      (*nh)();
-    } catch (const std::bad_alloc&) {
-      if (!nothrow) throw;
-      return NULL;
-    }
-#endif  // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
-
-    // we get here if new_handler returns successfully. So we retry
-    // allocation.
-    void* rv = retry_fn(retry_arg);
-    if (rv != NULL) {
-      return rv;
-    }
-
-    // if allocation failed again we go to next loop iteration
-  }
-}
-
-// Copy of FLAGS_tcmalloc_large_alloc_report_threshold with
-// automatic increases factored in.
-static int64_t large_alloc_threshold =
-  (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold
-   ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold);
-
-static void ReportLargeAlloc(Length num_pages, void* result) {
-  StackTrace stack;
-  stack.depth = GetStackTrace(stack.stack, tcmalloc::kMaxStackDepth, 1);
-
-  static const int N = 1000;
-  char buffer[N];
-  TCMalloc_Printer printer(buffer, N);
-  printer.printf("tcmalloc: large alloc %" PRIu64 " bytes == %p @ ",
-                 static_cast<uint64>(num_pages) << kPageShift,
-                 result);
-  for (int i = 0; i < stack.depth; i++) {
-    printer.printf(" %p", stack.stack[i]);
-  }
-  printer.printf("\n");
-  write(STDERR_FILENO, buffer, strlen(buffer));
-}
-
-// Must be called with the page lock held.
-inline bool should_report_large(Length num_pages) {
-  const int64 threshold = large_alloc_threshold;
-  if (threshold > 0 && num_pages >= (threshold >> kPageShift)) {
-    // Increase the threshold by 1/8 every time we generate a report.
-    // We cap the threshold at 8GiB to avoid overflow problems.
-    large_alloc_threshold = (threshold + threshold/8 < 8ll<<30
-                             ? threshold + threshold/8 : 8ll<<30);
-    return true;
-  }
-  return false;
-}
-
-// Helper for do_malloc().
-static void* do_malloc_pages(ThreadCache* heap, size_t size) {
-  void* result;
-  bool report_large;
-
-  Length num_pages = tcmalloc::pages(size);
-
-  // NOTE: we're passing original size here as opposed to rounded-up
-  // size as we do in do_malloc_small. The difference is small here
-  // (at most 4k out of at least 256k). And not rounding up saves us
-  // from possibility of overflow, which rounding up could produce.
-  //
-  // See https://github.com/gperftools/gperftools/issues/723
-  if (heap->SampleAllocation(size)) {
-    result = DoSampledAllocation(size);
-
-    SpinLockHolder h(Static::pageheap_lock());
-    report_large = should_report_large(num_pages);
-  } else {
-    SpinLockHolder h(Static::pageheap_lock());
-    Span* span = Static::pageheap()->New(num_pages);
-    result = (PREDICT_FALSE(span == NULL) ? NULL : SpanToMallocResult(span));
-    report_large = should_report_large(num_pages);
-  }
-
-  if (report_large) {
-    ReportLargeAlloc(num_pages, result);
-  }
-  return result;
-}
-
-static void *nop_oom_handler(size_t size) {
-  return NULL;
-}
-
-ATTRIBUTE_ALWAYS_INLINE inline void* do_malloc(size_t size) {
-  if (PREDICT_FALSE(ThreadCache::IsUseEmergencyMalloc())) {
-    return tcmalloc::EmergencyMalloc(size);
-  }
-
-  // note: it will force initialization of malloc if necessary
-  ThreadCache* cache = ThreadCache::GetCache();
-  uint32 cl;
-
-  ASSERT(Static::IsInited());
-  ASSERT(cache != NULL);
-
-  if (PREDICT_FALSE(!Static::sizemap()->GetSizeClass(size, &cl))) {
-    return do_malloc_pages(cache, size);
-  }
-
-  size_t allocated_size = Static::sizemap()->class_to_size(cl);
-  if (PREDICT_FALSE(cache->SampleAllocation(allocated_size))) {
-    return DoSampledAllocation(size);
-  }
-
-  // The common case, and also the simplest.  This just pops the
-  // size-appropriate freelist, after replenishing it if it's empty.
-  return CheckedMallocResult(cache->Allocate(allocated_size, cl, nop_oom_handler));
-}
-
-static void *retry_malloc(void* size) {
-  return do_malloc(reinterpret_cast<size_t>(size));
-}
-
-ATTRIBUTE_ALWAYS_INLINE inline void* do_malloc_or_cpp_alloc(size_t size) {
-  void *rv = do_malloc(size);
-  if (PREDICT_TRUE(rv != NULL)) {
-    return rv;
-  }
-  return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
-                    false, true);
-}
-
-ATTRIBUTE_ALWAYS_INLINE inline void* do_calloc(size_t n, size_t elem_size) {
-  // Overflow check
-  const size_t size = n * elem_size;
-  if (elem_size != 0 && size / elem_size != n) return NULL;
-
-  void* result = do_malloc_or_cpp_alloc(size);
-  if (result != NULL) {
-    memset(result, 0, size);
-  }
-  return result;
-}
-
-// If ptr is NULL, do nothing.  Otherwise invoke the given function.
-inline void free_null_or_invalid(void* ptr, void (*invalid_free_fn)(void*)) {
-  if (ptr != NULL) {
-    (*invalid_free_fn)(ptr);
-  }
-}
-
-static ATTRIBUTE_NOINLINE void do_free_pages(Span* span, void* ptr) {
-  SpinLockHolder h(Static::pageheap_lock());
-  if (span->sample) {
-    StackTrace* st = reinterpret_cast<StackTrace*>(span->objects);
-    tcmalloc::DLL_Remove(span);
-    Static::stacktrace_allocator()->Delete(st);
-    span->objects = NULL;
-  }
-  Static::pageheap()->Delete(span);
-}
-
-// Helper for the object deletion (free, delete, etc.).  Inputs:
-//   ptr is object to be freed
-//   invalid_free_fn is a function that gets invoked on certain "bad frees"
-//
-// We can usually detect the case where ptr is not pointing to a page that
-// tcmalloc is using, and in those cases we invoke invalid_free_fn.
-ATTRIBUTE_ALWAYS_INLINE inline
-void do_free_with_callback(void* ptr,
-                           void (*invalid_free_fn)(void*),
-                           bool use_hint, size_t size_hint) {
-  ThreadCache* heap = ThreadCache::GetCacheIfPresent();
-
-  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-  uint32 cl;
-
-#ifndef NO_TCMALLOC_SAMPLES
-  // we only pass size hint when ptr is not page aligned. Which
-  // implies that it must be very small object.
-  ASSERT(!use_hint || size_hint < kPageSize);
-#endif
-
-  if (!use_hint || PREDICT_FALSE(!Static::sizemap()->GetSizeClass(size_hint, &cl))) {
-    // if we're in sized delete, but size is too large, no need to
-    // probe size cache
-    bool cache_hit = !use_hint && Static::pageheap()->TryGetSizeClass(p, &cl);
-    if (PREDICT_FALSE(!cache_hit)) {
-      Span* span  = Static::pageheap()->GetDescriptor(p);
-      if (PREDICT_FALSE(!span)) {
-        // span can be NULL because the pointer passed in is NULL or invalid
-        // (not something returned by malloc or friends), or because the
-        // pointer was allocated with some other allocator besides
-        // tcmalloc.  The latter can happen if tcmalloc is linked in via
-        // a dynamic library, but is not listed last on the link line.
-        // In that case, libraries after it on the link line will
-        // allocate with libc malloc, but free with tcmalloc's free.
-        free_null_or_invalid(ptr, invalid_free_fn);
-        return;
-      }
-      cl = span->sizeclass;
-      if (PREDICT_FALSE(cl == 0)) {
-        ASSERT(reinterpret_cast<uintptr_t>(ptr) % kPageSize == 0);
-        ASSERT(span != NULL && span->start == p);
-        do_free_pages(span, ptr);
-        return;
-      }
-      if (!use_hint) {
-        Static::pageheap()->SetCachedSizeClass(p, cl);
-      }
-    }
-  }
-
-  if (PREDICT_TRUE(heap != NULL)) {
-    ASSERT(Static::IsInited());
-    // If we've hit initialized thread cache, so we're done.
-    heap->Deallocate(ptr, cl);
-    return;
-  }
-
-  if (PREDICT_FALSE(!Static::IsInited())) {
-    // if free was called very early we've could have missed the case
-    // of invalid or nullptr free. I.e. because probing size classes
-    // cache could return bogus result (cl = 0 as of this
-    // writing). But since there is no way we could be dealing with
-    // ptr we've allocated, since successfull malloc implies IsInited,
-    // we can just call "invalid free" handling code.
-    free_null_or_invalid(ptr, invalid_free_fn);
-    return;
-  }
-
-  // Otherwise, delete directly into central cache
-  tcmalloc::SLL_SetNext(ptr, NULL);
-  Static::central_cache()[cl].InsertRange(ptr, ptr, 1);
-}
-
-// The default "do_free" that uses the default callback.
-ATTRIBUTE_ALWAYS_INLINE inline void do_free(void* ptr) {
-  return do_free_with_callback(ptr, &InvalidFree, false, 0);
-}
-
-// NOTE: some logic here is duplicated in GetOwnership (above), for
-// speed.  If you change this function, look at that one too.
-inline size_t GetSizeWithCallback(const void* ptr,
-                                  size_t (*invalid_getsize_fn)(const void*)) {
-  if (ptr == NULL)
-    return 0;
-  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-  uint32 cl;
-  if (Static::pageheap()->TryGetSizeClass(p, &cl)) {
-    return Static::sizemap()->ByteSizeForClass(cl);
-  }
-
-  const Span *span = Static::pageheap()->GetDescriptor(p);
-  if (PREDICT_FALSE(span == NULL)) {  // means we do not own this memory
-    return (*invalid_getsize_fn)(ptr);
-  }
-
-  if (span->sizeclass != 0) {
-    return Static::sizemap()->ByteSizeForClass(span->sizeclass);
-  }
-
-  if (span->sample) {
-    size_t orig_size = reinterpret_cast<StackTrace*>(span->objects)->size;
-    return tc_nallocx(orig_size, 0);
-  }
-
-  return span->length << kPageShift;
-}
-
-// This lets you call back to a given function pointer if ptr is invalid.
-// It is used primarily by windows code which wants a specialized callback.
-ATTRIBUTE_ALWAYS_INLINE inline void* do_realloc_with_callback(
-    void* old_ptr, size_t new_size,
-    void (*invalid_free_fn)(void*),
-    size_t (*invalid_get_size_fn)(const void*)) {
-  // Get the size of the old entry
-  const size_t old_size = GetSizeWithCallback(old_ptr, invalid_get_size_fn);
-
-  // Reallocate if the new size is larger than the old size,
-  // or if the new size is significantly smaller than the old size.
-  // We do hysteresis to avoid resizing ping-pongs:
-  //    . If we need to grow, grow to max(new_size, old_size * 1.X)
-  //    . Don't shrink unless new_size < old_size * 0.Y
-  // X and Y trade-off time for wasted space.  For now we do 1.25 and 0.5.
-  const size_t min_growth = min(old_size / 4,
-      (std::numeric_limits<size_t>::max)() - old_size);  // Avoid overflow.
-  const size_t lower_bound_to_grow = old_size + min_growth;
-  const size_t upper_bound_to_shrink = old_size / 2ul;
-  if ((new_size > old_size) || (new_size < upper_bound_to_shrink)) {
-    // Need to reallocate.
-    void* new_ptr = NULL;
-
-    if (new_size > old_size && new_size < lower_bound_to_grow) {
-      new_ptr = do_malloc_or_cpp_alloc(lower_bound_to_grow);
-    }
-    if (new_ptr == NULL) {
-      // Either new_size is not a tiny increment, or last do_malloc failed.
-      new_ptr = do_malloc_or_cpp_alloc(new_size);
-    }
-    if (PREDICT_FALSE(new_ptr == NULL)) {
-      return NULL;
-    }
-    MallocHook::InvokeNewHook(new_ptr, new_size);
-    memcpy(new_ptr, old_ptr, ((old_size < new_size) ? old_size : new_size));
-    MallocHook::InvokeDeleteHook(old_ptr);
-    // We could use a variant of do_free() that leverages the fact
-    // that we already know the sizeclass of old_ptr.  The benefit
-    // would be small, so don't bother.
-    do_free_with_callback(old_ptr, invalid_free_fn, false, 0);
-    return new_ptr;
-  } else {
-    // We still need to call hooks to report the updated size:
-    MallocHook::InvokeDeleteHook(old_ptr);
-    MallocHook::InvokeNewHook(old_ptr, new_size);
-    return old_ptr;
-  }
-}
-
-ATTRIBUTE_ALWAYS_INLINE inline void* do_realloc(void* old_ptr, size_t new_size) {
-  return do_realloc_with_callback(old_ptr, new_size,
-                                  &InvalidFree, &InvalidGetSizeForRealloc);
-}
-
-static ATTRIBUTE_ALWAYS_INLINE inline
-void* do_memalign_pages(size_t align, size_t size) {
-  ASSERT((align & (align - 1)) == 0);
-  ASSERT(align > kPageSize);
-  if (size + align < size) return NULL;         // Overflow
-
-  if (PREDICT_FALSE(Static::pageheap() == NULL)) ThreadCache::InitModule();
-
-  // Allocate at least one byte to avoid boundary conditions below
-  if (size == 0) size = 1;
-
-  // We will allocate directly from the page heap
-  SpinLockHolder h(Static::pageheap_lock());
-
-  // Allocate extra pages and carve off an aligned portion
-  const Length alloc = tcmalloc::pages(size + align);
-  Span* span = Static::pageheap()->New(alloc);
-  if (PREDICT_FALSE(span == NULL)) return NULL;
-
-  // Skip starting portion so that we end up aligned
-  Length skip = 0;
-  while ((((span->start+skip) << kPageShift) & (align - 1)) != 0) {
-    skip++;
-  }
-  ASSERT(skip < alloc);
-  if (skip > 0) {
-    Span* rest = Static::pageheap()->Split(span, skip);
-    Static::pageheap()->Delete(span);
-    span = rest;
-  }
-
-  // Skip trailing portion that we do not need to return
-  const Length needed = tcmalloc::pages(size);
-  ASSERT(span->length >= needed);
-  if (span->length > needed) {
-    Span* trailer = Static::pageheap()->Split(span, needed);
-    Static::pageheap()->Delete(trailer);
-  }
-  return SpanToMallocResult(span);
-}
-
-// Helpers for use by exported routines below:
-
-inline void do_malloc_stats() {
-  PrintStats(1);
-}
-
-inline int do_mallopt(int cmd, int value) {
-  return 1;     // Indicates error
-}
-
-#ifdef HAVE_STRUCT_MALLINFO
-inline struct mallinfo do_mallinfo() {
-  TCMallocStats stats;
-  ExtractStats(&stats, NULL, NULL, NULL);
-
-  // Just some of the fields are filled in.
-  struct mallinfo info;
-  memset(&info, 0, sizeof(info));
-
-  // Unfortunately, the struct contains "int" field, so some of the
-  // size values will be truncated.
-  info.arena     = static_cast<int>(stats.pageheap.system_bytes);
-  info.fsmblks   = static_cast<int>(stats.thread_bytes
-                                    + stats.central_bytes
-                                    + stats.transfer_bytes);
-  info.fordblks  = static_cast<int>(stats.pageheap.free_bytes +
-                                    stats.pageheap.unmapped_bytes);
-  info.uordblks  = static_cast<int>(stats.pageheap.system_bytes
-                                    - stats.thread_bytes
-                                    - stats.central_bytes
-                                    - stats.transfer_bytes
-                                    - stats.pageheap.free_bytes
-                                    - stats.pageheap.unmapped_bytes);
-
-  return info;
-}
-#endif  // HAVE_STRUCT_MALLINFO
-
-}  // end unnamed namespace
-
-// As promised, the definition of this function, declared above.
-size_t TCMallocImplementation::GetAllocatedSize(const void* ptr) {
-  if (ptr == NULL)
-    return 0;
-  ASSERT(TCMallocImplementation::GetOwnership(ptr)
-         != TCMallocImplementation::kNotOwned);
-  return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize);
-}
-
-void TCMallocImplementation::MarkThreadBusy() {
-  // Allocate to force the creation of a thread cache, but avoid
-  // invoking any hooks.
-  do_free(do_malloc(0));
-}
-
-//-------------------------------------------------------------------
-// Exported routines
-//-------------------------------------------------------------------
-
-extern "C" PERFTOOLS_DLL_DECL const char* tc_version(
-    int* major, int* minor, const char** patch) PERFTOOLS_NOTHROW {
-  if (major) *major = TC_VERSION_MAJOR;
-  if (minor) *minor = TC_VERSION_MINOR;
-  if (patch) *patch = TC_VERSION_PATCH;
-  return TC_VERSION_STRING;
-}
-
-// This function behaves similarly to MSVC's _set_new_mode.
-// If flag is 0 (default), calls to malloc will behave normally.
-// If flag is 1, calls to malloc will behave like calls to new,
-// and the std_new_handler will be invoked on failure.
-// Returns the previous mode.
-extern "C" PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW {
-  int old_mode = tc_new_mode;
-  tc_new_mode = flag;
-  return old_mode;
-}
-
-extern "C" PERFTOOLS_DLL_DECL int tc_query_new_mode() PERFTOOLS_NOTHROW {
-  return tc_new_mode;
-}
-
-#ifndef TCMALLOC_USING_DEBUGALLOCATION  // debugallocation.cc defines its own
-
-// CAVEAT: The code structure below ensures that MallocHook methods are always
-//         called from the stack frame of the invoked allocation function.
-//         heap-checker.cc depends on this to start a stack trace from
-//         the call to the (de)allocation function.
-
-namespace tcmalloc {
-
-
-static ATTRIBUTE_SECTION(google_malloc)
-void invoke_hooks_and_free(void *ptr) {
-  MallocHook::InvokeDeleteHook(ptr);
-  do_free(ptr);
-}
-
-ATTRIBUTE_SECTION(google_malloc)
-void* cpp_throw_oom(size_t size) {
-  return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
-                    true, false);
-}
-
-ATTRIBUTE_SECTION(google_malloc)
-void* cpp_nothrow_oom(size_t size) {
-  return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
-                    true, true);
-}
-
-ATTRIBUTE_SECTION(google_malloc)
-void* malloc_oom(size_t size) {
-  return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
-                    false, true);
-}
-
-// tcmalloc::allocate_full_XXX is called by fast-path malloc when some
-// complex handling is needed (such as fetching object from central
-// freelist or malloc sampling). It contains all 'operator new' logic,
-// as opposed to malloc_fast_path which only deals with important
-// subset of cases.
-//
-// Note that this is under tcmalloc namespace so that pprof
-// can automatically filter it out of growthz/heapz profiles.
-//
-// We have slightly fancy setup because we need to call hooks from
-// function in 'google_malloc' section and we cannot place template
-// into this section. Thus 3 separate functions 'built' by macros.
-//
-// Also note that we're carefully orchestrating for
-// MallocHook::GetCallerStackTrace to work even if compiler isn't
-// optimizing tail calls (e.g. -O0 is given). We still require
-// ATTRIBUTE_ALWAYS_INLINE to work for that case, but it was seen to
-// work for -O0 -fno-inline across both GCC and clang. I.e. in this
-// case we'll get stack frame for tc_new, followed by stack frame for
-// allocate_full_cpp_throw_oom, followed by hooks machinery and user
-// code's stack frames. So GetCallerStackTrace will find 2
-// subsequent stack frames in google_malloc section and correctly
-// 'cut' stack trace just before tc_new.
-template <void* OOMHandler(size_t)>
-ATTRIBUTE_ALWAYS_INLINE inline
-static void* do_allocate_full(size_t size) {
-  void* p = do_malloc(size);
-  if (PREDICT_FALSE(p == NULL)) {
-    p = OOMHandler(size);
-  }
-  MallocHook::InvokeNewHook(p, size);
-  return CheckedMallocResult(p);
-}
-
-#define AF(oom) \
-  ATTRIBUTE_SECTION(google_malloc)   \
-  void* allocate_full_##oom(size_t size) {   \
-    return do_allocate_full<oom>(size);     \
-  }
-
-AF(cpp_throw_oom)
-AF(cpp_nothrow_oom)
-AF(malloc_oom)
-
-#undef AF
-
-template <void* OOMHandler(size_t)>
-static ATTRIBUTE_ALWAYS_INLINE inline void* dispatch_allocate_full(size_t size) {
-  if (OOMHandler == cpp_throw_oom) {
-    return allocate_full_cpp_throw_oom(size);
-  }
-  if (OOMHandler == cpp_nothrow_oom) {
-    return allocate_full_cpp_nothrow_oom(size);
-  }
-  ASSERT(OOMHandler == malloc_oom);
-  return allocate_full_malloc_oom(size);
-}
-
-struct retry_memalign_data {
-  size_t align;
-  size_t size;
-};
-
-static void *retry_do_memalign(void *arg) {
-  retry_memalign_data *data = static_cast<retry_memalign_data *>(arg);
-  return do_memalign_pages(data->align, data->size);
-}
-
-static ATTRIBUTE_SECTION(google_malloc)
-void* memalign_pages(size_t align, size_t size,
-                     bool from_operator, bool nothrow) {
-  void *rv = do_memalign_pages(align, size);
-  if (PREDICT_FALSE(rv == NULL)) {
-    retry_memalign_data data;
-    data.align = align;
-    data.size = size;
-    rv = handle_oom(retry_do_memalign, &data,
-                    from_operator, nothrow);
-  }
-  MallocHook::InvokeNewHook(rv, size);
-  return CheckedMallocResult(rv);
-}
-
-} // namespace tcmalloc
-
-// This is quick, fast-path-only implementation of malloc/new. It is
-// designed to only have support for fast-path. It checks if more
-// complex handling is needed (such as a pageheap allocation or
-// sampling) and only performs allocation if none of those uncommon
-// conditions hold. When we have one of those odd cases it simply
-// tail-calls to one of tcmalloc::allocate_full_XXX defined above.
-//
-// Such approach was found to be quite effective. Generated code for
-// tc_{new,malloc} either succeeds quickly or tail-calls to
-// allocate_full. Terseness of the source and lack of
-// non-tail calls enables compiler to produce better code. Also
-// produced code is short enough to enable effort-less human
-// comprehension. Which itself led to elimination of various checks
-// that were not necessary for fast-path.
-template <void* OOMHandler(size_t)>
-ATTRIBUTE_ALWAYS_INLINE inline
-static void * malloc_fast_path(size_t size) {
-  if (PREDICT_FALSE(!base::internal::new_hooks_.empty())) {
-    return tcmalloc::dispatch_allocate_full<OOMHandler>(size);
-  }
-
-  ThreadCache *cache = ThreadCache::GetFastPathCache();
-
-  if (PREDICT_FALSE(cache == NULL)) {
-    return tcmalloc::dispatch_allocate_full<OOMHandler>(size);
-  }
-
-  uint32 cl;
-  if (PREDICT_FALSE(!Static::sizemap()->GetSizeClass(size, &cl))) {
-    return tcmalloc::dispatch_allocate_full<OOMHandler>(size);
-  }
-
-  size_t allocated_size = Static::sizemap()->ByteSizeForClass(cl);
-
-  if (PREDICT_FALSE(!cache->TryRecordAllocationFast(allocated_size))) {
-    return tcmalloc::dispatch_allocate_full<OOMHandler>(size);
-  }
-
-  return CheckedMallocResult(cache->Allocate(allocated_size, cl, OOMHandler));
-}
-
-template <void* OOMHandler(size_t)>
-ATTRIBUTE_ALWAYS_INLINE inline
-static void* memalign_fast_path(size_t align, size_t size) {
-  if (PREDICT_FALSE(align > kPageSize)) {
-    if (OOMHandler == tcmalloc::cpp_throw_oom) {
-      return tcmalloc::memalign_pages(align, size, true, false);
-    } else if (OOMHandler == tcmalloc::cpp_nothrow_oom) {
-      return tcmalloc::memalign_pages(align, size, true, true);
-    } else {
-      ASSERT(OOMHandler == tcmalloc::malloc_oom);
-      return tcmalloc::memalign_pages(align, size, false, true);
-    }
-  }
-
-  // Everything with alignment <= kPageSize we can easily delegate to
-  // regular malloc
-
-  return malloc_fast_path<OOMHandler>(align_size_up(size, align));
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void* tc_malloc(size_t size) PERFTOOLS_NOTHROW {
-  return malloc_fast_path<tcmalloc::malloc_oom>(size);
-}
-
-static ATTRIBUTE_ALWAYS_INLINE inline
-void free_fast_path(void *ptr) {
-  if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
-    tcmalloc::invoke_hooks_and_free(ptr);
-    return;
-  }
-  do_free(ptr);
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void tc_free(void* ptr) PERFTOOLS_NOTHROW {
-  free_fast_path(ptr);
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW {
-  if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
-    tcmalloc::invoke_hooks_and_free(ptr);
-    return;
-  }
-#ifndef NO_TCMALLOC_SAMPLES
-  // if ptr is kPageSize-aligned, then it could be sampled allocation,
-  // thus we don't trust hint and just do plain free. It also handles
-  // nullptr for us.
-  if (PREDICT_FALSE((reinterpret_cast<uintptr_t>(ptr) & (kPageSize-1)) == 0)) {
-    tc_free(ptr);
-    return;
-  }
-#else
-  if (!ptr) {
-    return;
-  }
-#endif
-  do_free_with_callback(ptr, &InvalidFree, true, size);
-}
-
-#ifdef TC_ALIAS
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void *p, size_t size) PERFTOOLS_NOTHROW
-  TC_ALIAS(tc_free_sized);
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void *p, size_t size) PERFTOOLS_NOTHROW
-  TC_ALIAS(tc_free_sized);
-
-#else
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void *p, size_t size) PERFTOOLS_NOTHROW {
-  tc_free_sized(p, size);
-}
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void *p, size_t size) PERFTOOLS_NOTHROW {
-  tc_free_sized(p, size);
-}
-
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_calloc(size_t n,
-                                              size_t elem_size) PERFTOOLS_NOTHROW {
-  if (ThreadCache::IsUseEmergencyMalloc()) {
-    return tcmalloc::EmergencyCalloc(n, elem_size);
-  }
-  void* result = do_calloc(n, elem_size);
-  MallocHook::InvokeNewHook(result, n * elem_size);
-  return result;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_free);
-#else
-{
-  free_fast_path(ptr);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_realloc(void* old_ptr,
-                                               size_t new_size) PERFTOOLS_NOTHROW {
-  if (old_ptr == NULL) {
-    void* result = do_malloc_or_cpp_alloc(new_size);
-    MallocHook::InvokeNewHook(result, new_size);
-    return result;
-  }
-  if (new_size == 0) {
-    MallocHook::InvokeDeleteHook(old_ptr);
-    do_free(old_ptr);
-    return NULL;
-  }
-  if (PREDICT_FALSE(tcmalloc::IsEmergencyPtr(old_ptr))) {
-    return tcmalloc::EmergencyRealloc(old_ptr, new_size);
-  }
-  return do_realloc(old_ptr, new_size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void* tc_new(size_t size) {
-  return malloc_fast_path<tcmalloc::cpp_throw_oom>(size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void* tc_new_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  return malloc_fast_path<tcmalloc::cpp_nothrow_oom>(size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_free);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-// Standard C++ library implementations define and use this
-// (via ::operator delete(ptr, nothrow)).
-// But it's really the same as normal delete, so we just do the same thing.
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_free);
-#else
-{
-  if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
-    tcmalloc::invoke_hooks_and_free(p);
-    return;
-  }
-  do_free(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size)
-#ifdef TC_ALIAS
-TC_ALIAS(tc_new);
-#else
-{
-  return malloc_fast_path<tcmalloc::cpp_throw_oom>(size);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::nothrow_t&)
-    PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_new_nothrow);
-#else
-{
-  return malloc_fast_path<tcmalloc::cpp_nothrow_oom>(size);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_free);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete_nothrow);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL CACHELINE_ALIGNED_FN
-void* tc_memalign(size_t align, size_t size) PERFTOOLS_NOTHROW {
-  return memalign_fast_path<tcmalloc::malloc_oom>(align, size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL int tc_posix_memalign(
-    void** result_ptr, size_t align, size_t size) PERFTOOLS_NOTHROW {
-  if (((align % sizeof(void*)) != 0) ||
-      ((align & (align - 1)) != 0) ||
-      (align == 0)) {
-    return EINVAL;
-  }
-
-  void* result = tc_memalign(align, size);
-  if (PREDICT_FALSE(result == NULL)) {
-    return ENOMEM;
-  } else {
-    *result_ptr = result;
-    return 0;
-  }
-}
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t align) {
-  return memalign_fast_path<tcmalloc::cpp_throw_oom>(static_cast<size_t>(align), size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t align, const std::nothrow_t&) PERFTOOLS_NOTHROW {
-  return memalign_fast_path<tcmalloc::cpp_nothrow_oom>(static_cast<size_t>(align), size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-// There is no easy way to obtain the actual size used by do_memalign to allocate aligned storage, so for now
-// just ignore the size. It might get useful in the future.
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t align) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t align)
-#ifdef TC_ALIAS
-TC_ALIAS(tc_new_aligned);
-#else
-{
-  return memalign_fast_path<tcmalloc::cpp_throw_oom>(static_cast<size_t>(align), size);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t align, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_new_aligned_nothrow);
-#else
-{
-  return memalign_fast_path<tcmalloc::cpp_nothrow_oom>(static_cast<size_t>(align), size);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete_aligned);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-// There is no easy way to obtain the actual size used by do_memalign to allocate aligned storage, so for now
-// just ignore the size. It might get useful in the future.
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t align) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete_sized_aligned);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW
-#ifdef TC_ALIAS
-TC_ALIAS(tc_delete_aligned_nothrow);
-#else
-{
-  free_fast_path(p);
-}
-#endif
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-static size_t pagesize = 0;
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_valloc(size_t size) PERFTOOLS_NOTHROW {
-  // Allocate page-aligned object of length >= size bytes
-  if (pagesize == 0) pagesize = getpagesize();
-  return tc_memalign(pagesize, size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t size) PERFTOOLS_NOTHROW {
-  // Round up size to a multiple of pagesize
-  if (pagesize == 0) pagesize = getpagesize();
-  if (size == 0) {     // pvalloc(0) should allocate one page, according to
-    size = pagesize;   // http://man.free4web.biz/man3/libmpatrol.3.html
-  }
-  size = (size + pagesize - 1) & ~(pagesize - 1);
-  return tc_memalign(pagesize, size);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW {
-  do_malloc_stats();
-}
-
-extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW {
-  return do_mallopt(cmd, value);
-}
-
-#ifdef HAVE_STRUCT_MALLINFO
-extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW {
-  return do_mallinfo();
-}
-#endif
-
-extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW {
-  return MallocExtension::instance()->GetAllocatedSize(ptr);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size)  PERFTOOLS_NOTHROW {
-  void* result = do_malloc(size);
-  MallocHook::InvokeNewHook(result, size);
-  return result;
-}
-
-#endif  // TCMALLOC_USING_DEBUGALLOCATION
diff --git a/third_party/tcmalloc/vendor/src/tcmalloc.h b/third_party/tcmalloc/vendor/src/tcmalloc.h
deleted file mode 100644
index 25cf982..0000000
--- a/third_party/tcmalloc/vendor/src/tcmalloc.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein <opensource@google.com>
-//
-// Some obscure memory-allocation routines may not be declared on all
-// systems.  In those cases, we'll just declare them ourselves.
-// This file is meant to be used only internally, for unittests.
-
-#include <config.h>
-
-#ifndef _XOPEN_SOURCE
-# define _XOPEN_SOURCE 600  // for posix_memalign
-#endif
-#include <stdlib.h>         // for posix_memalign
-// FreeBSD has malloc.h, but complains if you use it
-#if defined(HAVE_MALLOC_H) && !defined(__FreeBSD__)
-#include <malloc.h>         // for memalign, valloc, pvalloc
-#endif
-
-// __THROW is defined in glibc systems.  It means, counter-intuitively,
-// "This function will never throw an exception."  It's an optional
-// optimization tool, but we may need to use it to match glibc prototypes.
-#ifndef __THROW    // I guess we're not on a glibc system
-# define __THROW   // __THROW is just an optimization, so ok to make it ""
-#endif
-
-#if !HAVE_CFREE_SYMBOL
-extern "C" void cfree(void* ptr) __THROW;
-#endif
-#if !HAVE_DECL_POSIX_MEMALIGN
-extern "C" int posix_memalign(void** ptr, size_t align, size_t size) __THROW;
-#endif
-#if !HAVE_DECL_MEMALIGN
-extern "C" void* memalign(size_t __alignment, size_t __size) __THROW;
-#endif
-#if !HAVE_DECL_VALLOC
-extern "C" void* valloc(size_t __size) __THROW;
-#endif
-#if !HAVE_DECL_PVALLOC
-extern "C" void* pvalloc(size_t __size) __THROW;
-#endif
diff --git a/third_party/tcmalloc/vendor/src/tcmalloc_guard.h b/third_party/tcmalloc/vendor/src/tcmalloc_guard.h
deleted file mode 100644
index 84952ba..0000000
--- a/third_party/tcmalloc/vendor/src/tcmalloc_guard.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// We expose the TCMallocGuard class -- which initializes the tcmalloc
-// allocator -- so classes that need to be sure tcmalloc is loaded
-// before they do stuff -- notably heap-profiler -- can.  To use this
-// create a static TCMallocGuard instance at the top of a file where
-// you need tcmalloc to be initialized before global constructors run.
-
-#ifndef TCMALLOC_TCMALLOC_GUARD_H_
-#define TCMALLOC_TCMALLOC_GUARD_H_
-
-class TCMallocGuard {
- public:
-  TCMallocGuard();
-  ~TCMallocGuard();
-};
-
-#endif  // TCMALLOC_TCMALLOC_GUARD_H_
diff --git a/third_party/tcmalloc/vendor/src/tests/addressmap_unittest.cc b/third_party/tcmalloc/vendor/src/tests/addressmap_unittest.cc
deleted file mode 100644
index a847dd6f..0000000
--- a/third_party/tcmalloc/vendor/src/tests/addressmap_unittest.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-
-#include <stdlib.h>   // for rand()
-#include <vector>
-#include <set>
-#include <algorithm>
-#include <utility>
-#include "addressmap-inl.h"
-#include "base/logging.h"
-#include "base/commandlineflags.h"
-
-DEFINE_int32(iters, 20, "Number of test iterations");
-DEFINE_int32(N, 100000,  "Number of elements to test per iteration");
-
-using std::pair;
-using std::make_pair;
-using std::vector;
-using std::set;
-using std::random_shuffle;
-
-struct UniformRandomNumberGenerator {
-  size_t Uniform(size_t max_size) {
-    if (max_size == 0)
-      return 0;
-    return rand() % max_size;   // not a great random-number fn, but portable
-  }
-};
-static UniformRandomNumberGenerator rnd;
-
-
-// pair of associated value and object size
-typedef pair<int, size_t> ValueT;
-
-struct PtrAndSize {
-  char* ptr;
-  size_t size;
-  PtrAndSize(char* p, size_t s) : ptr(p), size(s) {}
-};
-
-size_t SizeFunc(const ValueT& v) { return v.second; }
-
-static void SetCheckCallback(const void* ptr, ValueT* val,
-                             set<pair<const void*, int> >* check_set) {
-  check_set->insert(make_pair(ptr, val->first));
-}
-
-int main(int argc, char** argv) {
-  // Get a bunch of pointers
-  const int N = FLAGS_N;
-  static const int kMaxRealSize = 49;
-  // 100Mb to stress not finding previous object (AddressMap's cluster is 1Mb):
-  static const size_t kMaxSize = 100*1000*1000;
-  vector<PtrAndSize> ptrs_and_sizes;
-  for (int i = 0; i < N; ++i) {
-    size_t s = rnd.Uniform(kMaxRealSize);
-    ptrs_and_sizes.push_back(PtrAndSize(new char[s], s));
-  }
-
-  for (int x = 0; x < FLAGS_iters; ++x) {
-    RAW_LOG(INFO, "Iteration %d/%d...\n", x, FLAGS_iters);
-
-    // Permute pointers to get rid of allocation order issues
-    random_shuffle(ptrs_and_sizes.begin(), ptrs_and_sizes.end());
-
-    AddressMap<ValueT> map(malloc, free);
-    const ValueT* result;
-    const void* res_p;
-
-    // Insert a bunch of entries
-    for (int i = 0; i < N; ++i) {
-      char* p = ptrs_and_sizes[i].ptr;
-      CHECK(!map.Find(p));
-      int offs = rnd.Uniform(ptrs_and_sizes[i].size);
-      CHECK(!map.FindInside(&SizeFunc, kMaxSize, p + offs, &res_p));
-      map.Insert(p, make_pair(i, ptrs_and_sizes[i].size));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i);
-      CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));
-      CHECK_EQ(res_p, p);
-      CHECK_EQ(result->first, i);
-      map.Insert(p, make_pair(i + N, ptrs_and_sizes[i].size));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + N);
-    }
-
-    // Delete the even entries
-    for (int i = 0; i < N; i += 2) {
-      void* p = ptrs_and_sizes[i].ptr;
-      ValueT removed;
-      CHECK(map.FindAndRemove(p, &removed));
-      CHECK_EQ(removed.first, i + N);
-    }
-
-    // Lookup the odd entries and adjust them
-    for (int i = 1; i < N; i += 2) {
-      char* p = ptrs_and_sizes[i].ptr;
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + N);
-      int offs = rnd.Uniform(ptrs_and_sizes[i].size);
-      CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));
-      CHECK_EQ(res_p, p);
-      CHECK_EQ(result->first, i + N);
-      map.Insert(p, make_pair(i + 2*N, ptrs_and_sizes[i].size));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + 2*N);
-    }
-
-    // Insert even entries back
-    for (int i = 0; i < N; i += 2) {
-      char* p = ptrs_and_sizes[i].ptr;
-      int offs = rnd.Uniform(ptrs_and_sizes[i].size);
-      CHECK(!map.FindInside(&SizeFunc, kMaxSize, p + offs, &res_p));
-      map.Insert(p, make_pair(i + 2*N, ptrs_and_sizes[i].size));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + 2*N);
-      CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));
-      CHECK_EQ(res_p, p);
-      CHECK_EQ(result->first, i + 2*N);
-    }
-
-    // Check all entries
-    set<pair<const void*, int> > check_set;
-    map.Iterate(SetCheckCallback, &check_set);
-    CHECK_EQ(check_set.size(), N);
-    for (int i = 0; i < N; ++i) {
-      void* p = ptrs_and_sizes[i].ptr;
-      check_set.erase(make_pair(p, i + 2*N));
-      CHECK(result = map.Find(p));
-      CHECK_EQ(result->first, i + 2*N);
-    }
-    CHECK_EQ(check_set.size(), 0);
-  }
-
-  for (int i = 0; i < N; ++i) {
-    delete[] ptrs_and_sizes[i].ptr;
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/atomicops_unittest.cc b/third_party/tcmalloc/vendor/src/tests/atomicops_unittest.cc
deleted file mode 100644
index aa82a6b5..0000000
--- a/third_party/tcmalloc/vendor/src/tests/atomicops_unittest.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-#include <stdio.h>
-#include "base/logging.h"
-#include "base/atomicops.h"
-
-#define GG_ULONGLONG(x)  static_cast<uint64>(x)
-
-
-#define NUM_BITS(T) (sizeof(T) * 8)
-
-
-template <class AtomicType>
-static void TestCompareAndSwap(AtomicType (*compare_and_swap_func)
-                               (volatile AtomicType*, AtomicType, AtomicType)) {
-  AtomicType value = 0;
-  AtomicType prev = (*compare_and_swap_func)(&value, 0, 1);
-  ASSERT_EQ(1, value);
-  ASSERT_EQ(0, prev);
-
-  // Use test value that has non-zero bits in both halves, more for testing
-  // 64-bit implementation on 32-bit platforms.
-  const AtomicType k_test_val = (GG_ULONGLONG(1) <<
-                                 (NUM_BITS(AtomicType) - 2)) + 11;
-  value = k_test_val;
-  prev = (*compare_and_swap_func)(&value, 0, 5);
-  ASSERT_EQ(k_test_val, value);
-  ASSERT_EQ(k_test_val, prev);
-
-  value = k_test_val;
-  prev = (*compare_and_swap_func)(&value, k_test_val, 5);
-  ASSERT_EQ(5, value);
-  ASSERT_EQ(k_test_val, prev);
-}
-
-
-template <class AtomicType>
-static void TestAtomicExchange(AtomicType (*atomic_exchange_func)
-                               (volatile AtomicType*, AtomicType)) {
-  AtomicType value = 0;
-  AtomicType new_value = (*atomic_exchange_func)(&value, 1);
-  ASSERT_EQ(1, value);
-  ASSERT_EQ(0, new_value);
-
-  // Use test value that has non-zero bits in both halves, more for testing
-  // 64-bit implementation on 32-bit platforms.
-  const AtomicType k_test_val = (GG_ULONGLONG(1) <<
-                                 (NUM_BITS(AtomicType) - 2)) + 11;
-  value = k_test_val;
-  new_value = (*atomic_exchange_func)(&value, k_test_val);
-  ASSERT_EQ(k_test_val, value);
-  ASSERT_EQ(k_test_val, new_value);
-
-  value = k_test_val;
-  new_value = (*atomic_exchange_func)(&value, 5);
-  ASSERT_EQ(5, value);
-  ASSERT_EQ(k_test_val, new_value);
-}
-
-
-// This is a simple sanity check that values are correct. Not testing
-// atomicity
-template <class AtomicType>
-static void TestStore() {
-  const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL);
-  const AtomicType kVal2 = static_cast<AtomicType>(-1);
-
-  AtomicType value;
-
-  base::subtle::NoBarrier_Store(&value, kVal1);
-  ASSERT_EQ(kVal1, value);
-  base::subtle::NoBarrier_Store(&value, kVal2);
-  ASSERT_EQ(kVal2, value);
-
-  base::subtle::Acquire_Store(&value, kVal1);
-  ASSERT_EQ(kVal1, value);
-  base::subtle::Acquire_Store(&value, kVal2);
-  ASSERT_EQ(kVal2, value);
-
-  base::subtle::Release_Store(&value, kVal1);
-  ASSERT_EQ(kVal1, value);
-  base::subtle::Release_Store(&value, kVal2);
-  ASSERT_EQ(kVal2, value);
-}
-
-// This is a simple sanity check that values are correct. Not testing
-// atomicity
-template <class AtomicType>
-static void TestLoad() {
-  const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL);
-  const AtomicType kVal2 = static_cast<AtomicType>(-1);
-
-  AtomicType value;
-
-  value = kVal1;
-  ASSERT_EQ(kVal1, base::subtle::NoBarrier_Load(&value));
-  value = kVal2;
-  ASSERT_EQ(kVal2, base::subtle::NoBarrier_Load(&value));
-
-  value = kVal1;
-  ASSERT_EQ(kVal1, base::subtle::Acquire_Load(&value));
-  value = kVal2;
-  ASSERT_EQ(kVal2, base::subtle::Acquire_Load(&value));
-
-  value = kVal1;
-  ASSERT_EQ(kVal1, base::subtle::Release_Load(&value));
-  value = kVal2;
-  ASSERT_EQ(kVal2, base::subtle::Release_Load(&value));
-}
-
-template <class AtomicType>
-static void TestAtomicOps() {
-  TestCompareAndSwap<AtomicType>(base::subtle::NoBarrier_CompareAndSwap);
-  TestCompareAndSwap<AtomicType>(base::subtle::Acquire_CompareAndSwap);
-  TestCompareAndSwap<AtomicType>(base::subtle::Release_CompareAndSwap);
-
-  TestAtomicExchange<AtomicType>(base::subtle::NoBarrier_AtomicExchange);
-  TestAtomicExchange<AtomicType>(base::subtle::Acquire_AtomicExchange);
-  TestAtomicExchange<AtomicType>(base::subtle::Release_AtomicExchange);
-
-  TestStore<AtomicType>();
-  TestLoad<AtomicType>();
-}
-
-int main(int argc, char** argv) {
-  TestAtomicOps<AtomicWord>();
-  TestAtomicOps<Atomic32>();
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/current_allocated_bytes_test.cc b/third_party/tcmalloc/vendor/src/tests/current_allocated_bytes_test.cc
deleted file mode 100644
index 49b7dc3..0000000
--- a/third_party/tcmalloc/vendor/src/tests/current_allocated_bytes_test.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// ---
-//
-// Author: Craig Silverstein
-
-// This tests the accounting done by tcmalloc.  When we allocate and
-// free a small buffer, the number of bytes used by the application
-// before the alloc+free should match the number of bytes used after.
-// However, the internal data structures used by tcmalloc will be
-// quite different -- new spans will have been allocated, etc.  This
-// is, thus, a simple test that we account properly for the internal
-// data structures, so that we report the actual application-used
-// bytes properly.
-
-#include "config_for_unittests.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <gperftools/malloc_extension.h>
-#include "base/logging.h"
-
-int main() {
-  // We don't do accounting right when using debugallocation.cc, so
-  // turn off the test then.  TODO(csilvers): get this working too.
-#ifdef NDEBUG
-  static const char kCurrent[] = "generic.current_allocated_bytes";
-
-  size_t before_bytes, after_bytes;
-  MallocExtension::instance()->GetNumericProperty(kCurrent, &before_bytes);
-  free(malloc(200));
-  MallocExtension::instance()->GetNumericProperty(kCurrent, &after_bytes);
-
-  CHECK_EQ(before_bytes, after_bytes);
-#endif
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/debugallocation_test.cc b/third_party/tcmalloc/vendor/src/tests/debugallocation_test.cc
deleted file mode 100644
index d935dbb1..0000000
--- a/third_party/tcmalloc/vendor/src/tests/debugallocation_test.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Fred Akalin
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h> // for memcmp
-#include <vector>
-#include "gperftools/malloc_extension.h"
-#include "gperftools/tcmalloc.h"
-#include "base/logging.h"
-
-using std::vector;
-
-vector<void (*)()> g_testlist;  // the tests to run
-
-#define TEST(a, b)                                      \
-  struct Test_##a##_##b {                               \
-    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
-    static void Run();                                  \
-  };                                                    \
-  static Test_##a##_##b g_test_##a##_##b;               \
-  void Test_##a##_##b::Run()
-
-
-static int RUN_ALL_TESTS() {
-  vector<void (*)()>::const_iterator it;
-  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
-    (*it)();   // The test will error-exit if there's a problem.
-  }
-  fprintf(stderr, "\nPassed %d tests\n\nPASS\n",
-          static_cast<int>(g_testlist.size()));
-  return 0;
-}
-
-// The death tests are meant to be run from a shell-script driver, which
-// passes in an integer saying which death test to run.  We store that
-// test-to-run here, and in the macro use a counter to see when we get
-// to that test, so we can run it.
-static int test_to_run = 0;     // set in main() based on argv
-static int test_counter = 0;    // incremented every time the macro is called
-#define IF_DEBUG_EXPECT_DEATH(statement, regex) do {    \
-  if (test_counter++ == test_to_run) {                  \
-    fprintf(stderr, "Expected regex:%s\n", regex);      \
-    statement;                                          \
-  }                                                     \
-} while (false)
-
-// This flag won't be compiled in in opt mode.
-DECLARE_int32(max_free_queue_size);
-
-// Test match as well as mismatch rules.  But do not test on OS X; on
-// OS X the OS converts new/new[] to malloc before it gets to us, so
-// we are unable to catch these mismatch errors.
-#ifndef __APPLE__
-TEST(DebugAllocationTest, DeallocMismatch) {
-  // malloc can be matched only by free
-  // new can be matched only by delete and delete(nothrow)
-  // new[] can be matched only by delete[] and delete[](nothrow)
-  // new(nothrow) can be matched only by delete and delete(nothrow)
-  // new(nothrow)[] can be matched only by delete[] and delete[](nothrow)
-
-  // Allocate with malloc.
-  {
-    int* x = static_cast<int*>(malloc(sizeof(*x)));
-    IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete");
-    IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]");
-    // Should work fine.
-    free(x);
-  }
-
-  // Allocate with new.
-  {
-    int* x = new int;
-    int* y = new int;
-    IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
-    IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]");
-    delete x;
-    ::operator delete(y, std::nothrow);
-  }
-
-  // Allocate with new[].
-  {
-    int* x = new int[1];
-    int* y = new int[1];
-    IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
-    IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete");
-    delete [] x;
-    ::operator delete[](y, std::nothrow);
-  }
-
-  // Allocate with new(nothrow).
-  {
-    int* x = new(std::nothrow) int;
-    int* y = new(std::nothrow) int;
-    IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
-    IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]");
-    delete x;
-    ::operator delete(y, std::nothrow);
-  }
-
-  // Allocate with new(nothrow)[].
-  {
-    int* x = new(std::nothrow) int[1];
-    int* y = new(std::nothrow) int[1];
-    IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
-    IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete");
-    delete [] x;
-    ::operator delete[](y, std::nothrow);
-  }
-}
-#endif  // #ifdef OS_MACOSX
-
-TEST(DebugAllocationTest, DoubleFree) {
-  int* pint = new int;
-  delete pint;
-  IF_DEBUG_EXPECT_DEATH(delete pint, "has been already deallocated");
-}
-
-TEST(DebugAllocationTest, StompBefore) {
-  int* pint = new int;
-#ifndef NDEBUG   // don't stomp memory if we're not in a position to detect it
-  pint[-1] = 5;
-  IF_DEBUG_EXPECT_DEATH(delete pint, "a word before object");
-#endif
-}
-
-TEST(DebugAllocationTest, StompAfter) {
-  int* pint = new int;
-#ifndef NDEBUG   // don't stomp memory if we're not in a position to detect it
-  pint[1] = 5;
-  IF_DEBUG_EXPECT_DEATH(delete pint, "a word after object");
-#endif
-}
-
-TEST(DebugAllocationTest, FreeQueueTest) {
-  // Verify that the allocator doesn't return blocks that were recently freed.
-  int* x = new int;
-  int* old_x = x;
-  delete x;
-  x = new int;
-  #if 1
-    // This check should not be read as a universal guarantee of behavior.  If
-    // other threads are executing, it would be theoretically possible for this
-    // check to fail despite the efforts of debugallocation.cc to the contrary.
-    // It should always hold under the controlled conditions of this unittest,
-    // however.
-    EXPECT_NE(x, old_x);  // Allocator shouldn't return recently freed blocks
-  #else
-    // The below check passes, but since it isn't *required* to pass, I've left
-    // it commented out.
-    // EXPECT_EQ(x, old_x);
-  #endif
-  old_x = NULL;  // avoid breaking opt build with an unused variable warning.
-  delete x;
-}
-
-TEST(DebugAllocationTest, DanglingPointerWriteTest) {
-  // This test can only be run if debugging.
-  //
-  // If not debugging, the 'new' following the dangling write might not be
-  // safe.  When debugging, we expect the (trashed) deleted block to be on the
-  // list of recently-freed blocks, so the following 'new' will be safe.
-#if 1
-  int* x = new int;
-  delete x;
-  int poisoned_x_value = *x;
-  *x = 1;  // a dangling write.
-
-  char* s = new char[FLAGS_max_free_queue_size];
-  // When we delete s, we push the storage that was previously allocated to x
-  // off the end of the free queue.  At that point, the write to that memory
-  // will be detected.
-  IF_DEBUG_EXPECT_DEATH(delete [] s, "Memory was written to after being freed.");
-
-  // restore the poisoned value of x so that we can delete s without causing a
-  // crash.
-  *x = poisoned_x_value;
-  delete [] s;
-#endif
-}
-
-TEST(DebugAllocationTest, DanglingWriteAtExitTest) {
-  int *x = new int;
-  delete x;
-  int old_x_value = *x;
-  *x = 1;
-  // verify that dangling writes are caught at program termination if the
-  // corrupted block never got pushed off of the end of the free queue.
-  IF_DEBUG_EXPECT_DEATH(exit(0), "Memory was written to after being freed.");
-  *x = old_x_value;  // restore x so that the test can exit successfully.
-}
-
-TEST(DebugAllocationTest, StackTraceWithDanglingWriteAtExitTest) {
-  int *x = new int;
-  delete x;
-  int old_x_value = *x;
-  *x = 1;
-  // verify that we also get a stack trace when we have a dangling write.
-  // The " @ " is part of the stack trace output.
-  IF_DEBUG_EXPECT_DEATH(exit(0), " @ .*main");
-  *x = old_x_value;  // restore x so that the test can exit successfully.
-}
-
-static size_t CurrentlyAllocatedBytes() {
-  size_t value;
-  CHECK(MallocExtension::instance()->GetNumericProperty(
-            "generic.current_allocated_bytes", &value));
-  return value;
-}
-
-TEST(DebugAllocationTest, CurrentlyAllocated) {
-  // Clear the free queue
-#if 1
-  FLAGS_max_free_queue_size = 0;
-  // Force a round-trip through the queue management code so that the
-  // new size is seen and the queue of recently-freed blocks is flushed.
-  free(malloc(1));
-  FLAGS_max_free_queue_size = 1048576;
-#endif
-
-  // Free something and check that it disappears from allocated bytes
-  // immediately.
-  char* p = new char[1000];
-  size_t after_malloc = CurrentlyAllocatedBytes();
-  delete[] p;
-  size_t after_free = CurrentlyAllocatedBytes();
-  EXPECT_LE(after_free, after_malloc - 1000);
-}
-
-TEST(DebugAllocationTest, GetAllocatedSizeTest) {
-#if 1
-  // When debug_allocation is in effect, GetAllocatedSize should return
-  // exactly requested size, since debug_allocation doesn't allow users
-  // to write more than that.
-  for (int i = 0; i < 10; ++i) {
-    void *p = malloc(i);
-    EXPECT_EQ(i, MallocExtension::instance()->GetAllocatedSize(p));
-    free(p);
-  }
-#endif
-  void* a = malloc(1000);
-  EXPECT_GE(MallocExtension::instance()->GetAllocatedSize(a), 1000);
-  // This is just a sanity check.  If we allocated too much, alloc is broken
-  EXPECT_LE(MallocExtension::instance()->GetAllocatedSize(a), 5000);
-  EXPECT_GE(MallocExtension::instance()->GetEstimatedAllocatedSize(1000), 1000);
-  free(a);
-}
-
-TEST(DebugAllocationTest, HugeAlloc) {
-  // This must not be a const variable so it doesn't form an
-  // integral-constant-expression which can be *statically* rejected by the
-  // compiler as too large for the allocation.
-  size_t kTooBig = ~static_cast<size_t>(0);
-  void* a = NULL;
-
-#ifndef NDEBUG
-
-  a = malloc(kTooBig);
-  EXPECT_EQ(NULL, a);
-
-  // kAlsoTooBig is small enough not to get caught by debugallocation's check,
-  // but will still fall through to tcmalloc's check. This must also be
-  // a non-const variable. See kTooBig for more details.
-  size_t kAlsoTooBig = kTooBig - 1024;
-
-  a = malloc(kAlsoTooBig);
-  EXPECT_EQ(NULL, a);
-#endif
-}
-
-// based on test program contributed by mikesart@gmail.com aka
-// mikesart@valvesoftware.com. See issue-464.
-TEST(DebugAllocationTest, ReallocAfterMemalign) {
-  char stuff[50];
-  memset(stuff, 0x11, sizeof(stuff));
-  void *p = tc_memalign(16, sizeof(stuff));
-  EXPECT_NE(p, NULL);
-  memcpy(stuff, p, sizeof(stuff));
-
-  p = realloc(p, sizeof(stuff) + 10);
-  EXPECT_NE(p, NULL);
-
-  int rv = memcmp(stuff, p, sizeof(stuff));
-  EXPECT_EQ(rv, 0);
-}
-
-int main(int argc, char** argv) {
-  // If you run without args, we run the non-death parts of the test.
-  // Otherwise, argv[1] should be a number saying which death-test
-  // to run.  We will output a regexp we expect the death-message
-  // to include, and then run the given death test (which hopefully
-  // will produce that error message).  If argv[1] > the number of
-  // death tests, we will run only the non-death parts.  One way to
-  // tell when you are done with all tests is when no 'expected
-  // regexp' message is printed for a given argv[1].
-  if (argc < 2) {
-    test_to_run = -1;   // will never match
-  } else {
-    test_to_run = atoi(argv[1]);
-  }
-  return RUN_ALL_TESTS();
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/debugallocation_test.sh b/third_party/tcmalloc/vendor/src/tests/debugallocation_test.sh
deleted file mode 100755
index 0f94ad0..0000000
--- a/third_party/tcmalloc/vendor/src/tests/debugallocation_test.sh
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2009, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# ---
-# Author: Craig Silverstein
-
-BINDIR="${BINDIR:-.}"
-# We expect PPROF_PATH to be set in the environment.
-# If not, we set it to some reasonable value
-export PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir]"
-  echo "       By default, unittest_dir=$BINDIR"
-  exit 1
-fi
-
-DEBUGALLOCATION_TEST="${1:-$BINDIR/debugallocation_test}"
-
-num_failures=0
-
-# Run the i-th death test and make sure the test has the expected
-# regexp.  We can depend on the first line of the output being
-#    Expected regex:<regex>
-# Evaluates to "done" if we are not actually a death-test (so $1 is
-# too big a number, and we can stop).  Evaluates to "" otherwise.
-# Increments num_failures if the death test does not succeed.
-OneDeathTest() {
-  "$DEBUGALLOCATION_TEST" "$1" 2>&1 | {
-    regex_line='dummy'
-    # Normally the regex_line is the first line of output, but not
-    # always (if tcmalloc itself does any logging to stderr).
-    while test -n "$regex_line"; do
-      read regex_line
-      regex=`expr "$regex_line" : "Expected regex:\(.*\)"`
-      test -n "$regex" && break   # found the regex line
-    done
-    test -z "$regex" && echo "done" || grep "$regex" 2>&1
-  }
-}
-
-death_test_num=0   # which death test to run
-while :; do        # same as 'while true', but more portable
-  echo -n "Running death test $death_test_num..."
-  output="`OneDeathTest $death_test_num`"
-  case $output in
-     # Empty string means grep didn't find anything.
-     "")      echo "FAILED"; num_failures=`expr $num_failures + 1`;;
-     "done"*) echo "done with death tests"; break;;
-     # Any other string means grep found something, like it ought to.
-     *)       echo "OK";;
-  esac
-  death_test_num=`expr $death_test_num + 1`
-done
-
-# Test the non-death parts of the test too
-echo -n "Running non-death tests..."
-if "$DEBUGALLOCATION_TEST"; then
-  echo "OK"
-else
-  echo "FAILED"
-  num_failures=`expr $num_failures + 1`
-fi
-
-if [ "$num_failures" = 0 ]; then
-  echo "PASS"
-else
-  echo "Failed with $num_failures failures"
-fi
-exit $num_failures
diff --git a/third_party/tcmalloc/vendor/src/tests/frag_unittest.cc b/third_party/tcmalloc/vendor/src/tests/frag_unittest.cc
deleted file mode 100644
index c4016f9..0000000
--- a/third_party/tcmalloc/vendor/src/tests/frag_unittest.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2003, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Test speed of handling fragmented heap
-
-#include "config_for_unittests.h"
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/time.h>           // for struct timeval
-#include <sys/resource.h>       // for getrusage
-#endif
-#ifdef _WIN32
-#include <windows.h>            // for GetTickCount()
-#endif
-#include <vector>
-#include "base/logging.h"
-#include "common.h"
-#include <gperftools/malloc_extension.h>
-
-using std::vector;
-
-int main(int argc, char** argv) {
-  // Make kAllocSize one page larger than the maximum small object size.
-  static const int kAllocSize = kMaxSize + kPageSize;
-  // Allocate 400MB in total.
-  static const int kTotalAlloc = 400 << 20;
-  static const int kAllocIterations = kTotalAlloc / kAllocSize;
-
-  // Allocate lots of objects
-  vector<char*> saved(kAllocIterations);
-  for (int i = 0; i < kAllocIterations; i++) {
-    saved[i] = new char[kAllocSize];
-  }
-
-  // Check the current "slack".
-  size_t slack_before;
-  MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
-                                                  &slack_before);
-
-  // Free alternating ones to fragment heap
-  size_t free_bytes = 0;
-  for (int i = 0; i < saved.size(); i += 2) {
-    delete[] saved[i];
-    free_bytes += kAllocSize;
-  }
-
-  // Check that slack delta is within 10% of expected.
-  size_t slack_after;
-  MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
-                                                  &slack_after);
-  CHECK_GE(slack_after, slack_before);
-  size_t slack = slack_after - slack_before;
-
-  CHECK_GT(double(slack), 0.9*free_bytes);
-  CHECK_LT(double(slack), 1.1*free_bytes);
-
-  // Dump malloc stats
-  static const int kBufSize = 1<<20;
-  char* buffer = new char[kBufSize];
-  MallocExtension::instance()->GetStats(buffer, kBufSize);
-  VLOG(1, "%s", buffer);
-  delete[] buffer;
-
-  // Now do timing tests
-  for (int i = 0; i < 5; i++) {
-    static const int kIterations = 100000;
-#ifdef HAVE_SYS_RESOURCE_H
-    struct rusage r;
-    getrusage(RUSAGE_SELF, &r);    // figure out user-time spent on this
-    struct timeval tv_start = r.ru_utime;
-#elif defined(_WIN32)
-    long long int tv_start = GetTickCount();
-#else
-# error No way to calculate time on your system
-#endif
-
-    for (int i = 0; i < kIterations; i++) {
-      size_t s;
-      MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
-                                                      &s);
-    }
-
-#ifdef HAVE_SYS_RESOURCE_H
-    getrusage(RUSAGE_SELF, &r);
-    struct timeval tv_end = r.ru_utime;
-    int64 sumsec = static_cast<int64>(tv_end.tv_sec) - tv_start.tv_sec;
-    int64 sumusec = static_cast<int64>(tv_end.tv_usec) - tv_start.tv_usec;
-#elif defined(_WIN32)
-    long long int tv_end = GetTickCount();
-    int64 sumsec = (tv_end - tv_start) / 1000;
-    // Resolution in windows is only to the millisecond, alas
-    int64 sumusec = ((tv_end - tv_start) % 1000) * 1000;
-#else
-# error No way to calculate time on your system
-#endif
-    fprintf(stderr, "getproperty: %6.1f ns/call\n",
-            (sumsec * 1e9 + sumusec * 1e3) / kIterations);
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/getpc_test.cc b/third_party/tcmalloc/vendor/src/tests/getpc_test.cc
deleted file mode 100644
index d75e40b..0000000
--- a/third_party/tcmalloc/vendor/src/tests/getpc_test.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This verifies that GetPC works correctly.  This test uses a minimum
-// of Google infrastructure, to make it very easy to port to various
-// O/Ses and CPUs and test that GetPC is working.
-
-#include "config.h"
-#include "getpc.h"        // should be first to get the _GNU_SOURCE dfn
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <sys/time.h>     // for setitimer
-
-// Needs to be volatile so compiler doesn't try to optimize it away
-static volatile void* getpc_retval = NULL;    // what GetPC returns
-static volatile bool prof_handler_called = false;
-
-static void prof_handler(int sig, siginfo_t*, void* signal_ucontext) {
-  if (!prof_handler_called)
-    getpc_retval = GetPC(*reinterpret_cast<ucontext_t*>(signal_ucontext));
-  prof_handler_called = true;  // only store the retval once
-}
-
-static void RoutineCallingTheSignal() {
-  struct sigaction sa;
-  sa.sa_sigaction = prof_handler;
-  sa.sa_flags = SA_RESTART | SA_SIGINFO;
-  sigemptyset(&sa.sa_mask);
-  if (sigaction(SIGPROF, &sa, NULL) != 0) {
-    perror("sigaction");
-    exit(1);
-  }
-
-  struct itimerval timer;
-  timer.it_interval.tv_sec = 0;
-  timer.it_interval.tv_usec = 1000;
-  timer.it_value = timer.it_interval;
-  setitimer(ITIMER_PROF, &timer, 0);
-
-  // Now we need to do some work for a while, that doesn't call any
-  // other functions, so we can be guaranteed that when the SIGPROF
-  // fires, we're the routine executing.
-  int r = 0;
-  for (int i = 0; !prof_handler_called; ++i) {
-    for (int j = 0; j < i; j++) {
-      r ^= i;
-      r <<= 1;
-      r ^= j;
-      r >>= 1;
-    }
-  }
-
-  // Now make sure the above loop doesn't get optimized out
-  srand(r);
-}
-
-// This is an upper bound of how many bytes the instructions for
-// RoutineCallingTheSignal might be.  There's probably a more
-// principled way to do this, but I don't know how portable it would be.
-// (The function is 372 bytes when compiled with -g on Mac OS X 10.4.
-// I can imagine it would be even bigger in 64-bit architectures.)
-const int kRoutineSize = 512 * sizeof(void*)/4;    // allow 1024 for 64-bit
-
-int main(int argc, char** argv) {
-  RoutineCallingTheSignal();
-
-  // Annoyingly, C++ disallows casting pointer-to-function to
-  // pointer-to-object, so we use a C-style cast instead.
-  char* expected = (char*)&RoutineCallingTheSignal;
-  char* actual = (char*)getpc_retval;
-
-  // For ia64, ppc64v1, and parisc64, the function pointer is actually
-  // a struct.  For instance, ia64's dl-fptr.h:
-  //   struct fdesc {          /* An FDESC is a function descriptor.  */
-  //      ElfW(Addr) ip;      /* code entry point */
-  //      ElfW(Addr) gp;      /* global pointer */
-  //   };
-  // We want the code entry point.
-  // NOTE: ppc64 ELFv2 (Little Endian) does not have function pointers
-#if defined(__ia64) || \
-    (defined(__powerpc64__) && _CALL_ELF != 2)
-  expected = ((char**)expected)[0];         // this is "ip"
-#endif
-
-  if (actual < expected || actual > expected + kRoutineSize) {
-    printf("Test FAILED: actual PC: %p, expected PC: %p\n", actual, expected);
-    return 1;
-  } else {
-    printf("PASS\n");
-    return 0;
-  }
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/heap-checker-death_unittest.sh b/third_party/tcmalloc/vendor/src/tests/heap-checker-death_unittest.sh
deleted file mode 100755
index 69db0c9e0..0000000
--- a/third_party/tcmalloc/vendor/src/tests/heap-checker-death_unittest.sh
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/bin/sh
-# Copyright (c) 2005, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Maxim Lifantsev
-#
-# Run the heap checker unittest in a mode where it is supposed to crash and
-# return an error if it doesn't.
-
-# We expect BINDIR to be set in the environment.
-# If not, we set it to some reasonable value.
-BINDIR="${BINDIR:-.}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir]"
-  echo "       By default, unittest_dir=$BINDIR"
-  exit 1
-fi
-
-EXE="${1:-$BINDIR/heap-checker_unittest}"
-TMPDIR="/tmp/heap_check_death_info"
-
-ALARM() {
-  # You need perl to run pprof, so I assume it's installed
-  perl -e '
-    $timeout=$ARGV[0]; shift;
-    $retval = 255;   # the default retval, for the case where we timed out
-    eval {           # need to run in an eval-block to trigger during system()
-      local $SIG{ALRM} = sub { die "alarm\n" };  # \n is required!
-      alarm $timeout;
-      $retval = system(@ARGV);
-      # Make retval bash-style: exit status, or 128+n if terminated by signal n
-      $retval = ($retval & 127) ? (128 + $retval) : ($retval >> 8);
-      alarm 0;
-    };
-    exit $retval;  # return system()-retval, or 255 if system() never returned
-' "$@"
-}
-
-# $1: timeout for alarm;
-# $2: regexp of expected exit code(s);
-# $3: regexp to match a line in the output;
-# $4: regexp to not match a line in the output;
-# $5+ args to pass to $EXE
-Test() {
-  # Note: make sure these varnames don't conflict with any vars outside Test()!
-  timeout="$1"
-  shift
-  expected_ec="$1"
-  shift
-  expected_regexp="$1"
-  shift
-  unexpected_regexp="$1"
-  shift
-
-  echo -n "Testing $EXE with $@ ... "
-  output="$TMPDIR/output"
-  ALARM $timeout env "$@" $EXE > "$output" 2>&1
-  actual_ec=$?
-  ec_ok=`expr "$actual_ec" : "$expected_ec$" >/dev/null || echo false`
-  matches_ok=`test -z "$expected_regexp" || \
-              grep "$expected_regexp" "$output" >/dev/null 2>&1 || echo false`
-  negmatches_ok=`test -z "$unexpected_regexp" || \
-                 ! grep "$unexpected_regexp" "$output" >/dev/null 2>&1 || echo false`
-  if $ec_ok && $matches_ok && $negmatches_ok; then
-    echo "PASS"
-    return 0  # 0: success
-  fi
-  # If we get here, we failed.  Now we just need to report why
-  echo "FAIL"
-  if [ $actual_ec -eq 255 ]; then  # 255 == SIGTERM due to $ALARM
-    echo "Test was taking unexpectedly long time to run and so we aborted it."
-    echo "Try the test case manually or raise the timeout from $timeout"
-    echo "to distinguish test slowness from a real problem."
-  else
-    $ec_ok || \
-      echo "Wrong exit code: expected: '$expected_ec'; actual: $actual_ec"
-    $matches_ok || \
-      echo "Output did not match '$expected_regexp'"
-    $negmatches_ok || \
-      echo "Output unexpectedly matched '$unexpected_regexp'"
-  fi
-  echo "Output from failed run:"
-  echo "---"
-  cat "$output"
-  echo "---"
-  return 1  # 1: failure
-}
-
-TMPDIR=/tmp/heap_check_death_info
-rm -rf $TMPDIR || exit 1
-mkdir $TMPDIR || exit 2
-
-export HEAPCHECK=strict       # default mode
-
-# These invocations should pass (0 == PASS):
-
-# This tests that turning leak-checker off dynamically works fine
-Test 120 0 "^PASS$" "" HEAPCHECK="" || exit 1
-
-# This disables threads so we can cause leaks reliably and test finding them
-Test 120 0 "^PASS$" "" HEAP_CHECKER_TEST_NO_THREADS=1 || exit 2
-
-# Test that --test_cancel_global_check works
-Test 20 0 "Canceling .* whole-program .* leak check$" "" \
-  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK=1 || exit 3
-Test 20 0 "Canceling .* whole-program .* leak check$" "" \
-  HEAP_CHECKER_TEST_TEST_LOOP_LEAK=1 HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK=1 || exit 4
-
-# Test that very early log messages are present and controllable:
-EARLY_MSG="Starting tracking the heap$"
-
-Test 60 0 "$EARLY_MSG" "" \
-  HEAPCHECK="" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
-  PERFTOOLS_VERBOSE=10 || exit 5
-Test 60 0 "MemoryRegionMap Init$" "" \
-  HEAPCHECK="" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
-  PERFTOOLS_VERBOSE=11 || exit 6
-Test 60 0 "" "$EARLY_MSG" \
-  HEAPCHECK="" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
-  PERFTOOLS_VERBOSE=-11 || exit 7
-
-# These invocations should fail with very high probability,
-# rather than return 0 or hang (1 == exit(1), 134 == abort(), 139 = SIGSEGV):
-
-Test 60 1 "Exiting .* because of .* leaks$" "" \
-  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 || exit 8
-Test 60 1 "Exiting .* because of .* leaks$" "" \
-  HEAP_CHECKER_TEST_TEST_LOOP_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 || exit 9
-
-# Test that we produce a reasonable textual leak report.
-Test 60 1 "MakeALeak" "" \
-          HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
-  || exit 10
-
-# Test that very early log messages are present and controllable:
-Test 60 1 "Starting tracking the heap$" "" \
-  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 PERFTOOLS_VERBOSE=10 \
-  || exit 11
-Test 60 1 "" "Starting tracking the heap" \
-  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 PERFTOOLS_VERBOSE=-10 \
-  || exit 12
-
-cd /    # so we're not in TMPDIR when we delete it
-rm -rf $TMPDIR
-
-echo "PASS"
-
-exit 0
diff --git a/third_party/tcmalloc/vendor/src/tests/heap-checker_unittest.cc b/third_party/tcmalloc/vendor/src/tests/heap-checker_unittest.cc
deleted file mode 100644
index ee60af5..0000000
--- a/third_party/tcmalloc/vendor/src/tests/heap-checker_unittest.cc
+++ /dev/null
@@ -1,1538 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Maxim Lifantsev
-//
-// Running:
-// ./heap-checker_unittest
-//
-// If the unittest crashes because it can't find pprof, try:
-// PPROF_PATH=/usr/local/someplace/bin/pprof ./heap-checker_unittest
-//
-// To test that the whole-program heap checker will actually cause a leak, try:
-// HEAPCHECK_TEST_LEAK= ./heap-checker_unittest
-// HEAPCHECK_TEST_LOOP_LEAK= ./heap-checker_unittest
-//
-// Note: Both of the above commands *should* abort with an error message.
-
-// CAVEAT: Do not use vector<> and string on-heap objects in this test,
-// otherwise the test can sometimes fail for tricky leak checks
-// when we want some allocated object not to be found live by the heap checker.
-// This can happen with memory allocators like tcmalloc that can allocate
-// heap objects back to back without any book-keeping data in between.
-// What happens is that end-of-storage pointers of a live vector
-// (or a string depending on the STL implementation used)
-// can happen to point to that other heap-allocated
-// object that is not reachable otherwise and that
-// we don't want to be reachable.
-//
-// The implication of this for real leak checking
-// is just one more chance for the liveness flood to be inexact
-// (see the comment in our .h file).
-
-#include "config_for_unittests.h"
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uint16_t (ISO naming madness)
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uint16_t might be defined
-#endif
-#include <sys/types.h>
-#include <stdlib.h>
-#include <errno.h>              // errno
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>             // for sleep(), geteuid()
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#include <fcntl.h>              // for open(), close()
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>           // backtrace
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>                // getgrent, getgrnam
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-
-#include <algorithm>
-#include <iostream>             // for cout
-#include <iomanip>              // for hex
-#include <list>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/commandlineflags.h"
-#include "base/googleinit.h"
-#include "base/logging.h"
-#include "base/commandlineflags.h"
-#include "base/thread_lister.h"
-#include <gperftools/heap-checker.h>
-#include "memory_region_map.h"
-#include <gperftools/malloc_extension.h>
-#include <gperftools/stacktrace.h>
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-using namespace std;
-
-// ========================================================================= //
-
-// TODO(maxim): write a shell script to test that these indeed crash us
-//              (i.e. we do detect leaks)
-//              Maybe add more such crash tests.
-
-DEFINE_bool(test_leak,
-            EnvToBool("HEAP_CHECKER_TEST_TEST_LEAK", false),
-            "If should cause a leak crash");
-DEFINE_bool(test_loop_leak,
-            EnvToBool("HEAP_CHECKER_TEST_TEST_LOOP_LEAK", false),
-            "If should cause a looped leak crash");
-DEFINE_bool(test_register_leak,
-            EnvToBool("HEAP_CHECKER_TEST_TEST_REGISTER_LEAK", false),
-            "If should cause a leak crash by hiding a pointer "
-            "that is only in a register");
-DEFINE_bool(test_cancel_global_check,
-            EnvToBool("HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK", false),
-            "If should test HeapLeakChecker::CancelGlobalCheck "
-            "when --test_leak or --test_loop_leak are given; "
-            "the test should not fail then");
-DEFINE_bool(maybe_stripped,
-            EnvToBool("HEAP_CHECKER_TEST_MAYBE_STRIPPED", true),
-            "If we think we can be a stripped binary");
-DEFINE_bool(interfering_threads,
-            EnvToBool("HEAP_CHECKER_TEST_INTERFERING_THREADS", true),
-            "If we should use threads trying "
-            "to interfere with leak checking");
-DEFINE_bool(hoarding_threads,
-            EnvToBool("HEAP_CHECKER_TEST_HOARDING_THREADS", true),
-            "If threads (usually the manager thread) are known "
-            "to retain some old state in their global buffers, "
-            "so that it's hard to force leaks when threads are around");
-            // TODO(maxim): Chage the default to false
-            // when the standard environment used NTPL threads:
-            // they do not seem to have this problem.
-DEFINE_bool(no_threads,
-            EnvToBool("HEAP_CHECKER_TEST_NO_THREADS", false),
-            "If we should not use any threads");
-            // This is used so we can make can_create_leaks_reliably true
-            // for any pthread implementation and test with that.
-
-DECLARE_int64(heap_check_max_pointer_offset);   // heap-checker.cc
-DECLARE_string(heap_check);  // in heap-checker.cc
-
-#define WARN_IF(cond, msg)   LOG_IF(WARNING, cond, msg)
-
-// This is an evil macro!  Be very careful using it...
-#undef VLOG          // and we start by evilling overriding logging.h VLOG
-#define VLOG(lvl)    if (FLAGS_verbose >= (lvl))  cout << "\n"
-// This is, likewise, evil
-#define LOGF         VLOG(INFO)
-
-static void RunHeapBusyThreads();  // below
-
-
-class Closure {
- public:
-  virtual ~Closure() { }
-  virtual void Run() = 0;
-};
-
-class Callback0 : public Closure {
- public:
-  typedef void (*FunctionSignature)();
-
-  inline Callback0(FunctionSignature f) : f_(f) {}
-  virtual void Run() { (*f_)(); delete this; }
-
- private:
-  FunctionSignature f_;
-};
-
-template <class P1> class Callback1 : public Closure {
- public:
-  typedef void (*FunctionSignature)(P1);
-
-  inline Callback1<P1>(FunctionSignature f, P1 p1) : f_(f), p1_(p1) {}
-  virtual void Run() { (*f_)(p1_); delete this; }
-
- private:
-  FunctionSignature f_;
-  P1 p1_;
-};
-
-template <class P1, class P2> class Callback2 : public Closure {
- public:
-  typedef void (*FunctionSignature)(P1,P2);
-
-  inline Callback2<P1,P2>(FunctionSignature f, P1 p1, P2 p2) : f_(f), p1_(p1), p2_(p2) {}
-  virtual void Run() { (*f_)(p1_, p2_); delete this; }
-
- private:
-  FunctionSignature f_;
-  P1 p1_;
-  P2 p2_;
-};
-
-inline Callback0* NewCallback(void (*function)()) {
-  return new Callback0(function);
-}
-
-template <class P1>
-inline Callback1<P1>* NewCallback(void (*function)(P1), P1 p1) {
-  return new Callback1<P1>(function, p1);
-}
-
-template <class P1, class P2>
-inline Callback2<P1,P2>* NewCallback(void (*function)(P1,P2), P1 p1, P2 p2) {
-  return new Callback2<P1,P2>(function, p1, p2);
-}
-
-
-// Set to true at end of main, so threads know.  Not entirely thread-safe!,
-// but probably good enough.
-static bool g_have_exited_main = false;
-
-// If we can reliably create leaks (i.e. make leaked object
-// really unreachable from any global data).
-static bool can_create_leaks_reliably = false;
-
-// We use a simple allocation wrapper
-// to make sure we wipe out the newly allocated objects
-// in case they still happened to contain some pointer data
-// accidentally left by the memory allocator.
-struct Initialized { };
-static Initialized initialized;
-void* operator new(size_t size, const Initialized&) {
-  // Below we use "p = new(initialized) Foo[1];" and  "delete[] p;"
-  // instead of "p = new(initialized) Foo;"
-  // when we need to delete an allocated object.
-  void* p = malloc(size);
-  memset(p, 0, size);
-  return p;
-}
-void* operator new[](size_t size, const Initialized&) {
-  char* p = new char[size];
-  memset(p, 0, size);
-  return p;
-}
-
-static void DoWipeStack(int n);  // defined below
-static void WipeStack() { DoWipeStack(20); }
-
-static void Pause() {
-  poll(NULL, 0, 77);  // time for thread activity in HeapBusyThreadBody
-
-  // Indirectly test malloc_extension.*:
-  CHECK(MallocExtension::instance()->VerifyAllMemory());
-  int blocks;
-  size_t total;
-  int histogram[kMallocHistogramSize];
-  if (MallocExtension::instance()
-       ->MallocMemoryStats(&blocks, &total, histogram)  &&  total != 0) {
-    VLOG(3) << "Malloc stats: " << blocks << " blocks of "
-            << total << " bytes";
-    for (int i = 0; i < kMallocHistogramSize; ++i) {
-      if (histogram[i]) {
-        VLOG(3) << "  Malloc histogram at " << i << " : " << histogram[i];
-      }
-    }
-  }
-  WipeStack();  // e.g. MallocExtension::VerifyAllMemory
-                // can leave pointers to heap objects on stack
-}
-
-// Make gcc think a pointer is "used"
-template <class T>
-static void Use(T** foo) {
-  VLOG(2) << "Dummy-using " << static_cast<void*>(*foo) << " at " << foo;
-}
-
-// Arbitrary value, but not such that xor'ing with it is likely
-// to map one valid pointer to another valid pointer:
-static const uintptr_t kHideMask =
-  static_cast<uintptr_t>(0xF03A5F7BF03A5F7BLL);
-
-// Helpers to hide a pointer from live data traversal.
-// We just xor the pointer so that (with high probability)
-// it's not a valid address of a heap object anymore.
-// Both Hide and UnHide must be executed within RunHidden() below
-// to prevent leaving stale data on active stack that can be a pointer
-// to a heap object that is not actually reachable via live variables.
-// (UnHide might leave heap pointer value for an object
-//  that will be deallocated but later another object
-//  can be allocated at the same heap address.)
-template <class T>
-static void Hide(T** ptr) {
-  // we cast values, not dereferenced pointers, so no aliasing issues:
-  *ptr = reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(*ptr) ^ kHideMask);
-  VLOG(2) << "hid: " << static_cast<void*>(*ptr);
-}
-
-template <class T>
-static void UnHide(T** ptr) {
-  VLOG(2) << "unhiding: " << static_cast<void*>(*ptr);
-  // we cast values, not dereferenced pointers, so no aliasing issues:
-  *ptr = reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(*ptr) ^ kHideMask);
-}
-
-static void LogHidden(const char* message, const void* ptr) {
-  LOGF << message << " : "
-       << ptr << " ^ " << reinterpret_cast<void*>(kHideMask) << endl;
-}
-
-// volatile to fool the compiler against inlining the calls to these
-void (*volatile run_hidden_ptr)(Closure* c, int n);
-void (*volatile wipe_stack_ptr)(int n);
-
-static void DoRunHidden(Closure* c, int n) {
-  if (n) {
-    VLOG(10) << "Level " << n << " at " << &n;
-    (*run_hidden_ptr)(c, n-1);
-    (*wipe_stack_ptr)(n);
-    sleep(0);  // undo -foptimize-sibling-calls
-  } else {
-    c->Run();
-  }
-}
-
-/*static*/ void DoWipeStack(int n) {
-  VLOG(10) << "Wipe level " << n << " at " << &n;
-  if (n) {
-    const int sz = 30;
-    volatile int arr[sz] ATTRIBUTE_UNUSED;
-    for (int i = 0; i < sz; ++i) arr[i] = 0;
-    (*wipe_stack_ptr)(n-1);
-    sleep(0);  // undo -foptimize-sibling-calls
-  }
-}
-
-// This executes closure c several stack frames down from the current one
-// and then makes an effort to also wipe out the stack data that was used by
-// the closure.
-// This way we prevent leak checker from finding any temporary pointers
-// of the closure execution on the stack and deciding that
-// these pointers (and the pointed objects) are still live.
-static void RunHidden(Closure* c) {
-  DoRunHidden(c, 15);
-  DoWipeStack(20);
-}
-
-static void DoAllocHidden(size_t size, void** ptr) {
-  void* p = new(initialized) char[size];
-  Hide(&p);
-  Use(&p);  // use only hidden versions
-  VLOG(2) << "Allocated hidden " << p << " at " << &p;
-  *ptr = p;  // assign the hidden versions
-}
-
-static void* AllocHidden(size_t size) {
-  void* r;
-  RunHidden(NewCallback(DoAllocHidden, size, &r));
-  return r;
-}
-
-static void DoDeAllocHidden(void** ptr) {
-  Use(ptr);  // use only hidden versions
-  void* p = *ptr;
-  VLOG(2) << "Deallocating hidden " << p;
-  UnHide(&p);
-  delete [] reinterpret_cast<char*>(p);
-}
-
-static void DeAllocHidden(void** ptr) {
-  RunHidden(NewCallback(DoDeAllocHidden, ptr));
-  *ptr = NULL;
-  Use(ptr);
-}
-
-void PreventHeapReclaiming(size_t size) {
-#ifdef NDEBUG
-  if (true) {
-    static void** no_reclaim_list = NULL;
-    CHECK(size >= sizeof(void*));
-    // We can't use malloc_reclaim_memory flag in opt mode as debugallocation.cc
-    // is not used. Instead we allocate a bunch of heap objects that are
-    // of the same size as what we are going to leak to ensure that the object
-    // we are about to leak is not at the same address as some old allocated
-    // and freed object that might still have pointers leading to it.
-    for (int i = 0; i < 100; ++i) {
-      void** p = reinterpret_cast<void**>(new(initialized) char[size]);
-      p[0] = no_reclaim_list;
-      no_reclaim_list = p;
-    }
-  }
-#endif
-}
-
-static bool RunSilent(HeapLeakChecker* check,
-                      bool (HeapLeakChecker::* func)()) {
-  // By default, don't print the 'we detected a leak' message in the
-  // cases we're expecting a leak (we still print when --v is >= 1).
-  // This way, the logging output is less confusing: we only print
-  // "we detected a leak", and how to diagnose it, for *unexpected* leaks.
-  int32 old_FLAGS_verbose = FLAGS_verbose;
-  if (!VLOG_IS_ON(1))             // not on a verbose setting
-    FLAGS_verbose = FATAL;        // only log fatal errors
-  const bool retval = (check->*func)();
-  FLAGS_verbose = old_FLAGS_verbose;
-  return retval;
-}
-
-#define RUN_SILENT(check, func)  RunSilent(&(check), &HeapLeakChecker::func)
-
-enum CheckType { SAME_HEAP, NO_LEAKS };
-
-static void VerifyLeaks(HeapLeakChecker* check, CheckType type,
-                        int leaked_bytes, int leaked_objects) {
-  WipeStack();  // to help with can_create_leaks_reliably
-  const bool no_leaks =
-    type == NO_LEAKS ? RUN_SILENT(*check, BriefNoLeaks)
-                     : RUN_SILENT(*check, BriefSameHeap);
-  if (can_create_leaks_reliably) {
-    // these might still fail occasionally, but it should be very rare
-    CHECK_EQ(no_leaks, false);
-    CHECK_EQ(check->BytesLeaked(), leaked_bytes);
-    CHECK_EQ(check->ObjectsLeaked(), leaked_objects);
-  } else {
-    WARN_IF(no_leaks != false,
-            "Expected leaks not found: "
-            "Some liveness flood must be too optimistic");
-  }
-}
-
-// not deallocates
-static void TestHeapLeakCheckerDeathSimple() {
-  HeapLeakChecker check("death_simple");
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  void* bar = AllocHidden(300);
-  Use(&bar);
-  LogHidden("Leaking", foo);
-  LogHidden("Leaking", bar);
-  Pause();
-  VerifyLeaks(&check, NO_LEAKS, 300 + 100 * sizeof(int), 2);
-  DeAllocHidden(&foo);
-  DeAllocHidden(&bar);
-}
-
-static void MakeDeathLoop(void** arr1, void** arr2) {
-  PreventHeapReclaiming(2 * sizeof(void*));
-  void** a1 = new(initialized) void*[2];
-  void** a2 = new(initialized) void*[2];
-  a1[1] = reinterpret_cast<void*>(a2);
-  a2[1] = reinterpret_cast<void*>(a1);
-  Hide(&a1);
-  Hide(&a2);
-  Use(&a1);
-  Use(&a2);
-  VLOG(2) << "Made hidden loop at " << &a1 << " to " << arr1;
-  *arr1 = a1;
-  *arr2 = a2;
-}
-
-// not deallocates two objects linked together
-static void TestHeapLeakCheckerDeathLoop() {
-  HeapLeakChecker check("death_loop");
-  void* arr1;
-  void* arr2;
-  RunHidden(NewCallback(MakeDeathLoop, &arr1, &arr2));
-  Use(&arr1);
-  Use(&arr2);
-  LogHidden("Leaking", arr1);
-  LogHidden("Leaking", arr2);
-  Pause();
-  VerifyLeaks(&check, NO_LEAKS, 4 * sizeof(void*), 2);
-  DeAllocHidden(&arr1);
-  DeAllocHidden(&arr2);
-}
-
-// deallocates more than allocates
-static void TestHeapLeakCheckerDeathInverse() {
-  void* bar = AllocHidden(250 * sizeof(int));
-  Use(&bar);
-  LogHidden("Pre leaking", bar);
-  Pause();
-  HeapLeakChecker check("death_inverse");
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  LogHidden("Leaking", foo);
-  DeAllocHidden(&bar);
-  Pause();
-  VerifyLeaks(&check, SAME_HEAP,
-              100 * static_cast<int64>(sizeof(int)),
-              1);
-  DeAllocHidden(&foo);
-}
-
-// deallocates more than allocates
-static void TestHeapLeakCheckerDeathNoLeaks() {
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  void* bar = AllocHidden(250 * sizeof(int));
-  Use(&bar);
-  HeapLeakChecker check("death_noleaks");
-  DeAllocHidden(&bar);
-  CHECK_EQ(check.BriefNoLeaks(), true);
-  DeAllocHidden(&foo);
-}
-
-// have less objecs
-static void TestHeapLeakCheckerDeathCountLess() {
-  void* bar1 = AllocHidden(50 * sizeof(int));
-  Use(&bar1);
-  void* bar2 = AllocHidden(50 * sizeof(int));
-  Use(&bar2);
-  LogHidden("Pre leaking", bar1);
-  LogHidden("Pre leaking", bar2);
-  Pause();
-  HeapLeakChecker check("death_count_less");
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  LogHidden("Leaking", foo);
-  DeAllocHidden(&bar1);
-  DeAllocHidden(&bar2);
-  Pause();
-  VerifyLeaks(&check, SAME_HEAP,
-              100 * sizeof(int),
-              1);
-  DeAllocHidden(&foo);
-}
-
-// have more objecs
-static void TestHeapLeakCheckerDeathCountMore() {
-  void* foo = AllocHidden(100 * sizeof(int));
-  Use(&foo);
-  LogHidden("Pre leaking", foo);
-  Pause();
-  HeapLeakChecker check("death_count_more");
-  void* bar1 = AllocHidden(50 * sizeof(int));
-  Use(&bar1);
-  void* bar2 = AllocHidden(50 * sizeof(int));
-  Use(&bar2);
-  LogHidden("Leaking", bar1);
-  LogHidden("Leaking", bar2);
-  DeAllocHidden(&foo);
-  Pause();
-  VerifyLeaks(&check, SAME_HEAP,
-              100 * sizeof(int),
-              2);
-  DeAllocHidden(&bar1);
-  DeAllocHidden(&bar2);
-}
-
-static void TestHiddenPointer() {
-  int i;
-  void* foo = &i;
-  HiddenPointer<void> p(foo);
-  CHECK_EQ(foo, p.get());
-
-  // Confirm pointer doesn't appear to contain a byte sequence
-  // that == the pointer.  We don't really need to test that
-  // the xor trick itself works, as without it nothing in this
-  // test suite would work.  See the Hide/Unhide/*Hidden* set
-  // of helper methods.
-  void **pvoid = reinterpret_cast<void**>(&p);
-  CHECK_NE(foo, *pvoid);
-}
-
-// simple tests that deallocate what they allocated
-static void TestHeapLeakChecker() {
-  { HeapLeakChecker check("trivial");
-    int foo = 5;
-    int* p = &foo;
-    Use(&p);
-    Pause();
-    CHECK(check.BriefSameHeap());
-  }
-  Pause();
-  { HeapLeakChecker check("simple");
-    void* foo = AllocHidden(100 * sizeof(int));
-    Use(&foo);
-    void* bar = AllocHidden(200 * sizeof(int));
-    Use(&bar);
-    DeAllocHidden(&foo);
-    DeAllocHidden(&bar);
-    Pause();
-    CHECK(check.BriefSameHeap());
-  }
-}
-
-// no false positives
-static void TestHeapLeakCheckerNoFalsePositives() {
-  { HeapLeakChecker check("trivial_p");
-    int foo = 5;
-    int* p = &foo;
-    Use(&p);
-    Pause();
-    CHECK(check.BriefSameHeap());
-  }
-  Pause();
-  { HeapLeakChecker check("simple_p");
-    void* foo = AllocHidden(100 * sizeof(int));
-    Use(&foo);
-    void* bar = AllocHidden(200 * sizeof(int));
-    Use(&bar);
-    DeAllocHidden(&foo);
-    DeAllocHidden(&bar);
-    Pause();
-    CHECK(check.SameHeap());
-  }
-}
-
-// test that we detect leaks when we have same total # of bytes and
-// objects, but different individual object sizes
-static void TestLeakButTotalsMatch() {
-  void* bar1 = AllocHidden(240 * sizeof(int));
-  Use(&bar1);
-  void* bar2 = AllocHidden(160 * sizeof(int));
-  Use(&bar2);
-  LogHidden("Pre leaking", bar1);
-  LogHidden("Pre leaking", bar2);
-  Pause();
-  HeapLeakChecker check("trick");
-  void* foo1 = AllocHidden(280 * sizeof(int));
-  Use(&foo1);
-  void* foo2 = AllocHidden(120 * sizeof(int));
-  Use(&foo2);
-  LogHidden("Leaking", foo1);
-  LogHidden("Leaking", foo2);
-  DeAllocHidden(&bar1);
-  DeAllocHidden(&bar2);
-  Pause();
-
-  // foo1 and foo2 leaked
-  VerifyLeaks(&check, NO_LEAKS, (280+120)*sizeof(int), 2);
-
-  DeAllocHidden(&foo1);
-  DeAllocHidden(&foo2);
-}
-
-// no false negatives from pprof
-static void TestHeapLeakCheckerDeathTrick() {
-  void* bar1 = AllocHidden(240 * sizeof(int));
-  Use(&bar1);
-  void* bar2 = AllocHidden(160 * sizeof(int));
-  Use(&bar2);
-  HeapLeakChecker check("death_trick");
-  DeAllocHidden(&bar1);
-  DeAllocHidden(&bar2);
-  void* foo1 = AllocHidden(280 * sizeof(int));
-  Use(&foo1);
-  void* foo2 = AllocHidden(120 * sizeof(int));
-  Use(&foo2);
-  // TODO(maxim): use the above if we make pprof work in automated test runs
-  if (!FLAGS_maybe_stripped) {
-    CHECK_EQ(RUN_SILENT(check, SameHeap), false);
-      // pprof checking should catch the leak
-  } else {
-    WARN_IF(RUN_SILENT(check, SameHeap) != false,
-            "death_trick leak is not caught; "
-            "we must be using a stripped binary");
-  }
-  DeAllocHidden(&foo1);
-  DeAllocHidden(&foo2);
-}
-
-// simple leak
-static void TransLeaks() {
-  AllocHidden(1 * sizeof(char));
-}
-
-// range-based disabling using Disabler
-static void ScopedDisabledLeaks() {
-  HeapLeakChecker::Disabler disabler;
-  AllocHidden(3 * sizeof(int));
-  TransLeaks();
-  (void)malloc(10);  // Direct leak
-}
-
-// have different disabled leaks
-static void* RunDisabledLeaks(void* a) {
-  ScopedDisabledLeaks();
-  return a;
-}
-
-// have different disabled leaks inside of a thread
-static void ThreadDisabledLeaks() {
-  if (FLAGS_no_threads)  return;
-  pthread_t tid;
-  pthread_attr_t attr;
-  CHECK_EQ(pthread_attr_init(&attr), 0);
-  CHECK_EQ(pthread_create(&tid, &attr, RunDisabledLeaks, NULL), 0);
-  void* res;
-  CHECK_EQ(pthread_join(tid, &res), 0);
-}
-
-// different disabled leaks (some in threads)
-static void TestHeapLeakCheckerDisabling() {
-  HeapLeakChecker check("disabling");
-
-  RunDisabledLeaks(NULL);
-  RunDisabledLeaks(NULL);
-  ThreadDisabledLeaks();
-  RunDisabledLeaks(NULL);
-  ThreadDisabledLeaks();
-  ThreadDisabledLeaks();
-
-  Pause();
-
-  CHECK(check.SameHeap());
-}
-
-typedef set<int> IntSet;
-
-static int some_ints[] = { 1, 2, 3, 21, 22, 23, 24, 25 };
-
-static void DoTestSTLAlloc() {
-  IntSet* x = new(initialized) IntSet[1];
-  *x = IntSet(some_ints, some_ints + 6);
-  for (int i = 0; i < 1000; i++) {
-    x->insert(i*3);
-  }
-  delete [] x;
-}
-
-// Check that normal STL usage does not result in a leak report.
-// (In particular we test that there's no complex STL's own allocator
-// running on top of our allocator with hooks to heap profiler
-// that can result in false leak report in this case.)
-static void TestSTLAlloc() {
-  HeapLeakChecker check("stl");
-  RunHidden(NewCallback(DoTestSTLAlloc));
-  CHECK_EQ(check.BriefSameHeap(), true);
-}
-
-static void DoTestSTLAllocInverse(IntSet** setx) {
-  IntSet* x = new(initialized) IntSet[1];
-  *x = IntSet(some_ints, some_ints + 3);
-  for (int i = 0; i < 100; i++) {
-    x->insert(i*2);
-  }
-  Hide(&x);
-  *setx = x;
-}
-
-static void FreeTestSTLAllocInverse(IntSet** setx) {
-  IntSet* x = *setx;
-  UnHide(&x);
-  delete [] x;
-}
-
-// Check that normal leaked STL usage *does* result in a leak report.
-// (In particular we test that there's no complex STL's own allocator
-// running on top of our allocator with hooks to heap profiler
-// that can result in false absence of leak report in this case.)
-static void TestSTLAllocInverse() {
-  HeapLeakChecker check("death_inverse_stl");
-  IntSet* x;
-  RunHidden(NewCallback(DoTestSTLAllocInverse, &x));
-  LogHidden("Leaking", x);
-  if (can_create_leaks_reliably) {
-    WipeStack();  // to help with can_create_leaks_reliably
-    // these might still fail occasionally, but it should be very rare
-    CHECK_EQ(RUN_SILENT(check, BriefNoLeaks), false);
-    CHECK_GE(check.BytesLeaked(), 100 * sizeof(int));
-    CHECK_GE(check.ObjectsLeaked(), 100);
-      // assumes set<>s are represented by some kind of binary tree
-      // or something else allocating >=1 heap object per set object
-  } else {
-    WARN_IF(RUN_SILENT(check, BriefNoLeaks) != false,
-            "Expected leaks not found: "
-            "Some liveness flood must be too optimistic");
-  }
-  RunHidden(NewCallback(FreeTestSTLAllocInverse, &x));
-}
-
-template<class Alloc>
-static void DirectTestSTLAlloc(Alloc allocator, const char* name) {
-  HeapLeakChecker check((string("direct_stl-") + name).c_str());
-  static const int kSize = 1000;
-  typename Alloc::pointer ptrs[kSize];
-  for (int i = 0; i < kSize; ++i) {
-    typename Alloc::pointer p = allocator.allocate(i*3+1);
-    HeapLeakChecker::IgnoreObject(p);
-    // This will crash if p is not known to heap profiler:
-    // (i.e. STL's "allocator" does not have a direct hook to heap profiler)
-    HeapLeakChecker::UnIgnoreObject(p);
-    ptrs[i] = p;
-  }
-  for (int i = 0; i < kSize; ++i) {
-    allocator.deallocate(ptrs[i], i*3+1);
-    ptrs[i] = NULL;
-  }
-  CHECK(check.BriefSameHeap());  // just in case
-}
-
-static struct group* grp = NULL;
-static const int kKeys = 50;
-static pthread_key_t key[kKeys];
-
-static void KeyFree(void* ptr) {
-  delete [] reinterpret_cast<char*>(ptr);
-}
-
-static bool key_init_has_run = false;
-
-static void KeyInit() {
-  for (int i = 0; i < kKeys; ++i) {
-    CHECK_EQ(pthread_key_create(&key[i], KeyFree), 0);
-    VLOG(2) << "pthread key " << i << " : " << key[i];
-  }
-  key_init_has_run = true;   // needed for a sanity-check
-}
-
-// force various C library static and thread-specific allocations
-static void TestLibCAllocate() {
-  CHECK(key_init_has_run);
-  for (int i = 0; i < kKeys; ++i) {
-    void* p = pthread_getspecific(key[i]);
-    if (NULL == p) {
-      if (i == 0) {
-        // Test-logging inside threads which (potentially) creates and uses
-        // thread-local data inside standard C++ library:
-        VLOG(0) << "Adding pthread-specifics for thread " << pthread_self()
-                << " pid " << getpid();
-      }
-      p = new(initialized) char[77 + i];
-      VLOG(2) << "pthread specific " << i << " : " << p;
-      pthread_setspecific(key[i], p);
-    }
-  }
-
-  strerror(errno);
-  const time_t now = time(NULL);
-  ctime(&now);
-#ifdef HAVE_EXECINFO_H
-  void *stack[1];
-  backtrace(stack, 1);
-#endif
-#ifdef HAVE_GRP_H
-  gid_t gid = getgid();
-  getgrgid(gid);
-  if (grp == NULL)  grp = getgrent();  // a race condition here is okay
-  getgrnam(grp->gr_name);
-#endif
-#ifdef HAVE_PWD_H
-  getpwuid(geteuid());
-#endif
-}
-
-// Continuous random heap memory activity to try to disrupt heap checking.
-static void* HeapBusyThreadBody(void* a) {
-  const int thread_num = reinterpret_cast<intptr_t>(a);
-  VLOG(0) << "A new HeapBusyThread " << thread_num;
-  TestLibCAllocate();
-
-  int user = 0;
-  // Try to hide ptr from heap checker in a CPU register:
-  // Here we are just making a best effort to put the only pointer
-  // to a heap object into a thread register to test
-  // the thread-register finding machinery in the heap checker.
-#if defined(__i386__) && defined(__GNUC__)
-  register int** ptr asm("esi");
-#elif defined(__x86_64__) && defined(__GNUC__)
-  register int** ptr asm("r15");
-#else
-  register int** ptr;
-#endif
-  ptr = NULL;
-  typedef set<int> Set;
-  Set s1;
-  while (1) {
-    // TestLibCAllocate() calls libc functions that don't work so well
-    // after main() has exited.  So we just don't do the test then.
-    if (!g_have_exited_main)
-      TestLibCAllocate();
-
-    if (ptr == NULL) {
-      ptr = new(initialized) int*[1];
-      *ptr = new(initialized) int[1];
-    }
-    set<int>* s2 = new(initialized) set<int>[1];
-    s1.insert(random());
-    s2->insert(*s1.begin());
-    user += *s2->begin();
-    **ptr += user;
-    if (random() % 51 == 0) {
-      s1.clear();
-      if (random() % 2 == 0) {
-        s1.~Set();
-        new(&s1) Set;
-      }
-    }
-    VLOG(3) << pthread_self() << " (" << getpid() << "): in wait: "
-            << ptr << ", " << *ptr << "; " << s1.size();
-    VLOG(2) << pthread_self() << " (" << getpid() << "): in wait, ptr = "
-            << reinterpret_cast<void*>(
-                 reinterpret_cast<uintptr_t>(ptr) ^ kHideMask)
-            << "^" << reinterpret_cast<void*>(kHideMask);
-    if (FLAGS_test_register_leak  &&  thread_num % 5 == 0) {
-      // Hide the register "ptr" value with an xor mask.
-      // If one provides --test_register_leak flag, the test should
-      // (with very high probability) crash on some leak check
-      // with a leak report (of some x * sizeof(int) + y * sizeof(int*) bytes)
-      // pointing at the two lines above in this function
-      // with "new(initialized) int" in them as the allocators
-      // of the leaked objects.
-      // CAVEAT: We can't really prevent a compiler to save some
-      // temporary values of "ptr" on the stack and thus let us find
-      // the heap objects not via the register.
-      // Hence it's normal if for certain compilers or optimization modes
-      // --test_register_leak does not cause a leak crash of the above form
-      // (this happens e.g. for gcc 4.0.1 in opt mode).
-      ptr = reinterpret_cast<int **>(
-          reinterpret_cast<uintptr_t>(ptr) ^ kHideMask);
-      // busy loop to get the thread interrupted at:
-      for (int i = 1; i < 10000000; ++i)  user += (1 + user * user * 5) / i;
-      ptr = reinterpret_cast<int **>(
-          reinterpret_cast<uintptr_t>(ptr) ^ kHideMask);
-    } else {
-      poll(NULL, 0, random() % 100);
-    }
-    VLOG(2) << pthread_self() << ": continuing";
-    if (random() % 3 == 0) {
-      delete [] *ptr;
-      delete [] ptr;
-      ptr = NULL;
-    }
-    delete [] s2;
-  }
-  return a;
-}
-
-static void RunHeapBusyThreads() {
-  KeyInit();
-  if (!FLAGS_interfering_threads || FLAGS_no_threads)  return;
-
-  const int n = 17;  // make many threads
-
-  pthread_t tid;
-  pthread_attr_t attr;
-  CHECK_EQ(pthread_attr_init(&attr), 0);
-  // make them and let them run
-  for (int i = 0; i < n; ++i) {
-    VLOG(0) << "Creating extra thread " << i + 1;
-    CHECK(pthread_create(&tid, &attr, HeapBusyThreadBody,
-                         reinterpret_cast<void*>(i)) == 0);
-  }
-
-  Pause();
-  Pause();
-}
-
-// ========================================================================= //
-
-// This code section is to test that objects that are reachable from global
-// variables are not reported as leaks
-// as well as that (Un)IgnoreObject work for such objects fine.
-
-// An object making functions:
-// returns a "weird" pointer to a new object for which
-// it's worth checking that the object is reachable via that pointer.
-typedef void* (*ObjMakerFunc)();
-static list<ObjMakerFunc> obj_makers;  // list of registered object makers
-
-// Helper macro to register an object making function
-// 'name' is an identifier of this object maker,
-// 'body' is its function body that must declare
-//        pointer 'p' to the nex object to return.
-// Usage example:
-//   REGISTER_OBJ_MAKER(trivial, int* p = new(initialized) int;)
-#define REGISTER_OBJ_MAKER(name, body) \
-  void* ObjMaker_##name##_() { \
-    VLOG(1) << "Obj making " << #name; \
-    body; \
-    return p; \
-  } \
-  static ObjMakerRegistrar maker_reg_##name##__(&ObjMaker_##name##_);
-// helper class for REGISTER_OBJ_MAKER
-struct ObjMakerRegistrar {
-  ObjMakerRegistrar(ObjMakerFunc obj_maker) { obj_makers.push_back(obj_maker); }
-};
-
-// List of the objects/pointers made with all the obj_makers
-// to test reachability via global data pointers during leak checks.
-static list<void*>* live_objects = new list<void*>;
-  // pointer so that it does not get destructed on exit
-
-// Exerciser for one ObjMakerFunc.
-static void TestPointerReach(ObjMakerFunc obj_maker) {
-  HeapLeakChecker::IgnoreObject(obj_maker());  // test IgnoreObject
-
-  void* obj = obj_maker();
-  HeapLeakChecker::IgnoreObject(obj);
-  HeapLeakChecker::UnIgnoreObject(obj);  // test UnIgnoreObject
-  HeapLeakChecker::IgnoreObject(obj);  // not to need deletion for obj
-
-  live_objects->push_back(obj_maker());  // test reachability at leak check
-}
-
-// Test all ObjMakerFunc registred via REGISTER_OBJ_MAKER.
-static void TestObjMakers() {
-  for (list<ObjMakerFunc>::const_iterator i = obj_makers.begin();
-       i != obj_makers.end(); ++i) {
-    TestPointerReach(*i);
-    TestPointerReach(*i);  // a couple more times would not hurt
-    TestPointerReach(*i);
-  }
-}
-
-// A dummy class to mimic allocation behavior of string-s.
-template<class T>
-struct Array {
-  Array() {
-    size = 3 + random() % 30;
-    ptr = new(initialized) T[size];
-  }
-  ~Array() { delete [] ptr; }
-  Array(const Array& x) {
-    size = x.size;
-    ptr = new(initialized) T[size];
-    for (size_t i = 0; i < size; ++i) {
-      ptr[i] = x.ptr[i];
-    }
-  }
-  void operator=(const Array& x) {
-    delete [] ptr;
-    size = x.size;
-    ptr = new(initialized) T[size];
-    for (size_t i = 0; i < size; ++i) {
-      ptr[i] = x.ptr[i];
-    }
-  }
-  void append(const Array& x) {
-    T* p = new(initialized) T[size + x.size];
-    for (size_t i = 0; i < size; ++i) {
-      p[i] = ptr[i];
-    }
-    for (size_t i = 0; i < x.size; ++i) {
-      p[size+i] = x.ptr[i];
-    }
-    size += x.size;
-    delete [] ptr;
-    ptr = p;
-  }
- private:
-  size_t size;
-  T* ptr;
-};
-
-// to test pointers to objects, built-in arrays, string, etc:
-REGISTER_OBJ_MAKER(plain, int* p = new(initialized) int;)
-REGISTER_OBJ_MAKER(int_array_1, int* p = new(initialized) int[1];)
-REGISTER_OBJ_MAKER(int_array, int* p = new(initialized) int[10];)
-REGISTER_OBJ_MAKER(string, Array<char>* p = new(initialized) Array<char>();)
-REGISTER_OBJ_MAKER(string_array,
-                   Array<char>* p = new(initialized) Array<char>[5];)
-REGISTER_OBJ_MAKER(char_array, char* p = new(initialized) char[5];)
-REGISTER_OBJ_MAKER(appended_string,
-  Array<char>* p = new Array<char>();
-  p->append(Array<char>());
-)
-REGISTER_OBJ_MAKER(plain_ptr, int** p = new(initialized) int*;)
-REGISTER_OBJ_MAKER(linking_ptr,
-  int** p = new(initialized) int*;
-  *p = new(initialized) int;
-)
-
-// small objects:
-REGISTER_OBJ_MAKER(0_sized, void* p = malloc(0);)  // 0-sized object (important)
-REGISTER_OBJ_MAKER(1_sized, void* p = malloc(1);)
-REGISTER_OBJ_MAKER(2_sized, void* p = malloc(2);)
-REGISTER_OBJ_MAKER(3_sized, void* p = malloc(3);)
-REGISTER_OBJ_MAKER(4_sized, void* p = malloc(4);)
-
-static int set_data[] = { 1, 2, 3, 4, 5, 6, 7, 21, 22, 23, 24, 25, 26, 27 };
-static set<int> live_leak_set(set_data, set_data+7);
-static const set<int> live_leak_const_set(set_data, set_data+14);
-
-REGISTER_OBJ_MAKER(set,
-  set<int>* p = new(initialized) set<int>(set_data, set_data + 13);
-)
-
-class ClassA {
- public:
-  explicit ClassA(int a) : ptr(NULL) { }
-  mutable char* ptr;
-};
-static const ClassA live_leak_mutable(1);
-
-template<class C>
-class TClass {
- public:
-  explicit TClass(int a) : ptr(NULL) { }
-  mutable C val;
-  mutable C* ptr;
-};
-static const TClass<Array<char> > live_leak_templ_mutable(1);
-
-class ClassB {
- public:
-  ClassB() { }
-  char b[7];
-  virtual void f() { }
-  virtual ~ClassB() { }
-};
-
-class ClassB2 {
- public:
-  ClassB2() { }
-  char b2[11];
-  virtual void f2() { }
-  virtual ~ClassB2() { }
-};
-
-class ClassD1 : public ClassB {
-  char d1[15];
-  virtual void f() { }
-};
-
-class ClassD2 : public ClassB2 {
-  char d2[19];
-  virtual void f2() { }
-};
-
-class ClassD : public ClassD1, public ClassD2 {
-  char d[3];
-  virtual void f() { }
-  virtual void f2() { }
-};
-
-// to test pointers to objects of base subclasses:
-
-REGISTER_OBJ_MAKER(B,  ClassB*  p = new(initialized) ClassB;)
-REGISTER_OBJ_MAKER(D1, ClassD1* p = new(initialized) ClassD1;)
-REGISTER_OBJ_MAKER(D2, ClassD2* p = new(initialized) ClassD2;)
-REGISTER_OBJ_MAKER(D,  ClassD*  p = new(initialized) ClassD;)
-
-REGISTER_OBJ_MAKER(D1_as_B,  ClassB*  p = new(initialized) ClassD1;)
-REGISTER_OBJ_MAKER(D2_as_B2, ClassB2* p = new(initialized) ClassD2;)
-REGISTER_OBJ_MAKER(D_as_B,   ClassB*  p = new(initialized)  ClassD;)
-REGISTER_OBJ_MAKER(D_as_D1,  ClassD1* p = new(initialized) ClassD;)
-// inside-object pointers:
-REGISTER_OBJ_MAKER(D_as_B2,  ClassB2* p = new(initialized) ClassD;)
-REGISTER_OBJ_MAKER(D_as_D2,  ClassD2* p = new(initialized) ClassD;)
-
-class InterfaceA {
- public:
-  virtual void A() = 0;
-  virtual ~InterfaceA() { }
- protected:
-  InterfaceA() { }
-};
-
-class InterfaceB {
- public:
-  virtual void B() = 0;
-  virtual ~InterfaceB() { }
- protected:
-  InterfaceB() { }
-};
-
-class InterfaceC : public InterfaceA {
- public:
-  virtual void C() = 0;
-  virtual ~InterfaceC() { }
- protected:
-  InterfaceC() { }
-};
-
-class ClassMltD1 : public ClassB, public InterfaceB, public InterfaceC {
- public:
-  char d1[11];
-  virtual void f() { }
-  virtual void A() { }
-  virtual void B() { }
-  virtual void C() { }
-};
-
-class ClassMltD2 : public InterfaceA, public InterfaceB, public ClassB {
- public:
-  char d2[15];
-  virtual void f() { }
-  virtual void A() { }
-  virtual void B() { }
-};
-
-// to specifically test heap reachability under
-// inerface-only multiple inheritance (some use inside-object pointers):
-REGISTER_OBJ_MAKER(MltD1,       ClassMltD1* p = new(initialized) ClassMltD1;)
-REGISTER_OBJ_MAKER(MltD1_as_B,  ClassB*     p = new(initialized) ClassMltD1;)
-REGISTER_OBJ_MAKER(MltD1_as_IA, InterfaceA* p = new(initialized) ClassMltD1;)
-REGISTER_OBJ_MAKER(MltD1_as_IB, InterfaceB* p = new(initialized) ClassMltD1;)
-REGISTER_OBJ_MAKER(MltD1_as_IC, InterfaceC* p = new(initialized) ClassMltD1;)
-
-REGISTER_OBJ_MAKER(MltD2,       ClassMltD2* p = new(initialized) ClassMltD2;)
-REGISTER_OBJ_MAKER(MltD2_as_B,  ClassB*     p = new(initialized) ClassMltD2;)
-REGISTER_OBJ_MAKER(MltD2_as_IA, InterfaceA* p = new(initialized) ClassMltD2;)
-REGISTER_OBJ_MAKER(MltD2_as_IB, InterfaceB* p = new(initialized) ClassMltD2;)
-
-// to mimic UnicodeString defined in third_party/icu,
-// which store a platform-independent-sized refcount in the first
-// few bytes and keeps a pointer pointing behind the refcount.
-REGISTER_OBJ_MAKER(unicode_string,
-  char* p = new char[sizeof(uint32) * 10];
-  p += sizeof(uint32);
-)
-// similar, but for platform-dependent-sized refcount
-REGISTER_OBJ_MAKER(ref_counted,
-  char* p = new char[sizeof(int) * 20];
-  p += sizeof(int);
-)
-
-struct Nesting {
-  struct Inner {
-    Nesting* parent;
-    Inner(Nesting* p) : parent(p) {}
-  };
-  Inner i0;
-  char n1[5];
-  Inner i1;
-  char n2[11];
-  Inner i2;
-  char n3[27];
-  Inner i3;
-  Nesting() : i0(this), i1(this), i2(this), i3(this) {}
-};
-
-// to test inside-object pointers pointing at objects nested into heap objects:
-REGISTER_OBJ_MAKER(nesting_i0, Nesting::Inner* p = &((new Nesting())->i0);)
-REGISTER_OBJ_MAKER(nesting_i1, Nesting::Inner* p = &((new Nesting())->i1);)
-REGISTER_OBJ_MAKER(nesting_i2, Nesting::Inner* p = &((new Nesting())->i2);)
-REGISTER_OBJ_MAKER(nesting_i3, Nesting::Inner* p = &((new Nesting())->i3);)
-
-void (* volatile init_forcer)(...);
-
-// allocate many objects reachable from global data
-static void TestHeapLeakCheckerLiveness() {
-  live_leak_mutable.ptr = new(initialized) char[77];
-  live_leak_templ_mutable.ptr = new(initialized) Array<char>();
-  live_leak_templ_mutable.val = Array<char>();
-
-  // smart compiler may see that live_leak_mutable is not used
-  // anywhere so .ptr assignment is not used.
-  //
-  // We force compiler to assume that it is used by having function
-  // variable (set to 0 which hopefully won't be known to compiler)
-  // which gets address of those objects. So compiler has to assume
-  // that .ptr is used.
-  if (init_forcer) {
-    init_forcer(&live_leak_mutable, &live_leak_templ_mutable);
-  }
-  TestObjMakers();
-}
-
-// ========================================================================= //
-
-// Get address (PC value) following the mmap call into addr_after_mmap_call
-static void* Mmapper(uintptr_t* addr_after_mmap_call) {
-  void* r = mmap(NULL, 100, PROT_READ|PROT_WRITE,
-                 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-  // Get current PC value into addr_after_mmap_call
-  void* stack[1];
-  CHECK_EQ(GetStackTrace(stack, 1, 0), 1);
-  *addr_after_mmap_call = reinterpret_cast<uintptr_t>(stack[0]);
-  sleep(0);  // undo -foptimize-sibling-calls
-  return r;
-}
-
-// On PPC64 the stacktrace returned by GetStatcTrace contains the function
-// address from .text segment while function pointers points to ODP entries.
-// The following code decodes the ODP to get the actual symbol address.
-#if defined(__linux) && defined(__PPC64__) && (_CALL_ELF != 2)
-static inline uintptr_t GetFunctionAddress (void* (*func)(uintptr_t*))
-{
-  struct odp_entry_t {
-    unsigned long int symbol;
-    unsigned long int toc;
-    unsigned long int env;
-  } *odp_entry = reinterpret_cast<odp_entry_t*>(func);
-
-  return static_cast<uintptr_t>(odp_entry->symbol);
-}
-#else
-static inline uintptr_t GetFunctionAddress (void* (*func)(uintptr_t*))
-{
-  return reinterpret_cast<uintptr_t>(func);
-}
-#endif
-
-// to trick complier into preventing inlining
-static void* (*mmapper_addr)(uintptr_t* addr) = &Mmapper;
-
-// TODO(maxim): copy/move this to memory_region_map_unittest
-// TODO(maxim): expand this test to include mmap64, mremap and sbrk calls.
-static void VerifyMemoryRegionMapStackGet() {
-  uintptr_t caller_addr_limit;
-  void* addr = (*mmapper_addr)(&caller_addr_limit);
-  uintptr_t caller = 0;
-  { MemoryRegionMap::LockHolder l;
-    for (MemoryRegionMap::RegionIterator
-           i = MemoryRegionMap::BeginRegionLocked();
-           i != MemoryRegionMap::EndRegionLocked(); ++i) {
-      if (i->start_addr == reinterpret_cast<uintptr_t>(addr)) {
-        CHECK_EQ(caller, 0);
-        caller = i->caller();
-      }
-    }
-  }
-  // caller must point into Mmapper function:
-  if (!(GetFunctionAddress(mmapper_addr) <= caller  &&
-        caller < caller_addr_limit)) {
-    LOGF << std::hex << "0x" << caller
-         << " does not seem to point into code of function Mmapper at "
-         << "0x" << reinterpret_cast<uintptr_t>(mmapper_addr)
-         << "! Stack frame collection must be off in MemoryRegionMap!";
-    LOG(FATAL, "\n");
-  }
-  munmap(addr, 100);
-}
-
-static void* Mallocer(uintptr_t* addr_after_malloc_call) {
-  void* r = malloc(100);
-  sleep(0);  // undo -foptimize-sibling-calls
-  // Get current PC value into addr_after_malloc_call
-  void* stack[1];
-  CHECK_EQ(GetStackTrace(stack, 1, 0), 1);
-  *addr_after_malloc_call = reinterpret_cast<uintptr_t>(stack[0]);
-  return r;
-}
-
-// to trick compiler into preventing inlining
-static void* (* volatile mallocer_addr)(uintptr_t* addr) = &Mallocer;
-
-// non-static for friendship with HeapProfiler
-// TODO(maxim): expand this test to include
-// realloc, calloc, memalign, valloc, pvalloc, new, and new[].
-extern void VerifyHeapProfileTableStackGet() {
-  uintptr_t caller_addr_limit;
-  void* addr = (*mallocer_addr)(&caller_addr_limit);
-  uintptr_t caller =
-    reinterpret_cast<uintptr_t>(HeapLeakChecker::GetAllocCaller(addr));
-  // caller must point into Mallocer function:
-  if (!(GetFunctionAddress(mallocer_addr) <= caller  &&
-        caller < caller_addr_limit)) {
-    LOGF << std::hex << "0x" << caller
-         << " does not seem to point into code of function Mallocer at "
-         << "0x" << reinterpret_cast<uintptr_t>(mallocer_addr)
-         << "! Stack frame collection must be off in heap profiler!";
-    LOG(FATAL, "\n");
-  }
-  free(addr);
-}
-
-// ========================================================================= //
-
-static void MakeALeak(void** arr) {
-  PreventHeapReclaiming(10 * sizeof(int));
-  void* a = new(initialized) int[10];
-  Hide(&a);
-  *arr = a;
-}
-
-// Helper to do 'return 0;' inside main(): insted we do 'return Pass();'
-static int Pass() {
-  fprintf(stdout, "PASS\n");
-  g_have_exited_main = true;
-  return 0;
-}
-
-int main(int argc, char** argv) {
-  run_hidden_ptr = DoRunHidden;
-  wipe_stack_ptr = DoWipeStack;
-  if (!HeapLeakChecker::IsActive()) {
-    CHECK_EQ(FLAGS_heap_check, "");
-    LOG(WARNING, "HeapLeakChecker got turned off; we won't test much...");
-  } else {
-    VerifyMemoryRegionMapStackGet();
-    VerifyHeapProfileTableStackGet();
-  }
-
-  KeyInit();
-
-  // glibc 2.4, on x86_64 at least, has a lock-ordering bug, which
-  // means deadlock is possible when one thread calls dl_open at the
-  // same time another thread is calling dl_iterate_phdr.  libunwind
-  // calls dl_iterate_phdr, and TestLibCAllocate calls dl_open (or the
-  // various syscalls in it do), at least the first time it's run.
-  // To avoid the deadlock, we run TestLibCAllocate once before getting
-  // multi-threaded.
-  // TODO(csilvers): once libc is fixed, or libunwind can work around it,
-  //                 get rid of this early call.  We *want* our test to
-  //                 find potential problems like this one!
-  TestLibCAllocate();
-
-  if (FLAGS_interfering_threads) {
-    RunHeapBusyThreads();  // add interference early
-  }
-  TestLibCAllocate();
-
-  LOGF << "In main(): heap_check=" << FLAGS_heap_check << endl;
-
-  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good
-
-  if (FLAGS_test_leak) {
-    void* arr;
-    RunHidden(NewCallback(MakeALeak, &arr));
-    Use(&arr);
-    LogHidden("Leaking", arr);
-    if (FLAGS_test_cancel_global_check) {
-      HeapLeakChecker::CancelGlobalCheck();
-    } else {
-      // Verify we can call NoGlobalLeaks repeatedly without deadlocking
-      HeapLeakChecker::NoGlobalLeaks();
-      HeapLeakChecker::NoGlobalLeaks();
-    }
-    return Pass();
-      // whole-program leak-check should (with very high probability)
-      // catch the leak of arr (10 * sizeof(int) bytes)
-      // (when !FLAGS_test_cancel_global_check)
-  }
-
-  if (FLAGS_test_loop_leak) {
-    void* arr1;
-    void* arr2;
-    RunHidden(NewCallback(MakeDeathLoop, &arr1, &arr2));
-    Use(&arr1);
-    Use(&arr2);
-    LogHidden("Loop leaking", arr1);
-    LogHidden("Loop leaking", arr2);
-    if (FLAGS_test_cancel_global_check) {
-      HeapLeakChecker::CancelGlobalCheck();
-    } else {
-      // Verify we can call NoGlobalLeaks repeatedly without deadlocking
-      HeapLeakChecker::NoGlobalLeaks();
-      HeapLeakChecker::NoGlobalLeaks();
-    }
-    return Pass();
-      // whole-program leak-check should (with very high probability)
-      // catch the leak of arr1 and arr2 (4 * sizeof(void*) bytes)
-      // (when !FLAGS_test_cancel_global_check)
-  }
-
-  if (FLAGS_test_register_leak) {
-    // make us fail only where the .sh test expects:
-    Pause();
-    for (int i = 0; i < 100; ++i) {  // give it some time to crash
-      CHECK(HeapLeakChecker::NoGlobalLeaks());
-      Pause();
-    }
-    return Pass();
-  }
-
-  TestHeapLeakCheckerLiveness();
-
-  HeapLeakChecker heap_check("all");
-
-  TestHiddenPointer();
-
-  TestHeapLeakChecker();
-  Pause();
-  TestLeakButTotalsMatch();
-  Pause();
-
-  TestHeapLeakCheckerDeathSimple();
-  Pause();
-  TestHeapLeakCheckerDeathLoop();
-  Pause();
-  TestHeapLeakCheckerDeathInverse();
-  Pause();
-  TestHeapLeakCheckerDeathNoLeaks();
-  Pause();
-  TestHeapLeakCheckerDeathCountLess();
-  Pause();
-  TestHeapLeakCheckerDeathCountMore();
-  Pause();
-
-  TestHeapLeakCheckerDeathTrick();
-  Pause();
-
-  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good
-
-  TestHeapLeakCheckerNoFalsePositives();
-  Pause();
-
-  TestHeapLeakCheckerDisabling();
-  Pause();
-
-  TestSTLAlloc();
-  Pause();
-  TestSTLAllocInverse();
-  Pause();
-
-  // Test that various STL allocators work.  Some of these are redundant, but
-  // we don't know how STL might change in the future.  For example,
-  // http://wiki/Main/StringNeStdString.
-#define DTSL(a) { DirectTestSTLAlloc(a, #a); \
-                  Pause(); }
-  DTSL(std::allocator<char>());
-  DTSL(std::allocator<int>());
-  DTSL(std::string().get_allocator());
-  DTSL(string().get_allocator());
-  DTSL(vector<int>().get_allocator());
-  DTSL(vector<double>().get_allocator());
-  DTSL(vector<vector<int> >().get_allocator());
-  DTSL(vector<string>().get_allocator());
-  DTSL((map<string, string>().get_allocator()));
-  DTSL((map<string, int>().get_allocator()));
-  DTSL(set<char>().get_allocator());
-#undef DTSL
-
-  TestLibCAllocate();
-  Pause();
-
-  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good
-
-  Pause();
-
-  if (!FLAGS_maybe_stripped) {
-    CHECK(heap_check.SameHeap());
-  } else {
-    WARN_IF(heap_check.SameHeap() != true,
-            "overall leaks are caught; we must be using a stripped binary");
-  }
-
-  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good
-
-  return Pass();
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/heap-checker_unittest.sh b/third_party/tcmalloc/vendor/src/tests/heap-checker_unittest.sh
deleted file mode 100755
index 3c9c0e9..0000000
--- a/third_party/tcmalloc/vendor/src/tests/heap-checker_unittest.sh
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2005, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Craig Silverstein
-#
-# Runs the heap-checker unittest with various environment variables.
-# This is necessary because we turn on features like the heap profiler
-# and heap checker via environment variables.  This test makes sure
-# they all play well together.
-
-# We expect BINDIR and PPROF_PATH to be set in the environment.
-# If not, we set them to some reasonable values
-BINDIR="${BINDIR:-.}"
-PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir] [path to pprof]"
-  echo "       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
-  exit 1
-fi
-
-HEAP_CHECKER="${1:-$BINDIR/heap-checker_unittest}"
-PPROF_PATH="${2:-$PPROF_PATH}"
-
-TMPDIR=/tmp/heap_check_info
-rm -rf $TMPDIR || exit 2
-mkdir $TMPDIR || exit 3
-
-# $1: value of heap-check env. var.
-run_check() {
-    export PPROF_PATH="$PPROF_PATH"
-    [ -n "$1" ] && export HEAPCHECK="$1" || unset HEAPPROFILE
-
-    echo -n "Testing $HEAP_CHECKER with HEAPCHECK=$1 ... "
-    if $HEAP_CHECKER > $TMPDIR/output 2>&1; then
-      echo "OK"
-    else
-      echo "FAILED"
-      echo "Output from the failed run:"
-      echo "----"
-      cat $TMPDIR/output
-      echo "----"      
-      exit 4
-    fi
-
-    # If we set HEAPPROFILE, then we expect it to actually have emitted
-    # a profile.  Check that it did.
-    if [ -n "$HEAPPROFILE" ]; then
-      [ -e "$HEAPPROFILE.0001.heap" ] || exit 5
-    fi
-}
-
-run_check ""
-run_check "local"
-run_check "normal"
-run_check "strict"
-
-rm -rf $TMPDIR      # clean up
-
-echo "PASS"
diff --git a/third_party/tcmalloc/vendor/src/tests/heap-profiler_unittest.cc b/third_party/tcmalloc/vendor/src/tests/heap-profiler_unittest.cc
deleted file mode 100644
index 33178132..0000000
--- a/third_party/tcmalloc/vendor/src/tests/heap-profiler_unittest.cc
+++ /dev/null
@@ -1,168 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// A small program that just exercises our heap profiler by allocating
-// memory and letting the heap-profiler emit a profile.  We don't test
-// threads (TODO).  By itself, this unittest tests that the heap-profiler
-// doesn't crash on simple programs, but its output can be analyzed by
-// another testing script to actually verify correctness.  See, eg,
-// heap-profiler_unittest.sh.
-
-#include "config_for_unittests.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>                  // for mkdir()
-#include <sys/stat.h>               // for mkdir() on freebsd and os x
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                 // for fork()
-#endif
-#include <sys/wait.h>               // for wait()
-#include <string>
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include <gperftools/heap-profiler.h>
-
-using std::string;
-
-static const int kMaxCount = 100000;
-int* g_array[kMaxCount];              // an array of int-vectors
-
-static ATTRIBUTE_NOINLINE void Allocate(int start, int end, int size) {
-  // NOTE: we're using this to prevent gcc 5 from merging otherwise
-  // identical Allocate & Allocate2 functions.
-  VLOG(10, "Allocate");
-  for (int i = start; i < end; ++i) {
-    if (i < kMaxCount)
-      g_array[i] = new int[size];
-  }
-}
-
-static ATTRIBUTE_NOINLINE void Allocate2(int start, int end, int size) {
-  VLOG(10, "Allocate2");
-  for (int i = start; i < end; ++i) {
-    if (i < kMaxCount)
-      g_array[i] = new int[size];
-  }
-}
-
-static void Deallocate(int start, int end) {
-  for (int i = start; i < end; ++i) {
-    delete[] g_array[i];
-    g_array[i] = 0;
-  }
-}
-
-static void TestHeapProfilerStartStopIsRunning() {
-  // If you run this with whole-program heap-profiling on, than
-  // IsHeapProfilerRunning should return true.
-  if (!IsHeapProfilerRunning()) {
-    const char* tmpdir = getenv("TMPDIR");
-    if (tmpdir == NULL)
-      tmpdir = "/tmp";
-    mkdir(tmpdir, 0755);     // if necessary
-    HeapProfilerStart((string(tmpdir) + "/start_stop").c_str());
-    CHECK(IsHeapProfilerRunning());
-
-    Allocate(0, 40, 100);
-    Deallocate(0, 40);
-
-    HeapProfilerStop();
-    CHECK(!IsHeapProfilerRunning());
-  }
-}
-
-static void TestDumpHeapProfiler() {
-  // If you run this with whole-program heap-profiling on, than
-  // IsHeapProfilerRunning should return true.
-  if (!IsHeapProfilerRunning()) {
-    const char* tmpdir = getenv("TMPDIR");
-    if (tmpdir == NULL)
-      tmpdir = "/tmp";
-    mkdir(tmpdir, 0755);     // if necessary
-    HeapProfilerStart((string(tmpdir) + "/dump").c_str());
-    CHECK(IsHeapProfilerRunning());
-
-    Allocate(0, 40, 100);
-    Deallocate(0, 40);
-
-    char* output = GetHeapProfile();
-    free(output);
-    HeapProfilerStop();
-  }
-}
-
-
-int main(int argc, char** argv) {
-  if (argc > 2 || (argc == 2 && argv[1][0] == '-')) {
-    printf("USAGE: %s [number of children to fork]\n", argv[0]);
-    exit(0);
-  }
-  int num_forks = 0;
-  if (argc == 2) {
-    num_forks = atoi(argv[1]);
-  }
-
-  TestHeapProfilerStartStopIsRunning();
-  TestDumpHeapProfiler();
-
-  Allocate(0, 40, 100);
-  Deallocate(0, 40);
-
-  Allocate(0, 40, 100);
-  Allocate(0, 40, 100);
-  Allocate2(40, 400, 1000);
-  Allocate2(400, 1000, 10000);
-  Deallocate(0, 1000);
-
-  Allocate(0, 100, 100000);
-  Deallocate(0, 10);
-  Deallocate(10, 20);
-  Deallocate(90, 100);
-  Deallocate(20, 90);
-
-  while (num_forks-- > 0) {
-    switch (fork()) {
-      case -1:
-        printf("FORK failed!\n");
-        return 1;
-      case 0:             // child
-        return execl(argv[0], argv[0], NULL);   // run child with no args
-      default:
-        wait(NULL);       // we'll let the kids run one at a time
-    }
-  }
-
-  printf("DONE.\n");
-
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/heap-profiler_unittest.sh b/third_party/tcmalloc/vendor/src/tests/heap-profiler_unittest.sh
deleted file mode 100755
index 91af04f..0000000
--- a/third_party/tcmalloc/vendor/src/tests/heap-profiler_unittest.sh
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2005, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Craig Silverstein
-#
-# Runs the heap-profiler unittest and makes sure the profile looks appropriate.
-#
-# We run under the assumption that if $HEAP_PROFILER is run with --help,
-# it prints a usage line of the form
-#   USAGE: <actual executable being run> [...]
-#
-# This is because libtool sometimes turns the 'executable' into a
-# shell script which runs an actual binary somewhere else.
-
-# We expect BINDIR and PPROF_PATH to be set in the environment.
-# If not, we set them to some reasonable values
-BINDIR="${BINDIR:-.}"
-PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir] [path to pprof]"
-  echo "       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
-  exit 1
-fi
-
-HEAP_PROFILER="${1:-$BINDIR/heap-profiler_unittest}"
-PPROF="${2:-$PPROF_PATH}"
-TEST_TMPDIR=`mktemp -d /tmp/heap-profiler_unittest.XXXXXX`
-
-# It's meaningful to the profiler, so make sure we know its state
-unset HEAPPROFILE
-
-num_failures=0
-
-# Given one profile (to check the contents of that profile) or two
-# profiles (to check the diff between the profiles), and a function
-# name, verify that the function name takes up at least 90% of the
-# allocated memory.  The function name is actually specified first.
-VerifyMemFunction() {
-  function="$1"
-  shift
-
-  # get program name.  Note we have to unset HEAPPROFILE so running
-  # help doesn't overwrite existing profiles.
-  exec=`unset HEAPPROFILE; $HEAP_PROFILER --help | awk '{print $2; exit;}'`
-
-  if [ $# = 2 ]; then
-    [ -f "$1" ] || { echo "Profile not found: $1"; exit 1; }
-    [ -f "$2" ] || { echo "Profile not found: $2"; exit 1; }
-    $PPROF --base="$1" $exec "$2" >"$TEST_TMPDIR/output.pprof" 2>&1
-  else
-    [ -f "$1" ] || { echo "Profile not found: $1"; exit 1; }
-    $PPROF $exec "$1" >"$TEST_TMPDIR/output.pprof" 2>&1
-  fi
-
-  cat "$TEST_TMPDIR/output.pprof" \
-      | tr -d % | awk '$6 ~ /^'$function'$/ && $2 > 90 {exit 1;}'
-  if [ $? != 1 ]; then
-    echo
-    echo "--- Test failed for $function: didn't account for 90% of executable memory"
-    echo "--- Program output:"
-    cat "$TEST_TMPDIR/output"
-    echo "--- pprof output:"
-    cat "$TEST_TMPDIR/output.pprof"
-    echo "---"
-    num_failures=`expr $num_failures + 1`
-  fi
-}
-
-VerifyOutputContains() {
-  text="$1"
-
-  if ! grep "$text" "$TEST_TMPDIR/output" >/dev/null 2>&1; then
-    echo "--- Test failed: output does not contain '$text'"
-    echo "--- Program output:"
-    cat "$TEST_TMPDIR/output"
-    echo "---"
-    num_failures=`expr $num_failures + 1`
-  fi
-}
-
-HEAPPROFILE="$TEST_TMPDIR/test"
-HEAP_PROFILE_INUSE_INTERVAL="10240"   # need this to be 10Kb
-HEAP_PROFILE_ALLOCATION_INTERVAL="$HEAP_PROFILE_INUSE_INTERVAL"
-HEAP_PROFILE_DEALLOCATION_INTERVAL="$HEAP_PROFILE_INUSE_INTERVAL"
-export HEAPPROFILE
-export HEAP_PROFILE_INUSE_INTERVAL
-export HEAP_PROFILE_ALLOCATION_INTERVAL
-export HEAP_PROFILE_DEALLOCATION_INTERVAL
-
-# We make the unittest run a child process, to test that the child
-# process doesn't try to write a heap profile as well and step on the
-# parent's toes.  If it does, we expect the parent-test to fail.
-$HEAP_PROFILER 1 >$TEST_TMPDIR/output 2>&1     # run program, with 1 child proc
-
-VerifyMemFunction Allocate2 "$HEAPPROFILE.1329.heap"
-VerifyMemFunction Allocate "$HEAPPROFILE.1448.heap" "$HEAPPROFILE.1548.heap"
-
-# Check the child process got to emit its own profile as well.
-VerifyMemFunction Allocate2 "$HEAPPROFILE"_*.1329.heap
-VerifyMemFunction Allocate "$HEAPPROFILE"_*.1448.heap "$HEAPPROFILE"_*.1548.heap
-
-# Make sure we logged both about allocating and deallocating memory
-VerifyOutputContains "62 MB allocated"
-VerifyOutputContains "62 MB freed"
-
-# Now try running without --heap_profile specified, to allow
-# testing of the HeapProfileStart/Stop functionality.
-$HEAP_PROFILER >"$TEST_TMPDIR/output2" 2>&1
-
-rm -rf $TEST_TMPDIR      # clean up
-
-if [ $num_failures = 0 ]; then
-  echo "PASS"
-else
-  echo "Tests finished with $num_failures failures"
-fi
-exit $num_failures
diff --git a/third_party/tcmalloc/vendor/src/tests/large_heap_fragmentation_unittest.cc b/third_party/tcmalloc/vendor/src/tests/large_heap_fragmentation_unittest.cc
deleted file mode 100644
index 0886599..0000000
--- a/third_party/tcmalloc/vendor/src/tests/large_heap_fragmentation_unittest.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This is a unit test for exercising fragmentation of large (over 1
-// meg) page spans. It makes sure that allocations/releases of
-// increasing memory chunks do not blowup memory
-// usage. See also https://code.google.com/p/gperftools/issues/detail?id=368
-
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "base/logging.h"
-#include "common.h"
-#include <gperftools/malloc_extension.h>
-
-
-int main (int argc, char** argv) {
-  for (int pass = 1; pass <= 3; pass++) {
-    size_t size = 100*1024*1024;
-    while (size < 500*1024*1024) {
-      void *ptr = malloc(size);
-      free(ptr);
-      size += 20000;
-
-      size_t heap_size = static_cast<size_t>(-1);
-      MallocExtension::instance()->GetNumericProperty("generic.heap_size",
-                                                      &heap_size);
-
-
-      CHECK_LT(heap_size, 1*1024*1024*1024);
-    }
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/low_level_alloc_unittest.cc b/third_party/tcmalloc/vendor/src/tests/low_level_alloc_unittest.cc
deleted file mode 100644
index e3cb5552..0000000
--- a/third_party/tcmalloc/vendor/src/tests/low_level_alloc_unittest.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// A test for low_level_alloc.cc
-
-#include <stdio.h>
-#include <map>
-#include "base/low_level_alloc.h"
-#include "base/logging.h"
-#include <gperftools/malloc_hook.h>
-
-using std::map;
-
-// a block of memory obtained from the allocator
-struct BlockDesc {
-  char *ptr;      // pointer to memory
-  int len;        // number of bytes
-  int fill;       // filled with data starting with this
-};
-
-// Check that the pattern placed in the block d
-// by RandomizeBlockDesc is still there.
-static void CheckBlockDesc(const BlockDesc &d) {
-  for (int i = 0; i != d.len; i++) {
-    CHECK((d.ptr[i] & 0xff) == ((d.fill + i) & 0xff));
-  }
-}
-
-// Fill the block "*d" with a pattern
-// starting with a random byte.
-static void RandomizeBlockDesc(BlockDesc *d) {
-  d->fill = rand() & 0xff;
-  for (int i = 0; i != d->len; i++) {
-    d->ptr[i] = (d->fill + i) & 0xff;
-  }
-}
-
-// Use to indicate to the malloc hooks that
-// this calls is from LowLevelAlloc.
-static bool using_low_level_alloc = false;
-
-// n times, toss a coin, and based on the outcome
-// either allocate a new block or deallocate an old block.
-// New blocks are placed in a map with a random key
-// and initialized with RandomizeBlockDesc().
-// If keys conflict, the older block is freed.
-// Old blocks are always checked with CheckBlockDesc()
-// before being freed.  At the end of the run,
-// all remaining allocated blocks are freed.
-// If use_new_arena is true, use a fresh arena, and then delete it.
-// If call_malloc_hook is true and user_arena is true,
-// allocations and deallocations are reported via the MallocHook
-// interface.
-static void Test(bool use_new_arena, bool call_malloc_hook, int n) {
-  typedef map<int, BlockDesc> AllocMap;
-  AllocMap allocated;
-  AllocMap::iterator it;
-  BlockDesc block_desc;
-  int rnd;
-  LowLevelAlloc::Arena *arena = 0;
-  if (use_new_arena) {
-    int32 flags = call_malloc_hook?  LowLevelAlloc::kCallMallocHook :  0;
-    arena = LowLevelAlloc::NewArena(flags, LowLevelAlloc::DefaultArena());
-  }
-  for (int i = 0; i != n; i++) {
-    if (i != 0 && i % 10000 == 0) {
-      printf(".");
-      fflush(stdout);
-    }
-
-    switch(rand() & 1) {      // toss a coin
-    case 0:     // coin came up heads: add a block
-      using_low_level_alloc = true;
-      block_desc.len = rand() & 0x3fff;
-      block_desc.ptr =
-        reinterpret_cast<char *>(
-                        arena == 0
-                        ? LowLevelAlloc::Alloc(block_desc.len)
-                        : LowLevelAlloc::AllocWithArena(block_desc.len, arena));
-      using_low_level_alloc = false;
-      RandomizeBlockDesc(&block_desc);
-      rnd = rand();
-      it = allocated.find(rnd);
-      if (it != allocated.end()) {
-        CheckBlockDesc(it->second);
-        using_low_level_alloc = true;
-        LowLevelAlloc::Free(it->second.ptr);
-        using_low_level_alloc = false;
-        it->second = block_desc;
-      } else {
-        allocated[rnd] = block_desc;
-      }
-      break;
-    case 1:     // coin came up tails: remove a block
-      it = allocated.begin();
-      if (it != allocated.end()) {
-        CheckBlockDesc(it->second);
-        using_low_level_alloc = true;
-        LowLevelAlloc::Free(it->second.ptr);
-        using_low_level_alloc = false;
-        allocated.erase(it);
-      }
-      break;
-    }
-  }
-  // remove all remaniing blocks
-  while ((it = allocated.begin()) != allocated.end()) {
-    CheckBlockDesc(it->second);
-    using_low_level_alloc = true;
-    LowLevelAlloc::Free(it->second.ptr);
-    using_low_level_alloc = false;
-    allocated.erase(it);
-  }
-  if (use_new_arena) {
-    CHECK(LowLevelAlloc::DeleteArena(arena));
-  }
-}
-
-// used for counting allocates and frees
-static int32 allocates;
-static int32 frees;
-
-// called on each alloc if kCallMallocHook specified
-static void AllocHook(const void *p, size_t size) {
-  if (using_low_level_alloc) {
-    allocates++;
-  }
-}
-
-// called on each free if kCallMallocHook specified
-static void FreeHook(const void *p) {
-  if (using_low_level_alloc) {
-    frees++;
-  }
-}
-
-int main(int argc, char *argv[]) {
-  // This is needed by maybe_threads_unittest.sh, which parses argv[0]
-  // to figure out what directory low_level_alloc_unittest is in.
-  if (argc != 1) {
-    fprintf(stderr, "USAGE: %s\n", argv[0]);
-    return 1;
-  }
-
-  CHECK(MallocHook::AddNewHook(&AllocHook));
-  CHECK(MallocHook::AddDeleteHook(&FreeHook));
-  CHECK_EQ(allocates, 0);
-  CHECK_EQ(frees, 0);
-  Test(false, false, 50000);
-  CHECK_NE(allocates, 0);   // default arena calls hooks
-  CHECK_NE(frees, 0);
-  for (int i = 0; i != 16; i++) {
-    bool call_hooks = ((i & 1) == 1);
-    allocates = 0;
-    frees = 0;
-    Test(true, call_hooks, 15000);
-    if (call_hooks) {
-      CHECK_GT(allocates, 5000); // arena calls hooks
-      CHECK_GT(frees, 5000);
-    } else {
-      CHECK_EQ(allocates, 0);    // arena doesn't call hooks
-      CHECK_EQ(frees, 0);
-    }
-  }
-  printf("\nPASS\n");
-  CHECK(MallocHook::RemoveNewHook(&AllocHook));
-  CHECK(MallocHook::RemoveDeleteHook(&FreeHook));
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/malloc_extension_c_test.c b/third_party/tcmalloc/vendor/src/tests/malloc_extension_c_test.c
deleted file mode 100644
index 278fdb7..0000000
--- a/third_party/tcmalloc/vendor/src/tests/malloc_extension_c_test.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* Copyright (c) 2009, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Craig Silverstein
- *
- * This tests the c shims: malloc_extension_c.h and malloc_hook_c.h.
- * Mostly, we'll just care that these shims compile under gcc
- * (*not* g++!)
- *
- * NOTE: this is C code, not C++ code!
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>   /* for size_t */
-#include <gperftools/malloc_extension_c.h>
-#include <gperftools/malloc_hook_c.h>
-
-#define FAIL(msg) do {                          \
-  fprintf(stderr, "FATAL ERROR: %s\n", msg);    \
-  exit(1);                                      \
-} while (0)
-
-static int g_new_hook_calls = 0;
-static int g_delete_hook_calls = 0;
-
-void TestNewHook(const void* ptr, size_t size) {
-  g_new_hook_calls++;
-}
-
-void TestDeleteHook(const void* ptr) {
-  g_delete_hook_calls++;
-}
-
-static
-void *forced_malloc(size_t size)
-{
-  extern void *tc_malloc(size_t);
-  void *rv = tc_malloc(size);
-  if (!rv) {
-    FAIL("malloc is not supposed to fail here");
-  }
-  return rv;
-}
-
-void TestMallocHook(void) {
-  /* TODO(csilvers): figure out why we get:
-   * E0100 00:00:00.000000  7383 malloc_hook.cc:244] RAW: google_malloc section is missing, thus InHookCaller is broken!
-   */
-#if 0
-  void* result[5];
-
-  if (MallocHook_GetCallerStackTrace(result, sizeof(result)/sizeof(*result),
-                                     0) < 2) {  /* should have this and main */
-    FAIL("GetCallerStackTrace failed");
-  }
-#endif
-
-  if (!MallocHook_AddNewHook(&TestNewHook)) {
-    FAIL("Failed to add new hook");
-  }
-  if (!MallocHook_AddDeleteHook(&TestDeleteHook)) {
-    FAIL("Failed to add delete hook");
-  }
-
-  free(forced_malloc(10));
-  free(forced_malloc(20));
-  if (g_new_hook_calls != 2) {
-    FAIL("Wrong number of calls to the new hook");
-  }
-  if (g_delete_hook_calls != 2) {
-    FAIL("Wrong number of calls to the delete hook");
-  }
-  if (!MallocHook_RemoveNewHook(&TestNewHook)) {
-    FAIL("Failed to remove new hook");
-  }
-  if (!MallocHook_RemoveDeleteHook(&TestDeleteHook)) {
-    FAIL("Failed to remove delete hook");
-  }
-
-  free(forced_malloc(10));
-  free(forced_malloc(20));
-  if (g_new_hook_calls != 2) {
-    FAIL("Wrong number of calls to the new hook");
-  }
-
-  MallocHook_SetNewHook(&TestNewHook);
-  MallocHook_SetDeleteHook(&TestDeleteHook);
-
-  free(forced_malloc(10));
-  free(forced_malloc(20));
-  if (g_new_hook_calls != 4) {
-    FAIL("Wrong number of calls to the singular new hook");
-  }
-
-  if (MallocHook_SetNewHook(NULL) == NULL) {
-    FAIL("Failed to set new hook");
-  }
-  if (MallocHook_SetDeleteHook(NULL) == NULL) {
-    FAIL("Failed to set delete hook");
-  }
-}
-
-void TestMallocExtension(void) {
-  int blocks;
-  size_t total;
-  int hist[64];
-  char buffer[200];
-  char* x = (char*)malloc(10);
-
-  MallocExtension_VerifyAllMemory();
-  MallocExtension_VerifyMallocMemory(x);
-  MallocExtension_MallocMemoryStats(&blocks, &total, hist);
-  MallocExtension_GetStats(buffer, sizeof(buffer));
-  if (!MallocExtension_GetNumericProperty("generic.current_allocated_bytes",
-                                          &total)) {
-    FAIL("GetNumericProperty failed for generic.current_allocated_bytes");
-  }
-  if (total < 10) {
-    FAIL("GetNumericProperty had bad return for generic.current_allocated_bytes");
-  }
-  if (!MallocExtension_GetNumericProperty("generic.current_allocated_bytes",
-                                          &total)) {
-    FAIL("GetNumericProperty failed for generic.current_allocated_bytes");
-  }
-  MallocExtension_MarkThreadIdle();
-  MallocExtension_MarkThreadBusy();
-  MallocExtension_ReleaseToSystem(1);
-  MallocExtension_ReleaseFreeMemory();
-  if (MallocExtension_GetEstimatedAllocatedSize(10) < 10) {
-    FAIL("GetEstimatedAllocatedSize returned a bad value (too small)");
-  }
-  if (MallocExtension_GetAllocatedSize(x) < 10) {
-    FAIL("GetEstimatedAllocatedSize returned a bad value (too small)");
-  }
-  if (MallocExtension_GetOwnership(x) != MallocExtension_kOwned) {
-    FAIL("DidAllocatePtr returned a bad value (kNotOwned)");
-  }
-  /* TODO(csilvers): this relies on undocumented behavior that
-     GetOwnership works on stack-allocated variables.  Use a better test. */
-  if (MallocExtension_GetOwnership(hist) != MallocExtension_kNotOwned) {
-    FAIL("DidAllocatePtr returned a bad value (kOwned)");
-  }
-
-  free(x);
-}
-
-int main(int argc, char** argv) {
-  TestMallocHook();
-  TestMallocExtension();
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/malloc_extension_test.cc b/third_party/tcmalloc/vendor/src/tests/malloc_extension_test.cc
deleted file mode 100644
index 31c4968..0000000
--- a/third_party/tcmalloc/vendor/src/tests/malloc_extension_test.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// Simple test of malloc_extension.  Includes test of C shims.
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#include <sys/types.h>
-#include "base/logging.h"
-#include <gperftools/malloc_extension.h>
-#include <gperftools/malloc_extension_c.h>
-
-int main(int argc, char** argv) {
-  void* a = malloc(1000);
-
-  size_t cxx_bytes_used, c_bytes_used;
-  ASSERT_TRUE(MallocExtension::instance()->GetNumericProperty(
-      "generic.current_allocated_bytes", &cxx_bytes_used));
-  ASSERT_TRUE(MallocExtension_GetNumericProperty(
-      "generic.current_allocated_bytes", &c_bytes_used));
-  ASSERT_GT(cxx_bytes_used, 1000);
-  ASSERT_EQ(cxx_bytes_used, c_bytes_used);
-
-  ASSERT_TRUE(MallocExtension::instance()->VerifyAllMemory());
-  ASSERT_TRUE(MallocExtension_VerifyAllMemory());
-
-  ASSERT_EQ(MallocExtension::kOwned,
-            MallocExtension::instance()->GetOwnership(a));
-  // TODO(csilvers): this relies on undocumented behavior that
-  // GetOwnership works on stack-allocated variables.  Use a better test.
-  ASSERT_EQ(MallocExtension::kNotOwned,
-            MallocExtension::instance()->GetOwnership(&cxx_bytes_used));
-  ASSERT_EQ(MallocExtension::kNotOwned,
-            MallocExtension::instance()->GetOwnership(NULL));
-  ASSERT_GE(MallocExtension::instance()->GetAllocatedSize(a), 1000);
-  // This is just a sanity check.  If we allocated too much, tcmalloc is broken
-  ASSERT_LE(MallocExtension::instance()->GetAllocatedSize(a), 5000);
-  ASSERT_GE(MallocExtension::instance()->GetEstimatedAllocatedSize(1000), 1000);
-
-  for (int i = 0; i < 10; ++i) {
-    void *p = malloc(i);
-    ASSERT_GE(MallocExtension::instance()->GetAllocatedSize(p),
-             MallocExtension::instance()->GetEstimatedAllocatedSize(i));
-    free(p);
-  }
-
-  // Check the c-shim version too.
-  ASSERT_EQ(MallocExtension_kOwned, MallocExtension_GetOwnership(a));
-  ASSERT_EQ(MallocExtension_kNotOwned,
-            MallocExtension_GetOwnership(&cxx_bytes_used));
-  ASSERT_EQ(MallocExtension_kNotOwned, MallocExtension_GetOwnership(NULL));
-  ASSERT_GE(MallocExtension_GetAllocatedSize(a), 1000);
-  ASSERT_LE(MallocExtension_GetAllocatedSize(a), 5000);
-  ASSERT_GE(MallocExtension_GetEstimatedAllocatedSize(1000), 1000);
-
-  free(a);
-
-  // Verify that the .cc file and .h file have the same enum values.
-  ASSERT_EQ(static_cast<int>(MallocExtension::kUnknownOwnership),
-            static_cast<int>(MallocExtension_kUnknownOwnership));
-  ASSERT_EQ(static_cast<int>(MallocExtension::kOwned),
-            static_cast<int>(MallocExtension_kOwned));
-  ASSERT_EQ(static_cast<int>(MallocExtension::kNotOwned),
-            static_cast<int>(MallocExtension_kNotOwned));
-
-  printf("DONE\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/malloc_hook_test.cc b/third_party/tcmalloc/vendor/src/tests/malloc_hook_test.cc
deleted file mode 100644
index a5cd860..0000000
--- a/third_party/tcmalloc/vendor/src/tests/malloc_hook_test.cc
+++ /dev/null
@@ -1,367 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ----
-// Author: llib@google.com (Bill Clarke)
-
-#include "config_for_unittests.h"
-#include <assert.h>
-#include <stdio.h>
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for sleep()
-#endif
-#include <algorithm>
-#include <string>
-#include <vector>
-#include <gperftools/malloc_hook.h>
-#include "malloc_hook-inl.h"
-#include "base/logging.h"
-#include "base/simple_mutex.h"
-#include "base/sysinfo.h"
-#include "tests/testutil.h"
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-namespace {
-
-using std::string;
-using std::vector;
-
-vector<void (*)()> g_testlist;  // the tests to run
-
-#define TEST(a, b)                                      \
-  struct Test_##a##_##b {                               \
-    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
-    static void Run();                                  \
-  };                                                    \
-  static Test_##a##_##b g_test_##a##_##b;               \
-  void Test_##a##_##b::Run()
-
-
-static int RUN_ALL_TESTS() {
-  vector<void (*)()>::const_iterator it;
-  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
-    (*it)();   // The test will error-exit if there's a problem.
-  }
-  fprintf(stderr, "\nPassed %d tests\n\nPASS\n",
-          static_cast<int>(g_testlist.size()));
-  return 0;
-}
-
-void Sleep(int seconds) {
-#ifdef _MSC_VER
-  _sleep(seconds * 1000);   // Windows's _sleep takes milliseconds argument
-#else
-  sleep(seconds);
-#endif
-}
-
-using std::min;
-using base::internal::kHookListMaxValues;
-
-// Since HookList is a template and is defined in malloc_hook.cc, we can only
-// use an instantiation of it from malloc_hook.cc.  We then reinterpret those
-// values as integers for testing.
-typedef base::internal::HookList<MallocHook::NewHook> TestHookList;
-
-int TestHookList_Traverse(const TestHookList& list, uintptr_t* output_array, int n) {
-  MallocHook::NewHook values_as_hooks[kHookListMaxValues];
-  int result = list.Traverse(values_as_hooks, min(n, kHookListMaxValues));
-  for (int i = 0; i < result; ++i) {
-    output_array[i] = reinterpret_cast<const uintptr_t>(*values_as_hooks[i]);
-  }
-  return result;
-}
-
-bool TestHookList_Add(TestHookList* list, int val) {
-  return list->Add(reinterpret_cast<MallocHook::NewHook>(val));
-}
-
-bool TestHookList_Remove(TestHookList* list, int val) {
-  return list->Remove(reinterpret_cast<MallocHook::NewHook>(val));
-}
-
-// Note that this is almost the same as INIT_HOOK_LIST in malloc_hook.cc without
-// the cast.
-#define INIT_HOOK_LIST(initial_value) { 1, { initial_value } }
-
-TEST(HookListTest, InitialValueExists) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(1, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(69, values[0]);
-  EXPECT_EQ(1, list.priv_end);
-}
-
-TEST(HookListTest, CanRemoveInitialValue) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  ASSERT_TRUE(TestHookList_Remove(&list, 69));
-  EXPECT_EQ(0, list.priv_end);
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(0, TestHookList_Traverse(list, values, 2));
-}
-
-TEST(HookListTest, AddAppends) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  ASSERT_TRUE(TestHookList_Add(&list, 42));
-  EXPECT_EQ(2, list.priv_end);
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(2, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(69, values[0]);
-  EXPECT_EQ(42, values[1]);
-}
-
-TEST(HookListTest, RemoveWorksAndWillClearSize) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  ASSERT_TRUE(TestHookList_Add(&list, 42));
-
-  ASSERT_TRUE(TestHookList_Remove(&list, 69));
-  EXPECT_EQ(2, list.priv_end);
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(1, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(42, values[0]);
-
-  ASSERT_TRUE(TestHookList_Remove(&list, 42));
-  EXPECT_EQ(0, list.priv_end);
-  EXPECT_EQ(0, TestHookList_Traverse(list, values, 2));
-}
-
-TEST(HookListTest, AddPrependsAfterRemove) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  ASSERT_TRUE(TestHookList_Add(&list, 42));
-
-  ASSERT_TRUE(TestHookList_Remove(&list, 69));
-  EXPECT_EQ(2, list.priv_end);
-
-  ASSERT_TRUE(TestHookList_Add(&list, 7));
-  EXPECT_EQ(2, list.priv_end);
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(2, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(7, values[0]);
-  EXPECT_EQ(42, values[1]);
-}
-
-TEST(HookListTest, InvalidAddRejected) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  EXPECT_FALSE(TestHookList_Add(&list, 0));
-
-  uintptr_t values[2] = { 0, 0 };
-  EXPECT_EQ(1, TestHookList_Traverse(list, values, 2));
-  EXPECT_EQ(69, values[0]);
-  EXPECT_EQ(1, list.priv_end);
-}
-
-TEST(HookListTest, FillUpTheList) {
-  TestHookList list = INIT_HOOK_LIST(69);
-  int num_inserts = 0;
-  while (TestHookList_Add(&list, ++num_inserts))
-    ;
-  EXPECT_EQ(kHookListMaxValues, num_inserts);
-  EXPECT_EQ(kHookListMaxValues, list.priv_end);
-
-  uintptr_t values[kHookListMaxValues + 1];
-  EXPECT_EQ(kHookListMaxValues, TestHookList_Traverse(list, values,
-                                                      kHookListMaxValues));
-  EXPECT_EQ(69, values[0]);
-  for (int i = 1; i < kHookListMaxValues; ++i) {
-    EXPECT_EQ(i, values[i]);
-  }
-}
-
-void MultithreadedTestThread(TestHookList* list, int shift,
-                             int thread_num) {
-  string message;
-  char buf[64];
-  for (int i = 1; i < 1000; ++i) {
-    // In each loop, we insert a unique value, check it exists, remove it, and
-    // check it doesn't exist.  We also record some stats to log at the end of
-    // each thread.  Each insertion location and the length of the list is
-    // non-deterministic (except for the very first one, over all threads, and
-    // after the very last one the list should be empty).
-    int value = (i << shift) + thread_num;
-    EXPECT_TRUE(TestHookList_Add(list, value));
-    sched_yield();  // Ensure some more interleaving.
-    uintptr_t values[kHookListMaxValues + 1];
-    int num_values = TestHookList_Traverse(*list, values, kHookListMaxValues);
-    EXPECT_LT(0, num_values);
-    int value_index;
-    for (value_index = 0;
-         value_index < num_values && values[value_index] != value;
-         ++value_index)
-      ;
-    EXPECT_LT(value_index, num_values);  // Should have found value.
-    snprintf(buf, sizeof(buf), "[%d/%d; ", value_index, num_values);
-    message += buf;
-    sched_yield();
-    EXPECT_TRUE(TestHookList_Remove(list, value));
-    sched_yield();
-    num_values = TestHookList_Traverse(*list, values, kHookListMaxValues);
-    for (value_index = 0;
-         value_index < num_values && values[value_index] != value;
-         ++value_index)
-      ;
-    EXPECT_EQ(value_index, num_values);  // Should not have found value.
-    snprintf(buf, sizeof(buf), "%d]", num_values);
-    message += buf;
-    sched_yield();
-  }
-  fprintf(stderr, "thread %d: %s\n", thread_num, message.c_str());
-}
-
-static volatile int num_threads_remaining;
-static TestHookList list = INIT_HOOK_LIST(69);
-static Mutex threadcount_lock;
-
-void MultithreadedTestThreadRunner(int thread_num) {
-  // Wait for all threads to start running.
-  {
-    MutexLock ml(&threadcount_lock);
-    assert(num_threads_remaining > 0);
-    --num_threads_remaining;
-
-    // We should use condvars and the like, but for this test, we'll
-    // go simple and busy-wait.
-    while (num_threads_remaining > 0) {
-      threadcount_lock.Unlock();
-      Sleep(1);
-      threadcount_lock.Lock();
-    }
-  }
-
-  // shift is the smallest number such that (1<<shift) > kHookListMaxValues
-  int shift = 0;
-  for (int i = kHookListMaxValues; i > 0; i >>= 1)
-    shift += 1;
-
-  MultithreadedTestThread(&list, shift, thread_num);
-}
-
-
-TEST(HookListTest, MultithreadedTest) {
-  ASSERT_TRUE(TestHookList_Remove(&list, 69));
-  ASSERT_EQ(0, list.priv_end);
-
-  // Run kHookListMaxValues thread, each running MultithreadedTestThread.
-  // First, we need to set up the rest of the globals.
-  num_threads_remaining = kHookListMaxValues;   // a global var
-  RunManyThreadsWithId(&MultithreadedTestThreadRunner, num_threads_remaining,
-                       1 << 15);
-
-  uintptr_t values[kHookListMaxValues + 1];
-  EXPECT_EQ(0, TestHookList_Traverse(list, values, kHookListMaxValues));
-  EXPECT_EQ(0, list.priv_end);
-}
-
-// We only do mmap-hooking on (some) linux systems.
-#if defined(HAVE_MMAP) && defined(__linux) && \
-    (defined(__i386__) || defined(__x86_64__) || defined(__PPC__))
-
-int mmap_calls = 0;
-int mmap_matching_calls = 0;
-int munmap_calls = 0;
-int munmap_matching_calls = 0;
-const int kMmapMagicFd = 1;
-void* const kMmapMagicPointer = reinterpret_cast<void*>(1);
-
-int MmapReplacement(const void* start,
-                     size_t size,
-                     int protection,
-                     int flags,
-                     int fd,
-                     off_t offset,
-                     void** result) {
-  ++mmap_calls;
-  if (fd == kMmapMagicFd) {
-    ++mmap_matching_calls;
-    *result = kMmapMagicPointer;
-    return true;
-  }
-  return false;
-}
-
-int MunmapReplacement(const void* ptr, size_t size, int* result) {
-  ++munmap_calls;
-  if (ptr == kMmapMagicPointer) {
-    ++munmap_matching_calls;
-    *result = 0;
-    return true;
-  }
-  return false;
-}
-
-TEST(MallocMookTest, MmapReplacements) {
-  mmap_calls = mmap_matching_calls = munmap_calls = munmap_matching_calls = 0;
-  MallocHook::SetMmapReplacement(&MmapReplacement);
-  MallocHook::SetMunmapReplacement(&MunmapReplacement);
-  EXPECT_EQ(kMmapMagicPointer, mmap(NULL, 1, PROT_READ, MAP_PRIVATE,
-                                    kMmapMagicFd, 0));
-  EXPECT_EQ(1, mmap_matching_calls);
-
-  char* ptr = reinterpret_cast<char*>(
-      mmap(NULL, 1, PROT_READ | PROT_WRITE,
-           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
-  EXPECT_EQ(2, mmap_calls);
-  EXPECT_EQ(1, mmap_matching_calls);
-  ASSERT_NE(MAP_FAILED, ptr);
-  *ptr = 'a';
-
-  EXPECT_EQ(0, munmap(kMmapMagicPointer, 1));
-  EXPECT_EQ(1, munmap_calls);
-  EXPECT_EQ(1, munmap_matching_calls);
-
-  EXPECT_EQ(0, munmap(ptr, 1));
-  EXPECT_EQ(2, munmap_calls);
-  EXPECT_EQ(1, munmap_matching_calls);
-
-  // The DEATH test below is flaky, because we've just munmapped the memory,
-  // making it available for mmap()ing again. There is no guarantee that it
-  // will stay unmapped, and in fact it gets reused ~10% of the time.
-  // It the area is reused, then not only we don't die, but we also corrupt
-  // whoever owns that memory now.
-  // EXPECT_DEATH(*ptr = 'a', "SIGSEGV");
-}
-#endif  // #ifdef HAVE_MMAP && linux && ...
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  return RUN_ALL_TESTS();
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/markidle_unittest.cc b/third_party/tcmalloc/vendor/src/tests/markidle_unittest.cc
deleted file mode 100644
index 92b4cc4a..0000000
--- a/third_party/tcmalloc/vendor/src/tests/markidle_unittest.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2003, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// MallocExtension::MarkThreadIdle() testing
-#include <stdio.h>
-
-#include "config_for_unittests.h"
-#include "base/logging.h"
-#include <gperftools/malloc_extension.h>
-#include "tests/testutil.h"   // for RunThread()
-
-// Helper routine to do lots of allocations
-static void TestAllocation() {
-  static const int kNum = 100;
-  void* ptr[kNum];
-  for (int size = 8; size <= 65536; size*=2) {
-    for (int i = 0; i < kNum; i++) {
-      ptr[i] = malloc(size);
-    }
-    for (int i = 0; i < kNum; i++) {
-      free(ptr[i]);
-    }
-  }
-}
-
-// Routine that does a bunch of MarkThreadIdle() calls in sequence
-// without any intervening allocations
-static void MultipleIdleCalls() {
-  for (int i = 0; i < 4; i++) {
-    MallocExtension::instance()->MarkThreadIdle();
-  }
-}
-
-// Routine that does a bunch of MarkThreadIdle() calls in sequence
-// with intervening allocations
-static void MultipleIdleNonIdlePhases() {
-  for (int i = 0; i < 4; i++) {
-    TestAllocation();
-    MallocExtension::instance()->MarkThreadIdle();
-  }
-}
-
-// Get current thread cache usage
-static size_t GetTotalThreadCacheSize() {
-  size_t result;
-  CHECK(MallocExtension::instance()->GetNumericProperty(
-            "tcmalloc.current_total_thread_cache_bytes",
-            &result));
-  return result;
-}
-
-// Check that MarkThreadIdle() actually reduces the amount
-// of per-thread memory.
-static void TestIdleUsage() {
-  const size_t original = GetTotalThreadCacheSize();
-
-  TestAllocation();
-  const size_t post_allocation = GetTotalThreadCacheSize();
-  CHECK_GT(post_allocation, original);
-
-  MallocExtension::instance()->MarkThreadIdle();
-  const size_t post_idle = GetTotalThreadCacheSize();
-  CHECK_LE(post_idle, original);
-
-  // Log after testing because logging can allocate heap memory.
-  VLOG(0, "Original usage: %" PRIuS "\n", original);
-  VLOG(0, "Post allocation: %" PRIuS "\n", post_allocation);
-  VLOG(0, "Post idle: %" PRIuS "\n", post_idle);
-}
-
-static void TestTemporarilyIdleUsage() {
-  const size_t original = MallocExtension::instance()->GetThreadCacheSize();
-
-  TestAllocation();
-  const size_t post_allocation = MallocExtension::instance()->GetThreadCacheSize();
-  CHECK_GT(post_allocation, original);
-
-  MallocExtension::instance()->MarkThreadIdle();
-  const size_t post_idle = MallocExtension::instance()->GetThreadCacheSize();
-  CHECK_EQ(post_idle, 0);
-
-  // Log after testing because logging can allocate heap memory.
-  VLOG(0, "Original usage: %" PRIuS "\n", original);
-  VLOG(0, "Post allocation: %" PRIuS "\n", post_allocation);
-  VLOG(0, "Post idle: %" PRIuS "\n", post_idle);
-}
-
-int main(int argc, char** argv) {
-  RunThread(&TestIdleUsage);
-  RunThread(&TestAllocation);
-  RunThread(&MultipleIdleCalls);
-  RunThread(&MultipleIdleNonIdlePhases);
-  RunThread(&TestTemporarilyIdleUsage);
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/maybe_threads_unittest.sh b/third_party/tcmalloc/vendor/src/tests/maybe_threads_unittest.sh
deleted file mode 100755
index 77b3b788..0000000
--- a/third_party/tcmalloc/vendor/src/tests/maybe_threads_unittest.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2007, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Craig Silverstein
-#
-# maybe_threads.cc was written to allow LD_PRELOAD=libtcmalloc.so to
-# work even on binaries that were not linked with pthreads.  This
-# unittest tests that, by running low_level_alloc_unittest with an
-# LD_PRELOAD.  (low_level_alloc_unittest was chosen because it doesn't
-# link in tcmalloc.)
-#
-# We assume all the .so files are in the same directory as both
-# addressmap_unittest and profiler1_unittest.  The reason we need
-# profiler1_unittest is because it's instrumented to show the directory
-# it's "really" in when run without any args.  In practice this will either
-# be BINDIR, or, when using libtool, BINDIR/.lib.
-
-# We expect BINDIR to be set in the environment.
-# If not, we set them to some reasonable values.
-BINDIR="${BINDIR:-.}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir]"
-  echo "       By default, unittest_dir=$BINDIR"
-  exit 1
-fi
-
-UNITTEST_DIR=${1:-$BINDIR}
-
-# Figure out the "real" unittest directory.  Also holds the .so files.
-UNITTEST_DIR=`$UNITTEST_DIR/low_level_alloc_unittest --help 2>&1 \
-              | awk '{print $2; exit;}' \
-              | xargs dirname`
-
-# Figure out where libtcmalloc lives.   It should be in UNITTEST_DIR,
-# but with libtool it might be in a subdir.
-if [ -r "$UNITTEST_DIR/libtcmalloc_minimal.so" ]; then
-  LIB_PATH="$UNITTEST_DIR/libtcmalloc_minimal.so"
-elif [ -r "$UNITTEST_DIR/.libs/libtcmalloc_minimal.so" ]; then
-  LIB_PATH="$UNITTEST_DIR/.libs/libtcmalloc_minimal.so"
-elif [ -r "$UNITTEST_DIR/libtcmalloc_minimal.dylib" ]; then   # for os x
-  LIB_PATH="$UNITTEST_DIR/libtcmalloc_minimal.dylib"
-elif [ -r "$UNITTEST_DIR/.libs/libtcmalloc_minimal.dylib" ]; then
-  LIB_PATH="$UNITTEST_DIR/.libs/libtcmalloc_minimal.dylib"
-else
-  echo "Cannot run $0: cannot find libtcmalloc_minimal.so"
-  exit 2
-fi
-
-LD_PRELOAD="$LIB_PATH" $UNITTEST_DIR/low_level_alloc_unittest
diff --git a/third_party/tcmalloc/vendor/src/tests/memalign_unittest.cc b/third_party/tcmalloc/vendor/src/tests/memalign_unittest.cc
deleted file mode 100644
index 309a3df..0000000
--- a/third_party/tcmalloc/vendor/src/tests/memalign_unittest.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2004, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Check memalign related routines.
-//
-// We can't really do a huge amount of checking, but at the very
-// least, the following code checks that return values are properly
-// aligned, and that writing into the objects works.
-
-#include "config_for_unittests.h"
-
-// Complicated ordering requirements.  tcmalloc.h defines (indirectly)
-// _POSIX_C_SOURCE, which it needs so stdlib.h defines posix_memalign.
-// unistd.h, on the other hand, requires _POSIX_C_SOURCE to be unset,
-// at least on Mac OS X, in order to define getpagesize.  The solution
-// is to #include unistd.h first.  This is safe because unistd.h
-// doesn't sub-include stdlib.h, so we'll still get posix_memalign
-// when we #include stdlib.h.  Blah.
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>        // for getpagesize()
-#endif
-#include "tcmalloc.h"      // must come early, to pick up posix_memalign
-#include <assert.h>
-#include <stdlib.h>        // defines posix_memalign
-#include <stdio.h>         // for the printf at the end
-#ifdef HAVE_STDINT_H
-#include <stdint.h>        // for uintptr_t
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>        // for getpagesize()
-#endif
-// Malloc can be in several places on older versions of OS X.
-#if defined(HAVE_MALLOC_H)
-#include <malloc.h>        // for memalign() and valloc()
-#elif defined(HAVE_MALLOC_MALLOC_H)
-#include <malloc/malloc.h>
-#elif defined(HAVE_SYS_MALLOC_H)
-#include <sys/malloc.h>
-#endif
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "tests/testutil.h"
-
-
-// Return the next interesting size/delta to check.  Returns -1 if no more.
-static int NextSize(int size) {
-  if (size < 100) {
-    return size+1;
-  } else if (size < 1048576) {
-    // Find next power of two
-    int power = 1;
-    while (power < size) {
-      power <<= 1;
-    }
-
-    // Yield (power-1, power, power+1)
-    if (size < power-1) {
-      return power-1;
-    } else if (size == power-1) {
-      return power;
-    } else {
-      assert(size == power);
-      return power+1;
-    }
-  } else {
-    return -1;
-  }
-}
-
-// Shortform for cast
-static uintptr_t Number(void* p) {
-  return reinterpret_cast<uintptr_t>(p);
-}
-
-// Check alignment
-static void CheckAlignment(void* p, int align) {
-  if ((Number(p) & (align-1)) != 0)
-    LOG(FATAL, "wrong alignment; wanted 0x%x; got %p\n", align, p);
-}
-
-// Fill a buffer of the specified size with a predetermined pattern
-static void Fill(void* p, int n, char seed) {
-  unsigned char* buffer = reinterpret_cast<unsigned char*>(p);
-  for (int i = 0; i < n; i++) {
-    buffer[i] = ((seed + i) & 0xff);
-  }
-}
-
-// Check that the specified buffer has the predetermined pattern
-// generated by Fill()
-static bool Valid(const void* p, int n, char seed) {
-  const unsigned char* buffer = reinterpret_cast<const unsigned char*>(p);
-  for (int i = 0; i < n; i++) {
-    if (buffer[i] != ((seed + i) & 0xff)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-int main(int argc, char** argv) {
-  SetTestResourceLimit();
-
-  // Try allocating data with a bunch of alignments and sizes
-  for (int a = 1; a < 1048576; a *= 2) {
-    for (int s = 0; s != -1; s = NextSize(s)) {
-      void* ptr = memalign(a, s);
-      CheckAlignment(ptr, a);
-      Fill(ptr, s, 'x');
-      CHECK(Valid(ptr, s, 'x'));
-      free(ptr);
-
-      if ((a >= sizeof(void*)) && ((a & (a-1)) == 0)) {
-        CHECK(posix_memalign(&ptr, a, s) == 0);
-        CheckAlignment(ptr, a);
-        Fill(ptr, s, 'y');
-        CHECK(Valid(ptr, s, 'y'));
-        free(ptr);
-      }
-    }
-  }
-
-  {
-    // Check various corner cases
-    void* p1 = memalign(1<<20, 1<<19);
-    void* p2 = memalign(1<<19, 1<<19);
-    void* p3 = memalign(1<<21, 1<<19);
-    CheckAlignment(p1, 1<<20);
-    CheckAlignment(p2, 1<<19);
-    CheckAlignment(p3, 1<<21);
-    Fill(p1, 1<<19, 'a');
-    Fill(p2, 1<<19, 'b');
-    Fill(p3, 1<<19, 'c');
-    CHECK(Valid(p1, 1<<19, 'a'));
-    CHECK(Valid(p2, 1<<19, 'b'));
-    CHECK(Valid(p3, 1<<19, 'c'));
-    free(p1);
-    free(p2);
-    free(p3);
-  }
-
-  {
-    // posix_memalign
-    void* ptr;
-    CHECK(posix_memalign(&ptr, 0, 1) == EINVAL);
-    CHECK(posix_memalign(&ptr, sizeof(void*)/2, 1) == EINVAL);
-    CHECK(posix_memalign(&ptr, sizeof(void*)+1, 1) == EINVAL);
-    CHECK(posix_memalign(&ptr, 4097, 1) == EINVAL);
-
-    // Grab some memory so that the big allocation below will definitely fail.
-    void* p_small = malloc(4*1048576);
-    CHECK(p_small != NULL);
-
-    // Make sure overflow is returned as ENOMEM
-    const size_t zero = 0;
-    static const size_t kMinusNTimes = 10;
-    for ( size_t i = 1; i < kMinusNTimes; ++i ) {
-      int r = posix_memalign(&ptr, 1024, zero - i);
-      CHECK(r == ENOMEM);
-    }
-
-    free(p_small);
-  }
-
-  const int pagesize = getpagesize();
-  {
-    // valloc
-    for (int s = 0; s != -1; s = NextSize(s)) {
-      void* p = valloc(s);
-      CheckAlignment(p, pagesize);
-      Fill(p, s, 'v');
-      CHECK(Valid(p, s, 'v'));
-      free(p);
-    }
-  }
-
-  {
-    // pvalloc
-    for (int s = 0; s != -1; s = NextSize(s)) {
-      void* p = pvalloc(s);
-      CheckAlignment(p, pagesize);
-      int alloc_needed = ((s + pagesize - 1) / pagesize) * pagesize;
-      Fill(p, alloc_needed, 'x');
-      CHECK(Valid(p, alloc_needed, 'x'));
-      free(p);
-    }
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/packed-cache_test.cc b/third_party/tcmalloc/vendor/src/tests/packed-cache_test.cc
deleted file mode 100644
index 3984594c..0000000
--- a/third_party/tcmalloc/vendor/src/tests/packed-cache_test.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Geoff Pike
-
-#include <stdio.h>
-#include "base/logging.h"
-#include "packed-cache-inl.h"
-
-static const int kHashbits = PackedCache<20>::kHashbits;
-
-template <int kKeybits>
-static size_t MustGet(const PackedCache<kKeybits>& cache, uintptr_t key) {
-  uint32 rv;
-  CHECK(cache.TryGet(key, &rv));
-  return rv;
-}
-
-template <int kKeybits>
-static size_t Has(const PackedCache<kKeybits>& cache, uintptr_t key) {
-  uint32 dummy;
-  return cache.TryGet(key, &dummy);
-}
-
-// A basic sanity test.
-void PackedCacheTest_basic() {
-  PackedCache<20> cache;
-
-  CHECK(!Has(cache, 0));
-  cache.Put(0, 17);
-  CHECK(Has(cache, 0));
-  CHECK_EQ(MustGet(cache, 0), 17);
-
-  cache.Put(19, 99);
-  CHECK_EQ(MustGet(cache, 0), 17);
-  CHECK_EQ(MustGet(cache, 19), 99);
-
-  // Knock <0, 17> out by using a conflicting key.
-  cache.Put(1 << kHashbits, 22);
-  CHECK(!Has(cache, 0));
-  CHECK_EQ(MustGet(cache, 1 << kHashbits), 22);
-
-  cache.Invalidate(19);
-  CHECK(!Has(cache, 19));
-  CHECK(!Has(cache, 0));
-  CHECK(Has(cache, 1 << kHashbits));
-}
-
-int main(int argc, char **argv) {
-  PackedCacheTest_basic();
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/page_heap_test.cc b/third_party/tcmalloc/vendor/src/tests/page_heap_test.cc
deleted file mode 100644
index e82a1da..0000000
--- a/third_party/tcmalloc/vendor/src/tests/page_heap_test.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright 2009 Google Inc. All Rights Reserved.
-// Author: fikes@google.com (Andrew Fikes)
-//
-// Use of this source code is governed by a BSD-style license that can
-// be found in the LICENSE file.
-
-#include "config_for_unittests.h"
-#include "page_heap.h"
-#include "system-alloc.h"
-#include <stdio.h>
-#include "base/logging.h"
-#include "common.h"
-
-DECLARE_int64(tcmalloc_heap_limit_mb);
-
-namespace {
-
-// The system will only release memory if the block size is equal or hight than
-// system page size.
-static bool HaveSystemRelease =
-    TCMalloc_SystemRelease(
-      TCMalloc_SystemAlloc(getpagesize(), NULL, 0), getpagesize());
-
-static void CheckStats(const tcmalloc::PageHeap* ph,
-                       uint64_t system_pages,
-                       uint64_t free_pages,
-                       uint64_t unmapped_pages) {
-  tcmalloc::PageHeap::Stats stats = ph->stats();
-
-  if (!HaveSystemRelease) {
-    free_pages += unmapped_pages;
-    unmapped_pages = 0;
-  }
-
-  EXPECT_EQ(system_pages, stats.system_bytes >> kPageShift);
-  EXPECT_EQ(free_pages, stats.free_bytes >> kPageShift);
-  EXPECT_EQ(unmapped_pages, stats.unmapped_bytes >> kPageShift);
-}
-
-static void TestPageHeap_Stats() {
-  tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();
-
-  // Empty page heap
-  CheckStats(ph, 0, 0, 0);
-
-  // Allocate a span 's1'
-  tcmalloc::Span* s1 = ph->New(256);
-  CheckStats(ph, 256, 0, 0);
-
-  // Split span 's1' into 's1', 's2'.  Delete 's2'
-  tcmalloc::Span* s2 = ph->Split(s1, 128);
-  ph->Delete(s2);
-  CheckStats(ph, 256, 128, 0);
-
-  // Unmap deleted span 's2'
-  ph->ReleaseAtLeastNPages(1);
-  CheckStats(ph, 256, 0, 128);
-
-  // Delete span 's1'
-  ph->Delete(s1);
-  CheckStats(ph, 256, 128, 128);
-
-  delete ph;
-}
-
-static void TestPageHeap_Limit() {
-  tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();
-
-  CHECK_EQ(kMaxPages, 1 << (20 - kPageShift));
-
-  // We do not know much is taken from the system for other purposes,
-  // so we detect the proper limit:
-  {
-    FLAGS_tcmalloc_heap_limit_mb = 1;
-    tcmalloc::Span* s = NULL;
-    while((s = ph->New(kMaxPages)) == NULL) {
-      FLAGS_tcmalloc_heap_limit_mb++;
-    }
-    FLAGS_tcmalloc_heap_limit_mb += 9;
-    ph->Delete(s);
-    // We are [10, 11) mb from the limit now.
-  }
-
-  // Test AllocLarge and GrowHeap first:
-  {
-    tcmalloc::Span * spans[10];
-    for (int i=0; i<10; ++i) {
-      spans[i] = ph->New(kMaxPages);
-      EXPECT_NE(spans[i], NULL);
-    }
-    EXPECT_EQ(ph->New(kMaxPages), NULL);
-
-    for (int i=0; i<10; i += 2) {
-      ph->Delete(spans[i]);
-    }
-
-    tcmalloc::Span *defragmented = ph->New(5 * kMaxPages);
-
-    if (HaveSystemRelease) {
-      // EnsureLimit should release deleted normal spans
-      EXPECT_NE(defragmented, NULL);
-      EXPECT_TRUE(ph->CheckExpensive());
-      ph->Delete(defragmented);
-    }
-    else
-    {
-      EXPECT_EQ(defragmented, NULL);
-      EXPECT_TRUE(ph->CheckExpensive());
-    }
-
-    for (int i=1; i<10; i += 2) {
-      ph->Delete(spans[i]);
-    }
-  }
-
-  // Once again, testing small lists this time (twice smaller spans):
-  {
-    tcmalloc::Span * spans[20];
-    for (int i=0; i<20; ++i) {
-      spans[i] = ph->New(kMaxPages >> 1);
-      EXPECT_NE(spans[i], NULL);
-    }
-    // one more half size allocation may be possible:
-    tcmalloc::Span * lastHalf = ph->New(kMaxPages >> 1);
-    EXPECT_EQ(ph->New(kMaxPages >> 1), NULL);
-
-    for (int i=0; i<20; i += 2) {
-      ph->Delete(spans[i]);
-    }
-
-    for(Length len = kMaxPages >> 2; len < 5 * kMaxPages; len = len << 1)
-    {
-      if(len <= kMaxPages >> 1 || HaveSystemRelease) {
-        tcmalloc::Span *s = ph->New(len);
-        EXPECT_NE(s, NULL);
-        ph->Delete(s);
-      }
-    }
-
-    EXPECT_TRUE(ph->CheckExpensive());
-
-    for (int i=1; i<20; i += 2) {
-      ph->Delete(spans[i]);
-    }
-
-    if (lastHalf != NULL) {
-      ph->Delete(lastHalf);
-    }
-  }
-
-  delete ph;
-}
-
-}  // namespace
-
-int main(int argc, char **argv) {
-  TestPageHeap_Stats();
-  TestPageHeap_Limit();
-  printf("PASS\n");
-  // on windows as part of library destructors we call getenv which
-  // calls malloc which fails due to our exhausted heap limit. It then
-  // causes fancy stack overflow because log message we're printing
-  // for failed allocation somehow cause malloc calls too
-  //
-  // To keep us out of trouble we just drop malloc limit
-  FLAGS_tcmalloc_heap_limit_mb = 0;
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/pagemap_unittest.cc b/third_party/tcmalloc/vendor/src/tests/pagemap_unittest.cc
deleted file mode 100644
index 88d46e7..0000000
--- a/third_party/tcmalloc/vendor/src/tests/pagemap_unittest.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2003, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#include <stdlib.h>
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get intptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place intptr_t might be defined
-#endif
-#include <sys/types.h>
-#include <vector>
-#include "base/logging.h"
-#include "pagemap.h"
-
-using std::vector;
-
-static void Permute(vector<intptr_t>* elements) {
-  if (elements->empty())
-    return;
-  const size_t num_elements = elements->size();
-  for (size_t i = num_elements - 1; i > 0; --i) {
-    const size_t newpos = rand() % (i + 1);
-    const intptr_t tmp = (*elements)[i];   // swap
-    (*elements)[i] = (*elements)[newpos];
-    (*elements)[newpos] = tmp;
-  }
-}
-
-// Note: we leak memory every time a map is constructed, so do not
-// create too many maps.
-
-// Test specified map type
-template <class Type>
-void TestMap(int limit, bool limit_is_below_the_overflow_boundary) {
-  RAW_LOG(INFO, "Running test with %d iterations...\n", limit);
-
-  { // Test sequential ensure/assignment
-    Type map(malloc);
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      map.Ensure(i, 1);
-      map.set(i, (void*)(i+1));
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-  }
-
-  { // Test bulk Ensure
-    Type map(malloc);
-    map.Ensure(0, limit);
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      map.set(i, (void*)(i+1));
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-  }
-
-  // Test that we correctly notice overflow
-  {
-    Type map(malloc);
-    CHECK_EQ(map.Ensure(limit, limit+1), limit_is_below_the_overflow_boundary);
-  }
-
-  { // Test randomized accesses
-    srand(301);   // srand isn't great, but it's portable
-    vector<intptr_t> elements;
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) elements.push_back(i);
-    Permute(&elements);
-
-    Type map(malloc);
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      map.Ensure(elements[i], 1);
-      map.set(elements[i], (void*)(elements[i]+1));
-      CHECK_EQ(map.get(elements[i]), (void*)(elements[i]+1));
-    }
-    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {
-      CHECK_EQ(map.get(i), (void*)(i+1));
-    }
-  }
-}
-
-// REQUIRES: BITS==10, i.e., valid range is [0,1023].
-// Representations for different types will end up being:
-//    PageMap1: array[1024]
-//    PageMap2: array[32][32]
-//    PageMap3: array[16][16][4]
-template <class Type>
-void TestNext(const char* name) {
-  RAW_LOG(ERROR, "Running NextTest %s\n", name);
-  Type map(malloc);
-  char a, b, c, d, e;
-
-  // When map is empty
-  CHECK(map.Next(0) == NULL);
-  CHECK(map.Next(5) == NULL);
-  CHECK(map.Next(1<<30) == NULL);
-
-  // Add a single value
-  map.Ensure(40, 1);
-  map.set(40, &a);
-  CHECK(map.Next(0) == &a);
-  CHECK(map.Next(39) == &a);
-  CHECK(map.Next(40) == &a);
-  CHECK(map.Next(41) == NULL);
-  CHECK(map.Next(1<<30) == NULL);
-
-  // Add a few values
-  map.Ensure(41, 1);
-  map.Ensure(100, 3);
-  map.set(41, &b);
-  map.set(100, &c);
-  map.set(101, &d);
-  map.set(102, &e);
-  CHECK(map.Next(0) == &a);
-  CHECK(map.Next(39) == &a);
-  CHECK(map.Next(40) == &a);
-  CHECK(map.Next(41) == &b);
-  CHECK(map.Next(42) == &c);
-  CHECK(map.Next(63) == &c);
-  CHECK(map.Next(64) == &c);
-  CHECK(map.Next(65) == &c);
-  CHECK(map.Next(99) == &c);
-  CHECK(map.Next(100) == &c);
-  CHECK(map.Next(101) == &d);
-  CHECK(map.Next(102) == &e);
-  CHECK(map.Next(103) == NULL);
-}
-
-int main(int argc, char** argv) {
-  TestMap< TCMalloc_PageMap1<10> > (100, true);
-  TestMap< TCMalloc_PageMap1<10> > (1 << 10, false);
-  TestMap< TCMalloc_PageMap2<20> > (100, true);
-  TestMap< TCMalloc_PageMap2<20> > (1 << 20, false);
-  TestMap< TCMalloc_PageMap3<20> > (100, true);
-  TestMap< TCMalloc_PageMap3<20> > (1 << 20, false);
-
-  TestNext< TCMalloc_PageMap1<10> >("PageMap1");
-  TestNext< TCMalloc_PageMap2<10> >("PageMap2");
-  TestNext< TCMalloc_PageMap3<10> >("PageMap3");
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/profile-handler_unittest.cc b/third_party/tcmalloc/vendor/src/tests/profile-handler_unittest.cc
deleted file mode 100644
index a8afbca..0000000
--- a/third_party/tcmalloc/vendor/src/tests/profile-handler_unittest.cc
+++ /dev/null
@@ -1,398 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright 2009 Google Inc. All Rights Reserved.
-// Author: Nabeel Mian (nabeelmian@google.com)
-//         Chris Demetriou (cgd@google.com)
-//
-// Use of this source code is governed by a BSD-style license that can
-// be found in the LICENSE file.
-//
-//
-// This file contains the unit tests for profile-handler.h interface.
-
-#include "config.h"
-#include "profile-handler.h"
-
-#include <assert.h>
-#include <pthread.h>
-#include <sys/time.h>
-#include <time.h>
-#include "base/logging.h"
-#include "base/simple_mutex.h"
-
-// Some helpful macros for the test class
-#define TEST_F(cls, fn)    void cls :: fn()
-
-// Do we expect the profiler to be enabled?
-DEFINE_bool(test_profiler_enabled, true,
-            "expect profiler to be enabled during tests");
-
-namespace {
-
-// TODO(csilvers): error-checking on the pthreads routines
-class Thread {
- public:
-  Thread() : joinable_(false) { }
-  virtual ~Thread() { }
-  void SetJoinable(bool value) { joinable_ = value; }
-  void Start() {
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-    pthread_attr_setdetachstate(&attr, joinable_ ? PTHREAD_CREATE_JOINABLE
-                                                 : PTHREAD_CREATE_DETACHED);
-    pthread_create(&thread_, &attr, &DoRun, this);
-    pthread_attr_destroy(&attr);
-  }
-  void Join()  {
-    assert(joinable_);
-    pthread_join(thread_, NULL);
-  }
-  virtual void Run() = 0;
- private:
-  static void* DoRun(void* cls) {
-    ProfileHandlerRegisterThread();
-    reinterpret_cast<Thread*>(cls)->Run();
-    return NULL;
-  }
-  pthread_t thread_;
-  bool joinable_;
-};
-
-// Sleep interval in nano secs. ITIMER_PROF goes off only afer the specified CPU
-// time is consumed. Under heavy load this process may no get scheduled in a
-// timely fashion. Therefore, give enough time (20x of ProfileHandle timer
-// interval 10ms (100Hz)) for this process to accumulate enought CPU time to get
-// a profile tick.
-int kSleepInterval = 200000000;
-
-// Sleep interval in nano secs. To ensure that if the timer has expired it is
-// reset.
-int kTimerResetInterval = 5000000;
-
-static bool linux_per_thread_timers_mode_ = false;
-static int timer_type_ = ITIMER_PROF;
-
-// Delays processing by the specified number of nano seconds. 'delay_ns'
-// must be less than the number of nano seconds in a second (1000000000).
-void Delay(int delay_ns) {
-  static const int kNumNSecInSecond = 1000000000;
-  EXPECT_LT(delay_ns, kNumNSecInSecond);
-  struct timespec delay = { 0, delay_ns };
-  nanosleep(&delay, 0);
-}
-
-// Checks whether the profile timer is enabled for the current thread.
-bool IsTimerEnabled() {
-  itimerval current_timer;
-  EXPECT_EQ(0, getitimer(timer_type_, &current_timer));
-  if ((current_timer.it_value.tv_sec == 0) &&
-      (current_timer.it_value.tv_usec != 0)) {
-    // May be the timer has expired. Sleep for a bit and check again.
-    Delay(kTimerResetInterval);
-    EXPECT_EQ(0, getitimer(timer_type_, &current_timer));
-  }
-  return (current_timer.it_value.tv_sec != 0 ||
-          current_timer.it_value.tv_usec != 0);
-}
-
-// Dummy worker thread to accumulate cpu time.
-class BusyThread : public Thread {
- public:
-  BusyThread() : stop_work_(false) {
-  }
-
-  // Setter/Getters
-  bool stop_work() {
-    MutexLock lock(&mu_);
-    return stop_work_;
-  }
-  void set_stop_work(bool stop_work) {
-    MutexLock lock(&mu_);
-    stop_work_ = stop_work;
-  }
-
- private:
-  // Protects stop_work_ below.
-  Mutex mu_;
-  // Whether to stop work?
-  bool stop_work_;
-
-  // Do work until asked to stop.
-  void Run() {
-    while (!stop_work()) {
-    }
-  }
-};
-
-class NullThread : public Thread {
- private:
-  void Run() {
-  }
-};
-
-// Signal handler which tracks the profile timer ticks.
-static void TickCounter(int sig, siginfo_t* sig_info, void *vuc,
-                        void* tick_counter) {
-  int* counter = static_cast<int*>(tick_counter);
-  ++(*counter);
-}
-
-// This class tests the profile-handler.h interface.
-class ProfileHandlerTest {
- protected:
-
-  // Determines the timer type.
-  static void SetUpTestCase() {
-    timer_type_ = (getenv("CPUPROFILE_REALTIME") ? ITIMER_REAL : ITIMER_PROF);
-
-#if HAVE_LINUX_SIGEV_THREAD_ID
-    linux_per_thread_timers_mode_ = (getenv("CPUPROFILE_PER_THREAD_TIMERS") != NULL);
-    const char *signal_number = getenv("CPUPROFILE_TIMER_SIGNAL");
-    if (signal_number) {
-      //signal_number_ = strtol(signal_number, NULL, 0);
-      linux_per_thread_timers_mode_ = true;
-      Delay(kTimerResetInterval);
-    }
-#endif
-  }
-
-  // Sets up the profile timers and SIGPROF/SIGALRM handler in a known state.
-  // It does the following:
-  // 1. Unregisters all the callbacks, stops the timer and clears out
-  //    timer_sharing state in the ProfileHandler. This clears out any state
-  //    left behind by the previous test or during module initialization when
-  //    the test program was started.
-  // 3. Starts a busy worker thread to accumulate CPU usage.
-  virtual void SetUp() {
-    // Reset the state of ProfileHandler between each test. This unregisters
-    // all callbacks and stops the timer.
-    ProfileHandlerReset();
-    EXPECT_EQ(0, GetCallbackCount());
-    VerifyDisabled();
-    // Start worker to accumulate cpu usage.
-    StartWorker();
-  }
-
-  virtual void TearDown() {
-    ProfileHandlerReset();
-    // Stops the worker thread.
-    StopWorker();
-  }
-
-  // Starts a busy worker thread to accumulate cpu time. There should be only
-  // one busy worker running. This is required for the case where there are
-  // separate timers for each thread.
-  void StartWorker() {
-    busy_worker_ = new BusyThread();
-    busy_worker_->SetJoinable(true);
-    busy_worker_->Start();
-    // Wait for worker to start up and register with the ProfileHandler.
-    // TODO(nabeelmian) This may not work under very heavy load.
-    Delay(kSleepInterval);
-  }
-
-  // Stops the worker thread.
-  void StopWorker() {
-    busy_worker_->set_stop_work(true);
-    busy_worker_->Join();
-    delete busy_worker_;
-  }
-
-  // Gets the number of callbacks registered with the ProfileHandler.
-  uint32 GetCallbackCount() {
-    ProfileHandlerState state;
-    ProfileHandlerGetState(&state);
-    return state.callback_count;
-  }
-
-  // Gets the current ProfileHandler interrupt count.
-  uint64 GetInterruptCount() {
-    ProfileHandlerState state;
-    ProfileHandlerGetState(&state);
-    return state.interrupts;
-  }
-
-  // Verifies that a callback is correctly registered and receiving
-  // profile ticks.
-  void VerifyRegistration(const int& tick_counter) {
-    // Check the callback count.
-    EXPECT_GT(GetCallbackCount(), 0);
-    // Check that the profile timer is enabled.
-    EXPECT_EQ(FLAGS_test_profiler_enabled, linux_per_thread_timers_mode_ || IsTimerEnabled());
-    uint64 interrupts_before = GetInterruptCount();
-    // Sleep for a bit and check that tick counter is making progress.
-    int old_tick_count = tick_counter;
-    Delay(kSleepInterval);
-    int new_tick_count = tick_counter;
-    uint64 interrupts_after = GetInterruptCount();
-    if (FLAGS_test_profiler_enabled) {
-      EXPECT_GT(new_tick_count, old_tick_count);
-      EXPECT_GT(interrupts_after, interrupts_before);
-    } else {
-      EXPECT_EQ(new_tick_count, old_tick_count);
-      EXPECT_EQ(interrupts_after, interrupts_before);
-    }
-  }
-
-  // Verifies that a callback is not receiving profile ticks.
-  void VerifyUnregistration(const int& tick_counter) {
-    // Sleep for a bit and check that tick counter is not making progress.
-    int old_tick_count = tick_counter;
-    Delay(kSleepInterval);
-    int new_tick_count = tick_counter;
-    EXPECT_EQ(old_tick_count, new_tick_count);
-    // If no callbacks, timer should be disabled.
-    if (GetCallbackCount() == 0) {
-      EXPECT_FALSE(IsTimerEnabled());
-    }
-  }
-
-  // Verifies that the timer is disabled. Expects the worker to be running.
-  void VerifyDisabled() {
-    // Check that the callback count is 0.
-    EXPECT_EQ(0, GetCallbackCount());
-    // Check that the timer is disabled.
-    EXPECT_FALSE(IsTimerEnabled());
-    // Verify that the ProfileHandler is not accumulating profile ticks.
-    uint64 interrupts_before = GetInterruptCount();
-    Delay(kSleepInterval);
-    uint64 interrupts_after = GetInterruptCount();
-    EXPECT_EQ(interrupts_before, interrupts_after);
-  }
-
-  // Registers a callback and waits for kTimerResetInterval for timers to get
-  // reset.
-  ProfileHandlerToken* RegisterCallback(void* callback_arg) {
-    ProfileHandlerToken* token = ProfileHandlerRegisterCallback(
-        TickCounter, callback_arg);
-    Delay(kTimerResetInterval);
-    return token;
-  }
-
-  // Unregisters a callback and waits for kTimerResetInterval for timers to get
-  // reset.
-  void UnregisterCallback(ProfileHandlerToken* token) {
-    ProfileHandlerUnregisterCallback(token);
-    Delay(kTimerResetInterval);
-  }
-
-  // Busy worker thread to accumulate cpu usage.
-  BusyThread* busy_worker_;
-
- private:
-  // The tests to run
-  void RegisterUnregisterCallback();
-  void MultipleCallbacks();
-  void Reset();
-  void RegisterCallbackBeforeThread();
-
- public:
-#define RUN(test)  do {                         \
-    printf("Running %s\n", #test);              \
-    ProfileHandlerTest pht;                     \
-    pht.SetUp();                                \
-    pht.test();                                 \
-    pht.TearDown();                             \
-} while (0)
-
-  static int RUN_ALL_TESTS() {
-    SetUpTestCase();
-    RUN(RegisterUnregisterCallback);
-    RUN(MultipleCallbacks);
-    RUN(Reset);
-    RUN(RegisterCallbackBeforeThread);
-    printf("Done\n");
-    return 0;
-  }
-};
-
-// Verifies ProfileHandlerRegisterCallback and
-// ProfileHandlerUnregisterCallback.
-TEST_F(ProfileHandlerTest, RegisterUnregisterCallback) {
-  int tick_count = 0;
-  ProfileHandlerToken* token = RegisterCallback(&tick_count);
-  VerifyRegistration(tick_count);
-  UnregisterCallback(token);
-  VerifyUnregistration(tick_count);
-}
-
-// Verifies that multiple callbacks can be registered.
-TEST_F(ProfileHandlerTest, MultipleCallbacks) {
-  // Register first callback.
-  int first_tick_count = 0;
-  ProfileHandlerToken* token1 = RegisterCallback(&first_tick_count);
-  // Check that callback was registered correctly.
-  VerifyRegistration(first_tick_count);
-  EXPECT_EQ(1, GetCallbackCount());
-
-  // Register second callback.
-  int second_tick_count = 0;
-  ProfileHandlerToken* token2 = RegisterCallback(&second_tick_count);
-  // Check that callback was registered correctly.
-  VerifyRegistration(second_tick_count);
-  EXPECT_EQ(2, GetCallbackCount());
-
-  // Unregister first callback.
-  UnregisterCallback(token1);
-  VerifyUnregistration(first_tick_count);
-  EXPECT_EQ(1, GetCallbackCount());
-  // Verify that second callback is still registered.
-  VerifyRegistration(second_tick_count);
-
-  // Unregister second callback.
-  UnregisterCallback(token2);
-  VerifyUnregistration(second_tick_count);
-  EXPECT_EQ(0, GetCallbackCount());
-
-  // Verify that the timers is correctly disabled.
-  if (!linux_per_thread_timers_mode_) VerifyDisabled();
-}
-
-// Verifies ProfileHandlerReset
-TEST_F(ProfileHandlerTest, Reset) {
-  // Verify that the profile timer interrupt is disabled.
-  if (!linux_per_thread_timers_mode_) VerifyDisabled();
-  int first_tick_count = 0;
-  RegisterCallback(&first_tick_count);
-  VerifyRegistration(first_tick_count);
-  EXPECT_EQ(1, GetCallbackCount());
-
-  // Register second callback.
-  int second_tick_count = 0;
-  RegisterCallback(&second_tick_count);
-  VerifyRegistration(second_tick_count);
-  EXPECT_EQ(2, GetCallbackCount());
-
-  // Reset the profile handler and verify that callback were correctly
-  // unregistered and the timer is disabled.
-  ProfileHandlerReset();
-  VerifyUnregistration(first_tick_count);
-  VerifyUnregistration(second_tick_count);
-  if (!linux_per_thread_timers_mode_) VerifyDisabled();
-}
-
-// Verifies that ProfileHandler correctly handles a case where a callback was
-// registered before the second thread started.
-TEST_F(ProfileHandlerTest, RegisterCallbackBeforeThread) {
-  // Stop the worker.
-  StopWorker();
-  // Unregister all existing callbacks and stop the timer.
-  ProfileHandlerReset();
-  EXPECT_EQ(0, GetCallbackCount());
-  VerifyDisabled();
-
-  // Start the worker.
-  StartWorker();
-  // Register a callback and check that profile ticks are being delivered and
-  // the timer is enabled.
-  int tick_count = 0;
-  RegisterCallback(&tick_count);
-  EXPECT_EQ(1, GetCallbackCount());
-  VerifyRegistration(tick_count);
-  EXPECT_EQ(FLAGS_test_profiler_enabled, linux_per_thread_timers_mode_ || IsTimerEnabled());
-}
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  return ProfileHandlerTest::RUN_ALL_TESTS();
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/profiledata_unittest.cc b/third_party/tcmalloc/vendor/src/tests/profiledata_unittest.cc
deleted file mode 100644
index 3286b9c8..0000000
--- a/third_party/tcmalloc/vendor/src/tests/profiledata_unittest.cc
+++ /dev/null
@@ -1,612 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Chris Demetriou
-//
-// This file contains the unit tests for the ProfileData class.
-
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uintptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uintptr_t might be defined
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <string.h>
-#include <string>
-
-#include "profiledata.h"
-
-#include "base/commandlineflags.h"
-#include "base/logging.h"
-
-using std::string;
-
-// Some helpful macros for the test class
-#define TEST_F(cls, fn)    void cls :: fn()
-
-namespace {
-
-template<typename T> class scoped_array {
- public:
-  scoped_array(T* data) : data_(data) { }
-  ~scoped_array() { delete[] data_; }
-  T* get() { return data_; }
-  T& operator[](int i) { return data_[i]; }
- private:
-  T* const data_;
-};
-
-// Re-runs fn until it doesn't cause EINTR.
-#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
-
-// Read up to "count" bytes from file descriptor "fd" into the buffer
-// starting at "buf" while handling short reads and EINTR.  On
-// success, return the number of bytes read.  Otherwise, return -1.
-static ssize_t ReadPersistent(const int fd, void *buf, const size_t count) {
-  CHECK_GE(fd, 0);
-  char *buf0 = reinterpret_cast<char *>(buf);
-  ssize_t num_bytes = 0;
-  while (num_bytes < count) {
-    ssize_t len;
-    NO_INTR(len = read(fd, buf0 + num_bytes, count - num_bytes));
-    if (len < 0) {  // There was an error other than EINTR.
-      return -1;
-    }
-    if (len == 0) {  // Reached EOF.
-      break;
-    }
-    num_bytes += len;
-  }
-  CHECK(num_bytes <= count);
-  return num_bytes;
-}
-
-// Thin wrapper around a file descriptor so that the file descriptor
-// gets closed for sure.
-struct FileDescriptor {
-  const int fd_;
-  explicit FileDescriptor(int fd) : fd_(fd) {}
-  ~FileDescriptor() {
-    if (fd_ >= 0) {
-      NO_INTR(close(fd_));
-    }
-  }
-  int get() { return fd_; }
-};
-
-// must be the same as with ProfileData::Slot.
-typedef uintptr_t ProfileDataSlot;
-
-// Quick and dirty function to make a number into a void* for use in a
-// sample.
-inline void* V(intptr_t x) { return reinterpret_cast<void*>(x); }
-
-// String returned by ProfileDataChecker helper functions to indicate success.
-const char kNoError[] = "";
-
-class ProfileDataChecker {
- public:
-  ProfileDataChecker() {
-    const char* tmpdir = getenv("TMPDIR");
-    if (tmpdir == NULL)
-      tmpdir = "/tmp";
-    mkdir(tmpdir, 0755);     // if necessary
-    filename_ = string(tmpdir) + "/profiledata_unittest.tmp";
-  }
-
-  string filename() const { return filename_; }
-
-  // Checks the first 'num_slots' profile data slots in the file
-  // against the data pointed to by 'slots'.  Returns kNoError if the
-  // data matched, otherwise returns an indication of the cause of the
-  // mismatch.
-  string Check(const ProfileDataSlot* slots, int num_slots) {
-    return CheckWithSkips(slots, num_slots, NULL, 0);
-  }
-
-  // Checks the first 'num_slots' profile data slots in the file
-  // against the data pointed to by 'slots', skipping over entries
-  // described by 'skips' and 'num_skips'.
-  //
-  // 'skips' must be a sorted list of (0-based) slot numbers to be
-  // skipped, of length 'num_skips'.  Note that 'num_slots' includes
-  // any skipped slots, i.e., the first 'num_slots' profile data slots
-  // will be considered, but some may be skipped.
-  //
-  // Returns kNoError if the data matched, otherwise returns an
-  // indication of the cause of the mismatch.
-  string CheckWithSkips(const ProfileDataSlot* slots, int num_slots,
-                        const int* skips, int num_skips);
-
-  // Validate that a profile is correctly formed.  The profile is
-  // assumed to have been created by the same kind of binary (e.g.,
-  // same slot size, same endian, etc.) as is validating the profile.
-  //
-  // Returns kNoError if the profile appears valid, otherwise returns
-  // an indication of the problem with the profile.
-  string ValidateProfile();
-
- private:
-  string filename_;
-};
-
-string ProfileDataChecker::CheckWithSkips(const ProfileDataSlot* slots,
-                                          int num_slots, const int* skips,
-                                          int num_skips) {
-  FileDescriptor fd(open(filename_.c_str(), O_RDONLY));
-  if (fd.get() < 0)
-    return "file open error";
-
-  scoped_array<ProfileDataSlot> filedata(new ProfileDataSlot[num_slots]);
-  size_t expected_bytes = num_slots * sizeof filedata[0];
-  ssize_t bytes_read = ReadPersistent(fd.get(), filedata.get(), expected_bytes);
-  if (expected_bytes != bytes_read)
-    return "file too small";
-
-  for (int i = 0; i < num_slots; i++) {
-    if (num_skips > 0 && *skips == i) {
-      num_skips--;
-      skips++;
-      continue;
-    }
-    if (slots[i] != filedata[i])
-      return "data mismatch";
-  }
-  return kNoError;
-}
-
-string ProfileDataChecker::ValidateProfile() {
-  FileDescriptor fd(open(filename_.c_str(), O_RDONLY));
-  if (fd.get() < 0)
-    return "file open error";
-
-  struct stat statbuf;
-  if (fstat(fd.get(), &statbuf) != 0)
-    return "fstat error";
-  if (statbuf.st_size != static_cast<ssize_t>(statbuf.st_size))
-    return "file impossibly large";
-  ssize_t filesize = statbuf.st_size;
-
-  scoped_array<char> filedata(new char[filesize]);
-  if (ReadPersistent(fd.get(), filedata.get(), filesize) != filesize)
-    return "read of whole file failed";
-
-  // Must have enough data for the header and the trailer.
-  if (filesize < (5 + 3) * sizeof(ProfileDataSlot))
-    return "not enough data in profile for header + trailer";
-
-  // Check the header
-  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[0] != 0)
-    return "error in header: non-zero count";
-  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[1] != 3)
-    return "error in header: num_slots != 3";
-  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[2] != 0)
-    return "error in header: non-zero format version";
-  // Period (slot 3) can have any value.
-  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[4] != 0)
-    return "error in header: non-zero padding value";
-  ssize_t cur_offset = 5 * sizeof(ProfileDataSlot);
-
-  // While there are samples, skip them.  Each sample consists of
-  // at least three slots.
-  bool seen_trailer = false;
-  while (!seen_trailer) {
-    if (cur_offset > filesize - 3 * sizeof(ProfileDataSlot))
-      return "truncated sample header";
-    ProfileDataSlot* sample =
-        reinterpret_cast<ProfileDataSlot*>(filedata.get() + cur_offset);
-    ProfileDataSlot slots_this_sample = 2 + sample[1];
-    ssize_t size_this_sample = slots_this_sample * sizeof(ProfileDataSlot);
-    if (cur_offset > filesize - size_this_sample)
-      return "truncated sample";
-
-    if (sample[0] == 0 && sample[1] == 1 && sample[2] == 0) {
-      seen_trailer = true;
-    } else {
-      if (sample[0] < 1)
-        return "error in sample: sample count < 1";
-      if (sample[1] < 1)
-        return "error in sample: num_pcs < 1";
-      for (int i = 2; i < slots_this_sample; i++) {
-        if (sample[i] == 0)
-          return "error in sample: NULL PC";
-      }
-    }
-    cur_offset += size_this_sample;
-  }
-
-  // There must be at least one line in the (text) list of mapped objects,
-  // and it must be terminated by a newline.  Note, the use of newline
-  // here and below Might not be reasonable on non-UNIX systems.
-  if (cur_offset >= filesize)
-    return "no list of mapped objects";
-  if (filedata[filesize - 1] != '\n')
-    return "profile did not end with a complete line";
-
-  while (cur_offset < filesize) {
-    char* line_start = filedata.get() + cur_offset;
-
-    // Find the end of the line, and replace it with a NUL for easier
-    // scanning.
-    char* line_end = strchr(line_start, '\n');
-    *line_end = '\0';
-
-    // Advance past any leading space.  It's allowed in some lines,
-    // but not in others.
-    bool has_leading_space = false;
-    char* line_cur = line_start;
-    while (*line_cur == ' ') {
-      has_leading_space = true;
-      line_cur++;
-    }
-
-    bool found_match = false;
-
-    // Check for build lines.
-    if (!found_match) {
-      found_match = (strncmp(line_cur, "build=", 6) == 0);
-      // Anything may follow "build=", and leading space is allowed.
-    }
-
-    // A line from ProcMapsIterator::FormatLine, of the form:
-    //
-    // 40000000-40015000 r-xp 00000000 03:01 12845071   /lib/ld-2.3.2.so
-    //
-    // Leading space is not allowed.  The filename may be omitted or
-    // may consist of multiple words, so we scan only up to the
-    // space before the filename.
-    if (!found_match) {
-      int chars_scanned = -1;
-      sscanf(line_cur, "%*x-%*x %*c%*c%*c%*c %*x %*x:%*x %*d %n",
-             &chars_scanned);
-      found_match = (chars_scanned > 0 && !has_leading_space);
-    }
-
-    // A line from DumpAddressMap, of the form:
-    //
-    // 40000000-40015000: /lib/ld-2.3.2.so
-    //
-    // Leading space is allowed.  The filename may be omitted or may
-    // consist of multiple words, so we scan only up to the space
-    // before the filename.
-    if (!found_match) {
-      int chars_scanned = -1;
-      sscanf(line_cur, "%*x-%*x: %n", &chars_scanned);
-      found_match = (chars_scanned > 0);
-    }
-
-    if (!found_match)
-      return "unrecognized line in text section";
-
-    cur_offset += (line_end - line_start) + 1;
-  }
-
-  return kNoError;
-}
-
-class ProfileDataTest {
- protected:
-  void ExpectStopped() {
-    EXPECT_FALSE(collector_.enabled());
-  }
-
-  void ExpectRunningSamples(int samples) {
-    ProfileData::State state;
-    collector_.GetCurrentState(&state);
-    EXPECT_TRUE(state.enabled);
-    EXPECT_EQ(samples, state.samples_gathered);
-  }
-
-  void ExpectSameState(const ProfileData::State& before,
-                       const ProfileData::State& after) {
-    EXPECT_EQ(before.enabled, after.enabled);
-    EXPECT_EQ(before.samples_gathered, after.samples_gathered);
-    EXPECT_EQ(before.start_time, after.start_time);
-    EXPECT_STREQ(before.profile_name, after.profile_name);
-  }
-
-  ProfileData        collector_;
-  ProfileDataChecker checker_;
-
- private:
-  // The tests to run
-  void OpsWhenStopped();
-  void StartStopEmpty();
-  void StartStopNoOptionsEmpty();
-  void StartWhenStarted();
-  void StartStopEmpty2();
-  void CollectOne();
-  void CollectTwoMatching();
-  void CollectTwoFlush();
-  void StartResetRestart();
-
- public:
-#define RUN(test)  do {                         \
-    printf("Running %s\n", #test);              \
-    ProfileDataTest pdt;                        \
-    pdt.test();                                 \
-} while (0)
-
-  static int RUN_ALL_TESTS() {
-    RUN(OpsWhenStopped);
-    RUN(StartStopEmpty);
-    RUN(StartWhenStarted);
-    RUN(StartStopEmpty2);
-    RUN(CollectOne);
-    RUN(CollectTwoMatching);
-    RUN(CollectTwoFlush);
-    RUN(StartResetRestart);
-    RUN(StartStopNoOptionsEmpty);
-    return 0;
-  }
-};
-
-// Check that various operations are safe when stopped.
-TEST_F(ProfileDataTest, OpsWhenStopped) {
-  ExpectStopped();
-  EXPECT_FALSE(collector_.enabled());
-
-  // Verify that state is disabled, all-empty/all-0
-  ProfileData::State state_before;
-  collector_.GetCurrentState(&state_before);
-  EXPECT_FALSE(state_before.enabled);
-  EXPECT_EQ(0, state_before.samples_gathered);
-  EXPECT_EQ(0, state_before.start_time);
-  EXPECT_STREQ("", state_before.profile_name);
-
-  // Safe to call stop again.
-  collector_.Stop();
-
-  // Safe to call FlushTable.
-  collector_.FlushTable();
-
-  // Safe to call Add.
-  const void *trace[] = { V(100), V(101), V(102), V(103), V(104) };
-  collector_.Add(arraysize(trace), trace);
-
-  ProfileData::State state_after;
-  collector_.GetCurrentState(&state_after);
-
-  ExpectSameState(state_before, state_after);
-}
-
-// Start and Stop, collecting no samples.  Verify output contents.
-TEST_F(ProfileDataTest, StartStopEmpty) {
-  const int frequency = 1;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-// Start and Stop with no options, collecting no samples.  Verify
-// output contents.
-TEST_F(ProfileDataTest, StartStopNoOptionsEmpty) {
-  // We're not requesting a specific period, implementation can do
-  // whatever it likes.
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 0 /* skipped */, 0,        // binary header
-    0, 1, 0                             // binary trailer
-  };
-  int slots_to_skip[] = { 3 };
-
-  ExpectStopped();
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(),
-                               ProfileData::Options()));
-  ExpectRunningSamples(0);
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.CheckWithSkips(slots, arraysize(slots),
-                                              slots_to_skip,
-                                              arraysize(slots_to_skip)));
-}
-
-// Start after already started.  Should return false and not impact
-// collected data or state.
-TEST_F(ProfileDataTest, StartWhenStarted) {
-  const int frequency = 1;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    0, 1, 0                             // binary trailer
-  };
-
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-
-  ProfileData::State state_before;
-  collector_.GetCurrentState(&state_before);
-
-  options.set_frequency(frequency * 2);
-  CHECK(!collector_.Start("foobar", options));
-
-  ProfileData::State state_after;
-  collector_.GetCurrentState(&state_after);
-  ExpectSameState(state_before, state_after);
-
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-// Like StartStopEmpty, but uses a different file name and frequency.
-TEST_F(ProfileDataTest, StartStopEmpty2) {
-  const int frequency = 2;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-TEST_F(ProfileDataTest, CollectOne) {
-  const int frequency = 2;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    1, 5, 100, 101, 102, 103, 104,      // our sample
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-
-  const void *trace[] = { V(100), V(101), V(102), V(103), V(104) };
-  collector_.Add(arraysize(trace), trace);
-  ExpectRunningSamples(1);
-
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-TEST_F(ProfileDataTest, CollectTwoMatching) {
-  const int frequency = 2;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    2, 5, 100, 201, 302, 403, 504,      // our two samples
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-
-  for (int i = 0; i < 2; ++i) {
-    const void *trace[] = { V(100), V(201), V(302), V(403), V(504) };
-    collector_.Add(arraysize(trace), trace);
-    ExpectRunningSamples(i + 1);
-  }
-
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-TEST_F(ProfileDataTest, CollectTwoFlush) {
-  const int frequency = 2;
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    1, 5, 100, 201, 302, 403, 504,      // first sample (flushed)
-    1, 5, 100, 201, 302, 403, 504,      // second identical sample
-    0, 1, 0                             // binary trailer
-  };
-
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-
-  const void *trace[] = { V(100), V(201), V(302), V(403), V(504) };
-
-  collector_.Add(arraysize(trace), trace);
-  ExpectRunningSamples(1);
-  collector_.FlushTable();
-
-  collector_.Add(arraysize(trace), trace);
-  ExpectRunningSamples(2);
-
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-// Start then reset, verify that the result is *not* a valid profile.
-// Then start again and make sure the result is OK.
-TEST_F(ProfileDataTest, StartResetRestart) {
-  ExpectStopped();
-  ProfileData::Options options;
-  options.set_frequency(1);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-  collector_.Reset();
-  ExpectStopped();
-  // We expect the resulting file to be empty.  This is a minimal test
-  // of ValidateProfile.
-  EXPECT_NE(kNoError, checker_.ValidateProfile());
-
-  struct stat statbuf;
-  EXPECT_EQ(0, stat(checker_.filename().c_str(), &statbuf));
-  EXPECT_EQ(0, statbuf.st_size);
-
-  const int frequency = 2;  // Different frequency than used above.
-  ProfileDataSlot slots[] = {
-    0, 3, 0, 1000000 / frequency, 0,    // binary header
-    0, 1, 0                             // binary trailer
-  };
-
-  options.set_frequency(frequency);
-  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));
-  ExpectRunningSamples(0);
-  collector_.Stop();
-  ExpectStopped();
-  EXPECT_EQ(kNoError, checker_.ValidateProfile());
-  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));
-}
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  int rc = ProfileDataTest::RUN_ALL_TESTS();
-  printf("%s\n", rc == 0 ? "PASS" : "FAIL");
-  return rc;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/profiler_unittest.cc b/third_party/tcmalloc/vendor/src/tests/profiler_unittest.cc
deleted file mode 100644
index dfc653f0..0000000
--- a/third_party/tcmalloc/vendor/src/tests/profiler_unittest.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// Does some simple arithmetic and a few libc routines, so we can profile it.
-// Define WITH_THREADS to add pthread functionality as well (otherwise, btw,
-// the num_threads argument to this program is ingored).
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>                 // for fork()
-#endif
-#include <sys/wait.h>               // for wait()
-#include "gperftools/profiler.h"
-#include "base/simple_mutex.h"
-#include "tests/testutil.h"
-
-static volatile int result = 0;
-static int g_iters = 0;   // argv[1]
-
-Mutex mutex(Mutex::LINKER_INITIALIZED);
-
-static void test_other_thread() {
-#ifndef NO_THREADS
-  ProfilerRegisterThread();
-
-  int i, m;
-  char b[128];
-  MutexLock ml(&mutex);
-  for (m = 0; m < 1000000; ++m) {          // run millions of times
-    for (i = 0; i < g_iters; ++i ) {
-      result ^= i;
-    }
-    snprintf(b, sizeof(b), "other: %d", result);  // get some libc action
-  }
-#endif
-}
-
-static void test_main_thread() {
-  int i, m;
-  char b[128];
-  MutexLock ml(&mutex);
-  for (m = 0; m < 1000000; ++m) {          // run millions of times
-    for (i = 0; i < g_iters; ++i ) {
-      result ^= i;
-    }
-    snprintf(b, sizeof(b), "same: %d", result);  // get some libc action
-  }
-}
-
-int main(int argc, char** argv) {
-  if ( argc <= 1 ) {
-    fprintf(stderr, "USAGE: %s <iters> [num_threads] [filename]\n", argv[0]);
-    fprintf(stderr, "   iters: How many million times to run the XOR test.\n");
-    fprintf(stderr, "   num_threads: how many concurrent threads.\n");
-    fprintf(stderr, "                0 or 1 for single-threaded mode,\n");
-    fprintf(stderr, "                -# to fork instead of thread.\n");
-    fprintf(stderr, "   filename: The name of the output profile.\n");
-    fprintf(stderr, ("             If you don't specify, set CPUPROFILE "
-                     "in the environment instead!\n"));
-    return 1;
-  }
-
-  g_iters = atoi(argv[1]);
-  int num_threads = 1;
-  const char* filename = NULL;
-  if (argc > 2) {
-    num_threads = atoi(argv[2]);
-  }
-  if (argc > 3) {
-    filename = argv[3];
-  }
-
-  if (filename) {
-    ProfilerStart(filename);
-  }
-
-  test_main_thread();
-
-  ProfilerFlush();                           // just because we can
-
-  // The other threads, if any, will run only half as long as the main thread
-  if(num_threads > 0) {
-    RunManyThreads(test_other_thread, num_threads);
-  } else {
-  // Or maybe they asked to fork.  The fork test is only interesting
-  // when we use CPUPROFILE to name, so check for that
-#ifdef HAVE_UNISTD_H
-    for (; num_threads < 0; ++num_threads) {   // -<num_threads> to fork
-      if (filename) {
-        printf("FORK test only makes sense when no filename is specified.\n");
-        return 2;
-      }
-      switch (fork()) {
-        case -1:
-          printf("FORK failed!\n");
-          return 1;
-        case 0:             // child
-          return execl(argv[0], argv[0], argv[1], NULL);
-        default:
-          wait(NULL);       // we'll let the kids run one at a time
-      }
-    }
-#else
-    fprintf(stderr, "%s was compiled without support for fork() and exec()\n", argv[0]);
-#endif
-  }
-
-  test_main_thread();
-
-  if (filename) {
-    ProfilerStop();
-  }
-
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/profiler_unittest.sh b/third_party/tcmalloc/vendor/src/tests/profiler_unittest.sh
deleted file mode 100755
index 4085f2c..0000000
--- a/third_party/tcmalloc/vendor/src/tests/profiler_unittest.sh
+++ /dev/null
@@ -1,269 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2005, Google Inc.
-# All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Craig Silverstein
-#
-# Runs the 4 profiler unittests and makes sure their profiles look
-# appropriate.  We expect two commandline args, as described below.
-#
-# We run under the assumption that if $PROFILER1 is run with no
-# arguments, it prints a usage line of the form
-#   USAGE: <actual executable being run> [...]
-#
-# This is because libtool sometimes turns the 'executable' into a
-# shell script which runs an actual binary somewhere else.
-
-# We expect BINDIR and PPROF_PATH to be set in the environment.
-# If not, we set them to some reasonable values
-BINDIR="${BINDIR:-.}"
-PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir] [path to pprof]"
-  echo "       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
-  exit 1
-fi
-
-TMPDIR=/tmp/profile_info
-
-UNITTEST_DIR=${1:-$BINDIR}
-PPROF=${2:-$PPROF_PATH}
-
-# We test the sliding-window functionality of the cpu-profile reader
-# by using a small stride, forcing lots of reads.
-PPROF_FLAGS="--test_stride=128"
-
-PROFILER1="$UNITTEST_DIR/profiler1_unittest"
-PROFILER2="$UNITTEST_DIR/profiler2_unittest"
-PROFILER3="$UNITTEST_DIR/profiler3_unittest"
-PROFILER4="$UNITTEST_DIR/profiler4_unittest"
-
-# Unfortunately, for us, libtool can replace executables with a shell
-# script that does some work before calling the 'real' executable
-# under a different name.  We need the 'real' executable name to run
-# pprof on it.  We've constructed all the binaries used in this
-# unittest so when they are called with no arguments, they report
-# their argv[0], which is the real binary name.
-Realname() {
-  "$1" 2>&1 | awk '{print $2; exit;}'
-}
-
-PROFILER1_REALNAME=`Realname "$PROFILER1"`
-PROFILER2_REALNAME=`Realname "$PROFILER2"`
-PROFILER3_REALNAME=`Realname "$PROFILER3"`
-PROFILER4_REALNAME=`Realname "$PROFILER4"`
-
-# It's meaningful to the profiler, so make sure we know its state
-unset CPUPROFILE
-
-# Some output/logging in the profiler can cause issues when running the unit
-# tests. For example, logging a warning when the profiler is detected as being
-# present but no CPUPROFILE is specified in the environment. Especially when
-# we are checking for a silent run or specific timing constraints are being
-# checked. So set the env variable signifying that we are running in a unit
-# test environment.
-PERFTOOLS_UNITTEST=1 
-
-rm -rf "$TMPDIR"
-mkdir "$TMPDIR" || exit 2
-
-num_failures=0
-
-RegisterFailure() {
-  num_failures=`expr $num_failures + 1`
-}
-
-# Takes two filenames representing profiles, with their executable scripts,
-# and a multiplier, and verifies that the 'contentful' functions in each
-# profile take the same time (possibly scaled by the given multiplier). It
-# used to be "same" meant within 50%, after adding an noise-reducing X units
-# to each value.  But even that would often spuriously fail, so now it's
-# "both non-zero". We're pretty forgiving.
-VerifySimilar() {
-  prof1="$TMPDIR/$1"
-  exec1="$2"
-  prof2="$TMPDIR/$3"
-  exec2="$4"
-  mult="$5"
-
-  # We are careful not to put exec1 and exec2 in quotes, because if
-  # they are the empty string, it means we want to use the 1-arg
-  # version of pprof.
-  mthread1=`"$PPROF" $PPROF_FLAGS $exec1 "$prof1" | grep test_main_thread | awk '{print $1}'`
-  mthread2=`"$PPROF" $PPROF_FLAGS $exec2 "$prof2" | grep test_main_thread | awk '{print $1}'`
-  mthread1_plus=`expr $mthread1 + 5`
-  mthread2_plus=`expr $mthread2 + 5`
-  if [ -z "$mthread1" ] || [ -z "$mthread2" ] || \
-     [ "$mthread1" -le 0 -o "$mthread2" -le 0 ]
-#    || [ `expr $mthread1_plus \* $mult` -gt `expr $mthread2_plus \* 2` -o \
-#         `expr $mthread1_plus \* $mult \* 2` -lt `expr $mthread2_plus` ]
-  then
-    echo
-    echo ">>> profile on $exec1 vs $exec2 with multiplier $mult failed:"
-    echo "Actual times (in profiling units) were '$mthread1' vs. '$mthread2'"
-    echo
-    RegisterFailure
-  fi
-}
-
-# Takes two filenames representing profiles, and optionally their
-# executable scripts (these may be empty if the profiles include
-# symbols), and verifies that the two profiles are identical.
-VerifyIdentical() {
-  prof1="$TMPDIR/$1"
-  exec1="$2"
-  prof2="$TMPDIR/$3"
-  exec2="$4"
-
-  # We are careful not to put exec1 and exec2 in quotes, because if
-  # they are the empty string, it means we want to use the 1-arg
-  # version of pprof.
-  "$PPROF" $PPROF_FLAGS $exec1 "$prof1" > "$TMPDIR/out1"
-  "$PPROF" $PPROF_FLAGS $exec2 "$prof2" > "$TMPDIR/out2"
-  diff=`diff "$TMPDIR/out1" "$TMPDIR/out2"`
-
-  if [ ! -z "$diff" ]; then
-    echo
-    echo ">>> profile doesn't match, args: $exec1 $prof1 vs. $exec2 $prof2"
-    echo ">>> Diff:"
-    echo "$diff"
-    echo
-    RegisterFailure
-  fi
-}
-
-# Takes a filename representing a profile, with its executable,
-# and a multiplier, and verifies that the main-thread function takes
-# the same amount of time as the other-threads function (possibly scaled
-# by the given multiplier).  Figuring out the multiplier can be tricky,
-# since by design the main thread runs twice as long as each of the
-# 'other' threads!  It used to be "same" meant within 50%, after adding an 
-# noise-reducing X units to each value.  But even that would often
-# spuriously fail, so now it's "both non-zero".  We're pretty forgiving.
-VerifyAcrossThreads() {
-  prof1="$TMPDIR/$1"
-  # We need to run the script with no args to get the actual exe name
-  exec1="$2"
-  mult="$3"
-
-  # We are careful not to put exec1 in quotes, because if it is the
-  # empty string, it means we want to use the 1-arg version of pprof.
-  mthread=`$PPROF $PPROF_FLAGS $exec1 "$prof1" | grep test_main_thread | awk '{print $1}'`
-  othread=`$PPROF $PPROF_FLAGS $exec1 "$prof1" | grep test_other_thread | awk '{print $1}'`
-  if [ -z "$mthread" ] || [ -z "$othread" ] || \
-     [ "$mthread" -le 0 -o "$othread" -le 0 ]
-#    || [ `expr $mthread \* $mult \* 3` -gt `expr $othread \* 10` -o \
-#         `expr $mthread \* $mult \* 10` -lt `expr $othread \* 3` ]
-  then
-    echo
-    echo ">>> profile on $exec1 (main vs thread) with multiplier $mult failed:"
-    echo "Actual times (in profiling units) were '$mthread' vs. '$othread'"
-    echo
-    RegisterFailure
-  fi
-}
-
-echo
-echo ">>> WARNING <<<"
-echo "This test looks at timing information to determine correctness."
-echo "If your system is loaded, the test may spuriously fail."
-echo "If the test does fail with an 'Actual times' error, try running again."
-echo
-
-# profiler1 is a non-threaded version
-"$PROFILER1" 50 1 "$TMPDIR/p1" || RegisterFailure
-"$PROFILER1" 100 1 "$TMPDIR/p2" || RegisterFailure
-VerifySimilar p1 "$PROFILER1_REALNAME" p2 "$PROFILER1_REALNAME" 2
-
-# Verify the same thing works if we statically link
-"$PROFILER2" 50 1 "$TMPDIR/p3" || RegisterFailure
-"$PROFILER2" 100 1 "$TMPDIR/p4" || RegisterFailure
-VerifySimilar p3 "$PROFILER2_REALNAME" p4 "$PROFILER2_REALNAME" 2
-
-# Verify the same thing works if we specify via CPUPROFILE
-CPUPROFILE="$TMPDIR/p5" "$PROFILER2" 50 || RegisterFailure
-CPUPROFILE="$TMPDIR/p6" "$PROFILER2" 100 || RegisterFailure
-VerifySimilar p5 "$PROFILER2_REALNAME" p6 "$PROFILER2_REALNAME" 2
-
-CPUPROFILE="$TMPDIR/p5b" "$PROFILER3" 30 || RegisterFailure
-CPUPROFILE="$TMPDIR/p5c" "$PROFILER3" 60 || RegisterFailure
-VerifySimilar p5b "$PROFILER3_REALNAME" p5c "$PROFILER3_REALNAME" 2
-
-# Now try what happens when we use threads
-"$PROFILER3" 30 2 "$TMPDIR/p7" || RegisterFailure
-"$PROFILER3" 60 2 "$TMPDIR/p8" || RegisterFailure
-VerifySimilar p7 "$PROFILER3_REALNAME" p8 "$PROFILER3_REALNAME" 2
-
-"$PROFILER4" 30 2 "$TMPDIR/p9" || RegisterFailure
-"$PROFILER4" 60 2 "$TMPDIR/p10" || RegisterFailure
-VerifySimilar p9 "$PROFILER4_REALNAME" p10 "$PROFILER4_REALNAME" 2
-
-# More threads!
-"$PROFILER4" 25 3 "$TMPDIR/p9" || RegisterFailure
-"$PROFILER4" 50 3 "$TMPDIR/p10" || RegisterFailure
-VerifySimilar p9 "$PROFILER4_REALNAME" p10 "$PROFILER4_REALNAME" 2
-
-# Compare how much time the main thread takes compared to the other threads
-# Recall the main thread runs twice as long as the other threads, by design.
-"$PROFILER4" 20 4 "$TMPDIR/p11" || RegisterFailure
-VerifyAcrossThreads p11 "$PROFILER4_REALNAME" 2
-
-# Test symbol save and restore
-"$PROFILER1" 50 1 "$TMPDIR/p12" || RegisterFailure
-"$PPROF" $PPROF_FLAGS "$PROFILER1_REALNAME" "$TMPDIR/p12" --raw \
-    >"$TMPDIR/p13" 2>/dev/null || RegisterFailure
-VerifyIdentical p12 "$PROFILER1_REALNAME" p13 "" || RegisterFailure
-
-"$PROFILER3" 30 2 "$TMPDIR/p14" || RegisterFailure
-"$PPROF" $PPROF_FLAGS "$PROFILER3_REALNAME" "$TMPDIR/p14" --raw \
-    >"$TMPDIR/p15" 2>/dev/null || RegisterFailure
-VerifyIdentical p14 "$PROFILER3_REALNAME" p15 "" || RegisterFailure
-
-# Test using ITIMER_REAL instead of ITIMER_PROF.
-env CPUPROFILE_REALTIME=1 "$PROFILER3" 30 2 "$TMPDIR/p16" || RegisterFailure
-env CPUPROFILE_REALTIME=1 "$PROFILER3" 60 2 "$TMPDIR/p17" || RegisterFailure
-VerifySimilar p16 "$PROFILER3_REALNAME" p17 "$PROFILER3_REALNAME" 2
-
-
-# Make sure that when we have a process with a fork, the profiles don't
-# clobber each other
-CPUPROFILE="$TMPDIR/pfork" "$PROFILER1" 1 -2 || RegisterFailure
-n=`ls $TMPDIR/pfork* | wc -l`
-if [ $n != 3 ]; then
-  echo "FORK test FAILED: expected 3 profiles (for main + 2 children), found $n"
-  num_failures=`expr $num_failures + 1`
-fi
-
-rm -rf "$TMPDIR"      # clean up
-
-echo "Tests finished with $num_failures failures"
-exit $num_failures
diff --git a/third_party/tcmalloc/vendor/src/tests/raw_printer_test.cc b/third_party/tcmalloc/vendor/src/tests/raw_printer_test.cc
deleted file mode 100644
index 2c7be6ac0..0000000
--- a/third_party/tcmalloc/vendor/src/tests/raw_printer_test.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright 2009 Google Inc. All Rights Reserved.
-// Author: sanjay@google.com (Sanjay Ghemawat)
-//
-// Use of this source code is governed by a BSD-style license that can
-// be found in the LICENSE file.
-
-#include "raw_printer.h"
-#include <stdio.h>
-#include <string>
-#include "base/logging.h"
-
-using std::string;
-
-#define TEST(a, b)  void TEST_##a##_##b()
-#define RUN_TEST(a, b)  TEST_##a##_##b()
-
-TEST(RawPrinter, Empty) {
-  char buffer[1];
-  base::RawPrinter printer(buffer, arraysize(buffer));
-  CHECK_EQ(0, printer.length());
-  CHECK_EQ(string(""), buffer);
-  CHECK_EQ(0, printer.space_left());
-  printer.Printf("foo");
-  CHECK_EQ(string(""), string(buffer));
-  CHECK_EQ(0, printer.length());
-  CHECK_EQ(0, printer.space_left());
-}
-
-TEST(RawPrinter, PartiallyFilled) {
-  char buffer[100];
-  base::RawPrinter printer(buffer, arraysize(buffer));
-  printer.Printf("%s %s", "hello", "world");
-  CHECK_EQ(string("hello world"), string(buffer));
-  CHECK_EQ(11, printer.length());
-  CHECK_LT(0, printer.space_left());
-}
-
-TEST(RawPrinter, Truncated) {
-  char buffer[3];
-  base::RawPrinter printer(buffer, arraysize(buffer));
-  printer.Printf("%d", 12345678);
-  CHECK_EQ(string("12"), string(buffer));
-  CHECK_EQ(2, printer.length());
-  CHECK_EQ(0, printer.space_left());
-}
-
-TEST(RawPrinter, ExactlyFilled) {
-  char buffer[12];
-  base::RawPrinter printer(buffer, arraysize(buffer));
-  printer.Printf("%s %s", "hello", "world");
-  CHECK_EQ(string("hello world"), string(buffer));
-  CHECK_EQ(11, printer.length());
-  CHECK_EQ(0, printer.space_left());
-}
-
-int main(int argc, char **argv) {
-  RUN_TEST(RawPrinter, Empty);
-  RUN_TEST(RawPrinter, PartiallyFilled);
-  RUN_TEST(RawPrinter, Truncated);
-  RUN_TEST(RawPrinter, ExactlyFilled);
-  printf("PASS\n");
-  return 0;   // 0 means success
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/realloc_unittest.cc b/third_party/tcmalloc/vendor/src/tests/realloc_unittest.cc
deleted file mode 100644
index e3d7b59..0000000
--- a/third_party/tcmalloc/vendor/src/tests/realloc_unittest.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2004, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Test realloc() functionality
-
-#include "config_for_unittests.h"
-#include <assert.h>                     // for assert
-#include <stdio.h>
-#include <stddef.h>                     // for size_t, NULL
-#include <stdlib.h>                     // for free, malloc, realloc
-#include <algorithm>                    // for min
-#include "base/logging.h"
-
-using std::min;
-
-
-// Fill a buffer of the specified size with a predetermined pattern
-static void Fill(unsigned char* buffer, int n) {
-  for (int i = 0; i < n; i++) {
-    buffer[i] = (i & 0xff);
-  }
-}
-
-// Check that the specified buffer has the predetermined pattern
-// generated by Fill()
-static bool Valid(unsigned char* buffer, int n) {
-  for (int i = 0; i < n; i++) {
-    if (buffer[i] != (i & 0xff)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-// Return the next interesting size/delta to check.  Returns -1 if no more.
-static int NextSize(int size) {
-  if (size < 100) {
-    return size+1;
-  } else if (size < 100000) {
-    // Find next power of two
-    int power = 1;
-    while (power < size) {
-      power <<= 1;
-    }
-
-    // Yield (power-1, power, power+1)
-    if (size < power-1) {
-      return power-1;
-    } else if (size == power-1) {
-      return power;
-    } else {
-      assert(size == power);
-      return power+1;
-    }
-  } else {
-    return -1;
-  }
-}
-
-int main(int argc, char** argv) {
-  for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) {
-    for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) {
-      unsigned char* src = (unsigned char*) malloc(src_size);
-      Fill(src, src_size);
-      unsigned char* dst = (unsigned char*) realloc(src, dst_size);
-      CHECK(Valid(dst, min(src_size, dst_size)));
-      Fill(dst, dst_size);
-      CHECK(Valid(dst, dst_size));
-      if (dst != NULL) free(dst);
-    }
-  }
-
-  // Now make sure realloc works correctly even when we overflow the
-  // packed cache, so some entries are evicted from the cache.
-  // The cache has 2^12 entries, keyed by page number.
-  const int kNumEntries = 1 << 14;
-  int** p = (int**)malloc(sizeof(*p) * kNumEntries);
-  int sum = 0;
-  for (int i = 0; i < kNumEntries; i++) {
-    p[i] = (int*)malloc(8192);   // no page size is likely to be bigger
-    p[i][1000] = i;              // use memory deep in the heart of p
-  }
-  for (int i = 0; i < kNumEntries; i++) {
-    p[i] = (int*)realloc(p[i], 9000);
-  }
-  for (int i = 0; i < kNumEntries; i++) {
-    sum += p[i][1000];
-    free(p[i]);
-  }
-  CHECK_EQ(kNumEntries/2 * (kNumEntries - 1), sum);  // assume kNE is even
-  free(p);
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/sampler_test.cc b/third_party/tcmalloc/vendor/src/tests/sampler_test.cc
deleted file mode 100755
index e0d24d4..0000000
--- a/third_party/tcmalloc/vendor/src/tests/sampler_test.cc
+++ /dev/null
@@ -1,631 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Daniel Ford
-//
-// Checks basic properties of the sampler
-
-#include "config_for_unittests.h"
-#include <stdlib.h>        // defines posix_memalign
-#include <stdio.h>         // for the printf at the end
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uintptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uintptr_t might be defined
-#endif
-#include <sys/types.h>
-#include <iostream>
-#include <algorithm>
-#include <vector>
-#include <string>
-#include <math.h>
-#include "base/logging.h"
-#include "base/commandlineflags.h"
-#include "sampler.h"       // The Sampler class being tested
-
-using std::sort;
-using std::min;
-using std::max;
-using std::vector;
-using std::abs;
-
-vector<void (*)()> g_testlist;  // the tests to run
-
-#define TEST(a, b)                                      \
-  struct Test_##a##_##b {                               \
-    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
-    static void Run();                                  \
-  };                                                    \
-  static Test_##a##_##b g_test_##a##_##b;               \
-  void Test_##a##_##b::Run()
-
-
-static int RUN_ALL_TESTS() {
-  vector<void (*)()>::const_iterator it;
-  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
-    (*it)();   // The test will error-exit if there's a problem.
-  }
-  fprintf(stderr, "\nPassed %d tests\n\nPASS\n", (int)g_testlist.size());
-  return 0;
-}
-
-#undef LOG   // defined in base/logging.h
-// Ideally, we'd put the newline at the end, but this hack puts the
-// newline at the end of the previous log message, which is good enough :-)
-#define LOG(level)  std::cerr << "\n"
-
-static std::string StringPrintf(const char* format, ...) {
-  char buf[256];   // should be big enough for all logging
-  va_list ap;
-  va_start(ap, format);
-  perftools_vsnprintf(buf, sizeof(buf), format, ap);
-  va_end(ap);
-  return buf;
-}
-
-namespace {
-template<typename T> class scoped_array {
- public:
-  scoped_array(T* p) : p_(p) { }
-  ~scoped_array() { delete[] p_; }
-  const T* get() const { return p_; }
-  T* get() { return p_; }
-  T& operator[](int i) { return p_[i]; }
- private:
-  T* p_;
-};
-}
-
-// Note that these tests are stochastic.
-// This mean that the chance of correct code passing the test is,
-// in the case of 5 standard deviations:
-// kSigmas=5:    ~99.99994267%
-// in the case of 4 standard deviations:
-// kSigmas=4:    ~99.993666%
-static const double kSigmas = 4;
-static const size_t kSamplingInterval = 512*1024;
-
-// Tests that GetSamplePeriod returns the expected value
-// which is 1<<19
-TEST(Sampler, TestGetSamplePeriod) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t sample_period;
-  sample_period = sampler.GetSamplePeriod();
-  CHECK_GT(sample_period, 0);
-}
-
-// Tests of the quality of the random numbers generated
-// This uses the Anderson Darling test for uniformity.
-// See "Evaluating the Anderson-Darling Distribution" by Marsaglia
-// for details.
-
-// Short cut version of ADinf(z), z>0 (from Marsaglia)
-// This returns the p-value for Anderson Darling statistic in
-// the limit as n-> infinity. For finite n, apply the error fix below.
-double AndersonDarlingInf(double z) {
-  if (z < 2) {
-    return exp(-1.2337141 / z) / sqrt(z) * (2.00012 + (0.247105 -
-                (0.0649821 - (0.0347962 - (0.011672 - 0.00168691
-                * z) * z) * z) * z) * z);
-  }
-  return exp( - exp(1.0776 - (2.30695 - (0.43424 - (0.082433 -
-                    (0.008056 - 0.0003146 * z) * z) * z) * z) * z));
-}
-
-// Corrects the approximation error in AndersonDarlingInf for small values of n
-// Add this to AndersonDarlingInf to get a better approximation
-// (from Marsaglia)
-double AndersonDarlingErrFix(int n, double x) {
-  if (x > 0.8) {
-    return (-130.2137 + (745.2337 - (1705.091 - (1950.646 -
-            (1116.360 - 255.7844 * x) * x) * x) * x) * x) / n;
-  }
-  double cutoff = 0.01265 + 0.1757 / n;
-  double t;
-  if (x < cutoff) {
-    t = x / cutoff;
-    t = sqrt(t) * (1 - t) * (49 * t - 102);
-    return t * (0.0037 / (n * n) + 0.00078 / n + 0.00006) / n;
-  } else {
-    t = (x - cutoff) / (0.8 - cutoff);
-    t = -0.00022633 + (6.54034 - (14.6538 - (14.458 - (8.259 - 1.91864
-          * t) * t) * t) * t) * t;
-    return t * (0.04213 + 0.01365 / n) / n;
-  }
-}
-
-// Returns the AndersonDarling p-value given n and the value of the statistic
-double AndersonDarlingPValue(int n, double z) {
-  double ad = AndersonDarlingInf(z);
-  double errfix = AndersonDarlingErrFix(n, ad);
-  return ad + errfix;
-}
-
-double AndersonDarlingStatistic(int n, double* random_sample) {
-  double ad_sum = 0;
-  for (int i = 0; i < n; i++) {
-    ad_sum += (2*i + 1) * log(random_sample[i] * (1 - random_sample[n-1-i]));
-  }
-  double ad_statistic = - n - 1/static_cast<double>(n) * ad_sum;
-  return ad_statistic;
-}
-
-// Tests if the array of doubles is uniformly distributed.
-// Returns the p-value of the Anderson Darling Statistic
-// for the given set of sorted random doubles
-// See "Evaluating the Anderson-Darling Distribution" by
-// Marsaglia and Marsaglia for details.
-double AndersonDarlingTest(int n, double* random_sample) {
-  double ad_statistic = AndersonDarlingStatistic(n, random_sample);
-  LOG(INFO) << StringPrintf("AD stat = %f, n=%d\n", ad_statistic, n);
-  double p = AndersonDarlingPValue(n, ad_statistic);
-  return p;
-}
-
-// Test the AD Test. The value of the statistic should go to zero as n->infty
-// Not run as part of regular tests
-void ADTestTest(int n) {
-  scoped_array<double> random_sample(new double[n]);
-  for (int i = 0; i < n; i++) {
-    random_sample[i] = (i+0.01)/n;
-  }
-  sort(random_sample.get(), random_sample.get() + n);
-  double ad_stat = AndersonDarlingStatistic(n, random_sample.get());
-  LOG(INFO) << StringPrintf("Testing the AD test. n=%d, ad_stat = %f",
-                            n, ad_stat);
-}
-
-// Print the CDF of the distribution of the Anderson-Darling Statistic
-// Used for checking the Anderson-Darling Test
-// Not run as part of regular tests
-void ADCDF() {
-  for (int i = 1; i < 40; i++) {
-    double x = i/10.0;
-    LOG(INFO) << "x= " << x << "  adpv= "
-              << AndersonDarlingPValue(100, x) << ", "
-              << AndersonDarlingPValue(1000, x);
-  }
-}
-
-// Testing that NextRandom generates uniform
-// random numbers.
-// Applies the Anderson-Darling test for uniformity
-void TestNextRandom(int n) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t x = 1;
-  // This assumes that the prng returns 48 bit numbers
-  uint64_t max_prng_value = static_cast<uint64_t>(1)<<48;
-  // Initialize
-  for (int i = 1; i <= 20; i++) {  // 20 mimics sampler.Init()
-    x = sampler.NextRandom(x);
-  }
-  scoped_array<uint64_t> int_random_sample(new uint64_t[n]);
-  // Collect samples
-  for (int i = 0; i < n; i++) {
-    int_random_sample[i] = x;
-    x = sampler.NextRandom(x);
-  }
-  // First sort them...
-  sort(int_random_sample.get(), int_random_sample.get() + n);
-  scoped_array<double> random_sample(new double[n]);
-  // Convert them to uniform randoms (in the range [0,1])
-  for (int i = 0; i < n; i++) {
-    random_sample[i] = static_cast<double>(int_random_sample[i])/max_prng_value;
-  }
-  // Now compute the Anderson-Darling statistic
-  double ad_pvalue = AndersonDarlingTest(n, random_sample.get());
-  LOG(INFO) << StringPrintf("pvalue for AndersonDarlingTest "
-                            "with n= %d is p= %f\n", n, ad_pvalue);
-  CHECK_GT(min(ad_pvalue, 1 - ad_pvalue), 0.0001);
-  //           << StringPrintf("prng is not uniform, %d\n", n);
-}
-
-
-TEST(Sampler, TestNextRandom_MultipleValues) {
-  TestNextRandom(10);  // Check short-range correlation
-  TestNextRandom(100);
-  TestNextRandom(1000);
-  TestNextRandom(10000);  // Make sure there's no systematic error
-}
-
-// Tests that PickNextSamplePeriod generates
-// geometrically distributed random numbers.
-// First converts to uniforms then applied the
-// Anderson-Darling test for uniformity.
-void TestPickNextSample(int n) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  scoped_array<uint64_t> int_random_sample(new uint64_t[n]);
-  int sample_period = sampler.GetSamplePeriod();
-  int ones_count = 0;
-  for (int i = 0; i < n; i++) {
-    int_random_sample[i] = sampler.PickNextSamplingPoint();
-    CHECK_GE(int_random_sample[i], 1);
-    if (int_random_sample[i] == 1) {
-      ones_count += 1;
-    }
-    CHECK_LT(ones_count, 4); // << " out of " << i << " samples.";
-  }
-  // First sort them...
-  sort(int_random_sample.get(), int_random_sample.get() + n);
-  scoped_array<double> random_sample(new double[n]);
-  // Convert them to uniform random numbers
-  // by applying the geometric CDF
-  for (int i = 0; i < n; i++) {
-    random_sample[i] = 1 - exp(-static_cast<double>(int_random_sample[i])
-                           / sample_period);
-  }
-  // Now compute the Anderson-Darling statistic
-  double geom_ad_pvalue = AndersonDarlingTest(n, random_sample.get());
-  LOG(INFO) << StringPrintf("pvalue for geometric AndersonDarlingTest "
-                             "with n= %d is p= %f\n", n, geom_ad_pvalue);
-  CHECK_GT(min(geom_ad_pvalue, 1 - geom_ad_pvalue), 0.0001);
-      //          << "PickNextSamplingPoint does not produce good "
-      //             "geometric/exponential random numbers\n";
-}
-
-TEST(Sampler, TestPickNextSample_MultipleValues) {
-  TestPickNextSample(10);  // Make sure the first few are good (enough)
-  TestPickNextSample(100);
-  TestPickNextSample(1000);
-  TestPickNextSample(10000);  // Make sure there's no systematic error
-}
-
-
-// This is superceeded by the Anderson-Darling Test
-// and it not run now.
-// Tests how fast nearby values are spread out with  LRand64
-// The purpose of this code is to determine how many
-// steps to apply to the seed during initialization
-void TestLRand64Spread() {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t current_value;
-  printf("Testing LRand64 Spread\n");
-  for (int i = 1; i < 10; i++) {
-    printf("%d ", i);
-    current_value = i;
-    for (int j = 1; j < 100; j++) {
-      current_value = sampler.NextRandom(current_value);
-    }
-    LOG(INFO) << current_value;
-  }
-}
-
-
-// Futher tests
-
-bool CheckMean(size_t mean, int num_samples) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  size_t total = 0;
-  for (int i = 0; i < num_samples; i++) {
-    total += sampler.PickNextSamplingPoint();
-  }
-  double empirical_mean = total / static_cast<double>(num_samples);
-  double expected_sd = mean / pow(num_samples * 1.0, 0.5);
-  return(fabs(mean-empirical_mean) < expected_sd * kSigmas);
-}
-
-// Prints a sequence so you can look at the distribution
-void OutputSequence(int sequence_length) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  size_t next_step;
-  for (int i = 0; i< sequence_length; i++) {
-    next_step = sampler.PickNextSamplingPoint();
-    LOG(INFO) << next_step;
-  }
-}
-
-
-double StandardDeviationsErrorInSample(
-              int total_samples, int picked_samples,
-              int alloc_size, int sampling_interval) {
-  double p = 1 - exp(-(static_cast<double>(alloc_size) / sampling_interval));
-  double expected_samples = total_samples * p;
-  double sd = pow(p*(1-p)*total_samples, 0.5);
-  return((picked_samples - expected_samples) / sd);
-}
-
-TEST(Sampler, LargeAndSmallAllocs_CombinedTest) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  int counter_big = 0;
-  int counter_small = 0;
-  int size_big = 129*8*1024+1;
-  int size_small = 1024*8;
-  int num_iters = 128*4*8;
-  // Allocate in mixed chunks
-  for (int i = 0; i < num_iters; i++) {
-    if (!sampler.RecordAllocation(size_big)) {
-      counter_big += 1;
-    }
-    for (int i = 0; i < 129; i++) {
-      if (!sampler.RecordAllocation(size_small)) {
-        counter_small += 1;
-      }
-    }
-  }
-  // Now test that there are the right number of each
-  double large_allocs_sds =
-     StandardDeviationsErrorInSample(num_iters, counter_big,
-                                     size_big, kSamplingInterval);
-  double small_allocs_sds =
-     StandardDeviationsErrorInSample(num_iters*129, counter_small,
-                                     size_small, kSamplingInterval);
-  LOG(INFO) << StringPrintf("large_allocs_sds = %f\n", large_allocs_sds);
-  LOG(INFO) << StringPrintf("small_allocs_sds = %f\n", small_allocs_sds);
-  CHECK_LE(fabs(large_allocs_sds), kSigmas);
-  CHECK_LE(fabs(small_allocs_sds), kSigmas);
-}
-
-// Tests whether the mean is about right over 1000 samples
-TEST(Sampler, IsMeanRight) {
-  CHECK(CheckMean(kSamplingInterval, 1000));
-}
-
-// This flag is for the OldSampler class to use
-const int64 FLAGS_mock_tcmalloc_sample_parameter = 1<<19;
-
-// A cut down and slightly refactored version of the old Sampler
-class OldSampler {
- public:
-  void Init(uint32_t seed);
-  void Cleanup() {}
-
-  // Record allocation of "k" bytes.  Return true iff allocation
-  // should be sampled
-  bool SampleAllocation(size_t k);
-
-  // Generate a geometric with mean 1M (or FLAG value)
-  void PickNextSample(size_t k);
-
-  // Initialize the statics for the Sample class
-  static void InitStatics() {
-    sample_period = 1048583;
-  }
-  size_t bytes_until_sample_;
-
- private:
-  uint32_t rnd_;                   // Cheap random number generator
-  static uint64_t sample_period;
-  // Should be a prime just above a power of 2:
-  // 2, 5, 11, 17, 37, 67, 131, 257,
-  // 521, 1031, 2053, 4099, 8209, 16411,
-  // 32771, 65537, 131101, 262147, 524309, 1048583,
-  // 2097169, 4194319, 8388617, 16777259, 33554467
-};
-
-// Statics for OldSampler
-uint64_t OldSampler::sample_period;
-
-void OldSampler::Init(uint32_t seed) {
-  // Initialize PRNG -- run it for a bit to get to good values
-  if (seed != 0) {
-    rnd_ = seed;
-  } else {
-    rnd_ = 12345;
-  }
-  bytes_until_sample_ = 0;
-  for (int i = 0; i < 100; i++) {
-    PickNextSample(sample_period * 2);
-  }
-};
-
-// A cut-down version of the old PickNextSampleRoutine
-void OldSampler::PickNextSample(size_t k) {
-  // Make next "random" number
-  // x^32+x^22+x^2+x^1+1 is a primitive polynomial for random numbers
-  static const uint32_t kPoly = (1 << 22) | (1 << 2) | (1 << 1) | (1 << 0);
-  uint32_t r = rnd_;
-  rnd_ = (r << 1) ^ ((static_cast<int32_t>(r) >> 31) & kPoly);
-
-  // Next point is "rnd_ % (sample_period)".  I.e., average
-  // increment is "sample_period/2".
-  const int flag_value = FLAGS_mock_tcmalloc_sample_parameter;
-  static int last_flag_value = -1;
-
-  if (flag_value != last_flag_value) {
-    // There should be a spinlock here, but this code is
-    // for benchmarking only.
-    sample_period = 1048583;
-    last_flag_value = flag_value;
-  }
-
-  bytes_until_sample_ += rnd_ % sample_period;
-
-  if (k > (static_cast<size_t>(-1) >> 2)) {
-    // If the user has asked for a huge allocation then it is possible
-    // for the code below to loop infinitely.  Just return (note that
-    // this throws off the sampling accuracy somewhat, but a user who
-    // is allocating more than 1G of memory at a time can live with a
-    // minor inaccuracy in profiling of small allocations, and also
-    // would rather not wait for the loop below to terminate).
-    return;
-  }
-
-  while (bytes_until_sample_ < k) {
-    // Increase bytes_until_sample_ by enough average sampling periods
-    // (sample_period >> 1) to allow us to sample past the current
-    // allocation.
-    bytes_until_sample_ += (sample_period >> 1);
-  }
-
-  bytes_until_sample_ -= k;
-}
-
-inline bool OldSampler::SampleAllocation(size_t k) {
-  if (bytes_until_sample_ < k) {
-    PickNextSample(k);
-    return true;
-  } else {
-    bytes_until_sample_ -= k;
-    return false;
-  }
-}
-
-// This checks that the stated maximum value for the
-// tcmalloc_sample_parameter flag never overflows bytes_until_sample_
-TEST(Sampler, bytes_until_sample_Overflow_Underflow) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t one = 1;
-  // sample_parameter = 0;  // To test the edge case
-  uint64_t sample_parameter_array[4] = {0, 1, one<<19, one<<58};
-  for (int i = 0; i < 4; i++) {
-    uint64_t sample_parameter = sample_parameter_array[i];
-    LOG(INFO) << "sample_parameter = " << sample_parameter;
-    double sample_scaling = - log(2.0) * sample_parameter;
-    // Take the top 26 bits as the random number
-    // (This plus the 1<<26 sampling bound give a max step possible of
-    // 1209424308 bytes.)
-    const uint64_t prng_mod_power = 48;  // Number of bits in prng
-
-    // First, check the largest_prng value
-    uint64_t largest_prng_value = (static_cast<uint64_t>(1)<<48) - 1;
-    double q = (largest_prng_value >> (prng_mod_power - 26)) + 1.0;
-    LOG(INFO) << StringPrintf("q = %f\n", q);
-    LOG(INFO) << StringPrintf("log2(q) = %f\n", log(q)/log(2.0));
-    uint64_t smallest_sample_step
-        = static_cast<uint64_t>(min(log2(q) - 26, 0.0)
-                                * sample_scaling + 1);
-    LOG(INFO) << "Smallest sample step is " << smallest_sample_step;
-    uint64_t cutoff = static_cast<uint64_t>(10)
-                      * (sample_parameter/(one<<24) + 1);
-    LOG(INFO) << "Acceptable value is < " << cutoff;
-    // This checks that the answer is "small" and positive
-    CHECK_LE(smallest_sample_step, cutoff);
-
-    // Next, check with the smallest prng value
-    uint64_t smallest_prng_value = 0;
-    q = (smallest_prng_value >> (prng_mod_power - 26)) + 1.0;
-    LOG(INFO) << StringPrintf("q = %f\n", q);
-    uint64_t largest_sample_step
-        = static_cast<uint64_t>(min(log2(q) - 26, 0.0)
-                                * sample_scaling + 1);
-    LOG(INFO) << "Largest sample step is " << largest_sample_step;
-    CHECK_LE(largest_sample_step, one<<63);
-    CHECK_GE(largest_sample_step, smallest_sample_step);
-  }
-}
-
-
-// Test that NextRand is in the right range.  Unfortunately, this is a
-// stochastic test which could miss problems.
-TEST(Sampler, NextRand_range) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t one = 1;
-  // The next number should be (one << 48) - 1
-  uint64_t max_value = (one << 48) - 1;
-  uint64_t x = (one << 55);
-  int n = 22;  // 27;
-  LOG(INFO) << "Running sampler.NextRandom 1<<" << n << " times";
-  for (int i = 1; i <= (1<<n); i++) {  // 20 mimics sampler.Init()
-    x = sampler.NextRandom(x);
-    CHECK_LE(x, max_value);
-  }
-}
-
-// Tests certain arithmetic operations to make sure they compute what we
-// expect them too (for testing across different platforms)
-TEST(Sampler, arithmetic_1) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  uint64_t rnd;  // our 48 bit random number, which we don't trust
-  const uint64_t prng_mod_power = 48;
-  uint64_t one = 1;
-  rnd = one;
-  uint64_t max_value = (one << 48) - 1;
-  for (int i = 1; i <= (1>>27); i++) {  // 20 mimics sampler.Init()
-    rnd = sampler.NextRandom(rnd);
-    CHECK_LE(rnd, max_value);
-    double q = (rnd >> (prng_mod_power - 26)) + 1.0;
-    CHECK_GE(q, 0); // << rnd << "  " << prng_mod_power;
-  }
-  // Test some potentially out of bounds value for rnd
-  for (int i = 1; i <= 63; i++) {
-    rnd = one << i;
-    double q = (rnd >> (prng_mod_power - 26)) + 1.0;
-    LOG(INFO) << "rnd = " << rnd << " i=" << i << " q=" << q;
-    CHECK_GE(q, 0);
-    //        << " rnd=" << rnd << "  i=" << i << " prng_mod_power" << prng_mod_power;
-  }
-}
-
-void test_arithmetic(uint64_t rnd) {
-  const uint64_t prng_mod_power = 48;  // Number of bits in prng
-  uint64_t shifted_rnd = rnd >> (prng_mod_power - 26);
-  CHECK_GE(shifted_rnd, 0);
-  CHECK_LT(shifted_rnd, (1<<26));
-  LOG(INFO) << shifted_rnd;
-  LOG(INFO) << static_cast<double>(shifted_rnd);
-  CHECK_GE(static_cast<double>(static_cast<uint32_t>(shifted_rnd)), 0);
-      //      << " rnd=" << rnd << "  srnd=" << shifted_rnd;
-  CHECK_GE(static_cast<double>(shifted_rnd), 0);
-      //      << " rnd=" << rnd << "  srnd=" << shifted_rnd;
-  double q = static_cast<double>(shifted_rnd) + 1.0;
-  CHECK_GT(q, 0);
-}
-
-// Tests certain arithmetic operations to make sure they compute what we
-// expect them too (for testing across different platforms)
-// know bad values under with -c dbg --cpu piii for _some_ binaries:
-// rnd=227453640600554
-// shifted_rnd=54229173
-// (hard to reproduce)
-TEST(Sampler, arithmetic_2) {
-  uint64_t rnd = 227453640600554LL;
-  test_arithmetic(rnd);
-}
-
-
-// It's not really a test, but it's good to know
-TEST(Sample, size_of_class) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  LOG(INFO) << "Size of Sampler class is: " << sizeof(tcmalloc::Sampler);
-  LOG(INFO) << "Size of Sampler object is: " << sizeof(sampler);
-}
-
-// Make sure sampling is enabled, or the tests won't work right.
-DECLARE_int64(tcmalloc_sample_parameter);
-
-int main(int argc, char **argv) {
-  if (FLAGS_tcmalloc_sample_parameter == 0)
-    FLAGS_tcmalloc_sample_parameter = 524288;
-  return RUN_ALL_TESTS();
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/sampling_test.cc b/third_party/tcmalloc/vendor/src/tests/sampling_test.cc
deleted file mode 100644
index 729aba8..0000000
--- a/third_party/tcmalloc/vendor/src/tests/sampling_test.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This tests ReadStackTraces and ReadGrowthStackTraces.  It does this
-// by doing a bunch of allocations and then calling those functions.
-// A driver shell-script can call this, and then call pprof, and
-// verify the expected output.  The output is written to
-// argv[1].heap and argv[1].growth
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-#include "base/logging.h"
-#include <gperftools/malloc_extension.h>
-
-using std::string;
-
-extern "C" void* AllocateAllocate() ATTRIBUTE_NOINLINE;
-
-extern "C" void* AllocateAllocate() {
-  // The VLOG's are mostly to discourage inlining
-  VLOG(1, "Allocating some more");
-  void* p = malloc(10000);
-  VLOG(1, "Done allocating");
-  return p;
-}
-
-static void WriteStringToFile(const string& s, const string& filename) {
-  FILE* fp = fopen(filename.c_str(), "w");
-  fwrite(s.data(), 1, s.length(), fp);
-  fclose(fp);
-}
-
-int main(int argc, char** argv) {
-  if (argc < 2) {
-    fprintf(stderr, "USAGE: %s <base of output files>\n", argv[0]);
-    exit(1);
-  }
-  for (int i = 0; i < 8000; i++) {
-    AllocateAllocate();
-  }
-
-  string s;
-  MallocExtension::instance()->GetHeapSample(&s);
-  WriteStringToFile(s, string(argv[1]) + ".heap");
-
-  s.clear();
-  MallocExtension::instance()->GetHeapGrowthStacks(&s);
-  WriteStringToFile(s, string(argv[1]) + ".growth");
-
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/sampling_test.sh b/third_party/tcmalloc/vendor/src/tests/sampling_test.sh
deleted file mode 100755
index 2a58426..0000000
--- a/third_party/tcmalloc/vendor/src/tests/sampling_test.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2008, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# ---
-# Author: Craig Silverstein
-#
-# This is a test that tcmalloc creates, and pprof reads, sampling data
-# correctly: both for the heap profile (ReadStackTraces) and for
-# growth in the heap sized (ReadGrowthStackTraces).
-
-BINDIR="${BINDIR:-.}"
-PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-
-if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
-  echo "USAGE: $0 [unittest dir] [path to pprof]"
-  echo "       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
-  exit 1
-fi
-
-SAMPLING_TEST="${1:-$BINDIR/sampling_test}"
-PPROF="${2:-$PPROF_PATH}"
-OUTDIR="/tmp/sampling_test_dir"
-
-# libtool is annoying, and puts the actual executable in a different
-# directory, replacing the seeming-executable with a shell script.
-# We use the error output of sampling_test to indicate its real location
-SAMPLING_TEST_BINARY=`"$SAMPLING_TEST" 2>&1 | awk '/USAGE/ {print $2; exit;}'`
-
-# A kludge for cygwin.  Unfortunately, 'test -f' says that 'foo' exists
-# even when it doesn't, and only foo.exe exists.  Other unix utilities
-# (like nm) need you to say 'foo.exe'.  We use one such utility, cat, to
-# see what the *real* binary name is.
-if ! cat "$SAMPLING_TEST_BINARY" >/dev/null 2>&1; then
-  SAMPLING_TEST_BINARY="$SAMPLING_TEST_BINARY".exe
-fi
-
-die() {    # runs the command given as arguments, and then dies.
-    echo "FAILED.  Output from $@"
-    echo "----"
-    "$@"
-    echo "----"
-    exit 1
-}
-
-rm -rf "$OUTDIR" || die "Unable to delete $OUTDIR"
-mkdir "$OUTDIR" || die "Unable to create $OUTDIR"
-
-# This puts the output into out.heap and out.growth.  It allocates
-# 8*10^7 bytes of memory, which is 76M.  Because we sample, the
-# estimate may be a bit high or a bit low: we accept anything from
-# 50M to 99M.
-"$SAMPLING_TEST" "$OUTDIR/out"
-
-echo "Testing heap output..."
-"$PPROF" --text "$SAMPLING_TEST_BINARY" "$OUTDIR/out.heap" \
-   | grep '[5-9][0-9]\.[0-9][ 0-9.%]*_*AllocateAllocate' >/dev/null \
-   || die "$PPROF" --text "$SAMPLING_TEST_BINARY" "$OUTDIR/out.heap"
-echo "OK"
-
-echo "Testing growth output..."
-"$PPROF" --text "$SAMPLING_TEST_BINARY" "$OUTDIR/out.growth" \
-   | grep '[5-9][0-9]\.[0-9][ 0-9.%]*_*AllocateAllocate' >/dev/null \
-   || die "$PPROF" --text "$SAMPLING_TEST_BINARY" "$OUTDIR/out.growth"
-echo "OK"
-
-echo "PASS"
diff --git a/third_party/tcmalloc/vendor/src/tests/simple_compat_test.cc b/third_party/tcmalloc/vendor/src/tests/simple_compat_test.cc
deleted file mode 100644
index 24583a0..0000000
--- a/third_party/tcmalloc/vendor/src/tests/simple_compat_test.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// This just verifies that we can compile code that #includes stuff
-// via the backwards-compatibility 'google/' #include-dir.  It does
-// not include config.h on purpose, to better simulate a perftools
-// client.
-
-#include <stddef.h>
-#include <stdio.h>
-
-#define GPERFTOOLS_SUPPRESS_LEGACY_WARNING
-
-#include <google/heap-checker.h>
-#include <google/heap-profiler.h>
-#include <google/malloc_extension.h>
-#include <google/malloc_extension_c.h>
-#include <google/malloc_hook.h>
-#include <google/malloc_hook_c.h>
-#include <google/profiler.h>
-#include <google/stacktrace.h>
-#include <google/tcmalloc.h>
-
-// We don't link in -lprofiler for this test, so be sure not to make
-// any function calls that require the cpu-profiler code.  The
-// heap-profiler is ok.
-
-HeapLeakChecker::Disabler* heap_checker_h;
-void (*heap_profiler_h)(const char*) = &HeapProfilerStart;
-MallocExtension::Ownership malloc_extension_h;
-MallocExtension_Ownership malloc_extension_c_h;
-MallocHook::NewHook* malloc_hook_h;
-MallocHook_NewHook* malloc_hook_c_h;
-ProfilerOptions* profiler_h;
-int (*stacktrace_h)(void**, int, int) = &GetStackTrace;
-void* (*tcmalloc_h)(size_t) = &tc_new;
-
-int main(int argc, char** argv) {
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/stack_trace_table_test.cc b/third_party/tcmalloc/vendor/src/tests/stack_trace_table_test.cc
deleted file mode 100644
index 3cacd2d..0000000
--- a/third_party/tcmalloc/vendor/src/tests/stack_trace_table_test.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright 2009 Google Inc. All Rights Reserved.
-// Author: fikes@google.com (Andrew Fikes)
-//
-// Use of this source code is governed by a BSD-style license that can
-// be found in the LICENSE file.
-
-
-#include "config_for_unittests.h"
-#include <stdio.h>   // for puts()
-#include "stack_trace_table.h"
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "static_vars.h"
-
-#undef ARRAYSIZE   // may be defined on, eg, windows
-#define ARRAYSIZE(a)  ( sizeof(a) / sizeof(*(a)) )
-
-static void CheckTracesAndReset(tcmalloc::StackTraceTable* table,
-                        const uintptr_t* expected, int len) {
-  void** entries = table->ReadStackTracesAndClear();
-  for (int i = 0; i < len; ++i) {
-    CHECK_EQ(reinterpret_cast<uintptr_t>(entries[i]), expected[i]);
-  }
-  delete[] entries;
-}
-
-static void AddTrace(tcmalloc::StackTraceTable* table,
-                     const tcmalloc::StackTrace& t) {
-  // Normally we'd need this lock, but since the test is single-threaded
-  // we don't.  I comment it out on windows because the DLL-decl thing
-  // is really annoying in this case.
-#ifndef _MSC_VER
-  SpinLockHolder h(tcmalloc::Static::pageheap_lock());
-#endif
-  table->AddTrace(t);
-}
-
-int main(int argc, char **argv) {
-  tcmalloc::StackTraceTable table;
-
-  // Empty table
-  CHECK_EQ(table.depth_total(), 0);
-  CHECK_EQ(table.bucket_total(), 0);
-  static const uintptr_t k1[] = {0};
-  CheckTracesAndReset(&table, k1, ARRAYSIZE(k1));
-
-  tcmalloc::StackTrace t1;
-  t1.size = static_cast<uintptr_t>(1024);
-  t1.depth = static_cast<uintptr_t>(2);
-  t1.stack[0] = reinterpret_cast<void*>(1);
-  t1.stack[1] = reinterpret_cast<void*>(2);
-
-
-  tcmalloc::StackTrace t2;
-  t2.size = static_cast<uintptr_t>(512);
-  t2.depth = static_cast<uintptr_t>(2);
-  t2.stack[0] = reinterpret_cast<void*>(2);
-  t2.stack[1] = reinterpret_cast<void*>(1);
-
-  // Table w/ just t1
-  AddTrace(&table, t1);
-  CHECK_EQ(table.depth_total(), 2);
-  CHECK_EQ(table.bucket_total(), 1);
-  static const uintptr_t k2[] = {1, 1024, 2, 1, 2, 0};
-  CheckTracesAndReset(&table, k2, ARRAYSIZE(k2));
-
-  // Table w/ t1, t2
-  AddTrace(&table, t1);
-  AddTrace(&table, t2);
-  CHECK_EQ(table.depth_total(), 4);
-  CHECK_EQ(table.bucket_total(), 2);
-  static const uintptr_t k3[] = {1, 1024, 2, 1, 2, 1,  512, 2, 2, 1, 0};
-  CheckTracesAndReset(&table, k3, ARRAYSIZE(k3));
-
-  // Table w/ 2 x t1, 1 x t2
-  AddTrace(&table, t1);
-  AddTrace(&table, t2);
-  AddTrace(&table, t1);
-  CHECK_EQ(table.depth_total(), 4);
-  CHECK_EQ(table.bucket_total(), 2);
-  static const uintptr_t k4[] = {2, 2048, 2, 1, 2, 1,  512, 2, 2, 1, 0};
-  CheckTracesAndReset(&table, k4, ARRAYSIZE(k4));
-
-  // Same stack as t1, but w/ different size
-  tcmalloc::StackTrace t3;
-  t3.size = static_cast<uintptr_t>(2);
-  t3.depth = static_cast<uintptr_t>(2);
-  t3.stack[0] = reinterpret_cast<void*>(1);
-  t3.stack[1] = reinterpret_cast<void*>(2);
-
-  // Table w/ t1, t3
-  AddTrace(&table, t1);
-  AddTrace(&table, t3);
-  CHECK_EQ(table.depth_total(), 2);
-  CHECK_EQ(table.bucket_total(), 1);
-  static const uintptr_t k5[] = {2, 1026, 2, 1, 2, 0};
-  CheckTracesAndReset(&table, k5, ARRAYSIZE(k5));
-
-  puts("PASS");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/stacktrace_unittest.cc b/third_party/tcmalloc/vendor/src/tests/stacktrace_unittest.cc
deleted file mode 100644
index 3c9f7353..0000000
--- a/third_party/tcmalloc/vendor/src/tests/stacktrace_unittest.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "config_for_unittests.h"
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include "base/commandlineflags.h"
-#include "base/logging.h"
-#include <gperftools/stacktrace.h>
-
-namespace {
-
-// Obtain a backtrace, verify that the expected callers are present in the
-// backtrace, and maybe print the backtrace to stdout.
-
-// The sequence of functions whose return addresses we expect to see in the
-// backtrace.
-const int BACKTRACE_STEPS = 6;
-
-struct AddressRange {
-  const void *start, *end;
-};
-
-// Expected function [start,end] range.
-AddressRange expected_range[BACKTRACE_STEPS];
-
-#if __GNUC__
-// Using GCC extension: address of a label can be taken with '&&label'.
-// Start should be a label somewhere before recursive call, end somewhere
-// after it.
-#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange)           \
-  do {                                                                   \
-    (prange)->start = &&start_label;                                     \
-    (prange)->end = &&end_label;                                         \
-    CHECK_LT((prange)->start, (prange)->end);                            \
-  } while (0)
-// This macro expands into "unmovable" code (opaque to GCC), and that
-// prevents GCC from moving a_label up or down in the code.
-// Without it, there is no code following the 'end' label, and GCC
-// (4.3.1, 4.4.0) thinks it safe to assign &&end an address that is before
-// the recursive call.
-#define DECLARE_ADDRESS_LABEL(a_label)                                   \
-  a_label: do { __asm__ __volatile__(""); } while (0)
-// Gcc 4.4.0 may split function into multiple chunks, and the chunk
-// performing recursive call may end up later in the code then the return
-// instruction (this actually happens with FDO).
-// Adjust function range from __builtin_return_address.
-#define ADJUST_ADDRESS_RANGE_FROM_RA(prange)                             \
-  do {                                                                   \
-    void *ra = __builtin_return_address(0);                              \
-    CHECK_LT((prange)->start, ra);                                       \
-    if (ra > (prange)->end) {                                            \
-      printf("Adjusting range from %p..%p to %p..%p\n",                  \
-             (prange)->start, (prange)->end,                             \
-             (prange)->start, ra);                                       \
-      (prange)->end = ra;                                                \
-    }                                                                    \
-  } while (0)
-#else
-// Assume the Check* functions below are not longer than 256 bytes.
-#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange)           \
-  do {                                                                   \
-    (prange)->start = reinterpret_cast<const void *>(&fn);               \
-    (prange)->end = reinterpret_cast<const char *>(&fn) + 256;           \
-  } while (0)
-#define DECLARE_ADDRESS_LABEL(a_label) do { } while (0)
-#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) do { } while (0)
-#endif  // __GNUC__
-
-//-----------------------------------------------------------------------//
-
-void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range)
-{
-  CHECK_GE(ret_addr, range.start);
-  CHECK_LE(ret_addr, range.end);
-}
-
-//-----------------------------------------------------------------------//
-
-void ATTRIBUTE_NOINLINE CheckStackTrace(int);
-void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) {
-  const int STACK_LEN = 10;
-  void *stack[STACK_LEN];
-  int size;
-
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);
-  INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
-  DECLARE_ADDRESS_LABEL(start);
-  size = GetStackTrace(stack, STACK_LEN, 0);
-  printf("Obtained %d stack frames.\n", size);
-  CHECK_GE(size, 1);
-  CHECK_LE(size, STACK_LEN);
-
-#ifdef HAVE_EXECINFO_H
-  {
-    char **strings = backtrace_symbols(stack, size);
-    printf("Obtained %d stack frames.\n", size);
-    for (int i = 0; i < size; i++)
-      printf("%s %p\n", strings[i], stack[i]);
-    printf("CheckStackTrace() addr: %p\n", &CheckStackTrace);
-    free(strings);
-  }
-#endif
-
-  for (int i = 0; i < BACKTRACE_STEPS; i++) {
-    printf("Backtrace %d: expected: %p..%p  actual: %p ... ",
-           i, expected_range[i].start, expected_range[i].end, stack[i]);
-    fflush(stdout);
-    CheckRetAddrIsInFunction(stack[i], expected_range[i]);
-    printf("OK\n");
-  }
-  DECLARE_ADDRESS_LABEL(end);
-}
-
-//-----------------------------------------------------------------------//
-
-/* Dummy functions to make the backtrace more interesting. */
-void ATTRIBUTE_NOINLINE CheckStackTrace4(int i) {
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[2]);
-  INIT_ADDRESS_RANGE(CheckStackTrace4, start, end, &expected_range[1]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTraceLeaf();
-  DECLARE_ADDRESS_LABEL(end);
-}
-void ATTRIBUTE_NOINLINE CheckStackTrace3(int i) {
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[3]);
-  INIT_ADDRESS_RANGE(CheckStackTrace3, start, end, &expected_range[2]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTrace4(j);
-  DECLARE_ADDRESS_LABEL(end);
-}
-void ATTRIBUTE_NOINLINE CheckStackTrace2(int i) {
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[4]);
-  INIT_ADDRESS_RANGE(CheckStackTrace2, start, end, &expected_range[3]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTrace3(j);
-  DECLARE_ADDRESS_LABEL(end);
-}
-void ATTRIBUTE_NOINLINE CheckStackTrace1(int i) {
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[5]);
-  INIT_ADDRESS_RANGE(CheckStackTrace1, start, end, &expected_range[4]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTrace2(j);
-  DECLARE_ADDRESS_LABEL(end);
-}
-void ATTRIBUTE_NOINLINE CheckStackTrace(int i) {
-  INIT_ADDRESS_RANGE(CheckStackTrace, start, end, &expected_range[5]);
-  DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
-    CheckStackTrace1(j);
-  DECLARE_ADDRESS_LABEL(end);
-}
-
-}  // namespace
-//-----------------------------------------------------------------------//
-
-int main(int argc, char ** argv) {
-  CheckStackTrace(0);
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/system-alloc_unittest.cc b/third_party/tcmalloc/vendor/src/tests/system-alloc_unittest.cc
deleted file mode 100644
index 4a5f7c08..0000000
--- a/third_party/tcmalloc/vendor/src/tests/system-alloc_unittest.cc
+++ /dev/null
@@ -1,155 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Arun Sharma
-
-#include "config_for_unittests.h"
-#include "system-alloc.h"
-#include <stdio.h>
-#if defined HAVE_STDINT_H
-#include <stdint.h>             // to get uintptr_t
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>           // another place uintptr_t might be defined
-#endif
-#include <sys/types.h>
-#include <algorithm>
-#include <limits>
-#include "base/logging.h"               // for Check_GEImpl, Check_LTImpl, etc
-#include <gperftools/malloc_extension.h>    // for MallocExtension::instance
-#include "common.h"                     // for kAddressBits
-
-class ArraySysAllocator : public SysAllocator {
-public:
-  // Was this allocator invoked at least once?
-  bool invoked_;
-
-  ArraySysAllocator() : SysAllocator() {
-    ptr_ = 0;
-    invoked_ = false;
-  }
-
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment) {
-    invoked_ = true;
-
-    if (size > kArraySize) {
-      return NULL;
-    }
-
-    void *result = &array_[ptr_];
-    uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-
-    if (actual_size) {
-      *actual_size = size;
-    }
-
-    // Try to get more memory for alignment
-    size_t extra = alignment - (ptr & (alignment-1));
-    size += extra;
-    CHECK_LT(ptr_ + size, kArraySize);
-
-    if ((ptr & (alignment-1)) != 0) {
-      ptr += alignment - (ptr & (alignment-1));
-    }
-
-    ptr_ += size;
-    return reinterpret_cast<void *>(ptr);
-  }
-
-  void DumpStats() {
-  }
-
-private:
-  static const int kArraySize = 8 * 1024 * 1024;
-  char array_[kArraySize];
-  // We allocate the next chunk from here
-  int ptr_;
-
-};
-const int ArraySysAllocator::kArraySize;
-ArraySysAllocator a;
-
-static void TestBasicInvoked() {
-  MallocExtension::instance()->SetSystemAllocator(&a);
-
-  // An allocation size that is likely to trigger the system allocator.
-  // XXX: this is implementation specific.
-  char *p = new char[1024 * 1024];
-  delete [] p;
-
-  // Make sure that our allocator was invoked.
-  CHECK(a.invoked_);
-}
-
-#if 0  // could port this to various OSs, but won't bother for now
-TEST(AddressBits, CpuVirtualBits) {
-  // Check that kAddressBits is as least as large as either the number of bits
-  // in a pointer or as the number of virtual bits handled by the processor.
-  // To be effective this test must be run on each processor model.
-  const int kPointerBits = 8 * sizeof(void*);
-  const int kImplementedVirtualBits = NumImplementedVirtualBits();
-
-  CHECK_GE(kAddressBits, std::min(kImplementedVirtualBits, kPointerBits));
-}
-#endif
-
-static void TestBasicRetryFailTest() {
-  // Check with the allocator still works after a failed allocation.
-  //
-  // There is no way to call malloc and guarantee it will fail.  malloc takes a
-  // size_t parameter and the C++ standard does not constrain the size of
-  // size_t.  For example, consider an implementation where size_t is 32 bits
-  // and pointers are 64 bits.
-  //
-  // It is likely, though, that sizeof(size_t) == sizeof(void*).  In that case,
-  // the first allocation here might succeed but the second allocation must
-  // fail.
-  //
-  // If the second allocation succeeds, you will have to rewrite or
-  // disable this test.
-  // The weird parens are to avoid macro-expansion of 'max' on windows.
-  const size_t kHugeSize = (std::numeric_limits<size_t>::max)() / 2;
-  void* p1 = malloc(kHugeSize);
-  void* p2 = malloc(kHugeSize);
-  CHECK(p2 == NULL);
-  if (p1 != NULL) free(p1);
-
-  char* q = new char[1024];
-  CHECK(q != NULL);
-  delete [] q;
-}
-
-int main(int argc, char** argv) {
-  TestBasicInvoked();
-  TestBasicRetryFailTest();
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/tcmalloc_large_unittest.cc b/third_party/tcmalloc/vendor/src/tests/tcmalloc_large_unittest.cc
deleted file mode 100644
index ff22007..0000000
--- a/third_party/tcmalloc/vendor/src/tests/tcmalloc_large_unittest.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Michael Chastain
-//
-// This is a unit test for large allocations in malloc and friends.
-// "Large" means "so large that they overflow the address space".
-// For 32 bits, this means allocations near 2^32 bytes and 2^31 bytes.
-// For 64 bits, this means allocations near 2^64 bytes and 2^63 bytes.
-
-#include <stddef.h>                     // for size_t, NULL
-#include <stdlib.h>                     // for malloc, free, realloc
-#include <stdio.h>
-#include <set>                          // for set, etc
-
-#include "base/logging.h"               // for operator<<, CHECK, etc
-
-using std::set;
-
-// Alloc a size that should always fail.
-
-void TryAllocExpectFail(size_t size) {
-  void* p1 = malloc(size);
-  CHECK(p1 == NULL);
-
-  void* p2 = malloc(1);
-  CHECK(p2 != NULL);
-
-  void* p3 = realloc(p2, size);
-  CHECK(p3 == NULL);
-
-  free(p2);
-}
-
-// Alloc a size that might work and might fail.
-// If it does work, touch some pages.
-
-void TryAllocMightFail(size_t size) {
-  unsigned char* p = static_cast<unsigned char*>(malloc(size));
-  if ( p != NULL ) {
-    unsigned char volatile* vp = p;  // prevent optimizations
-    static const size_t kPoints = 1024;
-
-    for ( size_t i = 0; i < kPoints; ++i ) {
-      vp[i * (size / kPoints)] = static_cast<unsigned char>(i);
-    }
-
-    for ( size_t i = 0; i < kPoints; ++i ) {
-      CHECK(vp[i * (size / kPoints)] == static_cast<unsigned char>(i));
-    }
-
-    vp[size-1] = 'M';
-    CHECK(vp[size-1] == 'M');
-  }
-
-  free(p);
-}
-
-int main (int argc, char** argv) {
-  // Allocate some 0-byte objects.  They better be unique.
-  // 0 bytes is not large but it exercises some paths related to
-  // large-allocation code.
-  {
-    static const int kZeroTimes = 1024;
-    printf("Test malloc(0) x %d\n", kZeroTimes);
-    set<char*> p_set;
-    for ( int i = 0; i < kZeroTimes; ++i ) {
-      char* p = new char;
-      CHECK(p != NULL);
-      CHECK(p_set.find(p) == p_set.end());
-      p_set.insert(p_set.end(), p);
-    }
-    // Just leak the memory.
-  }
-
-  // Grab some memory so that some later allocations are guaranteed to fail.
-  printf("Test small malloc\n");
-  void* p_small = malloc(4*1048576);
-  CHECK(p_small != NULL);
-
-  // Test sizes up near the maximum size_t.
-  // These allocations test the wrap-around code.
-  printf("Test malloc(0 - N)\n");
-  const size_t zero = 0;
-  static const size_t kMinusNTimes = 16384;
-  for ( size_t i = 1; i < kMinusNTimes; ++i ) {
-    TryAllocExpectFail(zero - i);
-  }
-
-  // Test sizes a bit smaller.
-  // The small malloc above guarantees that all these return NULL.
-  printf("Test malloc(0 - 1048576 - N)\n");
-  static const size_t kMinusMBMinusNTimes = 16384;
-  for ( size_t i = 0; i < kMinusMBMinusNTimes; ++i) {
-    TryAllocExpectFail(zero - 1048576 - i);
-  }
-
-  // Test sizes at half of size_t.
-  // These might or might not fail to allocate.
-  printf("Test malloc(max/2 +- N)\n");
-  static const size_t kHalfPlusMinusTimes = 64;
-  const size_t half = (zero - 2) / 2 + 1;
-  for ( size_t i = 0; i < kHalfPlusMinusTimes; ++i) {
-    TryAllocMightFail(half - i);
-    TryAllocMightFail(half + i);
-  }
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/tcmalloc_unittest.cc b/third_party/tcmalloc/vendor/src/tests/tcmalloc_unittest.cc
deleted file mode 100644
index 7ab6b90..0000000
--- a/third_party/tcmalloc/vendor/src/tests/tcmalloc_unittest.cc
+++ /dev/null
@@ -1,1645 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Unittest for the TCMalloc implementation.
-//
-// * The test consists of a set of threads.
-// * Each thread maintains a set of allocated objects, with
-//   a bound on the total amount of data in the set.
-// * Each allocated object's contents are generated by
-//   hashing the object pointer, and a generation count
-//   in the object.  This allows us to easily check for
-//   data corruption.
-// * At any given step, the thread can do any of the following:
-//     a. Allocate an object
-//     b. Increment an object's generation count and update
-//        its contents.
-//     c. Pass the object to another thread
-//     d. Free an object
-//   Also, at the end of every step, object(s) are freed to maintain
-//   the memory upper-bound.
-//
-// If this test is compiled with -DDEBUGALLOCATION, then we don't
-// run some tests that test the inner workings of tcmalloc and
-// break on debugallocation: that certain allocations are aligned
-// in a certain way (even though no standard requires it), and that
-// realloc() tries to minimize copying (which debug allocators don't
-// care about).
-
-#include "config_for_unittests.h"
-// Complicated ordering requirements.  tcmalloc.h defines (indirectly)
-// _POSIX_C_SOURCE, which it needs so stdlib.h defines posix_memalign.
-// unistd.h, on the other hand, requires _POSIX_C_SOURCE to be unset,
-// at least on FreeBSD, in order to define sbrk.  The solution
-// is to #include unistd.h first.  This is safe because unistd.h
-// doesn't sub-include stdlib.h, so we'll still get posix_memalign
-// when we #include stdlib.h.  Blah.
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>        // for testing sbrk hooks
-#endif
-#include "tcmalloc.h"      // must come early, to pick up posix_memalign
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>        // for intptr_t
-#endif
-#include <sys/types.h>     // for size_t
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>         // for open; used with mmap-hook test
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>      // for testing mmap hooks
-#endif
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>        // defines pvalloc/etc on cygwin
-#endif
-#include <assert.h>
-#include <vector>
-#include <algorithm>
-#include <string>
-#include <new>
-#include "base/logging.h"
-#include "base/simple_mutex.h"
-#include "gperftools/malloc_hook.h"
-#include "gperftools/malloc_extension.h"
-#include "gperftools/nallocx.h"
-#include "gperftools/tcmalloc.h"
-#include "thread_cache.h"
-#include "system-alloc.h"
-#include "tests/testutil.h"
-
-// Windows doesn't define pvalloc and a few other obsolete unix
-// functions; nor does it define posix_memalign (which is not obsolete).
-#if defined(_WIN32)
-# define cfree free         // don't bother to try to test these obsolete fns
-# define valloc malloc
-# define pvalloc malloc
-// I'd like to map posix_memalign to _aligned_malloc, but _aligned_malloc
-// must be paired with _aligned_free (not normal free), which is too
-// invasive a change to how we allocate memory here.  So just bail
-static bool kOSSupportsMemalign = false;
-static inline void* Memalign(size_t align, size_t size) {
-  //LOG(FATAL) << "memalign not supported on windows";
-  exit(1);
-  return NULL;
-}
-static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
-  //LOG(FATAL) << "posix_memalign not supported on windows";
-  exit(1);
-  return -1;
-}
-
-// OS X defines posix_memalign in some OS versions but not others;
-// it's confusing enough to check that it's easiest to just not to test.
-#elif defined(__APPLE__)
-static bool kOSSupportsMemalign = false;
-static inline void* Memalign(size_t align, size_t size) {
-  //LOG(FATAL) << "memalign not supported on OS X";
-  exit(1);
-  return NULL;
-}
-static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
-  //LOG(FATAL) << "posix_memalign not supported on OS X";
-  exit(1);
-  return -1;
-}
-
-#else
-static bool kOSSupportsMemalign = true;
-static inline void* Memalign(size_t align, size_t size) {
-  return memalign(align, size);
-}
-static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
-  return posix_memalign(ptr, align, size);
-}
-
-#endif
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-#define OVERALIGNMENT 64
-
-struct overaligned_type
-{
-#if defined(__GNUC__)
-  __attribute__((__aligned__(OVERALIGNMENT)))
-#elif defined(_MSC_VER)
-  __declspec(align(OVERALIGNMENT))
-#else
-  alignas(OVERALIGNMENT)
-#endif
-  unsigned char data[OVERALIGNMENT * 2]; // make the object size different from
-                                         // alignment to make sure the correct
-                                         // values are passed to the new/delete
-                                         // implementation functions
-};
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
-// form of the name instead.
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-#define LOGSTREAM   stdout
-
-using std::vector;
-using std::string;
-
-DECLARE_double(tcmalloc_release_rate);
-DECLARE_int32(max_free_queue_size);     // in debugallocation.cc
-DECLARE_int64(tcmalloc_sample_parameter);
-
-struct OOMAbleSysAlloc : public SysAllocator {
-  SysAllocator *child;
-  int simulate_oom;
-
-  void* Alloc(size_t size, size_t* actual_size, size_t alignment) {
-    if (simulate_oom) {
-      return NULL;
-    }
-    return child->Alloc(size, actual_size, alignment);
-  }
-};
-
-static union {
-  char buf[sizeof(OOMAbleSysAlloc)];
-  void *ptr;
-} test_sys_alloc_space;
-
-static OOMAbleSysAlloc* get_test_sys_alloc() {
-  return reinterpret_cast<OOMAbleSysAlloc*>(&test_sys_alloc_space);
-}
-
-void setup_oomable_sys_alloc() {
-  SysAllocator *def = MallocExtension::instance()->GetSystemAllocator();
-
-  OOMAbleSysAlloc *alloc = get_test_sys_alloc();
-  new (alloc) OOMAbleSysAlloc;
-  alloc->child = def;
-
-  MallocExtension::instance()->SetSystemAllocator(alloc);
-}
-
-namespace testing {
-
-static const int FLAGS_numtests = 50000;
-static const int FLAGS_log_every_n_tests = 50000; // log exactly once
-
-// Testing parameters
-static const int FLAGS_lgmaxsize = 16;   // lg() of the max size object to alloc
-static const int FLAGS_numthreads = 10;  // Number of threads
-static const int FLAGS_threadmb = 4;     // Max memory size allocated by thread
-static const int FLAGS_lg_max_memalign = 18; // lg of max alignment for memalign
-
-static const double FLAGS_memalign_min_fraction = 0;    // min expected%
-static const double FLAGS_memalign_max_fraction = 0.4;  // max expected%
-static const double FLAGS_memalign_max_alignment_ratio = 6;  // alignment/size
-
-// Weights of different operations
-static const int FLAGS_allocweight = 50;    // Weight for picking allocation
-static const int FLAGS_freeweight = 50;     // Weight for picking free
-static const int FLAGS_updateweight = 10;   // Weight for picking update
-static const int FLAGS_passweight = 1;      // Weight for passing object
-
-static const int kSizeBits = 8 * sizeof(size_t);
-static const size_t kMaxSize = ~static_cast<size_t>(0);
-static const size_t kMaxSignedSize = ((size_t(1) << (kSizeBits-1)) - 1);
-
-static const size_t kNotTooBig = 100000;
-// We want an allocation that is definitely more than main memory.  OS
-// X has special logic to discard very big allocs before even passing
-// the request along to the user-defined memory allocator; we're not
-// interested in testing their logic, so we have to make sure we're
-// not *too* big.
-static const size_t kTooBig = kMaxSize - 100000;
-
-static int news_handled = 0;
-
-// Global array of threads
-class TesterThread;
-static TesterThread** threads;
-
-// To help with generating random numbers
-class TestHarness {
- private:
-  // Information kept per type
-  struct Type {
-    string      name;
-    int         type;
-    int         weight;
-  };
-
- public:
-  TestHarness(int seed)
-      : types_(new vector<Type>), total_weight_(0), num_tests_(0) {
-    srandom(seed);
-  }
-  ~TestHarness() {
-    delete types_;
-  }
-
-  // Add operation type with specified weight.  When starting a new
-  // iteration, an operation type is picked with probability
-  // proportional to its weight.
-  //
-  // "type" must be non-negative.
-  // "weight" must be non-negative.
-  void AddType(int type, int weight, const char* name);
-
-  // Call this to get the type of operation for the next iteration.
-  // It returns a random operation type from the set of registered
-  // operations.  Returns -1 if tests should finish.
-  int PickType();
-
-  // If n == 0, returns the next pseudo-random number in the range [0 .. 0]
-  // If n != 0, returns the next pseudo-random number in the range [0 .. n)
-  int Uniform(int n) {
-    if (n == 0) {
-      return random() * 0;
-    } else {
-      return random() % n;
-    }
-  }
-  // Pick "base" uniformly from range [0,max_log] and then return
-  // "base" random bits.  The effect is to pick a number in the range
-  // [0,2^max_log-1] with bias towards smaller numbers.
-  int Skewed(int max_log) {
-    const int base = random() % (max_log+1);
-    return random() % (1 << base);
-  }
-
- private:
-  vector<Type>*         types_;         // Registered types
-  int                   total_weight_;  // Total weight of all types
-  int                   num_tests_;     // Num tests run so far
-};
-
-void TestHarness::AddType(int type, int weight, const char* name) {
-  Type t;
-  t.name = name;
-  t.type = type;
-  t.weight = weight;
-  types_->push_back(t);
-  total_weight_ += weight;
-}
-
-int TestHarness::PickType() {
-  if (num_tests_ >= FLAGS_numtests) return -1;
-  num_tests_++;
-
-  assert(total_weight_ > 0);
-  // This is a little skewed if total_weight_ doesn't divide 2^31, but it's close
-  int v = Uniform(total_weight_);
-  int i;
-  for (i = 0; i < types_->size(); i++) {
-    v -= (*types_)[i].weight;
-    if (v < 0) {
-      break;
-    }
-  }
-
-  assert(i < types_->size());
-  if ((num_tests_ % FLAGS_log_every_n_tests) == 0) {
-    fprintf(LOGSTREAM, "  Test %d out of %d: %s\n",
-            num_tests_, FLAGS_numtests, (*types_)[i].name.c_str());
-  }
-  return (*types_)[i].type;
-}
-
-class AllocatorState : public TestHarness {
- public:
-  explicit AllocatorState(int seed) : TestHarness(seed), memalign_fraction_(0) {
-    if (kOSSupportsMemalign) {
-      CHECK_GE(FLAGS_memalign_max_fraction, 0);
-      CHECK_LE(FLAGS_memalign_max_fraction, 1);
-      CHECK_GE(FLAGS_memalign_min_fraction, 0);
-      CHECK_LE(FLAGS_memalign_min_fraction, 1);
-      double delta = FLAGS_memalign_max_fraction - FLAGS_memalign_min_fraction;
-      CHECK_GE(delta, 0);
-      memalign_fraction_ = (Uniform(10000)/10000.0 * delta +
-                            FLAGS_memalign_min_fraction);
-      //fprintf(LOGSTREAM, "memalign fraction: %f\n", memalign_fraction_);
-    }
-  }
-  virtual ~AllocatorState() {}
-
-  // Allocate memory.  Randomly choose between malloc() or posix_memalign().
-  void* alloc(size_t size) {
-    if (Uniform(100) < memalign_fraction_ * 100) {
-      // Try a few times to find a reasonable alignment, or fall back on malloc.
-      for (int i = 0; i < 5; i++) {
-        size_t alignment = 1 << Uniform(FLAGS_lg_max_memalign);
-        if (alignment >= sizeof(intptr_t) &&
-            (size < sizeof(intptr_t) ||
-             alignment < FLAGS_memalign_max_alignment_ratio * size)) {
-          void *result = reinterpret_cast<void*>(static_cast<intptr_t>(0x1234));
-          int err = PosixMemalign(&result, alignment, size);
-          if (err != 0) {
-            CHECK_EQ(err, ENOMEM);
-          }
-          return err == 0 ? result : NULL;
-        }
-      }
-    }
-    return malloc(size);
-  }
-
- private:
-  double memalign_fraction_;
-};
-
-
-// Info kept per thread
-class TesterThread {
- private:
-  // Info kept per allocated object
-  struct Object {
-    char*       ptr;                    // Allocated pointer
-    int         size;                   // Allocated size
-    int         generation;             // Generation counter of object contents
-  };
-
-  Mutex                 lock_;          // For passing in another thread's obj
-  int                   id_;            // My thread id
-  AllocatorState        rnd_;           // For generating random numbers
-  vector<Object>        heap_;          // This thread's heap
-  vector<Object>        passed_;        // Pending objects passed from others
-  size_t                heap_size_;     // Current heap size
-  int                   locks_ok_;      // Number of OK TryLock() ops
-  int                   locks_failed_;  // Number of failed TryLock() ops
-
-  // Type of operations
-  enum Type { ALLOC, FREE, UPDATE, PASS };
-
-  // ACM minimal standard random number generator.  (re-entrant.)
-  class ACMRandom {
-    int32 seed_;
-   public:
-    explicit ACMRandom(int32 seed) { seed_ = seed; }
-    int32 Next() {
-      const int32 M = 2147483647L;   // 2^31-1
-      const int32 A = 16807;
-      // In effect, we are computing seed_ = (seed_ * A) % M, where M = 2^31-1
-      uint32 lo = A * (int32)(seed_ & 0xFFFF);
-      uint32 hi = A * (int32)((uint32)seed_ >> 16);
-      lo += (hi & 0x7FFF) << 16;
-      if (lo > M) {
-        lo &= M;
-        ++lo;
-      }
-      lo += hi >> 15;
-      if (lo > M) {
-        lo &= M;
-        ++lo;
-      }
-      return (seed_ = (int32) lo);
-    }
-  };
-
- public:
-  TesterThread(int id)
-    : id_(id),
-      rnd_(id+1),
-      heap_size_(0),
-      locks_ok_(0),
-      locks_failed_(0) {
-  }
-
-  virtual ~TesterThread() {
-    if (FLAGS_verbose)
-      fprintf(LOGSTREAM, "Thread %2d: locks %6d ok; %6d trylocks failed\n",
-              id_, locks_ok_, locks_failed_);
-    if (locks_ok_ + locks_failed_ >= 1000) {
-      CHECK_LE(locks_failed_, locks_ok_ / 2);
-    }
-  }
-
-  virtual void Run() {
-    rnd_.AddType(ALLOC,  FLAGS_allocweight,   "allocate");
-    rnd_.AddType(FREE,   FLAGS_freeweight,    "free");
-    rnd_.AddType(UPDATE, FLAGS_updateweight,  "update");
-    rnd_.AddType(PASS,   FLAGS_passweight,    "pass");
-
-    while (true) {
-      AcquirePassedObjects();
-
-      switch (rnd_.PickType()) {
-        case ALLOC:   AllocateObject(); break;
-        case FREE:    FreeObject();     break;
-        case UPDATE:  UpdateObject();   break;
-        case PASS:    PassObject();     break;
-        case -1:      goto done;
-        default:      assert(NULL == "Unknown type");
-      }
-
-      ShrinkHeap();
-    }
-
- done:
-    DeleteHeap();
-  }
-
-  // Allocate a new object
-  void AllocateObject() {
-    Object object;
-    object.size = rnd_.Skewed(FLAGS_lgmaxsize);
-    object.ptr = static_cast<char*>(rnd_.alloc(object.size));
-    CHECK(object.ptr);
-    object.generation = 0;
-    FillContents(&object);
-    heap_.push_back(object);
-    heap_size_ += object.size;
-  }
-
-  // Mutate a random object
-  void UpdateObject() {
-    if (heap_.empty()) return;
-    const int index = rnd_.Uniform(heap_.size());
-    CheckContents(heap_[index]);
-    heap_[index].generation++;
-    FillContents(&heap_[index]);
-  }
-
-  // Free a random object
-  void FreeObject() {
-    if (heap_.empty()) return;
-    const int index = rnd_.Uniform(heap_.size());
-    Object object = heap_[index];
-    CheckContents(object);
-    free(object.ptr);
-    heap_size_ -= object.size;
-    heap_[index] = heap_[heap_.size()-1];
-    heap_.pop_back();
-  }
-
-  // Delete all objects in the heap
-  void DeleteHeap() {
-    while (!heap_.empty()) {
-      FreeObject();
-    }
-  }
-
-  // Free objects until our heap is small enough
-  void ShrinkHeap() {
-    while (heap_size_ > FLAGS_threadmb << 20) {
-      assert(!heap_.empty());
-      FreeObject();
-    }
-  }
-
-  // Pass a random object to another thread
-  void PassObject() {
-    // Pick object to pass
-    if (heap_.empty()) return;
-    const int index = rnd_.Uniform(heap_.size());
-    Object object = heap_[index];
-    CheckContents(object);
-
-    // Pick thread to pass
-    const int tid = rnd_.Uniform(FLAGS_numthreads);
-    TesterThread* thread = threads[tid];
-
-    if (thread->lock_.TryLock()) {
-      // Pass the object
-      locks_ok_++;
-      thread->passed_.push_back(object);
-      thread->lock_.Unlock();
-      heap_size_ -= object.size;
-      heap_[index] = heap_[heap_.size()-1];
-      heap_.pop_back();
-    } else {
-      locks_failed_++;
-    }
-  }
-
-  // Grab any objects passed to this thread by another thread
-  void AcquirePassedObjects() {
-    // We do not create unnecessary contention by always using
-    // TryLock().  Plus we unlock immediately after swapping passed
-    // objects into a local vector.
-    vector<Object> copy;
-    { // Locking scope
-      if (!lock_.TryLock()) {
-        locks_failed_++;
-        return;
-      }
-      locks_ok_++;
-      swap(copy, passed_);
-      lock_.Unlock();
-    }
-
-    for (int i = 0; i < copy.size(); ++i) {
-      const Object& object = copy[i];
-      CheckContents(object);
-      heap_.push_back(object);
-      heap_size_ += object.size;
-    }
-  }
-
-  // Fill object contents according to ptr/generation
-  void FillContents(Object* object) {
-    ACMRandom r(reinterpret_cast<intptr_t>(object->ptr) & 0x7fffffff);
-    for (int i = 0; i < object->generation; ++i) {
-      r.Next();
-    }
-    const char c = static_cast<char>(r.Next());
-    memset(object->ptr, c, object->size);
-  }
-
-  // Check object contents
-  void CheckContents(const Object& object) {
-    ACMRandom r(reinterpret_cast<intptr_t>(object.ptr) & 0x7fffffff);
-    for (int i = 0; i < object.generation; ++i) {
-      r.Next();
-    }
-
-    // For large objects, we just check a prefix/suffix
-    const char expected = static_cast<char>(r.Next());
-    const int limit1 = object.size < 32 ? object.size : 32;
-    const int start2 = limit1 > object.size - 32 ? limit1 : object.size - 32;
-    for (int i = 0; i < limit1; ++i) {
-      CHECK_EQ(object.ptr[i], expected);
-    }
-    for (int i = start2; i < object.size; ++i) {
-      CHECK_EQ(object.ptr[i], expected);
-    }
-  }
-};
-
-static void RunThread(int thread_id) {
-  threads[thread_id]->Run();
-}
-
-static void TryHugeAllocation(size_t s, AllocatorState* rnd) {
-  void* p = rnd->alloc(s);
-  CHECK(p == NULL);   // huge allocation s should fail!
-}
-
-static void TestHugeAllocations(AllocatorState* rnd) {
-  // Check that asking for stuff tiny bit smaller than largest possible
-  // size returns NULL.
-  for (size_t i = 0; i < 70000; i += rnd->Uniform(20)) {
-    TryHugeAllocation(kMaxSize - i, rnd);
-  }
-  // Asking for memory sizes near signed/unsigned boundary (kMaxSignedSize)
-  // might work or not, depending on the amount of virtual memory.
-#ifndef DEBUGALLOCATION    // debug allocation takes forever for huge allocs
-  for (size_t i = 0; i < 100; i++) {
-    void* p = NULL;
-    p = rnd->alloc(kMaxSignedSize + i);
-    if (p) free(p);    // if: free(NULL) is not necessarily defined
-    p = rnd->alloc(kMaxSignedSize - i);
-    if (p) free(p);
-  }
-#endif
-
-  // Check that ReleaseFreeMemory has no visible effect (aka, does not
-  // crash the test):
-  MallocExtension* inst = MallocExtension::instance();
-  CHECK(inst);
-  inst->ReleaseFreeMemory();
-}
-
-static void TestCalloc(size_t n, size_t s, bool ok) {
-  char* p = reinterpret_cast<char*>(calloc(n, s));
-  if (FLAGS_verbose)
-    fprintf(LOGSTREAM, "calloc(%" PRIxS ", %" PRIxS "): %p\n", n, s, p);
-  if (!ok) {
-    CHECK(p == NULL);  // calloc(n, s) should not succeed
-  } else {
-    CHECK(p != NULL);  // calloc(n, s) should succeed
-    for (int i = 0; i < n*s; i++) {
-      CHECK(p[i] == '\0');
-    }
-    free(p);
-  }
-}
-
-// This makes sure that reallocing a small number of bytes in either
-// direction doesn't cause us to allocate new memory.
-static void TestRealloc() {
-#ifndef DEBUGALLOCATION  // debug alloc doesn't try to minimize reallocs
-  // When sampling, we always allocate in units of page-size, which
-  // makes reallocs of small sizes do extra work (thus, failing these
-  // checks).  Since sampling is random, we turn off sampling to make
-  // sure that doesn't happen to us here.
-  const int64 old_sample_parameter = FLAGS_tcmalloc_sample_parameter;
-  FLAGS_tcmalloc_sample_parameter = 0;   // turn off sampling
-
-  int start_sizes[] = { 100, 1000, 10000, 100000 };
-  int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 };
-
-  for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) {
-    void* p = malloc(start_sizes[s]);
-    CHECK(p);
-    // The larger the start-size, the larger the non-reallocing delta.
-    for (int d = 0; d < (s+1) * 2; ++d) {
-      void* new_p = realloc(p, start_sizes[s] + deltas[d]);
-      CHECK(p == new_p);  // realloc should not allocate new memory
-    }
-    // Test again, but this time reallocing smaller first.
-    for (int d = 0; d < s*2; ++d) {
-      void* new_p = realloc(p, start_sizes[s] - deltas[d]);
-      CHECK(p == new_p);  // realloc should not allocate new memory
-    }
-    free(p);
-  }
-  FLAGS_tcmalloc_sample_parameter = old_sample_parameter;
-#endif
-}
-
-static void TestNewHandler() {
-  ++news_handled;
-  throw std::bad_alloc();
-}
-
-static void TestOneNew(void* (*func)(size_t)) {
-  // success test
-  try {
-    void* ptr = (*func)(kNotTooBig);
-    if (0 == ptr) {
-      fprintf(LOGSTREAM, "allocation should not have failed.\n");
-      abort();
-    }
-  } catch (...) {
-    fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
-    abort();
-  }
-
-  // failure test
-  // we should always receive a bad_alloc exception
-  try {
-    (*func)(kTooBig);
-    fprintf(LOGSTREAM, "allocation should have failed.\n");
-    abort();
-  } catch (const std::bad_alloc&) {
-    // correct
-  } catch (...) {
-    fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
-    abort();
-  }
-}
-
-static void TestNew(void* (*func)(size_t)) {
-  news_handled = 0;
-
-  // test without new_handler:
-  std::new_handler saved_handler = std::set_new_handler(0);
-  TestOneNew(func);
-
-  // test with new_handler:
-  std::set_new_handler(TestNewHandler);
-  TestOneNew(func);
-  if (news_handled != 1) {
-    fprintf(LOGSTREAM, "new_handler was not called.\n");
-    abort();
-  }
-  std::set_new_handler(saved_handler);
-}
-
-static void TestOneNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {
-  // success test
-  try {
-    void* ptr = (*func)(kNotTooBig, std::nothrow);
-    if (0 == ptr) {
-      fprintf(LOGSTREAM, "allocation should not have failed.\n");
-      abort();
-    }
-  } catch (...) {
-    fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
-    abort();
-  }
-
-  // failure test
-  // we should always receive a bad_alloc exception
-  try {
-    if ((*func)(kTooBig, std::nothrow) != 0) {
-      fprintf(LOGSTREAM, "allocation should have failed.\n");
-      abort();
-    }
-  } catch (...) {
-    fprintf(LOGSTREAM, "nothrow allocation threw unexpected exception.\n");
-    abort();
-  }
-}
-
-static void TestNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {
-  news_handled = 0;
-
-  // test without new_handler:
-  std::new_handler saved_handler = std::set_new_handler(0);
-  TestOneNothrowNew(func);
-
-  // test with new_handler:
-  std::set_new_handler(TestNewHandler);
-  TestOneNothrowNew(func);
-  if (news_handled != 1) {
-    fprintf(LOGSTREAM, "nothrow new_handler was not called.\n");
-    abort();
-  }
-  std::set_new_handler(saved_handler);
-}
-
-
-// These are used as callbacks by the sanity-check.  Set* and Reset*
-// register the hook that counts how many times the associated memory
-// function is called.  After each such call, call Verify* to verify
-// that we used the tcmalloc version of the call, and not the libc.
-// Note the ... in the hook signature: we don't care what arguments
-// the hook takes.
-#define MAKE_HOOK_CALLBACK(hook_type, ...)                              \
-  static volatile int g_##hook_type##_calls = 0;                                 \
-  static void IncrementCallsTo##hook_type(__VA_ARGS__) {                \
-    g_##hook_type##_calls++;                                            \
-  }                                                                     \
-  static void Verify##hook_type##WasCalled() {                          \
-    CHECK_GT(g_##hook_type##_calls, 0);                                 \
-    g_##hook_type##_calls = 0;  /* reset for next call */               \
-  }                                                                     \
-  static void Set##hook_type() {                                        \
-    CHECK(MallocHook::Add##hook_type(                                   \
-        (MallocHook::hook_type)&IncrementCallsTo##hook_type));          \
-  }                                                                     \
-  static void Reset##hook_type() {                                      \
-    CHECK(MallocHook::Remove##hook_type(                                \
-        (MallocHook::hook_type)&IncrementCallsTo##hook_type));          \
-  }
-
-// We do one for each hook typedef in malloc_hook.h
-MAKE_HOOK_CALLBACK(NewHook, const void*, size_t);
-MAKE_HOOK_CALLBACK(DeleteHook, const void*);
-MAKE_HOOK_CALLBACK(MmapHook, const void*, const void*, size_t, int, int, int,
-                   off_t);
-MAKE_HOOK_CALLBACK(MremapHook, const void*, const void*, size_t, size_t, int,
-                   const void*);
-MAKE_HOOK_CALLBACK(MunmapHook, const void *, size_t);
-MAKE_HOOK_CALLBACK(SbrkHook, const void *, ptrdiff_t);
-
-static void TestAlignmentForSize(int size) {
-  fprintf(LOGSTREAM, "Testing alignment of malloc(%d)\n", size);
-  static const int kNum = 100;
-  void* ptrs[kNum];
-  for (int i = 0; i < kNum; i++) {
-    ptrs[i] = malloc(size);
-    uintptr_t p = reinterpret_cast<uintptr_t>(ptrs[i]);
-    CHECK((p % sizeof(void*)) == 0);
-    CHECK((p % sizeof(double)) == 0);
-
-    // Must have 16-byte (or 8-byte in case of -DTCMALLOC_ALIGN_8BYTES)
-    // alignment for large enough objects
-    if (size >= kMinAlign) {
-      CHECK((p % kMinAlign) == 0);
-    }
-  }
-  for (int i = 0; i < kNum; i++) {
-    free(ptrs[i]);
-  }
-}
-
-static void TestMallocAlignment() {
-  for (int lg = 0; lg < 16; lg++) {
-    TestAlignmentForSize((1<<lg) - 1);
-    TestAlignmentForSize((1<<lg) + 0);
-    TestAlignmentForSize((1<<lg) + 1);
-  }
-}
-
-static void TestHugeThreadCache() {
-  fprintf(LOGSTREAM, "==== Testing huge thread cache\n");
-  // More than 2^16 to cause integer overflow of 16 bit counters.
-  static const int kNum = 70000;
-  char** array = new char*[kNum];
-  for (int i = 0; i < kNum; ++i) {
-    array[i] = new char[10];
-  }
-  for (int i = 0; i < kNum; ++i) {
-    delete[] array[i];
-  }
-  delete[] array;
-}
-
-namespace {
-
-struct RangeCallbackState {
-  uintptr_t ptr;
-  base::MallocRange::Type expected_type;
-  size_t min_size;
-  bool matched;
-};
-
-static void RangeCallback(void* arg, const base::MallocRange* r) {
-  RangeCallbackState* state = reinterpret_cast<RangeCallbackState*>(arg);
-  if (state->ptr >= r->address &&
-      state->ptr < r->address + r->length) {
-    if (state->expected_type == base::MallocRange::FREE) {
-      // We are expecting r->type == FREE, but ReleaseMemory
-      // may have already moved us to UNMAPPED state instead (this happens in
-      // approximately 0.1% of executions). Accept either state.
-      CHECK(r->type == base::MallocRange::FREE ||
-            r->type == base::MallocRange::UNMAPPED);
-    } else {
-      CHECK_EQ(r->type, state->expected_type);
-    }
-    CHECK_GE(r->length, state->min_size);
-    state->matched = true;
-  }
-}
-
-// Check that at least one of the callbacks from Ranges() contains
-// the specified address with the specified type, and has size
-// >= min_size.
-static void CheckRangeCallback(void* ptr, base::MallocRange::Type type,
-                               size_t min_size) {
-  RangeCallbackState state;
-  state.ptr = reinterpret_cast<uintptr_t>(ptr);
-  state.expected_type = type;
-  state.min_size = min_size;
-  state.matched = false;
-  MallocExtension::instance()->Ranges(&state, RangeCallback);
-  CHECK(state.matched);
-}
-
-}
-
-static bool HaveSystemRelease =
-    TCMalloc_SystemRelease(TCMalloc_SystemAlloc(kPageSize, NULL, 0), kPageSize);
-
-static void TestRanges() {
-  static const int MB = 1048576;
-  void* a = malloc(MB);
-  void* b = malloc(MB);
-  base::MallocRange::Type releasedType =
-      HaveSystemRelease ? base::MallocRange::UNMAPPED : base::MallocRange::FREE;
-
-  CheckRangeCallback(a, base::MallocRange::INUSE, MB);
-  CheckRangeCallback(b, base::MallocRange::INUSE, MB);
-  free(a);
-  CheckRangeCallback(a, base::MallocRange::FREE, MB);
-  CheckRangeCallback(b, base::MallocRange::INUSE, MB);
-  MallocExtension::instance()->ReleaseFreeMemory();
-  CheckRangeCallback(a, releasedType, MB);
-  CheckRangeCallback(b, base::MallocRange::INUSE, MB);
-  free(b);
-  CheckRangeCallback(a, releasedType, MB);
-  CheckRangeCallback(b, base::MallocRange::FREE, MB);
-}
-
-#ifndef DEBUGALLOCATION
-static size_t GetUnmappedBytes() {
-  size_t bytes;
-  CHECK(MallocExtension::instance()->GetNumericProperty(
-      "tcmalloc.pageheap_unmapped_bytes", &bytes));
-  return bytes;
-}
-#endif
-
-class AggressiveDecommitChanger {
-  size_t old_value_;
-public:
-  AggressiveDecommitChanger(size_t new_value) {
-    MallocExtension *inst = MallocExtension::instance();
-    bool rv = inst->GetNumericProperty("tcmalloc.aggressive_memory_decommit", &old_value_);
-    CHECK_CONDITION(rv);
-    rv = inst->SetNumericProperty("tcmalloc.aggressive_memory_decommit", new_value);
-    CHECK_CONDITION(rv);
-  }
-  ~AggressiveDecommitChanger() {
-    MallocExtension *inst = MallocExtension::instance();
-    bool rv = inst->SetNumericProperty("tcmalloc.aggressive_memory_decommit", old_value_);
-    CHECK_CONDITION(rv);
-  }
-};
-
-static void TestReleaseToSystem() {
-  // Debug allocation mode adds overhead to each allocation which
-  // messes up all the equality tests here.  I just disable the
-  // teset in this mode.  TODO(csilvers): get it to work for debugalloc?
-#ifndef DEBUGALLOCATION
-
-  if(!HaveSystemRelease) return;
-
-  const double old_tcmalloc_release_rate = FLAGS_tcmalloc_release_rate;
-  FLAGS_tcmalloc_release_rate = 0;
-
-  AggressiveDecommitChanger disabler(0);
-
-  static const int MB = 1048576;
-  void* a = malloc(MB);
-  void* b = malloc(MB);
-  MallocExtension::instance()->ReleaseFreeMemory();
-  size_t starting_bytes = GetUnmappedBytes();
-
-  // Calling ReleaseFreeMemory() a second time shouldn't do anything.
-  MallocExtension::instance()->ReleaseFreeMemory();
-  EXPECT_EQ(starting_bytes, GetUnmappedBytes());
-
-  // ReleaseToSystem shouldn't do anything either.
-  MallocExtension::instance()->ReleaseToSystem(MB);
-  EXPECT_EQ(starting_bytes, GetUnmappedBytes());
-
-  free(a);
-
-  // The span to release should be 1MB.
-  MallocExtension::instance()->ReleaseToSystem(MB/2);
-  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
-
-  // Should do nothing since the previous call released too much.
-  MallocExtension::instance()->ReleaseToSystem(MB/4);
-  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
-
-  free(b);
-
-  // Use up the extra MB/4 bytes from 'a' and also release 'b'.
-  MallocExtension::instance()->ReleaseToSystem(MB/2);
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  // Should do nothing since the previous call released too much.
-  MallocExtension::instance()->ReleaseToSystem(MB/2);
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  // Nothing else to release.
-  MallocExtension::instance()->ReleaseFreeMemory();
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  a = malloc(MB);
-  free(a);
-  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
-
-  // Releasing less than a page should still trigger a release.
-  MallocExtension::instance()->ReleaseToSystem(1);
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  FLAGS_tcmalloc_release_rate = old_tcmalloc_release_rate;
-#endif   // #ifndef DEBUGALLOCATION
-}
-
-static void TestAggressiveDecommit() {
-  // Debug allocation mode adds overhead to each allocation which
-  // messes up all the equality tests here.  I just disable the
-  // teset in this mode.
-#ifndef DEBUGALLOCATION
-
-  if(!HaveSystemRelease) return;
-
-  fprintf(LOGSTREAM, "Testing aggressive de-commit\n");
-
-  AggressiveDecommitChanger enabler(1);
-
-  static const int MB = 1048576;
-  void* a = malloc(MB);
-  void* b = malloc(MB);
-
-  size_t starting_bytes = GetUnmappedBytes();
-
-  // ReleaseToSystem shouldn't do anything either.
-  MallocExtension::instance()->ReleaseToSystem(MB);
-  EXPECT_EQ(starting_bytes, GetUnmappedBytes());
-
-  free(a);
-
-  // The span to release should be 1MB.
-  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
-
-  free(b);
-
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  // Nothing else to release.
-  MallocExtension::instance()->ReleaseFreeMemory();
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  a = malloc(MB);
-  free(a);
-
-  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
-
-  fprintf(LOGSTREAM, "Done testing aggressive de-commit\n");
-
-#endif   // #ifndef DEBUGALLOCATION
-}
-
-// On MSVC10, in release mode, the optimizer convinces itself
-// g_no_memory is never changed (I guess it doesn't realize OnNoMemory
-// might be called).  Work around this by setting the var volatile.
-volatile bool g_no_memory = false;
-std::new_handler g_old_handler = NULL;
-static void OnNoMemory() {
-  g_no_memory = true;
-  std::set_new_handler(g_old_handler);
-}
-
-static void TestSetNewMode() {
-  int old_mode = tc_set_new_mode(1);
-
-  g_old_handler = std::set_new_handler(&OnNoMemory);
-  g_no_memory = false;
-  void* ret = malloc(kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_TRUE(g_no_memory);
-
-  g_old_handler = std::set_new_handler(&OnNoMemory);
-  g_no_memory = false;
-  ret = calloc(1, kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_TRUE(g_no_memory);
-
-  g_old_handler = std::set_new_handler(&OnNoMemory);
-  g_no_memory = false;
-  ret = realloc(NULL, kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_TRUE(g_no_memory);
-
-  if (kOSSupportsMemalign) {
-    // Not really important, but must be small enough such that
-    // kAlignment + kTooBig does not overflow.
-    const int kAlignment = 1 << 5;
-
-    g_old_handler = std::set_new_handler(&OnNoMemory);
-    g_no_memory = false;
-    ret = Memalign(kAlignment, kTooBig);
-    EXPECT_EQ(NULL, ret);
-    EXPECT_TRUE(g_no_memory);
-
-    g_old_handler = std::set_new_handler(&OnNoMemory);
-    g_no_memory = false;
-    EXPECT_EQ(ENOMEM,
-              PosixMemalign(&ret, kAlignment, kTooBig));
-    EXPECT_EQ(NULL, ret);
-    EXPECT_TRUE(g_no_memory);
-  }
-
-  tc_set_new_mode(old_mode);
-}
-
-static void TestErrno(void) {
-  void* ret;
-  if (kOSSupportsMemalign) {
-    errno = 0;
-    ret = Memalign(128, kTooBig);
-    EXPECT_EQ(NULL, ret);
-    EXPECT_EQ(ENOMEM, errno);
-  }
-
-  errno = 0;
-  ret = malloc(kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_EQ(ENOMEM, errno);
-
-  errno = 0;
-  ret = tc_malloc_skip_new_handler(kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_EQ(ENOMEM, errno);
-}
-
-
-#ifndef DEBUGALLOCATION
-// Ensure that nallocx works before main.
-struct GlobalNallocx {
-  GlobalNallocx() { CHECK_GT(nallocx(99, 0), 99); }
-} global_nallocx;
-
-#if defined(__GNUC__)
-
-static void check_global_nallocx() __attribute__((constructor));
-static void check_global_nallocx() { CHECK_GT(nallocx(99, 0), 99); }
-
-#endif // __GNUC__
-
-static void TestNAllocX() {
-  for (size_t size = 0; size <= (1 << 20); size += 7) {
-    size_t rounded = nallocx(size, 0);
-    ASSERT_GE(rounded, size);
-    void* ptr = malloc(size);
-    ASSERT_EQ(rounded, MallocExtension::instance()->GetAllocatedSize(ptr));
-    free(ptr);
-  }
-}
-
-static void TestNAllocXAlignment() {
-  for (size_t size = 0; size <= (1 << 20); size += 7) {
-    for (size_t align = 0; align < 10; align++) {
-      size_t rounded = nallocx(size, MALLOCX_LG_ALIGN(align));
-      ASSERT_GE(rounded, size);
-      ASSERT_EQ(rounded % (1 << align), 0);
-      void* ptr = tc_memalign(1 << align, size);
-      ASSERT_EQ(rounded, MallocExtension::instance()->GetAllocatedSize(ptr));
-      free(ptr);
-    }
-  }
-}
-
-static int saw_new_handler_runs;
-static void* volatile oom_test_last_ptr;
-
-static void test_new_handler() {
-  get_test_sys_alloc()->simulate_oom = false;
-  void *ptr = oom_test_last_ptr;
-  oom_test_last_ptr = NULL;
-  ::operator delete[](ptr);
-  saw_new_handler_runs++;
-}
-
-static ATTRIBUTE_NOINLINE void TestNewOOMHandling() {
-  // debug allocator does internal allocations and crashes when such
-  // internal allocation fails. So don't test it.
-  setup_oomable_sys_alloc();
-
-  std::new_handler old = std::set_new_handler(test_new_handler);
-  get_test_sys_alloc()->simulate_oom = true;
-
-  ASSERT_EQ(saw_new_handler_runs, 0);
-
-  for (int i = 0; i < 10240; i++) {
-    oom_test_last_ptr = new char [512];
-    ASSERT_NE(oom_test_last_ptr, NULL);
-    if (saw_new_handler_runs) {
-      break;
-    }
-  }
-
-  ASSERT_GE(saw_new_handler_runs, 1);
-
-  get_test_sys_alloc()->simulate_oom = false;
-  std::set_new_handler(old);
-}
-#endif  // !DEBUGALLOCATION
-
-static int RunAllTests(int argc, char** argv) {
-  // Optional argv[1] is the seed
-  AllocatorState rnd(argc > 1 ? atoi(argv[1]) : 100);
-
-  SetTestResourceLimit();
-
-#ifndef DEBUGALLOCATION
-  TestNewOOMHandling();
-#endif
-
-  // TODO(odo):  This test has been disabled because it is only by luck that it
-  // does not result in fragmentation.  When tcmalloc makes an allocation which
-  // spans previously unused leaves of the pagemap it will allocate and fill in
-  // the leaves to cover the new allocation.  The leaves happen to be 256MiB in
-  // the 64-bit build, and with the sbrk allocator these allocations just
-  // happen to fit in one leaf by luck.  With other allocators (mmap,
-  // memfs_malloc when used with small pages) the allocations generally span
-  // two leaves and this results in a very bad fragmentation pattern with this
-  // code.  The same failure can be forced with the sbrk allocator just by
-  // allocating something on the order of 128MiB prior to starting this test so
-  // that the test allocations straddle a 256MiB boundary.
-
-  // TODO(csilvers): port MemoryUsage() over so the test can use that
-#if 0
-# include <unistd.h>      // for getpid()
-  // Allocate and deallocate blocks of increasing sizes to check if the alloc
-  // metadata fragments the memory. (Do not put other allocations/deallocations
-  // before this test, it may break).
-  {
-    size_t memory_usage = MemoryUsage(getpid());
-    fprintf(LOGSTREAM, "Testing fragmentation\n");
-    for ( int i = 200; i < 240; ++i ) {
-      int size = i << 20;
-      void *test1 = rnd.alloc(size);
-      CHECK(test1);
-      for ( int j = 0; j < size; j += (1 << 12) ) {
-        static_cast<char*>(test1)[j] = 1;
-      }
-      free(test1);
-    }
-    // There may still be a bit of fragmentation at the beginning, until we
-    // reach kPageMapBigAllocationThreshold bytes so we check for
-    // 200 + 240 + margin.
-    CHECK_LT(MemoryUsage(getpid()), memory_usage + (450 << 20) );
-  }
-#endif
-
-  // Check that empty allocation works
-  fprintf(LOGSTREAM, "Testing empty allocation\n");
-  {
-    void* p1 = rnd.alloc(0);
-    CHECK(p1 != NULL);
-    void* p2 = rnd.alloc(0);
-    CHECK(p2 != NULL);
-    CHECK(p1 != p2);
-    free(p1);
-    free(p2);
-  }
-
-  // This code stresses some of the memory allocation via STL.
-  // It may call operator delete(void*, nothrow_t).
-  fprintf(LOGSTREAM, "Testing STL use\n");
-  {
-    std::vector<int> v;
-    v.push_back(1);
-    v.push_back(2);
-    v.push_back(3);
-    v.push_back(0);
-    std::stable_sort(v.begin(), v.end());
-  }
-
-  // Test each of the memory-allocation functions once, just as a sanity-check
-  fprintf(LOGSTREAM, "Sanity-testing all the memory allocation functions\n");
-  {
-    // We use new-hook and delete-hook to verify we actually called the
-    // tcmalloc version of these routines, and not the libc version.
-    SetNewHook();      // defined as part of MAKE_HOOK_CALLBACK, above
-    SetDeleteHook();   // ditto
-
-    void* p1 = malloc(10);
-    CHECK(p1 != NULL);    // force use of this variable
-    VerifyNewHookWasCalled();
-    // Also test the non-standard tc_malloc_size
-    size_t actual_p1_size = tc_malloc_size(p1);
-    CHECK_GE(actual_p1_size, 10);
-    CHECK_LT(actual_p1_size, 100000);   // a reasonable upper-bound, I think
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    p1 = tc_malloc_skip_new_handler(10);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    p1 = calloc(10, 2);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    // We make sure we realloc to a big size, since some systems (OS
-    // X) will notice if the realloced size continues to fit into the
-    // malloc-block and make this a noop if so.
-    p1 = realloc(p1, 30000);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    VerifyDeleteHookWasCalled();
-    cfree(p1);  // synonym for free
-    VerifyDeleteHookWasCalled();
-
-    if (kOSSupportsMemalign) {
-      CHECK_EQ(PosixMemalign(&p1, sizeof(p1), 40), 0);
-      CHECK(p1 != NULL);
-      VerifyNewHookWasCalled();
-      free(p1);
-      VerifyDeleteHookWasCalled();
-
-      p1 = Memalign(sizeof(p1) * 2, 50);
-      CHECK(p1 != NULL);
-      VerifyNewHookWasCalled();
-      free(p1);
-      VerifyDeleteHookWasCalled();
-    }
-
-    // Windows has _aligned_malloc.  Let's test that that's captured too.
-#if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(PERFTOOLS_NO_ALIGNED_MALLOC)
-    p1 = _aligned_malloc(sizeof(p1) * 2, 64);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    _aligned_free(p1);
-    VerifyDeleteHookWasCalled();
-#endif
-
-    p1 = valloc(60);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    p1 = pvalloc(70);
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    char* p2 = new char;
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete p2;
-    VerifyDeleteHookWasCalled();
-
-    p2 = new char[100];
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete[] p2;
-    VerifyDeleteHookWasCalled();
-
-    p2 = new(std::nothrow) char;
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete p2;
-    VerifyDeleteHookWasCalled();
-
-    p2 = new(std::nothrow) char[100];
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete[] p2;
-    VerifyDeleteHookWasCalled();
-
-    // Another way of calling operator new
-    p2 = static_cast<char*>(::operator new(100));
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2);
-    VerifyDeleteHookWasCalled();
-
-    // Try to call nothrow's delete too.  Compilers use this.
-    p2 = static_cast<char*>(::operator new(100, std::nothrow));
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, std::nothrow);
-    VerifyDeleteHookWasCalled();
-
-#ifdef ENABLE_SIZED_DELETE
-    p2 = new char;
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, sizeof(char));
-    VerifyDeleteHookWasCalled();
-
-    p2 = new char[100];
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete[](p2, sizeof(char) * 100);
-    VerifyDeleteHookWasCalled();
-#endif
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-    overaligned_type* poveraligned = new overaligned_type;
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = new overaligned_type[10];
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete[] poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = new(std::nothrow) overaligned_type;
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = new(std::nothrow) overaligned_type[10];
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete[] poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    // Another way of calling operator new
-    p2 = static_cast<char*>(::operator new(100, std::align_val_t(OVERALIGNMENT)));
-    CHECK(p2 != NULL);
-    CHECK((((size_t)p2) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, std::align_val_t(OVERALIGNMENT));
-    VerifyDeleteHookWasCalled();
-
-    p2 = static_cast<char*>(::operator new(100, std::align_val_t(OVERALIGNMENT), std::nothrow));
-    CHECK(p2 != NULL);
-    CHECK((((size_t)p2) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, std::align_val_t(OVERALIGNMENT), std::nothrow);
-    VerifyDeleteHookWasCalled();
-
-#ifdef ENABLE_SIZED_DELETE
-    poveraligned = new overaligned_type;
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    ::operator delete(poveraligned, sizeof(overaligned_type), std::align_val_t(OVERALIGNMENT));
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = new overaligned_type[10];
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    ::operator delete[](poveraligned, sizeof(overaligned_type) * 10, std::align_val_t(OVERALIGNMENT));
-    VerifyDeleteHookWasCalled();
-#endif
-
-#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
-
-    // Try strdup(), which the system allocates but we must free.  If
-    // all goes well, libc will use our malloc!
-    p2 = strdup("in memory of James Golick");
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    free(p2);
-    VerifyDeleteHookWasCalled();
-
-
-    // Test mmap too: both anonymous mmap and mmap of a file
-    // Note that for right now we only override mmap on linux
-    // systems, so those are the only ones for which we check.
-    SetMmapHook();
-    SetMremapHook();
-    SetMunmapHook();
-#if defined(HAVE_MMAP) && defined(__linux) && \
-       (defined(__i386__) || defined(__x86_64__))
-    int size = 8192*2;
-    p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE,
-              -1, 0);
-    CHECK(p1 != NULL);
-    VerifyMmapHookWasCalled();
-    p1 = mremap(p1, size, size/2, 0);
-    CHECK(p1 != NULL);
-    VerifyMremapHookWasCalled();
-    size /= 2;
-    munmap(p1, size);
-    VerifyMunmapHookWasCalled();
-
-    int fd = open("/dev/zero", O_RDONLY);
-    CHECK_GE(fd, 0);   // make sure the open succeeded
-    p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);
-    CHECK(p1 != NULL);
-    VerifyMmapHookWasCalled();
-    munmap(p1, 8192);
-    VerifyMunmapHookWasCalled();
-    close(fd);
-#else   // this is just to quiet the compiler: make sure all fns are called
-    IncrementCallsToMmapHook(NULL, NULL, 0, 0, 0, 0, 0);
-    IncrementCallsToMunmapHook(NULL, 0);
-    IncrementCallsToMremapHook(NULL, NULL, 0, 0, 0, NULL);
-    VerifyMmapHookWasCalled();
-    VerifyMremapHookWasCalled();
-    VerifyMunmapHookWasCalled();
-#endif
-
-    // Test sbrk
-    SetSbrkHook();
-#if defined(HAVE_SBRK) && defined(__linux) && \
-       (defined(__i386__) || defined(__x86_64__))
-    p1 = sbrk(8192);
-    CHECK(p1 != NULL);
-    VerifySbrkHookWasCalled();
-    p1 = sbrk(-8192);
-    CHECK(p1 != NULL);
-    VerifySbrkHookWasCalled();
-    // However, sbrk hook should *not* be called with sbrk(0)
-    p1 = sbrk(0);
-    CHECK(p1 != NULL);
-    CHECK_EQ(g_SbrkHook_calls, 0);
-#else   // this is just to quiet the compiler: make sure all fns are called
-    IncrementCallsToSbrkHook(NULL, 0);
-    VerifySbrkHookWasCalled();
-#endif
-
-    // Reset the hooks to what they used to be.  These are all
-    // defined as part of MAKE_HOOK_CALLBACK, above.
-    ResetNewHook();
-    ResetDeleteHook();
-    ResetMmapHook();
-    ResetMremapHook();
-    ResetMunmapHook();
-    ResetSbrkHook();
-  }
-
-  // Check that "lots" of memory can be allocated
-  fprintf(LOGSTREAM, "Testing large allocation\n");
-  {
-    const int mb_to_allocate = 100;
-    void* p = rnd.alloc(mb_to_allocate << 20);
-    CHECK(p != NULL);  // could not allocate
-    free(p);
-  }
-
-  TestMallocAlignment();
-
-  // Check calloc() with various arguments
-  fprintf(LOGSTREAM, "Testing calloc\n");
-  TestCalloc(0, 0, true);
-  TestCalloc(0, 1, true);
-  TestCalloc(1, 1, true);
-  TestCalloc(1<<10, 0, true);
-  TestCalloc(1<<20, 0, true);
-  TestCalloc(0, 1<<10, true);
-  TestCalloc(0, 1<<20, true);
-  TestCalloc(1<<20, 2, true);
-  TestCalloc(2, 1<<20, true);
-  TestCalloc(1000, 1000, true);
-
-  TestCalloc(kMaxSize, 2, false);
-  TestCalloc(2, kMaxSize, false);
-  TestCalloc(kMaxSize, kMaxSize, false);
-
-  TestCalloc(kMaxSignedSize, 3, false);
-  TestCalloc(3, kMaxSignedSize, false);
-  TestCalloc(kMaxSignedSize, kMaxSignedSize, false);
-
-  // Test that realloc doesn't always reallocate and copy memory.
-  fprintf(LOGSTREAM, "Testing realloc\n");
-  TestRealloc();
-
-  fprintf(LOGSTREAM, "Testing operator new(nothrow).\n");
-  TestNothrowNew(&::operator new);
-  fprintf(LOGSTREAM, "Testing operator new[](nothrow).\n");
-  TestNothrowNew(&::operator new[]);
-  fprintf(LOGSTREAM, "Testing operator new.\n");
-  TestNew(&::operator new);
-  fprintf(LOGSTREAM, "Testing operator new[].\n");
-  TestNew(&::operator new[]);
-
-  // Create threads
-  fprintf(LOGSTREAM, "Testing threaded allocation/deallocation (%d threads)\n",
-          FLAGS_numthreads);
-  threads = new TesterThread*[FLAGS_numthreads];
-  for (int i = 0; i < FLAGS_numthreads; ++i) {
-    threads[i] = new TesterThread(i);
-  }
-
-  // This runs all the tests at the same time, with a 1M stack size each
-  RunManyThreadsWithId(RunThread, FLAGS_numthreads, 1<<20);
-
-  for (int i = 0; i < FLAGS_numthreads; ++i) delete threads[i];    // Cleanup
-
-  // Do the memory intensive tests after threads are done, since exhausting
-  // the available address space can make pthread_create to fail.
-
-  // Check that huge allocations fail with NULL instead of crashing
-  fprintf(LOGSTREAM, "Testing huge allocations\n");
-  TestHugeAllocations(&rnd);
-
-  // Check that large allocations fail with NULL instead of crashing
-#ifndef DEBUGALLOCATION    // debug allocation takes forever for huge allocs
-  fprintf(LOGSTREAM, "Testing out of memory\n");
-  for (int s = 0; ; s += (10<<20)) {
-    void* large_object = rnd.alloc(s);
-    if (large_object == NULL) break;
-    free(large_object);
-  }
-#endif
-
-  TestHugeThreadCache();
-  TestRanges();
-  TestReleaseToSystem();
-  TestAggressiveDecommit();
-  TestSetNewMode();
-  TestErrno();
-
-// GetAllocatedSize under DEBUGALLOCATION returns the size that we asked for.
-#ifndef DEBUGALLOCATION
-  TestNAllocX();
-  TestNAllocXAlignment();
-#endif
-
-  return 0;
-}
-
-}
-
-using testing::RunAllTests;
-
-int main(int argc, char** argv) {
-#ifdef DEBUGALLOCATION    // debug allocation takes forever for huge allocs
-  FLAGS_max_free_queue_size = 0;  // return freed blocks to tcmalloc immediately
-#endif
-
-  RunAllTests(argc, argv);
-
-  // Test tc_version()
-  fprintf(LOGSTREAM, "Testing tc_version()\n");
-  int major;
-  int minor;
-  const char* patch;
-  char mmp[64];
-  const char* human_version = tc_version(&major, &minor, &patch);
-  snprintf(mmp, sizeof(mmp), "%d.%d%s", major, minor, patch);
-  CHECK(!strcmp(PACKAGE_STRING, human_version));
-  CHECK(!strcmp(PACKAGE_VERSION, mmp));
-
-  fprintf(LOGSTREAM, "PASS\n");
-}
diff --git a/third_party/tcmalloc/vendor/src/tests/tcmalloc_unittest.sh b/third_party/tcmalloc/vendor/src/tests/tcmalloc_unittest.sh
deleted file mode 100755
index 0e7996a..0000000
--- a/third_party/tcmalloc/vendor/src/tests/tcmalloc_unittest.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2013, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Author: Adhemerval Zanella
-#
-# Runs the tcmalloc_unittest with various environment variables.
-# This is necessary because tuning some environment variables
-# (TCMALLOC_TRANSFER_NUM_OBJ for instance) should not change program
-# behavior, just performance.
-
-BINDIR="${BINDIR:-.}"
-TCMALLOC_UNITTEST="${1:-$BINDIR/tcmalloc_unittest}"
-
-TMPDIR=/tmp/tcmalloc_unittest
-rm -rf $TMPDIR || exit 2
-mkdir $TMPDIR || exit 3
-
-run_unittest() {
-    if $TCMALLOC_UNITTEST > $TMPDIR/output 2>&1; then
-      echo "OK"
-    else
-      echo "FAILED"
-      echo "Output from the failed run:"
-      echo "----"
-      cat $TMPDIR/output
-      echo "----"
-      exit 4
-    fi
-}
-
-# $1: value of tcmalloc_unittest env. var.
-run_check_transfer_num_obj() {
-    [ -n "$1" ] && export TCMALLOC_TRANSFER_NUM_OBJ="$1"
-
-    echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_TRANSFER_NUM_OBJ=$1 ... "
-    run_unittest
-}
-
-run_check_transfer_num_obj ""
-run_check_transfer_num_obj "40"
-run_check_transfer_num_obj "4096"
-
-echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_AGGRESSIVE_DECOMMIT=t ... "
-
-TCMALLOC_AGGRESSIVE_DECOMMIT=t run_unittest
-
-echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_HEAP_LIMIT_MB=512 ... "
-
-TCMALLOC_HEAP_LIMIT_MB=512 run_unittest
-
-echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_ENABLE_SIZED_DELETE=t ..."
-
-TCMALLOC_ENABLE_SIZED_DELETE=t run_unittest
-
-echo "PASS"
diff --git a/third_party/tcmalloc/vendor/src/tests/testutil.cc b/third_party/tcmalloc/vendor/src/tests/testutil.cc
deleted file mode 100644
index c2c71cb3..0000000
--- a/third_party/tcmalloc/vendor/src/tests/testutil.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-//
-// A few routines that are useful for multiple tests in this directory.
-
-#include "config_for_unittests.h"
-#include <stdlib.h>           // for NULL, abort()
-// On FreeBSD, if you #include <sys/resource.h>, you have to get stdint first.
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-#include "tests/testutil.h"
-
-
-// When compiled 64-bit and run on systems with swap several unittests will end
-// up trying to consume all of RAM+swap, and that can take quite some time.  By
-// limiting the address-space size we get sufficient coverage without blowing
-// out job limits.
-void SetTestResourceLimit() {
-#ifdef HAVE_SYS_RESOURCE_H
-  // The actual resource we need to set varies depending on which flavour of
-  // unix.  On Linux we need RLIMIT_AS because that covers the use of mmap.
-  // Otherwise hopefully RLIMIT_RSS is good enough.  (Unfortunately 64-bit
-  // and 32-bit headers disagree on the type of these constants!)
-#ifdef RLIMIT_AS
-#define USE_RESOURCE RLIMIT_AS
-#else
-#define USE_RESOURCE RLIMIT_RSS
-#endif
-
-  // Restrict the test to 1GiB, which should fit comfortably well on both
-  // 32-bit and 64-bit hosts, and executes in ~1s.
-  const rlim_t kMaxMem = 1<<30;
-
-  struct rlimit rlim;
-  if (getrlimit(USE_RESOURCE, &rlim) == 0) {
-    if (rlim.rlim_cur == RLIM_INFINITY || rlim.rlim_cur > kMaxMem) {
-      rlim.rlim_cur = kMaxMem;
-      setrlimit(USE_RESOURCE, &rlim); // ignore result
-    }
-  }
-#endif  /* HAVE_SYS_RESOURCE_H */
-}
-
-
-struct FunctionAndId {
-  void (*ptr_to_function)(int);
-  int id;
-};
-
-#if defined(NO_THREADS) || !(defined(HAVE_PTHREAD) || defined(_WIN32))
-
-extern "C" void RunThread(void (*fn)()) {
-  (*fn)();
-}
-
-extern "C" void RunManyThreads(void (*fn)(), int count) {
-  // I guess the best we can do is run fn sequentially, 'count' times
-  for (int i = 0; i < count; i++)
-    (*fn)();
-}
-
-extern "C" void RunManyThreadsWithId(void (*fn)(int), int count, int) {
-  for (int i = 0; i < count; i++)
-    (*fn)(i);    // stacksize doesn't make sense in a non-threaded context
-}
-
-#elif defined(_WIN32)
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */
-#endif
-#include <windows.h>
-
-extern "C" {
-  // This helper function has the signature that pthread_create wants.
-  DWORD WINAPI RunFunctionInThread(LPVOID ptr_to_ptr_to_fn) {
-    (**static_cast<void (**)()>(ptr_to_ptr_to_fn))();    // runs fn
-    return 0;
-  }
-
-  DWORD WINAPI RunFunctionInThreadWithId(LPVOID ptr_to_fnid) {
-    FunctionAndId* fn_and_id = static_cast<FunctionAndId*>(ptr_to_fnid);
-    (*fn_and_id->ptr_to_function)(fn_and_id->id);   // runs fn
-    return 0;
-  }
-
-  void RunManyThreads(void (*fn)(), int count) {
-    DWORD dummy;
-    HANDLE* hThread = new HANDLE[count];
-    for (int i = 0; i < count; i++) {
-      hThread[i] = CreateThread(NULL, 0, RunFunctionInThread, &fn, 0, &dummy);
-      if (hThread[i] == NULL)  ExitProcess(i);
-    }
-    WaitForMultipleObjects(count, hThread, TRUE, INFINITE);
-    for (int i = 0; i < count; i++) {
-      CloseHandle(hThread[i]);
-    }
-    delete[] hThread;
-  }
-
-  void RunThread(void (*fn)()) {
-    RunManyThreads(fn, 1);
-  }
-
-  void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize) {
-    DWORD dummy;
-    HANDLE* hThread = new HANDLE[count];
-    FunctionAndId* fn_and_ids = new FunctionAndId[count];
-    for (int i = 0; i < count; i++) {
-      fn_and_ids[i].ptr_to_function = fn;
-      fn_and_ids[i].id = i;
-      hThread[i] = CreateThread(NULL, stacksize, RunFunctionInThreadWithId,
-                                &fn_and_ids[i], 0, &dummy);
-      if (hThread[i] == NULL)  ExitProcess(i);
-    }
-    WaitForMultipleObjects(count, hThread, TRUE, INFINITE);
-    for (int i = 0; i < count; i++) {
-      CloseHandle(hThread[i]);
-    }
-    delete[] fn_and_ids;
-    delete[] hThread;
-  }
-}
-
-#else  // not NO_THREADS, not !HAVE_PTHREAD, not _WIN32
-
-#include <pthread.h>
-
-#define SAFE_PTHREAD(fncall)  do { if ((fncall) != 0) abort(); } while (0)
-
-extern "C" {
-  // This helper function has the signature that pthread_create wants.
-  static void* RunFunctionInThread(void *ptr_to_ptr_to_fn) {
-    (**static_cast<void (**)()>(ptr_to_ptr_to_fn))();    // runs fn
-    return NULL;
-  }
-
-  static void* RunFunctionInThreadWithId(void *ptr_to_fnid) {
-    FunctionAndId* fn_and_id = static_cast<FunctionAndId*>(ptr_to_fnid);
-    (*fn_and_id->ptr_to_function)(fn_and_id->id);   // runs fn
-    return NULL;
-  }
-
-  // Run a function in a thread of its own and wait for it to finish.
-  // This is useful for tcmalloc testing, because each thread is
-  // handled separately in tcmalloc, so there's interesting stuff to
-  // test even if the threads are not running concurrently.
-  void RunThread(void (*fn)()) {
-    pthread_t thr;
-    // Even though fn is on the stack, it's safe to pass a pointer to it,
-    // because we pthread_join immediately (ie, before RunInThread exits).
-    SAFE_PTHREAD(pthread_create(&thr, NULL, RunFunctionInThread, &fn));
-    SAFE_PTHREAD(pthread_join(thr, NULL));
-  }
-
-  void RunManyThreads(void (*fn)(), int count) {
-    pthread_t* thr = new pthread_t[count];
-    for (int i = 0; i < count; i++) {
-      SAFE_PTHREAD(pthread_create(&thr[i], NULL, RunFunctionInThread, &fn));
-    }
-    for (int i = 0; i < count; i++) {
-      SAFE_PTHREAD(pthread_join(thr[i], NULL));
-    }
-    delete[] thr;
-  }
-
-  void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize) {
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-    pthread_attr_setstacksize(&attr, stacksize);
-
-    pthread_t* thr = new pthread_t[count];
-    FunctionAndId* fn_and_ids = new FunctionAndId[count];
-    for (int i = 0; i < count; i++) {
-      fn_and_ids[i].ptr_to_function = fn;
-      fn_and_ids[i].id = i;
-      SAFE_PTHREAD(pthread_create(&thr[i], &attr,
-                                  RunFunctionInThreadWithId, &fn_and_ids[i]));
-    }
-    for (int i = 0; i < count; i++) {
-      SAFE_PTHREAD(pthread_join(thr[i], NULL));
-    }
-    delete[] fn_and_ids;
-    delete[] thr;
-
-    pthread_attr_destroy(&attr);
-  }
-}
-
-#endif
diff --git a/third_party/tcmalloc/vendor/src/tests/testutil.h b/third_party/tcmalloc/vendor/src/tests/testutil.h
deleted file mode 100644
index 071a209..0000000
--- a/third_party/tcmalloc/vendor/src/tests/testutil.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Craig Silverstein
-
-#ifndef TCMALLOC_TOOLS_TESTUTIL_H_
-#define TCMALLOC_TOOLS_TESTUTIL_H_
-
-// Run a function in a thread of its own and wait for it to finish.
-// The function you pass in must have the signature
-//    void MyFunction();
-extern "C" void RunThread(void (*fn)());
-
-// Run a function X times, in X threads, and wait for them all to finish.
-// The function you pass in must have the signature
-//    void MyFunction();
-extern "C" void RunManyThreads(void (*fn)(), int count);
-
-// The 'advanced' version: run a function X times, in X threads, and
-// wait for them all to finish.  Give them all the specified stack-size.
-// (If you're curious why this takes a stacksize and the others don't,
-// it's because the one client of this fn wanted to specify stacksize. :-) )
-// The function you pass in must have the signature
-//    void MyFunction(int idx);
-// where idx is the index of the thread (which of the X threads this is).
-extern "C" void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize);
-
-// When compiled 64-bit and run on systems with swap several unittests will end
-// up trying to consume all of RAM+swap, and that can take quite some time.  By
-// limiting the address-space size we get sufficient coverage without blowing
-// out job limits.
-void SetTestResourceLimit();
-
-#endif  // TCMALLOC_TOOLS_TESTUTIL_H_
diff --git a/third_party/tcmalloc/vendor/src/tests/thread_dealloc_unittest.cc b/third_party/tcmalloc/vendor/src/tests/thread_dealloc_unittest.cc
deleted file mode 100644
index 97615cd..0000000
--- a/third_party/tcmalloc/vendor/src/tests/thread_dealloc_unittest.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2004, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat
-//
-// Check that we do not leak memory when cycling through lots of threads.
-
-#include "config_for_unittests.h"
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>    // for sleep()
-#endif
-#include "base/logging.h"
-#include <gperftools/malloc_extension.h>
-#include "tests/testutil.h"   // for RunThread()
-
-// Size/number of objects to allocate per thread (1 MB per thread)
-static const int kObjectSize = 1024;
-static const int kNumObjects = 1024;
-
-// Number of threads to create and destroy
-static const int kNumThreads = 1000;
-
-// Allocate lots of stuff
-static void AllocStuff() {
-  void** objects = new void*[kNumObjects];
-  for (int i = 0; i < kNumObjects; i++) {
-    objects[i] = malloc(kObjectSize);
-  }
-  for (int i = 0; i < kNumObjects; i++) {
-    free(objects[i]);
-  }
-  delete[] objects;
-}
-
-int main(int argc, char** argv) {
-  static const int kDisplaySize = 1048576;
-  char* display = new char[kDisplaySize];
-
-  for (int i = 0; i < kNumThreads; i++) {
-    RunThread(&AllocStuff);
-
-    if (((i+1) % 200) == 0) {
-      fprintf(stderr, "Iteration: %d of %d\n", (i+1), kNumThreads);
-      MallocExtension::instance()->GetStats(display, kDisplaySize);
-      fprintf(stderr, "%s\n", display);
-    }
-  }
-  delete[] display;
-
-  printf("PASS\n");
-#ifdef HAVE_UNISTD_H
-  sleep(1);     // Prevent exit race problem with glibc
-#endif
-  return 0;
-}
diff --git a/third_party/tcmalloc/vendor/src/third_party/valgrind.h b/third_party/tcmalloc/vendor/src/third_party/valgrind.h
deleted file mode 100644
index 577c59a..0000000
--- a/third_party/tcmalloc/vendor/src/third_party/valgrind.h
+++ /dev/null
@@ -1,3924 +0,0 @@
-/* -*- c -*-
-   ----------------------------------------------------------------
-
-   Notice that the following BSD-style license applies to this one
-   file (valgrind.h) only.  The rest of Valgrind is licensed under the
-   terms of the GNU General Public License, version 2, unless
-   otherwise indicated.  See the COPYING file in the source
-   distribution for details.
-
-   ----------------------------------------------------------------
-
-   This file is part of Valgrind, a dynamic binary instrumentation
-   framework.
-
-   Copyright (C) 2000-2008 Julian Seward.  All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-
-   1. Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-   2. The origin of this software must not be misrepresented; you must 
-      not claim that you wrote the original software.  If you use this 
-      software in a product, an acknowledgment in the product 
-      documentation would be appreciated but is not required.
-
-   3. Altered source versions must be plainly marked as such, and must
-      not be misrepresented as being the original software.
-
-   4. The name of the author may not be used to endorse or promote 
-      products derived from this software without specific prior written 
-      permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-   ----------------------------------------------------------------
-
-   Notice that the above BSD-style license applies to this one file
-   (valgrind.h) only.  The entire rest of Valgrind is licensed under
-   the terms of the GNU General Public License, version 2.  See the
-   COPYING file in the source distribution for details.
-
-   ---------------------------------------------------------------- 
-*/
-
-
-/* This file is for inclusion into client (your!) code.
-
-   You can use these macros to manipulate and query Valgrind's 
-   execution inside your own programs.
-
-   The resulting executables will still run without Valgrind, just a
-   little bit more slowly than they otherwise would, but otherwise
-   unchanged.  When not running on valgrind, each client request
-   consumes very few (eg. 7) instructions, so the resulting performance
-   loss is negligible unless you plan to execute client requests
-   millions of times per second.  Nevertheless, if that is still a
-   problem, you can compile with the NVALGRIND symbol defined (gcc
-   -DNVALGRIND) so that client requests are not even compiled in.  */
-
-#ifndef __VALGRIND_H
-#define __VALGRIND_H
-
-#include <stdarg.h>
-
-/* Nb: this file might be included in a file compiled with -ansi.  So
-   we can't use C++ style "//" comments nor the "asm" keyword (instead
-   use "__asm__"). */
-
-/* Derive some tags indicating what the target platform is.  Note
-   that in this file we're using the compiler's CPP symbols for
-   identifying architectures, which are different to the ones we use
-   within the rest of Valgrind.  Note, __powerpc__ is active for both
-   32 and 64-bit PPC, whereas __powerpc64__ is only active for the
-   latter (on Linux, that is). */
-#undef PLAT_x86_linux
-#undef PLAT_amd64_linux
-#undef PLAT_ppc32_linux
-#undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
-
-#if !defined(_AIX) && defined(__i386__)
-#  define PLAT_x86_linux 1
-#elif !defined(_AIX) && defined(__x86_64__)
-#  define PLAT_amd64_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
-#  define PLAT_ppc32_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
-#  define PLAT_ppc64_linux 1
-#elif defined(_AIX) && defined(__64BIT__)
-#  define PLAT_ppc64_aix5 1
-#elif defined(_AIX) && !defined(__64BIT__)
-#  define PLAT_ppc32_aix5 1
-#endif
-
-
-/* If we're not compiling for our target platform, don't generate
-   any inline asms.  */
-#if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \
-    && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \
-    && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5)
-#  if !defined(NVALGRIND)
-#    define NVALGRIND 1
-#  endif
-#endif
-
-
-/* ------------------------------------------------------------------ */
-/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
-/* in here of use to end-users -- skip to the next section.           */
-/* ------------------------------------------------------------------ */
-
-#if defined(NVALGRIND)
-
-/* Define NVALGRIND to completely remove the Valgrind magic sequence
-   from the compiled code (analogous to NDEBUG's effects on
-   assert()) */
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-   {                                                              \
-      (_zzq_rlval) = (_zzq_default);                              \
-   }
-
-#else  /* ! NVALGRIND */
-
-/* The following defines the magic code sequences which the JITter
-   spots and handles magically.  Don't look too closely at them as
-   they will rot your brain.
-
-   The assembly code sequences for all architectures is in this one
-   file.  This is because this file must be stand-alone, and we don't
-   want to have multiple files.
-
-   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
-   value gets put in the return slot, so that everything works when
-   this is executed not under Valgrind.  Args are passed in a memory
-   block, and so there's no intrinsic limit to the number that could
-   be passed, but it's currently five.
-   
-   The macro args are: 
-      _zzq_rlval    result lvalue
-      _zzq_default  default value (result returned when running on real CPU)
-      _zzq_request  request code
-      _zzq_arg1..5  request params
-
-   The other two macros are used to support function wrapping, and are
-   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
-   guest's NRADDR pseudo-register and whatever other information is
-   needed to safely run the call original from the wrapper: on
-   ppc64-linux, the R2 value at the divert point is also needed.  This
-   information is abstracted into a user-visible type, OrigFn.
-
-   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
-   guest, but guarantees that the branch instruction will not be
-   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
-   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
-   complete inline asm, since it needs to be combined with more magic
-   inline asm stuff to be useful.
-*/
-
-/* ------------------------- x86-linux ------------------------- */
-
-#if defined(PLAT_x86_linux)
-
-typedef
-   struct { 
-      unsigned int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
-                     "roll $29, %%edi ; roll $19, %%edi\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-  { volatile unsigned int _zzq_args[6];                           \
-    volatile unsigned int _zzq_result;                            \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %EDX = client_request ( %EAX ) */         \
-                     "xchgl %%ebx,%%ebx"                          \
-                     : "=d" (_zzq_result)                         \
-                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    volatile unsigned int __addr;                                 \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %EAX = guest_NRADDR */                    \
-                     "xchgl %%ecx,%%ecx"                          \
-                     : "=a" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_CALL_NOREDIR_EAX                                 \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* call-noredir *%EAX */                     \
-                     "xchgl %%edx,%%edx\n\t"
-#endif /* PLAT_x86_linux */
-
-/* ------------------------ amd64-linux ------------------------ */
-
-#if defined(PLAT_amd64_linux)
-
-typedef
-   struct { 
-      unsigned long long int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
-                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-  { volatile unsigned long long int _zzq_args[6];                 \
-    volatile unsigned long long int _zzq_result;                  \
-    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
-    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
-    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
-    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
-    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
-    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %RDX = client_request ( %RAX ) */         \
-                     "xchgq %%rbx,%%rbx"                          \
-                     : "=d" (_zzq_result)                         \
-                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    volatile unsigned long long int __addr;                       \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %RAX = guest_NRADDR */                    \
-                     "xchgq %%rcx,%%rcx"                          \
-                     : "=a" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_CALL_NOREDIR_RAX                                 \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* call-noredir *%RAX */                     \
-                     "xchgq %%rdx,%%rdx\n\t"
-#endif /* PLAT_amd64_linux */
-
-/* ------------------------ ppc32-linux ------------------------ */
-
-#if defined(PLAT_ppc32_linux)
-
-typedef
-   struct { 
-      unsigned int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
-                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  {          unsigned int  _zzq_args[6];                          \
-             unsigned int  _zzq_result;                           \
-             unsigned int* _zzq_ptr;                              \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
-                     "mr 4,%2\n\t" /*ptr*/                        \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"     /*result*/                     \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
-                     : "cc", "memory", "r3", "r4");               \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    unsigned int __addr;                                          \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory", "r3"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-#endif /* PLAT_ppc32_linux */
-
-/* ------------------------ ppc64-linux ------------------------ */
-
-#if defined(PLAT_ppc64_linux)
-
-typedef
-   struct { 
-      unsigned long long int nraddr; /* where's the code? */
-      unsigned long long int r2;  /* what tocptr do we need? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
-                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  {          unsigned long long int  _zzq_args[6];                \
-    register unsigned long long int  _zzq_result __asm__("r3");   \
-    register unsigned long long int* _zzq_ptr __asm__("r4");      \
-    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
-    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
-    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
-    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
-    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
-    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1"                                   \
-                     : "=r" (_zzq_result)                         \
-                     : "0" (_zzq_default), "r" (_zzq_ptr)         \
-                     : "cc", "memory");                           \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    register unsigned long long int __addr __asm__("r3");         \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2"                                   \
-                     : "=r" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR_GPR2 */                \
-                     "or 4,4,4"                                   \
-                     : "=r" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->r2 = __addr;                                       \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-
-#endif /* PLAT_ppc64_linux */
-
-/* ------------------------ ppc32-aix5 ------------------------- */
-
-#if defined(PLAT_ppc32_aix5)
-
-typedef
-   struct { 
-      unsigned int nraddr; /* where's the code? */
-      unsigned int r2;  /* what tocptr do we need? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
-                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  {          unsigned int  _zzq_args[7];                          \
-    register unsigned int  _zzq_result;                           \
-    register unsigned int* _zzq_ptr;                              \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    _zzq_args[6] = (unsigned int)(_zzq_default);                  \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 4,%1\n\t"                                \
-                     "lwz 3, 24(4)\n\t"                           \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_ptr)                             \
-                     : "r3", "r4", "cc", "memory");               \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    register unsigned int __addr;                                 \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR_GPR2 */                \
-                     "or 4,4,4\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->r2 = __addr;                                       \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-
-#endif /* PLAT_ppc32_aix5 */
-
-/* ------------------------ ppc64-aix5 ------------------------- */
-
-#if defined(PLAT_ppc64_aix5)
-
-typedef
-   struct { 
-      unsigned long long int nraddr; /* where's the code? */
-      unsigned long long int r2;  /* what tocptr do we need? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
-                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  {          unsigned long long int  _zzq_args[7];                \
-    register unsigned long long int  _zzq_result;                 \
-    register unsigned long long int* _zzq_ptr;                    \
-    _zzq_args[0] = (unsigned int long long)(_zzq_request);        \
-    _zzq_args[1] = (unsigned int long long)(_zzq_arg1);           \
-    _zzq_args[2] = (unsigned int long long)(_zzq_arg2);           \
-    _zzq_args[3] = (unsigned int long long)(_zzq_arg3);           \
-    _zzq_args[4] = (unsigned int long long)(_zzq_arg4);           \
-    _zzq_args[5] = (unsigned int long long)(_zzq_arg5);           \
-    _zzq_args[6] = (unsigned int long long)(_zzq_default);        \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 4,%1\n\t"                                \
-                     "ld 3, 48(4)\n\t"                            \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_ptr)                             \
-                     : "r3", "r4", "cc", "memory");               \
-    _zzq_rlval = _zzq_result;                                     \
-  }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    register unsigned long long int __addr;                       \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR_GPR2 */                \
-                     "or 4,4,4\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->r2 = __addr;                                       \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-
-#endif /* PLAT_ppc64_aix5 */
-
-/* Insert assembly code for other platforms here... */
-
-#endif /* NVALGRIND */
-
-
-/* ------------------------------------------------------------------ */
-/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
-/* ugly.  It's the least-worst tradeoff I can think of.               */
-/* ------------------------------------------------------------------ */
-
-/* This section defines magic (a.k.a appalling-hack) macros for doing
-   guaranteed-no-redirection macros, so as to get from function
-   wrappers to the functions they are wrapping.  The whole point is to
-   construct standard call sequences, but to do the call itself with a
-   special no-redirect call pseudo-instruction that the JIT
-   understands and handles specially.  This section is long and
-   repetitious, and I can't see a way to make it shorter.
-
-   The naming scheme is as follows:
-
-      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
-
-   'W' stands for "word" and 'v' for "void".  Hence there are
-   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
-   and for each, the possibility of returning a word-typed result, or
-   no result.
-*/
-
-/* Use these to write the name of your wrapper.  NOTE: duplicates
-   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
-
-#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
-   _vgwZU_##soname##_##fnname
-
-#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
-   _vgwZZ_##soname##_##fnname
-
-/* Use this macro from within a wrapper function to collect the
-   context (address and possibly other info) of the original function.
-   Once you have that you can then use it in one of the CALL_FN_
-   macros.  The type of the argument _lval is OrigFn. */
-#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
-
-/* Derivatives of the main macros below, for calling functions
-   returning void. */
-
-#define CALL_FN_v_v(fnptr)                                        \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_v(_junk,fnptr); } while (0)
-
-#define CALL_FN_v_W(fnptr, arg1)                                  \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
-
-#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
-
-#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
-
-/* ------------------------- x86-linux ------------------------- */
-
-#if defined(PLAT_x86_linux)
-
-/* These regs are trashed by the hidden call.  No need to mention eax
-   as gcc can already see that, plus causes gcc to bomb. */
-#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
-
-/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
-   long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      __asm__ volatile(                                           \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $4, %%esp\n"                                       \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      __asm__ volatile(                                           \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $8, %%esp\n"                                       \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      __asm__ volatile(                                           \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $12, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      __asm__ volatile(                                           \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $16, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      __asm__ volatile(                                           \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $20, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      __asm__ volatile(                                           \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $24, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      __asm__ volatile(                                           \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $28, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      __asm__ volatile(                                           \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $32, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      __asm__ volatile(                                           \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $36, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      __asm__ volatile(                                           \
-         "pushl 40(%%eax)\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $40, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11)                          \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      __asm__ volatile(                                           \
-         "pushl 44(%%eax)\n\t"                                    \
-         "pushl 40(%%eax)\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $44, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11,arg12)                    \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      _argvec[12] = (unsigned long)(arg12);                       \
-      __asm__ volatile(                                           \
-         "pushl 48(%%eax)\n\t"                                    \
-         "pushl 44(%%eax)\n\t"                                    \
-         "pushl 40(%%eax)\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $48, %%esp\n"                                      \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_x86_linux */
-
-/* ------------------------ amd64-linux ------------------------ */
-
-#if defined(PLAT_amd64_linux)
-
-/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
-                            "rdi", "r8", "r9", "r10", "r11"
-
-/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
-   long) == 8. */
-
-/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
-   macros.  In order not to trash the stack redzone, we need to drop
-   %rsp by 128 before the hidden call, and restore afterwards.  The
-   nastyness is that it is only by luck that the stack still appears
-   to be unwindable during the hidden call - since then the behaviour
-   of any routine using this macro does not match what the CFI data
-   says.  Sigh.
-
-   Why is this important?  Imagine that a wrapper has a stack
-   allocated local, and passes to the hidden call, a pointer to it.
-   Because gcc does not know about the hidden call, it may allocate
-   that local in the redzone.  Unfortunately the hidden call may then
-   trash it before it comes to use it.  So we must step clear of the
-   redzone, for the duration of the hidden call, to make it safe.
-
-   Probably the same problem afflicts the other redzone-style ABIs too
-   (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
-   self describing (none of this CFI nonsense) so at least messing
-   with the stack pointer doesn't give a danger of non-unwindable
-   stack. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         "addq $128,%%rsp\n\t"                                    \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $8, %%rsp\n"                                       \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $16, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 72(%%rax)\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $24, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 80(%%rax)\n\t"                                    \
-         "pushq 72(%%rax)\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $32, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 88(%%rax)\n\t"                                    \
-         "pushq 80(%%rax)\n\t"                                    \
-         "pushq 72(%%rax)\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $40, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      _argvec[12] = (unsigned long)(arg12);                       \
-      __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
-         "pushq 96(%%rax)\n\t"                                    \
-         "pushq 88(%%rax)\n\t"                                    \
-         "pushq 80(%%rax)\n\t"                                    \
-         "pushq 72(%%rax)\n\t"                                    \
-         "pushq 64(%%rax)\n\t"                                    \
-         "pushq 56(%%rax)\n\t"                                    \
-         "movq 48(%%rax), %%r9\n\t"                               \
-         "movq 40(%%rax), %%r8\n\t"                               \
-         "movq 32(%%rax), %%rcx\n\t"                              \
-         "movq 24(%%rax), %%rdx\n\t"                              \
-         "movq 16(%%rax), %%rsi\n\t"                              \
-         "movq 8(%%rax), %%rdi\n\t"                               \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         VALGRIND_CALL_NOREDIR_RAX                                \
-         "addq $48, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_amd64_linux */
-
-/* ------------------------ ppc32-linux ------------------------ */
-
-#if defined(PLAT_ppc32_linux)
-
-/* This is useful for finding out about the on-stack stuff:
-
-   extern int f9  ( int,int,int,int,int,int,int,int,int );
-   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
-   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
-   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
-
-   int g9 ( void ) {
-      return f9(11,22,33,44,55,66,77,88,99);
-   }
-   int g10 ( void ) {
-      return f10(11,22,33,44,55,66,77,88,99,110);
-   }
-   int g11 ( void ) {
-      return f11(11,22,33,44,55,66,77,88,99,110,121);
-   }
-   int g12 ( void ) {
-      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
-   }
-*/
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* These CALL_FN_ macros assume that on ppc32-linux, 
-   sizeof(unsigned long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-16\n\t"                                       \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "addi 1,1,16\n\t"                                        \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      _argvec[10] = (unsigned long)arg10;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-16\n\t"                                       \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,12(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "addi 1,1,16\n\t"                                        \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      _argvec[10] = (unsigned long)arg10;                         \
-      _argvec[11] = (unsigned long)arg11;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-32\n\t"                                       \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,16(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,12(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "addi 1,1,32\n\t"                                        \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      _argvec[10] = (unsigned long)arg10;                         \
-      _argvec[11] = (unsigned long)arg11;                         \
-      _argvec[12] = (unsigned long)arg12;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-32\n\t"                                       \
-         /* arg12 */                                              \
-         "lwz 3,48(11)\n\t"                                       \
-         "stw 3,20(1)\n\t"                                        \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,16(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,12(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "addi 1,1,32\n\t"                                        \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc32_linux */
-
-/* ------------------------ ppc64-linux ------------------------ */
-
-#if defined(PLAT_ppc64_linux)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
-   long) == 8. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+0];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1] = (unsigned long)_orig.r2;                       \
-      _argvec[2] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+1];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+2];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+3];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+4];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+5];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+6];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+7];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+8];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)" /* restore tocptr */                      \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+9];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-128\n\t"  /* expand stack frame */            \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         "addi 1,1,128"     /* restore frame */                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+10];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-128\n\t"  /* expand stack frame */            \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         "addi 1,1,128"     /* restore frame */                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+11];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-144\n\t"  /* expand stack frame */            \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         "addi 1,1,144"     /* restore frame */                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+12];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      _argvec[2+12] = (unsigned long)arg12;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-144\n\t"  /* expand stack frame */            \
-         /* arg12 */                                              \
-         "ld  3,96(11)\n\t"                                       \
-         "std 3,136(1)\n\t"                                       \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         "addi 1,1,144"     /* restore frame */                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc64_linux */
-
-/* ------------------------ ppc32-aix5 ------------------------- */
-
-#if defined(PLAT_ppc32_aix5)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* Expand the stack frame, copying enough info that unwinding
-   still works.  Trashes r3. */
-
-#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
-         "addi 1,1,-" #_n_fr "\n\t"                               \
-         "lwz  3," #_n_fr "(1)\n\t"                               \
-         "stw  3,0(1)\n\t"
-
-#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
-         "addi 1,1," #_n_fr "\n\t"
-
-/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
-   long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+0];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1] = (unsigned long)_orig.r2;                       \
-      _argvec[2] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+1];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+2];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+3];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+4];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+5];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t" /* arg2->r4 */                       \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+6];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+7];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+8];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+9];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(64)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+10];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,60(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(64)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+11];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,64(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,60(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(72)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+12];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      _argvec[2+12] = (unsigned long)arg12;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
-         /* arg12 */                                              \
-         "lwz 3,48(11)\n\t"                                       \
-         "stw 3,68(1)\n\t"                                        \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,64(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,60(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(72)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc32_aix5 */
-
-/* ------------------------ ppc64-aix5 ------------------------- */
-
-#if defined(PLAT_ppc64_aix5)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* Expand the stack frame, copying enough info that unwinding
-   still works.  Trashes r3. */
-
-#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
-         "addi 1,1,-" #_n_fr "\n\t"                               \
-         "ld   3," #_n_fr "(1)\n\t"                               \
-         "std  3,0(1)\n\t"
-
-#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
-         "addi 1,1," #_n_fr "\n\t"
-
-/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
-   long) == 8. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+0];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1] = (unsigned long)_orig.r2;                       \
-      _argvec[2] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+1];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+2];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+3];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+4];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+5];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+6];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+7];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+8];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+9];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(128)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+10];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(128)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+11];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(144)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+12];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      _argvec[2+12] = (unsigned long)arg12;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
-         /* arg12 */                                              \
-         "ld  3,96(11)\n\t"                                       \
-         "std 3,136(1)\n\t"                                       \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(144)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc64_aix5 */
-
-
-/* ------------------------------------------------------------------ */
-/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
-/*                                                                    */
-/* ------------------------------------------------------------------ */
-
-/* Some request codes.  There are many more of these, but most are not
-   exposed to end-user view.  These are the public ones, all of the
-   form 0x1000 + small_number.
-
-   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
-   ones start at 0x2000.
-*/
-
-/* These macros are used by tools -- they must be public, but don't
-   embed them into other programs. */
-#define VG_USERREQ_TOOL_BASE(a,b) \
-   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
-#define VG_IS_TOOL_USERREQ(a, b, v) \
-   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
-
-/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! 
-   This enum comprises an ABI exported by Valgrind to programs
-   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
-   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
-typedef
-   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
-          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
-
-          /* These allow any function to be called from the simulated
-             CPU but run on the real CPU.  Nb: the first arg passed to
-             the function is always the ThreadId of the running
-             thread!  So CLIENT_CALL0 actually requires a 1 arg
-             function, etc. */
-          VG_USERREQ__CLIENT_CALL0 = 0x1101,
-          VG_USERREQ__CLIENT_CALL1 = 0x1102,
-          VG_USERREQ__CLIENT_CALL2 = 0x1103,
-          VG_USERREQ__CLIENT_CALL3 = 0x1104,
-
-          /* Can be useful in regression testing suites -- eg. can
-             send Valgrind's output to /dev/null and still count
-             errors. */
-          VG_USERREQ__COUNT_ERRORS = 0x1201,
-
-          /* These are useful and can be interpreted by any tool that
-             tracks malloc() et al, by using vg_replace_malloc.c. */
-          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
-          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
-          /* Memory pool support. */
-          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
-          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
-          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
-          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
-          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
-          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
-          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
-          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
-
-          /* Allow printfs to valgrind log. */
-          VG_USERREQ__PRINTF           = 0x1401,
-          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
-
-          /* Stack support. */
-          VG_USERREQ__STACK_REGISTER   = 0x1501,
-          VG_USERREQ__STACK_DEREGISTER = 0x1502,
-          VG_USERREQ__STACK_CHANGE     = 0x1503
-   } Vg_ClientRequest;
-
-#if !defined(__GNUC__)
-#  define __extension__ /* */
-#endif
-
-/* Returns the number of Valgrinds this code is running under.  That
-   is, 0 if running natively, 1 if running under Valgrind, 2 if
-   running under Valgrind which is running under another Valgrind,
-   etc. */
-#define RUNNING_ON_VALGRIND  __extension__                        \
-   ({unsigned int _qzz_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */,          \
-                               VG_USERREQ__RUNNING_ON_VALGRIND,   \
-                               0, 0, 0, 0, 0);                    \
-    _qzz_res;                                                     \
-   })
-
-
-/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
-   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
-   since it provides a way to make sure valgrind will retranslate the
-   invalidated area.  Returns no value. */
-#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)         \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__DISCARD_TRANSLATIONS,  \
-                               _qzz_addr, _qzz_len, 0, 0, 0);     \
-   }
-
-
-/* These requests are for getting Valgrind itself to print something.
-   Possibly with a backtrace.  This is a really ugly hack. */
-
-#if defined(NVALGRIND)
-
-#  define VALGRIND_PRINTF(...)
-#  define VALGRIND_PRINTF_BACKTRACE(...)
-
-#else /* NVALGRIND */
-
-/* Modern GCC will optimize the static routine out if unused,
-   and unused attribute will shut down warnings about it.  */
-static int VALGRIND_PRINTF(const char *format, ...)
-   __attribute__((format(__printf__, 1, 2), __unused__));
-static int
-VALGRIND_PRINTF(const char *format, ...)
-{
-   unsigned long _qzz_res;
-   va_list vargs;
-   va_start(vargs, format);
-   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
-                              (unsigned long)format, (unsigned long)vargs, 
-                              0, 0, 0);
-   va_end(vargs);
-   return (int)_qzz_res;
-}
-
-static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
-   __attribute__((format(__printf__, 1, 2), __unused__));
-static int
-VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
-{
-   unsigned long _qzz_res;
-   va_list vargs;
-   va_start(vargs, format);
-   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
-                              (unsigned long)format, (unsigned long)vargs, 
-                              0, 0, 0);
-   va_end(vargs);
-   return (int)_qzz_res;
-}
-
-#endif /* NVALGRIND */
-
-
-/* These requests allow control to move from the simulated CPU to the
-   real CPU, calling an arbitary function.
-   
-   Note that the current ThreadId is inserted as the first argument.
-   So this call:
-
-     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
-
-   requires f to have this signature:
-
-     Word f(Word tid, Word arg1, Word arg2)
-
-   where "Word" is a word-sized type.
-
-   Note that these client requests are not entirely reliable.  For example,
-   if you call a function with them that subsequently calls printf(),
-   there's a high chance Valgrind will crash.  Generally, your prospects of
-   these working are made higher if the called function does not refer to
-   any global variables, and does not refer to any libc or other functions
-   (printf et al).  Any kind of entanglement with libc or dynamic linking is
-   likely to have a bad outcome, for tricky reasons which we've grappled
-   with a lot in the past.
-*/
-#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL0,          \
-                               _qyy_fn,                           \
-                               0, 0, 0, 0);                       \
-    _qyy_res;                                                     \
-   })
-
-#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)               \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL1,          \
-                               _qyy_fn,                           \
-                               _qyy_arg1, 0, 0, 0);               \
-    _qyy_res;                                                     \
-   })
-
-#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)    \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL2,          \
-                               _qyy_fn,                           \
-                               _qyy_arg1, _qyy_arg2, 0, 0);       \
-    _qyy_res;                                                     \
-   })
-
-#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL3,          \
-                               _qyy_fn,                           \
-                               _qyy_arg1, _qyy_arg2,              \
-                               _qyy_arg3, 0);                     \
-    _qyy_res;                                                     \
-   })
-
-
-/* Counts the number of errors that have been recorded by a tool.  Nb:
-   the tool must record the errors with VG_(maybe_record_error)() or
-   VG_(unique_error)() for them to be counted. */
-#define VALGRIND_COUNT_ERRORS                                     \
-   __extension__                                                  \
-   ({unsigned int _qyy_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__COUNT_ERRORS,          \
-                               0, 0, 0, 0, 0);                    \
-    _qyy_res;                                                     \
-   })
-
-/* Mark a block of memory as having been allocated by a malloc()-like
-   function.  `addr' is the start of the usable block (ie. after any
-   redzone) `rzB' is redzone size if the allocator can apply redzones;
-   use '0' if not.  Adding redzones makes it more likely Valgrind will spot
-   block overruns.  `is_zeroed' indicates if the memory is zeroed, as it is
-   for calloc().  Put it immediately after the point where a block is
-   allocated. 
-   
-   If you're using Memcheck: If you're allocating memory via superblocks,
-   and then handing out small chunks of each superblock, if you don't have
-   redzones on your small blocks, it's worth marking the superblock with
-   VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are
-   detected.  But if you can put redzones on, it's probably better to not do
-   this, so that messages for small overruns are described in terms of the
-   small block rather than the superblock (but if you have a big overrun
-   that skips over a redzone, you could miss an error this way).  See
-   memcheck/tests/custom_alloc.c for an example.
-
-   WARNING: if your allocator uses malloc() or 'new' to allocate
-   superblocks, rather than mmap() or brk(), this will not work properly --
-   you'll likely get assertion failures during leak detection.  This is
-   because Valgrind doesn't like seeing overlapping heap blocks.  Sorry.
-
-   Nb: block must be freed via a free()-like function specified
-   with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
-#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)    \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MALLOCLIKE_BLOCK,      \
-                               addr, sizeB, rzB, is_zeroed, 0);   \
-   }
-
-/* Mark a block of memory as having been freed by a free()-like function.
-   `rzB' is redzone size;  it must match that given to
-   VALGRIND_MALLOCLIKE_BLOCK.  Memory not freed will be detected by the leak
-   checker.  Put it immediately after the point where the block is freed. */
-#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                        \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__FREELIKE_BLOCK,        \
-                               addr, rzB, 0, 0, 0);               \
-   }
-
-/* Create a memory pool. */
-#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__CREATE_MEMPOOL,        \
-                               pool, rzB, is_zeroed, 0, 0);       \
-   }
-
-/* Destroy a memory pool. */
-#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__DESTROY_MEMPOOL,       \
-                               pool, 0, 0, 0, 0);                 \
-   }
-
-/* Associate a piece of memory with a memory pool. */
-#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_ALLOC,         \
-                               pool, addr, size, 0, 0);           \
-   }
-
-/* Disassociate a piece of memory from a memory pool. */
-#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_FREE,          \
-                               pool, addr, 0, 0, 0);              \
-   }
-
-/* Disassociate any pieces outside a particular range. */
-#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_TRIM,          \
-                               pool, addr, size, 0, 0);           \
-   }
-
-/* Resize and/or move a piece associated with a memory pool. */
-#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MOVE_MEMPOOL,          \
-                               poolA, poolB, 0, 0, 0);            \
-   }
-
-/* Resize and/or move a piece associated with a memory pool. */
-#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_CHANGE,        \
-                               pool, addrA, addrB, size, 0);      \
-   }
-
-/* Return 1 if a mempool exists, else 0. */
-#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
-   ({unsigned int _qzz_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__MEMPOOL_EXISTS,        \
-                               pool, 0, 0, 0, 0);                 \
-    _qzz_res;                                                     \
-   })
-
-/* Mark a piece of memory as being a stack. Returns a stack id. */
-#define VALGRIND_STACK_REGISTER(start, end)                       \
-   ({unsigned int _qzz_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__STACK_REGISTER,        \
-                               start, end, 0, 0, 0);              \
-    _qzz_res;                                                     \
-   })
-
-/* Unmark the piece of memory associated with a stack id as being a
-   stack. */
-#define VALGRIND_STACK_DEREGISTER(id)                             \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__STACK_DEREGISTER,      \
-                               id, 0, 0, 0, 0);                   \
-   }
-
-/* Change the start and end address of the stack id. */
-#define VALGRIND_STACK_CHANGE(id, start, end)                     \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
-                               VG_USERREQ__STACK_CHANGE,          \
-                               id, start, end, 0, 0);             \
-   }
-
-
-#undef PLAT_x86_linux
-#undef PLAT_amd64_linux
-#undef PLAT_ppc32_linux
-#undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
-
-#endif   /* __VALGRIND_H */
diff --git a/third_party/tcmalloc/vendor/src/thread_cache.cc b/third_party/tcmalloc/vendor/src/thread_cache.cc
deleted file mode 100644
index 6d2f832..0000000
--- a/third_party/tcmalloc/vendor/src/thread_cache.cc
+++ /dev/null
@@ -1,529 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Ken Ashcraft <opensource@google.com>
-
-#include <config.h>
-#include "thread_cache.h"
-#include <errno.h>
-#include <string.h>                     // for memcpy
-#include <algorithm>                    // for max, min
-#include "base/commandlineflags.h"      // for SpinLockHolder
-#include "base/spinlock.h"              // for SpinLockHolder
-#include "getenv_safe.h"                // for TCMallocGetenvSafe
-#include "central_freelist.h"           // for CentralFreeListPadded
-#include "maybe_threads.h"
-
-using std::min;
-using std::max;
-
-// Note: this is initialized manually in InitModule to ensure that
-// it's configured at right time
-//
-// DEFINE_int64(tcmalloc_max_total_thread_cache_bytes,
-//              EnvToInt64("TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES",
-//                         kDefaultOverallThreadCacheSize),
-//              "Bound on the total amount of bytes allocated to "
-//              "thread caches. This bound is not strict, so it is possible "
-//              "for the cache to go over this bound in certain circumstances. "
-//              "Maximum value of this flag is capped to 1 GB.");
-
-
-namespace tcmalloc {
-
-static bool phinited = false;
-
-volatile size_t ThreadCache::per_thread_cache_size_ = kMaxThreadCacheSize;
-size_t ThreadCache::overall_thread_cache_size_ = kDefaultOverallThreadCacheSize;
-ssize_t ThreadCache::unclaimed_cache_space_ = kDefaultOverallThreadCacheSize;
-PageHeapAllocator<ThreadCache> threadcache_allocator;
-ThreadCache* ThreadCache::thread_heaps_ = NULL;
-int ThreadCache::thread_heap_count_ = 0;
-ThreadCache* ThreadCache::next_memory_steal_ = NULL;
-#ifdef HAVE_TLS
-__thread ThreadCache::ThreadLocalData ThreadCache::threadlocal_data_
-    ATTR_INITIAL_EXEC CACHELINE_ALIGNED;
-#endif
-bool ThreadCache::tsd_inited_ = false;
-pthread_key_t ThreadCache::heap_key_;
-
-void ThreadCache::Init(pthread_t tid) {
-  size_ = 0;
-
-  max_size_ = 0;
-  IncreaseCacheLimitLocked();
-  if (max_size_ == 0) {
-    // There isn't enough memory to go around.  Just give the minimum to
-    // this thread.
-    SetMaxSize(kMinThreadCacheSize);
-
-    // Take unclaimed_cache_space_ negative.
-    unclaimed_cache_space_ -= kMinThreadCacheSize;
-    ASSERT(unclaimed_cache_space_ < 0);
-  }
-
-  next_ = NULL;
-  prev_ = NULL;
-  tid_  = tid;
-  in_setspecific_ = false;
-  for (uint32 cl = 0; cl < Static::num_size_classes(); ++cl) {
-    list_[cl].Init(Static::sizemap()->class_to_size(cl));
-  }
-
-  uint32_t sampler_seed;
-  memcpy(&sampler_seed, &tid, sizeof(sampler_seed));
-  sampler_.Init(sampler_seed);
-}
-
-void ThreadCache::Cleanup() {
-  // Put unused memory back into central cache
-  for (uint32 cl = 0; cl < Static::num_size_classes(); ++cl) {
-    if (list_[cl].length() > 0) {
-      ReleaseToCentralCache(&list_[cl], cl, list_[cl].length());
-    }
-  }
-}
-
-// Remove some objects of class "cl" from central cache and add to thread heap.
-// On success, return the first object for immediate use; otherwise return NULL.
-void* ThreadCache::FetchFromCentralCache(uint32 cl, int32_t byte_size,
-                                         void *(*oom_handler)(size_t size)) {
-  FreeList* list = &list_[cl];
-  ASSERT(list->empty());
-  const int batch_size = Static::sizemap()->num_objects_to_move(cl);
-
-  const int num_to_move = min<int>(list->max_length(), batch_size);
-  void *start, *end;
-  int fetch_count = Static::central_cache()[cl].RemoveRange(
-      &start, &end, num_to_move);
-
-  if (fetch_count == 0) {
-    ASSERT(start == NULL);
-    return oom_handler(byte_size);
-  }
-  ASSERT(start != NULL);
-
-  if (--fetch_count >= 0) {
-    size_ += byte_size * fetch_count;
-    list->PushRange(fetch_count, SLL_Next(start), end);
-  }
-
-  // Increase max length slowly up to batch_size.  After that,
-  // increase by batch_size in one shot so that the length is a
-  // multiple of batch_size.
-  if (list->max_length() < batch_size) {
-    list->set_max_length(list->max_length() + 1);
-  } else {
-    // Don't let the list get too long.  In 32 bit builds, the length
-    // is represented by a 16 bit int, so we need to watch out for
-    // integer overflow.
-    int new_length = min<int>(list->max_length() + batch_size,
-                              kMaxDynamicFreeListLength);
-    // The list's max_length must always be a multiple of batch_size,
-    // and kMaxDynamicFreeListLength is not necessarily a multiple
-    // of batch_size.
-    new_length -= new_length % batch_size;
-    ASSERT(new_length % batch_size == 0);
-    list->set_max_length(new_length);
-  }
-  return start;
-}
-
-void ThreadCache::ListTooLong(FreeList* list, uint32 cl) {
-  size_ += list->object_size();
-
-  const int batch_size = Static::sizemap()->num_objects_to_move(cl);
-  ReleaseToCentralCache(list, cl, batch_size);
-
-  // If the list is too long, we need to transfer some number of
-  // objects to the central cache.  Ideally, we would transfer
-  // num_objects_to_move, so the code below tries to make max_length
-  // converge on num_objects_to_move.
-
-  if (list->max_length() < batch_size) {
-    // Slow start the max_length so we don't overreserve.
-    list->set_max_length(list->max_length() + 1);
-  } else if (list->max_length() > batch_size) {
-    // If we consistently go over max_length, shrink max_length.  If we don't
-    // shrink it, some amount of memory will always stay in this freelist.
-    list->set_length_overages(list->length_overages() + 1);
-    if (list->length_overages() > kMaxOverages) {
-      ASSERT(list->max_length() > batch_size);
-      list->set_max_length(list->max_length() - batch_size);
-      list->set_length_overages(0);
-    }
-  }
-
-  if (PREDICT_FALSE(size_ > max_size_)) {
-    Scavenge();
-  }
-}
-
-// Remove some objects of class "cl" from thread heap and add to central cache
-void ThreadCache::ReleaseToCentralCache(FreeList* src, uint32 cl, int N) {
-  ASSERT(src == &list_[cl]);
-  if (N > src->length()) N = src->length();
-  size_t delta_bytes = N * Static::sizemap()->ByteSizeForClass(cl);
-
-  // We return prepackaged chains of the correct size to the central cache.
-  // TODO: Use the same format internally in the thread caches?
-  int batch_size = Static::sizemap()->num_objects_to_move(cl);
-  while (N > batch_size) {
-    void *tail, *head;
-    src->PopRange(batch_size, &head, &tail);
-    Static::central_cache()[cl].InsertRange(head, tail, batch_size);
-    N -= batch_size;
-  }
-  void *tail, *head;
-  src->PopRange(N, &head, &tail);
-  Static::central_cache()[cl].InsertRange(head, tail, N);
-  size_ -= delta_bytes;
-}
-
-// Release idle memory to the central cache
-void ThreadCache::Scavenge() {
-  // If the low-water mark for the free list is L, it means we would
-  // not have had to allocate anything from the central cache even if
-  // we had reduced the free list size by L.  We aim to get closer to
-  // that situation by dropping L/2 nodes from the free list.  This
-  // may not release much memory, but if so we will call scavenge again
-  // pretty soon and the low-water marks will be high on that call.
-  for (int cl = 0; cl < Static::num_size_classes(); cl++) {
-    FreeList* list = &list_[cl];
-    const int lowmark = list->lowwatermark();
-    if (lowmark > 0) {
-      const int drop = (lowmark > 1) ? lowmark/2 : 1;
-      ReleaseToCentralCache(list, cl, drop);
-
-      // Shrink the max length if it isn't used.  Only shrink down to
-      // batch_size -- if the thread was active enough to get the max_length
-      // above batch_size, it will likely be that active again.  If
-      // max_length shinks below batch_size, the thread will have to
-      // go through the slow-start behavior again.  The slow-start is useful
-      // mainly for threads that stay relatively idle for their entire
-      // lifetime.
-      const int batch_size = Static::sizemap()->num_objects_to_move(cl);
-      if (list->max_length() > batch_size) {
-        list->set_max_length(
-            max<int>(list->max_length() - batch_size, batch_size));
-      }
-    }
-    list->clear_lowwatermark();
-  }
-
-  IncreaseCacheLimit();
-}
-
-void ThreadCache::IncreaseCacheLimit() {
-  SpinLockHolder h(Static::pageheap_lock());
-  IncreaseCacheLimitLocked();
-}
-
-void ThreadCache::IncreaseCacheLimitLocked() {
-  if (unclaimed_cache_space_ > 0) {
-    // Possibly make unclaimed_cache_space_ negative.
-    unclaimed_cache_space_ -= kStealAmount;
-    SetMaxSize(max_size_ + kStealAmount);
-    return;
-  }
-  // Don't hold pageheap_lock too long.  Try to steal from 10 other
-  // threads before giving up.  The i < 10 condition also prevents an
-  // infinite loop in case none of the existing thread heaps are
-  // suitable places to steal from.
-  for (int i = 0; i < 10;
-       ++i, next_memory_steal_ = next_memory_steal_->next_) {
-    // Reached the end of the linked list.  Start at the beginning.
-    if (next_memory_steal_ == NULL) {
-      ASSERT(thread_heaps_ != NULL);
-      next_memory_steal_ = thread_heaps_;
-    }
-    if (next_memory_steal_ == this ||
-        next_memory_steal_->max_size_ <= kMinThreadCacheSize) {
-      continue;
-    }
-    next_memory_steal_->SetMaxSize(next_memory_steal_->max_size_ - kStealAmount);
-    SetMaxSize(max_size_ + kStealAmount);
-
-    next_memory_steal_ = next_memory_steal_->next_;
-    return;
-  }
-}
-
-int ThreadCache::GetSamplePeriod() {
-  return sampler_.GetSamplePeriod();
-}
-
-void ThreadCache::InitModule() {
-  {
-    SpinLockHolder h(Static::pageheap_lock());
-    if (phinited) {
-      return;
-    }
-    const char *tcb = TCMallocGetenvSafe("TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES");
-    if (tcb) {
-      set_overall_thread_cache_size(strtoll(tcb, NULL, 10));
-    }
-    Static::InitStaticVars();
-    threadcache_allocator.Init();
-    phinited = 1;
-  }
-
-  // We do "late" part of initialization without holding lock since
-  // there is chance it'll recurse into malloc
-  Static::InitLateMaybeRecursive();
-}
-
-void ThreadCache::InitTSD() {
-  ASSERT(!tsd_inited_);
-  perftools_pthread_key_create(&heap_key_, DestroyThreadCache);
-  tsd_inited_ = true;
-
-#ifdef PTHREADS_CRASHES_IF_RUN_TOO_EARLY
-  // We may have used a fake pthread_t for the main thread.  Fix it.
-  pthread_t zero;
-  memset(&zero, 0, sizeof(zero));
-  SpinLockHolder h(Static::pageheap_lock());
-  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
-    if (h->tid_ == zero) {
-      h->tid_ = pthread_self();
-    }
-  }
-#endif
-}
-
-ThreadCache* ThreadCache::CreateCacheIfNecessary() {
-  if (!tsd_inited_) {
-#ifndef NDEBUG
-    // tests that freeing nullptr very early is working
-    free(NULL);
-#endif
-
-    InitModule();
-  }
-
-  // Initialize per-thread data if necessary
-  ThreadCache* heap = NULL;
-
-  bool seach_condition = true;
-#ifdef HAVE_TLS
-  static __thread ThreadCache** current_heap_ptr;
-  if (tsd_inited_) {
-    // In most common case we're avoiding expensive linear search
-    // through all heaps (see below). Working TLS enables faster
-    // protection from malloc recursion in pthread_setspecific
-    seach_condition = false;
-
-    if (current_heap_ptr != NULL) {
-      // we're being recursively called by pthread_setspecific below.
-      return *current_heap_ptr;
-    }
-    current_heap_ptr = &heap;
-  }
-#endif
-
-  {
-    SpinLockHolder h(Static::pageheap_lock());
-    // On some old glibc's, and on freebsd's libc (as of freebsd 8.1),
-    // calling pthread routines (even pthread_self) too early could
-    // cause a segfault.  Since we can call pthreads quite early, we
-    // have to protect against that in such situations by making a
-    // 'fake' pthread.  This is not ideal since it doesn't work well
-    // when linking tcmalloc statically with apps that create threads
-    // before main, so we only do it if we have to.
-#ifdef PTHREADS_CRASHES_IF_RUN_TOO_EARLY
-    pthread_t me;
-    if (!tsd_inited_) {
-      memset(&me, 0, sizeof(me));
-    } else {
-      me = pthread_self();
-    }
-#else
-    const pthread_t me = pthread_self();
-#endif
-
-    // This may be a recursive malloc call from pthread_setspecific()
-    // In that case, the heap for this thread has already been created
-    // and added to the linked list.  So we search for that first.
-    if (seach_condition) {
-      for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
-        if (h->tid_ == me) {
-          heap = h;
-          break;
-        }
-      }
-    }
-
-    if (heap == NULL) heap = NewHeap(me);
-  }
-
-  // We call pthread_setspecific() outside the lock because it may
-  // call malloc() recursively.  We check for the recursive call using
-  // the "in_setspecific_" flag so that we can avoid calling
-  // pthread_setspecific() if we are already inside pthread_setspecific().
-  if (!heap->in_setspecific_ && tsd_inited_) {
-    heap->in_setspecific_ = true;
-    perftools_pthread_setspecific(heap_key_, heap);
-#ifdef HAVE_TLS
-    // Also keep a copy in __thread for faster retrieval
-    threadlocal_data_.heap = heap;
-    threadlocal_data_.fast_path_heap = heap;
-#endif
-    heap->in_setspecific_ = false;
-  }
-#ifdef HAVE_TLS
-  current_heap_ptr = NULL;
-#endif
-  return heap;
-}
-
-ThreadCache* ThreadCache::NewHeap(pthread_t tid) {
-  // Create the heap and add it to the linked list
-  ThreadCache *heap = threadcache_allocator.New();
-  heap->Init(tid);
-  heap->next_ = thread_heaps_;
-  heap->prev_ = NULL;
-  if (thread_heaps_ != NULL) {
-    thread_heaps_->prev_ = heap;
-  } else {
-    // This is the only thread heap at the momment.
-    ASSERT(next_memory_steal_ == NULL);
-    next_memory_steal_ = heap;
-  }
-  thread_heaps_ = heap;
-  thread_heap_count_++;
-  return heap;
-}
-
-void ThreadCache::BecomeIdle() {
-  if (!tsd_inited_) return;              // No caches yet
-  ThreadCache* heap = GetThreadHeap();
-  if (heap == NULL) return;             // No thread cache to remove
-  if (heap->in_setspecific_) return;    // Do not disturb the active caller
-
-  heap->in_setspecific_ = true;
-  perftools_pthread_setspecific(heap_key_, NULL);
-#ifdef HAVE_TLS
-  // Also update the copy in __thread
-  threadlocal_data_.heap = NULL;
-  threadlocal_data_.fast_path_heap = NULL;
-#endif
-  heap->in_setspecific_ = false;
-  if (GetThreadHeap() == heap) {
-    // Somehow heap got reinstated by a recursive call to malloc
-    // from pthread_setspecific.  We give up in this case.
-    return;
-  }
-
-  // We can now get rid of the heap
-  DeleteCache(heap);
-}
-
-void ThreadCache::BecomeTemporarilyIdle() {
-  ThreadCache* heap = GetCacheIfPresent();
-  if (heap)
-    heap->Cleanup();
-}
-
-void ThreadCache::DestroyThreadCache(void* ptr) {
-  // Note that "ptr" cannot be NULL since pthread promises not
-  // to invoke the destructor on NULL values, but for safety,
-  // we check anyway.
-  if (ptr == NULL) return;
-#ifdef HAVE_TLS
-  // Prevent fast path of GetThreadHeap() from returning heap.
-  threadlocal_data_.heap = NULL;
-  threadlocal_data_.fast_path_heap = NULL;
-#endif
-  DeleteCache(reinterpret_cast<ThreadCache*>(ptr));
-}
-
-void ThreadCache::DeleteCache(ThreadCache* heap) {
-  // Remove all memory from heap
-  heap->Cleanup();
-
-  // Remove from linked list
-  SpinLockHolder h(Static::pageheap_lock());
-  if (heap->next_ != NULL) heap->next_->prev_ = heap->prev_;
-  if (heap->prev_ != NULL) heap->prev_->next_ = heap->next_;
-  if (thread_heaps_ == heap) thread_heaps_ = heap->next_;
-  thread_heap_count_--;
-
-  if (next_memory_steal_ == heap) next_memory_steal_ = heap->next_;
-  if (next_memory_steal_ == NULL) next_memory_steal_ = thread_heaps_;
-  unclaimed_cache_space_ += heap->max_size_;
-
-  threadcache_allocator.Delete(heap);
-}
-
-void ThreadCache::RecomputePerThreadCacheSize() {
-  // Divide available space across threads
-  int n = thread_heap_count_ > 0 ? thread_heap_count_ : 1;
-  size_t space = overall_thread_cache_size_ / n;
-
-  // Limit to allowed range
-  if (space < kMinThreadCacheSize) space = kMinThreadCacheSize;
-  if (space > kMaxThreadCacheSize) space = kMaxThreadCacheSize;
-
-  double ratio = space / max<double>(1, per_thread_cache_size_);
-  size_t claimed = 0;
-  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
-    // Increasing the total cache size should not circumvent the
-    // slow-start growth of max_size_.
-    if (ratio < 1.0) {
-      h->SetMaxSize(h->max_size_ * ratio);
-    }
-    claimed += h->max_size_;
-  }
-  unclaimed_cache_space_ = overall_thread_cache_size_ - claimed;
-  per_thread_cache_size_ = space;
-}
-
-void ThreadCache::GetThreadStats(uint64_t* total_bytes, uint64_t* class_count) {
-  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
-    *total_bytes += h->Size();
-    if (class_count) {
-      for (int cl = 0; cl < Static::num_size_classes(); ++cl) {
-        class_count[cl] += h->freelist_length(cl);
-      }
-    }
-  }
-}
-
-void ThreadCache::set_overall_thread_cache_size(size_t new_size) {
-  // Clip the value to a reasonable range
-  if (new_size < kMinThreadCacheSize) new_size = kMinThreadCacheSize;
-  if (new_size > (1<<30)) new_size = (1<<30);     // Limit to 1GB
-  overall_thread_cache_size_ = new_size;
-
-  RecomputePerThreadCacheSize();
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/tcmalloc/vendor/src/thread_cache.h b/third_party/tcmalloc/vendor/src/thread_cache.h
deleted file mode 100644
index f8be1526..0000000
--- a/third_party/tcmalloc/vendor/src/thread_cache.h
+++ /dev/null
@@ -1,510 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#ifndef TCMALLOC_THREAD_CACHE_H_
-#define TCMALLOC_THREAD_CACHE_H_
-
-#include <config.h>
-#ifdef HAVE_PTHREAD
-#include <pthread.h>                    // for pthread_t, pthread_key_t
-#endif
-#include <stddef.h>                     // for size_t, NULL
-#ifdef HAVE_STDINT_H
-#include <stdint.h>                     // for uint32_t, uint64_t
-#endif
-#include <sys/types.h>                  // for ssize_t
-#include "base/commandlineflags.h"
-#include "common.h"
-#include "linked_list.h"
-#include "maybe_threads.h"
-#include "page_heap_allocator.h"
-#include "sampler.h"
-#include "static_vars.h"
-
-#include "common.h"            // for SizeMap, kMaxSize, etc
-#include "internal_logging.h"  // for ASSERT, etc
-#include "linked_list.h"       // for SLL_Pop, SLL_PopRange, etc
-#include "page_heap_allocator.h"  // for PageHeapAllocator
-#include "sampler.h"           // for Sampler
-#include "static_vars.h"       // for Static
-
-DECLARE_int64(tcmalloc_sample_parameter);
-
-namespace tcmalloc {
-
-//-------------------------------------------------------------------
-// Data kept per thread
-//-------------------------------------------------------------------
-
-class ThreadCache {
- public:
-#ifdef HAVE_TLS
-  enum { have_tls = true };
-#else
-  enum { have_tls = false };
-#endif
-
-  void Init(pthread_t tid);
-  void Cleanup();
-
-  // Accessors (mostly just for printing stats)
-  int freelist_length(uint32 cl) const { return list_[cl].length(); }
-
-  // Total byte size in cache
-  size_t Size() const { return size_; }
-
-  // Allocate an object of the given size and class. The size given
-  // must be the same as the size of the class in the size map.
-  void* Allocate(size_t size, uint32 cl, void *(*oom_handler)(size_t size));
-  void Deallocate(void* ptr, uint32 size_class);
-
-  void Scavenge();
-
-  int GetSamplePeriod();
-
-  // Record allocation of "k" bytes.  Return true iff allocation
-  // should be sampled
-  bool SampleAllocation(size_t k);
-
-  bool TryRecordAllocationFast(size_t k);
-
-  static void         InitModule();
-  static void         InitTSD();
-  static ThreadCache* GetThreadHeap();
-  static ThreadCache* GetCache();
-  static ThreadCache* GetCacheIfPresent();
-  static ThreadCache* GetFastPathCache();
-  static ThreadCache* GetCacheWhichMustBePresent();
-  static ThreadCache* CreateCacheIfNecessary();
-  static void         BecomeIdle();
-  static void         BecomeTemporarilyIdle();
-  static void         SetUseEmergencyMalloc();
-  static void         ResetUseEmergencyMalloc();
-  static bool         IsUseEmergencyMalloc();
-
-  // Return the number of thread heaps in use.
-  static inline int HeapsInUse();
-
-  // Adds to *total_bytes the total number of bytes used by all thread heaps.
-  // Also, if class_count is not NULL, it must be an array of size kNumClasses,
-  // and this function will increment each element of class_count by the number
-  // of items in all thread-local freelists of the corresponding size class.
-  // REQUIRES: Static::pageheap_lock is held.
-  static void GetThreadStats(uint64_t* total_bytes, uint64_t* class_count);
-
-  // Sets the total thread cache size to new_size, recomputing the
-  // individual thread cache sizes as necessary.
-  // REQUIRES: Static::pageheap lock is held.
-  static void set_overall_thread_cache_size(size_t new_size);
-  static size_t overall_thread_cache_size() {
-    return overall_thread_cache_size_;
-  }
-
- private:
-  class FreeList {
-   private:
-    void*    list_;       // Linked list of nodes
-
-#ifdef _LP64
-    // On 64-bit hardware, manipulating 16-bit values may be slightly slow.
-    uint32_t length_;      // Current length.
-    uint32_t lowater_;     // Low water mark for list length.
-    uint32_t max_length_;  // Dynamic max list length based on usage.
-    // Tracks the number of times a deallocation has caused
-    // length_ > max_length_.  After the kMaxOverages'th time, max_length_
-    // shrinks and length_overages_ is reset to zero.
-    uint32_t length_overages_;
-#else
-    // If we aren't using 64-bit pointers then pack these into less space.
-    uint16_t length_;
-    uint16_t lowater_;
-    uint16_t max_length_;
-    uint16_t length_overages_;
-#endif
-
-    int32_t size_;
-
-   public:
-    void Init(size_t size) {
-      list_ = NULL;
-      length_ = 0;
-      lowater_ = 0;
-      max_length_ = 1;
-      length_overages_ = 0;
-      size_ = size;
-    }
-
-    // Return current length of list
-    size_t length() const {
-      return length_;
-    }
-
-    int32_t object_size() const {
-      return size_;
-    }
-
-    // Return the maximum length of the list.
-    size_t max_length() const {
-      return max_length_;
-    }
-
-    // Set the maximum length of the list.  If 'new_max' > length(), the
-    // client is responsible for removing objects from the list.
-    void set_max_length(size_t new_max) {
-      max_length_ = new_max;
-    }
-
-    // Return the number of times that length() has gone over max_length().
-    size_t length_overages() const {
-      return length_overages_;
-    }
-
-    void set_length_overages(size_t new_count) {
-      length_overages_ = new_count;
-    }
-
-    // Is list empty?
-    bool empty() const {
-      return list_ == NULL;
-    }
-
-    // Low-water mark management
-    int lowwatermark() const { return lowater_; }
-    void clear_lowwatermark() { lowater_ = length_; }
-
-    uint32_t Push(void* ptr) {
-      uint32_t length = length_ + 1;
-      SLL_Push(&list_, ptr);
-      length_ = length;
-      return length;
-    }
-
-    void* Pop() {
-      ASSERT(list_ != NULL);
-      length_--;
-      if (length_ < lowater_) lowater_ = length_;
-      return SLL_Pop(&list_);
-    }
-
-    bool TryPop(void **rv) {
-      if (SLL_TryPop(&list_, rv)) {
-        length_--;
-        if (PREDICT_FALSE(length_ < lowater_)) lowater_ = length_;
-        return true;
-      }
-      return false;
-    }
-
-    void* Next() {
-      return SLL_Next(&list_);
-    }
-
-    void PushRange(int N, void *start, void *end) {
-      SLL_PushRange(&list_, start, end);
-      length_ += N;
-    }
-
-    void PopRange(int N, void **start, void **end) {
-      SLL_PopRange(&list_, N, start, end);
-      ASSERT(length_ >= N);
-      length_ -= N;
-      if (length_ < lowater_) lowater_ = length_;
-    }
-  };
-
-  // Gets and returns an object from the central cache, and, if possible,
-  // also adds some objects of that size class to this thread cache.
-  void* FetchFromCentralCache(uint32 cl, int32_t byte_size,
-                              void *(*oom_handler)(size_t size));
-
-  void ListTooLong(void* ptr, uint32 cl);
-
-  // Releases some number of items from src.  Adjusts the list's max_length
-  // to eventually converge on num_objects_to_move(cl).
-  void ListTooLong(FreeList* src, uint32 cl);
-
-  // Releases N items from this thread cache.
-  void ReleaseToCentralCache(FreeList* src, uint32 cl, int N);
-
-  void SetMaxSize(int32 new_max_size);
-
-  // Increase max_size_ by reducing unclaimed_cache_space_ or by
-  // reducing the max_size_ of some other thread.  In both cases,
-  // the delta is kStealAmount.
-  void IncreaseCacheLimit();
-  // Same as above but requires Static::pageheap_lock() is held.
-  void IncreaseCacheLimitLocked();
-
-  // If TLS is available, we also store a copy of the per-thread object
-  // in a __thread variable since __thread variables are faster to read
-  // than pthread_getspecific().  We still need pthread_setspecific()
-  // because __thread variables provide no way to run cleanup code when
-  // a thread is destroyed.
-  // We also give a hint to the compiler to use the "initial exec" TLS
-  // model.  This is faster than the default TLS model, at the cost that
-  // you cannot dlopen this library.  (To see the difference, look at
-  // the CPU use of __tls_get_addr with and without this attribute.)
-  // Since we don't really use dlopen in google code -- and using dlopen
-  // on a malloc replacement is asking for trouble in any case -- that's
-  // a good tradeoff for us.
-#ifdef HAVE_TLS
-  struct ThreadLocalData {
-    ThreadCache* fast_path_heap;
-    ThreadCache* heap;
-    bool use_emergency_malloc;
-  };
-  static __thread ThreadLocalData threadlocal_data_
-    CACHELINE_ALIGNED ATTR_INITIAL_EXEC;
-
-#endif
-
-  // Thread-specific key.  Initialization here is somewhat tricky
-  // because some Linux startup code invokes malloc() before it
-  // is in a good enough state to handle pthread_keycreate().
-  // Therefore, we use TSD keys only after tsd_inited is set to true.
-  // Until then, we use a slow path to get the heap object.
-  static ATTRIBUTE_HIDDEN bool tsd_inited_;
-  static pthread_key_t heap_key_;
-
-  // Linked list of heap objects.  Protected by Static::pageheap_lock.
-  static ThreadCache* thread_heaps_;
-  static int thread_heap_count_;
-
-  // A pointer to one of the objects in thread_heaps_.  Represents
-  // the next ThreadCache from which a thread over its max_size_ should
-  // steal memory limit.  Round-robin through all of the objects in
-  // thread_heaps_.  Protected by Static::pageheap_lock.
-  static ThreadCache* next_memory_steal_;
-
-  // Overall thread cache size.  Protected by Static::pageheap_lock.
-  static size_t overall_thread_cache_size_;
-
-  // Global per-thread cache size.  Writes are protected by
-  // Static::pageheap_lock.  Reads are done without any locking, which should be
-  // fine as long as size_t can be written atomically and we don't place
-  // invariants between this variable and other pieces of state.
-  static volatile size_t per_thread_cache_size_;
-
-  // Represents overall_thread_cache_size_ minus the sum of max_size_
-  // across all ThreadCaches.  Protected by Static::pageheap_lock.
-  static ssize_t unclaimed_cache_space_;
-
-  // This class is laid out with the most frequently used fields
-  // first so that hot elements are placed on the same cache line.
-
-  FreeList      list_[kClassSizesMax];     // Array indexed by size-class
-
-  int32         size_;                     // Combined size of data
-  int32         max_size_;                 // size_ > max_size_ --> Scavenge()
-
-  // We sample allocations, biased by the size of the allocation
-  Sampler       sampler_;               // A sampler
-
-  pthread_t     tid_;                   // Which thread owns it
-  bool          in_setspecific_;        // In call to pthread_setspecific?
-
-  // Allocate a new heap. REQUIRES: Static::pageheap_lock is held.
-  static ThreadCache* NewHeap(pthread_t tid);
-
-  // Use only as pthread thread-specific destructor function.
-  static void DestroyThreadCache(void* ptr);
-
-  static void DeleteCache(ThreadCache* heap);
-  static void RecomputePerThreadCacheSize();
-
-public:
-
-  // All ThreadCache objects are kept in a linked list (for stats collection)
-  ThreadCache* next_;
-  ThreadCache* prev_;
-
-  // Ensure that this class is cacheline-aligned. This is critical for
-  // performance, as false sharing would negate many of the benefits
-  // of a per-thread cache.
-} CACHELINE_ALIGNED;
-
-// Allocator for thread heaps
-// This is logically part of the ThreadCache class, but MSVC, at
-// least, does not like using ThreadCache as a template argument
-// before the class is fully defined.  So we put it outside the class.
-extern PageHeapAllocator<ThreadCache> threadcache_allocator;
-
-inline int ThreadCache::HeapsInUse() {
-  return threadcache_allocator.inuse();
-}
-
-inline ATTRIBUTE_ALWAYS_INLINE void* ThreadCache::Allocate(
-  size_t size, uint32 cl, void *(*oom_handler)(size_t size)) {
-  FreeList* list = &list_[cl];
-
-#ifdef NO_TCMALLOC_SAMPLES
-  size = list->object_size();
-#endif
-
-  ASSERT(size <= kMaxSize);
-  ASSERT(size != 0);
-  ASSERT(size == 0 || size == Static::sizemap()->ByteSizeForClass(cl));
-
-  void* rv;
-  if (!list->TryPop(&rv)) {
-    return FetchFromCentralCache(cl, size, oom_handler);
-  }
-  size_ -= size;
-  return rv;
-}
-
-inline ATTRIBUTE_ALWAYS_INLINE void ThreadCache::Deallocate(void* ptr, uint32 cl) {
-  ASSERT(list_[cl].max_length() > 0);
-  FreeList* list = &list_[cl];
-
-  // This catches back-to-back frees of allocs in the same size
-  // class. A more comprehensive (and expensive) test would be to walk
-  // the entire freelist. But this might be enough to find some bugs.
-  ASSERT(ptr != list->Next());
-
-  uint32_t length = list->Push(ptr);
-
-  if (PREDICT_FALSE(length > list->max_length())) {
-    ListTooLong(list, cl);
-    return;
-  }
-
-  size_ += list->object_size();
-  if (PREDICT_FALSE(size_ > max_size_)){
-    Scavenge();
-  }
-}
-
-inline ThreadCache* ThreadCache::GetThreadHeap() {
-#ifdef HAVE_TLS
-  return threadlocal_data_.heap;
-#else
-  return reinterpret_cast<ThreadCache *>(
-      perftools_pthread_getspecific(heap_key_));
-#endif
-}
-
-inline ThreadCache* ThreadCache::GetCacheWhichMustBePresent() {
-#ifdef HAVE_TLS
-  ASSERT(threadlocal_data_.heap);
-  return threadlocal_data_.heap;
-#else
-  ASSERT(perftools_pthread_getspecific(heap_key_));
-  return reinterpret_cast<ThreadCache *>(
-      perftools_pthread_getspecific(heap_key_));
-#endif
-}
-
-inline ThreadCache* ThreadCache::GetCache() {
-#ifdef HAVE_TLS
-  ThreadCache* ptr = GetThreadHeap();
-#else
-  ThreadCache* ptr = NULL;
-  if (PREDICT_TRUE(tsd_inited_)) {
-    ptr = GetThreadHeap();
-  }
-#endif
-  if (ptr == NULL) ptr = CreateCacheIfNecessary();
-  return ptr;
-}
-
-// In deletion paths, we do not try to create a thread-cache.  This is
-// because we may be in the thread destruction code and may have
-// already cleaned up the cache for this thread.
-inline ThreadCache* ThreadCache::GetCacheIfPresent() {
-#ifndef HAVE_TLS
-  if (PREDICT_FALSE(!tsd_inited_)) return NULL;
-#endif
-  return GetThreadHeap();
-}
-
-inline ThreadCache* ThreadCache::GetFastPathCache() {
-#ifndef HAVE_TLS
-  return GetCacheIfPresent();
-#else
-  return threadlocal_data_.fast_path_heap;
-#endif
-}
-
-inline void ThreadCache::SetUseEmergencyMalloc() {
-#ifdef HAVE_TLS
-  threadlocal_data_.fast_path_heap = NULL;
-  threadlocal_data_.use_emergency_malloc = true;
-#endif
-}
-
-inline void ThreadCache::ResetUseEmergencyMalloc() {
-#ifdef HAVE_TLS
-  ThreadCache *heap = threadlocal_data_.heap;
-  threadlocal_data_.fast_path_heap = heap;
-  threadlocal_data_.use_emergency_malloc = false;
-#endif
-}
-
-inline bool ThreadCache::IsUseEmergencyMalloc() {
-#if defined(HAVE_TLS) && defined(ENABLE_EMERGENCY_MALLOC)
-  return PREDICT_FALSE(threadlocal_data_.use_emergency_malloc);
-#else
-  return false;
-#endif
-}
-
-inline void ThreadCache::SetMaxSize(int32 new_max_size) {
-  max_size_ = new_max_size;
-}
-
-#ifndef NO_TCMALLOC_SAMPLES
-
-inline bool ThreadCache::SampleAllocation(size_t k) {
-  return !sampler_.RecordAllocation(k);
-}
-
-inline bool ThreadCache::TryRecordAllocationFast(size_t k) {
-  return sampler_.TryRecordAllocationFast(k);
-}
-
-#else
-
-inline bool ThreadCache::SampleAllocation(size_t k) {
-  return false;
-}
-
-inline bool ThreadCache::TryRecordAllocationFast(size_t k) {
-  return true;
-}
-
-#endif
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_THREAD_CACHE_H_
diff --git a/third_party/tcmalloc/vendor/src/windows/TODO b/third_party/tcmalloc/vendor/src/windows/TODO
deleted file mode 100644
index 708ec237..0000000
--- a/third_party/tcmalloc/vendor/src/windows/TODO
+++ /dev/null
@@ -1,86 +0,0 @@
-* Get heap-profile-table.cc using DeleteMatchingFiles
-* Get heap-profile-table.cc using FillProcSelfMaps, DumpProcSelfMaps
-* Play around with ExperimentalGetStackTrace
-* Support the windows-level memory-allocation functions?  See
-    /home/build/googleclient/earth/client/tools/memorytracking/client/memorytrace/src/memorytrace.cpp
-    /home/build/googleclient/total_recall/common/sitestep/*
-    http://www.internals.com/articles/apispy/apispy.htm
-    http://www.wheaty.net/APISPY32.zip
-* Verify /proc/xxx/maps:
-    http://www.geocities.com/wah_java_dotnet/procmap/index.html
-* Figure out how to edit the executable IAT so tcmalloc.dll is loaded first
-* Use QueryPerformanceCounter instead of GetTickCount() (also for sparsehash)
-
-----
-More info on windows-level memory-allocation functions:
-   C runtime malloc
-   LocalAlloc
-   GlobalAlloc
-   HeapAlloc
-   VirtualAlloc
-   mmap stuff
-
-malloc, LocalAlloc and GlobalAlloc call HeapAlloc, which calls
-VirtualAlloc when needed, which calls VirtualAllocEx (the __sbrk equiv?)
-
-siggi sez: If you want to do a generic job, you probably need to
-preserve the semantics of all of these Win32 calls:
-   Heap32First
-   Heap32ListFirst
-   Heap32ListNext
-   Heap32Next
-   HeapAlloc
-   HeapCompact
-   HeapCreate
-   HeapCreateTagsW
-   HeapDestroy
-   HeapExtend
-   HeapFree
-   HeapLock
-   HeapQueryInformation
-   HeapQueryTagW
-   HeapReAlloc
-   HeapSetInformation
-   HeapSize
-   HeapSummary
-   HeapUnlock
-   HeapUsage
-   HeapValidate
-   HeapWalk
-
-kernel32.dll export functions and nt.dll export functions:
-   http://www.shorthike.com/svn/trunk/tools_win32/dm/lib/kernel32.def
-   http://undocumented.ntinternals.net/
-
-You can edit the executable IAT to have the patching DLL be the
-first one loaded.
-
-Most complete way to intercept system calls is patch the functions
-(not the IAT).
-
-Microsoft has somee built-in routines for heap-checking:
-   http://support.microsoft.com/kb/268343
-
-----
-Itimer replacement:
-   http://msdn2.microsoft.com/en-us/library/ms712713.aspx
-
-----
-Changes I've had to make to the project file:
-
-0) When creating the project file, click on "no autogenerated files"
-
---- For each project:
-1) Alt-F7 -> General -> [pulldown "all configurations" ] -> Output Directory -> $(SolutionDir)$(ConfigurationName)
-2) Alt-F7 -> General -> [pulldown "all configurations" ] -> Intermediate Directory -> $(ConfigurationName)
-
---- For each .cc file:
-1) Alt-F7 -> C/C++ -> General -> [pulldown "all configurations"] -> Additional Include Directives --> src/windows + src/
-2) Alt-F7 -> C/C++ -> Code Generation -> Runtime Library -> Multi-threaded, debug/release, DLL or not
-
---- For DLL:
-3) Alt-F7 -> Linker -> Input -> [pulldown "all configurations" ] -> Module Definition File -> src\windows\vc7and8.def
---- For binaries depending on a DLL:
-3) Right-click on project -> Project Dependencies -> [add dll]
---- For static binaries (not depending on a DLL)
-3) Alt-F7 -> C/C++ -> Command Line -> [pulldown "all configurations"] -> /D PERFTOOLS_DLL_DECL=
diff --git a/third_party/tcmalloc/vendor/src/windows/addr2line-pdb.c b/third_party/tcmalloc/vendor/src/windows/addr2line-pdb.c
deleted file mode 100644
index 5c65a035..0000000
--- a/third_party/tcmalloc/vendor/src/windows/addr2line-pdb.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: David Vitek
- *
- * Dump function addresses using Microsoft debug symbols.  This works
- * on PDB files.  Note that this program will download symbols to
- * c:\websymbols without asking.
- */
-
-#define WIN32_LEAN_AND_MEAN
-#define _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_DEPRECATE
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <windows.h>
-#include <dbghelp.h>
-
-#define SEARCH_CAP (1024*1024)
-#define WEBSYM "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols"
-
-void usage() {
-  fprintf(stderr, "usage: "
-          "addr2line-pdb [-f|--functions] [-C|--demangle] [-e filename]\n");
-  fprintf(stderr, "(Then list the hex addresses on stdin, one per line)\n");
-}
-
-int main(int argc, char *argv[]) {
-  DWORD  error;
-  HANDLE process;
-  ULONG64 module_base;
-  int i;
-  char* search;
-  char buf[256];   /* Enough to hold one hex address, I trust! */
-  int rv = 0;
-  /* We may add SYMOPT_UNDNAME if --demangle is specified: */
-  DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES;
-  char* filename = "a.out";         /* The default if -e isn't specified */
-  int print_function_name = 0;      /* Set to 1 if -f is specified */
-
-  for (i = 1; i < argc; i++) {
-    if (strcmp(argv[i], "--functions") == 0 || strcmp(argv[i], "-f") == 0) {
-      print_function_name = 1;
-    } else if (strcmp(argv[i], "--demangle") == 0 ||
-               strcmp(argv[i], "-C") == 0) {
-      symopts |= SYMOPT_UNDNAME;
-    } else if (strcmp(argv[i], "-e") == 0) {
-      if (i + 1 >= argc) {
-        fprintf(stderr, "FATAL ERROR: -e must be followed by a filename\n");
-        return 1;
-      }
-      filename = argv[i+1];
-      i++;     /* to skip over filename too */
-    } else if (strcmp(argv[i], "--help") == 0) {
-      usage();
-      exit(0);
-    } else {
-      usage();
-      exit(1);
-    }
-  }
-
-  process = GetCurrentProcess();
-
-  if (!SymInitialize(process, NULL, FALSE)) {
-    error = GetLastError();
-    fprintf(stderr, "SymInitialize returned error : %d\n", error);
-    return 1;
-  }
-
-  search = malloc(SEARCH_CAP);
-  if (SymGetSearchPath(process, search, SEARCH_CAP)) {
-    if (strlen(search) + sizeof(";" WEBSYM) > SEARCH_CAP) {
-      fprintf(stderr, "Search path too long\n");
-      SymCleanup(process);
-      return 1;
-    }
-    strcat(search, ";" WEBSYM);
-  } else {
-    error = GetLastError();
-    fprintf(stderr, "SymGetSearchPath returned error : %d\n", error);
-    rv = 1;                   /* An error, but not a fatal one */
-    strcpy(search, WEBSYM);   /* Use a default value */
-  }
-  if (!SymSetSearchPath(process, search)) {
-    error = GetLastError();
-    fprintf(stderr, "SymSetSearchPath returned error : %d\n", error);
-    rv = 1;                   /* An error, but not a fatal one */
-  }
-
-  SymSetOptions(symopts);
-  module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0);
-  if (!module_base) {
-    /* SymLoadModuleEx failed */
-    error = GetLastError();
-    fprintf(stderr, "SymLoadModuleEx returned error : %d for %s\n",
-            error, filename);
-    SymCleanup(process);
-    return 1;
-  }
-
-  buf[sizeof(buf)-1] = '\0';  /* Just to be safe */
-  while (fgets(buf, sizeof(buf)-1, stdin)) {
-    /* GNU addr2line seems to just do a strtol and ignore any
-     * weird characters it gets, so we will too.
-     */
-    unsigned __int64 addr = _strtoui64(buf, NULL, 16);
-    ULONG64 buffer[(sizeof(SYMBOL_INFO) +
-                    MAX_SYM_NAME*sizeof(TCHAR) +
-                    sizeof(ULONG64) - 1)
-                   / sizeof(ULONG64)];
-    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
-    IMAGEHLP_LINE64 line;
-    DWORD dummy;
-    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
-    pSymbol->MaxNameLen = MAX_SYM_NAME;
-    if (print_function_name) {
-      if (SymFromAddr(process, (DWORD64)addr, NULL, pSymbol)) {
-        printf("%s\n", pSymbol->Name);
-      } else {
-        printf("??\n");
-      }
-    }
-    line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
-    if (SymGetLineFromAddr64(process, (DWORD64)addr, &dummy, &line)) {
-      printf("%s:%d\n", line.FileName, (int)line.LineNumber);
-    } else {
-      printf("??:0\n");
-    }
-  }
-  SymUnloadModule64(process, module_base);
-  SymCleanup(process);
-  return rv;
-}
diff --git a/third_party/tcmalloc/vendor/src/windows/auto_testing_hook.h b/third_party/tcmalloc/vendor/src/windows/auto_testing_hook.h
deleted file mode 100644
index fc2b710..0000000
--- a/third_party/tcmalloc/vendor/src/windows/auto_testing_hook.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Utility for using SideStep with unit tests.
-
-#ifndef CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
-#define CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "preamble_patcher.h"
-
-#define SIDESTEP_CHK(x)  CHECK(x)
-#define SIDESTEP_EXPECT_TRUE(x)  SIDESTEP_CHK(x)
-
-namespace sidestep {
-
-// Same trick as common/scope_cleanup.h ScopeGuardImplBase
-class AutoTestingHookBase {
- public:
-  virtual ~AutoTestingHookBase() {}
-};
-
-// This is the typedef you normally use for the class, e.g.
-//
-// AutoTestingHook hook = MakeTestingHook(TargetFunc, HookTargetFunc);
-//
-// The 'hook' variable will then be destroyed when it goes out of scope.
-//
-// NOTE: You must not hold this type as a member of another class.  Its
-// destructor will not get called.
-typedef const AutoTestingHookBase& AutoTestingHook;
-
-// This is the class you must use when holding a hook as a member of another
-// class, e.g.
-//
-// public:
-//  AutoTestingHookHolder holder_;
-//  MyClass() : my_hook_holder(MakeTestingHookHolder(Target, Hook)) {}
-class AutoTestingHookHolder {
- public:
-  explicit AutoTestingHookHolder(AutoTestingHookBase* hook) : hook_(hook) {}
-  ~AutoTestingHookHolder() { delete hook_; }
- private:
-  AutoTestingHookHolder() {}  // disallow
-  AutoTestingHookBase* hook_;
-};
-
-// This class helps patch a function, then unpatch it when the object exits
-// scope, and also maintains the pointer to the original function stub.
-//
-// To enable use of the class without having to explicitly provide the
-// type of the function pointers (and instead only providing it
-// implicitly) we use the same trick as ScopeGuard (see
-// common/scope_cleanup.h) uses, so to create a hook you use the MakeHook
-// function rather than a constructor.
-//
-// NOTE:  This function is only safe for e.g. unit tests and _not_ for
-// production code.  See PreamblePatcher class for details.
-template <typename T>
-class AutoTestingHookImpl : public AutoTestingHookBase {
- public:
-  static AutoTestingHookImpl<T> MakeTestingHook(T target_function,
-                                                T replacement_function,
-                                                bool do_it) {
-    return AutoTestingHookImpl<T>(target_function, replacement_function, do_it);
-  }
-
-  static AutoTestingHookImpl<T>* MakeTestingHookHolder(T target_function,
-                                                       T replacement_function,
-                                                       bool do_it) {
-    return new AutoTestingHookImpl<T>(target_function,
-                                      replacement_function, do_it);
-  }
-
-  ~AutoTestingHookImpl() {
-    if (did_it_) {
-      SIDESTEP_CHK(SIDESTEP_SUCCESS == PreamblePatcher::Unpatch(
-          (void*)target_function_, (void*)replacement_function_,
-          (void*)original_function_));
-    }
-  }
-
-  // Returns a pointer to the original function.  To use this method you will
-  // have to explicitly create an AutoTestingHookImpl of the specific
-  // function pointer type (i.e. not use the AutoTestingHook typedef).
-  T original_function() {
-    return original_function_;
-  }
-
- private:
-  AutoTestingHookImpl(T target_function, T replacement_function, bool do_it)
-      : target_function_(target_function),
-        original_function_(NULL),
-        replacement_function_(replacement_function),
-        did_it_(do_it) {
-    if (do_it) {
-      SIDESTEP_CHK(SIDESTEP_SUCCESS == PreamblePatcher::Patch(target_function,
-                                                     replacement_function,
-                                                     &original_function_));
-    }
-  }
-
-  T target_function_;  // always valid
-  T original_function_;  // always valid
-  T replacement_function_;  // always valid
-  bool did_it_;  // Remember if we did it or not...
-};
-
-template <typename T>
-inline AutoTestingHookImpl<T> MakeTestingHook(T target,
-                                              T replacement,
-                                              bool do_it) {
-  return AutoTestingHookImpl<T>::MakeTestingHook(target, replacement, do_it);
-}
-
-template <typename T>
-inline AutoTestingHookImpl<T> MakeTestingHook(T target, T replacement) {
-  return AutoTestingHookImpl<T>::MakeTestingHook(target, replacement, true);
-}
-
-template <typename T>
-inline AutoTestingHookImpl<T>* MakeTestingHookHolder(T target, T replacement) {
-  return AutoTestingHookImpl<T>::MakeTestingHookHolder(target, replacement,
-                                                       true);
-}
-
-};  // namespace sidestep
-
-#endif  // CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
diff --git a/third_party/tcmalloc/vendor/src/windows/config.h b/third_party/tcmalloc/vendor/src/windows/config.h
deleted file mode 100644
index e860bc35..0000000
--- a/third_party/tcmalloc/vendor/src/windows/config.h
+++ /dev/null
@@ -1,367 +0,0 @@
-/* A manual version of config.h fit for windows machines.
- *
- * Use of this source code is governed by a BSD-style license that can
- * be found in the LICENSE file.
- */
-
-/* Sometimes we accidentally #include this config.h instead of the one
-   in .. -- this is particularly true for msys/mingw, which uses the
-   unix config.h but also runs code in the windows directory.
-   */
-#ifdef __MINGW32__
-#include "../config.h"
-#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_
-#endif
-
-#ifndef GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_
-#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_
-/* used by tcmalloc.h */
-#define GPERFTOOLS_CONFIG_H_
-
-/* define this if you are linking tcmalloc statically and overriding the
- * default allocators.
- * For instructions on how to use this mode, see
- * http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b
- */
-/* #undef WIN32_OVERRIDE_ALLOCATORS */
-
-/* Build new/delete operators for overaligned types */
-/* #undef ENABLE_ALIGNED_NEW_DELETE */
-
-/* Build runtime detection for sized delete */
-/* #undef ENABLE_DYNAMIC_SIZED_DELETE */
-
-/* Build sized deletion operators */
-/* #undef ENABLE_SIZED_DELETE */
-
-/* Define to 1 if compiler supports __builtin_expect */
-/* #undef HAVE_BUILTIN_EXPECT */
-
-/* Define to 1 if compiler supports __builtin_stack_pointer */
-/* #undef HAVE_BUILTIN_STACK_POINTER */
-
-/* Define to 1 if you have the <conflict-signal.h> header file. */
-/* #undef HAVE_CONFLICT_SIGNAL_H */
-
-/* Define to 1 if you have the <cygwin/signal.h> header file. */
-/* #undef HAVE_CYGWIN_SIGNAL_H */
-
-/* Define to 1 if you have the declaration of `backtrace', and to 0 if you
-   don't. */
-/* #undef HAVE_DECL_BACKTRACE */
-
-/* Define to 1 if you have the declaration of `cfree', and to 0 if you don't.
-   */
-#define HAVE_DECL_CFREE 0
-
-/* Define to 1 if you have the declaration of `memalign', and to 0 if you
-   don't. */
-#define HAVE_DECL_MEMALIGN 0
-
-/* Define to 1 if you have the declaration of `nanosleep', and to 0 if you
-   don't. */
-#define HAVE_DECL_NANOSLEEP 0
-
-/* Define to 1 if you have the declaration of `posix_memalign', and to 0 if
-   you don't. */
-#define HAVE_DECL_POSIX_MEMALIGN 0
-
-/* Define to 1 if you have the declaration of `pvalloc', and to 0 if you
-   don't. */
-#define HAVE_DECL_PVALLOC 0
-
-/* Define to 1 if you have the declaration of `sleep', and to 0 if you don't.
-   */
-#define HAVE_DECL_SLEEP 0
-
-/* Define to 1 if you have the declaration of `uname', and to 0 if you don't.
-   */
-#define HAVE_DECL_UNAME 0
-
-/* Define to 1 if you have the declaration of `valloc', and to 0 if you don't.
-   */
-#define HAVE_DECL_VALLOC 0
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-/* #undef HAVE_DLFCN_H */
-
-/* Define to 1 if the system has the type `Elf32_Versym'. */
-/* #undef HAVE_ELF32_VERSYM */
-
-/* Define to 1 if you have the <execinfo.h> header file. */
-/* #undef HAVE_EXECINFO_H */
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the <features.h> header file. */
-/* #undef HAVE_FEATURES_H */
-
-/* Define to 1 if you have the `fork' function. */
-/* #undef HAVE_FORK */
-
-/* Define to 1 if you have the `geteuid' function. */
-/* #undef HAVE_GETEUID */
-
-/* Define to 1 if you have the `getpagesize' function. */
-#define HAVE_GETPAGESIZE 1   /* we define it in windows/port.cc */
-
-/* Define to 1 if you have the <glob.h> header file. */
-/* #undef HAVE_GLOB_H */
-
-/* Define to 1 if you have the <grp.h> header file. */
-/* #undef HAVE_GRP_H */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-#define HAVE_INTTYPES_H 1
-#endif
-
-/* Define to 1 if you have the <libunwind.h> header file. */
-/* #undef HAVE_LIBUNWIND_H */
-
-/* Define to 1 if you have the <linux/ptrace.h> header file. */
-/* #undef HAVE_LINUX_PTRACE_H */
-
-/* Define if this is Linux that has SIGEV_THREAD_ID */
-/* #undef HAVE_LINUX_SIGEV_THREAD_ID */
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#define HAVE_MALLOC_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have a working `mmap' system call. */
-/* #undef HAVE_MMAP */
-
-/* define if the compiler implements namespaces */
-#define HAVE_NAMESPACES 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-/* #undef HAVE_POLL_H */
-
-/* define if libc has program_invocation_name */
-/* #undef HAVE_PROGRAM_INVOCATION_NAME */
-
-/* Define if you have POSIX threads libraries and header files. */
-/* #undef HAVE_PTHREAD */
-
-/* defined to 1 if pthread symbols are exposed even without include pthread.h
-   */
-/* #undef HAVE_PTHREAD_DESPITE_ASKING_FOR */
-
-/* Define to 1 if you have the <pwd.h> header file. */
-/* #undef HAVE_PWD_H */
-
-/* Define to 1 if you have the `sbrk' function. */
-/* #undef HAVE_SBRK */
-
-/* Define to 1 if you have the <sched.h> header file. */
-/* #undef HAVE_SCHED_H */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-#define HAVE_STDINT_H 1
-#endif
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-/* #undef HAVE_STRINGS_H */
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if the system has the type `struct mallinfo'. */
-/* #undef HAVE_STRUCT_MALLINFO */
-
-/* Define to 1 if you have the <sys/cdefs.h> header file. */
-/* #undef HAVE_SYS_CDEFS_H */
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-/* #undef HAVE_SYS_PARAM_H */
-
-/* Define to 1 if you have the <sys/prctl.h> header file. */
-/* #undef HAVE_SYS_PRCTL_H */
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-/* #undef HAVE_SYS_RESOURCE_H */
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-/* #undef HAVE_SYS_SOCKET_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-/* #undef HAVE_SYS_SYSCALL_H */
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/ucontext.h> header file. */
-/* #undef HAVE_SYS_UCONTEXT_H */
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-/* #undef HAVE_SYS_WAIT_H */
-
-/* Define to 1 if compiler supports __thread */
-#define HAVE_TLS 1
-
-/* Define to 1 if you have the <ucontext.h> header file. */
-/* #undef HAVE_UCONTEXT_H */
-
-/* Define to 1 if you have the <unistd.h> header file. */
-/* #undef HAVE_UNISTD_H */
-
-/* Whether <unwind.h> contains _Unwind_Backtrace */
-/* #undef HAVE_UNWIND_BACKTRACE */
-
-/* Define to 1 if you have the <unwind.h> header file. */
-/* #undef HAVE_UNWIND_H */
-
-/* Define to 1 if you have the <valgrind.h> header file. */
-/* #undef HAVE_VALGRIND_H */
-
-/* define if your compiler has __attribute__ */
-/* #undef HAVE___ATTRIBUTE__ */
-
-/* define if your compiler supports alignment of functions */
-/* #undef HAVE___ATTRIBUTE__ALIGNED_FN */
-
-/* Define to 1 if compiler supports __environ */
-/* #undef HAVE___ENVIRON */
-
-/* Define to 1 if the system has the type `__int64'. */
-#define HAVE___INT64 1
-
-/* prefix where we look for installed files */
-/* #undef INSTALL_PREFIX */
-
-/* Define to 1 if int32_t is equivalent to intptr_t */
-#ifndef _WIN64
-#define INT32_EQUALS_INTPTR 1
-#endif
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-/* #undef LT_OBJDIR */
-
-/* Name of package */
-#define PACKAGE "gperftools"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "gperftools@googlegroups.com"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "gperftools"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gperftools 2.7"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "gperftools"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.7"
-
-/* How to access the PC from a struct ucontext */
-/* #undef PC_FROM_UCONTEXT */
-
-/* Always the empty-string on non-windows systems. On windows, should be
-   "__declspec(dllexport)". This way, when we compile the dll, we export our
-   functions/classes. It's safe to define this here because config.h is only
-   used internally, to compile the DLL, and every DLL source file #includes
-   "config.h" before anything else. */
-#ifndef PERFTOOLS_DLL_DECL
-# define PERFTOOLS_IS_A_DLL 1   /* not set if you're statically linking */
-# define PERFTOOLS_DLL_DECL __declspec(dllexport)
-# define PERFTOOLS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
-#endif
-
-/* printf format code for printing a size_t and ssize_t */
-#ifdef _WIN64
-#define PRIdS "lld"
-#else
-#define PRIdS "d"
-#endif
-
-/* printf format code for printing a size_t and ssize_t */
-#ifdef _WIN64
-#define PRIuS "llu"
-#else
-#define PRIuS "u"
-#endif
-
-/* printf format code for printing a size_t and ssize_t */
-#ifdef _WIN64
-#define PRIxS "llx"
-#else
-#define PRIxS "x"
-#endif
-
-/* Mark the systems where we know it's bad if pthreads runs too
-   early before main (before threads are initialized, presumably).  */
-#ifdef __FreeBSD__
-#define PTHREADS_CRASHES_IF_RUN_TOO_EARLY 1
-#endif
-
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* the namespace where STL code like vector<> is defined */
-#define STL_NAMESPACE std
-
-/* Define 32K of internal pages size for tcmalloc */
-/* #undef TCMALLOC_32K_PAGES */
-
-/* Define 64K of internal pages size for tcmalloc */
-/* #undef TCMALLOC_64K_PAGES */
-
-/* Define 8 bytes of allocation alignment for tcmalloc */
-/* #undef TCMALLOC_ALIGN_8BYTES */
-
-/* Version number of package */
-#define VERSION "2.7"
-
-/* C99 says: define this to get the PRI... macros from stdint.h */
-#ifndef __STDC_FORMAT_MACROS
-# define __STDC_FORMAT_MACROS 1
-#endif
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-// ---------------------------------------------------------------------
-// Extra stuff not found in config.h.in
-
-// This must be defined before the windows.h is included.  We need at
-// least 0x0400 for mutex.h to have access to TryLock, and at least
-// 0x0501 for patch_functions.cc to have access to GetModuleHandleEx.
-// (This latter is an optimization we could take out if need be.)
-#ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-#define HAVE_SNPRINTF 1
-#endif
-
-// We want to make sure not to ever try to #include heap-checker.h
-#define NO_HEAP_CHECK 1
-
-// TODO(csilvers): include windows/port.h in every relevant source file instead?
-#include "windows/port.h"
-
-#endif  /* GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ */
diff --git a/third_party/tcmalloc/vendor/src/windows/get_mangled_names.cc b/third_party/tcmalloc/vendor/src/windows/get_mangled_names.cc
deleted file mode 100644
index 08bd03b..0000000
--- a/third_party/tcmalloc/vendor/src/windows/get_mangled_names.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-// ---
-// Author: Craig Silverstein (opensource@google.com)
-
-// When you are porting perftools to a new compiler or architecture
-// (win64 vs win32) for instance, you'll need to change the mangled
-// symbol names for operator new and friends at the top of
-// patch_functions.cc.  This file helps you do that.
-//
-// It does this by defining these functions with the proper signature.
-// All you need to do is compile this file and the run dumpbin on it.
-// (See http://msdn.microsoft.com/en-us/library/5x49w699.aspx for more
-// on dumpbin).  To do this in MSVC, use the MSVC commandline shell:
-//    http://msdn.microsoft.com/en-us/library/ms235639(VS.80).aspx)
-//
-// The run:
-//    cl /c get_mangled_names.cc
-//    dumpbin /symbols get_mangled_names.obj
-//
-// It will print out the mangled (and associated unmangled) names of
-// the 8 symbols you need to put at the top of patch_functions.cc
-
-#include <sys/types.h>   // for size_t
-#include <new>           // for nothrow_t
-
-static char m;   // some dummy memory so new doesn't return NULL.
-
-void* operator new(size_t size) { return &m; }
-void operator delete(void* p) throw() { }
-void* operator new[](size_t size) { return &m; }
-void operator delete[](void* p) throw() { }
-
-void* operator new(size_t size, const std::nothrow_t&) throw() { return &m; }
-void operator delete(void* p, const std::nothrow_t&) throw() { }
-void* operator new[](size_t size, const std::nothrow_t&) throw() { return &m; }
-void operator delete[](void* p, const std::nothrow_t&) throw() { }
diff --git a/third_party/tcmalloc/vendor/src/windows/google/tcmalloc.h b/third_party/tcmalloc/vendor/src/windows/google/tcmalloc.h
deleted file mode 100644
index c7db631..0000000
--- a/third_party/tcmalloc/vendor/src/windows/google/tcmalloc.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* The code has moved to gperftools/.  Use that include-directory for
- * new code.
- */
-#include <gperftools/tcmalloc.h>
diff --git a/third_party/tcmalloc/vendor/src/windows/gperftools/tcmalloc.h b/third_party/tcmalloc/vendor/src/windows/gperftools/tcmalloc.h
deleted file mode 100644
index 46fb4ea..0000000
--- a/third_party/tcmalloc/vendor/src/windows/gperftools/tcmalloc.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat <opensource@google.com>
- *         .h file by Craig Silverstein <opensource@google.com>
- */
-
-#ifndef TCMALLOC_TCMALLOC_H_
-#define TCMALLOC_TCMALLOC_H_
-
-#include <stddef.h>                     /* for size_t */
-#ifdef __cplusplus
-#include <new>                          /* for std::nothrow_t, std::align_val_t */
-#endif
-
-/* Define the version number so folks can check against it */
-#define TC_VERSION_MAJOR  2
-#define TC_VERSION_MINOR  7
-#define TC_VERSION_PATCH  ""
-#define TC_VERSION_STRING "gperftools 2.7"
-
-#ifndef PERFTOOLS_NOTHROW
-
-#if __cplusplus >= 201103L
-#define PERFTOOLS_NOTHROW noexcept
-#elif defined(__cplusplus)
-#define PERFTOOLS_NOTHROW throw()
-#else
-# ifdef __GNUC__
-#  define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
-# else
-#  define PERFTOOLS_NOTHROW
-# endif
-#endif
-
-#endif
-
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-  /*
-   * Returns a human-readable version string.  If major, minor,
-   * and/or patch are not NULL, they are set to the major version,
-   * minor version, and patch-code (a string, usually "").
-   */
-  PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
-                                            const char** patch) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
-                                       size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
-                                           size_t align, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
-
-  /*
-   * This is an alias for MallocExtension::instance()->GetAllocatedSize().
-   * It is equivalent to
-   *    OS X: malloc_size()
-   *    glibc: malloc_usable_size()
-   *    Windows: _msize()
-   */
-  PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
-
-#ifdef __cplusplus
-  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_new(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-
-#if defined(__cpp_aligned_new) || (defined(_MSVC_LANG) && _MSVC_LANG > 201402L)
-  PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t al,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t al,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t al,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-#endif
-}
-#endif
-
-/* We're only un-defining for public */
-#if !defined(GPERFTOOLS_CONFIG_H_)
-
-#undef PERFTOOLS_NOTHROW
-
-#endif /* GPERFTOOLS_CONFIG_H_ */
-
-#endif  /* #ifndef TCMALLOC_TCMALLOC_H_ */
diff --git a/third_party/tcmalloc/vendor/src/windows/gperftools/tcmalloc.h.in b/third_party/tcmalloc/vendor/src/windows/gperftools/tcmalloc.h.in
deleted file mode 100644
index adb7962..0000000
--- a/third_party/tcmalloc/vendor/src/windows/gperftools/tcmalloc.h.in
+++ /dev/null
@@ -1,155 +0,0 @@
-// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2003, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Sanjay Ghemawat <opensource@google.com>
- *         .h file by Craig Silverstein <opensource@google.com>
- */
-
-#ifndef TCMALLOC_TCMALLOC_H_
-#define TCMALLOC_TCMALLOC_H_
-
-#include <stddef.h>                     /* for size_t */
-#ifdef __cplusplus
-#include <new>                          /* for std::nothrow_t, std::align_val_t */
-#endif
-
-/* Define the version number so folks can check against it */
-#define TC_VERSION_MAJOR  @TC_VERSION_MAJOR@
-#define TC_VERSION_MINOR  @TC_VERSION_MINOR@
-#define TC_VERSION_PATCH  "@TC_VERSION_PATCH@"
-#define TC_VERSION_STRING "gperftools @TC_VERSION_MAJOR@.@TC_VERSION_MINOR@@TC_VERSION_PATCH@"
-
-#ifndef PERFTOOLS_NOTHROW
-
-#if __cplusplus >= 201103L
-#define PERFTOOLS_NOTHROW noexcept
-#elif defined(__cplusplus)
-#define PERFTOOLS_NOTHROW throw()
-#else
-# ifdef __GNUC__
-#  define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
-# else
-#  define PERFTOOLS_NOTHROW
-# endif
-#endif
-
-#endif
-
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
-# else
-#   define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-  /*
-   * Returns a human-readable version string.  If major, minor,
-   * and/or patch are not NULL, they are set to the major version,
-   * minor version, and patch-code (a string, usually "").
-   */
-  PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
-                                            const char** patch) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
-                                       size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
-                                           size_t align, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
-
-  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
-
-  /*
-   * This is an alias for MallocExtension::instance()->GetAllocatedSize().
-   * It is equivalent to
-   *    OS X: malloc_size()
-   *    glibc: malloc_usable_size()
-   *    Windows: _msize()
-   */
-  PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
-
-#ifdef __cplusplus
-  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_new(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
-  PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-
-#if defined(__cpp_aligned_new) || (defined(_MSVC_LANG) && _MSVC_LANG > 201402L)
-  PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t al,
-                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t al,
-                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
-  PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al,
-                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t al,
-                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
-#endif
-}
-#endif
-
-/* We're only un-defining for public */
-#if !defined(GPERFTOOLS_CONFIG_H_)
-
-#undef PERFTOOLS_NOTHROW
-
-#endif /* GPERFTOOLS_CONFIG_H_ */
-
-#endif  /* #ifndef TCMALLOC_TCMALLOC_H_ */
diff --git a/third_party/tcmalloc/vendor/src/windows/ia32_modrm_map.cc b/third_party/tcmalloc/vendor/src/windows/ia32_modrm_map.cc
deleted file mode 100644
index 142c7cb..0000000
--- a/third_party/tcmalloc/vendor/src/windows/ia32_modrm_map.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Table of relevant information about how to decode the ModR/M byte.
- * Based on information in the IA-32 Intel® Architecture
- * Software Developer's Manual Volume 2: Instruction Set Reference.
- */
-
-#include "mini_disassembler.h"
-#include "mini_disassembler_types.h"
-
-namespace sidestep {
-
-const ModrmEntry MiniDisassembler::s_ia16_modrm_map_[] = {
-// mod == 00
-  /* r/m == 000 */ { false, false, OS_ZERO },
-  /* r/m == 001 */ { false, false, OS_ZERO },
-  /* r/m == 010 */ { false, false, OS_ZERO },
-  /* r/m == 011 */ { false, false, OS_ZERO },
-  /* r/m == 100 */ { false, false, OS_ZERO },
-  /* r/m == 101 */ { false, false, OS_ZERO },
-  /* r/m == 110 */ { true, false, OS_WORD },
-  /* r/m == 111 */ { false, false, OS_ZERO }, 
-// mod == 01
-  /* r/m == 000 */ { true, false, OS_BYTE },
-  /* r/m == 001 */ { true, false, OS_BYTE },
-  /* r/m == 010 */ { true, false, OS_BYTE },
-  /* r/m == 011 */ { true, false, OS_BYTE },
-  /* r/m == 100 */ { true, false, OS_BYTE },
-  /* r/m == 101 */ { true, false, OS_BYTE },
-  /* r/m == 110 */ { true, false, OS_BYTE },
-  /* r/m == 111 */ { true, false, OS_BYTE }, 
-// mod == 10
-  /* r/m == 000 */ { true, false, OS_WORD },
-  /* r/m == 001 */ { true, false, OS_WORD },
-  /* r/m == 010 */ { true, false, OS_WORD },
-  /* r/m == 011 */ { true, false, OS_WORD },
-  /* r/m == 100 */ { true, false, OS_WORD },
-  /* r/m == 101 */ { true, false, OS_WORD },
-  /* r/m == 110 */ { true, false, OS_WORD },
-  /* r/m == 111 */ { true, false, OS_WORD }, 
-// mod == 11
-  /* r/m == 000 */ { false, false, OS_ZERO },
-  /* r/m == 001 */ { false, false, OS_ZERO },
-  /* r/m == 010 */ { false, false, OS_ZERO },
-  /* r/m == 011 */ { false, false, OS_ZERO },
-  /* r/m == 100 */ { false, false, OS_ZERO },
-  /* r/m == 101 */ { false, false, OS_ZERO },
-  /* r/m == 110 */ { false, false, OS_ZERO },
-  /* r/m == 111 */ { false, false, OS_ZERO }
-};
-
-const ModrmEntry MiniDisassembler::s_ia32_modrm_map_[] = {
-// mod == 00
-  /* r/m == 000 */ { false, false, OS_ZERO },
-  /* r/m == 001 */ { false, false, OS_ZERO },
-  /* r/m == 010 */ { false, false, OS_ZERO },
-  /* r/m == 011 */ { false, false, OS_ZERO },
-  /* r/m == 100 */ { false, true, OS_ZERO },
-  /* r/m == 101 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 110 */ { false, false, OS_ZERO },
-  /* r/m == 111 */ { false, false, OS_ZERO }, 
-// mod == 01
-  /* r/m == 000 */ { true, false, OS_BYTE },
-  /* r/m == 001 */ { true, false, OS_BYTE },
-  /* r/m == 010 */ { true, false, OS_BYTE },
-  /* r/m == 011 */ { true, false, OS_BYTE },
-  /* r/m == 100 */ { true, true, OS_BYTE },
-  /* r/m == 101 */ { true, false, OS_BYTE },
-  /* r/m == 110 */ { true, false, OS_BYTE },
-  /* r/m == 111 */ { true, false, OS_BYTE }, 
-// mod == 10
-  /* r/m == 000 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 001 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 010 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 011 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 100 */ { true, true, OS_DOUBLE_WORD },
-  /* r/m == 101 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 110 */ { true, false, OS_DOUBLE_WORD },
-  /* r/m == 111 */ { true, false, OS_DOUBLE_WORD }, 
-// mod == 11
-  /* r/m == 000 */ { false, false, OS_ZERO },
-  /* r/m == 001 */ { false, false, OS_ZERO },
-  /* r/m == 010 */ { false, false, OS_ZERO },
-  /* r/m == 011 */ { false, false, OS_ZERO },
-  /* r/m == 100 */ { false, false, OS_ZERO },
-  /* r/m == 101 */ { false, false, OS_ZERO },
-  /* r/m == 110 */ { false, false, OS_ZERO },
-  /* r/m == 111 */ { false, false, OS_ZERO },
-};
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/vendor/src/windows/ia32_opcode_map.cc b/third_party/tcmalloc/vendor/src/windows/ia32_opcode_map.cc
deleted file mode 100644
index e14279c..0000000
--- a/third_party/tcmalloc/vendor/src/windows/ia32_opcode_map.cc
+++ /dev/null
@@ -1,1219 +0,0 @@
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Opcode decoding maps.  Based on the IA-32 Intel® Architecture
- * Software Developer's Manual Volume 2: Instruction Set Reference.  Idea
- * for how to lay out the tables in memory taken from the implementation
- * in the Bastard disassembly environment.
- */
-
-#include "mini_disassembler.h"
-
-namespace sidestep {
-
-/*
-* This is the first table to be searched; the first field of each
-* Opcode in the table is either 0 to indicate you're in the
-* right table, or an index to the correct table, in the global
-* map g_pentiumOpcodeMap
-*/
-const Opcode s_first_opcode_byte[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF */ { 1, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x10 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x11 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x12 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x13 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x14 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x15 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x16 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x17 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x18 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x19 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1E */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1F */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x20 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x21 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x22 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x23 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x24 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x25 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x26 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x27 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "daa", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x28 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x29 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "das", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x30 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x31 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x32 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x33 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x34 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x35 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x36 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x37 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "aaa", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x38 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x39 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "aas", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#ifdef _M_X64
-  /* REX Prefixes in 64-bit mode. */
-  /* 0x40 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x41 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x42 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x43 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x44 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x45 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x46 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x47 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x48 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x49 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4A */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4B */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4C */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4D */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4F */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#else
-  /* 0x40 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x41 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x42 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x43 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x44 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x45 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x46 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x47 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x48 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x49 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#endif
-  /* 0x50 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x51 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x52 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x53 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x54 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x55 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x56 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x57 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x58 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x59 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x60 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "pushad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x61 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "popad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x62 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_A, AM_NOT_USED, "bound", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x63 */ { 0, IT_GENERIC, AM_E | OT_W, AM_G | OT_W, AM_NOT_USED, "arpl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x64 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x65 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x66 */ { 0, IT_PREFIX_OPERAND, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x67 */ { 0, IT_PREFIX_ADDRESS, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x68 */ { 0, IT_GENERIC, AM_I | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x69 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I | OT_V, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6A */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I |  OT_B, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6C */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "insb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6D */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "insd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6E */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X | OT_B, AM_NOT_USED, "outsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X | OT_V, AM_NOT_USED, "outsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x70 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x71 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x72 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x73 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x74 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x75 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x76 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x77 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "ja", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x78 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "js", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x79 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7A */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7B */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7C */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7D */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7E */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7F */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x80 */ { 2, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x81 */ { 3, IT_REFERENCE, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x82 */ { 4, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x83 */ { 5, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x84 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x85 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x86 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x87 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x88 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x89 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8C */ { 0, IT_GENERIC, AM_E | OT_W, AM_S | OT_W, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8D */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, "lea", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8E */ { 0, IT_GENERIC, AM_S | OT_W, AM_E | OT_W, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8F */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x90 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "nop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x91 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x92 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x93 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x94 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x95 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x96 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x97 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x98 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cwde", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x99 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cdq", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9A */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, "callf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9B */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wait", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "pushfd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "popfd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9E */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sahf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lahf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_O | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_O | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA2 */ { 0, IT_GENERIC, AM_O | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA3 */ { 0, IT_GENERIC, AM_O | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA4 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, "movsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA5 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, "movsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA6 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, "cmpsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA7 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, "cmpsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAA */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "stosb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAB */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "stosd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X| OT_B, AM_NOT_USED, "lodsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X| OT_V, AM_NOT_USED, "lodsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAE */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_Y | OT_B, AM_NOT_USED, "scasb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_Y | OT_V, AM_NOT_USED, "scasd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB1 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB2 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB3 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#ifdef _M_X64
-  /* 0xB8 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBA */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBB */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBC */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBE */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V | IOS_64, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#else
-  /* 0xB8 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBA */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBB */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBC */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBE */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-#endif
-  /* 0xC0 */ { 6, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC1 */ { 7, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC2 */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, "ret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC3 */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC4 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, "les", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, "lds", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC8 */ { 0, IT_GENERIC, AM_I | OT_W, AM_I | OT_B, AM_NOT_USED, "enter", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "leave", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCA */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, "retf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCB */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "retf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "int3", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCD */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "int", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCE */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "into", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCF */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "iret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD0 */ { 8, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD1 */ { 9, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD2 */ { 10, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD3 */ { 11, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD4 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "aam", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD5 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "aad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "xlat", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  
-  // The following 8 lines would be references to the FPU tables, but we currently
-  // do not support the FPU instructions in this disassembler.
-  
-  /* 0xD8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDA */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDB */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDC */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDD */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDE */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xDF */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  
-  
-  /* 0xE0 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loopnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE1 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loopz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE2 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE3 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jcxz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE6 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE7 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE8 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE9 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEA */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEB */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_REGISTER | OT_W, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xED */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_W, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xEF */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_V, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF0 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lock:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF2 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "repne:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF3 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rep:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF4 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "hlt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cmc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF6 */ { 12, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF7 */ { 13, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "stc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cli", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFB */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFD */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "std", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFE */ { 14, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xFF */ { 15, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f[] = {
-  /* 0x0 */ { 16, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 17, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "lar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "lsl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "invd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wbinvd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ud2", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xE */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x10 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "movups", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "movsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "movss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "movupd" } },
-  /* 0x11 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movups", true,
-    /* F2h */ { 0, IT_GENERIC, AM_W | OT_SD, AM_V | OT_SD, AM_NOT_USED, "movsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_W | OT_SS, AM_V | OT_SS, AM_NOT_USED, "movss" },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movupd" } },
-  /* 0x12 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhlps" },  // only one of ...
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhlps" },  // ...these two is correct, Intel doesn't specify which
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_S, AM_NOT_USED, "movlpd" } },
-  /* 0x13 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movlps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movlpd" } },
-  /* 0x14 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, "unpcklps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, "unpcklpd" } },
-  /* 0x15 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, "unpckhps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, "unpckhpd" } },
-  /* 0x16 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movhps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlhps" },  // only one of...
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlhps" },  // ...these two is correct, Intel doesn't specify which
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movhpd" } },
-  /* 0x17 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhpd" } },
-  /* 0x18 */ { 18, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x19 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1C */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x20 */ { 0, IT_GENERIC, AM_R | OT_D, AM_C | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x21 */ { 0, IT_GENERIC, AM_R | OT_D, AM_D | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x22 */ { 0, IT_GENERIC, AM_C | OT_D, AM_R | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x23 */ { 0, IT_GENERIC, AM_D | OT_D, AM_R | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x24 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x25 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x26 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x27 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x28 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "movaps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "movapd" } },
-  /* 0x29 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movaps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movapd" } },
-  /* 0x2A */ { 0, IT_GENERIC, AM_V | OT_PS, AM_Q | OT_Q, AM_NOT_USED, "cvtpi2ps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_E | OT_D, AM_NOT_USED, "cvtsi2sd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_E | OT_D, AM_NOT_USED, "cvtsi2ss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_Q | OT_DQ, AM_NOT_USED, "cvtpi2pd" } },
-  /* 0x2B */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movntps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movntpd" } },
-  /* 0x2C */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, "cvttps2pi", true,
-    /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, "cvttsd2si" },
-    /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, "cvttss2si" },
-    /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvttpd2pi" } },
-  /* 0x2D */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, "cvtps2pi", true,
-    /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, "cvtsd2si" },
-    /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, "cvtss2si" },
-    /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvtpd2pi" } },
-  /* 0x2E */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "ucomiss", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "ucomisd" } },
-  /* 0x2F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_SS, AM_NOT_USED, "comiss", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "comisd" } },
-  /* 0x30 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wrmsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x31 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdtsc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x32 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdmsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x33 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdpmc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x34 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sysenter", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x35 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sysexit", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x36 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x37 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x38 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x39 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "movnti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x40 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x41 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x42 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x43 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x44 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x45 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x46 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x47 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmova", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x48 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x49 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4A */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4D */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4E */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4F */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x50 */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PS, AM_NOT_USED, "movmskps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PD, AM_NOT_USED, "movmskpd" } },
-  /* 0x51 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "sqrtps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "sqrtsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "sqrtss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "sqrtpd" } },
-  /* 0x52 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "rsqrtps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "rsqrtss" },
-    /* 66h */ { 0 } },
-  /* 0x53 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "rcpps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "rcpss" },
-    /* 66h */ { 0 } },
-  /* 0x54 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "andps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "andpd" } },
-  /* 0x55 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "andnps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "andnpd" } },
-  /* 0x56 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "orps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "orpd" } },
-  /* 0x57 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "xorps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "xorpd" } },
-  /* 0x58 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "addps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "addsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "addss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "addpd" } },
-  /* 0x59 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "mulps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "mulsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "mulss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "mulpd" } },
-  /* 0x5A */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PS, AM_NOT_USED, "cvtps2pd", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "cvtsd2ss" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "cvtss2sd" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PD, AM_NOT_USED, "cvtpd2ps" } },
-  /* 0x5B */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_DQ, AM_NOT_USED, "cvtdq2ps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, "cvttps2dq" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, "cvtps2dq" } },
-  /* 0x5C */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "subps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "subsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "subss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "subpd" } },
-  /* 0x5D */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "minps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "minsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "minss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "minpd" } },
-  /* 0x5E */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "divps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "divsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "divss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "divpd" } },
-  /* 0x5F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "maxps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "maxsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "maxss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "maxpd" } },
-  /* 0x60 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpcklbw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklbw" } },
-  /* 0x61 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpcklwd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklwd" } },
-  /* 0x62 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckldq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpckldq" } },
-  /* 0x63 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packsswb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "packsswb" } },
-  /* 0x64 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtb" } },
-  /* 0x65 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtw" } },
-  /* 0x66 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtd" } },
-  /* 0x67 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packuswb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "packuswb" } },
-  /* 0x68 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhbw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhbw" } },
-  /* 0x69 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhwd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhwd" } },
-  /* 0x6A */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhdq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhdq" } },
-  /* 0x6B */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packssdw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "packssdw" } },
-  /* 0x6C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklqdq" } },
-  /* 0x6D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklqdq" } },
-  /* 0x6E */ { 0, IT_GENERIC, AM_P | OT_D, AM_E | OT_D, AM_NOT_USED, "movd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_NOT_USED, "movd" } },
-  /* 0x6F */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "movq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "movdqu" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "movdqa" } },
-  /* 0x70 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_I |  OT_B, "pshuf", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshuflw" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshufhw" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshufd" } },
-  /* 0x71 */ { 19, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x72 */ { 20, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x73 */ { 21, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x74 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqb" } },
-  /* 0x75 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqw" } },
-  /* 0x76 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqd" } },
-  /* 0x77 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "emms", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  
-  // The following six opcodes are escapes into the MMX stuff, which this disassembler does not support.
-  /* 0x78 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x79 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7A */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7B */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7C */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7D */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  
-  /* 0x7E */ { 0, IT_GENERIC, AM_E | OT_D, AM_P | OT_D, AM_NOT_USED, "movd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movq" },
-    /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_DQ, AM_NOT_USED, "movd" } },
-  /* 0x7F */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_P | OT_Q, AM_NOT_USED, "movq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movdqu" },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movdqa" } },
-  /* 0x80 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x81 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x82 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x83 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x84 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x85 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x86 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x87 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "ja", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x88 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "js", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x89 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8A */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8B */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8C */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8D */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8E */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x8F */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x90 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "seto", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x91 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x92 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x93 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x94 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x95 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x96 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x97 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "seta", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x98 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "sets", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x99 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9A */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9B */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9C */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9D */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9E */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x9F */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cpuid", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "bt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, "shld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, "shld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA6 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA7 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rsm", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "bts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAC */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, "shrd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAD */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, "shrd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAE */ { 22, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xAF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "cmpxchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "cmpxchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB2 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lss", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "btr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB4 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lfs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB5 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lgs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB6 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, "movzx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB7 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "movzx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xB9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ud1", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBA */ { 23, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "btc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBC */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "bsf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBD */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "bsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBE */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, "movsx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xBF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "movsx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xadd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "xadd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC2 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, "cmpps", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_I | OT_B, "cmpsd" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W  | OT_SS, AM_I | OT_B, "cmpss" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, "cmppd" } },
-  /* 0xC3 */ { 0, IT_GENERIC, AM_E | OT_D, AM_G | OT_D, AM_NOT_USED, "movnti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_E | OT_D, AM_I | OT_B, "pinsrw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_I | OT_B, "pinsrw" } },
-  /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_I | OT_B, "pextrw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_I | OT_B, "pextrw" } },
-  /* 0xC6 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, "shufps", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, "shufpd" } },
-  /* 0xC7 */ { 24, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC8 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xC9 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCA */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCB */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCC */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCD */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCE */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xCF */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xD1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrlw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrlw" } },
-  /* 0xD2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrld", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrld" } },
-  /* 0xD3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrlq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrlq" } },
-  /* 0xD4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddq" } },
-  /* 0xD5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmullw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmullw" } },
-  /* 0xD6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "unused without prefix", true,
-    /* F2h */ { 0, IT_GENERIC, AM_P | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movdq2q" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_Q | OT_Q, AM_NOT_USED, "movq2dq" },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movq" } },
-  /* 0xD7 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_NOT_USED, "pmovmskb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_NOT_USED, "pmovmskb" } },
-  /* 0xD8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubusb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubusb" } },
-  /* 0xD9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubusw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubusw" } },
-  /* 0xDA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pminub", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pminub" } },
-  /* 0xDB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pand", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pand" } },
-  /* 0xDC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddusb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddusb" } },
-  /* 0xDD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddusw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddusw" } },
-  /* 0xDE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaxub", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaxub" } },
-  /* 0xDF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pandn", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pandn" } },
-  /* 0xE0 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pavgb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pavgb" } },
-  /* 0xE1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psraw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrqw" } },
-  /* 0xE2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrad", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrad" } },
-  /* 0xE3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pavgw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pavgw" } },
-  /* 0xE4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmulhuw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmulhuw" } },
-  /* 0xE5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmulhuw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmulhw" } },
-  /* 0xE6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true,
-    /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvtpd2dq" },
-    /* F3h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_DQ, AM_NOT_USED, "cvtdq2pd" },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvttpd2dq" } },
-  /* 0xE7 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movntq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movntdq" } },
-  /* 0xE8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubsb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubsb" } },
-  /* 0xE9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubsw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubsw" } },
-  /* 0xEA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pminsw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pminsw" } },
-  /* 0xEB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "por", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "por" } },
-  /* 0xEC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddsb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddsb" } },
-  /* 0xED */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddsw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddsw" } },
-  /* 0xEE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaxsw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaxsw" } },
-  /* 0xEF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pxor", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pxor" } },
-  /* 0xF0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0xF1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psllw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psllw" } },
-  /* 0xF2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pslld", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pslld" } },
-  /* 0xF3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psllq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psllq" } },
-  /* 0xF4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmuludq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmuludq" } },
-  /* 0xF5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaddwd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaddwd" } },
-  /* 0xF6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psadbw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psadbw" } },
-  /* 0xF7 */ { 0, IT_GENERIC, AM_P | OT_PI, AM_Q | OT_PI, AM_NOT_USED, "maskmovq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "maskmovdqu" } },
-  /* 0xF8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubb" } },
-  /* 0xF9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubw" } },
-  /* 0xFA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubd" } },
-  /* 0xFB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubq" } },
-  /* 0xFC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddb", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddb" } },
-  /* 0xFD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddw" } },
-  /* 0xFE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddd", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddd" } },
-  /* 0xFF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f00[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "sldt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "str", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "lldt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "ltr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "verr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "verw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f01[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "sgdt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "sidt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "lgdt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "lidt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "smsw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "lmsw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_M | OT_B, AM_NOT_USED, AM_NOT_USED, "invlpg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f18[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f71[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrlw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrlw" } },
-  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psraw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psraw" } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psllw", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psllw" } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f72[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrld", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrld" } },
-  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrad", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrad" } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "pslld", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslld" } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f73[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrlq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrlq" } },
-  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psllq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psllq" } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslldq", true,
-    /* F2h */ { 0 },
-    /* F3h */ { 0 },
-    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslldq" } },
-};
-
-const Opcode s_opcode_byte_after_0fae[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "fxsave", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "fxrstor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ldmxcsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "stmxcsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "mfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clflush/sfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-};
-
-const Opcode s_opcode_byte_after_0fba[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "bt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "bts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "btr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "btc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0fc7[] = {
-  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_Q, AM_NOT_USED, AM_NOT_USED, "cmpxch8b", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_80[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_81[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_82[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_83[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_c0[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_c1[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d0[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d1[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d2[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d3[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_f6[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "not", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "neg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, "mul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, "div", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, "idiv", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_f7[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "not", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "neg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "mul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "div", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "idiv", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_fe[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_ff[] = {
-  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x2 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x3 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x4 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x5 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-/*
-* A table of all the other tables, containing some extra information, e.g.
-* how to mask out the byte we're looking at.
-*/
-const OpcodeTable MiniDisassembler::s_ia32_opcode_map_[]={
-  // One-byte opcodes and jumps to larger
-  /*  0 */ {s_first_opcode_byte, 0, 0xff, 0, 0xff},
-  // Two-byte opcodes (second byte)
-  /*  1 */ {s_opcode_byte_after_0f, 0, 0xff, 0, 0xff},
-  // Start of tables for opcodes using ModR/M bits as extension
-  /*  2 */ {s_opcode_byte_after_80, 3, 0x07, 0, 0x07},
-  /*  3 */ {s_opcode_byte_after_81, 3, 0x07, 0, 0x07}, 
-  /*  4 */ {s_opcode_byte_after_82, 3, 0x07, 0, 0x07}, 
-  /*  5 */ {s_opcode_byte_after_83, 3, 0x07, 0, 0x07}, 
-  /*  6 */ {s_opcode_byte_after_c0, 3, 0x07, 0, 0x07}, 
-  /*  7 */ {s_opcode_byte_after_c1, 3, 0x07, 0, 0x07}, 
-  /*  8 */ {s_opcode_byte_after_d0, 3, 0x07, 0, 0x07}, 
-  /*  9 */ {s_opcode_byte_after_d1, 3, 0x07, 0, 0x07}, 
-  /* 10 */ {s_opcode_byte_after_d2, 3, 0x07, 0, 0x07}, 
-  /* 11 */ {s_opcode_byte_after_d3, 3, 0x07, 0, 0x07}, 
-  /* 12 */ {s_opcode_byte_after_f6, 3, 0x07, 0, 0x07}, 
-  /* 13 */ {s_opcode_byte_after_f7, 3, 0x07, 0, 0x07}, 
-  /* 14 */ {s_opcode_byte_after_fe, 3, 0x07, 0, 0x01}, 
-  /* 15 */ {s_opcode_byte_after_ff, 3, 0x07, 0, 0x07}, 
-  /* 16 */ {s_opcode_byte_after_0f00, 3, 0x07, 0, 0x07}, 
-  /* 17 */ {s_opcode_byte_after_0f01, 3, 0x07, 0, 0x07}, 
-  /* 18 */ {s_opcode_byte_after_0f18, 3, 0x07, 0, 0x07}, 
-  /* 19 */ {s_opcode_byte_after_0f71, 3, 0x07, 0, 0x07}, 
-  /* 20 */ {s_opcode_byte_after_0f72, 3, 0x07, 0, 0x07}, 
-  /* 21 */ {s_opcode_byte_after_0f73, 3, 0x07, 0, 0x07}, 
-  /* 22 */ {s_opcode_byte_after_0fae, 3, 0x07, 0, 0x07}, 
-  /* 23 */ {s_opcode_byte_after_0fba, 3, 0x07, 0, 0x07}, 
-  /* 24 */ {s_opcode_byte_after_0fc7, 3, 0x07, 0, 0x01}
-};
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/vendor/src/windows/mingw.h b/third_party/tcmalloc/vendor/src/windows/mingw.h
deleted file mode 100644
index c91a313..0000000
--- a/third_party/tcmalloc/vendor/src/windows/mingw.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Craig Silverstein
- *
- * MinGW is an interesting mix of unix and windows.  We use a normal
- * configure script, but still need the windows port.h to define some
- * stuff that MinGW doesn't support, like pthreads.
- */
-
-#ifndef GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_
-#define GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_
-
-#ifdef __MINGW32__
-
-// Older version of the mingw msvcrt don't define _aligned_malloc
-#if __MSVCRT_VERSION__ < 0x0700
-# define PERFTOOLS_NO_ALIGNED_MALLOC 1
-#endif
-
-// This must be defined before the windows.h is included.  We need at
-// least 0x0400 for mutex.h to have access to TryLock, and at least
-// 0x0501 for patch_functions.cc to have access to GetModuleHandleEx.
-// (This latter is an optimization we could take out if need be.)
-#ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-#endif
-
-#define HAVE_SNPRINTF 1
-
-// Some mingw distributions have a pthreads wrapper, but it doesn't
-// work as well as native windows spinlocks (at least for us).  So
-// pretend the pthreads wrapper doesn't exist, even when it does.
-#ifndef HAVE_PTHREAD_DESPITE_ASKING_FOR
-#undef HAVE_PTHREAD
-#endif
-
-#undef HAVE_FORK
-
-#define HAVE_PID_T
-
-#include "windows/port.h"
-
-#endif  /* __MINGW32__ */
-
-#endif  /* GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_ */
diff --git a/third_party/tcmalloc/vendor/src/windows/mini_disassembler.cc b/third_party/tcmalloc/vendor/src/windows/mini_disassembler.cc
deleted file mode 100644
index 0c620047..0000000
--- a/third_party/tcmalloc/vendor/src/windows/mini_disassembler.cc
+++ /dev/null
@@ -1,432 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Implementation of MiniDisassembler.
- */
-
-#include "mini_disassembler.h"
-
-namespace sidestep {
-
-MiniDisassembler::MiniDisassembler(bool operand_default_is_32_bits,
-                                   bool address_default_is_32_bits)
-    : operand_default_is_32_bits_(operand_default_is_32_bits),
-      address_default_is_32_bits_(address_default_is_32_bits) {
-  Initialize();
-}
-
-MiniDisassembler::MiniDisassembler()
-    : operand_default_is_32_bits_(true),
-      address_default_is_32_bits_(true) {
-  Initialize();
-}
-
-InstructionType MiniDisassembler::Disassemble(
-    unsigned char* start_byte,
-    unsigned int& instruction_bytes) {
-  // Clean up any state from previous invocations.
-  Initialize();
-
-  // Start by processing any prefixes.
-  unsigned char* current_byte = start_byte;
-  unsigned int size = 0;
-  InstructionType instruction_type = ProcessPrefixes(current_byte, size);
-
-  if (IT_UNKNOWN == instruction_type)
-    return instruction_type;
-
-  current_byte += size;
-  size = 0;
-
-  // Invariant: We have stripped all prefixes, and the operand_is_32_bits_
-  // and address_is_32_bits_ flags are correctly set.
-
-  instruction_type = ProcessOpcode(current_byte, 0, size);
-
-  // Check for error processing instruction
-  if ((IT_UNKNOWN == instruction_type_) || (IT_UNUSED == instruction_type_)) {
-    return IT_UNKNOWN;
-  }
-
-  current_byte += size;
-
-  // Invariant: operand_bytes_ indicates the total size of operands
-  // specified by the opcode and/or ModR/M byte and/or SIB byte.
-  // pCurrentByte points to the first byte after the ModR/M byte, or after
-  // the SIB byte if it is present (i.e. the first byte of any operands
-  // encoded in the instruction).
-
-  // We get the total length of any prefixes, the opcode, and the ModR/M and
-  // SIB bytes if present, by taking the difference of the original starting
-  // address and the current byte (which points to the first byte of the
-  // operands if present, or to the first byte of the next instruction if
-  // they are not).  Adding the count of bytes in the operands encoded in
-  // the instruction gives us the full length of the instruction in bytes.
-  instruction_bytes += operand_bytes_ + (current_byte - start_byte);
-
-  // Return the instruction type, which was set by ProcessOpcode().
-  return instruction_type_;
-}
-
-void MiniDisassembler::Initialize() {
-  operand_is_32_bits_ = operand_default_is_32_bits_;
-  address_is_32_bits_ = address_default_is_32_bits_;
-#ifdef _M_X64
-  operand_default_support_64_bits_ = true;
-#else
-  operand_default_support_64_bits_ = false;
-#endif
-  operand_is_64_bits_ = false;
-  operand_bytes_ = 0;
-  have_modrm_ = false;
-  should_decode_modrm_ = false;
-  instruction_type_ = IT_UNKNOWN;
-  got_f2_prefix_ = false;
-  got_f3_prefix_ = false;
-  got_66_prefix_ = false;
-}
-
-InstructionType MiniDisassembler::ProcessPrefixes(unsigned char* start_byte,
-                                                  unsigned int& size) {
-  InstructionType instruction_type = IT_GENERIC;
-  const Opcode& opcode = s_ia32_opcode_map_[0].table_[*start_byte];
-
-  switch (opcode.type_) {
-    case IT_PREFIX_ADDRESS:
-      address_is_32_bits_ = !address_default_is_32_bits_;
-      goto nochangeoperand;
-    case IT_PREFIX_OPERAND:
-      operand_is_32_bits_ = !operand_default_is_32_bits_;
-      nochangeoperand:
-    case IT_PREFIX:
-
-      if (0xF2 == (*start_byte))
-        got_f2_prefix_ = true;
-      else if (0xF3 == (*start_byte))
-        got_f3_prefix_ = true;
-      else if (0x66 == (*start_byte))
-        got_66_prefix_ = true;
-      else if (operand_default_support_64_bits_ && (*start_byte) & 0x48)
-        operand_is_64_bits_ = true;
-
-      instruction_type = opcode.type_;
-      size ++;
-      // we got a prefix, so add one and check next byte
-      ProcessPrefixes(start_byte + 1, size);
-    default:
-      break;   // not a prefix byte
-  }
-
-  return instruction_type;
-}
-
-InstructionType MiniDisassembler::ProcessOpcode(unsigned char* start_byte,
-                                                unsigned int table_index,
-                                                unsigned int& size) {
-  const OpcodeTable& table = s_ia32_opcode_map_[table_index];   // Get our table
-  unsigned char current_byte = (*start_byte) >> table.shift_;
-  current_byte = current_byte & table.mask_;  // Mask out the bits we will use
-
-  // Check whether the byte we have is inside the table we have.
-  if (current_byte < table.min_lim_ || current_byte > table.max_lim_) {
-    instruction_type_ = IT_UNKNOWN;
-    return instruction_type_;
-  }
-
-  const Opcode& opcode = table.table_[current_byte];
-  if (IT_UNUSED == opcode.type_) {
-    // This instruction is not used by the IA-32 ISA, so we indicate
-    // this to the user.  Probably means that we were pointed to
-    // a byte in memory that was not the start of an instruction.
-    instruction_type_ = IT_UNUSED;
-    return instruction_type_;
-  } else if (IT_REFERENCE == opcode.type_) {
-    // We are looking at an opcode that has more bytes (or is continued
-    // in the ModR/M byte).  Recursively find the opcode definition in
-    // the table for the opcode's next byte.
-    size++;
-    ProcessOpcode(start_byte + 1, opcode.table_index_, size);
-    return instruction_type_;
-  }
-
-  const SpecificOpcode* specific_opcode = (SpecificOpcode*)&opcode;
-  if (opcode.is_prefix_dependent_) {
-    if (got_f2_prefix_ && opcode.opcode_if_f2_prefix_.mnemonic_ != 0) {
-      specific_opcode = &opcode.opcode_if_f2_prefix_;
-    } else if (got_f3_prefix_ && opcode.opcode_if_f3_prefix_.mnemonic_ != 0) {
-      specific_opcode = &opcode.opcode_if_f3_prefix_;
-    } else if (got_66_prefix_ && opcode.opcode_if_66_prefix_.mnemonic_ != 0) {
-      specific_opcode = &opcode.opcode_if_66_prefix_;
-    }
-  }
-
-  // Inv: The opcode type is known.
-  instruction_type_ = specific_opcode->type_;
-
-  // Let's process the operand types to see if we have any immediate
-  // operands, and/or a ModR/M byte.
-
-  ProcessOperand(specific_opcode->flag_dest_);
-  ProcessOperand(specific_opcode->flag_source_);
-  ProcessOperand(specific_opcode->flag_aux_);
-
-  // Inv: We have processed the opcode and incremented operand_bytes_
-  // by the number of bytes of any operands specified by the opcode
-  // that are stored in the instruction (not registers etc.).  Now
-  // we need to return the total number of bytes for the opcode and
-  // for the ModR/M or SIB bytes if they are present.
-
-  if (table.mask_ != 0xff) {
-    if (have_modrm_) {
-      // we're looking at a ModR/M byte so we're not going to
-      // count that into the opcode size
-      ProcessModrm(start_byte, size);
-      return IT_GENERIC;
-    } else {
-      // need to count the ModR/M byte even if it's just being
-      // used for opcode extension
-      size++;
-      return IT_GENERIC;
-    }
-  } else {
-    if (have_modrm_) {
-      // The ModR/M byte is the next byte.
-      size++;
-      ProcessModrm(start_byte + 1, size);
-      return IT_GENERIC;
-    } else {
-      size++;
-      return IT_GENERIC;
-    }
-  }
-}
-
-bool MiniDisassembler::ProcessOperand(int flag_operand) {
-  bool succeeded = true;
-  if (AM_NOT_USED == flag_operand)
-    return succeeded;
-
-  // Decide what to do based on the addressing mode.
-  switch (flag_operand & AM_MASK) {
-    // No ModR/M byte indicated by these addressing modes, and no
-    // additional (e.g. immediate) parameters.
-    case AM_A: // Direct address
-    case AM_F: // EFLAGS register
-    case AM_X: // Memory addressed by the DS:SI register pair
-    case AM_Y: // Memory addressed by the ES:DI register pair
-    case AM_IMPLICIT: // Parameter is implicit, occupies no space in
-                       // instruction
-      break;
-
-    // There is a ModR/M byte but it does not necessarily need
-    // to be decoded.
-    case AM_C: // reg field of ModR/M selects a control register
-    case AM_D: // reg field of ModR/M selects a debug register
-    case AM_G: // reg field of ModR/M selects a general register
-    case AM_P: // reg field of ModR/M selects an MMX register
-    case AM_R: // mod field of ModR/M may refer only to a general register
-    case AM_S: // reg field of ModR/M selects a segment register
-    case AM_T: // reg field of ModR/M selects a test register
-    case AM_V: // reg field of ModR/M selects a 128-bit XMM register
-      have_modrm_ = true;
-      break;
-
-    // In these addressing modes, there is a ModR/M byte and it needs to be
-    // decoded. No other (e.g. immediate) params than indicated in ModR/M.
-    case AM_E: // Operand is either a general-purpose register or memory,
-                 // specified by ModR/M byte
-    case AM_M: // ModR/M byte will refer only to memory
-    case AM_Q: // Operand is either an MMX register or memory (complex
-                 // evaluation), specified by ModR/M byte
-    case AM_W: // Operand is either a 128-bit XMM register or memory (complex
-                 // eval), specified by ModR/M byte
-      have_modrm_ = true;
-      should_decode_modrm_ = true;
-      break;
-
-    // These addressing modes specify an immediate or an offset value
-    // directly, so we need to look at the operand type to see how many
-    // bytes.
-    case AM_I: // Immediate data.
-    case AM_J: // Jump to offset.
-    case AM_O: // Operand is at offset.
-      switch (flag_operand & OT_MASK) {
-        case OT_B: // Byte regardless of operand-size attribute.
-          operand_bytes_ += OS_BYTE;
-          break;
-        case OT_C: // Byte or word, depending on operand-size attribute.
-          if (operand_is_32_bits_)
-            operand_bytes_ += OS_WORD;
-          else
-            operand_bytes_ += OS_BYTE;
-          break;
-        case OT_D: // Doubleword, regardless of operand-size attribute.
-          operand_bytes_ += OS_DOUBLE_WORD;
-          break;
-        case OT_DQ: // Double-quadword, regardless of operand-size attribute.
-          operand_bytes_ += OS_DOUBLE_QUAD_WORD;
-          break;
-        case OT_P: // 32-bit or 48-bit pointer, depending on operand-size
-                     // attribute.
-          if (operand_is_32_bits_)
-            operand_bytes_ += OS_48_BIT_POINTER;
-          else
-            operand_bytes_ += OS_32_BIT_POINTER;
-          break;
-        case OT_PS: // 128-bit packed single-precision floating-point data.
-          operand_bytes_ += OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING;
-          break;
-        case OT_Q: // Quadword, regardless of operand-size attribute.
-          operand_bytes_ += OS_QUAD_WORD;
-          break;
-        case OT_S: // 6-byte pseudo-descriptor.
-          operand_bytes_ += OS_PSEUDO_DESCRIPTOR;
-          break;
-        case OT_SD: // Scalar Double-Precision Floating-Point Value
-        case OT_PD: // Unaligned packed double-precision floating point value
-          operand_bytes_ += OS_DOUBLE_PRECISION_FLOATING;
-          break;
-        case OT_SS:
-          // Scalar element of a 128-bit packed single-precision
-          // floating data.
-          // We simply return enItUnknown since we don't have to support
-          // floating point
-          succeeded = false;
-          break;
-        case OT_V: // Word, doubleword or quadword, depending on operand-size 
-                   // attribute.
-          if (operand_is_64_bits_ && flag_operand & AM_I &&
-              flag_operand & IOS_64)
-            operand_bytes_ += OS_QUAD_WORD;
-          else if (operand_is_32_bits_)
-            operand_bytes_ += OS_DOUBLE_WORD;
-          else
-            operand_bytes_ += OS_WORD;
-          break;
-        case OT_W: // Word, regardless of operand-size attribute.
-          operand_bytes_ += OS_WORD;
-          break;
-
-        // Can safely ignore these.
-        case OT_A: // Two one-word operands in memory or two double-word
-                     // operands in memory
-        case OT_PI: // Quadword MMX technology register (e.g. mm0)
-        case OT_SI: // Doubleword integer register (e.g., eax)
-          break;
-
-        default:
-          break;
-      }
-      break;
-
-    default:
-      break;
-  }
-
-  return succeeded;
-}
-
-bool MiniDisassembler::ProcessModrm(unsigned char* start_byte,
-                                    unsigned int& size) {
-  // If we don't need to decode, we just return the size of the ModR/M
-  // byte (there is never a SIB byte in this case).
-  if (!should_decode_modrm_) {
-    size++;
-    return true;
-  }
-
-  // We never care about the reg field, only the combination of the mod
-  // and r/m fields, so let's start by packing those fields together into
-  // 5 bits.
-  unsigned char modrm = (*start_byte);
-  unsigned char mod = modrm & 0xC0; // mask out top two bits to get mod field
-  modrm = modrm & 0x07; // mask out bottom 3 bits to get r/m field
-  mod = mod >> 3; // shift the mod field to the right place
-  modrm = mod | modrm; // combine the r/m and mod fields as discussed
-  mod = mod >> 3; // shift the mod field to bits 2..0
-
-  // Invariant: modrm contains the mod field in bits 4..3 and the r/m field
-  // in bits 2..0, and mod contains the mod field in bits 2..0
-
-  const ModrmEntry* modrm_entry = 0;
-  if (address_is_32_bits_)
-    modrm_entry = &s_ia32_modrm_map_[modrm];
-  else
-    modrm_entry = &s_ia16_modrm_map_[modrm];
-
-  // Invariant: modrm_entry points to information that we need to decode
-  // the ModR/M byte.
-
-  // Add to the count of operand bytes, if the ModR/M byte indicates
-  // that some operands are encoded in the instruction.
-  if (modrm_entry->is_encoded_in_instruction_)
-    operand_bytes_ += modrm_entry->operand_size_;
-
-  // Process the SIB byte if necessary, and return the count
-  // of ModR/M and SIB bytes.
-  if (modrm_entry->use_sib_byte_) {
-    size++;
-    return ProcessSib(start_byte + 1, mod, size);
-  } else {
-    size++;
-    return true;
-  }
-}
-
-bool MiniDisassembler::ProcessSib(unsigned char* start_byte,
-                                  unsigned char mod,
-                                  unsigned int& size) {
-  // get the mod field from the 2..0 bits of the SIB byte
-  unsigned char sib_base = (*start_byte) & 0x07;
-  if (0x05 == sib_base) {
-    switch (mod) {
-    case 0x00: // mod == 00
-    case 0x02: // mod == 10
-      operand_bytes_ += OS_DOUBLE_WORD;
-      break;
-    case 0x01: // mod == 01
-      operand_bytes_ += OS_BYTE;
-      break;
-    case 0x03: // mod == 11
-      // According to the IA-32 docs, there does not seem to be a disp
-      // value for this value of mod
-    default:
-      break;
-    }
-  }
-
-  size++;
-  return true;
-}
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/vendor/src/windows/mini_disassembler.h b/third_party/tcmalloc/vendor/src/windows/mini_disassembler.h
deleted file mode 100644
index 93a522e5..0000000
--- a/third_party/tcmalloc/vendor/src/windows/mini_disassembler.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Definition of MiniDisassembler.
- */
-
-#ifndef GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_H_
-#define GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_H_
-
-#include "config.h"
-#include <windows.h>
-#include "mini_disassembler_types.h"
-
-// compatibility shim
-#include "base/logging.h"
-#define SIDESTEP_ASSERT(cond)  RAW_DCHECK(cond, #cond)
-#define SIDESTEP_LOG(msg)      RAW_VLOG(1, msg)
-
-namespace sidestep {
-
-// This small disassembler is very limited
-// in its functionality, and in fact does only the bare minimum required by the
-// preamble patching utility.  It may be useful for other purposes, however.
-//
-// The limitations include at least the following:
-//  -# No support for coprocessor opcodes, MMX, etc.
-//  -# No machine-readable identification of opcodes or decoding of
-//     assembly parameters. The name of the opcode (as a string) is given,
-//     however, to aid debugging.
-//
-// You may ask what this little disassembler actually does, then?  The answer is
-// that it does the following, which is exactly what the patching utility needs:
-//  -# Indicates if opcode is a jump (any kind) or a return (any kind)
-//     because this is important for the patching utility to determine if
-//     a function is too short or there are jumps too early in it for it
-//     to be preamble patched.
-//  -# The opcode length is always calculated, so that the patching utility
-//     can figure out where the next instruction starts, and whether it
-//     already has enough instructions to replace with the absolute jump
-//     to the patching code.
-//
-// The usage is quite simple; just create a MiniDisassembler and use its
-// Disassemble() method.
-//
-// If you would like to extend this disassembler, please refer to the
-// IA-32 Intel® Architecture Software Developer's Manual Volume 2:
-// Instruction Set Reference for information about operand decoding
-// etc.
-class PERFTOOLS_DLL_DECL MiniDisassembler {
- public:
-
-  // Creates a new instance and sets defaults.
-  //
-  // @param operand_default_32_bits If true, the default operand size is
-  // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.
-  // @param address_default_32_bits If true, the default address size is
-  // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.
-  MiniDisassembler(bool operand_default_32_bits,
-                   bool address_default_32_bits);
-
-  // Equivalent to MiniDisassembler(true, true);
-  MiniDisassembler();
-
-  // Attempts to disassemble a single instruction starting from the
-  // address in memory it is pointed to.
-  //
-  // @param start Address where disassembly should start.
-  // @param instruction_bytes Variable that will be <b>incremented</b> by
-  // the length in bytes of the instruction.
-  // @return enItJump, enItReturn or enItGeneric on success.  enItUnknown
-  // if unable to disassemble, enItUnused if this seems to be an unused
-  // opcode. In the last two (error) cases, cbInstruction will be set
-  // to 0xffffffff.
-  //
-  // @post This instance of the disassembler is ready to be used again,
-  // with unchanged defaults from creation time.
-  InstructionType Disassemble(unsigned char* start, unsigned int& instruction_bytes);
-
- private:
-
-  // Makes the disassembler ready for reuse.
-  void Initialize();
-
-  // Sets the flags for address and operand sizes.
-  // @return Number of prefix bytes.
-  InstructionType ProcessPrefixes(unsigned char* start, unsigned int& size);
-
-  // Sets the flag for whether we have ModR/M, and increments
-  // operand_bytes_ if any are specifies by the opcode directly.
-  // @return Number of opcode bytes.
-  InstructionType ProcessOpcode(unsigned char* start,
-                                unsigned int table,
-                                unsigned int& size);
-
-  // Checks the type of the supplied operand.  Increments
-  // operand_bytes_ if it directly indicates an immediate etc.
-  // operand.  Asserts have_modrm_ if the operand specifies
-  // a ModR/M byte.
-  bool ProcessOperand(int flag_operand);
-
-  // Increments operand_bytes_ by size specified by ModR/M and
-  // by SIB if present.
-  // @return 0 in case of error, 1 if there is just a ModR/M byte,
-  // 2 if there is a ModR/M byte and a SIB byte.
-  bool ProcessModrm(unsigned char* start, unsigned int& size);
-
-  // Processes the SIB byte that it is pointed to.
-  // @param start Pointer to the SIB byte.
-  // @param mod The mod field from the ModR/M byte.
-  // @return 1 to indicate success (indicates 1 SIB byte)
-  bool ProcessSib(unsigned char* start, unsigned char mod, unsigned int& size);
-
-  // The instruction type we have decoded from the opcode.
-  InstructionType instruction_type_;
-
-  // Counts the number of bytes that is occupied by operands in
-  // the current instruction (note: we don't care about how large
-  // operands stored in registers etc. are).
-  unsigned int operand_bytes_;
-
-  // True iff there is a ModR/M byte in this instruction.
-  bool have_modrm_;
-
-  // True iff we need to decode the ModR/M byte (sometimes it just
-  // points to a register, we can tell by the addressing mode).
-  bool should_decode_modrm_;
-
-  // Current operand size is 32 bits if true, 16 bits if false.
-  bool operand_is_32_bits_;
-
-  // Default operand size is 32 bits if true, 16 bits if false.
-  bool operand_default_is_32_bits_;
-
-  // Current address size is 32 bits if true, 16 bits if false.
-  bool address_is_32_bits_;
-
-  // Default address size is 32 bits if true, 16 bits if false.
-  bool address_default_is_32_bits_;
-
-  // Determines if 64 bit operands are supported (x64).
-  bool operand_default_support_64_bits_;
-
-  // Current operand size is 64 bits if true, 32 bits if false.
-  bool operand_is_64_bits_;
-
-  // Huge big opcode table based on the IA-32 manual, defined
-  // in Ia32OpcodeMap.cc
-  static const OpcodeTable s_ia32_opcode_map_[];
-
-  // Somewhat smaller table to help with decoding ModR/M bytes
-  // when 16-bit addressing mode is being used.  Defined in
-  // Ia32ModrmMap.cc
-  static const ModrmEntry s_ia16_modrm_map_[];
-
-  // Somewhat smaller table to help with decoding ModR/M bytes
-  // when 32-bit addressing mode is being used.  Defined in
-  // Ia32ModrmMap.cc
-  static const ModrmEntry s_ia32_modrm_map_[];
-
-  // Indicators of whether we got certain prefixes that certain
-  // silly Intel instructions depend on in nonstandard ways for
-  // their behaviors.
-  bool got_f2_prefix_, got_f3_prefix_, got_66_prefix_;
-};
-
-};  // namespace sidestep
-
-#endif  // GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_H_
diff --git a/third_party/tcmalloc/vendor/src/windows/mini_disassembler_types.h b/third_party/tcmalloc/vendor/src/windows/mini_disassembler_types.h
deleted file mode 100644
index aceecf4..0000000
--- a/third_party/tcmalloc/vendor/src/windows/mini_disassembler_types.h
+++ /dev/null
@@ -1,237 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- *
- * Several simple types used by the disassembler and some of the patching
- * mechanisms.
- */
-
-#ifndef GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
-#define GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
-
-namespace sidestep {
-
-// Categories of instructions that we care about
-enum InstructionType {
-  // This opcode is not used
-  IT_UNUSED,
-  // This disassembler does not recognize this opcode (error)
-  IT_UNKNOWN,
-  // This is not an instruction but a reference to another table
-  IT_REFERENCE,
-  // This byte is a prefix byte that we can ignore
-  IT_PREFIX,
-  // This is a prefix byte that switches to the nondefault address size
-  IT_PREFIX_ADDRESS,
-  // This is a prefix byte that switches to the nondefault operand size
-  IT_PREFIX_OPERAND,
-  // A jump or call instruction
-  IT_JUMP,
-  // A return instruction
-  IT_RETURN,
-  // Any other type of instruction (in this case we don't care what it is)
-  IT_GENERIC,
-};
-
-// Lists IA-32 operand sizes in multiples of 8 bits
-enum OperandSize {
-  OS_ZERO = 0,
-  OS_BYTE = 1,
-  OS_WORD = 2,
-  OS_DOUBLE_WORD = 4,
-  OS_QUAD_WORD = 8,
-  OS_DOUBLE_QUAD_WORD = 16,
-  OS_32_BIT_POINTER = 32/8,
-  OS_48_BIT_POINTER = 48/8,
-  OS_SINGLE_PRECISION_FLOATING = 32/8,
-  OS_DOUBLE_PRECISION_FLOATING = 64/8,
-  OS_DOUBLE_EXTENDED_PRECISION_FLOATING = 80/8,
-  OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING = 128/8,
-  OS_PSEUDO_DESCRIPTOR = 6
-};
-
-// Operand addressing methods from the IA-32 manual.  The enAmMask value
-// is a mask for the rest.  The other enumeration values are named for the
-// names given to the addressing methods in the manual, e.g. enAm_D is for
-// the D addressing method.
-//
-// The reason we use a full 4 bytes and a mask, is that we need to combine
-// these flags with the enOperandType to store the details
-// on the operand in a single integer.
-enum AddressingMethod {
-  AM_NOT_USED = 0,        // This operand is not used for this instruction
-  AM_MASK = 0x00FF0000,  // Mask for the rest of the values in this enumeration
-  AM_A = 0x00010000,    // A addressing type
-  AM_C = 0x00020000,    // C addressing type
-  AM_D = 0x00030000,    // D addressing type
-  AM_E = 0x00040000,    // E addressing type
-  AM_F = 0x00050000,    // F addressing type
-  AM_G = 0x00060000,    // G addressing type
-  AM_I = 0x00070000,    // I addressing type
-  AM_J = 0x00080000,    // J addressing type
-  AM_M = 0x00090000,    // M addressing type
-  AM_O = 0x000A0000,    // O addressing type
-  AM_P = 0x000B0000,    // P addressing type
-  AM_Q = 0x000C0000,    // Q addressing type
-  AM_R = 0x000D0000,    // R addressing type
-  AM_S = 0x000E0000,    // S addressing type
-  AM_T = 0x000F0000,    // T addressing type
-  AM_V = 0x00100000,    // V addressing type
-  AM_W = 0x00110000,    // W addressing type
-  AM_X = 0x00120000,    // X addressing type
-  AM_Y = 0x00130000,    // Y addressing type
-  AM_REGISTER = 0x00140000,  // Specific register is always used as this op
-  AM_IMPLICIT = 0x00150000,  // An implicit, fixed value is used
-};
-
-// Operand types from the IA-32 manual. The enOtMask value is
-// a mask for the rest. The rest of the values are named for the
-// names given to these operand types in the manual, e.g. enOt_ps
-// is for the ps operand type in the manual.
-//
-// The reason we use a full 4 bytes and a mask, is that we need
-// to combine these flags with the enAddressingMethod to store the details
-// on the operand in a single integer.
-enum OperandType {
-  OT_MASK = 0xFF000000,
-  OT_A = 0x01000000,
-  OT_B = 0x02000000,
-  OT_C = 0x03000000,
-  OT_D = 0x04000000,
-  OT_DQ = 0x05000000,
-  OT_P = 0x06000000,
-  OT_PI = 0x07000000,
-  OT_PS = 0x08000000,  // actually unsupported for (we don't know its size)
-  OT_Q = 0x09000000,
-  OT_S = 0x0A000000,
-  OT_SS = 0x0B000000,
-  OT_SI = 0x0C000000,
-  OT_V = 0x0D000000,
-  OT_W = 0x0E000000,
-  OT_SD = 0x0F000000,  // scalar double-precision floating-point value
-  OT_PD = 0x10000000,  // double-precision floating point
-  // dummy "operand type" for address mode M - which doesn't specify
-  // operand type
-  OT_ADDRESS_MODE_M = 0x80000000
-};
-
-// Flag that indicates if an immediate operand is 64-bits.
-//
-// The Intel 64 and IA-32 Architecture Software Developer's Manual currently
-// defines MOV as the only instruction supporting a 64-bit immediate operand.
-enum ImmediateOperandSize {
-  IOS_MASK = 0x0000F000,
-  IOS_DEFAULT = 0x0,
-  IOS_64 = 0x00001000
-};
-
-// Everything that's in an Opcode (see below) except the three
-// alternative opcode structs for different prefixes.
-struct SpecificOpcode {
-  // Index to continuation table, or 0 if this is the last
-  // byte in the opcode.
-  int table_index_;
-
-  // The opcode type
-  InstructionType type_;
-
-  // Description of the type of the dest, src and aux operands,
-  // put together from enOperandType, enAddressingMethod and 
-  // enImmediateOperandSize flags.
-  int flag_dest_;
-  int flag_source_;
-  int flag_aux_;
-
-  // We indicate the mnemonic for debugging purposes
-  const char* mnemonic_;
-};
-
-// The information we keep in our tables about each of the different
-// valid instructions recognized by the IA-32 architecture.
-struct Opcode {
-  // Index to continuation table, or 0 if this is the last
-  // byte in the opcode.
-  int table_index_;
-
-  // The opcode type
-  InstructionType type_;
-
-  // Description of the type of the dest, src and aux operands,
-  // put together from an enOperandType flag and an enAddressingMethod
-  // flag.
-  unsigned flag_dest_;
-  unsigned flag_source_;
-  unsigned flag_aux_;
-
-  // We indicate the mnemonic for debugging purposes
-  const char* mnemonic_;
-
-  // Alternative opcode info if certain prefixes are specified.
-  // In most cases, all of these are zeroed-out.  Only used if
-  // bPrefixDependent is true.
-  bool is_prefix_dependent_;
-  SpecificOpcode opcode_if_f2_prefix_;
-  SpecificOpcode opcode_if_f3_prefix_;
-  SpecificOpcode opcode_if_66_prefix_;
-};
-
-// Information about each table entry.
-struct OpcodeTable {
-  // Table of instruction entries
-  const Opcode* table_;
-  // How many bytes left to shift ModR/M byte <b>before</b> applying mask
-  unsigned char shift_;
-  // Mask to apply to byte being looked at before comparing to table
-  unsigned char mask_;
-  // Minimum/maximum indexes in table.
-  unsigned char min_lim_;
-  unsigned char max_lim_;
-};
-
-// Information about each entry in table used to decode ModR/M byte.
-struct ModrmEntry {
-  // Is the operand encoded as bytes in the instruction (rather than
-  // if it's e.g. a register in which case it's just encoded in the
-  // ModR/M byte)
-  bool is_encoded_in_instruction_;
-
-  // Is there a SIB byte?  In this case we always need to decode it.
-  bool use_sib_byte_;
-
-  // What is the size of the operand (only important if it's encoded
-  // in the instruction)?
-  OperandSize operand_size_;
-};
-
-};  // namespace sidestep
-
-#endif  // GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
diff --git a/third_party/tcmalloc/vendor/src/windows/nm-pdb.c b/third_party/tcmalloc/vendor/src/windows/nm-pdb.c
deleted file mode 100644
index 95a080d..0000000
--- a/third_party/tcmalloc/vendor/src/windows/nm-pdb.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* Copyright (c) 2008, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: David Vitek
- *
- * Dump function addresses using Microsoft debug symbols.  This works
- * on PDB files.  Note that this program will download symbols to
- * c:\websymbols without asking.
- */
-
-#define WIN32_LEAN_AND_MEAN
-#define _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_DEPRECATE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>   // for _strdup
-
-#include <windows.h>
-#include <dbghelp.h>
-
-// Unfortunately, there is no versioning info in dbghelp.h so I can
-// tell whether it has an old-style (circa VC7.1) IMAGEHLP_MODULE64
-// struct, with only a few fields, or a new-style (circa VC8)
-// IMAGEHLP_MODULE64, with lots of fields.  These fields are just used
-// for debugging, so it's fine to just assume the smaller struct, but
-// for most people, using a modern MSVC, the full struct is available.
-// If you are one of those people and would like this extra debugging
-// info, you can uncomment the line below.
-//#define VC8_OR_ABOVE
-
-#define SEARCH_CAP (1024*1024)
-#define WEBSYM "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols"
-
-typedef struct {
-  char *name;
-  ULONG64 addr;
-  ULONG flags;
-} SYM;
-
-typedef struct {
-  ULONG64 module_base;
-  SYM *syms;
-  DWORD syms_len;
-  DWORD syms_cap;
-} SYM_CONTEXT;
-
-static int sym_cmp(const void *_s1, const void *_s2) {
-  const SYM *s1 = (const SYM *)_s1;
-  const SYM *s2 = (const SYM *)_s2;
-
-  if (s1->addr < s2->addr)
-    return -1;
-  if (s1->addr > s2->addr)
-    return 1;
-  return 0;
-}
-
-static BOOL CALLBACK EnumSymProc(PSYMBOL_INFO symbol_info,
-                                 ULONG symbol_size,
-                                 PVOID user_context) {
-  SYM_CONTEXT *ctx = (SYM_CONTEXT*)user_context;
-  if (symbol_info->Address < ctx->module_base ||
-      (symbol_info->Flags & SYMFLAG_TLSREL)) {
-    return TRUE;
-  }
-  if (ctx->syms_len == ctx->syms_cap) {
-    if (!ctx->syms_cap)
-      ctx->syms_cap++;
-    ctx->syms_cap *= 2;
-    ctx->syms = realloc(ctx->syms, sizeof(ctx->syms[0]) * ctx->syms_cap);
-  }
-  ctx->syms[ctx->syms_len].name = _strdup(symbol_info->Name);
-  ctx->syms[ctx->syms_len].addr = symbol_info->Address;
-  ctx->syms[ctx->syms_len].flags = symbol_info->Flags;
-  ctx->syms_len++;
-  return TRUE;
-}
-
-static void MaybePrint(const char* var, const char* description) {
-  if (var[0])
-    printf("%s: %s\n", description, var);
-}
-
-static void PrintAvailability(BOOL var, const char *description) {
-  printf("%s: %s\n", description, (var ? "Available" : "Not available"));
-}
-
-static void ShowSymbolInfo(HANDLE process, ULONG64 module_base) {
-  /* Get module information. */
-  IMAGEHLP_MODULE64 module_info;
-  BOOL getmoduleinfo_rv;
-  printf("Load Address: %I64x\n", module_base);
-  memset(&module_info, 0, sizeof(module_info));
-  module_info.SizeOfStruct = sizeof(module_info);
-  getmoduleinfo_rv = SymGetModuleInfo64(process, module_base, &module_info);
-  if (!getmoduleinfo_rv)  {
-    printf("Error: SymGetModuleInfo64() failed. Error code: %u\n",
-           GetLastError());
-    return;
-  }
-  /* Display information about symbols, based on kind of symbol. */
-  switch (module_info.SymType)  {
-    case SymNone:
-      printf(("No symbols available for the module.\n"));
-      break;
-    case SymExport:
-      printf(("Loaded symbols: Exports\n"));
-      break;
-    case SymCoff:
-      printf(("Loaded symbols: COFF\n"));
-      break;
-    case SymCv:
-      printf(("Loaded symbols: CodeView\n"));
-      break;
-    case SymSym:
-      printf(("Loaded symbols: SYM\n"));
-      break;
-    case SymVirtual:
-      printf(("Loaded symbols: Virtual\n"));
-      break;
-    case SymPdb:
-      printf(("Loaded symbols: PDB\n"));
-      break;
-    case SymDia:
-      printf(("Loaded symbols: DIA\n"));
-      break;
-    case SymDeferred:
-      printf(("Loaded symbols: Deferred\n"));  /* not actually loaded */
-      break;
-    default:
-      printf(("Loaded symbols: Unknown format.\n"));
-      break;
-  }
-
-  MaybePrint("Image name", module_info.ImageName);
-  MaybePrint("Loaded image name", module_info.LoadedImageName);
-#ifdef VC8_OR_ABOVE   /* TODO(csilvers): figure out how to tell */
-  MaybePrint("PDB file name", module_info.LoadedPdbName);
-  if (module_info.PdbUnmatched || module_info.DbgUnmatched)  {
-    /* This can only happen if the debug information is contained in a
-     * separate file (.DBG or .PDB)
-     */
-    printf(("Warning: Unmatched symbols.\n"));
-  }
-#endif
-
-  /* Contents */
-#ifdef VC8_OR_ABOVE   /* TODO(csilvers): figure out how to tell */
-  PrintAvailability("Line numbers", module_info.LineNumbers);
-  PrintAvailability("Global symbols", module_info.GlobalSymbols);
-  PrintAvailability("Type information", module_info.TypeInfo);
-#endif
-}
-
-void usage() {
-  fprintf(stderr, "usage: nm-pdb [-C|--demangle] <module or filename>\n");
-}
-
-int main(int argc, char *argv[]) {
-  DWORD  error;
-  HANDLE process;
-  ULONG64 module_base;
-  SYM_CONTEXT ctx;
-  int i;
-  char* search;
-  char* filename = NULL;
-  int rv = 0;
-  /* We may add SYMOPT_UNDNAME if --demangle is specified: */
-  DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG;
-
-  for (i = 1; i < argc; i++) {
-    if (strcmp(argv[i], "--demangle") == 0 || strcmp(argv[i], "-C") == 0) {
-      symopts |= SYMOPT_UNDNAME;
-    } else if (strcmp(argv[i], "--help") == 0) {
-      usage();
-      exit(0);
-    } else {
-      break;
-    }
-  }
-  if (i != argc - 1) {
-    usage();
-    exit(1);
-  }
-  filename = argv[i];
-
-  process = GetCurrentProcess();
-
-  if (!SymInitialize(process, NULL, FALSE)) {
-    error = GetLastError();
-    fprintf(stderr, "SymInitialize returned error : %d\n", error);
-    return 1;
-  }
-
-  search = malloc(SEARCH_CAP);
-  if (SymGetSearchPath(process, search, SEARCH_CAP)) {
-    if (strlen(search) + sizeof(";" WEBSYM) > SEARCH_CAP) {
-      fprintf(stderr, "Search path too long\n");
-      SymCleanup(process);
-      return 1;
-    }
-    strcat(search, ";" WEBSYM);
-  } else {
-    error = GetLastError();
-    fprintf(stderr, "SymGetSearchPath returned error : %d\n", error);
-    rv = 1;                   /* An error, but not a fatal one */
-    strcpy(search, WEBSYM);   /* Use a default value */
-  }
-  if (!SymSetSearchPath(process, search)) {
-    error = GetLastError();
-    fprintf(stderr, "SymSetSearchPath returned error : %d\n", error);
-    rv = 1;                   /* An error, but not a fatal one */
- }
-
-  SymSetOptions(symopts);
-  module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0);
-  if (!module_base) {
-    /* SymLoadModuleEx failed */
-    error = GetLastError();
-    fprintf(stderr, "SymLoadModuleEx returned error : %d for %s\n",
-            error, filename);
-    SymCleanup(process);
-    return 1;
-  }
-
-  ShowSymbolInfo(process, module_base);
-
-  memset(&ctx, 0, sizeof(ctx));
-  ctx.module_base = module_base;
-  if (!SymEnumSymbols(process, module_base, NULL, EnumSymProc, &ctx)) {
-    error = GetLastError();
-    fprintf(stderr, "SymEnumSymbols returned error: %d\n", error);
-    rv = 1;
-  } else {
-    DWORD j;
-    qsort(ctx.syms, ctx.syms_len, sizeof(ctx.syms[0]), sym_cmp);
-    for (j = 0; j < ctx.syms_len; j++) {
-      printf("%016I64x X %s\n", ctx.syms[j].addr, ctx.syms[j].name);
-    }
-    /* In a perfect world, maybe we'd clean up ctx's memory? */
-  }
-  SymUnloadModule64(process, module_base);
-  SymCleanup(process);
-  return rv;
-}
diff --git a/third_party/tcmalloc/vendor/src/windows/override_functions.cc b/third_party/tcmalloc/vendor/src/windows/override_functions.cc
deleted file mode 100644
index f6f519a..0000000
--- a/third_party/tcmalloc/vendor/src/windows/override_functions.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Mike Belshe
-// 
-// To link tcmalloc into a EXE or DLL statically without using the patching
-// facility, we can take a stock libcmt and remove all the allocator functions.
-// When we relink the EXE/DLL with the modified libcmt and tcmalloc, a few
-// functions are missing.  This file contains the additional overrides which
-// are required in the VS2005 libcmt in order to link the modified libcmt.
-//
-// See also
-// http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b
-
-#include <config.h>
-
-#ifndef _WIN32
-# error You should only be including this file in a windows environment!
-#endif
-
-#ifndef WIN32_OVERRIDE_ALLOCATORS
-# error This file is intended for use when overriding allocators
-#endif
-
-#include "tcmalloc.cc"
-
-extern "C" {
-
-void* _malloc_base(size_t size) {
-  return malloc(size);
-}
-
-void _free_base(void* p) {
-  free(p);
-}
-
-void* _calloc_base(size_t n, size_t size) {
-  return calloc(n, size);
-}
-
-void* _recalloc(void* p, size_t n, size_t size) {
-  void* result = realloc(p, n * size);
-  memset(result, 0, n * size);
-  return result;
-}
-
-void* _calloc_impl(size_t n, size_t size) {
-  return calloc(n, size);
-}
-
-size_t _msize(void* p) {
-  return MallocExtension::instance()->GetAllocatedSize(p);
-}
-
-HANDLE __acrt_heap = nullptr;
-
-bool __acrt_initialize_heap() {
-  new TCMallocGuard();
-  return true;
-}
-
-bool __acrt_uninitialize_heap(bool) {
-  return true;
-}
-
-intptr_t _get_heap_handle() {
-  return 0;
-}
-
-HANDLE __acrt_getheap() {
-  return __acrt_heap;
-}
-
-// The CRT heap initialization stub.
-int _heap_init() {
-  // We intentionally leak this object.  It lasts for the process
-  // lifetime.  Trying to teardown at _heap_term() is so late that
-  // you can't do anything useful anyway.
-  new TCMallocGuard();
-  return 1;
-}
-
-// The CRT heap cleanup stub.
-void _heap_term() {
-}
-
-// We set this to 1 because part of the CRT uses a check of _crtheap != 0
-// to test whether the CRT has been initialized.  Once we've ripped out
-// the allocators from libcmt, we need to provide this definition so that
-// the rest of the CRT is still usable.
-void* _crtheap = reinterpret_cast<void*>(1);
-
-int _set_new_mode(int flag) {
-  return tc_set_new_mode(flag);
-}
-
-int _query_new_mode() {
-  return tc_query_new_mode();
-}
-
-}  // extern "C"
-
-#ifndef NDEBUG
-#undef malloc
-#undef free
-#undef calloc
-int _CrtDbgReport(int, const char*, int, const char*, const char*, ...) {
-  return 0;
-}
-
-int _CrtDbgReportW(int, const wchar_t*, int, const wchar_t*, const wchar_t*, ...) {
-  return 0;
-}
-
-int _CrtSetReportMode(int, int) {
-  return 0;
-}
-
-extern "C" void* _malloc_dbg(size_t size, int , const char*, int) {
-  return malloc(size);
-}
-
-extern "C" void _free_dbg(void* ptr, int) {
-  free(ptr);
-}
-
-extern "C" void* _calloc_dbg(size_t n, size_t size, int, const char*, int) {
-  return calloc(n, size);
-}
-#endif  // NDEBUG
diff --git a/third_party/tcmalloc/vendor/src/windows/patch_functions.cc b/third_party/tcmalloc/vendor/src/windows/patch_functions.cc
deleted file mode 100644
index 5417880..0000000
--- a/third_party/tcmalloc/vendor/src/windows/patch_functions.cc
+++ /dev/null
@@ -1,1081 +0,0 @@
-// Copyright (c) 2007, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-// Author: Craig Silverstein
-//
-// The main purpose of this file is to patch the libc allocation
-// routines (malloc and friends, but also _msize and other
-// windows-specific libc-style routines).  However, we also patch
-// windows routines to do accounting.  We do better at the former than
-// the latter.  Here are some comments from Paul Pluzhnikov about what
-// it might take to do a really good job patching windows routines to
-// keep track of memory usage:
-//
-// "You should intercept at least the following:
-//     HeapCreate HeapDestroy HeapAlloc HeapReAlloc HeapFree
-//     RtlCreateHeap RtlDestroyHeap RtlAllocateHeap RtlFreeHeap
-//     malloc calloc realloc free
-//     malloc_dbg calloc_dbg realloc_dbg free_dbg
-// Some of these call the other ones (but not always), sometimes
-// recursively (i.e. HeapCreate may call HeapAlloc on a different
-// heap, IIRC)."
-//
-// Since Paul didn't mention VirtualAllocEx, he may not have even been
-// considering all the mmap-like functions that windows has (or he may
-// just be ignoring it because he's seen we already patch it).  Of the
-// above, we do not patch the *_dbg functions, and of the windows
-// functions, we only patch HeapAlloc and HeapFree.
-//
-// The *_dbg functions come into play with /MDd, /MTd, and /MLd,
-// probably.  It may be ok to just turn off tcmalloc in those cases --
-// if the user wants the windows debug malloc, they probably don't
-// want tcmalloc!  We should also test with all of /MD, /MT, and /ML,
-// which we're not currently doing.
-
-// TODO(csilvers): try to do better here?  Paul does conclude:
-//                 "Keeping track of all of this was a nightmare."
-
-#ifndef _WIN32
-# error You should only be including windows/patch_functions.cc in a windows environment!
-#endif
-
-#include <config.h>
-
-#ifdef WIN32_OVERRIDE_ALLOCATORS
-#error This file is intended for patching allocators - use override_functions.cc instead.
-#endif
-
-// We use psapi.  Non-MSVC systems will have to link this in themselves.
-#ifdef _MSC_VER
-#pragma comment(lib, "Psapi.lib")
-#endif
-
-// Make sure we always use the 'old' names of the psapi functions.
-#ifndef PSAPI_VERSION
-#define PSAPI_VERSION 1
-#endif
-
-#include <windows.h>
-#include <stdio.h>
-#include <malloc.h>       // for _msize and _expand
-#include <psapi.h>        // for EnumProcessModules, GetModuleInformation, etc.
-#include <set>
-#include <map>
-#include <vector>
-#include <base/logging.h>
-#include "base/spinlock.h"
-#include "gperftools/malloc_hook.h"
-#include "malloc_hook-inl.h"
-#include "preamble_patcher.h"
-
-// The maximum number of modules we allow to be in one executable
-const int kMaxModules = 8182;
-
-// These are hard-coded, unfortunately. :-( They are also probably
-// compiler specific.  See get_mangled_names.cc, in this directory,
-// for instructions on how to update these names for your compiler.
-#ifdef _WIN64
-const char kMangledNew[] = "??2@YAPEAX_K@Z";
-const char kMangledNewArray[] = "??_U@YAPEAX_K@Z";
-const char kMangledDelete[] = "??3@YAXPEAX@Z";
-const char kMangledDeleteArray[] = "??_V@YAXPEAX@Z";
-const char kMangledNewNothrow[] = "??2@YAPEAX_KAEBUnothrow_t@std@@@Z";
-const char kMangledNewArrayNothrow[] = "??_U@YAPEAX_KAEBUnothrow_t@std@@@Z";
-const char kMangledDeleteNothrow[] = "??3@YAXPEAXAEBUnothrow_t@std@@@Z";
-const char kMangledDeleteArrayNothrow[] = "??_V@YAXPEAXAEBUnothrow_t@std@@@Z";
-#else
-const char kMangledNew[] = "??2@YAPAXI@Z";
-const char kMangledNewArray[] = "??_U@YAPAXI@Z";
-const char kMangledDelete[] = "??3@YAXPAX@Z";
-const char kMangledDeleteArray[] = "??_V@YAXPAX@Z";
-const char kMangledNewNothrow[] = "??2@YAPAXIABUnothrow_t@std@@@Z";
-const char kMangledNewArrayNothrow[] = "??_U@YAPAXIABUnothrow_t@std@@@Z";
-const char kMangledDeleteNothrow[] = "??3@YAXPAXABUnothrow_t@std@@@Z";
-const char kMangledDeleteArrayNothrow[] = "??_V@YAXPAXABUnothrow_t@std@@@Z";
-#endif
-
-// This is an unused but exported symbol that we can use to tell the
-// MSVC linker to bring in libtcmalloc, via the /INCLUDE linker flag.
-// Without this, the linker will likely decide that libtcmalloc.dll
-// doesn't add anything to the executable (since it does all its work
-// through patching, which the linker can't see), and ignore it
-// entirely.  (The name 'tcmalloc' is already reserved for a
-// namespace.  I'd rather export a variable named "_tcmalloc", but I
-// couldn't figure out how to get that to work.  This function exports
-// the symbol "__tcmalloc".)
-extern "C" PERFTOOLS_DLL_DECL void _tcmalloc();
-void _tcmalloc() { }
-
-// This is the version needed for windows x64, which has a different
-// decoration scheme which doesn't auto-add a leading underscore.
-extern "C" PERFTOOLS_DLL_DECL void __tcmalloc();
-void __tcmalloc() { }
-
-namespace {    // most everything here is in an unnamed namespace
-
-typedef void (*GenericFnPtr)();
-
-using sidestep::PreamblePatcher;
-
-struct ModuleEntryCopy;   // defined below
-
-// These functions are how we override the memory allocation
-// functions, just like tcmalloc.cc and malloc_hook.cc do.
-
-// This is information about the routines we're patching, for a given
-// module that implements libc memory routines.  A single executable
-// can have several libc implementations running about (in different
-// .dll's), and we need to patch/unpatch them all.  This defines
-// everything except the new functions we're patching in, which
-// are defined in LibcFunctions, below.
-class LibcInfo {
- public:
-  LibcInfo() {
-    memset(this, 0, sizeof(*this));  // easiest way to initialize the array
-  }
-
-  bool patched() const { return is_valid(); }
-  void set_is_valid(bool b) { is_valid_ = b; }
-  // According to http://msdn.microsoft.com/en-us/library/ms684229(VS.85).aspx:
-  // "The load address of a module (lpBaseOfDll) is the same as the HMODULE
-  // value."
-  HMODULE hmodule() const {
-    return reinterpret_cast<HMODULE>(const_cast<void*>(module_base_address_));
-  }
-
-  // Populates all the windows_fn_[] vars based on our module info.
-  // Returns false if windows_fn_ is all NULL's, because there's
-  // nothing to patch.  Also populates the rest of the module_entry
-  // info, such as the module's name.
-  bool PopulateWindowsFn(const ModuleEntryCopy& module_entry);
-
- protected:
-  void CopyFrom(const LibcInfo& that) {
-    if (this == &that)
-      return;
-    this->is_valid_ = that.is_valid_;
-    memcpy(this->windows_fn_, that.windows_fn_, sizeof(windows_fn_));
-    this->module_base_address_ = that.module_base_address_;
-    this->module_base_size_ = that.module_base_size_;
-  }
-
-  enum {
-    kMalloc, kFree, kRealloc, kCalloc,
-    kNew, kNewArray, kDelete, kDeleteArray,
-    kNewNothrow, kNewArrayNothrow, kDeleteNothrow, kDeleteArrayNothrow,
-    // These are windows-only functions from malloc.h
-    k_Msize, k_Expand,
-    // A MS CRT "internal" function, implemented using _calloc_impl
-    k_CallocCrt, kFreeBase,
-    kNumFunctions
-  };
-
-  // I'd like to put these together in a struct (perhaps in the
-  // subclass, so we can put in perftools_fn_ as well), but vc8 seems
-  // to have a bug where it doesn't initialize the struct properly if
-  // we try to take the address of a function that's not yet loaded
-  // from a dll, as is the common case for static_fn_.  So we need
-  // each to be in its own array. :-(
-  static const char* const function_name_[kNumFunctions];
-
-  // This function is only used when statically linking the binary.
-  // In that case, loading malloc/etc from the dll (via
-  // PatchOneModule) won't work, since there are no dlls.  Instead,
-  // you just want to be taking the address of malloc/etc directly.
-  // In the common, non-static-link case, these pointers will all be
-  // NULL, since this initializer runs before msvcrt.dll is loaded.
-  static const GenericFnPtr static_fn_[kNumFunctions];
-
-  // This is the address of the function we are going to patch
-  // (malloc, etc).  Other info about the function is in the
-  // patch-specific subclasses, below.
-  GenericFnPtr windows_fn_[kNumFunctions];
-
-  // This is set to true when this structure is initialized (because
-  // we're patching a new library) and set to false when it's
-  // uninitialized (because we've freed that library).
-  bool is_valid_;
-
-  const void *module_base_address_;
-  size_t module_base_size_;
-
- public:
-  // These shouldn't have to be public, since only subclasses of
-  // LibcInfo need it, but they do.  Maybe something to do with
-  // templates.  Shrug.  I hide them down here so users won't see
-  // them. :-)  (OK, I also need to define ctrgProcAddress late.)
-  bool is_valid() const { return is_valid_; }
-  GenericFnPtr windows_fn(int ifunction) const {
-    return windows_fn_[ifunction];
-  }
-  // These three are needed by ModuleEntryCopy.
-  static const int ctrgProcAddress = kNumFunctions;
-  static GenericFnPtr static_fn(int ifunction) {
-    return static_fn_[ifunction];
-  }
-  static const char* const function_name(int ifunction) {
-    return function_name_[ifunction];
-  }
-};
-
-// Template trickiness: logically, a LibcInfo would include
-// Windows_malloc_, origstub_malloc_, and Perftools_malloc_: for a
-// given module, these three go together.  And in fact,
-// Perftools_malloc_ may need to call origstub_malloc_, which means we
-// either need to change Perftools_malloc_ to take origstub_malloc_ as
-// an argument -- unfortunately impossible since it needs to keep the
-// same API as normal malloc -- or we need to write a different
-// version of Perftools_malloc_ for each LibcInfo instance we create.
-// We choose the second route, and use templates to implement it (we
-// could have also used macros).  So to get multiple versions
-// of the struct, we say "struct<1> var1; struct<2> var2;".  The price
-// we pay is some code duplication, and more annoying, each instance
-// of this var is a separate type.
-template<int> class LibcInfoWithPatchFunctions : public LibcInfo {
- public:
-  // me_info should have had PopulateWindowsFn() called on it, so the
-  // module_* vars and windows_fn_ are set up.
-  bool Patch(const LibcInfo& me_info);
-  void Unpatch();
-
- private:
-  // This holds the original function contents after we patch the function.
-  // This has to be defined static in the subclass, because the perftools_fns
-  // reference origstub_fn_.
-  static GenericFnPtr origstub_fn_[kNumFunctions];
-
-  // This is the function we want to patch in
-  static const GenericFnPtr perftools_fn_[kNumFunctions];
-
-  static void* Perftools_malloc(size_t size) __THROW;
-  static void Perftools_free(void* ptr) __THROW;
-  static void Perftools_free_base(void* ptr) __THROW;
-  static void* Perftools_realloc(void* ptr, size_t size) __THROW;
-  static void* Perftools_calloc(size_t nmemb, size_t size) __THROW;
-  static void* Perftools_new(size_t size);
-  static void* Perftools_newarray(size_t size);
-  static void Perftools_delete(void *ptr);
-  static void Perftools_deletearray(void *ptr);
-  static void* Perftools_new_nothrow(size_t size,
-                                     const std::nothrow_t&) __THROW;
-  static void* Perftools_newarray_nothrow(size_t size,
-                                          const std::nothrow_t&) __THROW;
-  static void Perftools_delete_nothrow(void *ptr,
-                                       const std::nothrow_t&) __THROW;
-  static void Perftools_deletearray_nothrow(void *ptr,
-                                            const std::nothrow_t&) __THROW;
-  static size_t Perftools__msize(void *ptr) __THROW;
-  static void* Perftools__expand(void *ptr, size_t size) __THROW;
-  // malloc.h also defines these functions:
-  //   _aligned_malloc, _aligned_free,
-  //   _recalloc, _aligned_offset_malloc, _aligned_realloc, _aligned_recalloc
-  //   _aligned_offset_realloc, _aligned_offset_recalloc, _malloca, _freea
-  // But they seem pretty obscure, and I'm fine not overriding them for now.
-  // It may be they all call into malloc/free anyway.
-};
-
-// This is a subset of MODDULEENTRY32, that we need for patching.
-struct ModuleEntryCopy {
-  LPVOID  modBaseAddr;     // the same as hmodule
-  DWORD   modBaseSize;
-  // This is not part of MODDULEENTRY32, but is needed to avoid making
-  // windows syscalls while we're holding patch_all_modules_lock (see
-  // lock-inversion comments at patch_all_modules_lock definition, below).
-  GenericFnPtr rgProcAddresses[LibcInfo::ctrgProcAddress];
-
-  ModuleEntryCopy() {
-    modBaseAddr = NULL;
-    modBaseSize = 0;
-    for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++)
-      rgProcAddresses[i] = LibcInfo::static_fn(i);
-  }
-  ModuleEntryCopy(const MODULEINFO& mi) {
-    this->modBaseAddr = mi.lpBaseOfDll;
-    this->modBaseSize = mi.SizeOfImage;
-    LPVOID modEndAddr = (char*)mi.lpBaseOfDll + mi.SizeOfImage;
-    for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++) {
-      FARPROC target = ::GetProcAddress(
-          reinterpret_cast<const HMODULE>(mi.lpBaseOfDll),
-          LibcInfo::function_name(i));
-      // Sometimes a DLL forwards a function to a function in another
-      // DLL.  We don't want to patch those forwarded functions --
-      // they'll get patched when the other DLL is processed.
-      if (target >= modBaseAddr && target < modEndAddr)
-        rgProcAddresses[i] = (GenericFnPtr)target;
-      else
-        rgProcAddresses[i] = (GenericFnPtr)NULL;
-    }
-  }
-};
-
-// This class is easier because there's only one of them.
-class WindowsInfo {
- public:
-  void Patch();
-  void Unpatch();
-
- private:
-  // TODO(csilvers): should we be patching GlobalAlloc/LocalAlloc instead,
-  //                 for pre-XP systems?
-  enum {
-    kHeapAlloc, kHeapFree, kVirtualAllocEx, kVirtualFreeEx,
-    kMapViewOfFileEx, kUnmapViewOfFile, kLoadLibraryExW, kFreeLibrary,
-    kNumFunctions
-  };
-
-  struct FunctionInfo {
-    const char* const name;          // name of fn in a module (eg "malloc")
-    GenericFnPtr windows_fn;         // the fn whose name we call (&malloc)
-    GenericFnPtr origstub_fn;        // original fn contents after we patch
-    const GenericFnPtr perftools_fn; // fn we want to patch in
-  };
-
-  static FunctionInfo function_info_[kNumFunctions];
-
-  // A Windows-API equivalent of malloc and free
-  static LPVOID WINAPI Perftools_HeapAlloc(HANDLE hHeap, DWORD dwFlags,
-                                           DWORD_PTR dwBytes);
-  static BOOL WINAPI Perftools_HeapFree(HANDLE hHeap, DWORD dwFlags,
-                                        LPVOID lpMem);
-  // A Windows-API equivalent of mmap and munmap, for "anonymous regions"
-  static LPVOID WINAPI Perftools_VirtualAllocEx(HANDLE process, LPVOID address,
-                                                SIZE_T size, DWORD type,
-                                                DWORD protect);
-  static BOOL WINAPI Perftools_VirtualFreeEx(HANDLE process, LPVOID address,
-                                             SIZE_T size, DWORD type);
-  // A Windows-API equivalent of mmap and munmap, for actual files
-  static LPVOID WINAPI Perftools_MapViewOfFileEx(HANDLE hFileMappingObject,
-                                                 DWORD dwDesiredAccess,
-                                                 DWORD dwFileOffsetHigh,
-                                                 DWORD dwFileOffsetLow,
-                                                 SIZE_T dwNumberOfBytesToMap,
-                                                 LPVOID lpBaseAddress);
-  static BOOL WINAPI Perftools_UnmapViewOfFile(LPCVOID lpBaseAddress);
-  // We don't need the other 3 variants because they all call this one. */
-  static HMODULE WINAPI Perftools_LoadLibraryExW(LPCWSTR lpFileName,
-                                                 HANDLE hFile,
-                                                 DWORD dwFlags);
-  static BOOL WINAPI Perftools_FreeLibrary(HMODULE hLibModule);
-};
-
-// If you run out, just add a few more to the array.  You'll also need
-// to update the switch statement in PatchOneModule(), and the list in
-// UnpatchWindowsFunctions().
-// main_executable and main_executable_windows are two windows into
-// the same executable.  One is responsible for patching the libc
-// routines that live in the main executable (if any) to use tcmalloc;
-// the other is responsible for patching the windows routines like
-// HeapAlloc/etc to use tcmalloc.
-static LibcInfoWithPatchFunctions<0> main_executable;
-static LibcInfoWithPatchFunctions<1> libc1;
-static LibcInfoWithPatchFunctions<2> libc2;
-static LibcInfoWithPatchFunctions<3> libc3;
-static LibcInfoWithPatchFunctions<4> libc4;
-static LibcInfoWithPatchFunctions<5> libc5;
-static LibcInfoWithPatchFunctions<6> libc6;
-static LibcInfoWithPatchFunctions<7> libc7;
-static LibcInfoWithPatchFunctions<8> libc8;
-static LibcInfo* g_module_libcs[] = {
-  &libc1, &libc2, &libc3, &libc4, &libc5, &libc6, &libc7, &libc8
-};
-static WindowsInfo main_executable_windows;
-
-const char* const LibcInfo::function_name_[] = {
-  "malloc", "free", "realloc", "calloc",
-  kMangledNew, kMangledNewArray, kMangledDelete, kMangledDeleteArray,
-  // Ideally we should patch the nothrow versions of new/delete, but
-  // at least in msvcrt, nothrow-new machine-code is of a type we
-  // can't patch.  Since these are relatively rare, I'm hoping it's ok
-  // not to patch them.  (NULL name turns off patching.)
-  NULL,  // kMangledNewNothrow,
-  NULL,  // kMangledNewArrayNothrow,
-  NULL,  // kMangledDeleteNothrow,
-  NULL,  // kMangledDeleteArrayNothrow,
-  "_msize", "_expand", "_calloc_crt", "_free_base"
-};
-
-// For mingw, I can't patch the new/delete here, because the
-// instructions are too small to patch.  Luckily, they're so small
-// because all they do is call into malloc/free, so they still end up
-// calling tcmalloc routines, and we don't actually lose anything
-// (except maybe some stacktrace goodness) by not patching.
-const GenericFnPtr LibcInfo::static_fn_[] = {
-  (GenericFnPtr)&::malloc,
-  (GenericFnPtr)&::free,
-  (GenericFnPtr)&::realloc,
-  (GenericFnPtr)&::calloc,
-#ifdef __MINGW32__
-  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-#else
-  (GenericFnPtr)(void*(*)(size_t))&::operator new,
-  (GenericFnPtr)(void*(*)(size_t))&::operator new[],
-  (GenericFnPtr)(void(*)(void*))&::operator delete,
-  (GenericFnPtr)(void(*)(void*))&::operator delete[],
-  (GenericFnPtr)
-  (void*(*)(size_t, struct std::nothrow_t const &))&::operator new,
-  (GenericFnPtr)
-  (void*(*)(size_t, struct std::nothrow_t const &))&::operator new[],
-  (GenericFnPtr)
-  (void(*)(void*, struct std::nothrow_t const &))&::operator delete,
-  (GenericFnPtr)
-  (void(*)(void*, struct std::nothrow_t const &))&::operator delete[],
-#endif
-  (GenericFnPtr)&::_msize,
-  (GenericFnPtr)&::_expand,
-  (GenericFnPtr)&::calloc,
-  (GenericFnPtr)&::free
-};
-
-template<int T> GenericFnPtr LibcInfoWithPatchFunctions<T>::origstub_fn_[] = {
-  // This will get filled in at run-time, as patching is done.
-};
-
-template<int T>
-const GenericFnPtr LibcInfoWithPatchFunctions<T>::perftools_fn_[] = {
-  (GenericFnPtr)&Perftools_malloc,
-  (GenericFnPtr)&Perftools_free,
-  (GenericFnPtr)&Perftools_realloc,
-  (GenericFnPtr)&Perftools_calloc,
-  (GenericFnPtr)&Perftools_new,
-  (GenericFnPtr)&Perftools_newarray,
-  (GenericFnPtr)&Perftools_delete,
-  (GenericFnPtr)&Perftools_deletearray,
-  (GenericFnPtr)&Perftools_new_nothrow,
-  (GenericFnPtr)&Perftools_newarray_nothrow,
-  (GenericFnPtr)&Perftools_delete_nothrow,
-  (GenericFnPtr)&Perftools_deletearray_nothrow,
-  (GenericFnPtr)&Perftools__msize,
-  (GenericFnPtr)&Perftools__expand,
-  (GenericFnPtr)&Perftools_calloc,
-  (GenericFnPtr)&Perftools_free_base
-};
-
-/*static*/ WindowsInfo::FunctionInfo WindowsInfo::function_info_[] = {
-  { "HeapAlloc", NULL, NULL, (GenericFnPtr)&Perftools_HeapAlloc },
-  { "HeapFree", NULL, NULL, (GenericFnPtr)&Perftools_HeapFree },
-  { "VirtualAllocEx", NULL, NULL, (GenericFnPtr)&Perftools_VirtualAllocEx },
-  { "VirtualFreeEx", NULL, NULL, (GenericFnPtr)&Perftools_VirtualFreeEx },
-  { "MapViewOfFileEx", NULL, NULL, (GenericFnPtr)&Perftools_MapViewOfFileEx },
-  { "UnmapViewOfFile", NULL, NULL, (GenericFnPtr)&Perftools_UnmapViewOfFile },
-  { "LoadLibraryExW", NULL, NULL, (GenericFnPtr)&Perftools_LoadLibraryExW },
-  { "FreeLibrary", NULL, NULL, (GenericFnPtr)&Perftools_FreeLibrary },
-};
-
-bool LibcInfo::PopulateWindowsFn(const ModuleEntryCopy& module_entry) {
-  // First, store the location of the function to patch before
-  // patching it.  If none of these functions are found in the module,
-  // then this module has no libc in it, and we just return false.
-  for (int i = 0; i < kNumFunctions; i++) {
-    if (!function_name_[i])     // we can turn off patching by unsetting name
-      continue;
-    // The ::GetProcAddress calls were done in the ModuleEntryCopy
-    // constructor, so we don't have to make any windows calls here.
-    const GenericFnPtr fn = module_entry.rgProcAddresses[i];
-    if (fn) {
-      windows_fn_[i] = PreamblePatcher::ResolveTarget(fn);
-    }
-  }
-
-  // Some modules use the same function pointer for new and new[].  If
-  // we find that, set one of the pointers to NULL so we don't double-
-  // patch.  Same may happen with new and nothrow-new, or even new[]
-  // and nothrow-new.  It's easiest just to check each fn-ptr against
-  // every other.
-  for (int i = 0; i < kNumFunctions; i++) {
-    for (int j = i+1; j < kNumFunctions; j++) {
-      if (windows_fn_[i] == windows_fn_[j]) {
-        // We NULL the later one (j), so as to minimize the chances we
-        // NULL kFree and kRealloc.  See comments below.  This is fragile!
-        windows_fn_[j] = NULL;
-      }
-    }
-  }
-
-  // There's always a chance that our module uses the same function
-  // as another module that we've already loaded.  In that case, we
-  // need to set our windows_fn to NULL, to avoid double-patching.
-  for (int ifn = 0; ifn < kNumFunctions; ifn++) {
-    for (int imod = 0;
-         imod < sizeof(g_module_libcs)/sizeof(*g_module_libcs);  imod++) {
-      if (g_module_libcs[imod]->is_valid() &&
-          this->windows_fn(ifn) == g_module_libcs[imod]->windows_fn(ifn)) {
-        windows_fn_[ifn] = NULL;
-      }
-    }
-  }
-
-  bool found_non_null = false;
-  for (int i = 0; i < kNumFunctions; i++) {
-    if (windows_fn_[i])
-      found_non_null = true;
-  }
-  if (!found_non_null)
-    return false;
-
-  // It's important we didn't NULL out windows_fn_[kFree] or [kRealloc].
-  // The reason is, if those are NULL-ed out, we'll never patch them
-  // and thus never get an origstub_fn_ value for them, and when we
-  // try to call origstub_fn_[kFree/kRealloc] in Perftools_free and
-  // Perftools_realloc, below, it will fail.  We could work around
-  // that by adding a pointer from one patch-unit to the other, but we
-  // haven't needed to yet.
-  CHECK(windows_fn_[kFree]);
-  CHECK(windows_fn_[kRealloc]);
-
-  // OK, we successfully populated.  Let's store our member information.
-  module_base_address_ = module_entry.modBaseAddr;
-  module_base_size_ = module_entry.modBaseSize;
-  return true;
-}
-
-template<int T>
-bool LibcInfoWithPatchFunctions<T>::Patch(const LibcInfo& me_info) {
-  CopyFrom(me_info);   // copies the module_entry and the windows_fn_ array
-  for (int i = 0; i < kNumFunctions; i++) {
-    if (windows_fn_[i] && windows_fn_[i] != perftools_fn_[i]) {
-      // if origstub_fn_ is not NULL, it's left around from a previous
-      // patch.  We need to set it to NULL for the new Patch call.
-      //
-      // Note that origstub_fn_ was logically freed by
-      // PreamblePatcher::Unpatch, so we don't have to do anything
-      // about it.
-      origstub_fn_[i] = NULL;   // Patch() will fill this in
-      CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
-               PreamblePatcher::Patch(windows_fn_[i], perftools_fn_[i],
-                                      &origstub_fn_[i]));
-    }
-  }
-  set_is_valid(true);
-  return true;
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Unpatch() {
-  // We have to cast our GenericFnPtrs to void* for unpatch.  This is
-  // contra the C++ spec; we use C-style casts to empahsize that.
-  for (int i = 0; i < kNumFunctions; i++) {
-    if (windows_fn_[i])
-      CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
-               PreamblePatcher::Unpatch((void*)windows_fn_[i],
-                                        (void*)perftools_fn_[i],
-                                        (void*)origstub_fn_[i]));
-  }
-  set_is_valid(false);
-}
-
-void WindowsInfo::Patch() {
-  HMODULE hkernel32 = ::GetModuleHandleA("kernel32");
-  CHECK_NE(hkernel32, NULL);
-
-  // Unlike for libc, we know these exist in our module, so we can get
-  // and patch at the same time.
-  for (int i = 0; i < kNumFunctions; i++) {
-    function_info_[i].windows_fn = (GenericFnPtr)
-        ::GetProcAddress(hkernel32, function_info_[i].name);
-    // If origstub_fn is not NULL, it's left around from a previous
-    // patch.  We need to set it to NULL for the new Patch call.
-    // Since we've patched Unpatch() not to delete origstub_fn_ (it
-    // causes problems in some contexts, though obviously not this
-    // one), we should delete it now, before setting it to NULL.
-    // NOTE: casting from a function to a pointer is contra the C++
-    //       spec.  It's not safe on IA64, but is on i386.  We use
-    //       a C-style cast here to emphasize this is not legal C++.
-    delete[] (char*)(function_info_[i].origstub_fn);
-    function_info_[i].origstub_fn = NULL;  // Patch() will fill this in
-    CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
-             PreamblePatcher::Patch(function_info_[i].windows_fn,
-                                    function_info_[i].perftools_fn,
-                                    &function_info_[i].origstub_fn));
-  }
-}
-
-void WindowsInfo::Unpatch() {
-  // We have to cast our GenericFnPtrs to void* for unpatch.  This is
-  // contra the C++ spec; we use C-style casts to empahsize that.
-  for (int i = 0; i < kNumFunctions; i++) {
-    CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
-             PreamblePatcher::Unpatch((void*)function_info_[i].windows_fn,
-                                      (void*)function_info_[i].perftools_fn,
-                                      (void*)function_info_[i].origstub_fn));
-  }
-}
-
-// You should hold the patch_all_modules_lock when calling this.
-void PatchOneModuleLocked(const LibcInfo& me_info) {
-  // If we don't already have info on this module, let's add it.  This
-  // is where we're sad that each libcX has a different type, so we
-  // can't use an array; instead, we have to use a switch statement.
-  // Patch() returns false if there were no libc functions in the module.
-  for (int i = 0; i < sizeof(g_module_libcs)/sizeof(*g_module_libcs); i++) {
-    if (!g_module_libcs[i]->is_valid()) {   // found an empty spot to add!
-      switch (i) {
-        case 0: libc1.Patch(me_info); return;
-        case 1: libc2.Patch(me_info); return;
-        case 2: libc3.Patch(me_info); return;
-        case 3: libc4.Patch(me_info); return;
-        case 4: libc5.Patch(me_info); return;
-        case 5: libc6.Patch(me_info); return;
-        case 6: libc7.Patch(me_info); return;
-        case 7: libc8.Patch(me_info); return;
-      }
-    }
-  }
-  printf("PERFTOOLS ERROR: Too many modules containing libc in this executable\n");
-}
-
-void PatchMainExecutableLocked() {
-  if (main_executable.patched())
-    return;    // main executable has already been patched
-  ModuleEntryCopy fake_module_entry;   // make a fake one to pass into Patch()
-  // No need to call PopulateModuleEntryProcAddresses on the main executable.
-  main_executable.PopulateWindowsFn(fake_module_entry);
-  main_executable.Patch(main_executable);
-}
-
-// This lock is subject to a subtle and annoying lock inversion
-// problem: it may interact badly with unknown internal windows locks.
-// In particular, windows may be holding a lock when it calls
-// LoadLibraryExW and FreeLibrary, which we've patched.  We have those
-// routines call PatchAllModules, which acquires this lock.  If we
-// make windows system calls while holding this lock, those system
-// calls may need the internal windows locks that are being held in
-// the call to LoadLibraryExW, resulting in deadlock.  The solution is
-// to be very careful not to call *any* windows routines while holding
-// patch_all_modules_lock, inside PatchAllModules().
-static SpinLock patch_all_modules_lock(SpinLock::LINKER_INITIALIZED);
-
-// last_loaded: The set of modules that were loaded the last time
-// PatchAllModules was called.  This is an optimization for only
-// looking at modules that were added or removed from the last call.
-static std::set<HMODULE> *g_last_loaded;
-
-// Iterates over all the modules currently loaded by the executable,
-// according to windows, and makes sure they're all patched.  Most
-// modules will already be in loaded_modules, meaning we have already
-// loaded and either patched them or determined they did not need to
-// be patched.  Others will not, which means we need to patch them
-// (if necessary).  Finally, we have to go through the existing
-// g_module_libcs and see if any of those are *not* in the modules
-// currently loaded by the executable.  If so, we need to invalidate
-// them.  Returns true if we did any work (patching or invalidating),
-// false if we were a noop.  May update loaded_modules as well.
-// NOTE: you must hold the patch_all_modules_lock to access loaded_modules.
-bool PatchAllModules() {
-  std::vector<ModuleEntryCopy> modules;
-  bool made_changes = false;
-
-  const HANDLE hCurrentProcess = GetCurrentProcess();
-  DWORD num_modules = 0;
-  HMODULE hModules[kMaxModules];  // max # of modules we support in one process
-  if (!::EnumProcessModules(hCurrentProcess, hModules, sizeof(hModules),
-                            &num_modules)) {
-    num_modules = 0;
-  }
-  // EnumProcessModules actually set the bytes written into hModules,
-  // so we need to divide to make num_modules actually be a module-count.
-  num_modules /= sizeof(*hModules);
-  if (num_modules >= kMaxModules) {
-    printf("PERFTOOLS ERROR: Too many modules in this executable to try"
-           " to patch them all (if you need to, raise kMaxModules in"
-           " patch_functions.cc).\n");
-    num_modules = kMaxModules;
-  }
-
-  // Now we handle the unpatching of modules we have in g_module_libcs
-  // but that were not found in EnumProcessModules.  We need to
-  // invalidate them.  To speed that up, we store the EnumProcessModules
-  // output in a set.
-  // At the same time, we prepare for the adding of new modules, by
-  // removing from hModules all the modules we know we've already
-  // patched (or decided don't need to be patched).  At the end,
-  // hModules will hold only the modules that we need to consider patching.
-  std::set<HMODULE> currently_loaded_modules;
-  {
-    SpinLockHolder h(&patch_all_modules_lock);
-    if (!g_last_loaded)  g_last_loaded = new std::set<HMODULE>;
-    // At the end of this loop, currently_loaded_modules contains the
-    // full list of EnumProcessModules, and hModules just the ones we
-    // haven't handled yet.
-    for (int i = 0; i < num_modules; ) {
-      currently_loaded_modules.insert(hModules[i]);
-      if (g_last_loaded->count(hModules[i]) > 0) {
-        hModules[i] = hModules[--num_modules];  // replace element i with tail
-      } else {
-        i++;                                    // keep element i
-      }
-    }
-    // Now we do the unpatching/invalidation.
-    for (int i = 0; i < sizeof(g_module_libcs)/sizeof(*g_module_libcs); i++) {
-      if (g_module_libcs[i]->patched() &&
-          currently_loaded_modules.count(g_module_libcs[i]->hmodule()) == 0) {
-        // Means g_module_libcs[i] is no longer loaded (no me32 matched).
-        // We could call Unpatch() here, but why bother?  The module
-        // has gone away, so nobody is going to call into it anyway.
-        g_module_libcs[i]->set_is_valid(false);
-        made_changes = true;
-      }
-    }
-    // Update the loaded module cache.
-    g_last_loaded->swap(currently_loaded_modules);
-  }
-
-  // Now that we know what modules are new, let's get the info we'll
-  // need to patch them.  Note this *cannot* be done while holding the
-  // lock, since it needs to make windows calls (see the lock-inversion
-  // comments before the definition of patch_all_modules_lock).
-  MODULEINFO mi;
-  for (int i = 0; i < num_modules; i++) {
-    if (::GetModuleInformation(hCurrentProcess, hModules[i], &mi, sizeof(mi)))
-      modules.push_back(ModuleEntryCopy(mi));
-  }
-
-  // Now we can do the patching of new modules.
-  {
-    SpinLockHolder h(&patch_all_modules_lock);
-    for (std::vector<ModuleEntryCopy>::iterator it = modules.begin();
-         it != modules.end(); ++it) {
-      LibcInfo libc_info;
-      if (libc_info.PopulateWindowsFn(*it)) { // true==module has libc routines
-        PatchOneModuleLocked(libc_info);
-        made_changes = true;
-      }
-    }
-
-    // Now that we've dealt with the modules (dlls), update the main
-    // executable.  We do this last because PatchMainExecutableLocked
-    // wants to look at how other modules were patched.
-    if (!main_executable.patched()) {
-      PatchMainExecutableLocked();
-      made_changes = true;
-    }
-  }
-  // TODO(csilvers): for this to be reliable, we need to also take
-  // into account if we *would* have patched any modules had they not
-  // already been loaded.  (That is, made_changes should ignore
-  // g_last_loaded.)
-  return made_changes;
-}
-
-
-}  // end unnamed namespace
-
-// ---------------------------------------------------------------------
-// Now that we've done all the patching machinery, let's actually
-// define the functions we're patching in.  Mostly these are
-// simple wrappers around the do_* routines in tcmalloc.cc.
-//
-// In fact, we #include tcmalloc.cc to get at the tcmalloc internal
-// do_* functions, the better to write our own hook functions.
-// U-G-L-Y, I know.  But the alternatives are, perhaps, worse.  This
-// also lets us define _msize(), _expand(), and other windows-specific
-// functions here, using tcmalloc internals, without polluting
-// tcmalloc.cc.
-// -------------------------------------------------------------------
-
-// TODO(csilvers): refactor tcmalloc.cc into two files, so I can link
-// against the file with do_malloc, and ignore the one with malloc.
-#include "tcmalloc.cc"
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_malloc(size_t size) __THROW {
-  return malloc_fast_path<tcmalloc::malloc_oom>(size);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_free(void* ptr) __THROW {
-  MallocHook::InvokeDeleteHook(ptr);
-  // This calls the windows free if do_free decides ptr was not
-  // allocated by tcmalloc.  Note it calls the origstub_free from
-  // *this* templatized instance of LibcInfo.  See "template
-  // trickiness" above.
-  do_free_with_callback(ptr, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_free_base(void* ptr) __THROW{
-  MallocHook::InvokeDeleteHook(ptr);
-  // This calls the windows free if do_free decides ptr was not
-  // allocated by tcmalloc.  Note it calls the origstub_free from
-  // *this* templatized instance of LibcInfo.  See "template
-  // trickiness" above.
-  do_free_with_callback(ptr, (void(*)(void*))origstub_fn_[kFreeBase], false, 0);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_realloc(
-    void* old_ptr, size_t new_size) __THROW {
-  if (old_ptr == NULL) {
-    void* result = do_malloc_or_cpp_alloc(new_size);
-    MallocHook::InvokeNewHook(result, new_size);
-    return result;
-  }
-  if (new_size == 0) {
-    MallocHook::InvokeDeleteHook(old_ptr);
-    do_free_with_callback(old_ptr,
-                          (void (*)(void*))origstub_fn_[kFree], false, 0);
-    return NULL;
-  }
-  return do_realloc_with_callback(
-      old_ptr, new_size,
-      (void (*)(void*))origstub_fn_[kFree],
-      (size_t (*)(const void*))origstub_fn_[k_Msize]);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_calloc(
-    size_t n, size_t elem_size) __THROW {
-  void* result = do_calloc(n, elem_size);
-  MallocHook::InvokeNewHook(result, n * elem_size);
-  return result;
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_new(size_t size) {
-  return malloc_fast_path<tcmalloc::cpp_throw_oom>(size);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_newarray(size_t size) {
-  return malloc_fast_path<tcmalloc::cpp_throw_oom>(size);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_delete(void *p) {
-  MallocHook::InvokeDeleteHook(p);
-  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_deletearray(void *p) {
-  MallocHook::InvokeDeleteHook(p);
-  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_new_nothrow(
-    size_t size, const std::nothrow_t&) __THROW {
-  return malloc_fast_path<tcmalloc::cpp_nothrow_oom>(size);
-}
-
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools_newarray_nothrow(
-    size_t size, const std::nothrow_t&) __THROW {
-  return malloc_fast_path<tcmalloc::cpp_nothrow_oom>(size);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_delete_nothrow(
-    void *p, const std::nothrow_t&) __THROW {
-  MallocHook::InvokeDeleteHook(p);
-  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools_deletearray_nothrow(
-    void *p, const std::nothrow_t&) __THROW {
-  MallocHook::InvokeDeleteHook(p);
-  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree], false, 0);
-}
-
-
-// _msize() lets you figure out how much space is reserved for a
-// pointer, in Windows.  Even if applications don't call it, any DLL
-// with global constructors will call (transitively) something called
-// __dllonexit_lk in order to make sure the destructors get called
-// when the dll unloads.  And that will call msize -- horrible things
-// can ensue if this is not hooked.  Other parts of libc may also call
-// this internally.
-
-template<int T>
-size_t LibcInfoWithPatchFunctions<T>::Perftools__msize(void* ptr) __THROW {
-  return GetSizeWithCallback(ptr, (size_t (*)(const void*))origstub_fn_[k_Msize]);
-}
-
-// We need to define this because internal windows functions like to
-// call into it(?).  _expand() is like realloc but doesn't move the
-// pointer.  We punt, which will cause callers to fall back on realloc.
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools__expand(void *ptr,
-                                                       size_t size) __THROW {
-  return NULL;
-}
-
-LPVOID WINAPI WindowsInfo::Perftools_HeapAlloc(HANDLE hHeap, DWORD dwFlags,
-                                               DWORD_PTR dwBytes) {
-  LPVOID result = ((LPVOID (WINAPI *)(HANDLE, DWORD, DWORD_PTR))
-                   function_info_[kHeapAlloc].origstub_fn)(
-                       hHeap, dwFlags, dwBytes);
-  MallocHook::InvokeNewHook(result, dwBytes);
-  return result;
-}
-
-BOOL WINAPI WindowsInfo::Perftools_HeapFree(HANDLE hHeap, DWORD dwFlags,
-                                            LPVOID lpMem) {
-  MallocHook::InvokeDeleteHook(lpMem);
-  return ((BOOL (WINAPI *)(HANDLE, DWORD, LPVOID))
-          function_info_[kHeapFree].origstub_fn)(
-              hHeap, dwFlags, lpMem);
-}
-
-LPVOID WINAPI WindowsInfo::Perftools_VirtualAllocEx(HANDLE process,
-                                                    LPVOID address,
-                                                    SIZE_T size, DWORD type,
-                                                    DWORD protect) {
-  LPVOID result = ((LPVOID (WINAPI *)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD))
-                   function_info_[kVirtualAllocEx].origstub_fn)(
-                       process, address, size, type, protect);
-  // VirtualAllocEx() seems to be the Windows equivalent of mmap()
-  MallocHook::InvokeMmapHook(result, address, size, protect, type, -1, 0);
-  return result;
-}
-
-BOOL WINAPI WindowsInfo::Perftools_VirtualFreeEx(HANDLE process, LPVOID address,
-                                                 SIZE_T size, DWORD type) {
-  MallocHook::InvokeMunmapHook(address, size);
-  return ((BOOL (WINAPI *)(HANDLE, LPVOID, SIZE_T, DWORD))
-          function_info_[kVirtualFreeEx].origstub_fn)(
-              process, address, size, type);
-}
-
-LPVOID WINAPI WindowsInfo::Perftools_MapViewOfFileEx(
-    HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,
-    DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress) {
-  // For this function pair, you always deallocate the full block of
-  // data that you allocate, so NewHook/DeleteHook is the right API.
-  LPVOID result = ((LPVOID (WINAPI *)(HANDLE, DWORD, DWORD, DWORD,
-                                      SIZE_T, LPVOID))
-                   function_info_[kMapViewOfFileEx].origstub_fn)(
-                       hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh,
-                       dwFileOffsetLow, dwNumberOfBytesToMap, lpBaseAddress);
-  MallocHook::InvokeNewHook(result, dwNumberOfBytesToMap);
-  return result;
-}
-
-BOOL WINAPI WindowsInfo::Perftools_UnmapViewOfFile(LPCVOID lpBaseAddress) {
-  MallocHook::InvokeDeleteHook(lpBaseAddress);
-  return ((BOOL (WINAPI *)(LPCVOID))
-          function_info_[kUnmapViewOfFile].origstub_fn)(
-              lpBaseAddress);
-}
-
-HMODULE WINAPI WindowsInfo::Perftools_LoadLibraryExW(LPCWSTR lpFileName,
-                                                     HANDLE hFile,
-                                                     DWORD dwFlags) {
-  HMODULE rv;
-  // Check to see if the modules is already loaded, flag 0 gets a
-  // reference if it was loaded.  If it was loaded no need to call
-  // PatchAllModules, just increase the reference count to match
-  // what GetModuleHandleExW does internally inside windows.
-  if (::GetModuleHandleExW(0, lpFileName, &rv)) {
-    return rv;
-  } else {
-    // Not already loaded, so load it.
-    rv = ((HMODULE (WINAPI *)(LPCWSTR, HANDLE, DWORD))
-                  function_info_[kLoadLibraryExW].origstub_fn)(
-                      lpFileName, hFile, dwFlags);
-    // This will patch any newly loaded libraries, if patching needs
-    // to be done.
-    PatchAllModules();
-
-    return rv;
-  }
-}
-
-BOOL WINAPI WindowsInfo::Perftools_FreeLibrary(HMODULE hLibModule) {
-  BOOL rv = ((BOOL (WINAPI *)(HMODULE))
-             function_info_[kFreeLibrary].origstub_fn)(hLibModule);
-
-  // Check to see if the module is still loaded by passing the base
-  // address and seeing if it comes back with the same address.  If it
-  // is the same address it's still loaded, so the FreeLibrary() call
-  // was a noop, and there's no need to redo the patching.
-  HMODULE owner = NULL;
-  BOOL result = ::GetModuleHandleExW(
-      (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
-       GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
-      (LPCWSTR)hLibModule,
-      &owner);
-  if (result && owner == hLibModule)
-    return rv;
-
-  PatchAllModules();    // this will fix up the list of patched libraries
-  return rv;
-}
-
-
-// ---------------------------------------------------------------------
-// PatchWindowsFunctions()
-//    This is the function that is exposed to the outside world.
-//    It should be called before the program becomes multi-threaded,
-//    since main_executable_windows.Patch() is not thread-safe.
-// ---------------------------------------------------------------------
-
-void PatchWindowsFunctions() {
-  // This does the libc patching in every module, and the main executable.
-  PatchAllModules();
-  main_executable_windows.Patch();
-}
-
-#if 0
-// It's possible to unpatch all the functions when we are exiting.
-
-// The idea is to handle properly windows-internal data that is
-// allocated before PatchWindowsFunctions is called.  If all
-// destruction happened in reverse order from construction, then we
-// could call UnpatchWindowsFunctions at just the right time, so that
-// that early-allocated data would be freed using the windows
-// allocation functions rather than tcmalloc.  The problem is that
-// windows allocates some structures lazily, so it would allocate them
-// late (using tcmalloc) and then try to deallocate them late as well.
-// So instead of unpatching, we just modify all the tcmalloc routines
-// so they call through to the libc rountines if the memory in
-// question doesn't seem to have been allocated with tcmalloc.  I keep
-// this unpatch code around for reference.
-
-void UnpatchWindowsFunctions() {
-  // We need to go back to the system malloc/etc at global destruct time,
-  // so objects that were constructed before tcmalloc, using the system
-  // malloc, can destroy themselves using the system free.  This depends
-  // on DLLs unloading in the reverse order in which they load!
-  //
-  // We also go back to the default HeapAlloc/etc, just for consistency.
-  // Who knows, it may help avoid weird bugs in some situations.
-  main_executable_windows.Unpatch();
-  main_executable.Unpatch();
-  if (libc1.is_valid()) libc1.Unpatch();
-  if (libc2.is_valid()) libc2.Unpatch();
-  if (libc3.is_valid()) libc3.Unpatch();
-  if (libc4.is_valid()) libc4.Unpatch();
-  if (libc5.is_valid()) libc5.Unpatch();
-  if (libc6.is_valid()) libc6.Unpatch();
-  if (libc7.is_valid()) libc7.Unpatch();
-  if (libc8.is_valid()) libc8.Unpatch();
-}
-#endif
diff --git a/third_party/tcmalloc/vendor/src/windows/port.cc b/third_party/tcmalloc/vendor/src/windows/port.cc
deleted file mode 100644
index 76224a2..0000000
--- a/third_party/tcmalloc/vendor/src/windows/port.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Craig Silverstein
- */
-
-#ifndef _WIN32
-# error You should only be including windows/port.cc in a windows environment!
-#endif
-
-#define NOMINMAX       // so std::max, below, compiles correctly
-#include <config.h>
-#include <string.h>    // for strlen(), memset(), memcmp()
-#include <assert.h>
-#include <stdarg.h>    // for va_list, va_start, va_end
-#include <algorithm>   // for std:{min,max}
-#include <windows.h>
-#include "port.h"
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "internal_logging.h"
-
-// -----------------------------------------------------------------------
-// Basic libraries
-
-PERFTOOLS_DLL_DECL
-int getpagesize() {
-  static int pagesize = 0;
-  if (pagesize == 0) {
-    SYSTEM_INFO system_info;
-    GetSystemInfo(&system_info);
-    pagesize = std::max(system_info.dwPageSize,
-                        system_info.dwAllocationGranularity);
-  }
-  return pagesize;
-}
-
-extern "C" PERFTOOLS_DLL_DECL void* __sbrk(ptrdiff_t increment) {
-  LOG(FATAL, "Windows doesn't implement sbrk!\n");
-  return NULL;
-}
-
-// We need to write to 'stderr' without having windows allocate memory.
-// The safest way is via a low-level call like WriteConsoleA().  But
-// even then we need to be sure to print in small bursts so as to not
-// require memory allocation.
-extern "C" PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len) {
-  // Looks like windows allocates for writes of >80 bytes
-  for (int i = 0; i < len; i += 80) {
-    write(STDERR_FILENO, buf + i, std::min(80, len - i));
-  }
-}
-
-
-// -----------------------------------------------------------------------
-// Threads code
-
-// Windows doesn't support pthread_key_create's destr_function, and in
-// fact it's a bit tricky to get code to run when a thread exits.  This
-// is cargo-cult magic from http://www.codeproject.com/threads/tls.asp.
-// This code is for VC++ 7.1 and later; VC++ 6.0 support is possible
-// but more busy-work -- see the webpage for how to do it.  If all
-// this fails, we could use DllMain instead.  The big problem with
-// DllMain is it doesn't run if this code is statically linked into a
-// binary (it also doesn't run if the thread is terminated via
-// TerminateThread, which if we're lucky this routine does).
-
-// Force a reference to _tls_used to make the linker create the TLS directory
-// if it's not already there (that is, even if __declspec(thread) is not used).
-// Force a reference to p_thread_callback_tcmalloc and p_process_term_tcmalloc
-// to prevent whole program optimization from discarding the variables.
-#ifdef _MSC_VER
-#if defined(_M_IX86)
-#pragma comment(linker, "/INCLUDE:__tls_used")
-#pragma comment(linker, "/INCLUDE:_p_thread_callback_tcmalloc")
-#pragma comment(linker, "/INCLUDE:_p_process_term_tcmalloc")
-#elif defined(_M_X64)
-#pragma comment(linker, "/INCLUDE:_tls_used")
-#pragma comment(linker, "/INCLUDE:p_thread_callback_tcmalloc")
-#pragma comment(linker, "/INCLUDE:p_process_term_tcmalloc")
-#endif
-#endif
-
-// When destr_fn eventually runs, it's supposed to take as its
-// argument the tls-value associated with key that pthread_key_create
-// creates.  (Yeah, it sounds confusing but it's really not.)  We
-// store the destr_fn/key pair in this data structure.  Because we
-// store this in a single var, this implies we can only have one
-// destr_fn in a program!  That's enough in practice.  If asserts
-// trigger because we end up needing more, we'll have to turn this
-// into an array.
-struct DestrFnClosure {
-  void (*destr_fn)(void*);
-  pthread_key_t key_for_destr_fn_arg;
-};
-
-static DestrFnClosure destr_fn_info;   // initted to all NULL/0.
-
-static int on_process_term(void) {
-  if (destr_fn_info.destr_fn) {
-    void *ptr = TlsGetValue(destr_fn_info.key_for_destr_fn_arg);
-    // This shouldn't be necessary, but in Release mode, Windows
-    // sometimes trashes the pointer in the TLS slot, so we need to
-    // remove the pointer from the TLS slot before the thread dies.
-    TlsSetValue(destr_fn_info.key_for_destr_fn_arg, NULL);
-    if (ptr)  // pthread semantics say not to call if ptr is NULL
-      (*destr_fn_info.destr_fn)(ptr);
-  }
-  return 0;
-}
-
-static void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv) {
-  if (dwReason == DLL_THREAD_DETACH) {   // thread is being destroyed!
-    on_process_term();
-  }
-}
-
-#ifdef _MSC_VER
-
-// extern "C" suppresses C++ name mangling so we know the symbol names
-// for the linker /INCLUDE:symbol pragmas above.
-extern "C" {
-// This tells the linker to run these functions.
-#pragma data_seg(push, old_seg)
-#pragma data_seg(".CRT$XLB")
-void (NTAPI *p_thread_callback_tcmalloc)(
-    HINSTANCE h, DWORD dwReason, PVOID pv) = on_tls_callback;
-#pragma data_seg(".CRT$XTU")
-int (*p_process_term_tcmalloc)(void) = on_process_term;
-#pragma data_seg(pop, old_seg)
-}  // extern "C"
-
-#else  // #ifdef _MSC_VER  [probably msys/mingw]
-
-// We have to try the DllMain solution here, because we can't use the
-// msvc-specific pragmas.
-BOOL WINAPI DllMain(HINSTANCE h, DWORD dwReason, PVOID pv) {
-  if (dwReason == DLL_THREAD_DETACH)
-    on_tls_callback(h, dwReason, pv);
-  else if (dwReason == DLL_PROCESS_DETACH)
-    on_process_term();
-  return TRUE;
-}
-
-#endif  // #ifdef _MSC_VER
-
-extern "C" pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)) {
-  // Semantics are: we create a new key, and then promise to call
-  // destr_fn with TlsGetValue(key) when the thread is destroyed
-  // (as long as TlsGetValue(key) is not NULL).
-  pthread_key_t key = TlsAlloc();
-  if (destr_fn) {   // register it
-    // If this assert fails, we'll need to support an array of destr_fn_infos
-    assert(destr_fn_info.destr_fn == NULL);
-    destr_fn_info.destr_fn = destr_fn;
-    destr_fn_info.key_for_destr_fn_arg = key;
-  }
-  return key;
-}
-
-// NOTE: this is Win2K and later.  For Win98 we could use a CRITICAL_SECTION...
-extern "C" int perftools_pthread_once(pthread_once_t *once_control,
-                                      void (*init_routine)(void)) {
-  // Try for a fast path first. Note: this should be an acquire semantics read.
-  // It is on x86 and x64, where Windows runs.
-  if (*once_control != 1) {
-    while (true) {
-      switch (InterlockedCompareExchange(once_control, 2, 0)) {
-        case 0:
-          init_routine();
-          InterlockedExchange(once_control, 1);
-          return 0;
-        case 1:
-          // The initializer has already been executed
-          return 0;
-        default:
-          // The initializer is being processed by another thread
-          SwitchToThread();
-      }
-    }
-  }
-  return 0;
-}
-
-
-// -----------------------------------------------------------------------
-// These functions rework existing functions of the same name in the
-// Google codebase.
-
-// A replacement for HeapProfiler::CleanupOldProfiles.
-void DeleteMatchingFiles(const char* prefix, const char* full_glob) {
-  WIN32_FIND_DATAA found;  // that final A is for Ansi (as opposed to Unicode)
-  HANDLE hFind = FindFirstFileA(full_glob, &found);   // A is for Ansi
-  if (hFind != INVALID_HANDLE_VALUE) {
-    const int prefix_length = strlen(prefix);
-    do {
-      const char *fname = found.cFileName;
-      if ((strlen(fname) >= prefix_length) &&
-          (memcmp(fname, prefix, prefix_length) == 0)) {
-        RAW_VLOG(0, "Removing old heap profile %s\n", fname);
-        // TODO(csilvers): we really need to unlink dirname + fname
-        _unlink(fname);
-      }
-    } while (FindNextFileA(hFind, &found) != FALSE);  // A is for Ansi
-    FindClose(hFind);
-  }
-}
diff --git a/third_party/tcmalloc/vendor/src/windows/port.h b/third_party/tcmalloc/vendor/src/windows/port.h
deleted file mode 100644
index eb9702b..0000000
--- a/third_party/tcmalloc/vendor/src/windows/port.h
+++ /dev/null
@@ -1,499 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Craig Silverstein
- *
- * These are some portability typedefs and defines to make it a bit
- * easier to compile this code under VC++.
- *
- * Several of these are taken from glib:
- *    http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
- */
-
-#ifndef GOOGLE_BASE_WINDOWS_H_
-#define GOOGLE_BASE_WINDOWS_H_
-
-/* You should never include this file directly, but always include it
-   from either config.h (MSVC) or mingw.h (MinGW/msys). */
-#if !defined(GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_) && \
-    !defined(GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_)
-# error "port.h should only be included from config.h or mingw.h"
-#endif
-
-#ifdef _WIN32
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */
-#endif
-#include <windows.h>
-#include <io.h>              /* because we so often use open/close/etc */
-#include <direct.h>          /* for _getcwd */
-#include <process.h>         /* for _getpid */
-#include <limits.h>          /* for PATH_MAX */
-#include <stdarg.h>          /* for va_list */
-#include <stdio.h>           /* need this to override stdio's (v)snprintf */
-#include <sys/types.h>       /* for _off_t */
-#include <assert.h>
-#include <stdlib.h>          /* for rand, srand, _strtoxxx */
-
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-#define _TIMESPEC_DEFINED
-#include <time.h>
-#endif
-
-/*
- * 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i)
- * 4244: otherwise we get problems when subtracting two size_t's to an int
- * 4288: VC++7 gets confused when a var is defined in a loop and then after it
- * 4267: too many false positives for "conversion gives possible data loss"
- * 4290: it's ok windows ignores the "throw" directive
- * 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv()
- * 4146: internal_logging.cc intentionally negates an unsigned value
- */
-#ifdef _MSC_VER
-#pragma warning(disable:4018 4244 4288 4267 4290 4996 4146)
-#endif
-
-#ifndef __cplusplus
-/* MSVC does not support C99 */
-# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
-#  ifdef _MSC_VER
-#    define inline __inline
-#  else
-#    define inline static
-#  endif
-# endif
-#endif
-
-#ifdef __cplusplus
-# define EXTERN_C  extern "C"
-#else
-# define EXTERN_C  extern
-#endif
-
-/* ----------------------------------- BASIC TYPES */
-
-#ifndef HAVE_STDINT_H
-#ifndef HAVE___INT64    /* we need to have all the __intX names */
-# error  Do not know how to set up type aliases.  Edit port.h for your system.
-#endif
-
-typedef __int8 int8_t;
-typedef __int16 int16_t;
-typedef __int32 int32_t;
-typedef __int64 int64_t;
-typedef unsigned __int8 uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
-#endif  /* #ifndef HAVE_STDINT_H */
-
-/* I guess MSVC's <types.h> doesn't include ssize_t by default? */
-#ifdef _MSC_VER
-typedef intptr_t ssize_t;
-#endif
-
-/* ----------------------------------- THREADS */
-
-#ifndef HAVE_PTHREAD   /* not true for MSVC, but may be true for MSYS */
-typedef DWORD pthread_t;
-typedef DWORD pthread_key_t;
-typedef LONG pthread_once_t;
-enum { PTHREAD_ONCE_INIT = 0 };   /* important that this be 0! for SpinLock */
-
-inline pthread_t pthread_self(void) {
-  return GetCurrentThreadId();
-}
-
-#ifdef __cplusplus
-inline bool pthread_equal(pthread_t left, pthread_t right) {
-  return left == right;
-}
-
-/*
- * windows/port.h defines compatibility APIs for several .h files, which
- * we therefore shouldn't be #including directly.  This hack keeps us from
- * doing so.  TODO(csilvers): do something more principled.
- */
-#define GOOGLE_MAYBE_THREADS_H_ 1
-/* This replaces maybe_threads.{h,cc} */
-
-EXTERN_C pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*));  /* port.cc */
-
-inline int perftools_pthread_key_create(pthread_key_t *pkey,
-                                        void (*destructor)(void*)) {
-  pthread_key_t key = PthreadKeyCreate(destructor);
-  if (key != TLS_OUT_OF_INDEXES) {
-    *(pkey) = key;
-    return 0;
-  } else {
-    return GetLastError();
-  }
-}
-
-inline void* perftools_pthread_getspecific(DWORD key) {
-  DWORD err = GetLastError();
-  void* rv = TlsGetValue(key);
-  if (err) SetLastError(err);
-  return rv;
-}
-
-inline int perftools_pthread_setspecific(pthread_key_t key, const void *value) {
-  if (TlsSetValue(key, (LPVOID)value))
-    return 0;
-  else
-    return GetLastError();
-}
-
-EXTERN_C int perftools_pthread_once(pthread_once_t *once_control,
-                                    void (*init_routine)(void));
-
-#endif  /* __cplusplus */
-
-inline void sched_yield(void) {
-  Sleep(0);
-}
-
-#endif  /* HAVE_PTHREAD */
-
-/*
- * __declspec(thread) isn't usable in a dll opened via LoadLibrary().
- * But it doesn't work to LoadLibrary() us anyway, because of all the
- * things we need to do before main()!  So this kind of TLS is safe for us.
- */
-#define __thread __declspec(thread)
-
-/*
- * This code is obsolete, but I keep it around in case we are ever in
- * an environment where we can't or don't want to use google spinlocks
- * (from base/spinlock.{h,cc}).  In that case, uncommenting this out,
- * and removing spinlock.cc from the build, should be enough to revert
- * back to using native spinlocks.
- */
-#if 0
-// Windows uses a spinlock internally for its mutexes, making our life easy!
-// However, the Windows spinlock must always be initialized, making life hard,
-// since we want LINKER_INITIALIZED.  We work around this by having the
-// linker initialize a bool to 0, and check that before accessing the mutex.
-// This replaces spinlock.{h,cc}, and all the stuff it depends on (atomicops)
-#ifdef __cplusplus
-class SpinLock {
- public:
-  SpinLock() : initialize_token_(PTHREAD_ONCE_INIT) {}
-  // Used for global SpinLock vars (see base/spinlock.h for more details).
-  enum StaticInitializer { LINKER_INITIALIZED };
-  explicit SpinLock(StaticInitializer) : initialize_token_(PTHREAD_ONCE_INIT) {
-    perftools_pthread_once(&initialize_token_, InitializeMutex);
-  }
-
-  // It's important SpinLock not have a destructor: otherwise we run
-  // into problems when the main thread has exited, but other threads
-  // are still running and try to access a main-thread spinlock.  This
-  // means we leak mutex_ (we should call DeleteCriticalSection()
-  // here).  However, I've verified that all SpinLocks used in
-  // perftools have program-long scope anyway, so the leak is
-  // perfectly fine.  But be aware of this for the future!
-
-  void Lock() {
-    // You'd thionk this would be unnecessary, since we call
-    // InitializeMutex() in our constructor.  But sometimes Lock() can
-    // be called before our constructor is!  This can only happen in
-    // global constructors, when this is a global.  If we live in
-    // bar.cc, and some global constructor in foo.cc calls a routine
-    // in bar.cc that calls this->Lock(), then Lock() may well run
-    // before our global constructor does.  To protect against that,
-    // we do this check.  For SpinLock objects created after main()
-    // has started, this pthread_once call will always be a noop.
-    perftools_pthread_once(&initialize_token_, InitializeMutex);
-    EnterCriticalSection(&mutex_);
-  }
-  void Unlock() {
-    LeaveCriticalSection(&mutex_);
-  }
-
-  // Used in assertion checks: assert(lock.IsHeld()) (see base/spinlock.h).
-  inline bool IsHeld() const {
-    // This works, but probes undocumented internals, so I've commented it out.
-    // c.f. http://msdn.microsoft.com/msdnmag/issues/03/12/CriticalSections/
-    //return mutex_.LockCount>=0 && mutex_.OwningThread==GetCurrentThreadId();
-    return true;
-  }
- private:
-  void InitializeMutex() { InitializeCriticalSection(&mutex_); }
-
-  pthread_once_t initialize_token_;
-  CRITICAL_SECTION mutex_;
-};
-
-class SpinLockHolder {  // Acquires a spinlock for as long as the scope lasts
- private:
-  SpinLock* lock_;
- public:
-  inline explicit SpinLockHolder(SpinLock* l) : lock_(l) { l->Lock(); }
-  inline ~SpinLockHolder() { lock_->Unlock(); }
-};
-#endif  // #ifdef __cplusplus
-
-// This keeps us from using base/spinlock.h's implementation of SpinLock.
-#define BASE_SPINLOCK_H_ 1
-
-#endif  /* #if 0 */
-
-/* ----------------------------------- MMAP and other memory allocation */
-
-#ifndef HAVE_MMAP   /* not true for MSVC, but may be true for msys */
-#define MAP_FAILED  0
-#define MREMAP_FIXED  2  /* the value in linux, though it doesn't really matter */
-/* These, when combined with the mmap invariants below, yield the proper action */
-#define PROT_READ      PAGE_READWRITE
-#define PROT_WRITE     PAGE_READWRITE
-#define MAP_ANONYMOUS  MEM_RESERVE
-#define MAP_PRIVATE    MEM_COMMIT
-#define MAP_SHARED     MEM_RESERVE   /* value of this #define is 100% arbitrary */
-
-#if __STDC__ && !defined(__MINGW32__)
-typedef _off_t off_t;
-#endif
-
-/* VirtualAlloc only replaces for mmap when certain invariants are kept. */
-inline void *mmap(void *addr, size_t length, int prot, int flags,
-                  int fd, off_t offset) {
-  if (addr == NULL && fd == -1 && offset == 0 &&
-      prot == (PROT_READ|PROT_WRITE) && flags == (MAP_PRIVATE|MAP_ANONYMOUS)) {
-    return VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
-  } else {
-    return NULL;
-  }
-}
-
-inline int munmap(void *addr, size_t length) {
-  return VirtualFree(addr, 0, MEM_RELEASE) ? 0 : -1;
-}
-#endif  /* HAVE_MMAP */
-
-/* We could maybe use VirtualAlloc for sbrk as well, but no need */
-inline void *sbrk(intptr_t increment) {
-  // sbrk returns -1 on failure
-  return (void*)-1;
-}
-
-
-/* ----------------------------------- STRING ROUTINES */
-
-/*
- * We can't just use _vsnprintf and _snprintf as drop-in-replacements,
- * because they don't always NUL-terminate. :-(  We also can't use the
- * name vsnprintf, since windows defines that (but not snprintf (!)).
- */
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-/* We can use safe CRT functions, which the required functionality */
-inline int perftools_vsnprintf(char *str, size_t size, const char *format,
-                               va_list ap) {
-  return vsnprintf_s(str, size, _TRUNCATE, format, ap);
-}
-#else
-inline int perftools_vsnprintf(char *str, size_t size, const char *format,
-                               va_list ap) {
-  if (size == 0)        /* not even room for a \0? */
-    return -1;        /* not what C99 says to do, but what windows does */
-  str[size-1] = '\0';
-  return _vsnprintf(str, size-1, format, ap);
-}
-#endif
-
-#ifndef HAVE_SNPRINTF
-inline int snprintf(char *str, size_t size, const char *format, ...) {
-  va_list ap;
-  int r;
-  va_start(ap, format);
-  r = perftools_vsnprintf(str, size, format, ap);
-  va_end(ap);
-  return r;
-}
-#endif
-
-#ifndef HAVE_INTTYPES_H
-#define PRIx64  "I64x"
-#define SCNx64  "I64x"
-#define PRId64  "I64d"
-#define SCNd64  "I64d"
-#define PRIu64  "I64u"
-#ifdef _WIN64
-# define PRIuPTR "llu"
-# define PRIxPTR "llx"
-#else
-# define PRIuPTR "lu"
-# define PRIxPTR "lx"
-#endif
-#endif
-
-/* ----------------------------------- FILE IO */
-
-#ifndef PATH_MAX
-#define PATH_MAX 1024
-#endif
-#ifndef __MINGW32__
-enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
-#endif
-#ifndef O_RDONLY
-#define O_RDONLY  _O_RDONLY
-#endif
-
-#if __STDC__ && !defined(__MINGW32__)
-/* These functions are considered non-standard */
-inline int access(const char *pathname, int mode) {
-  return _access(pathname, mode);
-}
-inline int open(const char *pathname, int flags, int mode = 0) {
-  return _open(pathname, flags, mode);
-}
-inline int close(int fd) {
-  return _close(fd);
-}
-inline ssize_t read(int fd, void *buf, size_t count) {
-  return _read(fd, buf, count);
-}
-inline ssize_t write(int fd, const void *buf, size_t count) {
-  return _write(fd, buf, count);
-}
-inline off_t lseek(int fd, off_t offset, int whence) {
-  return _lseek(fd, offset, whence);
-}
-inline char *getcwd(char *buf, size_t size) {
-  return _getcwd(buf, size);
-}
-inline int mkdir(const char *pathname, int) {
-  return _mkdir(pathname);
-}
-
-inline FILE *popen(const char *command, const char *type) {
-  return _popen(command, type);
-}
-inline int pclose(FILE *stream) {
-  return _pclose(stream);
-}
-#endif
-
-EXTERN_C PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len);
-
-/* ----------------------------------- SYSTEM/PROCESS */
-
-#ifndef HAVE_PID_T
-typedef int pid_t;
-#endif
-
-#if __STDC__ && !defined(__MINGW32__)
-inline pid_t getpid(void) { return _getpid(); }
-#endif
-inline pid_t getppid(void) { return 0; }
-
-/* Handle case when poll is used to simulate sleep. */
-inline int poll(struct pollfd* fds, int nfds, int timeout) {
-  assert(fds == NULL);
-  assert(nfds == 0);
-  Sleep(timeout);
-  return 0;
-}
-
-EXTERN_C PERFTOOLS_DLL_DECL int getpagesize();   /* in port.cc */
-
-/* ----------------------------------- OTHER */
-
-inline void srandom(unsigned int seed) { srand(seed); }
-inline long random(void) { return rand(); }
-
-#ifndef HAVE_DECL_SLEEP
-#define HAVE_DECL_SLEEP 0
-#endif
-
-#if !HAVE_DECL_SLEEP
-inline unsigned int sleep(unsigned int seconds) {
-  Sleep(seconds * 1000);
-  return 0;
-}
-#endif
-
-// mingw64 seems to define timespec (though mingw.org mingw doesn't),
-// protected by the _TIMESPEC_DEFINED macro.
-#ifndef _TIMESPEC_DEFINED
-struct timespec {
-  int tv_sec;
-  int tv_nsec;
-};
-#endif
-
-#ifndef HAVE_DECL_NANOSLEEP
-#define HAVE_DECL_NANOSLEEP 0
-#endif
-
-// latest mingw64 has nanosleep. Earlier mingw and MSVC do not
-#if !HAVE_DECL_NANOSLEEP
-inline int nanosleep(const struct timespec *req, struct timespec *rem) {
-  Sleep(req->tv_sec * 1000 + req->tv_nsec / 1000000);
-  return 0;
-}
-#endif
-
-#ifndef __MINGW32__
-#if defined(_MSC_VER) && _MSC_VER < 1800
-inline long long int strtoll(const char *nptr, char **endptr, int base) {
-    return _strtoi64(nptr, endptr, base);
-}
-inline unsigned long long int strtoull(const char *nptr, char **endptr,
-                                       int base) {
-    return _strtoui64(nptr, endptr, base);
-}
-inline long long int strtoq(const char *nptr, char **endptr, int base) {
-    return _strtoi64(nptr, endptr, base);
-}
-#endif
-inline unsigned long long int strtouq(const char *nptr, char **endptr,
-                                      int base) {
-    return _strtoui64(nptr, endptr, base);
-}
-inline long long atoll(const char *nptr) {
-  return _atoi64(nptr);
-}
-#endif
-
-#define __THROW throw()
-
-/* ----------------------------------- TCMALLOC-SPECIFIC */
-
-/* tcmalloc.cc calls this so we can patch VirtualAlloc() et al. */
-extern void PatchWindowsFunctions();
-
-#endif  /* _WIN32 */
-
-#undef inline
-#undef EXTERN_C
-
-#endif  /* GOOGLE_BASE_WINDOWS_H_ */
diff --git a/third_party/tcmalloc/vendor/src/windows/preamble_patcher.cc b/third_party/tcmalloc/vendor/src/windows/preamble_patcher.cc
deleted file mode 100644
index 9ce08168..0000000
--- a/third_party/tcmalloc/vendor/src/windows/preamble_patcher.cc
+++ /dev/null
@@ -1,736 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- * Author: Scott Francis
- *
- * Implementation of PreamblePatcher
- */
-
-#include "preamble_patcher.h"
-
-#include "mini_disassembler.h"
-
-// compatibility shims
-#include "base/logging.h"
-
-// Definitions of assembly statements we need
-#define ASM_JMP32REL 0xE9
-#define ASM_INT3 0xCC
-#define ASM_JMP32ABS_0 0xFF
-#define ASM_JMP32ABS_1 0x25
-#define ASM_JMP8REL 0xEB
-#define ASM_JCC32REL_0 0x0F
-#define ASM_JCC32REL_1_MASK 0x80
-#define ASM_NOP 0x90
-// X64 opcodes
-#define ASM_REXW 0x48
-#define ASM_MOVRAX_IMM 0xB8
-#define ASM_JMP 0xFF
-#define ASM_JMP_RAX 0xE0
-
-namespace sidestep {
-
-PreamblePatcher::PreamblePage* PreamblePatcher::preamble_pages_ = NULL;
-long PreamblePatcher::granularity_ = 0;
-long PreamblePatcher::pagesize_ = 0;
-bool PreamblePatcher::initialized_ = false;
-
-static const unsigned int kPreamblePageMagic = 0x4347414D; // "MAGC"
-
-// Handle a special case that we see with functions that point into an
-// IAT table (including functions linked statically into the
-// application): these function already starts with ASM_JMP32*.  For
-// instance, malloc() might be implemented as a JMP to __malloc().
-// This function follows the initial JMPs for us, until we get to the
-// place where the actual code is defined.  If we get to STOP_BEFORE,
-// we return the address before stop_before.  The stop_before_trampoline
-// flag is used in 64-bit mode.  If true, we will return the address
-// before a trampoline is detected.  Trampolines are defined as:
-//
-//    nop
-//    mov rax, <replacement_function>
-//    jmp rax
-//
-// See PreamblePatcher::RawPatchWithStub for more information.
-void* PreamblePatcher::ResolveTargetImpl(unsigned char* target,
-                                         unsigned char* stop_before,
-                                         bool stop_before_trampoline) {
-  if (target == NULL)
-    return NULL;
-  while (1) {
-    unsigned char* new_target;
-    if (target[0] == ASM_JMP32REL) {
-      // target[1-4] holds the place the jmp goes to, but it's
-      // relative to the next instruction.
-      int relative_offset;   // Windows guarantees int is 4 bytes
-      SIDESTEP_ASSERT(sizeof(relative_offset) == 4);
-      memcpy(reinterpret_cast<void*>(&relative_offset),
-             reinterpret_cast<void*>(target + 1), 4);
-      new_target = target + 5 + relative_offset;
-    } else if (target[0] == ASM_JMP8REL) {
-      // Visual Studio 7.1 implements new[] as an 8 bit jump to new
-      signed char relative_offset;
-      memcpy(reinterpret_cast<void*>(&relative_offset),
-             reinterpret_cast<void*>(target + 1), 1);
-      new_target = target + 2 + relative_offset;
-    } else if (target[0] == ASM_JMP32ABS_0 &&
-               target[1] == ASM_JMP32ABS_1) {
-    jmp32rel:
-      // Visual studio seems to sometimes do it this way instead of the
-      // previous way.  Not sure what the rules are, but it was happening
-      // with operator new in some binaries.
-      void** new_target_v;
-      if (kIs64BitBinary) {
-        // In 64-bit mode JMPs are RIP-relative, not absolute
-        int target_offset;
-        memcpy(reinterpret_cast<void*>(&target_offset),
-               reinterpret_cast<void*>(target + 2), 4);
-        new_target_v = reinterpret_cast<void**>(target + target_offset + 6);
-      } else {
-        SIDESTEP_ASSERT(sizeof(new_target) == 4);
-        memcpy(&new_target_v, reinterpret_cast<void*>(target + 2), 4);
-      }
-      new_target = reinterpret_cast<unsigned char*>(*new_target_v);
-    } else if (kIs64BitBinary && target[0] == ASM_REXW
-               && target[1] == ASM_JMP32ABS_0
-               && target[2] == ASM_JMP32ABS_1) {
-      // in Visual Studio 2012 we're seeing jump like that:
-      //   rex.W jmpq *0x11d019(%rip)
-      //
-      // according to docs I have, rex prefix is actually unneeded and
-      // can be ignored. I.e. docs say for jumps like that operand
-      // already defaults to 64-bit. But clearly it breaks abs. jump
-      // detection above and we just skip rex
-      target++;
-      goto jmp32rel;
-    } else {
-      break;
-    }
-    if (new_target == stop_before)
-      break;
-    if (stop_before_trampoline && *new_target == ASM_NOP
-        && new_target[1] == ASM_REXW && new_target[2] == ASM_MOVRAX_IMM)
-      break;
-    target = new_target;
-  }
-  return target;
-}
-
-// Special case scoped_ptr to avoid dependency on scoped_ptr below.
-class DeleteUnsignedCharArray {
- public:
-  DeleteUnsignedCharArray(unsigned char* array) : array_(array) {
-  }
-
-  ~DeleteUnsignedCharArray() {
-    if (array_) {
-      PreamblePatcher::FreePreambleBlock(array_);
-    }
-  }
-
-  unsigned char* Release() {
-    unsigned char* temp = array_;
-    array_ = NULL;
-    return temp;
-  }
-
- private:
-  unsigned char* array_;
-};
-
-SideStepError PreamblePatcher::RawPatchWithStubAndProtections(
-    void* target_function, void *replacement_function,
-    unsigned char* preamble_stub, unsigned long stub_size,
-    unsigned long* bytes_needed) {
-  // We need to be able to write to a process-local copy of the first
-  // MAX_PREAMBLE_STUB_SIZE bytes of target_function
-  DWORD old_target_function_protect = 0;
-  BOOL succeeded = ::VirtualProtect(reinterpret_cast<void*>(target_function),
-                                    MAX_PREAMBLE_STUB_SIZE,
-                                    PAGE_EXECUTE_READWRITE,
-                                    &old_target_function_protect);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to make page containing target function "
-                    "copy-on-write.");
-    return SIDESTEP_ACCESS_DENIED;
-  }
-
-  SideStepError error_code = RawPatchWithStub(target_function,
-                                              replacement_function,
-                                              preamble_stub,
-                                              stub_size,
-                                              bytes_needed);
-
-  // Restore the protection of the first MAX_PREAMBLE_STUB_SIZE bytes of
-  // pTargetFunction to what they were before we started goofing around.
-  // We do this regardless of whether the patch succeeded or not.
-  succeeded = ::VirtualProtect(reinterpret_cast<void*>(target_function),
-                               MAX_PREAMBLE_STUB_SIZE,
-                               old_target_function_protect,
-                               &old_target_function_protect);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false &&
-                    "Failed to restore protection to target function.");
-    // We must not return an error here because the function has
-    // likely actually been patched, and returning an error might
-    // cause our client code not to unpatch it.  So we just keep
-    // going.
-  }
-
-  if (SIDESTEP_SUCCESS != error_code) {  // Testing RawPatchWithStub, above
-    SIDESTEP_ASSERT(false);
-    return error_code;
-  }
-
-  // Flush the instruction cache to make sure the processor doesn't execute the
-  // old version of the instructions (before our patch).
-  //
-  // FlushInstructionCache is actually a no-op at least on
-  // single-processor XP machines.  I'm not sure why this is so, but
-  // it is, yet I want to keep the call to the API here for
-  // correctness in case there is a difference in some variants of
-  // Windows/hardware.
-  succeeded = ::FlushInstructionCache(::GetCurrentProcess(),
-                                      target_function,
-                                      MAX_PREAMBLE_STUB_SIZE);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to flush instruction cache.");
-    // We must not return an error here because the function has actually
-    // been patched, and returning an error would likely cause our client
-    // code not to unpatch it.  So we just keep going.
-  }
-
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::RawPatch(void* target_function,
-                                        void* replacement_function,
-                                        void** original_function_stub) {
-  if (!target_function || !replacement_function || !original_function_stub ||
-      (*original_function_stub) || target_function == replacement_function) {
-    SIDESTEP_ASSERT(false && "Preconditions not met");
-    return SIDESTEP_INVALID_PARAMETER;
-  }
-
-  BOOL succeeded = FALSE;
-
-  // First, deal with a special case that we see with functions that
-  // point into an IAT table (including functions linked statically
-  // into the application): these function already starts with
-  // ASM_JMP32REL.  For instance, malloc() might be implemented as a
-  // JMP to __malloc().  In that case, we replace the destination of
-  // the JMP (__malloc), rather than the JMP itself (malloc).  This
-  // way we get the correct behavior no matter how malloc gets called.
-  void* new_target = ResolveTarget(target_function);
-  if (new_target != target_function) {
-    target_function = new_target;
-  }
-
-  // In 64-bit mode, preamble_stub must be within 2GB of target function
-  // so that if target contains a jump, we can translate it.
-  unsigned char* preamble_stub = AllocPreambleBlockNear(target_function);
-  if (!preamble_stub) {
-    SIDESTEP_ASSERT(false && "Unable to allocate preamble-stub.");
-    return SIDESTEP_INSUFFICIENT_BUFFER;
-  }
-
-  // Frees the array at end of scope.
-  DeleteUnsignedCharArray guard_preamble_stub(preamble_stub);
-
-  SideStepError error_code = RawPatchWithStubAndProtections(
-      target_function, replacement_function, preamble_stub,
-      MAX_PREAMBLE_STUB_SIZE, NULL);
-
-  if (SIDESTEP_SUCCESS != error_code) {
-    SIDESTEP_ASSERT(false);
-    return error_code;
-  }
-
-  // Flush the instruction cache to make sure the processor doesn't execute the
-  // old version of the instructions (before our patch).
-  //
-  // FlushInstructionCache is actually a no-op at least on
-  // single-processor XP machines.  I'm not sure why this is so, but
-  // it is, yet I want to keep the call to the API here for
-  // correctness in case there is a difference in some variants of
-  // Windows/hardware.
-  succeeded = ::FlushInstructionCache(::GetCurrentProcess(),
-                                      target_function,
-                                      MAX_PREAMBLE_STUB_SIZE);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to flush instruction cache.");
-    // We must not return an error here because the function has actually
-    // been patched, and returning an error would likely cause our client
-    // code not to unpatch it.  So we just keep going.
-  }
-
-  SIDESTEP_LOG("PreamblePatcher::RawPatch successfully patched.");
-
-  // detach the scoped pointer so the memory is not freed
-  *original_function_stub =
-      reinterpret_cast<void*>(guard_preamble_stub.Release());
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::Unpatch(void* target_function,
-                                       void* replacement_function,
-                                       void* original_function_stub) {
-  SIDESTEP_ASSERT(target_function && replacement_function &&
-                  original_function_stub);
-  if (!target_function || !replacement_function ||
-      !original_function_stub) {
-    return SIDESTEP_INVALID_PARAMETER;
-  }
-
-  // Before unpatching, target_function should be a JMP to
-  // replacement_function.  If it's not, then either it's an error, or
-  // we're falling into the case where the original instruction was a
-  // JMP, and we patched the jumped_to address rather than the JMP
-  // itself.  (For instance, if malloc() is just a JMP to __malloc(),
-  // we patched __malloc() and not malloc().)
-  unsigned char* target = reinterpret_cast<unsigned char*>(target_function);
-  target = reinterpret_cast<unsigned char*>(
-      ResolveTargetImpl(
-          target, reinterpret_cast<unsigned char*>(replacement_function),
-          true));
-  // We should end at the function we patched.  When we patch, we insert
-  // a ASM_JMP32REL instruction, so look for that as a sanity check.
-  if (target[0] != ASM_JMP32REL) {
-    SIDESTEP_ASSERT(false &&
-                    "target_function does not look like it was patched.");
-    return SIDESTEP_INVALID_PARAMETER;
-  }
-
-  const unsigned int kRequiredTargetPatchBytes = 5;
-
-  // We need to be able to write to a process-local copy of the first
-  // kRequiredTargetPatchBytes bytes of target_function
-  DWORD old_target_function_protect = 0;
-  BOOL succeeded = ::VirtualProtect(reinterpret_cast<void*>(target),
-                                    kRequiredTargetPatchBytes,
-                                    PAGE_EXECUTE_READWRITE,
-                                    &old_target_function_protect);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to make page containing target function "
-                    "copy-on-write.");
-    return SIDESTEP_ACCESS_DENIED;
-  }
-
-  unsigned char* preamble_stub = reinterpret_cast<unsigned char*>(
-                                   original_function_stub);
-
-  // Disassemble the preamble of stub and copy the bytes back to target.
-  // If we've done any conditional jumps in the preamble we need to convert
-  // them back to the original REL8 jumps in the target.
-  MiniDisassembler disassembler;
-  unsigned int preamble_bytes = 0;
-  unsigned int target_bytes = 0;
-  while (target_bytes < kRequiredTargetPatchBytes) {
-    unsigned int cur_bytes = 0;
-    InstructionType instruction_type =
-        disassembler.Disassemble(preamble_stub + preamble_bytes, cur_bytes);
-    if (IT_JUMP == instruction_type) {
-      unsigned int jump_bytes = 0;
-      SideStepError jump_ret = SIDESTEP_JUMP_INSTRUCTION;
-      if (IsNearConditionalJump(preamble_stub + preamble_bytes, cur_bytes) ||
-          IsNearRelativeJump(preamble_stub + preamble_bytes, cur_bytes) ||
-          IsNearAbsoluteCall(preamble_stub + preamble_bytes, cur_bytes) ||
-          IsNearRelativeCall(preamble_stub + preamble_bytes, cur_bytes)) {
-        jump_ret = PatchNearJumpOrCall(preamble_stub + preamble_bytes, 
-                                       cur_bytes, target + target_bytes, 
-                                       &jump_bytes, MAX_PREAMBLE_STUB_SIZE);
-      }
-      if (jump_ret == SIDESTEP_JUMP_INSTRUCTION) {
-        SIDESTEP_ASSERT(false &&
-                        "Found unsupported jump instruction in stub!!");
-        return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-      }
-      target_bytes += jump_bytes;
-    } else if (IT_GENERIC == instruction_type) {
-      if (IsMovWithDisplacement(preamble_stub + preamble_bytes, cur_bytes)) {
-        unsigned int mov_bytes = 0;
-        if (PatchMovWithDisplacement(preamble_stub + preamble_bytes, cur_bytes,
-                                     target + target_bytes, &mov_bytes,
-                                     MAX_PREAMBLE_STUB_SIZE)
-                                     != SIDESTEP_SUCCESS) {
-          SIDESTEP_ASSERT(false &&
-                          "Found unsupported generic instruction in stub!!");
-          return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-        }
-      } else {
-        memcpy(reinterpret_cast<void*>(target + target_bytes),
-               reinterpret_cast<void*>(reinterpret_cast<unsigned char*>(
-                   original_function_stub) + preamble_bytes), cur_bytes);
-        target_bytes += cur_bytes;
-      }
-    } else {
-      SIDESTEP_ASSERT(false &&
-                      "Found unsupported instruction in stub!!");
-      return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-    }
-    preamble_bytes += cur_bytes;
-  }
-
-  FreePreambleBlock(reinterpret_cast<unsigned char*>(original_function_stub));
-
-  // Restore the protection of the first kRequiredTargetPatchBytes bytes of
-  // target to what they were before we started goofing around.
-  succeeded = ::VirtualProtect(reinterpret_cast<void*>(target),
-                               kRequiredTargetPatchBytes,
-                               old_target_function_protect,
-                               &old_target_function_protect);
-
-  // Flush the instruction cache to make sure the processor doesn't execute the
-  // old version of the instructions (before our patch).
-  //
-  // See comment on FlushInstructionCache elsewhere in this file.
-  succeeded = ::FlushInstructionCache(::GetCurrentProcess(),
-                                      target,
-                                      MAX_PREAMBLE_STUB_SIZE);
-  if (!succeeded) {
-    SIDESTEP_ASSERT(false && "Failed to flush instruction cache.");
-    return SIDESTEP_UNEXPECTED;
-  }
-
-  SIDESTEP_LOG("PreamblePatcher::Unpatch successfully unpatched.");
-  return SIDESTEP_SUCCESS;
-}
-
-void PreamblePatcher::Initialize() {
-  if (!initialized_) {
-    SYSTEM_INFO si = { 0 };
-    ::GetSystemInfo(&si);
-    granularity_ = si.dwAllocationGranularity;
-    pagesize_ = si.dwPageSize;
-    initialized_ = true;
-  }
-}
-
-unsigned char* PreamblePatcher::AllocPreambleBlockNear(void* target) {
-  PreamblePage* preamble_page = preamble_pages_;
-  while (preamble_page != NULL) {
-    if (preamble_page->free_ != NULL) {
-      __int64 val = reinterpret_cast<__int64>(preamble_page) -
-          reinterpret_cast<__int64>(target);
-      if ((val > 0 && val + pagesize_ <= INT_MAX) ||
-          (val < 0 && val >= INT_MIN)) {
-        break;
-      }
-    }
-    preamble_page = preamble_page->next_;
-  }
-
-  // The free_ member of the page is used to store the next available block
-  // of memory to use or NULL if there are no chunks available, in which case
-  // we'll allocate a new page.
-  if (preamble_page == NULL || preamble_page->free_ == NULL) {
-    // Create a new preamble page and initialize the free list
-    preamble_page = reinterpret_cast<PreamblePage*>(AllocPageNear(target));
-    SIDESTEP_ASSERT(preamble_page != NULL && "Could not allocate page!");
-    void** pp = &preamble_page->free_;
-    unsigned char* ptr = reinterpret_cast<unsigned char*>(preamble_page) +
-        MAX_PREAMBLE_STUB_SIZE;
-    unsigned char* limit = reinterpret_cast<unsigned char*>(preamble_page) +
-        pagesize_;
-    while (ptr < limit) {
-      *pp = ptr;
-      pp = reinterpret_cast<void**>(ptr);
-      ptr += MAX_PREAMBLE_STUB_SIZE;
-    }
-    *pp = NULL;
-    // Insert the new page into the list
-    preamble_page->magic_ = kPreamblePageMagic;
-    preamble_page->next_ = preamble_pages_;
-    preamble_pages_ = preamble_page;
-  }
-  unsigned char* ret = reinterpret_cast<unsigned char*>(preamble_page->free_);
-  preamble_page->free_ = *(reinterpret_cast<void**>(preamble_page->free_));
-  return ret;
-}
-
-void PreamblePatcher::FreePreambleBlock(unsigned char* block) {
-  SIDESTEP_ASSERT(block != NULL);
-  SIDESTEP_ASSERT(granularity_ != 0);
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(block);
-  ptr -= ptr & (granularity_ - 1);
-  PreamblePage* preamble_page = reinterpret_cast<PreamblePage*>(ptr);
-  SIDESTEP_ASSERT(preamble_page->magic_ == kPreamblePageMagic);
-  *(reinterpret_cast<void**>(block)) = preamble_page->free_;
-  preamble_page->free_ = block;
-}
-
-void* PreamblePatcher::AllocPageNear(void* target) {
-  MEMORY_BASIC_INFORMATION mbi = { 0 };
-  if (!::VirtualQuery(target, &mbi, sizeof(mbi))) {
-    SIDESTEP_ASSERT(false && "VirtualQuery failed on target address");
-    return 0;
-  }
-  if (initialized_ == false) {
-    PreamblePatcher::Initialize();
-    SIDESTEP_ASSERT(initialized_);
-  }
-  void* pv = NULL;
-  unsigned char* allocation_base = reinterpret_cast<unsigned char*>(
-      mbi.AllocationBase);
-  __int64 i = 1;
-  bool high_target = reinterpret_cast<__int64>(target) > UINT_MAX;
-  while (pv == NULL) {
-    __int64 val = reinterpret_cast<__int64>(allocation_base) -
-        (i * granularity_);
-    if (high_target &&
-        reinterpret_cast<__int64>(target) - val > INT_MAX) {
-        // We're further than 2GB from the target
-      break;
-    } else if (val <= 0) {
-      // Less than 0
-      break;
-    }
-    pv = ::VirtualAlloc(reinterpret_cast<void*>(allocation_base -
-                            (i++ * granularity_)),
-                        pagesize_, MEM_COMMIT | MEM_RESERVE,
-                        PAGE_EXECUTE_READWRITE);
-  }
-
-  // We couldn't allocate low, try to allocate high
-  if (pv == NULL) {
-    i = 1;
-    // Round up to the next multiple of page granularity
-    allocation_base = reinterpret_cast<unsigned char*>(
-        (reinterpret_cast<__int64>(target) &
-        (~(granularity_ - 1))) + granularity_);
-    while (pv == NULL) {
-      __int64 val = reinterpret_cast<__int64>(allocation_base) +
-          (i * granularity_) - reinterpret_cast<__int64>(target);
-      if (val > INT_MAX || val < 0) {
-        // We're too far or we overflowed
-        break;
-      }
-      pv = ::VirtualAlloc(reinterpret_cast<void*>(allocation_base +
-                              (i++ * granularity_)),
-                          pagesize_, MEM_COMMIT | MEM_RESERVE,
-                          PAGE_EXECUTE_READWRITE);
-    }
-  }
-  return pv;
-}
-
-bool PreamblePatcher::IsShortConditionalJump(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return (*(target) & 0x70) == 0x70 && instruction_size == 2;
-}
-
-bool PreamblePatcher::IsShortJump(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return target[0] == 0xeb && instruction_size == 2;
-}
-
-bool PreamblePatcher::IsNearConditionalJump(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return *(target) == 0xf && (*(target + 1) & 0x80) == 0x80 &&
-      instruction_size == 6;
-}
-
-bool PreamblePatcher::IsNearRelativeJump(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return *(target) == 0xe9 && instruction_size == 5;
-}
-
-bool PreamblePatcher::IsNearAbsoluteCall(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return *(target) == 0xff && (*(target + 1) & 0x10) == 0x10 &&
-      instruction_size == 6;
-}
-
-bool PreamblePatcher::IsNearRelativeCall(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  return *(target) == 0xe8 && instruction_size == 5;
-}
-
-bool PreamblePatcher::IsMovWithDisplacement(
-    unsigned char* target,
-    unsigned int instruction_size) {
-  // In this case, the ModRM byte's mod field will be 0 and r/m will be 101b (5)
-  return instruction_size == 7 && *target == 0x48 && *(target + 1) == 0x8b &&
-      (*(target + 2) >> 6) == 0 && (*(target + 2) & 0x7) == 5;
-}
-
-SideStepError PreamblePatcher::PatchShortConditionalJump(
-    unsigned char* source,
-    unsigned int instruction_size,
-    unsigned char* target,
-    unsigned int* target_bytes,
-    unsigned int target_size) {
-  // note: rel8 offset is signed. Thus we need to ask for signed char
-  // to negative offsets right
-  unsigned char* original_jump_dest = (source + 2) + static_cast<signed char>(source[1]);
-  unsigned char* stub_jump_from = target + 6;
-  __int64 fixup_jump_offset = original_jump_dest - stub_jump_from;
-  if (fixup_jump_offset > INT_MAX || fixup_jump_offset < INT_MIN) {
-    SIDESTEP_ASSERT(false &&
-                    "Unable to fix up short jump because target"
-                    " is too far away.");
-    return SIDESTEP_JUMP_INSTRUCTION;
-  }
-
-  *target_bytes = 6;
-  if (target_size > *target_bytes) {
-    // Convert the short jump to a near jump.
-    //
-    // 0f 8x xx xx xx xx = Jcc rel32off
-    unsigned short jmpcode = ((0x80 | (source[0] & 0xf)) << 8) | 0x0f;
-    memcpy(reinterpret_cast<void*>(target),
-           reinterpret_cast<void*>(&jmpcode), 2);
-    memcpy(reinterpret_cast<void*>(target + 2),
-           reinterpret_cast<void*>(&fixup_jump_offset), 4);
-  }
-
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::PatchShortJump(
-    unsigned char* source,
-    unsigned int instruction_size,
-    unsigned char* target,
-    unsigned int* target_bytes,
-    unsigned int target_size) {
-  // note: rel8 offset is _signed_. Thus we need signed char here.
-  unsigned char* original_jump_dest = (source + 2) + static_cast<signed char>(source[1]);
-  unsigned char* stub_jump_from = target + 5;
-  __int64 fixup_jump_offset = original_jump_dest - stub_jump_from;
-  if (fixup_jump_offset > INT_MAX || fixup_jump_offset < INT_MIN) {
-    SIDESTEP_ASSERT(false &&
-                    "Unable to fix up short jump because target"
-                    " is too far away.");
-    return SIDESTEP_JUMP_INSTRUCTION;
-  }
-
-  *target_bytes = 5;
-  if (target_size > *target_bytes) {
-    // Convert the short jump to a near jump.
-    //
-    // e9 xx xx xx xx = jmp rel32off
-    target[0] = 0xe9;
-    memcpy(reinterpret_cast<void*>(target + 1),
-           reinterpret_cast<void*>(&fixup_jump_offset), 4);
-  }
-
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::PatchNearJumpOrCall(
-    unsigned char* source,
-    unsigned int instruction_size,
-    unsigned char* target,
-    unsigned int* target_bytes,
-    unsigned int target_size) {
-  SIDESTEP_ASSERT(instruction_size == 5 || instruction_size == 6);
-  unsigned int jmp_offset_in_instruction = instruction_size == 5 ? 1 : 2;
-  unsigned char* original_jump_dest = reinterpret_cast<unsigned char *>(
-      reinterpret_cast<__int64>(source + instruction_size) +
-      *(reinterpret_cast<int*>(source + jmp_offset_in_instruction)));
-  unsigned char* stub_jump_from = target + instruction_size;
-  __int64 fixup_jump_offset = original_jump_dest - stub_jump_from;
-  if (fixup_jump_offset > INT_MAX || fixup_jump_offset < INT_MIN) {
-    SIDESTEP_ASSERT(false &&
-                    "Unable to fix up near jump because target"
-                    " is too far away.");
-    return SIDESTEP_JUMP_INSTRUCTION;
-  }
-
-  if ((fixup_jump_offset < SCHAR_MAX && fixup_jump_offset > SCHAR_MIN)) {
-    *target_bytes = 2;
-    if (target_size > *target_bytes) {
-      // If the new offset is in range, use a short jump instead of a near jump.
-      if (source[0] == ASM_JCC32REL_0 &&
-          (source[1] & ASM_JCC32REL_1_MASK) == ASM_JCC32REL_1_MASK) {
-        unsigned short jmpcode = (static_cast<unsigned char>(
-            fixup_jump_offset) << 8) | (0x70 | (source[1] & 0xf));
-        memcpy(reinterpret_cast<void*>(target),
-               reinterpret_cast<void*>(&jmpcode),
-               2);
-      } else {
-        target[0] = ASM_JMP8REL;
-        target[1] = static_cast<unsigned char>(fixup_jump_offset);
-      }
-    }
-  } else {
-    *target_bytes = instruction_size;
-    if (target_size > *target_bytes) {
-      memcpy(reinterpret_cast<void*>(target),
-             reinterpret_cast<void*>(source),
-             jmp_offset_in_instruction);
-      memcpy(reinterpret_cast<void*>(target + jmp_offset_in_instruction),
-             reinterpret_cast<void*>(&fixup_jump_offset),
-             4);
-    }
-  }
-
-  return SIDESTEP_SUCCESS;
-}
-
-SideStepError PreamblePatcher::PatchMovWithDisplacement(
-     unsigned char* source,
-     unsigned int instruction_size,
-     unsigned char* target,
-     unsigned int* target_bytes,
-     unsigned int target_size) {
-  SIDESTEP_ASSERT(instruction_size == 7);
-  const int mov_offset_in_instruction = 3; // 0x48 0x8b 0x0d <offset>
-  unsigned char* original_mov_dest = reinterpret_cast<unsigned char*>(
-      reinterpret_cast<__int64>(source + instruction_size) +
-      *(reinterpret_cast<int*>(source + mov_offset_in_instruction)));
-  unsigned char* stub_mov_from = target + instruction_size;
-  __int64 fixup_mov_offset = original_mov_dest - stub_mov_from;
-  if (fixup_mov_offset > INT_MAX || fixup_mov_offset < INT_MIN) {
-    SIDESTEP_ASSERT(false &&
-        "Unable to fix up near MOV because target is too far away.");
-    return SIDESTEP_UNEXPECTED;
-  }
-  *target_bytes = instruction_size;
-  if (target_size > *target_bytes) {
-    memcpy(reinterpret_cast<void*>(target),
-           reinterpret_cast<void*>(source),
-           mov_offset_in_instruction);
-    memcpy(reinterpret_cast<void*>(target + mov_offset_in_instruction),
-           reinterpret_cast<void*>(&fixup_mov_offset),
-           4);
-  }
-  return SIDESTEP_SUCCESS;
-}
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/vendor/src/windows/preamble_patcher.h b/third_party/tcmalloc/vendor/src/windows/preamble_patcher.h
deleted file mode 100644
index 76f158a1..0000000
--- a/third_party/tcmalloc/vendor/src/windows/preamble_patcher.h
+++ /dev/null
@@ -1,620 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- * Author: Scott Francis
- *
- * Definition of PreamblePatcher
- */
-
-#ifndef GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
-#define GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
-
-#include "config.h"
-#include <windows.h>
-
-// compatibility shim
-#include "base/logging.h"
-#define SIDESTEP_ASSERT(cond)  RAW_DCHECK(cond, #cond)
-#define SIDESTEP_LOG(msg)      RAW_VLOG(1, msg)
-
-// Maximum size of the preamble stub. We overwrite at least the first 5
-// bytes of the function. Considering the worst case scenario, we need 4
-// bytes + the max instruction size + 5 more bytes for our jump back to
-// the original code. With that in mind, 32 is a good number :)
-#ifdef _M_X64
-// In 64-bit mode we may need more room.  In 64-bit mode all jumps must be
-// within +/-2GB of RIP.  Because of this limitation we may need to use a
-// trampoline to jump to the replacement function if it is further than 2GB
-// away from the target. The trampoline is 14 bytes.
-//
-// So 4 bytes + max instruction size (17 bytes) + 5 bytes to jump back to the
-// original code + trampoline size.  64 bytes is a nice number :-)
-#define MAX_PREAMBLE_STUB_SIZE    (64)
-#else
-#define MAX_PREAMBLE_STUB_SIZE    (32)
-#endif
-
-// Determines if this is a 64-bit binary.
-#ifdef _M_X64
-static const bool kIs64BitBinary = true;
-#else
-static const bool kIs64BitBinary = false;
-#endif
-
-namespace sidestep {
-
-// Possible results of patching/unpatching
-enum SideStepError {
-  SIDESTEP_SUCCESS = 0,
-  SIDESTEP_INVALID_PARAMETER,
-  SIDESTEP_INSUFFICIENT_BUFFER,
-  SIDESTEP_JUMP_INSTRUCTION,
-  SIDESTEP_FUNCTION_TOO_SMALL,
-  SIDESTEP_UNSUPPORTED_INSTRUCTION,
-  SIDESTEP_NO_SUCH_MODULE,
-  SIDESTEP_NO_SUCH_FUNCTION,
-  SIDESTEP_ACCESS_DENIED,
-  SIDESTEP_UNEXPECTED,
-};
-
-#define SIDESTEP_TO_HRESULT(error)                      \
-  MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, error)
-
-class DeleteUnsignedCharArray;
-
-// Implements a patching mechanism that overwrites the first few bytes of
-// a function preamble with a jump to our hook function, which is then
-// able to call the original function via a specially-made preamble-stub
-// that imitates the action of the original preamble.
-//
-// NOTE:  This patching mechanism should currently only be used for
-// non-production code, e.g. unit tests, because it is not threadsafe.
-// See the TODO in preamble_patcher_with_stub.cc for instructions on what
-// we need to do before using it in production code; it's fairly simple
-// but unnecessary for now since we only intend to use it in unit tests.
-//
-// To patch a function, use either of the typesafe Patch() methods.  You
-// can unpatch a function using Unpatch().
-//
-// Typical usage goes something like this:
-// @code
-// typedef int (*MyTypesafeFuncPtr)(int x);
-// MyTypesafeFuncPtr original_func_stub;
-// int MyTypesafeFunc(int x) { return x + 1; }
-// int HookMyTypesafeFunc(int x) { return 1 + original_func_stub(x); }
-// 
-// void MyPatchInitializingFunction() {
-//   original_func_stub = PreamblePatcher::Patch(
-//              MyTypesafeFunc, HookMyTypesafeFunc);
-//   if (!original_func_stub) {
-//     // ... error handling ...
-//   }
-//
-//   // ... continue - you have patched the function successfully ...
-// }
-// @endcode
-//
-// Note that there are a number of ways that this method of patching can
-// fail.  The most common are:
-//    - If there is a jump (jxx) instruction in the first 5 bytes of
-//    the function being patched, we cannot patch it because in the
-//    current implementation we do not know how to rewrite relative
-//    jumps after relocating them to the preamble-stub.  Note that
-//    if you really really need to patch a function like this, it
-//    would be possible to add this functionality (but at some cost).
-//    - If there is a return (ret) instruction in the first 5 bytes
-//    we cannot patch the function because it may not be long enough
-//    for the jmp instruction we use to inject our patch.
-//    - If there is another thread currently executing within the bytes
-//    that are copied to the preamble stub, it will crash in an undefined
-//    way.
-//
-// If you get any other error than the above, you're either pointing the
-// patcher at an invalid instruction (e.g. into the middle of a multi-
-// byte instruction, or not at memory containing executable instructions)
-// or, there may be a bug in the disassembler we use to find
-// instruction boundaries.
-//
-// NOTE:  In optimized builds, when you have very trivial functions that
-// the compiler can reason do not have side effects, the compiler may
-// reuse the result of calling the function with a given parameter, which
-// may mean if you patch the function in between your patch will never get
-// invoked.  See preamble_patcher_test.cc for an example.
-class PERFTOOLS_DLL_DECL PreamblePatcher {
- public:
-
-  // This is a typesafe version of RawPatch(), identical in all other
-  // ways than it takes a template parameter indicating the type of the
-  // function being patched.
-  //
-  // @param T The type of the function you are patching. Usually
-  // you will establish this type using a typedef, as in the following
-  // example:
-  // @code
-  // typedef BOOL (WINAPI *MessageBoxPtr)(HWND, LPCTSTR, LPCTSTR, UINT);
-  // MessageBoxPtr original = NULL;
-  // PreamblePatcher::Patch(MessageBox, Hook_MessageBox, &original);
-  // @endcode
-  template <class T>
-  static SideStepError Patch(T target_function,
-                             T replacement_function,
-                             T* original_function_stub) {
-    // NOTE: casting from a function to a pointer is contra the C++
-    //       spec.  It's not safe on IA64, but is on i386.  We use
-    //       a C-style cast here to emphasize this is not legal C++.
-    return RawPatch((void*)(target_function),
-                    (void*)(replacement_function),
-                    (void**)(original_function_stub));
-  }
-
-  // Patches a named function imported from the named module using
-  // preamble patching.  Uses RawPatch() to do the actual patching
-  // work.
-  //
-  // @param T The type of the function you are patching.  Must
-  // exactly match the function you specify using module_name and
-  // function_name.
-  //
-  // @param module_name The name of the module from which the function
-  // is being imported.  Note that the patch will fail if this module
-  // has not already been loaded into the current process.
-  //
-  // @param function_name The name of the function you wish to patch.
-  //
-  // @param replacement_function Your replacement function which
-  // will be called whenever code tries to call the original function.
-  //
-  // @param original_function_stub Pointer to memory that should receive a
-  // pointer that can be used (e.g. in the replacement function) to call the
-  // original function, or NULL to indicate failure.
-  //
-  // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
-  // indicates success.
-  template <class T>
-  static SideStepError Patch(LPCTSTR module_name,
-                             LPCSTR function_name,
-                             T replacement_function,
-                             T* original_function_stub) {
-    SIDESTEP_ASSERT(module_name && function_name);
-    if (!module_name || !function_name) {
-      SIDESTEP_ASSERT(false &&
-                      "You must specify a module name and function name.");
-      return SIDESTEP_INVALID_PARAMETER;
-    }
-    HMODULE module = ::GetModuleHandle(module_name);
-    SIDESTEP_ASSERT(module != NULL);
-    if (!module) {
-      SIDESTEP_ASSERT(false && "Invalid module name.");
-      return SIDESTEP_NO_SUCH_MODULE;
-    }
-    FARPROC existing_function = ::GetProcAddress(module, function_name);
-    if (!existing_function) {
-      SIDESTEP_ASSERT(
-          false && "Did not find any function with that name in the module.");
-      return SIDESTEP_NO_SUCH_FUNCTION;
-    }
-    // NOTE: casting from a function to a pointer is contra the C++
-    //       spec.  It's not safe on IA64, but is on i386.  We use
-    //       a C-style cast here to emphasize this is not legal C++.
-    return RawPatch((void*)existing_function, (void*)replacement_function,
-                    (void**)(original_function_stub));
-  }
-
-  // Patches a function by overwriting its first few bytes with
-  // a jump to a different function.  This is the "worker" function
-  // for each of the typesafe Patch() functions.  In most cases,
-  // it is preferable to use the Patch() functions rather than
-  // this one as they do more checking at compile time.
-  //
-  // @param target_function A pointer to the function that should be
-  // patched.
-  //
-  // @param replacement_function A pointer to the function that should
-  // replace the target function.  The replacement function must have
-  // exactly the same calling convention and parameters as the original
-  // function.
-  //
-  // @param original_function_stub Pointer to memory that should receive a
-  // pointer that can be used (e.g. in the replacement function) to call the
-  // original function, or NULL to indicate failure.
-  //
-  // @param original_function_stub Pointer to memory that should receive a
-  // pointer that can be used (e.g. in the replacement function) to call the
-  // original function, or NULL to indicate failure.
-  //
-  // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
-  // indicates success.
-  //
-  // @note The preamble-stub (the memory pointed to by
-  // *original_function_stub) is allocated on the heap, and (in
-  // production binaries) never destroyed, resulting in a memory leak.  This
-  // will be the case until we implement safe unpatching of a method.
-  // However, it is quite difficult to unpatch a method (because other
-  // threads in the process may be using it) so we are leaving it for now.
-  // See however UnsafeUnpatch, which can be used for binaries where you
-  // know only one thread is running, e.g. unit tests.
-  static SideStepError RawPatch(void* target_function,
-                                void* replacement_function,
-                                void** original_function_stub);
-
-  // Unpatches target_function and deletes the stub that previously could be
-  // used to call the original version of the function.
-  //
-  // DELETES the stub that is passed to the function.
-  //
-  // @param target_function Pointer to the target function which was
-  // previously patched, i.e. a pointer which value should match the value
-  // of the symbol prior to patching it.
-  //
-  // @param replacement_function Pointer to the function target_function
-  // was patched to.
-  //
-  // @param original_function_stub Pointer to the stub returned when
-  // patching, that could be used to call the original version of the
-  // patched function.  This function will also delete the stub, which after
-  // unpatching is useless.
-  //
-  // If your original call was
-  //    Patch(VirtualAlloc, MyVirtualAlloc, &origptr)
-  // then to undo it you would call
-  //    Unpatch(VirtualAlloc, MyVirtualAlloc, origptr);
-  //
-  // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
-  // indicates success.
-  static SideStepError Unpatch(void* target_function,
-                               void* replacement_function,
-                               void* original_function_stub);
-
-  // A helper routine when patching, which follows jmp instructions at
-  // function addresses, to get to the "actual" function contents.
-  // This allows us to identify two functions that are at different
-  // addresses but actually resolve to the same code.
-  //
-  // @param target_function Pointer to a function.
-  //
-  // @return Either target_function (the input parameter), or if
-  // target_function's body consists entirely of a JMP instruction,
-  // the address it JMPs to (or more precisely, the address at the end
-  // of a chain of JMPs).
-  template <class T>
-  static T ResolveTarget(T target_function) {
-    return (T)ResolveTargetImpl((unsigned char*)target_function, NULL);
-  }
-
-  // Allocates a block of memory of size MAX_PREAMBLE_STUB_SIZE that is as
-  // close (within 2GB) as possible to target.  This is done to ensure that 
-  // we can perform a relative jump from target to a trampoline if the 
-  // replacement function is > +-2GB from target.  This means that we only need 
-  // to patch 5 bytes in the target function.
-  //
-  // @param target    Pointer to target function.
-  //
-  // @return  Returns a block of memory of size MAX_PREAMBLE_STUB_SIZE that can
-  //          be used to store a function preamble block.
-  static unsigned char* AllocPreambleBlockNear(void* target);
-
-  // Frees a block allocated by AllocPreambleBlockNear.
-  //
-  // @param block     Block that was returned by AllocPreambleBlockNear.
-  static void FreePreambleBlock(unsigned char* block);
-
- private:
-  friend class DeleteUnsignedCharArray;
-
-   // Used to store data allocated for preamble stubs
-  struct PreamblePage {
-    unsigned int magic_;
-    PreamblePage* next_;
-    // This member points to a linked list of free blocks within the page
-    // or NULL if at the end
-    void* free_;
-  };
-
-  // In 64-bit mode, the replacement function must be within 2GB of the original
-  // target in order to only require 5 bytes for the function patch.  To meet
-  // this requirement we're creating an allocator within this class to
-  // allocate blocks that are within 2GB of a given target. This member is the
-  // head of a linked list of pages used to allocate blocks that are within
-  // 2GB of the target.
-  static PreamblePage* preamble_pages_;
-  
-  // Page granularity
-  static long granularity_;
-
-  // Page size
-  static long pagesize_;
-
-  // Determines if the patcher has been initialized.
-  static bool initialized_;
-
-  // Used to initialize static members.
-  static void Initialize();
-
-  // Patches a function by overwriting its first few bytes with
-  // a jump to a different function.  This is similar to the RawPatch
-  // function except that it uses the stub allocated by the caller
-  // instead of allocating it.
-  //
-  // We call VirtualProtect to make the
-  // target function writable at least for the duration of the call.
-  //
-  // @param target_function A pointer to the function that should be
-  // patched.
-  //
-  // @param replacement_function A pointer to the function that should
-  // replace the target function.  The replacement function must have
-  // exactly the same calling convention and parameters as the original
-  // function.
-  //
-  // @param preamble_stub A pointer to a buffer where the preamble stub
-  // should be copied. The size of the buffer should be sufficient to
-  // hold the preamble bytes.
-  //
-  // @param stub_size Size in bytes of the buffer allocated for the
-  // preamble_stub
-  //
-  // @param bytes_needed Pointer to a variable that receives the minimum
-  // number of bytes required for the stub.  Can be set to NULL if you're
-  // not interested.
-  //
-  // @return An error code indicating the result of patching.
-  static SideStepError RawPatchWithStubAndProtections(
-      void* target_function,
-      void* replacement_function,
-      unsigned char* preamble_stub,
-      unsigned long stub_size,
-      unsigned long* bytes_needed);
-
-  // A helper function used by RawPatchWithStubAndProtections -- it
-  // does everything but the VirtualProtect work.  Defined in
-  // preamble_patcher_with_stub.cc.
-  //
-  // @param target_function A pointer to the function that should be
-  // patched.
-  //
-  // @param replacement_function A pointer to the function that should
-  // replace the target function.  The replacement function must have
-  // exactly the same calling convention and parameters as the original
-  // function.
-  //
-  // @param preamble_stub A pointer to a buffer where the preamble stub
-  // should be copied. The size of the buffer should be sufficient to
-  // hold the preamble bytes.
-  //
-  // @param stub_size Size in bytes of the buffer allocated for the
-  // preamble_stub
-  //
-  // @param bytes_needed Pointer to a variable that receives the minimum
-  // number of bytes required for the stub.  Can be set to NULL if you're
-  // not interested.
-  //
-  // @return An error code indicating the result of patching.
-  static SideStepError RawPatchWithStub(void* target_function,
-                                        void* replacement_function,
-                                        unsigned char* preamble_stub,
-                                        unsigned long stub_size,
-                                        unsigned long* bytes_needed);
-
-
-  // A helper routine when patching, which follows jmp instructions at
-  // function addresses, to get to the "actual" function contents.
-  // This allows us to identify two functions that are at different
-  // addresses but actually resolve to the same code.
-  //
-  // @param target_function Pointer to a function.
-  //
-  // @param stop_before If, when following JMP instructions from
-  // target_function, we get to the address stop, we return
-  // immediately, the address that jumps to stop_before.
-  //
-  // @param stop_before_trampoline  When following JMP instructions from 
-  // target_function, stop before a trampoline is detected.  See comment in
-  // PreamblePatcher::RawPatchWithStub for more information.  This parameter 
-  // has no effect in 32-bit mode.
-  //
-  // @return Either target_function (the input parameter), or if
-  // target_function's body consists entirely of a JMP instruction,
-  // the address it JMPs to (or more precisely, the address at the end
-  // of a chain of JMPs).
-  static void* ResolveTargetImpl(unsigned char* target_function,
-                                 unsigned char* stop_before,
-                                 bool stop_before_trampoline = false);
-
-  // Helper routine that attempts to allocate a page as close (within 2GB)
-  // as possible to target.
-  //
-  // @param target    Pointer to target function.
-  //
-  // @return   Returns an address that is within 2GB of target.
-  static void* AllocPageNear(void* target);
-
-  // Helper routine that determines if a target instruction is a short
-  // conditional jump.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a short conditional jump.
-  static bool IsShortConditionalJump(unsigned char* target,
-                                     unsigned int instruction_size);
-
-  static bool IsShortJump(unsigned char *target, unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a near
-  // conditional jump.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a near conditional jump.
-  static bool IsNearConditionalJump(unsigned char* target,
-                                    unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a near
-  // relative jump.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a near absolute jump.
-  static bool IsNearRelativeJump(unsigned char* target,
-                                 unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a near 
-  // absolute call.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a near absolute call.
-  static bool IsNearAbsoluteCall(unsigned char* target,
-                                 unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a near 
-  // absolute call.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a near absolute call.
-  static bool IsNearRelativeCall(unsigned char* target,
-                                 unsigned int instruction_size);
-
-  // Helper routine that determines if a target instruction is a 64-bit MOV
-  // that uses a RIP-relative displacement.
-  //
-  // @param target            Pointer to instruction.
-  //
-  // @param instruction_size  Size of the instruction in bytes.
-  //
-  // @return  Returns true if the instruction is a MOV with displacement.
-  static bool IsMovWithDisplacement(unsigned char* target,
-                                    unsigned int instruction_size);
-
-  // Helper routine that converts a short conditional jump instruction
-  // to a near conditional jump in a target buffer.  Note that the target
-  // buffer must be within 2GB of the source for the near jump to work.
-  //
-  // A short conditional jump instruction is in the format:
-  // 7x xx = Jcc rel8off
-  //
-  // @param source              Pointer to instruction.
-  //
-  // @param instruction_size    Size of the instruction.
-  //
-  // @param target              Target buffer to write the new instruction.
-  //
-  // @param target_bytes        Pointer to a buffer that contains the size
-  //                            of the target instruction, in bytes.
-  //
-  // @param target_size         Size of the target buffer.
-  //
-  // @return  Returns SIDESTEP_SUCCESS if successful, otherwise an error.
-  static SideStepError PatchShortConditionalJump(unsigned char* source,
-                                                 unsigned int instruction_size,
-                                                 unsigned char* target,
-                                                 unsigned int* target_bytes,
-                                                 unsigned int target_size);
-
-  static SideStepError PatchShortJump(unsigned char* source,
-                                      unsigned int instruction_size,
-                                      unsigned char* target,
-                                      unsigned int* target_bytes,
-                                      unsigned int target_size);
-
-  // Helper routine that converts an instruction that will convert various
-  // jump-like instructions to corresponding instructions in the target buffer.
-  // What this routine does is fix up the relative offsets contained in jump
-  // instructions to point back to the original target routine.  Like with
-  // PatchShortConditionalJump, the target buffer must be within 2GB of the
-  // source.
-  //
-  // We currently handle the following instructions:
-  //
-  // E9 xx xx xx xx     = JMP rel32off
-  // 0F 8x xx xx xx xx  = Jcc rel32off
-  // FF /2 xx xx xx xx  = CALL reg/mem32/mem64
-  // E8 xx xx xx xx     = CALL rel32off
-  //
-  // It should not be hard to update this function to support other
-  // instructions that jump to relative targets.
-  //
-  // @param source              Pointer to instruction.
-  //
-  // @param instruction_size    Size of the instruction.
-  //
-  // @param target              Target buffer to write the new instruction.
-  //
-  // @param target_bytes        Pointer to a buffer that contains the size
-  //                            of the target instruction, in bytes.
-  //
-  // @param target_size         Size of the target buffer.
-  //
-  // @return  Returns SIDESTEP_SUCCESS if successful, otherwise an error.
-  static SideStepError PatchNearJumpOrCall(unsigned char* source,
-                                           unsigned int instruction_size,
-                                           unsigned char* target,
-                                           unsigned int* target_bytes,
-                                           unsigned int target_size);
-  
-  // Helper routine that patches a 64-bit MOV instruction with a RIP-relative
-  // displacement.  The target buffer must be within 2GB of the source.
-  //
-  // 48 8B 0D XX XX XX XX = MOV rel32off
-  //
-  // @param source              Pointer to instruction.
-  //
-  // @param instruction_size    Size of the instruction.
-  //
-  // @param target              Target buffer to write the new instruction.
-  //
-  // @param target_bytes        Pointer to a buffer that contains the size
-  //                            of the target instruction, in bytes.
-  //
-  // @param target_size         Size of the target buffer.
-  //
-  // @return  Returns SIDESTEP_SUCCESS if successful, otherwise an error.
-  static SideStepError PatchMovWithDisplacement(unsigned char* source,
-                                                unsigned int instruction_size,
-                                                unsigned char* target,
-                                                unsigned int* target_bytes,
-                                                unsigned int target_size);
-};
-
-};  // namespace sidestep
-
-#endif  // GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
diff --git a/third_party/tcmalloc/vendor/src/windows/preamble_patcher_test.cc b/third_party/tcmalloc/vendor/src/windows/preamble_patcher_test.cc
deleted file mode 100644
index e4605c6..0000000
--- a/third_party/tcmalloc/vendor/src/windows/preamble_patcher_test.cc
+++ /dev/null
@@ -1,368 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2011, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- * Author: Scott Francis
- *
- * Unit tests for PreamblePatcher
- */
-
-#include "config_for_unittests.h"
-#include "preamble_patcher.h"
-#include "mini_disassembler.h"
-#pragma warning(push)
-#pragma warning(disable:4553)
-#include "auto_testing_hook.h"
-#pragma warning(pop)
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <tchar.h>
-
-// Turning off all optimizations for this file, since the official build's
-// "Whole program optimization" seems to cause the TestPatchUsingDynamicStub
-// test to crash with an access violation.  We debugged this and found
-// that the optimized access a register that is changed by a call to the hook
-// function.
-#pragma optimize("", off)
-
-// A convenience macro to avoid a lot of casting in the tests.
-// I tried to make this a templated function, but windows complained:
-//     error C2782: 'sidestep::SideStepError `anonymous-namespace'::Unpatch(T,T,T *)' : template parameter 'T' is ambiguous
-//        could be 'int (int)'
-//        or       'int (__cdecl *)(int)'
-// My life isn't long enough to try to figure out how to fix this.
-#define UNPATCH(target_function, replacement_function, original_function_stub) \
-  sidestep::PreamblePatcher::Unpatch((void*)(target_function),          \
-                                     (void*)(replacement_function),     \
-                                     (void*)(original_function))
-
-namespace {
-
-// Function for testing - this is what we patch
-//
-// NOTE:  Because of the way the compiler optimizes this function in
-// release builds, we need to use a different input value every time we
-// call it within a function, otherwise the compiler will just reuse the
-// last calculated incremented value.
-int __declspec(noinline) IncrementNumber(int i) {
-#ifdef _M_X64
-  __int64 i2 = i + 1;
-  return (int) i2;
-#else
-   return i + 1;
-#endif
-}
-
-extern "C" int TooShortFunction(int);
-
-extern "C" int JumpShortCondFunction(int);
-
-extern "C" int JumpNearCondFunction(int);
-
-extern "C" int JumpAbsoluteFunction(int);
-
-extern "C" int CallNearRelativeFunction(int);
-
-typedef int (*IncrementingFunc)(int);
-IncrementingFunc original_function = NULL;
-
-int HookIncrementNumber(int i) {
-  SIDESTEP_ASSERT(original_function != NULL);
-  int incremented_once = original_function(i);
-  return incremented_once + 1;
-}
-
-// For the AutoTestingHook test, we can't use original_function, because
-// all that is encapsulated.
-// This function "increments" by 10, just to set it apart from the other
-// functions.
-int __declspec(noinline) AutoHookIncrementNumber(int i) {
-  return i + 10;
-}
-
-};  // namespace
-
-namespace sidestep {
-
-bool TestDisassembler() {
-   unsigned int instruction_size = 0;
-   sidestep::MiniDisassembler disassembler;
-   void * target = reinterpret_cast<unsigned char *>(IncrementNumber);
-   void * new_target = PreamblePatcher::ResolveTarget(target);
-   if (target != new_target)
-      target = new_target;
-
-   while (1) {
-      sidestep::InstructionType instructionType = disassembler.Disassemble(
-         reinterpret_cast<unsigned char *>(target) + instruction_size,
-         instruction_size);
-      if (sidestep::IT_RETURN == instructionType) {
-         return true;
-      }
-   }
-}
-
-bool TestPatchWithLongJump() {
-  original_function = NULL;
-  void *p = ::VirtualAlloc(reinterpret_cast<void *>(0x0000020000000000), 4096,
-                           MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
-  SIDESTEP_EXPECT_TRUE(p != NULL);
-  memset(p, 0xcc, 4096);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(IncrementNumber,
-                                                        (IncrementingFunc) p,
-                                                        &original_function));
-  SIDESTEP_ASSERT((*original_function)(1) == 2);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(IncrementNumber,
-                               (IncrementingFunc)p,
-                               original_function));
-  ::VirtualFree(p, 0, MEM_RELEASE);
-  return true;
-}
-
-bool TestPatchWithPreambleShortCondJump() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(JumpShortCondFunction,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  (*original_function)(1);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(JumpShortCondFunction,
-                               (void*)HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool TestPatchWithPreambleNearRelativeCondJump() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(JumpNearCondFunction,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  (*original_function)(0);
-  (*original_function)(1);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(JumpNearCondFunction,
-                               HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool TestPatchWithPreambleAbsoluteJump() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(JumpAbsoluteFunction,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  (*original_function)(0);
-  (*original_function)(1);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(JumpAbsoluteFunction,
-                               HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool TestPatchWithPreambleNearRelativeCall() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(
-                                                    CallNearRelativeFunction,
-                                                    HookIncrementNumber,
-                                                    &original_function));
-  (*original_function)(0);
-  (*original_function)(1);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(CallNearRelativeFunction,
-                               HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool TestPatchUsingDynamicStub() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 2);
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(IncrementNumber,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  SIDESTEP_EXPECT_TRUE(original_function);
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(2) == 4);
-  SIDESTEP_EXPECT_TRUE(original_function(3) == 4);
-
-  // Clearbox test to see that the function has been patched.
-  sidestep::MiniDisassembler disassembler;
-  unsigned int instruction_size = 0;
-  SIDESTEP_EXPECT_TRUE(sidestep::IT_JUMP == disassembler.Disassemble(
-                           reinterpret_cast<unsigned char*>(IncrementNumber),
-                           instruction_size));
-
-  // Since we patched IncrementNumber, its first statement is a
-  // jmp to the hook function.  So verify that we now can not patch
-  // IncrementNumber because it starts with a jump.
-#if 0
-  IncrementingFunc dummy = NULL;
-  // TODO(joi@chromium.org): restore this test once flag is added to
-  // disable JMP following
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_JUMP_INSTRUCTION ==
-                       sidestep::PreamblePatcher::Patch(IncrementNumber,
-                                                        HookIncrementNumber,
-                                                        &dummy));
-
-  // This test disabled because code in preamble_patcher_with_stub.cc
-  // asserts before returning the error code -- so there is no way
-  // to get an error code here, in debug build.
-  dummy = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_FUNCTION_TOO_SMALL ==
-                       sidestep::PreamblePatcher::Patch(TooShortFunction,
-                                                        HookIncrementNumber,
-                                                        &dummy));
-#endif
-
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(IncrementNumber,
-                               HookIncrementNumber,
-                               original_function));
-  return true;
-}
-
-bool PatchThenUnpatch() {
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       sidestep::PreamblePatcher::Patch(IncrementNumber,
-                                                        HookIncrementNumber,
-                                                        &original_function));
-  SIDESTEP_EXPECT_TRUE(original_function);
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 3);
-  SIDESTEP_EXPECT_TRUE(original_function(2) == 3);
-
-  SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
-                       UNPATCH(IncrementNumber,
-                               HookIncrementNumber,
-                               original_function));
-  original_function = NULL;
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(3) == 4);
-
-  return true;
-}
-
-bool AutoTestingHookTest() {
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 2);
-
-  // Inner scope, so we can test what happens when the AutoTestingHook
-  // goes out of scope
-  {
-    AutoTestingHook hook = MakeTestingHook(IncrementNumber,
-                                           AutoHookIncrementNumber);
-    (void) hook;
-    SIDESTEP_EXPECT_TRUE(IncrementNumber(2) == 12);
-  }
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(3) == 4);
-
-  return true;
-}
-
-bool AutoTestingHookInContainerTest() {
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 2);
-
-  // Inner scope, so we can test what happens when the AutoTestingHook
-  // goes out of scope
-  {
-    AutoTestingHookHolder hook(MakeTestingHookHolder(IncrementNumber,
-                                                     AutoHookIncrementNumber));
-    (void) hook;
-    SIDESTEP_EXPECT_TRUE(IncrementNumber(2) == 12);
-  }
-  SIDESTEP_EXPECT_TRUE(IncrementNumber(3) == 4);
-
-  return true;
-}
-
-bool TestPreambleAllocation() {
-  __int64 diff = 0;
-  void* p1 = reinterpret_cast<void*>(0x110000000);
-  void* p2 = reinterpret_cast<void*>(0x810000000);
-  unsigned char* b1 = PreamblePatcher::AllocPreambleBlockNear(p1);
-  SIDESTEP_EXPECT_TRUE(b1 != NULL);
-  diff = reinterpret_cast<__int64>(p1) - reinterpret_cast<__int64>(b1);
-  // Ensure blocks are within 2GB
-  SIDESTEP_EXPECT_TRUE(diff <= INT_MAX && diff >= INT_MIN);
-  unsigned char* b2 = PreamblePatcher::AllocPreambleBlockNear(p2);
-  SIDESTEP_EXPECT_TRUE(b2 != NULL);
-  diff = reinterpret_cast<__int64>(p2) - reinterpret_cast<__int64>(b2);
-  SIDESTEP_EXPECT_TRUE(diff <= INT_MAX && diff >= INT_MIN);
-
-  // Ensure we're reusing free blocks
-  unsigned char* b3 = b1;
-  unsigned char* b4 = b2;
-  PreamblePatcher::FreePreambleBlock(b1);
-  PreamblePatcher::FreePreambleBlock(b2);
-  b1 = PreamblePatcher::AllocPreambleBlockNear(p1);
-  SIDESTEP_EXPECT_TRUE(b1 == b3);
-  b2 = PreamblePatcher::AllocPreambleBlockNear(p2);
-  SIDESTEP_EXPECT_TRUE(b2 == b4);
-  PreamblePatcher::FreePreambleBlock(b1);
-  PreamblePatcher::FreePreambleBlock(b2);
-
-  return true;
-}
-
-bool UnitTests() {
-  return TestPatchWithPreambleNearRelativeCall() &&
-      TestPatchWithPreambleAbsoluteJump() &&
-      TestPatchWithPreambleNearRelativeCondJump() && 
-      TestPatchWithPreambleShortCondJump() &&
-      TestDisassembler() && TestPatchWithLongJump() &&
-      TestPatchUsingDynamicStub() && PatchThenUnpatch() &&
-      AutoTestingHookTest() && AutoTestingHookInContainerTest() &&
-      TestPreambleAllocation();
-}
-
-};  // namespace sidestep
-
-int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
-  if (size == 0)        // not even room for a \0?
-    return -1;          // not what C99 says to do, but what windows does
-  str[size-1] = '\0';
-  return _vsnprintf(str, size-1, format, ap);
-}
-
-int _tmain(int argc, _TCHAR* argv[])
-{
-  bool ret = sidestep::UnitTests();
-  printf("%s\n", ret ? "PASS" : "FAIL");
-  return ret ? 0 : -1;
-}
-
-#pragma optimize("", on)
diff --git a/third_party/tcmalloc/vendor/src/windows/preamble_patcher_with_stub.cc b/third_party/tcmalloc/vendor/src/windows/preamble_patcher_with_stub.cc
deleted file mode 100644
index 23f9d3a..0000000
--- a/third_party/tcmalloc/vendor/src/windows/preamble_patcher_with_stub.cc
+++ /dev/null
@@ -1,302 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2007, Google Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- * Author: Scott Francis
- *
- * Implementation of PreamblePatcher
- */
-
-#include "preamble_patcher.h"
-
-#include "mini_disassembler.h"
-
-// Definitions of assembly statements we need
-#define ASM_JMP32REL 0xE9
-#define ASM_INT3 0xCC
-#define ASM_NOP 0x90
-// X64 opcodes
-#define ASM_MOVRAX_IMM 0xB8
-#define ASM_REXW 0x48
-#define ASM_JMP 0xFF
-#define ASM_JMP_RAX 0xE0
-#define ASM_PUSH 0x68
-#define ASM_RET 0xC3
-
-namespace sidestep {
-
-SideStepError PreamblePatcher::RawPatchWithStub(
-    void* target_function,
-    void* replacement_function,
-    unsigned char* preamble_stub,
-    unsigned long stub_size,
-    unsigned long* bytes_needed) {
-  if ((NULL == target_function) ||
-      (NULL == replacement_function) ||
-      (NULL == preamble_stub)) {
-    SIDESTEP_ASSERT(false &&
-                    "Invalid parameters - either pTargetFunction or "
-                    "pReplacementFunction or pPreambleStub were NULL.");
-    return SIDESTEP_INVALID_PARAMETER;
-  }
-
-  // TODO(V7:joi) Siggi and I just had a discussion and decided that both
-  // patching and unpatching are actually unsafe.  We also discussed a
-  // method of making it safe, which is to freeze all other threads in the
-  // process, check their thread context to see if their eip is currently
-  // inside the block of instructions we need to copy to the stub, and if so
-  // wait a bit and try again, then unfreeze all threads once we've patched.
-  // Not implementing this for now since we're only using SideStep for unit
-  // testing, but if we ever use it for production code this is what we
-  // should do.
-  //
-  // NOTE: Stoyan suggests we can write 8 or even 10 bytes atomically using
-  // FPU instructions, and on newer processors we could use cmpxchg8b or
-  // cmpxchg16b. So it might be possible to do the patching/unpatching
-  // atomically and avoid having to freeze other threads.  Note though, that
-  // doing it atomically does not help if one of the other threads happens
-  // to have its eip in the middle of the bytes you change while you change
-  // them.
-  unsigned char* target = reinterpret_cast<unsigned char*>(target_function);
-  unsigned int required_trampoline_bytes = 0;
-  const unsigned int kRequiredStubJumpBytes = 5;
-  const unsigned int kRequiredTargetPatchBytes = 5;
-
-  // Initialize the stub with INT3's just in case.
-  if (stub_size) {
-    memset(preamble_stub, 0xcc, stub_size);
-  }
-  if (kIs64BitBinary) {
-    // In 64-bit mode JMP instructions are always relative to RIP.  If the
-    // replacement - target offset is > 2GB, we can't JMP to the replacement
-    // function.  In this case, we're going to use a trampoline - that is,
-    // we're going to do a relative jump to a small chunk of code in the stub
-    // that will then do the absolute jump to the replacement function.  By
-    // doing this, we only need to patch 5 bytes in the target function, as
-    // opposed to patching 12 bytes if we were to do an absolute jump.
-    //
-    // Note that the first byte of the trampoline is a NOP instruction.  This
-    // is used as a trampoline signature that will be detected when unpatching
-    // the function.
-    //
-    // jmp <trampoline>
-    //
-    // trampoline:
-    //    nop
-    //    mov rax, <replacement_function>
-    //    jmp rax
-    //
-    __int64 replacement_target_offset = reinterpret_cast<__int64>(
-        replacement_function) - reinterpret_cast<__int64>(target) - 5;
-    if (replacement_target_offset > INT_MAX
-        || replacement_target_offset < INT_MIN) {
-      // The stub needs to be within 2GB of the target for the trampoline to
-      // work!
-      __int64 trampoline_offset = reinterpret_cast<__int64>(preamble_stub)
-          - reinterpret_cast<__int64>(target) - 5;
-      if (trampoline_offset > INT_MAX || trampoline_offset < INT_MIN) {
-        // We're screwed.
-        SIDESTEP_ASSERT(false 
-                       && "Preamble stub is too far from target to patch.");
-        return SIDESTEP_UNEXPECTED;
-      }
-      required_trampoline_bytes = 13;
-    }
-  }
-
-  // Let's disassemble the preamble of the target function to see if we can
-  // patch, and to see how much of the preamble we need to take.  We need 5
-  // bytes for our jmp instruction, so let's find the minimum number of
-  // instructions to get 5 bytes.
-  MiniDisassembler disassembler;
-  unsigned int preamble_bytes = 0;
-  unsigned int stub_bytes = 0;
-  while (preamble_bytes < kRequiredTargetPatchBytes) {
-    unsigned int cur_bytes = 0;
-    InstructionType instruction_type =
-        disassembler.Disassemble(target + preamble_bytes, cur_bytes);
-    if (IT_JUMP == instruction_type) {
-      unsigned int jump_bytes = 0;
-      SideStepError jump_ret = SIDESTEP_JUMP_INSTRUCTION;
-      if (IsShortConditionalJump(target + preamble_bytes, cur_bytes)) {
-        jump_ret = PatchShortConditionalJump(target + preamble_bytes, cur_bytes,
-                                             preamble_stub + stub_bytes,
-                                             &jump_bytes,
-                                             stub_size - stub_bytes);
-      } else if (IsShortJump(target + preamble_bytes, cur_bytes)) {
-        jump_ret = PatchShortJump(target + preamble_bytes, cur_bytes,
-                                  preamble_stub + stub_bytes,
-                                  &jump_bytes,
-                                  stub_size - stub_bytes);
-      } else if (IsNearConditionalJump(target + preamble_bytes, cur_bytes) ||
-                 IsNearRelativeJump(target + preamble_bytes, cur_bytes) ||
-                 IsNearAbsoluteCall(target + preamble_bytes, cur_bytes) ||
-                 IsNearRelativeCall(target + preamble_bytes, cur_bytes)) {
-         jump_ret = PatchNearJumpOrCall(target + preamble_bytes, cur_bytes,
-                                        preamble_stub + stub_bytes, &jump_bytes,
-                                        stub_size - stub_bytes);
-      }
-      if (jump_ret != SIDESTEP_SUCCESS) {
-        SIDESTEP_ASSERT(false &&
-                        "Unable to patch because there is an unhandled branch "
-                        "instruction in the initial preamble bytes.");
-        return SIDESTEP_JUMP_INSTRUCTION;
-      }
-      stub_bytes += jump_bytes;
-    } else if (IT_RETURN == instruction_type) {
-      SIDESTEP_ASSERT(false &&
-                      "Unable to patch because function is too short");
-      return SIDESTEP_FUNCTION_TOO_SMALL;
-    } else if (IT_GENERIC == instruction_type) {
-      if (IsMovWithDisplacement(target + preamble_bytes, cur_bytes)) {
-        unsigned int mov_bytes = 0;
-        if (PatchMovWithDisplacement(target + preamble_bytes, cur_bytes,
-                                     preamble_stub + stub_bytes, &mov_bytes,
-                                     stub_size - stub_bytes)
-            != SIDESTEP_SUCCESS) {
-          return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-        }
-        stub_bytes += mov_bytes;
-      } else {
-        memcpy(reinterpret_cast<void*>(preamble_stub + stub_bytes),
-               reinterpret_cast<void*>(target + preamble_bytes), cur_bytes);
-        stub_bytes += cur_bytes;
-      }
-    } else {
-      SIDESTEP_ASSERT(false &&
-                      "Disassembler encountered unsupported instruction "
-                      "(either unused or unknown");
-      return SIDESTEP_UNSUPPORTED_INSTRUCTION;
-    }
-    preamble_bytes += cur_bytes;
-  }
-
-  if (NULL != bytes_needed)
-    *bytes_needed = stub_bytes + kRequiredStubJumpBytes
-        + required_trampoline_bytes;
-
-  // Inv: cbPreamble is the number of bytes (at least 5) that we need to take
-  // from the preamble to have whole instructions that are 5 bytes or more
-  // in size total. The size of the stub required is cbPreamble +
-  // kRequiredStubJumpBytes (5) + required_trampoline_bytes (0 or 13)
-  if (stub_bytes + kRequiredStubJumpBytes + required_trampoline_bytes
-      > stub_size) {
-    SIDESTEP_ASSERT(false);
-    return SIDESTEP_INSUFFICIENT_BUFFER;
-  }
-
-  // Now, make a jmp instruction to the rest of the target function (minus the
-  // preamble bytes we moved into the stub) and copy it into our preamble-stub.
-  // find address to jump to, relative to next address after jmp instruction
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4244)
-#endif
-  int relative_offset_to_target_rest
-      = ((reinterpret_cast<unsigned char*>(target) + preamble_bytes) -
-         (preamble_stub + stub_bytes + kRequiredStubJumpBytes));
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-  // jmp (Jump near, relative, displacement relative to next instruction)
-  preamble_stub[stub_bytes] = ASM_JMP32REL;
-  // copy the address
-  memcpy(reinterpret_cast<void*>(preamble_stub + stub_bytes + 1),
-         reinterpret_cast<void*>(&relative_offset_to_target_rest), 4);
-
-  if (kIs64BitBinary && required_trampoline_bytes != 0) {
-    // Construct the trampoline
-    unsigned int trampoline_pos = stub_bytes + kRequiredStubJumpBytes;
-    preamble_stub[trampoline_pos] = ASM_NOP;
-    preamble_stub[trampoline_pos + 1] = ASM_REXW;
-    preamble_stub[trampoline_pos + 2] = ASM_MOVRAX_IMM;
-    memcpy(reinterpret_cast<void*>(preamble_stub + trampoline_pos + 3),
-           reinterpret_cast<void*>(&replacement_function),
-           sizeof(void *));
-    preamble_stub[trampoline_pos + 11] = ASM_JMP;
-    preamble_stub[trampoline_pos + 12] = ASM_JMP_RAX;
-
-    // Now update replacement_function to point to the trampoline
-    replacement_function = preamble_stub + trampoline_pos;
-  }
-
-  // Inv: preamble_stub points to assembly code that will execute the
-  // original function by first executing the first cbPreamble bytes of the
-  // preamble, then jumping to the rest of the function.
-
-  // Overwrite the first 5 bytes of the target function with a jump to our
-  // replacement function.
-  // (Jump near, relative, displacement relative to next instruction)
-  target[0] = ASM_JMP32REL;
-
-  // Find offset from instruction after jmp, to the replacement function.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4244)
-#endif
-  int offset_to_replacement_function =
-      reinterpret_cast<unsigned char*>(replacement_function) -
-      reinterpret_cast<unsigned char*>(target) - 5;
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-  // complete the jmp instruction
-  memcpy(reinterpret_cast<void*>(target + 1),
-         reinterpret_cast<void*>(&offset_to_replacement_function), 4);
-
-  // Set any remaining bytes that were moved to the preamble-stub to INT3 so
-  // as not to cause confusion (otherwise you might see some strange
-  // instructions if you look at the disassembly, or even invalid
-  // instructions). Also, by doing this, we will break into the debugger if
-  // some code calls into this portion of the code.  If this happens, it
-  // means that this function cannot be patched using this patcher without
-  // further thought.
-  if (preamble_bytes > kRequiredTargetPatchBytes) {
-    memset(reinterpret_cast<void*>(target + kRequiredTargetPatchBytes),
-           ASM_INT3, preamble_bytes - kRequiredTargetPatchBytes);
-  }
-
-  // Inv: The memory pointed to by target_function now points to a relative
-  // jump instruction that jumps over to the preamble_stub.  The preamble
-  // stub contains the first stub_size bytes of the original target
-  // function's preamble code, followed by a relative jump back to the next
-  // instruction after the first cbPreamble bytes.
-  //
-  // In 64-bit mode the memory pointed to by target_function *may* point to a
-  // relative jump instruction that jumps to a trampoline which will then
-  // perform an absolute jump to the replacement function.  The preamble stub
-  // still contains the original target function's preamble code, followed by a
-  // jump back to the instructions after the first preamble bytes.
-  //
-  return SIDESTEP_SUCCESS;
-}
-
-};  // namespace sidestep
diff --git a/third_party/tcmalloc/vendor/src/windows/shortproc.asm b/third_party/tcmalloc/vendor/src/windows/shortproc.asm
deleted file mode 100644
index 7e8e3d7..0000000
--- a/third_party/tcmalloc/vendor/src/windows/shortproc.asm
+++ /dev/null
@@ -1,169 +0,0 @@
-; Copyright (c) 2011, Google Inc.
-; All rights reserved.
-; 
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions are
-; met:
-; 
-;     * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-;     * Redistributions in binary form must reproduce the above
-; copyright notice, this list of conditions and the following disclaimer
-; in the documentation and/or other materials provided with the
-; distribution.
-;     * Neither the name of Google Inc. nor the names of its
-; contributors may be used to endorse or promote products derived from
-; this software without specific prior written permission.
-; 
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-;
-; ---
-; Author: Scott Francis
-;
-; Unit tests for PreamblePatcher

- 

-.MODEL small

- 

-.CODE

-

-TooShortFunction PROC

-	ret

-TooShortFunction ENDP

-

-JumpShortCondFunction PROC

-	test cl, 1

-	jnz jumpspot

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-	int 3

-jumpspot:

-	nop

-	nop

-	nop

-	nop

-	mov rax, 1

-	ret

-JumpShortCondFunction ENDP

-

-JumpNearCondFunction PROC

-	test cl, 1

-	jnz jumpspot

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-jumpspot:

-	nop

-	nop

-	mov rax, 1

-	ret

-JumpNearCondFunction ENDP

-

-JumpAbsoluteFunction PROC

-	test cl, 1

-	jmp jumpspot

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-jumpspot:

-	nop

-	nop

-	mov rax, 1

-	ret

-JumpAbsoluteFunction ENDP

-

-CallNearRelativeFunction PROC

-	test cl, 1

-	call TooShortFunction

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	mov rdx, 0ffff1111H

-	nop

-	nop

-	nop

-	ret

-CallNearRelativeFunction ENDP

-

-END

diff --git a/third_party/tcmalloc/vendor/src/windows/system-alloc.cc b/third_party/tcmalloc/vendor/src/windows/system-alloc.cc
deleted file mode 100644
index ea1f17d9..0000000
--- a/third_party/tcmalloc/vendor/src/windows/system-alloc.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (c) 2013, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Petr Hosek
-
-#ifndef _WIN32
-# error You should only be including windows/system-alloc.cc in a windows environment!
-#endif
-
-#include <config.h>
-#include <windows.h>
-#include <algorithm> // std::min
-#include <gperftools/malloc_extension.h>
-#include "base/logging.h"
-#include "base/spinlock.h"
-#include "internal_logging.h"
-#include "system-alloc.h"
-
-static SpinLock spinlock(SpinLock::LINKER_INITIALIZED);
-
-// The current system allocator declaration
-SysAllocator* tcmalloc_sys_alloc = NULL;
-// Number of bytes taken from system.
-size_t TCMalloc_SystemTaken = 0;
-
-class VirtualSysAllocator : public SysAllocator {
-public:
-  VirtualSysAllocator() : SysAllocator() {
-  }
-  void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-};
-static char virtual_space[sizeof(VirtualSysAllocator)];
-
-// This is mostly like MmapSysAllocator::Alloc, except it does these weird
-// munmap's in the middle of the page, which is forbidden in windows.
-void* VirtualSysAllocator::Alloc(size_t size, size_t *actual_size,
-                                 size_t alignment) {
-  // Align on the pagesize boundary
-  const int pagesize = getpagesize();
-  if (alignment < pagesize) alignment = pagesize;
-  size = ((size + alignment - 1) / alignment) * alignment;
-
-  // Report the total number of bytes the OS actually delivered.  This might be
-  // greater than |size| because of alignment concerns.  The full size is
-  // necessary so that adjacent spans can be coalesced.
-  // TODO(antonm): proper processing of alignments
-  // in actual_size and decommitting.
-  if (actual_size) {
-    *actual_size = size;
-  }
-
-  // We currently do not support alignments larger than the pagesize or
-  // alignments that are not multiples of the pagesize after being floored.
-  // If this ability is needed it can be done by the caller (assuming it knows
-  // the page size).
-  assert(alignment <= pagesize);
-
-  void* result = VirtualAlloc(0, size,
-                              MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
-  if (result == NULL)
-    return NULL;
-
-  // If the result is not aligned memory fragmentation will result which can
-  // lead to pathological memory use.
-  assert((reinterpret_cast<uintptr_t>(result) & (alignment - 1)) == 0);
-
-  return result;
-}
-
-#ifdef _MSC_VER
-
-extern "C" SysAllocator* tc_get_sysalloc_override(SysAllocator *def);
-extern "C" SysAllocator* tc_get_sysalloc_default(SysAllocator *def)
-{
-  return def;
-}
-
-#if defined(_M_IX86)
-#pragma comment(linker, "/alternatename:_tc_get_sysalloc_override=_tc_get_sysalloc_default")
-#elif defined(_M_X64)
-#pragma comment(linker, "/alternatename:tc_get_sysalloc_override=tc_get_sysalloc_default")
-#endif
-
-#else // !_MSC_VER
-
-extern "C" ATTRIBUTE_NOINLINE
-SysAllocator* tc_get_sysalloc_override(SysAllocator *def)
-{
-  return def;
-}
-
-#endif
-
-static bool system_alloc_inited = false;
-void InitSystemAllocators(void) {
-  VirtualSysAllocator *alloc = new (virtual_space) VirtualSysAllocator();
-  tcmalloc_sys_alloc = tc_get_sysalloc_override(alloc);
-}
-
-extern PERFTOOLS_DLL_DECL
-void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
-			   size_t alignment) {
-  SpinLockHolder lock_holder(&spinlock);
-
-  if (!system_alloc_inited) {
-    InitSystemAllocators();
-    system_alloc_inited = true;
-  }
-
-  void* result = tcmalloc_sys_alloc->Alloc(size, actual_size, alignment);
-  if (result != NULL) {
-    if (actual_size) {
-      TCMalloc_SystemTaken += *actual_size;
-    } else {
-      TCMalloc_SystemTaken += size;
-    }
-  }
-  return result;
-}
-
-extern PERFTOOLS_DLL_DECL
-bool TCMalloc_SystemRelease(void* start, size_t length) {
-  if (VirtualFree(start, length, MEM_DECOMMIT))
-    return true;
-
-  // The decommit may fail if the memory region consists of allocations
-  // from more than one call to VirtualAlloc.  In this case, fall back to
-  // using VirtualQuery to retrieve the allocation boundaries and decommit
-  // them each individually.
-
-  char* ptr = static_cast<char*>(start);
-  char* end = ptr + length;
-  MEMORY_BASIC_INFORMATION info;
-  while (ptr < end) {
-    size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
-    assert(resultSize == sizeof(info));
-    size_t decommitSize = std::min<size_t>(info.RegionSize, end - ptr);
-    BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT);
-    assert(success == TRUE);
-    ptr += decommitSize;
-  }
-
-  return true;
-}
-
-extern PERFTOOLS_DLL_DECL
-void TCMalloc_SystemCommit(void* start, size_t length) {
-  if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start)
-    return;
-
-  // The commit may fail if the memory region consists of allocations
-  // from more than one call to VirtualAlloc.  In this case, fall back to
-  // using VirtualQuery to retrieve the allocation boundaries and commit them
-  // each individually.
-
-  char* ptr = static_cast<char*>(start);
-  char* end = ptr + length;
-  MEMORY_BASIC_INFORMATION info;
-  while (ptr < end) {
-    size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
-    assert(resultSize == sizeof(info));
-
-    size_t commitSize = std::min<size_t>(info.RegionSize, end - ptr);
-    void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT,
-                                    PAGE_READWRITE);
-    assert(newAddress == ptr);
-    ptr += commitSize;
-  }
-}
-
-bool RegisterSystemAllocator(SysAllocator *allocator, int priority) {
-  return false;   // we don't allow registration on windows, right now
-}
-
-void DumpSystemAllocatorStats(TCMalloc_Printer* printer) {
-  // We don't dump stats on windows, right now
-}
diff --git a/tools/binary_size/libsupersize/viewer/README.md b/tools/binary_size/libsupersize/viewer/README.md
index a511ec4..a25f1ef6 100644
--- a/tools/binary_size/libsupersize/viewer/README.md
+++ b/tools/binary_size/libsupersize/viewer/README.md
@@ -46,7 +46,7 @@
 
 [see here]: https://docs.google.com/document/d/1qstcG9DxtwoohCnslvLs6Z7UfvO-dlkNi0s8PH-HYtI/edit?usp=sharing
 
-## Developer Overview
+## Code Overview
 
 The viewer has no server component beyond static file serving. `.size` files
 are parsed using WebAssembly (`caspian/` directory). The `.wasm` module runs
@@ -54,6 +54,12 @@
 information is sent to the main page via JSON on-demand (when tree nodes
 are expanded).
 
+### Code Style
+
+Code should follow Chrome's [styleguide] where possible.
+
+[styleguide]: https://chromium.googlesource.com/chromium/src/+/main/styleguide/web/web.md
+
 ### static/index.html
 
 This uses JSON files to populate the dropdowns:
diff --git a/tools/binary_size/libsupersize/viewer/caspian/README.md b/tools/binary_size/libsupersize/viewer/caspian/README.md
index 1549197..194fbceb 100644
--- a/tools/binary_size/libsupersize/viewer/caspian/README.md
+++ b/tools/binary_size/libsupersize/viewer/caspian/README.md
@@ -82,3 +82,16 @@
    git pull origin main --tags
    ```
 2.  Update this README's Emscripten version above, then follow its steps.
+
+## Code Overview
+
+Caspian is a port of the Python implementation, and tries as much as possible to
+follow the same patterns and names as the Python. Keeping them as similar as
+possible makes it easier to keep them in sync.
+
+### Code Style
+
+Follow Chrome's C++ [styleguide] where possible. One notable exception is that
+Caspian does not use `//base` due to the current lack of WASM support in it.
+
+[styleguide]: https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++.md
diff --git a/tools/binary_size/libsupersize/viewer/static/shared.js b/tools/binary_size/libsupersize/viewer/static/shared.js
index 16b4a3c..afb4359 100644
--- a/tools/binary_size/libsupersize/viewer/static/shared.js
+++ b/tools/binary_size/libsupersize/viewer/static/shared.js
@@ -38,10 +38,7 @@
 
 /**
  * @typedef {object} TreeProgress
- * @prop {TreeNode} root Root node and its direct children.
  * @prop {number} percent Number from (0-1] to represent percentage.
- * @prop {boolean} diffMode True if we are currently showing the diff of two
- * different size files.
  * @prop {string} [error] Error message, if an error occured in the worker.
  * If unset, then there was no error.
  */
diff --git a/tools/binary_size/libsupersize/viewer/static/start-worker.js b/tools/binary_size/libsupersize/viewer/static/start-worker.js
index c8100361..3fe6383f 100644
--- a/tools/binary_size/libsupersize/viewer/static/start-worker.js
+++ b/tools/binary_size/libsupersize/viewer/static/start-worker.js
@@ -33,6 +33,7 @@
    *
    * @param {string} action
    * @param {any} data
+   * @returns {any}
    */
   _waitForResponse(action, data) {
     const id = ++this._requestId;
@@ -65,24 +66,32 @@
   }
 
   /**
-   * Loads the tree data given on a worker thread and replaces the tree view in
-   * the UI once complete. Uses query string as state for the options.
-   * Use `onProgress` before calling `loadTree`.
+   * Loads a new file.
    * @param {?string=} input
    * @param {?string=} accessToken
-   * @returns {Promise<TreeProgress>}
+   * @returns {Promise<any>}
    */
-  loadTree(input = null, accessToken = null) {
-    return this._waitForResponse('load', {
+  loadAndBuildTree(input = null, accessToken = null) {
+    return this._waitForResponse('loadAndBuildTree', {
       input,
       accessToken,
       options: location.search.slice(1),
     });
   }
+
+  /**
+   * Rebuilds the tree with the current query parameters.
+   * @returns {Promise<any>}
+   */
+  buildTree() {
+    return this._waitForResponse('buildTree', {
+      options: location.search.slice(1),
+    });
+  }
 }
 
 function restartWorker(onProgressHandler) {
-  let innerWorker = new Worker('tree-worker-wasm.js');
+  const innerWorker = new Worker('tree-worker-wasm.js');
   window.supersize.worker = new TreeWorker(innerWorker, onProgressHandler);
   return window.supersize.worker;
 }
diff --git a/tools/binary_size/libsupersize/viewer/static/tree-ui.js b/tools/binary_size/libsupersize/viewer/static/tree-ui.js
index e232102..2682ac1c 100644
--- a/tools/binary_size/libsupersize/viewer/static/tree-ui.js
+++ b/tools/binary_size/libsupersize/viewer/static/tree-ui.js
@@ -405,16 +405,51 @@
   const _dataUrlInput = form.elements.namedItem('load_url');
   const _progress = new ProgressBar('progress');
 
-  /** @type {boolean} */
-  let _doneLoad = false;
-
   /**
-   * Displays the given data as a tree view
-   * @param {TreeProgress} message
+   * @param {!TreeProgress} message
    */
-  function displayTree(message) {
-    const {root, percent, diffMode, error} = message;
+  function onProgressMessage(message) {
+    const {error, percent} = message;
+    _progress.setValue(percent);
+    document.body.classList.toggle('error', Boolean(error));
+  }
+
+  // Process response of an initial load / upload.
+  function processLoadTreeResponse(message) {
+    const {diffMode, beforeBlobUrl, loadBlobUrl, isMultiContainer} =
+        message.loadResults;
+    console.log(
+        '%cPro Tip: %cawait supersize.worker.openNode("$FILE_PATH")',
+        'font-weight:bold;color:red;', '')
+
+    displayOrHideDownloadButton(beforeBlobUrl, loadBlobUrl);
+
     state.set('diff_mode', diffMode ? 'on' : null);
+    document.body.classList.toggle('diff', Boolean(diffMode));
+    const noSymbols = Object.keys(root.childStats).length === 0;
+    toggleNoSymbolsMessage(noSymbols);
+
+    const groupByEl = document.getElementById('group-by-container');
+    groupByEl.toggleAttribute('disabled', !isMultiContainer);
+    if (isMultiContainer) {
+      groupByEl.checked = true;
+      // Fire a change event manually to reload the tree.
+      // TODO(crbug/1186921): Rework such that we don't build the tree twice.
+      document.getElementById('options').dispatchEvent(new Event('change'));
+    } else {
+      processBuildTreeResponse(message);
+    }
+  }
+
+  // Process the result of a buildTree() message.
+  function processBuildTreeResponse(message) {
+    const {root} = message;
+    _progress.setValue(1);
+
+    if (Object.keys(root.childStats).length === 0) {
+      displayNoSymbolsMessage();
+    }
+
     /** @type {DocumentFragment | null} */
     let rootElement = null;
     if (root) {
@@ -425,37 +460,14 @@
       link.click();
       link.tabIndex = 0;
     }
-    if (diffMode) {
-      if(Object.keys(root.childStats).length === 0) {
-        displayNoSymbolsMessage();
-      }
-    }
 
     // Double requestAnimationFrame ensures that the code inside executes in a
     // different frame than the above tree element creation.
-    requestAnimationFrame(() =>
+    requestAnimationFrame(() => {
       requestAnimationFrame(() => {
-        _progress.setValue(percent);
-        if (error) {
-          document.body.classList.add('error');
-        } else {
-          document.body.classList.remove('error');
-        }
-        if (diffMode) {
-          document.body.classList.add('diff');
-        } else {
-          document.body.classList.remove('diff');
-        }
-
         dom.replace(_symbolTree, rootElement);
-        if (!_doneLoad && percent === 1) {
-          _doneLoad = true;
-          console.log(
-              '%cPro Tip: %cawait supersize.worker.openNode("$FILE_PATH")',
-              'font-weight:bold; color: red;', '')
-        }
-      })
-    );
+      });
+    });
   }
 
   /**
@@ -480,36 +492,35 @@
 
   /**
    * Displays an error modal if the .sizediff file is empty.
+   * @param {boolean} show
    */
-  function displayNoSymbolsMessage() {
+  function toggleNoSymbolsMessage(show) {
       const errorModal = document.getElementById('error-modal');
       errorModal.querySelector('div').style.alignItems = 'center';
-      errorModal.style.display = '';
+      errorModal.style.display = show ? '' : 'none';
   }
 
   async function performInitialLoad() {
     let accessToken = null;
+    _progress.setValue(0.1);
     if (requiresAuthentication()) {
       accessToken = await fetchAccessToken();
+      _progress.setValue(0.2);
     }
-    let worker = restartWorker(displayTree);
-    let message = await worker.loadTree('from-url://', accessToken);
+    const worker = restartWorker(onProgressMessage);
+    _progress.setValue(0.3);
+    const message = await worker.loadAndBuildTree('from-url://', accessToken);
+    processLoadTreeResponse(message);
+  }
 
-    if (message.isMultiContainer) {
-      document.getElementById('group-by-container').checked = true;
-      // Fire a change event manually to reload the tree (it does not fire on
-      // its own). No need to display the tree since it is going to be
-      // reloaded anyways.
-      document.getElementById('options').dispatchEvent(new Event('change'));
-    } else {
-      document.querySelector('#group-by-container')
-        .toggleAttribute('disabled', true);
-      displayTree(message);
-    }
-    displayOrHideDownloadButton(message.beforeBlobUrl, message.loadBlobUrl);
+  async function rebuildTree() {
+    _progress.setValue(0);
+    const message = await window.supersize.worker.buildTree();
+    processBuildTreeResponse(message);
   }
 
   _fileUpload.addEventListener('change', async (event) => {
+    _progress.setValue(0.1);
     const input = /** @type {HTMLInputElement} */ (event.currentTarget);
     const file = input.files.item(0);
     const fileUrl = URL.createObjectURL(file);
@@ -517,11 +528,10 @@
     _dataUrlInput.value = '';
     _dataUrlInput.dispatchEvent(new Event('change'));
 
-    displayOrHideDownloadButton();
-
-    let worker = restartWorker(displayTree);
-    let message = await worker.loadTree(fileUrl);
-    displayTree(message);
+    const worker = restartWorker(onProgressMessage);
+    _progress.setValue(0.3);
+    const message = await worker.loadAndBuildTree(fileUrl);
+    processLoadTreeResponse(message);
     // Clean up afterwards so new files trigger event.
     input.value = '';
   });
@@ -531,14 +541,12 @@
     // Some options update the tree themselves, don't regenerate when those
     // options (marked by `data-dynamic`) are changed.
     if (!event.target.dataset.hasOwnProperty('dynamic')) {
-      _progress.setValue(0);
-      window.supersize.worker.loadTree().then(displayTree);
+      rebuildTree();
     }
   });
   form.addEventListener('submit', event => {
     event.preventDefault();
-    _progress.setValue(0);
-    window.supersize.worker.loadTree().then(displayTree);
+    rebuildTree();
   });
 
   if (new URLSearchParams(location.search).has('load_url')) {
diff --git a/tools/binary_size/libsupersize/viewer/static/tree-worker-wasm.js b/tools/binary_size/libsupersize/viewer/static/tree-worker-wasm.js
index a8ebc62..63533eb3 100644
--- a/tools/binary_size/libsupersize/viewer/static/tree-worker-wasm.js
+++ b/tools/binary_size/libsupersize/viewer/static/tree-worker-wasm.js
@@ -8,7 +8,7 @@
 importScripts('./shared.js');
 importScripts('./caspian_web.js');
 
-const LoadWasm = new Promise(function(resolve, reject) {
+const g_wasmPromise = new Promise(function(resolve, reject) {
   Module['onRuntimeInitialized'] = function() {
     console.log('Loaded WebAssembly runtime');
     resolve();
@@ -23,67 +23,37 @@
   uncompressed: _FLAGS.UNCOMPRESSED,
 });
 
+let g_loadTreePromise = null;
+let g_buildTreePromise = null;
+
 
 /**
  * Wrapper around fetch for requesting the same resource multiple times.
  */
 class DataFetcher {
-  constructor(accessToken) {
+  constructor(accessToken, url) {
     /** @type {string | null} */
     this._accessToken = accessToken;
-    /** @type {AbortController | null} */
-    this._controller = null;
-    /** @type {string | null} */
-    this._input = null;
-    /** @type {Uint8Array | null} */
-    this._cache = null;
+    /** @type {string} */
+    this._url = url;
   }
 
-  /**
-   * Sets the input that describes what will be fetched. Also clears the cache.
-   * @param {string | Request} input URL to the resource you want to fetch.
-   */
-  setInput(input) {
-    if (this._input && this._input.startsWith('blob:')) {
-      // Revoke the previous Blob url to prevent memory leaks
-      URL.revokeObjectURL(this._input);
-    }
-
-    this._cache = null;
-    this._input = input;
-  }
-
-  /**
-   * Starts a new request and aborts the previous one.
-   * @param {string | Request} url
-   */
-  async fetchUrl(url) {
-    if (this._accessToken && looksLikeGoogleCloudStorage(url)) {
-      return this._fetchFromGoogleCloudStorage(url);
-    } else {
-      return this._doFetch(url);
-    }
-  }
-
-  async _fetchFromGoogleCloudStorage(url) {
-    const {bucket, file} = parseGoogleCloudStorageUrl(url);
+  _fetchFromGoogleCloudStorage() {
+    const {bucket, file} = parseGoogleCloudStorageUrl(this._url);
     const params = `alt=media`;
     const api_url = `${STORAGE_API_ENDPOINT}/b/${bucket}/o/${file}?${params}`;
     const headers = new Headers();
     headers.append('Authorization', `Bearer ${this._accessToken}`);
-    return this._doFetch(api_url, headers);
+    return this._fetchDirectly(api_url, headers);
   }
 
-  async _doFetch(url, headers) {
-    if (this._controller) this._controller.abort();
-    this._controller = new AbortController();
+  async _fetchDirectly(url, headers = null) {
     if (!headers) {
       headers = new Headers();
     }
-    let response = await fetch(url, {
+    const response = await fetch(url, {
       headers,
       credentials: 'same-origin',
-      signal: this._controller.signal,
     });
     if (!response.ok) {
       throw new Error('Fetch failed.');
@@ -91,15 +61,14 @@
     return response;
   }
 
-  /**
-   * Outputs a single UInt8Array encompassing the entire input .size file.
-   */
-  async loadSizeBuffer() {
-    if (!this._cache) {
-      const response = await this.fetchUrl(this._input);
-      this._cache = new Uint8Array(await response.arrayBuffer());
+  async fetchSizeBuffer() {
+    let response;
+    if (this._accessToken && looksLikeGoogleCloudStorage(this._url)) {
+      response = await this._fetchFromGoogleCloudStorage();
+    } else {
+      response = await this._fetchDirectly(this._url);
     }
-    return this._cache;
+    return new Uint8Array(await response.arrayBuffer());
   }
 }
 
@@ -122,96 +91,107 @@
   return dataHeap;
 }
 
+function sendProgressMessage(percent) {
+  // @ts-ignore
+  self.postMessage({percent, id: 0});
+};
+
 async function Open(name) {
-  return LoadWasm.then(() => {
-    _Open = Module.cwrap('Open', 'number', ['string']);
-    const stringPtr = _Open(name);
-    // Something has gone wrong if we get back a string longer than 67MB.
-    const ret = JSON.parse(Module.UTF8ToString(stringPtr, 2 ** 26));
-    return ret;
-  });
+  const wasmOpen = Module.cwrap('Open', 'number', ['string']);
+  const stringPtr = wasmOpen(name);
+  // Something has gone wrong if we get back a string longer than 67MB.
+  return JSON.parse(Module.UTF8ToString(stringPtr, 2 ** 26));
 }
 
-let g_fetcher = null;
-let g_beforeFetcher = null;
-let g_sizeFileLoaded = false;
-
-/** @type {SizeProperties} */
-let g_size_properties = null;
-
-async function loadSizeFile(isBefore, fetcher) {
-  const sizeBuffer = await fetcher.loadSizeBuffer();
+function loadSizeFile(isBefore, sizeBuffer) {
   const heapBuffer = mallocBuffer(sizeBuffer);
-  const LoadSizeFile = Module.cwrap(
+  const wasmLoadSizeFile = Module.cwrap(
       isBefore ? 'LoadBeforeSizeFile' : 'LoadSizeFile', 'bool',
       ['number', 'number']);
   const start_time = Date.now();
-  LoadSizeFile(heapBuffer.byteOffset, sizeBuffer.byteLength);
+  wasmLoadSizeFile(heapBuffer.byteOffset, sizeBuffer.byteLength);
   console.log(
       'Loaded size file in ' + (Date.now() - start_time) / 1000.0 + ' seconds');
   Module._free(heapBuffer.byteOffset);
-  const urlBlob = URL.createObjectURL(new Blob([sizeBuffer.buffer],
-                                      {type: 'application/octet-stream'}));
-  return urlBlob;
 }
 
-async function loadSizeProperties() {
-  const QueryProperty = Module.cwrap('QueryProperty', 'number', ['string']);
+function loadSizeProperties() {
+  const wasmQueryProperty = Module.cwrap('QueryProperty', 'number', ['string']);
   const getProperty = (key) => {
-    const stringPtr = QueryProperty(key);
+    const stringPtr = wasmQueryProperty(key);
     const r = Module.UTF8ToString(stringPtr, 2 ** 16);
     return r;
   };
-  g_size_properties = {
+  return {
     isMultiContainer: (getProperty('isMultiContainer') === 'true')
   };
 }
 
+async function loadTree(input, accessToken, url, beforeUrl) {
+  const isUpload = input !== 'from-url://';
+
+  if (isUpload) {
+    console.info('Displaying uploaded data');
+  } else {
+    console.info('Displaying data from', url);
+  }
+  const loadFetcher = new DataFetcher(accessToken, isUpload ? input : url);
+  let beforeFetcher = null;
+  if (beforeUrl) {
+    beforeFetcher = new DataFetcher(accessToken, beforeUrl);
+  }
+
+  let isMultiContainer = null;
+  let beforeBlobUrl = null;
+  let loadBlobUrl = null;
+  try {
+    // It takes a few seconds to process large .size files, so download the main
+    // file first, and then overlap its processing with the subsequent download.
+    // Don't download both at the same time to ensure bandwidth is not split
+    // between them.
+    const mainSizeBuffer = await loadFetcher.fetchSizeBuffer();
+    sendProgressMessage(.4);
+    let beforeSizeBuffer = null;
+    const beforeSizeBufferPromise = beforeFetcher?.fetchSizeBuffer();
+    await loadSizeFile(false, mainSizeBuffer);
+    sendProgressMessage(.6);
+    if (beforeSizeBufferPromise) {
+      beforeSizeBuffer = await beforeSizeBufferPromise;
+      sendProgressMessage(.7);
+      await loadSizeFile(true, beforeSizeBuffer);
+    }
+    sendProgressMessage(.8);
+    const sizeProperties = await loadSizeProperties();
+    isMultiContainer = sizeProperties.isMultiContainer;
+    if (!isUpload) {
+      loadBlobUrl = URL.createObjectURL(new Blob(
+          [mainSizeBuffer.buffer], {type: 'application/octet-stream'}));
+      if (beforeSizeBuffer) {
+        beforeBlobUrl = URL.createObjectURL(new Blob(
+            [beforeSizeBuffer.buffer], {type: 'application/octet-stream'}));
+      }
+    }
+  } catch (e) {
+    sendProgressMessage(1);
+    throw e;
+  }
+
+  return {beforeBlobUrl, loadBlobUrl, isMultiContainer}
+}
+
 async function buildTree(
     groupBy, includeRegex, excludeRegex, includeSections, minSymbolSize,
-    flagToFilter, methodCountMode, onProgress) {
-
-  onProgress({percent: 0.1, id: 0});
-  /** @type {Metadata} */
-  return await LoadWasm.then(async () => {
-    let beforeBlobUrl = null;
-    let loadBlobUrl = null;
-    if (!g_sizeFileLoaded) {
-      try {
-        if (g_beforeFetcher !== null) {
-          beforeBlobUrl = await loadSizeFile(true, g_beforeFetcher);
-        }
-        loadBlobUrl = await loadSizeFile(false, g_fetcher);
-        await loadSizeProperties();
-      } catch (e) {
-        onProgress({ percent: 1, id: 0 });
-        throw e;
-      }
-      onProgress({ percent: 0.4, id: 0 });
-      g_sizeFileLoaded = true;
-    }
-
-    const BuildTree = Module.cwrap(
-        'BuildTree', 'bool',
-        ['bool', 'string', 'string', 'string', 'string', 'number', 'number']);
-    const start_time = Date.now();
-    const diffMode = BuildTree(
-        methodCountMode, groupBy, includeRegex, excludeRegex,
-        includeSections, minSymbolSize, flagToFilter);
-    console.log(
-        'Constructed tree in ' + (Date.now() - start_time) / 1000.0 +
-        ' seconds');
-    onProgress({percent: 0.8, id: 0});
-    const root = await Open('');
-    return {
-      root,
-      percent: 1.0,
-      diffMode,
-      isMultiContainer: g_size_properties.isMultiContainer,
-      beforeBlobUrl,
-      loadBlobUrl
-    };
-  });
+    flagToFilter, methodCountMode) {
+  const wasmBuildTree = Module.cwrap(
+      'BuildTree', 'bool',
+      ['bool', 'string', 'string', 'string', 'string', 'number', 'number']);
+  const start_time = Date.now();
+  const diffMode = wasmBuildTree(
+      methodCountMode, groupBy, includeRegex, excludeRegex,
+      includeSections, minSymbolSize, flagToFilter);
+  console.log(
+      'Constructed tree in ' + (Date.now() - start_time) / 1000.0 + ' seconds');
+  return diffMode;
 }
 
 /**
@@ -233,7 +213,7 @@
     includeSections = _DEX_METHOD_SYMBOL_TYPE;
   } else if (includeSections === null) {
     // Exclude native symbols by default.
-    let includeSectionsSet = new Set(_SYMBOL_TYPE_SET);
+    const includeSectionsSet = new Set(_SYMBOL_TYPE_SET);
     includeSectionsSet.delete('b');
     includeSections = Array.from(includeSectionsSet.values()).join('');
   }
@@ -262,9 +242,26 @@
 
 const actions = {
   /**
-   * @param {{input:string|null,accessToken:string|null,options:string}} param0
+   * @param {{input:string,accessToken:?string,options:string}} param0
    */
-  load({input, accessToken, options}) {
+  async loadAndBuildTree({input, accessToken, options}) {
+    const {
+      url,
+      beforeUrl,
+    } = parseOptions(options);
+
+    if (g_loadTreePromise) {
+      // New loads should create new WebWorkers instead.
+      throw new Error('loadTree with input called multiple times.');
+    }
+    g_loadTreePromise = loadTree(input, accessToken, url, beforeUrl);
+    const loadResults = await g_loadTreePromise;
+    const ret = await actions.buildTree({options});
+    ret.loadResults = loadResults;
+    return ret;
+  },
+
+  async buildTree({options}) {
     const {
       groupBy,
       includeRegex,
@@ -273,33 +270,34 @@
       minSymbolSize,
       flagToFilter,
       methodCountMode,
-      url,
-      beforeUrl,
     } = parseOptions(options);
-    if (!g_fetcher) {
-      g_fetcher = new DataFetcher(accessToken);
-    }
-    if (input === 'from-url://' && url) {
-      // Display the data from the `load_url` query parameter
-      console.info('Displaying data from', url);
-      g_fetcher.setInput(url);
-    } else if (input != null) {
-      console.info('Displaying uploaded data');
-      g_fetcher.setInput(input);
-    }
 
-    if (beforeUrl) {
-      g_beforeFetcher = new DataFetcher(accessToken);
-      g_beforeFetcher.setInput(beforeUrl);
-    }
+    // Ensure iniitial load is complete.
+    await g_loadTreePromise;
 
-    return buildTree(
+    // Wait for queued up calls to complete. There should not be too many
+    // since we debounce load calls.
+    // TODO(huangs): Replace this and runActionDebounced() with explicit logic
+    //     to cancel stale requests.
+    while (g_buildTreePromise) {
+      await g_buildTreePromise;
+    }
+    g_buildTreePromise = buildTree(
         groupBy, includeRegex, excludeRegex, includeSections, minSymbolSize,
-        flagToFilter, methodCountMode, progress => {
-          // @ts-ignore
-          self.postMessage(progress);
-        });
+        flagToFilter, methodCountMode);
+
+    const diffMode = await g_buildTreePromise;
+    g_buildTreePromise = null;
+    sendProgressMessage(0.9);
+    const root = await Open('');
+    // TODO(crbug.com/1290946): Move diffMode to loadResults and do not store it
+    //     the viewer's query parameters.
+    return {
+      root,
+      diffMode,
+    };
   },
+
   /** @param {string} path */
   async open(path) {
     return Open(path);
@@ -320,7 +318,7 @@
     self.postMessage({id, result});
   } catch (err) {
     // @ts-ignore
-    self.postMessage({id, error: err.message});
+    self.postMessage({id: 0, error: err.message});
     throw err;
   }
 }
@@ -331,8 +329,9 @@
  * @param {MessageEvent} event Event for when this worker receives a message.
  */
 self.onmessage = async event => {
+  await g_wasmPromise;
   const {id, action, data} = event.data;
-  if (action === 'load') {
+  if (action === 'buildTree') {
     // Loading large files will block the worker thread until complete or when
     // an await statement is reached. During this time, multiple load messages
     // can pile up due to filters being adjusted. We debounce the load call
diff --git a/tools/clang/blink_gc_plugin/tests/optional_gc_object.cpp b/tools/clang/blink_gc_plugin/tests/optional_gc_object.cpp
index c8a2e44..b348e9c 100644
--- a/tools/clang/blink_gc_plugin/tests/optional_gc_object.cpp
+++ b/tools/clang/blink_gc_plugin/tests/optional_gc_object.cpp
@@ -15,11 +15,10 @@
 };
 
 void DisallowedUseOfUniquePtr() {
-  absl::optional<Base> optional_base;  // Must be okay.
-  (void)optional_base;
+  [[maybe_unused]] absl::optional<Base> optional_base;  // Must be okay.
 
-  absl::optional<Derived> optional_derived;  // Must also be okay.
-  (void)optional_derived;
+  [[maybe_unused]] absl::optional<Derived>
+      optional_derived;  // Must also be okay.
 
   new absl::optional<Base>;  // New expression with gced optionals are not
                              // allowed.
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index 1f84d9e..c7d1d9d 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -532,6 +532,10 @@
     "META": {"sizes": {"includes": [120],}},
     "includes": [3320],
   },
+  "ash/webui/multidevice_debug/resources/multidevice_debug_resources.grd": {
+    "META": {"join": 2},
+    "includes": [3330],
+  },
   "<(SHARED_INTERMEDIATE_DIR)/ash/webui/personalization_app/resources/ash_personalization_app_resources.grd": {
     "META": {"sizes": {"includes": [120],}},
     "includes": [3340],
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 8df2507..192002d 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -647,6 +647,7 @@
 
     'client.devtools-frontend.integration': {
       'DevTools Linux': 'release_trybot_blink',
+      'DevTools Linux Fastbuild': 'release_trybot_blink_skip_typecheck',
     },
 
     'client.openscreen.chromium': {
@@ -765,11 +766,11 @@
       # waterfall bots, and run_web_tests.py can't handle that (by design).
       'linux-blink-rel': 'release_bot_blink_minimal_symbols',
       'linux-blink-optional-highdpi-rel': 'release_bot_blink_minimal_symbols',
-      'mac10.12-blink-rel': 'release_bot_blink_minimal_symbols',
-      'mac10.13-blink-rel': 'release_bot_blink_minimal_symbols',
-      'mac10.14-blink-rel': 'release_bot_blink_minimal_symbols',
+      'mac10.12-blink-rel': 'release_bot_blink_minimal_symbols_no_nacl',
+      'mac10.13-blink-rel': 'release_bot_blink_minimal_symbols_no_nacl',
+      'mac10.14-blink-rel': 'release_bot_blink_minimal_symbols_no_nacl',
       'mac10.15-blink-rel': 'release_bot_blink_minimal_symbols_no_nacl',
-      'mac11.0-blink-rel': 'release_bot_blink_minimal_symbols',
+      'mac11.0-blink-rel': 'release_bot_blink_minimal_symbols_no_nacl',
       'mac11.0.arm64-blink-rel': 'release_bot_blink_arm64_minimal_symbols',
       'win7-blink-rel': 'release_bot_blink_x86_minimal_symbols',
       'win10.20h2-blink-rel': 'release_bot_blink_x86_minimal_symbols',
@@ -1058,7 +1059,7 @@
       'linux_chromium_asan_rel_ng-orchestrator': 'asan_lsan_release_trybot',
       'linux_chromium_asan_rel_ng_rts': 'asan_lsan_release_trybot',
       'linux_chromium_cfi_rel_ng': 'cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on_goma',
-      'linux_chromium_chromeos_asan_rel_ng': 'asan_lsan_chromeos_release_trybot',
+      'linux_chromium_chromeos_asan_rel_ng': 'asan_lsan_chromeos_release_bot_dcheck_always_on',
       'linux_chromium_chromeos_msan_rel_ng': 'chromeos_msan_release_bot',
       'linux_chromium_clobber_deterministic': 'release_trybot',
       'linux_chromium_clobber_rel_ng': 'release_trybot',
@@ -1222,6 +1223,7 @@
     'tryserver.devtools-frontend': {
       # Align devtools blink builders with chromium linux-rel
       'devtools_frontend_linux_blink_light_rel': 'release_trybot_blink',
+      'devtools_frontend_linux_blink_light_rel_fastbuild': 'release_trybot_blink_skip_typecheck',
       'devtools_frontend_linux_blink_rel': 'release_trybot_blink',
     },
 
@@ -1744,10 +1746,6 @@
       'asan', 'lsan', 'chromeos', 'release_trybot_minimal_symbols',
     ],
 
-    'asan_lsan_chromeos_release_trybot': [
-      'asan', 'lsan', 'chromeos', 'release_trybot',
-    ],
-
     'asan_lsan_debug_bot_reclient': [
       'asan', 'lsan', 'debug_bot_reclient',
     ],
@@ -2994,6 +2992,10 @@
       'release_trybot_blink',
     ],
 
+    'release_trybot_blink_skip_typecheck': [
+      'release_trybot_blink', 'devtools_skip_typecheck',
+    ],
+
     'release_trybot_dcheck_off': [
       'release_trybot_dcheck_off',
     ],
@@ -3433,6 +3435,10 @@
       'mixins': ['debug', 'static', 'minimal_symbols', 'reclient'],
     },
 
+    'devtools_skip_typecheck': {
+      'gn_args': 'devtools_skip_typecheck=true',
+    },
+
     'disable_nacl': {
       'gn_args': 'enable_nacl=false',
     },
diff --git a/tools/mb/mb_config_expectations/client.devtools-frontend.integration.json b/tools/mb/mb_config_expectations/client.devtools-frontend.integration.json
index 6b7c8dc..9cd1b65 100644
--- a/tools/mb/mb_config_expectations/client.devtools-frontend.integration.json
+++ b/tools/mb/mb_config_expectations/client.devtools-frontend.integration.json
@@ -9,5 +9,17 @@
       "symbol_level": 1,
       "use_goma": true
     }
+  },
+  "DevTools Linux Fastbuild": {
+    "gn_args": {
+      "dcheck_always_on": true,
+      "devtools_skip_typecheck": true,
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "symbol_level": 1,
+      "use_goma": true
+    }
   }
 }
\ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/tryserver.blink.json b/tools/mb/mb_config_expectations/tryserver.blink.json
index 5d0f36d..d73db1c6 100644
--- a/tools/mb/mb_config_expectations/tryserver.blink.json
+++ b/tools/mb/mb_config_expectations/tryserver.blink.json
@@ -24,6 +24,7 @@
   "mac10.12-blink-rel": {
     "gn_args": {
       "dcheck_always_on": false,
+      "enable_nacl": false,
       "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
@@ -35,6 +36,7 @@
   "mac10.13-blink-rel": {
     "gn_args": {
       "dcheck_always_on": false,
+      "enable_nacl": false,
       "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
@@ -46,6 +48,7 @@
   "mac10.14-blink-rel": {
     "gn_args": {
       "dcheck_always_on": false,
+      "enable_nacl": false,
       "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
@@ -69,6 +72,7 @@
   "mac11.0-blink-rel": {
     "gn_args": {
       "dcheck_always_on": false,
+      "enable_nacl": false,
       "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
index a56ac434..b94bb86d 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
@@ -943,7 +943,7 @@
       "is_component_build": false,
       "is_debug": false,
       "is_lsan": true,
-      "symbol_level": 0,
+      "symbol_level": 1,
       "target_os": "chromeos",
       "use_goma": true
     }
diff --git a/tools/mb/mb_config_expectations/tryserver.devtools-frontend.json b/tools/mb/mb_config_expectations/tryserver.devtools-frontend.json
index 2060cc07..3762677 100644
--- a/tools/mb/mb_config_expectations/tryserver.devtools-frontend.json
+++ b/tools/mb/mb_config_expectations/tryserver.devtools-frontend.json
@@ -10,6 +10,18 @@
       "use_goma": true
     }
   },
+  "devtools_frontend_linux_blink_light_rel_fastbuild": {
+    "gn_args": {
+      "dcheck_always_on": true,
+      "devtools_skip_typecheck": true,
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "symbol_level": 1,
+      "use_goma": true
+    }
+  },
   "devtools_frontend_linux_blink_rel": {
     "gn_args": {
       "dcheck_always_on": true,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 028c4e41..7f5487f5 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -8432,6 +8432,8 @@
   <int value="262" label="RFH_INACTIVE_CHECK_FROM_PENDING_COMMIT_RFH"/>
   <int value="263" label="MSDH_INVALID_STREAM_TYPE_COMBINATION"/>
   <int value="264" label="AUTH_INVALID_FENCED_FRAME"/>
+  <int value="265" label="BIBI_BIND_GAMEPAD_MONITOR_FOR_FENCED_FRAME"/>
+  <int value="266" label="BIBI_BIND_GAMEPAD_HAPTICS_MANAGER_FOR_FENCED_FRAME"/>
 </enum>
 
 <enum name="BadMessageReasonExtensions">
@@ -28608,6 +28610,9 @@
 </enum>
 
 <enum name="EnterpriseUploadJobSuccess">
+  <obsolete>
+    Deprecated 01/2022
+  </obsolete>
   <summary>
     Number of UploadJob retries as defined in
     chrome/browser/ash/policy/uploading/upload_job_impl.cc.
@@ -52062,6 +52067,7 @@
   <int value="-1322882747" label="disable-datasaver-prompt"/>
   <int value="-1322830330" label="ContextualSearchNewSettings:enabled"/>
   <int value="-1321935621" label="WebAppsCrosapi:enabled"/>
+  <int value="-1321796919" label="TrafficCountersHandlerEnabled:disabled"/>
   <int value="-1321640296"
       label="AutofillDownstreamCvcPromptUseGooglePayLogo:enabled"/>
   <int value="-1321212159" label="MediaAppAnnotation:enabled"/>
@@ -53270,7 +53276,6 @@
   <int value="-446220201" label="EnableIncognitoShortcutOnDesktop:enabled"/>
   <int value="-444867364" label="Metal:enabled"/>
   <int value="-442352394" label="IframeOneGoogleBar:disabled"/>
-  <int value="-441508443" label="enable-canvas-context-lost-in-background"/>
   <int value="-438379844" label="SwapSideVolumeButtonsForOrientation:enabled"/>
   <int value="-436470115" label="TouchpadAndWheelScrollLatching:enabled"/>
   <int value="-435914745" label="ClipboardContentSetting:disabled"/>
@@ -54999,6 +55004,7 @@
   <int value="820650704" label="disable-ntp-popular-sites"/>
   <int value="821192723" label="show-fps-counter"/>
   <int value="824961931" label="use-simple-cache-backend"/>
+  <int value="826519677" label="TailoredSecurityIntegration:disabled"/>
   <int value="828092263" label="TemporaryUnexpireFlagsM78:enabled"/>
   <int value="830282555" label="DecodeJpeg420ImagesToYUV:enabled"/>
   <int value="832142463" label="WebAssemblyStreaming:enabled"/>
@@ -55093,6 +55099,8 @@
   <int value="889837286" label="EnableHostnameSetting:enabled"/>
   <int value="892899792" label="MaterialDesignIncognitoNTP:disabled"/>
   <int value="894434593" label="TabRestoreSubMenus:enabled"/>
+  <int value="896506516"
+      label="enable-canvas-context-lost-in-background (obsolete)"/>
   <int value="898311758" label="ReaderMode:disabled"/>
   <int value="899347105" label="NearbySharingWifiLan:enabled"/>
   <int value="900614020" label="ContentSuggestionsShowSummary:disabled"/>
@@ -55280,6 +55288,7 @@
   <int value="1043334401" label="disable-slimming-paint-invalidation"/>
   <int value="1043511715" label="CategoricalSearch:enabled"/>
   <int value="1044210009" label="SharingPeerConnectionReceiver:disabled"/>
+  <int value="1044873795" label="TailoredSecurityIntegration:enabled"/>
   <int value="1044928476"
       label="AllowDownloadResumptionWithoutStrongValidators:enabled"/>
   <int value="1045152062" label="SecurePaymentConfirmationBrowser:enabled"/>
@@ -55288,6 +55297,7 @@
   <int value="1047110483" label="ShelfHotseat:disabled"/>
   <int value="1049339770" label="AppMenuMobileSiteOption:enabled"/>
   <int value="1049346775" label="OmniboxDocumentProviderAso:disabled"/>
+  <int value="1049601544" label="TrafficCountersHandlerEnabled:enabled"/>
   <int value="1049885154" label="OfflinePagesPrefetching:disabled"/>
   <int value="1050048304" label="enable-font-cache-scaling"/>
   <int value="1050321458" label="new-profile-management"/>
@@ -73020,6 +73030,19 @@
   <int value="14" label="NACL_BROKER_PROCESS"/>
 </enum>
 
+<enum name="ProduceCropTargetFunctionResult">
+  <int value="0" label="PromiseProduced"/>
+  <int value="1" label="GenericError"/>
+  <int value="2" label="InvalidContext"/>
+  <int value="3" label="DuplicateCallBeforePromiseResolution"/>
+  <int value="4" label="DuplicateCallAfterPromiseResolution"/>
+</enum>
+
+<enum name="ProduceCropTargetPromiseResult">
+  <int value="0" label="PromiseResolved"/>
+  <int value="1" label="PromiseRejected"/>
+</enum>
+
 <enum name="Profile">
   <int value="0" label="Guest Profile"/>
   <int value="1" label="Profile 01"/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 8346d10a..6680ff5 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -2498,8 +2498,8 @@
 </histogram>
 
 <histogram name="Ash.Shelf.Menu.NumItemsEnabledUponSelection" units="Count"
-    expires_after="2021-01-26">
-  <owner>anasalazar@google.com</owner>
+    expires_after="2022-01-24">
+  <owner>anasalazar@chromium.org</owner>
   <owner>mmourgos@google.com</owner>
   <summary>
     Tracks the number of menu items that are enabled in a shelf item's secondary
@@ -2508,8 +2508,8 @@
 </histogram>
 
 <histogram name="Ash.Shelf.Menu.SelectedMenuItemIndex" units="Index"
-    expires_after="2021-01-26">
-  <owner>anasalazar@google.com</owner>
+    expires_after="2022-01-24">
+  <owner>anasalazar@chromium.org</owner>
   <owner>mmourgos@google.com</owner>
   <summary>
     Tracks the index of the selected menu item in a shelf item's secondary menu.
@@ -2533,7 +2533,7 @@
 
 <histogram name="Ash.Shelf.NumberOfItems" units="Icons"
     expires_after="2022-04-24">
-  <owner>anasalazar@google.com</owner>
+  <owner>anasalazar@chromium.org</owner>
   <owner>mmourgos@google.com</owner>
   <summary>
     The number of icons in the shelf, not including the App Launcher icon. This
@@ -2542,8 +2542,8 @@
 </histogram>
 
 <histogram name="Ash.Shelf.NumberOfPinnedItems" units="Icons"
-    expires_after="2022-02-20">
-  <owner>anasalazar@google.com</owner>
+    expires_after="2023-01-24">
+  <owner>anasalazar@chromium.org</owner>
   <owner>mmourgos@google.com</owner>
   <summary>
     The number of pinned icons in the shelf, not including the App Launcher
@@ -2552,8 +2552,8 @@
 </histogram>
 
 <histogram name="Ash.Shelf.NumberOfUnpinnedItems" units="Icons"
-    expires_after="2022-02-06">
-  <owner>anasalazar@google.com</owner>
+    expires_after="2023-01-24">
+  <owner>anasalazar@chromium.org</owner>
   <owner>mmourgos@google.com</owner>
   <summary>
     The number of unpinned icons in the shelf. This metric is recorded every 30
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
index d2051ce..68bf789 100644
--- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml
+++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -93,6 +93,13 @@
   </token>
 </histogram>
 
+<histogram name="Bluetooth.ChromeOS.DeviceDisconnect"
+    enum="BluetoothDeviceType" expires_after="2023-01-24">
+  <owner>khorimoto@chromium.org</owner>
+  <owner>cros-connectivity@google.com</owner>
+  <summary>Emitted each time a Bluetooth device is disconnected.</summary>
+</histogram>
+
 <histogram
     name="Bluetooth.ChromeOS.DeviceSelectionDuration{DeviceSelectionUISurfaces}"
     units="ms" expires_after="2022-07-01">
@@ -138,6 +145,13 @@
 
 <histogram name="Bluetooth.ChromeOS.Disconnect.Result{BluetoothTransportTypes}"
     enum="DisconnectResult" expires_after="2022-07-21">
+  <obsolete>
+    Removed 2022-01-25. Removed in favor of
+    Bluetooth.ChromeOS.UserInitiatedDisconnect.Result, because this actually
+    recorded only user initiated disconnect results, and a more general
+    Bluetooth.ChromeOS.DeviceDisconnect was introduced to record all device
+    disconnections. check http://b/215601529 for details.
+  </obsolete>
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -741,6 +755,19 @@
   </summary>
 </histogram>
 
+<histogram name="Bluetooth.ChromeOS.FastPair.PairRetry.Count" units="count"
+    expires_after="2022-09-20">
+  <owner>shanefitz@google.com</owner>
+  <owner>julietlevesque@google.com</owner>
+  <owner>chromeos-cross-device-eng@google.com</owner>
+  <summary>
+    Records the count of the number of retry attempts needed for a successful
+    Fast Pair pairing, which can be zero if no retry was needed. Emitted
+    following the successful pairing. There are only three retry attempts before
+    failure is declared. No metric is emitted on failure.
+  </summary>
+</histogram>
+
 <histogram name="Bluetooth.ChromeOS.FastPair.Passkey.Decrypt.Result"
     enum="BooleanSuccess" expires_after="2022-09-20">
   <owner>shanefitz@google.com</owner>
@@ -1027,6 +1054,20 @@
 </histogram>
 
 <histogram
+    name="Bluetooth.ChromeOS.UserInitiatedDisconnect.Result{BluetoothTransportTypes}"
+    enum="DisconnectResult" expires_after="2023-01-24">
+  <owner>khorimoto@chromium.org</owner>
+  <owner>cros-connectivity@google.com</owner>
+  <summary>
+    Emitted each time a user attempted disconnection completes.
+    {BluetoothTransportTypes}
+  </summary>
+  <token key="BluetoothTransportTypes" variants="BluetoothTransportTypes">
+    <variant name=""/>
+  </token>
+</histogram>
+
+<histogram
     name="Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Duration.Failure{BluetoothTransportTypes}"
     units="ms" expires_after="2022-07-19">
   <owner>khorimoto@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml
index f6f371c..119863f 100644
--- a/tools/metrics/histograms/metadata/browser/histograms.xml
+++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -346,9 +346,10 @@
 </histogram>
 
 <histogram name="Browser.Responsiveness.JankyIntervalsPerThirtySeconds2"
-    units="janks" expires_after="2022-07-17">
-<!-- JankyIntervalsPerThirtySeconds3 is on probation to replace this -->
-
+    units="janks" expires_after="M98">
+  <obsolete>
+    Replaced by Browser.Responsiveness.JankyIntervalsPerThirtySeconds3
+  </obsolete>
   <owner>erikchen@chromium.org</owner>
   <owner>fdoray@chromium.org</owner>
   <summary>
@@ -367,7 +368,7 @@
 </histogram>
 
 <histogram name="Browser.Responsiveness.JankyIntervalsPerThirtySeconds3"
-    units="janks" expires_after="2022-06-05">
+    units="janks" expires_after="2022-09-05">
 <!-- on probation: expected to graduate as a go/chrome-browser-guiding-metrics -->
 
   <owner>etienneb@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/data/histograms.xml b/tools/metrics/histograms/metadata/data/histograms.xml
index 8e733ea..9782cad 100644
--- a/tools/metrics/histograms/metadata/data/histograms.xml
+++ b/tools/metrics/histograms/metadata/data/histograms.xml
@@ -96,6 +96,9 @@
 
 <histogram name="DataReductionProxy.BypassedBytes.NotBypassed" units="bytes"
     expires_after="M85">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>bengr@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -106,6 +109,9 @@
 
 <histogram name="DataReductionProxy.DaysSinceEnabled" units="days"
     expires_after="2021-03-10">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>rajendrant@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -119,6 +125,9 @@
 
 <histogram name="DataReductionProxy.DeleteBrowsingHistory.NumBuckets"
     units="units" expires_after="M77">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>robertogden@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
@@ -145,6 +154,9 @@
 
 <histogram name="DataReductionProxy.HistoricalDataUsageLoadTime" units="ms"
     expires_after="M77">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>kundaji@chromium.org</owner>
   <summary>
     Time taken to load historical data usage from Level DB into memory. This UMA
@@ -155,6 +167,9 @@
 
 <histogram name="DataReductionProxy.LastWeekAggregateKB.Services"
     enum="DataUseServicesHash" expires_after="2022-07-03">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>rajendrant@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
@@ -170,6 +185,9 @@
 <histogram
     name="DataReductionProxy.LastWeekAggregateKB.UserTraffic.Downstream.ContentType"
     enum="DataUseContentType" expires_after="2022-07-03">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>rajendrant@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
@@ -184,11 +202,17 @@
 
 <histogram name="DataReductionProxy.LevelDBOpenStatus"
     enum="DataReductionProxyStoreStatus" expires_after="M77">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>kundaji@chromium.org</owner>
   <summary>Status of calling Open() on Data Reduction Proxy LevelDB.</summary>
 </histogram>
 
 <histogram name="DataReductionProxy.LevelDBSize" units="KB" expires_after="M77">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>kundaji@chromium.org</owner>
   <summary>Size of Data Reduction Proxy LevelDB measured at startup.</summary>
 </histogram>
@@ -207,6 +231,9 @@
 
 <histogram name="DataReductionProxy.ReportSaveDataSavings.ParseResult"
     enum="Boolean" expires_after="2021-04-01">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>rajendrant@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -217,6 +244,9 @@
 
 <histogram name="DataReductionProxy.SavingsCleared.Reason"
     enum="DataReductionProxySavingsClearedReason" expires_after="M77">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>robertogden@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
@@ -227,6 +257,9 @@
 
 <histogram name="DataReductionProxy.SnackbarPromo.DataSavings" units="MB"
     expires_after="M85">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>bengr@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -238,6 +271,9 @@
 
 <histogram name="DataReductionProxy.StartupNegativeSavingsPercent" units="%"
     expires_after="2021-08-01">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>rajendrant@chromium.org</owner>
   <owner>mcrouse@chromium.org</owner>
   <summary>
@@ -249,6 +285,9 @@
 
 <histogram name="DataReductionProxy.StartupSavingsPercent" units="%"
     expires_after="2021-08-01">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>rajendrant@chromium.org</owner>
   <owner>mcrouse@chromium.org</owner>
   <summary>
@@ -272,6 +311,9 @@
 
 <histogram name="DataReductionProxy.ThisWeekAggregateKB.Services"
     enum="DataUseServicesHash" expires_after="2022-07-03">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>rajendrant@chromium.org</owner>
   <owner>mcrouse@chromium.org</owner>
   <summary>
@@ -287,6 +329,9 @@
 <histogram
     name="DataReductionProxy.ThisWeekAggregateKB.UserTraffic.Downstream.ContentType"
     enum="DataUseContentType" expires_after="2022-07-03">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>rajendrant@chromium.org</owner>
   <owner>mcrouse@chromium.org</owner>
   <summary>
@@ -301,6 +346,9 @@
 
 <histogram name="DataReductionProxy.UIAction" enum="DataReductionProxyUIAction"
     expires_after="2022-07-11">
+  <obsolete>
+    Obsoleted Jan 2022.
+  </obsolete>
   <owner>bengr@chromium.org</owner>
   <owner>mcrouse@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/enterprise/histograms.xml b/tools/metrics/histograms/metadata/enterprise/histograms.xml
index 91d0182..ceb4b88 100644
--- a/tools/metrics/histograms/metadata/enterprise/histograms.xml
+++ b/tools/metrics/histograms/metadata/enterprise/histograms.xml
@@ -1873,6 +1873,9 @@
 
 <histogram name="Enterprise.UploadJobSuccess" enum="EnterpriseUploadJobSuccess"
     expires_after="M87">
+  <obsolete>
+    Removed 2022/01
+  </obsolete>
   <owner>bmalcolm@chromium.org</owner>
   <owner>managed-devices@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index 3787dbc1..a23db31 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -3539,6 +3539,31 @@
   </summary>
 </histogram>
 
+<histogram name="Media.RegionCapture.ProduceCropTarget.Function.Result"
+    enum="ProduceCropTargetFunctionResult" expires_after="2023-01-25">
+  <owner>eladalon@chromium.org</owner>
+  <owner>jophba@chromium.org</owner>
+  <owner>mfoltz@chromium.org</owner>
+  <summary>
+    Tracks the result of calls to MediaDevices.produceCropTarget().
+    Specifically, this histogram tracks whether a new Promise was produced, and
+    if not, why not. Another histogram tracks the result of new Promises, i.e.
+    whether they were resolved or rejected.
+  </summary>
+</histogram>
+
+<histogram name="Media.RegionCapture.ProduceCropTarget.Promise.Result"
+    enum="ProduceCropTargetPromiseResult" expires_after="2023-01-25">
+  <owner>eladalon@chromium.org</owner>
+  <owner>jophba@chromium.org</owner>
+  <owner>mfoltz@chromium.org</owner>
+  <summary>
+    When ProduceCropTarget() is called for the first time on a given
+    HTMLElement, a new Promise is produced. This histogram tracks the result of
+    this Promise - whether it was resolved or rejected.
+  </summary>
+</histogram>
+
 <histogram name="Media.Remoting.AllowedByPage" enum="BooleanEnabled"
     expires_after="2022-10-26">
   <owner>jophba@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/offline/histograms.xml b/tools/metrics/histograms/metadata/offline/histograms.xml
index fd8ebbd..b02fdbb 100644
--- a/tools/metrics/histograms/metadata/offline/histograms.xml
+++ b/tools/metrics/histograms/metadata/offline/histograms.xml
@@ -24,6 +24,9 @@
 
 <histogram name="Offline.Measurements.HttpProbeResult"
     enum="OfflineMeasurementsHttpProbeResult" expires_after="2022-06-19">
+  <obsolete>
+    Removed M100. No longer used.
+  </obsolete>
   <owner>curranmax@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -38,6 +41,9 @@
 
 <histogram name="Offline.Measurements.IsAirplaneModeEnabled"
     enum="BooleanEnabled" expires_after="2022-06-19">
+  <obsolete>
+    Removed M100. No longer used.
+  </obsolete>
   <owner>curranmax@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -54,6 +60,9 @@
 
 <histogram name="Offline.Measurements.IsRoaming" enum="Boolean"
     expires_after="2022-06-19">
+  <obsolete>
+    Removed M100. No longer used.
+  </obsolete>
   <owner>curranmax@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -71,6 +80,9 @@
 
 <histogram name="Offline.Measurements.MeasurementInterval" units="minutes"
     expires_after="2022-04-17">
+  <obsolete>
+    Removed M100. No longer used.
+  </obsolete>
   <owner>curranmax@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -82,6 +94,9 @@
 
 <histogram name="Offline.Measurements.TimeBetweenChecks" units="minutes"
     expires_after="2022-06-19">
+  <obsolete>
+    Removed M100. No longer used.
+  </obsolete>
   <owner>curranmax@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -93,6 +108,9 @@
 
 <histogram name="Offline.Measurements.UserState"
     enum="OfflineMeasurementsUserState" expires_after="2022-06-19">
+  <obsolete>
+    Removed M100. No longer used.
+  </obsolete>
   <owner>curranmax@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index 962bdc5..d773e037 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -5308,6 +5308,9 @@
 
 <histogram name="Downgrade.TakeSnapshot.FailureCount" units="count"
     expires_after="2021-12-12">
+  <obsolete>
+    Removed in M100.
+  </obsolete>
   <owner>grt@chromium.org</owner>
   <owner>ydago@chromium.org</owner>
   <summary>
@@ -5317,12 +5320,12 @@
 </histogram>
 
 <histogram name="Downgrade.TakeSnapshot.ItemFailure" enum="SnapshotItemId"
-    expires_after="2021-12-12">
+    expires_after="2022-12-12">
   <owner>grt@chromium.org</owner>
   <owner>ydago@chromium.org</owner>
   <summary>
     Indicates the id of an item that failed to be copied when taking a user data
-    snapshot.
+    snapshot. The metrics does not cover the data from 12/12/2021 to 03/29/2022.
   </summary>
 </histogram>
 
@@ -5367,6 +5370,9 @@
 
 <histogram name="Downgrade.TakeSnapshot.Result" enum="SnapshotOperationResult"
     expires_after="2021-12-05">
+  <obsolete>
+    Removed in M100.
+  </obsolete>
   <owner>grt@chromium.org</owner>
   <owner>ydago@chromium.org</owner>
   <summary>
@@ -11963,7 +11969,18 @@
 </histogram>
 
 <histogram name="ReportingAndNEL.NumberOfLoadedNELPolicies"
-    units="policy count" expires_after="2020-09-09">
+    units="policy count" expires_after="2022-06-25">
+  <owner>yhirano@chromium.org</owner>
+  <owner>src/net/reporting/OWNERS</owner>
+  <summary>
+    The number of NEL policies loaded from the store. This is recorded when the
+    NetworkErrorLoggingService requests a load from the backing store, which
+    typically happens upon the first network request after startup.
+  </summary>
+</histogram>
+
+<histogram name="ReportingAndNEL.NumberOfLoadedNELPolicies2"
+    units="policy count" expires_after="2022-06-25">
   <owner>yhirano@chromium.org</owner>
   <owner>src/net/reporting/OWNERS</owner>
   <summary>
@@ -11974,7 +11991,19 @@
 </histogram>
 
 <histogram name="ReportingAndNEL.NumberOfLoadedReportingEndpointGroups"
-    units="endpoint group count" expires_after="2020-09-09">
+    units="endpoint group count" expires_after="2022-06-25">
+  <owner>yhirano@chromium.org</owner>
+  <owner>src/net/reporting/OWNERS</owner>
+  <summary>
+    The number of Reporting endpoint groups loaded from the store. This is
+    recorded when the ReportingCache requests a load from the backing store,
+    which happens upon receipt of the first Report-To header or queued report
+    after startup.
+  </summary>
+</histogram>
+
+<histogram name="ReportingAndNEL.NumberOfLoadedReportingEndpointGroups2"
+    units="endpoint group count" expires_after="2022-06-25">
   <owner>yhirano@chromium.org</owner>
   <owner>src/net/reporting/OWNERS</owner>
   <summary>
@@ -11986,7 +12015,19 @@
 </histogram>
 
 <histogram name="ReportingAndNEL.NumberOfLoadedReportingEndpoints"
-    units="endpoint count" expires_after="2020-09-09">
+    units="endpoint count" expires_after="2022-06-25">
+  <owner>yhirano@chromium.org</owner>
+  <owner>src/net/reporting/OWNERS</owner>
+  <summary>
+    The number of Reporting endpoints loaded from the store. This is recorded
+    when the ReportingCache requests a load from the backing store, which
+    happens upon receipt of the first Report-To header or queued report after
+    startup.
+  </summary>
+</histogram>
+
+<histogram name="ReportingAndNEL.NumberOfLoadedReportingEndpoints2"
+    units="endpoint count" expires_after="2022-06-25">
   <owner>yhirano@chromium.org</owner>
   <owner>src/net/reporting/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/webauthn/histograms.xml b/tools/metrics/histograms/metadata/webauthn/histograms.xml
index ee93aa670..a7b9e4a 100644
--- a/tools/metrics/histograms/metadata/webauthn/histograms.xml
+++ b/tools/metrics/histograms/metadata/webauthn/histograms.xml
@@ -212,7 +212,7 @@
 </histogram>
 
 <histogram name="WebAuthentication.MakeCredentialResponseTransport"
-    enum="WebAuthenticationFidoTransport" expires_after="2022-01-30">
+    enum="WebAuthenticationFidoTransport" expires_after="2022-12-31">
   <owner>kenrb@chromium.org</owner>
   <owner>martinkr@google.com</owner>
   <summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 9e0fdcfe..cf24c94 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -12026,6 +12026,9 @@
 </event>
 
 <event name="OfflineMeasurements">
+  <obsolete>
+    Removed M100. No longer used.
+  </obsolete>
   <owner>curranmax@chromium.org</owner>
   <summary>
     Data collected by the OfflineMeasurementsBackgroundTask. At a regular
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 377d0c1c..bcbfd8e 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@
             "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "3eac7a8b4e2a5c66ce4be28d8c6d722d73277eab",
-            "remote_path": "perfetto_binaries/trace_processor_shell/win/d7b55ea623d1106cb4e1961a4180caf1280ec6ab/trace_processor_shell.exe"
+            "hash": "253a4ad52224f4ff41d30b2d31d7c07bcd819ecb",
+            "remote_path": "perfetto_binaries/trace_processor_shell/win/cfae0ba38e605c2a9d9dd08ac9c2f0225bb32063/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
             "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "mac": {
-            "hash": "fa3a16e144a1d924f505fbe78ecd163b81b63f39",
-            "remote_path": "perfetto_binaries/trace_processor_shell/mac/d7b55ea623d1106cb4e1961a4180caf1280ec6ab/trace_processor_shell"
+            "hash": "1f8ea64b13e45226c26e4c3fd44cda9ea9d4cffb",
+            "remote_path": "perfetto_binaries/trace_processor_shell/mac/d55790478283bd2e1ca01c02ad9b24f8bf4c600d/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "c0397e87456ad6c6a7aa0133e5b81c97adbab4ab",
             "remote_path": "perfetto_binaries/trace_processor_shell/mac_arm64/cefb3e0ec3a0580c996f801e854fe02963c03d5c/trace_processor_shell"
         },
         "linux": {
-            "hash": "e74792f0962a1dff41b9f8b9f7390d24c0e93c5c",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/d7b55ea623d1106cb4e1961a4180caf1280ec6ab/trace_processor_shell"
+            "hash": "656fe1487ec18f7e03b803a01e468be4c8fe0536",
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/350b8fe08804c8cf1a3b939a906be63737b7ff39/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
index cd6098f..da57f69 100644
--- a/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
@@ -1364,10 +1364,6 @@
         "name": "blink_perf.webaudio/biquad-filter-node.html"
     },
     {
-        "duration": "121.0",
-        "name": "blink_perf.webaudio/dynamics-compressor-node.html"
-    },
-    {
         "duration": "94.0",
         "name": "blink_perf.webaudio/gain-node.html"
     },
diff --git a/tools/perf/core/shard_maps/timing_data/android_nexus5x_webview_perf_timing.json b/tools/perf/core/shard_maps/timing_data/android_nexus5x_webview_perf_timing.json
index ad9755ef..f6ddc4b94 100644
--- a/tools/perf/core/shard_maps/timing_data/android_nexus5x_webview_perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/android_nexus5x_webview_perf_timing.json
@@ -1400,10 +1400,6 @@
         "name": "blink_perf.webaudio/biquad-filter-node.html"
     },
     {
-        "duration": "112.0",
-        "name": "blink_perf.webaudio/dynamics-compressor-node.html"
-    },
-    {
         "duration": "88.0",
         "name": "blink_perf.webaudio/gain-node.html"
     },
diff --git a/tools/perf/core/shard_maps/timing_data/mac-laptop_high_end-perf_timing.json b/tools/perf/core/shard_maps/timing_data/mac-laptop_high_end-perf_timing.json
index 8173fd33..56a31c96 100644
--- a/tools/perf/core/shard_maps/timing_data/mac-laptop_high_end-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/mac-laptop_high_end-perf_timing.json
@@ -1376,10 +1376,6 @@
         "name": "blink_perf.webaudio/biquad-filter-node.html"
     },
     {
-        "duration": "96.0",
-        "name": "blink_perf.webaudio/dynamics-compressor-node.html"
-    },
-    {
         "duration": "93.0",
         "name": "blink_perf.webaudio/gain-node.html"
     },
diff --git a/tools/perf/page_sets/.gitignore b/tools/perf/page_sets/.gitignore
index 54ebcaf..a8d6d198 100644
--- a/tools/perf/page_sets/.gitignore
+++ b/tools/perf/page_sets/.gitignore
@@ -6,9 +6,7 @@
 *.mp4
 *.ogg
 *.ogv
-# TODO(jonross): re-add this once tests requiring hard-coded .png files have
-# been updated.
-#*.png
+*.png
 *.wav
 *.webm
 *.wpr
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index c9dde495..1b24011 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -293,7 +293,7 @@
  <item id="ambient_photo_cache" added_in_milestone="98" content_hash_code="07dbf21e" os_list="chromeos" file_path="ash/ambient/ambient_photo_cache.cc" />
  <item id="ambient_photo_controller" added_in_milestone="98" content_hash_code="03284b8a" os_list="chromeos" file_path="ash/ambient/ambient_photo_controller.cc" />
  <item id="image_downloader" added_in_milestone="98" content_hash_code="05b52680" os_list="chromeos" file_path="ash/assistant/assistant_controller_impl.cc" />
- <item id="fast_pair_footprints_request" added_in_milestone="98" type="partial" second_id="oauth2_api_call_flow" content_hash_code="0181e407" os_list="chromeos" semantics_fields="1,2,3,4,5" policy_fields="-1,3,5" file_path="ash/quick_pair/repository/fast_pair/footprints_fetcher.cc" />
+ <item id="fast_pair_footprints_request" added_in_milestone="98" type="partial" second_id="oauth2_api_call_flow" content_hash_code="01d3d58d" os_list="chromeos" semantics_fields="1,2,3,4,5" policy_fields="-1,3,5" file_path="ash/quick_pair/repository/fast_pair/footprints_fetcher.cc" />
  <item id="kiosk_app_icon" added_in_milestone="98" content_hash_code="04f02fef" os_list="chromeos" file_path="chrome/browser/ash/app_mode/web_app/web_kiosk_app_data.cc" />
  <item id="arc_auth_code_fetcher" added_in_milestone="98" content_hash_code="057519ca" os_list="chromeos" file_path="chrome/browser/ash/arc/auth/arc_background_auth_code_fetcher.cc" />
  <item id="customization_wallpaper_downloader" added_in_milestone="98" content_hash_code="03ee8364" os_list="chromeos" file_path="chrome/browser/ash/customization/customization_wallpaper_downloader.cc" />
@@ -353,4 +353,6 @@
  <item id="webapk_create" added_in_milestone="99" content_hash_code="07b8fd35" os_list="android" file_path="chrome/browser/android/webapk/webapk_installer.cc" />
  <item id="webapk_update" added_in_milestone="99" content_hash_code="0763f8a7" os_list="android" file_path="chrome/browser/android/webapk/webapk_installer.cc" />
  <item id="safe_browsing_extension_telemetry" added_in_milestone="98" content_hash_code="07998e68" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_uploader.cc" />
+ <item id="fast_pair_image_decoder" added_in_milestone="100" content_hash_code="04d764bc" os_list="chromeos" file_path="ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.cc" />
+ <item id="fast_pair_device_metadata_fetcher" added_in_milestone="100" content_hash_code="04d764bf" os_list="chromeos" file_path="ash/quick_pair/repository/fast_pair/device_metadata_fetcher.cc" />
 </annotations>
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml
index f61e0b30..e600a320 100644
--- a/tools/traffic_annotation/summary/grouping.xml
+++ b/tools/traffic_annotation/summary/grouping.xml
@@ -65,6 +65,8 @@
       <traffic_annotation unique_id="customization_wallpaper_downloader"/>
       <traffic_annotation unique_id="edu_account_login_profile_image_fetcher"/>
       <traffic_annotation unique_id="fast_pair_footprints_request"/>
+      <traffic_annotation unique_id="fast_pair_image_decoder"/>
+      <traffic_annotation unique_id="fast_pair_device_metadata_fetcher"/>
       <traffic_annotation unique_id="fwupd_firmware_update"/>
       <traffic_annotation unique_id="gaia_reauth_token_fetcher"/>
       <traffic_annotation unique_id="ime_url_downloader"/>
diff --git a/tools/update_pgo_profiles.py b/tools/update_pgo_profiles.py
index f48dbcf..9bb26de 100755
--- a/tools/update_pgo_profiles.py
+++ b/tools/update_pgo_profiles.py
@@ -132,7 +132,7 @@
   parser.add_argument(
       '--target',
       required=True,
-      choices=['win32', 'win64', 'mac', 'linux'],
+      choices=['win32', 'win64', 'mac', 'mac-arm', 'linux'],
       help='Identifier of a specific target platform + architecture.')
   subparsers = parser.add_subparsers()
 
diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn
index 2c23725ac..3b9e969 100644
--- a/ui/accessibility/BUILD.gn
+++ b/ui/accessibility/BUILD.gn
@@ -288,11 +288,15 @@
   data_deps = [ "//testing/buildbot/filters:accessibility_unittests_filters" ]
 
   if (is_fuchsia) {
-    sources += [ "platform/fuchsia/semantic_provider_unittest.cc" ]
+    sources += [
+      "platform/fuchsia/accessibility_bridge_fuchsia_unittest.cc",
+      "platform/fuchsia/semantic_provider_unittest.cc",
+    ]
 
     deps += [
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.math",
+      "//third_party/fuchsia-sdk/sdk/pkg/inspect",
       "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
       "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
     ]
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc
index 467e3615..443d33a 100644
--- a/ui/accessibility/ax_node.cc
+++ b/ui/accessibility/ax_node.cc
@@ -1405,10 +1405,23 @@
 }
 
 bool AXNode::IsOrderedSetItem() const {
+  // Tree grid rows should be treated as ordered set items. Since we don't have
+  // a separate row role for tree grid rows, we can't just add the Role::kRow to
+  // IsItemLike. We need to validate that the row is indeed part of a tree grid.
+  if (IsRowInTreeGrid(GetOrderedSet()))
+    return true;
+
   return ui::IsItemLike(GetRole());
 }
 
 bool AXNode::IsOrderedSet() const {
+  // Tree grid rows should be considered like ordered set items and a tree grid
+  // like an ordered set. Continuing that logic, in order to compute the right
+  // PosInSet and SetSize, row groups inside of a tree grid should also be
+  // ordered sets.
+  if (IsRowGroupInTreeGrid())
+    return true;
+
   return ui::IsSetLike(GetRole());
 }
 
@@ -1426,6 +1439,11 @@
 // Returns false otherwise.
 bool AXNode::SetRoleMatchesItemRole(const AXNode* ordered_set) const {
   ax::mojom::Role item_role = GetRole();
+
+  // Tree grid rows should be treated as ordered set items.
+  if (IsRowInTreeGrid(ordered_set))
+    return true;
+
   // Switch on role of ordered set
   switch (ordered_set->GetRole()) {
     case ax::mojom::Role::kFeed:
@@ -1451,6 +1469,8 @@
       return item_role == ax::mojom::Role::kTab;
     case ax::mojom::Role::kTree:
       return item_role == ax::mojom::Role::kTreeItem;
+    case ax::mojom::Role::kTreeGrid:
+      return item_role == ax::mojom::Role::kRow;
     case ax::mojom::Role::kListBox:
       return item_role == ax::mojom::Role::kListBoxOption;
     case ax::mojom::Role::kMenuListPopup:
@@ -1481,6 +1501,35 @@
          GetRole() == ax::mojom::Role::kUnknown;
 }
 
+bool AXNode::IsRowInTreeGrid(const AXNode* ordered_set) const {
+  // Tree grid rows have the requirement of being focusable, so we use it to
+  // avoid iterating over rows that clearly aren't part of a tree grid.
+  if (GetRole() != ax::mojom::Role::kRow ||
+      !HasState(ax::mojom::State::kFocusable) || !ordered_set) {
+    return false;
+  }
+
+  if (ordered_set->GetRole() == ax::mojom::Role::kTreeGrid)
+    return true;
+
+  return ordered_set->IsRowGroupInTreeGrid();
+}
+
+bool AXNode::IsRowGroupInTreeGrid() const {
+  // To the best of our understanding, row groups can't be nested.
+  //
+  // According to https://www.w3.org/TR/wai-aria-1.1/#rowgroup, a row group is a
+  // "structural equivalent to the thead, tfoot, and tbody elements in an HTML
+  // table". It is specified in the spec of the thead, tfoot and tbody elements
+  // that they need to be children of a table element, meaning that there can
+  // only be one level of such elements. We assume the same for row groups.
+  if (GetRole() != ax::mojom::Role::kRowGroup)
+    return false;
+
+  AXNode* ordered_set = GetOrderedSet();
+  return ordered_set && ordered_set->GetRole() == ax::mojom::Role::kTreeGrid;
+}
+
 int AXNode::UpdateUnignoredCachedValuesRecursive(int startIndex) {
   int count = 0;
   for (AXNode* child : children()) {
diff --git a/ui/accessibility/ax_node.h b/ui/accessibility/ax_node.h
index ddc239f..d506f62f 100644
--- a/ui/accessibility/ax_node.h
+++ b/ui/accessibility/ax_node.h
@@ -437,6 +437,12 @@
   // for ordered sets.
   bool IsIgnoredContainerForOrderedSet() const;
 
+  // Helper functions that returns true when we are on a row/row group inside of
+  // a tree grid. Also works for rows that are part of a row group inside a tree
+  // grid. Returns false otherwise.
+  bool IsRowInTreeGrid(const AXNode* ordered_set) const;
+  bool IsRowGroupInTreeGrid() const;
+
   // Returns the accessible name for this node. This could have originated from
   // e.g. an onscreen label, or an ARIA label.
   const std::string& GetNameUTF8() const;
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc
index a88900de..c507113 100644
--- a/ui/accessibility/ax_role_properties.cc
+++ b/ui/accessibility/ax_role_properties.cc
@@ -691,6 +691,7 @@
     case ax::mojom::Role::kRadioGroup:
     case ax::mojom::Role::kTabList:
     case ax::mojom::Role::kTree:
+    case ax::mojom::Role::kTreeGrid:
       return true;
     default:
       return false;
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc
index be415ff2..8cb6152a 100644
--- a/ui/accessibility/ax_tree.cc
+++ b/ui/accessibility/ax_tree.cc
@@ -2359,7 +2359,7 @@
   // not necessarily need to be contained in an ordered set.
   if (node.GetRole() != ax::mojom::Role::kComment &&
       node.GetRole() != ax::mojom::Role::kRadioButton &&
-      !node.SetRoleMatchesItemRole(ordered_set) && !IsSetLike(node.GetRole()))
+      !node.SetRoleMatchesItemRole(ordered_set) && !node.IsOrderedSet())
     return;
 
   // Find all items within ordered_set and add to |items_map_to_be_populated|.
@@ -2511,7 +2511,6 @@
   if (!ordered_set)
     return absl::nullopt;
 
-  // Compute, cache, then return.
   ComputeSetSizePosInSetAndCache(node, ordered_set);
   absl::optional<int> pos_in_set =
       node_set_size_pos_in_set_info_map_[node.id()].pos_in_set;
@@ -2545,11 +2544,12 @@
     return absl::nullopt;
   }
 
-  // If |node| is item-like, find its outerlying ordered set. Otherwise,
-  // |node| is the ordered set.
+  // If |node| is an ordered set item-like, find its outerlying ordered set.
+  // Otherwise, |node| is the ordered set.
   const AXNode* ordered_set = &node;
-  if (IsItemLike(node.GetRole()))
+  if (node.IsOrderedSetItem())
     ordered_set = node.GetOrderedSet();
+
   if (!ordered_set)
     return absl::nullopt;
 
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc
index 84813fd..a7d9a3d3 100644
--- a/ui/accessibility/ax_tree_unittest.cc
+++ b/ui/accessibility/ax_tree_unittest.cc
@@ -3468,6 +3468,37 @@
   EXPECT_OPTIONAL_EQ(3, item3->GetSetSize());
 }
 
+// Tests that PosInSet and SetSize can be calculated for TreeGrid rows if not
+// assigned.
+TEST(AXTreeTest, SetSizePosInSetInTreeGridUnassigned) {
+  AXTreeUpdate tree_update;
+  tree_update.root_id = 1;
+  tree_update.nodes.resize(4);
+  tree_update.nodes[0].id = 1;
+  tree_update.nodes[0].role = ax::mojom::Role::kTreeGrid;
+  tree_update.nodes[0].child_ids = {2, 3, 4};
+  tree_update.nodes[1].id = 2;
+  tree_update.nodes[1].role = ax::mojom::Role::kRow;
+  tree_update.nodes[1].AddState(ax::mojom::State::kFocusable);
+  tree_update.nodes[2].id = 3;
+  tree_update.nodes[2].role = ax::mojom::Role::kRow;
+  tree_update.nodes[2].AddState(ax::mojom::State::kFocusable);
+  tree_update.nodes[3].id = 4;
+  tree_update.nodes[3].role = ax::mojom::Role::kRow;
+  tree_update.nodes[3].AddState(ax::mojom::State::kFocusable);
+  AXTree tree(tree_update);
+
+  AXNode* item1 = tree.GetFromId(2);
+  EXPECT_OPTIONAL_EQ(1, item1->GetPosInSet());
+  EXPECT_OPTIONAL_EQ(3, item1->GetSetSize());
+  AXNode* item2 = tree.GetFromId(3);
+  EXPECT_OPTIONAL_EQ(2, item2->GetPosInSet());
+  EXPECT_OPTIONAL_EQ(3, item2->GetSetSize());
+  AXNode* item3 = tree.GetFromId(4);
+  EXPECT_OPTIONAL_EQ(3, item3->GetPosInSet());
+  EXPECT_OPTIONAL_EQ(3, item3->GetSetSize());
+}
+
 // Tests PosInSet can be calculated if unassigned, and SetSize can be
 // assigned on the outerlying ordered set.
 TEST(AXTreeTest, SetSizeAssignedOnContainer) {
diff --git a/ui/accessibility/extensions/caretbrowsing/background.js b/ui/accessibility/extensions/caretbrowsing/background.js
index 36758383..6d74826 100644
--- a/ui/accessibility/extensions/caretbrowsing/background.js
+++ b/ui/accessibility/extensions/caretbrowsing/background.js
@@ -32,11 +32,11 @@
  * Change the browser action icon and tooltip based on the enabled state.
  */
 CaretBkgnd.setIcon = function() {
-  chrome.browserAction.setIcon(
+  chrome.action.setIcon(
       {'path': CaretBkgnd.isEnabled ?
                '../caret_19_on.png' :
                '../caret_19.png'});
-  chrome.browserAction.setTitle(
+  chrome.action.setTitle(
       {'title': CaretBkgnd.isEnabled ?
                 'Turn Off Caret Browsing (F7)' :
                 'Turn On Caret Browsing (F7)' });
@@ -50,18 +50,17 @@
  */
 CaretBkgnd.injectContentScripts = function() {
   chrome.windows.getAll({'populate': true}, function(windows) {
-    for (let i = 0; i < windows.length; i++) {
-      const tabs = windows[i].tabs;
-      for (let j = 0; j < tabs.length; j++) {
-        for (let k = 0; k < CONTENT_SCRIPTS.length; k++) {
-          chrome.tabs.executeScript(
-              tabs[j].id,
-              {file: CONTENT_SCRIPTS[k], allFrames: true},
-              function(result) {
-                // Ignore.
-                chrome.runtime.lastError;
-              });
-        }
+    for (const w of windows) {
+      for (const tab of w.tabs) {
+        chrome.scripting.executeScript(
+            {
+              target: {tabId: tab.id, allFrames: true},
+              files: CONTENT_SCRIPTS,
+            },
+            function(result) {
+              // Ignore.
+              chrome.runtime.lastError;
+            });
       }
     }
   });
@@ -92,7 +91,7 @@
     CaretBkgnd.setIcon();
     CaretBkgnd.injectContentScripts();
 
-    chrome.browserAction.onClicked.addListener(function(tab) {
+    chrome.action.onClicked.addListener(function(tab) {
       CaretBkgnd.toggle();
     });
   });
diff --git a/ui/accessibility/extensions/caretbrowsing/manifest.json b/ui/accessibility/extensions/caretbrowsing/manifest.json
index 065b3730..bc32ce38 100644
--- a/ui/accessibility/extensions/caretbrowsing/manifest.json
+++ b/ui/accessibility/extensions/caretbrowsing/manifest.json
@@ -2,16 +2,16 @@
   "name": "__MSG_CARET_BROWSING_APPNAME__",
   "version": "1.0.2",
   "description": "__MSG_CARET_BROWSING_APPDESC__",
-  "manifest_version": 2,
+  "manifest_version": 3,
   "permissions": [
-    "<all_urls>",
-    "storage",
-    "tabs"
+    "scripting",
+    "storage"
   ],
+  "host_permissions": [ "<all_urls>" ],
   "background": {
     "service_worker": "background.js"
   },
-  "browser_action": {
+  "action": {
     "default_icon": "caret_19.png",
     "default_title": "__MSG_CARET_BROWSING_APPNAME__"
   },
diff --git a/ui/accessibility/extensions/colorenhancer/src/background.js b/ui/accessibility/extensions/colorenhancer/src/background.js
index f77eacf..01b8fbc 100644
--- a/ui/accessibility/extensions/colorenhancer/src/background.js
+++ b/ui/accessibility/extensions/colorenhancer/src/background.js
@@ -4,70 +4,65 @@
 
 importScripts('./common.js', './storage.js');
 
+const storage = new Storage();
+
+function forEachTab(tabCallback) {
+  chrome.windows.getAll({'populate': true}, windows => {
+    for (const w of windows) {
+      for (const tab of w.tabs) {
+        if (isDisallowedUrl(tab.url)) {
+          continue;
+        }
+        tabCallback(tab);
+      }
+    }
+  });
+}
+
 /**
  * Adds filter script and css to all existing tabs.
  *
  * TODO(wnwen): Verify content scripts are not being injected multiple times.
  */
 function injectContentScripts() {
-  chrome.windows.getAll({'populate': true}, function(windows) {
-    for (let i = 0; i < windows.length; i++) {
-      const tabs = windows[i].tabs;
-      for (let j = 0; j < tabs.length; j++) {
-        const url = tabs[j].url;
-        if (isDisallowedUrl(url)) {
-          continue;
-        }
-        chrome.scripting.executeScript({
-          target: {tabId: tabs[j].id},
-          files: ['src/common.js', 'src/cvd.js'],
-        });
-      }
-    }
-  });
+  forEachTab(tab => chrome.scripting.executeScript({
+      target: {tabId: tab.id},
+      files: ['src/common.js', 'src/cvd.js'],
+    }));
 }
 
 /**
  * Updates all existing tabs with config values.
  */
 function updateTabs() {
-  chrome.windows.getAll({'populate': true}, async function(windows) {
-    for (let i = 0; i < windows.length; i++) {
-      const tabs = windows[i].tabs;
-      for (let j = 0; j < tabs.length; j++) {
-        const url = tabs[j].url;
-        if (isDisallowedUrl(url)) {
-          continue;
-        }
-        const msg = {
-          'delta': await getSiteDelta(siteFromUrl(url)),
-          'severity': await getDefaultSeverity(),
-          'type': await getDefaultType(),
-          'simulate': await getDefaultSimulate(),
-          'enable': await getDefaultEnable()
-        };
-        debugPrint('updateTabs: sending ' + JSON.stringify(msg) + ' to ' +
-            siteFromUrl(url));
-        chrome.tabs.sendMessage(tabs[j].id, msg);
-      }
-    }
+  forEachTab(async function(tab) {
+    const msg = {
+      'delta': await storage.getSiteDelta(siteFromUrl(tab.url)),
+      'severity': await storage.getDefaultSeverity(),
+      'type': await storage.getDefaultType(),
+      'simulate': await storage.getDefaultSimulate(),
+      'enable': await storage.getDefaultEnable()
+    };
+    debugPrint('updateTabs: sending ' + JSON.stringify(msg) + ' to ' +
+        siteFromUrl(tab.url));
+    chrome.tabs.sendMessage(tab.id, msg);
   });
 }
 
 async function onInitReceived(sender) {
   let delta;
   if (sender.tab) {
-    delta = await getSiteDelta(siteFromUrl(sender.tab.url));
+    delta = await storage.getSiteDelta(siteFromUrl(sender.tab.url));
   } else {
-    delta = await getDefaultDelta();
+    delta = await storage.getDefaultDelta();
   }
 
   return {
     'delta': delta,
-    'severity': await getDefaultSeverity(),
-    'type': await getDefaultType(),
-    'simulate': await getDefaultSimulate(),
-    'enable': await getDefaultEnable()
+    'severity': await storage.getDefaultSeverity(),
+    'type': await storage.getDefaultType(),
+    'simulate': await storage.getDefaultSimulate(),
+    'enable': await storage.getDefaultEnable()
   };
 }
 
diff --git a/ui/accessibility/extensions/colorenhancer/src/popup.js b/ui/accessibility/extensions/colorenhancer/src/popup.js
index a83aca75..a14046ea 100644
--- a/ui/accessibility/extensions/colorenhancer/src/popup.js
+++ b/ui/accessibility/extensions/colorenhancer/src/popup.js
@@ -130,7 +130,7 @@
    * @return {boolean} True if settings are valid and update performed.
    */
   async update() {
-    const type = await getDefaultType();
+    const type = await storage.getDefaultType();
     let validType = false;
     Popup.CVD_TYPES.forEach((cvdType) => {
       if (cvdType == type) {
@@ -143,22 +143,22 @@
       return false;
 
     if (this.site) {
-      $('delta').value = await getSiteDelta(this.site);
+      $('delta').value = await storage.getSiteDelta(this.site);
     } else {
-      $('delta').value = await getDefaultDelta();
+      $('delta').value = await storage.getDefaultDelta();
     }
 
-    $('severity').value = await getDefaultSeverity();
+    $('severity').value = await storage.getDefaultSeverity();
 
     if (!$('setup-panel').classList.contains('collapsed'))
-      this.setCvdTypeSelection(await getDefaultType());
-    $('enable').checked = await getDefaultEnable();
+      this.setCvdTypeSelection(await storage.getDefaultType());
+    $('enable').checked = await storage.getDefaultEnable();
 
     debugPrint(
         'update: ' +
         ' del=' + $('delta').value + ' sev=' + $('severity').value +
-        ' typ=' + await getDefaultType() + ' enb=' + $('enable').checked +
-        ' for ' + this.site);
+        ' typ=' + await storage.getDefaultType() +
+        ' enb=' + $('enable').checked + ' for ' + this.site);
     chrome.runtime.sendMessage('updateTabs');
     return true;
   }
@@ -171,9 +171,9 @@
   onDeltaChange(value) {
     debugPrint('onDeltaChange: ' + value + ' for ' + this.site);
     if (this.site) {
-      setSiteDelta(this.site, value).then(this.update.bind(this));
+      storage.setSiteDelta(this.site, value).then(this.update.bind(this));
     }
-    setDefaultDelta(value).then(this.update.bind(this));
+    storage.setDefaultDelta(value).then(this.update.bind(this));
   }
 
   /**
@@ -183,7 +183,7 @@
    */
   onSeverityChange(value) {
     debugPrint('onSeverityChange: ' + value + ' for ' + this.site);
-    setDefaultSeverity(value).then(() => {
+    storage.setDefaultSeverity(value).then(() => {
       this.update();
       // Apply filter to popup swatches.
       const filter = window.getDefaultCvdCorrectionFilter(
@@ -201,7 +201,7 @@
    */
   onTypeChange(value) {
     debugPrint('onTypeChange: ' + value + ' for ' + this.site);
-    setDefaultType(value).then(() => {
+    storage.setDefaultType(value).then(() => {
       this.update();
       $('severity').value = 0;
       this.updateControls();
@@ -215,7 +215,7 @@
   */
   onEnableChange(value) {
     debugPrint('onEnableChange: ' + value + ' for ' + this.site);
-    setDefaultEnable(value).then(() => {
+    storage.setDefaultEnable(value).then(() => {
       if (!this.update()) {
         // Settings are not valid for a reconfiguration.
         $('setup').onclick();
@@ -239,8 +239,8 @@
       $('setup-panel').classList.remove('collapsed');
       // Store current settings in the event of a canceled setup.
       this.restoreSettings = {
-        type: await getDefaultType(),
-        severity: await getDefaultSeverity()
+        type: await storage.getDefaultType(),
+        severity: await storage.getDefaultSeverity()
       };
       // Initialize controls based on current settings.
       this.setCvdTypeSelection(this.restoreSettings.type);
@@ -259,9 +259,9 @@
     });
 
     $('reset').onclick = () => {
-      setDefaultSeverity(0);
-      setDefaultType('');
-      setDefaultEnable(false);
+      storage.setDefaultSeverity(0);
+      storage.setDefaultType('');
+      storage.setDefaultEnable(false);
       $('severity').value = 0;
       $('enable').checked = false;
       this.setCvdTypeSelection('');
@@ -286,8 +286,8 @@
             'restore previous settings: ' +
             'type = ' + this.restoreSettings.type +
             ', severity = ' + this.restoreSettings.severity);
-        setDefaultType(this.restoreSettings.type);
-        setDefaultSeverity(this.restoreSettings.severity);
+        storage.setDefaultType(this.restoreSettings.type);
+        storage.setDefaultSeverity(this.restoreSettings.severity);
       }
     };
 
@@ -380,4 +380,7 @@
   },
 ];
 
-window.addEventListener('DOMContentLoaded', () => window.popup = new Popup());
+window.addEventListener('DOMContentLoaded', () => {
+  window.popup = new Popup();
+  window.storage = new Storage();
+});
diff --git a/ui/accessibility/extensions/colorenhancer/src/storage.js b/ui/accessibility/extensions/colorenhancer/src/storage.js
index 3eee2781..e9ef887 100644
--- a/ui/accessibility/extensions/colorenhancer/src/storage.js
+++ b/ui/accessibility/extensions/colorenhancer/src/storage.js
@@ -2,210 +2,271 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// TODO(wnwen): Wrap calls, add JsDocs.
+// TODO(wnwen): Wrap calls.
 
-function validBoolean(b) {
-  return b == true || b == false;
-}
+class Storage {
+  // ======= Delta setting =======
 
-function store_(key, val, callback) {
-  const newVals = {};
-  newVals[key] = val;
-  chrome.storage.local.set(newVals, callback);
-}
-
-// ======= Delta setting =======
-
-/** @const {number} */ const DEFAULT_DELTA = 0.5;
-/** @const {string} */ const LOCAL_STORAGE_TAG_DELTA = 'cvd_delta';
-/** @const {string} */ const LOCAL_STORAGE_TAG_SITE_DELTA = 'cvd_site_delta';
-
-function validDelta(delta) {
-  return delta >= 0 && delta <= 1;
-}
-
-function getDefaultDelta() {
-  return new Promise(resolve => {
-    chrome.storage.local.get([LOCAL_STORAGE_TAG_DELTA], (result) => {
-      let delta = result[LOCAL_STORAGE_TAG_DELTA];
-      if (validDelta(delta)) {
-        resolve(delta);
-        return;
-      }
-      delta = DEFAULT_DELTA;
-      store_(LOCAL_STORAGE_TAG_DELTA, delta, () => resolve(delta));
-    });
-  });
-}
-
-function setDefaultDelta(delta) {
-  if (!validDelta(delta)) {
-    delta = DEFAULT_DELTA;
+  /**
+   * @param {number} delta
+   * @return {boolean}
+   * @private
+   */
+  validDelta_(delta) {
+    return delta >= 0 && delta <= 1;
   }
-  return new Promise(
-      resolve => store_(LOCAL_STORAGE_TAG_DELTA, delta, resolve));
-}
 
-function getSiteDelta(site) {
-  return new Promise(resolve => {
-    chrome.storage.local.get([LOCAL_STORAGE_TAG_SITE_DELTA], (result) => {
-      let delta;
-      try {
-        const siteDeltas = result[LOCAL_STORAGE_TAG_SITE_DELTA] || {};
-        delta = siteDeltas[site];
-        if (!validDelta(delta)) {
-          getDefaultDelta().then(resolve);
+  /** @return {Promise<number>} */
+  getDefaultDelta() {
+    return new Promise(resolve => {
+      chrome.storage.local.get([Storage.DELTA_TAG], (result) => {
+        let delta = result[Storage.DELTA_TAG];
+        if (this.validDelta_(delta)) {
+          resolve(delta);
           return;
         }
-      } catch (e) {
-        getDefaultDelta().then(resolve);
-        return;
-      }
-      resolve(delta);
+        delta = Storage.DEFAULT_DELTA;
+        this.store_(Storage.DELTA_TAG, delta, () => resolve(delta));
+      });
     });
-  });
-}
+  }
 
-function setSiteDelta(site, delta) {
-  return new Promise(async resolve => {
-    if (!validDelta(delta)) {
-      delta = await getDefaultDelta();
+  /**
+   * @param {number} delta
+   * @return {Promise}
+   */
+  setDefaultDelta(delta) {
+    if (!this.validDelta_(delta)) {
+      delta = Storage.DEFAULT_DELTA;
     }
-    chrome.storage.local.get([LOCAL_STORAGE_TAG_SITE_DELTA], (result) => {
-      let siteDeltas = {};
-      try {
-        siteDeltas = result[LOCAL_STORAGE_TAG_SITE_DELTA] || {};
-      } catch (e) {
-        siteDeltas = {};
-      }
-      siteDeltas[site] = delta;
-      store_(LOCAL_STORAGE_TAG_SITE_DELTA, siteDeltas, resolve);
-    });
-  });
-}
-
-function resetSiteDeltas() {
-  return new Promise(
-      resolve => store_(LOCAL_STORAGE_TAG_SITE_DELTA, {}, resolve));
-}
-
-// ======= Severity setting =======
-
-/** @const {number} */ const DEFAULT_SEVERITY = 1.0;
-/** @const {string} */ const LOCAL_STORAGE_TAG_SEVERITY = 'cvd_severity';
-
-
-function validSeverity(severity) {
-  return severity >= 0 && severity <= 1;
-}
-
-function getDefaultSeverity() {
-  return new Promise(resolve => {
-    chrome.storage.local.get([LOCAL_STORAGE_TAG_SEVERITY], (result) => {
-      let severity = result[LOCAL_STORAGE_TAG_SEVERITY];
-      if (validSeverity(severity)) {
-        resolve(severity);
-        return;
-      }
-      severity = DEFAULT_SEVERITY;
-      store_(LOCAL_STORAGE_TAG_SEVERITY, severity, () => resolve(severity));
-    });
-  });
-}
-
-function setDefaultSeverity(severity) {
-  if (!validSeverity(severity)) {
-    severity = DEFAULT_SEVERITY;
+    return new Promise(
+        resolve => this.store_(Storage.DELTA_TAG, delta, resolve));
   }
-  return new Promise(
-      resolve => store_(LOCAL_STORAGE_TAG_SEVERITY, severity, resolve));
-}
 
-// ======= Type setting =======
-
-/** @const {string} */ const INVALID_TYPE_PLACEHOLDER = '';
-/** @const {string} */ const LOCAL_STORAGE_TAG_TYPE = 'cvd_type';
-
-function validType(type) {
-  return type === 'PROTANOMALY' ||
-      type === 'DEUTERANOMALY' ||
-      type === 'TRITANOMALY';
-}
-
-function getDefaultType() {
-  return new Promise(resolve => {
-    chrome.storage.local.get([LOCAL_STORAGE_TAG_TYPE], (result) => {
-      const type = result[LOCAL_STORAGE_TAG_TYPE];
-      if (validType(type)) {
-        resolve(type);
-      } else {
-        // TODO(anastasi): add appropriate error handling
-        resolve();
-      }
+  /**
+   * @param {string} site
+   * @return {Promise<number>}
+   */
+  getSiteDelta(site) {
+    return new Promise(resolve => {
+      chrome.storage.local.get([Storage.PER_SITE_DELTA_TAG], (result) => {
+        const siteDeltas = result [Storage.PER_SITE_DELTA_TAG] || {};
+        const delta = siteDeltas[site];
+        if (!this.validDelta_(delta)) {
+          this.getDefaultDelta().then(resolve);
+          return;
+        }
+        resolve(delta);
+      });
     });
-  });
-}
-
-function setDefaultType(type) {
-  if (!validType(type)) {
-    type = INVALID_TYPE_PLACEHOLDER;
   }
-  return new Promise(
-      resolve => store_(LOCAL_STORAGE_TAG_TYPE, type, resolve));
-}
 
-// ======= Simulate setting =======
-
-/** @const {boolean} */ const DEFAULT_SIMULATE = false;
-/** @const {string} */ const LOCAL_STORAGE_TAG_SIMULATE = 'cvd_simulate';
-
-function getDefaultSimulate() {
-  return new Promise(resolve => {
-    chrome.storage.local.get([LOCAL_STORAGE_TAG_SIMULATE], (result) => {
-      let simulate = result[LOCAL_STORAGE_TAG_SIMULATE];
-
-      if (validBoolean(simulate)) {
-        resolve(simulate);
-        return;
+  /**
+   * @param {string} site
+   * @param {number} delta
+   * @return {Promise}
+   */
+  setSiteDelta(site, delta) {
+    return new Promise(async resolve => {
+      if (!this.validDelta_(delta)) {
+        delta = await this.getDefaultDelta();
       }
-      simulate = DEFAULT_SIMULATE;
-      store_(LOCAL_STORAGE_TAG_SIMULATE, simulate, () => resolve(simulate));
+      chrome.storage.local.get([Storage.PER_SITE_DELTA_TAG], (result) => {
+        const siteDeltas = result[Storage.PER_SITE_DELTA_TAG] || {};
+        siteDeltas[site] = delta;
+        this.store_(Storage.PER_SITE_DELTA_TAG, siteDeltas, resolve);
+      });
     });
-  });
-}
-
-function setDefaultSimulate(simulate) {
-  if (!validBoolean(simulate)) {
-    simulate = DEFAULT_SIMULATE;
   }
-  return new Promise(
-      resolve => store_(LOCAL_STORAGE_TAG_SIMULATE, simulate, resolve));
-}
 
-// ======= Enable setting =======
+  /** @return {Promise} */
+  resetSiteDeltas() {
+    return new Promise(
+        resolve => this.store_(Storage.PER_SITE_DELTA_TAG, {}, resolve));
+  }
 
-/** @const {boolean} */ const DEFAULT_ENABLE = false;
-/** @const {string} */ const LOCAL_STORAGE_TAG_ENABLE = 'cvd_enable';
+  // ======= Severity setting =======
 
-function getDefaultEnable() {
-  return new Promise(resolve => {
-    chrome.storage.local.get([LOCAL_STORAGE_TAG_ENABLE], (result) => {
-      let enable = result[LOCAL_STORAGE_TAG_ENABLE];
+  /**
+   * @param {number} severity
+   * @return {boolean}
+   * @private
+   */
+  validSeverity_(severity) {
+    return severity >= 0 && severity <= 1;
+  }
 
-      if (validBoolean(enable)) {
-        resolve(enable);
-        return;
-      }
-      enable = DEFAULT_ENABLE;
-      store_(LOCAL_STORAGE_TAG_ENABLE, enable, () => resolve(enable));
+  /** @return {Promise<number>} */
+  getDefaultSeverity() {
+    return new Promise(resolve => {
+      chrome.storage.local.get([Storage.SEVERITY_TAG], (result) => {
+        let severity = result[Storage.SEVERITY_TAG];
+        if (this.validSeverity_(severity)) {
+          resolve(severity);
+          return;
+        }
+        severity = Storage.DEFAULT_SEVERITY;
+        this.store_(Storage.SEVERITY_TAG, severity, () => resolve(severity));
+      });
     });
-  });
+  }
+
+  /**
+   * @param {number} severity
+   * @return {Promise}
+   */
+  setDefaultSeverity(severity) {
+    if (!this.validSeverity_(severity)) {
+      severity = Storage.DEFAULT_SEVERITY;
+    }
+    return new Promise(
+        resolve => this.store_(Storage.SEVERITY_TAG, severity, resolve));
+  }
+
+  // ======= Type setting =======
+
+  /**
+   * @param {string} type
+   * @return {boolean}
+   * @private
+   */
+  validType_(type) {
+    return type === 'PROTANOMALY' || type === 'DEUTERANOMALY' ||
+        type === 'TRITANOMALY';
+  }
+
+  /** @return {Promise<string>} */
+  getDefaultType() {
+    return new Promise(resolve => {
+      chrome.storage.local.get([Storage.TYPE_TAG], (result) => {
+        const type = result[Storage.TYPE_TAG];
+        if (this.validType_(type)) {
+          resolve(type);
+        } else {
+          // TODO(anastasi): add appropriate error handling
+          resolve(Storage.INVALID_TYPE_PLACEHOLDER);
+        }
+      });
+    });
+  }
+
+  /**
+   * @param {string} type
+   * @return {Promise}
+   */
+  setDefaultType(type) {
+    if (!this.validType_(type)) {
+      type = Storage.INVALID_TYPE_PLACEHOLDER;
+    }
+    return new Promise(resolve => this.store_(Storage.TYPE_TAG, type, resolve));
+  }
+
+  // ======= Simulate setting =======
+
+  /** @return {Promise<boolean>} */
+  getDefaultSimulate() {
+    return new Promise(resolve => {
+      chrome.storage.local.get([Storage.SIMULATE_TAG], (result) => {
+        let simulate = result[Storage.SIMULATE_TAG];
+
+        if (this.validBoolean_(simulate)) {
+          resolve(simulate);
+          return;
+        }
+        simulate = Storage.DEFAULT_SIMULATE;
+        this.store_(Storage.SIMULATE_TAG, simulate, () => resolve(simulate));
+      });
+    });
+  }
+
+  /**
+   * @param {boolean} simulate
+   * @return {Promise}
+   */
+  setDefaultSimulate(simulate) {
+    if (!this.validBoolean_(simulate)) {
+      simulate = Storage.DEFAULT_SIMULATE;
+    }
+    return new Promise(
+        resolve => this.store_(Storage.SIMULATE_TAG, simulate, resolve));
+  }
+
+  // ======= Enable setting =======
+
+  /** @return {Promise<boolean>} */
+  getDefaultEnable() {
+    return new Promise(resolve => {
+      chrome.storage.local.get([Storage.ENABLE_TAG], (result) => {
+        let enable = result[Storage.ENABLE_TAG];
+
+        if (this.validBoolean_(enable)) {
+          resolve(enable);
+          return;
+        }
+        enable = Storage.DEFAULT_ENABLE;
+        this.store_(Storage.ENABLE_TAG, enable, () => resolve(enable));
+      });
+    });
+  }
+
+  /**
+   * @param {boolean} enable
+   * @return {Promise}
+   */
+  setDefaultEnable(enable) {
+    if (!this.validBoolean_(enable)) {
+      enable = Storage.DEFAULT_ENABLE;
+    }
+    return new Promise(
+        resolve => this.store_(Storage.ENABLE_TAG, enable, resolve));
+  }
+
+  // ======= Helper functions ========
+
+  /**
+   * @return {boolean}
+   * @private
+   */
+  validBoolean_(b) {
+    return b == true || b == false;
+  }
+
+  /**
+   * @param {*} key
+   * @param {*} val
+   * @param {function()} callback
+   * @private
+   */
+  store_(key, val, callback) {
+    const newVals = {};
+    newVals[key] = val;
+    chrome.storage.local.set(newVals, callback);
+  }
 }
 
-function setDefaultEnable(enable) {
-  if (!validBoolean(enable)) {
-    enable = DEFAULT_ENABLE;
-  }
-  return new Promise(
-      resolve => store_(LOCAL_STORAGE_TAG_ENABLE, enable, resolve));
-}
+/** @const {number} */
+Storage.DEFAULT_DELTA = 0.5;
+/** @const {string} */
+Storage.DELTA_TAG = 'cvd_delta';
+/** @const {string} */
+Storage.PER_SITE_DELTA_TAG = 'cvd_site_delta';
+
+/** @const {number} */
+Storage.DEFAULT_SEVERITY = 1.0;
+/** @const {string} */
+Storage.SEVERITY_TAG = 'cvd_severity';
+
+/** @const {string} */
+Storage.INVALID_TYPE_PLACEHOLDER = '';
+/** @const {string} */
+Storage.TYPE_TAG = 'cvd_type';
+
+/** @const {boolean} */
+Storage.DEFAULT_SIMULATE = false;
+/** @const {string} */
+Storage.SIMULATE_TAG = 'cvd_simulate';
+
+/** @const {boolean} */
+Storage.DEFAULT_ENABLE = false;
+/** @const {string} */
+Storage.ENABLE_TAG = 'cvd_enable';
diff --git a/ui/accessibility/platform/BUILD.gn b/ui/accessibility/platform/BUILD.gn
index 506d9ef..a7fb808 100644
--- a/ui/accessibility/platform/BUILD.gn
+++ b/ui/accessibility/platform/BUILD.gn
@@ -91,12 +91,15 @@
   if (is_fuchsia) {
     sources += [
       "fuchsia/accessibility_bridge_fuchsia.h",
+      "fuchsia/accessibility_bridge_fuchsia_impl.cc",
+      "fuchsia/accessibility_bridge_fuchsia_impl.h",
       "fuchsia/accessibility_bridge_fuchsia_registry.cc",
       "fuchsia/accessibility_bridge_fuchsia_registry.h",
       "fuchsia/ax_platform_node_fuchsia.cc",
       "fuchsia/ax_platform_node_fuchsia.h",
-      "fuchsia/semantic_provider.cc",
       "fuchsia/semantic_provider.h",
+      "fuchsia/semantic_provider_impl.cc",
+      "fuchsia/semantic_provider_impl.h",
     ]
 
     public_deps += [
@@ -104,6 +107,7 @@
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.math",
+      "//third_party/fuchsia-sdk/sdk/pkg/inspect",
       "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
       "//ui/aura",
     ]
diff --git a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h
index c81511b..de6a2f71 100644
--- a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h
+++ b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h
@@ -6,6 +6,7 @@
 #define UI_ACCESSIBILITY_PLATFORM_FUCHSIA_ACCESSIBILITY_BRIDGE_FUCHSIA_H_
 
 #include <fuchsia/accessibility/semantics/cpp/fidl.h>
+#include <lib/inspect/cpp/vmo/types.h>
 
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/accessibility/ax_export.h"
@@ -44,6 +45,9 @@
 
   // Specifies the unique ID of the root platform node.
   virtual void SetRootID(uint32_t root_node_id) = 0;
+
+  // Returns an inspect::Node for the caller to own.
+  virtual inspect::Node GetInspectNode() = 0;
 };
 
 }  // namespace ui
diff --git a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.cc b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.cc
new file mode 100644
index 0000000..6358432
--- /dev/null
+++ b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.cc
@@ -0,0 +1,254 @@
+// Copyright 2022 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 "ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h"
+
+#include "base/strings/stringprintf.h"
+#include "ui/accessibility/ax_action_data.h"
+#include "ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_registry.h"
+#include "ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h"
+#include "ui/accessibility/platform/fuchsia/semantic_provider_impl.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+
+namespace ui {
+namespace {
+
+using HitTestCallback =
+    fuchsia::accessibility::semantics::SemanticListener::HitTestCallback;
+
+// Error allowed for each edge when converting from gfx::RectF to gfx::Rect.
+constexpr float kRectConversionError = 0.5;
+
+absl::optional<ax::mojom::Action> ConvertAction(
+    fuchsia::accessibility::semantics::Action fuchsia_action) {
+  switch (fuchsia_action) {
+    case fuchsia::accessibility::semantics::Action::DEFAULT:
+      return ax::mojom::Action::kDoDefault;
+    case fuchsia::accessibility::semantics::Action::DECREMENT:
+      return ax::mojom::Action::kDecrement;
+    case fuchsia::accessibility::semantics::Action::INCREMENT:
+      return ax::mojom::Action::kIncrement;
+    case fuchsia::accessibility::semantics::Action::SHOW_ON_SCREEN:
+      return ax::mojom::Action::kScrollToMakeVisible;
+    case fuchsia::accessibility::semantics::Action::SECONDARY:
+      LOG(WARNING) << "SECONDARY action not supported";
+      return {};
+    case fuchsia::accessibility::semantics::Action::SET_FOCUS:
+      return ax::mojom::Action::kFocus;
+    case fuchsia::accessibility::semantics::Action::SET_VALUE:
+      return ax::mojom::Action::kSetValue;
+    default:
+      LOG(WARNING)
+          << "Unknown fuchsia::accessibility::semantics::Action with value "
+          << static_cast<int>(fuchsia_action);
+      return {};
+  }
+}
+
+}  // namespace
+
+AccessibilityBridgeFuchsiaImpl::AccessibilityBridgeFuchsiaImpl(
+    aura::Window* window,
+    fuchsia::ui::views::ViewRef view_ref,
+    base::RepeatingCallback<float()> get_pixel_scale,
+    base::RepeatingCallback<void(bool)> on_semantics_enabled,
+    base::RepeatingCallback<bool()> on_connection_closed,
+    inspect::Node inspect_node)
+    : root_window_(window),
+      on_semantics_enabled_(std::move(on_semantics_enabled)),
+      on_connection_closed_(std::move(on_connection_closed)),
+      inspect_node_(std::move(inspect_node)) {
+  semantic_provider_ = std::make_unique<ui::AXFuchsiaSemanticProviderImpl>(
+      std::move(view_ref), std::move(get_pixel_scale), this);
+
+  ui::AccessibilityBridgeFuchsiaRegistry* registry =
+      ui::AccessibilityBridgeFuchsiaRegistry::GetInstance();
+  DCHECK(registry);
+  if (root_window_)
+    registry->RegisterAccessibilityBridge(root_window_, this);
+}
+
+AccessibilityBridgeFuchsiaImpl::~AccessibilityBridgeFuchsiaImpl() {
+  ui::AccessibilityBridgeFuchsiaRegistry* registry =
+      ui::AccessibilityBridgeFuchsiaRegistry::GetInstance();
+  DCHECK(registry);
+  if (root_window_)
+    registry->UnregisterAccessibilityBridge(root_window_);
+}
+
+uint32_t AccessibilityBridgeFuchsiaImpl::MaybeToFuchsiaRootID(
+    uint32_t node_id) {
+  // If |node_id| refers to the root, then map to fuchsia ID 0. Otherwise,
+  // use |node_id| directly.
+  if (root_node_id_ && node_id == *root_node_id_)
+    return AXFuchsiaSemanticProvider::kFuchsiaRootNodeId;
+
+  return node_id;
+}
+
+void AccessibilityBridgeFuchsiaImpl::UpdateNode(
+    fuchsia::accessibility::semantics::Node node) {
+  DCHECK(node.has_node_id());
+
+  node.set_node_id(MaybeToFuchsiaRootID(node.node_id()));
+
+  if (node.has_container_id())
+    node.set_container_id(MaybeToFuchsiaRootID(node.container_id()));
+
+  semantic_provider_->Update(std::move(node));
+}
+
+void AccessibilityBridgeFuchsiaImpl::DeleteNode(uint32_t node_id) {
+  uint32_t fuchsia_node_id = MaybeToFuchsiaRootID(node_id);
+  semantic_provider_->Delete(fuchsia_node_id);
+
+  // If we have deleted the root node, we should also clear root_node_id_.
+  if (fuchsia_node_id == AXFuchsiaSemanticProvider::kFuchsiaRootNodeId)
+    root_node_id_.reset();
+}
+
+void AccessibilityBridgeFuchsiaImpl::OnAccessibilityHitTestResult(
+    int hit_test_request_id,
+    absl::optional<uint32_t> result) {
+  auto it = pending_hit_test_callbacks_.find(hit_test_request_id);
+  if (it == pending_hit_test_callbacks_.end())
+    return;
+
+  fuchsia::accessibility::semantics::Hit hit;
+  if (result)
+    hit.set_node_id(MaybeToFuchsiaRootID(*result));
+
+  it->second(std::move(hit));
+  pending_hit_test_callbacks_.erase(it);
+}
+
+float AccessibilityBridgeFuchsiaImpl::GetDeviceScaleFactor() {
+  return semantic_provider_->GetPixelScale();
+}
+
+void AccessibilityBridgeFuchsiaImpl::SetRootID(uint32_t root_node_id) {
+  // If the root has changed, then we should delete the old root.
+  //
+  // If the old root was already deleted, then this operation will be a NOOP.
+  // If the old root was NOT yet deleted, then this operation will delete it.
+  // When the accessibility bridge client tries to delete it later (using its
+  // AXUniqueID), the accessibility bridge will no longer map its id to
+  // kFuchsiaRootNodeId. So, that deletion will also be a NOOP.
+  //
+  // In either case, this operation is safe, and the end state is that the old
+  // root node is deleted.
+  if (root_node_id_)
+    semantic_provider_->Delete(AXFuchsiaSemanticProvider::kFuchsiaRootNodeId);
+
+  root_node_id_ = root_node_id;
+}
+
+bool AccessibilityBridgeFuchsiaImpl::OnAccessibilityAction(
+    uint32_t node_id,
+    fuchsia::accessibility::semantics::Action action) {
+  // If the action was requested on the root, translate to the root node's
+  // unique ID.
+  if (node_id == AXFuchsiaSemanticProvider::kFuchsiaRootNodeId) {
+    if (!root_node_id_)
+      return false;
+
+    node_id = *root_node_id_;
+  }
+
+  ui::AXPlatformNode* ax_platform_node =
+      ui::AXPlatformNodeFuchsia::GetFromUniqueId(node_id);
+  ui::AXPlatformNodeFuchsia* ax_platform_node_fuchsia =
+      static_cast<ui::AXPlatformNodeFuchsia*>(ax_platform_node);
+
+  if (!ax_platform_node_fuchsia)
+    return false;
+
+  ui::AXActionData action_data = ui::AXActionData();
+
+  // The requested action is not supported.
+  absl::optional<ax::mojom::Action> ax_action = ConvertAction(action);
+  if (!ax_action)
+    return false;
+
+  action_data.action = *ax_action;
+  action_data.target_node_id = node_id;
+
+  if (action == fuchsia::accessibility::semantics::Action::SHOW_ON_SCREEN) {
+    // The scroll-to-make-visible action expects coordinates in the local
+    // coordinate space of |node|. So, we need to translate node's bounds to the
+    // origin.
+    gfx::Rect local_bounds = gfx::ToEnclosedRectIgnoringError(
+        ax_platform_node_fuchsia->GetData().relative_bounds.bounds,
+        kRectConversionError);
+    local_bounds = gfx::Rect(local_bounds.size());
+
+    action_data.target_rect = local_bounds;
+    action_data.horizontal_scroll_alignment =
+        ax::mojom::ScrollAlignment::kScrollAlignmentCenter;
+    action_data.vertical_scroll_alignment =
+        ax::mojom::ScrollAlignment::kScrollAlignmentCenter;
+    action_data.scroll_behavior = ax::mojom::ScrollBehavior::kScrollIfVisible;
+  }
+
+  ax_platform_node_fuchsia->PerformAction(action_data);
+  return true;
+}
+
+void AccessibilityBridgeFuchsiaImpl::OnHitTest(fuchsia::math::PointF point,
+                                               HitTestCallback callback) {
+  ui::AXPlatformNodeFuchsia* ax_platform_node_fuchsia = nullptr;
+
+  if (root_node_id_) {
+    // Target the root node.
+    ui::AXPlatformNode* ax_platform_node =
+        ui::AXPlatformNodeFuchsia::GetFromUniqueId(*root_node_id_);
+    ax_platform_node_fuchsia =
+        static_cast<ui::AXPlatformNodeFuchsia*>(ax_platform_node);
+  }
+
+  if (!ax_platform_node_fuchsia) {
+    fuchsia::accessibility::semantics::Hit hit;
+    callback(std::move(hit));
+    return;
+  }
+
+  ui::AXActionData action_data;
+  action_data.action = ax::mojom::Action::kHitTest;
+  gfx::Point target_point;
+  target_point.set_x(point.x);
+  target_point.set_y(point.y);
+  action_data.target_point = target_point;
+  action_data.hit_test_event_to_fire = ax::mojom::Event::kHitTestResult;
+  action_data.request_id = next_hittest_request_id_++;
+
+  pending_hit_test_callbacks_[action_data.request_id] = std::move(callback);
+
+  ax_platform_node_fuchsia->PerformAction(std::move(action_data));
+}
+
+void AccessibilityBridgeFuchsiaImpl::OnSemanticsEnabled(bool enabled) {
+  if (on_semantics_enabled_)
+    on_semantics_enabled_.Run(enabled);
+}
+
+bool AccessibilityBridgeFuchsiaImpl::OnSemanticsManagerConnectionClosed() {
+  if (on_connection_closed_)
+    return on_connection_closed_.Run();
+
+  // If the user does not specify a callback, then we can assume no attempt to
+  // reconnect should be made.
+  return false;
+}
+
+void AccessibilityBridgeFuchsiaImpl::set_semantic_provider_for_test(
+    std::unique_ptr<AXFuchsiaSemanticProvider> semantic_provider) {
+  semantic_provider_ = std::move(semantic_provider);
+}
+
+inspect::Node AccessibilityBridgeFuchsiaImpl::GetInspectNode() {
+  return inspect_node_.CreateChild(
+      base::StringPrintf("AXTree-%d", next_inspect_tree_number_++));
+}
+
+}  // namespace ui
diff --git a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h
new file mode 100644
index 0000000..a5fac6b3
--- /dev/null
+++ b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h
@@ -0,0 +1,128 @@
+// Copyright 2022 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 UI_ACCESSIBILITY_PLATFORM_FUCHSIA_ACCESSIBILITY_BRIDGE_FUCHSIA_IMPL_H_
+#define UI_ACCESSIBILITY_PLATFORM_FUCHSIA_ACCESSIBILITY_BRIDGE_FUCHSIA_IMPL_H_
+
+#include <fuchsia/accessibility/semantics/cpp/fidl.h>
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <lib/inspect/cpp/vmo/types.h>
+
+#include "base/callback.h"
+#include "base/containers/flat_map.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/accessibility/ax_export.h"
+#include "ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h"
+#include "ui/accessibility/platform/fuchsia/semantic_provider.h"
+#include "ui/aura/window.h"
+
+namespace ui {
+
+class AX_EXPORT AccessibilityBridgeFuchsiaImpl final
+    : public ui::AccessibilityBridgeFuchsia,
+      public ui::AXFuchsiaSemanticProvider::Delegate {
+ public:
+  // Constructor args:
+  //
+  // |root_window|: Refers to the root aura::Window for which this accessibility
+  // bridge instance is responsible. The pointer is NOT owned by this class.
+  // The accessibility bridge instance's lifespan is not explicitly tied to the
+  // window's, but they are expected to be deleted together.
+  //
+  // |view_ref|: The fuchsia ViewRef for the fuchsia view that corresponds to
+  // |root_window|.
+  //
+  // |get_pixel_scale|: Callback used to retrieve the pixel scale for this
+  // device. We use a callback here, because the correct value may not be
+  // available at the time of construction.
+  //
+  // |on_semantics_enabled|: Callback invoked when fuchsia's accessibility
+  // platform component requests to enable/disable semantics (e.g. when the
+  // screen reader is toggled on/off). The boolean argument to the callback
+  // indicates whether semantics should be enabled or disabled (true => enable
+  // semantics, false => disable semantics).
+  //
+  // |on_connection_closed|: Callback invoked when the FIDL connection to the
+  // fuchsia accessibility platform component closes. The return value indicates
+  // whether an attempt to reconnect should be made (true => reconnect, false =>
+  // do not reconnect).
+  AccessibilityBridgeFuchsiaImpl(
+      aura::Window* root_window,
+      fuchsia::ui::views::ViewRef view_ref,
+      base::RepeatingCallback<float()> get_pixel_scale,
+      base::RepeatingCallback<void(bool)> on_semantics_enabled,
+      base::RepeatingCallback<bool()> on_connection_closed,
+      inspect::Node inspect_node);
+  ~AccessibilityBridgeFuchsiaImpl() override;
+
+  // AccessibilityBridgeFuchsia overrides.
+  void UpdateNode(fuchsia::accessibility::semantics::Node node) override;
+  void DeleteNode(uint32_t node_id) override;
+  void OnAccessibilityHitTestResult(int hit_test_request_id,
+                                    absl::optional<uint32_t> result) override;
+  float GetDeviceScaleFactor() override;
+  void SetRootID(uint32_t root_node_id) override;
+  inspect::Node GetInspectNode() override;
+
+  // SemanticProvider::Delegate overrides.
+  bool OnSemanticsManagerConnectionClosed() override;
+  bool OnAccessibilityAction(
+      uint32_t node_id,
+      fuchsia::accessibility::semantics::Action action) override;
+  void OnHitTest(
+      fuchsia::math::PointF point,
+      fuchsia::accessibility::semantics::SemanticListener::HitTestCallback
+          callback) override;
+  void OnSemanticsEnabled(bool enabled) override;
+
+  // Test-only method to set |semantic_provider_|.
+  void set_semantic_provider_for_test(
+      std::unique_ptr<AXFuchsiaSemanticProvider> semantic_provider);
+
+ private:
+  // Returns kFuchsiaRootNodeId if node_id == *root_node_id_. Otherwise, returns
+  // node_id.
+  uint32_t MaybeToFuchsiaRootID(uint32_t node_id);
+
+  // Root window for the fuchsia view for which this accessibility bridge
+  // instance is responsible.
+  aura::Window* root_window_;
+
+  // Manages connections with the fuchsia semantics APIs.
+  std::unique_ptr<ui::AXFuchsiaSemanticProvider> semantic_provider_;
+
+  // Fuchsia semantic trees require that the root node ID == 0. The
+  // AXUniqueId of the chrome node corresponding to the fuchsia root will NOT be
+  // 0, so we need to store it here in order to map between the two.
+  absl::optional<uint32_t> root_node_id_;
+
+  // Holds callbacks for hit tests that have not yet completed, keyed by a
+  // request ID that this class generates.
+  base::flat_map<
+      int /* request_id */,
+      fuchsia::accessibility::semantics::SemanticListener::HitTestCallback>
+      pending_hit_test_callbacks_;
+
+  // Next hit test request ID to use.
+  int next_hittest_request_id_ = 1;
+
+  // Callback invoked whenever the semantics enabled state changes.
+  base::RepeatingCallback<void(bool)> on_semantics_enabled_;
+
+  // Callback invoked whenever the semantics manager connection is closed.
+  base::RepeatingCallback<bool()> on_connection_closed_;
+
+  // The inspect output will have a node for each AXTree in this accessibility
+  // bridge's window. Inspect node names are static, but AXTreeIDs can change.
+  // It could be misleading for users to see an old AXTreeID in the inspect
+  // output, so instead, we'll name each node "AXTree_#". The
+  // next_inspect_tree_number_ member is used to generate these names.
+  int next_inspect_tree_number_ = 1;
+
+  // Inspect node for the accessibility bridge.
+  inspect::Node inspect_node_;
+};
+
+}  // namespace ui
+#endif  // UI_ACCESSIBILITY_PLATFORM_FUCHSIA_ACCESSIBILITY_BRIDGE_FUCHSIA_IMPL_H_
diff --git a/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_unittest.cc b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_unittest.cc
new file mode 100644
index 0000000..068d169f
--- /dev/null
+++ b/ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_unittest.cc
@@ -0,0 +1,386 @@
+// Copyright 2022 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 <fuchsia/accessibility/semantics/cpp/fidl.h>
+#include <lib/ui/scenic/cpp/view_ref_pair.h>
+
+#include "base/test/task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/accessibility/platform/ax_platform_node_delegate_base.h"
+#include "ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h"
+#include "ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h"
+#include "ui/accessibility/platform/fuchsia/semantic_provider.h"
+
+namespace ui {
+namespace {
+
+class MockSemanticProvider : public AXFuchsiaSemanticProvider {
+ public:
+  // AXFuchsiaSemanticProvider overrides.
+  bool Update(fuchsia::accessibility::semantics::Node node) override {
+    last_update_ = std::move(node);
+    return true;
+  }
+
+  bool Delete(uint32_t node_id) override {
+    last_deletion_ = node_id;
+    return true;
+  }
+
+  bool Clear() override { return true; }
+
+  void SendEvent(
+      fuchsia::accessibility::semantics::SemanticEvent event) override {
+    last_event_ = std::move(event);
+  }
+
+  bool HasPendingUpdates() const override { return false; }
+
+  float GetPixelScale() const override { return pixel_scale_; }
+
+  const absl::optional<fuchsia::accessibility::semantics::Node>& last_update()
+      const {
+    return last_update_;
+  }
+  const absl::optional<uint32_t>& last_deletion() const {
+    return last_deletion_;
+  }
+  const absl::optional<fuchsia::accessibility::semantics::SemanticEvent>&
+  last_event() const {
+    return last_event_;
+  }
+
+  void set_pixel_scale(float pixel_scale) { pixel_scale_ = pixel_scale; }
+
+ private:
+  absl::optional<fuchsia::accessibility::semantics::Node> last_update_;
+  absl::optional<uint32_t> last_deletion_;
+  absl::optional<fuchsia::accessibility::semantics::SemanticEvent> last_event_;
+  float pixel_scale_ = 1.f;
+};
+
+class MockAXPlatformNodeDelegate : public AXPlatformNodeDelegateBase {
+ public:
+  MockAXPlatformNodeDelegate() = default;
+  ~MockAXPlatformNodeDelegate() override = default;
+
+  bool AccessibilityPerformAction(const AXActionData& data) override {
+    last_action_data_.emplace(data);
+    return true;
+  }
+
+  const AXUniqueId& GetUniqueId() const override { return unique_id_; }
+
+  const absl::optional<AXActionData>& last_action_data() {
+    return last_action_data_;
+  }
+
+  const ui::AXNodeData& GetData() const override { return ax_node_data_; }
+  void SetData(ui::AXNodeData ax_node_data) { ax_node_data_ = ax_node_data; }
+
+ private:
+  absl::optional<AXActionData> last_action_data_;
+  ui::AXUniqueId unique_id_;
+  ui::AXNodeData ax_node_data_ = {};
+};
+
+class AccessibilityBridgeFuchsiaTest : public ::testing::Test {
+ public:
+  AccessibilityBridgeFuchsiaTest() = default;
+  ~AccessibilityBridgeFuchsiaTest() override = default;
+
+  void SetUp() override {
+    mock_ax_platform_node_delegate_ =
+        std::make_unique<MockAXPlatformNodeDelegate>();
+    auto mock_semantic_provider = std::make_unique<MockSemanticProvider>();
+    mock_semantic_provider_ = mock_semantic_provider.get();
+    auto view_ref_pair = scenic::ViewRefPair::New();
+    accessibility_bridge_ = std::make_unique<AccessibilityBridgeFuchsiaImpl>(
+        /*root_window=*/nullptr, std::move(view_ref_pair.view_ref),
+        base::BindRepeating([]() { return 1.0f; }),
+        base::RepeatingCallback<void(bool)>(),
+        base::RepeatingCallback<bool()>(), inspect::Node());
+    accessibility_bridge_->set_semantic_provider_for_test(
+        std::move(mock_semantic_provider));
+  }
+
+ protected:
+  // Required for scenic::ViewRefPair::New().
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
+
+  std::unique_ptr<MockAXPlatformNodeDelegate> mock_ax_platform_node_delegate_;
+  MockSemanticProvider* mock_semantic_provider_;
+  std::unique_ptr<AccessibilityBridgeFuchsiaImpl> accessibility_bridge_;
+};
+
+TEST_F(AccessibilityBridgeFuchsiaTest, UpdateNode) {
+  fuchsia::accessibility::semantics::Node node;
+  node.set_node_id(1u);
+  node.mutable_attributes()->set_label("label");
+
+  accessibility_bridge_->UpdateNode(std::move(node));
+
+  const absl::optional<fuchsia::accessibility::semantics::Node>& last_update =
+      mock_semantic_provider_->last_update();
+  ASSERT_TRUE(last_update.has_value());
+  EXPECT_EQ(last_update->node_id(), 1u);
+  ASSERT_TRUE(last_update->has_attributes());
+  ASSERT_TRUE(last_update->attributes().has_label());
+  EXPECT_EQ(last_update->attributes().label(), "label");
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, UpdateNodeReplaceNodeID) {
+  accessibility_bridge_->SetRootID(1u);
+
+  fuchsia::accessibility::semantics::Node node;
+  node.set_node_id(1u);
+
+  accessibility_bridge_->UpdateNode(std::move(node));
+
+  const absl::optional<fuchsia::accessibility::semantics::Node>& last_update =
+      mock_semantic_provider_->last_update();
+  ASSERT_TRUE(last_update.has_value());
+  EXPECT_EQ(last_update->node_id(),
+            AXFuchsiaSemanticProvider::kFuchsiaRootNodeId);
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, UpdateNodeReplaceOffsetContainerID) {
+  accessibility_bridge_->SetRootID(1u);
+
+  fuchsia::accessibility::semantics::Node node;
+  node.set_node_id(2u);
+  node.set_container_id(1u);
+
+  accessibility_bridge_->UpdateNode(std::move(node));
+
+  const absl::optional<fuchsia::accessibility::semantics::Node>& last_update =
+      mock_semantic_provider_->last_update();
+  ASSERT_TRUE(last_update.has_value());
+  ASSERT_TRUE(last_update->has_container_id());
+  EXPECT_EQ(last_update->container_id(),
+            AXFuchsiaSemanticProvider::kFuchsiaRootNodeId);
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, SetRootIDDeletesOldRoot) {
+  accessibility_bridge_->SetRootID(1u);
+  accessibility_bridge_->SetRootID(2u);
+
+  const absl::optional<uint32_t>& last_deletion =
+      mock_semantic_provider_->last_deletion();
+  ASSERT_TRUE(last_deletion.has_value());
+  EXPECT_EQ(*last_deletion, AXFuchsiaSemanticProvider::kFuchsiaRootNodeId);
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, DeleteNode) {
+  accessibility_bridge_->SetRootID(1u);
+
+  // Delete a non-root node.
+  accessibility_bridge_->DeleteNode(2u);
+
+  const absl::optional<uint32_t>& last_deletion =
+      mock_semantic_provider_->last_deletion();
+  ASSERT_TRUE(last_deletion.has_value());
+  EXPECT_EQ(*last_deletion, 2u);
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, DeleteRoot) {
+  accessibility_bridge_->SetRootID(1u);
+
+  // Delete root node.
+  accessibility_bridge_->DeleteNode(1u);
+
+  {
+    const absl::optional<uint32_t>& last_deletion =
+        mock_semantic_provider_->last_deletion();
+    ASSERT_TRUE(last_deletion.has_value());
+    EXPECT_EQ(*last_deletion, AXFuchsiaSemanticProvider::kFuchsiaRootNodeId);
+  }
+
+  // Delete the node ID 1 again, and verify that it's no longer mapped to the
+  // root.
+  accessibility_bridge_->DeleteNode(1u);
+
+  {
+    const absl::optional<uint32_t>& last_deletion =
+        mock_semantic_provider_->last_deletion();
+    ASSERT_TRUE(last_deletion.has_value());
+    EXPECT_EQ(*last_deletion, 1u);
+  }
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, HitTest) {
+  auto root_delegate = std::make_unique<MockAXPlatformNodeDelegate>();
+  AXPlatformNode* root_platform_node =
+      AXPlatformNode::Create(root_delegate.get());
+
+  auto child_delegate = std::make_unique<MockAXPlatformNodeDelegate>();
+  AXPlatformNode* child_platform_node =
+      AXPlatformNode::Create(child_delegate.get());
+
+  // Set the platform node as the root, so that the accessibility bridge
+  // dispatches the hit test request to it.
+  accessibility_bridge_->SetRootID(root_platform_node->GetUniqueId());
+
+  fuchsia::math::PointF target_point;
+  target_point.x = 1.f;
+  target_point.y = 2.f;
+
+  // Set hit_test_result to a nonsense value to ensure that it's modified later.
+  uint32_t hit_test_result = 100u;
+
+  // Request a hit test. Note that the callback will not be invoked until
+  // OnAccessibilityHitTestResult() is called.
+  accessibility_bridge_->OnHitTest(
+      target_point,
+      [&hit_test_result](fuchsia::accessibility::semantics::Hit hit) {
+        ASSERT_TRUE(hit.has_node_id());
+        hit_test_result = hit.node_id();
+      });
+
+  // Verify that the platform node's delegate received the hit test request.
+  const absl::optional<ui::AXActionData>& action_data =
+      root_delegate->last_action_data();
+  ASSERT_TRUE(action_data.has_value());
+
+  // The request_id field defaults to -1, so verify that it was set to a
+  // non-negative value.
+  EXPECT_GE(action_data->request_id, 0);
+  EXPECT_EQ(action_data->target_point.x(), target_point.x);
+  EXPECT_EQ(action_data->target_point.y(), target_point.y);
+  EXPECT_EQ(action_data->action, ax::mojom::Action::kHitTest);
+
+  // Simulate a hit test result. This should invoke the callback.
+  uint32_t child_node_id =
+      static_cast<uint32_t>(child_platform_node->GetUniqueId());
+  accessibility_bridge_->OnAccessibilityHitTestResult(
+      action_data->request_id, absl::optional<uint32_t>(child_node_id));
+
+  EXPECT_EQ(hit_test_result, static_cast<uint32_t>(child_node_id));
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, HitTestReturnsRoot) {
+  auto root_delegate = std::make_unique<MockAXPlatformNodeDelegate>();
+  AXPlatformNode* root_platform_node =
+      AXPlatformNode::Create(root_delegate.get());
+
+  // Set the platform node as the root, so that the accessibility bridge
+  // dispatches the hit test request to it.
+  accessibility_bridge_->SetRootID(root_platform_node->GetUniqueId());
+
+  fuchsia::math::PointF target_point;
+  target_point.x = 1.f;
+  target_point.y = 2.f;
+
+  // Set hit_test_result to a nonsense value to ensure that it's modified later.
+  uint32_t hit_test_result = 100u;
+
+  // Request a hit test. Note that the callback will not be invoked until
+  // OnAccessibilityHitTestResult() is called.
+  accessibility_bridge_->OnHitTest(
+      target_point,
+      [&hit_test_result](fuchsia::accessibility::semantics::Hit hit) {
+        ASSERT_TRUE(hit.has_node_id());
+        hit_test_result = hit.node_id();
+      });
+
+  const absl::optional<ui::AXActionData>& action_data =
+      root_delegate->last_action_data();
+  ASSERT_TRUE(action_data.has_value());
+
+  // Simulate a hit test result. This should invoke the callback.
+  uint32_t root_node_id =
+      static_cast<uint32_t>(root_platform_node->GetUniqueId());
+  accessibility_bridge_->OnAccessibilityHitTestResult(
+      action_data->request_id, absl::optional<uint32_t>(root_node_id));
+
+  EXPECT_EQ(hit_test_result, AXFuchsiaSemanticProvider::kFuchsiaRootNodeId);
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, HitTestReturnsEmptyResult) {
+  auto root_delegate = std::make_unique<MockAXPlatformNodeDelegate>();
+  AXPlatformNode* root_platform_node =
+      AXPlatformNode::Create(root_delegate.get());
+
+  // Set the platform node as the root, so that the accessibility bridge
+  // dispatches the hit test request to it.
+  accessibility_bridge_->SetRootID(root_platform_node->GetUniqueId());
+
+  fuchsia::math::PointF target_point;
+  target_point.x = 1.f;
+  target_point.y = 2.f;
+
+  // Request a hit test. Note that the callback will not be invoked until
+  // OnAccessibilityHitTestResult() is called.
+  bool callback_ran = false;
+  accessibility_bridge_->OnHitTest(
+      target_point,
+      [&callback_ran](fuchsia::accessibility::semantics::Hit hit) {
+        callback_ran = true;
+        ASSERT_FALSE(hit.has_node_id());
+      });
+
+  const absl::optional<ui::AXActionData>& action_data =
+      root_delegate->last_action_data();
+  ASSERT_TRUE(action_data.has_value());
+
+  // Simulate a hit test result. This should invoke the callback.
+  accessibility_bridge_->OnAccessibilityHitTestResult(action_data->request_id,
+                                                      {});
+
+  // Verify that the callback ran. The callback itself will check that the hit
+  // result was empty.
+  EXPECT_TRUE(callback_ran);
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, PerformActionOnRoot) {
+  auto root_delegate = std::make_unique<MockAXPlatformNodeDelegate>();
+  AXPlatformNode* root_platform_node =
+      AXPlatformNode::Create(root_delegate.get());
+
+  // Set the platform node as the root, so that the accessibility bridge
+  // dispatches the hit test request to it.
+  accessibility_bridge_->SetRootID(root_platform_node->GetUniqueId());
+
+  // Perform DEFAULT action.
+  accessibility_bridge_->OnAccessibilityAction(
+      AXFuchsiaSemanticProvider::kFuchsiaRootNodeId,
+      fuchsia::accessibility::semantics::Action::DEFAULT);
+
+  const absl::optional<ui::AXActionData>& action_data =
+      root_delegate->last_action_data();
+  ASSERT_TRUE(action_data.has_value());
+  EXPECT_EQ(action_data->action, ax::mojom::Action::kDoDefault);
+}
+
+TEST_F(AccessibilityBridgeFuchsiaTest, ScrollToMakeVisible) {
+  auto delegate = std::make_unique<MockAXPlatformNodeDelegate>();
+  ui::AXNodeData data;
+  data.relative_bounds.bounds = gfx::RectF(
+      /*x_min=*/1.f, /*y_min=*/2.f, /*width=*/3.f, /*height=*/4.f);
+  delegate->SetData(data);
+  AXPlatformNode* platform_node = AXPlatformNode::Create(delegate.get());
+  ASSERT_TRUE(static_cast<AXPlatformNodeFuchsia*>(platform_node));
+
+  // Request a SHOW_ON_SCREEN action.
+  accessibility_bridge_->OnAccessibilityAction(
+      delegate->GetUniqueId(),
+      fuchsia::accessibility::semantics::Action::SHOW_ON_SCREEN);
+
+  const absl::optional<ui::AXActionData>& action_data =
+      delegate->last_action_data();
+  ASSERT_TRUE(action_data.has_value());
+  EXPECT_EQ(action_data->action, ax::mojom::Action::kScrollToMakeVisible);
+
+  // The target rect should have the same size as the node's bounds, but should
+  // have (x, y) == (0, 0).
+  EXPECT_EQ(action_data->target_rect.x(), 0.f);
+  EXPECT_EQ(action_data->target_rect.y(), 0.f);
+  EXPECT_EQ(action_data->target_rect.width(), 3.f);
+  EXPECT_EQ(action_data->target_rect.height(), 4.f);
+}
+
+}  // namespace
+}  // namespace ui
diff --git a/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h b/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h
index 1a06960..1eb548945 100644
--- a/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h
+++ b/ui/accessibility/platform/fuchsia/ax_platform_node_fuchsia.h
@@ -25,7 +25,7 @@
   gfx::NativeViewAccessible GetNativeViewAccessible() override;
 
   // Requests that the delegate perform the specified action.
-  void PerformAction(const AXActionData& data);
+  virtual void PerformAction(const AXActionData& data);
 
   // TODO(fxb.dev/89485): Implement fuchsia node conversion.
 };
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider.cc b/ui/accessibility/platform/fuchsia/semantic_provider.cc
deleted file mode 100644
index 07e486c..0000000
--- a/ui/accessibility/platform/fuchsia/semantic_provider.cc
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright 2021 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 "ui/accessibility/platform/fuchsia/semantic_provider.h"
-
-#include <lib/sys/cpp/component_context.h>
-
-#include "base/check.h"
-#include "base/check_op.h"
-#include "base/fuchsia/fuchsia_logging.h"
-#include "base/fuchsia/process_context.h"
-
-namespace ui {
-namespace {
-
-using fuchsia::accessibility::semantics::Node;
-
-constexpr uint32_t kFuchsiaRootNodeId = 0;
-constexpr size_t kMaxOperationsPerBatch = 16;
-
-}  // namespace
-
-AXFuchsiaSemanticProvider::Batch::Batch(Type type) : type_(type) {}
-AXFuchsiaSemanticProvider::Batch::Batch(Batch&& other) = default;
-AXFuchsiaSemanticProvider::Batch::~Batch() = default;
-
-bool AXFuchsiaSemanticProvider::Batch::IsFull() const {
-  return (
-      (type_ == Type::kUpdate && updates_.size() >= kMaxOperationsPerBatch) ||
-      (type_ == Type::kDelete &&
-       delete_node_ids_.size() >= kMaxOperationsPerBatch));
-}
-
-void AXFuchsiaSemanticProvider::Batch::Append(
-    fuchsia::accessibility::semantics::Node node) {
-  DCHECK_EQ(type_, Type::kUpdate);
-  DCHECK(!IsFull());
-  updates_.push_back(std::move(node));
-}
-
-void AXFuchsiaSemanticProvider::Batch::AppendDeletion(uint32_t delete_node_id) {
-  DCHECK_EQ(type_, Type::kDelete);
-  DCHECK(!IsFull());
-  delete_node_ids_.push_back(delete_node_id);
-}
-
-void AXFuchsiaSemanticProvider::Batch::Apply(
-    fuchsia::accessibility::semantics::SemanticTreePtr* semantic_tree) {
-  if (type_ == Type::kUpdate && !updates_.empty())
-    (*semantic_tree)->UpdateSemanticNodes(std::move(updates_));
-  else if (type_ == Type::kDelete && !delete_node_ids_.empty())
-    (*semantic_tree)->DeleteSemanticNodes(std::move(delete_node_ids_));
-}
-
-AXFuchsiaSemanticProvider::NodeInfo ::NodeInfo() = default;
-AXFuchsiaSemanticProvider::NodeInfo ::~NodeInfo() = default;
-
-AXFuchsiaSemanticProvider::Delegate::Delegate() = default;
-AXFuchsiaSemanticProvider::Delegate::~Delegate() = default;
-
-AXFuchsiaSemanticProvider::AXFuchsiaSemanticProvider(
-    fuchsia::ui::views::ViewRef view_ref,
-    float pixel_scale,
-    Delegate* delegate)
-    : view_ref_(std::move(view_ref)),
-      pixel_scale_(pixel_scale),
-      delegate_(delegate),
-      semantic_listener_binding_(this) {
-  sys::ComponentContext* component_context = base::ComponentContextForProcess();
-  DCHECK(component_context);
-  DCHECK(delegate_);
-
-  component_context->svc()
-      ->Connect<fuchsia::accessibility::semantics::SemanticsManager>()
-      ->RegisterViewForSemantics(std::move(view_ref_),
-                                 semantic_listener_binding_.NewBinding(),
-                                 semantic_tree_.NewRequest());
-  semantic_tree_.set_error_handler([this](zx_status_t status) {
-    ZX_LOG(ERROR, status) << "SemanticTree disconnected";
-    delegate_->OnSemanticsManagerConnectionClosed();
-    semantic_updates_enabled_ = false;
-  });
-}
-
-AXFuchsiaSemanticProvider::~AXFuchsiaSemanticProvider() = default;
-
-bool AXFuchsiaSemanticProvider::Update(
-    fuchsia::accessibility::semantics::Node node) {
-  if (!semantic_updates_enabled())
-    return false;
-
-  DCHECK(node.has_node_id());
-
-  if (node.node_id() != kFuchsiaRootNodeId) {
-    auto found_not_reachable = not_reachable_.find(node.node_id());
-    const bool is_not_reachable = found_not_reachable != not_reachable_.end();
-    const absl::optional<uint32_t> parent_node_id =
-        GetParentForNode(node.node_id());
-    if (is_not_reachable && parent_node_id) {
-      // Connection parent -> |node| exists now.
-      not_reachable_.erase(found_not_reachable);
-      nodes_[node.node_id()].parents.insert(*parent_node_id);
-    } else if (!parent_node_id) {
-      // No node or multiple nodes points to this one, so it is not reachable.
-      if (!is_not_reachable)
-        not_reachable_[node.node_id()] = {};
-    }
-  }
-
-  // If the node is not present in the map, the list of children will be empty
-  // so this is a no-op in the call below.
-  std::vector<uint32_t>& children = nodes_[node.node_id()].children;
-
-  // Before updating the node, update the list of children to be not reachable,
-  // in case the new list of children change.
-  MarkChildrenAsNotReachable(children, node.node_id());
-  children = node.has_child_ids() ? node.child_ids() : std::vector<uint32_t>();
-  MarkChildrenAsReachable(children, node.node_id());
-
-  Batch& batch = GetCurrentUnfilledBatch(Batch::Type::kUpdate);
-  batch.Append(std::move(node));
-  TryToCommit();
-  return true;
-}
-
-void AXFuchsiaSemanticProvider::TryToCommit() {
-  // Don't send out updates while the tree is mid-mutation.
-  if (commit_inflight_ || batches_.empty())
-    return;
-
-  // If a tree has nodes but no root, wait until the root is present or all
-  // nodes are deleted.
-  if (!nodes_.empty() && nodes_.find(kFuchsiaRootNodeId) == nodes_.end())
-    return;
-
-  if (!not_reachable_.empty())
-    return;
-
-  for (auto& batch : batches_) {
-    batch.Apply(&semantic_tree_);
-  }
-
-  batches_.clear();
-  semantic_tree_->CommitUpdates(
-      fit::bind_member(this, &AXFuchsiaSemanticProvider::OnCommitComplete));
-  commit_inflight_ = true;
-}
-
-bool AXFuchsiaSemanticProvider::Delete(uint32_t node_id) {
-  if (!semantic_updates_enabled())
-    return false;
-
-  auto it = nodes_.find(node_id);
-  if (it == nodes_.end())
-    return false;
-
-  if (it->second.parents.empty()) {
-    // No node points to this one, so it is safe to remove it from the tree.
-    not_reachable_.erase(node_id);
-  } else {
-    not_reachable_[node_id] =
-        it->second
-            .parents;  // Zero or more parents can be pointing to this node.
-  }
-  MarkChildrenAsNotReachable(it->second.children, node_id);
-
-  nodes_.erase(it);
-
-  Batch& batch = GetCurrentUnfilledBatch(Batch::Type::kDelete);
-  batch.AppendDeletion(node_id);
-  TryToCommit();
-  return true;
-}
-
-void AXFuchsiaSemanticProvider::SendEvent(
-    fuchsia::accessibility::semantics::SemanticEvent event) {
-  semantic_tree_->SendSemanticEvent(std::move(event), [](auto...) {});
-}
-
-bool AXFuchsiaSemanticProvider::HasPendingUpdates() const {
-  return commit_inflight_ || !batches_.empty();
-}
-
-bool AXFuchsiaSemanticProvider::Clear() {
-  if (!semantic_updates_enabled())
-    return false;
-
-  batches_.clear();
-  not_reachable_.clear();
-  nodes_.clear();
-  Batch& batch = GetCurrentUnfilledBatch(Batch::Type::kDelete);
-  batch.AppendDeletion(kFuchsiaRootNodeId);
-  TryToCommit();
-  return true;
-}
-
-void AXFuchsiaSemanticProvider::OnAccessibilityActionRequested(
-    uint32_t node_id,
-    fuchsia::accessibility::semantics::Action action,
-    fuchsia::accessibility::semantics::SemanticListener::
-        OnAccessibilityActionRequestedCallback callback) {
-  if (delegate_->OnAccessibilityAction(node_id, action)) {
-    callback(true);
-    return;
-  }
-
-  // The action was not handled.
-  callback(false);
-}
-
-void AXFuchsiaSemanticProvider::HitTest(fuchsia::math::PointF local_point,
-                                        HitTestCallback callback) {
-  fuchsia::math::PointF point;
-  point.x = local_point.x * pixel_scale_;
-  point.y = local_point.y * pixel_scale_;
-
-  delegate_->OnHitTest(point, std::move(callback));
-  return;
-}
-
-void AXFuchsiaSemanticProvider::OnSemanticsModeChanged(
-    bool update_enabled,
-    OnSemanticsModeChangedCallback callback) {
-  if (semantic_updates_enabled_ != update_enabled)
-    delegate_->OnSemanticsEnabled(update_enabled);
-
-  semantic_updates_enabled_ = update_enabled;
-  callback();
-}
-
-void AXFuchsiaSemanticProvider::MarkChildrenAsNotReachable(
-    const std::vector<uint32_t>& child_ids,
-    uint32_t parent_id) {
-  for (const uint32_t child_id : child_ids) {
-    const auto it = nodes_.find(child_id);
-    if (it != nodes_.end()) {
-      it->second.parents.erase(parent_id);
-      if (it->second.parents.empty())
-        not_reachable_[child_id] = {};
-      else
-        not_reachable_.erase(child_id);
-    } else {
-      auto not_reachable_it = not_reachable_.find(child_id);
-      // Child id is no longer in the regular map, deletes it also from
-      // not_reachable_ if no parent points to it anymore.
-      if (not_reachable_it != not_reachable_.end()) {
-        not_reachable_it->second.erase(parent_id);
-        if (not_reachable_it->second.empty())
-          not_reachable_.erase(not_reachable_it);
-      }
-    }
-  }
-}
-
-void AXFuchsiaSemanticProvider::MarkChildrenAsReachable(
-    const std::vector<uint32_t>& child_ids,
-    uint32_t parent_id) {
-  for (const uint32_t child_id : child_ids) {
-    auto it = nodes_.find(child_id);
-    if (it == nodes_.end())
-      not_reachable_[child_id].insert(parent_id);
-    else {
-      it->second.parents.insert(parent_id);
-      if (it->second.parents.size() == 1)
-        not_reachable_.erase(child_id);
-      else
-        not_reachable_[child_id].insert(parent_id);
-    }
-  }
-}
-
-absl::optional<uint32_t> AXFuchsiaSemanticProvider::GetParentForNode(
-    const uint32_t node_id) {
-  const auto it = nodes_.find(node_id);
-  if (it != nodes_.end()) {
-    if (it->second.parents.size() == 1)
-      return *it->second.parents.begin();
-    else
-      return absl::nullopt;
-  }
-
-  const auto not_reachable_it = not_reachable_.find(node_id);
-  if (not_reachable_it != not_reachable_.end()) {
-    if (not_reachable_it->second.size() == 1)
-      return *not_reachable_it->second.begin();
-    else
-      return absl::nullopt;
-  }
-
-  return absl::nullopt;
-}
-
-AXFuchsiaSemanticProvider::Batch&
-AXFuchsiaSemanticProvider::GetCurrentUnfilledBatch(Batch::Type type) {
-  if (batches_.empty() || batches_.back().type() != type ||
-      batches_.back().IsFull())
-    batches_.push_back(Batch(type));
-
-  return batches_.back();
-}
-
-void AXFuchsiaSemanticProvider::OnCommitComplete() {
-  commit_inflight_ = false;
-  TryToCommit();
-}
-
-}  // namespace ui
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider.h b/ui/accessibility/platform/fuchsia/semantic_provider.h
index dce679d..5be3d66 100644
--- a/ui/accessibility/platform/fuchsia/semantic_provider.h
+++ b/ui/accessibility/platform/fuchsia/semantic_provider.h
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2022 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.
 
@@ -6,28 +6,22 @@
 #define UI_ACCESSIBILITY_PLATFORM_FUCHSIA_SEMANTIC_PROVIDER_H_
 
 #include <fuchsia/accessibility/semantics/cpp/fidl.h>
-#include <fuchsia/ui/views/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
 
-#include <map>
-#include <set>
-#include <vector>
-
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/accessibility/ax_export.h"
 
 namespace ui {
 
 // Manages the connection with the Fuchsia Semantics API.
 //
-// Clients instantiate this class, which connects to the Fuchsia semantics API.
 // Semantic nodes can be added or deleted. When a batch of nodes would leave the
 // Fuchsia semantic tree in a valid state, they are committed. Please see
 // |fuchsia.accessibility.semantics| API for more documentation on valid
 // semantic trees.
-class AX_EXPORT AXFuchsiaSemanticProvider
-    : public fuchsia::accessibility::semantics::SemanticListener {
+class AX_EXPORT AXFuchsiaSemanticProvider {
  public:
+  // Fuchsia root node id.
+  static constexpr uint32_t kFuchsiaRootNodeId = 0u;
+
   // A delegate that can be registered by clients of this library to be notified
   // about Semantic changes.
   class Delegate {
@@ -35,6 +29,9 @@
     Delegate();
     virtual ~Delegate();
 
+    using HitTestCallback =
+        fuchsia::accessibility::semantics::SemanticListener::HitTestCallback;
+
     // Called when the FIDL channel to the Semantics Manager is closed. If this
     // callback returns true, an attempt to reconnect will be made.
     virtual bool OnSemanticsManagerConnectionClosed() = 0;
@@ -58,172 +55,34 @@
     virtual void OnSemanticsEnabled(bool enabled) = 0;
   };
 
-  // Arguments:
-  // |view_ref|: identifies the view providing semantics. Please consult
-  // |fuchsia.accessibility.semantics| API documentation.
-  // |pixel_scale|: Scales Scenic view coordinates to pixel coordinates.
-  // |delegate|: Handles semantic requests, please see Delegate class for more
-  // documentation. Caller is responsible for ensuring that |delegate| outlives
-  // |this|.
-  // During construction, this class connects to
-  // |fuchsia.accessibility.semantics.SemanticsManager| to register itself as a
-  // semantic provider.
-  AXFuchsiaSemanticProvider(fuchsia::ui::views::ViewRef view_ref,
-                            float pixel_scale,
-                            Delegate* delegate);
-  ~AXFuchsiaSemanticProvider() override;
-
-  // Returns true if Fuchsia has enabled semantics.
-  bool semantic_updates_enabled() const { return semantic_updates_enabled_; }
+  AXFuchsiaSemanticProvider() = default;
+  virtual ~AXFuchsiaSemanticProvider() = default;
 
   // Adds a semantic node to be updated. It is mandatory that the node has at
   // least an unique ID.
-  bool Update(fuchsia::accessibility::semantics::Node node);
+  virtual bool Update(fuchsia::accessibility::semantics::Node node) = 0;
 
   // Marks a semantic node to be deleted. Returns false if the node is not
   // present in the list of semantic nodes known by this provider.
-  bool Delete(uint32_t node_id);
+  virtual bool Delete(uint32_t node_id) = 0;
 
   // Clears the semantic tree.
-  bool Clear();
+  virtual bool Clear();
 
   // Sends an accessibility event to Fuchsia. Please consult
   // https://cs.opensource.google/fuchsia/fuchsia/+/master:sdk/fidl/fuchsia.accessibility.semantics/semantics_manager.fidl
   // for documentation on events.
-  void SendEvent(fuchsia::accessibility::semantics::SemanticEvent event);
+  virtual void SendEvent(
+      fuchsia::accessibility::semantics::SemanticEvent event) = 0;
 
   // Returns true if there are pending updates or deletions to be made.
-  bool HasPendingUpdates() const;
+  virtual bool HasPendingUpdates() const = 0;
 
- private:
-  // Holds information about a Fuchsia Semantic Node. It contains only the
-  // fields needed to check that the resulting tree would be valid.
-  struct NodeInfo {
-    NodeInfo();
-    ~NodeInfo();
-
-    // During a tree update a node may have multiple parents pointing to it,
-    // although after all updates are processed only one should be present.
-    std::set<uint32_t> parents;
-    std::vector<uint32_t> children;
-  };
-
-  // Represents a batch of nodes to be sent to Fuchsia.
-  // Batches can hold exactly one type: a series of updates or a series of
-  // deletions.
-  class Batch {
-   public:
-    enum class Type { kUpdate, kDelete };
-
-    Batch(Type type);
-    Batch(Batch&& other);
-    ~Batch();
-    Batch(const Batch& other) = delete;
-
-    Type type() const { return type_; }
-
-    // Returns true if the batch has reached its size limit.
-    bool IsFull() const;
-
-    // Adds an update or deletion to the batch. This fails if the batch is full
-    // or if the new item is not the same type of the batch.
-    void Append(fuchsia::accessibility::semantics::Node node);
-    void AppendDeletion(uint32_t delete_node_id);
-
-    // Sends enqueued operations to SemanticsManager.
-    void Apply(
-        fuchsia::accessibility::semantics::SemanticTreePtr* semantic_tree);
-
-   private:
-    Type type_;
-    std::vector<fuchsia::accessibility::semantics::Node> updates_;
-    std::vector<uint32_t> delete_node_ids_;
-  };
-
-  // Attempts to commit the pending updates to Fuchsia if the resulting updates
-  // would leave the final tree in a valid state.
-  void TryToCommit();
-
-  // Returns a batch that can receive an update or deletion depending on |type|.
-  Batch& GetCurrentUnfilledBatch(Batch::Type type);
-
-  // Invoked whenever Fuchsia responds that a commit was received. This tries to
-  // commit again if there are pending upedates or deletions.
-  void OnCommitComplete();
-
-  // Mark all |child_ids| not reachable from |parent_id|, meaning:
-  // - If |parent_id| was the only parent, the children are now disconnected
-  // from the tree.
-  // - If |parent_id| was an additional parent, now the children are connected
-  // to a single parent in the tree.
-  // - If the children do not exist, remove them from the list of nodes waiting
-  // to be updated.
-  void MarkChildrenAsNotReachable(const std::vector<uint32_t>& child_ids,
-                                  uint32_t parent_id);
-
-  // Mark all |child_ids| reachable from |parent_id|, meaning:
-  // - If |parent_id| is the only parent, the children are now connected to the
-  // tree and are all reachable.
-  // - If |parent_id| is an additional parent, now the children are not
-  // connected to the tree as multiple parents point to them.
-  // - If the children do not exist, the parent waits for the nodes to be
-  // created.
-  void MarkChildrenAsReachable(const std::vector<uint32_t>& child_ids,
-                               uint32_t parent_id);
-
-  // Returns the ID of the parent of this node if it has one. If it does not
-  // have a parent or it has multiple parents, returns absl::nullopt.
-  absl::optional<uint32_t> GetParentForNode(const uint32_t node_id);
-
-  // fuchsia::accessibility::semantics::SemanticListener:
-  void OnAccessibilityActionRequested(
-      uint32_t node_id,
-      fuchsia::accessibility::semantics::Action action,
-      fuchsia::accessibility::semantics::SemanticListener::
-          OnAccessibilityActionRequestedCallback callback) override;
-
-  // fuchsia::accessibility::semantics::SemanticListener:
-  void HitTest(::fuchsia::math::PointF local_point,
-               HitTestCallback callback) override;
-
-  // fuchsia::accessibility::semantics::SemanticListener:
-  void OnSemanticsModeChanged(bool update_enabled,
-                              OnSemanticsModeChangedCallback callback) override;
-
-  fuchsia::ui::views::ViewRef view_ref_;
-  float pixel_scale_;
-  Delegate* const delegate_;
-
-  fidl::Binding<fuchsia::accessibility::semantics::SemanticListener>
-      semantic_listener_binding_;
-
-  fuchsia::accessibility::semantics::SemanticTreePtr semantic_tree_;
-
-  bool semantic_updates_enabled_ = true;
-
-  // Nodes from this tree. If not empty, to be considered a valid tree, there
-  // must be:
-  // - A node which node id is equal to kFuchsiaRootNodeId;
-  // - Each node except the root has only one parent;
-  // - All children pointed by a parent exist in the tree.
-  // Only the node ID and the child IDs of the node are stored here because at
-  // this point we only check to see if the tree is valid.
-  std::map<uint32_t /*node_id*/, NodeInfo> nodes_;
-
-  // Key == the node ID that is not reachable from the root of the tree, value
-  // == 0 or more parents that point to this node. Note that nodes can be listed
-  // here but still be present in |nodes_|. This may happen, for example, if the
-  // parent of the node was deleted and there is no path from the root to it, so
-  // the node waits for a parent to connect to it.
-  std::map<uint32_t, std::set<uint32_t>> not_reachable_;
-
-  // Stores batches of node updates or deletions to be sent to Fuchsia. Note
-  // that a batch contains only updates or deletions, because they are pushed to
-  // Fuchsia differently.
-  std::vector<Batch> batches_;
-
-  bool commit_inflight_;
+  // TODO(abrusher): Push updates to the semantic provider, rather than polling.
+  // Returns the pixel scale.
+  virtual float GetPixelScale() const = 0;
 };
 
 }  // namespace ui
+
 #endif  // UI_ACCESSIBILITY_PLATFORM_FUCHSIA_SEMANTIC_PROVIDER_H_
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider_impl.cc b/ui/accessibility/platform/fuchsia/semantic_provider_impl.cc
new file mode 100644
index 0000000..f284e7d
--- /dev/null
+++ b/ui/accessibility/platform/fuchsia/semantic_provider_impl.cc
@@ -0,0 +1,316 @@
+// Copyright 2021 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 "ui/accessibility/platform/fuchsia/semantic_provider_impl.h"
+
+#include <lib/sys/cpp/component_context.h>
+
+#include "base/check.h"
+#include "base/check_op.h"
+#include "base/fuchsia/fuchsia_logging.h"
+#include "base/fuchsia/process_context.h"
+
+namespace ui {
+namespace {
+
+using fuchsia::accessibility::semantics::Node;
+
+constexpr size_t kMaxOperationsPerBatch = 16;
+
+}  // namespace
+
+AXFuchsiaSemanticProviderImpl::Batch::Batch(Type type) : type_(type) {}
+AXFuchsiaSemanticProviderImpl::Batch::Batch(Batch&& other) = default;
+AXFuchsiaSemanticProviderImpl::Batch::~Batch() = default;
+
+bool AXFuchsiaSemanticProviderImpl::Batch::IsFull() const {
+  return (
+      (type_ == Type::kUpdate && updates_.size() >= kMaxOperationsPerBatch) ||
+      (type_ == Type::kDelete &&
+       delete_node_ids_.size() >= kMaxOperationsPerBatch));
+}
+
+void AXFuchsiaSemanticProviderImpl::Batch::Append(
+    fuchsia::accessibility::semantics::Node node) {
+  DCHECK_EQ(type_, Type::kUpdate);
+  DCHECK(!IsFull());
+  updates_.push_back(std::move(node));
+}
+
+void AXFuchsiaSemanticProviderImpl::Batch::AppendDeletion(
+    uint32_t delete_node_id) {
+  DCHECK_EQ(type_, Type::kDelete);
+  DCHECK(!IsFull());
+  delete_node_ids_.push_back(delete_node_id);
+}
+
+void AXFuchsiaSemanticProviderImpl::Batch::Apply(
+    fuchsia::accessibility::semantics::SemanticTreePtr* semantic_tree) {
+  if (type_ == Type::kUpdate && !updates_.empty())
+    (*semantic_tree)->UpdateSemanticNodes(std::move(updates_));
+  else if (type_ == Type::kDelete && !delete_node_ids_.empty())
+    (*semantic_tree)->DeleteSemanticNodes(std::move(delete_node_ids_));
+}
+
+AXFuchsiaSemanticProviderImpl::NodeInfo ::NodeInfo() = default;
+AXFuchsiaSemanticProviderImpl::NodeInfo ::~NodeInfo() = default;
+
+AXFuchsiaSemanticProviderImpl::Delegate::Delegate() = default;
+AXFuchsiaSemanticProviderImpl::Delegate::~Delegate() = default;
+
+AXFuchsiaSemanticProviderImpl::AXFuchsiaSemanticProviderImpl(
+    fuchsia::ui::views::ViewRef view_ref,
+    base::RepeatingCallback<float()> get_pixel_scale,
+    Delegate* delegate)
+    : view_ref_(std::move(view_ref)),
+      get_pixel_scale_(std::move(get_pixel_scale)),
+      delegate_(delegate),
+      semantic_listener_binding_(this) {
+  sys::ComponentContext* component_context = base::ComponentContextForProcess();
+  DCHECK(component_context);
+  DCHECK(delegate_);
+
+  component_context->svc()
+      ->Connect<fuchsia::accessibility::semantics::SemanticsManager>()
+      ->RegisterViewForSemantics(std::move(view_ref_),
+                                 semantic_listener_binding_.NewBinding(),
+                                 semantic_tree_.NewRequest());
+  semantic_tree_.set_error_handler([this](zx_status_t status) {
+    ZX_LOG(ERROR, status) << "SemanticTree disconnected";
+    delegate_->OnSemanticsManagerConnectionClosed();
+    semantic_updates_enabled_ = false;
+  });
+}
+
+AXFuchsiaSemanticProviderImpl::~AXFuchsiaSemanticProviderImpl() = default;
+
+bool AXFuchsiaSemanticProviderImpl::Update(
+    fuchsia::accessibility::semantics::Node node) {
+  if (!semantic_updates_enabled())
+    return false;
+
+  DCHECK(node.has_node_id());
+
+  if (node.node_id() != kFuchsiaRootNodeId) {
+    auto found_not_reachable = not_reachable_.find(node.node_id());
+    const bool is_not_reachable = found_not_reachable != not_reachable_.end();
+    const absl::optional<uint32_t> parent_node_id =
+        GetParentForNode(node.node_id());
+    if (is_not_reachable && parent_node_id) {
+      // Connection parent -> |node| exists now.
+      not_reachable_.erase(found_not_reachable);
+      nodes_[node.node_id()].parents.insert(*parent_node_id);
+    } else if (!parent_node_id) {
+      // No node or multiple nodes points to this one, so it is not reachable.
+      if (!is_not_reachable)
+        not_reachable_[node.node_id()] = {};
+    }
+  }
+
+  // If the node is not present in the map, the list of children will be empty
+  // so this is a no-op in the call below.
+  std::vector<uint32_t>& children = nodes_[node.node_id()].children;
+
+  // Before updating the node, update the list of children to be not reachable,
+  // in case the new list of children change.
+  MarkChildrenAsNotReachable(children, node.node_id());
+  children = node.has_child_ids() ? node.child_ids() : std::vector<uint32_t>();
+  MarkChildrenAsReachable(children, node.node_id());
+
+  Batch& batch = GetCurrentUnfilledBatch(Batch::Type::kUpdate);
+  batch.Append(std::move(node));
+  TryToCommit();
+  return true;
+}
+
+void AXFuchsiaSemanticProviderImpl::TryToCommit() {
+  // Don't send out updates while the tree is mid-mutation.
+  if (commit_inflight_ || batches_.empty())
+    return;
+
+  // If a tree has nodes but no root, wait until the root is present or all
+  // nodes are deleted.
+  if (!nodes_.empty() && nodes_.find(kFuchsiaRootNodeId) == nodes_.end())
+    return;
+
+  if (!not_reachable_.empty())
+    return;
+
+  for (auto& batch : batches_) {
+    batch.Apply(&semantic_tree_);
+  }
+
+  batches_.clear();
+  semantic_tree_->CommitUpdates(
+      fit::bind_member(this, &AXFuchsiaSemanticProviderImpl::OnCommitComplete));
+  commit_inflight_ = true;
+}
+
+bool AXFuchsiaSemanticProviderImpl::Delete(uint32_t node_id) {
+  if (!semantic_updates_enabled())
+    return false;
+
+  auto it = nodes_.find(node_id);
+  if (it == nodes_.end())
+    return false;
+
+  if (it->second.parents.empty()) {
+    // No node points to this one, so it is safe to remove it from the tree.
+    not_reachable_.erase(node_id);
+  } else {
+    not_reachable_[node_id] =
+        it->second
+            .parents;  // Zero or more parents can be pointing to this node.
+  }
+  MarkChildrenAsNotReachable(it->second.children, node_id);
+
+  nodes_.erase(it);
+
+  Batch& batch = GetCurrentUnfilledBatch(Batch::Type::kDelete);
+  batch.AppendDeletion(node_id);
+  TryToCommit();
+  return true;
+}
+
+void AXFuchsiaSemanticProviderImpl::SendEvent(
+    fuchsia::accessibility::semantics::SemanticEvent event) {
+  semantic_tree_->SendSemanticEvent(std::move(event), [](auto...) {});
+}
+
+bool AXFuchsiaSemanticProviderImpl::HasPendingUpdates() const {
+  return commit_inflight_ || !batches_.empty();
+}
+
+bool AXFuchsiaSemanticProviderImpl::Clear() {
+  if (!semantic_updates_enabled())
+    return false;
+
+  batches_.clear();
+  not_reachable_.clear();
+  nodes_.clear();
+  Batch& batch = GetCurrentUnfilledBatch(Batch::Type::kDelete);
+  batch.AppendDeletion(kFuchsiaRootNodeId);
+  TryToCommit();
+  return true;
+}
+
+void AXFuchsiaSemanticProviderImpl::OnAccessibilityActionRequested(
+    uint32_t node_id,
+    fuchsia::accessibility::semantics::Action action,
+    fuchsia::accessibility::semantics::SemanticListener::
+        OnAccessibilityActionRequestedCallback callback) {
+  if (delegate_->OnAccessibilityAction(node_id, action)) {
+    callback(true);
+    return;
+  }
+
+  // The action was not handled.
+  callback(false);
+}
+
+void AXFuchsiaSemanticProviderImpl::HitTest(fuchsia::math::PointF local_point,
+                                            HitTestCallback callback) {
+  float pixel_scale = get_pixel_scale_.Run();
+  fuchsia::math::PointF point;
+  point.x = local_point.x * pixel_scale;
+  point.y = local_point.y * pixel_scale;
+
+  delegate_->OnHitTest(point, std::move(callback));
+  return;
+}
+
+void AXFuchsiaSemanticProviderImpl::OnSemanticsModeChanged(
+    bool update_enabled,
+    OnSemanticsModeChangedCallback callback) {
+  if (semantic_updates_enabled_ != update_enabled)
+    delegate_->OnSemanticsEnabled(update_enabled);
+
+  semantic_updates_enabled_ = update_enabled;
+  callback();
+}
+
+void AXFuchsiaSemanticProviderImpl::MarkChildrenAsNotReachable(
+    const std::vector<uint32_t>& child_ids,
+    uint32_t parent_id) {
+  for (const uint32_t child_id : child_ids) {
+    const auto it = nodes_.find(child_id);
+    if (it != nodes_.end()) {
+      it->second.parents.erase(parent_id);
+      if (it->second.parents.empty())
+        not_reachable_[child_id] = {};
+      else
+        not_reachable_.erase(child_id);
+    } else {
+      auto not_reachable_it = not_reachable_.find(child_id);
+      // Child id is no longer in the regular map, deletes it also from
+      // not_reachable_ if no parent points to it anymore.
+      if (not_reachable_it != not_reachable_.end()) {
+        not_reachable_it->second.erase(parent_id);
+        if (not_reachable_it->second.empty())
+          not_reachable_.erase(not_reachable_it);
+      }
+    }
+  }
+}
+
+void AXFuchsiaSemanticProviderImpl::MarkChildrenAsReachable(
+    const std::vector<uint32_t>& child_ids,
+    uint32_t parent_id) {
+  for (const uint32_t child_id : child_ids) {
+    auto it = nodes_.find(child_id);
+    if (it == nodes_.end())
+      not_reachable_[child_id].insert(parent_id);
+    else {
+      it->second.parents.insert(parent_id);
+      if (it->second.parents.size() == 1)
+        not_reachable_.erase(child_id);
+      else
+        not_reachable_[child_id].insert(parent_id);
+    }
+  }
+}
+
+absl::optional<uint32_t> AXFuchsiaSemanticProviderImpl::GetParentForNode(
+    const uint32_t node_id) {
+  const auto it = nodes_.find(node_id);
+  if (it != nodes_.end()) {
+    if (it->second.parents.size() == 1)
+      return *it->second.parents.begin();
+    else
+      return absl::nullopt;
+  }
+
+  const auto not_reachable_it = not_reachable_.find(node_id);
+  if (not_reachable_it != not_reachable_.end()) {
+    if (not_reachable_it->second.size() == 1)
+      return *not_reachable_it->second.begin();
+    else
+      return absl::nullopt;
+  }
+
+  return absl::nullopt;
+}
+
+AXFuchsiaSemanticProviderImpl::Batch&
+AXFuchsiaSemanticProviderImpl::GetCurrentUnfilledBatch(Batch::Type type) {
+  if (batches_.empty() || batches_.back().type() != type ||
+      batches_.back().IsFull())
+    batches_.push_back(Batch(type));
+
+  return batches_.back();
+}
+
+void AXFuchsiaSemanticProviderImpl::OnCommitComplete() {
+  commit_inflight_ = false;
+  TryToCommit();
+}
+
+float AXFuchsiaSemanticProviderImpl::GetPixelScale() const {
+  if (get_pixel_scale_)
+    return get_pixel_scale_.Run();
+
+  return 1.f;
+}
+
+}  // namespace ui
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider_impl.h b/ui/accessibility/platform/fuchsia/semantic_provider_impl.h
new file mode 100644
index 0000000..6652e04b
--- /dev/null
+++ b/ui/accessibility/platform/fuchsia/semantic_provider_impl.h
@@ -0,0 +1,192 @@
+// Copyright 2021 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 UI_ACCESSIBILITY_PLATFORM_FUCHSIA_SEMANTIC_PROVIDER_IMPL_H_
+#define UI_ACCESSIBILITY_PLATFORM_FUCHSIA_SEMANTIC_PROVIDER_IMPL_H_
+
+#include <fuchsia/accessibility/semantics/cpp/fidl.h>
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <lib/fidl/cpp/binding.h>
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include "base/callback.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/accessibility/ax_export.h"
+#include "ui/accessibility/platform/fuchsia/semantic_provider.h"
+
+namespace ui {
+
+// Clients instantiate this class, which connects to the Fuchsia semantics API.
+// This object must remain alive across the entire lifespan of the corresponding
+// fuchsia view.
+class AX_EXPORT AXFuchsiaSemanticProviderImpl
+    : public AXFuchsiaSemanticProvider,
+      public fuchsia::accessibility::semantics::SemanticListener {
+ public:
+  // Arguments:
+  // |view_ref|: identifies the view providing semantics. Please consult
+  // |fuchsia.accessibility.semantics| API documentation.
+  // |get_pixel_scale|: Callback to retrieve the pixel scale factor.
+  // |delegate|: Handles semantic requests, please see Delegate class for more
+  // documentation. Caller is responsible for ensuring that |delegate| outlives
+  // |this|.
+  // During construction, this class connects to
+  // |fuchsia.accessibility.semantics.SemanticsManager| to register itself as a
+  // semantic provider.
+  AXFuchsiaSemanticProviderImpl(
+      fuchsia::ui::views::ViewRef view_ref,
+      base::RepeatingCallback<float()> get_pixel_scale,
+      Delegate* delegate);
+  ~AXFuchsiaSemanticProviderImpl() override;
+
+  // Returns true if Fuchsia has enabled semantics.
+  bool semantic_updates_enabled() const { return semantic_updates_enabled_; }
+
+  // AXFuchsiaSemanticProvider overrides.
+  bool Update(fuchsia::accessibility::semantics::Node node) override;
+  bool Delete(uint32_t node_id) override;
+  bool Clear() override;
+  void SendEvent(
+      fuchsia::accessibility::semantics::SemanticEvent event) override;
+  bool HasPendingUpdates() const override;
+  float GetPixelScale() const override;
+
+ private:
+  // Holds information about a Fuchsia Semantic Node. It contains only the
+  // fields needed to check that the resulting tree would be valid.
+  struct NodeInfo {
+    NodeInfo();
+    ~NodeInfo();
+
+    // During a tree update a node may have multiple parents pointing to it,
+    // although after all updates are processed only one should be present.
+    std::set<uint32_t> parents;
+    std::vector<uint32_t> children;
+  };
+
+  // Represents a batch of nodes to be sent to Fuchsia.
+  // Batches can hold exactly one type: a series of updates or a series of
+  // deletions.
+  class Batch {
+   public:
+    enum class Type { kUpdate, kDelete };
+
+    Batch(Type type);
+    Batch(Batch&& other);
+    ~Batch();
+    Batch(const Batch& other) = delete;
+
+    Type type() const { return type_; }
+
+    // Returns true if the batch has reached its size limit.
+    bool IsFull() const;
+
+    // Adds an update or deletion to the batch. This fails if the batch is full
+    // or if the new item is not the same type of the batch.
+    void Append(fuchsia::accessibility::semantics::Node node);
+    void AppendDeletion(uint32_t delete_node_id);
+
+    // Sends enqueued operations to SemanticsManager.
+    void Apply(
+        fuchsia::accessibility::semantics::SemanticTreePtr* semantic_tree);
+
+   private:
+    Type type_;
+    std::vector<fuchsia::accessibility::semantics::Node> updates_;
+    std::vector<uint32_t> delete_node_ids_;
+  };
+
+  // Attempts to commit the pending updates to Fuchsia if the resulting updates
+  // would leave the final tree in a valid state.
+  void TryToCommit();
+
+  // Returns a batch that can receive an update or deletion depending on |type|.
+  Batch& GetCurrentUnfilledBatch(Batch::Type type);
+
+  // Invoked whenever Fuchsia responds that a commit was received. This tries to
+  // commit again if there are pending upedates or deletions.
+  void OnCommitComplete();
+
+  // Mark all |child_ids| not reachable from |parent_id|, meaning:
+  // - If |parent_id| was the only parent, the children are now disconnected
+  // from the tree.
+  // - If |parent_id| was an additional parent, now the children are connected
+  // to a single parent in the tree.
+  // - If the children do not exist, remove them from the list of nodes waiting
+  // to be updated.
+  void MarkChildrenAsNotReachable(const std::vector<uint32_t>& child_ids,
+                                  uint32_t parent_id);
+
+  // Mark all |child_ids| reachable from |parent_id|, meaning:
+  // - If |parent_id| is the only parent, the children are now connected to the
+  // tree and are all reachable.
+  // - If |parent_id| is an additional parent, now the children are not
+  // connected to the tree as multiple parents point to them.
+  // - If the children do not exist, the parent waits for the nodes to be
+  // created.
+  void MarkChildrenAsReachable(const std::vector<uint32_t>& child_ids,
+                               uint32_t parent_id);
+
+  // Returns the ID of the parent of this node if it has one. If it does not
+  // have a parent or it has multiple parents, returns absl::nullopt.
+  absl::optional<uint32_t> GetParentForNode(const uint32_t node_id);
+
+  // fuchsia::accessibility::semantics::SemanticListener:
+  void OnAccessibilityActionRequested(
+      uint32_t node_id,
+      fuchsia::accessibility::semantics::Action action,
+      fuchsia::accessibility::semantics::SemanticListener::
+          OnAccessibilityActionRequestedCallback callback) override;
+
+  // fuchsia::accessibility::semantics::SemanticListener:
+  void HitTest(::fuchsia::math::PointF local_point,
+               HitTestCallback callback) override;
+
+  // fuchsia::accessibility::semantics::SemanticListener:
+  void OnSemanticsModeChanged(bool update_enabled,
+                              OnSemanticsModeChangedCallback callback) override;
+
+  fuchsia::ui::views::ViewRef view_ref_;
+
+  // Callback used to retrieve the pixel scale.
+  base::RepeatingCallback<float()> get_pixel_scale_;
+
+  Delegate* const delegate_;
+
+  fidl::Binding<fuchsia::accessibility::semantics::SemanticListener>
+      semantic_listener_binding_;
+
+  fuchsia::accessibility::semantics::SemanticTreePtr semantic_tree_;
+
+  bool semantic_updates_enabled_ = false;
+
+  // Nodes from this tree. If not empty, to be considered a valid tree, there
+  // must be:
+  // - A node which node id is equal to kFuchsiaRootNodeId;
+  // - Each node except the root has only one parent;
+  // - All children pointed by a parent exist in the tree.
+  // Only the node ID and the child IDs of the node are stored here because at
+  // this point we only check to see if the tree is valid.
+  std::map<uint32_t /*node_id*/, NodeInfo> nodes_;
+
+  // Key == the node ID that is not reachable from the root of the tree, value
+  // == 0 or more parents that point to this node. Note that nodes can be listed
+  // here but still be present in |nodes_|. This may happen, for example, if the
+  // parent of the node was deleted and there is no path from the root to it, so
+  // the node waits for a parent to connect to it.
+  std::map<uint32_t, std::set<uint32_t>> not_reachable_;
+
+  // Stores batches of node updates or deletions to be sent to Fuchsia. Note
+  // that a batch contains only updates or deletions, because they are pushed to
+  // Fuchsia differently.
+  std::vector<Batch> batches_;
+
+  bool commit_inflight_ = false;
+};
+
+}  // namespace ui
+#endif  // UI_ACCESSIBILITY_PLATFORM_FUCHSIA_SEMANTIC_PROVIDER_IMPL_H_
diff --git a/ui/accessibility/platform/fuchsia/semantic_provider_unittest.cc b/ui/accessibility/platform/fuchsia/semantic_provider_unittest.cc
index dc2ed67..50d58ff 100644
--- a/ui/accessibility/platform/fuchsia/semantic_provider_unittest.cc
+++ b/ui/accessibility/platform/fuchsia/semantic_provider_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "semantic_provider.h"
+#include "semantic_provider_impl.h"
 
 #include <fuchsia/accessibility/semantics/cpp/fidl.h>
 #include <lib/ui/scenic/cpp/view_ref_pair.h>
@@ -45,8 +45,10 @@
     return true;
   }
 
-  void OnHitTest(fuchsia::math::PointF point,
-                 AXFuchsiaSemanticProvider::HitTestCallback callback) override {
+  void OnHitTest(
+      fuchsia::math::PointF point,
+      fuchsia::accessibility::semantics::SemanticListener::HitTestCallback
+          callback) override {
     on_hit_test_called_ = true;
     on_hit_test_point_ = std::move(point);
   }
@@ -114,8 +116,9 @@
     auto view_ref_pair = scenic::ViewRefPair::New();
     delegate_ = std::make_unique<AXFuchsiaSemanticProviderDelegate>();
 
-    semantic_provider_ = std::make_unique<AXFuchsiaSemanticProvider>(
-        std::move(view_ref_pair.view_ref), 2.0f, delegate_.get());
+    semantic_provider_ = std::make_unique<ui::AXFuchsiaSemanticProviderImpl>(
+        std::move(view_ref_pair.view_ref),
+        base::BindRepeating([]() { return 2.0f; }), delegate_.get());
 
     // Spin the loop to allow registration with the SemanticsManager to be
     // processed.
@@ -136,6 +139,7 @@
       ADD_FAILURE();
     });
     semantic_tree_binding_.Bind(std::move(semantic_tree_request));
+    semantic_listener_->OnSemanticsModeChanged(true, []() {});
   }
 
   // fuchsia::accessibility::semantics::SemanticTree implementation.
@@ -172,7 +176,7 @@
   fidl::Binding<fuchsia::accessibility::semantics::SemanticTree>
       semantic_tree_binding_;
   std::unique_ptr<AXFuchsiaSemanticProviderDelegate> delegate_;
-  std::unique_ptr<AXFuchsiaSemanticProvider> semantic_provider_;
+  std::unique_ptr<ui::AXFuchsiaSemanticProviderImpl> semantic_provider_;
 };
 
 TEST_F(AXFuchsiaSemanticProviderTest,
diff --git a/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.mm b/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.mm
index f18e3d1..7c56dd54 100644
--- a/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.mm
+++ b/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.mm
@@ -185,7 +185,7 @@
     return AXOptionalNSObject::Error();
   }
 
-  // Attributes.
+  // Get or set attribute value if the attribute is supported.
   for (NSString* attribute : AXAttributeNamesOf(target)) {
     if (property_node.IsMatching(base::SysNSStringToUTF8(attribute))) {
       // Setter
@@ -223,10 +223,20 @@
   // NSAccessibility attributes listed in default filters as a side effect.
   if (base::StartsWith(property_node.name_or_value, "accessibility") ||
       base::StartsWith(property_node.name_or_value, "isAccessibility")) {
-    absl::optional<id> optional_id =
-        PerformAXSelector(target, property_node.name_or_value);
-    if (optional_id)
-      return AXOptionalNSObject(*optional_id);
+    if (property_node.arguments.size() == 1) {
+      auto optional_id =
+          PerformAXSelector(target, property_node.name_or_value,
+                            property_node.arguments[0].name_or_value);
+      if (optional_id) {
+        return AXOptionalNSObject(*optional_id);
+      }
+    }
+    if (property_node.arguments.empty()) {
+      auto optional_id = PerformAXSelector(target, property_node.name_or_value);
+      if (optional_id) {
+        return AXOptionalNSObject(*optional_id);
+      }
+    }
   }
 
   // Unmatched attribute.
diff --git a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.h b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.h
index d4cc3a9..16076ed2 100644
--- a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.h
+++ b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.h
@@ -61,6 +61,15 @@
                                                const std::string& selector);
 
 //
+// Performs the given selector on the given node with exactly one string
+// argument and returns the result. If the node does not conform to the
+// NSAccessibility protocol or the selector is not found, then returns nullopt.
+AX_EXPORT absl::optional<id> PerformAXSelector(
+    const id node,
+    const std::string& selector_string,
+    const std::string& argument_string);
+
+//
 // Sets attribute value on a given node (either AXUIElement or
 // BrowserAccessibilityCocoa).
 AX_EXPORT void SetAXAttributeValueOf(const id node,
diff --git a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm
index 46f687bb..eaa8d56 100644
--- a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm
+++ b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm
@@ -235,6 +235,21 @@
   return absl::nullopt;
 }
 
+absl::optional<id> PerformAXSelector(const id node,
+                                     const std::string& selector_string,
+                                     const std::string& argument_string) {
+  if (![node conformsToProtocol:@protocol(NSAccessibility)])
+    return absl::nullopt;
+
+  SEL selector =
+      NSSelectorFromString(base::SysUTF8ToNSString(selector_string + ":"));
+  NSString* argument = base::SysUTF8ToNSString(argument_string);
+
+  if ([node respondsToSelector:selector])
+    return [node performSelector:selector withObject:argument];
+  return absl::nullopt;
+}
+
 void SetAXAttributeValueOf(const id node, NSString* attribute, id value) {
   if (IsNSAccessibilityElement(node)) {
     [node accessibilitySetValue:value forAttribute:attribute];
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index 0e42331..23af66d 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -131,11 +131,6 @@
   sources = [
     "java/res/color/blue_when_enabled.xml",
     "java/res/color/blue_when_enabled_dark.xml",
-    "java/res/color/chip_background_color.xml",
-    "java/res/color/chip_ripple_color.xml",
-    "java/res/color/chip_stroke_color.xml",
-    "java/res/color/chip_text_color.xml",
-    "java/res/color/chip_text_color_secondary.xml",
     "java/res/color/default_text_color_inverse_list.xml",
     "java/res/color/default_text_color_light_list.xml",
     "java/res/color/default_text_color_list_baseline.xml",
@@ -144,7 +139,6 @@
     "java/res/color/default_text_color_secondary_list_baseline.xml",
     "java/res/color/filled_button_bg.xml",
     "java/res/color/filled_button_ripple_color.xml",
-    "java/res/color/menu_chip_background.xml",
     "java/res/color/text_button_ripple_color.xml",
     "java/res/drawable-hdpi/btn_close.png",
     "java/res/drawable-hdpi/ic_expand_less_black_24dp.png",
@@ -337,7 +331,6 @@
     "java/src/org/chromium/ui/widget/AnchoredPopupWindow.java",
     "java/src/org/chromium/ui/widget/ButtonCompat.java",
     "java/src/org/chromium/ui/widget/CheckableImageView.java",
-    "java/src/org/chromium/ui/widget/ChipView.java",
     "java/src/org/chromium/ui/widget/ChromeBulletSpan.java",
     "java/src/org/chromium/ui/widget/ChromeImageButton.java",
     "java/src/org/chromium/ui/widget/ChromeImageView.java",
diff --git a/ui/android/java/res/COLOR_OWNERS b/ui/android/java/res/COLOR_OWNERS
deleted file mode 100644
index fcbb198..0000000
--- a/ui/android/java/res/COLOR_OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-lazzzis@google.com
-sinansahin@google.com
-skym@chromium.org
diff --git a/ui/android/java/res/LAYOUT_OWNERS b/ui/android/java/res/LAYOUT_OWNERS
index b0bda67..26d8cb9 100644
--- a/ui/android/java/res/LAYOUT_OWNERS
+++ b/ui/android/java/res/LAYOUT_OWNERS
@@ -1,5 +1,8 @@
 bsazonov@chromium.org
 dtrainor@chromium.org
+lazzzis@google.com
 mdjones@chromium.org
+sinansahin@google.com
+skym@chromium.org
 tedchoc@chromium.org
 twellington@chromium.org
diff --git a/ui/android/java/res/OWNERS b/ui/android/java/res/OWNERS
index 57d5068..ba7a123 100644
--- a/ui/android/java/res/OWNERS
+++ b/ui/android/java/res/OWNERS
@@ -3,7 +3,3 @@
 # we don't want them.
 set noparent
 file://ui/android/java/res/LAYOUT_OWNERS
-
-per-file ...color*.xml=file://ui/android/java/res/COLOR_OWNERS
-per-file ...style*.xml=file://ui/android/java/res/COLOR_OWNERS
-per-file ...SemanticColorUtils.java=file://ui/android/java/res/COLOR_OWNERS
diff --git a/ui/android/java/res/color/chip_text_color.xml b/ui/android/java/res/color/chip_text_color.xml
deleted file mode 100644
index 2e0a1dd..0000000
--- a/ui/android/java/res/color/chip_text_color.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:alpha="@dimen/default_disabled_alpha"
-        android:color="@color/chip_text_color_selected"
-        android:state_selected="true" android:state_enabled="false"/>
-    <item android:alpha="@dimen/default_disabled_alpha"
-        android:color="@color/default_chip_assistive_text_color" android:state_enabled="false" />
-    <item android:color="@color/chip_text_color_selected" android:state_selected="true" />
-    <item android:color="@color/default_chip_assistive_text_color" />
-</selector>
diff --git a/ui/android/java/res/values-night/colors.xml b/ui/android/java/res/values-night/colors.xml
index 148c679..c7883783 100644
--- a/ui/android/java/res/values-night/colors.xml
+++ b/ui/android/java/res/values-night/colors.xml
@@ -61,13 +61,6 @@
     <color name="default_control_color_normal_baseline">@color/default_control_color_normal_dark</color>
     <color name="default_control_color_active_baseline">@color/default_control_color_active_dark</color>
 
-    <!-- Chip colors -->
-    <color name="default_chip_outline_color">@color/default_chip_outline_color_dark</color>
-    <color name="chip_selected_hover">@color/chip_selected_hover_light</color>
-    <color name="chip_selected_focused">@color/chip_selected_focused_light</color>
-    <color name="chip_selected_hover_and_focused">@color/chip_selected_hover_and_focused_light</color>
-    <color name="chip_selected">@color/chip_selected_dark</color>
-
     <!-- CircularProgressView colors -->
     <color name="circular_progress_outer_circle_progress_color_small">@color/circular_progress_outer_circle_progress_color_small_dark</color>
     <color name="circular_progress_icon_color_small_large">@color/circular_progress_icon_color_small_large_dark</color>
@@ -99,8 +92,6 @@
     <color name="image_loading_color">@color/image_loading_color_light</color>
     <color name="promo_illustration_bg_color">@color/promo_illustration_bg_color_dark</color>
     <color name="preference_highlighted_bg_color">@color/preference_highlighted_bg_color_light</color>
-    <color name="menu_chip_background_color">@color/menu_chip_background_color_light</color>
-    <color name="menu_chip_background_color_disabled">@color/menu_chip_background_color_disabled_light</color>
     <color name="iph_highlight_blue">@color/iph_highlight_blue_light</color>
     <color name="rating_star_yellow">@color/rating_star_yellow_light</color>
     <color name="price_drop_annotation_bg_color">@color/price_drop_annotation_bg_color_dark</color>
diff --git a/ui/android/java/res/values-night/dimens.xml b/ui/android/java/res/values-night/dimens.xml
index 79d7927e9..be54175 100644
--- a/ui/android/java/res/values-night/dimens.xml
+++ b/ui/android/java/res/values-night/dimens.xml
@@ -5,9 +5,6 @@
      found in the LICENSE file.
 -->
 <resources>
-    <!-- Chips default measures -->
-    <dimen name="chip_background_selected_alpha">@dimen/chip_background_selected_alpha_dark</dimen>
-
     <!-- TODO(crbug.com/1236215): Remove once dynamic color is ready for all cards -->
     <dimen name="card_elevation">@dimen/default_elevation_2</dimen>
 </resources>
diff --git a/ui/android/java/res/values-v17/styles.xml b/ui/android/java/res/values-v17/styles.xml
index 51df0a0..d89b0404 100644
--- a/ui/android/java/res/values-v17/styles.xml
+++ b/ui/android/java/res/values-v17/styles.xml
@@ -58,54 +58,6 @@
         <item name="rippleColor">@color/filled_button_ripple_color</item>
     </style>
 
-    <!-- Chips -->
-    <style name="SuggestionChipThemeOverlay" tools:ignore="UnusedResources">
-        <item name="chipStyle">@style/SuggestionChip</item>
-    </style>
-
-    <style name="Chip">
-        <item name="android:minHeight">@dimen/min_touch_target_size</item>
-        <item name="android:gravity">center_vertical</item>
-        <item name="android:orientation">horizontal</item>
-        <item name="chipColor">@color/chip_background_color</item>
-        <item name="primaryTextAppearance">@style/TextAppearance.ChipText</item>
-        <item name="secondaryTextAppearance">@style/TextAppearance.ChipHint</item>
-        <item name="rippleColor">@color/chip_ripple_color</item>
-        <item name="verticalInset">@dimen/chip_bg_vertical_inset</item>
-    </style>
-    <style name="SuggestionChip" parent="Chip" tools:ignore="UnusedResources">
-        <item name="primaryTextAppearance">@style/TextAppearance.ChipHint</item>
-        <item name="cornerRadius">@dimen/chip_corner_radius</item>
-    </style>
-    <style name="InputChip" parent="Chip" tools:ignore="UnusedResources">
-        <item name="cornerRadius">@dimen/chip_default_height</item>
-    </style>
-    <style name="AssistiveChip" parent="Chip" tools:ignore="UnusedResources">
-        <item name="cornerRadius">@dimen/chip_default_height</item>
-    </style>
-    <style name="InputChipWithRemoveIcon" parent="InputChip" tools:ignore="UnusedResources">
-        <item name="iconWidth">28dp</item>
-        <item name="iconHeight">28dp</item>
-        <item name="useRoundedIcon">true</item>
-        <item name="endIconWidth">18dp</item>
-        <item name="endIconHeight">18dp</item>
-    </style>
-
-    <style name="ChipTextView" tools:ignore="UnusedResources">
-        <item name="android:gravity">center</item>
-        <item name="android:maxLines">1</item>
-        <item name="android:paddingStart">@dimen/chip_element_leading_padding</item>
-        <item name="android:textAlignment">center</item>
-    </style>
-
-    <style name="MenuChip" parent="Chip">
-        <item name="cornerRadius">@dimen/chip_default_height</item>
-        <item name="primaryTextAppearance">@style/TextAppearance.MenuChip.Text.Blue</item>
-        <item name="chipColor">@color/menu_chip_background</item>
-        <item name="solidColorChip">true</item>
-        <item name="verticalInset">@dimen/menu_chip_vertical_inset</item>
-    </style>
-
     <!-- Used by Chrome and Content -->
     <style name="TextAppearance" parent="android:TextAppearance" tools:ignore="UnusedResources" />
     <style name="TextAppearance.RobotoMediumStyle">
@@ -335,14 +287,6 @@
         <item name="android:textSize">@dimen/text_size_small</item>
     </style>
 
-    <!-- Chip Text Styles -->
-    <style name="TextAppearance.ChipText" parent="TextAppearance.TextAccentMediumThick">
-        <item name="android:textColor">@color/chip_text_color_secondary</item>
-    </style>
-    <style name="TextAppearance.ChipHint" parent="TextAppearance.TextAccentMediumThick">
-        <item name="android:textColor">@color/chip_text_color_secondary</item>
-    </style>
-
     <!-- Toast UI -->
     <style name="TextAppearance.Toast" parent="TextAppearance.TextSmall">
         <item name="android:textColor">@color/default_text_color_light</item>
diff --git a/ui/android/java/res/values/attrs.xml b/ui/android/java/res/values/attrs.xml
index 4cff7a42..7e8b195f 100644
--- a/ui/android/java/res/values/attrs.xml
+++ b/ui/android/java/res/values/attrs.xml
@@ -44,28 +44,6 @@
         <attr name="rippleCornerRadiusBottomEnd" format="reference|dimension" />
     </declare-styleable>
 
-    <declare-styleable name="ChipView">
-        <attr name="allowMultipleLines" format="boolean"/>
-        <attr name="extendLateralPadding" format="boolean"/>
-        <attr name="reduceEndPadding" format="boolean"/>
-        <attr name="solidColorChip" format="boolean"/>
-        <attr name="textAlignStart" format="boolean"/>
-        <attr name="reduceTextStartPadding" format="boolean"/>
-        <attr name="chipColor" format="color"/>
-        <attr name="chipStrokeColor" format="color"/>
-        <attr name="chipStyle" format="reference"/>
-        <attr name="cornerRadius" format="dimension"/>
-        <attr name="iconWidth" format="reference|dimension"/>
-        <attr name="iconHeight" format="reference|dimension"/>
-        <attr name="useRoundedIcon" format="boolean"/>
-        <attr name="primaryTextAppearance" format="reference"/>
-        <attr name="endIconWidth" format="reference|dimension"/>
-        <attr name="endIconHeight" format="reference|dimension"/>
-        <attr name="secondaryTextAppearance" format="reference"/>
-        <attr name="rippleColor"/>
-        <attr name="verticalInset"/>
-    </declare-styleable>
-
     <declare-styleable name="TextViewWithLeading">
         <attr name="leading" format="reference|dimension"/>
     </declare-styleable>
diff --git a/ui/android/java/res/values/dimens.xml b/ui/android/java/res/values/dimens.xml
index 2c0d5b4..ebacfc8f 100644
--- a/ui/android/java/res/values/dimens.xml
+++ b/ui/android/java/res/values/dimens.xml
@@ -33,31 +33,6 @@
     <dimen name="button_min_width">88dp</dimen>
     <dimen name="button_bg_vertical_inset">4dp</dimen>
 
-    <!-- Chips default measures -->
-    <item name="chip_background_selected_alpha_light" format="float" type="dimen">0.06</item>
-    <item name="chip_background_selected_alpha_dark" format="float" type="dimen">1</item>
-
-    <dimen name="chip_solid_border_width">0dp</dimen>
-    <dimen name="chip_border_width">1dp</dimen>
-    <dimen name="chip_corner_radius">8dp</dimen>
-    <dimen name="chip_default_height">32dp</dimen>
-    <dimen name="chip_end_padding">16dp</dimen>
-    <dimen name="chip_reduced_end_padding">12dp</dimen>
-    <dimen name="chip_element_leading_padding">8dp</dimen>
-    <dimen name="chip_element_extended_leading_padding">16dp</dimen>
-    <dimen name="chip_bg_vertical_inset">8dp</dimen>
-    <dimen name="chip_background_selected_alpha">@dimen/chip_background_selected_alpha_light</dimen>
-    <dimen name="chip_icon_size">20dp</dimen>
-    <dimen name="chip_loading_view_size">12dp</dimen>
-    <dimen name="chip_end_icon_margin_start">8dp</dimen>
-    <dimen name="chip_end_icon_extended_margin_start">16dp</dimen>
-    <dimen name="chip_end_padding_with_end_icon">6dp</dimen>
-    <dimen name="chip_extended_end_padding_with_end_icon">16dp</dimen>
-    <dimen name="chip_text_multiline_vertical_padding">12dp</dimen>
-    <dimen name="chip_text_reduced_leading_padding">4dp</dimen>
-    <!-- ( listPreferredItemHeightSmall(40dp) - text size(12sp) - top and bottom padding(8dp) ) / 2 -->
-    <dimen name="menu_chip_vertical_inset">10dp</dimen>
-
     <!-- Menu footer chip measures-->
     <!-- ( listPreferredItemHeightSmall(40dp) - text size(12sp) - top and bottom padding(12dp) ) / 2 -->
     <dimen name="menu_footer_chip_end_padding">8dp</dimen>
diff --git a/ui/android/java/res/values/semantic_colors_adaptive.xml b/ui/android/java/res/values/semantic_colors_adaptive.xml
index 0126e4c8..8dc6acf 100644
--- a/ui/android/java/res/values/semantic_colors_adaptive.xml
+++ b/ui/android/java/res/values/semantic_colors_adaptive.xml
@@ -75,21 +75,6 @@
     <color name="default_control_color_normal_baseline" tools:ignore="UnusedResources">@color/default_control_color_normal_light</color>
     <color name="default_control_color_active_baseline" tools:ignore="UnusedResources">@color/default_control_color_active_light</color>
 
-    <!-- Chip colors -->
-    <color name="default_chip_assistive_text_color">@color/default_text_color_baseline</color>
-    <color name="chip_text_color_selected">@color/default_text_color_on_accent2_container</color>
-    <color name="default_chip_assistive_text_color_secondary">@color/default_text_color_secondary</color>
-    <color name="chip_bg_color">@color/default_bg_color</color>
-    <color name="chip_background_color_disabled">@android:color/transparent</color>
-    <color name="default_chip_ripple_color">@color/default_bg_color_elev_2_baseline</color>
-    <color name="default_chip_outline_color" tools:ignore="UnusedResources">@color/default_chip_outline_color_light</color>
-    <color name="chip_selected_hover">@color/chip_selected_hover_dark</color>
-    <color name="chip_selected_focused">@color/chip_selected_focused_dark</color>
-    <color name="chip_selected_hover_and_focused">@color/chip_selected_hover_and_focused_dark</color>
-    <color name="chip_focused">@color/default_bg_color_elev_4_baseline</color>
-    <color name="chip_hover_focused">@color/default_bg_color_elev_4_baseline</color>
-    <color name="chip_selected">@color/chip_selected_light</color>
-
     <!-- CircularProgressView colors -->
     <color name="circular_progress_inner_background_color_small" tools:ignore="UnusedResources">@color/default_bg_color_elev_1_baseline</color>
     <color name="circular_progress_outer_circle_background_color_small" tools:ignore="UnusedResources">@color/default_bg_color_elev_1_baseline</color>
@@ -116,6 +101,7 @@
     <color name="menu_action_bar_bg_color_baseline">@color/menu_action_bar_bg_color_light_baseline</color>
     <color name="menu_action_bar_bg_color_light_baseline">@color/default_bg_color_light_elev_1_baseline</color>
     <color name="menu_action_bar_bg_color_dark_baseline">@color/default_bg_color_dark_elev_6_baseline</color>
+    <color name="menu_item_bg_color_baseline">@color/menu_item_bg_color</color>
     <color name="menu_item_bg_color">@color/menu_item_bg_color_light_baseline</color>
     <color name="menu_item_bg_color_light_baseline">@color/default_bg_color_light</color>
     <color name="menu_item_bg_color_dark_baseline">@color/default_bg_color_dark_elev_5_baseline</color>
@@ -131,8 +117,6 @@
     <color name="image_loading_color" tools:ignore="UnusedResources">@color/image_loading_color_dark</color>
     <color name="promo_illustration_bg_color" tools:ignore="UnusedResources">@color/promo_illustration_bg_color_light</color>
     <color name="preference_highlighted_bg_color">@color/preference_highlighted_bg_color_dark</color>
-    <color name="menu_chip_background_color">@color/menu_chip_background_color_dark</color>
-    <color name="menu_chip_background_color_disabled">@color/menu_chip_background_color_disabled_dark</color>
     <color name="iph_highlight_blue">@color/iph_highlight_blue_dark</color>
     <color name="rating_star_yellow">@color/rating_star_yellow_dark</color>
     <color name="price_drop_annotation_bg_color">@color/price_drop_annotation_bg_color_light</color>
diff --git a/ui/android/java/res/values/semantic_colors_non_adaptive.xml b/ui/android/java/res/values/semantic_colors_non_adaptive.xml
index 2dc4976..7e1829e 100644
--- a/ui/android/java/res/values/semantic_colors_non_adaptive.xml
+++ b/ui/android/java/res/values/semantic_colors_non_adaptive.xml
@@ -91,31 +91,6 @@
     <color name="default_scrim_color">@color/black_alpha_65</color>
     <color name="incognito_card_bg_color">@color/baseline_neutral_900_with_neutral_200_alpha_5_with_primary_200_alpha_2</color>
 
-    <!-- Chip Colors -->
-    <!-- Same as ?attr/colorOutline. -->
-    <color name="default_chip_outline_color_light">@color/baseline_neutral_variant_200</color>
-    <color name="default_chip_outline_color_dark">@color/baseline_neutral_variant_500</color>
-    <!-- Mix of ?attr/colorSecondaryContainer and ?attr/colorOnSurface. -->
-    <color name="chip_selected_hover_light">@color/baseline_secondary_300_with_neutral_100_alpha_8</color>
-    <color name="chip_selected_hover_dark">@color/baseline_secondary_100_with_neutral_900_alpha_8</color>
-    <!-- Mix of ?attr/colorSecondaryContainer and ?attr/colorOnSurface. -->
-    <color name="chip_selected_focused_light">@color/baseline_secondary_300_with_neutral_100_alpha_24</color>
-    <color name="chip_selected_focused_dark">@color/baseline_secondary_100_with_neutral_900_alpha_24</color>
-    <!-- Mix of ?attr/colorSecondaryContainer and ?attr/colorOnSurface. -->
-    <color name="chip_selected_hover_and_focused_light">@color/baseline_secondary_300_with_neutral_100_alpha_24</color>
-    <color name="chip_selected_hover_and_focused_dark">@color/baseline_secondary_100_with_neutral_900_alpha_24</color>
-    <!-- Same as ?attr/colorSecondaryContainer -->
-    <color name="chip_selected_light">@color/baseline_secondary_100</color>
-    <color name="chip_selected_dark">@color/baseline_secondary_300</color>
-    <color name="menu_chip_background_color_dark">@color/modern_blue_600_alpha_6</color>
-    <color name="menu_chip_background_color_light">@color/modern_blue_300_alpha_10</color>
-    <color name="menu_chip_background_color_disabled_dark">@color/modern_grey_100_alpha_38</color>
-    <color name="menu_chip_background_color_disabled_light">@color/white_alpha_6</color>
-    <color name="menu_footer_chip_background_color_dark">@color/modern_blue_600_alpha_10</color>
-    <color name="menu_footer_chip_background_color_light">@color/modern_blue_300_alpha_10</color>
-    <color name="menu_footer_chip_background_color_disabled_dark">@color/modern_grey_100</color>
-    <color name="menu_footer_chip_background_color_disabled_light">@color/white_alpha_6</color>
-
     <!-- IPH Highlight Colors -->
     <color name="iph_highlight_blue_dark">@color/modern_blue_600_alpha_10</color>
     <color name="iph_highlight_blue_light">@color/modern_blue_300_alpha_50</color>
diff --git a/ui/android/java/src/org/chromium/ui/widget/ChipView.java b/ui/android/java/src/org/chromium/ui/widget/ChipView.java
deleted file mode 100644
index ad574f9..0000000
--- a/ui/android/java/src/org/chromium/ui/widget/ChipView.java
+++ /dev/null
@@ -1,378 +0,0 @@
-// Copyright 2019 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.
-package org.chromium.ui.widget;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.AttrRes;
-import androidx.annotation.ColorInt;
-import androidx.annotation.DrawableRes;
-import androidx.annotation.IdRes;
-import androidx.annotation.Px;
-import androidx.annotation.StyleRes;
-import androidx.appcompat.widget.AppCompatTextView;
-import androidx.core.view.ViewCompat;
-
-import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.ui.R;
-
-/**
- * The view responsible for displaying a material chip. The chip has the following components :
- * - A primary text to be shown.
- * - An optional start icon that can be rounded as well.
- * - An optional secondary text view that is shown to the right of the primary text view.
- * - An optional remove icon at the end, intended for use with input chips.
- * - An optional boolean (solidColorChip) to remove the default chip border.
- * - An optional boolean (allowMultipleLines) to avoid longer text strings to wrap to a second line.
- * - An optional boolean (showLoadingView) to show a loading view in place of the start icon.
- */
-public class ChipView extends LinearLayout {
-    /** An id to use for {@link #setIcon(int, boolean)} when there is no icon on the chip. */
-    public static final int INVALID_ICON_ID = -1;
-    private static final int MAX_LINES = 2;
-
-    private final RippleBackgroundHelper mRippleBackgroundHelper;
-    private final AppCompatTextView mPrimaryText;
-    private final ChromeImageView mStartIcon;
-    private final boolean mUseRoundedStartIcon;
-    private final LoadingView mLoadingView;
-    private final @IdRes int mSecondaryTextAppearanceId;
-    private final int mEndIconWidth;
-    private final int mEndIconHeight;
-    private final int mEndIconStartPadding;
-    private final int mEndIconEndPadding;
-    private final int mCornerRadius;
-
-    private ViewGroup mEndIconWrapper;
-    private AppCompatTextView mSecondaryText;
-
-    /** Constructor for applying a theme overlay. */
-    public ChipView(Context context, @StyleRes int themeOverlay) {
-        this(new ContextThemeWrapper(context, themeOverlay), null, R.attr.chipStyle, 0);
-    }
-
-    /** Constructor for inflating from XML. */
-    public ChipView(Context context, AttributeSet attrs) {
-        this(new ContextThemeWrapper(context, R.style.SuggestionChipThemeOverlay), attrs,
-                R.attr.chipStyle, 0);
-    }
-
-    /** Constructor for base classes and programmatic creation. */
-    public ChipView(Context context, AttributeSet attrs, @AttrRes int defStyleAttr,
-            @StyleRes int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-
-        TypedArray a = getContext().obtainStyledAttributes(
-                attrs, R.styleable.ChipView, defStyleAttr, defStyleRes);
-
-        boolean extendLateralPadding =
-                a.getBoolean(R.styleable.ChipView_extendLateralPadding, false);
-        boolean reduceEndPadding = a.getBoolean(R.styleable.ChipView_reduceEndPadding, false);
-
-        @Px
-        int leadingElementPadding = extendLateralPadding
-                ? getResources().getDimensionPixelSize(
-                        R.dimen.chip_element_extended_leading_padding)
-                : getResources().getDimensionPixelSize(R.dimen.chip_element_leading_padding);
-
-        // End padding is already longer so no need to adjust in the 'extendLateralPadding' case.
-        @Px
-        int endPadding = reduceEndPadding
-                ? getResources().getDimensionPixelSize(R.dimen.chip_reduced_end_padding)
-                : getResources().getDimensionPixelSize(R.dimen.chip_end_padding);
-
-        mEndIconStartPadding = extendLateralPadding
-                ? getResources().getDimensionPixelSize(R.dimen.chip_end_icon_extended_margin_start)
-                : getResources().getDimensionPixelSize(R.dimen.chip_end_icon_margin_start);
-
-        mEndIconEndPadding = extendLateralPadding
-                ? getResources().getDimensionPixelSize(
-                        R.dimen.chip_extended_end_padding_with_end_icon)
-                : getResources().getDimensionPixelSize(R.dimen.chip_end_padding_with_end_icon);
-
-        boolean solidColorChip = a.getBoolean(R.styleable.ChipView_solidColorChip, false);
-        int chipBorderWidthId =
-                solidColorChip ? R.dimen.chip_solid_border_width : R.dimen.chip_border_width;
-        int chipColorId =
-                a.getResourceId(R.styleable.ChipView_chipColor, R.color.chip_background_color);
-        int rippleColorId =
-                a.getResourceId(R.styleable.ChipView_rippleColor, R.color.chip_ripple_color);
-        int chipStrokeColorId =
-                a.getResourceId(R.styleable.ChipView_chipStrokeColor, R.color.chip_stroke_color);
-        mCornerRadius = a.getDimensionPixelSize(R.styleable.ChipView_cornerRadius,
-                getContext().getResources().getDimensionPixelSize(R.dimen.chip_corner_radius));
-        int iconWidth = a.getDimensionPixelSize(R.styleable.ChipView_iconWidth,
-                getResources().getDimensionPixelSize(R.dimen.chip_icon_size));
-        int iconHeight = a.getDimensionPixelSize(R.styleable.ChipView_iconHeight,
-                getResources().getDimensionPixelSize(R.dimen.chip_icon_size));
-        mUseRoundedStartIcon = a.getBoolean(R.styleable.ChipView_useRoundedIcon, false);
-        int primaryTextAppearance = a.getResourceId(
-                R.styleable.ChipView_primaryTextAppearance, R.style.TextAppearance_ChipText);
-
-        mEndIconWidth = a.getDimensionPixelSize(R.styleable.ChipView_endIconWidth,
-                getResources().getDimensionPixelSize(R.dimen.chip_icon_size));
-        mEndIconHeight = a.getDimensionPixelSize(R.styleable.ChipView_endIconHeight,
-                getResources().getDimensionPixelSize(R.dimen.chip_icon_size));
-        mSecondaryTextAppearanceId = a.getResourceId(
-                R.styleable.ChipView_secondaryTextAppearance, R.style.TextAppearance_ChipText);
-        int verticalInset = a.getDimensionPixelSize(R.styleable.ChipView_verticalInset,
-                getResources().getDimensionPixelSize(R.dimen.chip_bg_vertical_inset));
-        boolean allowMultipleLines = a.getBoolean(R.styleable.ChipView_allowMultipleLines, false);
-        boolean textAlignStart = a.getBoolean(R.styleable.ChipView_textAlignStart, false);
-        boolean reduceTextStartPadding =
-                a.getBoolean(R.styleable.ChipView_reduceTextStartPadding, false);
-        a.recycle();
-
-        mStartIcon = new ChromeImageView(getContext());
-        mStartIcon.setLayoutParams(new LayoutParams(iconWidth, iconHeight));
-        addView(mStartIcon);
-
-        if (mUseRoundedStartIcon) {
-            int chipHeight = getResources().getDimensionPixelOffset(R.dimen.chip_default_height);
-            leadingElementPadding = (chipHeight - iconHeight) / 2;
-        }
-
-        int loadingViewSize = getResources().getDimensionPixelSize(R.dimen.chip_loading_view_size);
-        int loadingViewHeightPadding = (iconHeight - loadingViewSize) / 2;
-        int loadingViewWidthPadding = (iconWidth - loadingViewSize) / 2;
-        mLoadingView = new LoadingView(getContext());
-        mLoadingView.setVisibility(GONE);
-        mLoadingView.setIndeterminateTintList(ColorStateList.valueOf(ApiCompatibilityUtils.getColor(
-                getResources(), R.color.default_icon_color_accent1_baseline)));
-        mLoadingView.setPaddingRelative(loadingViewWidthPadding, loadingViewHeightPadding,
-                loadingViewWidthPadding, loadingViewHeightPadding);
-        addView(mLoadingView, new LayoutParams(iconWidth, iconHeight));
-
-        // Setting this enforces 16dp padding at the end and 8dp at the start (unless overridden).
-        // For text, the start padding needs to be 16dp which is why a ChipTextView contributes the
-        // remaining 8dp.
-        ViewCompat.setPaddingRelative(this, leadingElementPadding, 0, endPadding, 0);
-
-        mPrimaryText =
-                new AppCompatTextView(new ContextThemeWrapper(getContext(), R.style.ChipTextView));
-        ApiCompatibilityUtils.setTextAppearance(mPrimaryText, primaryTextAppearance);
-
-        // If false fall back to single line defined in XML styles.
-        if (allowMultipleLines) {
-            mPrimaryText.setMaxLines(MAX_LINES);
-            // Vertical padding must be explicitly defined for the text view to create space if text
-            // wrapping causes the chip to increase in size vertically.
-            int minMultilineVerticalTextPadding = getResources().getDimensionPixelSize(
-                    R.dimen.chip_text_multiline_vertical_padding);
-            // TODO(benwgold): Test for non multiline chips to see if 4dp vertical padding can be
-            // safely applied to all chips without affecting styling.
-            mPrimaryText.setPaddingRelative(mPrimaryText.getPaddingStart(),
-                    minMultilineVerticalTextPadding, mPrimaryText.getPaddingEnd(),
-                    minMultilineVerticalTextPadding);
-        }
-        if (textAlignStart) {
-            // Default of 'center' is defined in the ChipTextView style.
-            mPrimaryText.setTextAlignment((View.TEXT_ALIGNMENT_VIEW_START));
-        }
-        if (reduceTextStartPadding) {
-            mPrimaryText.setPaddingRelative(
-                    getResources().getDimensionPixelSize(R.dimen.chip_text_reduced_leading_padding),
-                    mPrimaryText.getPaddingTop(), mPrimaryText.getPaddingEnd(),
-                    mPrimaryText.getPaddingBottom());
-        }
-        addView(mPrimaryText);
-
-        // Reset icon and background:
-        mRippleBackgroundHelper = new RippleBackgroundHelper(this, chipColorId, rippleColorId,
-                mCornerRadius, chipStrokeColorId, chipBorderWidthId, verticalInset);
-        setIcon(INVALID_ICON_ID, false);
-    }
-
-    /**
-     * Unlike setSelected, setEnabled doesn't properly propagate the new state to its subcomponents.
-     * Enforce this so ColorStateLists used for the text appearance apply as intended.
-     * @param enabled The new enabled state for the chip view and the TextViews owned by it.
-     */
-    @Override
-    public void setEnabled(boolean enabled) {
-        super.setEnabled(enabled);
-        getPrimaryTextView().setEnabled(enabled);
-        mStartIcon.setEnabled(enabled);
-        if (mSecondaryText != null) mSecondaryText.setEnabled(enabled);
-    }
-
-    /**
-     * Sets the icon at the start of the chip view.
-     * @param icon The resource id pointing to the icon.
-     */
-    public void setIcon(@DrawableRes int icon, boolean tintWithTextColor) {
-        if (icon == INVALID_ICON_ID) {
-            mStartIcon.setVisibility(ViewGroup.GONE);
-            return;
-        }
-
-        mStartIcon.setVisibility(ViewGroup.VISIBLE);
-        mStartIcon.setImageResource(icon);
-        setTint(tintWithTextColor);
-    }
-
-    /**
-     * Sets the icon at the start of the chip view.
-     * @param drawable Drawable to display.
-     */
-    public void setIcon(Drawable drawable, boolean tintWithTextColor) {
-        mStartIcon.setVisibility(ViewGroup.VISIBLE);
-        mStartIcon.setImageDrawable(drawable);
-        setTint(tintWithTextColor);
-    }
-
-    /**
-     * Shows a {@link LoadingView} at the start of the chip view. This replaces the start icon.
-     * @param loadingViewObserver A {@link LoadingView.Observer} to add to the LoadingView.
-     */
-    public void showLoadingView(LoadingView.Observer loadingViewObserver) {
-        mLoadingView.addObserver(new LoadingView.Observer() {
-            @Override
-            public void onShowLoadingUIComplete() {
-                mStartIcon.setVisibility(GONE);
-            }
-
-            @Override
-            public void onHideLoadingUIComplete() {
-                mStartIcon.setVisibility(VISIBLE);
-            }
-        });
-        mLoadingView.addObserver(loadingViewObserver);
-        mLoadingView.showLoadingUI();
-    }
-
-    /**
-     * Hides the {@link LoadingView} at the start of the chip view.
-     * @param loadingViewObserver A {@link LoadingView.Observer} to add to the LoadingView.
-     */
-    public void hideLoadingView(LoadingView.Observer loadingViewObserver) {
-        mLoadingView.addObserver(loadingViewObserver);
-        mLoadingView.hideLoadingUI();
-    }
-
-    /**
-     * Adds a remove icon (X button) at the trailing end of the chip next to the primary text.
-     */
-    public void addRemoveIcon() {
-        if (mEndIconWrapper != null) return;
-
-        ChromeImageView endIcon = new ChromeImageView(getContext());
-        endIcon.setImageResource(R.drawable.btn_close);
-        ApiCompatibilityUtils.setImageTintList(endIcon, mPrimaryText.getTextColors());
-
-        // Adding a wrapper view around the X icon to make the touch target larger, which would
-        // cover the start and end margin for the X icon, and full height of the chip.
-        mEndIconWrapper = new FrameLayout(getContext());
-        mEndIconWrapper.setId(R.id.chip_cancel_btn);
-
-        FrameLayout.LayoutParams layoutParams =
-                new FrameLayout.LayoutParams(mEndIconWidth, mEndIconHeight);
-        layoutParams.setMarginStart(mEndIconStartPadding);
-        layoutParams.setMarginEnd(mEndIconEndPadding);
-        layoutParams.gravity = Gravity.CENTER_VERTICAL;
-        mEndIconWrapper.addView(endIcon, layoutParams);
-        addView(mEndIconWrapper,
-                new LayoutParams(
-                        ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
-
-        // Remove the end padding from the chip to make X icon touch target extend till the end of
-        // the chip.
-        ViewCompat.setPaddingRelative(
-                this, getPaddingStart(), getPaddingTop(), 0, getPaddingBottom());
-    }
-
-    /**
-     * Sets a {@link android.view.View.OnClickListener} for the remove icon.
-     * {@link ChipView#addRemoveIcon()} must be called prior to this method.
-     * @param listener The listener to be invoked on click events.
-     */
-    public void setRemoveIconClickListener(OnClickListener listener) {
-        mEndIconWrapper.setOnClickListener(listener);
-        String chipText = mPrimaryText.getText().toString();
-        assert !TextUtils.isEmpty(chipText);
-        mEndIconWrapper.setContentDescription(mPrimaryText.getContext().getString(
-                R.string.chip_remove_icon_content_description, chipText));
-    }
-
-    /**
-     * Returns the {@link TextView} that contains the label of the chip.
-     * @return A {@link TextView}.
-     */
-    public TextView getPrimaryTextView() {
-        return mPrimaryText;
-    }
-
-    /**
-     * Returns the {@link TextView} that contains the secondary label of the chip. If it wasn't used
-     * until now, this creates the view.
-     * @return A {@link TextView}.
-     */
-    public TextView getSecondaryTextView() {
-        if (mSecondaryText == null) {
-            mSecondaryText = new AppCompatTextView(
-                    new ContextThemeWrapper(getContext(), R.style.ChipTextView));
-            ApiCompatibilityUtils.setTextAppearance(mSecondaryText, mSecondaryTextAppearanceId);
-            // Ensure that basic state changes are aligned with the ChipView. They update
-            // automatically once the view is part of the hierarchy.
-            mSecondaryText.setSelected(isSelected());
-            mSecondaryText.setEnabled(isEnabled());
-            addView(mSecondaryText);
-        }
-        return mSecondaryText;
-    }
-
-    /**
-     * Returns the {@link RectProvider} that contains the start icon for the chip view.
-     * @return A {@link RectProvider}
-     */
-    public RectProvider getStartIconViewRect() {
-        return new ViewRectProvider(mStartIcon);
-    }
-
-    /**
-     * Sets the correct tinting on the Chip's image view.
-     * @param tintWithTextColor If true then the image view will be tinted with the primary text
-     *      color. If not, the tint will be cleared.
-     */
-    private void setTint(boolean tintWithTextColor) {
-        if (mPrimaryText.getTextColors() != null && tintWithTextColor) {
-            ApiCompatibilityUtils.setImageTintList(mStartIcon, mPrimaryText.getTextColors());
-        } else {
-            ApiCompatibilityUtils.setImageTintList(mStartIcon, null);
-        }
-    }
-
-    /**
-     * Sets border around the chip. If width is zero, then no border is drawn.
-     * @param width of the border in pixels.
-     * @param color of the border.
-     */
-    public void setBorder(int width, @ColorInt int color) {
-        mRippleBackgroundHelper.setBorder(width, color);
-    }
-
-    @Override
-    public void setBackgroundColor(@ColorInt int color) {
-        mRippleBackgroundHelper.setBackgroundColor(color);
-    }
-
-    /**
-     * @return The corner radius in pixels of this ChipView.
-     */
-    public @Px int getCornerRadius() {
-        return mCornerRadius;
-    }
-}
diff --git a/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java b/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java
index e04da7c..32125f1 100644
--- a/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java
+++ b/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java
@@ -194,7 +194,7 @@
     /**
      * @param color a single color to be set as the background color on the background drawable.
      */
-    void setBackgroundColor(@ColorInt int color) {
+    public void setBackgroundColor(@ColorInt int color) {
         mBackgroundGradient.setColor(color);
     }
 
@@ -203,7 +203,7 @@
      * @param width of the border in pixels.
      * @param color of the border.
      */
-    void setBorder(int width, @ColorInt int color) {
+    public void setBorder(int width, @ColorInt int color) {
         mBackgroundGradient.setStroke(width, color);
     }
 
diff --git a/ui/android/java/strings/android_ui_strings.grd b/ui/android/java/strings/android_ui_strings.grd
index d47683d..23b6eb7a 100644
--- a/ui/android/java/strings/android_ui_strings.grd
+++ b/ui/android/java/strings/android_ui_strings.grd
@@ -182,9 +182,6 @@
       <message name="IDS_LINK_COPIED" desc="Notification telling the user that the url has been copied to clipboard. [CHAR_LIMIT=32]">
         Link copied
       </message>
-      <message name="IDS_CHIP_REMOVE_ICON_CONTENT_DESCRIPTION" desc="Accessibility string for X icon on a chip announcing that clicking on this icon will remove this input chip.">
-        Remove '<ph name="CHIP_LABEL">%1$s<ex>News</ex></ph>'
-      </message>
     </messages>
   </release>
 </grit>
diff --git a/ui/chromeos/styles/cros_typography.json5 b/ui/chromeos/styles/cros_typography.json5
index b8d1e80..4dcf0ad 100644
--- a/ui/chromeos/styles/cros_typography.json5
+++ b/ui/chromeos/styles/cros_typography.json5
@@ -14,7 +14,7 @@
   typography: {
     font_families: {
       font_family_google_sans: "'Google Sans', 'Noto Sans', sans-serif",
-      font_family_roboto: "Roboto, 'Noto Sans', sans-serif",
+      font_family_roboto: "Roboto, 'Roboto', 'Noto Sans', sans-serif",
     },
     typefaces: {
       headline_1: {
diff --git a/ui/events/ozone/evdev/BUILD.gn b/ui/events/ozone/evdev/BUILD.gn
index 8e6a5774..063ea79 100644
--- a/ui/events/ozone/evdev/BUILD.gn
+++ b/ui/events/ozone/evdev/BUILD.gn
@@ -184,6 +184,7 @@
   }
 
   visibility += [
+    "//ash/webui/diagnostics_ui/*",
     "//ui/chromeos/*",
     "//ui/ozone/*",
   ]
diff --git a/ui/gfx/animation/keyframe/animation_curve.cc b/ui/gfx/animation/keyframe/animation_curve.cc
index 17fcc23..52bf7343 100644
--- a/ui/gfx/animation/keyframe/animation_curve.cc
+++ b/ui/gfx/animation/keyframe/animation_curve.cc
@@ -5,6 +5,7 @@
 #include "ui/gfx/animation/keyframe/animation_curve.h"
 
 #include "base/check.h"
+#include "ui/gfx/geometry/transform_operations.h"
 
 namespace gfx {
 
diff --git a/ui/gfx/animation/keyframe/animation_curve.h b/ui/gfx/animation/keyframe/animation_curve.h
index 105c53e..3b3d7c5 100644
--- a/ui/gfx/animation/keyframe/animation_curve.h
+++ b/ui/gfx/animation/keyframe/animation_curve.h
@@ -13,7 +13,6 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size_f.h"
 #include "ui/gfx/geometry/transform.h"
-#include "ui/gfx/geometry/transform_operations.h"
 
 namespace gfx {
 class TransformOperations;
diff --git a/ui/gfx/image/image_skia.h b/ui/gfx/image/image_skia.h
index 156c8283..60cc102 100644
--- a/ui/gfx/image/image_skia.h
+++ b/ui/gfx/image/image_skia.h
@@ -53,6 +53,10 @@
   // at |scale| and uses its dimensions to calculate the size in DIP.
   ImageSkia(std::unique_ptr<ImageSkiaSource> source, float scale);
 
+  // This constructor is explicitly deleted to ensure callers don't accidentally
+  // pass an int and have it converted to float.
+  ImageSkia(std::unique_ptr<ImageSkiaSource> source, int dont_use) = delete;
+
   explicit ImageSkia(const gfx::ImageSkiaRep& image_rep);
 
   // Copies a reference to |other|'s storage.
diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc
index 9ff516e..3c58e65d 100644
--- a/ui/gtk/gtk_ui.cc
+++ b/ui/gtk/gtk_ui.cc
@@ -211,7 +211,8 @@
   gfx::Size GetMinimumSize() const override { return gfx::Size(); }
   void Paint(gfx::Canvas* canvas, const gfx::Size& size) override {
     gfx::ImageSkia image(
-        std::make_unique<GtkButtonImageSource>(focus_, button_state_, size), 1);
+        std::make_unique<GtkButtonImageSource>(focus_, button_state_, size),
+        1.f);
     canvas->DrawImageInt(image, 0, 0);
   }
 
diff --git a/ui/lottie/animation.cc b/ui/lottie/animation.cc
index 1cf0a529d..e500da9 100644
--- a/ui/lottie/animation.cc
+++ b/ui/lottie/animation.cc
@@ -243,11 +243,8 @@
     SkSamplingOptions&) {
   cc::SkottieFrameDataProvider::ImageAsset& image_asset =
       *image_assets_.at(asset_id);
-  absl::optional<cc::SkottieFrameData> frame_data =
-      image_asset.GetFrameData(t, canvas->image_scale());
-  if (frame_data) {
-    all_frame_data.emplace(asset_id, std::move(frame_data.value()));
-  }
+  all_frame_data.emplace(asset_id,
+                         image_asset.GetFrameData(t, canvas->image_scale()));
   // Since this callback is only used for Seek() and not rendering, the output
   // arguments can be ignored and NO_UPDATE can be returned.
   return cc::SkottieWrapper::FrameDataFetchResult::NO_UPDATE;
diff --git a/ui/lottie/animation_unittest.cc b/ui/lottie/animation_unittest.cc
index b35b9f25..3ff4750 100644
--- a/ui/lottie/animation_unittest.cc
+++ b/ui/lottie/animation_unittest.cc
@@ -126,16 +126,13 @@
     ImageAssetImpl(const ImageAssetImpl& other) = delete;
     ImageAssetImpl& operator=(const ImageAssetImpl& other) = delete;
 
-    absl::optional<cc::SkottieFrameData> GetFrameData(
-        float t,
-        float scale_factor) override {
+    cc::SkottieFrameData GetFrameData(float t, float scale_factor) override {
       last_frame_t_ = t;
       last_frame_scale_factor_ = scale_factor;
       return current_frame_data_;
     }
 
-    void set_current_frame_data(
-        absl::optional<cc::SkottieFrameData> current_frame_data) {
+    void set_current_frame_data(cc::SkottieFrameData current_frame_data) {
       current_frame_data_ = std::move(current_frame_data);
     }
 
@@ -149,7 +146,7 @@
 
     ~ImageAssetImpl() override = default;
 
-    absl::optional<cc::SkottieFrameData> current_frame_data_;
+    cc::SkottieFrameData current_frame_data_;
     absl::optional<float> last_frame_t_;
     absl::optional<float> last_frame_scale_factor_;
   };
@@ -993,34 +990,6 @@
                               cc::HashSkottieResourceId("image_1"), frame_1)));
 }
 
-TEST_F(AnimationWithImageAssetsTest, SkipsNullAnimationImages) {
-  AdvanceClock(base::Milliseconds(300));
-
-  animation_->Start(Animation::Style::kLoop);
-
-  asset_0_->set_current_frame_data(CreateHighQualityTestFrameData());
-
-  display_list_->StartPaint();
-  animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
-  display_list_->EndPaintOfUnpaired(gfx::Rect(animation_->GetOriginalSize()));
-  display_list_->ReleaseAsRecord();
-
-  AdvanceClock(animation_->GetAnimationDuration() / 4);
-
-  asset_0_->set_current_frame_data(absl::nullopt);
-
-  display_list_->StartPaint();
-  animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
-  display_list_->EndPaintOfUnpaired(gfx::Rect(animation_->GetOriginalSize()));
-  sk_sp<cc::PaintRecord> paint_record = display_list_->ReleaseAsRecord();
-  ASSERT_THAT(paint_record, NotNull());
-  ASSERT_THAT(paint_record->size(), Eq(1u));
-  const cc::DrawSkottieOp* op =
-      paint_record->GetOpAtForTesting<cc::DrawSkottieOp>(0);
-  ASSERT_THAT(op, NotNull());
-  EXPECT_THAT(op->images, IsEmpty());
-}
-
 TEST_F(AnimationWithImageAssetsTest, LoadsCorrectFrameTimestamp) {
   AdvanceClock(base::Milliseconds(300));
 
diff --git a/ui/message_center/public/cpp/message_center_constants.h b/ui/message_center/public/cpp/message_center_constants.h
index 59adee0..e56f94df 100644
--- a/ui/message_center/public/cpp/message_center_constants.h
+++ b/ui/message_center/public/cpp/message_center_constants.h
@@ -70,9 +70,9 @@
 
 // Message.
 
-// Max number of lines for message_view_.
-constexpr int kMaxLinesForMessageView = 1;
-constexpr int kMaxLinesForExpandedMessageView = 4;
+// Max number of lines for message_label_.
+constexpr int kMaxLinesForMessageLabel = 1;
+constexpr int kMaxLinesForExpandedMessageLabel = 4;
 
 // Character limit = pixels per line * line limit / min. pixels per character.
 constexpr size_t kMessageCharacterLimit =
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc
index 0dc8d90..b5362e5d 100644
--- a/ui/message_center/views/notification_view.cc
+++ b/ui/message_center/views/notification_view.cc
@@ -46,12 +46,12 @@
 // Minimum size of a button in the actions row.
 constexpr gfx::Size kActionButtonMinSize(0, 32);
 
-constexpr int kMessageViewWidthWithIcon =
+constexpr int kMessageLabelWidthWithIcon =
     kNotificationWidth - kIconViewSize.width() -
     kLeftContentPaddingWithIcon.left() - kLeftContentPaddingWithIcon.right() -
     kContentRowPadding.left() - kContentRowPadding.right();
 
-constexpr int kMessageViewWidth =
+constexpr int kMessageLabelWidth =
     kNotificationWidth - kLeftContentPadding.left() -
     kLeftContentPadding.right() - kContentRowPadding.left() -
     kContentRowPadding.right();
@@ -471,16 +471,16 @@
   // Ideally, we should fix the original bug, but it seems there's no obvious
   // solution for the bug according to https://crbug.com/678337#c7, we should
   // ensure that the change won't break any of the users of BoxLayout class.
-  const int message_view_width =
-      (IsIconViewShown() ? kMessageViewWidthWithIcon : kMessageViewWidth) -
+  const int message_label_width =
+      (IsIconViewShown() ? kMessageLabelWidthWithIcon : kMessageLabelWidth) -
       GetInsets().width();
   if (title_view_)
-    title_view_->SizeToFit(message_view_width);
-  if (message_view()) {
-    message_view()->SetMultiLine(true);
-    message_view()->SetMaxLines(expanded ? kMaxLinesForExpandedMessageView
-                                         : kMaxLinesForMessageView);
-    message_view()->SizeToFit(message_view_width);
+    title_view_->SizeToFit(message_label_width);
+  if (message_label()) {
+    message_label()->SetMultiLine(true);
+    message_label()->SetMaxLines(expanded ? kMaxLinesForExpandedMessageLabel
+                                          : kMaxLinesForMessageLabel);
+    message_label()->SizeToFit(message_label_width);
   }
   NotificationViewBase::UpdateViewForExpandedState(expanded);
 }
@@ -551,8 +551,8 @@
     return false;
 
   // Expandable if the message exceeds one line.
-  if (message_view() && message_view()->GetVisible() &&
-      message_view()->GetRequiredLines() > 1) {
+  if (message_label() && message_label()->GetVisible() &&
+      message_label()->GetRequiredLines() > 1) {
     return true;
   }
   // Expandable if there is at least one inline action.
diff --git a/ui/message_center/views/notification_view_base.cc b/ui/message_center/views/notification_view_base.cc
index 0b63fd1..e94e4cc 100644
--- a/ui/message_center/views/notification_view_base.cc
+++ b/ui/message_center/views/notification_view_base.cc
@@ -282,7 +282,7 @@
 
   CreateOrUpdateHeaderView(notification);
   CreateOrUpdateTitleView(notification);
-  CreateOrUpdateMessageView(notification);
+  CreateOrUpdateMessageLabel(notification);
   CreateOrUpdateCompactTitleMessageView(notification);
   CreateOrUpdateProgressViews(notification);
   CreateOrUpdateListItemViews(notification);
@@ -329,7 +329,7 @@
 
   // We need to call IsExpandable() at the end of Layout() call, since whether
   // we should show expand button or not depends on the current view layout.
-  // (e.g. Show expand button when |message_view_| exceeds one line.)
+  // (e.g. Show expand button when |message_label_| exceeds one line.)
   SetExpandButtonEnabled(IsExpandable());
   header_row_->Layout();
 
@@ -645,32 +645,32 @@
   status_view_->SetText(notification.progress_status());
 }
 
-void NotificationViewBase::CreateOrUpdateMessageView(
+void NotificationViewBase::CreateOrUpdateMessageLabel(
     const Notification& notification) {
   if (notification.type() == NOTIFICATION_TYPE_PROGRESS ||
       notification.message().empty()) {
-    // Deletion will also remove |message_view_| from its parent.
-    delete message_view_;
-    message_view_ = nullptr;
+    // Deletion will also remove |message_label_| from its parent.
+    delete message_label_;
+    message_label_ = nullptr;
     return;
   }
 
   const std::u16string& text = gfx::TruncateString(
       notification.message(), kMessageCharacterLimit, gfx::WORD_BREAK);
 
-  if (!message_view_) {
-    auto message_view = std::make_unique<views::Label>(
+  if (!message_label_) {
+    auto message_label = std::make_unique<views::Label>(
         text, views::style::CONTEXT_DIALOG_BODY_TEXT,
         views::style::STYLE_SECONDARY);
-    message_view->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
-    message_view->SetAllowCharacterBreak(true);
-    message_view_ = AddViewToLeftContent(std::move(message_view));
+    message_label->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
+    message_label->SetAllowCharacterBreak(true);
+    message_label_ = AddViewToLeftContent(std::move(message_label));
   } else {
-    message_view_->SetText(text);
-    ReorderViewInLeftContent(message_view_);
+    message_label_->SetText(text);
+    ReorderViewInLeftContent(message_label_);
   }
 
-  message_view_->SetVisible(notification.items().empty());
+  message_label_->SetVisible(notification.items().empty());
 }
 
 void NotificationViewBase::CreateOrUpdateProgressViews(
@@ -689,7 +689,7 @@
 
   const std::vector<NotificationItem>& items = notification.items();
 
-  for (size_t i = 0; i < items.size() && i < kMaxLinesForExpandedMessageView;
+  for (size_t i = 0; i < items.size() && i < kMaxLinesForExpandedMessageLabel;
        ++i) {
     std::unique_ptr<views::View> item_view = CreateItemView(items[i]);
     item_views_.push_back(AddViewToLeftContent(std::move(item_view)));
@@ -884,13 +884,13 @@
     inline_reply_->SetVisible(false);
   }
 
-  for (size_t i = kMaxLinesForMessageView; i < item_views_.size(); ++i) {
+  for (size_t i = kMaxLinesForMessageLabel; i < item_views_.size(); ++i) {
     item_views_[i]->SetVisible(expanded);
   }
   if (status_view_)
     status_view_->SetVisible(expanded);
 
-  int max_items = expanded ? item_views_.size() : kMaxLinesForMessageView;
+  int max_items = expanded ? item_views_.size() : kMaxLinesForMessageLabel;
   if (!for_ash_notification_ && list_items_count_ > max_items)
     header_row_->SetOverflowIndicator(list_items_count_ - max_items);
   else if (!item_views_.empty())
diff --git a/ui/message_center/views/notification_view_base.h b/ui/message_center/views/notification_view_base.h
index 458d8e65..bd85548 100644
--- a/ui/message_center/views/notification_view_base.h
+++ b/ui/message_center/views/notification_view_base.h
@@ -243,8 +243,8 @@
   views::View* left_content() { return left_content_; }
   views::View* right_content() { return right_content_; }
 
-  views::Label* message_view() { return message_view_; }
-  const views::Label* message_view() const { return message_view_; }
+  views::Label* message_label() { return message_label_; }
+  const views::Label* message_label() const { return message_label_; }
 
   ProportionalImageView* icon_view() const { return icon_view_; }
 
@@ -326,7 +326,7 @@
 
   friend class NotificationViewBaseTest;
 
-  void CreateOrUpdateMessageView(const Notification& notification);
+  void CreateOrUpdateMessageLabel(const Notification& notification);
   virtual void CreateOrUpdateProgressViews(const Notification& notification);
   void CreateOrUpdateListItemViews(const Notification& notification);
   void CreateOrUpdateIconView(const Notification& notification);
@@ -375,7 +375,7 @@
   views::View* right_content_ = nullptr;
 
   // Views which are dynamically created inside view hierarchy.
-  raw_ptr<views::Label> message_view_ = nullptr;
+  raw_ptr<views::Label> message_label_ = nullptr;
   raw_ptr<views::Label> status_view_ = nullptr;
   raw_ptr<ProportionalImageView> icon_view_ = nullptr;
   views::View* image_container_view_ = nullptr;
diff --git a/ui/message_center/views/notification_view_base_unittest.cc b/ui/message_center/views/notification_view_base_unittest.cc
index 3b15007..52a082b 100644
--- a/ui/message_center/views/notification_view_base_unittest.cc
+++ b/ui/message_center/views/notification_view_base_unittest.cc
@@ -348,7 +348,7 @@
 // * FormatContextMessageTest
 
 TEST_F(NotificationViewBaseTest, CreateOrUpdateTest) {
-  EXPECT_NE(nullptr, notification_view()->message_view_);
+  EXPECT_NE(nullptr, notification_view()->message_label_);
   EXPECT_NE(nullptr, notification_view()->icon_view_);
   EXPECT_NE(nullptr, notification_view()->image_container_view_);
 
@@ -360,7 +360,7 @@
 
   notification_view()->CreateOrUpdateViews(*notification);
 
-  EXPECT_EQ(nullptr, notification_view()->message_view_.get());
+  EXPECT_EQ(nullptr, notification_view()->message_label_.get());
   EXPECT_TRUE(notification_view()->image_container_view_->children().empty());
   EXPECT_EQ(nullptr, notification_view()->icon_view_.get());
 }
@@ -1054,7 +1054,7 @@
   notification_view()->ToggleExpanded();
 
   // Get the height of the message view with a short title.
-  const int message_height = notification_view()->message_view_->height();
+  const int message_height = notification_view()->message_label_->height();
 
   notification->set_title(
       u"consectetur adipiscing elit, sed do eiusmod tempor incididunt ut "
@@ -1063,7 +1063,7 @@
   UpdateNotificationViews(*notification);
 
   // The height of the message view should stay the same with a long title.
-  EXPECT_EQ(message_height, notification_view()->message_view_->height());
+  EXPECT_EQ(message_height, notification_view()->message_label_->height());
 }
 
 TEST_F(NotificationViewBaseTest, AppNameExtension) {
diff --git a/ui/message_center/views/notification_view_unittest.cc b/ui/message_center/views/notification_view_unittest.cc
index e38864cc..3928be09 100644
--- a/ui/message_center/views/notification_view_unittest.cc
+++ b/ui/message_center/views/notification_view_unittest.cc
@@ -232,7 +232,7 @@
   }
   views::View* left_content() { return notification_view_->left_content(); }
   views::Label* title_view() { return notification_view_->title_view_; }
-  views::Label* message_view() { return notification_view_->message_view(); }
+  views::Label* message_label() { return notification_view_->message_label(); }
   views::View* inline_settings_row() {
     return notification_view_->inline_settings_row();
   }
@@ -289,9 +289,9 @@
 
 TEST_F(NotificationViewTest, UpdateViewsOrderingTest) {
   EXPECT_NE(nullptr, title_view());
-  EXPECT_NE(nullptr, message_view());
+  EXPECT_NE(nullptr, message_label());
   EXPECT_EQ(0, left_content()->GetIndexOf(title_view()));
-  EXPECT_EQ(1, left_content()->GetIndexOf(message_view()));
+  EXPECT_EQ(1, left_content()->GetIndexOf(message_label()));
 
   std::unique_ptr<Notification> notification = CreateSimpleNotification();
   notification->set_title(std::u16string());
@@ -299,17 +299,17 @@
   UpdateNotificationViews(*notification);
 
   EXPECT_EQ(nullptr, title_view());
-  EXPECT_NE(nullptr, message_view());
-  EXPECT_EQ(0, left_content()->GetIndexOf(message_view()));
+  EXPECT_NE(nullptr, message_label());
+  EXPECT_EQ(0, left_content()->GetIndexOf(message_label()));
 
   notification->set_title(u"title");
 
   UpdateNotificationViews(*notification);
 
   EXPECT_NE(nullptr, title_view());
-  EXPECT_NE(nullptr, message_view());
+  EXPECT_NE(nullptr, message_label());
   EXPECT_EQ(0, left_content()->GetIndexOf(title_view()));
-  EXPECT_EQ(1, left_content()->GetIndexOf(message_view()));
+  EXPECT_EQ(1, left_content()->GetIndexOf(message_label()));
 }
 
 TEST_F(NotificationViewTest, CreateOrUpdateTitle) {
@@ -607,7 +607,7 @@
 
   UpdateNotificationViews(*notification);
   EXPECT_FALSE(notification_view()->expanded_);
-  const int collapsed_height = message_view()->height();
+  const int collapsed_height = message_label()->height();
   const int collapsed_preferred_height =
       notification_view()->GetPreferredSize().height();
   EXPECT_LT(0, collapsed_height);
@@ -615,13 +615,13 @@
 
   notification_view()->ToggleExpanded();
   EXPECT_TRUE(notification_view()->expanded_);
-  EXPECT_LT(collapsed_height, message_view()->height());
+  EXPECT_LT(collapsed_height, message_label()->height());
   EXPECT_LT(collapsed_preferred_height,
             notification_view()->GetPreferredSize().height());
 
   notification_view()->ToggleExpanded();
   EXPECT_FALSE(notification_view()->expanded_);
-  EXPECT_EQ(collapsed_height, message_view()->height());
+  EXPECT_EQ(collapsed_height, message_label()->height());
   EXPECT_EQ(collapsed_preferred_height,
             notification_view()->GetPreferredSize().height());
 }
diff --git a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
index b474dfc..25503a4 100644
--- a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
+++ b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
@@ -111,6 +111,8 @@
   supports_dmabuf_ = supports_dma_buf;
 
   BindHostInterface(std::move(remote_host));
+
+  ProcessPendingTasks();
 }
 
 void WaylandBufferManagerGpu::OnSubmission(gfx::AcceleratedWidget widget,
@@ -207,10 +209,11 @@
     return;
   }
 
-  DCHECK(remote_host_);
-  remote_host_->CreateDmabufBasedBuffer(
-      mojo::PlatformHandle(std::move(dmabuf_fd)), size, strides, offsets,
+  base::OnceClosure task = base::BindOnce(
+      &WaylandBufferManagerGpu::CreateDmabufBasedBufferTask,
+      base::Unretained(this), std::move(dmabuf_fd), size, strides, offsets,
       modifiers, current_format, planes_count, buffer_id);
+  RunOrQueueTask(std::move(task));
 }
 
 void WaylandBufferManagerGpu::CreateShmBasedBuffer(base::ScopedFD shm_fd,
@@ -228,9 +231,10 @@
     return;
   }
 
-  DCHECK(remote_host_);
-  remote_host_->CreateShmBasedBuffer(mojo::PlatformHandle(std::move(shm_fd)),
-                                     length, size, buffer_id);
+  base::OnceClosure task = base::BindOnce(
+      &WaylandBufferManagerGpu::CreateShmBasedBufferTask,
+      base::Unretained(this), std::move(shm_fd), length, size, buffer_id);
+  RunOrQueueTask(std::move(task));
 }
 
 void WaylandBufferManagerGpu::CreateSolidColorBuffer(SkColor color,
@@ -246,8 +250,10 @@
     return;
   }
 
-  DCHECK(remote_host_);
-  remote_host_->CreateSolidColorBuffer(size, color, buf_id);
+  base::OnceClosure task =
+      base::BindOnce(&WaylandBufferManagerGpu::CreateSolidColorBufferTask,
+                     base::Unretained(this), color, size, buf_id);
+  RunOrQueueTask(std::move(task));
 }
 
 void WaylandBufferManagerGpu::CommitBuffer(gfx::AcceleratedWidget widget,
@@ -280,8 +286,10 @@
     return;
   }
 
-  DCHECK(remote_host_);
-  remote_host_->CommitOverlays(widget, std::move(overlays));
+  base::OnceClosure task =
+      base::BindOnce(&WaylandBufferManagerGpu::CommitOverlaysTask,
+                     base::Unretained(this), widget, std::move(overlays));
+  RunOrQueueTask(std::move(task));
 }
 
 void WaylandBufferManagerGpu::DestroyBuffer(gfx::AcceleratedWidget widget,
@@ -295,8 +303,10 @@
     return;
   }
 
-  DCHECK(remote_host_);
-  remote_host_->DestroyBuffer(widget, buffer_id);
+  base::OnceClosure task =
+      base::BindOnce(&WaylandBufferManagerGpu::DestroyBufferTask,
+                     base::Unretained(this), widget, buffer_id);
+  RunOrQueueTask(std::move(task));
 }
 
 #if defined(WAYLAND_GBM)
@@ -432,4 +442,77 @@
   associated_receiver_.reset();
 }
 
+void WaylandBufferManagerGpu::RunOrQueueTask(base::OnceClosure task) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
+  if (remote_host_) {
+    std::move(task).Run();
+    return;
+  }
+  pending_tasks_.emplace_back(std::move(task));
+}
+
+void WaylandBufferManagerGpu::ProcessPendingTasks() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
+  DCHECK(remote_host_);
+
+  for (auto& task : pending_tasks_)
+    std::move(task).Run();
+
+  pending_tasks_.clear();
+}
+
+void WaylandBufferManagerGpu::CreateDmabufBasedBufferTask(
+    base::ScopedFD dmabuf_fd,
+    gfx::Size size,
+    const std::vector<uint32_t>& strides,
+    const std::vector<uint32_t>& offsets,
+    const std::vector<uint64_t>& modifiers,
+    uint32_t current_format,
+    uint32_t planes_count,
+    uint32_t buffer_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
+  DCHECK(remote_host_);
+
+  remote_host_->CreateDmabufBasedBuffer(
+      mojo::PlatformHandle(std::move(dmabuf_fd)), size, strides, offsets,
+      modifiers, current_format, planes_count, buffer_id);
+}
+
+void WaylandBufferManagerGpu::CreateShmBasedBufferTask(base::ScopedFD shm_fd,
+                                                       size_t length,
+                                                       gfx::Size size,
+                                                       uint32_t buffer_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
+  DCHECK(remote_host_);
+
+  remote_host_->CreateShmBasedBuffer(mojo::PlatformHandle(std::move(shm_fd)),
+                                     length, size, buffer_id);
+}
+
+void WaylandBufferManagerGpu::CreateSolidColorBufferTask(SkColor color,
+                                                         const gfx::Size& size,
+                                                         uint32_t buf_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
+  DCHECK(remote_host_);
+
+  remote_host_->CreateSolidColorBuffer(size, color, buf_id);
+}
+
+void WaylandBufferManagerGpu::CommitOverlaysTask(
+    gfx::AcceleratedWidget widget,
+    std::vector<ozone::mojom::WaylandOverlayConfigPtr> overlays) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
+  DCHECK(remote_host_);
+
+  remote_host_->CommitOverlays(widget, std::move(overlays));
+}
+
+void WaylandBufferManagerGpu::DestroyBufferTask(gfx::AcceleratedWidget widget,
+                                                uint32_t buffer_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
+  DCHECK(remote_host_);
+
+  remote_host_->DestroyBuffer(widget, buffer_id);
+}
+
 }  // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
index 3b4debef..6dc1568dd 100644
--- a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
+++ b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
@@ -8,6 +8,7 @@
 #include <map>
 #include <memory>
 
+#include "base/callback_forward.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/threading/thread_checker.h"
@@ -161,6 +162,8 @@
                            GbmSurfacelessWaylandCommitOverlaysCallbacksTest);
   FRIEND_TEST_ALL_PREFIXES(WaylandSurfaceFactoryTest,
                            GbmSurfacelessWaylandGroupOnSubmissionCallbacksTest);
+  FRIEND_TEST_ALL_PREFIXES(WaylandBufferManagerTest,
+                           ExecutesTasksAfterInitialization);
 
   void BindHostInterface(
       mojo::PendingRemote<ozone::mojom::WaylandBufferManagerHost> remote_host);
@@ -183,6 +186,34 @@
 
   void OnHostDisconnected();
 
+  // Executes the |task| immediately if the pipe has been bound. Otherwise, the
+  // tasks are stored and executed after the remote pipe becomes bound.
+  void RunOrQueueTask(base::OnceClosure task);
+  // Called when the manager is initialized and the remote host is bound. Runs
+  // pending tasks.
+  void ProcessPendingTasks();
+
+  // Internal methods that do calls to the |remote_host|.
+  void CreateDmabufBasedBufferTask(base::ScopedFD dmabuf_fd,
+                                   gfx::Size size,
+                                   const std::vector<uint32_t>& strides,
+                                   const std::vector<uint32_t>& offsets,
+                                   const std::vector<uint64_t>& modifiers,
+                                   uint32_t current_format,
+                                   uint32_t planes_count,
+                                   uint32_t buffer_id);
+  void CreateShmBasedBufferTask(base::ScopedFD shm_fd,
+                                size_t length,
+                                gfx::Size size,
+                                uint32_t buffer_id);
+  void CreateSolidColorBufferTask(SkColor color,
+                                  const gfx::Size& size,
+                                  uint32_t buf_id);
+  void CommitOverlaysTask(
+      gfx::AcceleratedWidget widget,
+      std::vector<ozone::mojom::WaylandOverlayConfigPtr> overlays);
+  void DestroyBufferTask(gfx::AcceleratedWidget widget, uint32_t buffer_id);
+
 #if defined(WAYLAND_GBM)
   // Finds drm render node, opens it and stores the handle into
   // |drm_render_node_fd|.
@@ -252,6 +283,9 @@
   // Keeps track of the next unique buffer ID.
   uint32_t next_buffer_id_ = 0;
 
+  // The tasks that are blocked on a remote_host pipe becoming bound.
+  std::vector<base::OnceClosure> pending_tasks_;
+
   // All calls must happen on the correct sequence. See comments in the
   // constructor for more details.
   SEQUENCE_CHECKER(gpu_sequence_checker_);
diff --git a/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc b/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc
index 2602679..0e74f67 100644
--- a/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc
+++ b/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc
@@ -2209,6 +2209,38 @@
   DestroyBufferAndSetTerminateExpectation(widget, kBufferId2, false /*fail*/);
 }
 
+TEST_P(WaylandBufferManagerTest, ExecutesTasksAfterInitialization) {
+  // Unbind the pipe.
+  manager_host_->OnChannelDestroyed();
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(buffer_manager_gpu_->remote_host_);
+  EXPECT_TRUE(buffer_manager_gpu_->pending_tasks_.empty());
+
+  constexpr uint32_t kDmabufBufferId = 1;
+  CreateDmabufBasedBufferAndSetTerminateExpectation(false /*fail*/,
+                                                    kDmabufBufferId);
+  buffer_manager_gpu_->CommitBuffer(window_->GetWidget(), kDmabufBufferId,
+                                    window_->GetBounds(), kDefaultScale,
+                                    window_->GetBounds());
+  DestroyBufferAndSetTerminateExpectation(gfx::kNullAcceleratedWidget,
+                                          kDmabufBufferId, false /*fail*/);
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(3u, buffer_manager_gpu_->pending_tasks_.size());
+
+  auto interface_ptr = manager_host_->BindInterface();
+  buffer_manager_gpu_->Initialize(
+      std::move(interface_ptr), {}, false, true, false,
+      /*supports_non_backed_solid_color_buffers*/ false);
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_TRUE(buffer_manager_gpu_->pending_tasks_.empty());
+}
+
 INSTANTIATE_TEST_SUITE_P(XdgVersionStableTest,
                          WaylandBufferManagerTest,
                          Values(wl::ServerConfig{